*** empty log message ***
[bpt/emacs.git] / src / term.c
1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
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)
10 any later version.
11
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.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
23
24 #include <config.h>
25 #include <stdio.h>
26 #include <ctype.h>
27 #include <string.h>
28
29 #include "termchar.h"
30 #include "termopts.h"
31 #include "lisp.h"
32 #include "buffer.h"
33 #include "character.h"
34 #include "charset.h"
35 #include "coding.h"
36 #include "keyboard.h"
37 #include "frame.h"
38 #include "disptab.h"
39 #include "termhooks.h"
40 #include "dispextern.h"
41 #include "window.h"
42 #include "keymap.h"
43
44 /* For now, don't try to include termcap.h. On some systems,
45 configure finds a non-standard termcap.h that the main build
46 won't find. */
47
48 #if defined HAVE_TERMCAP_H && 0
49 #include <termcap.h>
50 #else
51 extern void tputs P_ ((const char *, int, int (*)(int)));
52 extern int tgetent P_ ((char *, const char *));
53 extern int tgetflag P_ ((char *id));
54 extern int tgetnum P_ ((char *id));
55 #endif
56
57 #include "cm.h"
58 #ifdef HAVE_X_WINDOWS
59 #include "xterm.h"
60 #endif
61 #ifdef MAC_OS
62 #include "macterm.h"
63 #endif
64
65 static void turn_on_face P_ ((struct frame *, int face_id));
66 static void turn_off_face P_ ((struct frame *, int face_id));
67 static void tty_show_cursor P_ ((void));
68 static void tty_hide_cursor P_ ((void));
69
70 #define OUTPUT(a) \
71 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
72 #define OUTPUT1(a) tputs (a, 1, cmputc)
73 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
74
75 #define OUTPUT_IF(a) \
76 do { \
77 if (a) \
78 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
79 - curY), cmputc); \
80 } while (0)
81
82 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
83
84 /* Function to use to ring the bell. */
85
86 Lisp_Object Vring_bell_function;
87
88 /* Terminal characteristics that higher levels want to look at.
89 These are all extern'd in termchar.h */
90
91 int must_write_spaces; /* Nonzero means spaces in the text
92 must actually be output; can't just skip
93 over some columns to leave them blank. */
94 int min_padding_speed; /* Speed below which no padding necessary */
95
96 int line_ins_del_ok; /* Terminal can insert and delete lines */
97 int char_ins_del_ok; /* Terminal can insert and delete chars */
98 int scroll_region_ok; /* Terminal supports setting the
99 scroll window */
100 int scroll_region_cost; /* Cost of setting a scroll window,
101 measured in characters */
102 int memory_below_frame; /* Terminal remembers lines
103 scrolled off bottom */
104 int fast_clear_end_of_line; /* Terminal has a `ce' string */
105
106 /* Nonzero means no need to redraw the entire frame on resuming
107 a suspended Emacs. This is useful on terminals with multiple pages,
108 where one page is used for Emacs and another for all else. */
109
110 int no_redraw_on_reenter;
111
112 /* Hook functions that you can set to snap out the functions in this file.
113 These are all extern'd in termhooks.h */
114
115 void (*cursor_to_hook) P_ ((int, int));
116 void (*raw_cursor_to_hook) P_ ((int, int));
117 void (*clear_to_end_hook) P_ ((void));
118 void (*clear_frame_hook) P_ ((void));
119 void (*clear_end_of_line_hook) P_ ((int));
120
121 void (*ins_del_lines_hook) P_ ((int, int));
122
123 void (*delete_glyphs_hook) P_ ((int));
124
125 void (*ring_bell_hook) P_ ((void));
126
127 void (*reset_terminal_modes_hook) P_ ((void));
128 void (*set_terminal_modes_hook) P_ ((void));
129 void (*update_begin_hook) P_ ((struct frame *));
130 void (*update_end_hook) P_ ((struct frame *));
131 void (*set_terminal_window_hook) P_ ((int));
132 void (*insert_glyphs_hook) P_ ((struct glyph *, int));
133 void (*write_glyphs_hook) P_ ((struct glyph *, int));
134 void (*delete_glyphs_hook) P_ ((int));
135
136 int (*read_socket_hook) P_ ((int, struct input_event *, int, int));
137
138 void (*frame_up_to_date_hook) P_ ((struct frame *));
139
140 /* Return the current position of the mouse.
141
142 Set *f to the frame the mouse is in, or zero if the mouse is in no
143 Emacs frame. If it is set to zero, all the other arguments are
144 garbage.
145
146 If the motion started in a scroll bar, set *bar_window to the
147 scroll bar's window, *part to the part the mouse is currently over,
148 *x to the position of the mouse along the scroll bar, and *y to the
149 overall length of the scroll bar.
150
151 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
152 row of the character cell the mouse is over.
153
154 Set *time to the time the mouse was at the returned position.
155
156 This should clear mouse_moved until the next motion
157 event arrives. */
158
159 void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
160 Lisp_Object *bar_window,
161 enum scroll_bar_part *part,
162 Lisp_Object *x,
163 Lisp_Object *y,
164 unsigned long *time));
165
166 /* When reading from a minibuffer in a different frame, Emacs wants
167 to shift the highlight from the selected frame to the mini-buffer's
168 frame; under X, this means it lies about where the focus is.
169 This hook tells the window system code to re-decide where to put
170 the highlight. */
171
172 void (*frame_rehighlight_hook) P_ ((FRAME_PTR f));
173
174 /* If we're displaying frames using a window system that can stack
175 frames on top of each other, this hook allows you to bring a frame
176 to the front, or bury it behind all the other windows. If this
177 hook is zero, that means the device we're displaying on doesn't
178 support overlapping frames, so there's no need to raise or lower
179 anything.
180
181 If RAISE is non-zero, F is brought to the front, before all other
182 windows. If RAISE is zero, F is sent to the back, behind all other
183 windows. */
184
185 void (*frame_raise_lower_hook) P_ ((FRAME_PTR f, int raise));
186
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. */
192
193 void (*set_vertical_scroll_bar_hook)
194 P_ ((struct window *window,
195 int portion, int whole, int position));
196
197
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. */
205
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.
209
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.
214
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. */
218
219 void (*condemn_scroll_bars_hook) P_ ((FRAME_PTR frame));
220
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. */
223
224 void (*redeem_scroll_bar_hook) P_ ((struct window *window));
225
226 /* Remove all scroll bars on FRAME that haven't been saved since the
227 last call to `*condemn_scroll_bars_hook'.
228
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.
233
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. */
237
238 void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME));
239
240 /* Strings, numbers and flags taken from the termcap entry. */
241
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) */
280
281 /* Value of the "NC" (no_color_video) capability, or 0 if not
282 present. */
283
284 static int TN_no_color_video;
285
286 /* Meaning of bits in no_color_video. Each bit set means that the
287 corresponding attribute cannot be combined with colors. */
288
289 enum no_color_bit
290 {
291 NC_STANDOUT = 1 << 0,
292 NC_UNDERLINE = 1 << 1,
293 NC_REVERSE = 1 << 2,
294 NC_BLINK = 1 << 3,
295 NC_DIM = 1 << 4,
296 NC_BOLD = 1 << 5,
297 NC_INVIS = 1 << 6,
298 NC_PROTECT = 1 << 7,
299 NC_ALT_CHARSET = 1 << 8
300 };
301
302 /* "md" -- turn on bold (extra bright mode). */
303
304 char *TS_enter_bold_mode;
305
306 /* "mh" -- turn on half-bright mode. */
307
308 char *TS_enter_dim_mode;
309
310 /* "mb" -- enter blinking mode. */
311
312 char *TS_enter_blink_mode;
313
314 /* "mr" -- enter reverse video mode. */
315
316 char *TS_enter_reverse_mode;
317
318 /* "us"/"ue" -- start/end underlining. */
319
320 char *TS_exit_underline_mode, *TS_enter_underline_mode;
321
322 /* "as"/"ae" -- start/end alternate character set. Not really
323 supported, yet. */
324
325 char *TS_enter_alt_charset_mode, *TS_exit_alt_charset_mode;
326
327 /* "me" -- switch appearances off. */
328
329 char *TS_exit_attribute_mode;
330
331 /* "Co" -- number of colors. */
332
333 int TN_max_colors;
334
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. */
337
338 int TN_max_pairs;
339
340 /* "op" -- SVr4 set default pair to its original value. */
341
342 char *TS_orig_pair;
343
344 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
345 1 param, the color index. */
346
347 char *TS_set_foreground, *TS_set_background;
348
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.
355 For t1061. */
356
357 static int RPov; /* # chars to start a TS_repeat */
358
359 static int delete_in_insert_mode; /* delete mode == insert mode */
360
361 static int se_is_so; /* 1 if same string both enters and leaves
362 standout mode */
363
364 /* internal state */
365
366 /* The largest frame width in any call to calculate_costs. */
367
368 int max_frame_cols;
369
370 /* The largest frame height in any call to calculate_costs. */
371
372 int max_frame_lines;
373
374 static int costs_set; /* Nonzero if costs have been calculated. */
375
376 int insert_mode; /* Nonzero when in insert mode. */
377 int standout_mode; /* Nonzero when in standout mode. */
378
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.
382
383 Effectively it excludes the bottom frame_lines - specified_window_size
384 lines from those operations. */
385
386 int specified_window;
387
388 /* Frame currently being redisplayed; 0 if not currently redisplaying.
389 (Direct output does not count). */
390
391 FRAME_PTR updating_frame;
392
393 /* Provided for lisp packages. */
394
395 static int system_uses_terminfo;
396
397 /* Flag used in tty_show/hide_cursor. */
398
399 static int tty_cursor_hidden;
400
401 char *tparam ();
402
403 extern char *tgetstr ();
404 \f
405
406 #ifdef WINDOWSNT
407 /* We aren't X windows, but we aren't termcap either. This makes me
408 uncertain as to what value to use for frame.output_method. For
409 this file, we'll define FRAME_TERMCAP_P to be zero so that our
410 output hooks get called instead of the termcap functions. Probably
411 the best long-term solution is to define an output_windows_nt... */
412
413 #undef FRAME_TERMCAP_P
414 #define FRAME_TERMCAP_P(_f_) 0
415 #endif /* WINDOWSNT */
416
417 void
418 ring_bell ()
419 {
420 if (!NILP (Vring_bell_function))
421 {
422 Lisp_Object function;
423
424 /* Temporarily set the global variable to nil
425 so that if we get an error, it stays nil
426 and we don't call it over and over.
427
428 We don't specbind it, because that would carefully
429 restore the bad value if there's an error
430 and make the loop of errors happen anyway. */
431
432 function = Vring_bell_function;
433 Vring_bell_function = Qnil;
434
435 call0 (function);
436
437 Vring_bell_function = function;
438 }
439 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame)))
440 (*ring_bell_hook) ();
441 else
442 OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell);
443 }
444
445 void
446 set_terminal_modes ()
447 {
448 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
449 {
450 OUTPUT_IF (TS_termcap_modes);
451 OUTPUT_IF (TS_cursor_visible);
452 OUTPUT_IF (TS_keypad_mode);
453 losecursor ();
454 }
455 else
456 (*set_terminal_modes_hook) ();
457 }
458
459 void
460 reset_terminal_modes ()
461 {
462 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
463 {
464 turn_off_highlight ();
465 turn_off_insert ();
466 OUTPUT_IF (TS_end_keypad_mode);
467 OUTPUT_IF (TS_cursor_normal);
468 OUTPUT_IF (TS_end_termcap_modes);
469 OUTPUT_IF (TS_orig_pair);
470 /* Output raw CR so kernel can track the cursor hpos. */
471 cmputc ('\r');
472 }
473 else if (reset_terminal_modes_hook)
474 (*reset_terminal_modes_hook) ();
475 }
476
477 void
478 update_begin (f)
479 struct frame *f;
480 {
481 updating_frame = f;
482 if (!FRAME_TERMCAP_P (f))
483 update_begin_hook (f);
484 }
485
486 void
487 update_end (f)
488 struct frame *f;
489 {
490 if (FRAME_TERMCAP_P (f))
491 {
492 if (!XWINDOW (selected_window)->cursor_off_p)
493 tty_show_cursor ();
494 turn_off_insert ();
495 background_highlight ();
496 }
497 else
498 update_end_hook (f);
499
500 updating_frame = NULL;
501 }
502
503 void
504 set_terminal_window (size)
505 int size;
506 {
507 if (FRAME_TERMCAP_P (updating_frame))
508 {
509 specified_window = size ? size : FRAME_LINES (updating_frame);
510 if (scroll_region_ok)
511 set_scroll_region (0, specified_window);
512 }
513 else
514 set_terminal_window_hook (size);
515 }
516
517 void
518 set_scroll_region (start, stop)
519 int start, stop;
520 {
521 char *buf;
522 struct frame *sf = XFRAME (selected_frame);
523
524 if (TS_set_scroll_region)
525 buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1);
526 else if (TS_set_scroll_region_1)
527 buf = tparam (TS_set_scroll_region_1, 0, 0,
528 FRAME_LINES (sf), start,
529 FRAME_LINES (sf) - stop,
530 FRAME_LINES (sf));
531 else
532 buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (sf));
533
534 OUTPUT (buf);
535 xfree (buf);
536 losecursor ();
537 }
538
539 \f
540 static void
541 turn_on_insert ()
542 {
543 if (!insert_mode)
544 OUTPUT (TS_insert_mode);
545 insert_mode = 1;
546 }
547
548 void
549 turn_off_insert ()
550 {
551 if (insert_mode)
552 OUTPUT (TS_end_insert_mode);
553 insert_mode = 0;
554 }
555 \f
556 /* Handle highlighting. */
557
558 void
559 turn_off_highlight ()
560 {
561 if (standout_mode)
562 OUTPUT_IF (TS_end_standout_mode);
563 standout_mode = 0;
564 }
565
566 static void
567 turn_on_highlight ()
568 {
569 if (!standout_mode)
570 OUTPUT_IF (TS_standout_mode);
571 standout_mode = 1;
572 }
573
574 static void
575 toggle_highlight ()
576 {
577 if (standout_mode)
578 turn_off_highlight ();
579 else
580 turn_on_highlight ();
581 }
582
583
584 /* Make cursor invisible. */
585
586 static void
587 tty_hide_cursor ()
588 {
589 if (tty_cursor_hidden == 0)
590 {
591 tty_cursor_hidden = 1;
592 OUTPUT_IF (TS_cursor_invisible);
593 }
594 }
595
596
597 /* Ensure that cursor is visible. */
598
599 static void
600 tty_show_cursor ()
601 {
602 if (tty_cursor_hidden)
603 {
604 tty_cursor_hidden = 0;
605 OUTPUT_IF (TS_cursor_normal);
606 OUTPUT_IF (TS_cursor_visible);
607 }
608 }
609
610
611 /* Set standout mode to the state it should be in for
612 empty space inside windows. What this is,
613 depends on the user option inverse-video. */
614
615 void
616 background_highlight ()
617 {
618 if (inverse_video)
619 turn_on_highlight ();
620 else
621 turn_off_highlight ();
622 }
623
624 /* Set standout mode to the mode specified for the text to be output. */
625
626 static void
627 highlight_if_desired ()
628 {
629 if (inverse_video)
630 turn_on_highlight ();
631 else
632 turn_off_highlight ();
633 }
634 \f
635
636 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
637 frame-relative coordinates. */
638
639 void
640 cursor_to (vpos, hpos)
641 int vpos, hpos;
642 {
643 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
644
645 if (! FRAME_TERMCAP_P (f) && cursor_to_hook)
646 {
647 (*cursor_to_hook) (vpos, hpos);
648 return;
649 }
650
651 /* Detect the case where we are called from reset_sys_modes
652 and the costs have never been calculated. Do nothing. */
653 if (! costs_set)
654 return;
655
656 if (curY == vpos && curX == hpos)
657 return;
658 if (!TF_standout_motion)
659 background_highlight ();
660 if (!TF_insmode_motion)
661 turn_off_insert ();
662 cmgoto (vpos, hpos);
663 }
664
665 /* Similar but don't take any account of the wasted characters. */
666
667 void
668 raw_cursor_to (row, col)
669 int row, col;
670 {
671 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
672 if (! FRAME_TERMCAP_P (f))
673 {
674 (*raw_cursor_to_hook) (row, col);
675 return;
676 }
677 if (curY == row && curX == col)
678 return;
679 if (!TF_standout_motion)
680 background_highlight ();
681 if (!TF_insmode_motion)
682 turn_off_insert ();
683 cmgoto (row, col);
684 }
685 \f
686 /* Erase operations */
687
688 /* clear from cursor to end of frame */
689 void
690 clear_to_end ()
691 {
692 register int i;
693
694 if (clear_to_end_hook && ! FRAME_TERMCAP_P (updating_frame))
695 {
696 (*clear_to_end_hook) ();
697 return;
698 }
699 if (TS_clr_to_bottom)
700 {
701 background_highlight ();
702 OUTPUT (TS_clr_to_bottom);
703 }
704 else
705 {
706 for (i = curY; i < FRAME_LINES (XFRAME (selected_frame)); i++)
707 {
708 cursor_to (i, 0);
709 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame)));
710 }
711 }
712 }
713
714 /* Clear entire frame */
715
716 void
717 clear_frame ()
718 {
719 struct frame *sf = XFRAME (selected_frame);
720
721 if (clear_frame_hook
722 && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : sf)))
723 {
724 (*clear_frame_hook) ();
725 return;
726 }
727 if (TS_clr_frame)
728 {
729 background_highlight ();
730 OUTPUT (TS_clr_frame);
731 cmat (0, 0);
732 }
733 else
734 {
735 cursor_to (0, 0);
736 clear_to_end ();
737 }
738 }
739
740 /* Clear from cursor to end of line.
741 Assume that the line is already clear starting at column first_unused_hpos.
742
743 Note that the cursor may be moved, on terminals lacking a `ce' string. */
744
745 void
746 clear_end_of_line (first_unused_hpos)
747 int first_unused_hpos;
748 {
749 register int i;
750
751 if (clear_end_of_line_hook
752 && ! FRAME_TERMCAP_P ((updating_frame
753 ? updating_frame
754 : XFRAME (selected_frame))))
755 {
756 (*clear_end_of_line_hook) (first_unused_hpos);
757 return;
758 }
759
760 /* Detect the case where we are called from reset_sys_modes
761 and the costs have never been calculated. Do nothing. */
762 if (! costs_set)
763 return;
764
765 if (curX >= first_unused_hpos)
766 return;
767 background_highlight ();
768 if (TS_clr_line)
769 {
770 OUTPUT1 (TS_clr_line);
771 }
772 else
773 { /* have to do it the hard way */
774 struct frame *sf = XFRAME (selected_frame);
775 turn_off_insert ();
776
777 /* Do not write in last row last col with Auto-wrap on. */
778 if (AutoWrap && curY == FRAME_LINES (sf) - 1
779 && first_unused_hpos == FRAME_COLS (sf))
780 first_unused_hpos--;
781
782 for (i = curX; i < first_unused_hpos; i++)
783 {
784 if (termscript)
785 fputc (' ', termscript);
786 putchar (' ');
787 }
788 cmplus (first_unused_hpos - curX);
789 }
790 }
791 \f
792 /* Buffer to store the result of terminal codes. It is initialized in
793 term_init and, if necessary, enlarged in encode_terminal_code. */
794 unsigned char *terminal_encode_buffer;
795 /* Size of terminal_encode_buffer. */
796 static int terminal_encode_buf_size;
797
798 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
799 store them in terminal_encode_buffer.
800
801 We store the number of glyphs actually converted in *CONSUMED. The
802 return value is the number of bytes stored in
803 terminal_encode_buffer.
804
805 This function will stop before encoding all glyphs in these two
806 cases.
807
808 (1) If the first glyph doesn't have a string entry in Vglyph_table,
809 it stops at encountering a glyph that has a string entry in
810 Vglyph_table.n
811
812 (2) If the first has a string entry in Vglyph_table, it stops after
813 encoding that string.
814 */
815
816 int
817 encode_terminal_code (src, src_len, consumed)
818 struct glyph *src;
819 int src_len;
820 int *consumed;
821 {
822 struct glyph *src_start = src, *src_end = src + src_len;
823 register GLYPH g;
824 register int c;
825 Lisp_Object string;
826 unsigned char *workbuf, *buf;
827 int nchars;
828 register int tlen = GLYPH_TABLE_LENGTH;
829 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
830 struct coding_system *coding;
831 Lisp_Object attrs, charset_list;
832
833 #if 1
834 /* GLYPH-TABLE is not supported anymore in xdisp.c. */
835 tlen = 0;
836 #endif
837
838 /* If terminal_coding does any conversion, use it, otherwise use
839 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
840 because it always return 1 if the member src_multibyte is 1. */
841 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
842 ? &terminal_coding
843 : &safe_terminal_coding);
844 coding->destination = terminal_encode_buffer;
845 coding->dst_bytes = terminal_encode_buf_size;
846 coding->mode |= CODING_MODE_LAST_BLOCK;
847 attrs = CODING_ID_ATTRS (coding->id);
848 charset_list = CODING_ATTR_CHARSET_LIST (attrs);
849
850 workbuf = buf = alloca (MAX_MULTIBYTE_LENGTH * src_len);
851 for (nchars = 0; src < src_end; src++)
852 {
853 /* We must skip glyphs to be padded for a wide character. */
854 if (! CHAR_GLYPH_PADDING_P (*src))
855 {
856 g = GLYPH_FROM_CHAR_GLYPH (src[0]);
857 string = Qnil;
858
859 if (g < 0 || g >= tlen)
860 c = src->u.ch;
861 else
862 {
863 /* This glyph has an entry in Vglyph_table,
864 so process any alias before testing for simpleness. */
865 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
866
867 if (GLYPH_SIMPLE_P (tbase, tlen, g))
868 /* We set the multi-byte form of a character in G
869 (that should be an ASCII character) at WORKBUF. */
870 c = FAST_GLYPH_CHAR (g);
871 else
872 /* We have a string in Vglyph_table. */
873 string = tbase[g];
874 }
875
876 if (NILP (string))
877 {
878 if (! char_charset (c, charset_list, NULL))
879 {
880 /* C is not encodable. */
881 int i;
882
883 for (i = CHAR_WIDTH (c) - 1; i >= 0; i--, nchars++)
884 *buf++ = '?';
885 }
886 else
887 {
888 /* Store the multibyte form of C at BUF. */
889 buf += CHAR_STRING (c, buf);
890 nchars++;
891 }
892 }
893 else
894 {
895 if (nchars == 0)
896 {
897 encode_coding_object (coding, string, 0, 0, SCHARS (string),
898 SBYTES (string), Qnil);
899 src++;
900 }
901 break;
902 }
903 }
904 }
905
906 if (nchars > 0)
907 {
908 coding->source = workbuf;
909 encode_coding_object (coding, Qnil, 0, 0, nchars,
910 buf - workbuf, Qnil);
911 }
912 /* coding->destination may have been reallocated. */
913 terminal_encode_buffer = coding->destination;
914 if (terminal_encode_buf_size < coding->dst_bytes)
915 terminal_encode_buf_size = coding->dst_bytes;
916
917 *consumed = src - src_start;
918 return (coding->produced);
919 }
920
921
922 void
923 write_glyphs (string, len)
924 register struct glyph *string;
925 register int len;
926 {
927 int produced, consumed;
928 struct frame *sf = XFRAME (selected_frame);
929 struct frame *f = updating_frame ? updating_frame : sf;
930
931 if (write_glyphs_hook
932 && ! FRAME_TERMCAP_P (f))
933 {
934 (*write_glyphs_hook) (string, len);
935 return;
936 }
937
938 turn_off_insert ();
939 tty_hide_cursor ();
940
941 /* Don't dare write in last column of bottom line, if Auto-Wrap,
942 since that would scroll the whole frame on some terminals. */
943
944 if (AutoWrap
945 && curY + 1 == FRAME_LINES (sf)
946 && (curX + len) == FRAME_COLS (sf))
947 len --;
948 if (len <= 0)
949 return;
950
951 cmplus (len);
952
953 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
954 the tail. */
955 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
956
957 while (len > 0)
958 {
959 /* Identify a run of glyphs with the same face. */
960 int face_id = string->face_id;
961 int n;
962
963 for (n = 1; n < len; ++n)
964 if (string[n].face_id != face_id)
965 break;
966
967 /* Turn appearance modes of the face of the run on. */
968 highlight_if_desired ();
969 turn_on_face (f, face_id);
970
971 while (n > 0)
972 {
973 produced = encode_terminal_code (string, n, &consumed);
974 if (produced > 0)
975 {
976 fwrite (terminal_encode_buffer, 1, produced, stdout);
977 if (ferror (stdout))
978 clearerr (stdout);
979 if (termscript)
980 fwrite (terminal_encode_buffer, 1, produced, termscript);
981 }
982 len -= consumed;
983 n -= consumed;
984 string += consumed;
985 }
986
987 /* Turn appearance modes off. */
988 turn_off_face (f, face_id);
989 turn_off_highlight ();
990 }
991
992 cmcheckmagic ();
993 }
994
995 /* If start is zero, insert blanks instead of a string at start */
996
997 void
998 insert_glyphs (start, len)
999 register struct glyph *start;
1000 register int len;
1001 {
1002 char *buf;
1003 struct glyph *glyph = NULL;
1004 struct frame *f, *sf;
1005
1006 if (len <= 0)
1007 return;
1008
1009 if (insert_glyphs_hook)
1010 {
1011 (*insert_glyphs_hook) (start, len);
1012 return;
1013 }
1014
1015 sf = XFRAME (selected_frame);
1016 f = updating_frame ? updating_frame : sf;
1017
1018 if (TS_ins_multi_chars)
1019 {
1020 buf = tparam (TS_ins_multi_chars, 0, 0, len);
1021 OUTPUT1 (buf);
1022 xfree (buf);
1023 if (start)
1024 write_glyphs (start, len);
1025 return;
1026 }
1027
1028 turn_on_insert ();
1029 cmplus (len);
1030 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
1031 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
1032 while (len-- > 0)
1033 {
1034 int produced, consumed;
1035
1036 OUTPUT1_IF (TS_ins_char);
1037 if (!start)
1038 {
1039 terminal_encode_buffer[0] = SPACEGLYPH;
1040 produced = 1;
1041 }
1042 else
1043 {
1044 highlight_if_desired ();
1045 turn_on_face (f, start->face_id);
1046 glyph = start;
1047 ++start;
1048 /* We must open sufficient space for a character which
1049 occupies more than one column. */
1050 while (len && CHAR_GLYPH_PADDING_P (*start))
1051 {
1052 OUTPUT1_IF (TS_ins_char);
1053 start++, len--;
1054 }
1055 produced = encode_terminal_code (glyph, 1, &consumed);
1056 }
1057
1058 if (produced > 0)
1059 {
1060 fwrite (terminal_encode_buffer, 1, produced, stdout);
1061 if (ferror (stdout))
1062 clearerr (stdout);
1063 if (termscript)
1064 fwrite (terminal_encode_buffer, 1, produced, termscript);
1065 }
1066
1067 OUTPUT1_IF (TS_pad_inserted_char);
1068 if (start)
1069 {
1070 turn_off_face (f, glyph->face_id);
1071 turn_off_highlight ();
1072 }
1073 }
1074
1075 cmcheckmagic ();
1076 }
1077
1078 void
1079 delete_glyphs (n)
1080 register int n;
1081 {
1082 char *buf;
1083 register int i;
1084
1085 if (delete_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame))
1086 {
1087 (*delete_glyphs_hook) (n);
1088 return;
1089 }
1090
1091 if (delete_in_insert_mode)
1092 {
1093 turn_on_insert ();
1094 }
1095 else
1096 {
1097 turn_off_insert ();
1098 OUTPUT_IF (TS_delete_mode);
1099 }
1100
1101 if (TS_del_multi_chars)
1102 {
1103 buf = tparam (TS_del_multi_chars, 0, 0, n);
1104 OUTPUT1 (buf);
1105 xfree (buf);
1106 }
1107 else
1108 for (i = 0; i < n; i++)
1109 OUTPUT1 (TS_del_char);
1110 if (!delete_in_insert_mode)
1111 OUTPUT_IF (TS_end_delete_mode);
1112 }
1113 \f
1114 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1115
1116 void
1117 ins_del_lines (vpos, n)
1118 int vpos, n;
1119 {
1120 char *multi = n > 0 ? TS_ins_multi_lines : TS_del_multi_lines;
1121 char *single = n > 0 ? TS_ins_line : TS_del_line;
1122 char *scroll = n > 0 ? TS_rev_scroll : TS_fwd_scroll;
1123 struct frame *sf;
1124
1125 register int i = n > 0 ? n : -n;
1126 register char *buf;
1127
1128 if (ins_del_lines_hook && ! FRAME_TERMCAP_P (updating_frame))
1129 {
1130 (*ins_del_lines_hook) (vpos, n);
1131 return;
1132 }
1133
1134 sf = XFRAME (selected_frame);
1135
1136 /* If the lines below the insertion are being pushed
1137 into the end of the window, this is the same as clearing;
1138 and we know the lines are already clear, since the matching
1139 deletion has already been done. So can ignore this. */
1140 /* If the lines below the deletion are blank lines coming
1141 out of the end of the window, don't bother,
1142 as there will be a matching inslines later that will flush them. */
1143 if (scroll_region_ok && vpos + i >= specified_window)
1144 return;
1145 if (!memory_below_frame && vpos + i >= FRAME_LINES (sf))
1146 return;
1147
1148 if (multi)
1149 {
1150 raw_cursor_to (vpos, 0);
1151 background_highlight ();
1152 buf = tparam (multi, 0, 0, i);
1153 OUTPUT (buf);
1154 xfree (buf);
1155 }
1156 else if (single)
1157 {
1158 raw_cursor_to (vpos, 0);
1159 background_highlight ();
1160 while (--i >= 0)
1161 OUTPUT (single);
1162 if (TF_teleray)
1163 curX = 0;
1164 }
1165 else
1166 {
1167 set_scroll_region (vpos, specified_window);
1168 if (n < 0)
1169 raw_cursor_to (specified_window - 1, 0);
1170 else
1171 raw_cursor_to (vpos, 0);
1172 background_highlight ();
1173 while (--i >= 0)
1174 OUTPUTL (scroll, specified_window - vpos);
1175 set_scroll_region (0, specified_window);
1176 }
1177
1178 if (!scroll_region_ok && memory_below_frame && n < 0)
1179 {
1180 cursor_to (FRAME_LINES (sf) + n, 0);
1181 clear_to_end ();
1182 }
1183 }
1184 \f
1185 /* Compute cost of sending "str", in characters,
1186 not counting any line-dependent padding. */
1187
1188 int
1189 string_cost (str)
1190 char *str;
1191 {
1192 cost = 0;
1193 if (str)
1194 tputs (str, 0, evalcost);
1195 return cost;
1196 }
1197
1198 /* Compute cost of sending "str", in characters,
1199 counting any line-dependent padding at one line. */
1200
1201 static int
1202 string_cost_one_line (str)
1203 char *str;
1204 {
1205 cost = 0;
1206 if (str)
1207 tputs (str, 1, evalcost);
1208 return cost;
1209 }
1210
1211 /* Compute per line amount of line-dependent padding,
1212 in tenths of characters. */
1213
1214 int
1215 per_line_cost (str)
1216 register char *str;
1217 {
1218 cost = 0;
1219 if (str)
1220 tputs (str, 0, evalcost);
1221 cost = - cost;
1222 if (str)
1223 tputs (str, 10, evalcost);
1224 return cost;
1225 }
1226
1227 #ifndef old
1228 /* char_ins_del_cost[n] is cost of inserting N characters.
1229 char_ins_del_cost[-n] is cost of deleting N characters.
1230 The length of this vector is based on max_frame_cols. */
1231
1232 int *char_ins_del_vector;
1233
1234 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1235 #endif
1236
1237 /* ARGSUSED */
1238 static void
1239 calculate_ins_del_char_costs (frame)
1240 FRAME_PTR frame;
1241 {
1242 int ins_startup_cost, del_startup_cost;
1243 int ins_cost_per_char, del_cost_per_char;
1244 register int i;
1245 register int *p;
1246
1247 if (TS_ins_multi_chars)
1248 {
1249 ins_cost_per_char = 0;
1250 ins_startup_cost = string_cost_one_line (TS_ins_multi_chars);
1251 }
1252 else if (TS_ins_char || TS_pad_inserted_char
1253 || (TS_insert_mode && TS_end_insert_mode))
1254 {
1255 ins_startup_cost = (30 * (string_cost (TS_insert_mode)
1256 + string_cost (TS_end_insert_mode))) / 100;
1257 ins_cost_per_char = (string_cost_one_line (TS_ins_char)
1258 + string_cost_one_line (TS_pad_inserted_char));
1259 }
1260 else
1261 {
1262 ins_startup_cost = 9999;
1263 ins_cost_per_char = 0;
1264 }
1265
1266 if (TS_del_multi_chars)
1267 {
1268 del_cost_per_char = 0;
1269 del_startup_cost = string_cost_one_line (TS_del_multi_chars);
1270 }
1271 else if (TS_del_char)
1272 {
1273 del_startup_cost = (string_cost (TS_delete_mode)
1274 + string_cost (TS_end_delete_mode));
1275 if (delete_in_insert_mode)
1276 del_startup_cost /= 2;
1277 del_cost_per_char = string_cost_one_line (TS_del_char);
1278 }
1279 else
1280 {
1281 del_startup_cost = 9999;
1282 del_cost_per_char = 0;
1283 }
1284
1285 /* Delete costs are at negative offsets */
1286 p = &char_ins_del_cost (frame)[0];
1287 for (i = FRAME_COLS (frame); --i >= 0;)
1288 *--p = (del_startup_cost += del_cost_per_char);
1289
1290 /* Doing nothing is free */
1291 p = &char_ins_del_cost (frame)[0];
1292 *p++ = 0;
1293
1294 /* Insert costs are at positive offsets */
1295 for (i = FRAME_COLS (frame); --i >= 0;)
1296 *p++ = (ins_startup_cost += ins_cost_per_char);
1297 }
1298
1299 void
1300 calculate_costs (frame)
1301 FRAME_PTR frame;
1302 {
1303 register char *f = (TS_set_scroll_region
1304 ? TS_set_scroll_region
1305 : TS_set_scroll_region_1);
1306
1307 FRAME_COST_BAUD_RATE (frame) = baud_rate;
1308
1309 scroll_region_cost = string_cost (f);
1310
1311 /* These variables are only used for terminal stuff. They are allocated
1312 once for the terminal frame of X-windows emacs, but not used afterwards.
1313
1314 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1315 X turns off char_ins_del_ok. */
1316
1317 max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
1318 max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
1319
1320 costs_set = 1;
1321
1322 if (char_ins_del_vector != 0)
1323 char_ins_del_vector
1324 = (int *) xrealloc (char_ins_del_vector,
1325 (sizeof (int)
1326 + 2 * max_frame_cols * sizeof (int)));
1327 else
1328 char_ins_del_vector
1329 = (int *) xmalloc (sizeof (int)
1330 + 2 * max_frame_cols * sizeof (int));
1331
1332 bzero (char_ins_del_vector, (sizeof (int)
1333 + 2 * max_frame_cols * sizeof (int)));
1334
1335 if (f && (!TS_ins_line && !TS_del_line))
1336 do_line_insertion_deletion_costs (frame,
1337 TS_rev_scroll, TS_ins_multi_lines,
1338 TS_fwd_scroll, TS_del_multi_lines,
1339 f, f, 1);
1340 else
1341 do_line_insertion_deletion_costs (frame,
1342 TS_ins_line, TS_ins_multi_lines,
1343 TS_del_line, TS_del_multi_lines,
1344 0, 0, 1);
1345
1346 calculate_ins_del_char_costs (frame);
1347
1348 /* Don't use TS_repeat if its padding is worse than sending the chars */
1349 if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000)
1350 RPov = string_cost (TS_repeat);
1351 else
1352 RPov = FRAME_COLS (frame) * 2;
1353
1354 cmcostinit (); /* set up cursor motion costs */
1355 }
1356 \f
1357 struct fkey_table {
1358 char *cap, *name;
1359 };
1360
1361 /* Termcap capability names that correspond directly to X keysyms.
1362 Some of these (marked "terminfo") aren't supplied by old-style
1363 (Berkeley) termcap entries. They're listed in X keysym order;
1364 except we put the keypad keys first, so that if they clash with
1365 other keys (as on the IBM PC keyboard) they get overridden.
1366 */
1367
1368 static struct fkey_table keys[] =
1369 {
1370 {"kh", "home"}, /* termcap */
1371 {"kl", "left"}, /* termcap */
1372 {"ku", "up"}, /* termcap */
1373 {"kr", "right"}, /* termcap */
1374 {"kd", "down"}, /* termcap */
1375 {"%8", "prior"}, /* terminfo */
1376 {"%5", "next"}, /* terminfo */
1377 {"@7", "end"}, /* terminfo */
1378 {"@1", "begin"}, /* terminfo */
1379 {"*6", "select"}, /* terminfo */
1380 {"%9", "print"}, /* terminfo */
1381 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1382 /*
1383 * "insert" --- see below
1384 */
1385 {"&8", "undo"}, /* terminfo */
1386 {"%0", "redo"}, /* terminfo */
1387 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1388 {"@0", "find"}, /* terminfo */
1389 {"@2", "cancel"}, /* terminfo */
1390 {"%1", "help"}, /* terminfo */
1391 /*
1392 * "break" goes here, but can't be reliably intercepted with termcap
1393 */
1394 {"&4", "reset"}, /* terminfo --- actually `restart' */
1395 /*
1396 * "system" and "user" --- no termcaps
1397 */
1398 {"kE", "clearline"}, /* terminfo */
1399 {"kA", "insertline"}, /* terminfo */
1400 {"kL", "deleteline"}, /* terminfo */
1401 {"kI", "insertchar"}, /* terminfo */
1402 {"kD", "deletechar"}, /* terminfo */
1403 {"kB", "backtab"}, /* terminfo */
1404 /*
1405 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1406 */
1407 {"@8", "kp-enter"}, /* terminfo */
1408 /*
1409 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1410 * "kp-multiply", "kp-add", "kp-separator",
1411 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1412 * --- no termcaps for any of these.
1413 */
1414 {"K4", "kp-1"}, /* terminfo */
1415 /*
1416 * "kp-2" --- no termcap
1417 */
1418 {"K5", "kp-3"}, /* terminfo */
1419 /*
1420 * "kp-4" --- no termcap
1421 */
1422 {"K2", "kp-5"}, /* terminfo */
1423 /*
1424 * "kp-6" --- no termcap
1425 */
1426 {"K1", "kp-7"}, /* terminfo */
1427 /*
1428 * "kp-8" --- no termcap
1429 */
1430 {"K3", "kp-9"}, /* terminfo */
1431 /*
1432 * "kp-equal" --- no termcap
1433 */
1434 {"k1", "f1"},
1435 {"k2", "f2"},
1436 {"k3", "f3"},
1437 {"k4", "f4"},
1438 {"k5", "f5"},
1439 {"k6", "f6"},
1440 {"k7", "f7"},
1441 {"k8", "f8"},
1442 {"k9", "f9"}
1443 };
1444
1445 static char **term_get_fkeys_arg;
1446 static Lisp_Object term_get_fkeys_1 ();
1447
1448 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1449 This function scans the termcap function key sequence entries, and
1450 adds entries to Vfunction_key_map for each function key it finds. */
1451
1452 void
1453 term_get_fkeys (address)
1454 char **address;
1455 {
1456 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1457 errors during the call. The only errors should be from Fdefine_key
1458 when given a key sequence containing an invalid prefix key. If the
1459 termcap defines function keys which use a prefix that is already bound
1460 to a command by the default bindings, we should silently ignore that
1461 function key specification, rather than giving the user an error and
1462 refusing to run at all on such a terminal. */
1463
1464 extern Lisp_Object Fidentity ();
1465 term_get_fkeys_arg = address;
1466 internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
1467 }
1468
1469 static Lisp_Object
1470 term_get_fkeys_1 ()
1471 {
1472 int i;
1473
1474 char **address = term_get_fkeys_arg;
1475
1476 /* This can happen if CANNOT_DUMP or with strange options. */
1477 if (!initialized)
1478 Vfunction_key_map = Fmake_sparse_keymap (Qnil);
1479
1480 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
1481 {
1482 char *sequence = tgetstr (keys[i].cap, address);
1483 if (sequence)
1484 Fdefine_key (Vfunction_key_map, build_string (sequence),
1485 Fmake_vector (make_number (1),
1486 intern (keys[i].name)));
1487 }
1488
1489 /* The uses of the "k0" capability are inconsistent; sometimes it
1490 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1491 We will attempt to politely accommodate both systems by testing for
1492 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1493 */
1494 {
1495 char *k_semi = tgetstr ("k;", address);
1496 char *k0 = tgetstr ("k0", address);
1497 char *k0_name = "f10";
1498
1499 if (k_semi)
1500 {
1501 if (k0)
1502 /* Define f0 first, so that f10 takes precedence in case the
1503 key sequences happens to be the same. */
1504 Fdefine_key (Vfunction_key_map, build_string (k0),
1505 Fmake_vector (make_number (1), intern ("f0")));
1506 Fdefine_key (Vfunction_key_map, build_string (k_semi),
1507 Fmake_vector (make_number (1), intern ("f10")));
1508 }
1509 else if (k0)
1510 Fdefine_key (Vfunction_key_map, build_string (k0),
1511 Fmake_vector (make_number (1), intern (k0_name)));
1512 }
1513
1514 /* Set up cookies for numbered function keys above f10. */
1515 {
1516 char fcap[3], fkey[4];
1517
1518 fcap[0] = 'F'; fcap[2] = '\0';
1519 for (i = 11; i < 64; i++)
1520 {
1521 if (i <= 19)
1522 fcap[1] = '1' + i - 11;
1523 else if (i <= 45)
1524 fcap[1] = 'A' + i - 20;
1525 else
1526 fcap[1] = 'a' + i - 46;
1527
1528 {
1529 char *sequence = tgetstr (fcap, address);
1530 if (sequence)
1531 {
1532 sprintf (fkey, "f%d", i);
1533 Fdefine_key (Vfunction_key_map, build_string (sequence),
1534 Fmake_vector (make_number (1),
1535 intern (fkey)));
1536 }
1537 }
1538 }
1539 }
1540
1541 /*
1542 * Various mappings to try and get a better fit.
1543 */
1544 {
1545 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1546 if (!tgetstr (cap1, address)) \
1547 { \
1548 char *sequence = tgetstr (cap2, address); \
1549 if (sequence) \
1550 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1551 Fmake_vector (make_number (1), \
1552 intern (sym))); \
1553 }
1554
1555 /* if there's no key_next keycap, map key_npage to `next' keysym */
1556 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1557 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1558 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1559 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1560 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1561 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1562 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1563
1564 /* IBM has their own non-standard dialect of terminfo.
1565 If the standard name isn't found, try the IBM name. */
1566 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1567 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1568 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1569 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1570 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1571 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1572 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1573 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1574 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1575 #undef CONDITIONAL_REASSIGN
1576 }
1577
1578 return Qnil;
1579 }
1580
1581 \f
1582 /***********************************************************************
1583 Character Display Information
1584 ***********************************************************************/
1585
1586 static void append_glyph P_ ((struct it *));
1587
1588
1589 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1590 terminal frames if IT->glyph_row != NULL. IT->c is the character
1591 for which to produce glyphs; IT->face_id contains the character's
1592 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1593 1. */
1594
1595 static void
1596 append_glyph (it)
1597 struct it *it;
1598 {
1599 struct glyph *glyph, *end;
1600 int i;
1601
1602 xassert (it->glyph_row);
1603 glyph = (it->glyph_row->glyphs[it->area]
1604 + it->glyph_row->used[it->area]);
1605 end = it->glyph_row->glyphs[1 + it->area];
1606
1607 for (i = 0;
1608 i < it->pixel_width && glyph < end;
1609 ++i)
1610 {
1611 glyph->type = CHAR_GLYPH;
1612 glyph->pixel_width = 1;
1613 glyph->u.ch = it->c;
1614 glyph->face_id = it->face_id;
1615 glyph->padding_p = i > 0;
1616 glyph->charpos = CHARPOS (it->position);
1617 glyph->object = it->object;
1618
1619 ++it->glyph_row->used[it->area];
1620 ++glyph;
1621 }
1622 }
1623
1624
1625 /* Produce glyphs for the display element described by IT. *IT
1626 specifies what we want to produce a glyph for (character, image, ...),
1627 and where in the glyph matrix we currently are (glyph row and hpos).
1628 produce_glyphs fills in output fields of *IT with information such as the
1629 pixel width and height of a character, and maybe output actual glyphs at
1630 the same time if IT->glyph_row is non-null. See the explanation of
1631 struct display_iterator in dispextern.h for an overview.
1632
1633 produce_glyphs also stores the result of glyph width, ascent
1634 etc. computations in *IT.
1635
1636 IT->glyph_row may be null, in which case produce_glyphs does not
1637 actually fill in the glyphs. This is used in the move_* functions
1638 in xdisp.c for text width and height computations.
1639
1640 Callers usually don't call produce_glyphs directly;
1641 instead they use the macro PRODUCE_GLYPHS. */
1642
1643 void
1644 produce_glyphs (it)
1645 struct it *it;
1646 {
1647 /* If a hook is installed, let it do the work. */
1648 xassert (it->what == IT_CHARACTER
1649 || it->what == IT_COMPOSITION
1650 || it->what == IT_IMAGE
1651 || it->what == IT_STRETCH);
1652
1653 /* Nothing but characters are supported on terminal frames. For a
1654 composition sequence, it->c is the first character of the
1655 sequence. */
1656 xassert (it->what == IT_CHARACTER
1657 || it->what == IT_COMPOSITION);
1658
1659 if (it->c >= 040 && it->c < 0177)
1660 {
1661 it->pixel_width = it->nglyphs = 1;
1662 if (it->glyph_row)
1663 append_glyph (it);
1664 }
1665 else if (it->c == '\n')
1666 it->pixel_width = it->nglyphs = 0;
1667 else if (it->c == '\t')
1668 {
1669 int absolute_x = (it->current_x
1670 + it->continuation_lines_width);
1671 int next_tab_x
1672 = (((1 + absolute_x + it->tab_width - 1)
1673 / it->tab_width)
1674 * it->tab_width);
1675 int nspaces;
1676
1677 /* If part of the TAB has been displayed on the previous line
1678 which is continued now, continuation_lines_width will have
1679 been incremented already by the part that fitted on the
1680 continued line. So, we will get the right number of spaces
1681 here. */
1682 nspaces = next_tab_x - absolute_x;
1683
1684 if (it->glyph_row)
1685 {
1686 int n = nspaces;
1687
1688 it->c = ' ';
1689 it->pixel_width = it->len = 1;
1690
1691 while (n--)
1692 append_glyph (it);
1693
1694 it->c = '\t';
1695 }
1696
1697 it->pixel_width = nspaces;
1698 it->nglyphs = nspaces;
1699 }
1700 else if (CHAR_BYTE8_P (it->c))
1701 {
1702 /* We must send the raw 8-bit byte as is to the terminal.
1703 Although there's no way to know how many columns it occupies
1704 on a screen, it is a good assumption that a single byte code
1705 has 1-column width. */
1706 it->pixel_width = it->nglyphs = 1;
1707 if (it->glyph_row)
1708 append_glyph (it);
1709 }
1710 else
1711 {
1712 it->pixel_width = CHAR_WIDTH (it->c);
1713 it->nglyphs = it->pixel_width;
1714
1715 if (it->glyph_row)
1716 append_glyph (it);
1717 }
1718
1719 /* Advance current_x by the pixel width as a convenience for
1720 the caller. */
1721 if (it->area == TEXT_AREA)
1722 it->current_x += it->pixel_width;
1723 it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0;
1724 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
1725 }
1726
1727
1728 /* Get information about special display element WHAT in an
1729 environment described by IT. WHAT is one of IT_TRUNCATION or
1730 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1731 non-null glyph_row member. This function ensures that fields like
1732 face_id, c, len of IT are left untouched. */
1733
1734 void
1735 produce_special_glyphs (it, what)
1736 struct it *it;
1737 enum display_element_type what;
1738 {
1739 struct it temp_it;
1740
1741 temp_it = *it;
1742 temp_it.dp = NULL;
1743 temp_it.what = IT_CHARACTER;
1744 temp_it.len = 1;
1745 temp_it.object = make_number (0);
1746 bzero (&temp_it.current, sizeof temp_it.current);
1747
1748 if (what == IT_CONTINUATION)
1749 {
1750 /* Continuation glyph. */
1751 if (it->dp
1752 && INTEGERP (DISP_CONTINUE_GLYPH (it->dp))
1753 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp))))
1754 {
1755 temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it->dp)));
1756 temp_it.len = CHAR_BYTES (temp_it.c);
1757 }
1758 else
1759 temp_it.c = '\\';
1760
1761 produce_glyphs (&temp_it);
1762 it->pixel_width = temp_it.pixel_width;
1763 it->nglyphs = temp_it.pixel_width;
1764 }
1765 else if (what == IT_TRUNCATION)
1766 {
1767 /* Truncation glyph. */
1768 if (it->dp
1769 && INTEGERP (DISP_TRUNC_GLYPH (it->dp))
1770 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp))))
1771 {
1772 temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it->dp)));
1773 temp_it.len = CHAR_BYTES (temp_it.c);
1774 }
1775 else
1776 temp_it.c = '$';
1777
1778 produce_glyphs (&temp_it);
1779 it->pixel_width = temp_it.pixel_width;
1780 it->nglyphs = temp_it.pixel_width;
1781 }
1782 else
1783 abort ();
1784 }
1785
1786
1787 \f
1788 /***********************************************************************
1789 Faces
1790 ***********************************************************************/
1791
1792 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1793 one of the enumerators from enum no_color_bit, or a bit set built
1794 from them. Some display attributes may not be used together with
1795 color; the termcap capability `NC' specifies which ones. */
1796
1797 #define MAY_USE_WITH_COLORS_P(ATTR) \
1798 (TN_max_colors > 0 \
1799 ? (TN_no_color_video & (ATTR)) == 0 \
1800 : 1)
1801
1802 /* Turn appearances of face FACE_ID on tty frame F on. */
1803
1804 static void
1805 turn_on_face (f, face_id)
1806 struct frame *f;
1807 int face_id;
1808 {
1809 struct face *face = FACE_FROM_ID (f, face_id);
1810 long fg = face->foreground;
1811 long bg = face->background;
1812
1813 /* Do this first because TS_end_standout_mode may be the same
1814 as TS_exit_attribute_mode, which turns all appearances off. */
1815 if (MAY_USE_WITH_COLORS_P (NC_REVERSE))
1816 {
1817 if (TN_max_colors > 0)
1818 {
1819 if (fg >= 0 && bg >= 0)
1820 {
1821 /* If the terminal supports colors, we can set them
1822 below without using reverse video. The face's fg
1823 and bg colors are set as they should appear on
1824 the screen, i.e. they take the inverse-video'ness
1825 of the face already into account. */
1826 }
1827 else if (inverse_video)
1828 {
1829 if (fg == FACE_TTY_DEFAULT_FG_COLOR
1830 || bg == FACE_TTY_DEFAULT_BG_COLOR)
1831 toggle_highlight ();
1832 }
1833 else
1834 {
1835 if (fg == FACE_TTY_DEFAULT_BG_COLOR
1836 || bg == FACE_TTY_DEFAULT_FG_COLOR)
1837 toggle_highlight ();
1838 }
1839 }
1840 else
1841 {
1842 /* If we can't display colors, use reverse video
1843 if the face specifies that. */
1844 if (inverse_video)
1845 {
1846 if (fg == FACE_TTY_DEFAULT_FG_COLOR
1847 || bg == FACE_TTY_DEFAULT_BG_COLOR)
1848 toggle_highlight ();
1849 }
1850 else
1851 {
1852 if (fg == FACE_TTY_DEFAULT_BG_COLOR
1853 || bg == FACE_TTY_DEFAULT_FG_COLOR)
1854 toggle_highlight ();
1855 }
1856 }
1857 }
1858
1859 if (face->tty_bold_p)
1860 {
1861 if (MAY_USE_WITH_COLORS_P (NC_BOLD))
1862 OUTPUT1_IF (TS_enter_bold_mode);
1863 }
1864 else if (face->tty_dim_p)
1865 if (MAY_USE_WITH_COLORS_P (NC_DIM))
1866 OUTPUT1_IF (TS_enter_dim_mode);
1867
1868 /* Alternate charset and blinking not yet used. */
1869 if (face->tty_alt_charset_p
1870 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET))
1871 OUTPUT1_IF (TS_enter_alt_charset_mode);
1872
1873 if (face->tty_blinking_p
1874 && MAY_USE_WITH_COLORS_P (NC_BLINK))
1875 OUTPUT1_IF (TS_enter_blink_mode);
1876
1877 if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (NC_UNDERLINE))
1878 OUTPUT1_IF (TS_enter_underline_mode);
1879
1880 if (TN_max_colors > 0)
1881 {
1882 char *p;
1883
1884 if (fg >= 0 && TS_set_foreground)
1885 {
1886 p = tparam (TS_set_foreground, NULL, 0, (int) fg);
1887 OUTPUT (p);
1888 xfree (p);
1889 }
1890
1891 if (bg >= 0 && TS_set_background)
1892 {
1893 p = tparam (TS_set_background, NULL, 0, (int) bg);
1894 OUTPUT (p);
1895 xfree (p);
1896 }
1897 }
1898 }
1899
1900
1901 /* Turn off appearances of face FACE_ID on tty frame F. */
1902
1903 static void
1904 turn_off_face (f, face_id)
1905 struct frame *f;
1906 int face_id;
1907 {
1908 struct face *face = FACE_FROM_ID (f, face_id);
1909
1910 xassert (face != NULL);
1911
1912 if (TS_exit_attribute_mode)
1913 {
1914 /* Capability "me" will turn off appearance modes double-bright,
1915 half-bright, reverse-video, standout, underline. It may or
1916 may not turn off alt-char-mode. */
1917 if (face->tty_bold_p
1918 || face->tty_dim_p
1919 || face->tty_reverse_p
1920 || face->tty_alt_charset_p
1921 || face->tty_blinking_p
1922 || face->tty_underline_p)
1923 {
1924 OUTPUT1_IF (TS_exit_attribute_mode);
1925 if (strcmp (TS_exit_attribute_mode, TS_end_standout_mode) == 0)
1926 standout_mode = 0;
1927 }
1928
1929 if (face->tty_alt_charset_p)
1930 OUTPUT_IF (TS_exit_alt_charset_mode);
1931 }
1932 else
1933 {
1934 /* If we don't have "me" we can only have those appearances
1935 that have exit sequences defined. */
1936 if (face->tty_alt_charset_p)
1937 OUTPUT_IF (TS_exit_alt_charset_mode);
1938
1939 if (face->tty_underline_p)
1940 OUTPUT_IF (TS_exit_underline_mode);
1941 }
1942
1943 /* Switch back to default colors. */
1944 if (TN_max_colors > 0
1945 && ((face->foreground != FACE_TTY_DEFAULT_COLOR
1946 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR)
1947 || (face->background != FACE_TTY_DEFAULT_COLOR
1948 && face->background != FACE_TTY_DEFAULT_BG_COLOR)))
1949 OUTPUT1_IF (TS_orig_pair);
1950 }
1951
1952
1953 /* Return non-zero if the terminal on frame F supports all of the
1954 capabilities in CAPS simultaneously, with foreground and background
1955 colors FG and BG. */
1956
1957 int
1958 tty_capable_p (f, caps, fg, bg)
1959 struct frame *f;
1960 unsigned caps;
1961 unsigned long fg, bg;
1962 {
1963 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
1964 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
1965 return 0;
1966
1967 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE, TS_standout_mode, NC_REVERSE);
1968 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE, TS_enter_underline_mode, NC_UNDERLINE);
1969 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD, TS_enter_bold_mode, NC_BOLD);
1970 TTY_CAPABLE_P_TRY (TTY_CAP_DIM, TS_enter_dim_mode, NC_DIM);
1971 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK, TS_enter_blink_mode, NC_BLINK);
1972 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET, TS_enter_alt_charset_mode, NC_ALT_CHARSET);
1973
1974 /* We can do it! */
1975 return 1;
1976 }
1977
1978
1979 /* Return non-zero if the terminal is capable to display colors. */
1980
1981 DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
1982 0, 1, 0,
1983 doc: /* Return non-nil if TTY can display colors on DISPLAY. */)
1984 (display)
1985 Lisp_Object display;
1986 {
1987 return TN_max_colors > 0 ? Qt : Qnil;
1988 }
1989
1990 /* Return the number of supported colors. */
1991 DEFUN ("tty-display-color-cells", Ftty_display_color_cells,
1992 Stty_display_color_cells, 0, 1, 0,
1993 doc: /* Return the number of colors supported by TTY on DISPLAY. */)
1994 (display)
1995 Lisp_Object display;
1996 {
1997 return make_number (TN_max_colors);
1998 }
1999
2000 #ifndef WINDOWSNT
2001
2002 /* Save or restore the default color-related capabilities of this
2003 terminal. */
2004 static void
2005 tty_default_color_capabilities (save)
2006 int save;
2007 {
2008 static char
2009 *default_orig_pair, *default_set_foreground, *default_set_background;
2010 static int default_max_colors, default_max_pairs, default_no_color_video;
2011
2012 if (save)
2013 {
2014 if (default_orig_pair)
2015 xfree (default_orig_pair);
2016 default_orig_pair = TS_orig_pair ? xstrdup (TS_orig_pair) : NULL;
2017
2018 if (default_set_foreground)
2019 xfree (default_set_foreground);
2020 default_set_foreground = TS_set_foreground ? xstrdup (TS_set_foreground)
2021 : NULL;
2022
2023 if (default_set_background)
2024 xfree (default_set_background);
2025 default_set_background = TS_set_background ? xstrdup (TS_set_background)
2026 : NULL;
2027
2028 default_max_colors = TN_max_colors;
2029 default_max_pairs = TN_max_pairs;
2030 default_no_color_video = TN_no_color_video;
2031 }
2032 else
2033 {
2034 TS_orig_pair = default_orig_pair;
2035 TS_set_foreground = default_set_foreground;
2036 TS_set_background = default_set_background;
2037 TN_max_colors = default_max_colors;
2038 TN_max_pairs = default_max_pairs;
2039 TN_no_color_video = default_no_color_video;
2040 }
2041 }
2042
2043 /* Setup one of the standard tty color schemes according to MODE.
2044 MODE's value is generally the number of colors which we want to
2045 support; zero means set up for the default capabilities, the ones
2046 we saw at term_init time; -1 means turn off color support. */
2047 void
2048 tty_setup_colors (mode)
2049 int mode;
2050 {
2051 switch (mode)
2052 {
2053 case -1: /* no colors at all */
2054 TN_max_colors = 0;
2055 TN_max_pairs = 0;
2056 TN_no_color_video = 0;
2057 TS_set_foreground = TS_set_background = TS_orig_pair = NULL;
2058 break;
2059 case 0: /* default colors, if any */
2060 default:
2061 tty_default_color_capabilities (0);
2062 break;
2063 case 8: /* 8 standard ANSI colors */
2064 TS_orig_pair = "\033[0m";
2065 #ifdef TERMINFO
2066 TS_set_foreground = "\033[3%p1%dm";
2067 TS_set_background = "\033[4%p1%dm";
2068 #else
2069 TS_set_foreground = "\033[3%dm";
2070 TS_set_background = "\033[4%dm";
2071 #endif
2072 TN_max_colors = 8;
2073 TN_max_pairs = 64;
2074 TN_no_color_video = 0;
2075 break;
2076 }
2077 }
2078
2079 void
2080 set_tty_color_mode (f, val)
2081 struct frame *f;
2082 Lisp_Object val;
2083 {
2084 Lisp_Object color_mode_spec, current_mode_spec;
2085 Lisp_Object color_mode, current_mode;
2086 int mode, old_mode;
2087 extern Lisp_Object Qtty_color_mode;
2088 Lisp_Object tty_color_mode_alist;
2089
2090 tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"),
2091 Qnil);
2092
2093 if (NATNUMP (val))
2094 color_mode = val;
2095 else
2096 {
2097 if (NILP (tty_color_mode_alist))
2098 color_mode_spec = Qnil;
2099 else
2100 color_mode_spec = Fassq (val, XSYMBOL (tty_color_mode_alist)->value);
2101 current_mode_spec = assq_no_quit (Qtty_color_mode, f->param_alist);
2102
2103 if (CONSP (color_mode_spec))
2104 color_mode = XCDR (color_mode_spec);
2105 else
2106 color_mode = Qnil;
2107 }
2108 if (CONSP (current_mode_spec))
2109 current_mode = XCDR (current_mode_spec);
2110 else
2111 current_mode = Qnil;
2112 if (NATNUMP (color_mode))
2113 mode = XINT (color_mode);
2114 else
2115 mode = 0; /* meaning default */
2116 if (NATNUMP (current_mode))
2117 old_mode = XINT (current_mode);
2118 else
2119 old_mode = 0;
2120
2121 if (mode != old_mode)
2122 {
2123 tty_setup_colors (mode);
2124 /* This recomputes all the faces given the new color
2125 definitions. */
2126 call0 (intern ("tty-set-up-initial-frame-faces"));
2127 redraw_frame (f);
2128 }
2129 }
2130
2131 #endif /* !WINDOWSNT */
2132
2133 \f
2134 /***********************************************************************
2135 Initialization
2136 ***********************************************************************/
2137
2138 void
2139 term_init (terminal_type)
2140 char *terminal_type;
2141 {
2142 char *area;
2143 char **address = &area;
2144 char buffer[2044];
2145 register char *p;
2146 int status;
2147 struct frame *sf = XFRAME (selected_frame);
2148
2149 #ifdef WINDOWSNT
2150 initialize_w32_display ();
2151
2152 Wcm_clear ();
2153
2154 area = (char *) xmalloc (2044);
2155
2156 if (area == 0)
2157 abort ();
2158
2159 FrameRows = FRAME_LINES (sf);
2160 FrameCols = FRAME_COLS (sf);
2161 specified_window = FRAME_LINES (sf);
2162
2163 delete_in_insert_mode = 1;
2164
2165 UseTabs = 0;
2166 scroll_region_ok = 0;
2167
2168 /* Seems to insert lines when it's not supposed to, messing
2169 up the display. In doing a trace, it didn't seem to be
2170 called much, so I don't think we're losing anything by
2171 turning it off. */
2172
2173 line_ins_del_ok = 0;
2174 char_ins_del_ok = 1;
2175
2176 baud_rate = 19200;
2177
2178 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2179 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
2180 TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
2181
2182 return;
2183 #else /* not WINDOWSNT */
2184
2185 Wcm_clear ();
2186
2187 status = tgetent (buffer, terminal_type);
2188 if (status < 0)
2189 {
2190 #ifdef TERMINFO
2191 fatal ("Cannot open terminfo database file");
2192 #else
2193 fatal ("Cannot open termcap database file");
2194 #endif
2195 }
2196 if (status == 0)
2197 {
2198 #ifdef TERMINFO
2199 fatal ("Terminal type %s is not defined.\n\
2200 If that is not the actual type of terminal you have,\n\
2201 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2202 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2203 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2204 terminal_type);
2205 #else
2206 fatal ("Terminal type %s is not defined.\n\
2207 If that is not the actual type of terminal you have,\n\
2208 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2209 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2210 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2211 terminal_type);
2212 #endif
2213 }
2214 #ifdef TERMINFO
2215 area = (char *) xmalloc (2044);
2216 #else
2217 area = (char *) xmalloc (strlen (buffer));
2218 #endif /* not TERMINFO */
2219 if (area == 0)
2220 abort ();
2221
2222 TS_ins_line = tgetstr ("al", address);
2223 TS_ins_multi_lines = tgetstr ("AL", address);
2224 TS_bell = tgetstr ("bl", address);
2225 BackTab = tgetstr ("bt", address);
2226 TS_clr_to_bottom = tgetstr ("cd", address);
2227 TS_clr_line = tgetstr ("ce", address);
2228 TS_clr_frame = tgetstr ("cl", address);
2229 ColPosition = NULL; /* tgetstr ("ch", address); */
2230 AbsPosition = tgetstr ("cm", address);
2231 CR = tgetstr ("cr", address);
2232 TS_set_scroll_region = tgetstr ("cs", address);
2233 TS_set_scroll_region_1 = tgetstr ("cS", address);
2234 RowPosition = tgetstr ("cv", address);
2235 TS_del_char = tgetstr ("dc", address);
2236 TS_del_multi_chars = tgetstr ("DC", address);
2237 TS_del_line = tgetstr ("dl", address);
2238 TS_del_multi_lines = tgetstr ("DL", address);
2239 TS_delete_mode = tgetstr ("dm", address);
2240 TS_end_delete_mode = tgetstr ("ed", address);
2241 TS_end_insert_mode = tgetstr ("ei", address);
2242 Home = tgetstr ("ho", address);
2243 TS_ins_char = tgetstr ("ic", address);
2244 TS_ins_multi_chars = tgetstr ("IC", address);
2245 TS_insert_mode = tgetstr ("im", address);
2246 TS_pad_inserted_char = tgetstr ("ip", address);
2247 TS_end_keypad_mode = tgetstr ("ke", address);
2248 TS_keypad_mode = tgetstr ("ks", address);
2249 LastLine = tgetstr ("ll", address);
2250 Right = tgetstr ("nd", address);
2251 Down = tgetstr ("do", address);
2252 if (!Down)
2253 Down = tgetstr ("nl", address); /* Obsolete name for "do" */
2254 #ifdef VMS
2255 /* VMS puts a carriage return before each linefeed,
2256 so it is not safe to use linefeeds. */
2257 if (Down && Down[0] == '\n' && Down[1] == '\0')
2258 Down = 0;
2259 #endif /* VMS */
2260 if (tgetflag ("bs"))
2261 Left = "\b"; /* can't possibly be longer! */
2262 else /* (Actually, "bs" is obsolete...) */
2263 Left = tgetstr ("le", address);
2264 if (!Left)
2265 Left = tgetstr ("bc", address); /* Obsolete name for "le" */
2266 TS_pad_char = tgetstr ("pc", address);
2267 TS_repeat = tgetstr ("rp", address);
2268 TS_end_standout_mode = tgetstr ("se", address);
2269 TS_fwd_scroll = tgetstr ("sf", address);
2270 TS_standout_mode = tgetstr ("so", address);
2271 TS_rev_scroll = tgetstr ("sr", address);
2272 Wcm.cm_tab = tgetstr ("ta", address);
2273 TS_end_termcap_modes = tgetstr ("te", address);
2274 TS_termcap_modes = tgetstr ("ti", address);
2275 Up = tgetstr ("up", address);
2276 TS_visible_bell = tgetstr ("vb", address);
2277 TS_cursor_normal = tgetstr ("ve", address);
2278 TS_cursor_visible = tgetstr ("vs", address);
2279 TS_cursor_invisible = tgetstr ("vi", address);
2280 TS_set_window = tgetstr ("wi", address);
2281
2282 TS_enter_underline_mode = tgetstr ("us", address);
2283 TS_exit_underline_mode = tgetstr ("ue", address);
2284 TS_enter_bold_mode = tgetstr ("md", address);
2285 TS_enter_dim_mode = tgetstr ("mh", address);
2286 TS_enter_blink_mode = tgetstr ("mb", address);
2287 TS_enter_reverse_mode = tgetstr ("mr", address);
2288 TS_enter_alt_charset_mode = tgetstr ("as", address);
2289 TS_exit_alt_charset_mode = tgetstr ("ae", address);
2290 TS_exit_attribute_mode = tgetstr ("me", address);
2291
2292 MultiUp = tgetstr ("UP", address);
2293 MultiDown = tgetstr ("DO", address);
2294 MultiLeft = tgetstr ("LE", address);
2295 MultiRight = tgetstr ("RI", address);
2296
2297 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2298 color because we can't switch back to the default foreground and
2299 background. */
2300 TS_orig_pair = tgetstr ("op", address);
2301 if (TS_orig_pair)
2302 {
2303 TS_set_foreground = tgetstr ("AF", address);
2304 TS_set_background = tgetstr ("AB", address);
2305 if (!TS_set_foreground)
2306 {
2307 /* SVr4. */
2308 TS_set_foreground = tgetstr ("Sf", address);
2309 TS_set_background = tgetstr ("Sb", address);
2310 }
2311
2312 TN_max_colors = tgetnum ("Co");
2313 TN_max_pairs = tgetnum ("pa");
2314
2315 TN_no_color_video = tgetnum ("NC");
2316 if (TN_no_color_video == -1)
2317 TN_no_color_video = 0;
2318 }
2319
2320 tty_default_color_capabilities (1);
2321
2322 MagicWrap = tgetflag ("xn");
2323 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2324 the former flag imply the latter. */
2325 AutoWrap = MagicWrap || tgetflag ("am");
2326 memory_below_frame = tgetflag ("db");
2327 TF_hazeltine = tgetflag ("hz");
2328 must_write_spaces = tgetflag ("in");
2329 meta_key = tgetflag ("km") || tgetflag ("MT");
2330 TF_insmode_motion = tgetflag ("mi");
2331 TF_standout_motion = tgetflag ("ms");
2332 TF_underscore = tgetflag ("ul");
2333 TF_teleray = tgetflag ("xt");
2334
2335 term_get_fkeys (address);
2336
2337 /* Get frame size from system, or else from termcap. */
2338 {
2339 int height, width;
2340 get_frame_size (&width, &height);
2341 FRAME_COLS (sf) = width;
2342 FRAME_LINES (sf) = height;
2343 }
2344
2345 if (FRAME_COLS (sf) <= 0)
2346 SET_FRAME_COLS (sf, tgetnum ("co"));
2347 else
2348 /* Keep width and external_width consistent */
2349 SET_FRAME_COLS (sf, FRAME_COLS (sf));
2350 if (FRAME_LINES (sf) <= 0)
2351 FRAME_LINES (sf) = tgetnum ("li");
2352
2353 if (FRAME_LINES (sf) < 3 || FRAME_COLS (sf) < 3)
2354 fatal ("Screen size %dx%d is too small",
2355 FRAME_LINES (sf), FRAME_COLS (sf));
2356
2357 min_padding_speed = tgetnum ("pb");
2358 TabWidth = tgetnum ("tw");
2359
2360 #ifdef VMS
2361 /* These capabilities commonly use ^J.
2362 I don't know why, but sending them on VMS does not work;
2363 it causes following spaces to be lost, sometimes.
2364 For now, the simplest fix is to avoid using these capabilities ever. */
2365 if (Down && Down[0] == '\n')
2366 Down = 0;
2367 #endif /* VMS */
2368
2369 if (!TS_bell)
2370 TS_bell = "\07";
2371
2372 if (!TS_fwd_scroll)
2373 TS_fwd_scroll = Down;
2374
2375 PC = TS_pad_char ? *TS_pad_char : 0;
2376
2377 if (TabWidth < 0)
2378 TabWidth = 8;
2379
2380 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2381 and newer termcap doc does not seem to say there is a default.
2382 if (!Wcm.cm_tab)
2383 Wcm.cm_tab = "\t";
2384 */
2385
2386 /* We don't support standout modes that use `magic cookies', so
2387 turn off any that do. */
2388 if (TS_standout_mode && tgetnum ("sg") >= 0)
2389 {
2390 TS_standout_mode = 0;
2391 TS_end_standout_mode = 0;
2392 }
2393 if (TS_enter_underline_mode && tgetnum ("ug") >= 0)
2394 {
2395 TS_enter_underline_mode = 0;
2396 TS_exit_underline_mode = 0;
2397 }
2398
2399 /* If there's no standout mode, try to use underlining instead. */
2400 if (TS_standout_mode == 0)
2401 {
2402 TS_standout_mode = TS_enter_underline_mode;
2403 TS_end_standout_mode = TS_exit_underline_mode;
2404 }
2405
2406 /* If no `se' string, try using a `me' string instead.
2407 If that fails, we can't use standout mode at all. */
2408 if (TS_end_standout_mode == 0)
2409 {
2410 char *s = tgetstr ("me", address);
2411 if (s != 0)
2412 TS_end_standout_mode = s;
2413 else
2414 TS_standout_mode = 0;
2415 }
2416
2417 if (TF_teleray)
2418 {
2419 Wcm.cm_tab = 0;
2420 /* We can't support standout mode, because it uses magic cookies. */
2421 TS_standout_mode = 0;
2422 /* But that means we cannot rely on ^M to go to column zero! */
2423 CR = 0;
2424 /* LF can't be trusted either -- can alter hpos */
2425 /* if move at column 0 thru a line with TS_standout_mode */
2426 Down = 0;
2427 }
2428
2429 /* Special handling for certain terminal types known to need it */
2430
2431 if (!strcmp (terminal_type, "supdup"))
2432 {
2433 memory_below_frame = 1;
2434 Wcm.cm_losewrap = 1;
2435 }
2436 if (!strncmp (terminal_type, "c10", 3)
2437 || !strcmp (terminal_type, "perq"))
2438 {
2439 /* Supply a makeshift :wi string.
2440 This string is not valid in general since it works only
2441 for windows starting at the upper left corner;
2442 but that is all Emacs uses.
2443
2444 This string works only if the frame is using
2445 the top of the video memory, because addressing is memory-relative.
2446 So first check the :ti string to see if that is true.
2447
2448 It would be simpler if the :wi string could go in the termcap
2449 entry, but it can't because it is not fully valid.
2450 If it were in the termcap entry, it would confuse other programs. */
2451 if (!TS_set_window)
2452 {
2453 p = TS_termcap_modes;
2454 while (*p && strcmp (p, "\033v "))
2455 p++;
2456 if (*p)
2457 TS_set_window = "\033v%C %C %C %C ";
2458 }
2459 /* Termcap entry often fails to have :in: flag */
2460 must_write_spaces = 1;
2461 /* :ti string typically fails to have \E^G! in it */
2462 /* This limits scope of insert-char to one line. */
2463 strcpy (area, TS_termcap_modes);
2464 strcat (area, "\033\007!");
2465 TS_termcap_modes = area;
2466 area += strlen (area) + 1;
2467 p = AbsPosition;
2468 /* Change all %+ parameters to %C, to handle
2469 values above 96 correctly for the C100. */
2470 while (*p)
2471 {
2472 if (p[0] == '%' && p[1] == '+')
2473 p[1] = 'C';
2474 p++;
2475 }
2476 }
2477
2478 FrameRows = FRAME_LINES (sf);
2479 FrameCols = FRAME_COLS (sf);
2480 specified_window = FRAME_LINES (sf);
2481
2482 if (Wcm_init () == -1) /* can't do cursor motion */
2483 #ifdef VMS
2484 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2485 It lacks the ability to position the cursor.\n\
2486 If that is not the actual type of terminal you have, use either the\n\
2487 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2488 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2489 terminal_type);
2490 #else /* not VMS */
2491 # ifdef TERMINFO
2492 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2493 It lacks the ability to position the cursor.\n\
2494 If that is not the actual type of terminal you have,\n\
2495 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2496 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2497 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2498 terminal_type);
2499 # else /* TERMCAP */
2500 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2501 It lacks the ability to position the cursor.\n\
2502 If that is not the actual type of terminal you have,\n\
2503 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2504 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2505 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2506 terminal_type);
2507 # endif /* TERMINFO */
2508 #endif /*VMS */
2509 if (FRAME_LINES (sf) <= 0
2510 || FRAME_COLS (sf) <= 0)
2511 fatal ("The frame size has not been specified");
2512
2513 delete_in_insert_mode
2514 = TS_delete_mode && TS_insert_mode
2515 && !strcmp (TS_delete_mode, TS_insert_mode);
2516
2517 se_is_so = (TS_standout_mode
2518 && TS_end_standout_mode
2519 && !strcmp (TS_standout_mode, TS_end_standout_mode));
2520
2521 UseTabs = tabs_safe_p () && TabWidth == 8;
2522
2523 scroll_region_ok
2524 = (Wcm.cm_abs
2525 && (TS_set_window || TS_set_scroll_region || TS_set_scroll_region_1));
2526
2527 line_ins_del_ok = (((TS_ins_line || TS_ins_multi_lines)
2528 && (TS_del_line || TS_del_multi_lines))
2529 || (scroll_region_ok && TS_fwd_scroll && TS_rev_scroll));
2530
2531 char_ins_del_ok = ((TS_ins_char || TS_insert_mode
2532 || TS_pad_inserted_char || TS_ins_multi_chars)
2533 && (TS_del_char || TS_del_multi_chars));
2534
2535 fast_clear_end_of_line = TS_clr_line != 0;
2536
2537 init_baud_rate ();
2538 if (read_socket_hook) /* Baudrate is somewhat */
2539 /* meaningless in this case */
2540 baud_rate = 9600;
2541
2542 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2543 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
2544
2545 if (! terminal_encode_buffer)
2546 {
2547 terminal_encode_buffer = xmalloc (1024);
2548 if (! terminal_encode_buffer)
2549 abort ();
2550 terminal_encode_buf_size = 1024;
2551 }
2552 #endif /* WINDOWSNT */
2553 }
2554
2555 /* VARARGS 1 */
2556 void
2557 fatal (str, arg1, arg2)
2558 char *str, *arg1, *arg2;
2559 {
2560 fprintf (stderr, "emacs: ");
2561 fprintf (stderr, str, arg1, arg2);
2562 fprintf (stderr, "\n");
2563 fflush (stderr);
2564 exit (1);
2565 }
2566
2567 void
2568 syms_of_term ()
2569 {
2570 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
2571 doc: /* Non-nil means the system uses terminfo rather than termcap.
2572 This variable can be used by terminal emulator packages. */);
2573 #ifdef TERMINFO
2574 system_uses_terminfo = 1;
2575 #else
2576 system_uses_terminfo = 0;
2577 #endif
2578
2579 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
2580 doc: /* Non-nil means call this function to ring the bell.
2581 The function should accept no arguments. */);
2582 Vring_bell_function = Qnil;
2583
2584 defsubr (&Stty_display_color_p);
2585 defsubr (&Stty_display_color_cells);
2586 }
2587