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