comparison src/dispnew.c @ 314:36a905212ceb

Initial revision
author Jim Blandy <jimb@redhat.com>
date Wed, 03 Jul 1991 12:10:07 +0000
parents
children cd7ffb1fcb45
comparison
equal deleted inserted replaced
313:ac18f34e3e33 314:36a905212ceb
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
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
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
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
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
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 the overlap is always less than SIZE, we can always
538 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, 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
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
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
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
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
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
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
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 i;
1252
1253 /* Only works for the leftmost window on a line. bufp is useless
1254 for the others. */
1255 if (window_left == 0)
1256 {
1257 for (i = line; i > XFASTINT (window->top); i--)
1258 if (FETCH_CHAR (bufp[i]-1) == '\n')
1259 break;
1260 }
1261
1262 posn
1263 = compute_motion (bufp[i], i, window_left,
1264 ZV, col, line,
1265 window_width, XINT (window->hscroll), 0)
1266 ->bufpos;
1267 }
1268
1269 current_buffer = old_current_buffer;
1270
1271 return posn;
1272 }
1273
1274 static int
1275 count_blanks (r)
1276 register GLYPH *r;
1277 {
1278 register GLYPH *p = r;
1279 while (*r++ == SPACEGLYPH);
1280 return r - p - 1;
1281 }
1282
1283 static int
1284 count_match (str1, str2)
1285 GLYPH *str1, *str2;
1286 {
1287 register GLYPH *p1 = str1;
1288 register GLYPH *p2 = str2;
1289 while (*p1++ == *p2++);
1290 return p1 - str1 - 1;
1291 }
1292
1293 /* Char insertion/deletion cost vector, from term.c */
1294 extern int *char_ins_del_vector;
1295
1296 #define char_ins_del_cost(s) (&char_ins_del_vector[SCREEN_HEIGHT((s))])
1297
1298 static void
1299 update_line (screen, vpos)
1300 register SCREEN_PTR screen;
1301 int vpos;
1302 {
1303 register GLYPH *obody, *nbody, *op1, *op2, *np1, *temp;
1304 int tem;
1305 int osp, nsp, begmatch, endmatch, olen, nlen;
1306 int save;
1307 register struct screen_glyphs *current_screen
1308 = SCREEN_CURRENT_GLYPHS (screen);
1309 register struct screen_glyphs *desired_screen
1310 = SCREEN_DESIRED_GLYPHS (screen);
1311
1312 if (desired_screen->highlight[vpos]
1313 != (current_screen->enable[vpos] && current_screen->highlight[vpos]))
1314 {
1315 change_line_highlight (desired_screen->highlight[vpos], vpos,
1316 (current_screen->enable[vpos] ?
1317 current_screen->used[vpos] : 0));
1318 current_screen->enable[vpos] = 0;
1319 }
1320 else
1321 reassert_line_highlight (desired_screen->highlight[vpos], vpos);
1322
1323 if (! current_screen->enable[vpos])
1324 {
1325 olen = 0;
1326 }
1327 else
1328 {
1329 obody = current_screen->glyphs[vpos];
1330 olen = current_screen->used[vpos];
1331 if (! current_screen->highlight[vpos])
1332 {
1333 if (!must_write_spaces)
1334 while (obody[olen - 1] == SPACEGLYPH && olen > 0)
1335 olen--;
1336 }
1337 else
1338 {
1339 /* For an inverse-video line, remember we gave it
1340 spaces all the way to the screen edge
1341 so that the reverse video extends all the way across. */
1342
1343 while (olen < SCREEN_WIDTH (screen) - 1)
1344 obody[olen++] = SPACEGLYPH;
1345 }
1346 }
1347
1348 /* One way or another, this will enable the line being updated. */
1349 current_screen->enable[vpos] = 1;
1350 current_screen->used[vpos] = desired_screen->used[vpos];
1351 current_screen->highlight[vpos] = desired_screen->highlight[vpos];
1352 current_screen->bufp[vpos] = desired_screen->bufp[vpos];
1353
1354 #ifdef HAVE_X_WINDOWS
1355 if (SCREEN_IS_X (screen))
1356 {
1357 current_screen->pix_width[vpos]
1358 = current_screen->used[vpos]
1359 * FONT_WIDTH (screen->display.x->font);
1360 current_screen->pix_height[vpos]
1361 = FONT_HEIGHT (screen->display.x->font);
1362 }
1363 #endif /* HAVE_X_WINDOWS */
1364
1365 if (!desired_screen->enable[vpos])
1366 {
1367 nlen = 0;
1368 goto just_erase;
1369 }
1370
1371 nbody = desired_screen->glyphs[vpos];
1372 nlen = desired_screen->used[vpos];
1373
1374 /* Pretend trailing spaces are not there at all,
1375 unless for one reason or another we must write all spaces. */
1376 if (! desired_screen->highlight[vpos])
1377 {
1378 if (!must_write_spaces)
1379 /* We know that the previous character byte contains 0. */
1380 while (nbody[nlen - 1] == SPACEGLYPH)
1381 nlen--;
1382 }
1383 else
1384 {
1385 /* For an inverse-video line, give it extra trailing spaces
1386 all the way to the screen edge
1387 so that the reverse video extends all the way across. */
1388
1389 while (nlen < SCREEN_WIDTH (screen) - 1)
1390 nbody[nlen++] = SPACEGLYPH;
1391 }
1392
1393 /* If there's no i/d char, quickly do the best we can without it. */
1394 if (!char_ins_del_ok)
1395 {
1396 int i,j;
1397
1398 for (i = 0; i < nlen; i++)
1399 {
1400 if (i >= olen || nbody[i] != obody[i]) /* A non-matching char. */
1401 {
1402 cursor_to (vpos, i);
1403 for (j = 1; (i + j < nlen &&
1404 (i + j >= olen || nbody[i+j] != obody[i+j]));
1405 j++);
1406
1407 /* Output this run of non-matching chars. */
1408 write_glyphs (nbody + i, j);
1409 i += j - 1;
1410
1411 /* Now find the next non-match. */
1412 }
1413 }
1414
1415 /* Clear the rest of the line, or the non-clear part of it. */
1416 if (olen > nlen)
1417 {
1418 cursor_to (vpos, nlen);
1419 clear_end_of_line (olen);
1420 }
1421
1422 /* Exchange contents between current_screen and new_screen. */
1423 temp = desired_screen->glyphs[vpos];
1424 desired_screen->glyphs[vpos] = current_screen->glyphs[vpos];
1425 current_screen->glyphs[vpos] = temp;
1426
1427 return;
1428 }
1429
1430 if (!olen)
1431 {
1432 nsp = (must_write_spaces || desired_screen->highlight[vpos])
1433 ? 0 : count_blanks (nbody);
1434 if (nlen > nsp)
1435 {
1436 cursor_to (vpos, nsp);
1437 write_glyphs (nbody + nsp, nlen - nsp);
1438 }
1439
1440 /* Exchange contents between current_screen and new_screen. */
1441 temp = desired_screen->glyphs[vpos];
1442 desired_screen->glyphs[vpos] = current_screen->glyphs[vpos];
1443 current_screen->glyphs[vpos] = temp;
1444
1445 return;
1446 }
1447
1448 obody[olen] = 1;
1449 save = nbody[nlen];
1450 nbody[nlen] = 0;
1451
1452 /* Compute number of leading blanks in old and new contents. */
1453 osp = count_blanks (obody);
1454 if (!desired_screen->highlight[vpos])
1455 nsp = count_blanks (nbody);
1456 else
1457 nsp = 0;
1458
1459 /* Compute number of matching chars starting with first nonblank. */
1460 begmatch = count_match (obody + osp, nbody + nsp);
1461
1462 /* Spaces in new match implicit space past the end of old. */
1463 /* A bug causing this to be a no-op was fixed in 18.29. */
1464 if (!must_write_spaces && osp + begmatch == olen)
1465 {
1466 np1 = nbody + nsp;
1467 while (np1[begmatch] == SPACEGLYPH)
1468 begmatch++;
1469 }
1470
1471 /* Avoid doing insert/delete char
1472 just cause number of leading spaces differs
1473 when the following text does not match. */
1474 if (begmatch == 0 && osp != nsp)
1475 osp = nsp = min (osp, nsp);
1476
1477 /* Find matching characters at end of line */
1478 op1 = obody + olen;
1479 np1 = nbody + nlen;
1480 op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
1481 while (op1 > op2 && op1[-1] == np1[-1])
1482 {
1483 op1--;
1484 np1--;
1485 }
1486 endmatch = obody + olen - op1;
1487
1488 /* Put correct value back in nbody[nlen].
1489 This is important because direct_output_for_insert
1490 can write into the line at a later point.
1491 If this screws up the zero at the end of the line, re-establish it. */
1492 nbody[nlen] = save;
1493 obody[olen] = 0;
1494
1495 /* tem gets the distance to insert or delete.
1496 endmatch is how many characters we save by doing so.
1497 Is it worth it? */
1498
1499 tem = (nlen - nsp) - (olen - osp);
1500 if (endmatch && tem
1501 && (!char_ins_del_ok || endmatch <= char_ins_del_cost (screen)[tem]))
1502 endmatch = 0;
1503
1504 /* nsp - osp is the distance to insert or delete.
1505 If that is nonzero, begmatch is known to be nonzero also.
1506 begmatch + endmatch is how much we save by doing the ins/del.
1507 Is it worth it? */
1508
1509 if (nsp != osp
1510 && (!char_ins_del_ok
1511 || begmatch + endmatch <= char_ins_del_cost (screen)[nsp - osp]))
1512 {
1513 begmatch = 0;
1514 endmatch = 0;
1515 osp = nsp = min (osp, nsp);
1516 }
1517
1518 /* Now go through the line, inserting, writing and
1519 deleting as appropriate. */
1520
1521 if (osp > nsp)
1522 {
1523 cursor_to (vpos, nsp);
1524 delete_glyphs (osp - nsp);
1525 }
1526 else if (nsp > osp)
1527 {
1528 /* If going to delete chars later in line
1529 and insert earlier in the line,
1530 must delete first to avoid losing data in the insert */
1531 if (endmatch && nlen < olen + nsp - osp)
1532 {
1533 cursor_to (vpos, nlen - endmatch + osp - nsp);
1534 delete_glyphs (olen + nsp - osp - nlen);
1535 olen = nlen - (nsp - osp);
1536 }
1537 cursor_to (vpos, osp);
1538 insert_glyphs ((char *)0, nsp - osp);
1539 }
1540 olen += nsp - osp;
1541
1542 tem = nsp + begmatch + endmatch;
1543 if (nlen != tem || olen != tem)
1544 {
1545 cursor_to (vpos, nsp + begmatch);
1546 if (!endmatch || nlen == olen)
1547 {
1548 /* If new text being written reaches right margin,
1549 there is no need to do clear-to-eol at the end.
1550 (and it would not be safe, since cursor is not
1551 going to be "at the margin" after the text is done) */
1552 if (nlen == SCREEN_WIDTH (screen))
1553 olen = 0;
1554 write_glyphs (nbody + nsp + begmatch, nlen - tem);
1555
1556 #ifdef obsolete
1557
1558 /* the following code loses disastrously if tem == nlen.
1559 Rather than trying to fix that case, I am trying the simpler
1560 solution found above. */
1561
1562 /* If the text reaches to the right margin,
1563 it will lose one way or another (depending on AutoWrap)
1564 to clear to end of line after outputting all the text.
1565 So pause with one character to go and clear the line then. */
1566 if (nlen == SCREEN_WIDTH (screen) && fast_clear_end_of_line && olen > nlen)
1567 {
1568 /* endmatch must be zero, and tem must equal nsp + begmatch */
1569 write_glyphs (nbody + tem, nlen - tem - 1);
1570 clear_end_of_line (olen);
1571 olen = 0; /* Don't let it be cleared again later */
1572 write_glyphs (nbody + nlen - 1, 1);
1573 }
1574 else
1575 write_glyphs (nbody + nsp + begmatch, nlen - tem);
1576 #endif /* OBSOLETE */
1577
1578 }
1579 else if (nlen > olen)
1580 {
1581 write_glyphs (nbody + nsp + begmatch, olen - tem);
1582 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
1583 olen = nlen;
1584 }
1585 else if (olen > nlen)
1586 {
1587 write_glyphs (nbody + nsp + begmatch, nlen - tem);
1588 delete_glyphs (olen - nlen);
1589 olen = nlen;
1590 }
1591 }
1592
1593 just_erase:
1594 /* If any unerased characters remain after the new line, erase them. */
1595 if (olen > nlen)
1596 {
1597 cursor_to (vpos, nlen);
1598 clear_end_of_line (olen);
1599 }
1600
1601 /* Exchange contents between current_screen and new_screen. */
1602 temp = desired_screen->glyphs[vpos];
1603 desired_screen->glyphs[vpos] = current_screen->glyphs[vpos];
1604 current_screen->glyphs[vpos] = temp;
1605 }
1606
1607 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
1608 1, 1, "FOpen termscript file: ",
1609 "Start writing all terminal output to FILE as well as the terminal.\n\
1610 FILE = nil means just close any termscript file currently open.")
1611 (file)
1612 Lisp_Object file;
1613 {
1614 if (termscript != 0) fclose (termscript);
1615 termscript = 0;
1616
1617 if (! NULL (file))
1618 {
1619 file = Fexpand_file_name (file, Qnil);
1620 termscript = fopen (XSTRING (file)->data, "w");
1621 if (termscript == 0)
1622 report_file_error ("Opening termscript", Fcons (file, Qnil));
1623 }
1624 return Qnil;
1625 }
1626
1627
1628 #ifdef SIGWINCH
1629 window_change_signal ()
1630 {
1631 int width, height;
1632 extern int errno;
1633 int old_errno = errno;
1634
1635 get_screen_size (&width, &height);
1636
1637 /* The screen size change obviously applies to a termcap-controlled
1638 screen. Find such a screen in the list, and assume it's the only
1639 one (since the redisplay code always writes to stdout, not a
1640 FILE * specified in the screen structure). Record the new size,
1641 but don't reallocate the data structures now. Let that be done
1642 later outside of the signal handler. */
1643
1644 {
1645 Lisp_Object tail;
1646
1647 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
1648 {
1649 SCREEN_PTR s = XSCREEN (XCONS (tail)->car);
1650
1651 if (s->output_method == output_termcap)
1652 {
1653 ++in_display;
1654 change_screen_size (s, height, width, 0);
1655 --in_display;
1656 break;
1657 }
1658 }
1659 }
1660
1661 signal (SIGWINCH, window_change_signal);
1662 errno = old_errno;
1663 }
1664 #endif /* SIGWINCH */
1665
1666
1667 /* Do any change in screen size that was requested by a signal. */
1668
1669 do_pending_window_change ()
1670 {
1671 /* If window_change_signal should have run before, run it now. */
1672 while (delayed_size_change)
1673 {
1674 Lisp_Object tail;
1675
1676 delayed_size_change = 0;
1677
1678 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
1679 {
1680 SCREEN_PTR s = XSCREEN (XCONS (tail)->car);
1681 int height = SCREEN_NEW_HEIGHT (s);
1682 int width = SCREEN_NEW_WIDTH (s);
1683
1684 SCREEN_NEW_HEIGHT (s) = 0;
1685 SCREEN_NEW_WIDTH (s) = 0;
1686
1687 if (height != 0)
1688 change_screen_size (s, height, width, 0);
1689 }
1690 }
1691 }
1692
1693
1694 /* Change the screen height and/or width. Values may be given as zero to
1695 indicate no change is to take place. */
1696
1697 change_screen_size (screen, newlength, newwidth, pretend)
1698 register SCREEN_PTR screen;
1699 register int newlength, newwidth, pretend;
1700 {
1701 /* If we can't deal with the change now, queue it for later. */
1702 if (in_display)
1703 {
1704 SCREEN_NEW_HEIGHT (screen) = newlength;
1705 SCREEN_NEW_WIDTH (screen) = newwidth;
1706 delayed_size_change = 1;
1707 return;
1708 }
1709
1710 /* This size-change overrides any pending one for this screen. */
1711 SCREEN_NEW_HEIGHT (screen) = 0;
1712 SCREEN_NEW_WIDTH (screen) = 0;
1713
1714 if ((newlength == 0 || newlength == SCREEN_HEIGHT (screen))
1715 && (newwidth == 0 || newwidth == SCREEN_WIDTH (screen)))
1716 return;
1717
1718 if (newlength && newlength != SCREEN_HEIGHT (screen))
1719 {
1720 if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))))
1721 == screen
1722 && ! EQ (SCREEN_MINIBUF_WINDOW (screen),
1723 SCREEN_ROOT_WINDOW (screen)))
1724 {
1725 /* Screen has both root and minibuffer. */
1726 set_window_height (SCREEN_ROOT_WINDOW (screen),
1727 newlength - 1, 0);
1728 XFASTINT (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))->top)
1729 = newlength - 1;
1730 set_window_height (SCREEN_MINIBUF_WINDOW (screen), 1, 0);
1731 }
1732 else
1733 /* Screen has just one top-level window. */
1734 set_window_height (SCREEN_ROOT_WINDOW (screen), newlength, 0);
1735
1736 if (SCREEN_IS_TERMCAP (screen) == output_termcap && !pretend)
1737 ScreenRows = newlength;
1738
1739 #if 0
1740 if (screen->output_method == output_termcap)
1741 {
1742 screen_height = newlength;
1743 if (!pretend)
1744 ScreenRows = newlength;
1745 }
1746 #endif
1747 }
1748
1749 if (newwidth && newwidth != SCREEN_WIDTH (screen))
1750 {
1751 set_window_width (SCREEN_ROOT_WINDOW (screen), newwidth, 0);
1752 if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))))
1753 == screen)
1754 set_window_width (SCREEN_MINIBUF_WINDOW (screen), newwidth, 0);
1755 SCREEN_WIDTH (screen) = newwidth;
1756
1757 if (SCREEN_IS_TERMCAP (screen) && !pretend)
1758 ScreenCols = newwidth;
1759 #if 0
1760 if (screen->output_method == output_termcap)
1761 {
1762 screen_width = newwidth;
1763 if (!pretend)
1764 ScreenCols = newwidth;
1765 }
1766 #endif
1767 }
1768
1769 if (newlength)
1770 SCREEN_HEIGHT (screen) = newlength;
1771
1772 remake_screen_glyphs (screen);
1773 calculate_costs (screen);
1774 }
1775
1776 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
1777 Ssend_string_to_terminal, 1, 1, 0,
1778 "Send STRING to the terminal without alteration.\n\
1779 Control characters in STRING will have terminal-dependent effects.")
1780 (str)
1781 Lisp_Object str;
1782 {
1783 CHECK_STRING (str, 0);
1784 fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, stdout);
1785 fflush (stdout);
1786 if (termscript)
1787 {
1788 fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, termscript);
1789 fflush (termscript);
1790 }
1791 return Qnil;
1792 }
1793
1794 DEFUN ("ding", Fding, Sding, 0, 1, 0,
1795 "Beep, or flash the screen.\n\
1796 Also, unless an argument is given,\n\
1797 terminate any keyboard macro currently executing.")
1798 (arg)
1799 Lisp_Object arg;
1800 {
1801 if (!NULL (arg))
1802 {
1803 ring_bell ();
1804 fflush (stdout);
1805 }
1806 else
1807 bitch_at_user ();
1808
1809 return Qnil;
1810 }
1811
1812 bitch_at_user ()
1813 {
1814 if (noninteractive)
1815 putchar (07);
1816 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
1817 error ("Keyboard macro terminated by a command ringing the bell");
1818 else
1819 ring_bell ();
1820 fflush (stdout);
1821 }
1822
1823 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
1824 "Pause, without updating display, for ARG seconds.\n\
1825 Optional second arg non-nil means ARG is measured in milliseconds.\n\
1826 \(Not all operating systems support milliseconds.)")
1827 (n, millisec)
1828 Lisp_Object n, millisec;
1829 {
1830 #ifndef subprocesses
1831 #ifdef HAVE_TIMEVAL
1832 struct timeval timeout, end_time, garbage1;
1833 #endif /* HAVE_TIMEVAL */
1834 #endif /* no subprocesses */
1835 int usec = 0;
1836 int sec;
1837
1838 CHECK_NUMBER (n, 0);
1839 sec = XINT (n);
1840 if (sec <= 0)
1841 return Qnil;
1842
1843 if (!NULL (millisec))
1844 {
1845 #ifndef HAVE_TIMEVAL
1846 error ("millisecond sit-for not supported on %s", SYSTEM_TYPE);
1847 #else
1848 usec = sec % 1000 * 1000;
1849 sec /= 1000;
1850 #endif
1851 }
1852
1853 #ifdef subprocesses
1854 wait_reading_process_input (sec, usec, 0, 0);
1855 #else /* No subprocesses */
1856 immediate_quit = 1;
1857 QUIT;
1858
1859 #ifdef VMS
1860 sys_sleep (sec);
1861 #else /* not VMS */
1862 /* The reason this is done this way
1863 (rather than defined (H_S) && defined (H_T))
1864 is because the VMS preprocessor doesn't grok `defined' */
1865 #ifdef HAVE_SELECT
1866 #ifdef HAVE_TIMEVAL
1867 gettimeofday (&end_time, &garbage1);
1868 end_time.tv_sec += sec;
1869 end_time.tv_usec += usec;
1870 if (end_time.tv_usec >= 1000000)
1871 end_time.tv_sec++, end_time.tv_usec -= 1000000;
1872
1873 while (1)
1874 {
1875 gettimeofday (&timeout, &garbage1);
1876 timeout.tv_sec = end_time.tv_sec - timeout.tv_sec;
1877 timeout.tv_usec = end_time.tv_usec - timeout.tv_usec;
1878 if (timeout.tv_usec < 0)
1879 timeout.tv_usec += 1000000, timeout.tv_sec--;
1880 if (timeout.tv_sec < 0)
1881 break;
1882 if (!select (1, 0, 0, 0, &timeout))
1883 break;
1884 }
1885 #else /* not HAVE_TIMEVAL */
1886 /* Is it safe to quit out of `sleep'? I'm afraid to trust it. */
1887 sleep (sec);
1888 #endif /* HAVE_TIMEVAL */
1889 #else /* not HAVE_SELECT */
1890 sleep (sec);
1891 #endif /* HAVE_SELECT */
1892 #endif /* not VMS */
1893
1894 immediate_quit = 0;
1895 #endif /* no subprocesses */
1896
1897 return Qnil;
1898 }
1899
1900 DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
1901 "Perform redisplay, then wait for ARG seconds or until input is available.\n\
1902 Optional second arg non-nil means ARG counts in milliseconds.\n\
1903 Optional third arg non-nil means don't redisplay, just wait for input.\n\
1904 Redisplay is preempted as always if input arrives, and does not happen\n\
1905 if input is available before it starts.\n\
1906 Value is t if waited the full time with no input arriving.")
1907 (n, millisec, nodisp)
1908 Lisp_Object n, millisec, nodisp;
1909 {
1910 #ifndef subprocesses
1911 #ifdef HAVE_TIMEVAL
1912 struct timeval timeout;
1913 #else
1914 int timeout_sec;
1915 #endif
1916 int waitchannels;
1917 #endif /* no subprocesses */
1918 int usec = 0;
1919 int sec;
1920
1921 CHECK_NUMBER (n, 0);
1922
1923 if (detect_input_pending ())
1924 return Qnil;
1925
1926 if (EQ (nodisp, Qnil))
1927 redisplay_preserve_echo_area ();
1928
1929 sec = XINT (n);
1930 if (sec <= 0)
1931 return Qt;
1932
1933 if (!NULL (millisec))
1934 {
1935 #ifndef HAVE_TIMEVAL
1936 error ("millisecond sleep-for not supported on %s", SYSTEM_TYPE);
1937 #else
1938 usec = sec % 1000 * 1000;
1939 sec /= 1000;
1940 #endif
1941 }
1942
1943 #ifdef subprocesses
1944 #ifdef SIGIO
1945 gobble_input ();
1946 #endif /* SIGIO */
1947 wait_reading_process_input (sec, usec, 1, 1);
1948 #else /* no subprocesses */
1949 immediate_quit = 1;
1950 QUIT;
1951
1952 waitchannels = 1;
1953 #ifdef VMS
1954 input_wait_timeout (XINT (n));
1955 #else /* not VMS */
1956 #ifndef HAVE_TIMEVAL
1957 timeout_sec = sec;
1958 select (1, &waitchannels, 0, 0, &timeout_sec);
1959 #else /* HAVE_TIMEVAL */
1960 timeout.tv_sec = sec;
1961 timeout.tv_usec = usec;
1962 select (1, &waitchannels, 0, 0, &timeout);
1963 #endif /* HAVE_TIMEVAL */
1964 #endif /* not VMS */
1965
1966 immediate_quit = 0;
1967 #endif /* no subprocesses */
1968
1969 return detect_input_pending () ? Qnil : Qt;
1970 }
1971
1972 DEFUN ("sleep-for-millisecs", Fsleep_for_millisecs, Ssleep_for_millisecs,
1973 1, 1, 0,
1974 "Pause, without updating display, for ARG milliseconds.")
1975 (n)
1976 Lisp_Object n;
1977 {
1978 #ifndef HAVE_TIMEVAL
1979 error ("sleep-for-millisecs not supported on %s", SYSTEM_TYPE);
1980 #else
1981 CHECK_NUMBER (n, 0);
1982 wait_reading_process_input (XINT (n) / 1000, XINT (n) % 1000 * 1000,
1983 0, 0);
1984 return Qnil;
1985 #endif /* HAVE_TIMEVAL */
1986 }
1987
1988 char *terminal_type;
1989
1990 /* Initialization done when Emacs fork is started, before doing stty. */
1991 /* Determine terminal type and set terminal_driver */
1992 /* Then invoke its decoding routine to set up variables
1993 in the terminal package */
1994
1995 init_display ()
1996 {
1997 #ifdef HAVE_X_WINDOWS
1998 extern int display_arg;
1999 #endif
2000
2001 meta_key = 0;
2002 inverse_video = 0;
2003 cursor_in_echo_area = 0;
2004 terminal_type = (char *) 0;
2005
2006 /* If the DISPLAY environment variable is set, try to use X, and
2007 die with an error message if that doesn't work. */
2008
2009 /* Check if we're using a window system here before trying to
2010 initialize the terminal. If we check the terminal first,
2011
2012 If someone has indicated that they want
2013 to use a window system, we shouldn't bother initializing the
2014 terminal. This is especially important when the terminal is so
2015 dumb that emacs gives up before and doesn't bother using the window
2016 system. */
2017
2018 #ifdef HAVE_X_WINDOWS
2019 if (!inhibit_window_system && (display_arg || egetenv ("DISPLAY")))
2020 {
2021 Vwindow_system = intern ("x");
2022 #ifdef HAVE_X11
2023 Vwindow_system_version = make_number (11);
2024 #else
2025 Vwindow_system_version = make_number (10);
2026 #endif
2027 return;
2028 }
2029 #endif /* HAVE_X_WINDOWS */
2030
2031 /* If no window system has been specified, try to use the terminal. */
2032 if (! isatty (0))
2033 {
2034 fprintf (stderr, "emacs: standard input is not a tty\n");
2035 exit (1);
2036 }
2037
2038 /* Look at the TERM variable */
2039 terminal_type = (char *) getenv ("TERM");
2040 if (!terminal_type)
2041 {
2042 #ifdef VMS
2043 fprintf (stderr, "Please specify your terminal type.\n\
2044 For types defined in VMS, use set term /device=TYPE.\n\
2045 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2046 \(The quotation marks are necessary since terminal types are lower case.)\n");
2047 #else
2048 fprintf (stderr, "Please set the environment variable TERM; see tset(1).\n");
2049 #endif
2050 exit (1);
2051 }
2052
2053 #ifdef VMS
2054 /* VMS DCL tends to upcase things, so downcase term type.
2055 Hardly any uppercase letters in terminal types; should be none. */
2056 {
2057 char *new = (char *) xmalloc (strlen (terminal_type) + 1);
2058 char *p;
2059
2060 strcpy (new, terminal_type);
2061
2062 for (p = new; *p; p++)
2063 if (isupper (*p))
2064 *p = tolower (*p);
2065
2066 terminal_type = new;
2067 }
2068 #endif
2069
2070 term_init (terminal_type);
2071
2072 remake_screen_glyphs (selected_screen);
2073 calculate_costs (selected_screen);
2074
2075 /* X and Y coordinates of the cursor between updates. */
2076 SCREEN_CURSOR_X (selected_screen) = 0;
2077 SCREEN_CURSOR_Y (selected_screen) = 0;
2078
2079 #ifdef SIGWINCH
2080 #ifndef CANNOT_DUMP
2081 if (initialized)
2082 #endif /* CANNOT_DUMP */
2083 signal (SIGWINCH, window_change_signal);
2084 #endif /* SIGWINCH */
2085 }
2086
2087 syms_of_display ()
2088 {
2089 #ifdef MULTI_SCREEN
2090 defsubr (&Sredraw_screen);
2091 #endif
2092 defsubr (&Sredraw_display);
2093 defsubr (&Sopen_termscript);
2094 defsubr (&Sding);
2095 defsubr (&Ssit_for);
2096 defsubr (&Ssleep_for);
2097 defsubr (&Ssend_string_to_terminal);
2098
2099 DEFVAR_INT ("baud-rate", &baud_rate,
2100 "The output baud rate of the terminal.\n\
2101 On most systems, changing this value will affect the amount of padding\n\
2102 and the other strategic decisions made during redisplay.");
2103 DEFVAR_BOOL ("inverse-video", &inverse_video,
2104 "*Non-nil means invert the entire screen display.\n\
2105 This means everything is in inverse video which otherwise would not be.");
2106 DEFVAR_BOOL ("visible-bell", &visible_bell,
2107 "*Non-nil means try to flash the screen to represent a bell.");
2108 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
2109 "*Non-nil means no need to redraw entire screen after suspending.\n\
2110 A non-nil value is useful if the terminal can automatically preserve\n\
2111 Emacs's screen display when you reenter Emacs.\n\
2112 It is up to you to set this variable if your terminal can do that.");
2113 DEFVAR_LISP ("window-system", &Vwindow_system,
2114 "A symbol naming the window-system under which Emacs is running\n\
2115 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2116 DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
2117 "The version number of the window system in use.\n\
2118 For X windows, this is 10 or 11.");
2119 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
2120 "Non-nil means put cursor in minibuffer, at end of any message there.");
2121 DEFVAR_LISP ("glyph-table", &Vglyph_table,
2122 "Table defining how to output a glyph code to the screen.\n\
2123 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2124 Each element can be:\n\
2125 integer: a glyph code which this glyph is an alias for.\n\
2126 string: output this glyph using that string (not impl. in X windows).\n\
2127 nil: this glyph mod 256 is char code to output,\n\
2128 and this glyph / 256 is face code for X windows (see `x-set-face').");
2129 Vglyph_table = Qnil;
2130
2131 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
2132 "Display table to use for buffers that specify none.\n\
2133 See `buffer-display-table' for more information.");
2134 Vstandard_display_table = Qnil;
2135
2136 /* Initialize `window-system', unless init_display already decided it. */
2137 #ifdef CANNOT_DUMP
2138 if (noninteractive)
2139 #endif
2140 {
2141 Vwindow_system = Qnil;
2142 Vwindow_system_version = Qnil;
2143 }
2144 }
2145