1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 1986, 1987, 1988, 1990,
3 1992, 1993 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, 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 "Clear and redisplay all visible frames.")
171 Lisp_Object frame
, tail
;
173 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
175 frame
= XCONS (tail
)->car
;
177 /* If we simply redrew all visible frames, whether or not they
178 were garbaged, then this would make all frames clear and
179 redraw whenever a new frame is created or an existing frame
180 is de-iconified; those events set the global frame_garbaged
181 flag, to which redisplay responds by calling this function.
183 This used to redraw all visible frames; the only advantage of
184 that approach is that if a frame changes from invisible to
185 visible without setting its garbaged flag, it still gets
186 redisplayed. But that should never happen; since invisible
187 frames are not updated, they should always be marked as
188 garbaged when they become visible again. If that doesn't
189 happen, it's a bug in the visibility code, not a bug here. */
190 if (FRAME_VISIBLE_P (XFRAME (frame
))
191 && FRAME_GARBAGED_P (XFRAME (frame
)))
192 Fredraw_frame (frame
);
201 XSET (frame
, Lisp_Frame
, f
);
202 Fredraw_frame (frame
);
205 #else /* not MULTI_FRAME */
207 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
208 "Clear screen and output again what is supposed to appear on it.")
212 set_terminal_modes ();
216 clear_frame_records (0);
217 windows_or_buffers_changed
++;
218 /* Mark all windows as INaccurate,
219 so that every window will have its redisplay done. */
220 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
224 #endif /* not MULTI_FRAME */
226 static struct frame_glyphs
*
227 make_frame_glyphs (frame
, empty
)
228 register FRAME_PTR frame
;
232 register width
= FRAME_WIDTH (frame
);
233 register height
= FRAME_HEIGHT (frame
);
234 register struct frame_glyphs
*new =
235 (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
237 SET_GLYPHS_FRAME (new, frame
);
238 new->height
= height
;
240 new->used
= (int *) xmalloc (height
* sizeof (int));
241 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
242 new->highlight
= (char *) xmalloc (height
* sizeof (char));
243 new->enable
= (char *) xmalloc (height
* sizeof (char));
244 bzero (new->enable
, height
* sizeof (char));
245 new->bufp
= (int *) xmalloc (height
* sizeof (int));
247 #ifdef HAVE_X_WINDOWS
248 if (FRAME_X_P (frame
))
250 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
251 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
252 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
253 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
254 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
260 /* Make the buffer used by decode_mode_spec. This buffer is also
261 used as temporary storage when updating the frame. See scroll.c. */
262 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
264 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
265 bzero (new->total_contents
, total_glyphs
);
269 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
271 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
272 bzero (new->total_contents
, total_glyphs
);
273 for (i
= 0; i
< height
; i
++)
274 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
281 free_frame_glyphs (frame
, glyphs
)
283 struct frame_glyphs
*glyphs
;
285 if (glyphs
->total_contents
)
286 free (glyphs
->total_contents
);
289 free (glyphs
->glyphs
);
290 free (glyphs
->highlight
);
291 free (glyphs
->enable
);
294 #ifdef HAVE_X_WINDOWS
295 if (FRAME_X_P (frame
))
297 free (glyphs
->top_left_x
);
298 free (glyphs
->top_left_y
);
299 free (glyphs
->pix_width
);
300 free (glyphs
->pix_height
);
301 free (glyphs
->max_ascent
);
309 remake_frame_glyphs (frame
)
312 if (FRAME_CURRENT_GLYPHS (frame
))
313 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
314 if (FRAME_DESIRED_GLYPHS (frame
))
315 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
316 if (FRAME_TEMP_GLYPHS (frame
))
317 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
319 if (FRAME_MESSAGE_BUF (frame
))
320 FRAME_MESSAGE_BUF (frame
)
321 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
322 FRAME_WIDTH (frame
) + 1);
324 FRAME_MESSAGE_BUF (frame
)
325 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
327 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
328 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
329 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
330 SET_FRAME_GARBAGED (frame
);
333 /* Return the hash code of contents of line VPOS in frame-matrix M. */
336 line_hash_code (m
, vpos
)
337 register struct frame_glyphs
*m
;
340 register GLYPH
*body
, *end
;
343 if (!m
->enable
[vpos
])
346 /* Give all highlighted lines the same hash code
347 so as to encourage scrolling to leave them in place. */
348 if (m
->highlight
[vpos
])
351 body
= m
->glyphs
[vpos
];
353 if (must_write_spaces
)
360 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
369 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
377 /* Return number of characters in line in M at vpos VPOS,
378 except don't count leading and trailing spaces
379 unless the terminal requires those to be explicitly output. */
382 line_draw_cost (m
, vpos
)
383 struct frame_glyphs
*m
;
386 register GLYPH
*beg
= m
->glyphs
[vpos
];
387 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
389 register int tlen
= GLYPH_TABLE_LENGTH
;
390 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
392 /* Ignore trailing and leading spaces if we can. */
393 if (!must_write_spaces
)
395 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
398 return (0); /* All blank line. */
400 while (*beg
== SPACEGLYPH
)
404 /* If we don't have a glyph-table, each glyph is one character,
405 so return the number of glyphs. */
409 /* Otherwise, scan the glyphs and accumulate their total size in I. */
411 while ((beg
<= end
) && *beg
)
413 register GLYPH g
= *beg
++;
415 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
418 i
+= GLYPH_LENGTH (tbase
, g
);
423 /* The functions on this page are the interface from xdisp.c to redisplay.
425 The only other interface into redisplay is through setting
426 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
427 and SET_FRAME_GARBAGED (frame). */
429 /* cancel_line eliminates any request to display a line at position `vpos' */
431 cancel_line (vpos
, frame
)
433 register FRAME_PTR frame
;
435 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
438 clear_frame_records (frame
)
439 register FRAME_PTR frame
;
441 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
444 /* Prepare to display on line VPOS starting at HPOS within it. */
447 get_display_line (frame
, vpos
, hpos
)
448 register FRAME_PTR frame
;
452 register struct frame_glyphs
*glyphs
;
453 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
459 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
462 if (! desired_glyphs
->enable
[vpos
])
464 desired_glyphs
->used
[vpos
] = 0;
465 desired_glyphs
->highlight
[vpos
] = 0;
466 desired_glyphs
->enable
[vpos
] = 1;
469 if (hpos
> desired_glyphs
->used
[vpos
])
471 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
472 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
474 desired_glyphs
->used
[vpos
] = hpos
;
480 /* Like bcopy except never gets confused by overlap. */
483 safe_bcopy (from
, to
, size
)
487 if (size
<= 0 || from
== to
)
490 /* If the source and destination don't overlap, then bcopy can
491 handle it. If they do overlap, but the destination is lower in
492 memory than the source, we'll assume bcopy can handle that. */
493 if (to
< from
|| from
+ size
<= to
)
494 bcopy (from
, to
, size
);
496 /* Otherwise, we'll copy from the end. */
499 register char *endf
= from
+ size
;
500 register char *endt
= to
+ size
;
502 /* If TO - FROM is large, then we should break the copy into
503 nonoverlapping chunks of TO - FROM bytes each. However, if
504 TO - FROM is small, then the bcopy function call overhead
505 makes this not worth it. The crossover point could be about
506 anywhere. Since I don't think the obvious copy loop is too
507 bad, I'm trying to err in its favor. */
512 while (endf
!= from
);
524 bcopy (endf
, endt
, to
- from
);
527 /* If SIZE wasn't a multiple of TO - FROM, there will be a
528 little left over. The amount left over is
529 (endt + (to - from)) - to, which is endt - from. */
530 bcopy (from
, to
, endt
- from
);
535 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
536 DISTANCE may be negative. */
539 rotate_vector (vector
, size
, distance
)
544 char *temp
= (char *) alloca (size
);
549 bcopy (vector
, temp
+ distance
, size
- distance
);
550 bcopy (vector
+ size
- distance
, temp
, distance
);
551 bcopy (temp
, vector
, size
);
554 /* Scroll lines from vpos FROM up to but not including vpos END
555 down by AMOUNT lines (AMOUNT may be negative).
556 Returns nonzero if done, zero if terminal cannot scroll them. */
559 scroll_frame_lines (frame
, from
, end
, amount
)
560 register FRAME_PTR frame
;
561 int from
, end
, amount
;
564 register struct frame_glyphs
*current_frame
565 = FRAME_CURRENT_GLYPHS (frame
);
567 if (!line_ins_del_ok
)
575 update_begin (frame
);
576 set_terminal_window (end
+ amount
);
577 if (!scroll_region_ok
)
578 ins_del_lines (end
, -amount
);
579 ins_del_lines (from
, amount
);
580 set_terminal_window (0);
582 rotate_vector (current_frame
->glyphs
+ from
,
583 sizeof (GLYPH
*) * (end
+ amount
- from
),
584 amount
* sizeof (GLYPH
*));
586 safe_bcopy (current_frame
->used
+ from
,
587 current_frame
->used
+ from
+ amount
,
588 (end
- from
) * sizeof current_frame
->used
[0]);
590 safe_bcopy (current_frame
->highlight
+ from
,
591 current_frame
->highlight
+ from
+ amount
,
592 (end
- from
) * sizeof current_frame
->highlight
[0]);
594 safe_bcopy (current_frame
->enable
+ from
,
595 current_frame
->enable
+ from
+ amount
,
596 (end
- from
) * sizeof current_frame
->enable
[0]);
598 /* Mark the lines made empty by scrolling as enabled, empty and
600 bzero (current_frame
->used
+ from
,
601 amount
* sizeof current_frame
->used
[0]);
602 bzero (current_frame
->highlight
+ from
,
603 amount
* sizeof current_frame
->highlight
[0]);
604 for (i
= from
; i
< from
+ amount
; i
++)
606 current_frame
->glyphs
[i
][0] = '\0';
607 current_frame
->enable
[i
] = 1;
610 safe_bcopy (current_frame
->bufp
+ from
,
611 current_frame
->bufp
+ from
+ amount
,
612 (end
- from
) * sizeof current_frame
->bufp
[0]);
614 #ifdef HAVE_X_WINDOWS
615 if (FRAME_X_P (frame
))
617 safe_bcopy (current_frame
->top_left_x
+ from
,
618 current_frame
->top_left_x
+ from
+ amount
,
619 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
621 safe_bcopy (current_frame
->top_left_y
+ from
,
622 current_frame
->top_left_y
+ from
+ amount
,
623 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
625 safe_bcopy (current_frame
->pix_width
+ from
,
626 current_frame
->pix_width
+ from
+ amount
,
627 (end
- from
) * sizeof current_frame
->pix_width
[0]);
629 safe_bcopy (current_frame
->pix_height
+ from
,
630 current_frame
->pix_height
+ from
+ amount
,
631 (end
- from
) * sizeof current_frame
->pix_height
[0]);
633 safe_bcopy (current_frame
->max_ascent
+ from
,
634 current_frame
->max_ascent
+ from
+ amount
,
635 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
637 #endif /* HAVE_X_WINDOWS */
643 update_begin (frame
);
644 set_terminal_window (end
);
645 ins_del_lines (from
+ amount
, amount
);
646 if (!scroll_region_ok
)
647 ins_del_lines (end
+ amount
, -amount
);
648 set_terminal_window (0);
650 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
651 sizeof (GLYPH
*) * (end
- from
- amount
),
652 amount
* sizeof (GLYPH
*));
654 safe_bcopy (current_frame
->used
+ from
,
655 current_frame
->used
+ from
+ amount
,
656 (end
- from
) * sizeof current_frame
->used
[0]);
658 safe_bcopy (current_frame
->highlight
+ from
,
659 current_frame
->highlight
+ from
+ amount
,
660 (end
- from
) * sizeof current_frame
->highlight
[0]);
662 safe_bcopy (current_frame
->enable
+ from
,
663 current_frame
->enable
+ from
+ amount
,
664 (end
- from
) * sizeof current_frame
->enable
[0]);
666 /* Mark the lines made empty by scrolling as enabled, empty and
668 bzero (current_frame
->used
+ end
+ amount
,
669 - amount
* sizeof current_frame
->used
[0]);
670 bzero (current_frame
->highlight
+ end
+ amount
,
671 - amount
* sizeof current_frame
->highlight
[0]);
672 for (i
= end
+ amount
; i
< end
; i
++)
674 current_frame
->glyphs
[i
][0] = '\0';
675 current_frame
->enable
[i
] = 1;
678 safe_bcopy (current_frame
->bufp
+ from
,
679 current_frame
->bufp
+ from
+ amount
,
680 (end
- from
) * sizeof current_frame
->bufp
[0]);
682 #ifdef HAVE_X_WINDOWS
683 if (FRAME_X_P (frame
))
685 safe_bcopy (current_frame
->top_left_x
+ from
,
686 current_frame
->top_left_x
+ from
+ amount
,
687 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
689 safe_bcopy (current_frame
->top_left_y
+ from
,
690 current_frame
->top_left_y
+ from
+ amount
,
691 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
693 safe_bcopy (current_frame
->pix_width
+ from
,
694 current_frame
->pix_width
+ from
+ amount
,
695 (end
- from
) * sizeof current_frame
->pix_width
[0]);
697 safe_bcopy (current_frame
->pix_height
+ from
,
698 current_frame
->pix_height
+ from
+ amount
,
699 (end
- from
) * sizeof current_frame
->pix_height
[0]);
701 safe_bcopy (current_frame
->max_ascent
+ from
,
702 current_frame
->max_ascent
+ from
+ amount
,
703 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
705 #endif /* HAVE_X_WINDOWS */
712 /* After updating a window W that isn't the full frame wide,
713 copy all the columns that W does not occupy
714 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
715 so that update_frame will not change those columns. */
717 preserve_other_columns (w
)
721 register struct frame_glyphs
*current_frame
, *desired_frame
;
722 register FRAME_PTR frame
= XFRAME (w
->frame
);
723 int start
= XFASTINT (w
->left
);
724 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
725 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
727 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
728 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
730 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
732 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
738 bcopy (current_frame
->glyphs
[vpos
],
739 desired_frame
->glyphs
[vpos
], start
);
740 len
= min (start
, current_frame
->used
[vpos
]);
741 if (desired_frame
->used
[vpos
] < len
)
742 desired_frame
->used
[vpos
] = len
;
744 if (current_frame
->used
[vpos
] > end
745 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
747 while (desired_frame
->used
[vpos
] < end
)
748 desired_frame
->glyphs
[vpos
][desired_frame
->used
[vpos
]++]
750 bcopy (current_frame
->glyphs
[vpos
] + end
,
751 desired_frame
->glyphs
[vpos
] + end
,
752 current_frame
->used
[vpos
] - end
);
753 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
761 /* If window w does not need to be updated and isn't the full frame wide,
762 copy all the columns that w does occupy
763 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
764 so that update_frame will not change those columns.
766 Have not been able to figure out how to use this correctly. */
768 preserve_my_columns (w
)
771 register int vpos
, fin
;
772 register struct frame_glyphs
*l1
, *l2
;
773 register FRAME_PTR frame
= XFRAME (w
->frame
);
774 int start
= XFASTINT (w
->left
);
775 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
776 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
778 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
780 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
781 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
783 if (l2
->length
> start
&& l1
->length
< l2
->length
)
786 if (fin
> end
) fin
= end
;
787 while (l1
->length
< start
)
788 l1
->body
[l1
->length
++] = ' ';
789 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
798 /* On discovering that the redisplay for a window was no good,
799 cancel the columns of that window, so that when the window is
800 displayed over again get_display_line will not complain. */
802 cancel_my_columns (w
)
806 register struct frame_glyphs
*desired_glyphs
=
807 FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
808 register int start
= XFASTINT (w
->left
);
809 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
811 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
812 if (desired_glyphs
->enable
[vpos
]
813 && desired_glyphs
->used
[vpos
] >= start
)
814 desired_glyphs
->used
[vpos
] = start
;
817 /* These functions try to perform directly and immediately on the frame
818 the necessary output for one change in the buffer.
819 They may return 0 meaning nothing was done if anything is difficult,
820 or 1 meaning the output was performed properly.
821 They assume that the frame was up to date before the buffer
822 change being displayed. They make various other assumptions too;
823 see command_loop_1 where these are called. */
826 direct_output_for_insert (g
)
829 register FRAME_PTR frame
= selected_frame
;
830 register struct frame_glyphs
*current_frame
831 = FRAME_CURRENT_GLYPHS (frame
);
833 #ifndef COMPILER_REGISTER_BUG
835 #endif /* COMPILER_REGISTER_BUG */
836 struct window
*w
= XWINDOW (selected_window
);
837 #ifndef COMPILER_REGISTER_BUG
839 #endif /* COMPILER_REGISTER_BUG */
840 int hpos
= FRAME_CURSOR_X (frame
);
841 #ifndef COMPILER_REGISTER_BUG
843 #endif /* COMPILER_REGISTER_BUG */
844 int vpos
= FRAME_CURSOR_Y (frame
);
846 /* Give up if about to continue line. */
847 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
849 /* Avoid losing if cursor is in invisible text off left margin */
850 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
852 /* Give up if cursor outside window (in minibuf, probably) */
853 || cursor_in_echo_area
854 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
855 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
857 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
858 || !display_completed
860 /* Give up if buffer appears in two places. */
863 /* Give up if w is minibuffer and a message is being displayed there */
864 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
867 current_frame
->glyphs
[vpos
][hpos
] = g
;
868 unchanged_modified
= MODIFF
;
869 beg_unchanged
= GPT
- BEG
;
870 XFASTINT (w
->last_point
) = point
;
871 XFASTINT (w
->last_point_x
) = hpos
;
872 XFASTINT (w
->last_modified
) = MODIFF
;
874 reassert_line_highlight (0, vpos
);
875 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
877 ++FRAME_CURSOR_X (frame
);
878 if (hpos
== current_frame
->used
[vpos
])
880 current_frame
->used
[vpos
] = hpos
+ 1;
881 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
888 direct_output_forward_char (n
)
891 register FRAME_PTR frame
= selected_frame
;
892 register struct window
*w
= XWINDOW (selected_window
);
894 /* Avoid losing if cursor is in invisible text off left margin
895 or about to go off either side of window. */
896 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
897 && (XINT (w
->hscroll
) || n
< 0))
899 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
900 || cursor_in_echo_area
)
903 FRAME_CURSOR_X (frame
) += n
;
904 XFASTINT (w
->last_point_x
) = FRAME_CURSOR_X (frame
);
905 XFASTINT (w
->last_point
) = point
;
906 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
911 static void update_line ();
913 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
914 Value is nonzero if redisplay stopped due to pending input.
915 FORCE nonzero means do not stop for pending input. */
918 update_frame (f
, force
, inhibit_hairy_id
)
921 int inhibit_hairy_id
;
923 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (f
);
924 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (f
);
927 int preempt_count
= baud_rate
/ 2400 + 1;
928 extern input_pending
;
929 #ifdef HAVE_X_WINDOWS
930 register int downto
, leftmost
;
933 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
935 detect_input_pending ();
936 if (input_pending
&& !force
)
944 if (!line_ins_del_ok
)
945 inhibit_hairy_id
= 1;
947 /* See if any of the desired lines are enabled; don't compute for
948 i/d line if just want cursor motion. */
949 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
950 if (desired_frame
->enable
[i
])
953 /* Try doing i/d line, if not yet inhibited. */
954 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
955 force
|= scrolling (f
);
957 /* Update the individual lines as needed. Do bottom line first. */
959 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
960 update_line (f
, FRAME_HEIGHT (f
) - 1);
962 #ifdef HAVE_X_WINDOWS
965 leftmost
= downto
= f
->display
.x
->internal_border_width
;
966 if (desired_frame
->enable
[0])
968 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
969 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
970 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
971 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
972 current_frame
->top_left_x
[0] = leftmost
;
973 current_frame
->top_left_y
[0] = downto
;
976 #endif /* HAVE_X_WINDOWS */
978 /* Now update the rest of the lines. */
979 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
981 if (desired_frame
->enable
[i
])
983 if (FRAME_TERMCAP_P (f
))
985 /* Flush out every so many lines.
986 Also flush out if likely to have more than 1k buffered
987 otherwise. I'm told that some telnet connections get
988 really screwed by more than 1k output at once. */
989 int outq
= PENDING_OUTPUT_COUNT (stdout
);
991 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
994 if (preempt_count
== 1)
996 #ifdef EMACS_OUTQSIZE
997 if (EMACS_OUTQSIZE (0, &outq
) < 0)
998 /* Probably not a tty. Ignore the error and reset
1000 outq
= PENDING_OUTPUT_COUNT (stdout
);
1003 sleep (outq
/ baud_rate
);
1006 if ((i
- 1) % preempt_count
== 0)
1007 detect_input_pending ();
1011 #ifdef HAVE_X_WINDOWS
1014 current_frame
->top_left_y
[i
] = downto
;
1015 current_frame
->top_left_x
[i
] = leftmost
;
1017 #endif /* HAVE_X_WINDOWS */
1020 #ifdef HAVE_X_WINDOWS
1022 downto
+= current_frame
->pix_height
[i
];
1025 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1027 /* Now just clean up termcap drivers and set cursor, etc. */
1030 if (cursor_in_echo_area
1031 && FRAME_HAS_MINIBUF_P (f
))
1033 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1036 if (cursor_in_echo_area
< 0)
1043 /* If the minibuffer is several lines high, find the last
1044 line that has any text on it. */
1045 row
= FRAME_HEIGHT (f
);
1049 if (current_frame
->enable
[row
])
1050 col
= current_frame
->used
[row
];
1054 while (row
> top
&& col
== 0);
1056 if (col
>= FRAME_WIDTH (f
))
1059 if (row
< FRAME_HEIGHT (f
) - 1)
1064 cursor_to (row
, col
);
1067 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1068 FRAME_WIDTH (f
) - 1), 0));
1074 fflush (termscript
);
1077 /* Here if output is preempted because input is detected. */
1080 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1081 display_completed
= !pause
;
1083 bzero (desired_frame
->enable
, FRAME_HEIGHT (f
));
1087 /* Called when about to quit, to check for doing so
1088 at an improper time. */
1093 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1095 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1097 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1101 /* Decide what insert/delete line to do, and do it */
1103 extern void scrolling_1 ();
1108 int unchanged_at_top
, unchanged_at_bottom
;
1111 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1112 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1113 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1115 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1116 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1117 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1119 /* Compute hash codes of all the lines.
1120 Also calculate number of changed lines,
1121 number of unchanged lines at the beginning,
1122 and number of unchanged lines at the end. */
1125 unchanged_at_top
= 0;
1126 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1127 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1129 /* Give up on this scrolling if some old lines are not enabled. */
1130 if (!current_frame
->enable
[i
])
1132 old_hash
[i
] = line_hash_code (current_frame
, i
);
1133 if (! desired_frame
->enable
[i
])
1134 new_hash
[i
] = old_hash
[i
];
1136 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1138 if (old_hash
[i
] != new_hash
[i
])
1141 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1143 else if (i
== unchanged_at_top
)
1145 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1148 /* If changed lines are few, don't allow preemption, don't scroll. */
1149 if (changed_lines
< baud_rate
/ 2400
1150 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1153 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1154 - unchanged_at_bottom
);
1156 if (scroll_region_ok
)
1157 free_at_end_vpos
-= unchanged_at_bottom
;
1158 else if (memory_below_frame
)
1159 free_at_end_vpos
= -1;
1161 /* If large window, fast terminal and few lines in common between
1162 current frame and desired frame, don't bother with i/d calc. */
1163 if (window_size
>= 18 && baud_rate
> 2400
1165 10 * scrolling_max_lines_saved (unchanged_at_top
,
1166 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1167 old_hash
, new_hash
, draw_cost
)))
1170 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1171 draw_cost
+ unchanged_at_top
- 1,
1172 old_hash
+ unchanged_at_top
- 1,
1173 new_hash
+ unchanged_at_top
- 1,
1174 free_at_end_vpos
- unchanged_at_top
);
1179 /* Return the offset in its buffer of the character at location col, line
1180 in the given window. */
1182 buffer_posn_from_coords (window
, col
, line
)
1183 struct window
*window
;
1186 int window_left
= XFASTINT (window
->left
);
1188 /* The actual width of the window is window->width less one for the
1189 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1191 int window_width
= window_internal_width (window
) - 1;
1193 int startp
= marker_position (window
->start
);
1195 /* Since compute_motion will only operate on the current buffer,
1196 we need to save the old one and restore it when we're done. */
1197 struct buffer
*old_current_buffer
= current_buffer
;
1198 struct position
*posn
;
1200 current_buffer
= XBUFFER (window
->buffer
);
1202 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1203 (window->frame))->bufp to avoid scanning from the very top of
1204 the window, but it isn't maintained correctly, and I'm not even
1205 sure I will keep it. */
1206 posn
= compute_motion (startp
, 0,
1207 (window
== XWINDOW (minibuf_window
) && startp
== 1
1208 ? minibuf_prompt_width
: 0),
1209 ZV
, line
, col
- window_left
,
1210 window_width
, XINT (window
->hscroll
), 0);
1212 current_buffer
= old_current_buffer
;
1214 /* compute_motion considers frame points past the end of a line
1215 to be *after* the newline, i.e. at the start of the next line.
1216 This is reasonable, but not really what we want. So if the
1217 result is on a line below LINE, back it up one character. */
1218 if (posn
->vpos
> line
)
1219 return posn
->bufpos
- 1;
1221 return posn
->bufpos
;
1228 register GLYPH
*p
= r
;
1229 while (*p
++ == SPACEGLYPH
);
1234 count_match (str1
, str2
)
1237 register GLYPH
*p1
= str1
;
1238 register GLYPH
*p2
= str2
;
1239 while (*p1
++ == *p2
++);
1240 return p1
- str1
- 1;
1243 /* Char insertion/deletion cost vector, from term.c */
1244 extern int *char_ins_del_vector
;
1246 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1249 update_line (frame
, vpos
)
1250 register FRAME_PTR frame
;
1253 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1255 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1257 register struct frame_glyphs
*current_frame
1258 = FRAME_CURRENT_GLYPHS (frame
);
1259 register struct frame_glyphs
*desired_frame
1260 = FRAME_DESIRED_GLYPHS (frame
);
1262 if (desired_frame
->highlight
[vpos
]
1263 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1265 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1266 (current_frame
->enable
[vpos
] ?
1267 current_frame
->used
[vpos
] : 0));
1268 current_frame
->enable
[vpos
] = 0;
1271 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1273 if (! current_frame
->enable
[vpos
])
1279 obody
= current_frame
->glyphs
[vpos
];
1280 olen
= current_frame
->used
[vpos
];
1281 if (! current_frame
->highlight
[vpos
])
1283 if (!must_write_spaces
)
1284 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1289 /* For an inverse-video line, remember we gave it
1290 spaces all the way to the frame edge
1291 so that the reverse video extends all the way across. */
1293 while (olen
< FRAME_WIDTH (frame
) - 1)
1294 obody
[olen
++] = SPACEGLYPH
;
1298 /* One way or another, this will enable the line being updated. */
1299 current_frame
->enable
[vpos
] = 1;
1300 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1301 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1302 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1304 #ifdef HAVE_X_WINDOWS
1305 if (FRAME_X_P (frame
))
1307 current_frame
->pix_width
[vpos
]
1308 = current_frame
->used
[vpos
]
1309 * FONT_WIDTH (frame
->display
.x
->font
);
1310 current_frame
->pix_height
[vpos
]
1311 = FONT_HEIGHT (frame
->display
.x
->font
);
1313 #endif /* HAVE_X_WINDOWS */
1315 if (!desired_frame
->enable
[vpos
])
1321 nbody
= desired_frame
->glyphs
[vpos
];
1322 nlen
= desired_frame
->used
[vpos
];
1324 /* Pretend trailing spaces are not there at all,
1325 unless for one reason or another we must write all spaces. */
1326 if (! desired_frame
->highlight
[vpos
])
1328 if (!must_write_spaces
)
1329 /* We know that the previous character byte contains 0. */
1330 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1335 /* For an inverse-video line, give it extra trailing spaces
1336 all the way to the frame edge
1337 so that the reverse video extends all the way across. */
1339 while (nlen
< FRAME_WIDTH (frame
) - 1)
1340 nbody
[nlen
++] = SPACEGLYPH
;
1343 /* If there's no i/d char, quickly do the best we can without it. */
1344 if (!char_ins_del_ok
)
1348 for (i
= 0; i
< nlen
; i
++)
1350 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1352 cursor_to (vpos
, i
);
1353 for (j
= 1; (i
+ j
< nlen
&&
1354 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1357 /* Output this run of non-matching chars. */
1358 write_glyphs (nbody
+ i
, j
);
1361 /* Now find the next non-match. */
1365 /* Clear the rest of the line, or the non-clear part of it. */
1368 cursor_to (vpos
, nlen
);
1369 clear_end_of_line (olen
);
1372 /* Exchange contents between current_frame and new_frame. */
1373 temp
= desired_frame
->glyphs
[vpos
];
1374 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1375 current_frame
->glyphs
[vpos
] = temp
;
1382 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1383 ? 0 : count_blanks (nbody
);
1386 cursor_to (vpos
, nsp
);
1387 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1390 /* Exchange contents between current_frame and new_frame. */
1391 temp
= desired_frame
->glyphs
[vpos
];
1392 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1393 current_frame
->glyphs
[vpos
] = temp
;
1402 /* Compute number of leading blanks in old and new contents. */
1403 osp
= count_blanks (obody
);
1404 if (!desired_frame
->highlight
[vpos
])
1405 nsp
= count_blanks (nbody
);
1409 /* Compute number of matching chars starting with first nonblank. */
1410 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1412 /* Spaces in new match implicit space past the end of old. */
1413 /* A bug causing this to be a no-op was fixed in 18.29. */
1414 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1417 while (np1
[begmatch
] == SPACEGLYPH
)
1421 /* Avoid doing insert/delete char
1422 just cause number of leading spaces differs
1423 when the following text does not match. */
1424 if (begmatch
== 0 && osp
!= nsp
)
1425 osp
= nsp
= min (osp
, nsp
);
1427 /* Find matching characters at end of line */
1430 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1431 while (op1
> op2
&& op1
[-1] == np1
[-1])
1436 endmatch
= obody
+ olen
- op1
;
1438 /* Put correct value back in nbody[nlen].
1439 This is important because direct_output_for_insert
1440 can write into the line at a later point.
1441 If this screws up the zero at the end of the line, re-establish it. */
1445 /* tem gets the distance to insert or delete.
1446 endmatch is how many characters we save by doing so.
1449 tem
= (nlen
- nsp
) - (olen
- osp
);
1451 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1454 /* nsp - osp is the distance to insert or delete.
1455 If that is nonzero, begmatch is known to be nonzero also.
1456 begmatch + endmatch is how much we save by doing the ins/del.
1460 && (!char_ins_del_ok
1461 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1465 osp
= nsp
= min (osp
, nsp
);
1468 /* Now go through the line, inserting, writing and
1469 deleting as appropriate. */
1473 cursor_to (vpos
, nsp
);
1474 delete_glyphs (osp
- nsp
);
1478 /* If going to delete chars later in line
1479 and insert earlier in the line,
1480 must delete first to avoid losing data in the insert */
1481 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1483 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1484 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1485 olen
= nlen
- (nsp
- osp
);
1487 cursor_to (vpos
, osp
);
1488 insert_glyphs ((char *)0, nsp
- osp
);
1492 tem
= nsp
+ begmatch
+ endmatch
;
1493 if (nlen
!= tem
|| olen
!= tem
)
1495 cursor_to (vpos
, nsp
+ begmatch
);
1496 if (!endmatch
|| nlen
== olen
)
1498 /* If new text being written reaches right margin,
1499 there is no need to do clear-to-eol at the end.
1500 (and it would not be safe, since cursor is not
1501 going to be "at the margin" after the text is done) */
1502 if (nlen
== FRAME_WIDTH (frame
))
1504 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1508 /* the following code loses disastrously if tem == nlen.
1509 Rather than trying to fix that case, I am trying the simpler
1510 solution found above. */
1512 /* If the text reaches to the right margin,
1513 it will lose one way or another (depending on AutoWrap)
1514 to clear to end of line after outputting all the text.
1515 So pause with one character to go and clear the line then. */
1516 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1518 /* endmatch must be zero, and tem must equal nsp + begmatch */
1519 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1520 clear_end_of_line (olen
);
1521 olen
= 0; /* Don't let it be cleared again later */
1522 write_glyphs (nbody
+ nlen
- 1, 1);
1525 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1526 #endif /* OBSOLETE */
1529 else if (nlen
> olen
)
1531 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1532 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1535 else if (olen
> nlen
)
1537 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1538 delete_glyphs (olen
- nlen
);
1544 /* If any unerased characters remain after the new line, erase them. */
1547 cursor_to (vpos
, nlen
);
1548 clear_end_of_line (olen
);
1551 /* Exchange contents between current_frame and new_frame. */
1552 temp
= desired_frame
->glyphs
[vpos
];
1553 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1554 current_frame
->glyphs
[vpos
] = temp
;
1557 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1558 1, 1, "FOpen termscript file: ",
1559 "Start writing all terminal output to FILE as well as the terminal.\n\
1560 FILE = nil means just close any termscript file currently open.")
1564 if (termscript
!= 0) fclose (termscript
);
1569 file
= Fexpand_file_name (file
, Qnil
);
1570 termscript
= fopen (XSTRING (file
)->data
, "w");
1571 if (termscript
== 0)
1572 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1580 window_change_signal ()
1584 int old_errno
= errno
;
1586 get_frame_size (&width
, &height
);
1588 /* The frame size change obviously applies to a termcap-controlled
1589 frame. Find such a frame in the list, and assume it's the only
1590 one (since the redisplay code always writes to stdout, not a
1591 FILE * specified in the frame structure). Record the new size,
1592 but don't reallocate the data structures now. Let that be done
1593 later outside of the signal handler. */
1599 FOR_EACH_FRAME (tail
, f
)
1601 if (FRAME_TERMCAP_P (f
))
1603 change_frame_size (f
, height
, width
, 0, 1);
1609 signal (SIGWINCH
, window_change_signal
);
1612 #endif /* SIGWINCH */
1615 /* Do any change in frame size that was requested by a signal. */
1617 do_pending_window_change ()
1619 /* If window_change_signal should have run before, run it now. */
1620 while (delayed_size_change
)
1625 delayed_size_change
= 0;
1627 FOR_EACH_FRAME (tail
, f
)
1629 int height
= FRAME_NEW_HEIGHT (f
);
1630 int width
= FRAME_NEW_WIDTH (f
);
1632 FRAME_NEW_HEIGHT (f
) = 0;
1633 FRAME_NEW_WIDTH (f
) = 0;
1636 change_frame_size (f
, height
, width
, 0, 0);
1642 /* Change the frame height and/or width. Values may be given as zero to
1643 indicate no change is to take place.
1645 If DELAY is non-zero, then assume we're being called from a signal
1646 handler, and queue the change for later - perhaps the next
1647 redisplay. Since this tries to resize windows, we can't call it
1648 from a signal handler. */
1650 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
1651 register FRAME_PTR frame
;
1652 int newheight
, newwidth
, pretend
;
1654 /* If we can't deal with the change now, queue it for later. */
1657 FRAME_NEW_HEIGHT (frame
) = newheight
;
1658 FRAME_NEW_WIDTH (frame
) = newwidth
;
1659 delayed_size_change
= 1;
1663 /* This size-change overrides any pending one for this frame. */
1664 FRAME_NEW_HEIGHT (frame
) = 0;
1665 FRAME_NEW_WIDTH (frame
) = 0;
1667 /* If an arguments is zero, set it to the current value. */
1668 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
1669 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
1671 /* Round up to the smallest acceptable size. */
1672 check_frame_size (frame
, &newheight
, &newwidth
);
1674 /* If we're not changing the frame size, quit now. */
1675 if (newheight
== FRAME_HEIGHT (frame
)
1676 && newwidth
== FRAME_WIDTH (frame
))
1679 if (newheight
!= FRAME_HEIGHT (frame
))
1681 if (FRAME_HAS_MINIBUF_P (frame
)
1682 && ! FRAME_MINIBUF_ONLY_P (frame
))
1684 /* Frame has both root and minibuffer. */
1685 set_window_height (FRAME_ROOT_WINDOW (frame
),
1687 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
)
1689 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
1692 /* Frame has just one top-level window. */
1693 set_window_height (FRAME_ROOT_WINDOW (frame
), newheight
, 0);
1695 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1696 FrameRows
= newheight
;
1699 if (frame
->output_method
== output_termcap
)
1701 frame_height
= newheight
;
1703 FrameRows
= newheight
;
1708 if (newwidth
!= FRAME_WIDTH (frame
))
1710 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
1711 if (FRAME_HAS_MINIBUF_P (frame
))
1712 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
1714 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1715 FrameCols
= newwidth
;
1717 if (frame
->output_method
== output_termcap
)
1719 frame_width
= newwidth
;
1721 FrameCols
= newwidth
;
1726 FRAME_HEIGHT (frame
) = newheight
;
1727 FRAME_WIDTH (frame
) = newwidth
;
1729 remake_frame_glyphs (frame
);
1730 calculate_costs (frame
);
1733 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
1734 Ssend_string_to_terminal
, 1, 1, 0,
1735 "Send STRING to the terminal without alteration.\n\
1736 Control characters in STRING will have terminal-dependent effects.")
1740 CHECK_STRING (str
, 0);
1741 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
1745 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
1746 fflush (termscript
);
1751 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
1752 "Beep, or flash the screen.\n\
1753 Also, unless an argument is given,\n\
1754 terminate any keyboard macro currently executing.")
1776 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
1777 error ("Keyboard macro terminated by a command ringing the bell");
1783 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
1784 "Pause, without updating display, for ARG seconds.\n\
1785 Optional second arg non-nil means ARG is measured in milliseconds.\n\
1786 \(Not all operating systems support milliseconds.)")
1788 Lisp_Object arg
, millisec
;
1793 CHECK_NUMBER (arg
, 0);
1798 if (!NILP (millisec
))
1800 #ifndef EMACS_HAS_USECS
1801 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
1803 usec
= sec
% 1000 * 1000;
1811 XFASTINT (zero
) = 0;
1812 wait_reading_process_input (sec
, usec
, zero
, 0);
1815 #if 0 /* No wait_reading_process_input */
1822 /* The reason this is done this way
1823 (rather than defined (H_S) && defined (H_T))
1824 is because the VMS preprocessor doesn't grok `defined' */
1826 EMACS_GET_TIME (end_time
);
1827 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
1828 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
1832 EMACS_GET_TIME (timeout
);
1833 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
1834 if (EMACS_TIME_NEG_P (timeout
)
1835 || !select (1, 0, 0, 0, &timeout
))
1838 #else /* not HAVE_SELECT */
1840 #endif /* HAVE_SELECT */
1841 #endif /* not VMS */
1844 #endif /* no subprocesses */
1849 /* This is just like wait_reading_process_input, except that
1850 it does the redisplay.
1852 It's also just like Fsit_for, except that it can be used for
1853 waiting for input as well. */
1856 sit_for (sec
, usec
, reading
, display
)
1857 int sec
, usec
, reading
, display
;
1859 Lisp_Object read_kbd
;
1861 if (detect_input_pending ())
1865 redisplay_preserve_echo_area ();
1867 if (sec
== 0 && usec
== 0)
1874 XSET (read_kbd
, Lisp_Int
, reading
? -1 : 1);
1875 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
1878 #if 0 /* No wait_reading_process_input available. */
1884 input_wait_timeout (XINT (arg
));
1886 #ifndef HAVE_TIMEVAL
1888 select (1, &waitchannels
, 0, 0, &timeout_sec
);
1889 #else /* HAVE_TIMEVAL */
1890 timeout
.tv_sec
= sec
;
1891 timeout
.tv_usec
= usec
;
1892 select (1, &waitchannels
, 0, 0, &timeout
);
1893 #endif /* HAVE_TIMEVAL */
1894 #endif /* not VMS */
1899 return detect_input_pending () ? Qnil
: Qt
;
1902 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
1903 "Perform redisplay, then wait for ARG seconds or until input is available.\n\
1904 Optional second arg non-nil means ARG counts in milliseconds.\n\
1905 Optional third arg non-nil means don't redisplay, just wait for input.\n\
1906 Redisplay is preempted as always if input arrives, and does not happen\n\
1907 if input is available before it starts.\n\
1908 Value is t if waited the full time with no input arriving.")
1909 (arg
, millisec
, nodisp
)
1910 Lisp_Object arg
, millisec
, nodisp
;
1915 CHECK_NUMBER (arg
, 0);
1918 if (!NILP (millisec
))
1920 #ifndef EMACS_HAS_USECS
1921 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
1923 usec
= (sec
% 1000) * 1000;
1928 return sit_for (sec
, usec
, 0, NILP (nodisp
));
1931 DEFUN ("sleep-for-millisecs", Fsleep_for_millisecs
, Ssleep_for_millisecs
,
1933 "Pause, without updating display, for ARG milliseconds.")
1939 #ifndef EMACS_HAS_USECS
1940 error ("sleep-for-millisecs not supported on %s", SYSTEM_TYPE
);
1942 CHECK_NUMBER (arg
, 0);
1944 XFASTINT (zero
) = 0;
1945 wait_reading_process_input (XINT (arg
) / 1000, XINT (arg
) % 1000 * 1000,
1948 #endif /* EMACS_HAS_USECS */
1951 char *terminal_type
;
1953 /* Initialization done when Emacs fork is started, before doing stty. */
1954 /* Determine terminal type and set terminal_driver */
1955 /* Then invoke its decoding routine to set up variables
1956 in the terminal package */
1960 #ifdef HAVE_X_WINDOWS
1961 extern int display_arg
;
1966 cursor_in_echo_area
= 0;
1967 terminal_type
= (char *) 0;
1969 /* If the DISPLAY environment variable is set, try to use X, and
1970 die with an error message if that doesn't work. */
1972 /* Check if we're using a window system here before trying to
1973 initialize the terminal. If we check the terminal first,
1975 If someone has indicated that they want
1976 to use a window system, we shouldn't bother initializing the
1977 terminal. This is especially important when the terminal is so
1978 dumb that emacs gives up before and doesn't bother using the window
1981 #ifdef HAVE_X_WINDOWS
1982 if (!inhibit_window_system
&& (display_arg
|| getenv ("DISPLAY")))
1984 Vwindow_system
= intern ("x");
1986 Vwindow_system_version
= make_number (11);
1988 Vwindow_system_version
= make_number (10);
1992 #endif /* HAVE_X_WINDOWS */
1994 /* If no window system has been specified, try to use the terminal. */
1997 fprintf (stderr
, "emacs: standard input is not a tty\n");
2001 /* Look at the TERM variable */
2002 terminal_type
= (char *) getenv ("TERM");
2006 fprintf (stderr
, "Please specify your terminal type.\n\
2007 For types defined in VMS, use set term /device=TYPE.\n\
2008 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2009 \(The quotation marks are necessary since terminal types are lower case.)\n");
2011 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2017 /* VMS DCL tends to upcase things, so downcase term type.
2018 Hardly any uppercase letters in terminal types; should be none. */
2020 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2023 strcpy (new, terminal_type
);
2025 for (p
= new; *p
; p
++)
2029 terminal_type
= new;
2033 term_init (terminal_type
);
2035 remake_frame_glyphs (selected_frame
);
2036 calculate_costs (selected_frame
);
2038 /* X and Y coordinates of the cursor between updates. */
2039 FRAME_CURSOR_X (selected_frame
) = 0;
2040 FRAME_CURSOR_Y (selected_frame
) = 0;
2045 #endif /* CANNOT_DUMP */
2046 signal (SIGWINCH
, window_change_signal
);
2047 #endif /* SIGWINCH */
2053 defsubr (&Sredraw_frame
);
2055 defsubr (&Sredraw_display
);
2056 defsubr (&Sopen_termscript
);
2058 defsubr (&Ssit_for
);
2059 defsubr (&Ssleep_for
);
2060 defsubr (&Ssend_string_to_terminal
);
2062 DEFVAR_INT ("baud-rate", &baud_rate
,
2063 "The output baud rate of the terminal.\n\
2064 On most systems, changing this value will affect the amount of padding\n\
2065 and the other strategic decisions made during redisplay.");
2066 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2067 "*Non-nil means invert the entire frame display.\n\
2068 This means everything is in inverse video which otherwise would not be.");
2069 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2070 "*Non-nil means try to flash the frame to represent a bell.");
2071 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2072 "*Non-nil means no need to redraw entire frame after suspending.\n\
2073 A non-nil value is useful if the terminal can automatically preserve\n\
2074 Emacs's frame display when you reenter Emacs.\n\
2075 It is up to you to set this variable if your terminal can do that.");
2076 DEFVAR_LISP ("window-system", &Vwindow_system
,
2077 "A symbol naming the window-system under which Emacs is running\n\
2078 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2079 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2080 "The version number of the window system in use.\n\
2081 For X windows, this is 10 or 11.");
2082 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2083 "Non-nil means put cursor in minibuffer, at end of any message there.");
2084 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2085 "Table defining how to output a glyph code to the frame.\n\
2086 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2087 Each element can be:\n\
2088 integer: a glyph code which this glyph is an alias for.\n\
2089 string: output this glyph using that string (not impl. in X windows).\n\
2090 nil: this glyph mod 256 is char code to output,\n\
2091 and this glyph / 256 is face code for X windows (see `x-set-face').");
2092 Vglyph_table
= Qnil
;
2094 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2095 "Display table to use for buffers that specify none.\n\
2096 See `buffer-display-table' for more information.");
2097 Vstandard_display_table
= Qnil
;
2099 /* Initialize `window-system', unless init_display already decided it. */
2104 Vwindow_system
= Qnil
;
2105 Vwindow_system_version
= Qnil
;