1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 1986, 1987, 1988, 1990,
3 1992 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
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 collectable 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);
167 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
168 "Redraw all frames marked as having their images garbled.")
171 Lisp_Object frame
, tail
;
173 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
175 frame
= XCONS (tail
)->car
;
176 if (XFRAME (frame
)->garbaged
&& XFRAME (frame
)->visible
)
177 Fredraw_frame (frame
);
186 XSET (frame
, Lisp_Frame
, f
);
187 Fredraw_frame (frame
);
190 #else /* not MULTI_FRAME */
192 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, 0,
193 "Clear screen and output again what is supposed to appear on it.")
197 set_terminal_modes ();
201 clear_frame_records (0);
202 windows_or_buffers_changed
++;
203 /* Mark all windows as INaccurate,
204 so that every window will have its redisplay done. */
205 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
209 #endif /* not MULTI_FRAME */
211 static struct frame_glyphs
*
212 make_frame_glyphs (frame
, empty
)
213 register FRAME_PTR frame
;
217 register width
= FRAME_WIDTH (frame
);
218 register height
= FRAME_HEIGHT (frame
);
219 register struct frame_glyphs
*new =
220 (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
222 SET_GLYPHS_FRAME (new, frame
);
223 new->height
= height
;
225 new->used
= (int *) xmalloc (height
* sizeof (int));
226 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
227 new->highlight
= (char *) xmalloc (height
* sizeof (char));
228 new->enable
= (char *) xmalloc (height
* sizeof (char));
229 bzero (new->enable
, height
* sizeof (char));
230 new->bufp
= (int *) xmalloc (height
* sizeof (int));
232 #ifdef HAVE_X_WINDOWS
233 if (FRAME_X_P (frame
))
235 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
236 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
237 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
238 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
239 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
245 /* Make the buffer used by decode_mode_spec. This buffer is also
246 used as temporary storage when updating the frame. See scroll.c. */
247 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
249 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
250 bzero (new->total_contents
, total_glyphs
);
254 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
256 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
257 bzero (new->total_contents
, total_glyphs
);
258 for (i
= 0; i
< height
; i
++)
259 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
266 free_frame_glyphs (frame
, glyphs
)
268 struct frame_glyphs
*glyphs
;
270 if (glyphs
->total_contents
)
271 free (glyphs
->total_contents
);
274 free (glyphs
->glyphs
);
275 free (glyphs
->highlight
);
276 free (glyphs
->enable
);
279 #ifdef HAVE_X_WINDOWS
280 if (FRAME_X_P (frame
))
282 free (glyphs
->top_left_x
);
283 free (glyphs
->top_left_y
);
284 free (glyphs
->pix_width
);
285 free (glyphs
->pix_height
);
286 free (glyphs
->max_ascent
);
294 remake_frame_glyphs (frame
)
297 if (FRAME_CURRENT_GLYPHS (frame
))
298 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
299 if (FRAME_DESIRED_GLYPHS (frame
))
300 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
301 if (FRAME_TEMP_GLYPHS (frame
))
302 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
304 if (FRAME_MESSAGE_BUF (frame
))
305 FRAME_MESSAGE_BUF (frame
)
306 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
307 FRAME_WIDTH (frame
) + 1);
309 FRAME_MESSAGE_BUF (frame
)
310 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
312 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
313 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
314 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
315 SET_FRAME_GARBAGED (frame
);
318 /* Return the hash code of contents of line VPOS in frame-matrix M. */
321 line_hash_code (m
, vpos
)
322 register struct frame_glyphs
*m
;
325 register GLYPH
*body
, *end
;
328 if (!m
->enable
[vpos
])
331 /* Give all highlighted lines the same hash code
332 so as to encourage scrolling to leave them in place. */
333 if (m
->highlight
[vpos
])
336 body
= m
->glyphs
[vpos
];
338 if (must_write_spaces
)
345 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
354 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
362 /* Return number of characters in line in M at vpos VPOS,
363 except don't count leading and trailing spaces
364 unless the terminal requires those to be explicitly output. */
367 line_draw_cost (m
, vpos
)
368 struct frame_glyphs
*m
;
371 register GLYPH
*beg
= m
->glyphs
[vpos
];
372 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
374 register int tlen
= GLYPH_TABLE_LENGTH
;
375 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
377 /* Ignore trailing and leading spaces if we can. */
378 if (!must_write_spaces
)
380 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
383 return (0); /* All blank line. */
385 while (*beg
== SPACEGLYPH
)
389 /* If we don't have a glyph-table, each glyph is one character,
390 so return the number of glyphs. */
394 /* Otherwise, scan the glyphs and accumulate their total size in I. */
396 while ((beg
<= end
) && *beg
)
398 register GLYPH g
= *beg
++;
400 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
403 i
+= GLYPH_LENGTH (tbase
, g
);
408 /* The functions on this page are the interface from xdisp.c to redisplay.
410 The only other interface into redisplay is through setting
411 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
412 and SET_FRAME_GARBAGED (frame). */
414 /* cancel_line eliminates any request to display a line at position `vpos' */
416 cancel_line (vpos
, frame
)
418 register FRAME_PTR frame
;
420 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
423 clear_frame_records (frame
)
424 register FRAME_PTR frame
;
426 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
429 /* Prepare to display on line VPOS starting at HPOS within it. */
432 get_display_line (frame
, vpos
, hpos
)
433 register FRAME_PTR frame
;
437 register struct frame_glyphs
*glyphs
;
438 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
444 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
447 if (! desired_glyphs
->enable
[vpos
])
449 desired_glyphs
->used
[vpos
] = 0;
450 desired_glyphs
->highlight
[vpos
] = 0;
451 desired_glyphs
->enable
[vpos
] = 1;
454 if (hpos
> desired_glyphs
->used
[vpos
])
456 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
457 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
459 desired_glyphs
->used
[vpos
] = hpos
;
465 /* Like bcopy except never gets confused by overlap. */
468 safe_bcopy (from
, to
, size
)
472 if (size
<= 0 || from
== to
)
475 /* If the source and destination don't overlap, then bcopy can
476 handle it. If they do overlap, but the destination is lower in
477 memory than the source, we'll assume bcopy can handle that. */
478 if (to
< from
|| from
+ size
<= to
)
479 bcopy (from
, to
, size
);
481 /* Otherwise, we'll copy from the end. */
484 register char *endf
= from
+ size
;
485 register char *endt
= to
+ size
;
487 /* If TO - FROM is large, then we should break the copy into
488 nonoverlapping chunks of TO - FROM bytes each. However, if
489 TO - FROM is small, then the bcopy function call overhead
490 makes this not worth it. The crossover point could be about
491 anywhere. Since I don't think the obvious copy loop is too
492 bad, I'm trying to err in its favor. */
497 while (endf
!= from
);
509 bcopy (endf
, endt
, to
- from
);
512 /* If SIZE wasn't a multiple of TO - FROM, there will be a
513 little left over. The amount left over is
514 (endt + (to - from)) - to, which is endt - from. */
515 bcopy (from
, to
, endt
- from
);
520 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
521 DISTANCE may be negative. */
524 rotate_vector (vector
, size
, distance
)
529 char *temp
= (char *) alloca (size
);
534 bcopy (vector
, temp
+ distance
, size
- distance
);
535 bcopy (vector
+ size
- distance
, temp
, distance
);
536 bcopy (temp
, vector
, size
);
539 /* Scroll lines from vpos FROM up to but not including vpos END
540 down by AMOUNT lines (AMOUNT may be negative).
541 Returns nonzero if done, zero if terminal cannot scroll them. */
544 scroll_frame_lines (frame
, from
, end
, amount
)
545 register FRAME_PTR frame
;
546 int from
, end
, amount
;
549 register struct frame_glyphs
*current_frame
550 = FRAME_CURRENT_GLYPHS (frame
);
552 if (!line_ins_del_ok
)
560 update_begin (frame
);
561 set_terminal_window (end
+ amount
);
562 if (!scroll_region_ok
)
563 ins_del_lines (end
, -amount
);
564 ins_del_lines (from
, amount
);
565 set_terminal_window (0);
567 rotate_vector (current_frame
->glyphs
+ from
,
568 sizeof (GLYPH
*) * (end
+ amount
- from
),
569 amount
* sizeof (GLYPH
*));
571 safe_bcopy (current_frame
->used
+ from
,
572 current_frame
->used
+ from
+ amount
,
573 (end
- from
) * sizeof current_frame
->used
[0]);
575 safe_bcopy (current_frame
->highlight
+ from
,
576 current_frame
->highlight
+ from
+ amount
,
577 (end
- from
) * sizeof current_frame
->highlight
[0]);
579 safe_bcopy (current_frame
->enable
+ from
,
580 current_frame
->enable
+ from
+ amount
,
581 (end
- from
) * sizeof current_frame
->enable
[0]);
583 /* Mark the lines made empty by scrolling as enabled, empty and
585 bzero (current_frame
->used
+ from
,
586 amount
* sizeof current_frame
->used
[0]);
587 bzero (current_frame
->highlight
+ from
,
588 amount
* sizeof current_frame
->highlight
[0]);
589 for (i
= from
; i
< from
+ amount
; i
++)
591 current_frame
->glyphs
[i
][0] = '\0';
592 current_frame
->enable
[i
] = 1;
595 safe_bcopy (current_frame
->bufp
+ from
,
596 current_frame
->bufp
+ from
+ amount
,
597 (end
- from
) * sizeof current_frame
->bufp
[0]);
599 #ifdef HAVE_X_WINDOWS
600 if (FRAME_X_P (frame
))
602 safe_bcopy (current_frame
->top_left_x
+ from
,
603 current_frame
->top_left_x
+ from
+ amount
,
604 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
606 safe_bcopy (current_frame
->top_left_y
+ from
,
607 current_frame
->top_left_y
+ from
+ amount
,
608 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
610 safe_bcopy (current_frame
->pix_width
+ from
,
611 current_frame
->pix_width
+ from
+ amount
,
612 (end
- from
) * sizeof current_frame
->pix_width
[0]);
614 safe_bcopy (current_frame
->pix_height
+ from
,
615 current_frame
->pix_height
+ from
+ amount
,
616 (end
- from
) * sizeof current_frame
->pix_height
[0]);
618 safe_bcopy (current_frame
->max_ascent
+ from
,
619 current_frame
->max_ascent
+ from
+ amount
,
620 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
622 #endif /* HAVE_X_WINDOWS */
628 update_begin (frame
);
629 set_terminal_window (end
);
630 ins_del_lines (from
+ amount
, amount
);
631 if (!scroll_region_ok
)
632 ins_del_lines (end
+ amount
, -amount
);
633 set_terminal_window (0);
635 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
636 sizeof (GLYPH
*) * (end
- from
- amount
),
637 amount
* sizeof (GLYPH
*));
639 safe_bcopy (current_frame
->used
+ from
,
640 current_frame
->used
+ from
+ amount
,
641 (end
- from
) * sizeof current_frame
->used
[0]);
643 safe_bcopy (current_frame
->highlight
+ from
,
644 current_frame
->highlight
+ from
+ amount
,
645 (end
- from
) * sizeof current_frame
->highlight
[0]);
647 safe_bcopy (current_frame
->enable
+ from
,
648 current_frame
->enable
+ from
+ amount
,
649 (end
- from
) * sizeof current_frame
->enable
[0]);
651 /* Mark the lines made empty by scrolling as enabled, empty and
653 bzero (current_frame
->used
+ end
+ amount
,
654 - amount
* sizeof current_frame
->used
[0]);
655 bzero (current_frame
->highlight
+ end
+ amount
,
656 - amount
* sizeof current_frame
->highlight
[0]);
657 for (i
= end
+ amount
; i
< end
; i
++)
659 current_frame
->glyphs
[i
][0] = '\0';
660 current_frame
->enable
[i
] = 1;
663 safe_bcopy (current_frame
->bufp
+ from
,
664 current_frame
->bufp
+ from
+ amount
,
665 (end
- from
) * sizeof current_frame
->bufp
[0]);
667 #ifdef HAVE_X_WINDOWS
668 if (FRAME_X_P (frame
))
670 safe_bcopy (current_frame
->top_left_x
+ from
,
671 current_frame
->top_left_x
+ from
+ amount
,
672 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
674 safe_bcopy (current_frame
->top_left_y
+ from
,
675 current_frame
->top_left_y
+ from
+ amount
,
676 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
678 safe_bcopy (current_frame
->pix_width
+ from
,
679 current_frame
->pix_width
+ from
+ amount
,
680 (end
- from
) * sizeof current_frame
->pix_width
[0]);
682 safe_bcopy (current_frame
->pix_height
+ from
,
683 current_frame
->pix_height
+ from
+ amount
,
684 (end
- from
) * sizeof current_frame
->pix_height
[0]);
686 safe_bcopy (current_frame
->max_ascent
+ from
,
687 current_frame
->max_ascent
+ from
+ amount
,
688 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
690 #endif /* HAVE_X_WINDOWS */
697 /* After updating a window W that isn't the full frame wide,
698 copy all the columns that W does not occupy
699 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
700 so that update_frame will not change those columns. */
702 preserve_other_columns (w
)
706 register struct frame_glyphs
*current_frame
, *desired_frame
;
707 register FRAME_PTR frame
= XFRAME (w
->frame
);
708 int start
= XFASTINT (w
->left
);
709 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
710 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
712 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
713 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
715 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
717 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
723 bcopy (current_frame
->glyphs
[vpos
],
724 desired_frame
->glyphs
[vpos
], start
);
725 len
= min (start
, current_frame
->used
[vpos
]);
726 if (desired_frame
->used
[vpos
] < len
)
727 desired_frame
->used
[vpos
] = len
;
729 if (current_frame
->used
[vpos
] > end
730 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
732 while (desired_frame
->used
[vpos
] < end
)
733 desired_frame
->glyphs
[vpos
][desired_frame
->used
[vpos
]++]
735 bcopy (current_frame
->glyphs
[vpos
] + end
,
736 desired_frame
->glyphs
[vpos
] + end
,
737 current_frame
->used
[vpos
] - end
);
738 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
746 /* If window w does not need to be updated and isn't the full frame wide,
747 copy all the columns that w does occupy
748 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
749 so that update_frame will not change those columns.
751 Have not been able to figure out how to use this correctly. */
753 preserve_my_columns (w
)
756 register int vpos
, fin
;
757 register struct frame_glyphs
*l1
, *l2
;
758 register FRAME_PTR frame
= XFRAME (w
->frame
);
759 int start
= XFASTINT (w
->left
);
760 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
761 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
763 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
765 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
766 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
768 if (l2
->length
> start
&& l1
->length
< l2
->length
)
771 if (fin
> end
) fin
= end
;
772 while (l1
->length
< start
)
773 l1
->body
[l1
->length
++] = ' ';
774 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
783 /* On discovering that the redisplay for a window was no good,
784 cancel the columns of that window, so that when the window is
785 displayed over again get_display_line will not complain. */
787 cancel_my_columns (w
)
791 register struct frame_glyphs
*desired_glyphs
=
792 FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
793 register int start
= XFASTINT (w
->left
);
794 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
796 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
797 if (desired_glyphs
->enable
[vpos
]
798 && desired_glyphs
->used
[vpos
] >= start
)
799 desired_glyphs
->used
[vpos
] = start
;
802 /* These functions try to perform directly and immediately on the frame
803 the necessary output for one change in the buffer.
804 They may return 0 meaning nothing was done if anything is difficult,
805 or 1 meaning the output was performed properly.
806 They assume that the frame was up to date before the buffer
807 change being displayed. They make various other assumptions too;
808 see command_loop_1 where these are called. */
811 direct_output_for_insert (g
)
814 register FRAME_PTR frame
= selected_frame
;
815 register struct frame_glyphs
*current_frame
816 = FRAME_CURRENT_GLYPHS (frame
);
818 #ifndef COMPILER_REGISTER_BUG
820 #endif /* COMPILER_REGISTER_BUG */
821 struct window
*w
= XWINDOW (selected_window
);
822 #ifndef COMPILER_REGISTER_BUG
824 #endif /* COMPILER_REGISTER_BUG */
825 int hpos
= FRAME_CURSOR_X (frame
);
826 #ifndef COMPILER_REGISTER_BUG
828 #endif /* COMPILER_REGISTER_BUG */
829 int vpos
= FRAME_CURSOR_Y (frame
);
831 /* Give up if about to continue line */
832 if (hpos
- XFASTINT (w
->left
) + 1 + 1 >= XFASTINT (w
->width
)
834 /* Avoid losing if cursor is in invisible text off left margin */
835 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
837 /* Give up if cursor outside window (in minibuf, probably) */
838 || cursor_in_echo_area
839 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
840 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
842 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
843 || !display_completed
845 /* Give up if buffer appears in two places. */
848 /* Give up if w is minibuffer and a message is being displayed there */
849 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
852 current_frame
->glyphs
[vpos
][hpos
] = g
;
853 unchanged_modified
= MODIFF
;
854 beg_unchanged
= GPT
- BEG
;
855 XFASTINT (w
->last_point
) = point
;
856 XFASTINT (w
->last_point_x
) = hpos
;
857 XFASTINT (w
->last_modified
) = MODIFF
;
859 reassert_line_highlight (0, vpos
);
860 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
862 ++FRAME_CURSOR_X (frame
);
863 if (hpos
== current_frame
->used
[vpos
])
865 current_frame
->used
[vpos
] = hpos
+ 1;
866 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
873 direct_output_forward_char (n
)
876 register FRAME_PTR frame
= selected_frame
;
877 register struct window
*w
= XWINDOW (selected_window
);
879 /* Avoid losing if cursor is in invisible text off left margin
880 or about to go off either side of window. */
881 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
882 && (XINT (w
->hscroll
) || n
< 0))
884 && (FRAME_CURSOR_X (frame
) + 1
885 >= (XFASTINT (w
->left
) + XFASTINT (w
->width
)
886 - (XFASTINT (w
->width
) < FRAME_WIDTH (frame
))
888 || cursor_in_echo_area
)
891 FRAME_CURSOR_X (frame
) += n
;
892 XFASTINT (w
->last_point_x
) = FRAME_CURSOR_X (frame
);
893 XFASTINT (w
->last_point
) = point
;
894 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
899 static void update_line ();
901 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
902 Value is nonzero if redisplay stopped due to pending input.
903 FORCE nonzero means do not stop for pending input. */
906 update_frame (f
, force
, inhibit_hairy_id
)
909 int inhibit_hairy_id
;
911 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (f
);
912 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (f
);
915 int preempt_count
= baud_rate
/ 2400 + 1;
916 extern input_pending
;
917 #ifdef HAVE_X_WINDOWS
918 register int downto
, leftmost
;
921 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
923 detect_input_pending ();
924 if (input_pending
&& !force
)
932 if (!line_ins_del_ok
)
933 inhibit_hairy_id
= 1;
935 /* See if any of the desired lines are enabled; don't compute for
936 i/d line if just want cursor motion. */
937 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
938 if (desired_frame
->enable
[i
])
941 /* Try doing i/d line, if not yet inhibited. */
942 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
943 force
|= scrolling (f
);
945 /* Update the individual lines as needed. Do bottom line first. */
947 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
948 update_line (f
, FRAME_HEIGHT (f
) - 1);
950 #ifdef HAVE_X_WINDOWS
953 leftmost
= downto
= f
->display
.x
->internal_border_width
;
954 if (desired_frame
->enable
[0])
956 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
957 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
958 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
959 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
960 current_frame
->top_left_x
[0] = leftmost
;
961 current_frame
->top_left_y
[0] = downto
;
964 #endif /* HAVE_X_WINDOWS */
966 /* Now update the rest of the lines. */
967 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
969 if (desired_frame
->enable
[i
])
971 if (FRAME_TERMCAP_P (f
))
973 /* Flush out every so many lines.
974 Also flush out if likely to have more than 1k buffered
975 otherwise. I'm told that some telnet connections get
976 really screwed by more than 1k output at once. */
977 int outq
= PENDING_OUTPUT_COUNT (stdout
);
979 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
982 if (preempt_count
== 1)
984 #ifdef EMACS_OUTQSIZE
985 if (EMACS_OUTQSIZE (0, &outq
) < 0)
986 /* Probably not a tty. Ignore the error and reset
988 outq
= PENDING_OUTPUT_COUNT (stdout
);
991 sleep (outq
/ baud_rate
);
994 if ((i
- 1) % preempt_count
== 0)
995 detect_input_pending ();
999 #ifdef HAVE_X_WINDOWS
1002 current_frame
->top_left_y
[i
] = downto
;
1003 current_frame
->top_left_x
[i
] = leftmost
;
1005 #endif /* HAVE_X_WINDOWS */
1008 #ifdef HAVE_X_WINDOWS
1010 downto
+= current_frame
->pix_height
[i
];
1013 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1015 /* Now just clean up termcap drivers and set cursor, etc. */
1018 if (cursor_in_echo_area
1019 && FRAME_HAS_MINIBUF_P (f
))
1021 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1024 if (cursor_in_echo_area
< 0)
1031 /* If the minibuffer is several lines high, find the last
1032 line that has any text on it. */
1033 row
= FRAME_HEIGHT (f
);
1037 if (current_frame
->enable
[row
])
1038 col
= current_frame
->used
[row
];
1042 while (row
> top
&& col
== 0);
1044 if (col
>= FRAME_WIDTH (f
))
1047 if (row
< FRAME_HEIGHT (f
) - 1)
1052 cursor_to (row
, col
);
1055 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1056 FRAME_WIDTH (f
) - 1), 0));
1062 fflush (termscript
);
1065 /* Here if output is preempted because input is detected. */
1068 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1069 display_completed
= !pause
;
1071 bzero (desired_frame
->enable
, FRAME_HEIGHT (f
));
1075 /* Called when about to quit, to check for doing so
1076 at an improper time. */
1081 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1083 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1085 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1089 /* Decide what insert/delete line to do, and do it */
1091 extern void scrolling_1 ();
1096 int unchanged_at_top
, unchanged_at_bottom
;
1099 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1100 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1101 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1103 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1104 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1105 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1107 /* Compute hash codes of all the lines.
1108 Also calculate number of changed lines,
1109 number of unchanged lines at the beginning,
1110 and number of unchanged lines at the end. */
1113 unchanged_at_top
= 0;
1114 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1115 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1117 /* Give up on this scrolling if some old lines are not enabled. */
1118 if (!current_frame
->enable
[i
])
1120 old_hash
[i
] = line_hash_code (current_frame
, i
);
1121 if (! desired_frame
->enable
[i
])
1122 new_hash
[i
] = old_hash
[i
];
1124 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1126 if (old_hash
[i
] != new_hash
[i
])
1129 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1131 else if (i
== unchanged_at_top
)
1133 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1136 /* If changed lines are few, don't allow preemption, don't scroll. */
1137 if (changed_lines
< baud_rate
/ 2400
1138 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1141 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1142 - unchanged_at_bottom
);
1144 if (scroll_region_ok
)
1145 free_at_end_vpos
-= unchanged_at_bottom
;
1146 else if (memory_below_frame
)
1147 free_at_end_vpos
= -1;
1149 /* If large window, fast terminal and few lines in common between
1150 current frame and desired frame, don't bother with i/d calc. */
1151 if (window_size
>= 18 && baud_rate
> 2400
1153 10 * scrolling_max_lines_saved (unchanged_at_top
,
1154 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1155 old_hash
, new_hash
, draw_cost
)))
1158 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1159 draw_cost
+ unchanged_at_top
- 1,
1160 old_hash
+ unchanged_at_top
- 1,
1161 new_hash
+ unchanged_at_top
- 1,
1162 free_at_end_vpos
- unchanged_at_top
);
1167 /* Return the offset in its buffer of the character at location col, line
1168 in the given window. */
1170 buffer_posn_from_coords (window
, col
, line
)
1171 struct window
*window
;
1174 int window_left
= XFASTINT (window
->left
);
1176 /* The actual width of the window is window->width less one for the
1177 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1179 int window_width
= (XFASTINT (window
->width
) - 1
1180 - (XFASTINT (window
->width
) + window_left
1181 != FRAME_WIDTH (XFRAME (window
->frame
))));
1183 int startp
= marker_position (window
->start
);
1185 /* Since compute_motion will only operate on the current buffer,
1186 we need to save the old one and restore it when we're done. */
1187 struct buffer
*old_current_buffer
= current_buffer
;
1188 struct position
*posn
;
1190 current_buffer
= XBUFFER (window
->buffer
);
1192 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1193 (window->frame))->bufp to avoid scanning from the very top of
1194 the window, but it isn't maintained correctly, and I'm not even
1195 sure I will keep it. */
1196 posn
= compute_motion (startp
, 0,
1197 (window
== XWINDOW (minibuf_window
) && startp
== 1
1198 ? minibuf_prompt_width
: 0),
1199 ZV
, line
, col
- window_left
,
1200 window_width
, XINT (window
->hscroll
), 0);
1202 current_buffer
= old_current_buffer
;
1204 /* compute_motion considers frame points past the end of a line
1205 to be *after* the newline, i.e. at the start of the next line.
1206 This is reasonable, but not really what we want. So if the
1207 result is on a line below LINE, back it up one character. */
1208 if (posn
->vpos
> line
)
1209 return posn
->bufpos
- 1;
1211 return posn
->bufpos
;
1218 register GLYPH
*p
= r
;
1219 while (*p
++ == SPACEGLYPH
);
1224 count_match (str1
, str2
)
1227 register GLYPH
*p1
= str1
;
1228 register GLYPH
*p2
= str2
;
1229 while (*p1
++ == *p2
++);
1230 return p1
- str1
- 1;
1233 /* Char insertion/deletion cost vector, from term.c */
1234 extern int *char_ins_del_vector
;
1236 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_HEIGHT((f))])
1239 update_line (frame
, vpos
)
1240 register FRAME_PTR frame
;
1243 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1245 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1247 register struct frame_glyphs
*current_frame
1248 = FRAME_CURRENT_GLYPHS (frame
);
1249 register struct frame_glyphs
*desired_frame
1250 = FRAME_DESIRED_GLYPHS (frame
);
1252 if (desired_frame
->highlight
[vpos
]
1253 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1255 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1256 (current_frame
->enable
[vpos
] ?
1257 current_frame
->used
[vpos
] : 0));
1258 current_frame
->enable
[vpos
] = 0;
1261 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1263 if (! current_frame
->enable
[vpos
])
1269 obody
= current_frame
->glyphs
[vpos
];
1270 olen
= current_frame
->used
[vpos
];
1271 if (! current_frame
->highlight
[vpos
])
1273 if (!must_write_spaces
)
1274 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1279 /* For an inverse-video line, remember we gave it
1280 spaces all the way to the frame edge
1281 so that the reverse video extends all the way across. */
1283 while (olen
< FRAME_WIDTH (frame
) - 1)
1284 obody
[olen
++] = SPACEGLYPH
;
1288 /* One way or another, this will enable the line being updated. */
1289 current_frame
->enable
[vpos
] = 1;
1290 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1291 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1292 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1294 #ifdef HAVE_X_WINDOWS
1295 if (FRAME_X_P (frame
))
1297 current_frame
->pix_width
[vpos
]
1298 = current_frame
->used
[vpos
]
1299 * FONT_WIDTH (frame
->display
.x
->font
);
1300 current_frame
->pix_height
[vpos
]
1301 = FONT_HEIGHT (frame
->display
.x
->font
);
1303 #endif /* HAVE_X_WINDOWS */
1305 if (!desired_frame
->enable
[vpos
])
1311 nbody
= desired_frame
->glyphs
[vpos
];
1312 nlen
= desired_frame
->used
[vpos
];
1314 /* Pretend trailing spaces are not there at all,
1315 unless for one reason or another we must write all spaces. */
1316 if (! desired_frame
->highlight
[vpos
])
1318 if (!must_write_spaces
)
1319 /* We know that the previous character byte contains 0. */
1320 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1325 /* For an inverse-video line, give it extra trailing spaces
1326 all the way to the frame edge
1327 so that the reverse video extends all the way across. */
1329 while (nlen
< FRAME_WIDTH (frame
) - 1)
1330 nbody
[nlen
++] = SPACEGLYPH
;
1333 /* If there's no i/d char, quickly do the best we can without it. */
1334 if (!char_ins_del_ok
)
1338 for (i
= 0; i
< nlen
; i
++)
1340 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1342 cursor_to (vpos
, i
);
1343 for (j
= 1; (i
+ j
< nlen
&&
1344 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1347 /* Output this run of non-matching chars. */
1348 write_glyphs (nbody
+ i
, j
);
1351 /* Now find the next non-match. */
1355 /* Clear the rest of the line, or the non-clear part of it. */
1358 cursor_to (vpos
, nlen
);
1359 clear_end_of_line (olen
);
1362 /* Exchange contents between current_frame and new_frame. */
1363 temp
= desired_frame
->glyphs
[vpos
];
1364 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1365 current_frame
->glyphs
[vpos
] = temp
;
1372 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1373 ? 0 : count_blanks (nbody
);
1376 cursor_to (vpos
, nsp
);
1377 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1380 /* Exchange contents between current_frame and new_frame. */
1381 temp
= desired_frame
->glyphs
[vpos
];
1382 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1383 current_frame
->glyphs
[vpos
] = temp
;
1392 /* Compute number of leading blanks in old and new contents. */
1393 osp
= count_blanks (obody
);
1394 if (!desired_frame
->highlight
[vpos
])
1395 nsp
= count_blanks (nbody
);
1399 /* Compute number of matching chars starting with first nonblank. */
1400 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1402 /* Spaces in new match implicit space past the end of old. */
1403 /* A bug causing this to be a no-op was fixed in 18.29. */
1404 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1407 while (np1
[begmatch
] == SPACEGLYPH
)
1411 /* Avoid doing insert/delete char
1412 just cause number of leading spaces differs
1413 when the following text does not match. */
1414 if (begmatch
== 0 && osp
!= nsp
)
1415 osp
= nsp
= min (osp
, nsp
);
1417 /* Find matching characters at end of line */
1420 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1421 while (op1
> op2
&& op1
[-1] == np1
[-1])
1426 endmatch
= obody
+ olen
- op1
;
1428 /* Put correct value back in nbody[nlen].
1429 This is important because direct_output_for_insert
1430 can write into the line at a later point.
1431 If this screws up the zero at the end of the line, re-establish it. */
1435 /* tem gets the distance to insert or delete.
1436 endmatch is how many characters we save by doing so.
1439 tem
= (nlen
- nsp
) - (olen
- osp
);
1441 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1444 /* nsp - osp is the distance to insert or delete.
1445 If that is nonzero, begmatch is known to be nonzero also.
1446 begmatch + endmatch is how much we save by doing the ins/del.
1450 && (!char_ins_del_ok
1451 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1455 osp
= nsp
= min (osp
, nsp
);
1458 /* Now go through the line, inserting, writing and
1459 deleting as appropriate. */
1463 cursor_to (vpos
, nsp
);
1464 delete_glyphs (osp
- nsp
);
1468 /* If going to delete chars later in line
1469 and insert earlier in the line,
1470 must delete first to avoid losing data in the insert */
1471 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1473 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1474 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1475 olen
= nlen
- (nsp
- osp
);
1477 cursor_to (vpos
, osp
);
1478 insert_glyphs ((char *)0, nsp
- osp
);
1482 tem
= nsp
+ begmatch
+ endmatch
;
1483 if (nlen
!= tem
|| olen
!= tem
)
1485 cursor_to (vpos
, nsp
+ begmatch
);
1486 if (!endmatch
|| nlen
== olen
)
1488 /* If new text being written reaches right margin,
1489 there is no need to do clear-to-eol at the end.
1490 (and it would not be safe, since cursor is not
1491 going to be "at the margin" after the text is done) */
1492 if (nlen
== FRAME_WIDTH (frame
))
1494 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1498 /* the following code loses disastrously if tem == nlen.
1499 Rather than trying to fix that case, I am trying the simpler
1500 solution found above. */
1502 /* If the text reaches to the right margin,
1503 it will lose one way or another (depending on AutoWrap)
1504 to clear to end of line after outputting all the text.
1505 So pause with one character to go and clear the line then. */
1506 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1508 /* endmatch must be zero, and tem must equal nsp + begmatch */
1509 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1510 clear_end_of_line (olen
);
1511 olen
= 0; /* Don't let it be cleared again later */
1512 write_glyphs (nbody
+ nlen
- 1, 1);
1515 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1516 #endif /* OBSOLETE */
1519 else if (nlen
> olen
)
1521 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1522 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1525 else if (olen
> nlen
)
1527 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1528 delete_glyphs (olen
- nlen
);
1534 /* If any unerased characters remain after the new line, erase them. */
1537 cursor_to (vpos
, nlen
);
1538 clear_end_of_line (olen
);
1541 /* Exchange contents between current_frame and new_frame. */
1542 temp
= desired_frame
->glyphs
[vpos
];
1543 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1544 current_frame
->glyphs
[vpos
] = temp
;
1547 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1548 1, 1, "FOpen termscript file: ",
1549 "Start writing all terminal output to FILE as well as the terminal.\n\
1550 FILE = nil means just close any termscript file currently open.")
1554 if (termscript
!= 0) fclose (termscript
);
1559 file
= Fexpand_file_name (file
, Qnil
);
1560 termscript
= fopen (XSTRING (file
)->data
, "w");
1561 if (termscript
== 0)
1562 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1570 window_change_signal ()
1574 int old_errno
= errno
;
1576 get_frame_size (&width
, &height
);
1578 /* The frame size change obviously applies to a termcap-controlled
1579 frame. Find such a frame in the list, and assume it's the only
1580 one (since the redisplay code always writes to stdout, not a
1581 FILE * specified in the frame structure). Record the new size,
1582 but don't reallocate the data structures now. Let that be done
1583 later outside of the signal handler. */
1589 FOR_EACH_FRAME (tail
, f
)
1591 if (FRAME_TERMCAP_P (f
))
1593 change_frame_size (f
, height
, width
, 0, 1);
1599 signal (SIGWINCH
, window_change_signal
);
1602 #endif /* SIGWINCH */
1605 /* Do any change in frame size that was requested by a signal. */
1607 do_pending_window_change ()
1609 /* If window_change_signal should have run before, run it now. */
1610 while (delayed_size_change
)
1615 delayed_size_change
= 0;
1617 FOR_EACH_FRAME (tail
, f
)
1619 int height
= FRAME_NEW_HEIGHT (f
);
1620 int width
= FRAME_NEW_WIDTH (f
);
1622 FRAME_NEW_HEIGHT (f
) = 0;
1623 FRAME_NEW_WIDTH (f
) = 0;
1626 change_frame_size (f
, height
, width
, 0, 0);
1632 /* Change the frame height and/or width. Values may be given as zero to
1633 indicate no change is to take place.
1635 If DELAY is non-zero, then assume we're being called from a signal
1636 handler, and queue the change for later - perhaps the next
1637 redisplay. Since this tries to resize windows, we can't call it
1638 from a signal handler. */
1640 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
1641 register FRAME_PTR frame
;
1642 int newheight
, newwidth
, pretend
;
1644 /* If we can't deal with the change now, queue it for later. */
1647 FRAME_NEW_HEIGHT (frame
) = newheight
;
1648 FRAME_NEW_WIDTH (frame
) = newwidth
;
1649 delayed_size_change
= 1;
1653 /* This size-change overrides any pending one for this frame. */
1654 FRAME_NEW_HEIGHT (frame
) = 0;
1655 FRAME_NEW_WIDTH (frame
) = 0;
1657 /* If an arguments is zero, set it to the current value. */
1658 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
1659 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
1661 /* Round up to the smallest acceptable size. */
1662 check_frame_size (frame
, &newheight
, &newwidth
);
1664 /* If we're not changing the frame size, quit now. */
1665 if (newheight
== FRAME_HEIGHT (frame
)
1666 && newwidth
== FRAME_WIDTH (frame
))
1669 if (newheight
!= FRAME_HEIGHT (frame
))
1671 if (FRAME_HAS_MINIBUF_P (frame
)
1672 && ! FRAME_MINIBUF_ONLY_P (frame
))
1674 /* Frame has both root and minibuffer. */
1675 set_window_height (FRAME_ROOT_WINDOW (frame
),
1677 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
)
1679 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
1682 /* Frame has just one top-level window. */
1683 set_window_height (FRAME_ROOT_WINDOW (frame
), newheight
, 0);
1685 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1686 FrameRows
= newheight
;
1689 if (frame
->output_method
== output_termcap
)
1691 frame_height
= newheight
;
1693 FrameRows
= newheight
;
1698 if (newwidth
!= FRAME_WIDTH (frame
))
1700 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
1701 if (FRAME_HAS_MINIBUF_P (frame
))
1702 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
1704 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1705 FrameCols
= newwidth
;
1707 if (frame
->output_method
== output_termcap
)
1709 frame_width
= newwidth
;
1711 FrameCols
= newwidth
;
1716 FRAME_HEIGHT (frame
) = newheight
;
1717 FRAME_WIDTH (frame
) = newwidth
;
1719 remake_frame_glyphs (frame
);
1720 calculate_costs (frame
);
1723 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
1724 Ssend_string_to_terminal
, 1, 1, 0,
1725 "Send STRING to the terminal without alteration.\n\
1726 Control characters in STRING will have terminal-dependent effects.")
1730 CHECK_STRING (str
, 0);
1731 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
1735 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
1736 fflush (termscript
);
1741 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
1742 "Beep, or flash the screen.\n\
1743 Also, unless an argument is given,\n\
1744 terminate any keyboard macro currently executing.")
1766 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
1767 error ("Keyboard macro terminated by a command ringing the bell");
1773 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
1774 "Pause, without updating display, for ARG seconds.\n\
1775 Optional second arg non-nil means ARG is measured in milliseconds.\n\
1776 \(Not all operating systems support milliseconds.)")
1778 Lisp_Object arg
, millisec
;
1783 CHECK_NUMBER (arg
, 0);
1788 if (!NILP (millisec
))
1790 #ifndef EMACS_HAS_USECS
1791 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
1793 usec
= sec
% 1000 * 1000;
1801 XFASTINT (zero
) = 0;
1802 wait_reading_process_input (sec
, usec
, zero
, 0);
1805 #if 0 /* No wait_reading_process_input */
1812 /* The reason this is done this way
1813 (rather than defined (H_S) && defined (H_T))
1814 is because the VMS preprocessor doesn't grok `defined' */
1816 EMACS_GET_TIME (end_time
);
1817 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
1818 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
1822 EMACS_GET_TIME (timeout
);
1823 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
1824 if (EMACS_TIME_NEG_P (timeout
)
1825 || !select (1, 0, 0, 0, &timeout
))
1828 #else /* not HAVE_SELECT */
1830 #endif /* HAVE_SELECT */
1831 #endif /* not VMS */
1834 #endif /* no subprocesses */
1839 /* This is just like wait_reading_process_input, except that
1840 it does the redisplay.
1842 It's also just like Fsit_for, except that it can be used for
1843 waiting for input as well. */
1846 sit_for (sec
, usec
, reading
, display
)
1847 int sec
, usec
, reading
, display
;
1849 Lisp_Object read_kbd
;
1851 if (detect_input_pending ())
1855 redisplay_preserve_echo_area ();
1857 if (sec
== 0 && usec
== 0)
1864 XSET (read_kbd
, Lisp_Int
, reading
? -1 : 1);
1865 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
1868 #if 0 /* No wait_reading_process_input available. */
1874 input_wait_timeout (XINT (arg
));
1876 #ifndef HAVE_TIMEVAL
1878 select (1, &waitchannels
, 0, 0, &timeout_sec
);
1879 #else /* HAVE_TIMEVAL */
1880 timeout
.tv_sec
= sec
;
1881 timeout
.tv_usec
= usec
;
1882 select (1, &waitchannels
, 0, 0, &timeout
);
1883 #endif /* HAVE_TIMEVAL */
1884 #endif /* not VMS */
1889 return detect_input_pending () ? Qnil
: Qt
;
1892 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
1893 "Perform redisplay, then wait for ARG seconds or until input is available.\n\
1894 Optional second arg non-nil means ARG counts in milliseconds.\n\
1895 Optional third arg non-nil means don't redisplay, just wait for input.\n\
1896 Redisplay is preempted as always if input arrives, and does not happen\n\
1897 if input is available before it starts.\n\
1898 Value is t if waited the full time with no input arriving.")
1899 (arg
, millisec
, nodisp
)
1900 Lisp_Object arg
, millisec
, nodisp
;
1905 CHECK_NUMBER (arg
, 0);
1908 if (!NILP (millisec
))
1910 #ifndef EMACS_HAS_USECS
1911 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
1913 usec
= (sec
% 1000) * 1000;
1918 return sit_for (sec
, usec
, 0, NILP (nodisp
));
1921 DEFUN ("sleep-for-millisecs", Fsleep_for_millisecs
, Ssleep_for_millisecs
,
1923 "Pause, without updating display, for ARG milliseconds.")
1929 #ifndef EMACS_HAS_USECS
1930 error ("sleep-for-millisecs not supported on %s", SYSTEM_TYPE
);
1932 CHECK_NUMBER (arg
, 0);
1934 XFASTINT (zero
) = 0;
1935 wait_reading_process_input (XINT (arg
) / 1000, XINT (arg
) % 1000 * 1000,
1938 #endif /* EMACS_HAS_USECS */
1941 char *terminal_type
;
1943 /* Initialization done when Emacs fork is started, before doing stty. */
1944 /* Determine terminal type and set terminal_driver */
1945 /* Then invoke its decoding routine to set up variables
1946 in the terminal package */
1950 #ifdef HAVE_X_WINDOWS
1951 extern int display_arg
;
1956 cursor_in_echo_area
= 0;
1957 terminal_type
= (char *) 0;
1959 /* If the DISPLAY environment variable is set, try to use X, and
1960 die with an error message if that doesn't work. */
1962 /* Check if we're using a window system here before trying to
1963 initialize the terminal. If we check the terminal first,
1965 If someone has indicated that they want
1966 to use a window system, we shouldn't bother initializing the
1967 terminal. This is especially important when the terminal is so
1968 dumb that emacs gives up before and doesn't bother using the window
1971 #ifdef HAVE_X_WINDOWS
1972 if (!inhibit_window_system
&& (display_arg
|| getenv ("DISPLAY")))
1974 Vwindow_system
= intern ("x");
1976 Vwindow_system_version
= make_number (11);
1978 Vwindow_system_version
= make_number (10);
1982 #endif /* HAVE_X_WINDOWS */
1984 /* If no window system has been specified, try to use the terminal. */
1987 fprintf (stderr
, "emacs: standard input is not a tty\n");
1991 /* Look at the TERM variable */
1992 terminal_type
= (char *) getenv ("TERM");
1996 fprintf (stderr
, "Please specify your terminal type.\n\
1997 For types defined in VMS, use set term /device=TYPE.\n\
1998 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
1999 \(The quotation marks are necessary since terminal types are lower case.)\n");
2001 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2007 /* VMS DCL tends to upcase things, so downcase term type.
2008 Hardly any uppercase letters in terminal types; should be none. */
2010 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2013 strcpy (new, terminal_type
);
2015 for (p
= new; *p
; p
++)
2019 terminal_type
= new;
2023 term_init (terminal_type
);
2025 remake_frame_glyphs (selected_frame
);
2026 calculate_costs (selected_frame
);
2028 /* X and Y coordinates of the cursor between updates. */
2029 FRAME_CURSOR_X (selected_frame
) = 0;
2030 FRAME_CURSOR_Y (selected_frame
) = 0;
2035 #endif /* CANNOT_DUMP */
2036 signal (SIGWINCH
, window_change_signal
);
2037 #endif /* SIGWINCH */
2043 defsubr (&Sredraw_frame
);
2045 defsubr (&Sredraw_display
);
2046 defsubr (&Sopen_termscript
);
2048 defsubr (&Ssit_for
);
2049 defsubr (&Ssleep_for
);
2050 defsubr (&Ssend_string_to_terminal
);
2052 DEFVAR_INT ("baud-rate", &baud_rate
,
2053 "The output baud rate of the terminal.\n\
2054 On most systems, changing this value will affect the amount of padding\n\
2055 and the other strategic decisions made during redisplay.");
2056 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2057 "*Non-nil means invert the entire frame display.\n\
2058 This means everything is in inverse video which otherwise would not be.");
2059 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2060 "*Non-nil means try to flash the frame to represent a bell.");
2061 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2062 "*Non-nil means no need to redraw entire frame after suspending.\n\
2063 A non-nil value is useful if the terminal can automatically preserve\n\
2064 Emacs's frame display when you reenter Emacs.\n\
2065 It is up to you to set this variable if your terminal can do that.");
2066 DEFVAR_LISP ("window-system", &Vwindow_system
,
2067 "A symbol naming the window-system under which Emacs is running\n\
2068 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2069 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2070 "The version number of the window system in use.\n\
2071 For X windows, this is 10 or 11.");
2072 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2073 "Non-nil means put cursor in minibuffer, at end of any message there.");
2074 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2075 "Table defining how to output a glyph code to the frame.\n\
2076 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2077 Each element can be:\n\
2078 integer: a glyph code which this glyph is an alias for.\n\
2079 string: output this glyph using that string (not impl. in X windows).\n\
2080 nil: this glyph mod 256 is char code to output,\n\
2081 and this glyph / 256 is face code for X windows (see `x-set-face').");
2082 Vglyph_table
= Qnil
;
2084 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2085 "Display table to use for buffers that specify none.\n\
2086 See `buffer-display-table' for more information.");
2087 Vstandard_display_table
= Qnil
;
2089 /* Initialize `window-system', unless init_display already decided it. */
2094 Vwindow_system
= Qnil
;
2095 Vwindow_system_version
= Qnil
;