1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
31 #include "dispextern.h"
44 #endif /* HAVE_X_WINDOWS */
46 #define max(a, b) ((a) > (b) ? (a) : (b))
47 #define min(a, b) ((a) < (b) ? (a) : (b))
49 #ifndef PENDING_OUTPUT_COUNT
50 /* Get number of chars of output now in the buffer of a stdio stream.
51 This ought to be built in in stdio, but it isn't.
52 Some s- files override this because their stdio internals differ. */
53 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
56 /* Nonzero upon entry to redisplay means do not assume anything about
57 current contents of actual terminal frame; clear and redraw it. */
61 /* Nonzero means last display completed. Zero means it was preempted. */
63 int display_completed
;
65 /* Lisp variable visible-bell; enables use of screen-flash
66 instead of audible bell. */
70 /* Invert the color of the whole frame, at a low level. */
74 /* Line speed of the terminal. */
78 /* nil or a symbol naming the window system under which emacs is
79 running ('x is the only current possibility). */
81 Lisp_Object Vwindow_system
;
83 /* Version number of X windows: 10, 11 or nil. */
84 Lisp_Object Vwindow_system_version
;
86 /* Vector of glyph definitions. Indexed by glyph number,
87 the contents are a string which is how to output the glyph.
89 If Vglyph_table is nil, a glyph is output by using its low 8 bits
90 as a character code. */
92 Lisp_Object Vglyph_table
;
94 /* Display table to use for vectors that don't specify their own. */
96 Lisp_Object Vstandard_display_table
;
98 /* Nonzero means reading single-character input with prompt
99 so put cursor on minibuffer after the prompt.
100 positive means at end of text in echo area;
101 negative means at beginning of line. */
102 int cursor_in_echo_area
;
104 /* The currently selected frame.
105 In a single-frame version, this variable always remains 0. */
107 FRAME_PTR selected_frame
;
109 /* A frame which is not just a minibuffer, or 0 if there are no such
110 frames. This is usually the most recent such frame that was
111 selected. In a single-frame version, this variable always remains 0. */
112 FRAME_PTR last_nonminibuf_frame
;
114 /* In a single-frame version, the information that would otherwise
115 exist inside frame objects lives in the following structure instead.
117 NOTE: the_only_frame is not checked for garbage collection; don't
118 store collectable objects in any of its fields!
120 You're not/The only frame in town/... */
123 struct frame the_only_frame
;
126 /* This is a vector, made larger whenever it isn't large enough,
127 which is used inside `update_frame' to hold the old contents
128 of the FRAME_PHYS_LINES of the frame being updated. */
129 struct frame_glyphs
**ophys_lines
;
130 /* Length of vector currently allocated. */
131 int ophys_lines_length
;
133 FILE *termscript
; /* Stdio stream being used for copy of all output. */
135 struct cm Wcm
; /* Structure for info on cursor positioning */
137 extern short ospeed
; /* Output speed (from sg_ospeed) */
139 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
143 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
144 "Clear frame FRAME and output again what is supposed to appear on it.")
150 CHECK_LIVE_FRAME (frame
, 0);
153 /* set_terminal_modes (); */
155 clear_frame_records (f
);
158 windows_or_buffers_changed
++;
159 /* Mark all windows as INaccurate,
160 so that every window will have its redisplay done. */
161 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
166 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
167 "Redraw all frames marked as having their images garbled.")
170 Lisp_Object frame
, tail
;
172 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
174 frame
= XCONS (tail
)->car
;
175 if (XFRAME (frame
)->garbaged
&& XFRAME (frame
)->visible
)
176 Fredraw_frame (frame
);
185 XSET (frame
, Lisp_Frame
, f
);
186 Fredraw_frame (frame
);
189 #else /* not MULTI_FRAME */
191 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, 0,
192 "Clear screen and output again what is supposed to appear on it.")
196 set_terminal_modes ();
200 clear_frame_records (0);
201 windows_or_buffers_changed
++;
202 /* Mark all windows as INaccurate,
203 so that every window will have its redisplay done. */
204 mark_window_display_accurate (XWINDOW (minibuf_window
)->prev
, 0);
208 #endif /* not MULTI_FRAME */
210 static struct frame_glyphs
*
211 make_frame_glyphs (frame
, empty
)
212 register FRAME_PTR frame
;
216 register width
= FRAME_WIDTH (frame
);
217 register height
= FRAME_HEIGHT (frame
);
218 register struct frame_glyphs
*new =
219 (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
221 SET_GLYPHS_FRAME (new, frame
);
222 new->height
= height
;
224 new->used
= (int *) xmalloc (height
* sizeof (int));
225 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
226 new->highlight
= (char *) xmalloc (height
* sizeof (char));
227 new->enable
= (char *) xmalloc (height
* sizeof (char));
228 bzero (new->enable
, height
* sizeof (char));
229 new->bufp
= (int *) xmalloc (height
* sizeof (int));
231 #ifdef HAVE_X_WINDOWS
232 if (FRAME_X_P (frame
))
234 new->nruns
= (int *) xmalloc (height
* sizeof (int));
236 = (struct run
**) xmalloc (height
* sizeof (struct run
*));
237 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
238 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
239 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
240 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
246 /* Make the buffer used by decode_mode_spec. This buffer is also
247 used as temporary storage when updating the frame. See scroll.c. */
248 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
250 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
251 bzero (new->total_contents
, total_glyphs
);
255 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
257 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
258 bzero (new->total_contents
, total_glyphs
);
259 for (i
= 0; i
< height
; i
++)
260 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
267 free_frame_glyphs (frame
, glyphs
)
269 struct frame_glyphs
*glyphs
;
271 if (glyphs
->total_contents
)
272 free (glyphs
->total_contents
);
275 free (glyphs
->glyphs
);
276 free (glyphs
->highlight
);
277 free (glyphs
->enable
);
280 #ifdef HAVE_X_WINDOWS
281 if (FRAME_X_P (frame
))
283 free (glyphs
->nruns
);
284 free (glyphs
->face_list
);
285 free (glyphs
->top_left_x
);
286 free (glyphs
->top_left_y
);
287 free (glyphs
->pix_width
);
288 free (glyphs
->pix_height
);
296 remake_frame_glyphs (frame
)
299 if (FRAME_CURRENT_GLYPHS (frame
))
300 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
301 if (FRAME_DESIRED_GLYPHS (frame
))
302 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
303 if (FRAME_TEMP_GLYPHS (frame
))
304 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
306 if (FRAME_MESSAGE_BUF (frame
))
307 FRAME_MESSAGE_BUF (frame
)
308 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
309 FRAME_WIDTH (frame
) + 1);
311 FRAME_MESSAGE_BUF (frame
)
312 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
314 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
315 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
316 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
317 SET_FRAME_GARBAGED (frame
);
320 /* Return the hash code of contents of line VPOS in frame-matrix M. */
323 line_hash_code (m
, vpos
)
324 register struct frame_glyphs
*m
;
327 register GLYPH
*body
, *end
;
330 if (!m
->enable
[vpos
])
333 /* Give all lighlighted lines the same hash code
334 so as to encourage scrolling to leave them in place. */
335 if (m
->highlight
[vpos
])
338 body
= m
->glyphs
[vpos
];
340 if (must_write_spaces
)
347 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
356 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
364 /* Return number of characters in line in M at vpos VPOS,
365 except don't count leading and trailing spaces
366 unless the terminal requires those to be explicitly output. */
369 line_draw_cost (m
, vpos
)
370 struct frame_glyphs
*m
;
373 register GLYPH
*beg
= m
->glyphs
[vpos
];
374 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
376 register int tlen
= GLYPH_TABLE_LENGTH
;
377 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
379 /* Ignore trailing and leading spaces if we can. */
380 if (!must_write_spaces
)
382 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
385 return (0); /* All blank line. */
387 while (*beg
== SPACEGLYPH
)
391 /* If we don't have a glyph-table, each glyph is one character,
392 so return the number of glyphs. */
396 /* Otherwise, scan the glyphs and accumulate their total size in I. */
398 while ((beg
<= end
) && *beg
)
400 register GLYPH g
= *beg
++;
402 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
405 i
+= GLYPH_LENGTH (tbase
, g
);
410 /* The functions on this page are the interface from xdisp.c to redisplay.
412 The only other interface into redisplay is through setting
413 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
414 and SET_FRAME_GARBAGED (frame). */
416 /* cancel_line eliminates any request to display a line at position `vpos' */
418 cancel_line (vpos
, frame
)
420 register FRAME_PTR frame
;
422 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
425 clear_frame_records (frame
)
426 register FRAME_PTR frame
;
428 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
431 /* Prepare to display on line VPOS starting at HPOS within it. */
434 get_display_line (frame
, vpos
, hpos
)
435 register FRAME_PTR frame
;
439 register struct frame_glyphs
*glyphs
;
440 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
443 if (vpos
< 0 || (! FRAME_VISIBLE_P (frame
)))
446 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
449 if (! desired_glyphs
->enable
[vpos
])
451 desired_glyphs
->used
[vpos
] = 0;
452 desired_glyphs
->highlight
[vpos
] = 0;
453 desired_glyphs
->enable
[vpos
] = 1;
456 if (hpos
> desired_glyphs
->used
[vpos
])
458 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
459 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
461 desired_glyphs
->used
[vpos
] = hpos
;
467 /* Like bcopy except never gets confused by overlap. */
470 safe_bcopy (from
, to
, size
)
480 /* If destination is higher in memory, and overlaps source zone,
481 copy from the end. */
482 if (from
< to
&& from
+ size
> to
)
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 ever
492 too bad, I'm trying to err in its favor. */
497 while (endf
!= from
);
501 /* Since TO - FROM >= 64, the overlap is less than SIZE,
502 so we can always safely do this loop once. */
508 bcopy (endf
, endt
, to
- from
);
511 /* If TO - FROM wasn't a multiple of SIZE, there will be a
512 little left over. The amount left over is
513 (endt + (to - from)) - to, which is endt - from. */
514 bcopy (from
, to
, endt
- from
);
518 bcopy (from
, to
, size
);
523 safe_bcopy (from
, to
, size
)
533 /* If destination is higher in memory, and overlaps source zone,
534 copy from the end. */
535 if (from
< to
&& from
+ size
> to
)
542 while (endf
!= from
);
547 bcopy (from
, to
, size
);
551 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
552 DISTANCE may be negative. */
555 rotate_vector (vector
, size
, distance
)
560 char *temp
= (char *) alloca (size
);
565 bcopy (vector
, temp
+ distance
, size
- distance
);
566 bcopy (vector
+ size
- distance
, temp
, distance
);
567 bcopy (temp
, vector
, size
);
570 /* Scroll lines from vpos FROM up to but not including vpos END
571 down by AMOUNT lines (AMOUNT may be negative).
572 Returns nonzero if done, zero if terminal cannot scroll them. */
575 scroll_frame_lines (frame
, from
, end
, amount
)
576 register FRAME_PTR frame
;
577 int from
, end
, amount
;
580 register struct frame_glyphs
*current_frame
581 = FRAME_CURRENT_GLYPHS (frame
);
583 if (!line_ins_del_ok
)
591 update_begin (frame
);
592 set_terminal_window (end
+ amount
);
593 if (!scroll_region_ok
)
594 ins_del_lines (end
, -amount
);
595 ins_del_lines (from
, amount
);
596 set_terminal_window (0);
598 rotate_vector (current_frame
->glyphs
+ from
,
599 sizeof (GLYPH
*) * (end
+ amount
- from
),
600 amount
* sizeof (GLYPH
*));
602 safe_bcopy (current_frame
->used
+ from
,
603 current_frame
->used
+ from
+ amount
,
604 (end
- from
) * sizeof current_frame
->used
[0]);
606 safe_bcopy (current_frame
->highlight
+ from
,
607 current_frame
->highlight
+ from
+ amount
,
608 (end
- from
) * sizeof current_frame
->highlight
[0]);
610 safe_bcopy (current_frame
->enable
+ from
,
611 current_frame
->enable
+ from
+ amount
,
612 (end
- from
) * sizeof current_frame
->enable
[0]);
614 /* Mark the lines made empty by scrolling as enabled, empty and
616 bzero (current_frame
->used
+ from
,
617 amount
* sizeof current_frame
->used
[0]);
618 bzero (current_frame
->highlight
+ from
,
619 amount
* sizeof current_frame
->highlight
[0]);
620 for (i
= from
; i
< from
+ amount
; i
++)
622 current_frame
->glyphs
[i
][0] = '\0';
623 current_frame
->enable
[i
] = 1;
626 safe_bcopy (current_frame
->bufp
+ from
,
627 current_frame
->bufp
+ from
+ amount
,
628 (end
- from
) * sizeof current_frame
->bufp
[0]);
630 #ifdef HAVE_X_WINDOWS
631 if (FRAME_X_P (frame
))
633 safe_bcopy (current_frame
->nruns
+ from
,
634 current_frame
->nruns
+ from
+ amount
,
635 (end
- from
) * sizeof current_frame
->nruns
[0]);
637 safe_bcopy (current_frame
->face_list
+ from
,
638 current_frame
->face_list
+ from
+ amount
,
639 (end
- from
) * sizeof current_frame
->face_list
[0]);
641 safe_bcopy (current_frame
->top_left_x
+ from
,
642 current_frame
->top_left_x
+ from
+ amount
,
643 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
645 safe_bcopy (current_frame
->top_left_y
+ from
,
646 current_frame
->top_left_y
+ from
+ amount
,
647 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
649 safe_bcopy (current_frame
->pix_width
+ from
,
650 current_frame
->pix_width
+ from
+ amount
,
651 (end
- from
) * sizeof current_frame
->pix_width
[0]);
653 safe_bcopy (current_frame
->pix_height
+ from
,
654 current_frame
->pix_height
+ from
+ amount
,
655 (end
- from
) * sizeof current_frame
->pix_height
[0]);
657 #endif /* HAVE_X_WINDOWS */
663 update_begin (frame
);
664 set_terminal_window (end
);
665 ins_del_lines (from
+ amount
, amount
);
666 if (!scroll_region_ok
)
667 ins_del_lines (end
+ amount
, -amount
);
668 set_terminal_window (0);
670 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
671 sizeof (GLYPH
*) * (end
- from
- amount
),
672 amount
* sizeof (GLYPH
*));
674 safe_bcopy (current_frame
->used
+ from
,
675 current_frame
->used
+ from
+ amount
,
676 (end
- from
) * sizeof current_frame
->used
[0]);
678 safe_bcopy (current_frame
->highlight
+ from
,
679 current_frame
->highlight
+ from
+ amount
,
680 (end
- from
) * sizeof current_frame
->highlight
[0]);
682 safe_bcopy (current_frame
->enable
+ from
,
683 current_frame
->enable
+ from
+ amount
,
684 (end
- from
) * sizeof current_frame
->enable
[0]);
686 /* Mark the lines made empty by scrolling as enabled, empty and
688 bzero (current_frame
->used
+ end
+ amount
,
689 - amount
* sizeof current_frame
->used
[0]);
690 bzero (current_frame
->highlight
+ end
+ amount
,
691 - amount
* sizeof current_frame
->highlight
[0]);
692 for (i
= end
+ amount
; i
< end
; i
++)
694 current_frame
->glyphs
[i
][0] = '\0';
695 current_frame
->enable
[i
] = 1;
698 safe_bcopy (current_frame
->bufp
+ from
,
699 current_frame
->bufp
+ from
+ amount
,
700 (end
- from
) * sizeof current_frame
->bufp
[0]);
702 #ifdef HAVE_X_WINDOWS
703 if (FRAME_X_P (frame
))
705 safe_bcopy (current_frame
->nruns
+ from
,
706 current_frame
->nruns
+ from
+ amount
,
707 (end
- from
) * sizeof current_frame
->nruns
[0]);
709 safe_bcopy (current_frame
->face_list
+ from
,
710 current_frame
->face_list
+ from
+ amount
,
711 (end
- from
) * sizeof current_frame
->face_list
[0]);
713 safe_bcopy (current_frame
->top_left_x
+ from
,
714 current_frame
->top_left_x
+ from
+ amount
,
715 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
717 safe_bcopy (current_frame
->top_left_y
+ from
,
718 current_frame
->top_left_y
+ from
+ amount
,
719 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
721 safe_bcopy (current_frame
->pix_width
+ from
,
722 current_frame
->pix_width
+ from
+ amount
,
723 (end
- from
) * sizeof current_frame
->pix_width
[0]);
725 safe_bcopy (current_frame
->pix_height
+ from
,
726 current_frame
->pix_height
+ from
+ amount
,
727 (end
- from
) * sizeof current_frame
->pix_height
[0]);
729 #endif /* HAVE_X_WINDOWS */
736 /* After updating a window W that isn't the full frame wide,
737 copy all the columns that W does not occupy
738 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
739 so that update_frame will not change those columns. */
741 preserve_other_columns (w
)
745 register struct frame_glyphs
*current_frame
, *desired_frame
;
746 register FRAME_PTR frame
= XFRAME (w
->frame
);
747 int start
= XFASTINT (w
->left
);
748 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
749 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
751 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
752 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
754 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
756 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
762 bcopy (current_frame
->glyphs
[vpos
],
763 desired_frame
->glyphs
[vpos
], start
);
764 len
= min (start
, current_frame
->used
[vpos
]);
765 if (desired_frame
->used
[vpos
] < len
)
766 desired_frame
->used
[vpos
] = len
;
768 if (current_frame
->used
[vpos
] > end
769 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
771 while (desired_frame
->used
[vpos
] < end
)
772 desired_frame
->glyphs
[vpos
][desired_frame
->used
[vpos
]++]
774 bcopy (current_frame
->glyphs
[vpos
] + end
,
775 desired_frame
->glyphs
[vpos
] + end
,
776 current_frame
->used
[vpos
] - end
);
777 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
785 /* If window w does not need to be updated and isn't the full frame wide,
786 copy all the columns that w does occupy
787 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
788 so that update_frame will not change those columns.
790 Have not been able to figure out how to use this correctly. */
792 preserve_my_columns (w
)
795 register int vpos
, fin
;
796 register struct frame_glyphs
*l1
, *l2
;
797 register FRAME_PTR frame
= XFRAME (w
->frame
);
798 int start
= XFASTINT (w
->left
);
799 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
800 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
802 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
804 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
805 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
807 if (l2
->length
> start
&& l1
->length
< l2
->length
)
810 if (fin
> end
) fin
= end
;
811 while (l1
->length
< start
)
812 l1
->body
[l1
->length
++] = ' ';
813 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
822 /* On discovering that the redisplay for a window was no good,
823 cancel the columns of that window, so that when the window is
824 displayed over again get_display_line will not complain. */
826 cancel_my_columns (w
)
830 register struct frame_glyphs
*desired_glyphs
=
831 FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
832 register int start
= XFASTINT (w
->left
);
833 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
835 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
836 if (desired_glyphs
->enable
[vpos
]
837 && desired_glyphs
->used
[vpos
] >= start
)
838 desired_glyphs
->used
[vpos
] = start
;
841 /* These functions try to perform directly and immediately on the frame
842 the necessary output for one change in the buffer.
843 They may return 0 meaning nothing was done if anything is difficult,
844 or 1 meaning the output was performed properly.
845 They assume that the frame was up to date before the buffer
846 change being displayed. THey make various other assumptions too;
847 see command_loop_1 where these are called. */
850 direct_output_for_insert (g
)
853 register FRAME_PTR frame
= selected_frame
;
854 register struct frame_glyphs
*current_frame
855 = FRAME_CURRENT_GLYPHS (frame
);
857 #ifndef COMPILER_REGISTER_BUG
859 #endif /* COMPILER_REGISTER_BUG */
860 struct window
*w
= XWINDOW (selected_window
);
861 #ifndef COMPILER_REGISTER_BUG
863 #endif /* COMPILER_REGISTER_BUG */
864 int hpos
= FRAME_CURSOR_X (frame
);
865 #ifndef COMPILER_REGISTER_BUG
867 #endif /* COMPILER_REGISTER_BUG */
868 int vpos
= FRAME_CURSOR_Y (frame
);
870 /* Give up if about to continue line */
871 if (hpos
- XFASTINT (w
->left
) + 1 + 1 >= XFASTINT (w
->width
)
873 /* Avoid losing if cursor is in invisible text off left margin */
874 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
876 /* Give up if cursor outside window (in minibuf, probably) */
877 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
878 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
880 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
881 || !display_completed
883 /* Give up if buffer appears in two places. */
886 /* Give up if w is minibuffer and a message is being displayed there */
887 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
890 current_frame
->glyphs
[vpos
][hpos
] = g
;
891 unchanged_modified
= MODIFF
;
892 beg_unchanged
= GPT
- BEG
;
893 XFASTINT (w
->last_point
) = point
;
894 XFASTINT (w
->last_point_x
) = hpos
;
895 XFASTINT (w
->last_modified
) = MODIFF
;
897 reassert_line_highlight (0, vpos
);
898 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
900 ++FRAME_CURSOR_X (frame
);
901 if (hpos
== current_frame
->used
[vpos
])
903 current_frame
->used
[vpos
] = hpos
+ 1;
904 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
911 direct_output_forward_char (n
)
914 register FRAME_PTR frame
= selected_frame
;
915 register struct window
*w
= XWINDOW (selected_window
);
917 /* Avoid losing if cursor is in invisible text off left margin
918 or about to go off either side of window. */
919 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
920 && (XINT (w
->hscroll
) || n
< 0))
922 && (FRAME_CURSOR_X (frame
) + 1
923 >= (XFASTINT (w
->left
) + XFASTINT (w
->width
)
924 - (XFASTINT (w
->width
) < FRAME_WIDTH (frame
))
928 FRAME_CURSOR_X (frame
) += n
;
929 XFASTINT (w
->last_point_x
) = FRAME_CURSOR_X (frame
);
930 XFASTINT (w
->last_point
) = point
;
931 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
936 static void update_line ();
938 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
939 Value is nonzero if redisplay stopped due to pending input.
940 FORCE nonzero means do not stop for pending input. */
943 update_frame (f
, force
, inhibit_hairy_id
)
946 int inhibit_hairy_id
;
948 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (f
);
949 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (f
);
952 int preempt_count
= baud_rate
/ 2400 + 1;
953 extern input_pending
;
954 #ifdef HAVE_X_WINDOWS
955 register int downto
, leftmost
;
958 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
960 detect_input_pending ();
961 if (input_pending
&& !force
)
969 if (!line_ins_del_ok
)
970 inhibit_hairy_id
= 1;
972 /* See if any of the desired lines are enabled; don't compute for
973 i/d line if just want cursor motion. */
974 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
975 if (desired_frame
->enable
[i
])
978 /* Try doing i/d line, if not yet inhibited. */
979 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
980 force
|= scrolling (f
);
982 /* Update the individual lines as needed. Do bottom line first. */
984 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
985 update_line (f
, FRAME_HEIGHT (f
) - 1);
987 #ifdef HAVE_X_WINDOWS
990 leftmost
= downto
= f
->display
.x
->internal_border_width
;
991 if (desired_frame
->enable
[0])
993 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
994 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
995 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
996 - LINE_HEIGHT(f
, FRAME_HEIGHT (f
) - 1);
997 current_frame
->top_left_x
[0] = leftmost
;
998 current_frame
->top_left_y
[0] = downto
;
1001 #endif /* HAVE_X_WINDOWS */
1003 /* Now update the rest of the lines. */
1004 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1006 if (desired_frame
->enable
[i
])
1008 if (FRAME_TERMCAP_P (f
))
1010 /* Flush out every so many lines.
1011 Also flush out if likely to have more than 1k buffered
1012 otherwise. I'm told that some telnet connections get
1013 really screwed by more than 1k output at once. */
1014 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1016 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1019 if (preempt_count
== 1)
1021 #ifdef EMACS_OUTQSIZE
1022 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1023 /* Probably not a tty. Ignore the error and reset
1024 * the outq count. */
1025 outq
= PENDING_OUTPUT_COUNT (stdout
);
1028 sleep (outq
/ baud_rate
);
1031 if ((i
- 1) % preempt_count
== 0)
1032 detect_input_pending ();
1036 #ifdef HAVE_X_WINDOWS
1039 current_frame
->top_left_y
[i
] = downto
;
1040 current_frame
->top_left_x
[i
] = leftmost
;
1042 #endif /* HAVE_X_WINDOWS */
1045 #ifdef HAVE_X_WINDOWS
1047 downto
+= LINE_HEIGHT(f
, i
);
1050 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1052 /* Now just clean up termcap drivers and set cursor, etc. */
1055 if (cursor_in_echo_area
)
1057 if (f
== selected_frame
1058 && cursor_in_echo_area
< 0)
1059 cursor_to (FRAME_HEIGHT (f
) - 1, 0);
1060 else if (f
== selected_frame
1061 && ! current_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1062 cursor_to (FRAME_HEIGHT (f
) - 1, 0);
1064 cursor_to (FRAME_HEIGHT (f
) - 1,
1065 min (FRAME_WIDTH (f
) - 1,
1066 current_frame
->used
[FRAME_HEIGHT (f
) - 1]));
1069 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1070 FRAME_WIDTH (f
) - 1), 0));
1076 fflush (termscript
);
1079 /* Here if output is preempted because input is detected. */
1082 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1083 display_completed
= !pause
;
1085 bzero (desired_frame
->enable
, FRAME_HEIGHT (f
));
1089 /* Called when about to quit, to check for doing so
1090 at an improper time. */
1095 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1097 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1099 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1103 /* Decide what insert/delete line to do, and do it */
1105 extern void scrolling_1 ();
1110 int unchanged_at_top
, unchanged_at_bottom
;
1113 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1114 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1115 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1117 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1118 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1119 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1121 /* Compute hash codes of all the lines.
1122 Also calculate number of changed lines,
1123 number of unchanged lines at the beginning,
1124 and number of unchanged lines at the end. */
1127 unchanged_at_top
= 0;
1128 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1129 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1131 /* Give up on this scrolling if some old lines are not enabled. */
1132 if (!current_frame
->enable
[i
])
1134 old_hash
[i
] = line_hash_code (current_frame
, i
);
1135 if (! desired_frame
->enable
[i
])
1136 new_hash
[i
] = old_hash
[i
];
1138 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1140 if (old_hash
[i
] != new_hash
[i
])
1143 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1145 else if (i
== unchanged_at_top
)
1147 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1150 /* If changed lines are few, don't allow preemption, don't scroll. */
1151 if (changed_lines
< baud_rate
/ 2400
1152 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1155 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1156 - unchanged_at_bottom
);
1158 if (scroll_region_ok
)
1159 free_at_end_vpos
-= unchanged_at_bottom
;
1160 else if (memory_below_frame
)
1161 free_at_end_vpos
= -1;
1163 /* If large window, fast terminal and few lines in common between
1164 current frame and desired frame, don't bother with i/d calc. */
1165 if (window_size
>= 18 && baud_rate
> 2400
1167 10 * scrolling_max_lines_saved (unchanged_at_top
,
1168 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1169 old_hash
, new_hash
, draw_cost
)))
1172 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1173 draw_cost
+ unchanged_at_top
- 1,
1174 old_hash
+ unchanged_at_top
- 1,
1175 new_hash
+ unchanged_at_top
- 1,
1176 free_at_end_vpos
- unchanged_at_top
);
1181 /* Return the offset in its buffer of the character at location col, line
1182 in the given window. */
1184 buffer_posn_from_coords (window
, col
, line
)
1185 struct window
*window
;
1188 int window_left
= XFASTINT (window
->left
);
1190 /* The actual width of the window is window->width less one for the
1191 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1193 int window_width
= (XFASTINT (window
->width
) - 1
1194 - (XFASTINT (window
->width
) + window_left
1195 != FRAME_WIDTH (XFRAME (window
->frame
))));
1197 int startp
= marker_position (window
->start
);
1199 /* Since compute_motion will only operate on the current buffer,
1200 we need to save the old one and restore it when we're done. */
1201 struct buffer
*old_current_buffer
= current_buffer
;
1202 struct position
*posn
;
1204 current_buffer
= XBUFFER (window
->buffer
);
1206 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1207 (window->frame))->bufp to avoid scanning from the very top of
1208 the window, but it isn't maintained correctly, and I'm not even
1209 sure I will keep it. */
1210 posn
= compute_motion (startp
, 0,
1211 (window
== XWINDOW (minibuf_window
) && startp
== 1
1212 ? minibuf_prompt_width
: 0),
1213 ZV
, line
, col
- window_left
,
1214 window_width
, XINT (window
->hscroll
), 0);
1216 current_buffer
= old_current_buffer
;
1218 /* compute_motion considers frame points past the end of a line
1219 to be *after* the newline, i.e. at the start of the next line.
1220 This is reasonable, but not really what we want. So if the
1221 result is on a line below LINE, back it up one character. */
1222 if (posn
->vpos
> line
)
1223 return posn
->bufpos
- 1;
1225 return posn
->bufpos
;
1232 register GLYPH
*p
= r
;
1233 while (*r
++ == SPACEGLYPH
);
1238 count_match (str1
, str2
)
1241 register GLYPH
*p1
= str1
;
1242 register GLYPH
*p2
= str2
;
1243 while (*p1
++ == *p2
++);
1244 return p1
- str1
- 1;
1247 /* Char insertion/deletion cost vector, from term.c */
1248 extern int *char_ins_del_vector
;
1250 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_HEIGHT((f))])
1253 update_line (frame
, vpos
)
1254 register FRAME_PTR frame
;
1257 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1259 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1261 register struct frame_glyphs
*current_frame
1262 = FRAME_CURRENT_GLYPHS (frame
);
1263 register struct frame_glyphs
*desired_frame
1264 = FRAME_DESIRED_GLYPHS (frame
);
1266 if (desired_frame
->highlight
[vpos
]
1267 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1269 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1270 (current_frame
->enable
[vpos
] ?
1271 current_frame
->used
[vpos
] : 0));
1272 current_frame
->enable
[vpos
] = 0;
1275 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1277 if (! current_frame
->enable
[vpos
])
1283 obody
= current_frame
->glyphs
[vpos
];
1284 olen
= current_frame
->used
[vpos
];
1285 if (! current_frame
->highlight
[vpos
])
1287 if (!must_write_spaces
)
1288 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1293 /* For an inverse-video line, remember we gave it
1294 spaces all the way to the frame edge
1295 so that the reverse video extends all the way across. */
1297 while (olen
< FRAME_WIDTH (frame
) - 1)
1298 obody
[olen
++] = SPACEGLYPH
;
1302 /* One way or another, this will enable the line being updated. */
1303 current_frame
->enable
[vpos
] = 1;
1304 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1305 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1306 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1308 #ifdef HAVE_X_WINDOWS
1309 if (FRAME_X_P (frame
))
1311 current_frame
->pix_width
[vpos
]
1312 = current_frame
->used
[vpos
]
1313 * FONT_WIDTH (frame
->display
.x
->font
);
1314 current_frame
->pix_height
[vpos
]
1315 = FONT_HEIGHT (frame
->display
.x
->font
);
1317 #endif /* HAVE_X_WINDOWS */
1319 if (!desired_frame
->enable
[vpos
])
1325 nbody
= desired_frame
->glyphs
[vpos
];
1326 nlen
= desired_frame
->used
[vpos
];
1328 /* Pretend trailing spaces are not there at all,
1329 unless for one reason or another we must write all spaces. */
1330 if (! desired_frame
->highlight
[vpos
])
1332 if (!must_write_spaces
)
1333 /* We know that the previous character byte contains 0. */
1334 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1339 /* For an inverse-video line, give it extra trailing spaces
1340 all the way to the frame edge
1341 so that the reverse video extends all the way across. */
1343 while (nlen
< FRAME_WIDTH (frame
) - 1)
1344 nbody
[nlen
++] = SPACEGLYPH
;
1347 /* If there's no i/d char, quickly do the best we can without it. */
1348 if (!char_ins_del_ok
)
1352 for (i
= 0; i
< nlen
; i
++)
1354 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1356 cursor_to (vpos
, i
);
1357 for (j
= 1; (i
+ j
< nlen
&&
1358 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1361 /* Output this run of non-matching chars. */
1362 write_glyphs (nbody
+ i
, j
);
1365 /* Now find the next non-match. */
1369 /* Clear the rest of the line, or the non-clear part of it. */
1372 cursor_to (vpos
, nlen
);
1373 clear_end_of_line (olen
);
1376 /* Exchange contents between current_frame and new_frame. */
1377 temp
= desired_frame
->glyphs
[vpos
];
1378 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1379 current_frame
->glyphs
[vpos
] = temp
;
1386 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1387 ? 0 : count_blanks (nbody
);
1390 cursor_to (vpos
, nsp
);
1391 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1394 /* Exchange contents between current_frame and new_frame. */
1395 temp
= desired_frame
->glyphs
[vpos
];
1396 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1397 current_frame
->glyphs
[vpos
] = temp
;
1406 /* Compute number of leading blanks in old and new contents. */
1407 osp
= count_blanks (obody
);
1408 if (!desired_frame
->highlight
[vpos
])
1409 nsp
= count_blanks (nbody
);
1413 /* Compute number of matching chars starting with first nonblank. */
1414 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1416 /* Spaces in new match implicit space past the end of old. */
1417 /* A bug causing this to be a no-op was fixed in 18.29. */
1418 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1421 while (np1
[begmatch
] == SPACEGLYPH
)
1425 /* Avoid doing insert/delete char
1426 just cause number of leading spaces differs
1427 when the following text does not match. */
1428 if (begmatch
== 0 && osp
!= nsp
)
1429 osp
= nsp
= min (osp
, nsp
);
1431 /* Find matching characters at end of line */
1434 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1435 while (op1
> op2
&& op1
[-1] == np1
[-1])
1440 endmatch
= obody
+ olen
- op1
;
1442 /* Put correct value back in nbody[nlen].
1443 This is important because direct_output_for_insert
1444 can write into the line at a later point.
1445 If this screws up the zero at the end of the line, re-establish it. */
1449 /* tem gets the distance to insert or delete.
1450 endmatch is how many characters we save by doing so.
1453 tem
= (nlen
- nsp
) - (olen
- osp
);
1455 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1458 /* nsp - osp is the distance to insert or delete.
1459 If that is nonzero, begmatch is known to be nonzero also.
1460 begmatch + endmatch is how much we save by doing the ins/del.
1464 && (!char_ins_del_ok
1465 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1469 osp
= nsp
= min (osp
, nsp
);
1472 /* Now go through the line, inserting, writing and
1473 deleting as appropriate. */
1477 cursor_to (vpos
, nsp
);
1478 delete_glyphs (osp
- nsp
);
1482 /* If going to delete chars later in line
1483 and insert earlier in the line,
1484 must delete first to avoid losing data in the insert */
1485 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1487 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1488 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1489 olen
= nlen
- (nsp
- osp
);
1491 cursor_to (vpos
, osp
);
1492 insert_glyphs ((char *)0, nsp
- osp
);
1496 tem
= nsp
+ begmatch
+ endmatch
;
1497 if (nlen
!= tem
|| olen
!= tem
)
1499 cursor_to (vpos
, nsp
+ begmatch
);
1500 if (!endmatch
|| nlen
== olen
)
1502 /* If new text being written reaches right margin,
1503 there is no need to do clear-to-eol at the end.
1504 (and it would not be safe, since cursor is not
1505 going to be "at the margin" after the text is done) */
1506 if (nlen
== FRAME_WIDTH (frame
))
1508 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1512 /* the following code loses disastrously if tem == nlen.
1513 Rather than trying to fix that case, I am trying the simpler
1514 solution found above. */
1516 /* If the text reaches to the right margin,
1517 it will lose one way or another (depending on AutoWrap)
1518 to clear to end of line after outputting all the text.
1519 So pause with one character to go and clear the line then. */
1520 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1522 /* endmatch must be zero, and tem must equal nsp + begmatch */
1523 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1524 clear_end_of_line (olen
);
1525 olen
= 0; /* Don't let it be cleared again later */
1526 write_glyphs (nbody
+ nlen
- 1, 1);
1529 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1530 #endif /* OBSOLETE */
1533 else if (nlen
> olen
)
1535 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1536 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1539 else if (olen
> nlen
)
1541 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1542 delete_glyphs (olen
- nlen
);
1548 /* If any unerased characters remain after the new line, erase them. */
1551 cursor_to (vpos
, nlen
);
1552 clear_end_of_line (olen
);
1555 /* Exchange contents between current_frame and new_frame. */
1556 temp
= desired_frame
->glyphs
[vpos
];
1557 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1558 current_frame
->glyphs
[vpos
] = temp
;
1561 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1562 1, 1, "FOpen termscript file: ",
1563 "Start writing all terminal output to FILE as well as the terminal.\n\
1564 FILE = nil means just close any termscript file currently open.")
1568 if (termscript
!= 0) fclose (termscript
);
1573 file
= Fexpand_file_name (file
, Qnil
);
1574 termscript
= fopen (XSTRING (file
)->data
, "w");
1575 if (termscript
== 0)
1576 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1584 window_change_signal ()
1588 int old_errno
= errno
;
1590 get_frame_size (&width
, &height
);
1592 /* The frame size change obviously applies to a termcap-controlled
1593 frame. Find such a frame in the list, and assume it's the only
1594 one (since the redisplay code always writes to stdout, not a
1595 FILE * specified in the frame structure). Record the new size,
1596 but don't reallocate the data structures now. Let that be done
1597 later outside of the signal handler. */
1603 FOR_EACH_FRAME (tail
, f
)
1605 if (FRAME_TERMCAP_P (f
))
1607 change_frame_size (f
, height
, width
, 0, 1);
1613 signal (SIGWINCH
, window_change_signal
);
1616 #endif /* SIGWINCH */
1619 /* Do any change in frame size that was requested by a signal. */
1621 do_pending_window_change ()
1623 /* If window_change_signal should have run before, run it now. */
1624 while (delayed_size_change
)
1629 delayed_size_change
= 0;
1631 FOR_EACH_FRAME (tail
, f
)
1633 int height
= FRAME_NEW_HEIGHT (f
);
1634 int width
= FRAME_NEW_WIDTH (f
);
1636 FRAME_NEW_HEIGHT (f
) = 0;
1637 FRAME_NEW_WIDTH (f
) = 0;
1640 change_frame_size (f
, height
, width
, 0, 0);
1646 /* Change the frame height and/or width. Values may be given as zero to
1647 indicate no change is to take place.
1649 If DELAY is non-zero, then assume we're being called from a signal
1650 handler, and queue the change for later - perhaps the next
1651 redisplay. Since this tries to resize windows, we can't call it
1652 from a signal handler. */
1654 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
1655 register FRAME_PTR frame
;
1656 int newheight
, newwidth
, pretend
;
1658 /* If we can't deal with the change now, queue it for later. */
1661 FRAME_NEW_HEIGHT (frame
) = newheight
;
1662 FRAME_NEW_WIDTH (frame
) = newwidth
;
1663 delayed_size_change
= 1;
1667 /* This size-change overrides any pending one for this frame. */
1668 FRAME_NEW_HEIGHT (frame
) = 0;
1669 FRAME_NEW_WIDTH (frame
) = 0;
1671 /* If an arguments is zero, set it to the current value. */
1672 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
1673 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
1675 /* Round up to the smallest acceptable size. */
1676 check_frame_size (frame
, &newheight
, &newwidth
);
1678 /* If we're not changing the frame size, quit now. */
1679 if (newheight
== FRAME_HEIGHT (frame
)
1680 && newwidth
== FRAME_WIDTH (frame
))
1683 if (newheight
!= FRAME_HEIGHT (frame
))
1685 if (FRAME_HAS_MINIBUF_P (frame
)
1686 && ! FRAME_MINIBUF_ONLY_P (frame
))
1688 /* Frame has both root and minibuffer. */
1689 set_window_height (FRAME_ROOT_WINDOW (frame
),
1691 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
)
1693 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
1696 /* Frame has just one top-level window. */
1697 set_window_height (FRAME_ROOT_WINDOW (frame
), newheight
, 0);
1699 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1700 FrameRows
= newheight
;
1703 if (frame
->output_method
== output_termcap
)
1705 frame_height
= newheight
;
1707 FrameRows
= newheight
;
1712 if (newwidth
!= FRAME_WIDTH (frame
))
1714 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
1715 if (FRAME_HAS_MINIBUF_P (frame
))
1716 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
1718 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1719 FrameCols
= newwidth
;
1721 if (frame
->output_method
== output_termcap
)
1723 frame_width
= newwidth
;
1725 FrameCols
= newwidth
;
1730 FRAME_HEIGHT (frame
) = newheight
;
1731 FRAME_WIDTH (frame
) = newwidth
;
1733 remake_frame_glyphs (frame
);
1734 calculate_costs (frame
);
1737 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
1738 Ssend_string_to_terminal
, 1, 1, 0,
1739 "Send STRING to the terminal without alteration.\n\
1740 Control characters in STRING will have terminal-dependent effects.")
1744 CHECK_STRING (str
, 0);
1745 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
1749 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
1750 fflush (termscript
);
1755 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
1756 "Beep, or flash the screen.\n\
1757 Also, unless an argument is given,\n\
1758 terminate any keyboard macro currently executing.")
1780 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
1781 error ("Keyboard macro terminated by a command ringing the bell");
1787 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
1788 "Pause, without updating display, for ARG seconds.\n\
1789 Optional second arg non-nil means ARG is measured in milliseconds.\n\
1790 \(Not all operating systems support milliseconds.)")
1792 Lisp_Object arg
, millisec
;
1797 CHECK_NUMBER (arg
, 0);
1802 if (!NILP (millisec
))
1804 #ifndef EMACS_HAS_USECS
1805 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
1807 usec
= sec
% 1000 * 1000;
1815 XFASTINT (zero
) = 0;
1816 wait_reading_process_input (sec
, usec
, zero
, 0);
1819 #if 0 /* No wait_reading_process_input */
1826 /* The reason this is done this way
1827 (rather than defined (H_S) && defined (H_T))
1828 is because the VMS preprocessor doesn't grok `defined' */
1830 EMACS_GET_TIME (end_time
);
1831 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
1832 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
1836 EMACS_GET_TIME (timeout
);
1837 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
1838 if (EMACS_TIME_NEG_P (timeout
)
1839 || !select (1, 0, 0, 0, &timeout
))
1842 #else /* not HAVE_SELECT */
1844 #endif /* HAVE_SELECT */
1845 #endif /* not VMS */
1848 #endif /* no subprocesses */
1853 /* This is just like wait_reading_process_input, except that
1854 it does the redisplay.
1856 It's also just like Fsit_for, except that it can be used for
1857 waiting for input as well. */
1860 sit_for (sec
, usec
, reading
, display
)
1861 int sec
, usec
, reading
, display
;
1863 Lisp_Object read_kbd
;
1865 if (detect_input_pending ())
1869 redisplay_preserve_echo_area ();
1871 if (sec
== 0 && usec
== 0)
1878 XSET (read_kbd
, Lisp_Int
, reading
? -1 : 1);
1879 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
1882 #if 0 /* No wait_reading_process_input available. */
1888 input_wait_timeout (XINT (arg
));
1890 #ifndef HAVE_TIMEVAL
1892 select (1, &waitchannels
, 0, 0, &timeout_sec
);
1893 #else /* HAVE_TIMEVAL */
1894 timeout
.tv_sec
= sec
;
1895 timeout
.tv_usec
= usec
;
1896 select (1, &waitchannels
, 0, 0, &timeout
);
1897 #endif /* HAVE_TIMEVAL */
1898 #endif /* not VMS */
1903 return detect_input_pending () ? Qnil
: Qt
;
1906 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
1907 "Perform redisplay, then wait for ARG seconds or until input is available.\n\
1908 Optional second arg non-nil means ARG counts in milliseconds.\n\
1909 Optional third arg non-nil means don't redisplay, just wait for input.\n\
1910 Redisplay is preempted as always if input arrives, and does not happen\n\
1911 if input is available before it starts.\n\
1912 Value is t if waited the full time with no input arriving.")
1913 (arg
, millisec
, nodisp
)
1914 Lisp_Object arg
, millisec
, nodisp
;
1919 CHECK_NUMBER (arg
, 0);
1922 if (!NILP (millisec
))
1924 #ifndef EMACS_HAS_USECS
1925 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
1927 usec
= (sec
% 1000) * 1000;
1932 return sit_for (sec
, usec
, 0, NILP (nodisp
));
1935 DEFUN ("sleep-for-millisecs", Fsleep_for_millisecs
, Ssleep_for_millisecs
,
1937 "Pause, without updating display, for ARG milliseconds.")
1943 #ifndef EMACS_HAS_USECS
1944 error ("sleep-for-millisecs not supported on %s", SYSTEM_TYPE
);
1946 CHECK_NUMBER (arg
, 0);
1948 XFASTINT (zero
) = 0;
1949 wait_reading_process_input (XINT (arg
) / 1000, XINT (arg
) % 1000 * 1000,
1952 #endif /* EMACS_HAS_USECS */
1955 char *terminal_type
;
1957 /* Initialization done when Emacs fork is started, before doing stty. */
1958 /* Determine terminal type and set terminal_driver */
1959 /* Then invoke its decoding routine to set up variables
1960 in the terminal package */
1964 #ifdef HAVE_X_WINDOWS
1965 extern int display_arg
;
1970 cursor_in_echo_area
= 0;
1971 terminal_type
= (char *) 0;
1973 /* If the DISPLAY environment variable is set, try to use X, and
1974 die with an error message if that doesn't work. */
1976 /* Check if we're using a window system here before trying to
1977 initialize the terminal. If we check the terminal first,
1979 If someone has indicated that they want
1980 to use a window system, we shouldn't bother initializing the
1981 terminal. This is especially important when the terminal is so
1982 dumb that emacs gives up before and doesn't bother using the window
1985 #ifdef HAVE_X_WINDOWS
1986 if (!inhibit_window_system
&& (display_arg
|| getenv ("DISPLAY")))
1988 Vwindow_system
= intern ("x");
1990 Vwindow_system_version
= make_number (11);
1992 Vwindow_system_version
= make_number (10);
1996 #endif /* HAVE_X_WINDOWS */
1998 /* If no window system has been specified, try to use the terminal. */
2001 fprintf (stderr
, "emacs: standard input is not a tty\n");
2005 /* Look at the TERM variable */
2006 terminal_type
= (char *) getenv ("TERM");
2010 fprintf (stderr
, "Please specify your terminal type.\n\
2011 For types defined in VMS, use set term /device=TYPE.\n\
2012 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2013 \(The quotation marks are necessary since terminal types are lower case.)\n");
2015 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2021 /* VMS DCL tends to upcase things, so downcase term type.
2022 Hardly any uppercase letters in terminal types; should be none. */
2024 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2027 strcpy (new, terminal_type
);
2029 for (p
= new; *p
; p
++)
2033 terminal_type
= new;
2037 term_init (terminal_type
);
2039 remake_frame_glyphs (selected_frame
);
2040 calculate_costs (selected_frame
);
2042 /* X and Y coordinates of the cursor between updates. */
2043 FRAME_CURSOR_X (selected_frame
) = 0;
2044 FRAME_CURSOR_Y (selected_frame
) = 0;
2049 #endif /* CANNOT_DUMP */
2050 signal (SIGWINCH
, window_change_signal
);
2051 #endif /* SIGWINCH */
2057 defsubr (&Sredraw_frame
);
2059 defsubr (&Sredraw_display
);
2060 defsubr (&Sopen_termscript
);
2062 defsubr (&Ssit_for
);
2063 defsubr (&Ssleep_for
);
2064 defsubr (&Ssend_string_to_terminal
);
2066 DEFVAR_INT ("baud-rate", &baud_rate
,
2067 "The output baud rate of the terminal.\n\
2068 On most systems, changing this value will affect the amount of padding\n\
2069 and the other strategic decisions made during redisplay.");
2070 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2071 "*Non-nil means invert the entire frame display.\n\
2072 This means everything is in inverse video which otherwise would not be.");
2073 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2074 "*Non-nil means try to flash the frame to represent a bell.");
2075 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2076 "*Non-nil means no need to redraw entire frame after suspending.\n\
2077 A non-nil value is useful if the terminal can automatically preserve\n\
2078 Emacs's frame display when you reenter Emacs.\n\
2079 It is up to you to set this variable if your terminal can do that.");
2080 DEFVAR_LISP ("window-system", &Vwindow_system
,
2081 "A symbol naming the window-system under which Emacs is running\n\
2082 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2083 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2084 "The version number of the window system in use.\n\
2085 For X windows, this is 10 or 11.");
2086 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2087 "Non-nil means put cursor in minibuffer, at end of any message there.");
2088 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2089 "Table defining how to output a glyph code to the frame.\n\
2090 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2091 Each element can be:\n\
2092 integer: a glyph code which this glyph is an alias for.\n\
2093 string: output this glyph using that string (not impl. in X windows).\n\
2094 nil: this glyph mod 256 is char code to output,\n\
2095 and this glyph / 256 is face code for X windows (see `x-set-face').");
2096 Vglyph_table
= Qnil
;
2098 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2099 "Display table to use for buffers that specify none.\n\
2100 See `buffer-display-table' for more information.");
2101 Vstandard_display_table
= Qnil
;
2103 /* Initialize `window-system', unless init_display already decided it. */
2108 Vwindow_system
= Qnil
;
2109 Vwindow_system_version
= Qnil
;