1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993 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->highlight
= (char *) xmalloc (height
* sizeof (char));
247 new->enable
= (char *) xmalloc (height
* sizeof (char));
248 bzero (new->enable
, height
* sizeof (char));
249 new->bufp
= (int *) xmalloc (height
* sizeof (int));
251 #ifdef HAVE_X_WINDOWS
252 if (FRAME_X_P (frame
))
254 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
255 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
256 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
257 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
258 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
264 /* Make the buffer used by decode_mode_spec. This buffer is also
265 used as temporary storage when updating the frame. See scroll.c. */
266 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
268 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
269 bzero (new->total_contents
, total_glyphs
);
273 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
275 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
276 bzero (new->total_contents
, total_glyphs
);
277 for (i
= 0; i
< height
; i
++)
278 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
285 free_frame_glyphs (frame
, glyphs
)
287 struct frame_glyphs
*glyphs
;
289 if (glyphs
->total_contents
)
290 xfree (glyphs
->total_contents
);
292 xfree (glyphs
->used
);
293 xfree (glyphs
->glyphs
);
294 xfree (glyphs
->highlight
);
295 xfree (glyphs
->enable
);
296 xfree (glyphs
->bufp
);
298 #ifdef HAVE_X_WINDOWS
299 if (FRAME_X_P (frame
))
301 xfree (glyphs
->top_left_x
);
302 xfree (glyphs
->top_left_y
);
303 xfree (glyphs
->pix_width
);
304 xfree (glyphs
->pix_height
);
305 xfree (glyphs
->max_ascent
);
313 remake_frame_glyphs (frame
)
316 if (FRAME_CURRENT_GLYPHS (frame
))
317 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
318 if (FRAME_DESIRED_GLYPHS (frame
))
319 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
320 if (FRAME_TEMP_GLYPHS (frame
))
321 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
323 if (FRAME_MESSAGE_BUF (frame
))
325 /* Reallocate the frame's message buffer; remember that
326 echo_area_glyphs may be pointing here. */
327 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
329 FRAME_MESSAGE_BUF (frame
)
330 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
331 FRAME_WIDTH (frame
) + 1);
333 if (echo_area_glyphs
== old_message_buf
)
334 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
335 if (previous_echo_glyphs
== old_message_buf
)
336 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
339 FRAME_MESSAGE_BUF (frame
)
340 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
342 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
343 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
344 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
345 SET_FRAME_GARBAGED (frame
);
348 /* Return the hash code of contents of line VPOS in frame-matrix M. */
351 line_hash_code (m
, vpos
)
352 register struct frame_glyphs
*m
;
355 register GLYPH
*body
, *end
;
358 if (!m
->enable
[vpos
])
361 /* Give all highlighted lines the same hash code
362 so as to encourage scrolling to leave them in place. */
363 if (m
->highlight
[vpos
])
366 body
= m
->glyphs
[vpos
];
368 if (must_write_spaces
)
375 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
384 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
392 /* Return number of characters in line in M at vpos VPOS,
393 except don't count leading and trailing spaces
394 unless the terminal requires those to be explicitly output. */
397 line_draw_cost (m
, vpos
)
398 struct frame_glyphs
*m
;
401 register GLYPH
*beg
= m
->glyphs
[vpos
];
402 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
404 register int tlen
= GLYPH_TABLE_LENGTH
;
405 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
407 /* Ignore trailing and leading spaces if we can. */
408 if (!must_write_spaces
)
410 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
413 return (0); /* All blank line. */
415 while (*beg
== SPACEGLYPH
)
419 /* If we don't have a glyph-table, each glyph is one character,
420 so return the number of glyphs. */
424 /* Otherwise, scan the glyphs and accumulate their total size in I. */
426 while ((beg
<= end
) && *beg
)
428 register GLYPH g
= *beg
++;
430 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
433 i
+= GLYPH_LENGTH (tbase
, g
);
438 /* The functions on this page are the interface from xdisp.c to redisplay.
440 The only other interface into redisplay is through setting
441 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
442 and SET_FRAME_GARBAGED (frame). */
444 /* cancel_line eliminates any request to display a line at position `vpos' */
446 cancel_line (vpos
, frame
)
448 register FRAME_PTR frame
;
450 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
453 clear_frame_records (frame
)
454 register FRAME_PTR frame
;
456 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
459 /* Prepare to display on line VPOS starting at HPOS within it. */
462 get_display_line (frame
, vpos
, hpos
)
463 register FRAME_PTR frame
;
467 register struct frame_glyphs
*glyphs
;
468 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
474 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
477 if (! desired_glyphs
->enable
[vpos
])
479 desired_glyphs
->used
[vpos
] = 0;
480 desired_glyphs
->highlight
[vpos
] = 0;
481 desired_glyphs
->enable
[vpos
] = 1;
484 if (hpos
> desired_glyphs
->used
[vpos
])
486 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
487 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
489 desired_glyphs
->used
[vpos
] = hpos
;
495 /* Like bcopy except never gets confused by overlap. */
498 safe_bcopy (from
, to
, size
)
502 if (size
<= 0 || from
== to
)
505 /* If the source and destination don't overlap, then bcopy can
506 handle it. If they do overlap, but the destination is lower in
507 memory than the source, we'll assume bcopy can handle that. */
508 if (to
< from
|| from
+ size
<= to
)
509 bcopy (from
, to
, size
);
511 /* Otherwise, we'll copy from the end. */
514 register char *endf
= from
+ size
;
515 register char *endt
= to
+ size
;
517 /* If TO - FROM is large, then we should break the copy into
518 nonoverlapping chunks of TO - FROM bytes each. However, if
519 TO - FROM is small, then the bcopy function call overhead
520 makes this not worth it. The crossover point could be about
521 anywhere. Since I don't think the obvious copy loop is too
522 bad, I'm trying to err in its favor. */
527 while (endf
!= from
);
539 bcopy (endf
, endt
, to
- from
);
542 /* If SIZE wasn't a multiple of TO - FROM, there will be a
543 little left over. The amount left over is
544 (endt + (to - from)) - to, which is endt - from. */
545 bcopy (from
, to
, endt
- from
);
550 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
551 DISTANCE may be negative. */
554 rotate_vector (vector
, size
, distance
)
559 char *temp
= (char *) alloca (size
);
564 bcopy (vector
, temp
+ distance
, size
- distance
);
565 bcopy (vector
+ size
- distance
, temp
, distance
);
566 bcopy (temp
, vector
, size
);
569 /* Scroll lines from vpos FROM up to but not including vpos END
570 down by AMOUNT lines (AMOUNT may be negative).
571 Returns nonzero if done, zero if terminal cannot scroll them. */
574 scroll_frame_lines (frame
, from
, end
, amount
)
575 register FRAME_PTR frame
;
576 int from
, end
, amount
;
579 register struct frame_glyphs
*current_frame
580 = FRAME_CURRENT_GLYPHS (frame
);
582 if (!line_ins_del_ok
)
590 update_begin (frame
);
591 set_terminal_window (end
+ amount
);
592 if (!scroll_region_ok
)
593 ins_del_lines (end
, -amount
);
594 ins_del_lines (from
, amount
);
595 set_terminal_window (0);
597 rotate_vector (current_frame
->glyphs
+ from
,
598 sizeof (GLYPH
*) * (end
+ amount
- from
),
599 amount
* sizeof (GLYPH
*));
601 safe_bcopy (current_frame
->used
+ from
,
602 current_frame
->used
+ from
+ amount
,
603 (end
- from
) * sizeof current_frame
->used
[0]);
605 safe_bcopy (current_frame
->highlight
+ from
,
606 current_frame
->highlight
+ from
+ amount
,
607 (end
- from
) * sizeof current_frame
->highlight
[0]);
609 safe_bcopy (current_frame
->enable
+ from
,
610 current_frame
->enable
+ from
+ amount
,
611 (end
- from
) * sizeof current_frame
->enable
[0]);
613 /* Mark the lines made empty by scrolling as enabled, empty and
615 bzero (current_frame
->used
+ from
,
616 amount
* sizeof current_frame
->used
[0]);
617 bzero (current_frame
->highlight
+ from
,
618 amount
* sizeof current_frame
->highlight
[0]);
619 for (i
= from
; i
< from
+ amount
; i
++)
621 current_frame
->glyphs
[i
][0] = '\0';
622 current_frame
->enable
[i
] = 1;
625 safe_bcopy (current_frame
->bufp
+ from
,
626 current_frame
->bufp
+ from
+ amount
,
627 (end
- from
) * sizeof current_frame
->bufp
[0]);
629 #ifdef HAVE_X_WINDOWS
630 if (FRAME_X_P (frame
))
632 safe_bcopy (current_frame
->top_left_x
+ from
,
633 current_frame
->top_left_x
+ from
+ amount
,
634 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
636 safe_bcopy (current_frame
->top_left_y
+ from
,
637 current_frame
->top_left_y
+ from
+ amount
,
638 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
640 safe_bcopy (current_frame
->pix_width
+ from
,
641 current_frame
->pix_width
+ from
+ amount
,
642 (end
- from
) * sizeof current_frame
->pix_width
[0]);
644 safe_bcopy (current_frame
->pix_height
+ from
,
645 current_frame
->pix_height
+ from
+ amount
,
646 (end
- from
) * sizeof current_frame
->pix_height
[0]);
648 safe_bcopy (current_frame
->max_ascent
+ from
,
649 current_frame
->max_ascent
+ from
+ amount
,
650 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
652 #endif /* HAVE_X_WINDOWS */
658 update_begin (frame
);
659 set_terminal_window (end
);
660 ins_del_lines (from
+ amount
, amount
);
661 if (!scroll_region_ok
)
662 ins_del_lines (end
+ amount
, -amount
);
663 set_terminal_window (0);
665 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
666 sizeof (GLYPH
*) * (end
- from
- amount
),
667 amount
* sizeof (GLYPH
*));
669 safe_bcopy (current_frame
->used
+ from
,
670 current_frame
->used
+ from
+ amount
,
671 (end
- from
) * sizeof current_frame
->used
[0]);
673 safe_bcopy (current_frame
->highlight
+ from
,
674 current_frame
->highlight
+ from
+ amount
,
675 (end
- from
) * sizeof current_frame
->highlight
[0]);
677 safe_bcopy (current_frame
->enable
+ from
,
678 current_frame
->enable
+ from
+ amount
,
679 (end
- from
) * sizeof current_frame
->enable
[0]);
681 /* Mark the lines made empty by scrolling as enabled, empty and
683 bzero (current_frame
->used
+ end
+ amount
,
684 - amount
* sizeof current_frame
->used
[0]);
685 bzero (current_frame
->highlight
+ end
+ amount
,
686 - amount
* sizeof current_frame
->highlight
[0]);
687 for (i
= end
+ amount
; i
< end
; i
++)
689 current_frame
->glyphs
[i
][0] = '\0';
690 current_frame
->enable
[i
] = 1;
693 safe_bcopy (current_frame
->bufp
+ from
,
694 current_frame
->bufp
+ from
+ amount
,
695 (end
- from
) * sizeof current_frame
->bufp
[0]);
697 #ifdef HAVE_X_WINDOWS
698 if (FRAME_X_P (frame
))
700 safe_bcopy (current_frame
->top_left_x
+ from
,
701 current_frame
->top_left_x
+ from
+ amount
,
702 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
704 safe_bcopy (current_frame
->top_left_y
+ from
,
705 current_frame
->top_left_y
+ from
+ amount
,
706 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
708 safe_bcopy (current_frame
->pix_width
+ from
,
709 current_frame
->pix_width
+ from
+ amount
,
710 (end
- from
) * sizeof current_frame
->pix_width
[0]);
712 safe_bcopy (current_frame
->pix_height
+ from
,
713 current_frame
->pix_height
+ from
+ amount
,
714 (end
- from
) * sizeof current_frame
->pix_height
[0]);
716 safe_bcopy (current_frame
->max_ascent
+ from
,
717 current_frame
->max_ascent
+ from
+ amount
,
718 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
720 #endif /* HAVE_X_WINDOWS */
727 /* After updating a window W that isn't the full frame wide,
728 copy all the columns that W does not occupy
729 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
730 so that update_frame will not change those columns. */
732 preserve_other_columns (w
)
736 register struct frame_glyphs
*current_frame
, *desired_frame
;
737 register FRAME_PTR frame
= XFRAME (w
->frame
);
738 int start
= XFASTINT (w
->left
);
739 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
740 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
742 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
743 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
745 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
747 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
753 bcopy (current_frame
->glyphs
[vpos
],
754 desired_frame
->glyphs
[vpos
],
755 start
* sizeof (current_frame
->glyphs
[vpos
]));
756 len
= min (start
, current_frame
->used
[vpos
]);
757 if (desired_frame
->used
[vpos
] < len
)
758 desired_frame
->used
[vpos
] = len
;
760 if (current_frame
->used
[vpos
] > end
761 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
763 while (desired_frame
->used
[vpos
] < end
)
764 desired_frame
->glyphs
[vpos
][desired_frame
->used
[vpos
]++]
766 bcopy (current_frame
->glyphs
[vpos
] + end
,
767 desired_frame
->glyphs
[vpos
] + end
,
768 ((current_frame
->used
[vpos
] - end
)
769 * sizeof (current_frame
->glyphs
[vpos
])));
770 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
778 /* If window w does not need to be updated and isn't the full frame wide,
779 copy all the columns that w does occupy
780 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
781 so that update_frame will not change those columns.
783 Have not been able to figure out how to use this correctly. */
785 preserve_my_columns (w
)
788 register int vpos
, fin
;
789 register struct frame_glyphs
*l1
, *l2
;
790 register FRAME_PTR frame
= XFRAME (w
->frame
);
791 int start
= XFASTINT (w
->left
);
792 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
793 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
795 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
797 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
798 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
800 if (l2
->length
> start
&& l1
->length
< l2
->length
)
803 if (fin
> end
) fin
= end
;
804 while (l1
->length
< start
)
805 l1
->body
[l1
->length
++] = ' ';
806 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
815 /* On discovering that the redisplay for a window was no good,
816 cancel the columns of that window, so that when the window is
817 displayed over again get_display_line will not complain. */
819 cancel_my_columns (w
)
823 register struct frame_glyphs
*desired_glyphs
=
824 FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
825 register int start
= XFASTINT (w
->left
);
826 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
828 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
829 if (desired_glyphs
->enable
[vpos
]
830 && desired_glyphs
->used
[vpos
] >= start
)
831 desired_glyphs
->used
[vpos
] = start
;
834 /* These functions try to perform directly and immediately on the frame
835 the necessary output for one change in the buffer.
836 They may return 0 meaning nothing was done if anything is difficult,
837 or 1 meaning the output was performed properly.
838 They assume that the frame was up to date before the buffer
839 change being displayed. They make various other assumptions too;
840 see command_loop_1 where these are called. */
843 direct_output_for_insert (g
)
846 register FRAME_PTR frame
= selected_frame
;
847 register struct frame_glyphs
*current_frame
848 = FRAME_CURRENT_GLYPHS (frame
);
850 #ifndef COMPILER_REGISTER_BUG
852 #endif /* COMPILER_REGISTER_BUG */
853 struct window
*w
= XWINDOW (selected_window
);
854 #ifndef COMPILER_REGISTER_BUG
856 #endif /* COMPILER_REGISTER_BUG */
857 int hpos
= FRAME_CURSOR_X (frame
);
858 #ifndef COMPILER_REGISTER_BUG
860 #endif /* COMPILER_REGISTER_BUG */
861 int vpos
= FRAME_CURSOR_Y (frame
);
863 /* Give up if about to continue line. */
864 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
866 /* Avoid losing if cursor is in invisible text off left margin */
867 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
869 /* Give up if cursor outside window (in minibuf, probably) */
870 || cursor_in_echo_area
871 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
872 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
874 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
875 || !display_completed
877 /* Give up if buffer appears in two places. */
880 #ifdef USE_TEXT_PROPERTIES
881 /* Intervals have already been adjusted, point is after the
882 character that was just inserted. */
883 /* Give up if character is invisible. */
884 /* Give up if character has a face property.
885 At the moment we only lose at end of line or end of buffer
886 and only with faces that have some background */
887 /* Instead of wasting time, give up if character has any text properties */
888 || ! NILP (Ftext_properties_at (XFASTINT (point
- 1), Qnil
))
891 /* Give up if w is minibuffer and a message is being displayed there */
892 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
896 #ifdef HAVE_X_WINDOWS
898 int face
= compute_char_face (frame
, w
, point
- 1, -1, -1, &dummy
, point
);
900 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
902 unchanged_modified
= MODIFF
;
903 beg_unchanged
= GPT
- BEG
;
904 XFASTINT (w
->last_point
) = point
;
905 XFASTINT (w
->last_point_x
) = hpos
;
906 XFASTINT (w
->last_modified
) = MODIFF
;
908 reassert_line_highlight (0, vpos
);
909 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
911 ++FRAME_CURSOR_X (frame
);
912 if (hpos
== current_frame
->used
[vpos
])
914 current_frame
->used
[vpos
] = hpos
+ 1;
915 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
922 direct_output_forward_char (n
)
925 register FRAME_PTR frame
= selected_frame
;
926 register struct window
*w
= XWINDOW (selected_window
);
928 int hpos
= FRAME_CURSOR_X (frame
);
930 /* Give up if in truncated text at end of line. */
931 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1)
934 /* Avoid losing if cursor is in invisible text off left margin
935 or about to go off either side of window. */
936 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
937 && (XINT (w
->hscroll
) || n
< 0))
939 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
940 || cursor_in_echo_area
)
943 /* Can't use direct output if highlighting a region. */
944 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
947 #ifdef USE_TEXT_PROPERTIES
948 /* Don't use direct output next to an invisible character
949 since we might need to do something special. */
951 XFASTINT (position
) = point
;
952 if (XFASTINT (position
) < ZV
953 && ! NILP (Fget_char_property (position
,
958 XFASTINT (position
) = point
- 1;
959 if (XFASTINT (position
) >= BEGV
960 && ! NILP (Fget_char_property (position
,
966 FRAME_CURSOR_X (frame
) += n
;
967 XFASTINT (w
->last_point_x
) = FRAME_CURSOR_X (frame
);
968 XFASTINT (w
->last_point
) = point
;
969 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
975 static void update_line ();
977 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
978 Value is nonzero if redisplay stopped due to pending input.
979 FORCE nonzero means do not stop for pending input. */
982 update_frame (f
, force
, inhibit_hairy_id
)
985 int inhibit_hairy_id
;
987 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (f
);
988 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (f
);
991 int preempt_count
= baud_rate
/ 2400 + 1;
992 extern input_pending
;
993 #ifdef HAVE_X_WINDOWS
994 register int downto
, leftmost
;
997 if (preempt_count
<= 0)
1000 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1002 detect_input_pending ();
1003 if (input_pending
&& !force
)
1011 if (!line_ins_del_ok
)
1012 inhibit_hairy_id
= 1;
1014 /* See if any of the desired lines are enabled; don't compute for
1015 i/d line if just want cursor motion. */
1016 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1017 if (desired_frame
->enable
[i
])
1020 /* Try doing i/d line, if not yet inhibited. */
1021 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1022 force
|= scrolling (f
);
1024 /* Update the individual lines as needed. Do bottom line first. */
1026 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1027 update_line (f
, FRAME_HEIGHT (f
) - 1);
1029 #ifdef HAVE_X_WINDOWS
1032 leftmost
= downto
= f
->display
.x
->internal_border_width
;
1033 if (desired_frame
->enable
[0])
1035 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1036 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1037 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
1038 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1039 current_frame
->top_left_x
[0] = leftmost
;
1040 current_frame
->top_left_y
[0] = downto
;
1043 #endif /* HAVE_X_WINDOWS */
1045 /* Now update the rest of the lines. */
1046 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1048 if (desired_frame
->enable
[i
])
1050 if (FRAME_TERMCAP_P (f
))
1052 /* Flush out every so many lines.
1053 Also flush out if likely to have more than 1k buffered
1054 otherwise. I'm told that some telnet connections get
1055 really screwed by more than 1k output at once. */
1056 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1058 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1061 if (preempt_count
== 1)
1063 #ifdef EMACS_OUTQSIZE
1064 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1065 /* Probably not a tty. Ignore the error and reset
1066 * the outq count. */
1067 outq
= PENDING_OUTPUT_COUNT (stdout
);
1070 if (baud_rate
>= outq
)
1071 sleep (outq
/ baud_rate
);
1074 if ((i
- 1) % preempt_count
== 0)
1075 detect_input_pending ();
1079 #ifdef HAVE_X_WINDOWS
1082 current_frame
->top_left_y
[i
] = downto
;
1083 current_frame
->top_left_x
[i
] = leftmost
;
1085 #endif /* HAVE_X_WINDOWS */
1088 #ifdef HAVE_X_WINDOWS
1090 downto
+= current_frame
->pix_height
[i
];
1093 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1095 /* Now just clean up termcap drivers and set cursor, etc. */
1098 if (cursor_in_echo_area
1099 && FRAME_HAS_MINIBUF_P (f
))
1101 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1104 if (cursor_in_echo_area
< 0)
1111 /* If the minibuffer is several lines high, find the last
1112 line that has any text on it. */
1113 row
= FRAME_HEIGHT (f
);
1117 if (current_frame
->enable
[row
])
1118 col
= current_frame
->used
[row
];
1122 while (row
> top
&& col
== 0);
1124 if (col
>= FRAME_WIDTH (f
))
1127 if (row
< FRAME_HEIGHT (f
) - 1)
1132 cursor_to (row
, col
);
1135 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1136 FRAME_WIDTH (f
) - 1), 0));
1142 fflush (termscript
);
1145 /* Here if output is preempted because input is detected. */
1148 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1149 display_completed
= !pause
;
1151 bzero (desired_frame
->enable
, FRAME_HEIGHT (f
));
1155 /* Called when about to quit, to check for doing so
1156 at an improper time. */
1161 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1163 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1165 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1169 /* Decide what insert/delete line to do, and do it */
1171 extern void scrolling_1 ();
1176 int unchanged_at_top
, unchanged_at_bottom
;
1179 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1180 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1181 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1183 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1184 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1185 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1187 /* Compute hash codes of all the lines.
1188 Also calculate number of changed lines,
1189 number of unchanged lines at the beginning,
1190 and number of unchanged lines at the end. */
1193 unchanged_at_top
= 0;
1194 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1195 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1197 /* Give up on this scrolling if some old lines are not enabled. */
1198 if (!current_frame
->enable
[i
])
1200 old_hash
[i
] = line_hash_code (current_frame
, i
);
1201 if (! desired_frame
->enable
[i
])
1202 new_hash
[i
] = old_hash
[i
];
1204 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1206 if (old_hash
[i
] != new_hash
[i
])
1209 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1211 else if (i
== unchanged_at_top
)
1213 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1216 /* If changed lines are few, don't allow preemption, don't scroll. */
1217 if (changed_lines
< baud_rate
/ 2400
1218 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1221 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1222 - unchanged_at_bottom
);
1224 if (scroll_region_ok
)
1225 free_at_end_vpos
-= unchanged_at_bottom
;
1226 else if (memory_below_frame
)
1227 free_at_end_vpos
= -1;
1229 /* If large window, fast terminal and few lines in common between
1230 current frame and desired frame, don't bother with i/d calc. */
1231 if (window_size
>= 18 && baud_rate
> 2400
1233 10 * scrolling_max_lines_saved (unchanged_at_top
,
1234 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1235 old_hash
, new_hash
, draw_cost
)))
1238 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1239 draw_cost
+ unchanged_at_top
- 1,
1240 old_hash
+ unchanged_at_top
- 1,
1241 new_hash
+ unchanged_at_top
- 1,
1242 free_at_end_vpos
- unchanged_at_top
);
1247 /* Return the offset in its buffer of the character at location col, line
1248 in the given window. */
1250 buffer_posn_from_coords (window
, col
, line
)
1251 struct window
*window
;
1254 int hscroll
= XINT (window
->hscroll
);
1255 int window_left
= XFASTINT (window
->left
);
1257 /* The actual width of the window is window->width less one for the
1258 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1260 int window_width
= window_internal_width (window
) - 1;
1262 int startp
= marker_position (window
->start
);
1264 /* Since compute_motion will only operate on the current buffer,
1265 we need to save the old one and restore it when we're done. */
1266 struct buffer
*old_current_buffer
= current_buffer
;
1267 struct position
*posn
;
1269 current_buffer
= XBUFFER (window
->buffer
);
1271 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1272 (window->frame))->bufp to avoid scanning from the very top of
1273 the window, but it isn't maintained correctly, and I'm not even
1274 sure I will keep it. */
1275 posn
= compute_motion (startp
, 0,
1276 (window
== XWINDOW (minibuf_window
) && startp
== 1
1277 ? minibuf_prompt_width
: 0)
1278 + (hscroll
? 1 - hscroll
: 0),
1280 window_width
, hscroll
, 0);
1282 current_buffer
= old_current_buffer
;
1284 /* compute_motion considers frame points past the end of a line
1285 to be *after* the newline, i.e. at the start of the next line.
1286 This is reasonable, but not really what we want. So if the
1287 result is on a line below LINE, back it up one character. */
1288 if (posn
->vpos
> line
)
1289 return posn
->bufpos
- 1;
1291 return posn
->bufpos
;
1298 register GLYPH
*p
= r
;
1299 while (*p
++ == SPACEGLYPH
);
1304 count_match (str1
, str2
)
1307 register GLYPH
*p1
= str1
;
1308 register GLYPH
*p2
= str2
;
1309 while (*p1
++ == *p2
++);
1310 return p1
- str1
- 1;
1313 /* Char insertion/deletion cost vector, from term.c */
1314 extern int *char_ins_del_vector
;
1316 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1319 update_line (frame
, vpos
)
1320 register FRAME_PTR frame
;
1323 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1325 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1327 register struct frame_glyphs
*current_frame
1328 = FRAME_CURRENT_GLYPHS (frame
);
1329 register struct frame_glyphs
*desired_frame
1330 = FRAME_DESIRED_GLYPHS (frame
);
1332 if (desired_frame
->highlight
[vpos
]
1333 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1335 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1336 (current_frame
->enable
[vpos
] ?
1337 current_frame
->used
[vpos
] : 0));
1338 current_frame
->enable
[vpos
] = 0;
1341 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1343 if (! current_frame
->enable
[vpos
])
1349 obody
= current_frame
->glyphs
[vpos
];
1350 olen
= current_frame
->used
[vpos
];
1351 if (! current_frame
->highlight
[vpos
])
1353 if (!must_write_spaces
)
1354 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1359 /* For an inverse-video line, remember we gave it
1360 spaces all the way to the frame edge
1361 so that the reverse video extends all the way across. */
1363 while (olen
< FRAME_WIDTH (frame
) - 1)
1364 obody
[olen
++] = SPACEGLYPH
;
1368 /* One way or another, this will enable the line being updated. */
1369 current_frame
->enable
[vpos
] = 1;
1370 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1371 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1372 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1374 #ifdef HAVE_X_WINDOWS
1375 if (FRAME_X_P (frame
))
1377 current_frame
->pix_width
[vpos
]
1378 = current_frame
->used
[vpos
]
1379 * FONT_WIDTH (frame
->display
.x
->font
);
1380 current_frame
->pix_height
[vpos
]
1381 = FONT_HEIGHT (frame
->display
.x
->font
);
1383 #endif /* HAVE_X_WINDOWS */
1385 if (!desired_frame
->enable
[vpos
])
1391 nbody
= desired_frame
->glyphs
[vpos
];
1392 nlen
= desired_frame
->used
[vpos
];
1394 /* Pretend trailing spaces are not there at all,
1395 unless for one reason or another we must write all spaces. */
1396 if (! desired_frame
->highlight
[vpos
])
1398 if (!must_write_spaces
)
1399 /* We know that the previous character byte contains 0. */
1400 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1405 /* For an inverse-video line, give it extra trailing spaces
1406 all the way to the frame edge
1407 so that the reverse video extends all the way across. */
1409 while (nlen
< FRAME_WIDTH (frame
) - 1)
1410 nbody
[nlen
++] = SPACEGLYPH
;
1413 /* If there's no i/d char, quickly do the best we can without it. */
1414 if (!char_ins_del_ok
)
1419 if (FRAME_X_P (frame
))
1421 /* Under X, erase everything we are going to rewrite,
1422 and rewrite everything from the first char that's changed.
1423 This is part of supporting fonts like Courier
1424 whose chars can overlap outside the char width. */
1425 for (i
= 0; i
< nlen
; i
++)
1426 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1429 cursor_to (vpos
, i
);
1431 clear_end_of_line (olen
);
1432 write_glyphs (nbody
+ i
, nlen
- i
);
1437 for (i
= 0; i
< nlen
; i
++)
1439 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1441 cursor_to (vpos
, i
);
1442 for (j
= 1; (i
+ j
< nlen
&&
1443 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1446 /* Output this run of non-matching chars. */
1447 write_glyphs (nbody
+ i
, j
);
1450 /* Now find the next non-match. */
1454 /* Clear the rest of the line, or the non-clear part of it. */
1457 cursor_to (vpos
, nlen
);
1458 clear_end_of_line (olen
);
1461 /* Exchange contents between current_frame and new_frame. */
1462 temp
= desired_frame
->glyphs
[vpos
];
1463 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1464 current_frame
->glyphs
[vpos
] = temp
;
1471 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1472 ? 0 : count_blanks (nbody
);
1475 cursor_to (vpos
, nsp
);
1476 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1479 /* Exchange contents between current_frame and new_frame. */
1480 temp
= desired_frame
->glyphs
[vpos
];
1481 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1482 current_frame
->glyphs
[vpos
] = temp
;
1491 /* Compute number of leading blanks in old and new contents. */
1492 osp
= count_blanks (obody
);
1493 if (!desired_frame
->highlight
[vpos
])
1494 nsp
= count_blanks (nbody
);
1498 /* Compute number of matching chars starting with first nonblank. */
1499 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1501 /* Spaces in new match implicit space past the end of old. */
1502 /* A bug causing this to be a no-op was fixed in 18.29. */
1503 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1506 while (np1
[begmatch
] == SPACEGLYPH
)
1510 /* Avoid doing insert/delete char
1511 just cause number of leading spaces differs
1512 when the following text does not match. */
1513 if (begmatch
== 0 && osp
!= nsp
)
1514 osp
= nsp
= min (osp
, nsp
);
1516 /* Find matching characters at end of line */
1519 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1520 while (op1
> op2
&& op1
[-1] == np1
[-1])
1525 endmatch
= obody
+ olen
- op1
;
1527 /* Put correct value back in nbody[nlen].
1528 This is important because direct_output_for_insert
1529 can write into the line at a later point.
1530 If this screws up the zero at the end of the line, re-establish it. */
1534 /* tem gets the distance to insert or delete.
1535 endmatch is how many characters we save by doing so.
1538 tem
= (nlen
- nsp
) - (olen
- osp
);
1540 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1543 /* nsp - osp is the distance to insert or delete.
1544 If that is nonzero, begmatch is known to be nonzero also.
1545 begmatch + endmatch is how much we save by doing the ins/del.
1549 && (!char_ins_del_ok
1550 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1554 osp
= nsp
= min (osp
, nsp
);
1557 /* Now go through the line, inserting, writing and
1558 deleting as appropriate. */
1562 cursor_to (vpos
, nsp
);
1563 delete_glyphs (osp
- nsp
);
1567 /* If going to delete chars later in line
1568 and insert earlier in the line,
1569 must delete first to avoid losing data in the insert */
1570 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1572 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1573 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1574 olen
= nlen
- (nsp
- osp
);
1576 cursor_to (vpos
, osp
);
1577 insert_glyphs ((char *)0, nsp
- osp
);
1581 tem
= nsp
+ begmatch
+ endmatch
;
1582 if (nlen
!= tem
|| olen
!= tem
)
1584 cursor_to (vpos
, nsp
+ begmatch
);
1585 if (!endmatch
|| nlen
== olen
)
1587 /* If new text being written reaches right margin,
1588 there is no need to do clear-to-eol at the end.
1589 (and it would not be safe, since cursor is not
1590 going to be "at the margin" after the text is done) */
1591 if (nlen
== FRAME_WIDTH (frame
))
1593 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1597 /* the following code loses disastrously if tem == nlen.
1598 Rather than trying to fix that case, I am trying the simpler
1599 solution found above. */
1601 /* If the text reaches to the right margin,
1602 it will lose one way or another (depending on AutoWrap)
1603 to clear to end of line after outputting all the text.
1604 So pause with one character to go and clear the line then. */
1605 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1607 /* endmatch must be zero, and tem must equal nsp + begmatch */
1608 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1609 clear_end_of_line (olen
);
1610 olen
= 0; /* Don't let it be cleared again later */
1611 write_glyphs (nbody
+ nlen
- 1, 1);
1614 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1615 #endif /* OBSOLETE */
1618 else if (nlen
> olen
)
1620 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1621 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1624 else if (olen
> nlen
)
1626 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1627 delete_glyphs (olen
- nlen
);
1633 /* If any unerased characters remain after the new line, erase them. */
1636 cursor_to (vpos
, nlen
);
1637 clear_end_of_line (olen
);
1640 /* Exchange contents between current_frame and new_frame. */
1641 temp
= desired_frame
->glyphs
[vpos
];
1642 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1643 current_frame
->glyphs
[vpos
] = temp
;
1646 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1647 1, 1, "FOpen termscript file: ",
1648 "Start writing all terminal output to FILE as well as the terminal.\n\
1649 FILE = nil means just close any termscript file currently open.")
1653 if (termscript
!= 0) fclose (termscript
);
1658 file
= Fexpand_file_name (file
, Qnil
);
1659 termscript
= fopen (XSTRING (file
)->data
, "w");
1660 if (termscript
== 0)
1661 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1669 window_change_signal ()
1673 int old_errno
= errno
;
1675 get_frame_size (&width
, &height
);
1677 /* The frame size change obviously applies to a termcap-controlled
1678 frame. Find such a frame in the list, and assume it's the only
1679 one (since the redisplay code always writes to stdout, not a
1680 FILE * specified in the frame structure). Record the new size,
1681 but don't reallocate the data structures now. Let that be done
1682 later outside of the signal handler. */
1685 Lisp_Object tail
, frame
;
1687 FOR_EACH_FRAME (tail
, frame
)
1689 if (FRAME_TERMCAP_P (XFRAME (frame
)))
1691 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
1697 signal (SIGWINCH
, window_change_signal
);
1700 #endif /* SIGWINCH */
1703 /* Do any change in frame size that was requested by a signal. */
1705 do_pending_window_change ()
1707 /* If window_change_signal should have run before, run it now. */
1708 while (delayed_size_change
)
1710 Lisp_Object tail
, frame
;
1712 delayed_size_change
= 0;
1714 FOR_EACH_FRAME (tail
, frame
)
1716 FRAME_PTR f
= XFRAME (frame
);
1718 int height
= FRAME_NEW_HEIGHT (f
);
1719 int width
= FRAME_NEW_WIDTH (f
);
1721 if (height
!= 0 || width
!= 0)
1722 change_frame_size (f
, height
, width
, 0, 0);
1728 /* Change the frame height and/or width. Values may be given as zero to
1729 indicate no change is to take place.
1731 If DELAY is non-zero, then assume we're being called from a signal
1732 handler, and queue the change for later - perhaps the next
1733 redisplay. Since this tries to resize windows, we can't call it
1734 from a signal handler. */
1736 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
1737 register FRAME_PTR frame
;
1738 int newheight
, newwidth
, pretend
;
1740 /* If we can't deal with the change now, queue it for later. */
1743 FRAME_NEW_HEIGHT (frame
) = newheight
;
1744 FRAME_NEW_WIDTH (frame
) = newwidth
;
1745 delayed_size_change
= 1;
1749 /* This size-change overrides any pending one for this frame. */
1750 FRAME_NEW_HEIGHT (frame
) = 0;
1751 FRAME_NEW_WIDTH (frame
) = 0;
1753 /* If an argument is zero, set it to the current value. */
1754 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
1755 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
1757 /* Round up to the smallest acceptable size. */
1758 check_frame_size (frame
, &newheight
, &newwidth
);
1760 /* If we're not changing the frame size, quit now. */
1761 if (newheight
== FRAME_HEIGHT (frame
)
1762 && newwidth
== FRAME_WIDTH (frame
))
1765 if (newheight
!= FRAME_HEIGHT (frame
))
1767 if (FRAME_HAS_MINIBUF_P (frame
)
1768 && ! FRAME_MINIBUF_ONLY_P (frame
))
1770 /* Frame has both root and minibuffer. */
1771 set_window_height (FRAME_ROOT_WINDOW (frame
),
1772 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
1773 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
)
1775 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
1778 /* Frame has just one top-level window. */
1779 set_window_height (FRAME_ROOT_WINDOW (frame
),
1780 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
1782 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1783 FrameRows
= newheight
;
1786 if (frame
->output_method
== output_termcap
)
1788 frame_height
= newheight
;
1790 FrameRows
= newheight
;
1795 if (newwidth
!= FRAME_WIDTH (frame
))
1797 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
1798 if (FRAME_HAS_MINIBUF_P (frame
))
1799 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
1801 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1802 FrameCols
= newwidth
;
1804 if (frame
->output_method
== output_termcap
)
1806 frame_width
= newwidth
;
1808 FrameCols
= newwidth
;
1813 FRAME_HEIGHT (frame
) = newheight
;
1814 FRAME_WIDTH (frame
) = newwidth
;
1816 remake_frame_glyphs (frame
);
1817 calculate_costs (frame
);
1820 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
1821 Ssend_string_to_terminal
, 1, 1, 0,
1822 "Send STRING to the terminal without alteration.\n\
1823 Control characters in STRING will have terminal-dependent effects.")
1827 CHECK_STRING (str
, 0);
1828 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
1832 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
1833 fflush (termscript
);
1838 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
1839 "Beep, or flash the screen.\n\
1840 Also, unless an argument is given,\n\
1841 terminate any keyboard macro currently executing.")
1863 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
1864 error ("Keyboard macro terminated by a command ringing the bell");
1870 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
1871 "Pause, without updating display, for SECONDS seconds.\n\
1872 SECONDS may be a floating-point value, meaning that you can wait for a\n\
1873 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
1874 additional wait period, in milliseconds; this may be useful if your\n\
1875 Emacs was built without floating point support.\n\
1876 \(Not all operating systems support waiting for a fraction of a second.)")
1877 (seconds
, milliseconds
)
1878 Lisp_Object seconds
, milliseconds
;
1882 if (NILP (milliseconds
))
1883 XSET (milliseconds
, Lisp_Int
, 0);
1885 CHECK_NUMBER (milliseconds
, 1);
1886 usec
= XINT (milliseconds
) * 1000;
1888 #ifdef LISP_FLOAT_TYPE
1890 double duration
= extract_float (seconds
);
1891 sec
= (int) duration
;
1892 usec
+= (duration
- sec
) * 1000000;
1895 CHECK_NUMBER (seconds
, 0);
1896 sec
= XINT (seconds
);
1899 #ifndef EMACS_HAS_USECS
1900 if (sec
== 0 && usec
!= 0)
1901 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
1904 /* Assure that 0 <= usec < 1000000. */
1907 /* We can't rely on the rounding being correct if user is negative. */
1908 if (-1000000 < usec
)
1909 sec
--, usec
+= 1000000;
1911 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
1914 sec
+= usec
/ 1000000, usec
%= 1000000;
1922 XFASTINT (zero
) = 0;
1923 wait_reading_process_input (sec
, usec
, zero
, 0);
1926 /* We should always have wait_reading_process_input; we have a dummy
1927 implementation for systems which don't support subprocesses. */
1929 /* No wait_reading_process_input */
1936 /* The reason this is done this way
1937 (rather than defined (H_S) && defined (H_T))
1938 is because the VMS preprocessor doesn't grok `defined' */
1940 EMACS_GET_TIME (end_time
);
1941 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
1942 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
1946 EMACS_GET_TIME (timeout
);
1947 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
1948 if (EMACS_TIME_NEG_P (timeout
)
1949 || !select (1, 0, 0, 0, &timeout
))
1952 #else /* not HAVE_SELECT */
1954 #endif /* HAVE_SELECT */
1955 #endif /* not VMS */
1958 #endif /* no subprocesses */
1963 /* This is just like wait_reading_process_input, except that
1964 it does the redisplay.
1966 It's also much like Fsit_for, except that it can be used for
1967 waiting for input as well. One differnce is that sit_for
1968 does not call prepare_menu_bars; Fsit_for does call that. */
1971 sit_for (sec
, usec
, reading
, display
)
1972 int sec
, usec
, reading
, display
;
1974 Lisp_Object read_kbd
;
1976 if (detect_input_pending ())
1980 redisplay_preserve_echo_area ();
1982 if (sec
== 0 && usec
== 0)
1989 XSET (read_kbd
, Lisp_Int
, reading
? -1 : 1);
1990 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
1993 /* wait_reading_process_input should always be available now; it is
1994 simulated in a simple way on systems that don't support
1997 /* No wait_reading_process_input available. */
2003 input_wait_timeout (XINT (arg
));
2005 #ifndef HAVE_TIMEVAL
2007 select (1, &waitchannels
, 0, 0, &timeout_sec
);
2008 #else /* HAVE_TIMEVAL */
2009 timeout
.tv_sec
= sec
;
2010 timeout
.tv_usec
= usec
;
2011 select (1, &waitchannels
, 0, 0, &timeout
);
2012 #endif /* HAVE_TIMEVAL */
2013 #endif /* not VMS */
2018 return detect_input_pending () ? Qnil
: Qt
;
2021 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2022 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2023 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2024 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2025 additional wait period, in milliseconds; this may be useful if your\n\
2026 Emacs was built without floating point support.\n\
2027 \(Not all operating systems support waiting for a fraction of a second.)\n\
2028 Optional third arg non-nil means don't redisplay, just wait for input.\n\
2029 Redisplay is preempted as always if input arrives, and does not happen\n\
2030 if input is available before it starts.\n\
2031 Value is t if waited the full time with no input arriving.")
2032 (seconds
, milliseconds
, nodisp
)
2033 Lisp_Object seconds
, milliseconds
, nodisp
;
2037 if (NILP (milliseconds
))
2038 XSET (milliseconds
, Lisp_Int
, 0);
2040 CHECK_NUMBER (milliseconds
, 1);
2041 usec
= XINT (milliseconds
) * 1000;
2043 #ifdef LISP_FLOAT_TYPE
2045 double duration
= extract_float (seconds
);
2046 sec
= (int) duration
;
2047 usec
+= (duration
- sec
) * 1000000;
2050 CHECK_NUMBER (seconds
, 0);
2051 sec
= XINT (seconds
);
2054 #ifndef EMACS_HAS_USECS
2055 if (usec
!= 0 && sec
== 0)
2056 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2060 prepare_menu_bars ();
2061 return sit_for (sec
, usec
, 0, NILP (nodisp
));
2064 char *terminal_type
;
2066 /* Initialization done when Emacs fork is started, before doing stty. */
2067 /* Determine terminal type and set terminal_driver */
2068 /* Then invoke its decoding routine to set up variables
2069 in the terminal package */
2073 #ifdef HAVE_X_WINDOWS
2074 extern int display_arg
;
2079 cursor_in_echo_area
= 0;
2080 terminal_type
= (char *) 0;
2082 /* Now is the time to initialize this; it's used by init_sys_modes
2084 Vwindow_system
= Qnil
;
2086 /* If the user wants to use a window system, we shouldn't bother
2087 initializing the terminal. This is especially important when the
2088 terminal is so dumb that emacs gives up before and doesn't bother
2089 using the window system.
2091 If the DISPLAY environment variable is set, try to use X, and die
2092 with an error message if that doesn't work. */
2094 #ifdef HAVE_X_WINDOWS
2098 display_arg
= (getenv ("DECW$DISPLAY") != 0);
2100 display_arg
= (getenv ("DISPLAY") != 0);
2104 if (!inhibit_window_system
&& display_arg
)
2106 Vwindow_system
= intern ("x");
2108 Vwindow_system_version
= make_number (11);
2110 Vwindow_system_version
= make_number (10);
2114 #endif /* HAVE_X_WINDOWS */
2116 /* If no window system has been specified, try to use the terminal. */
2119 fprintf (stderr
, "emacs: standard input is not a tty\n");
2123 /* Look at the TERM variable */
2124 terminal_type
= (char *) getenv ("TERM");
2128 fprintf (stderr
, "Please specify your terminal type.\n\
2129 For types defined in VMS, use set term /device=TYPE.\n\
2130 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2131 \(The quotation marks are necessary since terminal types are lower case.)\n");
2133 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2139 /* VMS DCL tends to upcase things, so downcase term type.
2140 Hardly any uppercase letters in terminal types; should be none. */
2142 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2145 strcpy (new, terminal_type
);
2147 for (p
= new; *p
; p
++)
2151 terminal_type
= new;
2155 term_init (terminal_type
);
2157 remake_frame_glyphs (selected_frame
);
2158 calculate_costs (selected_frame
);
2160 /* X and Y coordinates of the cursor between updates. */
2161 FRAME_CURSOR_X (selected_frame
) = 0;
2162 FRAME_CURSOR_Y (selected_frame
) = 0;
2167 #endif /* CANNOT_DUMP */
2168 signal (SIGWINCH
, window_change_signal
);
2169 #endif /* SIGWINCH */
2175 defsubr (&Sredraw_frame
);
2177 defsubr (&Sredraw_display
);
2178 defsubr (&Sopen_termscript
);
2180 defsubr (&Ssit_for
);
2181 defsubr (&Ssleep_for
);
2182 defsubr (&Ssend_string_to_terminal
);
2184 DEFVAR_INT ("baud-rate", &baud_rate
,
2185 "The output baud rate of the terminal.\n\
2186 On most systems, changing this value will affect the amount of padding\n\
2187 and the other strategic decisions made during redisplay.");
2188 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2189 "*Non-nil means invert the entire frame display.\n\
2190 This means everything is in inverse video which otherwise would not be.");
2191 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2192 "*Non-nil means try to flash the frame to represent a bell.");
2193 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2194 "*Non-nil means no need to redraw entire frame after suspending.\n\
2195 A non-nil value is useful if the terminal can automatically preserve\n\
2196 Emacs's frame display when you reenter Emacs.\n\
2197 It is up to you to set this variable if your terminal can do that.");
2198 DEFVAR_LISP ("window-system", &Vwindow_system
,
2199 "A symbol naming the window-system under which Emacs is running\n\
2200 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2201 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2202 "The version number of the window system in use.\n\
2203 For X windows, this is 10 or 11.");
2204 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2205 "Non-nil means put cursor in minibuffer, at end of any message there.");
2206 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2207 "Table defining how to output a glyph code to the frame.\n\
2208 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2209 Each element can be:\n\
2210 integer: a glyph code which this glyph is an alias for.\n\
2211 string: output this glyph using that string (not impl. in X windows).\n\
2212 nil: this glyph mod 256 is char code to output,\n\
2213 and this glyph / 256 is face code for X windows (see `x-set-face').");
2214 Vglyph_table
= Qnil
;
2216 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2217 "Display table to use for buffers that specify none.\n\
2218 See `buffer-display-table' for more information.");
2219 Vstandard_display_table
= Qnil
;
2221 /* Initialize `window-system', unless init_display already decided it. */
2226 Vwindow_system
= Qnil
;
2227 Vwindow_system_version
= Qnil
;