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. */
118 struct frame the_only_frame
;
121 /* This is a vector, made larger whenever it isn't large enough,
122 which is used inside `update_frame' to hold the old contents
123 of the FRAME_PHYS_LINES of the frame being updated. */
124 struct frame_glyphs
**ophys_lines
;
125 /* Length of vector currently allocated. */
126 int ophys_lines_length
;
128 FILE *termscript
; /* Stdio stream being used for copy of all output. */
130 struct cm Wcm
; /* Structure for info on cursor positioning */
132 extern short ospeed
; /* Output speed (from sg_ospeed) */
134 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
138 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
139 "Clear frame FRAME and output again what is supposed to appear on it.")
145 CHECK_LIVE_FRAME (frame
, 0);
148 /* set_terminal_modes (); */
150 clear_frame_records (f
);
153 windows_or_buffers_changed
++;
154 /* Mark all windows as INaccurate,
155 so that every window will have its redisplay done. */
156 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
161 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
162 "Redraw all frames marked as having their images garbled.")
165 Lisp_Object frame
, tail
;
167 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
169 frame
= XCONS (tail
)->car
;
170 if (XFRAME (frame
)->garbaged
&& XFRAME (frame
)->visible
)
171 Fredraw_frame (frame
);
180 XSET (frame
, Lisp_Frame
, f
);
181 Fredraw_frame (frame
);
184 #else /* not MULTI_FRAME */
186 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, 0,
187 "Clear screen and output again what is supposed to appear on it.")
191 set_terminal_modes ();
195 clear_frame_records (0);
196 windows_or_buffers_changed
++;
197 /* Mark all windows as INaccurate,
198 so that every window will have its redisplay done. */
199 mark_window_display_accurate (XWINDOW (minibuf_window
)->prev
, 0);
203 #endif /* not MULTI_FRAME */
205 static struct frame_glyphs
*
206 make_frame_glyphs (frame
, empty
)
207 register FRAME_PTR frame
;
211 register width
= FRAME_WIDTH (frame
);
212 register height
= FRAME_HEIGHT (frame
);
213 register struct frame_glyphs
*new =
214 (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
216 SET_GLYPHS_FRAME (new, frame
);
217 new->height
= height
;
219 new->used
= (int *) xmalloc (height
* sizeof (int));
220 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
221 new->highlight
= (char *) xmalloc (height
* sizeof (char));
222 new->enable
= (char *) xmalloc (height
* sizeof (char));
223 bzero (new->enable
, height
* sizeof (char));
224 new->bufp
= (int *) xmalloc (height
* sizeof (int));
226 #ifdef HAVE_X_WINDOWS
227 if (FRAME_X_P (frame
))
229 new->nruns
= (int *) xmalloc (height
* sizeof (int));
231 = (struct run
**) xmalloc (height
* sizeof (struct run
*));
232 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
233 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
234 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
235 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
241 /* Make the buffer used by decode_mode_spec. This buffer is also
242 used as temporary storage when updating the frame. See scroll.c. */
243 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
245 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
246 bzero (new->total_contents
, total_glyphs
);
250 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
252 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
253 bzero (new->total_contents
, total_glyphs
);
254 for (i
= 0; i
< height
; i
++)
255 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
262 free_frame_glyphs (frame
, glyphs
)
264 struct frame_glyphs
*glyphs
;
266 if (glyphs
->total_contents
)
267 free (glyphs
->total_contents
);
270 free (glyphs
->glyphs
);
271 free (glyphs
->highlight
);
272 free (glyphs
->enable
);
275 #ifdef HAVE_X_WINDOWS
276 if (FRAME_X_P (frame
))
278 free (glyphs
->nruns
);
279 free (glyphs
->face_list
);
280 free (glyphs
->top_left_x
);
281 free (glyphs
->top_left_y
);
282 free (glyphs
->pix_width
);
283 free (glyphs
->pix_height
);
291 remake_frame_glyphs (frame
)
294 if (FRAME_CURRENT_GLYPHS (frame
))
295 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
296 if (FRAME_DESIRED_GLYPHS (frame
))
297 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
298 if (FRAME_TEMP_GLYPHS (frame
))
299 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
301 if (FRAME_MESSAGE_BUF (frame
))
302 FRAME_MESSAGE_BUF (frame
)
303 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
304 FRAME_WIDTH (frame
) + 1);
306 FRAME_MESSAGE_BUF (frame
)
307 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
309 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
310 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
311 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
312 SET_FRAME_GARBAGED (frame
);
315 /* Return the hash code of contents of line VPOS in frame-matrix M. */
318 line_hash_code (m
, vpos
)
319 register struct frame_glyphs
*m
;
322 register GLYPH
*body
, *end
;
325 if (!m
->enable
[vpos
])
328 /* Give all lighlighted lines the same hash code
329 so as to encourage scrolling to leave them in place. */
330 if (m
->highlight
[vpos
])
333 body
= m
->glyphs
[vpos
];
335 if (must_write_spaces
)
342 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
351 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
359 /* Return number of characters in line in M at vpos VPOS,
360 except don't count leading and trailing spaces
361 unless the terminal requires those to be explicitly output. */
364 line_draw_cost (m
, vpos
)
365 struct frame_glyphs
*m
;
368 register GLYPH
*beg
= m
->glyphs
[vpos
];
369 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
371 register int tlen
= GLYPH_TABLE_LENGTH
;
372 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
374 /* Ignore trailing and leading spaces if we can. */
375 if (!must_write_spaces
)
377 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
380 return (0); /* All blank line. */
382 while (*beg
== SPACEGLYPH
)
386 /* If we don't have a glyph-table, each glyph is one character,
387 so return the number of glyphs. */
391 /* Otherwise, scan the glyphs and accumulate their total size in I. */
393 while ((beg
<= end
) && *beg
)
395 register GLYPH g
= *beg
++;
397 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
400 i
+= GLYPH_LENGTH (tbase
, g
);
405 /* The functions on this page are the interface from xdisp.c to redisplay.
407 The only other interface into redisplay is through setting
408 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
409 and SET_FRAME_GARBAGED (frame). */
411 /* cancel_line eliminates any request to display a line at position `vpos' */
413 cancel_line (vpos
, frame
)
415 register FRAME_PTR frame
;
417 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
420 clear_frame_records (frame
)
421 register FRAME_PTR frame
;
423 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
426 /* Prepare to display on line VPOS starting at HPOS within it. */
429 get_display_line (frame
, vpos
, hpos
)
430 register FRAME_PTR frame
;
434 register struct frame_glyphs
*glyphs
;
435 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
438 if (vpos
< 0 || (! FRAME_VISIBLE_P (frame
)))
441 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
444 if (! desired_glyphs
->enable
[vpos
])
446 desired_glyphs
->used
[vpos
] = 0;
447 desired_glyphs
->highlight
[vpos
] = 0;
448 desired_glyphs
->enable
[vpos
] = 1;
451 if (hpos
> desired_glyphs
->used
[vpos
])
453 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
454 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
456 desired_glyphs
->used
[vpos
] = hpos
;
462 /* Like bcopy except never gets confused by overlap. */
465 safe_bcopy (from
, to
, size
)
475 /* If destination is higher in memory, and overlaps source zone,
476 copy from the end. */
477 if (from
< to
&& from
+ size
> to
)
482 /* If TO - FROM is large, then we should break the copy into
483 nonoverlapping chunks of TO - FROM bytes each. However, if
484 TO - FROM is small, then the bcopy function call overhead
485 makes this not worth it. The crossover point could be about
486 anywhere. Since I don't think the obvious copy loop is ever
487 too bad, I'm trying to err in its favor. */
492 while (endf
!= from
);
496 /* Since TO - FROM >= 64, the overlap is less than SIZE,
497 so we can always safely do this loop once. */
503 bcopy (endf
, endt
, to
- from
);
506 /* If TO - FROM wasn't a multiple of SIZE, there will be a
507 little left over. The amount left over is
508 (endt + (to - from)) - to, which is endt - from. */
509 bcopy (from
, to
, endt
- from
);
513 bcopy (from
, to
, size
);
518 safe_bcopy (from
, to
, size
)
528 /* If destination is higher in memory, and overlaps source zone,
529 copy from the end. */
530 if (from
< to
&& from
+ size
> to
)
537 while (endf
!= from
);
542 bcopy (from
, to
, size
);
546 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
547 DISTANCE may be negative. */
550 rotate_vector (vector
, size
, distance
)
555 char *temp
= (char *) alloca (size
);
560 bcopy (vector
, temp
+ distance
, size
- distance
);
561 bcopy (vector
+ size
- distance
, temp
, distance
);
562 bcopy (temp
, vector
, size
);
565 /* Scroll lines from vpos FROM up to but not including vpos END
566 down by AMOUNT lines (AMOUNT may be negative).
567 Returns nonzero if done, zero if terminal cannot scroll them. */
570 scroll_frame_lines (frame
, from
, end
, amount
)
571 register FRAME_PTR frame
;
572 int from
, end
, amount
;
575 register struct frame_glyphs
*current_frame
576 = FRAME_CURRENT_GLYPHS (frame
);
578 if (!line_ins_del_ok
)
586 update_begin (frame
);
587 set_terminal_window (end
+ amount
);
588 if (!scroll_region_ok
)
589 ins_del_lines (end
, -amount
);
590 ins_del_lines (from
, amount
);
591 set_terminal_window (0);
593 rotate_vector (current_frame
->glyphs
+ from
,
594 sizeof (GLYPH
*) * (end
+ amount
- from
),
595 amount
* sizeof (GLYPH
*));
597 safe_bcopy (current_frame
->used
+ from
,
598 current_frame
->used
+ from
+ amount
,
599 (end
- from
) * sizeof current_frame
->used
[0]);
601 safe_bcopy (current_frame
->highlight
+ from
,
602 current_frame
->highlight
+ from
+ amount
,
603 (end
- from
) * sizeof current_frame
->highlight
[0]);
605 safe_bcopy (current_frame
->enable
+ from
,
606 current_frame
->enable
+ from
+ amount
,
607 (end
- from
) * sizeof current_frame
->enable
[0]);
609 /* Mark the lines made empty by scrolling as enabled, empty and
611 bzero (current_frame
->used
+ from
,
612 amount
* sizeof current_frame
->used
[0]);
613 bzero (current_frame
->highlight
+ from
,
614 amount
* sizeof current_frame
->highlight
[0]);
615 for (i
= from
; i
< from
+ amount
; i
++)
617 current_frame
->glyphs
[i
][0] = '\0';
618 current_frame
->enable
[i
] = 1;
621 safe_bcopy (current_frame
->bufp
+ from
,
622 current_frame
->bufp
+ from
+ amount
,
623 (end
- from
) * sizeof current_frame
->bufp
[0]);
625 #ifdef HAVE_X_WINDOWS
626 if (FRAME_X_P (frame
))
628 safe_bcopy (current_frame
->nruns
+ from
,
629 current_frame
->nruns
+ from
+ amount
,
630 (end
- from
) * sizeof current_frame
->nruns
[0]);
632 safe_bcopy (current_frame
->face_list
+ from
,
633 current_frame
->face_list
+ from
+ amount
,
634 (end
- from
) * sizeof current_frame
->face_list
[0]);
636 safe_bcopy (current_frame
->top_left_x
+ from
,
637 current_frame
->top_left_x
+ from
+ amount
,
638 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
640 safe_bcopy (current_frame
->top_left_y
+ from
,
641 current_frame
->top_left_y
+ from
+ amount
,
642 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
644 safe_bcopy (current_frame
->pix_width
+ from
,
645 current_frame
->pix_width
+ from
+ amount
,
646 (end
- from
) * sizeof current_frame
->pix_width
[0]);
648 safe_bcopy (current_frame
->pix_height
+ from
,
649 current_frame
->pix_height
+ from
+ amount
,
650 (end
- from
) * sizeof current_frame
->pix_height
[0]);
652 #endif /* HAVE_X_WINDOWS */
658 update_begin (frame
);
659 set_terminal_window (end
);
660 ins_del_lines (from
+ amount
, amount
);
661 if (!scroll_region_ok
)
662 ins_del_lines (end
+ amount
, -amount
);
663 set_terminal_window (0);
665 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
666 sizeof (GLYPH
*) * (end
- from
- amount
),
667 amount
* sizeof (GLYPH
*));
669 safe_bcopy (current_frame
->used
+ from
,
670 current_frame
->used
+ from
+ amount
,
671 (end
- from
) * sizeof current_frame
->used
[0]);
673 safe_bcopy (current_frame
->highlight
+ from
,
674 current_frame
->highlight
+ from
+ amount
,
675 (end
- from
) * sizeof current_frame
->highlight
[0]);
677 safe_bcopy (current_frame
->enable
+ from
,
678 current_frame
->enable
+ from
+ amount
,
679 (end
- from
) * sizeof current_frame
->enable
[0]);
681 /* Mark the lines made empty by scrolling as enabled, empty and
683 bzero (current_frame
->used
+ end
+ amount
,
684 - amount
* sizeof current_frame
->used
[0]);
685 bzero (current_frame
->highlight
+ end
+ amount
,
686 - amount
* sizeof current_frame
->highlight
[0]);
687 for (i
= end
+ amount
; i
< end
; i
++)
689 current_frame
->glyphs
[i
][0] = '\0';
690 current_frame
->enable
[i
] = 1;
693 safe_bcopy (current_frame
->bufp
+ from
,
694 current_frame
->bufp
+ from
+ amount
,
695 (end
- from
) * sizeof current_frame
->bufp
[0]);
697 #ifdef HAVE_X_WINDOWS
698 if (FRAME_X_P (frame
))
700 safe_bcopy (current_frame
->nruns
+ from
,
701 current_frame
->nruns
+ from
+ amount
,
702 (end
- from
) * sizeof current_frame
->nruns
[0]);
704 safe_bcopy (current_frame
->face_list
+ from
,
705 current_frame
->face_list
+ from
+ amount
,
706 (end
- from
) * sizeof current_frame
->face_list
[0]);
708 safe_bcopy (current_frame
->top_left_x
+ from
,
709 current_frame
->top_left_x
+ from
+ amount
,
710 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
712 safe_bcopy (current_frame
->top_left_y
+ from
,
713 current_frame
->top_left_y
+ from
+ amount
,
714 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
716 safe_bcopy (current_frame
->pix_width
+ from
,
717 current_frame
->pix_width
+ from
+ amount
,
718 (end
- from
) * sizeof current_frame
->pix_width
[0]);
720 safe_bcopy (current_frame
->pix_height
+ from
,
721 current_frame
->pix_height
+ from
+ amount
,
722 (end
- from
) * sizeof current_frame
->pix_height
[0]);
724 #endif /* HAVE_X_WINDOWS */
731 /* After updating a window W that isn't the full frame wide,
732 copy all the columns that W does not occupy
733 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
734 so that update_frame will not change those columns. */
736 preserve_other_columns (w
)
740 register struct frame_glyphs
*current_frame
, *desired_frame
;
741 register FRAME_PTR frame
= XFRAME (w
->frame
);
742 int start
= XFASTINT (w
->left
);
743 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
744 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
746 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
747 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
749 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
751 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
757 bcopy (current_frame
->glyphs
[vpos
],
758 desired_frame
->glyphs
[vpos
], start
);
759 len
= min (start
, current_frame
->used
[vpos
]);
760 if (desired_frame
->used
[vpos
] < len
)
761 desired_frame
->used
[vpos
] = len
;
763 if (current_frame
->used
[vpos
] > end
764 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
766 while (desired_frame
->used
[vpos
] < end
)
767 desired_frame
->glyphs
[vpos
][desired_frame
->used
[vpos
]++]
769 bcopy (current_frame
->glyphs
[vpos
] + end
,
770 desired_frame
->glyphs
[vpos
] + end
,
771 current_frame
->used
[vpos
] - end
);
772 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
780 /* If window w does not need to be updated and isn't the full frame wide,
781 copy all the columns that w does occupy
782 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
783 so that update_frame will not change those columns.
785 Have not been able to figure out how to use this correctly. */
787 preserve_my_columns (w
)
790 register int vpos
, fin
;
791 register struct frame_glyphs
*l1
, *l2
;
792 register FRAME_PTR frame
= XFRAME (w
->frame
);
793 int start
= XFASTINT (w
->left
);
794 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
795 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
797 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
799 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
800 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
802 if (l2
->length
> start
&& l1
->length
< l2
->length
)
805 if (fin
> end
) fin
= end
;
806 while (l1
->length
< start
)
807 l1
->body
[l1
->length
++] = ' ';
808 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
817 /* On discovering that the redisplay for a window was no good,
818 cancel the columns of that window, so that when the window is
819 displayed over again get_display_line will not complain. */
821 cancel_my_columns (w
)
825 register struct frame_glyphs
*desired_glyphs
=
826 FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
827 register int start
= XFASTINT (w
->left
);
828 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
830 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
831 if (desired_glyphs
->enable
[vpos
]
832 && desired_glyphs
->used
[vpos
] >= start
)
833 desired_glyphs
->used
[vpos
] = start
;
836 /* These functions try to perform directly and immediately on the frame
837 the necessary output for one change in the buffer.
838 They may return 0 meaning nothing was done if anything is difficult,
839 or 1 meaning the output was performed properly.
840 They assume that the frame was up to date before the buffer
841 change being displayed. THey make various other assumptions too;
842 see command_loop_1 where these are called. */
845 direct_output_for_insert (g
)
848 register FRAME_PTR frame
= selected_frame
;
849 register struct frame_glyphs
*current_frame
850 = FRAME_CURRENT_GLYPHS (frame
);
852 #ifndef COMPILER_REGISTER_BUG
854 #endif /* COMPILER_REGISTER_BUG */
855 struct window
*w
= XWINDOW (selected_window
);
856 #ifndef COMPILER_REGISTER_BUG
858 #endif /* COMPILER_REGISTER_BUG */
859 int hpos
= FRAME_CURSOR_X (frame
);
860 #ifndef COMPILER_REGISTER_BUG
862 #endif /* COMPILER_REGISTER_BUG */
863 int vpos
= FRAME_CURSOR_Y (frame
);
865 /* Give up if about to continue line */
866 if (hpos
- XFASTINT (w
->left
) + 1 + 1 >= XFASTINT (w
->width
)
868 /* Avoid losing if cursor is in invisible text off left margin */
869 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
871 /* Give up if cursor outside window (in minibuf, probably) */
872 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
873 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
875 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
876 || !display_completed
878 /* Give up if buffer appears in two places. */
881 /* Give up if w is minibuffer and a message is being displayed there */
882 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
885 current_frame
->glyphs
[vpos
][hpos
] = g
;
886 unchanged_modified
= MODIFF
;
887 beg_unchanged
= GPT
- BEG
;
888 XFASTINT (w
->last_point
) = point
;
889 XFASTINT (w
->last_point_x
) = hpos
;
890 XFASTINT (w
->last_modified
) = MODIFF
;
892 reassert_line_highlight (0, vpos
);
893 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
895 ++FRAME_CURSOR_X (frame
);
896 if (hpos
== current_frame
->used
[vpos
])
898 current_frame
->used
[vpos
] = hpos
+ 1;
899 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
906 direct_output_forward_char (n
)
909 register FRAME_PTR frame
= selected_frame
;
910 register struct window
*w
= XWINDOW (selected_window
);
912 /* Avoid losing if cursor is in invisible text off left margin
913 or about to go off either side of window. */
914 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
915 && (XINT (w
->hscroll
) || n
< 0))
917 && (FRAME_CURSOR_X (frame
) + 1
918 >= (XFASTINT (w
->left
) + XFASTINT (w
->width
)
919 - (XFASTINT (w
->width
) < FRAME_WIDTH (frame
))
923 FRAME_CURSOR_X (frame
) += n
;
924 XFASTINT (w
->last_point_x
) = FRAME_CURSOR_X (frame
);
925 XFASTINT (w
->last_point
) = point
;
926 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
931 static void update_line ();
933 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
934 Value is nonzero if redisplay stopped due to pending input.
935 FORCE nonzero means do not stop for pending input. */
938 update_frame (f
, force
, inhibit_hairy_id
)
941 int inhibit_hairy_id
;
943 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (f
);
944 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (f
);
947 int preempt_count
= baud_rate
/ 2400 + 1;
948 extern input_pending
;
949 #ifdef HAVE_X_WINDOWS
950 register int downto
, leftmost
;
953 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
955 detect_input_pending ();
956 if (input_pending
&& !force
)
964 if (!line_ins_del_ok
)
965 inhibit_hairy_id
= 1;
967 /* See if any of the desired lines are enabled; don't compute for
968 i/d line if just want cursor motion. */
969 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
970 if (desired_frame
->enable
[i
])
973 /* Try doing i/d line, if not yet inhibited. */
974 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
975 force
|= scrolling (f
);
977 /* Update the individual lines as needed. Do bottom line first. */
979 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
980 update_line (f
, FRAME_HEIGHT (f
) - 1);
982 #ifdef HAVE_X_WINDOWS
985 leftmost
= downto
= f
->display
.x
->internal_border_width
;
986 if (desired_frame
->enable
[0])
988 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
989 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
990 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
991 - LINE_HEIGHT(f
, FRAME_HEIGHT (f
) - 1);
992 current_frame
->top_left_x
[0] = leftmost
;
993 current_frame
->top_left_y
[0] = downto
;
996 #endif /* HAVE_X_WINDOWS */
998 /* Now update the rest of the lines. */
999 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1001 if (desired_frame
->enable
[i
])
1003 if (FRAME_TERMCAP_P (f
))
1005 /* Flush out every so many lines.
1006 Also flush out if likely to have more than 1k buffered
1007 otherwise. I'm told that some telnet connections get
1008 really screwed by more than 1k output at once. */
1009 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1011 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1014 if (preempt_count
== 1)
1016 #ifdef EMACS_OUTQSIZE
1017 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1018 /* Probably not a tty. Ignore the error and reset
1019 * the outq count. */
1020 outq
= PENDING_OUTPUT_COUNT (stdout
);
1023 sleep (outq
/ baud_rate
);
1026 if ((i
- 1) % preempt_count
== 0)
1027 detect_input_pending ();
1031 #ifdef HAVE_X_WINDOWS
1034 current_frame
->top_left_y
[i
] = downto
;
1035 current_frame
->top_left_x
[i
] = leftmost
;
1037 #endif /* HAVE_X_WINDOWS */
1040 #ifdef HAVE_X_WINDOWS
1042 downto
+= LINE_HEIGHT(f
, i
);
1045 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1047 /* Now just clean up termcap drivers and set cursor, etc. */
1050 if (cursor_in_echo_area
)
1052 if (f
== selected_frame
1053 && cursor_in_echo_area
< 0)
1054 cursor_to (FRAME_HEIGHT (f
) - 1, 0);
1055 else if (f
== selected_frame
1056 && ! current_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1057 cursor_to (FRAME_HEIGHT (f
) - 1, 0);
1059 cursor_to (FRAME_HEIGHT (f
) - 1,
1060 min (FRAME_WIDTH (f
) - 1,
1061 current_frame
->used
[FRAME_HEIGHT (f
) - 1]));
1064 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1065 FRAME_WIDTH (f
) - 1), 0));
1071 fflush (termscript
);
1074 /* Here if output is preempted because input is detected. */
1077 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1078 display_completed
= !pause
;
1080 bzero (desired_frame
->enable
, FRAME_HEIGHT (f
));
1084 /* Called when about to quit, to check for doing so
1085 at an improper time. */
1090 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1092 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1094 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1098 /* Decide what insert/delete line to do, and do it */
1100 extern void scrolling_1 ();
1105 int unchanged_at_top
, unchanged_at_bottom
;
1108 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1109 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1110 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1112 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1113 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1114 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1116 /* Compute hash codes of all the lines.
1117 Also calculate number of changed lines,
1118 number of unchanged lines at the beginning,
1119 and number of unchanged lines at the end. */
1122 unchanged_at_top
= 0;
1123 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1124 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1126 /* Give up on this scrolling if some old lines are not enabled. */
1127 if (!current_frame
->enable
[i
])
1129 old_hash
[i
] = line_hash_code (current_frame
, i
);
1130 if (! desired_frame
->enable
[i
])
1131 new_hash
[i
] = old_hash
[i
];
1133 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1135 if (old_hash
[i
] != new_hash
[i
])
1138 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1140 else if (i
== unchanged_at_top
)
1142 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1145 /* If changed lines are few, don't allow preemption, don't scroll. */
1146 if (changed_lines
< baud_rate
/ 2400
1147 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1150 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1151 - unchanged_at_bottom
);
1153 if (scroll_region_ok
)
1154 free_at_end_vpos
-= unchanged_at_bottom
;
1155 else if (memory_below_frame
)
1156 free_at_end_vpos
= -1;
1158 /* If large window, fast terminal and few lines in common between
1159 current frame and desired frame, don't bother with i/d calc. */
1160 if (window_size
>= 18 && baud_rate
> 2400
1162 10 * scrolling_max_lines_saved (unchanged_at_top
,
1163 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1164 old_hash
, new_hash
, draw_cost
)))
1167 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1168 draw_cost
+ unchanged_at_top
- 1,
1169 old_hash
+ unchanged_at_top
- 1,
1170 new_hash
+ unchanged_at_top
- 1,
1171 free_at_end_vpos
- unchanged_at_top
);
1176 /* Return the offset in its buffer of the character at location col, line
1177 in the given window. */
1179 buffer_posn_from_coords (window
, col
, line
)
1180 struct window
*window
;
1183 int window_left
= XFASTINT (window
->left
);
1185 /* The actual width of the window is window->width less one for the
1186 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1188 int window_width
= (XFASTINT (window
->width
) - 1
1189 - (XFASTINT (window
->width
) + window_left
1190 != FRAME_WIDTH (XFRAME (window
->frame
))));
1192 int startp
= marker_position (window
->start
);
1194 /* Since compute_motion will only operate on the current buffer,
1195 we need to save the old one and restore it when we're done. */
1196 struct buffer
*old_current_buffer
= current_buffer
;
1197 struct position
*posn
;
1199 current_buffer
= XBUFFER (window
->buffer
);
1201 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1202 (window->frame))->bufp to avoid scanning from the very top of
1203 the window, but it isn't maintained correctly, and I'm not even
1204 sure I will keep it. */
1205 posn
= compute_motion (startp
, 0,
1206 (window
== XWINDOW (minibuf_window
) && startp
== 1
1207 ? minibuf_prompt_width
: 0),
1208 ZV
, line
, col
- window_left
,
1209 window_width
, XINT (window
->hscroll
), 0);
1211 current_buffer
= old_current_buffer
;
1213 /* compute_motion considers frame points past the end of a line
1214 to be *after* the newline, i.e. at the start of the next line.
1215 This is reasonable, but not really what we want. So if the
1216 result is on a line below LINE, back it up one character. */
1217 if (posn
->vpos
> line
)
1218 return posn
->bufpos
- 1;
1220 return posn
->bufpos
;
1227 register GLYPH
*p
= r
;
1228 while (*r
++ == SPACEGLYPH
);
1233 count_match (str1
, str2
)
1236 register GLYPH
*p1
= str1
;
1237 register GLYPH
*p2
= str2
;
1238 while (*p1
++ == *p2
++);
1239 return p1
- str1
- 1;
1242 /* Char insertion/deletion cost vector, from term.c */
1243 extern int *char_ins_del_vector
;
1245 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_HEIGHT((f))])
1248 update_line (frame
, vpos
)
1249 register FRAME_PTR frame
;
1252 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1254 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1256 register struct frame_glyphs
*current_frame
1257 = FRAME_CURRENT_GLYPHS (frame
);
1258 register struct frame_glyphs
*desired_frame
1259 = FRAME_DESIRED_GLYPHS (frame
);
1261 if (desired_frame
->highlight
[vpos
]
1262 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1264 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1265 (current_frame
->enable
[vpos
] ?
1266 current_frame
->used
[vpos
] : 0));
1267 current_frame
->enable
[vpos
] = 0;
1270 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1272 if (! current_frame
->enable
[vpos
])
1278 obody
= current_frame
->glyphs
[vpos
];
1279 olen
= current_frame
->used
[vpos
];
1280 if (! current_frame
->highlight
[vpos
])
1282 if (!must_write_spaces
)
1283 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1288 /* For an inverse-video line, remember we gave it
1289 spaces all the way to the frame edge
1290 so that the reverse video extends all the way across. */
1292 while (olen
< FRAME_WIDTH (frame
) - 1)
1293 obody
[olen
++] = SPACEGLYPH
;
1297 /* One way or another, this will enable the line being updated. */
1298 current_frame
->enable
[vpos
] = 1;
1299 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1300 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1301 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1303 #ifdef HAVE_X_WINDOWS
1304 if (FRAME_X_P (frame
))
1306 current_frame
->pix_width
[vpos
]
1307 = current_frame
->used
[vpos
]
1308 * FONT_WIDTH (frame
->display
.x
->font
);
1309 current_frame
->pix_height
[vpos
]
1310 = FONT_HEIGHT (frame
->display
.x
->font
);
1312 #endif /* HAVE_X_WINDOWS */
1314 if (!desired_frame
->enable
[vpos
])
1320 nbody
= desired_frame
->glyphs
[vpos
];
1321 nlen
= desired_frame
->used
[vpos
];
1323 /* Pretend trailing spaces are not there at all,
1324 unless for one reason or another we must write all spaces. */
1325 if (! desired_frame
->highlight
[vpos
])
1327 if (!must_write_spaces
)
1328 /* We know that the previous character byte contains 0. */
1329 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1334 /* For an inverse-video line, give it extra trailing spaces
1335 all the way to the frame edge
1336 so that the reverse video extends all the way across. */
1338 while (nlen
< FRAME_WIDTH (frame
) - 1)
1339 nbody
[nlen
++] = SPACEGLYPH
;
1342 /* If there's no i/d char, quickly do the best we can without it. */
1343 if (!char_ins_del_ok
)
1347 for (i
= 0; i
< nlen
; i
++)
1349 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1351 cursor_to (vpos
, i
);
1352 for (j
= 1; (i
+ j
< nlen
&&
1353 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1356 /* Output this run of non-matching chars. */
1357 write_glyphs (nbody
+ i
, j
);
1360 /* Now find the next non-match. */
1364 /* Clear the rest of the line, or the non-clear part of it. */
1367 cursor_to (vpos
, nlen
);
1368 clear_end_of_line (olen
);
1371 /* Exchange contents between current_frame and new_frame. */
1372 temp
= desired_frame
->glyphs
[vpos
];
1373 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1374 current_frame
->glyphs
[vpos
] = temp
;
1381 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1382 ? 0 : count_blanks (nbody
);
1385 cursor_to (vpos
, nsp
);
1386 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1389 /* Exchange contents between current_frame and new_frame. */
1390 temp
= desired_frame
->glyphs
[vpos
];
1391 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1392 current_frame
->glyphs
[vpos
] = temp
;
1401 /* Compute number of leading blanks in old and new contents. */
1402 osp
= count_blanks (obody
);
1403 if (!desired_frame
->highlight
[vpos
])
1404 nsp
= count_blanks (nbody
);
1408 /* Compute number of matching chars starting with first nonblank. */
1409 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1411 /* Spaces in new match implicit space past the end of old. */
1412 /* A bug causing this to be a no-op was fixed in 18.29. */
1413 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1416 while (np1
[begmatch
] == SPACEGLYPH
)
1420 /* Avoid doing insert/delete char
1421 just cause number of leading spaces differs
1422 when the following text does not match. */
1423 if (begmatch
== 0 && osp
!= nsp
)
1424 osp
= nsp
= min (osp
, nsp
);
1426 /* Find matching characters at end of line */
1429 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1430 while (op1
> op2
&& op1
[-1] == np1
[-1])
1435 endmatch
= obody
+ olen
- op1
;
1437 /* Put correct value back in nbody[nlen].
1438 This is important because direct_output_for_insert
1439 can write into the line at a later point.
1440 If this screws up the zero at the end of the line, re-establish it. */
1444 /* tem gets the distance to insert or delete.
1445 endmatch is how many characters we save by doing so.
1448 tem
= (nlen
- nsp
) - (olen
- osp
);
1450 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1453 /* nsp - osp is the distance to insert or delete.
1454 If that is nonzero, begmatch is known to be nonzero also.
1455 begmatch + endmatch is how much we save by doing the ins/del.
1459 && (!char_ins_del_ok
1460 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1464 osp
= nsp
= min (osp
, nsp
);
1467 /* Now go through the line, inserting, writing and
1468 deleting as appropriate. */
1472 cursor_to (vpos
, nsp
);
1473 delete_glyphs (osp
- nsp
);
1477 /* If going to delete chars later in line
1478 and insert earlier in the line,
1479 must delete first to avoid losing data in the insert */
1480 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1482 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1483 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1484 olen
= nlen
- (nsp
- osp
);
1486 cursor_to (vpos
, osp
);
1487 insert_glyphs ((char *)0, nsp
- osp
);
1491 tem
= nsp
+ begmatch
+ endmatch
;
1492 if (nlen
!= tem
|| olen
!= tem
)
1494 cursor_to (vpos
, nsp
+ begmatch
);
1495 if (!endmatch
|| nlen
== olen
)
1497 /* If new text being written reaches right margin,
1498 there is no need to do clear-to-eol at the end.
1499 (and it would not be safe, since cursor is not
1500 going to be "at the margin" after the text is done) */
1501 if (nlen
== FRAME_WIDTH (frame
))
1503 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1507 /* the following code loses disastrously if tem == nlen.
1508 Rather than trying to fix that case, I am trying the simpler
1509 solution found above. */
1511 /* If the text reaches to the right margin,
1512 it will lose one way or another (depending on AutoWrap)
1513 to clear to end of line after outputting all the text.
1514 So pause with one character to go and clear the line then. */
1515 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1517 /* endmatch must be zero, and tem must equal nsp + begmatch */
1518 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1519 clear_end_of_line (olen
);
1520 olen
= 0; /* Don't let it be cleared again later */
1521 write_glyphs (nbody
+ nlen
- 1, 1);
1524 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1525 #endif /* OBSOLETE */
1528 else if (nlen
> olen
)
1530 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1531 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1534 else if (olen
> nlen
)
1536 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1537 delete_glyphs (olen
- nlen
);
1543 /* If any unerased characters remain after the new line, erase them. */
1546 cursor_to (vpos
, nlen
);
1547 clear_end_of_line (olen
);
1550 /* Exchange contents between current_frame and new_frame. */
1551 temp
= desired_frame
->glyphs
[vpos
];
1552 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1553 current_frame
->glyphs
[vpos
] = temp
;
1556 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1557 1, 1, "FOpen termscript file: ",
1558 "Start writing all terminal output to FILE as well as the terminal.\n\
1559 FILE = nil means just close any termscript file currently open.")
1563 if (termscript
!= 0) fclose (termscript
);
1568 file
= Fexpand_file_name (file
, Qnil
);
1569 termscript
= fopen (XSTRING (file
)->data
, "w");
1570 if (termscript
== 0)
1571 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1579 window_change_signal ()
1583 int old_errno
= errno
;
1585 get_frame_size (&width
, &height
);
1587 /* The frame size change obviously applies to a termcap-controlled
1588 frame. Find such a frame in the list, and assume it's the only
1589 one (since the redisplay code always writes to stdout, not a
1590 FILE * specified in the frame structure). Record the new size,
1591 but don't reallocate the data structures now. Let that be done
1592 later outside of the signal handler. */
1598 FOR_EACH_FRAME (tail
, f
)
1600 if (FRAME_TERMCAP_P (f
))
1602 change_frame_size (f
, height
, width
, 0, 1);
1608 signal (SIGWINCH
, window_change_signal
);
1611 #endif /* SIGWINCH */
1614 /* Do any change in frame size that was requested by a signal. */
1616 do_pending_window_change ()
1618 /* If window_change_signal should have run before, run it now. */
1619 while (delayed_size_change
)
1624 delayed_size_change
= 0;
1626 FOR_EACH_FRAME (tail
, f
)
1628 int height
= FRAME_NEW_HEIGHT (f
);
1629 int width
= FRAME_NEW_WIDTH (f
);
1631 FRAME_NEW_HEIGHT (f
) = 0;
1632 FRAME_NEW_WIDTH (f
) = 0;
1635 change_frame_size (f
, height
, width
, 0, 0);
1641 /* Change the frame height and/or width. Values may be given as zero to
1642 indicate no change is to take place.
1644 If DELAY is non-zero, then assume we're being called from a signal
1645 handler, and queue the change for later - perhaps the next
1646 redisplay. Since this tries to resize windows, we can't call it
1647 from a signal handler. */
1649 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
1650 register FRAME_PTR frame
;
1651 int newheight
, newwidth
, pretend
;
1653 /* If we can't deal with the change now, queue it for later. */
1656 FRAME_NEW_HEIGHT (frame
) = newheight
;
1657 FRAME_NEW_WIDTH (frame
) = newwidth
;
1658 delayed_size_change
= 1;
1662 /* This size-change overrides any pending one for this frame. */
1663 FRAME_NEW_HEIGHT (frame
) = 0;
1664 FRAME_NEW_WIDTH (frame
) = 0;
1666 /* If an arguments is zero, set it to the current value. */
1667 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
1668 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
1670 /* Round up to the smallest acceptable size. */
1671 check_frame_size (frame
, &newheight
, &newwidth
);
1673 /* If we're not changing the frame size, quit now. */
1674 if (newheight
== FRAME_HEIGHT (frame
)
1675 && newwidth
== FRAME_WIDTH (frame
))
1678 if (newheight
!= FRAME_HEIGHT (frame
))
1680 if (FRAME_HAS_MINIBUF_P (frame
)
1681 && ! FRAME_MINIBUF_ONLY_P (frame
))
1683 /* Frame has both root and minibuffer. */
1684 set_window_height (FRAME_ROOT_WINDOW (frame
),
1686 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
)
1688 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
1691 /* Frame has just one top-level window. */
1692 set_window_height (FRAME_ROOT_WINDOW (frame
), newheight
, 0);
1694 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1695 FrameRows
= newheight
;
1698 if (frame
->output_method
== output_termcap
)
1700 frame_height
= newheight
;
1702 FrameRows
= newheight
;
1707 if (newwidth
!= FRAME_WIDTH (frame
))
1709 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
1710 if (FRAME_HAS_MINIBUF_P (frame
))
1711 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
1713 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1714 FrameCols
= newwidth
;
1716 if (frame
->output_method
== output_termcap
)
1718 frame_width
= newwidth
;
1720 FrameCols
= newwidth
;
1725 FRAME_HEIGHT (frame
) = newheight
;
1726 FRAME_WIDTH (frame
) = newwidth
;
1728 remake_frame_glyphs (frame
);
1729 calculate_costs (frame
);
1732 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
1733 Ssend_string_to_terminal
, 1, 1, 0,
1734 "Send STRING to the terminal without alteration.\n\
1735 Control characters in STRING will have terminal-dependent effects.")
1739 CHECK_STRING (str
, 0);
1740 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
1744 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
1745 fflush (termscript
);
1750 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
1751 "Beep, or flash the screen.\n\
1752 Also, unless an argument is given,\n\
1753 terminate any keyboard macro currently executing.")
1775 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
1776 error ("Keyboard macro terminated by a command ringing the bell");
1782 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
1783 "Pause, without updating display, for ARG seconds.\n\
1784 Optional second arg non-nil means ARG is measured in milliseconds.\n\
1785 \(Not all operating systems support milliseconds.)")
1787 Lisp_Object arg
, millisec
;
1792 CHECK_NUMBER (arg
, 0);
1797 if (!NILP (millisec
))
1799 #ifndef EMACS_HAS_USECS
1800 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
1802 usec
= sec
% 1000 * 1000;
1810 XFASTINT (zero
) = 0;
1811 wait_reading_process_input (sec
, usec
, zero
, 0);
1814 #if 0 /* No wait_reading_process_input */
1821 /* The reason this is done this way
1822 (rather than defined (H_S) && defined (H_T))
1823 is because the VMS preprocessor doesn't grok `defined' */
1825 EMACS_GET_TIME (end_time
);
1826 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
1827 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
1831 EMACS_GET_TIME (timeout
);
1832 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
1833 if (EMACS_TIME_NEG_P (timeout
)
1834 || !select (1, 0, 0, 0, &timeout
))
1837 #else /* not HAVE_SELECT */
1839 #endif /* HAVE_SELECT */
1840 #endif /* not VMS */
1843 #endif /* no subprocesses */
1848 /* This is just like wait_reading_process_input, except that
1849 it does the redisplay.
1851 It's also just like Fsit_for, except that it can be used for
1852 waiting for input as well. */
1855 sit_for (sec
, usec
, reading
, display
)
1856 int sec
, usec
, reading
, display
;
1858 Lisp_Object read_kbd
;
1860 if (detect_input_pending ())
1864 redisplay_preserve_echo_area ();
1866 if (sec
== 0 && usec
== 0)
1873 XSET (read_kbd
, Lisp_Int
, reading
? -1 : 1);
1874 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
1877 #if 0 /* No wait_reading_process_input available. */
1883 input_wait_timeout (XINT (arg
));
1885 #ifndef HAVE_TIMEVAL
1887 select (1, &waitchannels
, 0, 0, &timeout_sec
);
1888 #else /* HAVE_TIMEVAL */
1889 timeout
.tv_sec
= sec
;
1890 timeout
.tv_usec
= usec
;
1891 select (1, &waitchannels
, 0, 0, &timeout
);
1892 #endif /* HAVE_TIMEVAL */
1893 #endif /* not VMS */
1898 return detect_input_pending () ? Qnil
: Qt
;
1901 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
1902 "Perform redisplay, then wait for ARG seconds or until input is available.\n\
1903 Optional second arg non-nil means ARG counts in milliseconds.\n\
1904 Optional third arg non-nil means don't redisplay, just wait for input.\n\
1905 Redisplay is preempted as always if input arrives, and does not happen\n\
1906 if input is available before it starts.\n\
1907 Value is t if waited the full time with no input arriving.")
1908 (arg
, millisec
, nodisp
)
1909 Lisp_Object arg
, millisec
, nodisp
;
1914 CHECK_NUMBER (arg
, 0);
1917 if (!NILP (millisec
))
1919 #ifndef EMACS_HAS_USECS
1920 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
1922 usec
= (sec
% 1000) * 1000;
1927 return sit_for (sec
, usec
, 0, NILP (nodisp
));
1930 DEFUN ("sleep-for-millisecs", Fsleep_for_millisecs
, Ssleep_for_millisecs
,
1932 "Pause, without updating display, for ARG milliseconds.")
1938 #ifndef EMACS_HAS_USECS
1939 error ("sleep-for-millisecs not supported on %s", SYSTEM_TYPE
);
1941 CHECK_NUMBER (arg
, 0);
1943 XFASTINT (zero
) = 0;
1944 wait_reading_process_input (XINT (arg
) / 1000, XINT (arg
) % 1000 * 1000,
1947 #endif /* EMACS_HAS_USECS */
1950 char *terminal_type
;
1952 /* Initialization done when Emacs fork is started, before doing stty. */
1953 /* Determine terminal type and set terminal_driver */
1954 /* Then invoke its decoding routine to set up variables
1955 in the terminal package */
1959 #ifdef HAVE_X_WINDOWS
1960 extern int display_arg
;
1965 cursor_in_echo_area
= 0;
1966 terminal_type
= (char *) 0;
1968 /* If the DISPLAY environment variable is set, try to use X, and
1969 die with an error message if that doesn't work. */
1971 /* Check if we're using a window system here before trying to
1972 initialize the terminal. If we check the terminal first,
1974 If someone has indicated that they want
1975 to use a window system, we shouldn't bother initializing the
1976 terminal. This is especially important when the terminal is so
1977 dumb that emacs gives up before and doesn't bother using the window
1980 #ifdef HAVE_X_WINDOWS
1981 if (!inhibit_window_system
&& (display_arg
|| getenv ("DISPLAY")))
1983 Vwindow_system
= intern ("x");
1985 Vwindow_system_version
= make_number (11);
1987 Vwindow_system_version
= make_number (10);
1991 #endif /* HAVE_X_WINDOWS */
1993 /* If no window system has been specified, try to use the terminal. */
1996 fprintf (stderr
, "emacs: standard input is not a tty\n");
2000 /* Look at the TERM variable */
2001 terminal_type
= (char *) getenv ("TERM");
2005 fprintf (stderr
, "Please specify your terminal type.\n\
2006 For types defined in VMS, use set term /device=TYPE.\n\
2007 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2008 \(The quotation marks are necessary since terminal types are lower case.)\n");
2010 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2016 /* VMS DCL tends to upcase things, so downcase term type.
2017 Hardly any uppercase letters in terminal types; should be none. */
2019 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2022 strcpy (new, terminal_type
);
2024 for (p
= new; *p
; p
++)
2028 terminal_type
= new;
2032 term_init (terminal_type
);
2034 remake_frame_glyphs (selected_frame
);
2035 calculate_costs (selected_frame
);
2037 /* X and Y coordinates of the cursor between updates. */
2038 FRAME_CURSOR_X (selected_frame
) = 0;
2039 FRAME_CURSOR_Y (selected_frame
) = 0;
2044 #endif /* CANNOT_DUMP */
2045 signal (SIGWINCH
, window_change_signal
);
2046 #endif /* SIGWINCH */
2052 defsubr (&Sredraw_frame
);
2054 defsubr (&Sredraw_display
);
2055 defsubr (&Sopen_termscript
);
2057 defsubr (&Ssit_for
);
2058 defsubr (&Ssleep_for
);
2059 defsubr (&Ssend_string_to_terminal
);
2061 DEFVAR_INT ("baud-rate", &baud_rate
,
2062 "The output baud rate of the terminal.\n\
2063 On most systems, changing this value will affect the amount of padding\n\
2064 and the other strategic decisions made during redisplay.");
2065 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2066 "*Non-nil means invert the entire frame display.\n\
2067 This means everything is in inverse video which otherwise would not be.");
2068 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2069 "*Non-nil means try to flash the frame to represent a bell.");
2070 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2071 "*Non-nil means no need to redraw entire frame after suspending.\n\
2072 A non-nil value is useful if the terminal can automatically preserve\n\
2073 Emacs's frame display when you reenter Emacs.\n\
2074 It is up to you to set this variable if your terminal can do that.");
2075 DEFVAR_LISP ("window-system", &Vwindow_system
,
2076 "A symbol naming the window-system under which Emacs is running\n\
2077 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2078 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2079 "The version number of the window system in use.\n\
2080 For X windows, this is 10 or 11.");
2081 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2082 "Non-nil means put cursor in minibuffer, at end of any message there.");
2083 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2084 "Table defining how to output a glyph code to the frame.\n\
2085 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2086 Each element can be:\n\
2087 integer: a glyph code which this glyph is an alias for.\n\
2088 string: output this glyph using that string (not impl. in X windows).\n\
2089 nil: this glyph mod 256 is char code to output,\n\
2090 and this glyph / 256 is face code for X windows (see `x-set-face').");
2091 Vglyph_table
= Qnil
;
2093 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2094 "Display table to use for buffers that specify none.\n\
2095 See `buffer-display-table' for more information.");
2096 Vstandard_display_table
= Qnil
;
2098 /* Initialize `window-system', unless init_display already decided it. */
2103 Vwindow_system
= Qnil
;
2104 Vwindow_system_version
= Qnil
;