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