1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
31 #include "termhooks.h"
33 #include "dispextern.h"
40 #include "intervals.h"
46 #endif /* HAVE_X_WINDOWS */
48 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
53 #define max(a, b) ((a) > (b) ? (a) : (b))
54 #define min(a, b) ((a) < (b) ? (a) : (b))
56 /* Get number of chars of output now in the buffer of a stdio stream.
57 This ought to be built in in stdio, but it isn't.
58 Some s- files override this because their stdio internals differ. */
59 #ifdef __GNU_LIBRARY__
60 /* The s- file might have overridden the definition with one that works for
61 the system's C library. But we are using the GNU C library, so this is
62 the right definition for every system. */
63 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
64 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
66 #undef PENDING_OUTPUT_COUNT
67 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
69 #else /* not __GNU_LIBRARY__ */
70 #ifndef PENDING_OUTPUT_COUNT
71 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
75 /* Nonzero upon entry to redisplay means do not assume anything about
76 current contents of actual terminal frame; clear and redraw it. */
80 /* Nonzero means last display completed. Zero means it was preempted. */
82 int display_completed
;
84 /* Lisp variable visible-bell; enables use of screen-flash
85 instead of audible bell. */
89 /* Invert the color of the whole frame, at a low level. */
93 /* Line speed of the terminal. */
97 /* nil or a symbol naming the window system under which emacs is
98 running ('x is the only current possibility). */
100 Lisp_Object Vwindow_system
;
102 /* Version number of X windows: 10, 11 or nil. */
103 Lisp_Object Vwindow_system_version
;
105 /* Vector of glyph definitions. Indexed by glyph number,
106 the contents are a string which is how to output the glyph.
108 If Vglyph_table is nil, a glyph is output by using its low 8 bits
109 as a character code. */
111 Lisp_Object Vglyph_table
;
113 /* Display table to use for vectors that don't specify their own. */
115 Lisp_Object Vstandard_display_table
;
117 /* Nonzero means reading single-character input with prompt
118 so put cursor on minibuffer after the prompt.
119 positive means at end of text in echo area;
120 negative means at beginning of line. */
121 int cursor_in_echo_area
;
123 /* The currently selected frame.
124 In a single-frame version, this variable always holds the address of
127 FRAME_PTR selected_frame
;
129 /* A frame which is not just a minibuffer, or 0 if there are no such
130 frames. This is usually the most recent such frame that was
131 selected. In a single-frame version, this variable always holds
132 the address of the_only_frame. */
133 FRAME_PTR last_nonminibuf_frame
;
135 /* In a single-frame version, the information that would otherwise
136 exist inside frame objects lives in the following structure instead.
138 NOTE: the_only_frame is not checked for garbage collection; don't
139 store collectible objects in any of its fields!
141 You're not/The only frame in town/... */
144 struct frame the_only_frame
;
147 /* This is a vector, made larger whenever it isn't large enough,
148 which is used inside `update_frame' to hold the old contents
149 of the FRAME_PHYS_LINES of the frame being updated. */
150 struct frame_glyphs
**ophys_lines
;
151 /* Length of vector currently allocated. */
152 int ophys_lines_length
;
154 FILE *termscript
; /* Stdio stream being used for copy of all output. */
156 struct cm Wcm
; /* Structure for info on cursor positioning */
158 extern short ospeed
; /* Output speed (from sg_ospeed) */
160 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
164 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
165 "Clear frame FRAME and output again what is supposed to appear on it.")
171 CHECK_LIVE_FRAME (frame
, 0);
174 /* set_terminal_modes (); */
176 clear_frame_records (f
);
179 windows_or_buffers_changed
++;
180 /* Mark all windows as INaccurate,
181 so that every window will have its redisplay done. */
182 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
191 XSETFRAME (frame
, f
);
192 Fredraw_frame (frame
);
197 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
198 "Clear frame FRAME and output again what is supposed to appear on it.")
203 set_terminal_modes ();
207 clear_frame_records (0);
208 windows_or_buffers_changed
++;
209 /* Mark all windows as INaccurate,
210 so that every window will have its redisplay done. */
211 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
217 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
218 "Clear and redisplay all visible frames.")
221 Lisp_Object tail
, frame
;
223 FOR_EACH_FRAME (tail
, frame
)
224 if (FRAME_VISIBLE_P (XFRAME (frame
)))
225 Fredraw_frame (frame
);
230 /* This is used when frame_garbaged is set.
231 Redraw the individual frames marked as garbaged. */
234 redraw_garbaged_frames ()
236 Lisp_Object tail
, frame
;
238 FOR_EACH_FRAME (tail
, frame
)
239 if (FRAME_VISIBLE_P (XFRAME (frame
))
240 && FRAME_GARBAGED_P (XFRAME (frame
)))
241 Fredraw_frame (frame
);
245 static struct frame_glyphs
*
246 make_frame_glyphs (frame
, empty
)
247 register FRAME_PTR frame
;
251 register width
= FRAME_WIDTH (frame
);
252 register height
= FRAME_HEIGHT (frame
);
253 register struct frame_glyphs
*new
254 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
256 SET_GLYPHS_FRAME (new, frame
);
257 new->height
= height
;
259 new->used
= (int *) xmalloc (height
* sizeof (int));
260 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
261 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
262 new->highlight
= (char *) xmalloc (height
* sizeof (char));
263 new->enable
= (char *) xmalloc (height
* sizeof (char));
264 bzero (new->enable
, height
* sizeof (char));
265 new->bufp
= (int *) xmalloc (height
* sizeof (int));
267 #ifdef HAVE_X_WINDOWS
268 if (FRAME_X_P (frame
))
270 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
271 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
272 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
273 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
274 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
280 /* Make the buffer used by decode_mode_spec. This buffer is also
281 used as temporary storage when updating the frame. See scroll.c. */
282 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
283 unsigned int total_charstarts
= (width
+ 2) * sizeof (int);
285 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
286 bzero (new->total_contents
, total_glyphs
);
288 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
289 bzero (new->total_charstarts
, total_glyphs
);
293 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
295 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
296 bzero (new->total_contents
, total_glyphs
);
297 for (i
= 0; i
< height
; i
++)
298 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
300 if (!FRAME_TERMCAP_P (frame
))
302 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
304 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
305 bzero (new->total_charstarts
, total_charstarts
);
306 for (i
= 0; i
< height
; i
++)
307 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
311 /* Without a window system, we don't really need charstarts.
312 So use a small amount of space to make enough data structure
313 to prevent crashes in display_text_line. */
314 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
315 for (i
= 0; i
< height
; i
++)
316 new->charstarts
[i
] = new->total_charstarts
;
324 free_frame_glyphs (frame
, glyphs
)
326 struct frame_glyphs
*glyphs
;
328 if (glyphs
->total_contents
)
329 xfree (glyphs
->total_contents
);
330 if (glyphs
->total_charstarts
)
331 xfree (glyphs
->total_charstarts
);
333 xfree (glyphs
->used
);
334 xfree (glyphs
->glyphs
);
335 xfree (glyphs
->highlight
);
336 xfree (glyphs
->enable
);
337 xfree (glyphs
->bufp
);
338 if (glyphs
->charstarts
)
339 xfree (glyphs
->charstarts
);
341 #ifdef HAVE_X_WINDOWS
342 if (FRAME_X_P (frame
))
344 xfree (glyphs
->top_left_x
);
345 xfree (glyphs
->top_left_y
);
346 xfree (glyphs
->pix_width
);
347 xfree (glyphs
->pix_height
);
348 xfree (glyphs
->max_ascent
);
356 remake_frame_glyphs (frame
)
359 if (FRAME_CURRENT_GLYPHS (frame
))
360 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
361 if (FRAME_DESIRED_GLYPHS (frame
))
362 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
363 if (FRAME_TEMP_GLYPHS (frame
))
364 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
366 if (FRAME_MESSAGE_BUF (frame
))
368 /* Reallocate the frame's message buffer; remember that
369 echo_area_glyphs may be pointing here. */
370 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
372 FRAME_MESSAGE_BUF (frame
)
373 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
374 FRAME_WIDTH (frame
) + 1);
376 if (echo_area_glyphs
== old_message_buf
)
377 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
378 if (previous_echo_glyphs
== old_message_buf
)
379 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
382 FRAME_MESSAGE_BUF (frame
)
383 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
385 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
386 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
387 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
388 SET_FRAME_GARBAGED (frame
);
391 /* Return the hash code of contents of line VPOS in frame-matrix M. */
394 line_hash_code (m
, vpos
)
395 register struct frame_glyphs
*m
;
398 register GLYPH
*body
, *end
;
401 if (!m
->enable
[vpos
])
404 /* Give all highlighted lines the same hash code
405 so as to encourage scrolling to leave them in place. */
406 if (m
->highlight
[vpos
])
409 body
= m
->glyphs
[vpos
];
411 if (must_write_spaces
)
418 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
427 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
435 /* Return number of characters in line in M at vpos VPOS,
436 except don't count leading and trailing spaces
437 unless the terminal requires those to be explicitly output. */
440 line_draw_cost (m
, vpos
)
441 struct frame_glyphs
*m
;
444 register GLYPH
*beg
= m
->glyphs
[vpos
];
445 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
447 register int tlen
= GLYPH_TABLE_LENGTH
;
448 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
450 /* Ignore trailing and leading spaces if we can. */
451 if (!must_write_spaces
)
453 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
456 return (0); /* All blank line. */
458 while (*beg
== SPACEGLYPH
)
462 /* If we don't have a glyph-table, each glyph is one character,
463 so return the number of glyphs. */
467 /* Otherwise, scan the glyphs and accumulate their total size in I. */
469 while ((beg
<= end
) && *beg
)
471 register GLYPH g
= *beg
++;
473 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
476 i
+= GLYPH_LENGTH (tbase
, g
);
481 /* The functions on this page are the interface from xdisp.c to redisplay.
483 The only other interface into redisplay is through setting
484 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
485 and SET_FRAME_GARBAGED (frame). */
487 /* cancel_line eliminates any request to display a line at position `vpos' */
489 cancel_line (vpos
, frame
)
491 register FRAME_PTR frame
;
493 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
496 clear_frame_records (frame
)
497 register FRAME_PTR frame
;
499 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
502 /* Prepare to display on line VPOS starting at HPOS within it. */
505 get_display_line (frame
, vpos
, hpos
)
506 register FRAME_PTR frame
;
510 register struct frame_glyphs
*glyphs
;
511 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
517 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
520 if (! desired_glyphs
->enable
[vpos
])
522 desired_glyphs
->used
[vpos
] = 0;
523 desired_glyphs
->highlight
[vpos
] = 0;
524 desired_glyphs
->enable
[vpos
] = 1;
527 if (hpos
> desired_glyphs
->used
[vpos
])
529 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
530 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
532 desired_glyphs
->used
[vpos
] = hpos
;
538 /* Like bcopy except never gets confused by overlap. */
541 safe_bcopy (from
, to
, size
)
545 if (size
<= 0 || from
== to
)
548 /* If the source and destination don't overlap, then bcopy can
549 handle it. If they do overlap, but the destination is lower in
550 memory than the source, we'll assume bcopy can handle that. */
551 if (to
< from
|| from
+ size
<= to
)
552 bcopy (from
, to
, size
);
554 /* Otherwise, we'll copy from the end. */
557 register char *endf
= from
+ size
;
558 register char *endt
= to
+ size
;
560 /* If TO - FROM is large, then we should break the copy into
561 nonoverlapping chunks of TO - FROM bytes each. However, if
562 TO - FROM is small, then the bcopy function call overhead
563 makes this not worth it. The crossover point could be about
564 anywhere. Since I don't think the obvious copy loop is too
565 bad, I'm trying to err in its favor. */
570 while (endf
!= from
);
582 bcopy (endf
, endt
, to
- from
);
585 /* If SIZE wasn't a multiple of TO - FROM, there will be a
586 little left over. The amount left over is
587 (endt + (to - from)) - to, which is endt - from. */
588 bcopy (from
, to
, endt
- from
);
593 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
594 DISTANCE may be negative. */
597 rotate_vector (vector
, size
, distance
)
602 char *temp
= (char *) alloca (size
);
607 bcopy (vector
, temp
+ distance
, size
- distance
);
608 bcopy (vector
+ size
- distance
, temp
, distance
);
609 bcopy (temp
, vector
, size
);
612 /* Scroll lines from vpos FROM up to but not including vpos END
613 down by AMOUNT lines (AMOUNT may be negative).
614 Returns nonzero if done, zero if terminal cannot scroll them. */
617 scroll_frame_lines (frame
, from
, end
, amount
, newpos
)
618 register FRAME_PTR frame
;
619 int from
, end
, amount
, newpos
;
622 register struct frame_glyphs
*current_frame
623 = FRAME_CURRENT_GLYPHS (frame
);
625 int width
= FRAME_WIDTH (frame
);
627 if (!line_ins_del_ok
)
635 update_begin (frame
);
636 set_terminal_window (end
+ amount
);
637 if (!scroll_region_ok
)
638 ins_del_lines (end
, -amount
);
639 ins_del_lines (from
, amount
);
640 set_terminal_window (0);
642 rotate_vector (current_frame
->glyphs
+ from
,
643 sizeof (GLYPH
*) * (end
+ amount
- from
),
644 amount
* sizeof (GLYPH
*));
646 rotate_vector (current_frame
->charstarts
+ from
,
647 sizeof (int *) * (end
+ amount
- from
),
648 amount
* sizeof (int *));
650 safe_bcopy (current_frame
->used
+ from
,
651 current_frame
->used
+ from
+ amount
,
652 (end
- from
) * sizeof current_frame
->used
[0]);
654 safe_bcopy (current_frame
->highlight
+ from
,
655 current_frame
->highlight
+ from
+ amount
,
656 (end
- from
) * sizeof current_frame
->highlight
[0]);
658 safe_bcopy (current_frame
->enable
+ from
,
659 current_frame
->enable
+ from
+ amount
,
660 (end
- from
) * sizeof current_frame
->enable
[0]);
662 /* Adjust the lines by an amount
663 that puts the first of them at NEWPOS. */
664 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
666 /* Offset each char position in the charstarts lines we moved
668 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
670 int *line
= current_frame
->charstarts
[i
];
672 for (col
= 0; col
< width
; col
++)
674 line
[col
] += pos_adjust
;
676 for (i
= from
; i
< from
+ amount
; i
++)
678 int *line
= current_frame
->charstarts
[i
];
681 for (col
= 0; col
< width
; col
++)
685 /* Mark the lines made empty by scrolling as enabled, empty and
687 bzero (current_frame
->used
+ from
,
688 amount
* sizeof current_frame
->used
[0]);
689 bzero (current_frame
->highlight
+ from
,
690 amount
* sizeof current_frame
->highlight
[0]);
691 for (i
= from
; i
< from
+ amount
; i
++)
693 current_frame
->glyphs
[i
][0] = '\0';
694 current_frame
->charstarts
[i
][0] = -1;
695 current_frame
->enable
[i
] = 1;
698 safe_bcopy (current_frame
->bufp
+ from
,
699 current_frame
->bufp
+ from
+ amount
,
700 (end
- from
) * sizeof current_frame
->bufp
[0]);
702 #ifdef HAVE_X_WINDOWS
703 if (FRAME_X_P (frame
))
705 safe_bcopy (current_frame
->top_left_x
+ from
,
706 current_frame
->top_left_x
+ from
+ amount
,
707 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
709 safe_bcopy (current_frame
->top_left_y
+ from
,
710 current_frame
->top_left_y
+ from
+ amount
,
711 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
713 safe_bcopy (current_frame
->pix_width
+ from
,
714 current_frame
->pix_width
+ from
+ amount
,
715 (end
- from
) * sizeof current_frame
->pix_width
[0]);
717 safe_bcopy (current_frame
->pix_height
+ from
,
718 current_frame
->pix_height
+ from
+ amount
,
719 (end
- from
) * sizeof current_frame
->pix_height
[0]);
721 safe_bcopy (current_frame
->max_ascent
+ from
,
722 current_frame
->max_ascent
+ from
+ amount
,
723 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
725 #endif /* HAVE_X_WINDOWS */
731 update_begin (frame
);
732 set_terminal_window (end
);
733 ins_del_lines (from
+ amount
, amount
);
734 if (!scroll_region_ok
)
735 ins_del_lines (end
+ amount
, -amount
);
736 set_terminal_window (0);
738 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
739 sizeof (GLYPH
*) * (end
- from
- amount
),
740 amount
* sizeof (GLYPH
*));
742 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
743 sizeof (int *) * (end
- from
- amount
),
744 amount
* sizeof (int *));
746 safe_bcopy (current_frame
->used
+ from
,
747 current_frame
->used
+ from
+ amount
,
748 (end
- from
) * sizeof current_frame
->used
[0]);
750 safe_bcopy (current_frame
->highlight
+ from
,
751 current_frame
->highlight
+ from
+ amount
,
752 (end
- from
) * sizeof current_frame
->highlight
[0]);
754 safe_bcopy (current_frame
->enable
+ from
,
755 current_frame
->enable
+ from
+ amount
,
756 (end
- from
) * sizeof current_frame
->enable
[0]);
758 /* Adjust the lines by an amount
759 that puts the first of them at NEWPOS. */
760 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
762 /* Offset each char position in the charstarts lines we moved
764 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
766 int *line
= current_frame
->charstarts
[i
];
768 for (col
= 0; col
< width
; col
++)
770 line
[col
] += pos_adjust
;
772 for (i
= end
+ amount
; i
< end
; i
++)
774 int *line
= current_frame
->charstarts
[i
];
777 for (col
= 0; col
< width
; col
++)
781 /* Mark the lines made empty by scrolling as enabled, empty and
783 bzero (current_frame
->used
+ end
+ amount
,
784 - amount
* sizeof current_frame
->used
[0]);
785 bzero (current_frame
->highlight
+ end
+ amount
,
786 - amount
* sizeof current_frame
->highlight
[0]);
787 for (i
= end
+ amount
; i
< end
; i
++)
789 current_frame
->glyphs
[i
][0] = '\0';
790 current_frame
->charstarts
[i
][0] = 0;
791 current_frame
->enable
[i
] = 1;
794 safe_bcopy (current_frame
->bufp
+ from
,
795 current_frame
->bufp
+ from
+ amount
,
796 (end
- from
) * sizeof current_frame
->bufp
[0]);
798 #ifdef HAVE_X_WINDOWS
799 if (FRAME_X_P (frame
))
801 safe_bcopy (current_frame
->top_left_x
+ from
,
802 current_frame
->top_left_x
+ from
+ amount
,
803 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
805 safe_bcopy (current_frame
->top_left_y
+ from
,
806 current_frame
->top_left_y
+ from
+ amount
,
807 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
809 safe_bcopy (current_frame
->pix_width
+ from
,
810 current_frame
->pix_width
+ from
+ amount
,
811 (end
- from
) * sizeof current_frame
->pix_width
[0]);
813 safe_bcopy (current_frame
->pix_height
+ from
,
814 current_frame
->pix_height
+ from
+ amount
,
815 (end
- from
) * sizeof current_frame
->pix_height
[0]);
817 safe_bcopy (current_frame
->max_ascent
+ from
,
818 current_frame
->max_ascent
+ from
+ amount
,
819 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
821 #endif /* HAVE_X_WINDOWS */
828 /* After updating a window W that isn't the full frame wide,
829 copy all the columns that W does not occupy
830 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
831 so that update_frame will not change those columns. */
833 preserve_other_columns (w
)
837 register struct frame_glyphs
*current_frame
, *desired_frame
;
838 register FRAME_PTR frame
= XFRAME (w
->frame
);
839 int start
= XFASTINT (w
->left
);
840 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
841 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
843 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
844 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
846 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
848 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
854 bcopy (current_frame
->glyphs
[vpos
],
855 desired_frame
->glyphs
[vpos
],
856 start
* sizeof (current_frame
->glyphs
[vpos
][0]));
857 bcopy (current_frame
->charstarts
[vpos
],
858 desired_frame
->charstarts
[vpos
],
859 start
* sizeof (current_frame
->charstarts
[vpos
][0]));
860 len
= min (start
, current_frame
->used
[vpos
]);
861 if (desired_frame
->used
[vpos
] < len
)
862 desired_frame
->used
[vpos
] = len
;
864 if (current_frame
->used
[vpos
] > end
865 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
867 while (desired_frame
->used
[vpos
] < end
)
869 int used
= desired_frame
->used
[vpos
]++;
870 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
871 desired_frame
->glyphs
[vpos
][used
] = 0;
873 bcopy (current_frame
->glyphs
[vpos
] + end
,
874 desired_frame
->glyphs
[vpos
] + end
,
875 ((current_frame
->used
[vpos
] - end
)
876 * sizeof (current_frame
->glyphs
[vpos
][0])));
877 bcopy (current_frame
->charstarts
[vpos
] + end
,
878 desired_frame
->charstarts
[vpos
] + end
,
879 ((current_frame
->used
[vpos
] - end
)
880 * sizeof (current_frame
->charstarts
[vpos
][0])));
881 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
889 /* If window w does not need to be updated and isn't the full frame wide,
890 copy all the columns that w does occupy
891 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
892 so that update_frame will not change those columns.
894 Have not been able to figure out how to use this correctly. */
896 preserve_my_columns (w
)
899 register int vpos
, fin
;
900 register struct frame_glyphs
*l1
, *l2
;
901 register FRAME_PTR frame
= XFRAME (w
->frame
);
902 int start
= XFASTINT (w
->left
);
903 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
904 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
906 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
908 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
909 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
911 if (l2
->length
> start
&& l1
->length
< l2
->length
)
914 if (fin
> end
) fin
= end
;
915 while (l1
->length
< start
)
916 l1
->body
[l1
->length
++] = ' ';
917 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
926 /* Adjust by ADJUST the charstart values in window W
927 after vpos VPOS, which counts relative to the frame
928 (not relative to W itself). */
931 adjust_window_charstarts (w
, vpos
, adjust
)
936 int left
= XFASTINT (w
->left
);
937 int top
= XFASTINT (w
->top
);
938 int right
= left
+ window_internal_width (w
);
939 int bottom
= top
+ window_internal_height (w
);
942 for (i
= vpos
+ 1; i
< bottom
; i
++)
945 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
947 for (j
= left
; j
< right
; j
++)
948 if (charstart
[j
] > 0)
949 charstart
[j
] += adjust
;
953 /* Check the charstarts values in the area of window W
954 for internal consistency. We cannot check that they are "right";
955 we can only look for something nonsensical. */
957 verify_charstarts (w
)
960 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
962 int top
= XFASTINT (w
->top
);
963 int bottom
= top
+ window_internal_height (w
);
964 int left
= XFASTINT (w
->left
);
965 int right
= left
+ window_internal_width (w
);
967 int truncate
= (XINT (w
->hscroll
)
968 || (truncate_partial_width_windows
969 && (XFASTINT (w
->width
) < FRAME_WIDTH (f
)))
970 || !NILP (XBUFFER (w
->buffer
)->truncate_lines
));
972 for (i
= top
; i
< bottom
; i
++)
976 int *charstart
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[i
];
982 /* If we are truncating lines, allow a jump
983 in charstarts from one line to the next. */
984 if (charstart
[left
] < next_line
)
989 if (charstart
[left
] != next_line
)
994 for (j
= left
; j
< right
; j
++)
995 if (charstart
[j
] > 0)
997 /* Record where the next line should start. */
999 if (BUF_ZV (XBUFFER (w
->buffer
)) != last
)
1001 /* If there's a newline between the two lines, count that. */
1002 int endchar
= *BUF_CHAR_ADDRESS (XBUFFER (w
->buffer
), last
);
1003 if (endchar
== '\n')
1009 /* On discovering that the redisplay for a window was no good,
1010 cancel the columns of that window, so that when the window is
1011 displayed over again get_display_line will not complain. */
1013 cancel_my_columns (w
)
1017 register struct frame_glyphs
*desired_glyphs
1018 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
1019 register int start
= XFASTINT (w
->left
);
1020 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
1022 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
1023 if (desired_glyphs
->enable
[vpos
]
1024 && desired_glyphs
->used
[vpos
] >= start
)
1025 desired_glyphs
->used
[vpos
] = start
;
1028 /* These functions try to perform directly and immediately on the frame
1029 the necessary output for one change in the buffer.
1030 They may return 0 meaning nothing was done if anything is difficult,
1031 or 1 meaning the output was performed properly.
1032 They assume that the frame was up to date before the buffer
1033 change being displayed. They make various other assumptions too;
1034 see command_loop_1 where these are called. */
1037 direct_output_for_insert (g
)
1040 register FRAME_PTR frame
= selected_frame
;
1041 register struct frame_glyphs
*current_frame
1042 = FRAME_CURRENT_GLYPHS (frame
);
1044 #ifndef COMPILER_REGISTER_BUG
1046 #endif /* COMPILER_REGISTER_BUG */
1047 struct window
*w
= XWINDOW (selected_window
);
1048 #ifndef COMPILER_REGISTER_BUG
1050 #endif /* COMPILER_REGISTER_BUG */
1051 int hpos
= FRAME_CURSOR_X (frame
);
1052 #ifndef COMPILER_REGISTER_BUG
1054 #endif /* COMPILER_REGISTER_BUG */
1055 int vpos
= FRAME_CURSOR_Y (frame
);
1057 /* Give up if about to continue line. */
1058 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
1060 /* Avoid losing if cursor is in invisible text off left margin */
1061 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
1063 /* Give up if cursor outside window (in minibuf, probably) */
1064 || cursor_in_echo_area
1065 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
1066 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
1068 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
1069 || !display_completed
1071 /* Give up if buffer appears in two places. */
1072 || buffer_shared
> 1
1074 #ifdef USE_TEXT_PROPERTIES
1075 /* Intervals have already been adjusted, point is after the
1076 character that was just inserted. */
1077 /* Give up if character is invisible. */
1078 /* Give up if character has a face property.
1079 At the moment we only lose at end of line or end of buffer
1080 and only with faces that have some background */
1081 /* Instead of wasting time, give up if character has any text properties */
1082 || ! NILP (Ftext_properties_at (make_number (point
- 1), Qnil
))
1085 /* Give up if w is minibuffer and a message is being displayed there */
1086 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1094 if (FRAME_X_P (frame
))
1095 face
= compute_char_face (frame
, w
, point
- 1, -1, -1, &dummy
, point
, 0);
1097 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1098 current_frame
->charstarts
[vpos
][hpos
] = point
- 1;
1099 /* Record the entry for after the newly inserted character. */
1100 current_frame
->charstarts
[vpos
][hpos
+ 1] = point
;
1101 adjust_window_charstarts (w
, vpos
, 1);
1103 unchanged_modified
= MODIFF
;
1104 beg_unchanged
= GPT
- BEG
;
1105 XSETFASTINT (w
->last_point
, point
);
1106 XSETFASTINT (w
->last_point_x
, hpos
);
1107 XSETFASTINT (w
->last_modified
, MODIFF
);
1109 reassert_line_highlight (0, vpos
);
1110 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
1112 ++FRAME_CURSOR_X (frame
);
1113 if (hpos
== current_frame
->used
[vpos
])
1115 current_frame
->used
[vpos
] = hpos
+ 1;
1116 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
1123 direct_output_forward_char (n
)
1126 register FRAME_PTR frame
= selected_frame
;
1127 register struct window
*w
= XWINDOW (selected_window
);
1128 Lisp_Object position
;
1129 int hpos
= FRAME_CURSOR_X (frame
);
1131 /* Give up if in truncated text at end of line. */
1132 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1)
1135 /* Avoid losing if cursor is in invisible text off left margin
1136 or about to go off either side of window. */
1137 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
1138 && (XINT (w
->hscroll
) || n
< 0))
1140 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
1141 || cursor_in_echo_area
)
1144 /* Can't use direct output if highlighting a region. */
1145 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1148 #ifdef USE_TEXT_PROPERTIES
1149 /* Don't use direct output next to an invisible character
1150 since we might need to do something special. */
1152 XSETFASTINT (position
, point
);
1153 if (XFASTINT (position
) < ZV
1154 && ! NILP (Fget_char_property (position
,
1159 XSETFASTINT (position
, point
- 1);
1160 if (XFASTINT (position
) >= BEGV
1161 && ! NILP (Fget_char_property (position
,
1167 FRAME_CURSOR_X (frame
) += n
;
1168 XSETFASTINT (w
->last_point_x
, FRAME_CURSOR_X (frame
));
1169 XSETFASTINT (w
->last_point
, point
);
1170 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1176 static void update_line ();
1178 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1179 Value is nonzero if redisplay stopped due to pending input.
1180 FORCE nonzero means do not stop for pending input. */
1183 update_frame (f
, force
, inhibit_hairy_id
)
1186 int inhibit_hairy_id
;
1188 register struct frame_glyphs
*current_frame
;
1189 register struct frame_glyphs
*desired_frame
= 0;
1192 int preempt_count
= baud_rate
/ 2400 + 1;
1193 extern input_pending
;
1194 #ifdef HAVE_X_WINDOWS
1195 register int downto
, leftmost
;
1198 if (preempt_count
<= 0)
1201 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1203 detect_input_pending ();
1204 if (input_pending
&& !force
)
1212 if (!line_ins_del_ok
)
1213 inhibit_hairy_id
= 1;
1215 /* These are separate to avoid a possible bug in the AIX C compiler. */
1216 current_frame
= FRAME_CURRENT_GLYPHS (f
);
1217 desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1219 /* See if any of the desired lines are enabled; don't compute for
1220 i/d line if just want cursor motion. */
1221 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1222 if (desired_frame
->enable
[i
])
1225 /* Try doing i/d line, if not yet inhibited. */
1226 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1227 force
|= scrolling (f
);
1229 /* Update the individual lines as needed. Do bottom line first. */
1231 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1232 update_line (f
, FRAME_HEIGHT (f
) - 1);
1234 #ifdef HAVE_X_WINDOWS
1237 leftmost
= downto
= f
->display
.x
->internal_border_width
;
1238 if (desired_frame
->enable
[0])
1240 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1241 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1242 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
1243 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1244 current_frame
->top_left_x
[0] = leftmost
;
1245 current_frame
->top_left_y
[0] = downto
;
1248 #endif /* HAVE_X_WINDOWS */
1250 /* Now update the rest of the lines. */
1251 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1253 if (desired_frame
->enable
[i
])
1255 if (FRAME_TERMCAP_P (f
))
1257 /* Flush out every so many lines.
1258 Also flush out if likely to have more than 1k buffered
1259 otherwise. I'm told that some telnet connections get
1260 really screwed by more than 1k output at once. */
1261 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1263 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1266 if (preempt_count
== 1)
1268 #ifdef EMACS_OUTQSIZE
1269 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1270 /* Probably not a tty. Ignore the error and reset
1271 * the outq count. */
1272 outq
= PENDING_OUTPUT_COUNT (stdout
);
1275 if (baud_rate
<= outq
&& baud_rate
> 0)
1276 sleep (outq
/ baud_rate
);
1279 if ((i
- 1) % preempt_count
== 0)
1280 detect_input_pending ();
1284 #ifdef HAVE_X_WINDOWS
1287 current_frame
->top_left_y
[i
] = downto
;
1288 current_frame
->top_left_x
[i
] = leftmost
;
1290 #endif /* HAVE_X_WINDOWS */
1293 #ifdef HAVE_X_WINDOWS
1295 downto
+= current_frame
->pix_height
[i
];
1298 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1300 /* Now just clean up termcap drivers and set cursor, etc. */
1303 if (cursor_in_echo_area
1304 && FRAME_HAS_MINIBUF_P (f
))
1306 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1309 if (cursor_in_echo_area
< 0)
1316 /* If the minibuffer is several lines high, find the last
1317 line that has any text on it. */
1318 row
= FRAME_HEIGHT (f
);
1322 if (current_frame
->enable
[row
])
1323 col
= current_frame
->used
[row
];
1327 while (row
> top
&& col
== 0);
1329 if (col
>= FRAME_WIDTH (f
))
1332 if (row
< FRAME_HEIGHT (f
) - 1)
1337 cursor_to (row
, col
);
1340 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1341 FRAME_WIDTH (f
) - 1), 0));
1347 fflush (termscript
);
1350 /* Here if output is preempted because input is detected. */
1353 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1354 display_completed
= !pause
;
1356 bzero (FRAME_DESIRED_GLYPHS (f
)->enable
, FRAME_HEIGHT (f
));
1360 /* Called when about to quit, to check for doing so
1361 at an improper time. */
1366 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1368 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1370 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1374 /* Decide what insert/delete line to do, and do it */
1376 extern void scrolling_1 ();
1381 int unchanged_at_top
, unchanged_at_bottom
;
1384 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1385 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1386 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1388 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1389 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1390 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1392 /* Compute hash codes of all the lines.
1393 Also calculate number of changed lines,
1394 number of unchanged lines at the beginning,
1395 and number of unchanged lines at the end. */
1398 unchanged_at_top
= 0;
1399 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1400 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1402 /* Give up on this scrolling if some old lines are not enabled. */
1403 if (!current_frame
->enable
[i
])
1405 old_hash
[i
] = line_hash_code (current_frame
, i
);
1406 if (! desired_frame
->enable
[i
])
1407 new_hash
[i
] = old_hash
[i
];
1409 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1411 if (old_hash
[i
] != new_hash
[i
])
1414 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1416 else if (i
== unchanged_at_top
)
1418 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1421 /* If changed lines are few, don't allow preemption, don't scroll. */
1422 if (changed_lines
< baud_rate
/ 2400
1423 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1426 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1427 - unchanged_at_bottom
);
1429 if (scroll_region_ok
)
1430 free_at_end_vpos
-= unchanged_at_bottom
;
1431 else if (memory_below_frame
)
1432 free_at_end_vpos
= -1;
1434 /* If large window, fast terminal and few lines in common between
1435 current frame and desired frame, don't bother with i/d calc. */
1436 if (window_size
>= 18 && baud_rate
> 2400
1438 10 * scrolling_max_lines_saved (unchanged_at_top
,
1439 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1440 old_hash
, new_hash
, draw_cost
)))
1443 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1444 draw_cost
+ unchanged_at_top
- 1,
1445 old_hash
+ unchanged_at_top
- 1,
1446 new_hash
+ unchanged_at_top
- 1,
1447 free_at_end_vpos
- unchanged_at_top
);
1452 /* Return the offset in its buffer of the character at location col, line
1453 in the given window. */
1455 buffer_posn_from_coords (window
, col
, line
)
1456 struct window
*window
;
1459 int hscroll
= XINT (window
->hscroll
);
1460 int window_left
= XFASTINT (window
->left
);
1462 /* The actual width of the window is window->width less one for the
1463 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1465 int window_width
= window_internal_width (window
) - 1;
1467 int startp
= marker_position (window
->start
);
1469 /* Since compute_motion will only operate on the current buffer,
1470 we need to save the old one and restore it when we're done. */
1471 struct buffer
*old_current_buffer
= current_buffer
;
1472 struct position
*posn
;
1474 current_buffer
= XBUFFER (window
->buffer
);
1476 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1477 (window->frame))->bufp to avoid scanning from the very top of
1478 the window, but it isn't maintained correctly, and I'm not even
1479 sure I will keep it. */
1480 posn
= compute_motion (startp
, 0,
1481 (window
== XWINDOW (minibuf_window
) && startp
== 1
1482 ? minibuf_prompt_width
: 0)
1483 + (hscroll
? 1 - hscroll
: 0),
1485 window_width
, hscroll
, 0, window
);
1487 current_buffer
= old_current_buffer
;
1489 /* compute_motion considers frame points past the end of a line
1490 to be *after* the newline, i.e. at the start of the next line.
1491 This is reasonable, but not really what we want. So if the
1492 result is on a line below LINE, back it up one character. */
1493 if (posn
->vpos
> line
)
1494 return posn
->bufpos
- 1;
1496 return posn
->bufpos
;
1503 register GLYPH
*p
= r
;
1504 while (*p
++ == SPACEGLYPH
);
1509 count_match (str1
, str2
)
1512 register GLYPH
*p1
= str1
;
1513 register GLYPH
*p2
= str2
;
1514 while (*p1
++ == *p2
++);
1515 return p1
- str1
- 1;
1518 /* Char insertion/deletion cost vector, from term.c */
1519 extern int *char_ins_del_vector
;
1521 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1524 update_line (frame
, vpos
)
1525 register FRAME_PTR frame
;
1528 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1531 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1533 register struct frame_glyphs
*current_frame
1534 = FRAME_CURRENT_GLYPHS (frame
);
1535 register struct frame_glyphs
*desired_frame
1536 = FRAME_DESIRED_GLYPHS (frame
);
1538 if (desired_frame
->highlight
[vpos
]
1539 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1541 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1542 (current_frame
->enable
[vpos
] ?
1543 current_frame
->used
[vpos
] : 0));
1544 current_frame
->enable
[vpos
] = 0;
1547 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1549 if (! current_frame
->enable
[vpos
])
1555 obody
= current_frame
->glyphs
[vpos
];
1556 olen
= current_frame
->used
[vpos
];
1557 if (! current_frame
->highlight
[vpos
])
1559 if (!must_write_spaces
)
1560 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1565 /* For an inverse-video line, remember we gave it
1566 spaces all the way to the frame edge
1567 so that the reverse video extends all the way across. */
1569 while (olen
< FRAME_WIDTH (frame
) - 1)
1570 obody
[olen
++] = SPACEGLYPH
;
1574 /* One way or another, this will enable the line being updated. */
1575 current_frame
->enable
[vpos
] = 1;
1576 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1577 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1578 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1580 #ifdef HAVE_X_WINDOWS
1581 if (FRAME_X_P (frame
))
1583 current_frame
->pix_width
[vpos
]
1584 = current_frame
->used
[vpos
]
1585 * FONT_WIDTH (frame
->display
.x
->font
);
1586 current_frame
->pix_height
[vpos
]
1587 = frame
->display
.x
->line_height
;
1589 #endif /* HAVE_X_WINDOWS */
1591 if (!desired_frame
->enable
[vpos
])
1597 nbody
= desired_frame
->glyphs
[vpos
];
1598 nlen
= desired_frame
->used
[vpos
];
1600 /* Pretend trailing spaces are not there at all,
1601 unless for one reason or another we must write all spaces. */
1602 if (! desired_frame
->highlight
[vpos
])
1604 if (!must_write_spaces
)
1605 /* We know that the previous character byte contains 0. */
1606 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1611 /* For an inverse-video line, give it extra trailing spaces
1612 all the way to the frame edge
1613 so that the reverse video extends all the way across. */
1615 while (nlen
< FRAME_WIDTH (frame
) - 1)
1616 nbody
[nlen
++] = SPACEGLYPH
;
1619 /* If there's no i/d char, quickly do the best we can without it. */
1620 if (!char_ins_del_ok
)
1625 if (FRAME_X_P (frame
))
1627 /* Under X, erase everything we are going to rewrite,
1628 and rewrite everything from the first char that's changed.
1629 This is part of supporting fonts like Courier
1630 whose chars can overlap outside the char width. */
1631 for (i
= 0; i
< nlen
; i
++)
1632 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1635 cursor_to (vpos
, i
);
1637 clear_end_of_line (olen
);
1638 write_glyphs (nbody
+ i
, nlen
- i
);
1643 for (i
= 0; i
< nlen
; i
++)
1645 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1647 cursor_to (vpos
, i
);
1648 for (j
= 1; (i
+ j
< nlen
&&
1649 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1652 /* Output this run of non-matching chars. */
1653 write_glyphs (nbody
+ i
, j
);
1656 /* Now find the next non-match. */
1660 /* Clear the rest of the line, or the non-clear part of it. */
1663 cursor_to (vpos
, nlen
);
1664 clear_end_of_line (olen
);
1667 /* Exchange contents between current_frame and new_frame. */
1668 temp
= desired_frame
->glyphs
[vpos
];
1669 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1670 current_frame
->glyphs
[vpos
] = temp
;
1672 /* Exchange charstarts between current_frame and new_frame. */
1673 temp1
= desired_frame
->charstarts
[vpos
];
1674 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1675 current_frame
->charstarts
[vpos
] = temp1
;
1682 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1683 ? 0 : count_blanks (nbody
);
1686 cursor_to (vpos
, nsp
);
1687 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1690 /* Exchange contents between current_frame and new_frame. */
1691 temp
= desired_frame
->glyphs
[vpos
];
1692 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1693 current_frame
->glyphs
[vpos
] = temp
;
1695 /* Exchange charstarts between current_frame and new_frame. */
1696 temp1
= desired_frame
->charstarts
[vpos
];
1697 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1698 current_frame
->charstarts
[vpos
] = temp1
;
1707 /* Compute number of leading blanks in old and new contents. */
1708 osp
= count_blanks (obody
);
1709 if (!desired_frame
->highlight
[vpos
])
1710 nsp
= count_blanks (nbody
);
1714 /* Compute number of matching chars starting with first nonblank. */
1715 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1717 /* Spaces in new match implicit space past the end of old. */
1718 /* A bug causing this to be a no-op was fixed in 18.29. */
1719 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1722 while (np1
[begmatch
] == SPACEGLYPH
)
1726 /* Avoid doing insert/delete char
1727 just cause number of leading spaces differs
1728 when the following text does not match. */
1729 if (begmatch
== 0 && osp
!= nsp
)
1730 osp
= nsp
= min (osp
, nsp
);
1732 /* Find matching characters at end of line */
1735 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1736 while (op1
> op2
&& op1
[-1] == np1
[-1])
1741 endmatch
= obody
+ olen
- op1
;
1743 /* Put correct value back in nbody[nlen].
1744 This is important because direct_output_for_insert
1745 can write into the line at a later point.
1746 If this screws up the zero at the end of the line, re-establish it. */
1750 /* tem gets the distance to insert or delete.
1751 endmatch is how many characters we save by doing so.
1754 tem
= (nlen
- nsp
) - (olen
- osp
);
1756 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1759 /* nsp - osp is the distance to insert or delete.
1760 If that is nonzero, begmatch is known to be nonzero also.
1761 begmatch + endmatch is how much we save by doing the ins/del.
1765 && (!char_ins_del_ok
1766 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1770 osp
= nsp
= min (osp
, nsp
);
1773 /* Now go through the line, inserting, writing and
1774 deleting as appropriate. */
1778 cursor_to (vpos
, nsp
);
1779 delete_glyphs (osp
- nsp
);
1783 /* If going to delete chars later in line
1784 and insert earlier in the line,
1785 must delete first to avoid losing data in the insert */
1786 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1788 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1789 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1790 olen
= nlen
- (nsp
- osp
);
1792 cursor_to (vpos
, osp
);
1793 insert_glyphs ((char *)0, nsp
- osp
);
1797 tem
= nsp
+ begmatch
+ endmatch
;
1798 if (nlen
!= tem
|| olen
!= tem
)
1800 cursor_to (vpos
, nsp
+ begmatch
);
1801 if (!endmatch
|| nlen
== olen
)
1803 /* If new text being written reaches right margin,
1804 there is no need to do clear-to-eol at the end.
1805 (and it would not be safe, since cursor is not
1806 going to be "at the margin" after the text is done) */
1807 if (nlen
== FRAME_WIDTH (frame
))
1809 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1813 /* the following code loses disastrously if tem == nlen.
1814 Rather than trying to fix that case, I am trying the simpler
1815 solution found above. */
1817 /* If the text reaches to the right margin,
1818 it will lose one way or another (depending on AutoWrap)
1819 to clear to end of line after outputting all the text.
1820 So pause with one character to go and clear the line then. */
1821 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1823 /* endmatch must be zero, and tem must equal nsp + begmatch */
1824 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1825 clear_end_of_line (olen
);
1826 olen
= 0; /* Don't let it be cleared again later */
1827 write_glyphs (nbody
+ nlen
- 1, 1);
1830 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1831 #endif /* OBSOLETE */
1834 else if (nlen
> olen
)
1836 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1837 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1840 else if (olen
> nlen
)
1842 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1843 delete_glyphs (olen
- nlen
);
1849 /* If any unerased characters remain after the new line, erase them. */
1852 cursor_to (vpos
, nlen
);
1853 clear_end_of_line (olen
);
1856 /* Exchange contents between current_frame and new_frame. */
1857 temp
= desired_frame
->glyphs
[vpos
];
1858 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1859 current_frame
->glyphs
[vpos
] = temp
;
1861 /* Exchange charstarts between current_frame and new_frame. */
1862 temp1
= desired_frame
->charstarts
[vpos
];
1863 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1864 current_frame
->charstarts
[vpos
] = temp1
;
1867 /* A vector of size >= NFRAMES + 3 * NBUFFERS + 1, containing the session's
1868 frames, buffers, buffer-read-only flags, and buffer-modified-flags,
1869 and a trailing sentinel (so we don't need to add length checks). */
1870 static Lisp_Object frame_and_buffer_state
;
1872 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p
,
1873 Sframe_or_buffer_changed_p
, 0, 0, 0,
1874 "Return non-nil if the frame and buffer state appears to have changed.\n\
1875 The state variable is an internal vector containing all frames and buffers,\n\
1876 along with the buffers' read-only and modified flags, which allows a fast\n\
1877 check to see whether the menu bars might need to be recomputed.\n\
1878 If this function returns non-nil, it updates the internal vector to reflect\n\
1879 the current state.\n")
1882 Lisp_Object tail
, frame
, buf
;
1885 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1886 FOR_EACH_FRAME (tail
, frame
)
1887 if (!EQ (*vecp
++, frame
))
1889 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1891 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1892 if (!EQ (*vecp
++, buf
))
1894 if (!EQ (*vecp
++, XBUFFER (buf
)->read_only
))
1896 if (!EQ (*vecp
++, Fbuffer_modified_p (buf
)))
1902 FOR_EACH_FRAME (tail
, frame
)
1904 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1906 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
1907 if (n
> XVECTOR (frame_and_buffer_state
)->size
1908 || n
< XVECTOR (frame_and_buffer_state
)->size
/ 2)
1909 frame_and_buffer_state
= Fmake_vector (make_number (n
), Qlambda
);
1910 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1911 FOR_EACH_FRAME (tail
, frame
)
1913 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1915 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1917 *vecp
++ = XBUFFER (buf
)->read_only
;
1918 *vecp
++ = Fbuffer_modified_p (buf
);
1920 /* If we left any slack in the vector, fill it up now. */
1921 for (; n
< XVECTOR (frame_and_buffer_state
)->size
; ++n
)
1926 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1927 1, 1, "FOpen termscript file: ",
1928 "Start writing all terminal output to FILE as well as the terminal.\n\
1929 FILE = nil means just close any termscript file currently open.")
1933 if (termscript
!= 0) fclose (termscript
);
1938 file
= Fexpand_file_name (file
, Qnil
);
1939 termscript
= fopen (XSTRING (file
)->data
, "w");
1940 if (termscript
== 0)
1941 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1949 window_change_signal ()
1953 int old_errno
= errno
;
1955 get_frame_size (&width
, &height
);
1957 /* The frame size change obviously applies to a termcap-controlled
1958 frame. Find such a frame in the list, and assume it's the only
1959 one (since the redisplay code always writes to stdout, not a
1960 FILE * specified in the frame structure). Record the new size,
1961 but don't reallocate the data structures now. Let that be done
1962 later outside of the signal handler. */
1965 Lisp_Object tail
, frame
;
1967 FOR_EACH_FRAME (tail
, frame
)
1969 if (FRAME_TERMCAP_P (XFRAME (frame
)))
1971 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
1977 signal (SIGWINCH
, window_change_signal
);
1980 #endif /* SIGWINCH */
1983 /* Do any change in frame size that was requested by a signal. */
1985 do_pending_window_change ()
1987 /* If window_change_signal should have run before, run it now. */
1988 while (delayed_size_change
)
1990 Lisp_Object tail
, frame
;
1992 delayed_size_change
= 0;
1994 FOR_EACH_FRAME (tail
, frame
)
1996 FRAME_PTR f
= XFRAME (frame
);
1998 int height
= FRAME_NEW_HEIGHT (f
);
1999 int width
= FRAME_NEW_WIDTH (f
);
2001 if (height
!= 0 || width
!= 0)
2002 change_frame_size (f
, height
, width
, 0, 0);
2008 /* Change the frame height and/or width. Values may be given as zero to
2009 indicate no change is to take place.
2011 If DELAY is non-zero, then assume we're being called from a signal
2012 handler, and queue the change for later - perhaps the next
2013 redisplay. Since this tries to resize windows, we can't call it
2014 from a signal handler. */
2016 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
2017 register FRAME_PTR frame
;
2018 int newheight
, newwidth
, pretend
;
2020 /* If we can't deal with the change now, queue it for later. */
2023 FRAME_NEW_HEIGHT (frame
) = newheight
;
2024 FRAME_NEW_WIDTH (frame
) = newwidth
;
2025 delayed_size_change
= 1;
2029 /* This size-change overrides any pending one for this frame. */
2030 FRAME_NEW_HEIGHT (frame
) = 0;
2031 FRAME_NEW_WIDTH (frame
) = 0;
2033 /* If an argument is zero, set it to the current value. */
2034 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
2035 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
2037 /* Round up to the smallest acceptable size. */
2038 check_frame_size (frame
, &newheight
, &newwidth
);
2040 /* If we're not changing the frame size, quit now. */
2041 if (newheight
== FRAME_HEIGHT (frame
)
2042 && newwidth
== FRAME_WIDTH (frame
))
2045 if (newheight
!= FRAME_HEIGHT (frame
))
2047 if (FRAME_HAS_MINIBUF_P (frame
)
2048 && ! FRAME_MINIBUF_ONLY_P (frame
))
2050 /* Frame has both root and minibuffer. */
2051 set_window_height (FRAME_ROOT_WINDOW (frame
),
2052 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
2053 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
,
2055 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
2058 /* Frame has just one top-level window. */
2059 set_window_height (FRAME_ROOT_WINDOW (frame
),
2060 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
2062 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2063 FrameRows
= newheight
;
2066 if (frame
->output_method
== output_termcap
)
2068 frame_height
= newheight
;
2070 FrameRows
= newheight
;
2075 if (newwidth
!= FRAME_WIDTH (frame
))
2077 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
2078 if (FRAME_HAS_MINIBUF_P (frame
))
2079 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
2081 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2082 FrameCols
= newwidth
;
2084 if (frame
->output_method
== output_termcap
)
2086 frame_width
= newwidth
;
2088 FrameCols
= newwidth
;
2093 FRAME_HEIGHT (frame
) = newheight
;
2094 FRAME_WIDTH (frame
) = newwidth
;
2096 if (FRAME_CURSOR_X (frame
) >= FRAME_WIDTH (frame
))
2097 FRAME_CURSOR_X (frame
) = FRAME_WIDTH (frame
) - 1;
2098 if (FRAME_CURSOR_Y (frame
) >= FRAME_HEIGHT (frame
))
2099 FRAME_CURSOR_Y (frame
) = FRAME_HEIGHT (frame
) - 1;
2101 remake_frame_glyphs (frame
);
2102 calculate_costs (frame
);
2105 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
2106 Ssend_string_to_terminal
, 1, 1, 0,
2107 "Send STRING to the terminal without alteration.\n\
2108 Control characters in STRING will have terminal-dependent effects.")
2112 CHECK_STRING (str
, 0);
2113 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
2117 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
2118 fflush (termscript
);
2123 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
2124 "Beep, or flash the screen.\n\
2125 Also, unless an argument is given,\n\
2126 terminate any keyboard macro currently executing.")
2148 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
2149 error ("Keyboard macro terminated by a command ringing the bell");
2155 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
2156 "Pause, without updating display, for SECONDS seconds.\n\
2157 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2158 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2159 additional wait period, in milliseconds; this may be useful if your\n\
2160 Emacs was built without floating point support.\n\
2161 \(Not all operating systems support waiting for a fraction of a second.)")
2162 (seconds
, milliseconds
)
2163 Lisp_Object seconds
, milliseconds
;
2167 if (NILP (milliseconds
))
2168 XSETINT (milliseconds
, 0);
2170 CHECK_NUMBER (milliseconds
, 1);
2171 usec
= XINT (milliseconds
) * 1000;
2173 #ifdef LISP_FLOAT_TYPE
2175 double duration
= extract_float (seconds
);
2176 sec
= (int) duration
;
2177 usec
+= (duration
- sec
) * 1000000;
2180 CHECK_NUMBER (seconds
, 0);
2181 sec
= XINT (seconds
);
2184 #ifndef EMACS_HAS_USECS
2185 if (sec
== 0 && usec
!= 0)
2186 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2189 /* Assure that 0 <= usec < 1000000. */
2192 /* We can't rely on the rounding being correct if user is negative. */
2193 if (-1000000 < usec
)
2194 sec
--, usec
+= 1000000;
2196 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2199 sec
+= usec
/ 1000000, usec
%= 1000000;
2207 XSETFASTINT (zero
, 0);
2208 wait_reading_process_input (sec
, usec
, zero
, 0);
2211 /* We should always have wait_reading_process_input; we have a dummy
2212 implementation for systems which don't support subprocesses. */
2214 /* No wait_reading_process_input */
2221 /* The reason this is done this way
2222 (rather than defined (H_S) && defined (H_T))
2223 is because the VMS preprocessor doesn't grok `defined' */
2225 EMACS_GET_TIME (end_time
);
2226 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2227 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2231 EMACS_GET_TIME (timeout
);
2232 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2233 if (EMACS_TIME_NEG_P (timeout
)
2234 || !select (1, 0, 0, 0, &timeout
))
2237 #else /* not HAVE_SELECT */
2239 #endif /* HAVE_SELECT */
2240 #endif /* not VMS */
2243 #endif /* no subprocesses */
2248 /* This is just like wait_reading_process_input, except that
2249 it does the redisplay.
2251 It's also much like Fsit_for, except that it can be used for
2252 waiting for input as well. One differnce is that sit_for
2253 does not call prepare_menu_bars; Fsit_for does call that. */
2256 sit_for (sec
, usec
, reading
, display
)
2257 int sec
, usec
, reading
, display
;
2259 Lisp_Object read_kbd
;
2261 if (detect_input_pending ())
2265 redisplay_preserve_echo_area ();
2267 if (sec
== 0 && usec
== 0)
2274 XSETINT (read_kbd
, reading
? -1 : 1);
2275 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2278 /* wait_reading_process_input should always be available now; it is
2279 simulated in a simple way on systems that don't support
2282 /* No wait_reading_process_input available. */
2288 input_wait_timeout (XINT (arg
));
2290 #ifndef HAVE_TIMEVAL
2292 select (1, &waitchannels
, 0, 0, &timeout_sec
);
2293 #else /* HAVE_TIMEVAL */
2294 timeout
.tv_sec
= sec
;
2295 timeout
.tv_usec
= usec
;
2296 select (1, &waitchannels
, 0, 0, &timeout
);
2297 #endif /* HAVE_TIMEVAL */
2298 #endif /* not VMS */
2303 return detect_input_pending () ? Qnil
: Qt
;
2306 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2307 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2308 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2309 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2310 additional wait period, in milliseconds; this may be useful if your\n\
2311 Emacs was built without floating point support.\n\
2312 \(Not all operating systems support waiting for a fraction of a second.)\n\
2313 Optional third arg non-nil means don't redisplay, just wait for input.\n\
2314 Redisplay is preempted as always if input arrives, and does not happen\n\
2315 if input is available before it starts.\n\
2316 Value is t if waited the full time with no input arriving.")
2317 (seconds
, milliseconds
, nodisp
)
2318 Lisp_Object seconds
, milliseconds
, nodisp
;
2322 if (NILP (milliseconds
))
2323 XSETINT (milliseconds
, 0);
2325 CHECK_NUMBER (milliseconds
, 1);
2326 usec
= XINT (milliseconds
) * 1000;
2328 #ifdef LISP_FLOAT_TYPE
2330 double duration
= extract_float (seconds
);
2331 sec
= (int) duration
;
2332 usec
+= (duration
- sec
) * 1000000;
2335 CHECK_NUMBER (seconds
, 0);
2336 sec
= XINT (seconds
);
2339 #ifndef EMACS_HAS_USECS
2340 if (usec
!= 0 && sec
== 0)
2341 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2345 prepare_menu_bars ();
2346 return sit_for (sec
, usec
, 0, NILP (nodisp
));
2349 char *terminal_type
;
2351 /* Initialization done when Emacs fork is started, before doing stty. */
2352 /* Determine terminal type and set terminal_driver */
2353 /* Then invoke its decoding routine to set up variables
2354 in the terminal package */
2358 #ifdef HAVE_X_WINDOWS
2359 extern int display_arg
;
2364 cursor_in_echo_area
= 0;
2365 terminal_type
= (char *) 0;
2367 /* Now is the time to initialize this; it's used by init_sys_modes
2369 Vwindow_system
= Qnil
;
2371 /* If the user wants to use a window system, we shouldn't bother
2372 initializing the terminal. This is especially important when the
2373 terminal is so dumb that emacs gives up before and doesn't bother
2374 using the window system.
2376 If the DISPLAY environment variable is set, try to use X, and die
2377 with an error message if that doesn't work. */
2379 #ifdef HAVE_X_WINDOWS
2383 display_arg
= (getenv ("DECW$DISPLAY") != 0);
2385 display_arg
= (getenv ("DISPLAY") != 0);
2389 if (!inhibit_window_system
&& display_arg
)
2391 Vwindow_system
= intern ("x");
2393 Vwindow_system_version
= make_number (11);
2395 Vwindow_system_version
= make_number (10);
2399 #endif /* HAVE_X_WINDOWS */
2401 /* If no window system has been specified, try to use the terminal. */
2404 fprintf (stderr
, "emacs: standard input is not a tty\n");
2408 /* Look at the TERM variable */
2409 terminal_type
= (char *) getenv ("TERM");
2413 fprintf (stderr
, "Please specify your terminal type.\n\
2414 For types defined in VMS, use set term /device=TYPE.\n\
2415 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2416 \(The quotation marks are necessary since terminal types are lower case.)\n");
2418 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2424 /* VMS DCL tends to upcase things, so downcase term type.
2425 Hardly any uppercase letters in terminal types; should be none. */
2427 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2430 strcpy (new, terminal_type
);
2432 for (p
= new; *p
; p
++)
2436 terminal_type
= new;
2440 term_init (terminal_type
);
2442 remake_frame_glyphs (selected_frame
);
2443 calculate_costs (selected_frame
);
2445 /* X and Y coordinates of the cursor between updates. */
2446 FRAME_CURSOR_X (selected_frame
) = 0;
2447 FRAME_CURSOR_Y (selected_frame
) = 0;
2452 #endif /* CANNOT_DUMP */
2453 signal (SIGWINCH
, window_change_signal
);
2454 #endif /* SIGWINCH */
2460 defsubr (&Sredraw_frame
);
2462 defsubr (&Sredraw_display
);
2463 defsubr (&Sframe_or_buffer_changed_p
);
2464 defsubr (&Sopen_termscript
);
2466 defsubr (&Ssit_for
);
2467 defsubr (&Ssleep_for
);
2468 defsubr (&Ssend_string_to_terminal
);
2470 frame_and_buffer_state
= Fmake_vector (make_number (1), Qlambda
);
2471 staticpro (&frame_and_buffer_state
);
2473 DEFVAR_INT ("baud-rate", &baud_rate
,
2474 "*The output baud rate of the terminal.\n\
2475 On most systems, changing this value will affect the amount of padding\n\
2476 and the other strategic decisions made during redisplay.");
2477 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2478 "*Non-nil means invert the entire frame display.\n\
2479 This means everything is in inverse video which otherwise would not be.");
2480 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2481 "*Non-nil means try to flash the frame to represent a bell.");
2482 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2483 "*Non-nil means no need to redraw entire frame after suspending.\n\
2484 A non-nil value is useful if the terminal can automatically preserve\n\
2485 Emacs's frame display when you reenter Emacs.\n\
2486 It is up to you to set this variable if your terminal can do that.");
2487 DEFVAR_LISP ("window-system", &Vwindow_system
,
2488 "A symbol naming the window-system under which Emacs is running\n\
2489 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2490 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2491 "The version number of the window system in use.\n\
2492 For X windows, this is 10 or 11.");
2493 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2494 "Non-nil means put cursor in minibuffer, at end of any message there.");
2495 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2496 "Table defining how to output a glyph code to the frame.\n\
2497 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2498 Each element can be:\n\
2499 integer: a glyph code which this glyph is an alias for.\n\
2500 string: output this glyph using that string (not impl. in X windows).\n\
2501 nil: this glyph mod 256 is char code to output,\n\
2502 and this glyph / 256 is face code for X windows (see `face-id').");
2503 Vglyph_table
= Qnil
;
2505 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2506 "Display table to use for buffers that specify none.\n\
2507 See `buffer-display-table' for more information.");
2508 Vstandard_display_table
= Qnil
;
2510 /* Initialize `window-system', unless init_display already decided it. */
2515 Vwindow_system
= Qnil
;
2516 Vwindow_system_version
= Qnil
;