1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
30 #include "termhooks.h"
32 #include "dispextern.h"
39 #include "intervals.h"
46 #endif /* HAVE_X_WINDOWS */
50 #define max(a, b) ((a) > (b) ? (a) : (b))
51 #define min(a, b) ((a) < (b) ? (a) : (b))
53 /* Get number of chars of output now in the buffer of a stdio stream.
54 This ought to be built in in stdio, but it isn't.
55 Some s- files override this because their stdio internals differ. */
56 #ifdef __GNU_LIBRARY__
57 /* The s- file might have overridden the definition with one that works for
58 the system's C library. But we are using the GNU C library, so this is
59 the right definition for every system. */
60 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
61 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
63 #undef PENDING_OUTPUT_COUNT
64 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
66 #else /* not __GNU_LIBRARY__ */
67 #ifndef PENDING_OUTPUT_COUNT
68 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
72 /* Nonzero upon entry to redisplay means do not assume anything about
73 current contents of actual terminal frame; clear and redraw it. */
77 /* Nonzero means last display completed. Zero means it was preempted. */
79 int display_completed
;
81 /* Lisp variable visible-bell; enables use of screen-flash
82 instead of audible bell. */
86 /* Invert the color of the whole frame, at a low level. */
90 /* Line speed of the terminal. */
94 /* nil or a symbol naming the window system under which emacs is
95 running ('x is the only current possibility). */
97 Lisp_Object Vwindow_system
;
99 /* Version number of X windows: 10, 11 or nil. */
100 Lisp_Object Vwindow_system_version
;
102 /* Vector of glyph definitions. Indexed by glyph number,
103 the contents are a string which is how to output the glyph.
105 If Vglyph_table is nil, a glyph is output by using its low 8 bits
106 as a character code. */
108 Lisp_Object Vglyph_table
;
110 /* Display table to use for vectors that don't specify their own. */
112 Lisp_Object Vstandard_display_table
;
114 /* Nonzero means reading single-character input with prompt
115 so put cursor on minibuffer after the prompt.
116 positive means at end of text in echo area;
117 negative means at beginning of line. */
118 int cursor_in_echo_area
;
120 /* The currently selected frame.
121 In a single-frame version, this variable always remains 0. */
123 FRAME_PTR selected_frame
;
125 /* A frame which is not just a minibuffer, or 0 if there are no such
126 frames. This is usually the most recent such frame that was
127 selected. In a single-frame version, this variable always remains 0. */
128 FRAME_PTR last_nonminibuf_frame
;
130 /* In a single-frame version, the information that would otherwise
131 exist inside frame objects lives in the following structure instead.
133 NOTE: the_only_frame is not checked for garbage collection; don't
134 store collectible objects in any of its fields!
136 You're not/The only frame in town/... */
139 struct frame the_only_frame
;
142 /* This is a vector, made larger whenever it isn't large enough,
143 which is used inside `update_frame' to hold the old contents
144 of the FRAME_PHYS_LINES of the frame being updated. */
145 struct frame_glyphs
**ophys_lines
;
146 /* Length of vector currently allocated. */
147 int ophys_lines_length
;
149 FILE *termscript
; /* Stdio stream being used for copy of all output. */
151 struct cm Wcm
; /* Structure for info on cursor positioning */
153 extern short ospeed
; /* Output speed (from sg_ospeed) */
155 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
159 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
160 "Clear frame FRAME and output again what is supposed to appear on it.")
166 CHECK_LIVE_FRAME (frame
, 0);
169 /* set_terminal_modes (); */
171 clear_frame_records (f
);
174 windows_or_buffers_changed
++;
175 /* Mark all windows as INaccurate,
176 so that every window will have its redisplay done. */
177 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
186 XSET (frame
, Lisp_Frame
, f
);
187 Fredraw_frame (frame
);
192 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
193 "Clear frame FRAME and output again what is supposed to appear on it.")
198 set_terminal_modes ();
202 clear_frame_records (0);
203 windows_or_buffers_changed
++;
204 /* Mark all windows as INaccurate,
205 so that every window will have its redisplay done. */
206 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
212 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
213 "Clear and redisplay all visible frames.")
216 Lisp_Object tail
, frame
;
218 FOR_EACH_FRAME (tail
, frame
)
219 if (FRAME_VISIBLE_P (XFRAME (frame
)))
220 Fredraw_frame (frame
);
225 /* This is used when frame_garbaged is set.
226 Redraw the individual frames marked as garbaged. */
229 redraw_garbaged_frames ()
231 Lisp_Object tail
, frame
;
233 FOR_EACH_FRAME (tail
, frame
)
234 if (FRAME_VISIBLE_P (XFRAME (frame
))
235 && FRAME_GARBAGED_P (XFRAME (frame
)))
236 Fredraw_frame (frame
);
240 static struct frame_glyphs
*
241 make_frame_glyphs (frame
, empty
)
242 register FRAME_PTR frame
;
246 register width
= FRAME_WIDTH (frame
);
247 register height
= FRAME_HEIGHT (frame
);
248 register struct frame_glyphs
*new
249 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
251 SET_GLYPHS_FRAME (new, frame
);
252 new->height
= height
;
254 new->used
= (int *) xmalloc (height
* sizeof (int));
255 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
256 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
257 new->highlight
= (char *) xmalloc (height
* sizeof (char));
258 new->enable
= (char *) xmalloc (height
* sizeof (char));
259 bzero (new->enable
, height
* sizeof (char));
260 new->bufp
= (int *) xmalloc (height
* sizeof (int));
262 #ifdef HAVE_X_WINDOWS
263 if (FRAME_X_P (frame
))
265 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
266 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
267 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
268 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
269 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
275 /* Make the buffer used by decode_mode_spec. This buffer is also
276 used as temporary storage when updating the frame. See scroll.c. */
277 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
278 unsigned int total_charstarts
= (width
+ 2) * sizeof (int);
280 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
281 bzero (new->total_contents
, total_glyphs
);
283 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
284 bzero (new->total_charstarts
, total_glyphs
);
288 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
290 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
291 bzero (new->total_contents
, total_glyphs
);
292 for (i
= 0; i
< height
; i
++)
293 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
295 if (!FRAME_TERMCAP_P (frame
))
297 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
299 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
300 bzero (new->total_charstarts
, total_charstarts
);
301 for (i
= 0; i
< height
; i
++)
302 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
306 /* Without a window system, we don't really need charstarts.
307 So use a small amount of space to make enough data structure
308 to prevent crashes in display_text_line. */
309 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
310 for (i
= 0; i
< height
; i
++)
311 new->charstarts
[i
] = new->total_charstarts
;
319 free_frame_glyphs (frame
, glyphs
)
321 struct frame_glyphs
*glyphs
;
323 if (glyphs
->total_contents
)
324 xfree (glyphs
->total_contents
);
325 if (glyphs
->total_charstarts
)
326 xfree (glyphs
->total_charstarts
);
328 xfree (glyphs
->used
);
329 xfree (glyphs
->glyphs
);
330 xfree (glyphs
->highlight
);
331 xfree (glyphs
->enable
);
332 xfree (glyphs
->bufp
);
333 if (glyphs
->charstarts
)
334 xfree (glyphs
->charstarts
);
336 #ifdef HAVE_X_WINDOWS
337 if (FRAME_X_P (frame
))
339 xfree (glyphs
->top_left_x
);
340 xfree (glyphs
->top_left_y
);
341 xfree (glyphs
->pix_width
);
342 xfree (glyphs
->pix_height
);
343 xfree (glyphs
->max_ascent
);
351 remake_frame_glyphs (frame
)
354 if (FRAME_CURRENT_GLYPHS (frame
))
355 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
356 if (FRAME_DESIRED_GLYPHS (frame
))
357 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
358 if (FRAME_TEMP_GLYPHS (frame
))
359 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
361 if (FRAME_MESSAGE_BUF (frame
))
363 /* Reallocate the frame's message buffer; remember that
364 echo_area_glyphs may be pointing here. */
365 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
367 FRAME_MESSAGE_BUF (frame
)
368 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
369 FRAME_WIDTH (frame
) + 1);
371 if (echo_area_glyphs
== old_message_buf
)
372 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
373 if (previous_echo_glyphs
== old_message_buf
)
374 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
377 FRAME_MESSAGE_BUF (frame
)
378 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
380 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
381 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
382 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
383 SET_FRAME_GARBAGED (frame
);
386 /* Return the hash code of contents of line VPOS in frame-matrix M. */
389 line_hash_code (m
, vpos
)
390 register struct frame_glyphs
*m
;
393 register GLYPH
*body
, *end
;
396 if (!m
->enable
[vpos
])
399 /* Give all highlighted lines the same hash code
400 so as to encourage scrolling to leave them in place. */
401 if (m
->highlight
[vpos
])
404 body
= m
->glyphs
[vpos
];
406 if (must_write_spaces
)
413 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
422 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
430 /* Return number of characters in line in M at vpos VPOS,
431 except don't count leading and trailing spaces
432 unless the terminal requires those to be explicitly output. */
435 line_draw_cost (m
, vpos
)
436 struct frame_glyphs
*m
;
439 register GLYPH
*beg
= m
->glyphs
[vpos
];
440 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
442 register int tlen
= GLYPH_TABLE_LENGTH
;
443 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
445 /* Ignore trailing and leading spaces if we can. */
446 if (!must_write_spaces
)
448 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
451 return (0); /* All blank line. */
453 while (*beg
== SPACEGLYPH
)
457 /* If we don't have a glyph-table, each glyph is one character,
458 so return the number of glyphs. */
462 /* Otherwise, scan the glyphs and accumulate their total size in I. */
464 while ((beg
<= end
) && *beg
)
466 register GLYPH g
= *beg
++;
468 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
471 i
+= GLYPH_LENGTH (tbase
, g
);
476 /* The functions on this page are the interface from xdisp.c to redisplay.
478 The only other interface into redisplay is through setting
479 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
480 and SET_FRAME_GARBAGED (frame). */
482 /* cancel_line eliminates any request to display a line at position `vpos' */
484 cancel_line (vpos
, frame
)
486 register FRAME_PTR frame
;
488 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
491 clear_frame_records (frame
)
492 register FRAME_PTR frame
;
494 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
497 /* Prepare to display on line VPOS starting at HPOS within it. */
500 get_display_line (frame
, vpos
, hpos
)
501 register FRAME_PTR frame
;
505 register struct frame_glyphs
*glyphs
;
506 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
512 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
515 if (! desired_glyphs
->enable
[vpos
])
517 desired_glyphs
->used
[vpos
] = 0;
518 desired_glyphs
->highlight
[vpos
] = 0;
519 desired_glyphs
->enable
[vpos
] = 1;
522 if (hpos
> desired_glyphs
->used
[vpos
])
524 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
525 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
527 desired_glyphs
->used
[vpos
] = hpos
;
533 /* Like bcopy except never gets confused by overlap. */
536 safe_bcopy (from
, to
, size
)
540 if (size
<= 0 || from
== to
)
543 /* If the source and destination don't overlap, then bcopy can
544 handle it. If they do overlap, but the destination is lower in
545 memory than the source, we'll assume bcopy can handle that. */
546 if (to
< from
|| from
+ size
<= to
)
547 bcopy (from
, to
, size
);
549 /* Otherwise, we'll copy from the end. */
552 register char *endf
= from
+ size
;
553 register char *endt
= to
+ size
;
555 /* If TO - FROM is large, then we should break the copy into
556 nonoverlapping chunks of TO - FROM bytes each. However, if
557 TO - FROM is small, then the bcopy function call overhead
558 makes this not worth it. The crossover point could be about
559 anywhere. Since I don't think the obvious copy loop is too
560 bad, I'm trying to err in its favor. */
565 while (endf
!= from
);
577 bcopy (endf
, endt
, to
- from
);
580 /* If SIZE wasn't a multiple of TO - FROM, there will be a
581 little left over. The amount left over is
582 (endt + (to - from)) - to, which is endt - from. */
583 bcopy (from
, to
, endt
- from
);
588 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
589 DISTANCE may be negative. */
592 rotate_vector (vector
, size
, distance
)
597 char *temp
= (char *) alloca (size
);
602 bcopy (vector
, temp
+ distance
, size
- distance
);
603 bcopy (vector
+ size
- distance
, temp
, distance
);
604 bcopy (temp
, vector
, size
);
607 /* Scroll lines from vpos FROM up to but not including vpos END
608 down by AMOUNT lines (AMOUNT may be negative).
609 Returns nonzero if done, zero if terminal cannot scroll them. */
612 scroll_frame_lines (frame
, from
, end
, amount
, newpos
)
613 register FRAME_PTR frame
;
614 int from
, end
, amount
, newpos
;
617 register struct frame_glyphs
*current_frame
618 = FRAME_CURRENT_GLYPHS (frame
);
620 int width
= FRAME_WIDTH (frame
);
622 if (!line_ins_del_ok
)
630 update_begin (frame
);
631 set_terminal_window (end
+ amount
);
632 if (!scroll_region_ok
)
633 ins_del_lines (end
, -amount
);
634 ins_del_lines (from
, amount
);
635 set_terminal_window (0);
637 rotate_vector (current_frame
->glyphs
+ from
,
638 sizeof (GLYPH
*) * (end
+ amount
- from
),
639 amount
* sizeof (GLYPH
*));
641 rotate_vector (current_frame
->charstarts
+ from
,
642 sizeof (int *) * (end
+ amount
- from
),
643 amount
* sizeof (int *));
645 safe_bcopy (current_frame
->used
+ from
,
646 current_frame
->used
+ from
+ amount
,
647 (end
- from
) * sizeof current_frame
->used
[0]);
649 safe_bcopy (current_frame
->highlight
+ from
,
650 current_frame
->highlight
+ from
+ amount
,
651 (end
- from
) * sizeof current_frame
->highlight
[0]);
653 safe_bcopy (current_frame
->enable
+ from
,
654 current_frame
->enable
+ from
+ amount
,
655 (end
- from
) * sizeof current_frame
->enable
[0]);
657 /* Adjust the lines by an amount
658 that puts the first of them at NEWPOS. */
659 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
661 /* Offset each char position in the charstarts lines we moved
663 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
665 int *line
= current_frame
->charstarts
[i
];
667 for (col
= 0; col
< width
; col
++)
669 line
[col
] += pos_adjust
;
671 for (i
= from
; i
< from
+ amount
; i
++)
673 int *line
= current_frame
->charstarts
[i
];
676 for (col
= 0; col
< width
; col
++)
680 /* Mark the lines made empty by scrolling as enabled, empty and
682 bzero (current_frame
->used
+ from
,
683 amount
* sizeof current_frame
->used
[0]);
684 bzero (current_frame
->highlight
+ from
,
685 amount
* sizeof current_frame
->highlight
[0]);
686 for (i
= from
; i
< from
+ amount
; i
++)
688 current_frame
->glyphs
[i
][0] = '\0';
689 current_frame
->charstarts
[i
][0] = -1;
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
->top_left_x
+ from
,
701 current_frame
->top_left_x
+ from
+ amount
,
702 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
704 safe_bcopy (current_frame
->top_left_y
+ from
,
705 current_frame
->top_left_y
+ from
+ amount
,
706 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
708 safe_bcopy (current_frame
->pix_width
+ from
,
709 current_frame
->pix_width
+ from
+ amount
,
710 (end
- from
) * sizeof current_frame
->pix_width
[0]);
712 safe_bcopy (current_frame
->pix_height
+ from
,
713 current_frame
->pix_height
+ from
+ amount
,
714 (end
- from
) * sizeof current_frame
->pix_height
[0]);
716 safe_bcopy (current_frame
->max_ascent
+ from
,
717 current_frame
->max_ascent
+ from
+ amount
,
718 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
720 #endif /* HAVE_X_WINDOWS */
726 update_begin (frame
);
727 set_terminal_window (end
);
728 ins_del_lines (from
+ amount
, amount
);
729 if (!scroll_region_ok
)
730 ins_del_lines (end
+ amount
, -amount
);
731 set_terminal_window (0);
733 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
734 sizeof (GLYPH
*) * (end
- from
- amount
),
735 amount
* sizeof (GLYPH
*));
737 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
738 sizeof (int *) * (end
- from
- amount
),
739 amount
* sizeof (int *));
741 safe_bcopy (current_frame
->used
+ from
,
742 current_frame
->used
+ from
+ amount
,
743 (end
- from
) * sizeof current_frame
->used
[0]);
745 safe_bcopy (current_frame
->highlight
+ from
,
746 current_frame
->highlight
+ from
+ amount
,
747 (end
- from
) * sizeof current_frame
->highlight
[0]);
749 safe_bcopy (current_frame
->enable
+ from
,
750 current_frame
->enable
+ from
+ amount
,
751 (end
- from
) * sizeof current_frame
->enable
[0]);
753 /* Adjust the lines by an amount
754 that puts the first of them at NEWPOS. */
755 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
757 /* Offset each char position in the charstarts lines we moved
759 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
761 int *line
= current_frame
->charstarts
[i
];
763 for (col
= 0; col
< width
; col
++)
765 line
[col
] += pos_adjust
;
767 for (i
= end
+ amount
; i
< end
; i
++)
769 int *line
= current_frame
->charstarts
[i
];
772 for (col
= 0; col
< width
; col
++)
776 /* Mark the lines made empty by scrolling as enabled, empty and
778 bzero (current_frame
->used
+ end
+ amount
,
779 - amount
* sizeof current_frame
->used
[0]);
780 bzero (current_frame
->highlight
+ end
+ amount
,
781 - amount
* sizeof current_frame
->highlight
[0]);
782 for (i
= end
+ amount
; i
< end
; i
++)
784 current_frame
->glyphs
[i
][0] = '\0';
785 current_frame
->charstarts
[i
][0] = 0;
786 current_frame
->enable
[i
] = 1;
789 safe_bcopy (current_frame
->bufp
+ from
,
790 current_frame
->bufp
+ from
+ amount
,
791 (end
- from
) * sizeof current_frame
->bufp
[0]);
793 #ifdef HAVE_X_WINDOWS
794 if (FRAME_X_P (frame
))
796 safe_bcopy (current_frame
->top_left_x
+ from
,
797 current_frame
->top_left_x
+ from
+ amount
,
798 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
800 safe_bcopy (current_frame
->top_left_y
+ from
,
801 current_frame
->top_left_y
+ from
+ amount
,
802 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
804 safe_bcopy (current_frame
->pix_width
+ from
,
805 current_frame
->pix_width
+ from
+ amount
,
806 (end
- from
) * sizeof current_frame
->pix_width
[0]);
808 safe_bcopy (current_frame
->pix_height
+ from
,
809 current_frame
->pix_height
+ from
+ amount
,
810 (end
- from
) * sizeof current_frame
->pix_height
[0]);
812 safe_bcopy (current_frame
->max_ascent
+ from
,
813 current_frame
->max_ascent
+ from
+ amount
,
814 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
816 #endif /* HAVE_X_WINDOWS */
823 /* After updating a window W that isn't the full frame wide,
824 copy all the columns that W does not occupy
825 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
826 so that update_frame will not change those columns. */
828 preserve_other_columns (w
)
832 register struct frame_glyphs
*current_frame
, *desired_frame
;
833 register FRAME_PTR frame
= XFRAME (w
->frame
);
834 int start
= XFASTINT (w
->left
);
835 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
836 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
838 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
839 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
841 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
843 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
849 bcopy (current_frame
->glyphs
[vpos
],
850 desired_frame
->glyphs
[vpos
],
851 start
* sizeof (current_frame
->glyphs
[vpos
]));
852 bcopy (current_frame
->charstarts
[vpos
],
853 desired_frame
->charstarts
[vpos
],
854 start
* sizeof (current_frame
->charstarts
[vpos
]));
855 len
= min (start
, current_frame
->used
[vpos
]);
856 if (desired_frame
->used
[vpos
] < len
)
857 desired_frame
->used
[vpos
] = len
;
859 if (current_frame
->used
[vpos
] > end
860 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
862 while (desired_frame
->used
[vpos
] < end
)
864 int used
= desired_frame
->used
[vpos
]++;
865 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
866 desired_frame
->glyphs
[vpos
][used
] = 0;
868 bcopy (current_frame
->glyphs
[vpos
] + end
,
869 desired_frame
->glyphs
[vpos
] + end
,
870 ((current_frame
->used
[vpos
] - end
)
871 * sizeof (current_frame
->glyphs
[vpos
])));
872 bcopy (current_frame
->charstarts
[vpos
] + end
,
873 desired_frame
->charstarts
[vpos
] + end
,
874 ((current_frame
->used
[vpos
] - end
)
875 * sizeof (current_frame
->charstarts
[vpos
])));
876 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
884 /* If window w does not need to be updated and isn't the full frame wide,
885 copy all the columns that w does occupy
886 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
887 so that update_frame will not change those columns.
889 Have not been able to figure out how to use this correctly. */
891 preserve_my_columns (w
)
894 register int vpos
, fin
;
895 register struct frame_glyphs
*l1
, *l2
;
896 register FRAME_PTR frame
= XFRAME (w
->frame
);
897 int start
= XFASTINT (w
->left
);
898 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
899 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
901 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
903 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
904 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
906 if (l2
->length
> start
&& l1
->length
< l2
->length
)
909 if (fin
> end
) fin
= end
;
910 while (l1
->length
< start
)
911 l1
->body
[l1
->length
++] = ' ';
912 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
921 /* Adjust by ADJUST the charstart values in window W
922 after vpos VPOS, which counts relative to the frame
923 (not relative to W itself). */
926 adjust_window_charstarts (w
, vpos
, adjust
)
931 int left
= XFASTINT (w
->left
);
932 int top
= XFASTINT (w
->top
);
933 int right
= left
+ window_internal_width (w
);
934 int bottom
= top
+ window_internal_height (w
);
937 for (i
= vpos
+ 1; i
< bottom
; i
++)
940 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
942 for (j
= left
; j
< right
; j
++)
943 if (charstart
[j
] > 0)
944 charstart
[j
] += adjust
;
948 /* Check the charstarts values in the area of window W
949 for internal consistency. We cannot check that they are "right";
950 we can only look for something nonsensical. */
952 verify_charstarts (w
)
955 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
957 int top
= XFASTINT (w
->top
);
958 int bottom
= top
+ window_internal_height (w
);
959 int left
= XFASTINT (w
->left
);
960 int right
= left
+ window_internal_width (w
);
962 int truncate
= (XINT (w
->hscroll
)
963 || (truncate_partial_width_windows
964 && (XFASTINT (w
->width
) < FRAME_WIDTH (f
)))
965 || !NILP (XBUFFER (w
->buffer
)->truncate_lines
));
967 for (i
= top
; i
< bottom
; i
++)
971 int *charstart
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[i
];
977 /* If we are truncating lines, allow a jump
978 in charstarts from one line to the next. */
979 if (charstart
[left
] < next_line
)
984 if (charstart
[left
] != next_line
)
989 for (j
= left
; j
< right
; j
++)
990 if (charstart
[j
] > 0)
992 /* Record where the next line should start. */
994 if (BUF_ZV (XBUFFER (w
->buffer
)) != last
)
996 /* If there's a newline between the two lines, count that. */
997 int endchar
= *BUF_CHAR_ADDRESS (XBUFFER (w
->buffer
), last
);
1004 /* On discovering that the redisplay for a window was no good,
1005 cancel the columns of that window, so that when the window is
1006 displayed over again get_display_line will not complain. */
1008 cancel_my_columns (w
)
1012 register struct frame_glyphs
*desired_glyphs
1013 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
1014 register int start
= XFASTINT (w
->left
);
1015 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
1017 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
1018 if (desired_glyphs
->enable
[vpos
]
1019 && desired_glyphs
->used
[vpos
] >= start
)
1020 desired_glyphs
->used
[vpos
] = start
;
1023 /* These functions try to perform directly and immediately on the frame
1024 the necessary output for one change in the buffer.
1025 They may return 0 meaning nothing was done if anything is difficult,
1026 or 1 meaning the output was performed properly.
1027 They assume that the frame was up to date before the buffer
1028 change being displayed. They make various other assumptions too;
1029 see command_loop_1 where these are called. */
1032 direct_output_for_insert (g
)
1035 register FRAME_PTR frame
= selected_frame
;
1036 register struct frame_glyphs
*current_frame
1037 = FRAME_CURRENT_GLYPHS (frame
);
1039 #ifndef COMPILER_REGISTER_BUG
1041 #endif /* COMPILER_REGISTER_BUG */
1042 struct window
*w
= XWINDOW (selected_window
);
1043 #ifndef COMPILER_REGISTER_BUG
1045 #endif /* COMPILER_REGISTER_BUG */
1046 int hpos
= FRAME_CURSOR_X (frame
);
1047 #ifndef COMPILER_REGISTER_BUG
1049 #endif /* COMPILER_REGISTER_BUG */
1050 int vpos
= FRAME_CURSOR_Y (frame
);
1052 /* Give up if about to continue line. */
1053 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
1055 /* Avoid losing if cursor is in invisible text off left margin */
1056 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
1058 /* Give up if cursor outside window (in minibuf, probably) */
1059 || cursor_in_echo_area
1060 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
1061 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
1063 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
1064 || !display_completed
1066 /* Give up if buffer appears in two places. */
1067 || buffer_shared
> 1
1069 #ifdef USE_TEXT_PROPERTIES
1070 /* Intervals have already been adjusted, point is after the
1071 character that was just inserted. */
1072 /* Give up if character is invisible. */
1073 /* Give up if character has a face property.
1074 At the moment we only lose at end of line or end of buffer
1075 and only with faces that have some background */
1076 /* Instead of wasting time, give up if character has any text properties */
1077 || ! NILP (Ftext_properties_at (XFASTINT (point
- 1), Qnil
))
1080 /* Give up if w is minibuffer and a message is being displayed there */
1081 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1085 #ifdef HAVE_X_WINDOWS
1087 int face
= compute_char_face (frame
, w
, point
- 1, -1, -1, &dummy
, point
);
1089 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1090 current_frame
->charstarts
[vpos
][hpos
] = point
- 1;
1091 /* Record the entry for after the newly inserted character. */
1092 current_frame
->charstarts
[vpos
][hpos
+ 1] = point
;
1093 adjust_window_charstarts (w
, vpos
, 1);
1095 unchanged_modified
= MODIFF
;
1096 beg_unchanged
= GPT
- BEG
;
1097 XFASTINT (w
->last_point
) = point
;
1098 XFASTINT (w
->last_point_x
) = hpos
;
1099 XFASTINT (w
->last_modified
) = MODIFF
;
1101 reassert_line_highlight (0, vpos
);
1102 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
1104 ++FRAME_CURSOR_X (frame
);
1105 if (hpos
== current_frame
->used
[vpos
])
1107 current_frame
->used
[vpos
] = hpos
+ 1;
1108 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
1115 direct_output_forward_char (n
)
1118 register FRAME_PTR frame
= selected_frame
;
1119 register struct window
*w
= XWINDOW (selected_window
);
1121 int hpos
= FRAME_CURSOR_X (frame
);
1123 /* Give up if in truncated text at end of line. */
1124 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1)
1127 /* Avoid losing if cursor is in invisible text off left margin
1128 or about to go off either side of window. */
1129 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
1130 && (XINT (w
->hscroll
) || n
< 0))
1132 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
1133 || cursor_in_echo_area
)
1136 /* Can't use direct output if highlighting a region. */
1137 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1140 #ifdef USE_TEXT_PROPERTIES
1141 /* Don't use direct output next to an invisible character
1142 since we might need to do something special. */
1144 XFASTINT (position
) = point
;
1145 if (XFASTINT (position
) < ZV
1146 && ! NILP (Fget_char_property (position
,
1151 XFASTINT (position
) = point
- 1;
1152 if (XFASTINT (position
) >= BEGV
1153 && ! NILP (Fget_char_property (position
,
1159 FRAME_CURSOR_X (frame
) += n
;
1160 XFASTINT (w
->last_point_x
) = FRAME_CURSOR_X (frame
);
1161 XFASTINT (w
->last_point
) = point
;
1162 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1168 static void update_line ();
1170 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1171 Value is nonzero if redisplay stopped due to pending input.
1172 FORCE nonzero means do not stop for pending input. */
1175 update_frame (f
, force
, inhibit_hairy_id
)
1178 int inhibit_hairy_id
;
1180 register struct frame_glyphs
*current_frame
;
1181 register struct frame_glyphs
*desired_frame
= 0;
1184 int preempt_count
= baud_rate
/ 2400 + 1;
1185 extern input_pending
;
1186 #ifdef HAVE_X_WINDOWS
1187 register int downto
, leftmost
;
1190 if (preempt_count
<= 0)
1193 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1195 detect_input_pending ();
1196 if (input_pending
&& !force
)
1204 if (!line_ins_del_ok
)
1205 inhibit_hairy_id
= 1;
1207 /* These are separate to avoid a possible bug in the AIX C compiler. */
1208 current_frame
= FRAME_CURRENT_GLYPHS (f
);
1209 desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1211 /* See if any of the desired lines are enabled; don't compute for
1212 i/d line if just want cursor motion. */
1213 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1214 if (desired_frame
->enable
[i
])
1217 /* Try doing i/d line, if not yet inhibited. */
1218 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1219 force
|= scrolling (f
);
1221 /* Update the individual lines as needed. Do bottom line first. */
1223 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1224 update_line (f
, FRAME_HEIGHT (f
) - 1);
1226 #ifdef HAVE_X_WINDOWS
1229 leftmost
= downto
= f
->display
.x
->internal_border_width
;
1230 if (desired_frame
->enable
[0])
1232 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1233 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1234 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
1235 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1236 current_frame
->top_left_x
[0] = leftmost
;
1237 current_frame
->top_left_y
[0] = downto
;
1240 #endif /* HAVE_X_WINDOWS */
1242 /* Now update the rest of the lines. */
1243 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1245 if (desired_frame
->enable
[i
])
1247 if (FRAME_TERMCAP_P (f
))
1249 /* Flush out every so many lines.
1250 Also flush out if likely to have more than 1k buffered
1251 otherwise. I'm told that some telnet connections get
1252 really screwed by more than 1k output at once. */
1253 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1255 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1258 if (preempt_count
== 1)
1260 #ifdef EMACS_OUTQSIZE
1261 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1262 /* Probably not a tty. Ignore the error and reset
1263 * the outq count. */
1264 outq
= PENDING_OUTPUT_COUNT (stdout
);
1267 if (baud_rate
<= outq
&& baud_rate
> 0)
1268 sleep (outq
/ baud_rate
);
1271 if ((i
- 1) % preempt_count
== 0)
1272 detect_input_pending ();
1276 #ifdef HAVE_X_WINDOWS
1279 current_frame
->top_left_y
[i
] = downto
;
1280 current_frame
->top_left_x
[i
] = leftmost
;
1282 #endif /* HAVE_X_WINDOWS */
1285 #ifdef HAVE_X_WINDOWS
1287 downto
+= current_frame
->pix_height
[i
];
1290 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1292 /* Now just clean up termcap drivers and set cursor, etc. */
1295 if (cursor_in_echo_area
1296 && FRAME_HAS_MINIBUF_P (f
))
1298 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1301 if (cursor_in_echo_area
< 0)
1308 /* If the minibuffer is several lines high, find the last
1309 line that has any text on it. */
1310 row
= FRAME_HEIGHT (f
);
1314 if (current_frame
->enable
[row
])
1315 col
= current_frame
->used
[row
];
1319 while (row
> top
&& col
== 0);
1321 if (col
>= FRAME_WIDTH (f
))
1324 if (row
< FRAME_HEIGHT (f
) - 1)
1329 cursor_to (row
, col
);
1332 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1333 FRAME_WIDTH (f
) - 1), 0));
1339 fflush (termscript
);
1342 /* Here if output is preempted because input is detected. */
1345 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1346 display_completed
= !pause
;
1348 bzero (FRAME_DESIRED_GLYPHS (f
)->enable
, FRAME_HEIGHT (f
));
1352 /* Called when about to quit, to check for doing so
1353 at an improper time. */
1358 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1360 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1362 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1366 /* Decide what insert/delete line to do, and do it */
1368 extern void scrolling_1 ();
1373 int unchanged_at_top
, unchanged_at_bottom
;
1376 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1377 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1378 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1380 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1381 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1382 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1384 /* Compute hash codes of all the lines.
1385 Also calculate number of changed lines,
1386 number of unchanged lines at the beginning,
1387 and number of unchanged lines at the end. */
1390 unchanged_at_top
= 0;
1391 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1392 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1394 /* Give up on this scrolling if some old lines are not enabled. */
1395 if (!current_frame
->enable
[i
])
1397 old_hash
[i
] = line_hash_code (current_frame
, i
);
1398 if (! desired_frame
->enable
[i
])
1399 new_hash
[i
] = old_hash
[i
];
1401 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1403 if (old_hash
[i
] != new_hash
[i
])
1406 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1408 else if (i
== unchanged_at_top
)
1410 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1413 /* If changed lines are few, don't allow preemption, don't scroll. */
1414 if (changed_lines
< baud_rate
/ 2400
1415 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1418 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1419 - unchanged_at_bottom
);
1421 if (scroll_region_ok
)
1422 free_at_end_vpos
-= unchanged_at_bottom
;
1423 else if (memory_below_frame
)
1424 free_at_end_vpos
= -1;
1426 /* If large window, fast terminal and few lines in common between
1427 current frame and desired frame, don't bother with i/d calc. */
1428 if (window_size
>= 18 && baud_rate
> 2400
1430 10 * scrolling_max_lines_saved (unchanged_at_top
,
1431 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1432 old_hash
, new_hash
, draw_cost
)))
1435 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1436 draw_cost
+ unchanged_at_top
- 1,
1437 old_hash
+ unchanged_at_top
- 1,
1438 new_hash
+ unchanged_at_top
- 1,
1439 free_at_end_vpos
- unchanged_at_top
);
1444 /* Return the offset in its buffer of the character at location col, line
1445 in the given window. */
1447 buffer_posn_from_coords (window
, col
, line
)
1448 struct window
*window
;
1451 int hscroll
= XINT (window
->hscroll
);
1452 int window_left
= XFASTINT (window
->left
);
1454 /* The actual width of the window is window->width less one for the
1455 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1457 int window_width
= window_internal_width (window
) - 1;
1459 int startp
= marker_position (window
->start
);
1461 /* Since compute_motion will only operate on the current buffer,
1462 we need to save the old one and restore it when we're done. */
1463 struct buffer
*old_current_buffer
= current_buffer
;
1464 struct position
*posn
;
1466 current_buffer
= XBUFFER (window
->buffer
);
1468 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1469 (window->frame))->bufp to avoid scanning from the very top of
1470 the window, but it isn't maintained correctly, and I'm not even
1471 sure I will keep it. */
1472 posn
= compute_motion (startp
, 0,
1473 (window
== XWINDOW (minibuf_window
) && startp
== 1
1474 ? minibuf_prompt_width
: 0)
1475 + (hscroll
? 1 - hscroll
: 0),
1477 window_width
, hscroll
, 0, window
);
1479 current_buffer
= old_current_buffer
;
1481 /* compute_motion considers frame points past the end of a line
1482 to be *after* the newline, i.e. at the start of the next line.
1483 This is reasonable, but not really what we want. So if the
1484 result is on a line below LINE, back it up one character. */
1485 if (posn
->vpos
> line
)
1486 return posn
->bufpos
- 1;
1488 return posn
->bufpos
;
1495 register GLYPH
*p
= r
;
1496 while (*p
++ == SPACEGLYPH
);
1501 count_match (str1
, str2
)
1504 register GLYPH
*p1
= str1
;
1505 register GLYPH
*p2
= str2
;
1506 while (*p1
++ == *p2
++);
1507 return p1
- str1
- 1;
1510 /* Char insertion/deletion cost vector, from term.c */
1511 extern int *char_ins_del_vector
;
1513 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1516 update_line (frame
, vpos
)
1517 register FRAME_PTR frame
;
1520 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1523 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1525 register struct frame_glyphs
*current_frame
1526 = FRAME_CURRENT_GLYPHS (frame
);
1527 register struct frame_glyphs
*desired_frame
1528 = FRAME_DESIRED_GLYPHS (frame
);
1530 if (desired_frame
->highlight
[vpos
]
1531 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1533 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1534 (current_frame
->enable
[vpos
] ?
1535 current_frame
->used
[vpos
] : 0));
1536 current_frame
->enable
[vpos
] = 0;
1539 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1541 if (! current_frame
->enable
[vpos
])
1547 obody
= current_frame
->glyphs
[vpos
];
1548 olen
= current_frame
->used
[vpos
];
1549 if (! current_frame
->highlight
[vpos
])
1551 if (!must_write_spaces
)
1552 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1557 /* For an inverse-video line, remember we gave it
1558 spaces all the way to the frame edge
1559 so that the reverse video extends all the way across. */
1561 while (olen
< FRAME_WIDTH (frame
) - 1)
1562 obody
[olen
++] = SPACEGLYPH
;
1566 /* One way or another, this will enable the line being updated. */
1567 current_frame
->enable
[vpos
] = 1;
1568 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1569 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1570 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1572 #ifdef HAVE_X_WINDOWS
1573 if (FRAME_X_P (frame
))
1575 current_frame
->pix_width
[vpos
]
1576 = current_frame
->used
[vpos
]
1577 * FONT_WIDTH (frame
->display
.x
->font
);
1578 current_frame
->pix_height
[vpos
]
1579 = frame
->display
.x
->line_height
;
1581 #endif /* HAVE_X_WINDOWS */
1583 if (!desired_frame
->enable
[vpos
])
1589 nbody
= desired_frame
->glyphs
[vpos
];
1590 nlen
= desired_frame
->used
[vpos
];
1592 /* Pretend trailing spaces are not there at all,
1593 unless for one reason or another we must write all spaces. */
1594 if (! desired_frame
->highlight
[vpos
])
1596 if (!must_write_spaces
)
1597 /* We know that the previous character byte contains 0. */
1598 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1603 /* For an inverse-video line, give it extra trailing spaces
1604 all the way to the frame edge
1605 so that the reverse video extends all the way across. */
1607 while (nlen
< FRAME_WIDTH (frame
) - 1)
1608 nbody
[nlen
++] = SPACEGLYPH
;
1611 /* If there's no i/d char, quickly do the best we can without it. */
1612 if (!char_ins_del_ok
)
1617 if (FRAME_X_P (frame
))
1619 /* Under X, erase everything we are going to rewrite,
1620 and rewrite everything from the first char that's changed.
1621 This is part of supporting fonts like Courier
1622 whose chars can overlap outside the char width. */
1623 for (i
= 0; i
< nlen
; i
++)
1624 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1627 cursor_to (vpos
, i
);
1629 clear_end_of_line (olen
);
1630 write_glyphs (nbody
+ i
, nlen
- i
);
1635 for (i
= 0; i
< nlen
; i
++)
1637 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1639 cursor_to (vpos
, i
);
1640 for (j
= 1; (i
+ j
< nlen
&&
1641 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1644 /* Output this run of non-matching chars. */
1645 write_glyphs (nbody
+ i
, j
);
1648 /* Now find the next non-match. */
1652 /* Clear the rest of the line, or the non-clear part of it. */
1655 cursor_to (vpos
, nlen
);
1656 clear_end_of_line (olen
);
1659 /* Exchange contents between current_frame and new_frame. */
1660 temp
= desired_frame
->glyphs
[vpos
];
1661 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1662 current_frame
->glyphs
[vpos
] = temp
;
1664 /* Exchange charstarts between current_frame and new_frame. */
1665 temp1
= desired_frame
->charstarts
[vpos
];
1666 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1667 current_frame
->charstarts
[vpos
] = temp1
;
1674 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1675 ? 0 : count_blanks (nbody
);
1678 cursor_to (vpos
, nsp
);
1679 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1682 /* Exchange contents between current_frame and new_frame. */
1683 temp
= desired_frame
->glyphs
[vpos
];
1684 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1685 current_frame
->glyphs
[vpos
] = temp
;
1687 /* Exchange charstarts between current_frame and new_frame. */
1688 temp1
= desired_frame
->charstarts
[vpos
];
1689 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1690 current_frame
->charstarts
[vpos
] = temp1
;
1699 /* Compute number of leading blanks in old and new contents. */
1700 osp
= count_blanks (obody
);
1701 if (!desired_frame
->highlight
[vpos
])
1702 nsp
= count_blanks (nbody
);
1706 /* Compute number of matching chars starting with first nonblank. */
1707 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1709 /* Spaces in new match implicit space past the end of old. */
1710 /* A bug causing this to be a no-op was fixed in 18.29. */
1711 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1714 while (np1
[begmatch
] == SPACEGLYPH
)
1718 /* Avoid doing insert/delete char
1719 just cause number of leading spaces differs
1720 when the following text does not match. */
1721 if (begmatch
== 0 && osp
!= nsp
)
1722 osp
= nsp
= min (osp
, nsp
);
1724 /* Find matching characters at end of line */
1727 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1728 while (op1
> op2
&& op1
[-1] == np1
[-1])
1733 endmatch
= obody
+ olen
- op1
;
1735 /* Put correct value back in nbody[nlen].
1736 This is important because direct_output_for_insert
1737 can write into the line at a later point.
1738 If this screws up the zero at the end of the line, re-establish it. */
1742 /* tem gets the distance to insert or delete.
1743 endmatch is how many characters we save by doing so.
1746 tem
= (nlen
- nsp
) - (olen
- osp
);
1748 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1751 /* nsp - osp is the distance to insert or delete.
1752 If that is nonzero, begmatch is known to be nonzero also.
1753 begmatch + endmatch is how much we save by doing the ins/del.
1757 && (!char_ins_del_ok
1758 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1762 osp
= nsp
= min (osp
, nsp
);
1765 /* Now go through the line, inserting, writing and
1766 deleting as appropriate. */
1770 cursor_to (vpos
, nsp
);
1771 delete_glyphs (osp
- nsp
);
1775 /* If going to delete chars later in line
1776 and insert earlier in the line,
1777 must delete first to avoid losing data in the insert */
1778 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1780 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1781 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1782 olen
= nlen
- (nsp
- osp
);
1784 cursor_to (vpos
, osp
);
1785 insert_glyphs ((char *)0, nsp
- osp
);
1789 tem
= nsp
+ begmatch
+ endmatch
;
1790 if (nlen
!= tem
|| olen
!= tem
)
1792 cursor_to (vpos
, nsp
+ begmatch
);
1793 if (!endmatch
|| nlen
== olen
)
1795 /* If new text being written reaches right margin,
1796 there is no need to do clear-to-eol at the end.
1797 (and it would not be safe, since cursor is not
1798 going to be "at the margin" after the text is done) */
1799 if (nlen
== FRAME_WIDTH (frame
))
1801 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1805 /* the following code loses disastrously if tem == nlen.
1806 Rather than trying to fix that case, I am trying the simpler
1807 solution found above. */
1809 /* If the text reaches to the right margin,
1810 it will lose one way or another (depending on AutoWrap)
1811 to clear to end of line after outputting all the text.
1812 So pause with one character to go and clear the line then. */
1813 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1815 /* endmatch must be zero, and tem must equal nsp + begmatch */
1816 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1817 clear_end_of_line (olen
);
1818 olen
= 0; /* Don't let it be cleared again later */
1819 write_glyphs (nbody
+ nlen
- 1, 1);
1822 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1823 #endif /* OBSOLETE */
1826 else if (nlen
> olen
)
1828 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1829 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1832 else if (olen
> nlen
)
1834 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1835 delete_glyphs (olen
- nlen
);
1841 /* If any unerased characters remain after the new line, erase them. */
1844 cursor_to (vpos
, nlen
);
1845 clear_end_of_line (olen
);
1848 /* Exchange contents between current_frame and new_frame. */
1849 temp
= desired_frame
->glyphs
[vpos
];
1850 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1851 current_frame
->glyphs
[vpos
] = temp
;
1853 /* Exchange charstarts between current_frame and new_frame. */
1854 temp1
= desired_frame
->charstarts
[vpos
];
1855 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1856 current_frame
->charstarts
[vpos
] = temp1
;
1859 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1860 1, 1, "FOpen termscript file: ",
1861 "Start writing all terminal output to FILE as well as the terminal.\n\
1862 FILE = nil means just close any termscript file currently open.")
1866 if (termscript
!= 0) fclose (termscript
);
1871 file
= Fexpand_file_name (file
, Qnil
);
1872 termscript
= fopen (XSTRING (file
)->data
, "w");
1873 if (termscript
== 0)
1874 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1882 window_change_signal ()
1886 int old_errno
= errno
;
1888 get_frame_size (&width
, &height
);
1890 /* The frame size change obviously applies to a termcap-controlled
1891 frame. Find such a frame in the list, and assume it's the only
1892 one (since the redisplay code always writes to stdout, not a
1893 FILE * specified in the frame structure). Record the new size,
1894 but don't reallocate the data structures now. Let that be done
1895 later outside of the signal handler. */
1898 Lisp_Object tail
, frame
;
1900 FOR_EACH_FRAME (tail
, frame
)
1902 if (FRAME_TERMCAP_P (XFRAME (frame
)))
1904 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
1910 signal (SIGWINCH
, window_change_signal
);
1913 #endif /* SIGWINCH */
1916 /* Do any change in frame size that was requested by a signal. */
1918 do_pending_window_change ()
1920 /* If window_change_signal should have run before, run it now. */
1921 while (delayed_size_change
)
1923 Lisp_Object tail
, frame
;
1925 delayed_size_change
= 0;
1927 FOR_EACH_FRAME (tail
, frame
)
1929 FRAME_PTR f
= XFRAME (frame
);
1931 int height
= FRAME_NEW_HEIGHT (f
);
1932 int width
= FRAME_NEW_WIDTH (f
);
1934 if (height
!= 0 || width
!= 0)
1935 change_frame_size (f
, height
, width
, 0, 0);
1941 /* Change the frame height and/or width. Values may be given as zero to
1942 indicate no change is to take place.
1944 If DELAY is non-zero, then assume we're being called from a signal
1945 handler, and queue the change for later - perhaps the next
1946 redisplay. Since this tries to resize windows, we can't call it
1947 from a signal handler. */
1949 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
1950 register FRAME_PTR frame
;
1951 int newheight
, newwidth
, pretend
;
1953 /* If we can't deal with the change now, queue it for later. */
1956 FRAME_NEW_HEIGHT (frame
) = newheight
;
1957 FRAME_NEW_WIDTH (frame
) = newwidth
;
1958 delayed_size_change
= 1;
1962 /* This size-change overrides any pending one for this frame. */
1963 FRAME_NEW_HEIGHT (frame
) = 0;
1964 FRAME_NEW_WIDTH (frame
) = 0;
1966 /* If an argument is zero, set it to the current value. */
1967 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
1968 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
1970 /* Round up to the smallest acceptable size. */
1971 check_frame_size (frame
, &newheight
, &newwidth
);
1973 /* If we're not changing the frame size, quit now. */
1974 if (newheight
== FRAME_HEIGHT (frame
)
1975 && newwidth
== FRAME_WIDTH (frame
))
1978 if (newheight
!= FRAME_HEIGHT (frame
))
1980 if (FRAME_HAS_MINIBUF_P (frame
)
1981 && ! FRAME_MINIBUF_ONLY_P (frame
))
1983 /* Frame has both root and minibuffer. */
1984 set_window_height (FRAME_ROOT_WINDOW (frame
),
1985 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
1986 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
)
1988 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
1991 /* Frame has just one top-level window. */
1992 set_window_height (FRAME_ROOT_WINDOW (frame
),
1993 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
1995 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1996 FrameRows
= newheight
;
1999 if (frame
->output_method
== output_termcap
)
2001 frame_height
= newheight
;
2003 FrameRows
= newheight
;
2008 if (newwidth
!= FRAME_WIDTH (frame
))
2010 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
2011 if (FRAME_HAS_MINIBUF_P (frame
))
2012 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
2014 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2015 FrameCols
= newwidth
;
2017 if (frame
->output_method
== output_termcap
)
2019 frame_width
= newwidth
;
2021 FrameCols
= newwidth
;
2026 FRAME_HEIGHT (frame
) = newheight
;
2027 FRAME_WIDTH (frame
) = newwidth
;
2029 remake_frame_glyphs (frame
);
2030 calculate_costs (frame
);
2033 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
2034 Ssend_string_to_terminal
, 1, 1, 0,
2035 "Send STRING to the terminal without alteration.\n\
2036 Control characters in STRING will have terminal-dependent effects.")
2040 CHECK_STRING (str
, 0);
2041 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
2045 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
2046 fflush (termscript
);
2051 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
2052 "Beep, or flash the screen.\n\
2053 Also, unless an argument is given,\n\
2054 terminate any keyboard macro currently executing.")
2076 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
2077 error ("Keyboard macro terminated by a command ringing the bell");
2083 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
2084 "Pause, without updating display, for SECONDS seconds.\n\
2085 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2086 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2087 additional wait period, in milliseconds; this may be useful if your\n\
2088 Emacs was built without floating point support.\n\
2089 \(Not all operating systems support waiting for a fraction of a second.)")
2090 (seconds
, milliseconds
)
2091 Lisp_Object seconds
, milliseconds
;
2095 if (NILP (milliseconds
))
2096 XSET (milliseconds
, Lisp_Int
, 0);
2098 CHECK_NUMBER (milliseconds
, 1);
2099 usec
= XINT (milliseconds
) * 1000;
2101 #ifdef LISP_FLOAT_TYPE
2103 double duration
= extract_float (seconds
);
2104 sec
= (int) duration
;
2105 usec
+= (duration
- sec
) * 1000000;
2108 CHECK_NUMBER (seconds
, 0);
2109 sec
= XINT (seconds
);
2112 #ifndef EMACS_HAS_USECS
2113 if (sec
== 0 && usec
!= 0)
2114 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2117 /* Assure that 0 <= usec < 1000000. */
2120 /* We can't rely on the rounding being correct if user is negative. */
2121 if (-1000000 < usec
)
2122 sec
--, usec
+= 1000000;
2124 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2127 sec
+= usec
/ 1000000, usec
%= 1000000;
2135 XFASTINT (zero
) = 0;
2136 wait_reading_process_input (sec
, usec
, zero
, 0);
2139 /* We should always have wait_reading_process_input; we have a dummy
2140 implementation for systems which don't support subprocesses. */
2142 /* No wait_reading_process_input */
2149 /* The reason this is done this way
2150 (rather than defined (H_S) && defined (H_T))
2151 is because the VMS preprocessor doesn't grok `defined' */
2153 EMACS_GET_TIME (end_time
);
2154 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2155 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2159 EMACS_GET_TIME (timeout
);
2160 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2161 if (EMACS_TIME_NEG_P (timeout
)
2162 || !select (1, 0, 0, 0, &timeout
))
2165 #else /* not HAVE_SELECT */
2167 #endif /* HAVE_SELECT */
2168 #endif /* not VMS */
2171 #endif /* no subprocesses */
2176 /* This is just like wait_reading_process_input, except that
2177 it does the redisplay.
2179 It's also much like Fsit_for, except that it can be used for
2180 waiting for input as well. One differnce is that sit_for
2181 does not call prepare_menu_bars; Fsit_for does call that. */
2184 sit_for (sec
, usec
, reading
, display
)
2185 int sec
, usec
, reading
, display
;
2187 Lisp_Object read_kbd
;
2189 if (detect_input_pending ())
2193 redisplay_preserve_echo_area ();
2195 if (sec
== 0 && usec
== 0)
2202 XSET (read_kbd
, Lisp_Int
, reading
? -1 : 1);
2203 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2206 /* wait_reading_process_input should always be available now; it is
2207 simulated in a simple way on systems that don't support
2210 /* No wait_reading_process_input available. */
2216 input_wait_timeout (XINT (arg
));
2218 #ifndef HAVE_TIMEVAL
2220 select (1, &waitchannels
, 0, 0, &timeout_sec
);
2221 #else /* HAVE_TIMEVAL */
2222 timeout
.tv_sec
= sec
;
2223 timeout
.tv_usec
= usec
;
2224 select (1, &waitchannels
, 0, 0, &timeout
);
2225 #endif /* HAVE_TIMEVAL */
2226 #endif /* not VMS */
2231 return detect_input_pending () ? Qnil
: Qt
;
2234 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2235 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2236 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2237 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2238 additional wait period, in milliseconds; this may be useful if your\n\
2239 Emacs was built without floating point support.\n\
2240 \(Not all operating systems support waiting for a fraction of a second.)\n\
2241 Optional third arg non-nil means don't redisplay, just wait for input.\n\
2242 Redisplay is preempted as always if input arrives, and does not happen\n\
2243 if input is available before it starts.\n\
2244 Value is t if waited the full time with no input arriving.")
2245 (seconds
, milliseconds
, nodisp
)
2246 Lisp_Object seconds
, milliseconds
, nodisp
;
2250 if (NILP (milliseconds
))
2251 XSET (milliseconds
, Lisp_Int
, 0);
2253 CHECK_NUMBER (milliseconds
, 1);
2254 usec
= XINT (milliseconds
) * 1000;
2256 #ifdef LISP_FLOAT_TYPE
2258 double duration
= extract_float (seconds
);
2259 sec
= (int) duration
;
2260 usec
+= (duration
- sec
) * 1000000;
2263 CHECK_NUMBER (seconds
, 0);
2264 sec
= XINT (seconds
);
2267 #ifndef EMACS_HAS_USECS
2268 if (usec
!= 0 && sec
== 0)
2269 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2273 prepare_menu_bars ();
2274 return sit_for (sec
, usec
, 0, NILP (nodisp
));
2277 char *terminal_type
;
2279 /* Initialization done when Emacs fork is started, before doing stty. */
2280 /* Determine terminal type and set terminal_driver */
2281 /* Then invoke its decoding routine to set up variables
2282 in the terminal package */
2286 #ifdef HAVE_X_WINDOWS
2287 extern int display_arg
;
2292 cursor_in_echo_area
= 0;
2293 terminal_type
= (char *) 0;
2295 /* Now is the time to initialize this; it's used by init_sys_modes
2297 Vwindow_system
= Qnil
;
2299 /* If the user wants to use a window system, we shouldn't bother
2300 initializing the terminal. This is especially important when the
2301 terminal is so dumb that emacs gives up before and doesn't bother
2302 using the window system.
2304 If the DISPLAY environment variable is set, try to use X, and die
2305 with an error message if that doesn't work. */
2307 #ifdef HAVE_X_WINDOWS
2311 display_arg
= (getenv ("DECW$DISPLAY") != 0);
2313 display_arg
= (getenv ("DISPLAY") != 0);
2317 if (!inhibit_window_system
&& display_arg
)
2319 Vwindow_system
= intern ("x");
2321 Vwindow_system_version
= make_number (11);
2323 Vwindow_system_version
= make_number (10);
2327 #endif /* HAVE_X_WINDOWS */
2329 /* If no window system has been specified, try to use the terminal. */
2332 fprintf (stderr
, "emacs: standard input is not a tty\n");
2336 /* Look at the TERM variable */
2337 terminal_type
= (char *) getenv ("TERM");
2341 fprintf (stderr
, "Please specify your terminal type.\n\
2342 For types defined in VMS, use set term /device=TYPE.\n\
2343 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2344 \(The quotation marks are necessary since terminal types are lower case.)\n");
2346 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2352 /* VMS DCL tends to upcase things, so downcase term type.
2353 Hardly any uppercase letters in terminal types; should be none. */
2355 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2358 strcpy (new, terminal_type
);
2360 for (p
= new; *p
; p
++)
2364 terminal_type
= new;
2368 term_init (terminal_type
);
2370 remake_frame_glyphs (selected_frame
);
2371 calculate_costs (selected_frame
);
2373 /* X and Y coordinates of the cursor between updates. */
2374 FRAME_CURSOR_X (selected_frame
) = 0;
2375 FRAME_CURSOR_Y (selected_frame
) = 0;
2380 #endif /* CANNOT_DUMP */
2381 signal (SIGWINCH
, window_change_signal
);
2382 #endif /* SIGWINCH */
2388 defsubr (&Sredraw_frame
);
2390 defsubr (&Sredraw_display
);
2391 defsubr (&Sopen_termscript
);
2393 defsubr (&Ssit_for
);
2394 defsubr (&Ssleep_for
);
2395 defsubr (&Ssend_string_to_terminal
);
2397 DEFVAR_INT ("baud-rate", &baud_rate
,
2398 "The output baud rate of the terminal.\n\
2399 On most systems, changing this value will affect the amount of padding\n\
2400 and the other strategic decisions made during redisplay.");
2401 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2402 "*Non-nil means invert the entire frame display.\n\
2403 This means everything is in inverse video which otherwise would not be.");
2404 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2405 "*Non-nil means try to flash the frame to represent a bell.");
2406 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2407 "*Non-nil means no need to redraw entire frame after suspending.\n\
2408 A non-nil value is useful if the terminal can automatically preserve\n\
2409 Emacs's frame display when you reenter Emacs.\n\
2410 It is up to you to set this variable if your terminal can do that.");
2411 DEFVAR_LISP ("window-system", &Vwindow_system
,
2412 "A symbol naming the window-system under which Emacs is running\n\
2413 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2414 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2415 "The version number of the window system in use.\n\
2416 For X windows, this is 10 or 11.");
2417 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2418 "Non-nil means put cursor in minibuffer, at end of any message there.");
2419 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2420 "Table defining how to output a glyph code to the frame.\n\
2421 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2422 Each element can be:\n\
2423 integer: a glyph code which this glyph is an alias for.\n\
2424 string: output this glyph using that string (not impl. in X windows).\n\
2425 nil: this glyph mod 256 is char code to output,\n\
2426 and this glyph / 256 is face code for X windows (see `face-id').");
2427 Vglyph_table
= Qnil
;
2429 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2430 "Display table to use for buffers that specify none.\n\
2431 See `buffer-display-table' for more information.");
2432 Vstandard_display_table
= Qnil
;
2434 /* Initialize `window-system', unless init_display already decided it. */
2439 Vwindow_system
= Qnil
;
2440 Vwindow_system_version
= Qnil
;