1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993 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. */
30 #include "termhooks.h"
32 #include "dispextern.h"
45 #endif /* HAVE_X_WINDOWS */
47 #define max(a, b) ((a) > (b) ? (a) : (b))
48 #define min(a, b) ((a) < (b) ? (a) : (b))
50 #ifndef PENDING_OUTPUT_COUNT
51 /* Get number of chars of output now in the buffer of a stdio stream.
52 This ought to be built in in stdio, but it isn't.
53 Some s- files override this because their stdio internals differ. */
54 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
57 /* Nonzero upon entry to redisplay means do not assume anything about
58 current contents of actual terminal frame; clear and redraw it. */
62 /* Nonzero means last display completed. Zero means it was preempted. */
64 int display_completed
;
66 /* Lisp variable visible-bell; enables use of screen-flash
67 instead of audible bell. */
71 /* Invert the color of the whole frame, at a low level. */
75 /* Line speed of the terminal. */
79 /* nil or a symbol naming the window system under which emacs is
80 running ('x is the only current possibility). */
82 Lisp_Object Vwindow_system
;
84 /* Version number of X windows: 10, 11 or nil. */
85 Lisp_Object Vwindow_system_version
;
87 /* Vector of glyph definitions. Indexed by glyph number,
88 the contents are a string which is how to output the glyph.
90 If Vglyph_table is nil, a glyph is output by using its low 8 bits
91 as a character code. */
93 Lisp_Object Vglyph_table
;
95 /* Display table to use for vectors that don't specify their own. */
97 Lisp_Object Vstandard_display_table
;
99 /* Nonzero means reading single-character input with prompt
100 so put cursor on minibuffer after the prompt.
101 positive means at end of text in echo area;
102 negative means at beginning of line. */
103 int cursor_in_echo_area
;
105 /* The currently selected frame.
106 In a single-frame version, this variable always remains 0. */
108 FRAME_PTR selected_frame
;
110 /* A frame which is not just a minibuffer, or 0 if there are no such
111 frames. This is usually the most recent such frame that was
112 selected. In a single-frame version, this variable always remains 0. */
113 FRAME_PTR last_nonminibuf_frame
;
115 /* In a single-frame version, the information that would otherwise
116 exist inside frame objects lives in the following structure instead.
118 NOTE: the_only_frame is not checked for garbage collection; don't
119 store collectible objects in any of its fields!
121 You're not/The only frame in town/... */
124 struct frame the_only_frame
;
127 /* This is a vector, made larger whenever it isn't large enough,
128 which is used inside `update_frame' to hold the old contents
129 of the FRAME_PHYS_LINES of the frame being updated. */
130 struct frame_glyphs
**ophys_lines
;
131 /* Length of vector currently allocated. */
132 int ophys_lines_length
;
134 FILE *termscript
; /* Stdio stream being used for copy of all output. */
136 struct cm Wcm
; /* Structure for info on cursor positioning */
138 extern short ospeed
; /* Output speed (from sg_ospeed) */
140 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
144 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
145 "Clear frame FRAME and output again what is supposed to appear on it.")
151 CHECK_LIVE_FRAME (frame
, 0);
154 /* set_terminal_modes (); */
156 clear_frame_records (f
);
159 windows_or_buffers_changed
++;
160 /* Mark all windows as INaccurate,
161 so that every window will have its redisplay done. */
162 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
171 XSET (frame
, Lisp_Frame
, f
);
172 Fredraw_frame (frame
);
177 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, "",
178 "Clear frame FRAME and output again what is supposed to appear on it.")
183 set_terminal_modes ();
187 clear_frame_records (0);
188 windows_or_buffers_changed
++;
189 /* Mark all windows as INaccurate,
190 so that every window will have its redisplay done. */
191 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
197 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
198 "Clear and redisplay all visible frames.")
201 Lisp_Object tail
, frame
;
203 FOR_EACH_FRAME (tail
, frame
)
204 if (FRAME_VISIBLE_P (XFRAME (frame
)))
205 Fredraw_frame (frame
);
210 /* This is used when frame_garbaged is set.
211 Redraw the individual frames marked as garbaged. */
214 redraw_garbaged_frames ()
216 Lisp_Object tail
, frame
;
218 FOR_EACH_FRAME (tail
, frame
)
219 if (FRAME_VISIBLE_P (XFRAME (frame
))
220 && FRAME_GARBAGED_P (XFRAME (frame
)))
221 Fredraw_frame (frame
);
225 static struct frame_glyphs
*
226 make_frame_glyphs (frame
, empty
)
227 register FRAME_PTR frame
;
231 register width
= FRAME_WIDTH (frame
);
232 register height
= FRAME_HEIGHT (frame
);
233 register struct frame_glyphs
*new =
234 (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
236 SET_GLYPHS_FRAME (new, frame
);
237 new->height
= height
;
239 new->used
= (int *) xmalloc (height
* sizeof (int));
240 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
241 new->highlight
= (char *) xmalloc (height
* sizeof (char));
242 new->enable
= (char *) xmalloc (height
* sizeof (char));
243 bzero (new->enable
, height
* sizeof (char));
244 new->bufp
= (int *) xmalloc (height
* sizeof (int));
246 #ifdef HAVE_X_WINDOWS
247 if (FRAME_X_P (frame
))
249 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
250 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
251 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
252 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
253 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
259 /* Make the buffer used by decode_mode_spec. This buffer is also
260 used as temporary storage when updating the frame. See scroll.c. */
261 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
263 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
264 bzero (new->total_contents
, total_glyphs
);
268 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
270 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
271 bzero (new->total_contents
, total_glyphs
);
272 for (i
= 0; i
< height
; i
++)
273 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
280 free_frame_glyphs (frame
, glyphs
)
282 struct frame_glyphs
*glyphs
;
284 if (glyphs
->total_contents
)
285 xfree (glyphs
->total_contents
);
287 xfree (glyphs
->used
);
288 xfree (glyphs
->glyphs
);
289 xfree (glyphs
->highlight
);
290 xfree (glyphs
->enable
);
291 xfree (glyphs
->bufp
);
293 #ifdef HAVE_X_WINDOWS
294 if (FRAME_X_P (frame
))
296 xfree (glyphs
->top_left_x
);
297 xfree (glyphs
->top_left_y
);
298 xfree (glyphs
->pix_width
);
299 xfree (glyphs
->pix_height
);
300 xfree (glyphs
->max_ascent
);
308 remake_frame_glyphs (frame
)
311 if (FRAME_CURRENT_GLYPHS (frame
))
312 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
313 if (FRAME_DESIRED_GLYPHS (frame
))
314 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
315 if (FRAME_TEMP_GLYPHS (frame
))
316 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
318 if (FRAME_MESSAGE_BUF (frame
))
320 /* Reallocate the frame's message buffer; remember that
321 echo_area_glyphs may be pointing here. */
322 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
324 FRAME_MESSAGE_BUF (frame
)
325 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
326 FRAME_WIDTH (frame
) + 1);
328 if (echo_area_glyphs
== old_message_buf
)
329 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
330 if (previous_echo_glyphs
== old_message_buf
)
331 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
334 FRAME_MESSAGE_BUF (frame
)
335 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
337 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
338 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
339 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
340 SET_FRAME_GARBAGED (frame
);
343 /* Return the hash code of contents of line VPOS in frame-matrix M. */
346 line_hash_code (m
, vpos
)
347 register struct frame_glyphs
*m
;
350 register GLYPH
*body
, *end
;
353 if (!m
->enable
[vpos
])
356 /* Give all highlighted lines the same hash code
357 so as to encourage scrolling to leave them in place. */
358 if (m
->highlight
[vpos
])
361 body
= m
->glyphs
[vpos
];
363 if (must_write_spaces
)
370 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
379 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
387 /* Return number of characters in line in M at vpos VPOS,
388 except don't count leading and trailing spaces
389 unless the terminal requires those to be explicitly output. */
392 line_draw_cost (m
, vpos
)
393 struct frame_glyphs
*m
;
396 register GLYPH
*beg
= m
->glyphs
[vpos
];
397 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
399 register int tlen
= GLYPH_TABLE_LENGTH
;
400 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
402 /* Ignore trailing and leading spaces if we can. */
403 if (!must_write_spaces
)
405 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
408 return (0); /* All blank line. */
410 while (*beg
== SPACEGLYPH
)
414 /* If we don't have a glyph-table, each glyph is one character,
415 so return the number of glyphs. */
419 /* Otherwise, scan the glyphs and accumulate their total size in I. */
421 while ((beg
<= end
) && *beg
)
423 register GLYPH g
= *beg
++;
425 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
428 i
+= GLYPH_LENGTH (tbase
, g
);
433 /* The functions on this page are the interface from xdisp.c to redisplay.
435 The only other interface into redisplay is through setting
436 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
437 and SET_FRAME_GARBAGED (frame). */
439 /* cancel_line eliminates any request to display a line at position `vpos' */
441 cancel_line (vpos
, frame
)
443 register FRAME_PTR frame
;
445 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
448 clear_frame_records (frame
)
449 register FRAME_PTR frame
;
451 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
454 /* Prepare to display on line VPOS starting at HPOS within it. */
457 get_display_line (frame
, vpos
, hpos
)
458 register FRAME_PTR frame
;
462 register struct frame_glyphs
*glyphs
;
463 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
469 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
472 if (! desired_glyphs
->enable
[vpos
])
474 desired_glyphs
->used
[vpos
] = 0;
475 desired_glyphs
->highlight
[vpos
] = 0;
476 desired_glyphs
->enable
[vpos
] = 1;
479 if (hpos
> desired_glyphs
->used
[vpos
])
481 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
482 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
484 desired_glyphs
->used
[vpos
] = hpos
;
490 /* Like bcopy except never gets confused by overlap. */
493 safe_bcopy (from
, to
, size
)
497 if (size
<= 0 || from
== to
)
500 /* If the source and destination don't overlap, then bcopy can
501 handle it. If they do overlap, but the destination is lower in
502 memory than the source, we'll assume bcopy can handle that. */
503 if (to
< from
|| from
+ size
<= to
)
504 bcopy (from
, to
, size
);
506 /* Otherwise, we'll copy from the end. */
509 register char *endf
= from
+ size
;
510 register char *endt
= to
+ size
;
512 /* If TO - FROM is large, then we should break the copy into
513 nonoverlapping chunks of TO - FROM bytes each. However, if
514 TO - FROM is small, then the bcopy function call overhead
515 makes this not worth it. The crossover point could be about
516 anywhere. Since I don't think the obvious copy loop is too
517 bad, I'm trying to err in its favor. */
522 while (endf
!= from
);
534 bcopy (endf
, endt
, to
- from
);
537 /* If SIZE wasn't a multiple of TO - FROM, there will be a
538 little left over. The amount left over is
539 (endt + (to - from)) - to, which is endt - from. */
540 bcopy (from
, to
, endt
- from
);
545 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
546 DISTANCE may be negative. */
549 rotate_vector (vector
, size
, distance
)
554 char *temp
= (char *) alloca (size
);
559 bcopy (vector
, temp
+ distance
, size
- distance
);
560 bcopy (vector
+ size
- distance
, temp
, distance
);
561 bcopy (temp
, vector
, size
);
564 /* Scroll lines from vpos FROM up to but not including vpos END
565 down by AMOUNT lines (AMOUNT may be negative).
566 Returns nonzero if done, zero if terminal cannot scroll them. */
569 scroll_frame_lines (frame
, from
, end
, amount
)
570 register FRAME_PTR frame
;
571 int from
, end
, amount
;
574 register struct frame_glyphs
*current_frame
575 = FRAME_CURRENT_GLYPHS (frame
);
577 if (!line_ins_del_ok
)
585 update_begin (frame
);
586 set_terminal_window (end
+ amount
);
587 if (!scroll_region_ok
)
588 ins_del_lines (end
, -amount
);
589 ins_del_lines (from
, amount
);
590 set_terminal_window (0);
592 rotate_vector (current_frame
->glyphs
+ from
,
593 sizeof (GLYPH
*) * (end
+ amount
- from
),
594 amount
* sizeof (GLYPH
*));
596 safe_bcopy (current_frame
->used
+ from
,
597 current_frame
->used
+ from
+ amount
,
598 (end
- from
) * sizeof current_frame
->used
[0]);
600 safe_bcopy (current_frame
->highlight
+ from
,
601 current_frame
->highlight
+ from
+ amount
,
602 (end
- from
) * sizeof current_frame
->highlight
[0]);
604 safe_bcopy (current_frame
->enable
+ from
,
605 current_frame
->enable
+ from
+ amount
,
606 (end
- from
) * sizeof current_frame
->enable
[0]);
608 /* Mark the lines made empty by scrolling as enabled, empty and
610 bzero (current_frame
->used
+ from
,
611 amount
* sizeof current_frame
->used
[0]);
612 bzero (current_frame
->highlight
+ from
,
613 amount
* sizeof current_frame
->highlight
[0]);
614 for (i
= from
; i
< from
+ amount
; i
++)
616 current_frame
->glyphs
[i
][0] = '\0';
617 current_frame
->enable
[i
] = 1;
620 safe_bcopy (current_frame
->bufp
+ from
,
621 current_frame
->bufp
+ from
+ amount
,
622 (end
- from
) * sizeof current_frame
->bufp
[0]);
624 #ifdef HAVE_X_WINDOWS
625 if (FRAME_X_P (frame
))
627 safe_bcopy (current_frame
->top_left_x
+ from
,
628 current_frame
->top_left_x
+ from
+ amount
,
629 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
631 safe_bcopy (current_frame
->top_left_y
+ from
,
632 current_frame
->top_left_y
+ from
+ amount
,
633 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
635 safe_bcopy (current_frame
->pix_width
+ from
,
636 current_frame
->pix_width
+ from
+ amount
,
637 (end
- from
) * sizeof current_frame
->pix_width
[0]);
639 safe_bcopy (current_frame
->pix_height
+ from
,
640 current_frame
->pix_height
+ from
+ amount
,
641 (end
- from
) * sizeof current_frame
->pix_height
[0]);
643 safe_bcopy (current_frame
->max_ascent
+ from
,
644 current_frame
->max_ascent
+ from
+ amount
,
645 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
647 #endif /* HAVE_X_WINDOWS */
653 update_begin (frame
);
654 set_terminal_window (end
);
655 ins_del_lines (from
+ amount
, amount
);
656 if (!scroll_region_ok
)
657 ins_del_lines (end
+ amount
, -amount
);
658 set_terminal_window (0);
660 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
661 sizeof (GLYPH
*) * (end
- from
- amount
),
662 amount
* sizeof (GLYPH
*));
664 safe_bcopy (current_frame
->used
+ from
,
665 current_frame
->used
+ from
+ amount
,
666 (end
- from
) * sizeof current_frame
->used
[0]);
668 safe_bcopy (current_frame
->highlight
+ from
,
669 current_frame
->highlight
+ from
+ amount
,
670 (end
- from
) * sizeof current_frame
->highlight
[0]);
672 safe_bcopy (current_frame
->enable
+ from
,
673 current_frame
->enable
+ from
+ amount
,
674 (end
- from
) * sizeof current_frame
->enable
[0]);
676 /* Mark the lines made empty by scrolling as enabled, empty and
678 bzero (current_frame
->used
+ end
+ amount
,
679 - amount
* sizeof current_frame
->used
[0]);
680 bzero (current_frame
->highlight
+ end
+ amount
,
681 - amount
* sizeof current_frame
->highlight
[0]);
682 for (i
= end
+ amount
; i
< end
; i
++)
684 current_frame
->glyphs
[i
][0] = '\0';
685 current_frame
->enable
[i
] = 1;
688 safe_bcopy (current_frame
->bufp
+ from
,
689 current_frame
->bufp
+ from
+ amount
,
690 (end
- from
) * sizeof current_frame
->bufp
[0]);
692 #ifdef HAVE_X_WINDOWS
693 if (FRAME_X_P (frame
))
695 safe_bcopy (current_frame
->top_left_x
+ from
,
696 current_frame
->top_left_x
+ from
+ amount
,
697 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
699 safe_bcopy (current_frame
->top_left_y
+ from
,
700 current_frame
->top_left_y
+ from
+ amount
,
701 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
703 safe_bcopy (current_frame
->pix_width
+ from
,
704 current_frame
->pix_width
+ from
+ amount
,
705 (end
- from
) * sizeof current_frame
->pix_width
[0]);
707 safe_bcopy (current_frame
->pix_height
+ from
,
708 current_frame
->pix_height
+ from
+ amount
,
709 (end
- from
) * sizeof current_frame
->pix_height
[0]);
711 safe_bcopy (current_frame
->max_ascent
+ from
,
712 current_frame
->max_ascent
+ from
+ amount
,
713 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
715 #endif /* HAVE_X_WINDOWS */
722 /* After updating a window W that isn't the full frame wide,
723 copy all the columns that W does not occupy
724 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
725 so that update_frame will not change those columns. */
727 preserve_other_columns (w
)
731 register struct frame_glyphs
*current_frame
, *desired_frame
;
732 register FRAME_PTR frame
= XFRAME (w
->frame
);
733 int start
= XFASTINT (w
->left
);
734 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
735 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
737 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
738 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
740 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
742 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
748 bcopy (current_frame
->glyphs
[vpos
],
749 desired_frame
->glyphs
[vpos
],
750 start
* sizeof (current_frame
->glyphs
[vpos
]));
751 len
= min (start
, current_frame
->used
[vpos
]);
752 if (desired_frame
->used
[vpos
] < len
)
753 desired_frame
->used
[vpos
] = len
;
755 if (current_frame
->used
[vpos
] > end
756 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
758 while (desired_frame
->used
[vpos
] < end
)
759 desired_frame
->glyphs
[vpos
][desired_frame
->used
[vpos
]++]
761 bcopy (current_frame
->glyphs
[vpos
] + end
,
762 desired_frame
->glyphs
[vpos
] + end
,
763 ((current_frame
->used
[vpos
] - end
)
764 * sizeof (current_frame
->glyphs
[vpos
])));
765 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
773 /* If window w does not need to be updated and isn't the full frame wide,
774 copy all the columns that w does occupy
775 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
776 so that update_frame will not change those columns.
778 Have not been able to figure out how to use this correctly. */
780 preserve_my_columns (w
)
783 register int vpos
, fin
;
784 register struct frame_glyphs
*l1
, *l2
;
785 register FRAME_PTR frame
= XFRAME (w
->frame
);
786 int start
= XFASTINT (w
->left
);
787 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
788 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
790 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
792 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
793 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
795 if (l2
->length
> start
&& l1
->length
< l2
->length
)
798 if (fin
> end
) fin
= end
;
799 while (l1
->length
< start
)
800 l1
->body
[l1
->length
++] = ' ';
801 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
810 /* On discovering that the redisplay for a window was no good,
811 cancel the columns of that window, so that when the window is
812 displayed over again get_display_line will not complain. */
814 cancel_my_columns (w
)
818 register struct frame_glyphs
*desired_glyphs
=
819 FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
820 register int start
= XFASTINT (w
->left
);
821 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
823 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
824 if (desired_glyphs
->enable
[vpos
]
825 && desired_glyphs
->used
[vpos
] >= start
)
826 desired_glyphs
->used
[vpos
] = start
;
829 /* These functions try to perform directly and immediately on the frame
830 the necessary output for one change in the buffer.
831 They may return 0 meaning nothing was done if anything is difficult,
832 or 1 meaning the output was performed properly.
833 They assume that the frame was up to date before the buffer
834 change being displayed. They make various other assumptions too;
835 see command_loop_1 where these are called. */
838 direct_output_for_insert (g
)
841 register FRAME_PTR frame
= selected_frame
;
842 register struct frame_glyphs
*current_frame
843 = FRAME_CURRENT_GLYPHS (frame
);
845 #ifndef COMPILER_REGISTER_BUG
847 #endif /* COMPILER_REGISTER_BUG */
848 struct window
*w
= XWINDOW (selected_window
);
849 #ifndef COMPILER_REGISTER_BUG
851 #endif /* COMPILER_REGISTER_BUG */
852 int hpos
= FRAME_CURSOR_X (frame
);
853 #ifndef COMPILER_REGISTER_BUG
855 #endif /* COMPILER_REGISTER_BUG */
856 int vpos
= FRAME_CURSOR_Y (frame
);
858 /* Give up if about to continue line. */
859 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
861 /* Avoid losing if cursor is in invisible text off left margin */
862 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
864 /* Give up if cursor outside window (in minibuf, probably) */
865 || cursor_in_echo_area
866 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
867 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
869 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
870 || !display_completed
872 /* Give up if buffer appears in two places. */
875 /* Give up if w is minibuffer and a message is being displayed there */
876 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
880 #ifdef HAVE_X_WINDOWS
882 int face
= compute_char_face (frame
, w
, point
- 1, -1, -1, &dummy
);
887 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (g
, face
);
889 unchanged_modified
= MODIFF
;
890 beg_unchanged
= GPT
- BEG
;
891 XFASTINT (w
->last_point
) = point
;
892 XFASTINT (w
->last_point_x
) = hpos
;
893 XFASTINT (w
->last_modified
) = MODIFF
;
895 reassert_line_highlight (0, vpos
);
896 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
898 ++FRAME_CURSOR_X (frame
);
899 if (hpos
== current_frame
->used
[vpos
])
901 current_frame
->used
[vpos
] = hpos
+ 1;
902 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
909 direct_output_forward_char (n
)
912 register FRAME_PTR frame
= selected_frame
;
913 register struct window
*w
= XWINDOW (selected_window
);
915 /* Avoid losing if cursor is in invisible text off left margin
916 or about to go off either side of window. */
917 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
918 && (XINT (w
->hscroll
) || n
< 0))
920 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
921 || cursor_in_echo_area
)
924 /* Can't use direct output if highlighting a region. */
925 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
928 FRAME_CURSOR_X (frame
) += n
;
929 XFASTINT (w
->last_point_x
) = FRAME_CURSOR_X (frame
);
930 XFASTINT (w
->last_point
) = point
;
931 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
936 static void update_line ();
938 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
939 Value is nonzero if redisplay stopped due to pending input.
940 FORCE nonzero means do not stop for pending input. */
943 update_frame (f
, force
, inhibit_hairy_id
)
946 int inhibit_hairy_id
;
948 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (f
);
949 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (f
);
952 int preempt_count
= baud_rate
/ 2400 + 1;
953 extern input_pending
;
954 #ifdef HAVE_X_WINDOWS
955 register int downto
, leftmost
;
958 if (preempt_count
<= 0)
961 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
963 detect_input_pending ();
964 if (input_pending
&& !force
)
972 if (!line_ins_del_ok
)
973 inhibit_hairy_id
= 1;
975 /* See if any of the desired lines are enabled; don't compute for
976 i/d line if just want cursor motion. */
977 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
978 if (desired_frame
->enable
[i
])
981 /* Try doing i/d line, if not yet inhibited. */
982 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
983 force
|= scrolling (f
);
985 /* Update the individual lines as needed. Do bottom line first. */
987 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
988 update_line (f
, FRAME_HEIGHT (f
) - 1);
990 #ifdef HAVE_X_WINDOWS
993 leftmost
= downto
= f
->display
.x
->internal_border_width
;
994 if (desired_frame
->enable
[0])
996 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
997 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
998 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
999 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1000 current_frame
->top_left_x
[0] = leftmost
;
1001 current_frame
->top_left_y
[0] = downto
;
1004 #endif /* HAVE_X_WINDOWS */
1006 /* Now update the rest of the lines. */
1007 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1009 if (desired_frame
->enable
[i
])
1011 if (FRAME_TERMCAP_P (f
))
1013 /* Flush out every so many lines.
1014 Also flush out if likely to have more than 1k buffered
1015 otherwise. I'm told that some telnet connections get
1016 really screwed by more than 1k output at once. */
1017 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1019 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1022 if (preempt_count
== 1)
1024 #ifdef EMACS_OUTQSIZE
1025 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1026 /* Probably not a tty. Ignore the error and reset
1027 * the outq count. */
1028 outq
= PENDING_OUTPUT_COUNT (stdout
);
1032 sleep (outq
/ baud_rate
);
1035 if ((i
- 1) % preempt_count
== 0)
1036 detect_input_pending ();
1040 #ifdef HAVE_X_WINDOWS
1043 current_frame
->top_left_y
[i
] = downto
;
1044 current_frame
->top_left_x
[i
] = leftmost
;
1046 #endif /* HAVE_X_WINDOWS */
1049 #ifdef HAVE_X_WINDOWS
1051 downto
+= current_frame
->pix_height
[i
];
1054 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1056 /* Now just clean up termcap drivers and set cursor, etc. */
1059 if (cursor_in_echo_area
1060 && FRAME_HAS_MINIBUF_P (f
))
1062 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1065 if (cursor_in_echo_area
< 0)
1072 /* If the minibuffer is several lines high, find the last
1073 line that has any text on it. */
1074 row
= FRAME_HEIGHT (f
);
1078 if (current_frame
->enable
[row
])
1079 col
= current_frame
->used
[row
];
1083 while (row
> top
&& col
== 0);
1085 if (col
>= FRAME_WIDTH (f
))
1088 if (row
< FRAME_HEIGHT (f
) - 1)
1093 cursor_to (row
, col
);
1096 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1097 FRAME_WIDTH (f
) - 1), 0));
1103 fflush (termscript
);
1106 /* Here if output is preempted because input is detected. */
1109 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1110 display_completed
= !pause
;
1112 bzero (desired_frame
->enable
, FRAME_HEIGHT (f
));
1116 /* Called when about to quit, to check for doing so
1117 at an improper time. */
1122 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1124 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1126 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1130 /* Decide what insert/delete line to do, and do it */
1132 extern void scrolling_1 ();
1137 int unchanged_at_top
, unchanged_at_bottom
;
1140 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1141 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1142 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1144 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1145 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1146 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1148 /* Compute hash codes of all the lines.
1149 Also calculate number of changed lines,
1150 number of unchanged lines at the beginning,
1151 and number of unchanged lines at the end. */
1154 unchanged_at_top
= 0;
1155 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1156 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1158 /* Give up on this scrolling if some old lines are not enabled. */
1159 if (!current_frame
->enable
[i
])
1161 old_hash
[i
] = line_hash_code (current_frame
, i
);
1162 if (! desired_frame
->enable
[i
])
1163 new_hash
[i
] = old_hash
[i
];
1165 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1167 if (old_hash
[i
] != new_hash
[i
])
1170 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1172 else if (i
== unchanged_at_top
)
1174 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1177 /* If changed lines are few, don't allow preemption, don't scroll. */
1178 if (changed_lines
< baud_rate
/ 2400
1179 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1182 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1183 - unchanged_at_bottom
);
1185 if (scroll_region_ok
)
1186 free_at_end_vpos
-= unchanged_at_bottom
;
1187 else if (memory_below_frame
)
1188 free_at_end_vpos
= -1;
1190 /* If large window, fast terminal and few lines in common between
1191 current frame and desired frame, don't bother with i/d calc. */
1192 if (window_size
>= 18 && baud_rate
> 2400
1194 10 * scrolling_max_lines_saved (unchanged_at_top
,
1195 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1196 old_hash
, new_hash
, draw_cost
)))
1199 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1200 draw_cost
+ unchanged_at_top
- 1,
1201 old_hash
+ unchanged_at_top
- 1,
1202 new_hash
+ unchanged_at_top
- 1,
1203 free_at_end_vpos
- unchanged_at_top
);
1208 /* Return the offset in its buffer of the character at location col, line
1209 in the given window. */
1211 buffer_posn_from_coords (window
, col
, line
)
1212 struct window
*window
;
1215 int window_left
= XFASTINT (window
->left
);
1217 /* The actual width of the window is window->width less one for the
1218 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1220 int window_width
= window_internal_width (window
) - 1;
1222 int startp
= marker_position (window
->start
);
1224 /* Since compute_motion will only operate on the current buffer,
1225 we need to save the old one and restore it when we're done. */
1226 struct buffer
*old_current_buffer
= current_buffer
;
1227 struct position
*posn
;
1229 current_buffer
= XBUFFER (window
->buffer
);
1231 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1232 (window->frame))->bufp to avoid scanning from the very top of
1233 the window, but it isn't maintained correctly, and I'm not even
1234 sure I will keep it. */
1235 posn
= compute_motion (startp
, 0,
1236 (window
== XWINDOW (minibuf_window
) && startp
== 1
1237 ? minibuf_prompt_width
: 0),
1239 window_width
, XINT (window
->hscroll
), 0);
1241 current_buffer
= old_current_buffer
;
1243 /* compute_motion considers frame points past the end of a line
1244 to be *after* the newline, i.e. at the start of the next line.
1245 This is reasonable, but not really what we want. So if the
1246 result is on a line below LINE, back it up one character. */
1247 if (posn
->vpos
> line
)
1248 return posn
->bufpos
- 1;
1250 return posn
->bufpos
;
1257 register GLYPH
*p
= r
;
1258 while (*p
++ == SPACEGLYPH
);
1263 count_match (str1
, str2
)
1266 register GLYPH
*p1
= str1
;
1267 register GLYPH
*p2
= str2
;
1268 while (*p1
++ == *p2
++);
1269 return p1
- str1
- 1;
1272 /* Char insertion/deletion cost vector, from term.c */
1273 extern int *char_ins_del_vector
;
1275 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1278 update_line (frame
, vpos
)
1279 register FRAME_PTR frame
;
1282 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1284 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1286 register struct frame_glyphs
*current_frame
1287 = FRAME_CURRENT_GLYPHS (frame
);
1288 register struct frame_glyphs
*desired_frame
1289 = FRAME_DESIRED_GLYPHS (frame
);
1291 if (desired_frame
->highlight
[vpos
]
1292 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1294 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1295 (current_frame
->enable
[vpos
] ?
1296 current_frame
->used
[vpos
] : 0));
1297 current_frame
->enable
[vpos
] = 0;
1300 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1302 if (! current_frame
->enable
[vpos
])
1308 obody
= current_frame
->glyphs
[vpos
];
1309 olen
= current_frame
->used
[vpos
];
1310 if (! current_frame
->highlight
[vpos
])
1312 if (!must_write_spaces
)
1313 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1318 /* For an inverse-video line, remember we gave it
1319 spaces all the way to the frame edge
1320 so that the reverse video extends all the way across. */
1322 while (olen
< FRAME_WIDTH (frame
) - 1)
1323 obody
[olen
++] = SPACEGLYPH
;
1327 /* One way or another, this will enable the line being updated. */
1328 current_frame
->enable
[vpos
] = 1;
1329 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1330 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1331 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1333 #ifdef HAVE_X_WINDOWS
1334 if (FRAME_X_P (frame
))
1336 current_frame
->pix_width
[vpos
]
1337 = current_frame
->used
[vpos
]
1338 * FONT_WIDTH (frame
->display
.x
->font
);
1339 current_frame
->pix_height
[vpos
]
1340 = FONT_HEIGHT (frame
->display
.x
->font
);
1342 #endif /* HAVE_X_WINDOWS */
1344 if (!desired_frame
->enable
[vpos
])
1350 nbody
= desired_frame
->glyphs
[vpos
];
1351 nlen
= desired_frame
->used
[vpos
];
1353 /* Pretend trailing spaces are not there at all,
1354 unless for one reason or another we must write all spaces. */
1355 if (! desired_frame
->highlight
[vpos
])
1357 if (!must_write_spaces
)
1358 /* We know that the previous character byte contains 0. */
1359 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1364 /* For an inverse-video line, give it extra trailing spaces
1365 all the way to the frame edge
1366 so that the reverse video extends all the way across. */
1368 while (nlen
< FRAME_WIDTH (frame
) - 1)
1369 nbody
[nlen
++] = SPACEGLYPH
;
1372 /* If there's no i/d char, quickly do the best we can without it. */
1373 if (!char_ins_del_ok
)
1378 if (FRAME_X_P (frame
))
1380 /* Under X, erase everything we are going to rewrite,
1381 and rewrite everything from the first char that's changed.
1382 This is part of supporting fonts like Courier
1383 whose chars can overlap outside the char width. */
1384 for (i
= 0; i
< nlen
; i
++)
1385 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1388 cursor_to (vpos
, i
);
1390 clear_end_of_line (olen
);
1391 write_glyphs (nbody
+ i
, nlen
- i
);
1396 for (i
= 0; i
< nlen
; i
++)
1398 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1400 cursor_to (vpos
, i
);
1401 for (j
= 1; (i
+ j
< nlen
&&
1402 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1405 /* Output this run of non-matching chars. */
1406 write_glyphs (nbody
+ i
, j
);
1409 /* Now find the next non-match. */
1413 /* Clear the rest of the line, or the non-clear part of it. */
1416 cursor_to (vpos
, nlen
);
1417 clear_end_of_line (olen
);
1420 /* Exchange contents between current_frame and new_frame. */
1421 temp
= desired_frame
->glyphs
[vpos
];
1422 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1423 current_frame
->glyphs
[vpos
] = temp
;
1430 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1431 ? 0 : count_blanks (nbody
);
1434 cursor_to (vpos
, nsp
);
1435 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1438 /* Exchange contents between current_frame and new_frame. */
1439 temp
= desired_frame
->glyphs
[vpos
];
1440 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1441 current_frame
->glyphs
[vpos
] = temp
;
1450 /* Compute number of leading blanks in old and new contents. */
1451 osp
= count_blanks (obody
);
1452 if (!desired_frame
->highlight
[vpos
])
1453 nsp
= count_blanks (nbody
);
1457 /* Compute number of matching chars starting with first nonblank. */
1458 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1460 /* Spaces in new match implicit space past the end of old. */
1461 /* A bug causing this to be a no-op was fixed in 18.29. */
1462 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1465 while (np1
[begmatch
] == SPACEGLYPH
)
1469 /* Avoid doing insert/delete char
1470 just cause number of leading spaces differs
1471 when the following text does not match. */
1472 if (begmatch
== 0 && osp
!= nsp
)
1473 osp
= nsp
= min (osp
, nsp
);
1475 /* Find matching characters at end of line */
1478 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1479 while (op1
> op2
&& op1
[-1] == np1
[-1])
1484 endmatch
= obody
+ olen
- op1
;
1486 /* Put correct value back in nbody[nlen].
1487 This is important because direct_output_for_insert
1488 can write into the line at a later point.
1489 If this screws up the zero at the end of the line, re-establish it. */
1493 /* tem gets the distance to insert or delete.
1494 endmatch is how many characters we save by doing so.
1497 tem
= (nlen
- nsp
) - (olen
- osp
);
1499 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1502 /* nsp - osp is the distance to insert or delete.
1503 If that is nonzero, begmatch is known to be nonzero also.
1504 begmatch + endmatch is how much we save by doing the ins/del.
1508 && (!char_ins_del_ok
1509 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1513 osp
= nsp
= min (osp
, nsp
);
1516 /* Now go through the line, inserting, writing and
1517 deleting as appropriate. */
1521 cursor_to (vpos
, nsp
);
1522 delete_glyphs (osp
- nsp
);
1526 /* If going to delete chars later in line
1527 and insert earlier in the line,
1528 must delete first to avoid losing data in the insert */
1529 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1531 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1532 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1533 olen
= nlen
- (nsp
- osp
);
1535 cursor_to (vpos
, osp
);
1536 insert_glyphs ((char *)0, nsp
- osp
);
1540 tem
= nsp
+ begmatch
+ endmatch
;
1541 if (nlen
!= tem
|| olen
!= tem
)
1543 cursor_to (vpos
, nsp
+ begmatch
);
1544 if (!endmatch
|| nlen
== olen
)
1546 /* If new text being written reaches right margin,
1547 there is no need to do clear-to-eol at the end.
1548 (and it would not be safe, since cursor is not
1549 going to be "at the margin" after the text is done) */
1550 if (nlen
== FRAME_WIDTH (frame
))
1552 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1556 /* the following code loses disastrously if tem == nlen.
1557 Rather than trying to fix that case, I am trying the simpler
1558 solution found above. */
1560 /* If the text reaches to the right margin,
1561 it will lose one way or another (depending on AutoWrap)
1562 to clear to end of line after outputting all the text.
1563 So pause with one character to go and clear the line then. */
1564 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1566 /* endmatch must be zero, and tem must equal nsp + begmatch */
1567 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1568 clear_end_of_line (olen
);
1569 olen
= 0; /* Don't let it be cleared again later */
1570 write_glyphs (nbody
+ nlen
- 1, 1);
1573 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1574 #endif /* OBSOLETE */
1577 else if (nlen
> olen
)
1579 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1580 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1583 else if (olen
> nlen
)
1585 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1586 delete_glyphs (olen
- nlen
);
1592 /* If any unerased characters remain after the new line, erase them. */
1595 cursor_to (vpos
, nlen
);
1596 clear_end_of_line (olen
);
1599 /* Exchange contents between current_frame and new_frame. */
1600 temp
= desired_frame
->glyphs
[vpos
];
1601 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1602 current_frame
->glyphs
[vpos
] = temp
;
1605 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1606 1, 1, "FOpen termscript file: ",
1607 "Start writing all terminal output to FILE as well as the terminal.\n\
1608 FILE = nil means just close any termscript file currently open.")
1612 if (termscript
!= 0) fclose (termscript
);
1617 file
= Fexpand_file_name (file
, Qnil
);
1618 termscript
= fopen (XSTRING (file
)->data
, "w");
1619 if (termscript
== 0)
1620 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1628 window_change_signal ()
1632 int old_errno
= errno
;
1634 get_frame_size (&width
, &height
);
1636 /* The frame size change obviously applies to a termcap-controlled
1637 frame. Find such a frame in the list, and assume it's the only
1638 one (since the redisplay code always writes to stdout, not a
1639 FILE * specified in the frame structure). Record the new size,
1640 but don't reallocate the data structures now. Let that be done
1641 later outside of the signal handler. */
1644 Lisp_Object tail
, frame
;
1646 FOR_EACH_FRAME (tail
, frame
)
1648 if (FRAME_TERMCAP_P (XFRAME (frame
)))
1650 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
1656 signal (SIGWINCH
, window_change_signal
);
1659 #endif /* SIGWINCH */
1662 /* Do any change in frame size that was requested by a signal. */
1664 do_pending_window_change ()
1666 /* If window_change_signal should have run before, run it now. */
1667 while (delayed_size_change
)
1669 Lisp_Object tail
, frame
;
1671 delayed_size_change
= 0;
1673 FOR_EACH_FRAME (tail
, frame
)
1675 FRAME_PTR f
= XFRAME (frame
);
1677 int height
= FRAME_NEW_HEIGHT (f
);
1678 int width
= FRAME_NEW_WIDTH (f
);
1680 if (height
!= 0 || width
!= 0)
1681 change_frame_size (f
, height
, width
, 0, 0);
1687 /* Change the frame height and/or width. Values may be given as zero to
1688 indicate no change is to take place.
1690 If DELAY is non-zero, then assume we're being called from a signal
1691 handler, and queue the change for later - perhaps the next
1692 redisplay. Since this tries to resize windows, we can't call it
1693 from a signal handler. */
1695 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
1696 register FRAME_PTR frame
;
1697 int newheight
, newwidth
, pretend
;
1699 /* If we can't deal with the change now, queue it for later. */
1702 FRAME_NEW_HEIGHT (frame
) = newheight
;
1703 FRAME_NEW_WIDTH (frame
) = newwidth
;
1704 delayed_size_change
= 1;
1708 /* This size-change overrides any pending one for this frame. */
1709 FRAME_NEW_HEIGHT (frame
) = 0;
1710 FRAME_NEW_WIDTH (frame
) = 0;
1712 /* If an argument is zero, set it to the current value. */
1713 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
1714 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
1716 /* Round up to the smallest acceptable size. */
1717 check_frame_size (frame
, &newheight
, &newwidth
);
1719 /* If we're not changing the frame size, quit now. */
1720 if (newheight
== FRAME_HEIGHT (frame
)
1721 && newwidth
== FRAME_WIDTH (frame
))
1724 if (newheight
!= FRAME_HEIGHT (frame
))
1726 if (FRAME_HAS_MINIBUF_P (frame
)
1727 && ! FRAME_MINIBUF_ONLY_P (frame
))
1729 /* Frame has both root and minibuffer. */
1730 set_window_height (FRAME_ROOT_WINDOW (frame
),
1731 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
1732 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
)
1734 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
1737 /* Frame has just one top-level window. */
1738 set_window_height (FRAME_ROOT_WINDOW (frame
),
1739 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
1741 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1742 FrameRows
= newheight
;
1745 if (frame
->output_method
== output_termcap
)
1747 frame_height
= newheight
;
1749 FrameRows
= newheight
;
1754 if (newwidth
!= FRAME_WIDTH (frame
))
1756 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
1757 if (FRAME_HAS_MINIBUF_P (frame
))
1758 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
1760 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1761 FrameCols
= newwidth
;
1763 if (frame
->output_method
== output_termcap
)
1765 frame_width
= newwidth
;
1767 FrameCols
= newwidth
;
1772 FRAME_HEIGHT (frame
) = newheight
;
1773 FRAME_WIDTH (frame
) = newwidth
;
1775 remake_frame_glyphs (frame
);
1776 calculate_costs (frame
);
1779 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
1780 Ssend_string_to_terminal
, 1, 1, 0,
1781 "Send STRING to the terminal without alteration.\n\
1782 Control characters in STRING will have terminal-dependent effects.")
1786 CHECK_STRING (str
, 0);
1787 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
1791 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
1792 fflush (termscript
);
1797 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
1798 "Beep, or flash the screen.\n\
1799 Also, unless an argument is given,\n\
1800 terminate any keyboard macro currently executing.")
1822 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
1823 error ("Keyboard macro terminated by a command ringing the bell");
1829 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
1830 "Pause, without updating display, for SECONDS seconds.\n\
1831 SECONDS may be a floating-point value, meaning that you can wait for a\n\
1832 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
1833 additional wait period, in milliseconds; this may be useful if your\n\
1834 Emacs was built without floating point support.\n\
1835 \(Not all operating systems support waiting for a fraction of a second.)")
1836 (seconds
, milliseconds
)
1837 Lisp_Object seconds
, milliseconds
;
1841 if (NILP (milliseconds
))
1842 XSET (milliseconds
, Lisp_Int
, 0);
1844 CHECK_NUMBER (milliseconds
, 1);
1845 usec
= XINT (milliseconds
) * 1000;
1847 #ifdef LISP_FLOAT_TYPE
1849 double duration
= extract_float (seconds
);
1850 sec
= (int) duration
;
1851 usec
+= (duration
- sec
) * 1000000;
1854 CHECK_NUMBER (seconds
, 0);
1855 sec
= XINT (seconds
);
1858 #ifndef EMACS_HAS_USECS
1859 if (sec
== 0 && usec
!= 0)
1860 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
1863 /* Assure that 0 <= usec < 1000000. */
1866 /* We can't rely on the rounding being correct if user is negative. */
1867 if (-1000000 < usec
)
1868 sec
--, usec
+= 1000000;
1870 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
1873 sec
+= usec
/ 1000000, usec
%= 1000000;
1881 XFASTINT (zero
) = 0;
1882 wait_reading_process_input (sec
, usec
, zero
, 0);
1885 /* We should always have wait_reading_process_input; we have a dummy
1886 implementation for systems which don't support subprocesses. */
1888 /* No wait_reading_process_input */
1895 /* The reason this is done this way
1896 (rather than defined (H_S) && defined (H_T))
1897 is because the VMS preprocessor doesn't grok `defined' */
1899 EMACS_GET_TIME (end_time
);
1900 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
1901 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
1905 EMACS_GET_TIME (timeout
);
1906 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
1907 if (EMACS_TIME_NEG_P (timeout
)
1908 || !select (1, 0, 0, 0, &timeout
))
1911 #else /* not HAVE_SELECT */
1913 #endif /* HAVE_SELECT */
1914 #endif /* not VMS */
1917 #endif /* no subprocesses */
1922 /* This is just like wait_reading_process_input, except that
1923 it does the redisplay.
1925 It's also just like Fsit_for, except that it can be used for
1926 waiting for input as well. */
1929 sit_for (sec
, usec
, reading
, display
)
1930 int sec
, usec
, reading
, display
;
1932 Lisp_Object read_kbd
;
1934 if (detect_input_pending ())
1938 redisplay_preserve_echo_area ();
1940 if (sec
== 0 && usec
== 0)
1947 XSET (read_kbd
, Lisp_Int
, reading
? -1 : 1);
1948 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
1951 /* wait_reading_process_input should always be available now; it is
1952 simulated in a simple way on systems that don't support
1955 /* No wait_reading_process_input available. */
1961 input_wait_timeout (XINT (arg
));
1963 #ifndef HAVE_TIMEVAL
1965 select (1, &waitchannels
, 0, 0, &timeout_sec
);
1966 #else /* HAVE_TIMEVAL */
1967 timeout
.tv_sec
= sec
;
1968 timeout
.tv_usec
= usec
;
1969 select (1, &waitchannels
, 0, 0, &timeout
);
1970 #endif /* HAVE_TIMEVAL */
1971 #endif /* not VMS */
1976 return detect_input_pending () ? Qnil
: Qt
;
1979 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
1980 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
1981 SECONDS may be a floating-point value, meaning that you can wait for a\n\
1982 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
1983 additional wait period, in milliseconds; this may be useful if your\n\
1984 Emacs was built without floating point support.\n\
1985 \(Not all operating systems support waiting for a fraction of a second.)\n\
1986 Optional third arg non-nil means don't redisplay, just wait for input.\n\
1987 Redisplay is preempted as always if input arrives, and does not happen\n\
1988 if input is available before it starts.\n\
1989 Value is t if waited the full time with no input arriving.")
1990 (seconds
, milliseconds
, nodisp
)
1991 Lisp_Object seconds
, milliseconds
, nodisp
;
1995 if (NILP (milliseconds
))
1996 XSET (milliseconds
, Lisp_Int
, 0);
1998 CHECK_NUMBER (milliseconds
, 1);
1999 usec
= XINT (milliseconds
) * 1000;
2001 #ifdef LISP_FLOAT_TYPE
2003 double duration
= extract_float (seconds
);
2004 sec
= (int) duration
;
2005 usec
+= (duration
- sec
) * 1000000;
2008 CHECK_NUMBER (seconds
, 0);
2009 sec
= XINT (seconds
);
2012 #ifndef EMACS_HAS_USECS
2013 if (usec
!= 0 && sec
== 0)
2014 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2017 return sit_for (sec
, usec
, 0, NILP (nodisp
));
2020 char *terminal_type
;
2022 /* Initialization done when Emacs fork is started, before doing stty. */
2023 /* Determine terminal type and set terminal_driver */
2024 /* Then invoke its decoding routine to set up variables
2025 in the terminal package */
2029 #ifdef HAVE_X_WINDOWS
2030 extern int display_arg
;
2035 cursor_in_echo_area
= 0;
2036 terminal_type
= (char *) 0;
2038 /* Now is the time to initialize this; it's used by init_sys_modes
2040 Vwindow_system
= Qnil
;
2042 /* If the user wants to use a window system, we shouldn't bother
2043 initializing the terminal. This is especially important when the
2044 terminal is so dumb that emacs gives up before and doesn't bother
2045 using the window system.
2047 If the DISPLAY environment variable is set, try to use X, and die
2048 with an error message if that doesn't work. */
2050 #ifdef HAVE_X_WINDOWS
2054 display_arg
= (getenv ("DECW$DISPLAY") != 0);
2056 display_arg
= (getenv ("DISPLAY") != 0);
2060 if (!inhibit_window_system
&& display_arg
)
2062 Vwindow_system
= intern ("x");
2064 Vwindow_system_version
= make_number (11);
2066 Vwindow_system_version
= make_number (10);
2070 #endif /* HAVE_X_WINDOWS */
2072 /* If no window system has been specified, try to use the terminal. */
2075 fprintf (stderr
, "emacs: standard input is not a tty\n");
2079 /* Look at the TERM variable */
2080 terminal_type
= (char *) getenv ("TERM");
2084 fprintf (stderr
, "Please specify your terminal type.\n\
2085 For types defined in VMS, use set term /device=TYPE.\n\
2086 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2087 \(The quotation marks are necessary since terminal types are lower case.)\n");
2089 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2095 /* VMS DCL tends to upcase things, so downcase term type.
2096 Hardly any uppercase letters in terminal types; should be none. */
2098 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2101 strcpy (new, terminal_type
);
2103 for (p
= new; *p
; p
++)
2107 terminal_type
= new;
2111 term_init (terminal_type
);
2113 remake_frame_glyphs (selected_frame
);
2114 calculate_costs (selected_frame
);
2116 /* X and Y coordinates of the cursor between updates. */
2117 FRAME_CURSOR_X (selected_frame
) = 0;
2118 FRAME_CURSOR_Y (selected_frame
) = 0;
2123 #endif /* CANNOT_DUMP */
2124 signal (SIGWINCH
, window_change_signal
);
2125 #endif /* SIGWINCH */
2131 defsubr (&Sredraw_frame
);
2133 defsubr (&Sredraw_display
);
2134 defsubr (&Sopen_termscript
);
2136 defsubr (&Ssit_for
);
2137 defsubr (&Ssleep_for
);
2138 defsubr (&Ssend_string_to_terminal
);
2140 DEFVAR_INT ("baud-rate", &baud_rate
,
2141 "The output baud rate of the terminal.\n\
2142 On most systems, changing this value will affect the amount of padding\n\
2143 and the other strategic decisions made during redisplay.");
2144 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2145 "*Non-nil means invert the entire frame display.\n\
2146 This means everything is in inverse video which otherwise would not be.");
2147 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2148 "*Non-nil means try to flash the frame to represent a bell.");
2149 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2150 "*Non-nil means no need to redraw entire frame after suspending.\n\
2151 A non-nil value is useful if the terminal can automatically preserve\n\
2152 Emacs's frame display when you reenter Emacs.\n\
2153 It is up to you to set this variable if your terminal can do that.");
2154 DEFVAR_LISP ("window-system", &Vwindow_system
,
2155 "A symbol naming the window-system under which Emacs is running\n\
2156 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2157 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2158 "The version number of the window system in use.\n\
2159 For X windows, this is 10 or 11.");
2160 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2161 "Non-nil means put cursor in minibuffer, at end of any message there.");
2162 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2163 "Table defining how to output a glyph code to the frame.\n\
2164 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2165 Each element can be:\n\
2166 integer: a glyph code which this glyph is an alias for.\n\
2167 string: output this glyph using that string (not impl. in X windows).\n\
2168 nil: this glyph mod 256 is char code to output,\n\
2169 and this glyph / 256 is face code for X windows (see `x-set-face').");
2170 Vglyph_table
= Qnil
;
2172 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2173 "Display table to use for buffers that specify none.\n\
2174 See `buffer-display-table' for more information.");
2175 Vstandard_display_table
= Qnil
;
2177 /* Initialize `window-system', unless init_display already decided it. */
2182 Vwindow_system
= Qnil
;
2183 Vwindow_system_version
= Qnil
;