1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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)
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.
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. */
30 #include "termhooks.h"
32 #include "dispextern.h"
39 #include "intervals.h"
46 #endif /* HAVE_X_WINDOWS */
48 #define max(a, b) ((a) > (b) ? (a) : (b))
49 #define min(a, b) ((a) < (b) ? (a) : (b))
51 #ifndef PENDING_OUTPUT_COUNT
52 /* Get number of chars of output now in the buffer of a stdio stream.
53 This ought to be built in in stdio, but it isn't.
54 Some s- files override this because their stdio internals differ. */
55 #ifdef __GNU_LIBRARY__
56 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
58 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
62 /* Nonzero upon entry to redisplay means do not assume anything about
63 current contents of actual terminal frame; clear and redraw it. */
67 /* Nonzero means last display completed. Zero means it was preempted. */
69 int display_completed
;
71 /* Lisp variable visible-bell; enables use of screen-flash
72 instead of audible bell. */
76 /* Invert the color of the whole frame, at a low level. */
80 /* Line speed of the terminal. */
84 /* nil or a symbol naming the window system under which emacs is
85 running ('x is the only current possibility). */
87 Lisp_Object Vwindow_system
;
89 /* Version number of X windows: 10, 11 or nil. */
90 Lisp_Object Vwindow_system_version
;
92 /* Vector of glyph definitions. Indexed by glyph number,
93 the contents are a string which is how to output the glyph.
95 If Vglyph_table is nil, a glyph is output by using its low 8 bits
96 as a character code. */
98 Lisp_Object Vglyph_table
;
100 /* Display table to use for vectors that don't specify their own. */
102 Lisp_Object Vstandard_display_table
;
104 /* Nonzero means reading single-character input with prompt
105 so put cursor on minibuffer after the prompt.
106 positive means at end of text in echo area;
107 negative means at beginning of line. */
108 int cursor_in_echo_area
;
110 /* The currently selected frame.
111 In a single-frame version, this variable always remains 0. */
113 FRAME_PTR selected_frame
;
115 /* A frame which is not just a minibuffer, or 0 if there are no such
116 frames. This is usually the most recent such frame that was
117 selected. In a single-frame version, this variable always remains 0. */
118 FRAME_PTR last_nonminibuf_frame
;
120 /* In a single-frame version, the information that would otherwise
121 exist inside frame objects lives in the following structure instead.
123 NOTE: the_only_frame is not checked for garbage collection; don't
124 store collectible objects in any of its fields!
126 You're not/The only frame in town/... */
129 struct frame the_only_frame
;
132 /* This is a vector, made larger whenever it isn't large enough,
133 which is used inside `update_frame' to hold the old contents
134 of the FRAME_PHYS_LINES of the frame being updated. */
135 struct frame_glyphs
**ophys_lines
;
136 /* Length of vector currently allocated. */
137 int ophys_lines_length
;
139 FILE *termscript
; /* Stdio stream being used for copy of all output. */
141 struct cm Wcm
; /* Structure for info on cursor positioning */
143 extern short ospeed
; /* Output speed (from sg_ospeed) */
145 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
149 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
150 "Clear frame FRAME and output again what is supposed to appear on it.")
156 CHECK_LIVE_FRAME (frame
, 0);
159 /* set_terminal_modes (); */
161 clear_frame_records (f
);
164 windows_or_buffers_changed
++;
165 /* Mark all windows as INaccurate,
166 so that every window will have its redisplay done. */
167 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
176 XSET (frame
, Lisp_Frame
, f
);
177 Fredraw_frame (frame
);
182 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
183 "Clear frame FRAME and output again what is supposed to appear on it.")
188 set_terminal_modes ();
192 clear_frame_records (0);
193 windows_or_buffers_changed
++;
194 /* Mark all windows as INaccurate,
195 so that every window will have its redisplay done. */
196 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
202 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
203 "Clear and redisplay all visible frames.")
206 Lisp_Object tail
, frame
;
208 FOR_EACH_FRAME (tail
, frame
)
209 if (FRAME_VISIBLE_P (XFRAME (frame
)))
210 Fredraw_frame (frame
);
215 /* This is used when frame_garbaged is set.
216 Redraw the individual frames marked as garbaged. */
219 redraw_garbaged_frames ()
221 Lisp_Object tail
, frame
;
223 FOR_EACH_FRAME (tail
, frame
)
224 if (FRAME_VISIBLE_P (XFRAME (frame
))
225 && FRAME_GARBAGED_P (XFRAME (frame
)))
226 Fredraw_frame (frame
);
230 static struct frame_glyphs
*
231 make_frame_glyphs (frame
, empty
)
232 register FRAME_PTR frame
;
236 register width
= FRAME_WIDTH (frame
);
237 register height
= FRAME_HEIGHT (frame
);
238 register struct frame_glyphs
*new
239 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
241 SET_GLYPHS_FRAME (new, frame
);
242 new->height
= height
;
244 new->used
= (int *) xmalloc (height
* sizeof (int));
245 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
246 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
247 new->highlight
= (char *) xmalloc (height
* sizeof (char));
248 new->enable
= (char *) xmalloc (height
* sizeof (char));
249 bzero (new->enable
, height
* sizeof (char));
250 new->bufp
= (int *) xmalloc (height
* sizeof (int));
252 #ifdef HAVE_X_WINDOWS
253 if (FRAME_X_P (frame
))
255 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
256 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
257 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
258 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
259 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
265 /* Make the buffer used by decode_mode_spec. This buffer is also
266 used as temporary storage when updating the frame. See scroll.c. */
267 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
269 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
270 bzero (new->total_contents
, total_glyphs
);
274 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
276 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
277 bzero (new->total_contents
, total_glyphs
);
278 for (i
= 0; i
< height
; i
++)
279 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
281 if (!FRAME_TERMCAP_P (frame
))
283 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
285 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
286 bzero (new->total_charstarts
, total_charstarts
);
287 for (i
= 0; i
< height
; i
++)
288 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
292 /* Without a window system, we don't really need charstarts.
293 So use a small amount of space to make enough data structure
294 to prevent crashes in display_text_line. */
295 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
296 for (i
= 0; i
< height
; i
++)
297 new->charstarts
[i
] = new->total_charstarts
;
305 free_frame_glyphs (frame
, glyphs
)
307 struct frame_glyphs
*glyphs
;
309 if (glyphs
->total_contents
)
310 xfree (glyphs
->total_contents
);
311 if (glyphs
->total_charstarts
)
312 xfree (glyphs
->total_charstarts
);
314 xfree (glyphs
->used
);
315 xfree (glyphs
->glyphs
);
316 xfree (glyphs
->highlight
);
317 xfree (glyphs
->enable
);
318 xfree (glyphs
->bufp
);
319 if (glyphs
->charstarts
)
320 xfree (glyphs
->charstarts
);
322 #ifdef HAVE_X_WINDOWS
323 if (FRAME_X_P (frame
))
325 xfree (glyphs
->top_left_x
);
326 xfree (glyphs
->top_left_y
);
327 xfree (glyphs
->pix_width
);
328 xfree (glyphs
->pix_height
);
329 xfree (glyphs
->max_ascent
);
337 remake_frame_glyphs (frame
)
340 if (FRAME_CURRENT_GLYPHS (frame
))
341 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
342 if (FRAME_DESIRED_GLYPHS (frame
))
343 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
344 if (FRAME_TEMP_GLYPHS (frame
))
345 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
347 if (FRAME_MESSAGE_BUF (frame
))
349 /* Reallocate the frame's message buffer; remember that
350 echo_area_glyphs may be pointing here. */
351 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
353 FRAME_MESSAGE_BUF (frame
)
354 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
355 FRAME_WIDTH (frame
) + 1);
357 if (echo_area_glyphs
== old_message_buf
)
358 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
359 if (previous_echo_glyphs
== old_message_buf
)
360 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
363 FRAME_MESSAGE_BUF (frame
)
364 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
366 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
367 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
368 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
369 SET_FRAME_GARBAGED (frame
);
372 /* Return the hash code of contents of line VPOS in frame-matrix M. */
375 line_hash_code (m
, vpos
)
376 register struct frame_glyphs
*m
;
379 register GLYPH
*body
, *end
;
382 if (!m
->enable
[vpos
])
385 /* Give all highlighted lines the same hash code
386 so as to encourage scrolling to leave them in place. */
387 if (m
->highlight
[vpos
])
390 body
= m
->glyphs
[vpos
];
392 if (must_write_spaces
)
399 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
408 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
416 /* Return number of characters in line in M at vpos VPOS,
417 except don't count leading and trailing spaces
418 unless the terminal requires those to be explicitly output. */
421 line_draw_cost (m
, vpos
)
422 struct frame_glyphs
*m
;
425 register GLYPH
*beg
= m
->glyphs
[vpos
];
426 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
428 register int tlen
= GLYPH_TABLE_LENGTH
;
429 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
431 /* Ignore trailing and leading spaces if we can. */
432 if (!must_write_spaces
)
434 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
437 return (0); /* All blank line. */
439 while (*beg
== SPACEGLYPH
)
443 /* If we don't have a glyph-table, each glyph is one character,
444 so return the number of glyphs. */
448 /* Otherwise, scan the glyphs and accumulate their total size in I. */
450 while ((beg
<= end
) && *beg
)
452 register GLYPH g
= *beg
++;
454 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
457 i
+= GLYPH_LENGTH (tbase
, g
);
462 /* The functions on this page are the interface from xdisp.c to redisplay.
464 The only other interface into redisplay is through setting
465 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
466 and SET_FRAME_GARBAGED (frame). */
468 /* cancel_line eliminates any request to display a line at position `vpos' */
470 cancel_line (vpos
, frame
)
472 register FRAME_PTR frame
;
474 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
477 clear_frame_records (frame
)
478 register FRAME_PTR frame
;
480 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
483 /* Prepare to display on line VPOS starting at HPOS within it. */
486 get_display_line (frame
, vpos
, hpos
)
487 register FRAME_PTR frame
;
491 register struct frame_glyphs
*glyphs
;
492 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
498 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
501 if (! desired_glyphs
->enable
[vpos
])
503 desired_glyphs
->used
[vpos
] = 0;
504 desired_glyphs
->highlight
[vpos
] = 0;
505 desired_glyphs
->enable
[vpos
] = 1;
508 if (hpos
> desired_glyphs
->used
[vpos
])
510 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
511 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
513 desired_glyphs
->used
[vpos
] = hpos
;
519 /* Like bcopy except never gets confused by overlap. */
522 safe_bcopy (from
, to
, size
)
526 if (size
<= 0 || from
== to
)
529 /* If the source and destination don't overlap, then bcopy can
530 handle it. If they do overlap, but the destination is lower in
531 memory than the source, we'll assume bcopy can handle that. */
532 if (to
< from
|| from
+ size
<= to
)
533 bcopy (from
, to
, size
);
535 /* Otherwise, we'll copy from the end. */
538 register char *endf
= from
+ size
;
539 register char *endt
= to
+ size
;
541 /* If TO - FROM is large, then we should break the copy into
542 nonoverlapping chunks of TO - FROM bytes each. However, if
543 TO - FROM is small, then the bcopy function call overhead
544 makes this not worth it. The crossover point could be about
545 anywhere. Since I don't think the obvious copy loop is too
546 bad, I'm trying to err in its favor. */
551 while (endf
!= from
);
563 bcopy (endf
, endt
, to
- from
);
566 /* If SIZE wasn't a multiple of TO - FROM, there will be a
567 little left over. The amount left over is
568 (endt + (to - from)) - to, which is endt - from. */
569 bcopy (from
, to
, endt
- from
);
574 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
575 DISTANCE may be negative. */
578 rotate_vector (vector
, size
, distance
)
583 char *temp
= (char *) alloca (size
);
588 bcopy (vector
, temp
+ distance
, size
- distance
);
589 bcopy (vector
+ size
- distance
, temp
, distance
);
590 bcopy (temp
, vector
, size
);
593 /* Scroll lines from vpos FROM up to but not including vpos END
594 down by AMOUNT lines (AMOUNT may be negative).
595 Returns nonzero if done, zero if terminal cannot scroll them. */
598 scroll_frame_lines (frame
, from
, end
, amount
, pos_adjust
)
599 register FRAME_PTR frame
;
600 int from
, end
, amount
, pos_adjust
;
603 register struct frame_glyphs
*current_frame
604 = FRAME_CURRENT_GLYPHS (frame
);
606 if (!line_ins_del_ok
)
614 update_begin (frame
);
615 set_terminal_window (end
+ amount
);
616 if (!scroll_region_ok
)
617 ins_del_lines (end
, -amount
);
618 ins_del_lines (from
, amount
);
619 set_terminal_window (0);
621 rotate_vector (current_frame
->glyphs
+ from
,
622 sizeof (GLYPH
*) * (end
+ amount
- from
),
623 amount
* sizeof (GLYPH
*));
625 rotate_vector (current_frame
->charstarts
+ from
,
626 sizeof (GLYPH
*) * (end
+ amount
- from
),
627 amount
* sizeof (GLYPH
*));
629 /* Offset each char position in the charstarts lines we moved
631 for (i
= from
+ amount
; i
< end
; i
++)
633 int *line
= current_frame
->charstarts
[from
];
635 for (col
= 0; col
< current_frame
->used
[from
]; col
++)
636 line
[col
] += pos_adjust
;
638 for (i
= from
; i
<= from
+ amount
; i
++)
640 int *line
= current_frame
->charstarts
[from
];
643 for (col
= 0; col
< current_frame
->used
[from
]; col
++)
647 safe_bcopy (current_frame
->used
+ from
,
648 current_frame
->used
+ from
+ amount
,
649 (end
- from
) * sizeof current_frame
->used
[0]);
651 safe_bcopy (current_frame
->highlight
+ from
,
652 current_frame
->highlight
+ from
+ amount
,
653 (end
- from
) * sizeof current_frame
->highlight
[0]);
655 safe_bcopy (current_frame
->enable
+ from
,
656 current_frame
->enable
+ from
+ amount
,
657 (end
- from
) * sizeof current_frame
->enable
[0]);
659 /* Mark the lines made empty by scrolling as enabled, empty and
661 bzero (current_frame
->used
+ from
,
662 amount
* sizeof current_frame
->used
[0]);
663 bzero (current_frame
->highlight
+ from
,
664 amount
* sizeof current_frame
->highlight
[0]);
665 for (i
= from
; i
< from
+ amount
; i
++)
667 current_frame
->glyphs
[i
][0] = '\0';
668 current_frame
->charstarts
[i
][0] = -1;
669 current_frame
->enable
[i
] = 1;
672 safe_bcopy (current_frame
->bufp
+ from
,
673 current_frame
->bufp
+ from
+ amount
,
674 (end
- from
) * sizeof current_frame
->bufp
[0]);
676 #ifdef HAVE_X_WINDOWS
677 if (FRAME_X_P (frame
))
679 safe_bcopy (current_frame
->top_left_x
+ from
,
680 current_frame
->top_left_x
+ from
+ amount
,
681 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
683 safe_bcopy (current_frame
->top_left_y
+ from
,
684 current_frame
->top_left_y
+ from
+ amount
,
685 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
687 safe_bcopy (current_frame
->pix_width
+ from
,
688 current_frame
->pix_width
+ from
+ amount
,
689 (end
- from
) * sizeof current_frame
->pix_width
[0]);
691 safe_bcopy (current_frame
->pix_height
+ from
,
692 current_frame
->pix_height
+ from
+ amount
,
693 (end
- from
) * sizeof current_frame
->pix_height
[0]);
695 safe_bcopy (current_frame
->max_ascent
+ from
,
696 current_frame
->max_ascent
+ from
+ amount
,
697 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
699 #endif /* HAVE_X_WINDOWS */
705 update_begin (frame
);
706 set_terminal_window (end
);
707 ins_del_lines (from
+ amount
, amount
);
708 if (!scroll_region_ok
)
709 ins_del_lines (end
+ amount
, -amount
);
710 set_terminal_window (0);
712 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
713 sizeof (GLYPH
*) * (end
- from
- amount
),
714 amount
* sizeof (GLYPH
*));
716 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
717 sizeof (GLYPH
*) * (end
- from
- amount
),
718 amount
* sizeof (GLYPH
*));
720 /* Offset each char position in the charstarts lines we moved
722 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
724 int *line
= current_frame
->charstarts
[from
];
726 for (col
= 0; col
< current_frame
->used
[from
]; col
++)
727 line
[col
] += pos_adjust
;
729 for (i
= end
+ amount
; i
<= end
; i
++)
731 int *line
= current_frame
->charstarts
[from
];
734 for (col
= 0; col
< current_frame
->used
[from
]; col
++)
738 safe_bcopy (current_frame
->used
+ from
,
739 current_frame
->used
+ from
+ amount
,
740 (end
- from
) * sizeof current_frame
->used
[0]);
742 safe_bcopy (current_frame
->highlight
+ from
,
743 current_frame
->highlight
+ from
+ amount
,
744 (end
- from
) * sizeof current_frame
->highlight
[0]);
746 safe_bcopy (current_frame
->enable
+ from
,
747 current_frame
->enable
+ from
+ amount
,
748 (end
- from
) * sizeof current_frame
->enable
[0]);
750 /* Mark the lines made empty by scrolling as enabled, empty and
752 bzero (current_frame
->used
+ end
+ amount
,
753 - amount
* sizeof current_frame
->used
[0]);
754 bzero (current_frame
->highlight
+ end
+ amount
,
755 - amount
* sizeof current_frame
->highlight
[0]);
756 for (i
= end
+ amount
; i
< end
; i
++)
758 current_frame
->glyphs
[i
][0] = '\0';
759 current_frame
->charstarts
[i
][0] = 0;
760 current_frame
->enable
[i
] = 1;
763 safe_bcopy (current_frame
->bufp
+ from
,
764 current_frame
->bufp
+ from
+ amount
,
765 (end
- from
) * sizeof current_frame
->bufp
[0]);
767 #ifdef HAVE_X_WINDOWS
768 if (FRAME_X_P (frame
))
770 safe_bcopy (current_frame
->top_left_x
+ from
,
771 current_frame
->top_left_x
+ from
+ amount
,
772 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
774 safe_bcopy (current_frame
->top_left_y
+ from
,
775 current_frame
->top_left_y
+ from
+ amount
,
776 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
778 safe_bcopy (current_frame
->pix_width
+ from
,
779 current_frame
->pix_width
+ from
+ amount
,
780 (end
- from
) * sizeof current_frame
->pix_width
[0]);
782 safe_bcopy (current_frame
->pix_height
+ from
,
783 current_frame
->pix_height
+ from
+ amount
,
784 (end
- from
) * sizeof current_frame
->pix_height
[0]);
786 safe_bcopy (current_frame
->max_ascent
+ from
,
787 current_frame
->max_ascent
+ from
+ amount
,
788 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
790 #endif /* HAVE_X_WINDOWS */
797 /* After updating a window W that isn't the full frame wide,
798 copy all the columns that W does not occupy
799 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
800 so that update_frame will not change those columns. */
802 preserve_other_columns (w
)
806 register struct frame_glyphs
*current_frame
, *desired_frame
;
807 register FRAME_PTR frame
= XFRAME (w
->frame
);
808 int start
= XFASTINT (w
->left
);
809 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
810 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
812 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
813 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
815 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
817 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
823 bcopy (current_frame
->glyphs
[vpos
],
824 desired_frame
->glyphs
[vpos
],
825 start
* sizeof (current_frame
->glyphs
[vpos
]));
826 bcopy (current_frame
->charstarts
[vpos
],
827 desired_frame
->charstarts
[vpos
],
828 start
* sizeof (current_frame
->charstarts
[vpos
]));
829 len
= min (start
, current_frame
->used
[vpos
]);
830 if (desired_frame
->used
[vpos
] < len
)
831 desired_frame
->used
[vpos
] = len
;
833 if (current_frame
->used
[vpos
] > end
834 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
836 while (desired_frame
->used
[vpos
] < end
)
838 int used
= desired_frame
->used
[vpos
]++;
839 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
840 desired_frame
->glyphs
[vpos
][used
] = 0;
842 bcopy (current_frame
->glyphs
[vpos
] + end
,
843 desired_frame
->glyphs
[vpos
] + end
,
844 ((current_frame
->used
[vpos
] - end
)
845 * sizeof (current_frame
->glyphs
[vpos
])));
846 bcopy (current_frame
->charstarts
[vpos
] + end
,
847 desired_frame
->charstarts
[vpos
] + end
,
848 ((current_frame
->used
[vpos
] - end
)
849 * sizeof (current_frame
->charstarts
[vpos
])));
850 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
858 /* If window w does not need to be updated and isn't the full frame wide,
859 copy all the columns that w does occupy
860 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
861 so that update_frame will not change those columns.
863 Have not been able to figure out how to use this correctly. */
865 preserve_my_columns (w
)
868 register int vpos
, fin
;
869 register struct frame_glyphs
*l1
, *l2
;
870 register FRAME_PTR frame
= XFRAME (w
->frame
);
871 int start
= XFASTINT (w
->left
);
872 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
873 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
875 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
877 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
878 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
880 if (l2
->length
> start
&& l1
->length
< l2
->length
)
883 if (fin
> end
) fin
= end
;
884 while (l1
->length
< start
)
885 l1
->body
[l1
->length
++] = ' ';
886 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
895 /* Adjust by ADJUST the charstart values in window W
896 before vpos VPOS, which counts relative to the frame
897 (not relative to W itself). */
900 adjust_window_charstarts (w
, vpos
, adjust
)
905 int left
= XFASTINT (w
->left
);
906 int top
= XFASTINT (w
->top
);
907 int right
= left
+ window_internal_height (w
);
908 int height
= window_internal_height (w
);
911 for (i
= vpos
+ 1; i
< top
+ height
; i
++)
914 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
916 for (j
= left
; j
< right
; j
++)
917 if (charstart
[j
] > 0)
918 charstart
[j
] += adjust
;
922 /* On discovering that the redisplay for a window was no good,
923 cancel the columns of that window, so that when the window is
924 displayed over again get_display_line will not complain. */
926 cancel_my_columns (w
)
930 register struct frame_glyphs
*desired_glyphs
931 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
932 register int start
= XFASTINT (w
->left
);
933 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
935 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
936 if (desired_glyphs
->enable
[vpos
]
937 && desired_glyphs
->used
[vpos
] >= start
)
938 desired_glyphs
->used
[vpos
] = start
;
941 /* These functions try to perform directly and immediately on the frame
942 the necessary output for one change in the buffer.
943 They may return 0 meaning nothing was done if anything is difficult,
944 or 1 meaning the output was performed properly.
945 They assume that the frame was up to date before the buffer
946 change being displayed. They make various other assumptions too;
947 see command_loop_1 where these are called. */
950 direct_output_for_insert (g
)
953 register FRAME_PTR frame
= selected_frame
;
954 register struct frame_glyphs
*current_frame
955 = FRAME_CURRENT_GLYPHS (frame
);
957 #ifndef COMPILER_REGISTER_BUG
959 #endif /* COMPILER_REGISTER_BUG */
960 struct window
*w
= XWINDOW (selected_window
);
961 #ifndef COMPILER_REGISTER_BUG
963 #endif /* COMPILER_REGISTER_BUG */
964 int hpos
= FRAME_CURSOR_X (frame
);
965 #ifndef COMPILER_REGISTER_BUG
967 #endif /* COMPILER_REGISTER_BUG */
968 int vpos
= FRAME_CURSOR_Y (frame
);
970 /* Give up if about to continue line. */
971 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
973 /* Avoid losing if cursor is in invisible text off left margin */
974 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
976 /* Give up if cursor outside window (in minibuf, probably) */
977 || cursor_in_echo_area
978 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
979 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
981 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
982 || !display_completed
984 /* Give up if buffer appears in two places. */
987 #ifdef USE_TEXT_PROPERTIES
988 /* Intervals have already been adjusted, point is after the
989 character that was just inserted. */
990 /* Give up if character is invisible. */
991 /* Give up if character has a face property.
992 At the moment we only lose at end of line or end of buffer
993 and only with faces that have some background */
994 /* Instead of wasting time, give up if character has any text properties */
995 || ! NILP (Ftext_properties_at (XFASTINT (point
- 1), Qnil
))
998 /* Give up if w is minibuffer and a message is being displayed there */
999 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1003 #ifdef HAVE_X_WINDOWS
1005 int face
= compute_char_face (frame
, w
, point
- 1, -1, -1, &dummy
, point
);
1007 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1008 current_frame
->charstarts
[vpos
][hpos
] = point
;
1009 adjust_window_charstarts (w
, vpos
, 1);
1011 unchanged_modified
= MODIFF
;
1012 beg_unchanged
= GPT
- BEG
;
1013 XFASTINT (w
->last_point
) = point
;
1014 XFASTINT (w
->last_point_x
) = hpos
;
1015 XFASTINT (w
->last_modified
) = MODIFF
;
1017 reassert_line_highlight (0, vpos
);
1018 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
1020 ++FRAME_CURSOR_X (frame
);
1021 if (hpos
== current_frame
->used
[vpos
])
1023 current_frame
->used
[vpos
] = hpos
+ 1;
1024 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
1031 direct_output_forward_char (n
)
1034 register FRAME_PTR frame
= selected_frame
;
1035 register struct window
*w
= XWINDOW (selected_window
);
1037 int hpos
= FRAME_CURSOR_X (frame
);
1039 /* Give up if in truncated text at end of line. */
1040 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1)
1043 /* Avoid losing if cursor is in invisible text off left margin
1044 or about to go off either side of window. */
1045 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
1046 && (XINT (w
->hscroll
) || n
< 0))
1048 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
1049 || cursor_in_echo_area
)
1052 /* Can't use direct output if highlighting a region. */
1053 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1056 #ifdef USE_TEXT_PROPERTIES
1057 /* Don't use direct output next to an invisible character
1058 since we might need to do something special. */
1060 XFASTINT (position
) = point
;
1061 if (XFASTINT (position
) < ZV
1062 && ! NILP (Fget_char_property (position
,
1067 XFASTINT (position
) = point
- 1;
1068 if (XFASTINT (position
) >= BEGV
1069 && ! NILP (Fget_char_property (position
,
1075 FRAME_CURSOR_X (frame
) += n
;
1076 XFASTINT (w
->last_point_x
) = FRAME_CURSOR_X (frame
);
1077 XFASTINT (w
->last_point
) = point
;
1078 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1084 static void update_line ();
1086 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1087 Value is nonzero if redisplay stopped due to pending input.
1088 FORCE nonzero means do not stop for pending input. */
1091 update_frame (f
, force
, inhibit_hairy_id
)
1094 int inhibit_hairy_id
;
1096 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (f
);
1097 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1100 int preempt_count
= baud_rate
/ 2400 + 1;
1101 extern input_pending
;
1102 #ifdef HAVE_X_WINDOWS
1103 register int downto
, leftmost
;
1106 if (preempt_count
<= 0)
1109 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1111 detect_input_pending ();
1112 if (input_pending
&& !force
)
1120 if (!line_ins_del_ok
)
1121 inhibit_hairy_id
= 1;
1123 /* See if any of the desired lines are enabled; don't compute for
1124 i/d line if just want cursor motion. */
1125 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1126 if (desired_frame
->enable
[i
])
1129 /* Try doing i/d line, if not yet inhibited. */
1130 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1131 force
|= scrolling (f
);
1133 /* Update the individual lines as needed. Do bottom line first. */
1135 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1136 update_line (f
, FRAME_HEIGHT (f
) - 1);
1138 #ifdef HAVE_X_WINDOWS
1141 leftmost
= downto
= f
->display
.x
->internal_border_width
;
1142 if (desired_frame
->enable
[0])
1144 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1145 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1146 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
1147 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1148 current_frame
->top_left_x
[0] = leftmost
;
1149 current_frame
->top_left_y
[0] = downto
;
1152 #endif /* HAVE_X_WINDOWS */
1154 /* Now update the rest of the lines. */
1155 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1157 if (desired_frame
->enable
[i
])
1159 if (FRAME_TERMCAP_P (f
))
1161 /* Flush out every so many lines.
1162 Also flush out if likely to have more than 1k buffered
1163 otherwise. I'm told that some telnet connections get
1164 really screwed by more than 1k output at once. */
1165 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1167 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1170 if (preempt_count
== 1)
1172 #ifdef EMACS_OUTQSIZE
1173 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1174 /* Probably not a tty. Ignore the error and reset
1175 * the outq count. */
1176 outq
= PENDING_OUTPUT_COUNT (stdout
);
1179 if (baud_rate
>= outq
)
1180 sleep (outq
/ baud_rate
);
1183 if ((i
- 1) % preempt_count
== 0)
1184 detect_input_pending ();
1188 #ifdef HAVE_X_WINDOWS
1191 current_frame
->top_left_y
[i
] = downto
;
1192 current_frame
->top_left_x
[i
] = leftmost
;
1194 #endif /* HAVE_X_WINDOWS */
1197 #ifdef HAVE_X_WINDOWS
1199 downto
+= current_frame
->pix_height
[i
];
1202 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1204 /* Now just clean up termcap drivers and set cursor, etc. */
1207 if (cursor_in_echo_area
1208 && FRAME_HAS_MINIBUF_P (f
))
1210 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1213 if (cursor_in_echo_area
< 0)
1220 /* If the minibuffer is several lines high, find the last
1221 line that has any text on it. */
1222 row
= FRAME_HEIGHT (f
);
1226 if (current_frame
->enable
[row
])
1227 col
= current_frame
->used
[row
];
1231 while (row
> top
&& col
== 0);
1233 if (col
>= FRAME_WIDTH (f
))
1236 if (row
< FRAME_HEIGHT (f
) - 1)
1241 cursor_to (row
, col
);
1244 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1245 FRAME_WIDTH (f
) - 1), 0));
1251 fflush (termscript
);
1254 /* Here if output is preempted because input is detected. */
1257 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1258 display_completed
= !pause
;
1260 bzero (desired_frame
->enable
, FRAME_HEIGHT (f
));
1264 /* Called when about to quit, to check for doing so
1265 at an improper time. */
1270 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1272 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1274 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1278 /* Decide what insert/delete line to do, and do it */
1280 extern void scrolling_1 ();
1285 int unchanged_at_top
, unchanged_at_bottom
;
1288 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1289 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1290 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1292 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1293 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1294 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1296 /* Compute hash codes of all the lines.
1297 Also calculate number of changed lines,
1298 number of unchanged lines at the beginning,
1299 and number of unchanged lines at the end. */
1302 unchanged_at_top
= 0;
1303 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1304 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1306 /* Give up on this scrolling if some old lines are not enabled. */
1307 if (!current_frame
->enable
[i
])
1309 old_hash
[i
] = line_hash_code (current_frame
, i
);
1310 if (! desired_frame
->enable
[i
])
1311 new_hash
[i
] = old_hash
[i
];
1313 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1315 if (old_hash
[i
] != new_hash
[i
])
1318 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1320 else if (i
== unchanged_at_top
)
1322 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1325 /* If changed lines are few, don't allow preemption, don't scroll. */
1326 if (changed_lines
< baud_rate
/ 2400
1327 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1330 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1331 - unchanged_at_bottom
);
1333 if (scroll_region_ok
)
1334 free_at_end_vpos
-= unchanged_at_bottom
;
1335 else if (memory_below_frame
)
1336 free_at_end_vpos
= -1;
1338 /* If large window, fast terminal and few lines in common between
1339 current frame and desired frame, don't bother with i/d calc. */
1340 if (window_size
>= 18 && baud_rate
> 2400
1342 10 * scrolling_max_lines_saved (unchanged_at_top
,
1343 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1344 old_hash
, new_hash
, draw_cost
)))
1347 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1348 draw_cost
+ unchanged_at_top
- 1,
1349 old_hash
+ unchanged_at_top
- 1,
1350 new_hash
+ unchanged_at_top
- 1,
1351 free_at_end_vpos
- unchanged_at_top
);
1356 /* Return the offset in its buffer of the character at location col, line
1357 in the given window. */
1359 buffer_posn_from_coords (window
, col
, line
)
1360 struct window
*window
;
1363 int hscroll
= XINT (window
->hscroll
);
1364 int window_left
= XFASTINT (window
->left
);
1366 /* The actual width of the window is window->width less one for the
1367 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1369 int window_width
= window_internal_width (window
) - 1;
1371 int startp
= marker_position (window
->start
);
1373 /* Since compute_motion will only operate on the current buffer,
1374 we need to save the old one and restore it when we're done. */
1375 struct buffer
*old_current_buffer
= current_buffer
;
1376 struct position
*posn
;
1378 current_buffer
= XBUFFER (window
->buffer
);
1380 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1381 (window->frame))->bufp to avoid scanning from the very top of
1382 the window, but it isn't maintained correctly, and I'm not even
1383 sure I will keep it. */
1384 posn
= compute_motion (startp
, 0,
1385 (window
== XWINDOW (minibuf_window
) && startp
== 1
1386 ? minibuf_prompt_width
: 0)
1387 + (hscroll
? 1 - hscroll
: 0),
1389 window_width
, hscroll
, 0);
1391 current_buffer
= old_current_buffer
;
1393 /* compute_motion considers frame points past the end of a line
1394 to be *after* the newline, i.e. at the start of the next line.
1395 This is reasonable, but not really what we want. So if the
1396 result is on a line below LINE, back it up one character. */
1397 if (posn
->vpos
> line
)
1398 return posn
->bufpos
- 1;
1400 return posn
->bufpos
;
1407 register GLYPH
*p
= r
;
1408 while (*p
++ == SPACEGLYPH
);
1413 count_match (str1
, str2
)
1416 register GLYPH
*p1
= str1
;
1417 register GLYPH
*p2
= str2
;
1418 while (*p1
++ == *p2
++);
1419 return p1
- str1
- 1;
1422 /* Char insertion/deletion cost vector, from term.c */
1423 extern int *char_ins_del_vector
;
1425 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1428 update_line (frame
, vpos
)
1429 register FRAME_PTR frame
;
1432 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1435 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1437 register struct frame_glyphs
*current_frame
1438 = FRAME_CURRENT_GLYPHS (frame
);
1439 register struct frame_glyphs
*desired_frame
1440 = FRAME_DESIRED_GLYPHS (frame
);
1442 if (desired_frame
->highlight
[vpos
]
1443 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1445 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1446 (current_frame
->enable
[vpos
] ?
1447 current_frame
->used
[vpos
] : 0));
1448 current_frame
->enable
[vpos
] = 0;
1451 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1453 if (! current_frame
->enable
[vpos
])
1459 obody
= current_frame
->glyphs
[vpos
];
1460 olen
= current_frame
->used
[vpos
];
1461 if (! current_frame
->highlight
[vpos
])
1463 if (!must_write_spaces
)
1464 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1469 /* For an inverse-video line, remember we gave it
1470 spaces all the way to the frame edge
1471 so that the reverse video extends all the way across. */
1473 while (olen
< FRAME_WIDTH (frame
) - 1)
1474 obody
[olen
++] = SPACEGLYPH
;
1478 /* One way or another, this will enable the line being updated. */
1479 current_frame
->enable
[vpos
] = 1;
1480 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1481 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1482 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1484 #ifdef HAVE_X_WINDOWS
1485 if (FRAME_X_P (frame
))
1487 current_frame
->pix_width
[vpos
]
1488 = current_frame
->used
[vpos
]
1489 * FONT_WIDTH (frame
->display
.x
->font
);
1490 current_frame
->pix_height
[vpos
]
1491 = FONT_HEIGHT (frame
->display
.x
->font
);
1493 #endif /* HAVE_X_WINDOWS */
1495 if (!desired_frame
->enable
[vpos
])
1501 nbody
= desired_frame
->glyphs
[vpos
];
1502 nlen
= desired_frame
->used
[vpos
];
1504 /* Pretend trailing spaces are not there at all,
1505 unless for one reason or another we must write all spaces. */
1506 if (! desired_frame
->highlight
[vpos
])
1508 if (!must_write_spaces
)
1509 /* We know that the previous character byte contains 0. */
1510 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1515 /* For an inverse-video line, give it extra trailing spaces
1516 all the way to the frame edge
1517 so that the reverse video extends all the way across. */
1519 while (nlen
< FRAME_WIDTH (frame
) - 1)
1520 nbody
[nlen
++] = SPACEGLYPH
;
1523 /* If there's no i/d char, quickly do the best we can without it. */
1524 if (!char_ins_del_ok
)
1529 if (FRAME_X_P (frame
))
1531 /* Under X, erase everything we are going to rewrite,
1532 and rewrite everything from the first char that's changed.
1533 This is part of supporting fonts like Courier
1534 whose chars can overlap outside the char width. */
1535 for (i
= 0; i
< nlen
; i
++)
1536 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1539 cursor_to (vpos
, i
);
1541 clear_end_of_line (olen
);
1542 write_glyphs (nbody
+ i
, nlen
- i
);
1547 for (i
= 0; i
< nlen
; i
++)
1549 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1551 cursor_to (vpos
, i
);
1552 for (j
= 1; (i
+ j
< nlen
&&
1553 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1556 /* Output this run of non-matching chars. */
1557 write_glyphs (nbody
+ i
, j
);
1560 /* Now find the next non-match. */
1564 /* Clear the rest of the line, or the non-clear part of it. */
1567 cursor_to (vpos
, nlen
);
1568 clear_end_of_line (olen
);
1571 /* Exchange contents between current_frame and new_frame. */
1572 temp
= desired_frame
->glyphs
[vpos
];
1573 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1574 current_frame
->glyphs
[vpos
] = temp
;
1576 /* Exchange charstarts between current_frame and new_frame. */
1577 temp1
= desired_frame
->charstarts
[vpos
];
1578 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1579 current_frame
->charstarts
[vpos
] = temp1
;
1586 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1587 ? 0 : count_blanks (nbody
);
1590 cursor_to (vpos
, nsp
);
1591 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1594 /* Exchange contents between current_frame and new_frame. */
1595 temp
= desired_frame
->glyphs
[vpos
];
1596 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1597 current_frame
->glyphs
[vpos
] = temp
;
1599 /* Exchange charstarts between current_frame and new_frame. */
1600 temp1
= desired_frame
->charstarts
[vpos
];
1601 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1602 current_frame
->charstarts
[vpos
] = temp1
;
1611 /* Compute number of leading blanks in old and new contents. */
1612 osp
= count_blanks (obody
);
1613 if (!desired_frame
->highlight
[vpos
])
1614 nsp
= count_blanks (nbody
);
1618 /* Compute number of matching chars starting with first nonblank. */
1619 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1621 /* Spaces in new match implicit space past the end of old. */
1622 /* A bug causing this to be a no-op was fixed in 18.29. */
1623 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1626 while (np1
[begmatch
] == SPACEGLYPH
)
1630 /* Avoid doing insert/delete char
1631 just cause number of leading spaces differs
1632 when the following text does not match. */
1633 if (begmatch
== 0 && osp
!= nsp
)
1634 osp
= nsp
= min (osp
, nsp
);
1636 /* Find matching characters at end of line */
1639 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1640 while (op1
> op2
&& op1
[-1] == np1
[-1])
1645 endmatch
= obody
+ olen
- op1
;
1647 /* Put correct value back in nbody[nlen].
1648 This is important because direct_output_for_insert
1649 can write into the line at a later point.
1650 If this screws up the zero at the end of the line, re-establish it. */
1654 /* tem gets the distance to insert or delete.
1655 endmatch is how many characters we save by doing so.
1658 tem
= (nlen
- nsp
) - (olen
- osp
);
1660 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1663 /* nsp - osp is the distance to insert or delete.
1664 If that is nonzero, begmatch is known to be nonzero also.
1665 begmatch + endmatch is how much we save by doing the ins/del.
1669 && (!char_ins_del_ok
1670 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1674 osp
= nsp
= min (osp
, nsp
);
1677 /* Now go through the line, inserting, writing and
1678 deleting as appropriate. */
1682 cursor_to (vpos
, nsp
);
1683 delete_glyphs (osp
- nsp
);
1687 /* If going to delete chars later in line
1688 and insert earlier in the line,
1689 must delete first to avoid losing data in the insert */
1690 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1692 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1693 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1694 olen
= nlen
- (nsp
- osp
);
1696 cursor_to (vpos
, osp
);
1697 insert_glyphs ((char *)0, nsp
- osp
);
1701 tem
= nsp
+ begmatch
+ endmatch
;
1702 if (nlen
!= tem
|| olen
!= tem
)
1704 cursor_to (vpos
, nsp
+ begmatch
);
1705 if (!endmatch
|| nlen
== olen
)
1707 /* If new text being written reaches right margin,
1708 there is no need to do clear-to-eol at the end.
1709 (and it would not be safe, since cursor is not
1710 going to be "at the margin" after the text is done) */
1711 if (nlen
== FRAME_WIDTH (frame
))
1713 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1717 /* the following code loses disastrously if tem == nlen.
1718 Rather than trying to fix that case, I am trying the simpler
1719 solution found above. */
1721 /* If the text reaches to the right margin,
1722 it will lose one way or another (depending on AutoWrap)
1723 to clear to end of line after outputting all the text.
1724 So pause with one character to go and clear the line then. */
1725 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1727 /* endmatch must be zero, and tem must equal nsp + begmatch */
1728 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1729 clear_end_of_line (olen
);
1730 olen
= 0; /* Don't let it be cleared again later */
1731 write_glyphs (nbody
+ nlen
- 1, 1);
1734 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1735 #endif /* OBSOLETE */
1738 else if (nlen
> olen
)
1740 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1741 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1744 else if (olen
> nlen
)
1746 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1747 delete_glyphs (olen
- nlen
);
1753 /* If any unerased characters remain after the new line, erase them. */
1756 cursor_to (vpos
, nlen
);
1757 clear_end_of_line (olen
);
1760 /* Exchange contents between current_frame and new_frame. */
1761 temp
= desired_frame
->glyphs
[vpos
];
1762 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1763 current_frame
->glyphs
[vpos
] = temp
;
1765 /* Exchange charstarts between current_frame and new_frame. */
1766 temp1
= desired_frame
->charstarts
[vpos
];
1767 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1768 current_frame
->charstarts
[vpos
] = temp1
;
1771 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1772 1, 1, "FOpen termscript file: ",
1773 "Start writing all terminal output to FILE as well as the terminal.\n\
1774 FILE = nil means just close any termscript file currently open.")
1778 if (termscript
!= 0) fclose (termscript
);
1783 file
= Fexpand_file_name (file
, Qnil
);
1784 termscript
= fopen (XSTRING (file
)->data
, "w");
1785 if (termscript
== 0)
1786 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1794 window_change_signal ()
1798 int old_errno
= errno
;
1800 get_frame_size (&width
, &height
);
1802 /* The frame size change obviously applies to a termcap-controlled
1803 frame. Find such a frame in the list, and assume it's the only
1804 one (since the redisplay code always writes to stdout, not a
1805 FILE * specified in the frame structure). Record the new size,
1806 but don't reallocate the data structures now. Let that be done
1807 later outside of the signal handler. */
1810 Lisp_Object tail
, frame
;
1812 FOR_EACH_FRAME (tail
, frame
)
1814 if (FRAME_TERMCAP_P (XFRAME (frame
)))
1816 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
1822 signal (SIGWINCH
, window_change_signal
);
1825 #endif /* SIGWINCH */
1828 /* Do any change in frame size that was requested by a signal. */
1830 do_pending_window_change ()
1832 /* If window_change_signal should have run before, run it now. */
1833 while (delayed_size_change
)
1835 Lisp_Object tail
, frame
;
1837 delayed_size_change
= 0;
1839 FOR_EACH_FRAME (tail
, frame
)
1841 FRAME_PTR f
= XFRAME (frame
);
1843 int height
= FRAME_NEW_HEIGHT (f
);
1844 int width
= FRAME_NEW_WIDTH (f
);
1846 if (height
!= 0 || width
!= 0)
1847 change_frame_size (f
, height
, width
, 0, 0);
1853 /* Change the frame height and/or width. Values may be given as zero to
1854 indicate no change is to take place.
1856 If DELAY is non-zero, then assume we're being called from a signal
1857 handler, and queue the change for later - perhaps the next
1858 redisplay. Since this tries to resize windows, we can't call it
1859 from a signal handler. */
1861 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
1862 register FRAME_PTR frame
;
1863 int newheight
, newwidth
, pretend
;
1865 /* If we can't deal with the change now, queue it for later. */
1868 FRAME_NEW_HEIGHT (frame
) = newheight
;
1869 FRAME_NEW_WIDTH (frame
) = newwidth
;
1870 delayed_size_change
= 1;
1874 /* This size-change overrides any pending one for this frame. */
1875 FRAME_NEW_HEIGHT (frame
) = 0;
1876 FRAME_NEW_WIDTH (frame
) = 0;
1878 /* If an argument is zero, set it to the current value. */
1879 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
1880 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
1882 /* Round up to the smallest acceptable size. */
1883 check_frame_size (frame
, &newheight
, &newwidth
);
1885 /* If we're not changing the frame size, quit now. */
1886 if (newheight
== FRAME_HEIGHT (frame
)
1887 && newwidth
== FRAME_WIDTH (frame
))
1890 if (newheight
!= FRAME_HEIGHT (frame
))
1892 if (FRAME_HAS_MINIBUF_P (frame
)
1893 && ! FRAME_MINIBUF_ONLY_P (frame
))
1895 /* Frame has both root and minibuffer. */
1896 set_window_height (FRAME_ROOT_WINDOW (frame
),
1897 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
1898 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
)
1900 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
1903 /* Frame has just one top-level window. */
1904 set_window_height (FRAME_ROOT_WINDOW (frame
),
1905 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
1907 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1908 FrameRows
= newheight
;
1911 if (frame
->output_method
== output_termcap
)
1913 frame_height
= newheight
;
1915 FrameRows
= newheight
;
1920 if (newwidth
!= FRAME_WIDTH (frame
))
1922 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
1923 if (FRAME_HAS_MINIBUF_P (frame
))
1924 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
1926 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1927 FrameCols
= newwidth
;
1929 if (frame
->output_method
== output_termcap
)
1931 frame_width
= newwidth
;
1933 FrameCols
= newwidth
;
1938 FRAME_HEIGHT (frame
) = newheight
;
1939 FRAME_WIDTH (frame
) = newwidth
;
1941 remake_frame_glyphs (frame
);
1942 calculate_costs (frame
);
1945 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
1946 Ssend_string_to_terminal
, 1, 1, 0,
1947 "Send STRING to the terminal without alteration.\n\
1948 Control characters in STRING will have terminal-dependent effects.")
1952 CHECK_STRING (str
, 0);
1953 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
1957 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
1958 fflush (termscript
);
1963 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
1964 "Beep, or flash the screen.\n\
1965 Also, unless an argument is given,\n\
1966 terminate any keyboard macro currently executing.")
1988 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
1989 error ("Keyboard macro terminated by a command ringing the bell");
1995 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
1996 "Pause, without updating display, for SECONDS seconds.\n\
1997 SECONDS may be a floating-point value, meaning that you can wait for a\n\
1998 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
1999 additional wait period, in milliseconds; this may be useful if your\n\
2000 Emacs was built without floating point support.\n\
2001 \(Not all operating systems support waiting for a fraction of a second.)")
2002 (seconds
, milliseconds
)
2003 Lisp_Object seconds
, milliseconds
;
2007 if (NILP (milliseconds
))
2008 XSET (milliseconds
, Lisp_Int
, 0);
2010 CHECK_NUMBER (milliseconds
, 1);
2011 usec
= XINT (milliseconds
) * 1000;
2013 #ifdef LISP_FLOAT_TYPE
2015 double duration
= extract_float (seconds
);
2016 sec
= (int) duration
;
2017 usec
+= (duration
- sec
) * 1000000;
2020 CHECK_NUMBER (seconds
, 0);
2021 sec
= XINT (seconds
);
2024 #ifndef EMACS_HAS_USECS
2025 if (sec
== 0 && usec
!= 0)
2026 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2029 /* Assure that 0 <= usec < 1000000. */
2032 /* We can't rely on the rounding being correct if user is negative. */
2033 if (-1000000 < usec
)
2034 sec
--, usec
+= 1000000;
2036 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2039 sec
+= usec
/ 1000000, usec
%= 1000000;
2047 XFASTINT (zero
) = 0;
2048 wait_reading_process_input (sec
, usec
, zero
, 0);
2051 /* We should always have wait_reading_process_input; we have a dummy
2052 implementation for systems which don't support subprocesses. */
2054 /* No wait_reading_process_input */
2061 /* The reason this is done this way
2062 (rather than defined (H_S) && defined (H_T))
2063 is because the VMS preprocessor doesn't grok `defined' */
2065 EMACS_GET_TIME (end_time
);
2066 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2067 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2071 EMACS_GET_TIME (timeout
);
2072 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2073 if (EMACS_TIME_NEG_P (timeout
)
2074 || !select (1, 0, 0, 0, &timeout
))
2077 #else /* not HAVE_SELECT */
2079 #endif /* HAVE_SELECT */
2080 #endif /* not VMS */
2083 #endif /* no subprocesses */
2088 /* This is just like wait_reading_process_input, except that
2089 it does the redisplay.
2091 It's also much like Fsit_for, except that it can be used for
2092 waiting for input as well. One differnce is that sit_for
2093 does not call prepare_menu_bars; Fsit_for does call that. */
2096 sit_for (sec
, usec
, reading
, display
)
2097 int sec
, usec
, reading
, display
;
2099 Lisp_Object read_kbd
;
2101 if (detect_input_pending ())
2105 redisplay_preserve_echo_area ();
2107 if (sec
== 0 && usec
== 0)
2114 XSET (read_kbd
, Lisp_Int
, reading
? -1 : 1);
2115 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2118 /* wait_reading_process_input should always be available now; it is
2119 simulated in a simple way on systems that don't support
2122 /* No wait_reading_process_input available. */
2128 input_wait_timeout (XINT (arg
));
2130 #ifndef HAVE_TIMEVAL
2132 select (1, &waitchannels
, 0, 0, &timeout_sec
);
2133 #else /* HAVE_TIMEVAL */
2134 timeout
.tv_sec
= sec
;
2135 timeout
.tv_usec
= usec
;
2136 select (1, &waitchannels
, 0, 0, &timeout
);
2137 #endif /* HAVE_TIMEVAL */
2138 #endif /* not VMS */
2143 return detect_input_pending () ? Qnil
: Qt
;
2146 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2147 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2148 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2149 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2150 additional wait period, in milliseconds; this may be useful if your\n\
2151 Emacs was built without floating point support.\n\
2152 \(Not all operating systems support waiting for a fraction of a second.)\n\
2153 Optional third arg non-nil means don't redisplay, just wait for input.\n\
2154 Redisplay is preempted as always if input arrives, and does not happen\n\
2155 if input is available before it starts.\n\
2156 Value is t if waited the full time with no input arriving.")
2157 (seconds
, milliseconds
, nodisp
)
2158 Lisp_Object seconds
, milliseconds
, nodisp
;
2162 if (NILP (milliseconds
))
2163 XSET (milliseconds
, Lisp_Int
, 0);
2165 CHECK_NUMBER (milliseconds
, 1);
2166 usec
= XINT (milliseconds
) * 1000;
2168 #ifdef LISP_FLOAT_TYPE
2170 double duration
= extract_float (seconds
);
2171 sec
= (int) duration
;
2172 usec
+= (duration
- sec
) * 1000000;
2175 CHECK_NUMBER (seconds
, 0);
2176 sec
= XINT (seconds
);
2179 #ifndef EMACS_HAS_USECS
2180 if (usec
!= 0 && sec
== 0)
2181 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2185 prepare_menu_bars ();
2186 return sit_for (sec
, usec
, 0, NILP (nodisp
));
2189 char *terminal_type
;
2191 /* Initialization done when Emacs fork is started, before doing stty. */
2192 /* Determine terminal type and set terminal_driver */
2193 /* Then invoke its decoding routine to set up variables
2194 in the terminal package */
2198 #ifdef HAVE_X_WINDOWS
2199 extern int display_arg
;
2204 cursor_in_echo_area
= 0;
2205 terminal_type
= (char *) 0;
2207 /* Now is the time to initialize this; it's used by init_sys_modes
2209 Vwindow_system
= Qnil
;
2211 /* If the user wants to use a window system, we shouldn't bother
2212 initializing the terminal. This is especially important when the
2213 terminal is so dumb that emacs gives up before and doesn't bother
2214 using the window system.
2216 If the DISPLAY environment variable is set, try to use X, and die
2217 with an error message if that doesn't work. */
2219 #ifdef HAVE_X_WINDOWS
2223 display_arg
= (getenv ("DECW$DISPLAY") != 0);
2225 display_arg
= (getenv ("DISPLAY") != 0);
2229 if (!inhibit_window_system
&& display_arg
)
2231 Vwindow_system
= intern ("x");
2233 Vwindow_system_version
= make_number (11);
2235 Vwindow_system_version
= make_number (10);
2239 #endif /* HAVE_X_WINDOWS */
2241 /* If no window system has been specified, try to use the terminal. */
2244 fprintf (stderr
, "emacs: standard input is not a tty\n");
2248 /* Look at the TERM variable */
2249 terminal_type
= (char *) getenv ("TERM");
2253 fprintf (stderr
, "Please specify your terminal type.\n\
2254 For types defined in VMS, use set term /device=TYPE.\n\
2255 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2256 \(The quotation marks are necessary since terminal types are lower case.)\n");
2258 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2264 /* VMS DCL tends to upcase things, so downcase term type.
2265 Hardly any uppercase letters in terminal types; should be none. */
2267 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2270 strcpy (new, terminal_type
);
2272 for (p
= new; *p
; p
++)
2276 terminal_type
= new;
2280 term_init (terminal_type
);
2282 remake_frame_glyphs (selected_frame
);
2283 calculate_costs (selected_frame
);
2285 /* X and Y coordinates of the cursor between updates. */
2286 FRAME_CURSOR_X (selected_frame
) = 0;
2287 FRAME_CURSOR_Y (selected_frame
) = 0;
2292 #endif /* CANNOT_DUMP */
2293 signal (SIGWINCH
, window_change_signal
);
2294 #endif /* SIGWINCH */
2300 defsubr (&Sredraw_frame
);
2302 defsubr (&Sredraw_display
);
2303 defsubr (&Sopen_termscript
);
2305 defsubr (&Ssit_for
);
2306 defsubr (&Ssleep_for
);
2307 defsubr (&Ssend_string_to_terminal
);
2309 DEFVAR_INT ("baud-rate", &baud_rate
,
2310 "The output baud rate of the terminal.\n\
2311 On most systems, changing this value will affect the amount of padding\n\
2312 and the other strategic decisions made during redisplay.");
2313 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2314 "*Non-nil means invert the entire frame display.\n\
2315 This means everything is in inverse video which otherwise would not be.");
2316 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2317 "*Non-nil means try to flash the frame to represent a bell.");
2318 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2319 "*Non-nil means no need to redraw entire frame after suspending.\n\
2320 A non-nil value is useful if the terminal can automatically preserve\n\
2321 Emacs's frame display when you reenter Emacs.\n\
2322 It is up to you to set this variable if your terminal can do that.");
2323 DEFVAR_LISP ("window-system", &Vwindow_system
,
2324 "A symbol naming the window-system under which Emacs is running\n\
2325 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2326 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2327 "The version number of the window system in use.\n\
2328 For X windows, this is 10 or 11.");
2329 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2330 "Non-nil means put cursor in minibuffer, at end of any message there.");
2331 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2332 "Table defining how to output a glyph code to the frame.\n\
2333 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2334 Each element can be:\n\
2335 integer: a glyph code which this glyph is an alias for.\n\
2336 string: output this glyph using that string (not impl. in X windows).\n\
2337 nil: this glyph mod 256 is char code to output,\n\
2338 and this glyph / 256 is face code for X windows (see `x-set-face').");
2339 Vglyph_table
= Qnil
;
2341 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2342 "Display table to use for buffers that specify none.\n\
2343 See `buffer-display-table' for more information.");
2344 Vstandard_display_table
= Qnil
;
2346 /* Initialize `window-system', unless init_display already decided it. */
2351 Vwindow_system
= Qnil
;
2352 Vwindow_system_version
= Qnil
;