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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
32 #include "termhooks.h"
33 /* cm.h must come after dispextern.h on Windows. */
34 #include "dispextern.h"
42 #include "intervals.h"
43 #include "blockinput.h"
46 #include "syssignal.h"
50 #endif /* HAVE_X_WINDOWS */
54 #endif /* HAVE_NTGUI */
56 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
61 #define max(a, b) ((a) > (b) ? (a) : (b))
62 #define min(a, b) ((a) < (b) ? (a) : (b))
64 /* Get number of chars of output now in the buffer of a stdio stream.
65 This ought to be built in in stdio, but it isn't.
66 Some s- files override this because their stdio internals differ. */
67 #ifdef __GNU_LIBRARY__
68 /* The s- file might have overridden the definition with one that works for
69 the system's C library. But we are using the GNU C library, so this is
70 the right definition for every system. */
71 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
72 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
74 #undef PENDING_OUTPUT_COUNT
75 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
77 #else /* not __GNU_LIBRARY__ */
78 #ifndef PENDING_OUTPUT_COUNT
79 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
83 static void change_frame_size_1 ();
85 /* Nonzero upon entry to redisplay means do not assume anything about
86 current contents of actual terminal frame; clear and redraw it. */
90 /* Nonzero means last display completed. Zero means it was preempted. */
92 int display_completed
;
94 /* Lisp variable visible-bell; enables use of screen-flash
95 instead of audible bell. */
99 /* Invert the color of the whole frame, at a low level. */
103 /* Line speed of the terminal. */
107 /* nil or a symbol naming the window system under which emacs is
108 running ('x is the only current possibility). */
110 Lisp_Object Vwindow_system
;
112 /* Version number of X windows: 10, 11 or nil. */
113 Lisp_Object Vwindow_system_version
;
115 /* Vector of glyph definitions. Indexed by glyph number,
116 the contents are a string which is how to output the glyph.
118 If Vglyph_table is nil, a glyph is output by using its low 8 bits
119 as a character code. */
121 Lisp_Object Vglyph_table
;
123 /* Display table to use for vectors that don't specify their own. */
125 Lisp_Object Vstandard_display_table
;
127 /* Nonzero means reading single-character input with prompt
128 so put cursor on minibuffer after the prompt.
129 positive means at end of text in echo area;
130 negative means at beginning of line. */
131 int cursor_in_echo_area
;
133 Lisp_Object Qdisplay_table
;
135 /* The currently selected frame.
136 In a single-frame version, this variable always holds the address of
139 FRAME_PTR selected_frame
;
141 /* A frame which is not just a minibuffer, or 0 if there are no such
142 frames. This is usually the most recent such frame that was
143 selected. In a single-frame version, this variable always holds
144 the address of the_only_frame. */
145 FRAME_PTR last_nonminibuf_frame
;
147 /* In a single-frame version, the information that would otherwise
148 exist inside frame objects lives in the following structure instead.
150 NOTE: the_only_frame is not checked for garbage collection; don't
151 store collectible objects in any of its fields!
153 You're not/The only frame in town/... */
156 struct frame the_only_frame
;
159 /* This is a vector, made larger whenever it isn't large enough,
160 which is used inside `update_frame' to hold the old contents
161 of the FRAME_PHYS_LINES of the frame being updated. */
162 struct frame_glyphs
**ophys_lines
;
163 /* Length of vector currently allocated. */
164 int ophys_lines_length
;
166 FILE *termscript
; /* Stdio stream being used for copy of all output. */
168 struct cm Wcm
; /* Structure for info on cursor positioning */
170 extern short ospeed
; /* Output speed (from sg_ospeed) */
172 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
176 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
177 "Clear frame FRAME and output again what is supposed to appear on it.")
183 CHECK_LIVE_FRAME (frame
, 0);
186 /* set_terminal_modes (); */
188 clear_frame_records (f
);
191 windows_or_buffers_changed
++;
192 /* Mark all windows as INaccurate,
193 so that every window will have its redisplay done. */
194 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
203 XSETFRAME (frame
, f
);
204 Fredraw_frame (frame
);
209 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
210 /* Don't confuse make-docfile by having two doc strings for this function.
211 make-docfile does not pay attention to #if, for good reason! */
217 set_terminal_modes ();
221 clear_frame_records (0);
222 windows_or_buffers_changed
++;
223 /* Mark all windows as INaccurate,
224 so that every window will have its redisplay done. */
225 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
231 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
232 "Clear and redisplay all visible frames.")
235 Lisp_Object tail
, frame
;
237 FOR_EACH_FRAME (tail
, frame
)
238 if (FRAME_VISIBLE_P (XFRAME (frame
)))
239 Fredraw_frame (frame
);
244 /* This is used when frame_garbaged is set.
245 Redraw the individual frames marked as garbaged. */
248 redraw_garbaged_frames ()
250 Lisp_Object tail
, frame
;
252 FOR_EACH_FRAME (tail
, frame
)
253 if (FRAME_VISIBLE_P (XFRAME (frame
))
254 && FRAME_GARBAGED_P (XFRAME (frame
)))
255 Fredraw_frame (frame
);
259 static struct frame_glyphs
*
260 make_frame_glyphs (frame
, empty
)
261 register FRAME_PTR frame
;
265 register width
= FRAME_WIDTH (frame
);
266 register height
= FRAME_HEIGHT (frame
);
267 register struct frame_glyphs
*new
268 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
270 SET_GLYPHS_FRAME (new, frame
);
271 new->height
= height
;
273 new->used
= (int *) xmalloc (height
* sizeof (int));
274 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
275 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
276 new->highlight
= (char *) xmalloc (height
* sizeof (char));
277 new->enable
= (char *) xmalloc (height
* sizeof (char));
278 bzero (new->enable
, height
* sizeof (char));
279 new->bufp
= (int *) xmalloc (height
* sizeof (int));
281 #ifdef HAVE_WINDOW_SYSTEM
282 if (FRAME_WINDOW_P (frame
))
284 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
285 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
286 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
287 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
288 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
290 #endif /* HAVE_WINDOW_SYSTEM */
294 /* Make the buffer used by decode_mode_spec. This buffer is also
295 used as temporary storage when updating the frame. See scroll.c. */
296 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
297 unsigned int total_charstarts
= (width
+ 2) * sizeof (int);
299 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
300 bzero (new->total_contents
, total_glyphs
);
302 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
303 bzero (new->total_charstarts
, total_charstarts
);
307 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
309 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
310 bzero (new->total_contents
, total_glyphs
);
311 for (i
= 0; i
< height
; i
++)
312 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
314 if (!FRAME_TERMCAP_P (frame
))
316 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
318 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
319 bzero (new->total_charstarts
, total_charstarts
);
320 for (i
= 0; i
< height
; i
++)
321 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
325 /* Without a window system, we don't really need charstarts.
326 So use a small amount of space to make enough data structure
327 to prevent crashes in display_text_line. */
328 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
329 for (i
= 0; i
< height
; i
++)
330 new->charstarts
[i
] = new->total_charstarts
;
338 free_frame_glyphs (frame
, glyphs
)
340 struct frame_glyphs
*glyphs
;
342 if (glyphs
->total_contents
)
343 xfree (glyphs
->total_contents
);
344 if (glyphs
->total_charstarts
)
345 xfree (glyphs
->total_charstarts
);
347 xfree (glyphs
->used
);
348 xfree (glyphs
->glyphs
);
349 xfree (glyphs
->highlight
);
350 xfree (glyphs
->enable
);
351 xfree (glyphs
->bufp
);
352 if (glyphs
->charstarts
)
353 xfree (glyphs
->charstarts
);
355 #ifdef HAVE_WINDOW_SYSTEM
356 if (FRAME_WINDOW_P (frame
))
358 xfree (glyphs
->top_left_x
);
359 xfree (glyphs
->top_left_y
);
360 xfree (glyphs
->pix_width
);
361 xfree (glyphs
->pix_height
);
362 xfree (glyphs
->max_ascent
);
364 #endif /* HAVE_WINDOW_SYSTEM */
370 remake_frame_glyphs (frame
)
373 if (FRAME_CURRENT_GLYPHS (frame
))
374 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
375 if (FRAME_DESIRED_GLYPHS (frame
))
376 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
377 if (FRAME_TEMP_GLYPHS (frame
))
378 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
380 if (FRAME_MESSAGE_BUF (frame
))
382 /* Reallocate the frame's message buffer; remember that
383 echo_area_glyphs may be pointing here. */
384 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
386 FRAME_MESSAGE_BUF (frame
)
387 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
388 FRAME_WIDTH (frame
) + 1);
390 if (echo_area_glyphs
== old_message_buf
)
391 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
392 if (previous_echo_glyphs
== old_message_buf
)
393 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
396 FRAME_MESSAGE_BUF (frame
)
397 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
399 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
400 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
401 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
402 if (! FRAME_TERMCAP_P (frame
) || frame
== selected_frame
)
403 SET_FRAME_GARBAGED (frame
);
406 /* Return the hash code of contents of line VPOS in frame-matrix M. */
409 line_hash_code (m
, vpos
)
410 register struct frame_glyphs
*m
;
413 register GLYPH
*body
, *end
;
416 if (!m
->enable
[vpos
])
419 /* Give all highlighted lines the same hash code
420 so as to encourage scrolling to leave them in place. */
421 if (m
->highlight
[vpos
])
424 body
= m
->glyphs
[vpos
];
426 if (must_write_spaces
)
433 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
442 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
450 /* Return number of characters in line in M at vpos VPOS,
451 except don't count leading and trailing spaces
452 unless the terminal requires those to be explicitly output. */
455 line_draw_cost (m
, vpos
)
456 struct frame_glyphs
*m
;
459 register GLYPH
*beg
= m
->glyphs
[vpos
];
460 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
462 register int tlen
= GLYPH_TABLE_LENGTH
;
463 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
465 /* Ignore trailing and leading spaces if we can. */
466 if (!must_write_spaces
)
468 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
471 return (0); /* All blank line. */
473 while (*beg
== SPACEGLYPH
)
477 /* If we don't have a glyph-table, each glyph is one character,
478 so return the number of glyphs. */
482 /* Otherwise, scan the glyphs and accumulate their total size in I. */
484 while ((beg
<= end
) && *beg
)
486 register GLYPH g
= *beg
++;
488 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
491 i
+= GLYPH_LENGTH (tbase
, g
);
496 /* The functions on this page are the interface from xdisp.c to redisplay.
498 The only other interface into redisplay is through setting
499 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
500 and SET_FRAME_GARBAGED (frame). */
502 /* cancel_line eliminates any request to display a line at position `vpos' */
504 cancel_line (vpos
, frame
)
506 register FRAME_PTR frame
;
508 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
511 clear_frame_records (frame
)
512 register FRAME_PTR frame
;
514 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
517 /* Clear out all display lines for a coming redisplay. */
520 init_desired_glyphs (frame
)
521 register FRAME_PTR frame
;
523 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
525 int height
= FRAME_HEIGHT (frame
);
527 for (vpos
= 0; vpos
< height
; vpos
++)
528 desired_glyphs
->enable
[vpos
] = 0;
531 /* Prepare to display on line VPOS starting at HPOS within it. */
534 get_display_line (frame
, vpos
, hpos
)
535 register FRAME_PTR frame
;
539 register struct frame_glyphs
*glyphs
;
540 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
546 if (! desired_glyphs
->enable
[vpos
])
548 desired_glyphs
->used
[vpos
] = 0;
549 desired_glyphs
->highlight
[vpos
] = 0;
550 desired_glyphs
->enable
[vpos
] = 1;
553 if (hpos
> desired_glyphs
->used
[vpos
])
555 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
556 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
558 desired_glyphs
->used
[vpos
] = hpos
;
564 /* Like bcopy except never gets confused by overlap. */
567 safe_bcopy (from
, to
, size
)
571 if (size
<= 0 || from
== to
)
574 /* If the source and destination don't overlap, then bcopy can
575 handle it. If they do overlap, but the destination is lower in
576 memory than the source, we'll assume bcopy can handle that. */
577 if (to
< from
|| from
+ size
<= to
)
578 bcopy (from
, to
, size
);
580 /* Otherwise, we'll copy from the end. */
583 register char *endf
= from
+ size
;
584 register char *endt
= to
+ size
;
586 /* If TO - FROM is large, then we should break the copy into
587 nonoverlapping chunks of TO - FROM bytes each. However, if
588 TO - FROM is small, then the bcopy function call overhead
589 makes this not worth it. The crossover point could be about
590 anywhere. Since I don't think the obvious copy loop is too
591 bad, I'm trying to err in its favor. */
596 while (endf
!= from
);
608 bcopy (endf
, endt
, to
- from
);
611 /* If SIZE wasn't a multiple of TO - FROM, there will be a
612 little left over. The amount left over is
613 (endt + (to - from)) - to, which is endt - from. */
614 bcopy (from
, to
, endt
- from
);
619 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
620 DISTANCE may be negative. */
623 rotate_vector (vector
, size
, distance
)
628 char *temp
= (char *) alloca (size
);
633 bcopy (vector
, temp
+ distance
, size
- distance
);
634 bcopy (vector
+ size
- distance
, temp
, distance
);
635 bcopy (temp
, vector
, size
);
638 /* Scroll lines from vpos FROM up to but not including vpos END
639 down by AMOUNT lines (AMOUNT may be negative).
640 Returns nonzero if done, zero if terminal cannot scroll them. */
643 scroll_frame_lines (frame
, from
, end
, amount
, newpos
)
644 register FRAME_PTR frame
;
645 int from
, end
, amount
, newpos
;
648 register struct frame_glyphs
*current_frame
649 = FRAME_CURRENT_GLYPHS (frame
);
651 int width
= FRAME_WIDTH (frame
);
653 if (!line_ins_del_ok
)
661 update_begin (frame
);
662 set_terminal_window (end
+ amount
);
663 if (!scroll_region_ok
)
664 ins_del_lines (end
, -amount
);
665 ins_del_lines (from
, amount
);
666 set_terminal_window (0);
668 rotate_vector (current_frame
->glyphs
+ from
,
669 sizeof (GLYPH
*) * (end
+ amount
- from
),
670 amount
* sizeof (GLYPH
*));
672 rotate_vector (current_frame
->charstarts
+ from
,
673 sizeof (int *) * (end
+ amount
- from
),
674 amount
* sizeof (int *));
676 safe_bcopy (current_frame
->used
+ from
,
677 current_frame
->used
+ from
+ amount
,
678 (end
- from
) * sizeof current_frame
->used
[0]);
680 safe_bcopy (current_frame
->highlight
+ from
,
681 current_frame
->highlight
+ from
+ amount
,
682 (end
- from
) * sizeof current_frame
->highlight
[0]);
684 safe_bcopy (current_frame
->enable
+ from
,
685 current_frame
->enable
+ from
+ amount
,
686 (end
- from
) * sizeof current_frame
->enable
[0]);
688 /* Adjust the lines by an amount
689 that puts the first of them at NEWPOS. */
690 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
692 /* Offset each char position in the charstarts lines we moved
694 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
696 int *line
= current_frame
->charstarts
[i
];
698 for (col
= 0; col
< width
; col
++)
700 line
[col
] += pos_adjust
;
702 for (i
= from
; i
< from
+ amount
; i
++)
704 int *line
= current_frame
->charstarts
[i
];
707 for (col
= 0; col
< width
; col
++)
711 /* Mark the lines made empty by scrolling as enabled, empty and
713 bzero (current_frame
->used
+ from
,
714 amount
* sizeof current_frame
->used
[0]);
715 bzero (current_frame
->highlight
+ from
,
716 amount
* sizeof current_frame
->highlight
[0]);
717 for (i
= from
; i
< from
+ amount
; i
++)
719 current_frame
->glyphs
[i
][0] = '\0';
720 current_frame
->charstarts
[i
][0] = -1;
721 current_frame
->enable
[i
] = 1;
724 safe_bcopy (current_frame
->bufp
+ from
,
725 current_frame
->bufp
+ from
+ amount
,
726 (end
- from
) * sizeof current_frame
->bufp
[0]);
728 #ifdef HAVE_WINDOW_SYSTEM
729 if (FRAME_WINDOW_P (frame
))
731 safe_bcopy (current_frame
->top_left_x
+ from
,
732 current_frame
->top_left_x
+ from
+ amount
,
733 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
735 safe_bcopy (current_frame
->top_left_y
+ from
,
736 current_frame
->top_left_y
+ from
+ amount
,
737 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
739 safe_bcopy (current_frame
->pix_width
+ from
,
740 current_frame
->pix_width
+ from
+ amount
,
741 (end
- from
) * sizeof current_frame
->pix_width
[0]);
743 safe_bcopy (current_frame
->pix_height
+ from
,
744 current_frame
->pix_height
+ from
+ amount
,
745 (end
- from
) * sizeof current_frame
->pix_height
[0]);
747 safe_bcopy (current_frame
->max_ascent
+ from
,
748 current_frame
->max_ascent
+ from
+ amount
,
749 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
751 #endif /* HAVE_WINDOW_SYSTEM */
757 update_begin (frame
);
758 set_terminal_window (end
);
759 ins_del_lines (from
+ amount
, amount
);
760 if (!scroll_region_ok
)
761 ins_del_lines (end
+ amount
, -amount
);
762 set_terminal_window (0);
764 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
765 sizeof (GLYPH
*) * (end
- from
- amount
),
766 amount
* sizeof (GLYPH
*));
768 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
769 sizeof (int *) * (end
- from
- amount
),
770 amount
* sizeof (int *));
772 safe_bcopy (current_frame
->used
+ from
,
773 current_frame
->used
+ from
+ amount
,
774 (end
- from
) * sizeof current_frame
->used
[0]);
776 safe_bcopy (current_frame
->highlight
+ from
,
777 current_frame
->highlight
+ from
+ amount
,
778 (end
- from
) * sizeof current_frame
->highlight
[0]);
780 safe_bcopy (current_frame
->enable
+ from
,
781 current_frame
->enable
+ from
+ amount
,
782 (end
- from
) * sizeof current_frame
->enable
[0]);
784 /* Adjust the lines by an amount
785 that puts the first of them at NEWPOS. */
786 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
788 /* Offset each char position in the charstarts lines we moved
790 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
792 int *line
= current_frame
->charstarts
[i
];
794 for (col
= 0; col
< width
; col
++)
796 line
[col
] += pos_adjust
;
798 for (i
= end
+ amount
; i
< end
; i
++)
800 int *line
= current_frame
->charstarts
[i
];
803 for (col
= 0; col
< width
; col
++)
807 /* Mark the lines made empty by scrolling as enabled, empty and
809 bzero (current_frame
->used
+ end
+ amount
,
810 - amount
* sizeof current_frame
->used
[0]);
811 bzero (current_frame
->highlight
+ end
+ amount
,
812 - amount
* sizeof current_frame
->highlight
[0]);
813 for (i
= end
+ amount
; i
< end
; i
++)
815 current_frame
->glyphs
[i
][0] = '\0';
816 current_frame
->charstarts
[i
][0] = 0;
817 current_frame
->enable
[i
] = 1;
820 safe_bcopy (current_frame
->bufp
+ from
,
821 current_frame
->bufp
+ from
+ amount
,
822 (end
- from
) * sizeof current_frame
->bufp
[0]);
824 #ifdef HAVE_WINDOW_SYSTEM
825 if (FRAME_WINDOW_P (frame
))
827 safe_bcopy (current_frame
->top_left_x
+ from
,
828 current_frame
->top_left_x
+ from
+ amount
,
829 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
831 safe_bcopy (current_frame
->top_left_y
+ from
,
832 current_frame
->top_left_y
+ from
+ amount
,
833 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
835 safe_bcopy (current_frame
->pix_width
+ from
,
836 current_frame
->pix_width
+ from
+ amount
,
837 (end
- from
) * sizeof current_frame
->pix_width
[0]);
839 safe_bcopy (current_frame
->pix_height
+ from
,
840 current_frame
->pix_height
+ from
+ amount
,
841 (end
- from
) * sizeof current_frame
->pix_height
[0]);
843 safe_bcopy (current_frame
->max_ascent
+ from
,
844 current_frame
->max_ascent
+ from
+ amount
,
845 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
847 #endif /* HAVE_WINDOW_SYSTEM */
854 /* After updating a window W that isn't the full frame wide,
855 copy all the columns that W does not occupy
856 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
857 so that update_frame will not change those columns. */
859 preserve_other_columns (w
)
863 register struct frame_glyphs
*current_frame
, *desired_frame
;
864 register FRAME_PTR frame
= XFRAME (w
->frame
);
865 int start
= XFASTINT (w
->left
);
866 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
867 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
869 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
870 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
872 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
874 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
880 bcopy (current_frame
->glyphs
[vpos
],
881 desired_frame
->glyphs
[vpos
],
882 start
* sizeof (current_frame
->glyphs
[vpos
][0]));
883 bcopy (current_frame
->charstarts
[vpos
],
884 desired_frame
->charstarts
[vpos
],
885 start
* sizeof (current_frame
->charstarts
[vpos
][0]));
886 len
= min (start
, current_frame
->used
[vpos
]);
887 if (desired_frame
->used
[vpos
] < len
)
888 desired_frame
->used
[vpos
] = len
;
890 if (current_frame
->used
[vpos
] > end
891 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
893 while (desired_frame
->used
[vpos
] < end
)
895 int used
= desired_frame
->used
[vpos
]++;
896 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
897 desired_frame
->glyphs
[vpos
][used
] = 0;
899 bcopy (current_frame
->glyphs
[vpos
] + end
,
900 desired_frame
->glyphs
[vpos
] + end
,
901 ((current_frame
->used
[vpos
] - end
)
902 * sizeof (current_frame
->glyphs
[vpos
][0])));
903 bcopy (current_frame
->charstarts
[vpos
] + end
,
904 desired_frame
->charstarts
[vpos
] + end
,
905 ((current_frame
->used
[vpos
] - end
)
906 * sizeof (current_frame
->charstarts
[vpos
][0])));
907 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
915 /* If window w does not need to be updated and isn't the full frame wide,
916 copy all the columns that w does occupy
917 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
918 so that update_frame will not change those columns.
920 Have not been able to figure out how to use this correctly. */
922 preserve_my_columns (w
)
925 register int vpos
, fin
;
926 register struct frame_glyphs
*l1
, *l2
;
927 register FRAME_PTR frame
= XFRAME (w
->frame
);
928 int start
= XFASTINT (w
->left
);
929 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
930 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
932 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
934 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
935 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
937 if (l2
->length
> start
&& l1
->length
< l2
->length
)
940 if (fin
> end
) fin
= end
;
941 while (l1
->length
< start
)
942 l1
->body
[l1
->length
++] = ' ';
943 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
952 /* Adjust by ADJUST the charstart values in window W
953 after vpos VPOS, which counts relative to the frame
954 (not relative to W itself). */
957 adjust_window_charstarts (w
, vpos
, adjust
)
962 int left
= XFASTINT (w
->left
);
963 int top
= XFASTINT (w
->top
);
964 int right
= left
+ window_internal_width (w
);
965 int bottom
= top
+ window_internal_height (w
);
968 for (i
= vpos
+ 1; i
< bottom
; i
++)
971 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
973 for (j
= left
; j
< right
; j
++)
974 if (charstart
[j
] > 0)
975 charstart
[j
] += adjust
;
979 /* Check the charstarts values in the area of window W
980 for internal consistency. We cannot check that they are "right";
981 we can only look for something nonsensical. */
983 verify_charstarts (w
)
986 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
988 int top
= XFASTINT (w
->top
);
989 int bottom
= top
+ window_internal_height (w
);
990 int left
= XFASTINT (w
->left
);
991 int right
= left
+ window_internal_width (w
);
993 int truncate
= (XINT (w
->hscroll
)
994 || (truncate_partial_width_windows
995 && (XFASTINT (w
->width
) < FRAME_WIDTH (f
)))
996 || !NILP (XBUFFER (w
->buffer
)->truncate_lines
));
998 for (i
= top
; i
< bottom
; i
++)
1002 int *charstart
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[i
];
1008 /* If we are truncating lines, allow a jump
1009 in charstarts from one line to the next. */
1010 if (charstart
[left
] < next_line
)
1015 if (charstart
[left
] != next_line
)
1020 for (j
= left
; j
< right
; j
++)
1021 if (charstart
[j
] > 0)
1022 last
= charstart
[j
];
1023 /* Record where the next line should start. */
1025 if (BUF_ZV (XBUFFER (w
->buffer
)) != last
)
1027 /* If there's a newline between the two lines, count that. */
1028 int endchar
= *BUF_CHAR_ADDRESS (XBUFFER (w
->buffer
), last
);
1029 if (endchar
== '\n')
1035 /* On discovering that the redisplay for a window was no good,
1036 cancel the columns of that window, so that when the window is
1037 displayed over again get_display_line will not complain. */
1039 cancel_my_columns (w
)
1043 register struct frame_glyphs
*desired_glyphs
1044 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
1045 register int start
= XFASTINT (w
->left
);
1046 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
1048 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
1049 if (desired_glyphs
->enable
[vpos
]
1050 && desired_glyphs
->used
[vpos
] >= start
)
1051 desired_glyphs
->used
[vpos
] = start
;
1054 /* These functions try to perform directly and immediately on the frame
1055 the necessary output for one change in the buffer.
1056 They may return 0 meaning nothing was done if anything is difficult,
1057 or 1 meaning the output was performed properly.
1058 They assume that the frame was up to date before the buffer
1059 change being displayed. They make various other assumptions too;
1060 see command_loop_1 where these are called. */
1063 direct_output_for_insert (g
)
1066 register FRAME_PTR frame
= selected_frame
;
1067 register struct frame_glyphs
*current_frame
1068 = FRAME_CURRENT_GLYPHS (frame
);
1070 #ifndef COMPILER_REGISTER_BUG
1072 #endif /* COMPILER_REGISTER_BUG */
1073 struct window
*w
= XWINDOW (selected_window
);
1074 #ifndef COMPILER_REGISTER_BUG
1076 #endif /* COMPILER_REGISTER_BUG */
1077 int hpos
= FRAME_CURSOR_X (frame
);
1078 #ifndef COMPILER_REGISTER_BUG
1080 #endif /* COMPILER_REGISTER_BUG */
1081 int vpos
= FRAME_CURSOR_Y (frame
);
1083 /* Give up if about to continue line. */
1084 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
1086 /* Avoid losing if cursor is in invisible text off left margin */
1087 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
1089 /* Give up if cursor outside window (in minibuf, probably) */
1090 || cursor_in_echo_area
1091 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
1092 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
1094 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
1095 || !display_completed
1097 /* Give up if buffer appears in two places. */
1098 || buffer_shared
> 1
1100 #ifdef USE_TEXT_PROPERTIES
1101 /* Intervals have already been adjusted, point is after the
1102 character that was just inserted. */
1103 /* Give up if character is invisible. */
1104 /* Give up if character has a face property.
1105 At the moment we only lose at end of line or end of buffer
1106 and only with faces that have some background */
1107 /* Instead of wasting time, give up if character has any text properties */
1108 || ! NILP (Ftext_properties_at (make_number (point
- 1), Qnil
))
1111 /* Give up if w is minibuffer and a message is being displayed there */
1112 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1120 if (FRAME_WINDOW_P (frame
))
1121 face
= compute_char_face (frame
, w
, point
- 1, -1, -1, &dummy
, point
, 0);
1123 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1124 current_frame
->charstarts
[vpos
][hpos
] = point
- 1;
1125 /* Record the entry for after the newly inserted character. */
1126 current_frame
->charstarts
[vpos
][hpos
+ 1] = point
;
1127 adjust_window_charstarts (w
, vpos
, 1);
1129 unchanged_modified
= MODIFF
;
1130 beg_unchanged
= GPT
- BEG
;
1131 XSETFASTINT (w
->last_point
, point
);
1132 XSETFASTINT (w
->last_point_x
, hpos
);
1133 XSETFASTINT (w
->last_modified
, MODIFF
);
1135 reassert_line_highlight (0, vpos
);
1136 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
1138 ++FRAME_CURSOR_X (frame
);
1139 if (hpos
== current_frame
->used
[vpos
])
1141 current_frame
->used
[vpos
] = hpos
+ 1;
1142 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
1149 direct_output_forward_char (n
)
1152 register FRAME_PTR frame
= selected_frame
;
1153 register struct window
*w
= XWINDOW (selected_window
);
1154 Lisp_Object position
;
1155 int hpos
= FRAME_CURSOR_X (frame
);
1157 /* Give up if in truncated text at end of line. */
1158 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1)
1161 /* Avoid losing if cursor is in invisible text off left margin
1162 or about to go off either side of window. */
1163 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
1164 && (XINT (w
->hscroll
) || n
< 0))
1166 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
1167 || cursor_in_echo_area
)
1170 /* Can't use direct output if highlighting a region. */
1171 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1174 /* Can't use direct output at an overlay boundary; it might have
1175 before-string or after-string properties. */
1176 if (overlay_touches_p (PT
) || overlay_touches_p (PT
- n
))
1179 #ifdef USE_TEXT_PROPERTIES
1180 /* Don't use direct output next to an invisible character
1181 since we might need to do something special. */
1183 XSETFASTINT (position
, point
);
1184 if (XFASTINT (position
) < ZV
1185 && ! NILP (Fget_char_property (position
,
1190 XSETFASTINT (position
, point
- 1);
1191 if (XFASTINT (position
) >= BEGV
1192 && ! NILP (Fget_char_property (position
,
1198 FRAME_CURSOR_X (frame
) += n
;
1199 XSETFASTINT (w
->last_point_x
, FRAME_CURSOR_X (frame
));
1200 XSETFASTINT (w
->last_point
, point
);
1201 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1207 static void update_line ();
1209 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1210 Value is nonzero if redisplay stopped due to pending input.
1211 FORCE nonzero means do not stop for pending input. */
1214 update_frame (f
, force
, inhibit_hairy_id
)
1217 int inhibit_hairy_id
;
1219 register struct frame_glyphs
*current_frame
;
1220 register struct frame_glyphs
*desired_frame
= 0;
1223 int preempt_count
= baud_rate
/ 2400 + 1;
1224 extern input_pending
;
1225 #ifdef HAVE_WINDOW_SYSTEM
1226 register int downto
, leftmost
;
1229 if (baud_rate
!= FRAME_COST_BAUD_RATE (f
))
1230 calculate_costs (f
);
1232 if (preempt_count
<= 0)
1235 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1237 detect_input_pending ();
1238 if (input_pending
&& !force
)
1246 if (!line_ins_del_ok
)
1247 inhibit_hairy_id
= 1;
1249 /* These are separate to avoid a possible bug in the AIX C compiler. */
1250 current_frame
= FRAME_CURRENT_GLYPHS (f
);
1251 desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1253 /* See if any of the desired lines are enabled; don't compute for
1254 i/d line if just want cursor motion. */
1255 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1256 if (desired_frame
->enable
[i
])
1259 /* Try doing i/d line, if not yet inhibited. */
1260 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1261 force
|= scrolling (f
);
1263 /* Update the individual lines as needed. Do bottom line first. */
1265 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1266 update_line (f
, FRAME_HEIGHT (f
) - 1);
1268 #ifdef HAVE_WINDOW_SYSTEM
1269 if (FRAME_WINDOW_P (f
))
1271 leftmost
= downto
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1272 if (desired_frame
->enable
[0])
1274 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1275 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1276 = PIXEL_HEIGHT (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
)
1277 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1278 current_frame
->top_left_x
[0] = leftmost
;
1279 current_frame
->top_left_y
[0] = downto
;
1282 #endif /* HAVE_WINDOW_SYSTEM */
1284 /* Now update the rest of the lines. */
1285 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1287 if (desired_frame
->enable
[i
])
1289 if (FRAME_TERMCAP_P (f
))
1291 /* Flush out every so many lines.
1292 Also flush out if likely to have more than 1k buffered
1293 otherwise. I'm told that some telnet connections get
1294 really screwed by more than 1k output at once. */
1295 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1297 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1300 if (preempt_count
== 1)
1302 #ifdef EMACS_OUTQSIZE
1303 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1304 /* Probably not a tty. Ignore the error and reset
1305 * the outq count. */
1306 outq
= PENDING_OUTPUT_COUNT (stdout
);
1309 if (baud_rate
<= outq
&& baud_rate
> 0)
1310 sleep (outq
/ baud_rate
);
1313 if ((i
- 1) % preempt_count
== 0)
1314 detect_input_pending ();
1318 #ifdef HAVE_WINDOW_SYSTEM
1319 if (FRAME_WINDOW_P (f
))
1321 current_frame
->top_left_y
[i
] = downto
;
1322 current_frame
->top_left_x
[i
] = leftmost
;
1324 #endif /* HAVE_WINDOW_SYSTEM */
1327 #ifdef HAVE_WINDOW_SYSTEM
1328 if (FRAME_WINDOW_P (f
))
1329 downto
+= current_frame
->pix_height
[i
];
1330 #endif /* HAVE_WINDOW_SYSTEM */
1332 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1334 /* Now just clean up termcap drivers and set cursor, etc. */
1337 if ((cursor_in_echo_area
1338 /* If we are showing a message instead of the minibuffer,
1339 show the cursor for the message instead of for the
1340 (now hidden) minibuffer contents. */
1341 || (EQ (minibuf_window
, selected_window
)
1342 && EQ (minibuf_window
, echo_area_window
)
1343 && echo_area_glyphs
!= 0))
1344 /* These cases apply only to the frame that contains
1345 the active minibuffer window. */
1346 && FRAME_HAS_MINIBUF_P (f
)
1347 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
1349 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1352 if (cursor_in_echo_area
< 0)
1359 /* If the minibuffer is several lines high, find the last
1360 line that has any text on it. */
1361 row
= FRAME_HEIGHT (f
);
1365 if (current_frame
->enable
[row
])
1366 col
= current_frame
->used
[row
];
1370 while (row
> top
&& col
== 0);
1372 if (col
>= FRAME_WIDTH (f
))
1375 if (row
< FRAME_HEIGHT (f
) - 1)
1380 cursor_to (row
, col
);
1383 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1384 FRAME_WIDTH (f
) - 1), 0));
1390 fflush (termscript
);
1393 /* Here if output is preempted because input is detected. */
1396 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1397 display_completed
= !pause
;
1399 bzero (FRAME_DESIRED_GLYPHS (f
)->enable
, FRAME_HEIGHT (f
));
1403 /* Called when about to quit, to check for doing so
1404 at an improper time. */
1410 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1412 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1414 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1419 /* Decide what insert/delete line to do, and do it */
1421 extern void scrolling_1 ();
1426 int unchanged_at_top
, unchanged_at_bottom
;
1429 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1430 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1431 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1432 int *old_draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1434 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1435 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1436 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1438 /* Compute hash codes of all the lines.
1439 Also calculate number of changed lines,
1440 number of unchanged lines at the beginning,
1441 and number of unchanged lines at the end. */
1444 unchanged_at_top
= 0;
1445 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1446 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1448 /* Give up on this scrolling if some old lines are not enabled. */
1449 if (!current_frame
->enable
[i
])
1451 old_hash
[i
] = line_hash_code (current_frame
, i
);
1452 if (! desired_frame
->enable
[i
])
1453 new_hash
[i
] = old_hash
[i
];
1455 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1457 if (old_hash
[i
] != new_hash
[i
])
1460 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1462 else if (i
== unchanged_at_top
)
1464 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1465 old_draw_cost
[i
] = line_draw_cost (current_frame
, i
);
1468 /* If changed lines are few, don't allow preemption, don't scroll. */
1469 if (!scroll_region_ok
&& changed_lines
< baud_rate
/ 2400
1470 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1473 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1474 - unchanged_at_bottom
);
1476 if (scroll_region_ok
)
1477 free_at_end_vpos
-= unchanged_at_bottom
;
1478 else if (memory_below_frame
)
1479 free_at_end_vpos
= -1;
1481 /* If large window, fast terminal and few lines in common between
1482 current frame and desired frame, don't bother with i/d calc. */
1483 if (!scroll_region_ok
&& window_size
>= 18 && baud_rate
> 2400
1485 10 * scrolling_max_lines_saved (unchanged_at_top
,
1486 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1487 old_hash
, new_hash
, draw_cost
)))
1490 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1491 draw_cost
+ unchanged_at_top
- 1,
1492 old_draw_cost
+ unchanged_at_top
- 1,
1493 old_hash
+ unchanged_at_top
- 1,
1494 new_hash
+ unchanged_at_top
- 1,
1495 free_at_end_vpos
- unchanged_at_top
);
1500 /* Return the offset in its buffer of the character at location col, line
1501 in the given window. */
1503 buffer_posn_from_coords (window
, col
, line
)
1504 struct window
*window
;
1507 int hscroll
= XINT (window
->hscroll
);
1508 int window_left
= XFASTINT (window
->left
);
1510 /* The actual width of the window is window->width less one for the
1511 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1513 int window_width
= window_internal_width (window
) - 1;
1515 int startp
= marker_position (window
->start
);
1517 /* Since compute_motion will only operate on the current buffer,
1518 we need to save the old one and restore it when we're done. */
1519 struct buffer
*old_current_buffer
= current_buffer
;
1520 struct position
*posn
;
1522 current_buffer
= XBUFFER (window
->buffer
);
1524 /* We can't get a correct result in this case,
1525 but at least prevent compute_motion from crashing. */
1529 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1530 (window->frame))->bufp to avoid scanning from the very top of
1531 the window, but it isn't maintained correctly, and I'm not even
1532 sure I will keep it. */
1533 posn
= compute_motion (startp
, 0,
1534 ((window
== XWINDOW (minibuf_window
) && startp
== BEG
1535 ? minibuf_prompt_width
: 0)
1536 + (hscroll
? 1 - hscroll
: 0)),
1539 window_width
, hscroll
, 0, window
);
1541 current_buffer
= old_current_buffer
;
1543 /* compute_motion considers frame points past the end of a line
1544 to be *after* the newline, i.e. at the start of the next line.
1545 This is reasonable, but not really what we want. So if the
1546 result is on a line below LINE, back it up one character. */
1547 if (posn
->vpos
> line
)
1548 return posn
->bufpos
- 1;
1550 return posn
->bufpos
;
1557 register GLYPH
*p
= r
;
1558 while (*p
++ == SPACEGLYPH
);
1563 count_match (str1
, str2
)
1566 register GLYPH
*p1
= str1
;
1567 register GLYPH
*p2
= str2
;
1568 while (*p1
++ == *p2
++);
1569 return p1
- str1
- 1;
1572 /* Char insertion/deletion cost vector, from term.c */
1573 extern int *char_ins_del_vector
;
1575 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1578 update_line (frame
, vpos
)
1579 register FRAME_PTR frame
;
1582 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1585 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1587 register struct frame_glyphs
*current_frame
1588 = FRAME_CURRENT_GLYPHS (frame
);
1589 register struct frame_glyphs
*desired_frame
1590 = FRAME_DESIRED_GLYPHS (frame
);
1592 if (desired_frame
->highlight
[vpos
]
1593 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1595 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1596 (current_frame
->enable
[vpos
] ?
1597 current_frame
->used
[vpos
] : 0));
1598 current_frame
->enable
[vpos
] = 0;
1601 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1603 if (! current_frame
->enable
[vpos
])
1609 obody
= current_frame
->glyphs
[vpos
];
1610 olen
= current_frame
->used
[vpos
];
1611 if (! current_frame
->highlight
[vpos
])
1613 if (!must_write_spaces
)
1614 while (olen
> 0 && obody
[olen
- 1] == SPACEGLYPH
)
1619 /* For an inverse-video line, remember we gave it
1620 spaces all the way to the frame edge
1621 so that the reverse video extends all the way across. */
1623 while (olen
< FRAME_WIDTH (frame
) - 1)
1624 obody
[olen
++] = SPACEGLYPH
;
1628 /* One way or another, this will enable the line being updated. */
1629 current_frame
->enable
[vpos
] = 1;
1630 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1631 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1632 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1634 #ifdef HAVE_WINDOW_SYSTEM
1635 if (FRAME_WINDOW_P (frame
))
1637 current_frame
->pix_width
[vpos
]
1638 = current_frame
->used
[vpos
]
1639 * FONT_WIDTH (FRAME_FONT (frame
));
1640 current_frame
->pix_height
[vpos
]
1641 = FRAME_LINE_HEIGHT (frame
);
1643 #endif /* HAVE_WINDOW_SYSTEM */
1645 if (!desired_frame
->enable
[vpos
])
1651 nbody
= desired_frame
->glyphs
[vpos
];
1652 nlen
= desired_frame
->used
[vpos
];
1654 /* Pretend trailing spaces are not there at all,
1655 unless for one reason or another we must write all spaces. */
1656 if (! desired_frame
->highlight
[vpos
])
1658 if (!must_write_spaces
)
1659 /* We know that the previous character byte contains 0. */
1660 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1665 /* For an inverse-video line, give it extra trailing spaces
1666 all the way to the frame edge
1667 so that the reverse video extends all the way across. */
1669 while (nlen
< FRAME_WIDTH (frame
) - 1)
1670 nbody
[nlen
++] = SPACEGLYPH
;
1673 /* If there's no i/d char, quickly do the best we can without it. */
1674 if (!char_ins_del_ok
)
1679 if (FRAME_X_P (frame
))
1681 /* Under X, erase everything we are going to rewrite,
1682 and rewrite everything from the first char that's changed.
1683 This is part of supporting fonts like Courier
1684 whose chars can overlap outside the char width. */
1685 for (i
= 0; i
< nlen
; i
++)
1686 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1689 cursor_to (vpos
, i
);
1691 clear_end_of_line (olen
);
1692 write_glyphs (nbody
+ i
, nlen
- i
);
1697 for (i
= 0; i
< nlen
; i
++)
1699 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1701 cursor_to (vpos
, i
);
1702 for (j
= 1; (i
+ j
< nlen
&&
1703 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1706 /* Output this run of non-matching chars. */
1707 write_glyphs (nbody
+ i
, j
);
1710 /* Now find the next non-match. */
1714 /* Clear the rest of the line, or the non-clear part of it. */
1717 cursor_to (vpos
, nlen
);
1718 clear_end_of_line (olen
);
1721 /* Exchange contents between current_frame and new_frame. */
1722 temp
= desired_frame
->glyphs
[vpos
];
1723 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1724 current_frame
->glyphs
[vpos
] = temp
;
1726 /* Exchange charstarts between current_frame and new_frame. */
1727 temp1
= desired_frame
->charstarts
[vpos
];
1728 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1729 current_frame
->charstarts
[vpos
] = temp1
;
1736 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1737 ? 0 : count_blanks (nbody
);
1740 cursor_to (vpos
, nsp
);
1741 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1744 /* Exchange contents between current_frame and new_frame. */
1745 temp
= desired_frame
->glyphs
[vpos
];
1746 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1747 current_frame
->glyphs
[vpos
] = temp
;
1749 /* Exchange charstarts between current_frame and new_frame. */
1750 temp1
= desired_frame
->charstarts
[vpos
];
1751 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1752 current_frame
->charstarts
[vpos
] = temp1
;
1761 /* Compute number of leading blanks in old and new contents. */
1762 osp
= count_blanks (obody
);
1763 if (!desired_frame
->highlight
[vpos
])
1764 nsp
= count_blanks (nbody
);
1768 /* Compute number of matching chars starting with first nonblank. */
1769 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1771 /* Spaces in new match implicit space past the end of old. */
1772 /* A bug causing this to be a no-op was fixed in 18.29. */
1773 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1776 while (np1
[begmatch
] == SPACEGLYPH
)
1780 /* Avoid doing insert/delete char
1781 just cause number of leading spaces differs
1782 when the following text does not match. */
1783 if (begmatch
== 0 && osp
!= nsp
)
1784 osp
= nsp
= min (osp
, nsp
);
1786 /* Find matching characters at end of line */
1789 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1790 while (op1
> op2
&& op1
[-1] == np1
[-1])
1795 endmatch
= obody
+ olen
- op1
;
1797 /* Put correct value back in nbody[nlen].
1798 This is important because direct_output_for_insert
1799 can write into the line at a later point.
1800 If this screws up the zero at the end of the line, re-establish it. */
1804 /* tem gets the distance to insert or delete.
1805 endmatch is how many characters we save by doing so.
1808 tem
= (nlen
- nsp
) - (olen
- osp
);
1810 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1813 /* nsp - osp is the distance to insert or delete.
1814 If that is nonzero, begmatch is known to be nonzero also.
1815 begmatch + endmatch is how much we save by doing the ins/del.
1819 && (!char_ins_del_ok
1820 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1824 osp
= nsp
= min (osp
, nsp
);
1827 /* Now go through the line, inserting, writing and
1828 deleting as appropriate. */
1832 cursor_to (vpos
, nsp
);
1833 delete_glyphs (osp
- nsp
);
1837 /* If going to delete chars later in line
1838 and insert earlier in the line,
1839 must delete first to avoid losing data in the insert */
1840 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1842 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1843 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1844 olen
= nlen
- (nsp
- osp
);
1846 cursor_to (vpos
, osp
);
1847 insert_glyphs ((char *)0, nsp
- osp
);
1851 tem
= nsp
+ begmatch
+ endmatch
;
1852 if (nlen
!= tem
|| olen
!= tem
)
1854 cursor_to (vpos
, nsp
+ begmatch
);
1855 if (!endmatch
|| nlen
== olen
)
1857 /* If new text being written reaches right margin,
1858 there is no need to do clear-to-eol at the end.
1859 (and it would not be safe, since cursor is not
1860 going to be "at the margin" after the text is done) */
1861 if (nlen
== FRAME_WIDTH (frame
))
1863 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1867 /* the following code loses disastrously if tem == nlen.
1868 Rather than trying to fix that case, I am trying the simpler
1869 solution found above. */
1871 /* If the text reaches to the right margin,
1872 it will lose one way or another (depending on AutoWrap)
1873 to clear to end of line after outputting all the text.
1874 So pause with one character to go and clear the line then. */
1875 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1877 /* endmatch must be zero, and tem must equal nsp + begmatch */
1878 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1879 clear_end_of_line (olen
);
1880 olen
= 0; /* Don't let it be cleared again later */
1881 write_glyphs (nbody
+ nlen
- 1, 1);
1884 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1885 #endif /* OBSOLETE */
1888 else if (nlen
> olen
)
1890 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1891 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1894 else if (olen
> nlen
)
1896 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1897 delete_glyphs (olen
- nlen
);
1903 /* If any unerased characters remain after the new line, erase them. */
1906 cursor_to (vpos
, nlen
);
1907 clear_end_of_line (olen
);
1910 /* Exchange contents between current_frame and new_frame. */
1911 temp
= desired_frame
->glyphs
[vpos
];
1912 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1913 current_frame
->glyphs
[vpos
] = temp
;
1915 /* Exchange charstarts between current_frame and new_frame. */
1916 temp1
= desired_frame
->charstarts
[vpos
];
1917 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1918 current_frame
->charstarts
[vpos
] = temp1
;
1921 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
1922 session's frames, frame names, buffers, buffer-read-only flags, and
1923 buffer-modified-flags, and a trailing sentinel (so we don't need to
1924 add length checks). */
1925 static Lisp_Object frame_and_buffer_state
;
1927 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p
,
1928 Sframe_or_buffer_changed_p
, 0, 0, 0,
1929 "Return non-nil if the frame and buffer state appears to have changed.\n\
1930 The state variable is an internal vector containing all frames and buffers,\n\
1931 aside from buffers whose names start with space,\n\
1932 along with the buffers' read-only and modified flags, which allows a fast\n\
1933 check to see whether the menu bars might need to be recomputed.\n\
1934 If this function returns non-nil, it updates the internal vector to reflect\n\
1935 the current state.\n")
1938 Lisp_Object tail
, frame
, buf
;
1942 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1943 FOR_EACH_FRAME (tail
, frame
)
1945 if (!EQ (*vecp
++, frame
))
1947 if (!EQ (*vecp
++, XFRAME (frame
)->name
))
1950 /* Check that the buffer info matches.
1951 No need to test for the end of the vector
1952 because the last element of the vector is lambda
1953 and that will always cause a mismatch. */
1954 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1956 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1957 /* Ignore buffers that aren't included in buffer lists. */
1958 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1960 if (!EQ (*vecp
++, buf
))
1962 if (!EQ (*vecp
++, XBUFFER (buf
)->read_only
))
1964 if (!EQ (*vecp
++, Fbuffer_modified_p (buf
)))
1967 /* Detect deletion of a buffer at the end of the list. */
1968 if (*vecp
== Qlambda
)
1971 /* Start with 1 so there is room for at least one lambda at the end. */
1973 FOR_EACH_FRAME (tail
, frame
)
1975 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1977 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
1978 if (n
> XVECTOR (frame_and_buffer_state
)->size
1979 || n
+ 20 < XVECTOR (frame_and_buffer_state
)->size
/ 2)
1980 /* Add 20 extra so we grow it less often. */
1981 frame_and_buffer_state
= Fmake_vector (make_number (n
+ 20), Qlambda
);
1982 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1983 FOR_EACH_FRAME (tail
, frame
)
1986 *vecp
++ = XFRAME (frame
)->name
;
1988 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1990 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1991 /* Ignore buffers that aren't included in buffer lists. */
1992 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1995 *vecp
++ = XBUFFER (buf
)->read_only
;
1996 *vecp
++ = Fbuffer_modified_p (buf
);
1998 /* Fill up the vector with lambdas (always at least one). */
2000 while (vecp
- XVECTOR (frame_and_buffer_state
)->contents
2001 < XVECTOR (frame_and_buffer_state
)->size
)
2003 /* Make sure we didn't overflow the vector. */
2004 if (vecp
- XVECTOR (frame_and_buffer_state
)->contents
2005 > XVECTOR (frame_and_buffer_state
)->size
)
2010 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
2011 1, 1, "FOpen termscript file: ",
2012 "Start writing all terminal output to FILE as well as the terminal.\n\
2013 FILE = nil means just close any termscript file currently open.")
2017 if (termscript
!= 0) fclose (termscript
);
2022 file
= Fexpand_file_name (file
, Qnil
);
2023 termscript
= fopen (XSTRING (file
)->data
, "w");
2024 if (termscript
== 0)
2025 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
2033 window_change_signal (signalnum
) /* If we don't have an argument, */
2034 int signalnum
; /* some compilers complain in signal calls. */
2038 int old_errno
= errno
;
2040 get_frame_size (&width
, &height
);
2042 /* The frame size change obviously applies to a termcap-controlled
2043 frame. Find such a frame in the list, and assume it's the only
2044 one (since the redisplay code always writes to stdout, not a
2045 FILE * specified in the frame structure). Record the new size,
2046 but don't reallocate the data structures now. Let that be done
2047 later outside of the signal handler. */
2050 Lisp_Object tail
, frame
;
2052 FOR_EACH_FRAME (tail
, frame
)
2054 if (FRAME_TERMCAP_P (XFRAME (frame
)))
2056 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
2062 signal (SIGWINCH
, window_change_signal
);
2065 #endif /* SIGWINCH */
2068 /* Do any change in frame size that was requested by a signal. */
2070 do_pending_window_change ()
2072 /* If window_change_signal should have run before, run it now. */
2073 while (delayed_size_change
)
2075 Lisp_Object tail
, frame
;
2077 delayed_size_change
= 0;
2079 FOR_EACH_FRAME (tail
, frame
)
2081 FRAME_PTR f
= XFRAME (frame
);
2083 int height
= FRAME_NEW_HEIGHT (f
);
2084 int width
= FRAME_NEW_WIDTH (f
);
2086 if (height
!= 0 || width
!= 0)
2087 change_frame_size (f
, height
, width
, 0, 0);
2093 /* Change the frame height and/or width. Values may be given as zero to
2094 indicate no change is to take place.
2096 If DELAY is non-zero, then assume we're being called from a signal
2097 handler, and queue the change for later - perhaps the next
2098 redisplay. Since this tries to resize windows, we can't call it
2099 from a signal handler. */
2101 change_frame_size (f
, newheight
, newwidth
, pretend
, delay
)
2102 register FRAME_PTR f
;
2103 int newheight
, newwidth
, pretend
;
2105 Lisp_Object tail
, frame
;
2106 if (FRAME_TERMCAP_P (f
))
2108 /* When using termcap, all frames use the same screen,
2109 so a change in size affects all termcap frames. */
2110 FOR_EACH_FRAME (tail
, frame
)
2111 if (FRAME_TERMCAP_P (XFRAME (frame
)))
2112 change_frame_size_1 (XFRAME (frame
), newheight
, newwidth
,
2116 change_frame_size_1 (f
, newheight
, newwidth
, pretend
, delay
);
2120 change_frame_size_1 (frame
, newheight
, newwidth
, pretend
, delay
)
2121 register FRAME_PTR frame
;
2122 int newheight
, newwidth
, pretend
, delay
;
2124 /* If we can't deal with the change now, queue it for later. */
2127 FRAME_NEW_HEIGHT (frame
) = newheight
;
2128 FRAME_NEW_WIDTH (frame
) = newwidth
;
2129 delayed_size_change
= 1;
2133 /* This size-change overrides any pending one for this frame. */
2134 FRAME_NEW_HEIGHT (frame
) = 0;
2135 FRAME_NEW_WIDTH (frame
) = 0;
2137 /* If an argument is zero, set it to the current value. */
2138 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
2139 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
2141 /* Round up to the smallest acceptable size. */
2142 check_frame_size (frame
, &newheight
, &newwidth
);
2144 /* If we're not changing the frame size, quit now. */
2145 if (newheight
== FRAME_HEIGHT (frame
)
2146 && newwidth
== FRAME_WIDTH (frame
))
2152 /* We only can set screen dimensions to certain values supported
2153 by our video hardware. Try to find the smallest size greater
2154 or equal to the requested dimensions. */
2155 dos_set_window_size (&newheight
, &newwidth
);
2158 if (newheight
!= FRAME_HEIGHT (frame
))
2160 if (FRAME_HAS_MINIBUF_P (frame
)
2161 && ! FRAME_MINIBUF_ONLY_P (frame
))
2163 /* Frame has both root and minibuffer. */
2164 set_window_height (FRAME_ROOT_WINDOW (frame
),
2165 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
2166 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
,
2168 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
2171 /* Frame has just one top-level window. */
2172 set_window_height (FRAME_ROOT_WINDOW (frame
),
2173 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
2175 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2176 FrameRows
= newheight
;
2179 if (frame
->output_method
== output_termcap
)
2181 frame_height
= newheight
;
2183 FrameRows
= newheight
;
2188 if (newwidth
!= FRAME_WIDTH (frame
))
2190 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
2191 if (FRAME_HAS_MINIBUF_P (frame
))
2192 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
2194 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2195 FrameCols
= newwidth
;
2197 if (frame
->output_method
== output_termcap
)
2199 frame_width
= newwidth
;
2201 FrameCols
= newwidth
;
2206 FRAME_HEIGHT (frame
) = newheight
;
2207 FRAME_WIDTH (frame
) = newwidth
;
2209 if (FRAME_CURSOR_X (frame
) >= FRAME_WIDTH (frame
))
2210 FRAME_CURSOR_X (frame
) = FRAME_WIDTH (frame
) - 1;
2211 if (FRAME_CURSOR_Y (frame
) >= FRAME_HEIGHT (frame
))
2212 FRAME_CURSOR_Y (frame
) = FRAME_HEIGHT (frame
) - 1;
2214 remake_frame_glyphs (frame
);
2215 calculate_costs (frame
);
2220 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
2221 Ssend_string_to_terminal
, 1, 1, 0,
2222 "Send STRING to the terminal without alteration.\n\
2223 Control characters in STRING will have terminal-dependent effects.")
2227 CHECK_STRING (string
, 0);
2228 fwrite (XSTRING (string
)->data
, 1, XSTRING (string
)->size
, stdout
);
2232 fwrite (XSTRING (string
)->data
, 1, XSTRING (string
)->size
, termscript
);
2233 fflush (termscript
);
2238 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
2239 "Beep, or flash the screen.\n\
2240 Also, unless an argument is given,\n\
2241 terminate any keyboard macro currently executing.")
2263 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
2264 error ("Keyboard macro terminated by a command ringing the bell");
2270 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
2271 "Pause, without updating display, for SECONDS seconds.\n\
2272 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2273 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2274 additional wait period, in milliseconds; this may be useful if your\n\
2275 Emacs was built without floating point support.\n\
2276 \(Not all operating systems support waiting for a fraction of a second.)")
2277 (seconds
, milliseconds
)
2278 Lisp_Object seconds
, milliseconds
;
2282 if (NILP (milliseconds
))
2283 XSETINT (milliseconds
, 0);
2285 CHECK_NUMBER (milliseconds
, 1);
2286 usec
= XINT (milliseconds
) * 1000;
2288 #ifdef LISP_FLOAT_TYPE
2290 double duration
= extract_float (seconds
);
2291 sec
= (int) duration
;
2292 usec
+= (duration
- sec
) * 1000000;
2295 CHECK_NUMBER (seconds
, 0);
2296 sec
= XINT (seconds
);
2299 #ifndef EMACS_HAS_USECS
2300 if (sec
== 0 && usec
!= 0)
2301 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2304 /* Assure that 0 <= usec < 1000000. */
2307 /* We can't rely on the rounding being correct if user is negative. */
2308 if (-1000000 < usec
)
2309 sec
--, usec
+= 1000000;
2311 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2314 sec
+= usec
/ 1000000, usec
%= 1000000;
2316 if (sec
< 0 || (sec
== 0 && usec
== 0))
2322 XSETFASTINT (zero
, 0);
2323 wait_reading_process_input (sec
, usec
, zero
, 0);
2326 /* We should always have wait_reading_process_input; we have a dummy
2327 implementation for systems which don't support subprocesses. */
2329 /* No wait_reading_process_input */
2336 /* The reason this is done this way
2337 (rather than defined (H_S) && defined (H_T))
2338 is because the VMS preprocessor doesn't grok `defined' */
2340 EMACS_GET_TIME (end_time
);
2341 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2342 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2346 EMACS_GET_TIME (timeout
);
2347 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2348 if (EMACS_TIME_NEG_P (timeout
)
2349 || !select (1, 0, 0, 0, &timeout
))
2352 #else /* not HAVE_SELECT */
2354 #endif /* HAVE_SELECT */
2355 #endif /* not VMS */
2358 #endif /* no subprocesses */
2363 /* This is just like wait_reading_process_input, except that
2364 it does the redisplay.
2366 It's also much like Fsit_for, except that it can be used for
2367 waiting for input as well. */
2370 sit_for (sec
, usec
, reading
, display
)
2371 int sec
, usec
, reading
, display
;
2373 Lisp_Object read_kbd
;
2375 swallow_events (display
);
2377 if (detect_input_pending_run_timers (display
))
2381 redisplay_preserve_echo_area ();
2383 if (sec
== 0 && usec
== 0)
2390 XSETINT (read_kbd
, reading
? -1 : 1);
2391 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2394 /* wait_reading_process_input should always be available now; it is
2395 simulated in a simple way on systems that don't support
2398 /* No wait_reading_process_input available. */
2404 input_wait_timeout (XINT (arg
));
2406 #ifndef HAVE_TIMEVAL
2408 select (1, &waitchannels
, 0, 0, &timeout_sec
);
2409 #else /* HAVE_TIMEVAL */
2410 timeout
.tv_sec
= sec
;
2411 timeout
.tv_usec
= usec
;
2412 select (1, &waitchannels
, 0, 0, &timeout
);
2413 #endif /* HAVE_TIMEVAL */
2414 #endif /* not VMS */
2419 return detect_input_pending () ? Qnil
: Qt
;
2422 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2423 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2424 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2425 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2426 additional wait period, in milliseconds; this may be useful if your\n\
2427 Emacs was built without floating point support.\n\
2428 \(Not all operating systems support waiting for a fraction of a second.)\n\
2429 Optional third arg NODISP non-nil means don't redisplay, just wait for input.\n\
2430 Redisplay is preempted as always if input arrives, and does not happen\n\
2431 if input is available before it starts.\n\
2432 Value is t if waited the full time with no input arriving.")
2433 (seconds
, milliseconds
, nodisp
)
2434 Lisp_Object seconds
, milliseconds
, nodisp
;
2438 if (NILP (milliseconds
))
2439 XSETINT (milliseconds
, 0);
2441 CHECK_NUMBER (milliseconds
, 1);
2442 usec
= XINT (milliseconds
) * 1000;
2444 #ifdef LISP_FLOAT_TYPE
2446 double duration
= extract_float (seconds
);
2447 sec
= (int) duration
;
2448 usec
+= (duration
- sec
) * 1000000;
2451 CHECK_NUMBER (seconds
, 0);
2452 sec
= XINT (seconds
);
2455 #ifndef EMACS_HAS_USECS
2456 if (usec
!= 0 && sec
== 0)
2457 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2460 return sit_for (sec
, usec
, 0, NILP (nodisp
));
2463 char *terminal_type
;
2465 /* Initialization done when Emacs fork is started, before doing stty. */
2466 /* Determine terminal type and set terminal_driver */
2467 /* Then invoke its decoding routine to set up variables
2468 in the terminal package */
2472 #ifdef HAVE_X_WINDOWS
2473 extern int display_arg
;
2478 cursor_in_echo_area
= 0;
2479 terminal_type
= (char *) 0;
2481 /* Now is the time to initialize this; it's used by init_sys_modes
2483 Vwindow_system
= Qnil
;
2485 /* If the user wants to use a window system, we shouldn't bother
2486 initializing the terminal. This is especially important when the
2487 terminal is so dumb that emacs gives up before and doesn't bother
2488 using the window system.
2490 If the DISPLAY environment variable is set and nonempty,
2491 try to use X, and die with an error message if that doesn't work. */
2493 #ifdef HAVE_X_WINDOWS
2498 display
= getenv ("DECW$DISPLAY");
2500 display
= getenv ("DISPLAY");
2503 display_arg
= (display
!= 0 && *display
!= 0);
2506 if (!inhibit_window_system
&& display_arg
)
2508 Vwindow_system
= intern ("x");
2510 Vwindow_system_version
= make_number (11);
2512 Vwindow_system_version
= make_number (10);
2514 #if defined (LINUX) && defined (HAVE_LIBNCURSES)
2515 /* In some versions of ncurses,
2516 tputs crashes if we have not called tgetent.
2518 { char b
[2044]; tgetent (b
, "xterm");}
2522 #endif /* HAVE_X_WINDOWS */
2525 if (!inhibit_window_system
)
2527 Vwindow_system
= intern ("win32");
2528 Vwindow_system_version
= make_number (1);
2531 #endif /* HAVE_NTGUI */
2533 /* If no window system has been specified, try to use the terminal. */
2536 fprintf (stderr
, "emacs: standard input is not a tty\n");
2540 /* Look at the TERM variable */
2541 terminal_type
= (char *) getenv ("TERM");
2545 fprintf (stderr
, "Please specify your terminal type.\n\
2546 For types defined in VMS, use set term /device=TYPE.\n\
2547 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2548 \(The quotation marks are necessary since terminal types are lower case.)\n");
2550 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2556 /* VMS DCL tends to upcase things, so downcase term type.
2557 Hardly any uppercase letters in terminal types; should be none. */
2559 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2562 strcpy (new, terminal_type
);
2564 for (p
= new; *p
; p
++)
2568 terminal_type
= new;
2572 term_init (terminal_type
);
2574 remake_frame_glyphs (selected_frame
);
2575 calculate_costs (selected_frame
);
2577 /* X and Y coordinates of the cursor between updates. */
2578 FRAME_CURSOR_X (selected_frame
) = 0;
2579 FRAME_CURSOR_Y (selected_frame
) = 0;
2584 #endif /* CANNOT_DUMP */
2585 signal (SIGWINCH
, window_change_signal
);
2586 #endif /* SIGWINCH */
2592 defsubr (&Sredraw_frame
);
2594 defsubr (&Sredraw_display
);
2595 defsubr (&Sframe_or_buffer_changed_p
);
2596 defsubr (&Sopen_termscript
);
2598 defsubr (&Ssit_for
);
2599 defsubr (&Ssleep_for
);
2600 defsubr (&Ssend_string_to_terminal
);
2602 frame_and_buffer_state
= Fmake_vector (make_number (20), Qlambda
);
2603 staticpro (&frame_and_buffer_state
);
2605 Qdisplay_table
= intern ("display-table");
2606 staticpro (&Qdisplay_table
);
2608 DEFVAR_INT ("baud-rate", &baud_rate
,
2609 "*The output baud rate of the terminal.\n\
2610 On most systems, changing this value will affect the amount of padding\n\
2611 and the other strategic decisions made during redisplay.");
2612 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2613 "*Non-nil means invert the entire frame display.\n\
2614 This means everything is in inverse video which otherwise would not be.");
2615 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2616 "*Non-nil means try to flash the frame to represent a bell.");
2617 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2618 "*Non-nil means no need to redraw entire frame after suspending.\n\
2619 A non-nil value is useful if the terminal can automatically preserve\n\
2620 Emacs's frame display when you reenter Emacs.\n\
2621 It is up to you to set this variable if your terminal can do that.");
2622 DEFVAR_LISP ("window-system", &Vwindow_system
,
2623 "A symbol naming the window-system under which Emacs is running\n\
2624 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2625 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2626 "The version number of the window system in use.\n\
2627 For X windows, this is 10 or 11.");
2628 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2629 "Non-nil means put cursor in minibuffer, at end of any message there.");
2630 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2631 "Table defining how to output a glyph code to the frame.\n\
2632 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2633 Each element can be:\n\
2634 integer: a glyph code which this glyph is an alias for.\n\
2635 string: output this glyph using that string (not impl. in X windows).\n\
2636 nil: this glyph mod 256 is char code to output,\n\
2637 and this glyph / 256 is face code for X windows (see `face-id').");
2638 Vglyph_table
= Qnil
;
2640 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2641 "Display table to use for buffers that specify none.\n\
2642 See `buffer-display-table' for more information.");
2643 Vstandard_display_table
= Qnil
;
2645 /* Initialize `window-system', unless init_display already decided it. */
2650 Vwindow_system
= Qnil
;
2651 Vwindow_system_version
= Qnil
;