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