]> code.delx.au - gnu-emacs/blob - src/dispnew.c
* xterm.c (XTread_socket): Never treat a modifier key as a
[gnu-emacs] / src / dispnew.c
1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #include <signal.h>
22
23 #include "config.h"
24 #include <stdio.h>
25 #include <ctype.h>
26
27 #include "lisp.h"
28 #include "termchar.h"
29 #include "termopts.h"
30 #include "termhooks.h"
31 #include "cm.h"
32 #include "dispextern.h"
33 #include "buffer.h"
34 #include "frame.h"
35 #include "window.h"
36 #include "commands.h"
37 #include "disptab.h"
38 #include "indent.h"
39
40 #include "systty.h"
41 #include "systime.h"
42
43 #ifdef HAVE_X_WINDOWS
44 #include "xterm.h"
45 #endif /* HAVE_X_WINDOWS */
46
47 #define max(a, b) ((a) > (b) ? (a) : (b))
48 #define min(a, b) ((a) < (b) ? (a) : (b))
49
50 #ifndef PENDING_OUTPUT_COUNT
51 /* Get number of chars of output now in the buffer of a stdio stream.
52 This ought to be built in in stdio, but it isn't.
53 Some s- files override this because their stdio internals differ. */
54 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
55 #endif
56
57 /* Nonzero upon entry to redisplay means do not assume anything about
58 current contents of actual terminal frame; clear and redraw it. */
59
60 int frame_garbaged;
61
62 /* Nonzero means last display completed. Zero means it was preempted. */
63
64 int display_completed;
65
66 /* Lisp variable visible-bell; enables use of screen-flash
67 instead of audible bell. */
68
69 int visible_bell;
70
71 /* Invert the color of the whole frame, at a low level. */
72
73 int inverse_video;
74
75 /* Line speed of the terminal. */
76
77 int baud_rate;
78
79 /* nil or a symbol naming the window system under which emacs is
80 running ('x is the only current possibility). */
81
82 Lisp_Object Vwindow_system;
83
84 /* Version number of X windows: 10, 11 or nil. */
85 Lisp_Object Vwindow_system_version;
86
87 /* Vector of glyph definitions. Indexed by glyph number,
88 the contents are a string which is how to output the glyph.
89
90 If Vglyph_table is nil, a glyph is output by using its low 8 bits
91 as a character code. */
92
93 Lisp_Object Vglyph_table;
94
95 /* Display table to use for vectors that don't specify their own. */
96
97 Lisp_Object Vstandard_display_table;
98
99 /* Nonzero means reading single-character input with prompt
100 so put cursor on minibuffer after the prompt.
101 positive means at end of text in echo area;
102 negative means at beginning of line. */
103 int cursor_in_echo_area;
104 \f
105 /* The currently selected frame.
106 In a single-frame version, this variable always remains 0. */
107
108 FRAME_PTR selected_frame;
109
110 /* A frame which is not just a minibuffer, or 0 if there are no such
111 frames. This is usually the most recent such frame that was
112 selected. In a single-frame version, this variable always remains 0. */
113 FRAME_PTR last_nonminibuf_frame;
114
115 /* In a single-frame version, the information that would otherwise
116 exist inside frame objects lives in the following structure instead.
117
118 NOTE: the_only_frame is not checked for garbage collection; don't
119 store collectible objects in any of its fields!
120
121 You're not/The only frame in town/... */
122
123 #ifndef MULTI_FRAME
124 struct frame the_only_frame;
125 #endif
126
127 /* This is a vector, made larger whenever it isn't large enough,
128 which is used inside `update_frame' to hold the old contents
129 of the FRAME_PHYS_LINES of the frame being updated. */
130 struct frame_glyphs **ophys_lines;
131 /* Length of vector currently allocated. */
132 int ophys_lines_length;
133
134 FILE *termscript; /* Stdio stream being used for copy of all output. */
135
136 struct cm Wcm; /* Structure for info on cursor positioning */
137
138 extern short ospeed; /* Output speed (from sg_ospeed) */
139
140 int delayed_size_change; /* 1 means SIGWINCH happened when not safe. */
141 \f
142 #ifdef MULTI_FRAME
143
144 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
145 "Clear frame FRAME and output again what is supposed to appear on it.")
146 (frame)
147 Lisp_Object frame;
148 {
149 FRAME_PTR f;
150
151 CHECK_LIVE_FRAME (frame, 0);
152 f = XFRAME (frame);
153 update_begin (f);
154 /* set_terminal_modes (); */
155 clear_frame ();
156 clear_frame_records (f);
157 update_end (f);
158 fflush (stdout);
159 windows_or_buffers_changed++;
160 /* Mark all windows as INaccurate,
161 so that every window will have its redisplay done. */
162 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
163 f->garbaged = 0;
164 return Qnil;
165 }
166
167 redraw_frame (f)
168 FRAME_PTR f;
169 {
170 Lisp_Object frame;
171 XSET (frame, Lisp_Frame, f);
172 Fredraw_frame (frame);
173 }
174
175 #else
176
177 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, "",
178 "Clear frame FRAME and output again what is supposed to appear on it.")
179 (frame)
180 Lisp_Object frame;
181 {
182 update_begin (0);
183 set_terminal_modes ();
184 clear_frame ();
185 update_end (0);
186 fflush (stdout);
187 clear_frame_records (0);
188 windows_or_buffers_changed++;
189 /* Mark all windows as INaccurate,
190 so that every window will have its redisplay done. */
191 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
192 return Qnil;
193 }
194
195 #endif
196
197 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
198 "Clear and redisplay all visible frames.")
199 ()
200 {
201 Lisp_Object tail, frame;
202
203 FOR_EACH_FRAME (tail, frame)
204 if (FRAME_VISIBLE_P (XFRAME (frame)))
205 Fredraw_frame (frame);
206
207 return Qnil;
208 }
209
210 /* This is used when frame_garbaged is set.
211 Redraw the individual frames marked as garbaged. */
212
213 void
214 redraw_garbaged_frames ()
215 {
216 Lisp_Object tail, frame;
217
218 FOR_EACH_FRAME (tail, frame)
219 if (FRAME_VISIBLE_P (XFRAME (frame))
220 && FRAME_GARBAGED_P (XFRAME (frame)))
221 Fredraw_frame (frame);
222 }
223
224 \f
225 static struct frame_glyphs *
226 make_frame_glyphs (frame, empty)
227 register FRAME_PTR frame;
228 int empty;
229 {
230 register int i;
231 register width = FRAME_WIDTH (frame);
232 register height = FRAME_HEIGHT (frame);
233 register struct frame_glyphs *new =
234 (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs));
235
236 SET_GLYPHS_FRAME (new, frame);
237 new->height = height;
238 new->width = width;
239 new->used = (int *) xmalloc (height * sizeof (int));
240 new->glyphs = (GLYPH **) xmalloc (height * sizeof (GLYPH *));
241 new->highlight = (char *) xmalloc (height * sizeof (char));
242 new->enable = (char *) xmalloc (height * sizeof (char));
243 bzero (new->enable, height * sizeof (char));
244 new->bufp = (int *) xmalloc (height * sizeof (int));
245
246 #ifdef HAVE_X_WINDOWS
247 if (FRAME_X_P (frame))
248 {
249 new->top_left_x = (short *) xmalloc (height * sizeof (short));
250 new->top_left_y = (short *) xmalloc (height * sizeof (short));
251 new->pix_width = (short *) xmalloc (height * sizeof (short));
252 new->pix_height = (short *) xmalloc (height * sizeof (short));
253 new->max_ascent = (short *) xmalloc (height * sizeof (short));
254 }
255 #endif
256
257 if (empty)
258 {
259 /* Make the buffer used by decode_mode_spec. This buffer is also
260 used as temporary storage when updating the frame. See scroll.c. */
261 unsigned int total_glyphs = (width + 2) * sizeof (GLYPH);
262
263 new->total_contents = (GLYPH *) xmalloc (total_glyphs);
264 bzero (new->total_contents, total_glyphs);
265 }
266 else
267 {
268 unsigned int total_glyphs = height * (width + 2) * sizeof (GLYPH);
269
270 new->total_contents = (GLYPH *) xmalloc (total_glyphs);
271 bzero (new->total_contents, total_glyphs);
272 for (i = 0; i < height; i++)
273 new->glyphs[i] = new->total_contents + i * (width + 2) + 1;
274 }
275
276 return new;
277 }
278
279 static void
280 free_frame_glyphs (frame, glyphs)
281 FRAME_PTR frame;
282 struct frame_glyphs *glyphs;
283 {
284 if (glyphs->total_contents)
285 xfree (glyphs->total_contents);
286
287 xfree (glyphs->used);
288 xfree (glyphs->glyphs);
289 xfree (glyphs->highlight);
290 xfree (glyphs->enable);
291 xfree (glyphs->bufp);
292
293 #ifdef HAVE_X_WINDOWS
294 if (FRAME_X_P (frame))
295 {
296 xfree (glyphs->top_left_x);
297 xfree (glyphs->top_left_y);
298 xfree (glyphs->pix_width);
299 xfree (glyphs->pix_height);
300 xfree (glyphs->max_ascent);
301 }
302 #endif
303
304 xfree (glyphs);
305 }
306
307 static void
308 remake_frame_glyphs (frame)
309 FRAME_PTR frame;
310 {
311 if (FRAME_CURRENT_GLYPHS (frame))
312 free_frame_glyphs (frame, FRAME_CURRENT_GLYPHS (frame));
313 if (FRAME_DESIRED_GLYPHS (frame))
314 free_frame_glyphs (frame, FRAME_DESIRED_GLYPHS (frame));
315 if (FRAME_TEMP_GLYPHS (frame))
316 free_frame_glyphs (frame, FRAME_TEMP_GLYPHS (frame));
317
318 if (FRAME_MESSAGE_BUF (frame))
319 {
320 /* Reallocate the frame's message buffer; remember that
321 echo_area_glyphs may be pointing here. */
322 char *old_message_buf = FRAME_MESSAGE_BUF (frame);
323
324 FRAME_MESSAGE_BUF (frame)
325 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame),
326 FRAME_WIDTH (frame) + 1);
327
328 if (echo_area_glyphs == old_message_buf)
329 echo_area_glyphs = FRAME_MESSAGE_BUF (frame);
330 if (previous_echo_glyphs == old_message_buf)
331 previous_echo_glyphs = FRAME_MESSAGE_BUF (frame);
332 }
333 else
334 FRAME_MESSAGE_BUF (frame)
335 = (char *) xmalloc (FRAME_WIDTH (frame) + 1);
336
337 FRAME_CURRENT_GLYPHS (frame) = make_frame_glyphs (frame, 0);
338 FRAME_DESIRED_GLYPHS (frame) = make_frame_glyphs (frame, 0);
339 FRAME_TEMP_GLYPHS (frame) = make_frame_glyphs (frame, 1);
340 SET_FRAME_GARBAGED (frame);
341 }
342 \f
343 /* Return the hash code of contents of line VPOS in frame-matrix M. */
344
345 static int
346 line_hash_code (m, vpos)
347 register struct frame_glyphs *m;
348 int vpos;
349 {
350 register GLYPH *body, *end;
351 register int h = 0;
352
353 if (!m->enable[vpos])
354 return 0;
355
356 /* Give all highlighted lines the same hash code
357 so as to encourage scrolling to leave them in place. */
358 if (m->highlight[vpos])
359 return -1;
360
361 body = m->glyphs[vpos];
362
363 if (must_write_spaces)
364 while (1)
365 {
366 GLYPH g = *body++;
367
368 if (g == 0)
369 break;
370 h = (((h << 4) + (h >> 24)) & 0x0fffffff) + g - SPACEGLYPH;
371 }
372 else
373 while (1)
374 {
375 GLYPH g = *body++;
376
377 if (g == 0)
378 break;
379 h = (((h << 4) + (h >> 24)) & 0x0fffffff) + g;
380 }
381
382 if (h)
383 return h;
384 return 1;
385 }
386
387 /* Return number of characters in line in M at vpos VPOS,
388 except don't count leading and trailing spaces
389 unless the terminal requires those to be explicitly output. */
390
391 static unsigned int
392 line_draw_cost (m, vpos)
393 struct frame_glyphs *m;
394 int vpos;
395 {
396 register GLYPH *beg = m->glyphs[vpos];
397 register GLYPH *end = m->glyphs[vpos] + m->used[vpos];
398 register int i;
399 register int tlen = GLYPH_TABLE_LENGTH;
400 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
401
402 /* Ignore trailing and leading spaces if we can. */
403 if (!must_write_spaces)
404 {
405 while ((end != beg) && (*end == SPACEGLYPH))
406 --end;
407 if (end == beg)
408 return (0); /* All blank line. */
409
410 while (*beg == SPACEGLYPH)
411 ++beg;
412 }
413
414 /* If we don't have a glyph-table, each glyph is one character,
415 so return the number of glyphs. */
416 if (tbase == 0)
417 return end - beg;
418
419 /* Otherwise, scan the glyphs and accumulate their total size in I. */
420 i = 0;
421 while ((beg <= end) && *beg)
422 {
423 register GLYPH g = *beg++;
424
425 if (GLYPH_SIMPLE_P (tbase, tlen, g))
426 i += 1;
427 else
428 i += GLYPH_LENGTH (tbase, g);
429 }
430 return i;
431 }
432 \f
433 /* The functions on this page are the interface from xdisp.c to redisplay.
434
435 The only other interface into redisplay is through setting
436 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
437 and SET_FRAME_GARBAGED (frame). */
438
439 /* cancel_line eliminates any request to display a line at position `vpos' */
440
441 cancel_line (vpos, frame)
442 int vpos;
443 register FRAME_PTR frame;
444 {
445 FRAME_DESIRED_GLYPHS (frame)->enable[vpos] = 0;
446 }
447
448 clear_frame_records (frame)
449 register FRAME_PTR frame;
450 {
451 bzero (FRAME_CURRENT_GLYPHS (frame)->enable, FRAME_HEIGHT (frame));
452 }
453
454 /* Prepare to display on line VPOS starting at HPOS within it. */
455
456 void
457 get_display_line (frame, vpos, hpos)
458 register FRAME_PTR frame;
459 int vpos;
460 register int hpos;
461 {
462 register struct frame_glyphs *glyphs;
463 register struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (frame);
464 register GLYPH *p;
465
466 if (vpos < 0)
467 abort ();
468
469 if ((desired_glyphs->enable[vpos]) && desired_glyphs->used[vpos] > hpos)
470 abort ();
471
472 if (! desired_glyphs->enable[vpos])
473 {
474 desired_glyphs->used[vpos] = 0;
475 desired_glyphs->highlight[vpos] = 0;
476 desired_glyphs->enable[vpos] = 1;
477 }
478
479 if (hpos > desired_glyphs->used[vpos])
480 {
481 GLYPH *g = desired_glyphs->glyphs[vpos] + desired_glyphs->used[vpos];
482 GLYPH *end = desired_glyphs->glyphs[vpos] + hpos;
483
484 desired_glyphs->used[vpos] = hpos;
485 while (g != end)
486 *g++ = SPACEGLYPH;
487 }
488 }
489
490 /* Like bcopy except never gets confused by overlap. */
491
492 void
493 safe_bcopy (from, to, size)
494 char *from, *to;
495 int size;
496 {
497 if (size <= 0 || from == to)
498 return;
499
500 /* If the source and destination don't overlap, then bcopy can
501 handle it. If they do overlap, but the destination is lower in
502 memory than the source, we'll assume bcopy can handle that. */
503 if (to < from || from + size <= to)
504 bcopy (from, to, size);
505
506 /* Otherwise, we'll copy from the end. */
507 else
508 {
509 register char *endf = from + size;
510 register char *endt = to + size;
511
512 /* If TO - FROM is large, then we should break the copy into
513 nonoverlapping chunks of TO - FROM bytes each. However, if
514 TO - FROM is small, then the bcopy function call overhead
515 makes this not worth it. The crossover point could be about
516 anywhere. Since I don't think the obvious copy loop is too
517 bad, I'm trying to err in its favor. */
518 if (to - from < 64)
519 {
520 do
521 *--endt = *--endf;
522 while (endf != from);
523 }
524 else
525 {
526 for (;;)
527 {
528 endt -= (to - from);
529 endf -= (to - from);
530
531 if (endt < to)
532 break;
533
534 bcopy (endf, endt, to - from);
535 }
536
537 /* If SIZE wasn't a multiple of TO - FROM, there will be a
538 little left over. The amount left over is
539 (endt + (to - from)) - to, which is endt - from. */
540 bcopy (from, to, endt - from);
541 }
542 }
543 }
544
545 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
546 DISTANCE may be negative. */
547
548 static void
549 rotate_vector (vector, size, distance)
550 char *vector;
551 int size;
552 int distance;
553 {
554 char *temp = (char *) alloca (size);
555
556 if (distance < 0)
557 distance += size;
558
559 bcopy (vector, temp + distance, size - distance);
560 bcopy (vector + size - distance, temp, distance);
561 bcopy (temp, vector, size);
562 }
563
564 /* Scroll lines from vpos FROM up to but not including vpos END
565 down by AMOUNT lines (AMOUNT may be negative).
566 Returns nonzero if done, zero if terminal cannot scroll them. */
567
568 int
569 scroll_frame_lines (frame, from, end, amount)
570 register FRAME_PTR frame;
571 int from, end, amount;
572 {
573 register int i;
574 register struct frame_glyphs *current_frame
575 = FRAME_CURRENT_GLYPHS (frame);
576
577 if (!line_ins_del_ok)
578 return 0;
579
580 if (amount == 0)
581 return 1;
582
583 if (amount > 0)
584 {
585 update_begin (frame);
586 set_terminal_window (end + amount);
587 if (!scroll_region_ok)
588 ins_del_lines (end, -amount);
589 ins_del_lines (from, amount);
590 set_terminal_window (0);
591
592 rotate_vector (current_frame->glyphs + from,
593 sizeof (GLYPH *) * (end + amount - from),
594 amount * sizeof (GLYPH *));
595
596 safe_bcopy (current_frame->used + from,
597 current_frame->used + from + amount,
598 (end - from) * sizeof current_frame->used[0]);
599
600 safe_bcopy (current_frame->highlight + from,
601 current_frame->highlight + from + amount,
602 (end - from) * sizeof current_frame->highlight[0]);
603
604 safe_bcopy (current_frame->enable + from,
605 current_frame->enable + from + amount,
606 (end - from) * sizeof current_frame->enable[0]);
607
608 /* Mark the lines made empty by scrolling as enabled, empty and
609 normal video. */
610 bzero (current_frame->used + from,
611 amount * sizeof current_frame->used[0]);
612 bzero (current_frame->highlight + from,
613 amount * sizeof current_frame->highlight[0]);
614 for (i = from; i < from + amount; i++)
615 {
616 current_frame->glyphs[i][0] = '\0';
617 current_frame->enable[i] = 1;
618 }
619
620 safe_bcopy (current_frame->bufp + from,
621 current_frame->bufp + from + amount,
622 (end - from) * sizeof current_frame->bufp[0]);
623
624 #ifdef HAVE_X_WINDOWS
625 if (FRAME_X_P (frame))
626 {
627 safe_bcopy (current_frame->top_left_x + from,
628 current_frame->top_left_x + from + amount,
629 (end - from) * sizeof current_frame->top_left_x[0]);
630
631 safe_bcopy (current_frame->top_left_y + from,
632 current_frame->top_left_y + from + amount,
633 (end - from) * sizeof current_frame->top_left_y[0]);
634
635 safe_bcopy (current_frame->pix_width + from,
636 current_frame->pix_width + from + amount,
637 (end - from) * sizeof current_frame->pix_width[0]);
638
639 safe_bcopy (current_frame->pix_height + from,
640 current_frame->pix_height + from + amount,
641 (end - from) * sizeof current_frame->pix_height[0]);
642
643 safe_bcopy (current_frame->max_ascent + from,
644 current_frame->max_ascent + from + amount,
645 (end - from) * sizeof current_frame->max_ascent[0]);
646 }
647 #endif /* HAVE_X_WINDOWS */
648
649 update_end (frame);
650 }
651 if (amount < 0)
652 {
653 update_begin (frame);
654 set_terminal_window (end);
655 ins_del_lines (from + amount, amount);
656 if (!scroll_region_ok)
657 ins_del_lines (end + amount, -amount);
658 set_terminal_window (0);
659
660 rotate_vector (current_frame->glyphs + from + amount,
661 sizeof (GLYPH *) * (end - from - amount),
662 amount * sizeof (GLYPH *));
663
664 safe_bcopy (current_frame->used + from,
665 current_frame->used + from + amount,
666 (end - from) * sizeof current_frame->used[0]);
667
668 safe_bcopy (current_frame->highlight + from,
669 current_frame->highlight + from + amount,
670 (end - from) * sizeof current_frame->highlight[0]);
671
672 safe_bcopy (current_frame->enable + from,
673 current_frame->enable + from + amount,
674 (end - from) * sizeof current_frame->enable[0]);
675
676 /* Mark the lines made empty by scrolling as enabled, empty and
677 normal video. */
678 bzero (current_frame->used + end + amount,
679 - amount * sizeof current_frame->used[0]);
680 bzero (current_frame->highlight + end + amount,
681 - amount * sizeof current_frame->highlight[0]);
682 for (i = end + amount; i < end; i++)
683 {
684 current_frame->glyphs[i][0] = '\0';
685 current_frame->enable[i] = 1;
686 }
687
688 safe_bcopy (current_frame->bufp + from,
689 current_frame->bufp + from + amount,
690 (end - from) * sizeof current_frame->bufp[0]);
691
692 #ifdef HAVE_X_WINDOWS
693 if (FRAME_X_P (frame))
694 {
695 safe_bcopy (current_frame->top_left_x + from,
696 current_frame->top_left_x + from + amount,
697 (end - from) * sizeof current_frame->top_left_x[0]);
698
699 safe_bcopy (current_frame->top_left_y + from,
700 current_frame->top_left_y + from + amount,
701 (end - from) * sizeof current_frame->top_left_y[0]);
702
703 safe_bcopy (current_frame->pix_width + from,
704 current_frame->pix_width + from + amount,
705 (end - from) * sizeof current_frame->pix_width[0]);
706
707 safe_bcopy (current_frame->pix_height + from,
708 current_frame->pix_height + from + amount,
709 (end - from) * sizeof current_frame->pix_height[0]);
710
711 safe_bcopy (current_frame->max_ascent + from,
712 current_frame->max_ascent + from + amount,
713 (end - from) * sizeof current_frame->max_ascent[0]);
714 }
715 #endif /* HAVE_X_WINDOWS */
716
717 update_end (frame);
718 }
719 return 1;
720 }
721 \f
722 /* After updating a window W that isn't the full frame wide,
723 copy all the columns that W does not occupy
724 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
725 so that update_frame will not change those columns. */
726
727 preserve_other_columns (w)
728 struct window *w;
729 {
730 register int vpos;
731 register struct frame_glyphs *current_frame, *desired_frame;
732 register FRAME_PTR frame = XFRAME (w->frame);
733 int start = XFASTINT (w->left);
734 int end = XFASTINT (w->left) + XFASTINT (w->width);
735 int bot = XFASTINT (w->top) + XFASTINT (w->height);
736
737 current_frame = FRAME_CURRENT_GLYPHS (frame);
738 desired_frame = FRAME_DESIRED_GLYPHS (frame);
739
740 for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
741 {
742 if (current_frame->enable[vpos] && desired_frame->enable[vpos])
743 {
744 if (start > 0)
745 {
746 int len;
747
748 bcopy (current_frame->glyphs[vpos],
749 desired_frame->glyphs[vpos],
750 start * sizeof (current_frame->glyphs[vpos]));
751 len = min (start, current_frame->used[vpos]);
752 if (desired_frame->used[vpos] < len)
753 desired_frame->used[vpos] = len;
754 }
755 if (current_frame->used[vpos] > end
756 && desired_frame->used[vpos] < current_frame->used[vpos])
757 {
758 while (desired_frame->used[vpos] < end)
759 desired_frame->glyphs[vpos][desired_frame->used[vpos]++]
760 = SPACEGLYPH;
761 bcopy (current_frame->glyphs[vpos] + end,
762 desired_frame->glyphs[vpos] + end,
763 ((current_frame->used[vpos] - end)
764 * sizeof (current_frame->glyphs[vpos])));
765 desired_frame->used[vpos] = current_frame->used[vpos];
766 }
767 }
768 }
769 }
770 \f
771 #if 0
772
773 /* If window w does not need to be updated and isn't the full frame wide,
774 copy all the columns that w does occupy
775 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
776 so that update_frame will not change those columns.
777
778 Have not been able to figure out how to use this correctly. */
779
780 preserve_my_columns (w)
781 struct window *w;
782 {
783 register int vpos, fin;
784 register struct frame_glyphs *l1, *l2;
785 register FRAME_PTR frame = XFRAME (w->frame);
786 int start = XFASTINT (w->left);
787 int end = XFASTINT (w->left) + XFASTINT (w->width);
788 int bot = XFASTINT (w->top) + XFASTINT (w->height);
789
790 for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
791 {
792 if ((l1 = FRAME_DESIRED_GLYPHS (frame)->glyphs[vpos + 1])
793 && (l2 = FRAME_PHYS_GLYPHS (frame)->glyphs[vpos + 1]))
794 {
795 if (l2->length > start && l1->length < l2->length)
796 {
797 fin = l2->length;
798 if (fin > end) fin = end;
799 while (l1->length < start)
800 l1->body[l1->length++] = ' ';
801 bcopy (l2->body + start, l1->body + start, fin - start);
802 l1->length = fin;
803 }
804 }
805 }
806 }
807
808 #endif
809 \f
810 /* On discovering that the redisplay for a window was no good,
811 cancel the columns of that window, so that when the window is
812 displayed over again get_display_line will not complain. */
813
814 cancel_my_columns (w)
815 struct window *w;
816 {
817 register int vpos;
818 register struct frame_glyphs *desired_glyphs =
819 FRAME_DESIRED_GLYPHS (XFRAME (w->frame));
820 register int start = XFASTINT (w->left);
821 register int bot = XFASTINT (w->top) + XFASTINT (w->height);
822
823 for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
824 if (desired_glyphs->enable[vpos]
825 && desired_glyphs->used[vpos] >= start)
826 desired_glyphs->used[vpos] = start;
827 }
828 \f
829 /* These functions try to perform directly and immediately on the frame
830 the necessary output for one change in the buffer.
831 They may return 0 meaning nothing was done if anything is difficult,
832 or 1 meaning the output was performed properly.
833 They assume that the frame was up to date before the buffer
834 change being displayed. They make various other assumptions too;
835 see command_loop_1 where these are called. */
836
837 int
838 direct_output_for_insert (g)
839 int g;
840 {
841 register FRAME_PTR frame = selected_frame;
842 register struct frame_glyphs *current_frame
843 = FRAME_CURRENT_GLYPHS (frame);
844
845 #ifndef COMPILER_REGISTER_BUG
846 register
847 #endif /* COMPILER_REGISTER_BUG */
848 struct window *w = XWINDOW (selected_window);
849 #ifndef COMPILER_REGISTER_BUG
850 register
851 #endif /* COMPILER_REGISTER_BUG */
852 int hpos = FRAME_CURSOR_X (frame);
853 #ifndef COMPILER_REGISTER_BUG
854 register
855 #endif /* COMPILER_REGISTER_BUG */
856 int vpos = FRAME_CURSOR_Y (frame);
857
858 /* Give up if about to continue line. */
859 if (hpos >= XFASTINT (w->left) + window_internal_width (w) - 1
860
861 /* Avoid losing if cursor is in invisible text off left margin */
862 || (XINT (w->hscroll) && hpos == XFASTINT (w->left))
863
864 /* Give up if cursor outside window (in minibuf, probably) */
865 || cursor_in_echo_area
866 || FRAME_CURSOR_Y (frame) < XFASTINT (w->top)
867 || FRAME_CURSOR_Y (frame) >= XFASTINT (w->top) + XFASTINT (w->height)
868
869 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
870 || !display_completed
871
872 /* Give up if buffer appears in two places. */
873 || buffer_shared > 1
874
875 /* Give up if w is minibuffer and a message is being displayed there */
876 || (MINI_WINDOW_P (w) && echo_area_glyphs))
877 return 0;
878
879 {
880 #ifdef HAVE_X_WINDOWS
881 int dummy;
882 int face = compute_char_face (frame, w, point, -1, -1, &dummy);
883 #else
884 int face = 0;
885 #endif
886
887 current_frame->glyphs[vpos][hpos] = MAKE_GLYPH (g, face);
888 }
889 unchanged_modified = MODIFF;
890 beg_unchanged = GPT - BEG;
891 XFASTINT (w->last_point) = point;
892 XFASTINT (w->last_point_x) = hpos;
893 XFASTINT (w->last_modified) = MODIFF;
894
895 reassert_line_highlight (0, vpos);
896 write_glyphs (&current_frame->glyphs[vpos][hpos], 1);
897 fflush (stdout);
898 ++FRAME_CURSOR_X (frame);
899 if (hpos == current_frame->used[vpos])
900 {
901 current_frame->used[vpos] = hpos + 1;
902 current_frame->glyphs[vpos][hpos + 1] = 0;
903 }
904
905 return 1;
906 }
907
908 int
909 direct_output_forward_char (n)
910 int n;
911 {
912 register FRAME_PTR frame = selected_frame;
913 register struct window *w = XWINDOW (selected_window);
914
915 /* Avoid losing if cursor is in invisible text off left margin
916 or about to go off either side of window. */
917 if ((FRAME_CURSOR_X (frame) == XFASTINT (w->left)
918 && (XINT (w->hscroll) || n < 0))
919 || (n > 0
920 && (FRAME_CURSOR_X (frame) + 1 >= window_internal_width (w) - 1))
921 || cursor_in_echo_area)
922 return 0;
923
924 /* Can't use direct output if highlighting a region. */
925 if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
926 return 0;
927
928 FRAME_CURSOR_X (frame) += n;
929 XFASTINT (w->last_point_x) = FRAME_CURSOR_X (frame);
930 XFASTINT (w->last_point) = point;
931 cursor_to (FRAME_CURSOR_Y (frame), FRAME_CURSOR_X (frame));
932 fflush (stdout);
933 return 1;
934 }
935 \f
936 static void update_line ();
937
938 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
939 Value is nonzero if redisplay stopped due to pending input.
940 FORCE nonzero means do not stop for pending input. */
941
942 int
943 update_frame (f, force, inhibit_hairy_id)
944 FRAME_PTR f;
945 int force;
946 int inhibit_hairy_id;
947 {
948 register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (f);
949 register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (f);
950 register int i;
951 int pause;
952 int preempt_count = baud_rate / 2400 + 1;
953 extern input_pending;
954 #ifdef HAVE_X_WINDOWS
955 register int downto, leftmost;
956 #endif
957
958 if (preempt_count <= 0)
959 preempt_count = 1;
960
961 if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
962
963 detect_input_pending ();
964 if (input_pending && !force)
965 {
966 pause = 1;
967 goto do_pause;
968 }
969
970 update_begin (f);
971
972 if (!line_ins_del_ok)
973 inhibit_hairy_id = 1;
974
975 /* See if any of the desired lines are enabled; don't compute for
976 i/d line if just want cursor motion. */
977 for (i = 0; i < FRAME_HEIGHT (f); i++)
978 if (desired_frame->enable[i])
979 break;
980
981 /* Try doing i/d line, if not yet inhibited. */
982 if (!inhibit_hairy_id && i < FRAME_HEIGHT (f))
983 force |= scrolling (f);
984
985 /* Update the individual lines as needed. Do bottom line first. */
986
987 if (desired_frame->enable[FRAME_HEIGHT (f) - 1])
988 update_line (f, FRAME_HEIGHT (f) - 1);
989
990 #ifdef HAVE_X_WINDOWS
991 if (FRAME_X_P (f))
992 {
993 leftmost = downto = f->display.x->internal_border_width;
994 if (desired_frame->enable[0])
995 {
996 current_frame->top_left_x[FRAME_HEIGHT (f) - 1] = leftmost;
997 current_frame->top_left_y[FRAME_HEIGHT (f) - 1]
998 = PIXEL_HEIGHT (f) - f->display.x->internal_border_width
999 - current_frame->pix_height[FRAME_HEIGHT (f) - 1];
1000 current_frame->top_left_x[0] = leftmost;
1001 current_frame->top_left_y[0] = downto;
1002 }
1003 }
1004 #endif /* HAVE_X_WINDOWS */
1005
1006 /* Now update the rest of the lines. */
1007 for (i = 0; i < FRAME_HEIGHT (f) - 1 && (force || !input_pending); i++)
1008 {
1009 if (desired_frame->enable[i])
1010 {
1011 if (FRAME_TERMCAP_P (f))
1012 {
1013 /* Flush out every so many lines.
1014 Also flush out if likely to have more than 1k buffered
1015 otherwise. I'm told that some telnet connections get
1016 really screwed by more than 1k output at once. */
1017 int outq = PENDING_OUTPUT_COUNT (stdout);
1018 if (outq > 900
1019 || (outq > 20 && ((i - 1) % preempt_count == 0)))
1020 {
1021 fflush (stdout);
1022 if (preempt_count == 1)
1023 {
1024 #ifdef EMACS_OUTQSIZE
1025 if (EMACS_OUTQSIZE (0, &outq) < 0)
1026 /* Probably not a tty. Ignore the error and reset
1027 * the outq count. */
1028 outq = PENDING_OUTPUT_COUNT (stdout);
1029 #endif
1030 outq *= 10;
1031 if (baud_rate > 0)
1032 sleep (outq / baud_rate);
1033 }
1034 }
1035 if ((i - 1) % preempt_count == 0)
1036 detect_input_pending ();
1037 }
1038
1039 update_line (f, i);
1040 #ifdef HAVE_X_WINDOWS
1041 if (FRAME_X_P (f))
1042 {
1043 current_frame->top_left_y[i] = downto;
1044 current_frame->top_left_x[i] = leftmost;
1045 }
1046 #endif /* HAVE_X_WINDOWS */
1047 }
1048
1049 #ifdef HAVE_X_WINDOWS
1050 if (FRAME_X_P (f))
1051 downto += current_frame->pix_height[i];
1052 #endif
1053 }
1054 pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0;
1055
1056 /* Now just clean up termcap drivers and set cursor, etc. */
1057 if (!pause)
1058 {
1059 if (cursor_in_echo_area
1060 && FRAME_HAS_MINIBUF_P (f))
1061 {
1062 int top = XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top);
1063 int row, col;
1064
1065 if (cursor_in_echo_area < 0)
1066 {
1067 row = top;
1068 col = 0;
1069 }
1070 else
1071 {
1072 /* If the minibuffer is several lines high, find the last
1073 line that has any text on it. */
1074 row = FRAME_HEIGHT (f);
1075 do
1076 {
1077 row--;
1078 if (current_frame->enable[row])
1079 col = current_frame->used[row];
1080 else
1081 col = 0;
1082 }
1083 while (row > top && col == 0);
1084
1085 if (col >= FRAME_WIDTH (f))
1086 {
1087 col = 0;
1088 if (row < FRAME_HEIGHT (f) - 1)
1089 row++;
1090 }
1091 }
1092
1093 cursor_to (row, col);
1094 }
1095 else
1096 cursor_to (FRAME_CURSOR_Y (f), max (min (FRAME_CURSOR_X (f),
1097 FRAME_WIDTH (f) - 1), 0));
1098 }
1099
1100 update_end (f);
1101
1102 if (termscript)
1103 fflush (termscript);
1104 fflush (stdout);
1105
1106 /* Here if output is preempted because input is detected. */
1107 do_pause:
1108
1109 if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
1110 display_completed = !pause;
1111
1112 bzero (desired_frame->enable, FRAME_HEIGHT (f));
1113 return pause;
1114 }
1115
1116 /* Called when about to quit, to check for doing so
1117 at an improper time. */
1118
1119 void
1120 quit_error_check ()
1121 {
1122 if (FRAME_DESIRED_GLYPHS (selected_frame) == 0)
1123 return;
1124 if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[0])
1125 abort ();
1126 if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[FRAME_HEIGHT (selected_frame) - 1])
1127 abort ();
1128 }
1129 \f
1130 /* Decide what insert/delete line to do, and do it */
1131
1132 extern void scrolling_1 ();
1133
1134 scrolling (frame)
1135 FRAME_PTR frame;
1136 {
1137 int unchanged_at_top, unchanged_at_bottom;
1138 int window_size;
1139 int changed_lines;
1140 int *old_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
1141 int *new_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
1142 int *draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
1143 register int i;
1144 int free_at_end_vpos = FRAME_HEIGHT (frame);
1145 register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (frame);
1146 register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (frame);
1147
1148 /* Compute hash codes of all the lines.
1149 Also calculate number of changed lines,
1150 number of unchanged lines at the beginning,
1151 and number of unchanged lines at the end. */
1152
1153 changed_lines = 0;
1154 unchanged_at_top = 0;
1155 unchanged_at_bottom = FRAME_HEIGHT (frame);
1156 for (i = 0; i < FRAME_HEIGHT (frame); i++)
1157 {
1158 /* Give up on this scrolling if some old lines are not enabled. */
1159 if (!current_frame->enable[i])
1160 return 0;
1161 old_hash[i] = line_hash_code (current_frame, i);
1162 if (! desired_frame->enable[i])
1163 new_hash[i] = old_hash[i];
1164 else
1165 new_hash[i] = line_hash_code (desired_frame, i);
1166
1167 if (old_hash[i] != new_hash[i])
1168 {
1169 changed_lines++;
1170 unchanged_at_bottom = FRAME_HEIGHT (frame) - i - 1;
1171 }
1172 else if (i == unchanged_at_top)
1173 unchanged_at_top++;
1174 draw_cost[i] = line_draw_cost (desired_frame, i);
1175 }
1176
1177 /* If changed lines are few, don't allow preemption, don't scroll. */
1178 if (changed_lines < baud_rate / 2400
1179 || unchanged_at_bottom == FRAME_HEIGHT (frame))
1180 return 1;
1181
1182 window_size = (FRAME_HEIGHT (frame) - unchanged_at_top
1183 - unchanged_at_bottom);
1184
1185 if (scroll_region_ok)
1186 free_at_end_vpos -= unchanged_at_bottom;
1187 else if (memory_below_frame)
1188 free_at_end_vpos = -1;
1189
1190 /* If large window, fast terminal and few lines in common between
1191 current frame and desired frame, don't bother with i/d calc. */
1192 if (window_size >= 18 && baud_rate > 2400
1193 && (window_size >=
1194 10 * scrolling_max_lines_saved (unchanged_at_top,
1195 FRAME_HEIGHT (frame) - unchanged_at_bottom,
1196 old_hash, new_hash, draw_cost)))
1197 return 0;
1198
1199 scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
1200 draw_cost + unchanged_at_top - 1,
1201 old_hash + unchanged_at_top - 1,
1202 new_hash + unchanged_at_top - 1,
1203 free_at_end_vpos - unchanged_at_top);
1204
1205 return 0;
1206 }
1207 \f
1208 /* Return the offset in its buffer of the character at location col, line
1209 in the given window. */
1210 int
1211 buffer_posn_from_coords (window, col, line)
1212 struct window *window;
1213 int col, line;
1214 {
1215 int window_left = XFASTINT (window->left);
1216
1217 /* The actual width of the window is window->width less one for the
1218 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1219 window. */
1220 int window_width = window_internal_width (window) - 1;
1221
1222 int startp = marker_position (window->start);
1223
1224 /* Since compute_motion will only operate on the current buffer,
1225 we need to save the old one and restore it when we're done. */
1226 struct buffer *old_current_buffer = current_buffer;
1227 struct position *posn;
1228
1229 current_buffer = XBUFFER (window->buffer);
1230
1231 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1232 (window->frame))->bufp to avoid scanning from the very top of
1233 the window, but it isn't maintained correctly, and I'm not even
1234 sure I will keep it. */
1235 posn = compute_motion (startp, 0,
1236 (window == XWINDOW (minibuf_window) && startp == 1
1237 ? minibuf_prompt_width : 0),
1238 ZV, line, col,
1239 window_width, XINT (window->hscroll), 0);
1240
1241 current_buffer = old_current_buffer;
1242
1243 /* compute_motion considers frame points past the end of a line
1244 to be *after* the newline, i.e. at the start of the next line.
1245 This is reasonable, but not really what we want. So if the
1246 result is on a line below LINE, back it up one character. */
1247 if (posn->vpos > line)
1248 return posn->bufpos - 1;
1249 else
1250 return posn->bufpos;
1251 }
1252 \f
1253 static int
1254 count_blanks (r)
1255 register GLYPH *r;
1256 {
1257 register GLYPH *p = r;
1258 while (*p++ == SPACEGLYPH);
1259 return p - r - 1;
1260 }
1261
1262 static int
1263 count_match (str1, str2)
1264 GLYPH *str1, *str2;
1265 {
1266 register GLYPH *p1 = str1;
1267 register GLYPH *p2 = str2;
1268 while (*p1++ == *p2++);
1269 return p1 - str1 - 1;
1270 }
1271
1272 /* Char insertion/deletion cost vector, from term.c */
1273 extern int *char_ins_del_vector;
1274
1275 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1276
1277 static void
1278 update_line (frame, vpos)
1279 register FRAME_PTR frame;
1280 int vpos;
1281 {
1282 register GLYPH *obody, *nbody, *op1, *op2, *np1, *temp;
1283 int tem;
1284 int osp, nsp, begmatch, endmatch, olen, nlen;
1285 int save;
1286 register struct frame_glyphs *current_frame
1287 = FRAME_CURRENT_GLYPHS (frame);
1288 register struct frame_glyphs *desired_frame
1289 = FRAME_DESIRED_GLYPHS (frame);
1290
1291 if (desired_frame->highlight[vpos]
1292 != (current_frame->enable[vpos] && current_frame->highlight[vpos]))
1293 {
1294 change_line_highlight (desired_frame->highlight[vpos], vpos,
1295 (current_frame->enable[vpos] ?
1296 current_frame->used[vpos] : 0));
1297 current_frame->enable[vpos] = 0;
1298 }
1299 else
1300 reassert_line_highlight (desired_frame->highlight[vpos], vpos);
1301
1302 if (! current_frame->enable[vpos])
1303 {
1304 olen = 0;
1305 }
1306 else
1307 {
1308 obody = current_frame->glyphs[vpos];
1309 olen = current_frame->used[vpos];
1310 if (! current_frame->highlight[vpos])
1311 {
1312 if (!must_write_spaces)
1313 while (obody[olen - 1] == SPACEGLYPH && olen > 0)
1314 olen--;
1315 }
1316 else
1317 {
1318 /* For an inverse-video line, remember we gave it
1319 spaces all the way to the frame edge
1320 so that the reverse video extends all the way across. */
1321
1322 while (olen < FRAME_WIDTH (frame) - 1)
1323 obody[olen++] = SPACEGLYPH;
1324 }
1325 }
1326
1327 /* One way or another, this will enable the line being updated. */
1328 current_frame->enable[vpos] = 1;
1329 current_frame->used[vpos] = desired_frame->used[vpos];
1330 current_frame->highlight[vpos] = desired_frame->highlight[vpos];
1331 current_frame->bufp[vpos] = desired_frame->bufp[vpos];
1332
1333 #ifdef HAVE_X_WINDOWS
1334 if (FRAME_X_P (frame))
1335 {
1336 current_frame->pix_width[vpos]
1337 = current_frame->used[vpos]
1338 * FONT_WIDTH (frame->display.x->font);
1339 current_frame->pix_height[vpos]
1340 = FONT_HEIGHT (frame->display.x->font);
1341 }
1342 #endif /* HAVE_X_WINDOWS */
1343
1344 if (!desired_frame->enable[vpos])
1345 {
1346 nlen = 0;
1347 goto just_erase;
1348 }
1349
1350 nbody = desired_frame->glyphs[vpos];
1351 nlen = desired_frame->used[vpos];
1352
1353 /* Pretend trailing spaces are not there at all,
1354 unless for one reason or another we must write all spaces. */
1355 if (! desired_frame->highlight[vpos])
1356 {
1357 if (!must_write_spaces)
1358 /* We know that the previous character byte contains 0. */
1359 while (nbody[nlen - 1] == SPACEGLYPH)
1360 nlen--;
1361 }
1362 else
1363 {
1364 /* For an inverse-video line, give it extra trailing spaces
1365 all the way to the frame edge
1366 so that the reverse video extends all the way across. */
1367
1368 while (nlen < FRAME_WIDTH (frame) - 1)
1369 nbody[nlen++] = SPACEGLYPH;
1370 }
1371
1372 /* If there's no i/d char, quickly do the best we can without it. */
1373 if (!char_ins_del_ok)
1374 {
1375 int i,j;
1376
1377 for (i = 0; i < nlen; i++)
1378 {
1379 if (i >= olen || nbody[i] != obody[i]) /* A non-matching char. */
1380 {
1381 cursor_to (vpos, i);
1382 for (j = 1; (i + j < nlen &&
1383 (i + j >= olen || nbody[i+j] != obody[i+j]));
1384 j++);
1385
1386 /* Output this run of non-matching chars. */
1387 write_glyphs (nbody + i, j);
1388 i += j - 1;
1389
1390 /* Now find the next non-match. */
1391 }
1392 }
1393
1394 /* Clear the rest of the line, or the non-clear part of it. */
1395 if (olen > nlen)
1396 {
1397 cursor_to (vpos, nlen);
1398 clear_end_of_line (olen);
1399 }
1400
1401 /* Exchange contents between current_frame and new_frame. */
1402 temp = desired_frame->glyphs[vpos];
1403 desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
1404 current_frame->glyphs[vpos] = temp;
1405
1406 return;
1407 }
1408
1409 if (!olen)
1410 {
1411 nsp = (must_write_spaces || desired_frame->highlight[vpos])
1412 ? 0 : count_blanks (nbody);
1413 if (nlen > nsp)
1414 {
1415 cursor_to (vpos, nsp);
1416 write_glyphs (nbody + nsp, nlen - nsp);
1417 }
1418
1419 /* Exchange contents between current_frame and new_frame. */
1420 temp = desired_frame->glyphs[vpos];
1421 desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
1422 current_frame->glyphs[vpos] = temp;
1423
1424 return;
1425 }
1426
1427 obody[olen] = 1;
1428 save = nbody[nlen];
1429 nbody[nlen] = 0;
1430
1431 /* Compute number of leading blanks in old and new contents. */
1432 osp = count_blanks (obody);
1433 if (!desired_frame->highlight[vpos])
1434 nsp = count_blanks (nbody);
1435 else
1436 nsp = 0;
1437
1438 /* Compute number of matching chars starting with first nonblank. */
1439 begmatch = count_match (obody + osp, nbody + nsp);
1440
1441 /* Spaces in new match implicit space past the end of old. */
1442 /* A bug causing this to be a no-op was fixed in 18.29. */
1443 if (!must_write_spaces && osp + begmatch == olen)
1444 {
1445 np1 = nbody + nsp;
1446 while (np1[begmatch] == SPACEGLYPH)
1447 begmatch++;
1448 }
1449
1450 /* Avoid doing insert/delete char
1451 just cause number of leading spaces differs
1452 when the following text does not match. */
1453 if (begmatch == 0 && osp != nsp)
1454 osp = nsp = min (osp, nsp);
1455
1456 /* Find matching characters at end of line */
1457 op1 = obody + olen;
1458 np1 = nbody + nlen;
1459 op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
1460 while (op1 > op2 && op1[-1] == np1[-1])
1461 {
1462 op1--;
1463 np1--;
1464 }
1465 endmatch = obody + olen - op1;
1466
1467 /* Put correct value back in nbody[nlen].
1468 This is important because direct_output_for_insert
1469 can write into the line at a later point.
1470 If this screws up the zero at the end of the line, re-establish it. */
1471 nbody[nlen] = save;
1472 obody[olen] = 0;
1473
1474 /* tem gets the distance to insert or delete.
1475 endmatch is how many characters we save by doing so.
1476 Is it worth it? */
1477
1478 tem = (nlen - nsp) - (olen - osp);
1479 if (endmatch && tem
1480 && (!char_ins_del_ok || endmatch <= char_ins_del_cost (frame)[tem]))
1481 endmatch = 0;
1482
1483 /* nsp - osp is the distance to insert or delete.
1484 If that is nonzero, begmatch is known to be nonzero also.
1485 begmatch + endmatch is how much we save by doing the ins/del.
1486 Is it worth it? */
1487
1488 if (nsp != osp
1489 && (!char_ins_del_ok
1490 || begmatch + endmatch <= char_ins_del_cost (frame)[nsp - osp]))
1491 {
1492 begmatch = 0;
1493 endmatch = 0;
1494 osp = nsp = min (osp, nsp);
1495 }
1496
1497 /* Now go through the line, inserting, writing and
1498 deleting as appropriate. */
1499
1500 if (osp > nsp)
1501 {
1502 cursor_to (vpos, nsp);
1503 delete_glyphs (osp - nsp);
1504 }
1505 else if (nsp > osp)
1506 {
1507 /* If going to delete chars later in line
1508 and insert earlier in the line,
1509 must delete first to avoid losing data in the insert */
1510 if (endmatch && nlen < olen + nsp - osp)
1511 {
1512 cursor_to (vpos, nlen - endmatch + osp - nsp);
1513 delete_glyphs (olen + nsp - osp - nlen);
1514 olen = nlen - (nsp - osp);
1515 }
1516 cursor_to (vpos, osp);
1517 insert_glyphs ((char *)0, nsp - osp);
1518 }
1519 olen += nsp - osp;
1520
1521 tem = nsp + begmatch + endmatch;
1522 if (nlen != tem || olen != tem)
1523 {
1524 cursor_to (vpos, nsp + begmatch);
1525 if (!endmatch || nlen == olen)
1526 {
1527 /* If new text being written reaches right margin,
1528 there is no need to do clear-to-eol at the end.
1529 (and it would not be safe, since cursor is not
1530 going to be "at the margin" after the text is done) */
1531 if (nlen == FRAME_WIDTH (frame))
1532 olen = 0;
1533 write_glyphs (nbody + nsp + begmatch, nlen - tem);
1534
1535 #ifdef obsolete
1536
1537 /* the following code loses disastrously if tem == nlen.
1538 Rather than trying to fix that case, I am trying the simpler
1539 solution found above. */
1540
1541 /* If the text reaches to the right margin,
1542 it will lose one way or another (depending on AutoWrap)
1543 to clear to end of line after outputting all the text.
1544 So pause with one character to go and clear the line then. */
1545 if (nlen == FRAME_WIDTH (frame) && fast_clear_end_of_line && olen > nlen)
1546 {
1547 /* endmatch must be zero, and tem must equal nsp + begmatch */
1548 write_glyphs (nbody + tem, nlen - tem - 1);
1549 clear_end_of_line (olen);
1550 olen = 0; /* Don't let it be cleared again later */
1551 write_glyphs (nbody + nlen - 1, 1);
1552 }
1553 else
1554 write_glyphs (nbody + nsp + begmatch, nlen - tem);
1555 #endif /* OBSOLETE */
1556
1557 }
1558 else if (nlen > olen)
1559 {
1560 write_glyphs (nbody + nsp + begmatch, olen - tem);
1561 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
1562 olen = nlen;
1563 }
1564 else if (olen > nlen)
1565 {
1566 write_glyphs (nbody + nsp + begmatch, nlen - tem);
1567 delete_glyphs (olen - nlen);
1568 olen = nlen;
1569 }
1570 }
1571
1572 just_erase:
1573 /* If any unerased characters remain after the new line, erase them. */
1574 if (olen > nlen)
1575 {
1576 cursor_to (vpos, nlen);
1577 clear_end_of_line (olen);
1578 }
1579
1580 /* Exchange contents between current_frame and new_frame. */
1581 temp = desired_frame->glyphs[vpos];
1582 desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
1583 current_frame->glyphs[vpos] = temp;
1584 }
1585 \f
1586 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
1587 1, 1, "FOpen termscript file: ",
1588 "Start writing all terminal output to FILE as well as the terminal.\n\
1589 FILE = nil means just close any termscript file currently open.")
1590 (file)
1591 Lisp_Object file;
1592 {
1593 if (termscript != 0) fclose (termscript);
1594 termscript = 0;
1595
1596 if (! NILP (file))
1597 {
1598 file = Fexpand_file_name (file, Qnil);
1599 termscript = fopen (XSTRING (file)->data, "w");
1600 if (termscript == 0)
1601 report_file_error ("Opening termscript", Fcons (file, Qnil));
1602 }
1603 return Qnil;
1604 }
1605 \f
1606
1607 #ifdef SIGWINCH
1608 SIGTYPE
1609 window_change_signal ()
1610 {
1611 int width, height;
1612 extern int errno;
1613 int old_errno = errno;
1614
1615 get_frame_size (&width, &height);
1616
1617 /* The frame size change obviously applies to a termcap-controlled
1618 frame. Find such a frame in the list, and assume it's the only
1619 one (since the redisplay code always writes to stdout, not a
1620 FILE * specified in the frame structure). Record the new size,
1621 but don't reallocate the data structures now. Let that be done
1622 later outside of the signal handler. */
1623
1624 {
1625 Lisp_Object tail, frame;
1626
1627 FOR_EACH_FRAME (tail, frame)
1628 {
1629 if (FRAME_TERMCAP_P (XFRAME (frame)))
1630 {
1631 change_frame_size (XFRAME (frame), height, width, 0, 1);
1632 break;
1633 }
1634 }
1635 }
1636
1637 signal (SIGWINCH, window_change_signal);
1638 errno = old_errno;
1639 }
1640 #endif /* SIGWINCH */
1641
1642
1643 /* Do any change in frame size that was requested by a signal. */
1644
1645 do_pending_window_change ()
1646 {
1647 /* If window_change_signal should have run before, run it now. */
1648 while (delayed_size_change)
1649 {
1650 Lisp_Object tail, frame;
1651
1652 delayed_size_change = 0;
1653
1654 FOR_EACH_FRAME (tail, frame)
1655 {
1656 FRAME_PTR f = XFRAME (frame);
1657
1658 int height = FRAME_NEW_HEIGHT (f);
1659 int width = FRAME_NEW_WIDTH (f);
1660
1661 if (height != 0 || width != 0)
1662 change_frame_size (f, height, width, 0, 0);
1663 }
1664 }
1665 }
1666
1667
1668 /* Change the frame height and/or width. Values may be given as zero to
1669 indicate no change is to take place.
1670
1671 If DELAY is non-zero, then assume we're being called from a signal
1672 handler, and queue the change for later - perhaps the next
1673 redisplay. Since this tries to resize windows, we can't call it
1674 from a signal handler. */
1675
1676 change_frame_size (frame, newheight, newwidth, pretend, delay)
1677 register FRAME_PTR frame;
1678 int newheight, newwidth, pretend;
1679 {
1680 /* If we can't deal with the change now, queue it for later. */
1681 if (delay)
1682 {
1683 FRAME_NEW_HEIGHT (frame) = newheight;
1684 FRAME_NEW_WIDTH (frame) = newwidth;
1685 delayed_size_change = 1;
1686 return;
1687 }
1688
1689 /* This size-change overrides any pending one for this frame. */
1690 FRAME_NEW_HEIGHT (frame) = 0;
1691 FRAME_NEW_WIDTH (frame) = 0;
1692
1693 /* If an argument is zero, set it to the current value. */
1694 newheight || (newheight = FRAME_HEIGHT (frame));
1695 newwidth || (newwidth = FRAME_WIDTH (frame));
1696
1697 /* Round up to the smallest acceptable size. */
1698 check_frame_size (frame, &newheight, &newwidth);
1699
1700 /* If we're not changing the frame size, quit now. */
1701 if (newheight == FRAME_HEIGHT (frame)
1702 && newwidth == FRAME_WIDTH (frame))
1703 return;
1704
1705 if (newheight != FRAME_HEIGHT (frame))
1706 {
1707 if (FRAME_HAS_MINIBUF_P (frame)
1708 && ! FRAME_MINIBUF_ONLY_P (frame))
1709 {
1710 /* Frame has both root and minibuffer. */
1711 set_window_height (FRAME_ROOT_WINDOW (frame),
1712 newheight - 1 - FRAME_MENU_BAR_LINES (frame), 0);
1713 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame))->top)
1714 = newheight - 1;
1715 set_window_height (FRAME_MINIBUF_WINDOW (frame), 1, 0);
1716 }
1717 else
1718 /* Frame has just one top-level window. */
1719 set_window_height (FRAME_ROOT_WINDOW (frame),
1720 newheight - FRAME_MENU_BAR_LINES (frame), 0);
1721
1722 if (FRAME_TERMCAP_P (frame) && !pretend)
1723 FrameRows = newheight;
1724
1725 #if 0
1726 if (frame->output_method == output_termcap)
1727 {
1728 frame_height = newheight;
1729 if (!pretend)
1730 FrameRows = newheight;
1731 }
1732 #endif
1733 }
1734
1735 if (newwidth != FRAME_WIDTH (frame))
1736 {
1737 set_window_width (FRAME_ROOT_WINDOW (frame), newwidth, 0);
1738 if (FRAME_HAS_MINIBUF_P (frame))
1739 set_window_width (FRAME_MINIBUF_WINDOW (frame), newwidth, 0);
1740
1741 if (FRAME_TERMCAP_P (frame) && !pretend)
1742 FrameCols = newwidth;
1743 #if 0
1744 if (frame->output_method == output_termcap)
1745 {
1746 frame_width = newwidth;
1747 if (!pretend)
1748 FrameCols = newwidth;
1749 }
1750 #endif
1751 }
1752
1753 FRAME_HEIGHT (frame) = newheight;
1754 FRAME_WIDTH (frame) = newwidth;
1755
1756 remake_frame_glyphs (frame);
1757 calculate_costs (frame);
1758 }
1759 \f
1760 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
1761 Ssend_string_to_terminal, 1, 1, 0,
1762 "Send STRING to the terminal without alteration.\n\
1763 Control characters in STRING will have terminal-dependent effects.")
1764 (str)
1765 Lisp_Object str;
1766 {
1767 CHECK_STRING (str, 0);
1768 fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, stdout);
1769 fflush (stdout);
1770 if (termscript)
1771 {
1772 fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, termscript);
1773 fflush (termscript);
1774 }
1775 return Qnil;
1776 }
1777
1778 DEFUN ("ding", Fding, Sding, 0, 1, 0,
1779 "Beep, or flash the screen.\n\
1780 Also, unless an argument is given,\n\
1781 terminate any keyboard macro currently executing.")
1782 (arg)
1783 Lisp_Object arg;
1784 {
1785 if (!NILP (arg))
1786 {
1787 if (noninteractive)
1788 putchar (07);
1789 else
1790 ring_bell ();
1791 fflush (stdout);
1792 }
1793 else
1794 bitch_at_user ();
1795
1796 return Qnil;
1797 }
1798
1799 bitch_at_user ()
1800 {
1801 if (noninteractive)
1802 putchar (07);
1803 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
1804 error ("Keyboard macro terminated by a command ringing the bell");
1805 else
1806 ring_bell ();
1807 fflush (stdout);
1808 }
1809
1810 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
1811 "Pause, without updating display, for SECONDS seconds.\n\
1812 SECONDS may be a floating-point value, meaning that you can wait for a\n\
1813 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
1814 additional wait period, in milliseconds; this may be useful if your\n\
1815 Emacs was built without floating point support.\n\
1816 \(Not all operating systems support waiting for a fraction of a second.)")
1817 (seconds, milliseconds)
1818 Lisp_Object seconds, milliseconds;
1819 {
1820 int sec, usec;
1821
1822 if (NILP (milliseconds))
1823 XSET (milliseconds, Lisp_Int, 0);
1824 else
1825 CHECK_NUMBER (milliseconds, 1);
1826 usec = XINT (milliseconds) * 1000;
1827
1828 #ifdef LISP_FLOAT_TYPE
1829 {
1830 double duration = extract_float (seconds);
1831 sec = (int) duration;
1832 usec += (duration - sec) * 1000000;
1833 }
1834 #else
1835 CHECK_NUMBER (seconds, 0);
1836 sec = XINT (seconds);
1837 #endif
1838
1839 #ifndef EMACS_HAS_USECS
1840 if (sec == 0 && usec != 0)
1841 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
1842 #endif
1843
1844 /* Assure that 0 <= usec < 1000000. */
1845 if (usec < 0)
1846 {
1847 /* We can't rely on the rounding being correct if user is negative. */
1848 if (-1000000 < usec)
1849 sec--, usec += 1000000;
1850 else
1851 sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
1852 }
1853 else
1854 sec += usec / 1000000, usec %= 1000000;
1855
1856 if (sec < 0)
1857 return Qnil;
1858
1859 {
1860 Lisp_Object zero;
1861
1862 XFASTINT (zero) = 0;
1863 wait_reading_process_input (sec, usec, zero, 0);
1864 }
1865
1866 /* We should always have wait_reading_process_input; we have a dummy
1867 implementation for systems which don't support subprocesses. */
1868 #if 0
1869 /* No wait_reading_process_input */
1870 immediate_quit = 1;
1871 QUIT;
1872
1873 #ifdef VMS
1874 sys_sleep (sec);
1875 #else /* not VMS */
1876 /* The reason this is done this way
1877 (rather than defined (H_S) && defined (H_T))
1878 is because the VMS preprocessor doesn't grok `defined' */
1879 #ifdef HAVE_SELECT
1880 EMACS_GET_TIME (end_time);
1881 EMACS_SET_SECS_USECS (timeout, sec, usec);
1882 EMACS_ADD_TIME (end_time, end_time, timeout);
1883
1884 while (1)
1885 {
1886 EMACS_GET_TIME (timeout);
1887 EMACS_SUB_TIME (timeout, end_time, timeout);
1888 if (EMACS_TIME_NEG_P (timeout)
1889 || !select (1, 0, 0, 0, &timeout))
1890 break;
1891 }
1892 #else /* not HAVE_SELECT */
1893 sleep (sec);
1894 #endif /* HAVE_SELECT */
1895 #endif /* not VMS */
1896
1897 immediate_quit = 0;
1898 #endif /* no subprocesses */
1899
1900 return Qnil;
1901 }
1902
1903 /* This is just like wait_reading_process_input, except that
1904 it does the redisplay.
1905
1906 It's also just like Fsit_for, except that it can be used for
1907 waiting for input as well. */
1908
1909 Lisp_Object
1910 sit_for (sec, usec, reading, display)
1911 int sec, usec, reading, display;
1912 {
1913 Lisp_Object read_kbd;
1914
1915 if (detect_input_pending ())
1916 return Qnil;
1917
1918 if (display)
1919 redisplay_preserve_echo_area ();
1920
1921 if (sec == 0 && usec == 0)
1922 return Qt;
1923
1924 #ifdef SIGIO
1925 gobble_input (0);
1926 #endif
1927
1928 XSET (read_kbd, Lisp_Int, reading ? -1 : 1);
1929 wait_reading_process_input (sec, usec, read_kbd, display);
1930
1931
1932 /* wait_reading_process_input should always be available now; it is
1933 simulated in a simple way on systems that don't support
1934 subprocesses. */
1935 #if 0
1936 /* No wait_reading_process_input available. */
1937 immediate_quit = 1;
1938 QUIT;
1939
1940 waitchannels = 1;
1941 #ifdef VMS
1942 input_wait_timeout (XINT (arg));
1943 #else /* not VMS */
1944 #ifndef HAVE_TIMEVAL
1945 timeout_sec = sec;
1946 select (1, &waitchannels, 0, 0, &timeout_sec);
1947 #else /* HAVE_TIMEVAL */
1948 timeout.tv_sec = sec;
1949 timeout.tv_usec = usec;
1950 select (1, &waitchannels, 0, 0, &timeout);
1951 #endif /* HAVE_TIMEVAL */
1952 #endif /* not VMS */
1953
1954 immediate_quit = 0;
1955 #endif
1956
1957 return detect_input_pending () ? Qnil : Qt;
1958 }
1959
1960 DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
1961 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
1962 SECONDS may be a floating-point value, meaning that you can wait for a\n\
1963 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
1964 additional wait period, in milliseconds; this may be useful if your\n\
1965 Emacs was built without floating point support.\n\
1966 \(Not all operating systems support waiting for a fraction of a second.)\n\
1967 Optional third arg non-nil means don't redisplay, just wait for input.\n\
1968 Redisplay is preempted as always if input arrives, and does not happen\n\
1969 if input is available before it starts.\n\
1970 Value is t if waited the full time with no input arriving.")
1971 (seconds, milliseconds, nodisp)
1972 Lisp_Object seconds, milliseconds, nodisp;
1973 {
1974 int sec, usec;
1975
1976 if (NILP (milliseconds))
1977 XSET (milliseconds, Lisp_Int, 0);
1978 else
1979 CHECK_NUMBER (milliseconds, 1);
1980 usec = XINT (milliseconds) * 1000;
1981
1982 #ifdef LISP_FLOAT_TYPE
1983 {
1984 double duration = extract_float (seconds);
1985 sec = (int) duration;
1986 usec += (duration - sec) * 1000000;
1987 }
1988 #else
1989 CHECK_NUMBER (seconds, 0);
1990 sec = XINT (seconds);
1991 #endif
1992
1993 #ifndef EMACS_HAS_USECS
1994 if (usec != 0 && sec == 0)
1995 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE);
1996 #endif
1997
1998 return sit_for (sec, usec, 0, NILP (nodisp));
1999 }
2000 \f
2001 char *terminal_type;
2002
2003 /* Initialization done when Emacs fork is started, before doing stty. */
2004 /* Determine terminal type and set terminal_driver */
2005 /* Then invoke its decoding routine to set up variables
2006 in the terminal package */
2007
2008 init_display ()
2009 {
2010 #ifdef HAVE_X_WINDOWS
2011 extern int display_arg;
2012 #endif
2013
2014 meta_key = 0;
2015 inverse_video = 0;
2016 cursor_in_echo_area = 0;
2017 terminal_type = (char *) 0;
2018
2019 /* Now is the time to initialize this; it's used by init_sys_modes
2020 during startup. */
2021 Vwindow_system = Qnil;
2022
2023 /* If the user wants to use a window system, we shouldn't bother
2024 initializing the terminal. This is especially important when the
2025 terminal is so dumb that emacs gives up before and doesn't bother
2026 using the window system.
2027
2028 If the DISPLAY environment variable is set, try to use X, and die
2029 with an error message if that doesn't work. */
2030
2031 #ifdef HAVE_X_WINDOWS
2032 if (! display_arg)
2033 {
2034 #ifdef VMS
2035 display_arg = (getenv ("DECW$DISPLAY") != 0);
2036 #else
2037 display_arg = (getenv ("DISPLAY") != 0);
2038 #endif
2039 }
2040
2041 if (!inhibit_window_system && display_arg)
2042 {
2043 Vwindow_system = intern ("x");
2044 #ifdef HAVE_X11
2045 Vwindow_system_version = make_number (11);
2046 #else
2047 Vwindow_system_version = make_number (10);
2048 #endif
2049 return;
2050 }
2051 #endif /* HAVE_X_WINDOWS */
2052
2053 /* If no window system has been specified, try to use the terminal. */
2054 if (! isatty (0))
2055 {
2056 fprintf (stderr, "emacs: standard input is not a tty\n");
2057 exit (1);
2058 }
2059
2060 /* Look at the TERM variable */
2061 terminal_type = (char *) getenv ("TERM");
2062 if (!terminal_type)
2063 {
2064 #ifdef VMS
2065 fprintf (stderr, "Please specify your terminal type.\n\
2066 For types defined in VMS, use set term /device=TYPE.\n\
2067 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2068 \(The quotation marks are necessary since terminal types are lower case.)\n");
2069 #else
2070 fprintf (stderr, "Please set the environment variable TERM; see tset(1).\n");
2071 #endif
2072 exit (1);
2073 }
2074
2075 #ifdef VMS
2076 /* VMS DCL tends to upcase things, so downcase term type.
2077 Hardly any uppercase letters in terminal types; should be none. */
2078 {
2079 char *new = (char *) xmalloc (strlen (terminal_type) + 1);
2080 char *p;
2081
2082 strcpy (new, terminal_type);
2083
2084 for (p = new; *p; p++)
2085 if (isupper (*p))
2086 *p = tolower (*p);
2087
2088 terminal_type = new;
2089 }
2090 #endif
2091
2092 term_init (terminal_type);
2093
2094 remake_frame_glyphs (selected_frame);
2095 calculate_costs (selected_frame);
2096
2097 /* X and Y coordinates of the cursor between updates. */
2098 FRAME_CURSOR_X (selected_frame) = 0;
2099 FRAME_CURSOR_Y (selected_frame) = 0;
2100
2101 #ifdef SIGWINCH
2102 #ifndef CANNOT_DUMP
2103 if (initialized)
2104 #endif /* CANNOT_DUMP */
2105 signal (SIGWINCH, window_change_signal);
2106 #endif /* SIGWINCH */
2107 }
2108 \f
2109 syms_of_display ()
2110 {
2111 #ifdef MULTI_FRAME
2112 defsubr (&Sredraw_frame);
2113 #endif
2114 defsubr (&Sredraw_display);
2115 defsubr (&Sopen_termscript);
2116 defsubr (&Sding);
2117 defsubr (&Ssit_for);
2118 defsubr (&Ssleep_for);
2119 defsubr (&Ssend_string_to_terminal);
2120
2121 DEFVAR_INT ("baud-rate", &baud_rate,
2122 "The output baud rate of the terminal.\n\
2123 On most systems, changing this value will affect the amount of padding\n\
2124 and the other strategic decisions made during redisplay.");
2125 DEFVAR_BOOL ("inverse-video", &inverse_video,
2126 "*Non-nil means invert the entire frame display.\n\
2127 This means everything is in inverse video which otherwise would not be.");
2128 DEFVAR_BOOL ("visible-bell", &visible_bell,
2129 "*Non-nil means try to flash the frame to represent a bell.");
2130 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
2131 "*Non-nil means no need to redraw entire frame after suspending.\n\
2132 A non-nil value is useful if the terminal can automatically preserve\n\
2133 Emacs's frame display when you reenter Emacs.\n\
2134 It is up to you to set this variable if your terminal can do that.");
2135 DEFVAR_LISP ("window-system", &Vwindow_system,
2136 "A symbol naming the window-system under which Emacs is running\n\
2137 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2138 DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
2139 "The version number of the window system in use.\n\
2140 For X windows, this is 10 or 11.");
2141 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
2142 "Non-nil means put cursor in minibuffer, at end of any message there.");
2143 DEFVAR_LISP ("glyph-table", &Vglyph_table,
2144 "Table defining how to output a glyph code to the frame.\n\
2145 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2146 Each element can be:\n\
2147 integer: a glyph code which this glyph is an alias for.\n\
2148 string: output this glyph using that string (not impl. in X windows).\n\
2149 nil: this glyph mod 256 is char code to output,\n\
2150 and this glyph / 256 is face code for X windows (see `x-set-face').");
2151 Vglyph_table = Qnil;
2152
2153 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
2154 "Display table to use for buffers that specify none.\n\
2155 See `buffer-display-table' for more information.");
2156 Vstandard_display_table = Qnil;
2157
2158 /* Initialize `window-system', unless init_display already decided it. */
2159 #ifdef CANNOT_DUMP
2160 if (noninteractive)
2161 #endif
2162 {
2163 Vwindow_system = Qnil;
2164 Vwindow_system_version = Qnil;
2165 }
2166 }
2167