1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95 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. */
31 #include "termhooks.h"
32 /* cm.h must come after dispextern.h on Windows. */
33 #include "dispextern.h"
41 #include "intervals.h"
44 #include "syssignal.h"
48 #endif /* HAVE_X_WINDOWS */
52 #endif /* HAVE_NTGUI */
54 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
59 #define max(a, b) ((a) > (b) ? (a) : (b))
60 #define min(a, b) ((a) < (b) ? (a) : (b))
62 /* Get number of chars of output now in the buffer of a stdio stream.
63 This ought to be built in in stdio, but it isn't.
64 Some s- files override this because their stdio internals differ. */
65 #ifdef __GNU_LIBRARY__
66 /* The s- file might have overridden the definition with one that works for
67 the system's C library. But we are using the GNU C library, so this is
68 the right definition for every system. */
69 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
70 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
72 #undef PENDING_OUTPUT_COUNT
73 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
75 #else /* not __GNU_LIBRARY__ */
76 #ifndef PENDING_OUTPUT_COUNT
77 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
81 static void change_frame_size_1 ();
83 /* Nonzero upon entry to redisplay means do not assume anything about
84 current contents of actual terminal frame; clear and redraw it. */
88 /* Nonzero means last display completed. Zero means it was preempted. */
90 int display_completed
;
92 /* Lisp variable visible-bell; enables use of screen-flash
93 instead of audible bell. */
97 /* Invert the color of the whole frame, at a low level. */
101 /* Line speed of the terminal. */
105 /* nil or a symbol naming the window system under which emacs is
106 running ('x is the only current possibility). */
108 Lisp_Object Vwindow_system
;
110 /* Version number of X windows: 10, 11 or nil. */
111 Lisp_Object Vwindow_system_version
;
113 /* Vector of glyph definitions. Indexed by glyph number,
114 the contents are a string which is how to output the glyph.
116 If Vglyph_table is nil, a glyph is output by using its low 8 bits
117 as a character code. */
119 Lisp_Object Vglyph_table
;
121 /* Display table to use for vectors that don't specify their own. */
123 Lisp_Object Vstandard_display_table
;
125 /* Nonzero means reading single-character input with prompt
126 so put cursor on minibuffer after the prompt.
127 positive means at end of text in echo area;
128 negative means at beginning of line. */
129 int cursor_in_echo_area
;
131 Lisp_Object Qdisplay_table
;
133 /* The currently selected frame.
134 In a single-frame version, this variable always holds the address of
137 FRAME_PTR selected_frame
;
139 /* A frame which is not just a minibuffer, or 0 if there are no such
140 frames. This is usually the most recent such frame that was
141 selected. In a single-frame version, this variable always holds
142 the address of the_only_frame. */
143 FRAME_PTR last_nonminibuf_frame
;
145 /* In a single-frame version, the information that would otherwise
146 exist inside frame objects lives in the following structure instead.
148 NOTE: the_only_frame is not checked for garbage collection; don't
149 store collectible objects in any of its fields!
151 You're not/The only frame in town/... */
154 struct frame the_only_frame
;
157 /* This is a vector, made larger whenever it isn't large enough,
158 which is used inside `update_frame' to hold the old contents
159 of the FRAME_PHYS_LINES of the frame being updated. */
160 struct frame_glyphs
**ophys_lines
;
161 /* Length of vector currently allocated. */
162 int ophys_lines_length
;
164 FILE *termscript
; /* Stdio stream being used for copy of all output. */
166 struct cm Wcm
; /* Structure for info on cursor positioning */
168 extern short ospeed
; /* Output speed (from sg_ospeed) */
170 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
174 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
175 "Clear frame FRAME and output again what is supposed to appear on it.")
181 CHECK_LIVE_FRAME (frame
, 0);
184 /* set_terminal_modes (); */
186 clear_frame_records (f
);
189 windows_or_buffers_changed
++;
190 /* Mark all windows as INaccurate,
191 so that every window will have its redisplay done. */
192 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
201 XSETFRAME (frame
, f
);
202 Fredraw_frame (frame
);
207 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
208 /* Don't confuse make-docfile by having two doc strings for this function.
209 make-docfile does not pay attention to #if, for good reason! */
215 set_terminal_modes ();
219 clear_frame_records (0);
220 windows_or_buffers_changed
++;
221 /* Mark all windows as INaccurate,
222 so that every window will have its redisplay done. */
223 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
229 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
230 "Clear and redisplay all visible frames.")
233 Lisp_Object tail
, frame
;
235 FOR_EACH_FRAME (tail
, frame
)
236 if (FRAME_VISIBLE_P (XFRAME (frame
)))
237 Fredraw_frame (frame
);
242 /* This is used when frame_garbaged is set.
243 Redraw the individual frames marked as garbaged. */
246 redraw_garbaged_frames ()
248 Lisp_Object tail
, frame
;
250 FOR_EACH_FRAME (tail
, frame
)
251 if (FRAME_VISIBLE_P (XFRAME (frame
))
252 && FRAME_GARBAGED_P (XFRAME (frame
)))
253 Fredraw_frame (frame
);
257 static struct frame_glyphs
*
258 make_frame_glyphs (frame
, empty
)
259 register FRAME_PTR frame
;
263 register width
= FRAME_WIDTH (frame
);
264 register height
= FRAME_HEIGHT (frame
);
265 register struct frame_glyphs
*new
266 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
268 SET_GLYPHS_FRAME (new, frame
);
269 new->height
= height
;
271 new->used
= (int *) xmalloc (height
* sizeof (int));
272 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
273 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
274 new->highlight
= (char *) xmalloc (height
* sizeof (char));
275 new->enable
= (char *) xmalloc (height
* sizeof (char));
276 bzero (new->enable
, height
* sizeof (char));
277 new->bufp
= (int *) xmalloc (height
* sizeof (int));
279 #ifdef HAVE_WINDOW_SYSTEM
280 if (FRAME_WINDOW_P (frame
))
282 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
283 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
284 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
285 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
286 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
288 #endif /* HAVE_WINDOW_SYSTEM */
292 /* Make the buffer used by decode_mode_spec. This buffer is also
293 used as temporary storage when updating the frame. See scroll.c. */
294 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
295 unsigned int total_charstarts
= (width
+ 2) * sizeof (int);
297 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
298 bzero (new->total_contents
, total_glyphs
);
300 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
301 bzero (new->total_charstarts
, total_glyphs
);
305 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
307 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
308 bzero (new->total_contents
, total_glyphs
);
309 for (i
= 0; i
< height
; i
++)
310 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
312 if (!FRAME_TERMCAP_P (frame
))
314 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
316 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
317 bzero (new->total_charstarts
, total_charstarts
);
318 for (i
= 0; i
< height
; i
++)
319 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
323 /* Without a window system, we don't really need charstarts.
324 So use a small amount of space to make enough data structure
325 to prevent crashes in display_text_line. */
326 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
327 for (i
= 0; i
< height
; i
++)
328 new->charstarts
[i
] = new->total_charstarts
;
336 free_frame_glyphs (frame
, glyphs
)
338 struct frame_glyphs
*glyphs
;
340 if (glyphs
->total_contents
)
341 xfree (glyphs
->total_contents
);
342 if (glyphs
->total_charstarts
)
343 xfree (glyphs
->total_charstarts
);
345 xfree (glyphs
->used
);
346 xfree (glyphs
->glyphs
);
347 xfree (glyphs
->highlight
);
348 xfree (glyphs
->enable
);
349 xfree (glyphs
->bufp
);
350 if (glyphs
->charstarts
)
351 xfree (glyphs
->charstarts
);
353 #ifdef HAVE_WINDOW_SYSTEM
354 if (FRAME_WINDOW_P (frame
))
356 xfree (glyphs
->top_left_x
);
357 xfree (glyphs
->top_left_y
);
358 xfree (glyphs
->pix_width
);
359 xfree (glyphs
->pix_height
);
360 xfree (glyphs
->max_ascent
);
362 #endif /* HAVE_WINDOW_SYSTEM */
368 remake_frame_glyphs (frame
)
371 if (FRAME_CURRENT_GLYPHS (frame
))
372 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
373 if (FRAME_DESIRED_GLYPHS (frame
))
374 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
375 if (FRAME_TEMP_GLYPHS (frame
))
376 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
378 if (FRAME_MESSAGE_BUF (frame
))
380 /* Reallocate the frame's message buffer; remember that
381 echo_area_glyphs may be pointing here. */
382 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
384 FRAME_MESSAGE_BUF (frame
)
385 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
386 FRAME_WIDTH (frame
) + 1);
388 if (echo_area_glyphs
== old_message_buf
)
389 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
390 if (previous_echo_glyphs
== old_message_buf
)
391 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
394 FRAME_MESSAGE_BUF (frame
)
395 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
397 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
398 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
399 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
400 if (! FRAME_TERMCAP_P (frame
) || frame
== selected_frame
)
401 SET_FRAME_GARBAGED (frame
);
404 /* Return the hash code of contents of line VPOS in frame-matrix M. */
407 line_hash_code (m
, vpos
)
408 register struct frame_glyphs
*m
;
411 register GLYPH
*body
, *end
;
414 if (!m
->enable
[vpos
])
417 /* Give all highlighted lines the same hash code
418 so as to encourage scrolling to leave them in place. */
419 if (m
->highlight
[vpos
])
422 body
= m
->glyphs
[vpos
];
424 if (must_write_spaces
)
431 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
440 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
448 /* Return number of characters in line in M at vpos VPOS,
449 except don't count leading and trailing spaces
450 unless the terminal requires those to be explicitly output. */
453 line_draw_cost (m
, vpos
)
454 struct frame_glyphs
*m
;
457 register GLYPH
*beg
= m
->glyphs
[vpos
];
458 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
460 register int tlen
= GLYPH_TABLE_LENGTH
;
461 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
463 /* Ignore trailing and leading spaces if we can. */
464 if (!must_write_spaces
)
466 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
469 return (0); /* All blank line. */
471 while (*beg
== SPACEGLYPH
)
475 /* If we don't have a glyph-table, each glyph is one character,
476 so return the number of glyphs. */
480 /* Otherwise, scan the glyphs and accumulate their total size in I. */
482 while ((beg
<= end
) && *beg
)
484 register GLYPH g
= *beg
++;
486 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
489 i
+= GLYPH_LENGTH (tbase
, g
);
494 /* The functions on this page are the interface from xdisp.c to redisplay.
496 The only other interface into redisplay is through setting
497 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
498 and SET_FRAME_GARBAGED (frame). */
500 /* cancel_line eliminates any request to display a line at position `vpos' */
502 cancel_line (vpos
, frame
)
504 register FRAME_PTR frame
;
506 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
509 clear_frame_records (frame
)
510 register FRAME_PTR frame
;
512 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
515 /* Clear out all display lines for a coming redisplay. */
518 init_desired_glyphs (frame
)
519 register FRAME_PTR frame
;
521 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
523 int height
= FRAME_HEIGHT (frame
);
525 for (vpos
= 0; vpos
< height
; vpos
++)
526 desired_glyphs
->enable
[vpos
] = 0;
529 /* Prepare to display on line VPOS starting at HPOS within it. */
532 get_display_line (frame
, vpos
, hpos
)
533 register FRAME_PTR frame
;
537 register struct frame_glyphs
*glyphs
;
538 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
544 if (! desired_glyphs
->enable
[vpos
])
546 desired_glyphs
->used
[vpos
] = 0;
547 desired_glyphs
->highlight
[vpos
] = 0;
548 desired_glyphs
->enable
[vpos
] = 1;
551 if (hpos
> desired_glyphs
->used
[vpos
])
553 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
554 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
556 desired_glyphs
->used
[vpos
] = hpos
;
562 /* Like bcopy except never gets confused by overlap. */
565 safe_bcopy (from
, to
, size
)
569 if (size
<= 0 || from
== to
)
572 /* If the source and destination don't overlap, then bcopy can
573 handle it. If they do overlap, but the destination is lower in
574 memory than the source, we'll assume bcopy can handle that. */
575 if (to
< from
|| from
+ size
<= to
)
576 bcopy (from
, to
, size
);
578 /* Otherwise, we'll copy from the end. */
581 register char *endf
= from
+ size
;
582 register char *endt
= to
+ size
;
584 /* If TO - FROM is large, then we should break the copy into
585 nonoverlapping chunks of TO - FROM bytes each. However, if
586 TO - FROM is small, then the bcopy function call overhead
587 makes this not worth it. The crossover point could be about
588 anywhere. Since I don't think the obvious copy loop is too
589 bad, I'm trying to err in its favor. */
594 while (endf
!= from
);
606 bcopy (endf
, endt
, to
- from
);
609 /* If SIZE wasn't a multiple of TO - FROM, there will be a
610 little left over. The amount left over is
611 (endt + (to - from)) - to, which is endt - from. */
612 bcopy (from
, to
, endt
- from
);
617 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
618 DISTANCE may be negative. */
621 rotate_vector (vector
, size
, distance
)
626 char *temp
= (char *) alloca (size
);
631 bcopy (vector
, temp
+ distance
, size
- distance
);
632 bcopy (vector
+ size
- distance
, temp
, distance
);
633 bcopy (temp
, vector
, size
);
636 /* Scroll lines from vpos FROM up to but not including vpos END
637 down by AMOUNT lines (AMOUNT may be negative).
638 Returns nonzero if done, zero if terminal cannot scroll them. */
641 scroll_frame_lines (frame
, from
, end
, amount
, newpos
)
642 register FRAME_PTR frame
;
643 int from
, end
, amount
, newpos
;
646 register struct frame_glyphs
*current_frame
647 = FRAME_CURRENT_GLYPHS (frame
);
649 int width
= FRAME_WIDTH (frame
);
651 if (!line_ins_del_ok
)
659 update_begin (frame
);
660 set_terminal_window (end
+ amount
);
661 if (!scroll_region_ok
)
662 ins_del_lines (end
, -amount
);
663 ins_del_lines (from
, amount
);
664 set_terminal_window (0);
666 rotate_vector (current_frame
->glyphs
+ from
,
667 sizeof (GLYPH
*) * (end
+ amount
- from
),
668 amount
* sizeof (GLYPH
*));
670 rotate_vector (current_frame
->charstarts
+ from
,
671 sizeof (int *) * (end
+ amount
- from
),
672 amount
* sizeof (int *));
674 safe_bcopy (current_frame
->used
+ from
,
675 current_frame
->used
+ from
+ amount
,
676 (end
- from
) * sizeof current_frame
->used
[0]);
678 safe_bcopy (current_frame
->highlight
+ from
,
679 current_frame
->highlight
+ from
+ amount
,
680 (end
- from
) * sizeof current_frame
->highlight
[0]);
682 safe_bcopy (current_frame
->enable
+ from
,
683 current_frame
->enable
+ from
+ amount
,
684 (end
- from
) * sizeof current_frame
->enable
[0]);
686 /* Adjust the lines by an amount
687 that puts the first of them at NEWPOS. */
688 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
690 /* Offset each char position in the charstarts lines we moved
692 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
694 int *line
= current_frame
->charstarts
[i
];
696 for (col
= 0; col
< width
; col
++)
698 line
[col
] += pos_adjust
;
700 for (i
= from
; i
< from
+ amount
; i
++)
702 int *line
= current_frame
->charstarts
[i
];
705 for (col
= 0; col
< width
; col
++)
709 /* Mark the lines made empty by scrolling as enabled, empty and
711 bzero (current_frame
->used
+ from
,
712 amount
* sizeof current_frame
->used
[0]);
713 bzero (current_frame
->highlight
+ from
,
714 amount
* sizeof current_frame
->highlight
[0]);
715 for (i
= from
; i
< from
+ amount
; i
++)
717 current_frame
->glyphs
[i
][0] = '\0';
718 current_frame
->charstarts
[i
][0] = -1;
719 current_frame
->enable
[i
] = 1;
722 safe_bcopy (current_frame
->bufp
+ from
,
723 current_frame
->bufp
+ from
+ amount
,
724 (end
- from
) * sizeof current_frame
->bufp
[0]);
726 #ifdef HAVE_WINDOW_SYSTEM
727 if (FRAME_WINDOW_P (frame
))
729 safe_bcopy (current_frame
->top_left_x
+ from
,
730 current_frame
->top_left_x
+ from
+ amount
,
731 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
733 safe_bcopy (current_frame
->top_left_y
+ from
,
734 current_frame
->top_left_y
+ from
+ amount
,
735 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
737 safe_bcopy (current_frame
->pix_width
+ from
,
738 current_frame
->pix_width
+ from
+ amount
,
739 (end
- from
) * sizeof current_frame
->pix_width
[0]);
741 safe_bcopy (current_frame
->pix_height
+ from
,
742 current_frame
->pix_height
+ from
+ amount
,
743 (end
- from
) * sizeof current_frame
->pix_height
[0]);
745 safe_bcopy (current_frame
->max_ascent
+ from
,
746 current_frame
->max_ascent
+ from
+ amount
,
747 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
749 #endif /* HAVE_WINDOW_SYSTEM */
755 update_begin (frame
);
756 set_terminal_window (end
);
757 ins_del_lines (from
+ amount
, amount
);
758 if (!scroll_region_ok
)
759 ins_del_lines (end
+ amount
, -amount
);
760 set_terminal_window (0);
762 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
763 sizeof (GLYPH
*) * (end
- from
- amount
),
764 amount
* sizeof (GLYPH
*));
766 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
767 sizeof (int *) * (end
- from
- amount
),
768 amount
* sizeof (int *));
770 safe_bcopy (current_frame
->used
+ from
,
771 current_frame
->used
+ from
+ amount
,
772 (end
- from
) * sizeof current_frame
->used
[0]);
774 safe_bcopy (current_frame
->highlight
+ from
,
775 current_frame
->highlight
+ from
+ amount
,
776 (end
- from
) * sizeof current_frame
->highlight
[0]);
778 safe_bcopy (current_frame
->enable
+ from
,
779 current_frame
->enable
+ from
+ amount
,
780 (end
- from
) * sizeof current_frame
->enable
[0]);
782 /* Adjust the lines by an amount
783 that puts the first of them at NEWPOS. */
784 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
786 /* Offset each char position in the charstarts lines we moved
788 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
790 int *line
= current_frame
->charstarts
[i
];
792 for (col
= 0; col
< width
; col
++)
794 line
[col
] += pos_adjust
;
796 for (i
= end
+ amount
; i
< end
; i
++)
798 int *line
= current_frame
->charstarts
[i
];
801 for (col
= 0; col
< width
; col
++)
805 /* Mark the lines made empty by scrolling as enabled, empty and
807 bzero (current_frame
->used
+ end
+ amount
,
808 - amount
* sizeof current_frame
->used
[0]);
809 bzero (current_frame
->highlight
+ end
+ amount
,
810 - amount
* sizeof current_frame
->highlight
[0]);
811 for (i
= end
+ amount
; i
< end
; i
++)
813 current_frame
->glyphs
[i
][0] = '\0';
814 current_frame
->charstarts
[i
][0] = 0;
815 current_frame
->enable
[i
] = 1;
818 safe_bcopy (current_frame
->bufp
+ from
,
819 current_frame
->bufp
+ from
+ amount
,
820 (end
- from
) * sizeof current_frame
->bufp
[0]);
822 #ifdef HAVE_WINDOW_SYSTEM
823 if (FRAME_WINDOW_P (frame
))
825 safe_bcopy (current_frame
->top_left_x
+ from
,
826 current_frame
->top_left_x
+ from
+ amount
,
827 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
829 safe_bcopy (current_frame
->top_left_y
+ from
,
830 current_frame
->top_left_y
+ from
+ amount
,
831 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
833 safe_bcopy (current_frame
->pix_width
+ from
,
834 current_frame
->pix_width
+ from
+ amount
,
835 (end
- from
) * sizeof current_frame
->pix_width
[0]);
837 safe_bcopy (current_frame
->pix_height
+ from
,
838 current_frame
->pix_height
+ from
+ amount
,
839 (end
- from
) * sizeof current_frame
->pix_height
[0]);
841 safe_bcopy (current_frame
->max_ascent
+ from
,
842 current_frame
->max_ascent
+ from
+ amount
,
843 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
845 #endif /* HAVE_WINDOW_SYSTEM */
852 /* After updating a window W that isn't the full frame wide,
853 copy all the columns that W does not occupy
854 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
855 so that update_frame will not change those columns. */
857 preserve_other_columns (w
)
861 register struct frame_glyphs
*current_frame
, *desired_frame
;
862 register FRAME_PTR frame
= XFRAME (w
->frame
);
863 int start
= XFASTINT (w
->left
);
864 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
865 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
867 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
868 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
870 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
872 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
878 bcopy (current_frame
->glyphs
[vpos
],
879 desired_frame
->glyphs
[vpos
],
880 start
* sizeof (current_frame
->glyphs
[vpos
][0]));
881 bcopy (current_frame
->charstarts
[vpos
],
882 desired_frame
->charstarts
[vpos
],
883 start
* sizeof (current_frame
->charstarts
[vpos
][0]));
884 len
= min (start
, current_frame
->used
[vpos
]);
885 if (desired_frame
->used
[vpos
] < len
)
886 desired_frame
->used
[vpos
] = len
;
888 if (current_frame
->used
[vpos
] > end
889 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
891 while (desired_frame
->used
[vpos
] < end
)
893 int used
= desired_frame
->used
[vpos
]++;
894 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
895 desired_frame
->glyphs
[vpos
][used
] = 0;
897 bcopy (current_frame
->glyphs
[vpos
] + end
,
898 desired_frame
->glyphs
[vpos
] + end
,
899 ((current_frame
->used
[vpos
] - end
)
900 * sizeof (current_frame
->glyphs
[vpos
][0])));
901 bcopy (current_frame
->charstarts
[vpos
] + end
,
902 desired_frame
->charstarts
[vpos
] + end
,
903 ((current_frame
->used
[vpos
] - end
)
904 * sizeof (current_frame
->charstarts
[vpos
][0])));
905 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
913 /* If window w does not need to be updated and isn't the full frame wide,
914 copy all the columns that w does occupy
915 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
916 so that update_frame will not change those columns.
918 Have not been able to figure out how to use this correctly. */
920 preserve_my_columns (w
)
923 register int vpos
, fin
;
924 register struct frame_glyphs
*l1
, *l2
;
925 register FRAME_PTR frame
= XFRAME (w
->frame
);
926 int start
= XFASTINT (w
->left
);
927 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
928 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
930 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
932 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
933 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
935 if (l2
->length
> start
&& l1
->length
< l2
->length
)
938 if (fin
> end
) fin
= end
;
939 while (l1
->length
< start
)
940 l1
->body
[l1
->length
++] = ' ';
941 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
950 /* Adjust by ADJUST the charstart values in window W
951 after vpos VPOS, which counts relative to the frame
952 (not relative to W itself). */
955 adjust_window_charstarts (w
, vpos
, adjust
)
960 int left
= XFASTINT (w
->left
);
961 int top
= XFASTINT (w
->top
);
962 int right
= left
+ window_internal_width (w
);
963 int bottom
= top
+ window_internal_height (w
);
966 for (i
= vpos
+ 1; i
< bottom
; i
++)
969 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
971 for (j
= left
; j
< right
; j
++)
972 if (charstart
[j
] > 0)
973 charstart
[j
] += adjust
;
977 /* Check the charstarts values in the area of window W
978 for internal consistency. We cannot check that they are "right";
979 we can only look for something nonsensical. */
981 verify_charstarts (w
)
984 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
986 int top
= XFASTINT (w
->top
);
987 int bottom
= top
+ window_internal_height (w
);
988 int left
= XFASTINT (w
->left
);
989 int right
= left
+ window_internal_width (w
);
991 int truncate
= (XINT (w
->hscroll
)
992 || (truncate_partial_width_windows
993 && (XFASTINT (w
->width
) < FRAME_WIDTH (f
)))
994 || !NILP (XBUFFER (w
->buffer
)->truncate_lines
));
996 for (i
= top
; i
< bottom
; i
++)
1000 int *charstart
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[i
];
1006 /* If we are truncating lines, allow a jump
1007 in charstarts from one line to the next. */
1008 if (charstart
[left
] < next_line
)
1013 if (charstart
[left
] != next_line
)
1018 for (j
= left
; j
< right
; j
++)
1019 if (charstart
[j
] > 0)
1020 last
= charstart
[j
];
1021 /* Record where the next line should start. */
1023 if (BUF_ZV (XBUFFER (w
->buffer
)) != last
)
1025 /* If there's a newline between the two lines, count that. */
1026 int endchar
= *BUF_CHAR_ADDRESS (XBUFFER (w
->buffer
), last
);
1027 if (endchar
== '\n')
1033 /* On discovering that the redisplay for a window was no good,
1034 cancel the columns of that window, so that when the window is
1035 displayed over again get_display_line will not complain. */
1037 cancel_my_columns (w
)
1041 register struct frame_glyphs
*desired_glyphs
1042 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
1043 register int start
= XFASTINT (w
->left
);
1044 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
1046 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
1047 if (desired_glyphs
->enable
[vpos
]
1048 && desired_glyphs
->used
[vpos
] >= start
)
1049 desired_glyphs
->used
[vpos
] = start
;
1052 /* These functions try to perform directly and immediately on the frame
1053 the necessary output for one change in the buffer.
1054 They may return 0 meaning nothing was done if anything is difficult,
1055 or 1 meaning the output was performed properly.
1056 They assume that the frame was up to date before the buffer
1057 change being displayed. They make various other assumptions too;
1058 see command_loop_1 where these are called. */
1061 direct_output_for_insert (g
)
1064 register FRAME_PTR frame
= selected_frame
;
1065 register struct frame_glyphs
*current_frame
1066 = FRAME_CURRENT_GLYPHS (frame
);
1068 #ifndef COMPILER_REGISTER_BUG
1070 #endif /* COMPILER_REGISTER_BUG */
1071 struct window
*w
= XWINDOW (selected_window
);
1072 #ifndef COMPILER_REGISTER_BUG
1074 #endif /* COMPILER_REGISTER_BUG */
1075 int hpos
= FRAME_CURSOR_X (frame
);
1076 #ifndef COMPILER_REGISTER_BUG
1078 #endif /* COMPILER_REGISTER_BUG */
1079 int vpos
= FRAME_CURSOR_Y (frame
);
1081 /* Give up if about to continue line. */
1082 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
1084 /* Avoid losing if cursor is in invisible text off left margin */
1085 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
1087 /* Give up if cursor outside window (in minibuf, probably) */
1088 || cursor_in_echo_area
1089 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
1090 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
1092 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
1093 || !display_completed
1095 /* Give up if buffer appears in two places. */
1096 || buffer_shared
> 1
1098 #ifdef USE_TEXT_PROPERTIES
1099 /* Intervals have already been adjusted, point is after the
1100 character that was just inserted. */
1101 /* Give up if character is invisible. */
1102 /* Give up if character has a face property.
1103 At the moment we only lose at end of line or end of buffer
1104 and only with faces that have some background */
1105 /* Instead of wasting time, give up if character has any text properties */
1106 || ! NILP (Ftext_properties_at (make_number (point
- 1), Qnil
))
1109 /* Give up if w is minibuffer and a message is being displayed there */
1110 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1118 if (FRAME_WINDOW_P (frame
))
1119 face
= compute_char_face (frame
, w
, point
- 1, -1, -1, &dummy
, point
, 0);
1121 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1122 current_frame
->charstarts
[vpos
][hpos
] = point
- 1;
1123 /* Record the entry for after the newly inserted character. */
1124 current_frame
->charstarts
[vpos
][hpos
+ 1] = point
;
1125 adjust_window_charstarts (w
, vpos
, 1);
1127 unchanged_modified
= MODIFF
;
1128 beg_unchanged
= GPT
- BEG
;
1129 XSETFASTINT (w
->last_point
, point
);
1130 XSETFASTINT (w
->last_point_x
, hpos
);
1131 XSETFASTINT (w
->last_modified
, MODIFF
);
1133 reassert_line_highlight (0, vpos
);
1134 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
1136 ++FRAME_CURSOR_X (frame
);
1137 if (hpos
== current_frame
->used
[vpos
])
1139 current_frame
->used
[vpos
] = hpos
+ 1;
1140 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
1147 direct_output_forward_char (n
)
1150 register FRAME_PTR frame
= selected_frame
;
1151 register struct window
*w
= XWINDOW (selected_window
);
1152 Lisp_Object position
;
1153 int hpos
= FRAME_CURSOR_X (frame
);
1155 /* Give up if in truncated text at end of line. */
1156 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1)
1159 /* Avoid losing if cursor is in invisible text off left margin
1160 or about to go off either side of window. */
1161 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
1162 && (XINT (w
->hscroll
) || n
< 0))
1164 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
1165 || cursor_in_echo_area
)
1168 /* Can't use direct output if highlighting a region. */
1169 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1172 /* Can't use direct output at an overlay boundary; it might have
1173 before-string or after-string properties. */
1174 if (overlay_touches_p (PT
) || overlay_touches_p (PT
- n
))
1177 #ifdef USE_TEXT_PROPERTIES
1178 /* Don't use direct output next to an invisible character
1179 since we might need to do something special. */
1181 XSETFASTINT (position
, point
);
1182 if (XFASTINT (position
) < ZV
1183 && ! NILP (Fget_char_property (position
,
1188 XSETFASTINT (position
, point
- 1);
1189 if (XFASTINT (position
) >= BEGV
1190 && ! NILP (Fget_char_property (position
,
1196 FRAME_CURSOR_X (frame
) += n
;
1197 XSETFASTINT (w
->last_point_x
, FRAME_CURSOR_X (frame
));
1198 XSETFASTINT (w
->last_point
, point
);
1199 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1205 static void update_line ();
1207 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1208 Value is nonzero if redisplay stopped due to pending input.
1209 FORCE nonzero means do not stop for pending input. */
1212 update_frame (f
, force
, inhibit_hairy_id
)
1215 int inhibit_hairy_id
;
1217 register struct frame_glyphs
*current_frame
;
1218 register struct frame_glyphs
*desired_frame
= 0;
1221 int preempt_count
= baud_rate
/ 2400 + 1;
1222 extern input_pending
;
1223 #ifdef HAVE_WINDOW_SYSTEM
1224 register int downto
, leftmost
;
1227 if (baud_rate
!= FRAME_COST_BAUD_RATE (f
))
1228 calculate_costs (f
);
1230 if (preempt_count
<= 0)
1233 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1235 detect_input_pending ();
1236 if (input_pending
&& !force
)
1244 if (!line_ins_del_ok
)
1245 inhibit_hairy_id
= 1;
1247 /* These are separate to avoid a possible bug in the AIX C compiler. */
1248 current_frame
= FRAME_CURRENT_GLYPHS (f
);
1249 desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1251 /* See if any of the desired lines are enabled; don't compute for
1252 i/d line if just want cursor motion. */
1253 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1254 if (desired_frame
->enable
[i
])
1257 /* Try doing i/d line, if not yet inhibited. */
1258 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1259 force
|= scrolling (f
);
1261 /* Update the individual lines as needed. Do bottom line first. */
1263 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1264 update_line (f
, FRAME_HEIGHT (f
) - 1);
1266 #ifdef HAVE_WINDOW_SYSTEM
1267 if (FRAME_WINDOW_P (f
))
1269 leftmost
= downto
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1270 if (desired_frame
->enable
[0])
1272 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1273 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1274 = PIXEL_HEIGHT (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
)
1275 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1276 current_frame
->top_left_x
[0] = leftmost
;
1277 current_frame
->top_left_y
[0] = downto
;
1280 #endif /* HAVE_WINDOW_SYSTEM */
1282 /* Now update the rest of the lines. */
1283 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1285 if (desired_frame
->enable
[i
])
1287 if (FRAME_TERMCAP_P (f
))
1289 /* Flush out every so many lines.
1290 Also flush out if likely to have more than 1k buffered
1291 otherwise. I'm told that some telnet connections get
1292 really screwed by more than 1k output at once. */
1293 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1295 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1298 if (preempt_count
== 1)
1300 #ifdef EMACS_OUTQSIZE
1301 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1302 /* Probably not a tty. Ignore the error and reset
1303 * the outq count. */
1304 outq
= PENDING_OUTPUT_COUNT (stdout
);
1307 if (baud_rate
<= outq
&& baud_rate
> 0)
1308 sleep (outq
/ baud_rate
);
1311 if ((i
- 1) % preempt_count
== 0)
1312 detect_input_pending ();
1316 #ifdef HAVE_WINDOW_SYSTEM
1317 if (FRAME_WINDOW_P (f
))
1319 current_frame
->top_left_y
[i
] = downto
;
1320 current_frame
->top_left_x
[i
] = leftmost
;
1322 #endif /* HAVE_WINDOW_SYSTEM */
1325 #ifdef HAVE_WINDOW_SYSTEM
1326 if (FRAME_WINDOW_P (f
))
1327 downto
+= current_frame
->pix_height
[i
];
1328 #endif /* HAVE_WINDOW_SYSTEM */
1330 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1332 /* Now just clean up termcap drivers and set cursor, etc. */
1335 if ((cursor_in_echo_area
1336 /* If we are showing a message instead of the minibuffer,
1337 show the cursor for the message instead of for the
1338 (now hidden) minibuffer contents. */
1339 || (EQ (minibuf_window
, selected_window
)
1340 && EQ (minibuf_window
, echo_area_window
)
1341 && echo_area_glyphs
!= 0))
1342 /* These cases apply only to the frame that contains
1343 the active minibuffer window. */
1344 && FRAME_HAS_MINIBUF_P (f
)
1345 && EQ (FRAME_MINIBUF_WINDOW (f
), minibuf_window
))
1347 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1350 if (cursor_in_echo_area
< 0)
1357 /* If the minibuffer is several lines high, find the last
1358 line that has any text on it. */
1359 row
= FRAME_HEIGHT (f
);
1363 if (current_frame
->enable
[row
])
1364 col
= current_frame
->used
[row
];
1368 while (row
> top
&& col
== 0);
1370 if (col
>= FRAME_WIDTH (f
))
1373 if (row
< FRAME_HEIGHT (f
) - 1)
1378 cursor_to (row
, col
);
1381 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1382 FRAME_WIDTH (f
) - 1), 0));
1388 fflush (termscript
);
1391 /* Here if output is preempted because input is detected. */
1394 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1395 display_completed
= !pause
;
1397 bzero (FRAME_DESIRED_GLYPHS (f
)->enable
, FRAME_HEIGHT (f
));
1401 /* Called when about to quit, to check for doing so
1402 at an improper time. */
1408 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1410 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1412 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1417 /* Decide what insert/delete line to do, and do it */
1419 extern void scrolling_1 ();
1424 int unchanged_at_top
, unchanged_at_bottom
;
1427 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1428 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1429 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1430 int *old_draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1432 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1433 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1434 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1436 /* Compute hash codes of all the lines.
1437 Also calculate number of changed lines,
1438 number of unchanged lines at the beginning,
1439 and number of unchanged lines at the end. */
1442 unchanged_at_top
= 0;
1443 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1444 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1446 /* Give up on this scrolling if some old lines are not enabled. */
1447 if (!current_frame
->enable
[i
])
1449 old_hash
[i
] = line_hash_code (current_frame
, i
);
1450 if (! desired_frame
->enable
[i
])
1451 new_hash
[i
] = old_hash
[i
];
1453 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1455 if (old_hash
[i
] != new_hash
[i
])
1458 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1460 else if (i
== unchanged_at_top
)
1462 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1463 old_draw_cost
[i
] = line_draw_cost (current_frame
, i
);
1466 /* If changed lines are few, don't allow preemption, don't scroll. */
1467 if (!scroll_region_ok
&& changed_lines
< baud_rate
/ 2400
1468 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1471 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1472 - unchanged_at_bottom
);
1474 if (scroll_region_ok
)
1475 free_at_end_vpos
-= unchanged_at_bottom
;
1476 else if (memory_below_frame
)
1477 free_at_end_vpos
= -1;
1479 /* If large window, fast terminal and few lines in common between
1480 current frame and desired frame, don't bother with i/d calc. */
1481 if (!scroll_region_ok
&& window_size
>= 18 && baud_rate
> 2400
1483 10 * scrolling_max_lines_saved (unchanged_at_top
,
1484 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1485 old_hash
, new_hash
, draw_cost
)))
1488 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1489 draw_cost
+ unchanged_at_top
- 1,
1490 old_draw_cost
+ unchanged_at_top
- 1,
1491 old_hash
+ unchanged_at_top
- 1,
1492 new_hash
+ unchanged_at_top
- 1,
1493 free_at_end_vpos
- unchanged_at_top
);
1498 /* Return the offset in its buffer of the character at location col, line
1499 in the given window. */
1501 buffer_posn_from_coords (window
, col
, line
)
1502 struct window
*window
;
1505 int hscroll
= XINT (window
->hscroll
);
1506 int window_left
= XFASTINT (window
->left
);
1508 /* The actual width of the window is window->width less one for the
1509 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1511 int window_width
= window_internal_width (window
) - 1;
1513 int startp
= marker_position (window
->start
);
1515 /* Since compute_motion will only operate on the current buffer,
1516 we need to save the old one and restore it when we're done. */
1517 struct buffer
*old_current_buffer
= current_buffer
;
1518 struct position
*posn
;
1520 current_buffer
= XBUFFER (window
->buffer
);
1522 /* We can't get a correct result in this case,
1523 but at least prevent compute_motion from crashing. */
1527 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1528 (window->frame))->bufp to avoid scanning from the very top of
1529 the window, but it isn't maintained correctly, and I'm not even
1530 sure I will keep it. */
1531 posn
= compute_motion (startp
, 0,
1532 ((window
== XWINDOW (minibuf_window
) && startp
== BEG
1533 ? minibuf_prompt_width
: 0)
1534 + (hscroll
? 1 - hscroll
: 0)),
1537 window_width
, hscroll
, 0, window
);
1539 current_buffer
= old_current_buffer
;
1541 /* compute_motion considers frame points past the end of a line
1542 to be *after* the newline, i.e. at the start of the next line.
1543 This is reasonable, but not really what we want. So if the
1544 result is on a line below LINE, back it up one character. */
1545 if (posn
->vpos
> line
)
1546 return posn
->bufpos
- 1;
1548 return posn
->bufpos
;
1555 register GLYPH
*p
= r
;
1556 while (*p
++ == SPACEGLYPH
);
1561 count_match (str1
, str2
)
1564 register GLYPH
*p1
= str1
;
1565 register GLYPH
*p2
= str2
;
1566 while (*p1
++ == *p2
++);
1567 return p1
- str1
- 1;
1570 /* Char insertion/deletion cost vector, from term.c */
1571 extern int *char_ins_del_vector
;
1573 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1576 update_line (frame
, vpos
)
1577 register FRAME_PTR frame
;
1580 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1583 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1585 register struct frame_glyphs
*current_frame
1586 = FRAME_CURRENT_GLYPHS (frame
);
1587 register struct frame_glyphs
*desired_frame
1588 = FRAME_DESIRED_GLYPHS (frame
);
1590 if (desired_frame
->highlight
[vpos
]
1591 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1593 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1594 (current_frame
->enable
[vpos
] ?
1595 current_frame
->used
[vpos
] : 0));
1596 current_frame
->enable
[vpos
] = 0;
1599 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1601 if (! current_frame
->enable
[vpos
])
1607 obody
= current_frame
->glyphs
[vpos
];
1608 olen
= current_frame
->used
[vpos
];
1609 if (! current_frame
->highlight
[vpos
])
1611 if (!must_write_spaces
)
1612 while (olen
> 0 && obody
[olen
- 1] == SPACEGLYPH
)
1617 /* For an inverse-video line, remember we gave it
1618 spaces all the way to the frame edge
1619 so that the reverse video extends all the way across. */
1621 while (olen
< FRAME_WIDTH (frame
) - 1)
1622 obody
[olen
++] = SPACEGLYPH
;
1626 /* One way or another, this will enable the line being updated. */
1627 current_frame
->enable
[vpos
] = 1;
1628 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1629 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1630 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1632 #ifdef HAVE_WINDOW_SYSTEM
1633 if (FRAME_WINDOW_P (frame
))
1635 current_frame
->pix_width
[vpos
]
1636 = current_frame
->used
[vpos
]
1637 * FONT_WIDTH (FRAME_FONT (frame
));
1638 current_frame
->pix_height
[vpos
]
1639 = FRAME_LINE_HEIGHT (frame
);
1641 #endif /* HAVE_WINDOW_SYSTEM */
1643 if (!desired_frame
->enable
[vpos
])
1649 nbody
= desired_frame
->glyphs
[vpos
];
1650 nlen
= desired_frame
->used
[vpos
];
1652 /* Pretend trailing spaces are not there at all,
1653 unless for one reason or another we must write all spaces. */
1654 if (! desired_frame
->highlight
[vpos
])
1656 if (!must_write_spaces
)
1657 /* We know that the previous character byte contains 0. */
1658 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1663 /* For an inverse-video line, give it extra trailing spaces
1664 all the way to the frame edge
1665 so that the reverse video extends all the way across. */
1667 while (nlen
< FRAME_WIDTH (frame
) - 1)
1668 nbody
[nlen
++] = SPACEGLYPH
;
1671 /* If there's no i/d char, quickly do the best we can without it. */
1672 if (!char_ins_del_ok
)
1677 if (FRAME_X_P (frame
))
1679 /* Under X, erase everything we are going to rewrite,
1680 and rewrite everything from the first char that's changed.
1681 This is part of supporting fonts like Courier
1682 whose chars can overlap outside the char width. */
1683 for (i
= 0; i
< nlen
; i
++)
1684 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1687 cursor_to (vpos
, i
);
1689 clear_end_of_line (olen
);
1690 write_glyphs (nbody
+ i
, nlen
- i
);
1695 for (i
= 0; i
< nlen
; i
++)
1697 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1699 cursor_to (vpos
, i
);
1700 for (j
= 1; (i
+ j
< nlen
&&
1701 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1704 /* Output this run of non-matching chars. */
1705 write_glyphs (nbody
+ i
, j
);
1708 /* Now find the next non-match. */
1712 /* Clear the rest of the line, or the non-clear part of it. */
1715 cursor_to (vpos
, nlen
);
1716 clear_end_of_line (olen
);
1719 /* Exchange contents between current_frame and new_frame. */
1720 temp
= desired_frame
->glyphs
[vpos
];
1721 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1722 current_frame
->glyphs
[vpos
] = temp
;
1724 /* Exchange charstarts between current_frame and new_frame. */
1725 temp1
= desired_frame
->charstarts
[vpos
];
1726 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1727 current_frame
->charstarts
[vpos
] = temp1
;
1734 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1735 ? 0 : count_blanks (nbody
);
1738 cursor_to (vpos
, nsp
);
1739 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1742 /* Exchange contents between current_frame and new_frame. */
1743 temp
= desired_frame
->glyphs
[vpos
];
1744 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1745 current_frame
->glyphs
[vpos
] = temp
;
1747 /* Exchange charstarts between current_frame and new_frame. */
1748 temp1
= desired_frame
->charstarts
[vpos
];
1749 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1750 current_frame
->charstarts
[vpos
] = temp1
;
1759 /* Compute number of leading blanks in old and new contents. */
1760 osp
= count_blanks (obody
);
1761 if (!desired_frame
->highlight
[vpos
])
1762 nsp
= count_blanks (nbody
);
1766 /* Compute number of matching chars starting with first nonblank. */
1767 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1769 /* Spaces in new match implicit space past the end of old. */
1770 /* A bug causing this to be a no-op was fixed in 18.29. */
1771 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1774 while (np1
[begmatch
] == SPACEGLYPH
)
1778 /* Avoid doing insert/delete char
1779 just cause number of leading spaces differs
1780 when the following text does not match. */
1781 if (begmatch
== 0 && osp
!= nsp
)
1782 osp
= nsp
= min (osp
, nsp
);
1784 /* Find matching characters at end of line */
1787 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1788 while (op1
> op2
&& op1
[-1] == np1
[-1])
1793 endmatch
= obody
+ olen
- op1
;
1795 /* Put correct value back in nbody[nlen].
1796 This is important because direct_output_for_insert
1797 can write into the line at a later point.
1798 If this screws up the zero at the end of the line, re-establish it. */
1802 /* tem gets the distance to insert or delete.
1803 endmatch is how many characters we save by doing so.
1806 tem
= (nlen
- nsp
) - (olen
- osp
);
1808 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1811 /* nsp - osp is the distance to insert or delete.
1812 If that is nonzero, begmatch is known to be nonzero also.
1813 begmatch + endmatch is how much we save by doing the ins/del.
1817 && (!char_ins_del_ok
1818 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1822 osp
= nsp
= min (osp
, nsp
);
1825 /* Now go through the line, inserting, writing and
1826 deleting as appropriate. */
1830 cursor_to (vpos
, nsp
);
1831 delete_glyphs (osp
- nsp
);
1835 /* If going to delete chars later in line
1836 and insert earlier in the line,
1837 must delete first to avoid losing data in the insert */
1838 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1840 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1841 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1842 olen
= nlen
- (nsp
- osp
);
1844 cursor_to (vpos
, osp
);
1845 insert_glyphs ((char *)0, nsp
- osp
);
1849 tem
= nsp
+ begmatch
+ endmatch
;
1850 if (nlen
!= tem
|| olen
!= tem
)
1852 cursor_to (vpos
, nsp
+ begmatch
);
1853 if (!endmatch
|| nlen
== olen
)
1855 /* If new text being written reaches right margin,
1856 there is no need to do clear-to-eol at the end.
1857 (and it would not be safe, since cursor is not
1858 going to be "at the margin" after the text is done) */
1859 if (nlen
== FRAME_WIDTH (frame
))
1861 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1865 /* the following code loses disastrously if tem == nlen.
1866 Rather than trying to fix that case, I am trying the simpler
1867 solution found above. */
1869 /* If the text reaches to the right margin,
1870 it will lose one way or another (depending on AutoWrap)
1871 to clear to end of line after outputting all the text.
1872 So pause with one character to go and clear the line then. */
1873 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1875 /* endmatch must be zero, and tem must equal nsp + begmatch */
1876 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1877 clear_end_of_line (olen
);
1878 olen
= 0; /* Don't let it be cleared again later */
1879 write_glyphs (nbody
+ nlen
- 1, 1);
1882 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1883 #endif /* OBSOLETE */
1886 else if (nlen
> olen
)
1888 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1889 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1892 else if (olen
> nlen
)
1894 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1895 delete_glyphs (olen
- nlen
);
1901 /* If any unerased characters remain after the new line, erase them. */
1904 cursor_to (vpos
, nlen
);
1905 clear_end_of_line (olen
);
1908 /* Exchange contents between current_frame and new_frame. */
1909 temp
= desired_frame
->glyphs
[vpos
];
1910 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1911 current_frame
->glyphs
[vpos
] = temp
;
1913 /* Exchange charstarts between current_frame and new_frame. */
1914 temp1
= desired_frame
->charstarts
[vpos
];
1915 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1916 current_frame
->charstarts
[vpos
] = temp1
;
1919 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
1920 session's frames, frame names, buffers, buffer-read-only flags, and
1921 buffer-modified-flags, and a trailing sentinel (so we don't need to
1922 add length checks). */
1923 static Lisp_Object frame_and_buffer_state
;
1925 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p
,
1926 Sframe_or_buffer_changed_p
, 0, 0, 0,
1927 "Return non-nil if the frame and buffer state appears to have changed.\n\
1928 The state variable is an internal vector containing all frames and buffers,\n\
1929 aside from buffers whose names start with space,\n\
1930 along with the buffers' read-only and modified flags, which allows a fast\n\
1931 check to see whether the menu bars might need to be recomputed.\n\
1932 If this function returns non-nil, it updates the internal vector to reflect\n\
1933 the current state.\n")
1936 Lisp_Object tail
, frame
, buf
;
1940 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1941 FOR_EACH_FRAME (tail
, frame
)
1943 if (!EQ (*vecp
++, frame
))
1945 if (!EQ (*vecp
++, XFRAME (frame
)->name
))
1948 /* Check that the buffer info matches.
1949 No need to test for the end of the vector
1950 because the last element of the vector is lambda
1951 and that will always cause a mismatch. */
1952 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1954 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1955 /* Ignore buffers that aren't included in buffer lists. */
1956 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1958 if (!EQ (*vecp
++, buf
))
1960 if (!EQ (*vecp
++, XBUFFER (buf
)->read_only
))
1962 if (!EQ (*vecp
++, Fbuffer_modified_p (buf
)))
1965 /* Detect deletion of a buffer at the end of the list. */
1966 if (*vecp
== Qlambda
)
1969 /* Start with 1 so there is room for at least one lambda at the end. */
1971 FOR_EACH_FRAME (tail
, frame
)
1973 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1975 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
1976 if (n
> XVECTOR (frame_and_buffer_state
)->size
1977 || n
+ 20 < XVECTOR (frame_and_buffer_state
)->size
/ 2)
1978 /* Add 20 extra so we grow it less often. */
1979 frame_and_buffer_state
= Fmake_vector (make_number (n
+ 20), Qlambda
);
1980 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1981 FOR_EACH_FRAME (tail
, frame
)
1984 *vecp
++ = XFRAME (frame
)->name
;
1986 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1988 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1989 /* Ignore buffers that aren't included in buffer lists. */
1990 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1993 *vecp
++ = XBUFFER (buf
)->read_only
;
1994 *vecp
++ = Fbuffer_modified_p (buf
);
1996 /* Fill up the vector with lambdas (always at least one). */
1998 while (vecp
- XVECTOR (frame_and_buffer_state
)->contents
1999 < XVECTOR (frame_and_buffer_state
)->size
)
2001 /* Make sure we didn't overflow the vector. */
2002 if (vecp
- XVECTOR (frame_and_buffer_state
)->contents
2003 > XVECTOR (frame_and_buffer_state
)->size
)
2008 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
2009 1, 1, "FOpen termscript file: ",
2010 "Start writing all terminal output to FILE as well as the terminal.\n\
2011 FILE = nil means just close any termscript file currently open.")
2015 if (termscript
!= 0) fclose (termscript
);
2020 file
= Fexpand_file_name (file
, Qnil
);
2021 termscript
= fopen (XSTRING (file
)->data
, "w");
2022 if (termscript
== 0)
2023 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
2031 window_change_signal (signalnum
) /* If we don't have an argument, */
2032 int signalnum
; /* some compilers complain in signal calls. */
2036 int old_errno
= errno
;
2038 get_frame_size (&width
, &height
);
2040 /* The frame size change obviously applies to a termcap-controlled
2041 frame. Find such a frame in the list, and assume it's the only
2042 one (since the redisplay code always writes to stdout, not a
2043 FILE * specified in the frame structure). Record the new size,
2044 but don't reallocate the data structures now. Let that be done
2045 later outside of the signal handler. */
2048 Lisp_Object tail
, frame
;
2050 FOR_EACH_FRAME (tail
, frame
)
2052 if (FRAME_TERMCAP_P (XFRAME (frame
)))
2054 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
2060 signal (SIGWINCH
, window_change_signal
);
2063 #endif /* SIGWINCH */
2066 /* Do any change in frame size that was requested by a signal. */
2068 do_pending_window_change ()
2070 /* If window_change_signal should have run before, run it now. */
2071 while (delayed_size_change
)
2073 Lisp_Object tail
, frame
;
2075 delayed_size_change
= 0;
2077 FOR_EACH_FRAME (tail
, frame
)
2079 FRAME_PTR f
= XFRAME (frame
);
2081 int height
= FRAME_NEW_HEIGHT (f
);
2082 int width
= FRAME_NEW_WIDTH (f
);
2084 if (height
!= 0 || width
!= 0)
2085 change_frame_size (f
, height
, width
, 0, 0);
2091 /* Change the frame height and/or width. Values may be given as zero to
2092 indicate no change is to take place.
2094 If DELAY is non-zero, then assume we're being called from a signal
2095 handler, and queue the change for later - perhaps the next
2096 redisplay. Since this tries to resize windows, we can't call it
2097 from a signal handler. */
2099 change_frame_size (f
, newheight
, newwidth
, pretend
, delay
)
2100 register FRAME_PTR f
;
2101 int newheight
, newwidth
, pretend
;
2103 Lisp_Object tail
, frame
;
2104 if (FRAME_TERMCAP_P (f
))
2106 /* When using termcap, all frames use the same screen,
2107 so a change in size affects all termcap frames. */
2108 FOR_EACH_FRAME (tail
, frame
)
2109 if (FRAME_TERMCAP_P (XFRAME (frame
)))
2110 change_frame_size_1 (XFRAME (frame
), newheight
, newwidth
,
2114 change_frame_size_1 (f
, newheight
, newwidth
, pretend
, delay
);
2118 change_frame_size_1 (frame
, newheight
, newwidth
, pretend
, delay
)
2119 register FRAME_PTR frame
;
2120 int newheight
, newwidth
, pretend
, delay
;
2122 /* If we can't deal with the change now, queue it for later. */
2125 FRAME_NEW_HEIGHT (frame
) = newheight
;
2126 FRAME_NEW_WIDTH (frame
) = newwidth
;
2127 delayed_size_change
= 1;
2131 /* This size-change overrides any pending one for this frame. */
2132 FRAME_NEW_HEIGHT (frame
) = 0;
2133 FRAME_NEW_WIDTH (frame
) = 0;
2135 /* If an argument is zero, set it to the current value. */
2136 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
2137 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
2139 /* Round up to the smallest acceptable size. */
2140 check_frame_size (frame
, &newheight
, &newwidth
);
2142 /* If we're not changing the frame size, quit now. */
2143 if (newheight
== FRAME_HEIGHT (frame
)
2144 && newwidth
== FRAME_WIDTH (frame
))
2147 if (newheight
!= FRAME_HEIGHT (frame
))
2149 if (FRAME_HAS_MINIBUF_P (frame
)
2150 && ! FRAME_MINIBUF_ONLY_P (frame
))
2152 /* Frame has both root and minibuffer. */
2153 set_window_height (FRAME_ROOT_WINDOW (frame
),
2154 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
2155 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
,
2157 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
2160 /* Frame has just one top-level window. */
2161 set_window_height (FRAME_ROOT_WINDOW (frame
),
2162 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
2164 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2165 FrameRows
= newheight
;
2168 if (frame
->output_method
== output_termcap
)
2170 frame_height
= newheight
;
2172 FrameRows
= newheight
;
2177 if (newwidth
!= FRAME_WIDTH (frame
))
2179 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
2180 if (FRAME_HAS_MINIBUF_P (frame
))
2181 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
2183 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2184 FrameCols
= newwidth
;
2186 if (frame
->output_method
== output_termcap
)
2188 frame_width
= newwidth
;
2190 FrameCols
= newwidth
;
2195 FRAME_HEIGHT (frame
) = newheight
;
2196 FRAME_WIDTH (frame
) = newwidth
;
2198 if (FRAME_CURSOR_X (frame
) >= FRAME_WIDTH (frame
))
2199 FRAME_CURSOR_X (frame
) = FRAME_WIDTH (frame
) - 1;
2200 if (FRAME_CURSOR_Y (frame
) >= FRAME_HEIGHT (frame
))
2201 FRAME_CURSOR_Y (frame
) = FRAME_HEIGHT (frame
) - 1;
2203 remake_frame_glyphs (frame
);
2204 calculate_costs (frame
);
2207 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
2208 Ssend_string_to_terminal
, 1, 1, 0,
2209 "Send STRING to the terminal without alteration.\n\
2210 Control characters in STRING will have terminal-dependent effects.")
2214 CHECK_STRING (str
, 0);
2215 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
2219 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
2220 fflush (termscript
);
2225 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
2226 "Beep, or flash the screen.\n\
2227 Also, unless an argument is given,\n\
2228 terminate any keyboard macro currently executing.")
2250 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
2251 error ("Keyboard macro terminated by a command ringing the bell");
2257 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
2258 "Pause, without updating display, for SECONDS seconds.\n\
2259 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2260 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2261 additional wait period, in milliseconds; this may be useful if your\n\
2262 Emacs was built without floating point support.\n\
2263 \(Not all operating systems support waiting for a fraction of a second.)")
2264 (seconds
, milliseconds
)
2265 Lisp_Object seconds
, milliseconds
;
2269 if (NILP (milliseconds
))
2270 XSETINT (milliseconds
, 0);
2272 CHECK_NUMBER (milliseconds
, 1);
2273 usec
= XINT (milliseconds
) * 1000;
2275 #ifdef LISP_FLOAT_TYPE
2277 double duration
= extract_float (seconds
);
2278 sec
= (int) duration
;
2279 usec
+= (duration
- sec
) * 1000000;
2282 CHECK_NUMBER (seconds
, 0);
2283 sec
= XINT (seconds
);
2286 #ifndef EMACS_HAS_USECS
2287 if (sec
== 0 && usec
!= 0)
2288 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2291 /* Assure that 0 <= usec < 1000000. */
2294 /* We can't rely on the rounding being correct if user is negative. */
2295 if (-1000000 < usec
)
2296 sec
--, usec
+= 1000000;
2298 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2301 sec
+= usec
/ 1000000, usec
%= 1000000;
2309 XSETFASTINT (zero
, 0);
2310 wait_reading_process_input (sec
, usec
, zero
, 0);
2313 /* We should always have wait_reading_process_input; we have a dummy
2314 implementation for systems which don't support subprocesses. */
2316 /* No wait_reading_process_input */
2323 /* The reason this is done this way
2324 (rather than defined (H_S) && defined (H_T))
2325 is because the VMS preprocessor doesn't grok `defined' */
2327 EMACS_GET_TIME (end_time
);
2328 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2329 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2333 EMACS_GET_TIME (timeout
);
2334 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2335 if (EMACS_TIME_NEG_P (timeout
)
2336 || !select (1, 0, 0, 0, &timeout
))
2339 #else /* not HAVE_SELECT */
2341 #endif /* HAVE_SELECT */
2342 #endif /* not VMS */
2345 #endif /* no subprocesses */
2350 /* This is just like wait_reading_process_input, except that
2351 it does the redisplay.
2353 It's also much like Fsit_for, except that it can be used for
2354 waiting for input as well. */
2357 sit_for (sec
, usec
, reading
, display
)
2358 int sec
, usec
, reading
, display
;
2360 Lisp_Object read_kbd
;
2362 if (detect_input_pending ())
2366 redisplay_preserve_echo_area ();
2368 if (sec
== 0 && usec
== 0)
2375 XSETINT (read_kbd
, reading
? -1 : 1);
2376 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2379 /* wait_reading_process_input should always be available now; it is
2380 simulated in a simple way on systems that don't support
2383 /* No wait_reading_process_input available. */
2389 input_wait_timeout (XINT (arg
));
2391 #ifndef HAVE_TIMEVAL
2393 select (1, &waitchannels
, 0, 0, &timeout_sec
);
2394 #else /* HAVE_TIMEVAL */
2395 timeout
.tv_sec
= sec
;
2396 timeout
.tv_usec
= usec
;
2397 select (1, &waitchannels
, 0, 0, &timeout
);
2398 #endif /* HAVE_TIMEVAL */
2399 #endif /* not VMS */
2404 return detect_input_pending () ? Qnil
: Qt
;
2407 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2408 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2409 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2410 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2411 additional wait period, in milliseconds; this may be useful if your\n\
2412 Emacs was built without floating point support.\n\
2413 \(Not all operating systems support waiting for a fraction of a second.)\n\
2414 Optional third arg non-nil means don't redisplay, just wait for input.\n\
2415 Redisplay is preempted as always if input arrives, and does not happen\n\
2416 if input is available before it starts.\n\
2417 Value is t if waited the full time with no input arriving.")
2418 (seconds
, milliseconds
, nodisp
)
2419 Lisp_Object seconds
, milliseconds
, nodisp
;
2423 if (NILP (milliseconds
))
2424 XSETINT (milliseconds
, 0);
2426 CHECK_NUMBER (milliseconds
, 1);
2427 usec
= XINT (milliseconds
) * 1000;
2429 #ifdef LISP_FLOAT_TYPE
2431 double duration
= extract_float (seconds
);
2432 sec
= (int) duration
;
2433 usec
+= (duration
- sec
) * 1000000;
2436 CHECK_NUMBER (seconds
, 0);
2437 sec
= XINT (seconds
);
2440 #ifndef EMACS_HAS_USECS
2441 if (usec
!= 0 && sec
== 0)
2442 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2445 return sit_for (sec
, usec
, 0, NILP (nodisp
));
2448 char *terminal_type
;
2450 /* Initialization done when Emacs fork is started, before doing stty. */
2451 /* Determine terminal type and set terminal_driver */
2452 /* Then invoke its decoding routine to set up variables
2453 in the terminal package */
2457 #ifdef HAVE_X_WINDOWS
2458 extern int display_arg
;
2463 cursor_in_echo_area
= 0;
2464 terminal_type
= (char *) 0;
2466 /* Now is the time to initialize this; it's used by init_sys_modes
2468 Vwindow_system
= Qnil
;
2470 /* If the user wants to use a window system, we shouldn't bother
2471 initializing the terminal. This is especially important when the
2472 terminal is so dumb that emacs gives up before and doesn't bother
2473 using the window system.
2475 If the DISPLAY environment variable is set, try to use X, and die
2476 with an error message if that doesn't work. */
2478 #ifdef HAVE_X_WINDOWS
2482 display_arg
= (getenv ("DECW$DISPLAY") != 0);
2484 display_arg
= (getenv ("DISPLAY") != 0);
2488 if (!inhibit_window_system
&& display_arg
)
2490 Vwindow_system
= intern ("x");
2492 Vwindow_system_version
= make_number (11);
2494 Vwindow_system_version
= make_number (10);
2498 #endif /* HAVE_X_WINDOWS */
2501 if (!inhibit_window_system
)
2503 Vwindow_system
= intern ("win32");
2504 Vwindow_system_version
= make_number (1);
2507 #endif /* HAVE_NTGUI */
2509 /* If no window system has been specified, try to use the terminal. */
2512 fprintf (stderr
, "emacs: standard input is not a tty\n");
2516 /* Look at the TERM variable */
2517 terminal_type
= (char *) getenv ("TERM");
2521 fprintf (stderr
, "Please specify your terminal type.\n\
2522 For types defined in VMS, use set term /device=TYPE.\n\
2523 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2524 \(The quotation marks are necessary since terminal types are lower case.)\n");
2526 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2532 /* VMS DCL tends to upcase things, so downcase term type.
2533 Hardly any uppercase letters in terminal types; should be none. */
2535 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2538 strcpy (new, terminal_type
);
2540 for (p
= new; *p
; p
++)
2544 terminal_type
= new;
2548 term_init (terminal_type
);
2550 remake_frame_glyphs (selected_frame
);
2551 calculate_costs (selected_frame
);
2553 /* X and Y coordinates of the cursor between updates. */
2554 FRAME_CURSOR_X (selected_frame
) = 0;
2555 FRAME_CURSOR_Y (selected_frame
) = 0;
2560 #endif /* CANNOT_DUMP */
2561 signal (SIGWINCH
, window_change_signal
);
2562 #endif /* SIGWINCH */
2568 defsubr (&Sredraw_frame
);
2570 defsubr (&Sredraw_display
);
2571 defsubr (&Sframe_or_buffer_changed_p
);
2572 defsubr (&Sopen_termscript
);
2574 defsubr (&Ssit_for
);
2575 defsubr (&Ssleep_for
);
2576 defsubr (&Ssend_string_to_terminal
);
2578 frame_and_buffer_state
= Fmake_vector (make_number (20), Qlambda
);
2579 staticpro (&frame_and_buffer_state
);
2581 Qdisplay_table
= intern ("display-table");
2582 staticpro (&Qdisplay_table
);
2584 DEFVAR_INT ("baud-rate", &baud_rate
,
2585 "*The output baud rate of the terminal.\n\
2586 On most systems, changing this value will affect the amount of padding\n\
2587 and the other strategic decisions made during redisplay.");
2588 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2589 "*Non-nil means invert the entire frame display.\n\
2590 This means everything is in inverse video which otherwise would not be.");
2591 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2592 "*Non-nil means try to flash the frame to represent a bell.");
2593 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2594 "*Non-nil means no need to redraw entire frame after suspending.\n\
2595 A non-nil value is useful if the terminal can automatically preserve\n\
2596 Emacs's frame display when you reenter Emacs.\n\
2597 It is up to you to set this variable if your terminal can do that.");
2598 DEFVAR_LISP ("window-system", &Vwindow_system
,
2599 "A symbol naming the window-system under which Emacs is running\n\
2600 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2601 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2602 "The version number of the window system in use.\n\
2603 For X windows, this is 10 or 11.");
2604 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2605 "Non-nil means put cursor in minibuffer, at end of any message there.");
2606 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2607 "Table defining how to output a glyph code to the frame.\n\
2608 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2609 Each element can be:\n\
2610 integer: a glyph code which this glyph is an alias for.\n\
2611 string: output this glyph using that string (not impl. in X windows).\n\
2612 nil: this glyph mod 256 is char code to output,\n\
2613 and this glyph / 256 is face code for X windows (see `face-id').");
2614 Vglyph_table
= Qnil
;
2616 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2617 "Display table to use for buffers that specify none.\n\
2618 See `buffer-display-table' for more information.");
2619 Vstandard_display_table
= Qnil
;
2621 /* Initialize `window-system', unless init_display already decided it. */
2626 Vwindow_system
= Qnil
;
2627 Vwindow_system_version
= Qnil
;