1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 1998
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
37 #include "termhooks.h"
38 /* cm.h must come after dispextern.h on Windows. */
39 #include "dispextern.h"
48 #include "intervals.h"
49 #include "blockinput.h"
53 /* I don't know why DEC Alpha OSF1 fail to compile this file if we
54 include the following file. */
55 /* #include "systty.h" */
56 #include "syssignal.h"
60 #endif /* HAVE_X_WINDOWS */
64 #endif /* HAVE_NTGUI */
66 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
71 #define max(a, b) ((a) > (b) ? (a) : (b))
72 #define min(a, b) ((a) < (b) ? (a) : (b))
73 #define minmax(floor, val, ceil) \
74 ((val) < (floor) ? (floor) : (val) > (ceil) ? (ceil) : (val))
76 /* Get number of chars of output now in the buffer of a stdio stream.
77 This ought to be built in in stdio, but it isn't.
78 Some s- files override this because their stdio internals differ. */
79 #ifdef __GNU_LIBRARY__
80 /* The s- file might have overridden the definition with one that works for
81 the system's C library. But we are using the GNU C library, so this is
82 the right definition for every system. */
83 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
84 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
86 #undef PENDING_OUTPUT_COUNT
87 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
89 #else /* not __GNU_LIBRARY__ */
90 #ifndef PENDING_OUTPUT_COUNT
91 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
95 static void change_frame_size_1 ();
97 /* Nonzero upon entry to redisplay means do not assume anything about
98 current contents of actual terminal frame; clear and redraw it. */
102 /* Nonzero means last display completed. Zero means it was preempted. */
104 int display_completed
;
106 /* Lisp variable visible-bell; enables use of screen-flash
107 instead of audible bell. */
111 /* Invert the color of the whole frame, at a low level. */
115 /* Line speed of the terminal. */
119 /* nil or a symbol naming the window system under which emacs is
120 running ('x is the only current possibility). */
122 Lisp_Object Vwindow_system
;
124 /* Version number of X windows: 10, 11 or nil. */
125 Lisp_Object Vwindow_system_version
;
127 /* Vector of glyph definitions. Indexed by glyph number,
128 the contents are a string which is how to output the glyph.
130 If Vglyph_table is nil, a glyph is output by using its low 8 bits
131 as a character code. */
133 Lisp_Object Vglyph_table
;
135 /* Display table to use for vectors that don't specify their own. */
137 Lisp_Object Vstandard_display_table
;
139 /* Nonzero means reading single-character input with prompt
140 so put cursor on minibuffer after the prompt.
141 positive means at end of text in echo area;
142 negative means at beginning of line. */
143 int cursor_in_echo_area
;
145 Lisp_Object Qdisplay_table
;
147 /* The currently selected frame.
148 In a single-frame version, this variable always holds the address of
151 FRAME_PTR selected_frame
;
153 /* A frame which is not just a minibuffer, or 0 if there are no such
154 frames. This is usually the most recent such frame that was
155 selected. In a single-frame version, this variable always holds
156 the address of the_only_frame. */
157 FRAME_PTR last_nonminibuf_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 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
172 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
173 "Clear frame FRAME and output again what is supposed to appear on it.")
179 CHECK_LIVE_FRAME (frame
, 0);
182 /* Erase the frame and its glyph records--if it has any records.
183 It may have none, in the case of the terminal frame
184 that initially exists but is never used
185 when Emacs is using a window system. */
186 if (FRAME_CURRENT_GLYPHS (f
) != 0)
189 if (FRAME_MSDOS_P (f
))
190 set_terminal_modes ();
192 clear_frame_records (f
);
197 windows_or_buffers_changed
++;
198 /* Mark all windows as INaccurate,
199 so that every window will have its redisplay done. */
200 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
210 XSETFRAME (frame
, f
);
211 Fredraw_frame (frame
);
214 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
215 "Clear and redisplay all visible frames.")
218 Lisp_Object tail
, frame
;
220 FOR_EACH_FRAME (tail
, frame
)
221 if (FRAME_VISIBLE_P (XFRAME (frame
)))
222 Fredraw_frame (frame
);
227 /* This is used when frame_garbaged is set.
228 Redraw the individual frames marked as garbaged. */
231 redraw_garbaged_frames ()
233 Lisp_Object tail
, frame
;
235 FOR_EACH_FRAME (tail
, frame
)
236 if (FRAME_VISIBLE_P (XFRAME (frame
))
237 && FRAME_GARBAGED_P (XFRAME (frame
)))
238 Fredraw_frame (frame
);
242 static struct frame_glyphs
*
243 make_frame_glyphs (frame
, empty
)
244 register FRAME_PTR frame
;
248 register int width
= FRAME_WINDOW_WIDTH (frame
);
249 register int height
= FRAME_HEIGHT (frame
);
250 register struct frame_glyphs
*new
251 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
253 SET_GLYPHS_FRAME (new, frame
);
254 new->height
= height
;
256 new->used
= (int *) xmalloc (height
* sizeof (int));
257 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
258 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
259 new->highlight
= (char *) xmalloc (height
* sizeof (char));
260 new->enable
= (char *) xmalloc (height
* sizeof (char));
261 bzero (new->enable
, height
* sizeof (char));
262 new->bufp
= (int *) xmalloc (height
* sizeof (int));
264 #ifdef HAVE_WINDOW_SYSTEM
265 if (FRAME_WINDOW_P (frame
))
267 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
268 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
269 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
270 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
271 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
273 #endif /* HAVE_WINDOW_SYSTEM */
277 /* Make the buffer used by decode_mode_spec. This buffer is also
278 used as temporary storage when updating the frame. See scroll.c. */
279 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
280 unsigned int total_charstarts
= (width
+ 2) * sizeof (int);
282 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
283 bzero (new->total_contents
, total_glyphs
);
285 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
286 bzero (new->total_charstarts
, total_charstarts
);
290 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
292 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
293 bzero (new->total_contents
, total_glyphs
);
294 for (i
= 0; i
< height
; i
++)
295 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
297 if (!FRAME_TERMCAP_P (frame
))
299 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
301 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
302 bzero (new->total_charstarts
, total_charstarts
);
303 for (i
= 0; i
< height
; i
++)
304 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
308 /* Without a window system, we don't really need charstarts.
309 So use a small amount of space to make enough data structure
310 to prevent crashes in display_text_line. */
311 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
312 for (i
= 0; i
< height
; i
++)
313 new->charstarts
[i
] = new->total_charstarts
;
321 free_frame_glyphs (frame
, glyphs
)
323 struct frame_glyphs
*glyphs
;
325 if (glyphs
->total_contents
)
326 xfree (glyphs
->total_contents
);
327 if (glyphs
->total_charstarts
)
328 xfree (glyphs
->total_charstarts
);
330 xfree (glyphs
->used
);
331 xfree (glyphs
->glyphs
);
332 xfree (glyphs
->highlight
);
333 xfree (glyphs
->enable
);
334 xfree (glyphs
->bufp
);
335 if (glyphs
->charstarts
)
336 xfree (glyphs
->charstarts
);
338 #ifdef HAVE_WINDOW_SYSTEM
339 if (FRAME_WINDOW_P (frame
))
341 xfree (glyphs
->top_left_x
);
342 xfree (glyphs
->top_left_y
);
343 xfree (glyphs
->pix_width
);
344 xfree (glyphs
->pix_height
);
345 xfree (glyphs
->max_ascent
);
347 #endif /* HAVE_WINDOW_SYSTEM */
353 remake_frame_glyphs (frame
)
356 if (FRAME_CURRENT_GLYPHS (frame
))
357 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
358 if (FRAME_DESIRED_GLYPHS (frame
))
359 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
360 if (FRAME_TEMP_GLYPHS (frame
))
361 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
363 if (FRAME_MESSAGE_BUF (frame
))
365 /* Reallocate the frame's message buffer; remember that
366 echo_area_glyphs may be pointing here. */
367 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
369 FRAME_MESSAGE_BUF (frame
)
370 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
371 FRAME_MESSAGE_BUF_SIZE (frame
) + 1);
373 if (echo_area_glyphs
== old_message_buf
)
374 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
375 if (previous_echo_glyphs
== old_message_buf
)
376 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
379 FRAME_MESSAGE_BUF (frame
)
380 = (char *) xmalloc (FRAME_MESSAGE_BUF_SIZE (frame
) + 1);
382 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
383 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
384 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
385 if (FRAME_WINDOW_P (frame
) || frame
== selected_frame
)
386 SET_FRAME_GARBAGED (frame
);
389 /* Return the hash code of contents of line VPOS in frame-matrix M. */
392 line_hash_code (m
, vpos
)
393 register struct frame_glyphs
*m
;
396 register GLYPH
*body
, *end
;
399 if (!m
->enable
[vpos
])
402 /* Give all highlighted lines the same hash code
403 so as to encourage scrolling to leave them in place. */
404 if (m
->highlight
[vpos
])
407 body
= m
->glyphs
[vpos
];
409 if (must_write_spaces
)
416 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
425 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
433 /* Return number of characters in line in M at vpos VPOS,
434 except don't count leading and trailing spaces
435 unless the terminal requires those to be explicitly output. */
438 line_draw_cost (m
, vpos
)
439 struct frame_glyphs
*m
;
442 register GLYPH
*beg
= m
->glyphs
[vpos
];
443 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
445 register int tlen
= GLYPH_TABLE_LENGTH
;
446 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
448 /* Ignore trailing and leading spaces if we can. */
449 if (!must_write_spaces
)
451 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
454 return (0); /* All blank line. */
456 while (*beg
== SPACEGLYPH
)
460 /* If we don't have a glyph-table, each glyph is one character,
461 so return the number of glyphs. */
465 /* Otherwise, scan the glyphs and accumulate their total size in I. */
467 while ((beg
<= end
) && *beg
)
469 register GLYPH g
= *beg
++;
471 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
474 i
+= GLYPH_LENGTH (tbase
, g
);
479 /* The functions on this page are the interface from xdisp.c to redisplay.
481 The only other interface into redisplay is through setting
482 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
483 and SET_FRAME_GARBAGED (frame). */
485 /* cancel_line eliminates any request to display a line at position `vpos' */
488 cancel_line (vpos
, frame
)
490 register FRAME_PTR frame
;
492 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
496 clear_frame_records (frame
)
497 register FRAME_PTR frame
;
499 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
502 /* Clear out all display lines for a coming redisplay. */
505 init_desired_glyphs (frame
)
506 register FRAME_PTR frame
;
508 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
510 int height
= FRAME_HEIGHT (frame
);
512 for (vpos
= 0; vpos
< height
; vpos
++)
513 desired_glyphs
->enable
[vpos
] = 0;
516 /* Prepare to display on line VPOS starting at HPOS within it. */
519 get_display_line (frame
, vpos
, hpos
)
520 register FRAME_PTR frame
;
524 register struct frame_glyphs
*glyphs
;
525 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
531 if (! desired_glyphs
->enable
[vpos
])
533 desired_glyphs
->used
[vpos
] = 0;
534 desired_glyphs
->highlight
[vpos
] = 0;
535 desired_glyphs
->enable
[vpos
] = 1;
538 if (hpos
> desired_glyphs
->used
[vpos
])
540 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
541 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
543 desired_glyphs
->used
[vpos
] = hpos
;
549 /* Like bcopy except never gets confused by overlap. */
552 safe_bcopy (from
, to
, size
)
556 if (size
<= 0 || from
== to
)
559 /* If the source and destination don't overlap, then bcopy can
560 handle it. If they do overlap, but the destination is lower in
561 memory than the source, we'll assume bcopy can handle that. */
562 if (to
< from
|| from
+ size
<= to
)
563 bcopy (from
, to
, size
);
565 /* Otherwise, we'll copy from the end. */
568 register char *endf
= from
+ size
;
569 register char *endt
= to
+ size
;
571 /* If TO - FROM is large, then we should break the copy into
572 nonoverlapping chunks of TO - FROM bytes each. However, if
573 TO - FROM is small, then the bcopy function call overhead
574 makes this not worth it. The crossover point could be about
575 anywhere. Since I don't think the obvious copy loop is too
576 bad, I'm trying to err in its favor. */
581 while (endf
!= from
);
593 bcopy (endf
, endt
, to
- from
);
596 /* If SIZE wasn't a multiple of TO - FROM, there will be a
597 little left over. The amount left over is
598 (endt + (to - from)) - to, which is endt - from. */
599 bcopy (from
, to
, endt
- from
);
604 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
605 DISTANCE may be negative. */
608 rotate_vector (vector
, size
, distance
)
613 char *temp
= (char *) alloca (size
);
618 bcopy (vector
, temp
+ distance
, size
- distance
);
619 bcopy (vector
+ size
- distance
, temp
, distance
);
620 bcopy (temp
, vector
, size
);
623 /* Scroll lines from vpos FROM up to but not including vpos END
624 down by AMOUNT lines (AMOUNT may be negative).
625 Returns nonzero if done, zero if terminal cannot scroll them. */
628 scroll_frame_lines (frame
, from
, end
, amount
, newpos
)
629 register FRAME_PTR frame
;
630 int from
, end
, amount
, newpos
;
633 register struct frame_glyphs
*current_frame
634 = FRAME_CURRENT_GLYPHS (frame
);
636 int width
= FRAME_WINDOW_WIDTH (frame
);
638 if (!line_ins_del_ok
)
646 update_begin (frame
);
647 set_terminal_window (end
+ amount
);
648 if (!scroll_region_ok
)
649 ins_del_lines (end
, -amount
);
650 ins_del_lines (from
, amount
);
651 set_terminal_window (0);
653 rotate_vector (current_frame
->glyphs
+ from
,
654 sizeof (GLYPH
*) * (end
+ amount
- from
),
655 amount
* sizeof (GLYPH
*));
657 rotate_vector (current_frame
->charstarts
+ from
,
658 sizeof (int *) * (end
+ amount
- from
),
659 amount
* sizeof (int *));
661 safe_bcopy (current_frame
->used
+ from
,
662 current_frame
->used
+ from
+ amount
,
663 (end
- from
) * sizeof current_frame
->used
[0]);
665 safe_bcopy (current_frame
->highlight
+ from
,
666 current_frame
->highlight
+ from
+ amount
,
667 (end
- from
) * sizeof current_frame
->highlight
[0]);
669 safe_bcopy (current_frame
->enable
+ from
,
670 current_frame
->enable
+ from
+ amount
,
671 (end
- from
) * sizeof current_frame
->enable
[0]);
673 /* Adjust the lines by an amount
674 that puts the first of them at NEWPOS. */
675 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
677 /* Offset each char position in the charstarts lines we moved
679 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
681 int *line
= current_frame
->charstarts
[i
];
683 for (col
= 0; col
< width
; col
++)
685 line
[col
] += pos_adjust
;
687 for (i
= from
; i
< from
+ amount
; i
++)
689 int *line
= current_frame
->charstarts
[i
];
692 for (col
= 0; col
< width
; col
++)
696 /* Mark the lines made empty by scrolling as enabled, empty and
698 bzero (current_frame
->used
+ from
,
699 amount
* sizeof current_frame
->used
[0]);
700 bzero (current_frame
->highlight
+ from
,
701 amount
* sizeof current_frame
->highlight
[0]);
702 for (i
= from
; i
< from
+ amount
; i
++)
704 current_frame
->glyphs
[i
][0] = '\0';
705 current_frame
->charstarts
[i
][0] = -1;
706 current_frame
->enable
[i
] = 1;
709 safe_bcopy (current_frame
->bufp
+ from
,
710 current_frame
->bufp
+ from
+ amount
,
711 (end
- from
) * sizeof current_frame
->bufp
[0]);
713 #ifdef HAVE_WINDOW_SYSTEM
714 if (FRAME_WINDOW_P (frame
))
716 safe_bcopy (current_frame
->top_left_x
+ from
,
717 current_frame
->top_left_x
+ from
+ amount
,
718 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
720 safe_bcopy (current_frame
->top_left_y
+ from
,
721 current_frame
->top_left_y
+ from
+ amount
,
722 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
724 safe_bcopy (current_frame
->pix_width
+ from
,
725 current_frame
->pix_width
+ from
+ amount
,
726 (end
- from
) * sizeof current_frame
->pix_width
[0]);
728 safe_bcopy (current_frame
->pix_height
+ from
,
729 current_frame
->pix_height
+ from
+ amount
,
730 (end
- from
) * sizeof current_frame
->pix_height
[0]);
732 safe_bcopy (current_frame
->max_ascent
+ from
,
733 current_frame
->max_ascent
+ from
+ amount
,
734 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
736 #endif /* HAVE_WINDOW_SYSTEM */
742 update_begin (frame
);
743 set_terminal_window (end
);
744 ins_del_lines (from
+ amount
, amount
);
745 if (!scroll_region_ok
)
746 ins_del_lines (end
+ amount
, -amount
);
747 set_terminal_window (0);
749 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
750 sizeof (GLYPH
*) * (end
- from
- amount
),
751 amount
* sizeof (GLYPH
*));
753 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
754 sizeof (int *) * (end
- from
- amount
),
755 amount
* sizeof (int *));
757 safe_bcopy (current_frame
->used
+ from
,
758 current_frame
->used
+ from
+ amount
,
759 (end
- from
) * sizeof current_frame
->used
[0]);
761 safe_bcopy (current_frame
->highlight
+ from
,
762 current_frame
->highlight
+ from
+ amount
,
763 (end
- from
) * sizeof current_frame
->highlight
[0]);
765 safe_bcopy (current_frame
->enable
+ from
,
766 current_frame
->enable
+ from
+ amount
,
767 (end
- from
) * sizeof current_frame
->enable
[0]);
769 /* Adjust the lines by an amount
770 that puts the first of them at NEWPOS. */
771 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
773 /* Offset each char position in the charstarts lines we moved
775 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
777 int *line
= current_frame
->charstarts
[i
];
779 for (col
= 0; col
< width
; col
++)
781 line
[col
] += pos_adjust
;
783 for (i
= end
+ amount
; i
< end
; i
++)
785 int *line
= current_frame
->charstarts
[i
];
788 for (col
= 0; col
< width
; col
++)
792 /* Mark the lines made empty by scrolling as enabled, empty and
794 bzero (current_frame
->used
+ end
+ amount
,
795 - amount
* sizeof current_frame
->used
[0]);
796 bzero (current_frame
->highlight
+ end
+ amount
,
797 - amount
* sizeof current_frame
->highlight
[0]);
798 for (i
= end
+ amount
; i
< end
; i
++)
800 current_frame
->glyphs
[i
][0] = '\0';
801 current_frame
->charstarts
[i
][0] = 0;
802 current_frame
->enable
[i
] = 1;
805 safe_bcopy (current_frame
->bufp
+ from
,
806 current_frame
->bufp
+ from
+ amount
,
807 (end
- from
) * sizeof current_frame
->bufp
[0]);
809 #ifdef HAVE_WINDOW_SYSTEM
810 if (FRAME_WINDOW_P (frame
))
812 safe_bcopy (current_frame
->top_left_x
+ from
,
813 current_frame
->top_left_x
+ from
+ amount
,
814 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
816 safe_bcopy (current_frame
->top_left_y
+ from
,
817 current_frame
->top_left_y
+ from
+ amount
,
818 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
820 safe_bcopy (current_frame
->pix_width
+ from
,
821 current_frame
->pix_width
+ from
+ amount
,
822 (end
- from
) * sizeof current_frame
->pix_width
[0]);
824 safe_bcopy (current_frame
->pix_height
+ from
,
825 current_frame
->pix_height
+ from
+ amount
,
826 (end
- from
) * sizeof current_frame
->pix_height
[0]);
828 safe_bcopy (current_frame
->max_ascent
+ from
,
829 current_frame
->max_ascent
+ from
+ amount
,
830 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
832 #endif /* HAVE_WINDOW_SYSTEM */
839 /* After updating a window W that isn't the full frame wide,
840 copy all the columns that W does not occupy
841 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
842 so that update_frame will not change those columns. */
845 preserve_other_columns (w
)
849 register struct frame_glyphs
*current_frame
, *desired_frame
;
850 register FRAME_PTR frame
= XFRAME (w
->frame
);
851 int start
= WINDOW_LEFT_MARGIN (w
);
852 int end
= WINDOW_RIGHT_EDGE (w
);
853 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
855 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
856 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
858 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
860 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
866 bcopy (current_frame
->glyphs
[vpos
],
867 desired_frame
->glyphs
[vpos
],
868 start
* sizeof (current_frame
->glyphs
[vpos
][0]));
869 bcopy (current_frame
->charstarts
[vpos
],
870 desired_frame
->charstarts
[vpos
],
871 start
* sizeof (current_frame
->charstarts
[vpos
][0]));
872 len
= min (start
, current_frame
->used
[vpos
]);
873 if (desired_frame
->used
[vpos
] < len
)
874 desired_frame
->used
[vpos
] = len
;
876 if (current_frame
->used
[vpos
] > end
877 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
879 while (desired_frame
->used
[vpos
] < end
)
881 int used
= desired_frame
->used
[vpos
]++;
882 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
883 desired_frame
->glyphs
[vpos
][used
] = 0;
885 bcopy (current_frame
->glyphs
[vpos
] + end
,
886 desired_frame
->glyphs
[vpos
] + end
,
887 ((current_frame
->used
[vpos
] - end
)
888 * sizeof (current_frame
->glyphs
[vpos
][0])));
889 bcopy (current_frame
->charstarts
[vpos
] + end
,
890 desired_frame
->charstarts
[vpos
] + end
,
891 ((current_frame
->used
[vpos
] - end
)
892 * sizeof (current_frame
->charstarts
[vpos
][0])));
893 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
901 /* If window w does not need to be updated and isn't the full frame wide,
902 copy all the columns that w does occupy
903 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
904 so that update_frame will not change those columns.
906 Have not been able to figure out how to use this correctly. */
908 preserve_my_columns (w
)
911 register int vpos
, fin
;
912 register struct frame_glyphs
*l1
, *l2
;
913 register FRAME_PTR frame
= XFRAME (w
->frame
);
914 int start
= WINDOW_LEFT_MARGIN (w
);
915 int end
= WINDOW_RIGHT_EDGE (w
);
916 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
918 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
920 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
921 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
923 if (l2
->length
> start
&& l1
->length
< l2
->length
)
926 if (fin
> end
) fin
= end
;
927 while (l1
->length
< start
)
928 l1
->body
[l1
->length
++] = ' ';
929 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
938 /* Adjust by ADJUST the charstart values in window W
939 after vpos VPOS, which counts relative to the frame
940 (not relative to W itself). */
943 adjust_window_charstarts (w
, vpos
, adjust
)
948 int left
= WINDOW_LEFT_MARGIN (w
);
949 int top
= XFASTINT (w
->top
);
950 int right
= left
+ window_internal_width (w
);
951 int bottom
= top
+ window_internal_height (w
);
954 for (i
= vpos
+ 1; i
< bottom
; i
++)
957 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
959 for (j
= left
; j
< right
; j
++)
960 if (charstart
[j
] > 0)
961 charstart
[j
] += adjust
;
965 /* Check the charstarts values in the area of window W
966 for internal consistency. We cannot check that they are "right";
967 we can only look for something nonsensical. */
970 verify_charstarts (w
)
973 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
975 int top
= XFASTINT (w
->top
);
976 int bottom
= top
+ window_internal_height (w
);
977 int left
= WINDOW_LEFT_MARGIN (w
);
978 int right
= left
+ window_internal_width (w
);
980 int truncate
= (XINT (w
->hscroll
)
981 || (truncate_partial_width_windows
982 && !WINDOW_FULL_WIDTH_P (w
))
983 || !NILP (XBUFFER (w
->buffer
)->truncate_lines
));
985 for (i
= top
; i
< bottom
; i
++)
989 int *charstart
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[i
];
995 /* If we are truncating lines, allow a jump
996 in charstarts from one line to the next. */
997 if (charstart
[left
] < next_line
)
1002 if (charstart
[left
] != next_line
)
1007 for (j
= left
; j
< right
; j
++)
1008 if (charstart
[j
] > 0)
1009 last
= charstart
[j
];
1010 /* Record where the next line should start. */
1012 if (BUF_ZV (XBUFFER (w
->buffer
)) != last
)
1014 /* If there's a newline between the two lines, count that. */
1015 int endchar
= *BUF_CHAR_ADDRESS (XBUFFER (w
->buffer
), last
);
1016 if (endchar
== '\n')
1022 /* On discovering that the redisplay for a window was no good,
1023 cancel the columns of that window, so that when the window is
1024 displayed over again get_display_line will not complain. */
1027 cancel_my_columns (w
)
1031 register struct frame_glyphs
*desired_glyphs
1032 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
1033 register int start
= WINDOW_LEFT_MARGIN (w
);
1034 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
1036 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
1037 if (desired_glyphs
->enable
[vpos
]
1038 && desired_glyphs
->used
[vpos
] >= start
)
1039 desired_glyphs
->used
[vpos
] = start
;
1042 /* These functions try to perform directly and immediately on the frame
1043 the necessary output for one change in the buffer.
1044 They may return 0 meaning nothing was done if anything is difficult,
1045 or 1 meaning the output was performed properly.
1046 They assume that the frame was up to date before the buffer
1047 change being displayed. They make various other assumptions too;
1048 see command_loop_1 where these are called. */
1051 direct_output_for_insert (g
)
1054 register FRAME_PTR frame
= selected_frame
;
1055 register struct frame_glyphs
*current_frame
1056 = FRAME_CURRENT_GLYPHS (frame
);
1058 #ifndef COMPILER_REGISTER_BUG
1060 #endif /* COMPILER_REGISTER_BUG */
1061 struct window
*w
= XWINDOW (selected_window
);
1062 #ifndef COMPILER_REGISTER_BUG
1064 #endif /* COMPILER_REGISTER_BUG */
1065 int hpos
= FRAME_CURSOR_X (frame
);
1066 #ifndef COMPILER_REGISTER_BUG
1068 #endif /* COMPILER_REGISTER_BUG */
1069 int vpos
= FRAME_CURSOR_Y (frame
);
1071 /* Give up if about to continue line. */
1072 if (hpos
>= WINDOW_LEFT_MARGIN (w
) + window_internal_width (w
) - 1
1074 /* Avoid losing if cursor is in invisible text off left margin */
1075 || (XINT (w
->hscroll
) && hpos
== WINDOW_LEFT_MARGIN (w
))
1077 /* Give up if cursor outside window (in minibuf, probably) */
1078 || cursor_in_echo_area
1079 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
1080 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
1082 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
1083 || !display_completed
1085 /* Give up if buffer appears in two places. */
1086 || buffer_shared
> 1
1088 #ifdef USE_TEXT_PROPERTIES
1089 /* Intervals have already been adjusted, point is after the
1090 character that was just inserted. */
1091 /* Give up if character is invisible. */
1092 /* Give up if character has a face property.
1093 At the moment we only lose at end of line or end of buffer
1094 and only with faces that have some background */
1095 /* Instead of wasting time, give up if character has any text properties */
1096 || ! NILP (Ftext_properties_at (make_number (PT
- 1), Qnil
))
1099 /* Give up if w is minibuffer and a message is being displayed there */
1100 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1108 if (FRAME_WINDOW_P (frame
) || FRAME_MSDOS_P (frame
))
1109 face
= compute_char_face (frame
, w
, PT
- 1, -1, -1, &dummy
, PT
, 0);
1111 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1112 current_frame
->charstarts
[vpos
][hpos
] = PT
- 1;
1113 /* Record the entry for after the newly inserted character. */
1114 current_frame
->charstarts
[vpos
][hpos
+ 1] = PT
;
1115 adjust_window_charstarts (w
, vpos
, 1);
1117 unchanged_modified
= MODIFF
;
1118 beg_unchanged
= GPT
- BEG
;
1119 XSETFASTINT (w
->last_point
, PT
);
1120 XSETFASTINT (w
->last_point_x
, hpos
+ 1);
1121 XSETFASTINT (w
->last_modified
, MODIFF
);
1122 XSETFASTINT (w
->last_overlay_modified
, OVERLAY_MODIFF
);
1124 reassert_line_highlight (0, vpos
);
1125 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
1127 ++FRAME_CURSOR_X (frame
);
1128 if (hpos
== current_frame
->used
[vpos
])
1130 current_frame
->used
[vpos
] = hpos
+ 1;
1131 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
1138 direct_output_forward_char (n
)
1141 register FRAME_PTR frame
= selected_frame
;
1142 register struct window
*w
= XWINDOW (selected_window
);
1143 Lisp_Object position
;
1144 int hpos
= FRAME_CURSOR_X (frame
);
1146 /* Give up if in truncated text at end of line. */
1147 /* This check is not redundant. */
1148 if (hpos
>= WINDOW_LEFT_MARGIN (w
) + window_internal_width (w
) - 1)
1151 /* Give up if the buffer's direction is reversed (i.e. right-to-left). */
1152 if (!NILP (XBUFFER(w
->buffer
)->direction_reversed
))
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
) == WINDOW_LEFT_MARGIN (w
)
1158 && (XINT (w
->hscroll
) || n
< 0))
1160 && (FRAME_CURSOR_X (frame
) + 1
1161 >= XFASTINT (w
->left
) + window_internal_width (w
) - 1))
1162 /* BUG FIX: Added "XFASTINT (w->left)". Without this,
1163 direct_output_forward_char() always fails on "the right"
1165 || cursor_in_echo_area
)
1168 /* Can't use direct output if highlighting a region. */
1169 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1172 /* Can't use direct output at an overlay boundary; it might have
1173 before-string or after-string properties. */
1174 if (overlay_touches_p (PT
) || overlay_touches_p (PT
- n
))
1177 #ifdef USE_TEXT_PROPERTIES
1178 /* Don't use direct output next to an invisible character
1179 since we might need to do something special. */
1181 XSETFASTINT (position
, PT
);
1182 if (XFASTINT (position
) < ZV
1183 && ! NILP (Fget_char_property (position
,
1188 XSETFASTINT (position
, PT
- 1);
1189 if (XFASTINT (position
) >= BEGV
1190 && ! NILP (Fget_char_property (position
,
1196 FRAME_CURSOR_X (frame
) += n
;
1197 XSETFASTINT (w
->last_point_x
, FRAME_CURSOR_X (frame
));
1198 XSETFASTINT (w
->last_point
, PT
);
1199 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1205 static void update_line ();
1207 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1208 Value is nonzero if redisplay stopped due to pending input.
1209 FORCE nonzero means do not stop for pending input. */
1212 update_frame (f
, force
, inhibit_hairy_id
)
1215 int inhibit_hairy_id
;
1217 register struct frame_glyphs
*current_frame
;
1218 register struct frame_glyphs
*desired_frame
= 0;
1221 int preempt_count
= baud_rate
/ 2400 + 1;
1222 extern int input_pending
;
1223 #ifdef HAVE_WINDOW_SYSTEM
1224 register int downto
, leftmost
;
1227 if (baud_rate
!= FRAME_COST_BAUD_RATE (f
))
1228 calculate_costs (f
);
1230 if (preempt_count
<= 0)
1233 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1235 detect_input_pending ();
1236 if (input_pending
&& !force
)
1244 if (!line_ins_del_ok
)
1245 inhibit_hairy_id
= 1;
1247 /* These are separate to avoid a possible bug in the AIX C compiler. */
1248 current_frame
= FRAME_CURRENT_GLYPHS (f
);
1249 desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1251 /* See if any of the desired lines are enabled; don't compute for
1252 i/d line if just want cursor motion. */
1253 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1254 if (desired_frame
->enable
[i
])
1257 /* Try doing i/d line, if not yet inhibited. */
1258 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1259 force
|= scrolling (f
);
1261 /* Update the individual lines as needed. Do bottom line first. */
1263 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1264 update_line (f
, FRAME_HEIGHT (f
) - 1);
1266 #ifdef HAVE_WINDOW_SYSTEM
1267 if (FRAME_WINDOW_P (f
))
1269 leftmost
= downto
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1270 if (desired_frame
->enable
[0])
1272 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1273 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1274 = PIXEL_HEIGHT (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
)
1275 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1276 current_frame
->top_left_x
[0] = leftmost
;
1277 current_frame
->top_left_y
[0] = downto
;
1280 #endif /* HAVE_WINDOW_SYSTEM */
1282 /* Now update the rest of the lines. */
1283 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1285 if (desired_frame
->enable
[i
])
1287 if (FRAME_TERMCAP_P (f
))
1289 /* Flush out every so many lines.
1290 Also flush out if likely to have more than 1k buffered
1291 otherwise. I'm told that some telnet connections get
1292 really screwed by more than 1k output at once. */
1293 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1295 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1298 if (preempt_count
== 1)
1300 #ifdef EMACS_OUTQSIZE
1301 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1302 /* Probably not a tty. Ignore the error and reset
1303 * the outq count. */
1304 outq
= PENDING_OUTPUT_COUNT (stdout
);
1307 if (baud_rate
<= outq
&& baud_rate
> 0)
1308 sleep (outq
/ baud_rate
);
1313 if ((i
- 1) % preempt_count
== 0)
1314 detect_input_pending ();
1317 #ifdef HAVE_WINDOW_SYSTEM
1318 if (FRAME_WINDOW_P (f
))
1320 current_frame
->top_left_y
[i
] = downto
;
1321 current_frame
->top_left_x
[i
] = leftmost
;
1323 #endif /* HAVE_WINDOW_SYSTEM */
1326 #ifdef HAVE_WINDOW_SYSTEM
1327 if (FRAME_WINDOW_P (f
))
1328 downto
+= current_frame
->pix_height
[i
];
1329 #endif /* HAVE_WINDOW_SYSTEM */
1331 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1333 /* Now just clean up termcap drivers and set cursor, etc. */
1336 if ((cursor_in_echo_area
1337 /* If we are showing a message instead of the minibuffer,
1338 show the cursor for the message instead of for the
1339 (now hidden) minibuffer contents. */
1340 || (EQ (minibuf_window
, selected_window
)
1341 && EQ (minibuf_window
, echo_area_window
)
1342 && echo_area_glyphs
!= 0))
1343 /* These cases apply only to the frame that contains
1344 the active minibuffer window. */
1345 && FRAME_HAS_MINIBUF_P (f
)
1346 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
1348 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1351 if (cursor_in_echo_area
< 0)
1358 /* If the minibuffer is several lines high, find the last
1359 line that has any text on it. */
1360 row
= FRAME_HEIGHT (f
);
1364 if (current_frame
->enable
[row
])
1365 col
= current_frame
->used
[row
];
1369 while (row
> top
&& col
== 0);
1371 /* Make sure COL is not out of range. */
1372 if (col
>= FRAME_CURSOR_X_LIMIT (f
))
1374 /* If we have another row, advance cursor into it. */
1375 if (row
< FRAME_HEIGHT (f
) - 1)
1377 col
= FRAME_LEFT_SCROLL_BAR_WIDTH (f
);
1380 /* Otherwise move it back in range. */
1382 col
= FRAME_CURSOR_X_LIMIT (f
) - 1;
1386 cursor_to (row
, col
);
1389 cursor_to (FRAME_CURSOR_Y (f
),
1390 minmax (0, FRAME_CURSOR_X (f
),
1391 FRAME_CURSOR_X_LIMIT (f
) - 1));
1397 fflush (termscript
);
1400 /* Here if output is preempted because input is detected. */
1403 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1404 display_completed
= !pause
;
1406 bzero (FRAME_DESIRED_GLYPHS (f
)->enable
, FRAME_HEIGHT (f
));
1410 /* Called when about to quit, to check for doing so
1411 at an improper time. */
1417 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1419 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1421 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1426 /* Decide what insert/delete line to do, and do it */
1428 extern void scrolling_1 ();
1434 int unchanged_at_top
, unchanged_at_bottom
;
1437 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1438 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1439 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1440 int *old_draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1442 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1443 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1444 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1446 /* Compute hash codes of all the lines.
1447 Also calculate number of changed lines,
1448 number of unchanged lines at the beginning,
1449 and number of unchanged lines at the end. */
1452 unchanged_at_top
= 0;
1453 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1454 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1456 /* Give up on this scrolling if some old lines are not enabled. */
1457 if (!current_frame
->enable
[i
])
1459 old_hash
[i
] = line_hash_code (current_frame
, i
);
1460 if (! desired_frame
->enable
[i
])
1462 /* This line cannot be redrawn, so don't let scrolling mess it. */
1463 new_hash
[i
] = old_hash
[i
];
1464 #define INFINITY 1000000 /* Taken from scroll.c */
1465 draw_cost
[i
] = INFINITY
;
1469 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1470 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1473 if (old_hash
[i
] != new_hash
[i
])
1476 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1478 else if (i
== unchanged_at_top
)
1480 old_draw_cost
[i
] = line_draw_cost (current_frame
, i
);
1483 /* If changed lines are few, don't allow preemption, don't scroll. */
1484 if (!scroll_region_ok
&& changed_lines
< baud_rate
/ 2400
1485 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1488 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1489 - unchanged_at_bottom
);
1491 if (scroll_region_ok
)
1492 free_at_end_vpos
-= unchanged_at_bottom
;
1493 else if (memory_below_frame
)
1494 free_at_end_vpos
= -1;
1496 /* If large window, fast terminal and few lines in common between
1497 current frame and desired frame, don't bother with i/d calc. */
1498 if (!scroll_region_ok
&& window_size
>= 18 && baud_rate
> 2400
1500 10 * scrolling_max_lines_saved (unchanged_at_top
,
1501 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1502 old_hash
, new_hash
, draw_cost
)))
1505 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1506 draw_cost
+ unchanged_at_top
- 1,
1507 old_draw_cost
+ unchanged_at_top
- 1,
1508 old_hash
+ unchanged_at_top
- 1,
1509 new_hash
+ unchanged_at_top
- 1,
1510 free_at_end_vpos
- unchanged_at_top
);
1515 /* Return the offset in its buffer of the character at location col, line
1516 in the given window. */
1518 buffer_posn_from_coords (window
, col
, line
)
1519 struct window
*window
;
1522 int hscroll
= XINT (window
->hscroll
);
1523 int window_left
= WINDOW_LEFT_MARGIN (window
);
1525 /* The actual width of the window is window->width less one for the
1526 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1528 int window_width
= window_internal_width (window
) - 1;
1530 int startp
= marker_position (window
->start
);
1532 /* Since compute_motion will only operate on the current buffer,
1533 we need to save the old one and restore it when we're done. */
1534 struct buffer
*old_current_buffer
= current_buffer
;
1535 struct position
*posn
;
1537 current_buffer
= XBUFFER (window
->buffer
);
1539 /* We can't get a correct result in this case,
1540 but at least prevent compute_motion from crashing. */
1544 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1545 (window->frame))->bufp to avoid scanning from the very top of
1546 the window, but it isn't maintained correctly, and I'm not even
1547 sure I will keep it. */
1548 posn
= compute_motion (startp
, 0,
1549 ((window
== XWINDOW (minibuf_window
) && startp
== BEG
1550 ? minibuf_prompt_width
: 0)
1551 + (hscroll
? 1 - hscroll
: 0)),
1554 window_width
, hscroll
, 0, window
);
1556 current_buffer
= old_current_buffer
;
1558 /* compute_motion considers frame points past the end of a line
1559 to be *after* the newline, i.e. at the start of the next line.
1560 This is reasonable, but not really what we want. So if the
1561 result is on a line below LINE, back it up one character. */
1562 if (posn
->vpos
> line
)
1563 return posn
->bufpos
- 1;
1565 return posn
->bufpos
;
1572 register GLYPH
*p
= r
;
1573 while (*p
++ == SPACEGLYPH
);
1578 count_match (str1
, str2
)
1581 register GLYPH
*p1
= str1
;
1582 register GLYPH
*p2
= str2
;
1583 while (*p1
++ == *p2
++);
1584 return p1
- str1
- 1;
1587 /* Char insertion/deletion cost vector, from term.c */
1588 extern int *char_ins_del_vector
;
1590 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))])
1593 update_line (frame
, vpos
)
1594 register FRAME_PTR frame
;
1597 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1600 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1602 register struct frame_glyphs
*current_frame
1603 = FRAME_CURRENT_GLYPHS (frame
);
1604 register struct frame_glyphs
*desired_frame
1605 = FRAME_DESIRED_GLYPHS (frame
);
1607 if (desired_frame
->highlight
[vpos
]
1608 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1610 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1611 (current_frame
->enable
[vpos
] ?
1612 current_frame
->used
[vpos
] : 0));
1613 current_frame
->enable
[vpos
] = 0;
1616 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1618 if (! current_frame
->enable
[vpos
])
1624 obody
= current_frame
->glyphs
[vpos
];
1625 olen
= current_frame
->used
[vpos
];
1626 if (! current_frame
->highlight
[vpos
])
1628 if (!must_write_spaces
)
1629 while (olen
> 0 && obody
[olen
- 1] == SPACEGLYPH
)
1634 /* For an inverse-video line, remember we gave it
1635 spaces all the way to the frame edge
1636 so that the reverse video extends all the way across. */
1638 while (olen
< FRAME_WINDOW_WIDTH (frame
) - 1)
1639 obody
[olen
++] = SPACEGLYPH
;
1643 /* One way or another, this will enable the line being updated. */
1644 current_frame
->enable
[vpos
] = 1;
1645 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1646 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1647 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1649 #ifdef HAVE_WINDOW_SYSTEM
1650 if (FRAME_WINDOW_P (frame
))
1652 current_frame
->pix_width
[vpos
]
1653 = current_frame
->used
[vpos
]
1654 * FONT_WIDTH (FRAME_FONT (frame
));
1655 current_frame
->pix_height
[vpos
]
1656 = FRAME_LINE_HEIGHT (frame
);
1658 #endif /* HAVE_WINDOW_SYSTEM */
1660 if (!desired_frame
->enable
[vpos
])
1666 nbody
= desired_frame
->glyphs
[vpos
];
1667 nlen
= desired_frame
->used
[vpos
];
1669 /* Pretend trailing spaces are not there at all,
1670 unless for one reason or another we must write all spaces. */
1671 if (! desired_frame
->highlight
[vpos
])
1673 if (!must_write_spaces
)
1674 /* We know that the previous character byte contains 0. */
1675 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1680 /* For an inverse-video line, give it extra trailing spaces
1681 all the way to the frame edge
1682 so that the reverse video extends all the way across. */
1684 while (nlen
< FRAME_WINDOW_WIDTH (frame
) - 1)
1685 nbody
[nlen
++] = SPACEGLYPH
;
1688 /* If there's no i/d char, quickly do the best we can without it. */
1689 if (!char_ins_del_ok
)
1694 if (FRAME_X_P (frame
))
1696 /* Under X, erase everything we are going to rewrite,
1697 and rewrite everything from the first char that's changed.
1698 This is part of supporting fonts like Courier
1699 whose chars can overlap outside the char width. */
1700 for (i
= 0; i
< nlen
; i
++)
1701 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1704 cursor_to (vpos
, i
);
1706 clear_end_of_line (olen
);
1707 write_glyphs (nbody
+ i
, nlen
- i
);
1712 for (i
= 0; i
< nlen
; i
++)
1714 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1716 cursor_to (vpos
, i
);
1719 && (i
+ j
>= olen
|| nbody
[i
+ j
] != obody
[i
+ j
]
1720 || (nbody
[i
+ j
] & GLYPH_MASK_PADDING
)));
1723 /* Output this run of non-matching chars. */
1724 write_glyphs (nbody
+ i
, j
);
1727 /* Now find the next non-match. */
1731 /* Clear the rest of the line, or the non-clear part of it. */
1734 cursor_to (vpos
, nlen
);
1735 clear_end_of_line (olen
);
1738 /* Exchange contents between current_frame and new_frame. */
1739 temp
= desired_frame
->glyphs
[vpos
];
1740 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1741 current_frame
->glyphs
[vpos
] = temp
;
1743 /* Exchange charstarts between current_frame and new_frame. */
1744 temp1
= desired_frame
->charstarts
[vpos
];
1745 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1746 current_frame
->charstarts
[vpos
] = temp1
;
1753 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1754 ? 0 : count_blanks (nbody
);
1757 cursor_to (vpos
, nsp
);
1758 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1761 /* Exchange contents between current_frame and new_frame. */
1762 temp
= desired_frame
->glyphs
[vpos
];
1763 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1764 current_frame
->glyphs
[vpos
] = temp
;
1766 /* Exchange charstarts between current_frame and new_frame. */
1767 temp1
= desired_frame
->charstarts
[vpos
];
1768 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1769 current_frame
->charstarts
[vpos
] = temp1
;
1778 /* Compute number of leading blanks in old and new contents. */
1779 osp
= count_blanks (obody
);
1780 if (!desired_frame
->highlight
[vpos
])
1781 nsp
= count_blanks (nbody
);
1785 /* Compute number of matching chars starting with first nonblank. */
1786 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1788 /* Spaces in new match implicit space past the end of old. */
1789 /* A bug causing this to be a no-op was fixed in 18.29. */
1790 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1793 while (np1
[begmatch
] == SPACEGLYPH
)
1797 /* Avoid doing insert/delete char
1798 just cause number of leading spaces differs
1799 when the following text does not match. */
1800 if (begmatch
== 0 && osp
!= nsp
)
1801 osp
= nsp
= min (osp
, nsp
);
1803 /* Find matching characters at end of line */
1806 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1807 while (op1
> op2
&& op1
[-1] == np1
[-1])
1812 endmatch
= obody
+ olen
- op1
;
1814 /* Put correct value back in nbody[nlen].
1815 This is important because direct_output_for_insert
1816 can write into the line at a later point.
1817 If this screws up the zero at the end of the line, re-establish it. */
1821 /* tem gets the distance to insert or delete.
1822 endmatch is how many characters we save by doing so.
1825 tem
= (nlen
- nsp
) - (olen
- osp
);
1827 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1830 /* nsp - osp is the distance to insert or delete.
1831 If that is nonzero, begmatch is known to be nonzero also.
1832 begmatch + endmatch is how much we save by doing the ins/del.
1836 && (!char_ins_del_ok
1837 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1841 osp
= nsp
= min (osp
, nsp
);
1844 /* Now go through the line, inserting, writing and
1845 deleting as appropriate. */
1849 cursor_to (vpos
, nsp
);
1850 delete_glyphs (osp
- nsp
);
1854 /* If going to delete chars later in line
1855 and insert earlier in the line,
1856 must delete first to avoid losing data in the insert */
1857 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1859 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1860 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1861 olen
= nlen
- (nsp
- osp
);
1863 cursor_to (vpos
, osp
);
1864 insert_glyphs ((GLYPH
*) 0, nsp
- osp
);
1868 tem
= nsp
+ begmatch
+ endmatch
;
1869 if (nlen
!= tem
|| olen
!= tem
)
1871 cursor_to (vpos
, nsp
+ begmatch
);
1872 if (!endmatch
|| nlen
== olen
)
1874 /* If new text being written reaches right margin,
1875 there is no need to do clear-to-eol at the end.
1876 (and it would not be safe, since cursor is not
1877 going to be "at the margin" after the text is done) */
1878 if (nlen
== FRAME_WINDOW_WIDTH (frame
))
1880 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1884 /* the following code loses disastrously if tem == nlen.
1885 Rather than trying to fix that case, I am trying the simpler
1886 solution found above. */
1888 /* If the text reaches to the right margin,
1889 it will lose one way or another (depending on AutoWrap)
1890 to clear to end of line after outputting all the text.
1891 So pause with one character to go and clear the line then. */
1892 if (nlen
== FRAME_WINDOW_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1894 /* endmatch must be zero, and tem must equal nsp + begmatch */
1895 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1896 clear_end_of_line (olen
);
1897 olen
= 0; /* Don't let it be cleared again later */
1898 write_glyphs (nbody
+ nlen
- 1, 1);
1901 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1902 #endif /* OBSOLETE */
1905 else if (nlen
> olen
)
1907 /* Here, we used to have the following simple code:
1908 ----------------------------------------
1909 write_glyphs (nbody + nsp + begmatch, olen - tem);
1910 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
1911 ----------------------------------------
1912 but it doesn't work if nbody[nsp + begmatch + olen - tem]
1913 is a padding glyph. */
1914 int out
= olen
- tem
; /* Columns to be overwritten originally. */
1917 /* Calculate columns we can actually overwrite. */
1918 while (nbody
[nsp
+ begmatch
+ out
] & GLYPH_MASK_PADDING
) out
--;
1919 write_glyphs (nbody
+ nsp
+ begmatch
, out
);
1920 /* If we left columns to be overwritten. we must delete them. */
1921 del
= olen
- tem
- out
;
1922 if (del
> 0) delete_glyphs (del
);
1923 /* At last, we insert columns not yet written out. */
1924 insert_glyphs (nbody
+ nsp
+ begmatch
+ out
, nlen
- olen
+ del
);
1927 else if (olen
> nlen
)
1929 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1930 delete_glyphs (olen
- nlen
);
1936 /* If any unerased characters remain after the new line, erase them. */
1939 cursor_to (vpos
, nlen
);
1940 clear_end_of_line (olen
);
1943 /* Exchange contents between current_frame and new_frame. */
1944 temp
= desired_frame
->glyphs
[vpos
];
1945 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1946 current_frame
->glyphs
[vpos
] = temp
;
1948 /* Exchange charstarts between current_frame and new_frame. */
1949 temp1
= desired_frame
->charstarts
[vpos
];
1950 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1951 current_frame
->charstarts
[vpos
] = temp1
;
1954 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
1955 session's frames, frame names, buffers, buffer-read-only flags, and
1956 buffer-modified-flags, and a trailing sentinel (so we don't need to
1957 add length checks). */
1958 static Lisp_Object frame_and_buffer_state
;
1960 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p
,
1961 Sframe_or_buffer_changed_p
, 0, 0, 0,
1962 "Return non-nil if the frame and buffer state appears to have changed.\n\
1963 The state variable is an internal vector containing all frames and buffers,\n\
1964 aside from buffers whose names start with space,\n\
1965 along with the buffers' read-only and modified flags, which allows a fast\n\
1966 check to see whether the menu bars might need to be recomputed.\n\
1967 If this function returns non-nil, it updates the internal vector to reflect\n\
1968 the current state.\n")
1971 Lisp_Object tail
, frame
, buf
;
1975 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1976 FOR_EACH_FRAME (tail
, frame
)
1978 if (!EQ (*vecp
++, frame
))
1980 if (!EQ (*vecp
++, XFRAME (frame
)->name
))
1983 /* Check that the buffer info matches.
1984 No need to test for the end of the vector
1985 because the last element of the vector is lambda
1986 and that will always cause a mismatch. */
1987 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1989 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1990 /* Ignore buffers that aren't included in buffer lists. */
1991 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1993 if (!EQ (*vecp
++, buf
))
1995 if (!EQ (*vecp
++, XBUFFER (buf
)->read_only
))
1997 if (!EQ (*vecp
++, Fbuffer_modified_p (buf
)))
2000 /* Detect deletion of a buffer at the end of the list. */
2001 if (EQ (*vecp
, Qlambda
))
2004 /* Start with 1 so there is room for at least one lambda at the end. */
2006 FOR_EACH_FRAME (tail
, frame
)
2008 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
2010 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
2011 if (n
> XVECTOR (frame_and_buffer_state
)->size
2012 || n
+ 20 < XVECTOR (frame_and_buffer_state
)->size
/ 2)
2013 /* Add 20 extra so we grow it less often. */
2014 frame_and_buffer_state
= Fmake_vector (make_number (n
+ 20), Qlambda
);
2015 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
2016 FOR_EACH_FRAME (tail
, frame
)
2019 *vecp
++ = XFRAME (frame
)->name
;
2021 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
2023 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
2024 /* Ignore buffers that aren't included in buffer lists. */
2025 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
2028 *vecp
++ = XBUFFER (buf
)->read_only
;
2029 *vecp
++ = Fbuffer_modified_p (buf
);
2031 /* Fill up the vector with lambdas (always at least one). */
2033 while (vecp
- XVECTOR (frame_and_buffer_state
)->contents
2034 < XVECTOR (frame_and_buffer_state
)->size
)
2036 /* Make sure we didn't overflow the vector. */
2037 if (vecp
- XVECTOR (frame_and_buffer_state
)->contents
2038 > XVECTOR (frame_and_buffer_state
)->size
)
2043 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
2044 1, 1, "FOpen termscript file: ",
2045 "Start writing all terminal output to FILE as well as the terminal.\n\
2046 FILE = nil means just close any termscript file currently open.")
2050 if (termscript
!= 0) fclose (termscript
);
2055 file
= Fexpand_file_name (file
, Qnil
);
2056 termscript
= fopen (XSTRING (file
)->data
, "w");
2057 if (termscript
== 0)
2058 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
2066 window_change_signal (signalnum
) /* If we don't have an argument, */
2067 int signalnum
; /* some compilers complain in signal calls. */
2071 int old_errno
= errno
;
2073 get_frame_size (&width
, &height
);
2075 /* The frame size change obviously applies to a termcap-controlled
2076 frame. Find such a frame in the list, and assume it's the only
2077 one (since the redisplay code always writes to stdout, not a
2078 FILE * specified in the frame structure). Record the new size,
2079 but don't reallocate the data structures now. Let that be done
2080 later outside of the signal handler. */
2083 Lisp_Object tail
, frame
;
2085 FOR_EACH_FRAME (tail
, frame
)
2087 if (FRAME_TERMCAP_P (XFRAME (frame
)))
2089 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
2095 signal (SIGWINCH
, window_change_signal
);
2098 #endif /* SIGWINCH */
2101 /* Do any change in frame size that was requested by a signal. */
2104 do_pending_window_change ()
2106 /* If window_change_signal should have run before, run it now. */
2107 while (delayed_size_change
)
2109 Lisp_Object tail
, frame
;
2111 delayed_size_change
= 0;
2113 FOR_EACH_FRAME (tail
, frame
)
2115 FRAME_PTR f
= XFRAME (frame
);
2117 int height
= FRAME_NEW_HEIGHT (f
);
2118 int width
= FRAME_NEW_WIDTH (f
);
2120 if (height
!= 0 || width
!= 0)
2121 change_frame_size (f
, height
, width
, 0, 0);
2127 /* Change the frame height and/or width. Values may be given as zero to
2128 indicate no change is to take place.
2130 If DELAY is non-zero, then assume we're being called from a signal
2131 handler, and queue the change for later - perhaps the next
2132 redisplay. Since this tries to resize windows, we can't call it
2133 from a signal handler. */
2136 change_frame_size (f
, newheight
, newwidth
, pretend
, delay
)
2137 register FRAME_PTR f
;
2138 int newheight
, newwidth
, pretend
, delay
;
2140 Lisp_Object tail
, frame
;
2142 if (! FRAME_WINDOW_P (f
))
2144 /* When using termcap, or on MS-DOS, all frames use
2145 the same screen, so a change in size affects all frames. */
2146 FOR_EACH_FRAME (tail
, frame
)
2147 if (! FRAME_WINDOW_P (XFRAME (frame
)))
2148 change_frame_size_1 (XFRAME (frame
), newheight
, newwidth
,
2152 change_frame_size_1 (f
, newheight
, newwidth
, pretend
, delay
);
2156 change_frame_size_1 (frame
, newheight
, newwidth
, pretend
, delay
)
2157 register FRAME_PTR frame
;
2158 int newheight
, newwidth
, pretend
, delay
;
2160 int new_frame_window_width
;
2161 unsigned int total_glyphs
;
2162 int count
= specpdl_ptr
- specpdl
;
2164 /* If we can't deal with the change now, queue it for later. */
2167 FRAME_NEW_HEIGHT (frame
) = newheight
;
2168 FRAME_NEW_WIDTH (frame
) = newwidth
;
2169 delayed_size_change
= 1;
2173 /* This size-change overrides any pending one for this frame. */
2174 FRAME_NEW_HEIGHT (frame
) = 0;
2175 FRAME_NEW_WIDTH (frame
) = 0;
2177 /* If an argument is zero, set it to the current value. */
2179 newheight
= FRAME_HEIGHT (frame
);
2181 newwidth
= FRAME_WIDTH (frame
);
2182 new_frame_window_width
= FRAME_WINDOW_WIDTH_ARG (frame
, newwidth
);
2184 total_glyphs
= newheight
* (newwidth
+ 2) * sizeof (GLYPH
);
2186 /* If these sizes are so big they cause overflow,
2187 just ignore the change. It's not clear what better we could do. */
2188 if (total_glyphs
/ sizeof (GLYPH
) / newheight
!= newwidth
+ 2)
2191 /* Round up to the smallest acceptable size. */
2192 check_frame_size (frame
, &newheight
, &newwidth
);
2194 /* If we're not changing the frame size, quit now. */
2195 if (newheight
== FRAME_HEIGHT (frame
)
2196 && new_frame_window_width
== FRAME_WINDOW_WIDTH (frame
))
2202 /* We only can set screen dimensions to certain values supported
2203 by our video hardware. Try to find the smallest size greater
2204 or equal to the requested dimensions. */
2205 dos_set_window_size (&newheight
, &newwidth
);
2208 if (newheight
!= FRAME_HEIGHT (frame
))
2210 if (FRAME_HAS_MINIBUF_P (frame
)
2211 && ! FRAME_MINIBUF_ONLY_P (frame
))
2213 /* Frame has both root and minibuffer. */
2214 set_window_height (FRAME_ROOT_WINDOW (frame
),
2215 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
2216 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
,
2218 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
2221 /* Frame has just one top-level window. */
2222 set_window_height (FRAME_ROOT_WINDOW (frame
),
2223 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
2225 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2226 FrameRows
= newheight
;
2229 if (frame
->output_method
== output_termcap
)
2231 frame_height
= newheight
;
2233 FrameRows
= newheight
;
2238 if (new_frame_window_width
!= FRAME_WINDOW_WIDTH (frame
))
2240 set_window_width (FRAME_ROOT_WINDOW (frame
), new_frame_window_width
, 0);
2241 if (FRAME_HAS_MINIBUF_P (frame
))
2242 set_window_width (FRAME_MINIBUF_WINDOW (frame
), new_frame_window_width
, 0);
2244 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2245 FrameCols
= newwidth
;
2247 if (frame
->output_method
== output_termcap
)
2249 frame_width
= newwidth
;
2251 FrameCols
= newwidth
;
2256 FRAME_HEIGHT (frame
) = newheight
;
2257 SET_FRAME_WIDTH (frame
, newwidth
);
2259 if (FRAME_CURSOR_X (frame
) >= FRAME_CURSOR_X_LIMIT (frame
))
2260 FRAME_CURSOR_X (frame
) = FRAME_CURSOR_X_LIMIT (frame
) - 1;
2261 if (FRAME_CURSOR_Y (frame
) >= FRAME_HEIGHT (frame
))
2262 FRAME_CURSOR_Y (frame
) = FRAME_HEIGHT (frame
) - 1;
2264 remake_frame_glyphs (frame
);
2265 calculate_costs (frame
);
2269 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2271 /* This isn't quite a no-op: it runs window-configuration-change-hook. */
2272 Fset_window_buffer (FRAME_SELECTED_WINDOW (frame
),
2273 XWINDOW (FRAME_SELECTED_WINDOW (frame
))->buffer
);
2275 unbind_to (count
, Qnil
);
2278 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
2279 Ssend_string_to_terminal
, 1, 1, 0,
2280 "Send STRING to the terminal without alteration.\n\
2281 Control characters in STRING will have terminal-dependent effects.")
2285 /* ??? Perhaps we should do something special for multibyte strings here. */
2286 CHECK_STRING (string
, 0);
2287 fwrite (XSTRING (string
)->data
, 1, STRING_BYTES (XSTRING (string
)), stdout
);
2291 fwrite (XSTRING (string
)->data
, 1, STRING_BYTES (XSTRING (string
)),
2293 fflush (termscript
);
2298 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
2299 "Beep, or flash the screen.\n\
2300 Also, unless an argument is given,\n\
2301 terminate any keyboard macro currently executing.")
2324 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
2325 error ("Keyboard macro terminated by a command ringing the bell");
2331 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
2332 "Pause, without updating display, for SECONDS seconds.\n\
2333 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2334 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2335 additional wait period, in milliseconds; this may be useful if your\n\
2336 Emacs was built without floating point support.\n\
2337 \(Not all operating systems support waiting for a fraction of a second.)")
2338 (seconds
, milliseconds
)
2339 Lisp_Object seconds
, milliseconds
;
2343 if (NILP (milliseconds
))
2344 XSETINT (milliseconds
, 0);
2346 CHECK_NUMBER (milliseconds
, 1);
2347 usec
= XINT (milliseconds
) * 1000;
2349 #ifdef LISP_FLOAT_TYPE
2351 double duration
= extract_float (seconds
);
2352 sec
= (int) duration
;
2353 usec
+= (duration
- sec
) * 1000000;
2356 CHECK_NUMBER (seconds
, 0);
2357 sec
= XINT (seconds
);
2360 #ifndef EMACS_HAS_USECS
2361 if (sec
== 0 && usec
!= 0)
2362 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2365 /* Assure that 0 <= usec < 1000000. */
2368 /* We can't rely on the rounding being correct if user is negative. */
2369 if (-1000000 < usec
)
2370 sec
--, usec
+= 1000000;
2372 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2375 sec
+= usec
/ 1000000, usec
%= 1000000;
2377 if (sec
< 0 || (sec
== 0 && usec
== 0))
2383 XSETFASTINT (zero
, 0);
2384 wait_reading_process_input (sec
, usec
, zero
, 0);
2387 /* We should always have wait_reading_process_input; we have a dummy
2388 implementation for systems which don't support subprocesses. */
2390 /* No wait_reading_process_input */
2397 /* The reason this is done this way
2398 (rather than defined (H_S) && defined (H_T))
2399 is because the VMS preprocessor doesn't grok `defined' */
2401 EMACS_GET_TIME (end_time
);
2402 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2403 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2407 EMACS_GET_TIME (timeout
);
2408 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2409 if (EMACS_TIME_NEG_P (timeout
)
2410 || !select (1, 0, 0, 0, &timeout
))
2413 #else /* not HAVE_SELECT */
2415 #endif /* HAVE_SELECT */
2416 #endif /* not VMS */
2419 #endif /* no subprocesses */
2424 /* This is just like wait_reading_process_input, except that
2425 it does the redisplay.
2427 It's also much like Fsit_for, except that it can be used for
2428 waiting for input as well. */
2431 sit_for (sec
, usec
, reading
, display
, initial_display
)
2432 int sec
, usec
, reading
, display
, initial_display
;
2434 Lisp_Object read_kbd
;
2436 swallow_events (display
);
2438 if (detect_input_pending_run_timers (display
))
2441 if (initial_display
)
2442 redisplay_preserve_echo_area ();
2444 if (sec
== 0 && usec
== 0)
2451 XSETINT (read_kbd
, reading
? -1 : 1);
2452 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2454 return detect_input_pending () ? Qnil
: Qt
;
2457 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2458 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2459 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2460 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2461 additional wait period, in milliseconds; this may be useful if your\n\
2462 Emacs was built without floating point support.\n\
2463 \(Not all operating systems support waiting for a fraction of a second.)\n\
2464 Optional third arg NODISP non-nil means don't redisplay, just wait for input.\n\
2465 Redisplay is preempted as always if input arrives, and does not happen\n\
2466 if input is available before it starts.\n\
2467 Value is t if waited the full time with no input arriving.")
2468 (seconds
, milliseconds
, nodisp
)
2469 Lisp_Object seconds
, milliseconds
, nodisp
;
2473 if (NILP (milliseconds
))
2474 XSETINT (milliseconds
, 0);
2476 CHECK_NUMBER (milliseconds
, 1);
2477 usec
= XINT (milliseconds
) * 1000;
2479 #ifdef LISP_FLOAT_TYPE
2481 double duration
= extract_float (seconds
);
2482 sec
= (int) duration
;
2483 usec
+= (duration
- sec
) * 1000000;
2486 CHECK_NUMBER (seconds
, 0);
2487 sec
= XINT (seconds
);
2490 #ifndef EMACS_HAS_USECS
2491 if (usec
!= 0 && sec
== 0)
2492 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2495 return sit_for (sec
, usec
, 0, NILP (nodisp
), NILP (nodisp
));
2498 char *terminal_type
;
2500 /* Initialization done when Emacs fork is started, before doing stty. */
2501 /* Determine terminal type and set terminal_driver */
2502 /* Then invoke its decoding routine to set up variables
2503 in the terminal package */
2508 #ifdef HAVE_X_WINDOWS
2509 extern int display_arg
;
2514 cursor_in_echo_area
= 0;
2515 terminal_type
= (char *) 0;
2517 /* Now is the time to initialize this; it's used by init_sys_modes
2519 Vwindow_system
= Qnil
;
2521 /* If the user wants to use a window system, we shouldn't bother
2522 initializing the terminal. This is especially important when the
2523 terminal is so dumb that emacs gives up before and doesn't bother
2524 using the window system.
2526 If the DISPLAY environment variable is set and nonempty,
2527 try to use X, and die with an error message if that doesn't work. */
2529 #ifdef HAVE_X_WINDOWS
2534 display
= getenv ("DECW$DISPLAY");
2536 display
= getenv ("DISPLAY");
2539 display_arg
= (display
!= 0 && *display
!= 0);
2542 if (!inhibit_window_system
&& display_arg
2548 Vwindow_system
= intern ("x");
2550 Vwindow_system_version
= make_number (11);
2552 Vwindow_system_version
= make_number (10);
2554 #if defined (LINUX) && defined (HAVE_LIBNCURSES)
2555 /* In some versions of ncurses,
2556 tputs crashes if we have not called tgetent.
2558 { char b
[2044]; tgetent (b
, "xterm");}
2562 #endif /* HAVE_X_WINDOWS */
2565 if (!inhibit_window_system
)
2567 Vwindow_system
= intern ("w32");
2568 Vwindow_system_version
= make_number (1);
2571 #endif /* HAVE_NTGUI */
2573 /* If no window system has been specified, try to use the terminal. */
2576 fatal ("standard input is not a tty");
2580 /* Look at the TERM variable */
2581 terminal_type
= (char *) getenv ("TERM");
2585 fprintf (stderr
, "Please specify your terminal type.\n\
2586 For types defined in VMS, use set term /device=TYPE.\n\
2587 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2588 \(The quotation marks are necessary since terminal types are lower case.)\n");
2590 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2596 /* VMS DCL tends to upcase things, so downcase term type.
2597 Hardly any uppercase letters in terminal types; should be none. */
2599 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2602 strcpy (new, terminal_type
);
2604 for (p
= new; *p
; p
++)
2608 terminal_type
= new;
2612 term_init (terminal_type
);
2615 int width
= FRAME_WINDOW_WIDTH (selected_frame
);
2616 int height
= FRAME_HEIGHT (selected_frame
);
2618 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
2620 /* If these sizes are so big they cause overflow,
2621 just ignore the change. It's not clear what better we could do. */
2622 if (total_glyphs
/ sizeof (GLYPH
) / height
!= width
+ 2)
2623 fatal ("screen size %dx%d too big", width
, height
);
2626 remake_frame_glyphs (selected_frame
);
2627 calculate_costs (selected_frame
);
2629 /* X and Y coordinates of the cursor between updates. */
2630 FRAME_CURSOR_X (selected_frame
) = 0;
2631 FRAME_CURSOR_Y (selected_frame
) = 0;
2636 #endif /* CANNOT_DUMP */
2637 signal (SIGWINCH
, window_change_signal
);
2638 #endif /* SIGWINCH */
2644 defsubr (&Sredraw_frame
);
2645 defsubr (&Sredraw_display
);
2646 defsubr (&Sframe_or_buffer_changed_p
);
2647 defsubr (&Sopen_termscript
);
2649 defsubr (&Ssit_for
);
2650 defsubr (&Ssleep_for
);
2651 defsubr (&Ssend_string_to_terminal
);
2653 frame_and_buffer_state
= Fmake_vector (make_number (20), Qlambda
);
2654 staticpro (&frame_and_buffer_state
);
2656 Qdisplay_table
= intern ("display-table");
2657 staticpro (&Qdisplay_table
);
2659 DEFVAR_INT ("baud-rate", &baud_rate
,
2660 "*The output baud rate of the terminal.\n\
2661 On most systems, changing this value will affect the amount of padding\n\
2662 and the other strategic decisions made during redisplay.");
2663 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2664 "*Non-nil means invert the entire frame display.\n\
2665 This means everything is in inverse video which otherwise would not be.");
2666 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2667 "*Non-nil means try to flash the frame to represent a bell.");
2668 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2669 "*Non-nil means no need to redraw entire frame after suspending.\n\
2670 A non-nil value is useful if the terminal can automatically preserve\n\
2671 Emacs's frame display when you reenter Emacs.\n\
2672 It is up to you to set this variable if your terminal can do that.");
2673 DEFVAR_LISP ("window-system", &Vwindow_system
,
2674 "A symbol naming the window-system under which Emacs is running\n\
2675 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2676 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2677 "The version number of the window system in use.\n\
2678 For X windows, this is 10 or 11.");
2679 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2680 "Non-nil means put cursor in minibuffer, at end of any message there.");
2681 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2682 "Table defining how to output a glyph code to the frame.\n\
2683 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2684 Each element can be:\n\
2685 integer: a glyph code which this glyph is an alias for.\n\
2686 string: output this glyph using that string (not impl. in X windows).\n\
2687 nil: this glyph mod 256 is char code to output,\n\
2688 and this glyph / 256 is face code for X windows (see `face-id').");
2689 Vglyph_table
= Qnil
;
2691 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2692 "Display table to use for buffers that specify none.\n\
2693 See `buffer-display-table' for more information.");
2694 Vstandard_display_table
= Qnil
;
2696 /* Initialize `window-system', unless init_display already decided it. */
2701 Vwindow_system
= Qnil
;
2702 Vwindow_system_version
= Qnil
;