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