1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
31 #include "termhooks.h"
33 #include "dispextern.h"
40 #include "intervals.h"
43 #include "syssignal.h"
47 #endif /* HAVE_X_WINDOWS */
49 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
54 #define max(a, b) ((a) > (b) ? (a) : (b))
55 #define min(a, b) ((a) < (b) ? (a) : (b))
57 /* Get number of chars of output now in the buffer of a stdio stream.
58 This ought to be built in in stdio, but it isn't.
59 Some s- files override this because their stdio internals differ. */
60 #ifdef __GNU_LIBRARY__
61 /* The s- file might have overridden the definition with one that works for
62 the system's C library. But we are using the GNU C library, so this is
63 the right definition for every system. */
64 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
65 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
67 #undef PENDING_OUTPUT_COUNT
68 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
70 #else /* not __GNU_LIBRARY__ */
71 #ifndef PENDING_OUTPUT_COUNT
72 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
76 static void change_frame_size_1 ();
78 /* Nonzero upon entry to redisplay means do not assume anything about
79 current contents of actual terminal frame; clear and redraw it. */
83 /* Nonzero means last display completed. Zero means it was preempted. */
85 int display_completed
;
87 /* Lisp variable visible-bell; enables use of screen-flash
88 instead of audible bell. */
92 /* Invert the color of the whole frame, at a low level. */
96 /* Line speed of the terminal. */
100 /* nil or a symbol naming the window system under which emacs is
101 running ('x is the only current possibility). */
103 Lisp_Object Vwindow_system
;
105 /* Version number of X windows: 10, 11 or nil. */
106 Lisp_Object Vwindow_system_version
;
108 /* Vector of glyph definitions. Indexed by glyph number,
109 the contents are a string which is how to output the glyph.
111 If Vglyph_table is nil, a glyph is output by using its low 8 bits
112 as a character code. */
114 Lisp_Object Vglyph_table
;
116 /* Display table to use for vectors that don't specify their own. */
118 Lisp_Object Vstandard_display_table
;
120 /* Nonzero means reading single-character input with prompt
121 so put cursor on minibuffer after the prompt.
122 positive means at end of text in echo area;
123 negative means at beginning of line. */
124 int cursor_in_echo_area
;
126 /* The currently selected frame.
127 In a single-frame version, this variable always holds the address of
130 FRAME_PTR selected_frame
;
132 /* A frame which is not just a minibuffer, or 0 if there are no such
133 frames. This is usually the most recent such frame that was
134 selected. In a single-frame version, this variable always holds
135 the address of the_only_frame. */
136 FRAME_PTR last_nonminibuf_frame
;
138 /* In a single-frame version, the information that would otherwise
139 exist inside frame objects lives in the following structure instead.
141 NOTE: the_only_frame is not checked for garbage collection; don't
142 store collectible objects in any of its fields!
144 You're not/The only frame in town/... */
147 struct frame the_only_frame
;
150 /* This is a vector, made larger whenever it isn't large enough,
151 which is used inside `update_frame' to hold the old contents
152 of the FRAME_PHYS_LINES of the frame being updated. */
153 struct frame_glyphs
**ophys_lines
;
154 /* Length of vector currently allocated. */
155 int ophys_lines_length
;
157 FILE *termscript
; /* Stdio stream being used for copy of all output. */
159 struct cm Wcm
; /* Structure for info on cursor positioning */
161 extern short ospeed
; /* Output speed (from sg_ospeed) */
163 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
167 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
168 "Clear frame FRAME and output again what is supposed to appear on it.")
174 CHECK_LIVE_FRAME (frame
, 0);
177 /* set_terminal_modes (); */
179 clear_frame_records (f
);
182 windows_or_buffers_changed
++;
183 /* Mark all windows as INaccurate,
184 so that every window will have its redisplay done. */
185 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
194 XSETFRAME (frame
, f
);
195 Fredraw_frame (frame
);
200 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
201 /* Don't confuse make-docfile by having two doc strings for this function.
202 make-docfile does not pay attention to #if, for good reason! */
208 set_terminal_modes ();
212 clear_frame_records (0);
213 windows_or_buffers_changed
++;
214 /* Mark all windows as INaccurate,
215 so that every window will have its redisplay done. */
216 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
222 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
223 "Clear and redisplay all visible frames.")
226 Lisp_Object tail
, frame
;
228 FOR_EACH_FRAME (tail
, frame
)
229 if (FRAME_VISIBLE_P (XFRAME (frame
)))
230 Fredraw_frame (frame
);
235 /* This is used when frame_garbaged is set.
236 Redraw the individual frames marked as garbaged. */
239 redraw_garbaged_frames ()
241 Lisp_Object tail
, frame
;
243 FOR_EACH_FRAME (tail
, frame
)
244 if (FRAME_VISIBLE_P (XFRAME (frame
))
245 && FRAME_GARBAGED_P (XFRAME (frame
)))
246 Fredraw_frame (frame
);
250 static struct frame_glyphs
*
251 make_frame_glyphs (frame
, empty
)
252 register FRAME_PTR frame
;
256 register width
= FRAME_WIDTH (frame
);
257 register height
= FRAME_HEIGHT (frame
);
258 register struct frame_glyphs
*new
259 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
261 SET_GLYPHS_FRAME (new, frame
);
262 new->height
= height
;
264 new->used
= (int *) xmalloc (height
* sizeof (int));
265 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
266 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
267 new->highlight
= (char *) xmalloc (height
* sizeof (char));
268 new->enable
= (char *) xmalloc (height
* sizeof (char));
269 bzero (new->enable
, height
* sizeof (char));
270 new->bufp
= (int *) xmalloc (height
* sizeof (int));
272 #ifdef HAVE_X_WINDOWS
273 if (FRAME_X_P (frame
))
275 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
276 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
277 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
278 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
279 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
285 /* Make the buffer used by decode_mode_spec. This buffer is also
286 used as temporary storage when updating the frame. See scroll.c. */
287 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
288 unsigned int total_charstarts
= (width
+ 2) * sizeof (int);
290 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
291 bzero (new->total_contents
, total_glyphs
);
293 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
294 bzero (new->total_charstarts
, total_glyphs
);
298 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
300 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
301 bzero (new->total_contents
, total_glyphs
);
302 for (i
= 0; i
< height
; i
++)
303 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
305 if (!FRAME_TERMCAP_P (frame
))
307 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
309 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
310 bzero (new->total_charstarts
, total_charstarts
);
311 for (i
= 0; i
< height
; i
++)
312 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
316 /* Without a window system, we don't really need charstarts.
317 So use a small amount of space to make enough data structure
318 to prevent crashes in display_text_line. */
319 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
320 for (i
= 0; i
< height
; i
++)
321 new->charstarts
[i
] = new->total_charstarts
;
329 free_frame_glyphs (frame
, glyphs
)
331 struct frame_glyphs
*glyphs
;
333 if (glyphs
->total_contents
)
334 xfree (glyphs
->total_contents
);
335 if (glyphs
->total_charstarts
)
336 xfree (glyphs
->total_charstarts
);
338 xfree (glyphs
->used
);
339 xfree (glyphs
->glyphs
);
340 xfree (glyphs
->highlight
);
341 xfree (glyphs
->enable
);
342 xfree (glyphs
->bufp
);
343 if (glyphs
->charstarts
)
344 xfree (glyphs
->charstarts
);
346 #ifdef HAVE_X_WINDOWS
347 if (FRAME_X_P (frame
))
349 xfree (glyphs
->top_left_x
);
350 xfree (glyphs
->top_left_y
);
351 xfree (glyphs
->pix_width
);
352 xfree (glyphs
->pix_height
);
353 xfree (glyphs
->max_ascent
);
361 remake_frame_glyphs (frame
)
364 if (FRAME_CURRENT_GLYPHS (frame
))
365 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
366 if (FRAME_DESIRED_GLYPHS (frame
))
367 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
368 if (FRAME_TEMP_GLYPHS (frame
))
369 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
371 if (FRAME_MESSAGE_BUF (frame
))
373 /* Reallocate the frame's message buffer; remember that
374 echo_area_glyphs may be pointing here. */
375 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
377 FRAME_MESSAGE_BUF (frame
)
378 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
379 FRAME_WIDTH (frame
) + 1);
381 if (echo_area_glyphs
== old_message_buf
)
382 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
383 if (previous_echo_glyphs
== old_message_buf
)
384 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
387 FRAME_MESSAGE_BUF (frame
)
388 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
390 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
391 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
392 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
393 if (! FRAME_TERMCAP_P (frame
) || frame
== selected_frame
)
394 SET_FRAME_GARBAGED (frame
);
397 /* Return the hash code of contents of line VPOS in frame-matrix M. */
400 line_hash_code (m
, vpos
)
401 register struct frame_glyphs
*m
;
404 register GLYPH
*body
, *end
;
407 if (!m
->enable
[vpos
])
410 /* Give all highlighted lines the same hash code
411 so as to encourage scrolling to leave them in place. */
412 if (m
->highlight
[vpos
])
415 body
= m
->glyphs
[vpos
];
417 if (must_write_spaces
)
424 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
433 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
441 /* Return number of characters in line in M at vpos VPOS,
442 except don't count leading and trailing spaces
443 unless the terminal requires those to be explicitly output. */
446 line_draw_cost (m
, vpos
)
447 struct frame_glyphs
*m
;
450 register GLYPH
*beg
= m
->glyphs
[vpos
];
451 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
453 register int tlen
= GLYPH_TABLE_LENGTH
;
454 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
456 /* Ignore trailing and leading spaces if we can. */
457 if (!must_write_spaces
)
459 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
462 return (0); /* All blank line. */
464 while (*beg
== SPACEGLYPH
)
468 /* If we don't have a glyph-table, each glyph is one character,
469 so return the number of glyphs. */
473 /* Otherwise, scan the glyphs and accumulate their total size in I. */
475 while ((beg
<= end
) && *beg
)
477 register GLYPH g
= *beg
++;
479 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
482 i
+= GLYPH_LENGTH (tbase
, g
);
487 /* The functions on this page are the interface from xdisp.c to redisplay.
489 The only other interface into redisplay is through setting
490 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
491 and SET_FRAME_GARBAGED (frame). */
493 /* cancel_line eliminates any request to display a line at position `vpos' */
495 cancel_line (vpos
, frame
)
497 register FRAME_PTR frame
;
499 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
502 clear_frame_records (frame
)
503 register FRAME_PTR frame
;
505 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
508 /* Clear out all display lines for a coming redisplay. */
511 init_desired_glyphs (frame
)
512 register FRAME_PTR frame
;
514 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
516 int height
= FRAME_HEIGHT (frame
);
518 for (vpos
= 0; vpos
< height
; vpos
++)
519 desired_glyphs
->enable
[vpos
] = 0;
522 /* Prepare to display on line VPOS starting at HPOS within it. */
525 get_display_line (frame
, vpos
, hpos
)
526 register FRAME_PTR frame
;
530 register struct frame_glyphs
*glyphs
;
531 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
537 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
540 if (! desired_glyphs
->enable
[vpos
])
542 desired_glyphs
->used
[vpos
] = 0;
543 desired_glyphs
->highlight
[vpos
] = 0;
544 desired_glyphs
->enable
[vpos
] = 1;
547 if (hpos
> desired_glyphs
->used
[vpos
])
549 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
550 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
552 desired_glyphs
->used
[vpos
] = hpos
;
558 /* Like bcopy except never gets confused by overlap. */
561 safe_bcopy (from
, to
, size
)
565 if (size
<= 0 || from
== to
)
568 /* If the source and destination don't overlap, then bcopy can
569 handle it. If they do overlap, but the destination is lower in
570 memory than the source, we'll assume bcopy can handle that. */
571 if (to
< from
|| from
+ size
<= to
)
572 bcopy (from
, to
, size
);
574 /* Otherwise, we'll copy from the end. */
577 register char *endf
= from
+ size
;
578 register char *endt
= to
+ size
;
580 /* If TO - FROM is large, then we should break the copy into
581 nonoverlapping chunks of TO - FROM bytes each. However, if
582 TO - FROM is small, then the bcopy function call overhead
583 makes this not worth it. The crossover point could be about
584 anywhere. Since I don't think the obvious copy loop is too
585 bad, I'm trying to err in its favor. */
590 while (endf
!= from
);
602 bcopy (endf
, endt
, to
- from
);
605 /* If SIZE wasn't a multiple of TO - FROM, there will be a
606 little left over. The amount left over is
607 (endt + (to - from)) - to, which is endt - from. */
608 bcopy (from
, to
, endt
- from
);
613 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
614 DISTANCE may be negative. */
617 rotate_vector (vector
, size
, distance
)
622 char *temp
= (char *) alloca (size
);
627 bcopy (vector
, temp
+ distance
, size
- distance
);
628 bcopy (vector
+ size
- distance
, temp
, distance
);
629 bcopy (temp
, vector
, size
);
632 /* Scroll lines from vpos FROM up to but not including vpos END
633 down by AMOUNT lines (AMOUNT may be negative).
634 Returns nonzero if done, zero if terminal cannot scroll them. */
637 scroll_frame_lines (frame
, from
, end
, amount
, newpos
)
638 register FRAME_PTR frame
;
639 int from
, end
, amount
, newpos
;
642 register struct frame_glyphs
*current_frame
643 = FRAME_CURRENT_GLYPHS (frame
);
645 int width
= FRAME_WIDTH (frame
);
647 if (!line_ins_del_ok
)
655 update_begin (frame
);
656 set_terminal_window (end
+ amount
);
657 if (!scroll_region_ok
)
658 ins_del_lines (end
, -amount
);
659 ins_del_lines (from
, amount
);
660 set_terminal_window (0);
662 rotate_vector (current_frame
->glyphs
+ from
,
663 sizeof (GLYPH
*) * (end
+ amount
- from
),
664 amount
* sizeof (GLYPH
*));
666 rotate_vector (current_frame
->charstarts
+ from
,
667 sizeof (int *) * (end
+ amount
- from
),
668 amount
* sizeof (int *));
670 safe_bcopy (current_frame
->used
+ from
,
671 current_frame
->used
+ from
+ amount
,
672 (end
- from
) * sizeof current_frame
->used
[0]);
674 safe_bcopy (current_frame
->highlight
+ from
,
675 current_frame
->highlight
+ from
+ amount
,
676 (end
- from
) * sizeof current_frame
->highlight
[0]);
678 safe_bcopy (current_frame
->enable
+ from
,
679 current_frame
->enable
+ from
+ amount
,
680 (end
- from
) * sizeof current_frame
->enable
[0]);
682 /* Adjust the lines by an amount
683 that puts the first of them at NEWPOS. */
684 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
686 /* Offset each char position in the charstarts lines we moved
688 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
690 int *line
= current_frame
->charstarts
[i
];
692 for (col
= 0; col
< width
; col
++)
694 line
[col
] += pos_adjust
;
696 for (i
= from
; i
< from
+ amount
; i
++)
698 int *line
= current_frame
->charstarts
[i
];
701 for (col
= 0; col
< width
; col
++)
705 /* Mark the lines made empty by scrolling as enabled, empty and
707 bzero (current_frame
->used
+ from
,
708 amount
* sizeof current_frame
->used
[0]);
709 bzero (current_frame
->highlight
+ from
,
710 amount
* sizeof current_frame
->highlight
[0]);
711 for (i
= from
; i
< from
+ amount
; i
++)
713 current_frame
->glyphs
[i
][0] = '\0';
714 current_frame
->charstarts
[i
][0] = -1;
715 current_frame
->enable
[i
] = 1;
718 safe_bcopy (current_frame
->bufp
+ from
,
719 current_frame
->bufp
+ from
+ amount
,
720 (end
- from
) * sizeof current_frame
->bufp
[0]);
722 #ifdef HAVE_X_WINDOWS
723 if (FRAME_X_P (frame
))
725 safe_bcopy (current_frame
->top_left_x
+ from
,
726 current_frame
->top_left_x
+ from
+ amount
,
727 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
729 safe_bcopy (current_frame
->top_left_y
+ from
,
730 current_frame
->top_left_y
+ from
+ amount
,
731 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
733 safe_bcopy (current_frame
->pix_width
+ from
,
734 current_frame
->pix_width
+ from
+ amount
,
735 (end
- from
) * sizeof current_frame
->pix_width
[0]);
737 safe_bcopy (current_frame
->pix_height
+ from
,
738 current_frame
->pix_height
+ from
+ amount
,
739 (end
- from
) * sizeof current_frame
->pix_height
[0]);
741 safe_bcopy (current_frame
->max_ascent
+ from
,
742 current_frame
->max_ascent
+ from
+ amount
,
743 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
745 #endif /* HAVE_X_WINDOWS */
751 update_begin (frame
);
752 set_terminal_window (end
);
753 ins_del_lines (from
+ amount
, amount
);
754 if (!scroll_region_ok
)
755 ins_del_lines (end
+ amount
, -amount
);
756 set_terminal_window (0);
758 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
759 sizeof (GLYPH
*) * (end
- from
- amount
),
760 amount
* sizeof (GLYPH
*));
762 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
763 sizeof (int *) * (end
- from
- amount
),
764 amount
* sizeof (int *));
766 safe_bcopy (current_frame
->used
+ from
,
767 current_frame
->used
+ from
+ amount
,
768 (end
- from
) * sizeof current_frame
->used
[0]);
770 safe_bcopy (current_frame
->highlight
+ from
,
771 current_frame
->highlight
+ from
+ amount
,
772 (end
- from
) * sizeof current_frame
->highlight
[0]);
774 safe_bcopy (current_frame
->enable
+ from
,
775 current_frame
->enable
+ from
+ amount
,
776 (end
- from
) * sizeof current_frame
->enable
[0]);
778 /* Adjust the lines by an amount
779 that puts the first of them at NEWPOS. */
780 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
782 /* Offset each char position in the charstarts lines we moved
784 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
786 int *line
= current_frame
->charstarts
[i
];
788 for (col
= 0; col
< width
; col
++)
790 line
[col
] += pos_adjust
;
792 for (i
= end
+ amount
; i
< end
; i
++)
794 int *line
= current_frame
->charstarts
[i
];
797 for (col
= 0; col
< width
; col
++)
801 /* Mark the lines made empty by scrolling as enabled, empty and
803 bzero (current_frame
->used
+ end
+ amount
,
804 - amount
* sizeof current_frame
->used
[0]);
805 bzero (current_frame
->highlight
+ end
+ amount
,
806 - amount
* sizeof current_frame
->highlight
[0]);
807 for (i
= end
+ amount
; i
< end
; i
++)
809 current_frame
->glyphs
[i
][0] = '\0';
810 current_frame
->charstarts
[i
][0] = 0;
811 current_frame
->enable
[i
] = 1;
814 safe_bcopy (current_frame
->bufp
+ from
,
815 current_frame
->bufp
+ from
+ amount
,
816 (end
- from
) * sizeof current_frame
->bufp
[0]);
818 #ifdef HAVE_X_WINDOWS
819 if (FRAME_X_P (frame
))
821 safe_bcopy (current_frame
->top_left_x
+ from
,
822 current_frame
->top_left_x
+ from
+ amount
,
823 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
825 safe_bcopy (current_frame
->top_left_y
+ from
,
826 current_frame
->top_left_y
+ from
+ amount
,
827 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
829 safe_bcopy (current_frame
->pix_width
+ from
,
830 current_frame
->pix_width
+ from
+ amount
,
831 (end
- from
) * sizeof current_frame
->pix_width
[0]);
833 safe_bcopy (current_frame
->pix_height
+ from
,
834 current_frame
->pix_height
+ from
+ amount
,
835 (end
- from
) * sizeof current_frame
->pix_height
[0]);
837 safe_bcopy (current_frame
->max_ascent
+ from
,
838 current_frame
->max_ascent
+ from
+ amount
,
839 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
841 #endif /* HAVE_X_WINDOWS */
848 /* After updating a window W that isn't the full frame wide,
849 copy all the columns that W does not occupy
850 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
851 so that update_frame will not change those columns. */
853 preserve_other_columns (w
)
857 register struct frame_glyphs
*current_frame
, *desired_frame
;
858 register FRAME_PTR frame
= XFRAME (w
->frame
);
859 int start
= XFASTINT (w
->left
);
860 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
861 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
863 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
864 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
866 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
868 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
874 bcopy (current_frame
->glyphs
[vpos
],
875 desired_frame
->glyphs
[vpos
],
876 start
* sizeof (current_frame
->glyphs
[vpos
][0]));
877 bcopy (current_frame
->charstarts
[vpos
],
878 desired_frame
->charstarts
[vpos
],
879 start
* sizeof (current_frame
->charstarts
[vpos
][0]));
880 len
= min (start
, current_frame
->used
[vpos
]);
881 if (desired_frame
->used
[vpos
] < len
)
882 desired_frame
->used
[vpos
] = len
;
884 if (current_frame
->used
[vpos
] > end
885 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
887 while (desired_frame
->used
[vpos
] < end
)
889 int used
= desired_frame
->used
[vpos
]++;
890 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
891 desired_frame
->glyphs
[vpos
][used
] = 0;
893 bcopy (current_frame
->glyphs
[vpos
] + end
,
894 desired_frame
->glyphs
[vpos
] + end
,
895 ((current_frame
->used
[vpos
] - end
)
896 * sizeof (current_frame
->glyphs
[vpos
][0])));
897 bcopy (current_frame
->charstarts
[vpos
] + end
,
898 desired_frame
->charstarts
[vpos
] + end
,
899 ((current_frame
->used
[vpos
] - end
)
900 * sizeof (current_frame
->charstarts
[vpos
][0])));
901 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
909 /* If window w does not need to be updated and isn't the full frame wide,
910 copy all the columns that w does occupy
911 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
912 so that update_frame will not change those columns.
914 Have not been able to figure out how to use this correctly. */
916 preserve_my_columns (w
)
919 register int vpos
, fin
;
920 register struct frame_glyphs
*l1
, *l2
;
921 register FRAME_PTR frame
= XFRAME (w
->frame
);
922 int start
= XFASTINT (w
->left
);
923 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
924 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
926 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
928 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
929 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
931 if (l2
->length
> start
&& l1
->length
< l2
->length
)
934 if (fin
> end
) fin
= end
;
935 while (l1
->length
< start
)
936 l1
->body
[l1
->length
++] = ' ';
937 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
946 /* Adjust by ADJUST the charstart values in window W
947 after vpos VPOS, which counts relative to the frame
948 (not relative to W itself). */
951 adjust_window_charstarts (w
, vpos
, adjust
)
956 int left
= XFASTINT (w
->left
);
957 int top
= XFASTINT (w
->top
);
958 int right
= left
+ window_internal_width (w
);
959 int bottom
= top
+ window_internal_height (w
);
962 for (i
= vpos
+ 1; i
< bottom
; i
++)
965 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
967 for (j
= left
; j
< right
; j
++)
968 if (charstart
[j
] > 0)
969 charstart
[j
] += adjust
;
973 /* Check the charstarts values in the area of window W
974 for internal consistency. We cannot check that they are "right";
975 we can only look for something nonsensical. */
977 verify_charstarts (w
)
980 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
982 int top
= XFASTINT (w
->top
);
983 int bottom
= top
+ window_internal_height (w
);
984 int left
= XFASTINT (w
->left
);
985 int right
= left
+ window_internal_width (w
);
987 int truncate
= (XINT (w
->hscroll
)
988 || (truncate_partial_width_windows
989 && (XFASTINT (w
->width
) < FRAME_WIDTH (f
)))
990 || !NILP (XBUFFER (w
->buffer
)->truncate_lines
));
992 for (i
= top
; i
< bottom
; i
++)
996 int *charstart
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[i
];
1002 /* If we are truncating lines, allow a jump
1003 in charstarts from one line to the next. */
1004 if (charstart
[left
] < next_line
)
1009 if (charstart
[left
] != next_line
)
1014 for (j
= left
; j
< right
; j
++)
1015 if (charstart
[j
] > 0)
1016 last
= charstart
[j
];
1017 /* Record where the next line should start. */
1019 if (BUF_ZV (XBUFFER (w
->buffer
)) != last
)
1021 /* If there's a newline between the two lines, count that. */
1022 int endchar
= *BUF_CHAR_ADDRESS (XBUFFER (w
->buffer
), last
);
1023 if (endchar
== '\n')
1029 /* On discovering that the redisplay for a window was no good,
1030 cancel the columns of that window, so that when the window is
1031 displayed over again get_display_line will not complain. */
1033 cancel_my_columns (w
)
1037 register struct frame_glyphs
*desired_glyphs
1038 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
1039 register int start
= XFASTINT (w
->left
);
1040 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
1042 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
1043 if (desired_glyphs
->enable
[vpos
]
1044 && desired_glyphs
->used
[vpos
] >= start
)
1045 desired_glyphs
->used
[vpos
] = start
;
1048 /* These functions try to perform directly and immediately on the frame
1049 the necessary output for one change in the buffer.
1050 They may return 0 meaning nothing was done if anything is difficult,
1051 or 1 meaning the output was performed properly.
1052 They assume that the frame was up to date before the buffer
1053 change being displayed. They make various other assumptions too;
1054 see command_loop_1 where these are called. */
1057 direct_output_for_insert (g
)
1060 register FRAME_PTR frame
= selected_frame
;
1061 register struct frame_glyphs
*current_frame
1062 = FRAME_CURRENT_GLYPHS (frame
);
1064 #ifndef COMPILER_REGISTER_BUG
1066 #endif /* COMPILER_REGISTER_BUG */
1067 struct window
*w
= XWINDOW (selected_window
);
1068 #ifndef COMPILER_REGISTER_BUG
1070 #endif /* COMPILER_REGISTER_BUG */
1071 int hpos
= FRAME_CURSOR_X (frame
);
1072 #ifndef COMPILER_REGISTER_BUG
1074 #endif /* COMPILER_REGISTER_BUG */
1075 int vpos
= FRAME_CURSOR_Y (frame
);
1077 /* Give up if about to continue line. */
1078 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
1080 /* Avoid losing if cursor is in invisible text off left margin */
1081 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
1083 /* Give up if cursor outside window (in minibuf, probably) */
1084 || cursor_in_echo_area
1085 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
1086 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
1088 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
1089 || !display_completed
1091 /* Give up if buffer appears in two places. */
1092 || buffer_shared
> 1
1094 #ifdef USE_TEXT_PROPERTIES
1095 /* Intervals have already been adjusted, point is after the
1096 character that was just inserted. */
1097 /* Give up if character is invisible. */
1098 /* Give up if character has a face property.
1099 At the moment we only lose at end of line or end of buffer
1100 and only with faces that have some background */
1101 /* Instead of wasting time, give up if character has any text properties */
1102 || ! NILP (Ftext_properties_at (make_number (point
- 1), Qnil
))
1105 /* Give up if w is minibuffer and a message is being displayed there */
1106 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1114 if (FRAME_X_P (frame
))
1115 face
= compute_char_face (frame
, w
, point
- 1, -1, -1, &dummy
, point
, 0);
1117 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1118 current_frame
->charstarts
[vpos
][hpos
] = point
- 1;
1119 /* Record the entry for after the newly inserted character. */
1120 current_frame
->charstarts
[vpos
][hpos
+ 1] = point
;
1121 adjust_window_charstarts (w
, vpos
, 1);
1123 unchanged_modified
= MODIFF
;
1124 beg_unchanged
= GPT
- BEG
;
1125 XSETFASTINT (w
->last_point
, point
);
1126 XSETFASTINT (w
->last_point_x
, hpos
);
1127 XSETFASTINT (w
->last_modified
, MODIFF
);
1129 reassert_line_highlight (0, vpos
);
1130 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
1132 ++FRAME_CURSOR_X (frame
);
1133 if (hpos
== current_frame
->used
[vpos
])
1135 current_frame
->used
[vpos
] = hpos
+ 1;
1136 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
1143 direct_output_forward_char (n
)
1146 register FRAME_PTR frame
= selected_frame
;
1147 register struct window
*w
= XWINDOW (selected_window
);
1148 Lisp_Object position
;
1149 int hpos
= FRAME_CURSOR_X (frame
);
1151 /* Give up if in truncated text at end of line. */
1152 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1)
1155 /* Avoid losing if cursor is in invisible text off left margin
1156 or about to go off either side of window. */
1157 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
1158 && (XINT (w
->hscroll
) || n
< 0))
1160 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
1161 || cursor_in_echo_area
)
1164 /* Can't use direct output if highlighting a region. */
1165 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1168 /* Can't use direct output at an overlay boundary; it might have
1169 before-string or after-string properties. */
1170 if (overlay_touches_p (PT
) || overlay_touches_p (PT
- n
))
1173 #ifdef USE_TEXT_PROPERTIES
1174 /* Don't use direct output next to an invisible character
1175 since we might need to do something special. */
1177 XSETFASTINT (position
, point
);
1178 if (XFASTINT (position
) < ZV
1179 && ! NILP (Fget_char_property (position
,
1184 XSETFASTINT (position
, point
- 1);
1185 if (XFASTINT (position
) >= BEGV
1186 && ! NILP (Fget_char_property (position
,
1192 FRAME_CURSOR_X (frame
) += n
;
1193 XSETFASTINT (w
->last_point_x
, FRAME_CURSOR_X (frame
));
1194 XSETFASTINT (w
->last_point
, point
);
1195 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1201 static void update_line ();
1203 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1204 Value is nonzero if redisplay stopped due to pending input.
1205 FORCE nonzero means do not stop for pending input. */
1208 update_frame (f
, force
, inhibit_hairy_id
)
1211 int inhibit_hairy_id
;
1213 register struct frame_glyphs
*current_frame
;
1214 register struct frame_glyphs
*desired_frame
= 0;
1217 int preempt_count
= baud_rate
/ 2400 + 1;
1218 extern input_pending
;
1219 #ifdef HAVE_X_WINDOWS
1220 register int downto
, leftmost
;
1223 if (baud_rate
!= FRAME_COST_BAUD_RATE (f
))
1224 calculate_costs (f
);
1226 if (preempt_count
<= 0)
1229 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1231 detect_input_pending ();
1232 if (input_pending
&& !force
)
1240 if (!line_ins_del_ok
)
1241 inhibit_hairy_id
= 1;
1243 /* These are separate to avoid a possible bug in the AIX C compiler. */
1244 current_frame
= FRAME_CURRENT_GLYPHS (f
);
1245 desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1247 /* See if any of the desired lines are enabled; don't compute for
1248 i/d line if just want cursor motion. */
1249 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1250 if (desired_frame
->enable
[i
])
1253 /* Try doing i/d line, if not yet inhibited. */
1254 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1255 force
|= scrolling (f
);
1257 /* Update the individual lines as needed. Do bottom line first. */
1259 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1260 update_line (f
, FRAME_HEIGHT (f
) - 1);
1262 #ifdef HAVE_X_WINDOWS
1265 leftmost
= downto
= f
->output_data
.x
->internal_border_width
;
1266 if (desired_frame
->enable
[0])
1268 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1269 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1270 = PIXEL_HEIGHT (f
) - f
->output_data
.x
->internal_border_width
1271 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1272 current_frame
->top_left_x
[0] = leftmost
;
1273 current_frame
->top_left_y
[0] = downto
;
1276 #endif /* HAVE_X_WINDOWS */
1278 /* Now update the rest of the lines. */
1279 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1281 if (desired_frame
->enable
[i
])
1283 if (FRAME_TERMCAP_P (f
))
1285 /* Flush out every so many lines.
1286 Also flush out if likely to have more than 1k buffered
1287 otherwise. I'm told that some telnet connections get
1288 really screwed by more than 1k output at once. */
1289 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1291 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1294 if (preempt_count
== 1)
1296 #ifdef EMACS_OUTQSIZE
1297 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1298 /* Probably not a tty. Ignore the error and reset
1299 * the outq count. */
1300 outq
= PENDING_OUTPUT_COUNT (stdout
);
1303 if (baud_rate
<= outq
&& baud_rate
> 0)
1304 sleep (outq
/ baud_rate
);
1307 if ((i
- 1) % preempt_count
== 0)
1308 detect_input_pending ();
1312 #ifdef HAVE_X_WINDOWS
1315 current_frame
->top_left_y
[i
] = downto
;
1316 current_frame
->top_left_x
[i
] = leftmost
;
1318 #endif /* HAVE_X_WINDOWS */
1321 #ifdef HAVE_X_WINDOWS
1323 downto
+= current_frame
->pix_height
[i
];
1326 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1328 /* Now just clean up termcap drivers and set cursor, etc. */
1331 if ((cursor_in_echo_area
1332 /* If we are showing a message instead of the minibuffer,
1333 show the cursor for the message instead of for the
1334 (now hidden) minibuffer contents. */
1335 || (EQ (minibuf_window
, selected_window
)
1336 && EQ (minibuf_window
, echo_area_window
)
1337 && echo_area_glyphs
!= 0))
1338 /* These cases apply only to the frame that contains
1339 the active minibuffer window. */
1340 && FRAME_HAS_MINIBUF_P (f
)
1341 && EQ (FRAME_MINIBUF_WINDOW (f
), minibuf_window
))
1343 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1346 if (cursor_in_echo_area
< 0)
1353 /* If the minibuffer is several lines high, find the last
1354 line that has any text on it. */
1355 row
= FRAME_HEIGHT (f
);
1359 if (current_frame
->enable
[row
])
1360 col
= current_frame
->used
[row
];
1364 while (row
> top
&& col
== 0);
1366 if (col
>= FRAME_WIDTH (f
))
1369 if (row
< FRAME_HEIGHT (f
) - 1)
1374 cursor_to (row
, col
);
1377 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1378 FRAME_WIDTH (f
) - 1), 0));
1384 fflush (termscript
);
1387 /* Here if output is preempted because input is detected. */
1390 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1391 display_completed
= !pause
;
1393 bzero (FRAME_DESIRED_GLYPHS (f
)->enable
, FRAME_HEIGHT (f
));
1397 /* Called when about to quit, to check for doing so
1398 at an improper time. */
1403 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1405 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1407 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1411 /* Decide what insert/delete line to do, and do it */
1413 extern void scrolling_1 ();
1418 int unchanged_at_top
, unchanged_at_bottom
;
1421 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1422 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1423 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1424 int *old_draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1426 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1427 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1428 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1430 /* Compute hash codes of all the lines.
1431 Also calculate number of changed lines,
1432 number of unchanged lines at the beginning,
1433 and number of unchanged lines at the end. */
1436 unchanged_at_top
= 0;
1437 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1438 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1440 /* Give up on this scrolling if some old lines are not enabled. */
1441 if (!current_frame
->enable
[i
])
1443 old_hash
[i
] = line_hash_code (current_frame
, i
);
1444 if (! desired_frame
->enable
[i
])
1445 new_hash
[i
] = old_hash
[i
];
1447 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1449 if (old_hash
[i
] != new_hash
[i
])
1452 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1454 else if (i
== unchanged_at_top
)
1456 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1457 old_draw_cost
[i
] = line_draw_cost (current_frame
, i
);
1460 /* If changed lines are few, don't allow preemption, don't scroll. */
1461 if (!scroll_region_ok
&& changed_lines
< baud_rate
/ 2400
1462 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1465 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1466 - unchanged_at_bottom
);
1468 if (scroll_region_ok
)
1469 free_at_end_vpos
-= unchanged_at_bottom
;
1470 else if (memory_below_frame
)
1471 free_at_end_vpos
= -1;
1473 /* If large window, fast terminal and few lines in common between
1474 current frame and desired frame, don't bother with i/d calc. */
1475 if (!scroll_region_ok
&& window_size
>= 18 && baud_rate
> 2400
1477 10 * scrolling_max_lines_saved (unchanged_at_top
,
1478 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1479 old_hash
, new_hash
, draw_cost
)))
1482 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1483 draw_cost
+ unchanged_at_top
- 1,
1484 old_draw_cost
+ unchanged_at_top
- 1,
1485 old_hash
+ unchanged_at_top
- 1,
1486 new_hash
+ unchanged_at_top
- 1,
1487 free_at_end_vpos
- unchanged_at_top
);
1492 /* Return the offset in its buffer of the character at location col, line
1493 in the given window. */
1495 buffer_posn_from_coords (window
, col
, line
)
1496 struct window
*window
;
1499 int hscroll
= XINT (window
->hscroll
);
1500 int window_left
= XFASTINT (window
->left
);
1502 /* The actual width of the window is window->width less one for the
1503 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1505 int window_width
= window_internal_width (window
) - 1;
1507 int startp
= marker_position (window
->start
);
1509 /* Since compute_motion will only operate on the current buffer,
1510 we need to save the old one and restore it when we're done. */
1511 struct buffer
*old_current_buffer
= current_buffer
;
1512 struct position
*posn
;
1514 current_buffer
= XBUFFER (window
->buffer
);
1516 /* We can't get a correct result in this case,
1517 but at least prevent compute_motion from crashing. */
1521 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1522 (window->frame))->bufp to avoid scanning from the very top of
1523 the window, but it isn't maintained correctly, and I'm not even
1524 sure I will keep it. */
1525 posn
= compute_motion (startp
, 0,
1526 ((window
== XWINDOW (minibuf_window
) && startp
== BEG
1527 ? minibuf_prompt_width
: 0)
1528 + (hscroll
? 1 - hscroll
: 0)),
1531 window_width
, hscroll
, 0, window
);
1533 current_buffer
= old_current_buffer
;
1535 /* compute_motion considers frame points past the end of a line
1536 to be *after* the newline, i.e. at the start of the next line.
1537 This is reasonable, but not really what we want. So if the
1538 result is on a line below LINE, back it up one character. */
1539 if (posn
->vpos
> line
)
1540 return posn
->bufpos
- 1;
1542 return posn
->bufpos
;
1549 register GLYPH
*p
= r
;
1550 while (*p
++ == SPACEGLYPH
);
1555 count_match (str1
, str2
)
1558 register GLYPH
*p1
= str1
;
1559 register GLYPH
*p2
= str2
;
1560 while (*p1
++ == *p2
++);
1561 return p1
- str1
- 1;
1564 /* Char insertion/deletion cost vector, from term.c */
1565 extern int *char_ins_del_vector
;
1567 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1570 update_line (frame
, vpos
)
1571 register FRAME_PTR frame
;
1574 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1577 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1579 register struct frame_glyphs
*current_frame
1580 = FRAME_CURRENT_GLYPHS (frame
);
1581 register struct frame_glyphs
*desired_frame
1582 = FRAME_DESIRED_GLYPHS (frame
);
1584 if (desired_frame
->highlight
[vpos
]
1585 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1587 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1588 (current_frame
->enable
[vpos
] ?
1589 current_frame
->used
[vpos
] : 0));
1590 current_frame
->enable
[vpos
] = 0;
1593 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1595 if (! current_frame
->enable
[vpos
])
1601 obody
= current_frame
->glyphs
[vpos
];
1602 olen
= current_frame
->used
[vpos
];
1603 if (! current_frame
->highlight
[vpos
])
1605 if (!must_write_spaces
)
1606 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1611 /* For an inverse-video line, remember we gave it
1612 spaces all the way to the frame edge
1613 so that the reverse video extends all the way across. */
1615 while (olen
< FRAME_WIDTH (frame
) - 1)
1616 obody
[olen
++] = SPACEGLYPH
;
1620 /* One way or another, this will enable the line being updated. */
1621 current_frame
->enable
[vpos
] = 1;
1622 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1623 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1624 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1626 #ifdef HAVE_X_WINDOWS
1627 if (FRAME_X_P (frame
))
1629 current_frame
->pix_width
[vpos
]
1630 = current_frame
->used
[vpos
]
1631 * FONT_WIDTH (frame
->output_data
.x
->font
);
1632 current_frame
->pix_height
[vpos
]
1633 = frame
->output_data
.x
->line_height
;
1635 #endif /* HAVE_X_WINDOWS */
1637 if (!desired_frame
->enable
[vpos
])
1643 nbody
= desired_frame
->glyphs
[vpos
];
1644 nlen
= desired_frame
->used
[vpos
];
1646 /* Pretend trailing spaces are not there at all,
1647 unless for one reason or another we must write all spaces. */
1648 if (! desired_frame
->highlight
[vpos
])
1650 if (!must_write_spaces
)
1651 /* We know that the previous character byte contains 0. */
1652 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1657 /* For an inverse-video line, give it extra trailing spaces
1658 all the way to the frame edge
1659 so that the reverse video extends all the way across. */
1661 while (nlen
< FRAME_WIDTH (frame
) - 1)
1662 nbody
[nlen
++] = SPACEGLYPH
;
1665 /* If there's no i/d char, quickly do the best we can without it. */
1666 if (!char_ins_del_ok
)
1671 if (FRAME_X_P (frame
))
1673 /* Under X, erase everything we are going to rewrite,
1674 and rewrite everything from the first char that's changed.
1675 This is part of supporting fonts like Courier
1676 whose chars can overlap outside the char width. */
1677 for (i
= 0; i
< nlen
; i
++)
1678 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1681 cursor_to (vpos
, i
);
1683 clear_end_of_line (olen
);
1684 write_glyphs (nbody
+ i
, nlen
- i
);
1689 for (i
= 0; i
< nlen
; i
++)
1691 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1693 cursor_to (vpos
, i
);
1694 for (j
= 1; (i
+ j
< nlen
&&
1695 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1698 /* Output this run of non-matching chars. */
1699 write_glyphs (nbody
+ i
, j
);
1702 /* Now find the next non-match. */
1706 /* Clear the rest of the line, or the non-clear part of it. */
1709 cursor_to (vpos
, nlen
);
1710 clear_end_of_line (olen
);
1713 /* Exchange contents between current_frame and new_frame. */
1714 temp
= desired_frame
->glyphs
[vpos
];
1715 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1716 current_frame
->glyphs
[vpos
] = temp
;
1718 /* Exchange charstarts between current_frame and new_frame. */
1719 temp1
= desired_frame
->charstarts
[vpos
];
1720 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1721 current_frame
->charstarts
[vpos
] = temp1
;
1728 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1729 ? 0 : count_blanks (nbody
);
1732 cursor_to (vpos
, nsp
);
1733 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1736 /* Exchange contents between current_frame and new_frame. */
1737 temp
= desired_frame
->glyphs
[vpos
];
1738 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1739 current_frame
->glyphs
[vpos
] = temp
;
1741 /* Exchange charstarts between current_frame and new_frame. */
1742 temp1
= desired_frame
->charstarts
[vpos
];
1743 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1744 current_frame
->charstarts
[vpos
] = temp1
;
1753 /* Compute number of leading blanks in old and new contents. */
1754 osp
= count_blanks (obody
);
1755 if (!desired_frame
->highlight
[vpos
])
1756 nsp
= count_blanks (nbody
);
1760 /* Compute number of matching chars starting with first nonblank. */
1761 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1763 /* Spaces in new match implicit space past the end of old. */
1764 /* A bug causing this to be a no-op was fixed in 18.29. */
1765 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1768 while (np1
[begmatch
] == SPACEGLYPH
)
1772 /* Avoid doing insert/delete char
1773 just cause number of leading spaces differs
1774 when the following text does not match. */
1775 if (begmatch
== 0 && osp
!= nsp
)
1776 osp
= nsp
= min (osp
, nsp
);
1778 /* Find matching characters at end of line */
1781 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1782 while (op1
> op2
&& op1
[-1] == np1
[-1])
1787 endmatch
= obody
+ olen
- op1
;
1789 /* Put correct value back in nbody[nlen].
1790 This is important because direct_output_for_insert
1791 can write into the line at a later point.
1792 If this screws up the zero at the end of the line, re-establish it. */
1796 /* tem gets the distance to insert or delete.
1797 endmatch is how many characters we save by doing so.
1800 tem
= (nlen
- nsp
) - (olen
- osp
);
1802 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1805 /* nsp - osp is the distance to insert or delete.
1806 If that is nonzero, begmatch is known to be nonzero also.
1807 begmatch + endmatch is how much we save by doing the ins/del.
1811 && (!char_ins_del_ok
1812 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1816 osp
= nsp
= min (osp
, nsp
);
1819 /* Now go through the line, inserting, writing and
1820 deleting as appropriate. */
1824 cursor_to (vpos
, nsp
);
1825 delete_glyphs (osp
- nsp
);
1829 /* If going to delete chars later in line
1830 and insert earlier in the line,
1831 must delete first to avoid losing data in the insert */
1832 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1834 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1835 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1836 olen
= nlen
- (nsp
- osp
);
1838 cursor_to (vpos
, osp
);
1839 insert_glyphs ((char *)0, nsp
- osp
);
1843 tem
= nsp
+ begmatch
+ endmatch
;
1844 if (nlen
!= tem
|| olen
!= tem
)
1846 cursor_to (vpos
, nsp
+ begmatch
);
1847 if (!endmatch
|| nlen
== olen
)
1849 /* If new text being written reaches right margin,
1850 there is no need to do clear-to-eol at the end.
1851 (and it would not be safe, since cursor is not
1852 going to be "at the margin" after the text is done) */
1853 if (nlen
== FRAME_WIDTH (frame
))
1855 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1859 /* the following code loses disastrously if tem == nlen.
1860 Rather than trying to fix that case, I am trying the simpler
1861 solution found above. */
1863 /* If the text reaches to the right margin,
1864 it will lose one way or another (depending on AutoWrap)
1865 to clear to end of line after outputting all the text.
1866 So pause with one character to go and clear the line then. */
1867 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1869 /* endmatch must be zero, and tem must equal nsp + begmatch */
1870 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1871 clear_end_of_line (olen
);
1872 olen
= 0; /* Don't let it be cleared again later */
1873 write_glyphs (nbody
+ nlen
- 1, 1);
1876 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1877 #endif /* OBSOLETE */
1880 else if (nlen
> olen
)
1882 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1883 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1886 else if (olen
> nlen
)
1888 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1889 delete_glyphs (olen
- nlen
);
1895 /* If any unerased characters remain after the new line, erase them. */
1898 cursor_to (vpos
, nlen
);
1899 clear_end_of_line (olen
);
1902 /* Exchange contents between current_frame and new_frame. */
1903 temp
= desired_frame
->glyphs
[vpos
];
1904 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1905 current_frame
->glyphs
[vpos
] = temp
;
1907 /* Exchange charstarts between current_frame and new_frame. */
1908 temp1
= desired_frame
->charstarts
[vpos
];
1909 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1910 current_frame
->charstarts
[vpos
] = temp1
;
1913 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
1914 session's frames, frame names, buffers, buffer-read-only flags, and
1915 buffer-modified-flags, and a trailing sentinel (so we don't need to
1916 add length checks). */
1917 static Lisp_Object frame_and_buffer_state
;
1919 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p
,
1920 Sframe_or_buffer_changed_p
, 0, 0, 0,
1921 "Return non-nil if the frame and buffer state appears to have changed.\n\
1922 The state variable is an internal vector containing all frames and buffers,\n\
1923 aside from buffers whose names start with space,\n\
1924 along with the buffers' read-only and modified flags, which allows a fast\n\
1925 check to see whether the menu bars might need to be recomputed.\n\
1926 If this function returns non-nil, it updates the internal vector to reflect\n\
1927 the current state.\n")
1930 Lisp_Object tail
, frame
, buf
;
1934 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1935 FOR_EACH_FRAME (tail
, frame
)
1937 if (!EQ (*vecp
++, frame
))
1939 if (!EQ (*vecp
++, XFRAME (frame
)->name
))
1942 /* Check that the buffer info matches.
1943 No need to test for the end of the vector
1944 because the last element of the vector is lambda
1945 and that will always cause a mismatch. */
1946 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1948 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1949 /* Ignore buffers that aren't included in buffer lists. */
1950 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1952 if (!EQ (*vecp
++, buf
))
1954 if (!EQ (*vecp
++, XBUFFER (buf
)->read_only
))
1956 if (!EQ (*vecp
++, Fbuffer_modified_p (buf
)))
1959 /* Detect deletion of a buffer at the end of the list. */
1960 if (*vecp
== Qlambda
)
1963 /* Start with 1 so there is room for at least one lambda at the end. */
1965 FOR_EACH_FRAME (tail
, frame
)
1967 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1969 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
1970 if (n
> XVECTOR (frame_and_buffer_state
)->size
1971 || n
+ 20 < XVECTOR (frame_and_buffer_state
)->size
/ 2)
1972 /* Add 20 extra so we grow it less often. */
1973 frame_and_buffer_state
= Fmake_vector (make_number (n
+ 20), Qlambda
);
1974 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1975 FOR_EACH_FRAME (tail
, frame
)
1978 *vecp
++ = XFRAME (frame
)->name
;
1980 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1982 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1983 /* Ignore buffers that aren't included in buffer lists. */
1984 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1987 *vecp
++ = XBUFFER (buf
)->read_only
;
1988 *vecp
++ = Fbuffer_modified_p (buf
);
1990 /* Fill up the vector with lambdas (always at least one). */
1992 while (vecp
- XVECTOR (frame_and_buffer_state
)->contents
1993 < XVECTOR (frame_and_buffer_state
)->size
)
1995 /* Make sure we didn't overflow the vector. */
1996 if (vecp
- XVECTOR (frame_and_buffer_state
)->contents
1997 > XVECTOR (frame_and_buffer_state
)->size
)
2002 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
2003 1, 1, "FOpen termscript file: ",
2004 "Start writing all terminal output to FILE as well as the terminal.\n\
2005 FILE = nil means just close any termscript file currently open.")
2009 if (termscript
!= 0) fclose (termscript
);
2014 file
= Fexpand_file_name (file
, Qnil
);
2015 termscript
= fopen (XSTRING (file
)->data
, "w");
2016 if (termscript
== 0)
2017 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
2025 window_change_signal (signalnum
) /* If we don't have an argument, */
2026 int signalnum
; /* some compilers complain in signal calls. */
2030 int old_errno
= errno
;
2032 get_frame_size (&width
, &height
);
2034 /* The frame size change obviously applies to a termcap-controlled
2035 frame. Find such a frame in the list, and assume it's the only
2036 one (since the redisplay code always writes to stdout, not a
2037 FILE * specified in the frame structure). Record the new size,
2038 but don't reallocate the data structures now. Let that be done
2039 later outside of the signal handler. */
2042 Lisp_Object tail
, frame
;
2044 FOR_EACH_FRAME (tail
, frame
)
2046 if (FRAME_TERMCAP_P (XFRAME (frame
)))
2048 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
2054 signal (SIGWINCH
, window_change_signal
);
2057 #endif /* SIGWINCH */
2060 /* Do any change in frame size that was requested by a signal. */
2062 do_pending_window_change ()
2064 /* If window_change_signal should have run before, run it now. */
2065 while (delayed_size_change
)
2067 Lisp_Object tail
, frame
;
2069 delayed_size_change
= 0;
2071 FOR_EACH_FRAME (tail
, frame
)
2073 FRAME_PTR f
= XFRAME (frame
);
2075 int height
= FRAME_NEW_HEIGHT (f
);
2076 int width
= FRAME_NEW_WIDTH (f
);
2078 if (height
!= 0 || width
!= 0)
2079 change_frame_size (f
, height
, width
, 0, 0);
2085 /* Change the frame height and/or width. Values may be given as zero to
2086 indicate no change is to take place.
2088 If DELAY is non-zero, then assume we're being called from a signal
2089 handler, and queue the change for later - perhaps the next
2090 redisplay. Since this tries to resize windows, we can't call it
2091 from a signal handler. */
2093 change_frame_size (f
, newheight
, newwidth
, pretend
, delay
)
2094 register FRAME_PTR f
;
2095 int newheight
, newwidth
, pretend
;
2097 Lisp_Object tail
, frame
;
2098 if (FRAME_TERMCAP_P (f
))
2100 /* When using termcap, all frames use the same screen,
2101 so a change in size affects all termcap frames. */
2102 FOR_EACH_FRAME (tail
, frame
)
2103 if (FRAME_TERMCAP_P (XFRAME (frame
)))
2104 change_frame_size_1 (XFRAME (frame
), newheight
, newwidth
,
2108 change_frame_size_1 (f
, newheight
, newwidth
, pretend
, delay
);
2112 change_frame_size_1 (frame
, newheight
, newwidth
, pretend
, delay
)
2113 register FRAME_PTR frame
;
2114 int newheight
, newwidth
, pretend
, delay
;
2116 /* If we can't deal with the change now, queue it for later. */
2119 FRAME_NEW_HEIGHT (frame
) = newheight
;
2120 FRAME_NEW_WIDTH (frame
) = newwidth
;
2121 delayed_size_change
= 1;
2125 /* This size-change overrides any pending one for this frame. */
2126 FRAME_NEW_HEIGHT (frame
) = 0;
2127 FRAME_NEW_WIDTH (frame
) = 0;
2129 /* If an argument is zero, set it to the current value. */
2130 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
2131 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
2133 /* Round up to the smallest acceptable size. */
2134 check_frame_size (frame
, &newheight
, &newwidth
);
2136 /* If we're not changing the frame size, quit now. */
2137 if (newheight
== FRAME_HEIGHT (frame
)
2138 && newwidth
== FRAME_WIDTH (frame
))
2141 if (newheight
!= FRAME_HEIGHT (frame
))
2143 if (FRAME_HAS_MINIBUF_P (frame
)
2144 && ! FRAME_MINIBUF_ONLY_P (frame
))
2146 /* Frame has both root and minibuffer. */
2147 set_window_height (FRAME_ROOT_WINDOW (frame
),
2148 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
2149 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
,
2151 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
2154 /* Frame has just one top-level window. */
2155 set_window_height (FRAME_ROOT_WINDOW (frame
),
2156 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
2158 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2159 FrameRows
= newheight
;
2162 if (frame
->output_method
== output_termcap
)
2164 frame_height
= newheight
;
2166 FrameRows
= newheight
;
2171 if (newwidth
!= FRAME_WIDTH (frame
))
2173 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
2174 if (FRAME_HAS_MINIBUF_P (frame
))
2175 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
2177 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2178 FrameCols
= newwidth
;
2180 if (frame
->output_method
== output_termcap
)
2182 frame_width
= newwidth
;
2184 FrameCols
= newwidth
;
2189 FRAME_HEIGHT (frame
) = newheight
;
2190 FRAME_WIDTH (frame
) = newwidth
;
2192 if (FRAME_CURSOR_X (frame
) >= FRAME_WIDTH (frame
))
2193 FRAME_CURSOR_X (frame
) = FRAME_WIDTH (frame
) - 1;
2194 if (FRAME_CURSOR_Y (frame
) >= FRAME_HEIGHT (frame
))
2195 FRAME_CURSOR_Y (frame
) = FRAME_HEIGHT (frame
) - 1;
2197 remake_frame_glyphs (frame
);
2198 calculate_costs (frame
);
2201 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
2202 Ssend_string_to_terminal
, 1, 1, 0,
2203 "Send STRING to the terminal without alteration.\n\
2204 Control characters in STRING will have terminal-dependent effects.")
2208 CHECK_STRING (str
, 0);
2209 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
2213 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
2214 fflush (termscript
);
2219 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
2220 "Beep, or flash the screen.\n\
2221 Also, unless an argument is given,\n\
2222 terminate any keyboard macro currently executing.")
2244 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
2245 error ("Keyboard macro terminated by a command ringing the bell");
2251 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
2252 "Pause, without updating display, for SECONDS seconds.\n\
2253 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2254 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2255 additional wait period, in milliseconds; this may be useful if your\n\
2256 Emacs was built without floating point support.\n\
2257 \(Not all operating systems support waiting for a fraction of a second.)")
2258 (seconds
, milliseconds
)
2259 Lisp_Object seconds
, milliseconds
;
2263 if (NILP (milliseconds
))
2264 XSETINT (milliseconds
, 0);
2266 CHECK_NUMBER (milliseconds
, 1);
2267 usec
= XINT (milliseconds
) * 1000;
2269 #ifdef LISP_FLOAT_TYPE
2271 double duration
= extract_float (seconds
);
2272 sec
= (int) duration
;
2273 usec
+= (duration
- sec
) * 1000000;
2276 CHECK_NUMBER (seconds
, 0);
2277 sec
= XINT (seconds
);
2280 #ifndef EMACS_HAS_USECS
2281 if (sec
== 0 && usec
!= 0)
2282 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2285 /* Assure that 0 <= usec < 1000000. */
2288 /* We can't rely on the rounding being correct if user is negative. */
2289 if (-1000000 < usec
)
2290 sec
--, usec
+= 1000000;
2292 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2295 sec
+= usec
/ 1000000, usec
%= 1000000;
2303 XSETFASTINT (zero
, 0);
2304 wait_reading_process_input (sec
, usec
, zero
, 0);
2307 /* We should always have wait_reading_process_input; we have a dummy
2308 implementation for systems which don't support subprocesses. */
2310 /* No wait_reading_process_input */
2317 /* The reason this is done this way
2318 (rather than defined (H_S) && defined (H_T))
2319 is because the VMS preprocessor doesn't grok `defined' */
2321 EMACS_GET_TIME (end_time
);
2322 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2323 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2327 EMACS_GET_TIME (timeout
);
2328 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2329 if (EMACS_TIME_NEG_P (timeout
)
2330 || !select (1, 0, 0, 0, &timeout
))
2333 #else /* not HAVE_SELECT */
2335 #endif /* HAVE_SELECT */
2336 #endif /* not VMS */
2339 #endif /* no subprocesses */
2344 /* This is just like wait_reading_process_input, except that
2345 it does the redisplay.
2347 It's also much like Fsit_for, except that it can be used for
2348 waiting for input as well. */
2351 sit_for (sec
, usec
, reading
, display
)
2352 int sec
, usec
, reading
, display
;
2354 Lisp_Object read_kbd
;
2356 if (detect_input_pending ())
2360 redisplay_preserve_echo_area ();
2362 if (sec
== 0 && usec
== 0)
2369 XSETINT (read_kbd
, reading
? -1 : 1);
2370 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2373 /* wait_reading_process_input should always be available now; it is
2374 simulated in a simple way on systems that don't support
2377 /* No wait_reading_process_input available. */
2383 input_wait_timeout (XINT (arg
));
2385 #ifndef HAVE_TIMEVAL
2387 select (1, &waitchannels
, 0, 0, &timeout_sec
);
2388 #else /* HAVE_TIMEVAL */
2389 timeout
.tv_sec
= sec
;
2390 timeout
.tv_usec
= usec
;
2391 select (1, &waitchannels
, 0, 0, &timeout
);
2392 #endif /* HAVE_TIMEVAL */
2393 #endif /* not VMS */
2398 return detect_input_pending () ? Qnil
: Qt
;
2401 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2402 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2403 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2404 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2405 additional wait period, in milliseconds; this may be useful if your\n\
2406 Emacs was built without floating point support.\n\
2407 \(Not all operating systems support waiting for a fraction of a second.)\n\
2408 Optional third arg non-nil means don't redisplay, just wait for input.\n\
2409 Redisplay is preempted as always if input arrives, and does not happen\n\
2410 if input is available before it starts.\n\
2411 Value is t if waited the full time with no input arriving.")
2412 (seconds
, milliseconds
, nodisp
)
2413 Lisp_Object seconds
, milliseconds
, nodisp
;
2417 if (NILP (milliseconds
))
2418 XSETINT (milliseconds
, 0);
2420 CHECK_NUMBER (milliseconds
, 1);
2421 usec
= XINT (milliseconds
) * 1000;
2423 #ifdef LISP_FLOAT_TYPE
2425 double duration
= extract_float (seconds
);
2426 sec
= (int) duration
;
2427 usec
+= (duration
- sec
) * 1000000;
2430 CHECK_NUMBER (seconds
, 0);
2431 sec
= XINT (seconds
);
2434 #ifndef EMACS_HAS_USECS
2435 if (usec
!= 0 && sec
== 0)
2436 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2439 return sit_for (sec
, usec
, 0, NILP (nodisp
));
2442 char *terminal_type
;
2444 /* Initialization done when Emacs fork is started, before doing stty. */
2445 /* Determine terminal type and set terminal_driver */
2446 /* Then invoke its decoding routine to set up variables
2447 in the terminal package */
2451 #ifdef HAVE_X_WINDOWS
2452 extern int display_arg
;
2457 cursor_in_echo_area
= 0;
2458 terminal_type
= (char *) 0;
2460 /* Now is the time to initialize this; it's used by init_sys_modes
2462 Vwindow_system
= Qnil
;
2464 /* If the user wants to use a window system, we shouldn't bother
2465 initializing the terminal. This is especially important when the
2466 terminal is so dumb that emacs gives up before and doesn't bother
2467 using the window system.
2469 If the DISPLAY environment variable is set, try to use X, and die
2470 with an error message if that doesn't work. */
2472 #ifdef HAVE_X_WINDOWS
2476 display_arg
= (getenv ("DECW$DISPLAY") != 0);
2478 display_arg
= (getenv ("DISPLAY") != 0);
2482 if (!inhibit_window_system
&& display_arg
)
2484 Vwindow_system
= intern ("x");
2486 Vwindow_system_version
= make_number (11);
2488 Vwindow_system_version
= make_number (10);
2492 #endif /* HAVE_X_WINDOWS */
2494 /* If no window system has been specified, try to use the terminal. */
2497 fprintf (stderr
, "emacs: standard input is not a tty\n");
2501 /* Look at the TERM variable */
2502 terminal_type
= (char *) getenv ("TERM");
2506 fprintf (stderr
, "Please specify your terminal type.\n\
2507 For types defined in VMS, use set term /device=TYPE.\n\
2508 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2509 \(The quotation marks are necessary since terminal types are lower case.)\n");
2511 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2517 /* VMS DCL tends to upcase things, so downcase term type.
2518 Hardly any uppercase letters in terminal types; should be none. */
2520 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2523 strcpy (new, terminal_type
);
2525 for (p
= new; *p
; p
++)
2529 terminal_type
= new;
2533 term_init (terminal_type
);
2535 remake_frame_glyphs (selected_frame
);
2536 calculate_costs (selected_frame
);
2538 /* X and Y coordinates of the cursor between updates. */
2539 FRAME_CURSOR_X (selected_frame
) = 0;
2540 FRAME_CURSOR_Y (selected_frame
) = 0;
2545 #endif /* CANNOT_DUMP */
2546 signal (SIGWINCH
, window_change_signal
);
2547 #endif /* SIGWINCH */
2553 defsubr (&Sredraw_frame
);
2555 defsubr (&Sredraw_display
);
2556 defsubr (&Sframe_or_buffer_changed_p
);
2557 defsubr (&Sopen_termscript
);
2559 defsubr (&Ssit_for
);
2560 defsubr (&Ssleep_for
);
2561 defsubr (&Ssend_string_to_terminal
);
2563 frame_and_buffer_state
= Fmake_vector (make_number (20), Qlambda
);
2564 staticpro (&frame_and_buffer_state
);
2566 DEFVAR_INT ("baud-rate", &baud_rate
,
2567 "*The output baud rate of the terminal.\n\
2568 On most systems, changing this value will affect the amount of padding\n\
2569 and the other strategic decisions made during redisplay.");
2570 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2571 "*Non-nil means invert the entire frame display.\n\
2572 This means everything is in inverse video which otherwise would not be.");
2573 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2574 "*Non-nil means try to flash the frame to represent a bell.");
2575 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2576 "*Non-nil means no need to redraw entire frame after suspending.\n\
2577 A non-nil value is useful if the terminal can automatically preserve\n\
2578 Emacs's frame display when you reenter Emacs.\n\
2579 It is up to you to set this variable if your terminal can do that.");
2580 DEFVAR_LISP ("window-system", &Vwindow_system
,
2581 "A symbol naming the window-system under which Emacs is running\n\
2582 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2583 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2584 "The version number of the window system in use.\n\
2585 For X windows, this is 10 or 11.");
2586 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2587 "Non-nil means put cursor in minibuffer, at end of any message there.");
2588 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2589 "Table defining how to output a glyph code to the frame.\n\
2590 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2591 Each element can be:\n\
2592 integer: a glyph code which this glyph is an alias for.\n\
2593 string: output this glyph using that string (not impl. in X windows).\n\
2594 nil: this glyph mod 256 is char code to output,\n\
2595 and this glyph / 256 is face code for X windows (see `face-id').");
2596 Vglyph_table
= Qnil
;
2598 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2599 "Display table to use for buffers that specify none.\n\
2600 See `buffer-display-table' for more information.");
2601 Vstandard_display_table
= Qnil
;
2603 /* Initialize `window-system', unless init_display already decided it. */
2608 Vwindow_system
= Qnil
;
2609 Vwindow_system_version
= Qnil
;