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 */
48 #define max(a, b) ((a) > (b) ? (a) : (b))
49 #define min(a, b) ((a) < (b) ? (a) : (b))
51 #ifndef PENDING_OUTPUT_COUNT
52 /* Get number of chars of output now in the buffer of a stdio stream.
53 This ought to be built in in stdio, but it isn't.
54 Some s- files override this because their stdio internals differ. */
55 #ifdef __GNU_LIBRARY__
56 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
58 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
62 /* Nonzero upon entry to redisplay means do not assume anything about
63 current contents of actual terminal frame; clear and redraw it. */
67 /* Nonzero means last display completed. Zero means it was preempted. */
69 int display_completed
;
71 /* Lisp variable visible-bell; enables use of screen-flash
72 instead of audible bell. */
76 /* Invert the color of the whole frame, at a low level. */
80 /* Line speed of the terminal. */
84 /* nil or a symbol naming the window system under which emacs is
85 running ('x is the only current possibility). */
87 Lisp_Object Vwindow_system
;
89 /* Version number of X windows: 10, 11 or nil. */
90 Lisp_Object Vwindow_system_version
;
92 /* Vector of glyph definitions. Indexed by glyph number,
93 the contents are a string which is how to output the glyph.
95 If Vglyph_table is nil, a glyph is output by using its low 8 bits
96 as a character code. */
98 Lisp_Object Vglyph_table
;
100 /* Display table to use for vectors that don't specify their own. */
102 Lisp_Object Vstandard_display_table
;
104 /* Nonzero means reading single-character input with prompt
105 so put cursor on minibuffer after the prompt.
106 positive means at end of text in echo area;
107 negative means at beginning of line. */
108 int cursor_in_echo_area
;
110 /* The currently selected frame.
111 In a single-frame version, this variable always remains 0. */
113 FRAME_PTR selected_frame
;
115 /* A frame which is not just a minibuffer, or 0 if there are no such
116 frames. This is usually the most recent such frame that was
117 selected. In a single-frame version, this variable always remains 0. */
118 FRAME_PTR last_nonminibuf_frame
;
120 /* In a single-frame version, the information that would otherwise
121 exist inside frame objects lives in the following structure instead.
123 NOTE: the_only_frame is not checked for garbage collection; don't
124 store collectible objects in any of its fields!
126 You're not/The only frame in town/... */
129 struct frame the_only_frame
;
132 /* This is a vector, made larger whenever it isn't large enough,
133 which is used inside `update_frame' to hold the old contents
134 of the FRAME_PHYS_LINES of the frame being updated. */
135 struct frame_glyphs
**ophys_lines
;
136 /* Length of vector currently allocated. */
137 int ophys_lines_length
;
139 FILE *termscript
; /* Stdio stream being used for copy of all output. */
141 struct cm Wcm
; /* Structure for info on cursor positioning */
143 extern short ospeed
; /* Output speed (from sg_ospeed) */
145 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
149 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
150 "Clear frame FRAME and output again what is supposed to appear on it.")
156 CHECK_LIVE_FRAME (frame
, 0);
159 /* set_terminal_modes (); */
161 clear_frame_records (f
);
164 windows_or_buffers_changed
++;
165 /* Mark all windows as INaccurate,
166 so that every window will have its redisplay done. */
167 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
176 XSET (frame
, Lisp_Frame
, f
);
177 Fredraw_frame (frame
);
182 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
183 "Clear frame FRAME and output again what is supposed to appear on it.")
188 set_terminal_modes ();
192 clear_frame_records (0);
193 windows_or_buffers_changed
++;
194 /* Mark all windows as INaccurate,
195 so that every window will have its redisplay done. */
196 mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
202 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
203 "Clear and redisplay all visible frames.")
206 Lisp_Object tail
, frame
;
208 FOR_EACH_FRAME (tail
, frame
)
209 if (FRAME_VISIBLE_P (XFRAME (frame
)))
210 Fredraw_frame (frame
);
215 /* This is used when frame_garbaged is set.
216 Redraw the individual frames marked as garbaged. */
219 redraw_garbaged_frames ()
221 Lisp_Object tail
, frame
;
223 FOR_EACH_FRAME (tail
, frame
)
224 if (FRAME_VISIBLE_P (XFRAME (frame
))
225 && FRAME_GARBAGED_P (XFRAME (frame
)))
226 Fredraw_frame (frame
);
230 static struct frame_glyphs
*
231 make_frame_glyphs (frame
, empty
)
232 register FRAME_PTR frame
;
236 register width
= FRAME_WIDTH (frame
);
237 register height
= FRAME_HEIGHT (frame
);
238 register struct frame_glyphs
*new
239 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
241 SET_GLYPHS_FRAME (new, frame
);
242 new->height
= height
;
244 new->used
= (int *) xmalloc (height
* sizeof (int));
245 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
246 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
247 new->highlight
= (char *) xmalloc (height
* sizeof (char));
248 new->enable
= (char *) xmalloc (height
* sizeof (char));
249 bzero (new->enable
, height
* sizeof (char));
250 new->bufp
= (int *) xmalloc (height
* sizeof (int));
252 #ifdef HAVE_X_WINDOWS
253 if (FRAME_X_P (frame
))
255 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
256 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
257 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
258 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
259 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
265 /* Make the buffer used by decode_mode_spec. This buffer is also
266 used as temporary storage when updating the frame. See scroll.c. */
267 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
268 unsigned int total_charstarts
= (width
+ 2) * sizeof (int);
270 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
271 bzero (new->total_contents
, total_glyphs
);
273 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
274 bzero (new->total_charstarts
, total_glyphs
);
278 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
280 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
281 bzero (new->total_contents
, total_glyphs
);
282 for (i
= 0; i
< height
; i
++)
283 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
285 if (!FRAME_TERMCAP_P (frame
))
287 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
289 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
290 bzero (new->total_charstarts
, total_charstarts
);
291 for (i
= 0; i
< height
; i
++)
292 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
296 /* Without a window system, we don't really need charstarts.
297 So use a small amount of space to make enough data structure
298 to prevent crashes in display_text_line. */
299 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
300 for (i
= 0; i
< height
; i
++)
301 new->charstarts
[i
] = new->total_charstarts
;
309 free_frame_glyphs (frame
, glyphs
)
311 struct frame_glyphs
*glyphs
;
313 if (glyphs
->total_contents
)
314 xfree (glyphs
->total_contents
);
315 if (glyphs
->total_charstarts
)
316 xfree (glyphs
->total_charstarts
);
318 xfree (glyphs
->used
);
319 xfree (glyphs
->glyphs
);
320 xfree (glyphs
->highlight
);
321 xfree (glyphs
->enable
);
322 xfree (glyphs
->bufp
);
323 if (glyphs
->charstarts
)
324 xfree (glyphs
->charstarts
);
326 #ifdef HAVE_X_WINDOWS
327 if (FRAME_X_P (frame
))
329 xfree (glyphs
->top_left_x
);
330 xfree (glyphs
->top_left_y
);
331 xfree (glyphs
->pix_width
);
332 xfree (glyphs
->pix_height
);
333 xfree (glyphs
->max_ascent
);
341 remake_frame_glyphs (frame
)
344 if (FRAME_CURRENT_GLYPHS (frame
))
345 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
346 if (FRAME_DESIRED_GLYPHS (frame
))
347 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
348 if (FRAME_TEMP_GLYPHS (frame
))
349 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
351 if (FRAME_MESSAGE_BUF (frame
))
353 /* Reallocate the frame's message buffer; remember that
354 echo_area_glyphs may be pointing here. */
355 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
357 FRAME_MESSAGE_BUF (frame
)
358 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
359 FRAME_WIDTH (frame
) + 1);
361 if (echo_area_glyphs
== old_message_buf
)
362 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
363 if (previous_echo_glyphs
== old_message_buf
)
364 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
367 FRAME_MESSAGE_BUF (frame
)
368 = (char *) xmalloc (FRAME_WIDTH (frame
) + 1);
370 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
371 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
372 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
373 SET_FRAME_GARBAGED (frame
);
376 /* Return the hash code of contents of line VPOS in frame-matrix M. */
379 line_hash_code (m
, vpos
)
380 register struct frame_glyphs
*m
;
383 register GLYPH
*body
, *end
;
386 if (!m
->enable
[vpos
])
389 /* Give all highlighted lines the same hash code
390 so as to encourage scrolling to leave them in place. */
391 if (m
->highlight
[vpos
])
394 body
= m
->glyphs
[vpos
];
396 if (must_write_spaces
)
403 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
412 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
420 /* Return number of characters in line in M at vpos VPOS,
421 except don't count leading and trailing spaces
422 unless the terminal requires those to be explicitly output. */
425 line_draw_cost (m
, vpos
)
426 struct frame_glyphs
*m
;
429 register GLYPH
*beg
= m
->glyphs
[vpos
];
430 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
432 register int tlen
= GLYPH_TABLE_LENGTH
;
433 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
435 /* Ignore trailing and leading spaces if we can. */
436 if (!must_write_spaces
)
438 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
441 return (0); /* All blank line. */
443 while (*beg
== SPACEGLYPH
)
447 /* If we don't have a glyph-table, each glyph is one character,
448 so return the number of glyphs. */
452 /* Otherwise, scan the glyphs and accumulate their total size in I. */
454 while ((beg
<= end
) && *beg
)
456 register GLYPH g
= *beg
++;
458 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
461 i
+= GLYPH_LENGTH (tbase
, g
);
466 /* The functions on this page are the interface from xdisp.c to redisplay.
468 The only other interface into redisplay is through setting
469 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
470 and SET_FRAME_GARBAGED (frame). */
472 /* cancel_line eliminates any request to display a line at position `vpos' */
474 cancel_line (vpos
, frame
)
476 register FRAME_PTR frame
;
478 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
481 clear_frame_records (frame
)
482 register FRAME_PTR frame
;
484 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
487 /* Prepare to display on line VPOS starting at HPOS within it. */
490 get_display_line (frame
, vpos
, hpos
)
491 register FRAME_PTR frame
;
495 register struct frame_glyphs
*glyphs
;
496 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
502 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
505 if (! desired_glyphs
->enable
[vpos
])
507 desired_glyphs
->used
[vpos
] = 0;
508 desired_glyphs
->highlight
[vpos
] = 0;
509 desired_glyphs
->enable
[vpos
] = 1;
512 if (hpos
> desired_glyphs
->used
[vpos
])
514 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
515 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
517 desired_glyphs
->used
[vpos
] = hpos
;
523 /* Like bcopy except never gets confused by overlap. */
526 safe_bcopy (from
, to
, size
)
530 if (size
<= 0 || from
== to
)
533 /* If the source and destination don't overlap, then bcopy can
534 handle it. If they do overlap, but the destination is lower in
535 memory than the source, we'll assume bcopy can handle that. */
536 if (to
< from
|| from
+ size
<= to
)
537 bcopy (from
, to
, size
);
539 /* Otherwise, we'll copy from the end. */
542 register char *endf
= from
+ size
;
543 register char *endt
= to
+ size
;
545 /* If TO - FROM is large, then we should break the copy into
546 nonoverlapping chunks of TO - FROM bytes each. However, if
547 TO - FROM is small, then the bcopy function call overhead
548 makes this not worth it. The crossover point could be about
549 anywhere. Since I don't think the obvious copy loop is too
550 bad, I'm trying to err in its favor. */
555 while (endf
!= from
);
567 bcopy (endf
, endt
, to
- from
);
570 /* If SIZE wasn't a multiple of TO - FROM, there will be a
571 little left over. The amount left over is
572 (endt + (to - from)) - to, which is endt - from. */
573 bcopy (from
, to
, endt
- from
);
578 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
579 DISTANCE may be negative. */
582 rotate_vector (vector
, size
, distance
)
587 char *temp
= (char *) alloca (size
);
592 bcopy (vector
, temp
+ distance
, size
- distance
);
593 bcopy (vector
+ size
- distance
, temp
, distance
);
594 bcopy (temp
, vector
, size
);
597 /* Scroll lines from vpos FROM up to but not including vpos END
598 down by AMOUNT lines (AMOUNT may be negative).
599 Returns nonzero if done, zero if terminal cannot scroll them. */
602 scroll_frame_lines (frame
, from
, end
, amount
, newpos
)
603 register FRAME_PTR frame
;
604 int from
, end
, amount
, newpos
;
607 register struct frame_glyphs
*current_frame
608 = FRAME_CURRENT_GLYPHS (frame
);
610 int width
= FRAME_WIDTH (frame
);
612 if (!line_ins_del_ok
)
620 update_begin (frame
);
621 set_terminal_window (end
+ amount
);
622 if (!scroll_region_ok
)
623 ins_del_lines (end
, -amount
);
624 ins_del_lines (from
, amount
);
625 set_terminal_window (0);
627 rotate_vector (current_frame
->glyphs
+ from
,
628 sizeof (GLYPH
*) * (end
+ amount
- from
),
629 amount
* sizeof (GLYPH
*));
631 rotate_vector (current_frame
->charstarts
+ from
,
632 sizeof (int *) * (end
+ amount
- from
),
633 amount
* sizeof (int *));
635 safe_bcopy (current_frame
->used
+ from
,
636 current_frame
->used
+ from
+ amount
,
637 (end
- from
) * sizeof current_frame
->used
[0]);
639 safe_bcopy (current_frame
->highlight
+ from
,
640 current_frame
->highlight
+ from
+ amount
,
641 (end
- from
) * sizeof current_frame
->highlight
[0]);
643 safe_bcopy (current_frame
->enable
+ from
,
644 current_frame
->enable
+ from
+ amount
,
645 (end
- from
) * sizeof current_frame
->enable
[0]);
647 /* Adjust the lines by an amount
648 that puts the first of them at NEWPOS. */
649 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
651 /* Offset each char position in the charstarts lines we moved
653 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
655 int *line
= current_frame
->charstarts
[i
];
657 for (col
= 0; col
< width
; col
++)
659 line
[col
] += pos_adjust
;
661 for (i
= from
; i
< from
+ amount
; i
++)
663 int *line
= current_frame
->charstarts
[i
];
666 for (col
= 0; col
< width
; col
++)
670 /* Mark the lines made empty by scrolling as enabled, empty and
672 bzero (current_frame
->used
+ from
,
673 amount
* sizeof current_frame
->used
[0]);
674 bzero (current_frame
->highlight
+ from
,
675 amount
* sizeof current_frame
->highlight
[0]);
676 for (i
= from
; i
< from
+ amount
; i
++)
678 current_frame
->glyphs
[i
][0] = '\0';
679 current_frame
->charstarts
[i
][0] = -1;
680 current_frame
->enable
[i
] = 1;
683 safe_bcopy (current_frame
->bufp
+ from
,
684 current_frame
->bufp
+ from
+ amount
,
685 (end
- from
) * sizeof current_frame
->bufp
[0]);
687 #ifdef HAVE_X_WINDOWS
688 if (FRAME_X_P (frame
))
690 safe_bcopy (current_frame
->top_left_x
+ from
,
691 current_frame
->top_left_x
+ from
+ amount
,
692 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
694 safe_bcopy (current_frame
->top_left_y
+ from
,
695 current_frame
->top_left_y
+ from
+ amount
,
696 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
698 safe_bcopy (current_frame
->pix_width
+ from
,
699 current_frame
->pix_width
+ from
+ amount
,
700 (end
- from
) * sizeof current_frame
->pix_width
[0]);
702 safe_bcopy (current_frame
->pix_height
+ from
,
703 current_frame
->pix_height
+ from
+ amount
,
704 (end
- from
) * sizeof current_frame
->pix_height
[0]);
706 safe_bcopy (current_frame
->max_ascent
+ from
,
707 current_frame
->max_ascent
+ from
+ amount
,
708 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
710 #endif /* HAVE_X_WINDOWS */
716 update_begin (frame
);
717 set_terminal_window (end
);
718 ins_del_lines (from
+ amount
, amount
);
719 if (!scroll_region_ok
)
720 ins_del_lines (end
+ amount
, -amount
);
721 set_terminal_window (0);
723 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
724 sizeof (GLYPH
*) * (end
- from
- amount
),
725 amount
* sizeof (GLYPH
*));
727 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
728 sizeof (int *) * (end
- from
- amount
),
729 amount
* sizeof (int *));
731 safe_bcopy (current_frame
->used
+ from
,
732 current_frame
->used
+ from
+ amount
,
733 (end
- from
) * sizeof current_frame
->used
[0]);
735 safe_bcopy (current_frame
->highlight
+ from
,
736 current_frame
->highlight
+ from
+ amount
,
737 (end
- from
) * sizeof current_frame
->highlight
[0]);
739 safe_bcopy (current_frame
->enable
+ from
,
740 current_frame
->enable
+ from
+ amount
,
741 (end
- from
) * sizeof current_frame
->enable
[0]);
743 /* Adjust the lines by an amount
744 that puts the first of them at NEWPOS. */
745 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
747 /* Offset each char position in the charstarts lines we moved
749 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
751 int *line
= current_frame
->charstarts
[i
];
753 for (col
= 0; col
< width
; col
++)
755 line
[col
] += pos_adjust
;
757 for (i
= end
+ amount
; i
< end
; i
++)
759 int *line
= current_frame
->charstarts
[i
];
762 for (col
= 0; col
< width
; col
++)
766 /* Mark the lines made empty by scrolling as enabled, empty and
768 bzero (current_frame
->used
+ end
+ amount
,
769 - amount
* sizeof current_frame
->used
[0]);
770 bzero (current_frame
->highlight
+ end
+ amount
,
771 - amount
* sizeof current_frame
->highlight
[0]);
772 for (i
= end
+ amount
; i
< end
; i
++)
774 current_frame
->glyphs
[i
][0] = '\0';
775 current_frame
->charstarts
[i
][0] = 0;
776 current_frame
->enable
[i
] = 1;
779 safe_bcopy (current_frame
->bufp
+ from
,
780 current_frame
->bufp
+ from
+ amount
,
781 (end
- from
) * sizeof current_frame
->bufp
[0]);
783 #ifdef HAVE_X_WINDOWS
784 if (FRAME_X_P (frame
))
786 safe_bcopy (current_frame
->top_left_x
+ from
,
787 current_frame
->top_left_x
+ from
+ amount
,
788 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
790 safe_bcopy (current_frame
->top_left_y
+ from
,
791 current_frame
->top_left_y
+ from
+ amount
,
792 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
794 safe_bcopy (current_frame
->pix_width
+ from
,
795 current_frame
->pix_width
+ from
+ amount
,
796 (end
- from
) * sizeof current_frame
->pix_width
[0]);
798 safe_bcopy (current_frame
->pix_height
+ from
,
799 current_frame
->pix_height
+ from
+ amount
,
800 (end
- from
) * sizeof current_frame
->pix_height
[0]);
802 safe_bcopy (current_frame
->max_ascent
+ from
,
803 current_frame
->max_ascent
+ from
+ amount
,
804 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
806 #endif /* HAVE_X_WINDOWS */
813 /* After updating a window W that isn't the full frame wide,
814 copy all the columns that W does not occupy
815 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
816 so that update_frame will not change those columns. */
818 preserve_other_columns (w
)
822 register struct frame_glyphs
*current_frame
, *desired_frame
;
823 register FRAME_PTR frame
= XFRAME (w
->frame
);
824 int start
= XFASTINT (w
->left
);
825 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
826 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
828 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
829 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
831 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
833 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
839 bcopy (current_frame
->glyphs
[vpos
],
840 desired_frame
->glyphs
[vpos
],
841 start
* sizeof (current_frame
->glyphs
[vpos
]));
842 bcopy (current_frame
->charstarts
[vpos
],
843 desired_frame
->charstarts
[vpos
],
844 start
* sizeof (current_frame
->charstarts
[vpos
]));
845 len
= min (start
, current_frame
->used
[vpos
]);
846 if (desired_frame
->used
[vpos
] < len
)
847 desired_frame
->used
[vpos
] = len
;
849 if (current_frame
->used
[vpos
] > end
850 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
852 while (desired_frame
->used
[vpos
] < end
)
854 int used
= desired_frame
->used
[vpos
]++;
855 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
856 desired_frame
->glyphs
[vpos
][used
] = 0;
858 bcopy (current_frame
->glyphs
[vpos
] + end
,
859 desired_frame
->glyphs
[vpos
] + end
,
860 ((current_frame
->used
[vpos
] - end
)
861 * sizeof (current_frame
->glyphs
[vpos
])));
862 bcopy (current_frame
->charstarts
[vpos
] + end
,
863 desired_frame
->charstarts
[vpos
] + end
,
864 ((current_frame
->used
[vpos
] - end
)
865 * sizeof (current_frame
->charstarts
[vpos
])));
866 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
874 /* If window w does not need to be updated and isn't the full frame wide,
875 copy all the columns that w does occupy
876 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
877 so that update_frame will not change those columns.
879 Have not been able to figure out how to use this correctly. */
881 preserve_my_columns (w
)
884 register int vpos
, fin
;
885 register struct frame_glyphs
*l1
, *l2
;
886 register FRAME_PTR frame
= XFRAME (w
->frame
);
887 int start
= XFASTINT (w
->left
);
888 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
889 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
891 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
893 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
894 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
896 if (l2
->length
> start
&& l1
->length
< l2
->length
)
899 if (fin
> end
) fin
= end
;
900 while (l1
->length
< start
)
901 l1
->body
[l1
->length
++] = ' ';
902 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
911 /* Adjust by ADJUST the charstart values in window W
912 after vpos VPOS, which counts relative to the frame
913 (not relative to W itself). */
916 adjust_window_charstarts (w
, vpos
, adjust
)
921 int left
= XFASTINT (w
->left
);
922 int top
= XFASTINT (w
->top
);
923 int right
= left
+ window_internal_width (w
);
924 int bottom
= top
+ window_internal_height (w
);
927 for (i
= vpos
+ 1; i
< bottom
; i
++)
930 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
932 for (j
= left
; j
< right
; j
++)
933 if (charstart
[j
] > 0)
934 charstart
[j
] += adjust
;
938 /* Check the charstarts values in the area of window W
939 for internal consistency. We cannot check that they are "right";
940 we can only look for something nonsensical. */
942 verify_charstarts (w
)
945 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
947 int top
= XFASTINT (w
->top
);
948 int bottom
= top
+ window_internal_height (w
);
949 int left
= XFASTINT (w
->left
);
950 int right
= left
+ window_internal_width (w
);
952 int truncate
= (XINT (w
->hscroll
)
953 || (truncate_partial_width_windows
954 && (XFASTINT (w
->width
) < FRAME_WIDTH (f
)))
955 || !NILP (XBUFFER (w
->buffer
)->truncate_lines
));
957 for (i
= top
; i
< bottom
; i
++)
961 int *charstart
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[i
];
967 /* If we are truncating lines, allow a jump
968 in charstarts from one line to the next. */
969 if (charstart
[left
] < next_line
)
974 if (charstart
[left
] != next_line
)
979 for (j
= left
; j
< right
; j
++)
980 if (charstart
[j
] > 0)
982 /* Record where the next line should start. */
984 if (BUF_ZV (XBUFFER (w
->buffer
)) != last
)
986 /* If there's a newline between the two lines, count that. */
987 int endchar
= *BUF_CHAR_ADDRESS (XBUFFER (w
->buffer
), last
);
994 /* On discovering that the redisplay for a window was no good,
995 cancel the columns of that window, so that when the window is
996 displayed over again get_display_line will not complain. */
998 cancel_my_columns (w
)
1002 register struct frame_glyphs
*desired_glyphs
1003 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
1004 register int start
= XFASTINT (w
->left
);
1005 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
1007 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
1008 if (desired_glyphs
->enable
[vpos
]
1009 && desired_glyphs
->used
[vpos
] >= start
)
1010 desired_glyphs
->used
[vpos
] = start
;
1013 /* These functions try to perform directly and immediately on the frame
1014 the necessary output for one change in the buffer.
1015 They may return 0 meaning nothing was done if anything is difficult,
1016 or 1 meaning the output was performed properly.
1017 They assume that the frame was up to date before the buffer
1018 change being displayed. They make various other assumptions too;
1019 see command_loop_1 where these are called. */
1022 direct_output_for_insert (g
)
1025 register FRAME_PTR frame
= selected_frame
;
1026 register struct frame_glyphs
*current_frame
1027 = FRAME_CURRENT_GLYPHS (frame
);
1029 #ifndef COMPILER_REGISTER_BUG
1031 #endif /* COMPILER_REGISTER_BUG */
1032 struct window
*w
= XWINDOW (selected_window
);
1033 #ifndef COMPILER_REGISTER_BUG
1035 #endif /* COMPILER_REGISTER_BUG */
1036 int hpos
= FRAME_CURSOR_X (frame
);
1037 #ifndef COMPILER_REGISTER_BUG
1039 #endif /* COMPILER_REGISTER_BUG */
1040 int vpos
= FRAME_CURSOR_Y (frame
);
1042 /* Give up if about to continue line. */
1043 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1
1045 /* Avoid losing if cursor is in invisible text off left margin */
1046 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
1048 /* Give up if cursor outside window (in minibuf, probably) */
1049 || cursor_in_echo_area
1050 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
1051 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
1053 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
1054 || !display_completed
1056 /* Give up if buffer appears in two places. */
1057 || buffer_shared
> 1
1059 #ifdef USE_TEXT_PROPERTIES
1060 /* Intervals have already been adjusted, point is after the
1061 character that was just inserted. */
1062 /* Give up if character is invisible. */
1063 /* Give up if character has a face property.
1064 At the moment we only lose at end of line or end of buffer
1065 and only with faces that have some background */
1066 /* Instead of wasting time, give up if character has any text properties */
1067 || ! NILP (Ftext_properties_at (XFASTINT (point
- 1), Qnil
))
1070 /* Give up if w is minibuffer and a message is being displayed there */
1071 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1075 #ifdef HAVE_X_WINDOWS
1077 int face
= compute_char_face (frame
, w
, point
- 1, -1, -1, &dummy
, point
);
1079 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1080 current_frame
->charstarts
[vpos
][hpos
] = point
- 1;
1081 /* Record the entry for after the newly inserted character. */
1082 current_frame
->charstarts
[vpos
][hpos
+ 1] = point
;
1083 adjust_window_charstarts (w
, vpos
, 1);
1085 unchanged_modified
= MODIFF
;
1086 beg_unchanged
= GPT
- BEG
;
1087 XFASTINT (w
->last_point
) = point
;
1088 XFASTINT (w
->last_point_x
) = hpos
;
1089 XFASTINT (w
->last_modified
) = MODIFF
;
1091 reassert_line_highlight (0, vpos
);
1092 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
1094 ++FRAME_CURSOR_X (frame
);
1095 if (hpos
== current_frame
->used
[vpos
])
1097 current_frame
->used
[vpos
] = hpos
+ 1;
1098 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
1105 direct_output_forward_char (n
)
1108 register FRAME_PTR frame
= selected_frame
;
1109 register struct window
*w
= XWINDOW (selected_window
);
1111 int hpos
= FRAME_CURSOR_X (frame
);
1113 /* Give up if in truncated text at end of line. */
1114 if (hpos
>= XFASTINT (w
->left
) + window_internal_width (w
) - 1)
1117 /* Avoid losing if cursor is in invisible text off left margin
1118 or about to go off either side of window. */
1119 if ((FRAME_CURSOR_X (frame
) == XFASTINT (w
->left
)
1120 && (XINT (w
->hscroll
) || n
< 0))
1122 && (FRAME_CURSOR_X (frame
) + 1 >= window_internal_width (w
) - 1))
1123 || cursor_in_echo_area
)
1126 /* Can't use direct output if highlighting a region. */
1127 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1130 #ifdef USE_TEXT_PROPERTIES
1131 /* Don't use direct output next to an invisible character
1132 since we might need to do something special. */
1134 XFASTINT (position
) = point
;
1135 if (XFASTINT (position
) < ZV
1136 && ! NILP (Fget_char_property (position
,
1141 XFASTINT (position
) = point
- 1;
1142 if (XFASTINT (position
) >= BEGV
1143 && ! NILP (Fget_char_property (position
,
1149 FRAME_CURSOR_X (frame
) += n
;
1150 XFASTINT (w
->last_point_x
) = FRAME_CURSOR_X (frame
);
1151 XFASTINT (w
->last_point
) = point
;
1152 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1158 static void update_line ();
1160 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1161 Value is nonzero if redisplay stopped due to pending input.
1162 FORCE nonzero means do not stop for pending input. */
1165 update_frame (f
, force
, inhibit_hairy_id
)
1168 int inhibit_hairy_id
;
1170 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (f
);
1171 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1174 int preempt_count
= baud_rate
/ 2400 + 1;
1175 extern input_pending
;
1176 #ifdef HAVE_X_WINDOWS
1177 register int downto
, leftmost
;
1180 if (preempt_count
<= 0)
1183 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1185 detect_input_pending ();
1186 if (input_pending
&& !force
)
1194 if (!line_ins_del_ok
)
1195 inhibit_hairy_id
= 1;
1197 /* See if any of the desired lines are enabled; don't compute for
1198 i/d line if just want cursor motion. */
1199 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1200 if (desired_frame
->enable
[i
])
1203 /* Try doing i/d line, if not yet inhibited. */
1204 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1205 force
|= scrolling (f
);
1207 /* Update the individual lines as needed. Do bottom line first. */
1209 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1210 update_line (f
, FRAME_HEIGHT (f
) - 1);
1212 #ifdef HAVE_X_WINDOWS
1215 leftmost
= downto
= f
->display
.x
->internal_border_width
;
1216 if (desired_frame
->enable
[0])
1218 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1219 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1220 = PIXEL_HEIGHT (f
) - f
->display
.x
->internal_border_width
1221 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1222 current_frame
->top_left_x
[0] = leftmost
;
1223 current_frame
->top_left_y
[0] = downto
;
1226 #endif /* HAVE_X_WINDOWS */
1228 /* Now update the rest of the lines. */
1229 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1231 if (desired_frame
->enable
[i
])
1233 if (FRAME_TERMCAP_P (f
))
1235 /* Flush out every so many lines.
1236 Also flush out if likely to have more than 1k buffered
1237 otherwise. I'm told that some telnet connections get
1238 really screwed by more than 1k output at once. */
1239 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1241 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1244 if (preempt_count
== 1)
1246 #ifdef EMACS_OUTQSIZE
1247 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1248 /* Probably not a tty. Ignore the error and reset
1249 * the outq count. */
1250 outq
= PENDING_OUTPUT_COUNT (stdout
);
1253 if (baud_rate
>= outq
)
1254 sleep (outq
/ baud_rate
);
1257 if ((i
- 1) % preempt_count
== 0)
1258 detect_input_pending ();
1262 #ifdef HAVE_X_WINDOWS
1265 current_frame
->top_left_y
[i
] = downto
;
1266 current_frame
->top_left_x
[i
] = leftmost
;
1268 #endif /* HAVE_X_WINDOWS */
1271 #ifdef HAVE_X_WINDOWS
1273 downto
+= current_frame
->pix_height
[i
];
1276 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1278 /* Now just clean up termcap drivers and set cursor, etc. */
1281 if (cursor_in_echo_area
1282 && FRAME_HAS_MINIBUF_P (f
))
1284 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1287 if (cursor_in_echo_area
< 0)
1294 /* If the minibuffer is several lines high, find the last
1295 line that has any text on it. */
1296 row
= FRAME_HEIGHT (f
);
1300 if (current_frame
->enable
[row
])
1301 col
= current_frame
->used
[row
];
1305 while (row
> top
&& col
== 0);
1307 if (col
>= FRAME_WIDTH (f
))
1310 if (row
< FRAME_HEIGHT (f
) - 1)
1315 cursor_to (row
, col
);
1318 cursor_to (FRAME_CURSOR_Y (f
), max (min (FRAME_CURSOR_X (f
),
1319 FRAME_WIDTH (f
) - 1), 0));
1325 fflush (termscript
);
1328 /* Here if output is preempted because input is detected. */
1331 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1332 display_completed
= !pause
;
1334 bzero (desired_frame
->enable
, FRAME_HEIGHT (f
));
1338 /* Called when about to quit, to check for doing so
1339 at an improper time. */
1344 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1346 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1348 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1352 /* Decide what insert/delete line to do, and do it */
1354 extern void scrolling_1 ();
1359 int unchanged_at_top
, unchanged_at_bottom
;
1362 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1363 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1364 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1366 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1367 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1368 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1370 /* Compute hash codes of all the lines.
1371 Also calculate number of changed lines,
1372 number of unchanged lines at the beginning,
1373 and number of unchanged lines at the end. */
1376 unchanged_at_top
= 0;
1377 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1378 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1380 /* Give up on this scrolling if some old lines are not enabled. */
1381 if (!current_frame
->enable
[i
])
1383 old_hash
[i
] = line_hash_code (current_frame
, i
);
1384 if (! desired_frame
->enable
[i
])
1385 new_hash
[i
] = old_hash
[i
];
1387 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1389 if (old_hash
[i
] != new_hash
[i
])
1392 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1394 else if (i
== unchanged_at_top
)
1396 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1399 /* If changed lines are few, don't allow preemption, don't scroll. */
1400 if (changed_lines
< baud_rate
/ 2400
1401 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1404 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1405 - unchanged_at_bottom
);
1407 if (scroll_region_ok
)
1408 free_at_end_vpos
-= unchanged_at_bottom
;
1409 else if (memory_below_frame
)
1410 free_at_end_vpos
= -1;
1412 /* If large window, fast terminal and few lines in common between
1413 current frame and desired frame, don't bother with i/d calc. */
1414 if (window_size
>= 18 && baud_rate
> 2400
1416 10 * scrolling_max_lines_saved (unchanged_at_top
,
1417 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1418 old_hash
, new_hash
, draw_cost
)))
1421 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1422 draw_cost
+ unchanged_at_top
- 1,
1423 old_hash
+ unchanged_at_top
- 1,
1424 new_hash
+ unchanged_at_top
- 1,
1425 free_at_end_vpos
- unchanged_at_top
);
1430 /* Return the offset in its buffer of the character at location col, line
1431 in the given window. */
1433 buffer_posn_from_coords (window
, col
, line
)
1434 struct window
*window
;
1437 int hscroll
= XINT (window
->hscroll
);
1438 int window_left
= XFASTINT (window
->left
);
1440 /* The actual width of the window is window->width less one for the
1441 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1443 int window_width
= window_internal_width (window
) - 1;
1445 int startp
= marker_position (window
->start
);
1447 /* Since compute_motion will only operate on the current buffer,
1448 we need to save the old one and restore it when we're done. */
1449 struct buffer
*old_current_buffer
= current_buffer
;
1450 struct position
*posn
;
1452 current_buffer
= XBUFFER (window
->buffer
);
1454 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1455 (window->frame))->bufp to avoid scanning from the very top of
1456 the window, but it isn't maintained correctly, and I'm not even
1457 sure I will keep it. */
1458 posn
= compute_motion (startp
, 0,
1459 (window
== XWINDOW (minibuf_window
) && startp
== 1
1460 ? minibuf_prompt_width
: 0)
1461 + (hscroll
? 1 - hscroll
: 0),
1463 window_width
, hscroll
, 0, window
);
1465 current_buffer
= old_current_buffer
;
1467 /* compute_motion considers frame points past the end of a line
1468 to be *after* the newline, i.e. at the start of the next line.
1469 This is reasonable, but not really what we want. So if the
1470 result is on a line below LINE, back it up one character. */
1471 if (posn
->vpos
> line
)
1472 return posn
->bufpos
- 1;
1474 return posn
->bufpos
;
1481 register GLYPH
*p
= r
;
1482 while (*p
++ == SPACEGLYPH
);
1487 count_match (str1
, str2
)
1490 register GLYPH
*p1
= str1
;
1491 register GLYPH
*p2
= str2
;
1492 while (*p1
++ == *p2
++);
1493 return p1
- str1
- 1;
1496 /* Char insertion/deletion cost vector, from term.c */
1497 extern int *char_ins_del_vector
;
1499 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
1502 update_line (frame
, vpos
)
1503 register FRAME_PTR frame
;
1506 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1509 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1511 register struct frame_glyphs
*current_frame
1512 = FRAME_CURRENT_GLYPHS (frame
);
1513 register struct frame_glyphs
*desired_frame
1514 = FRAME_DESIRED_GLYPHS (frame
);
1516 if (desired_frame
->highlight
[vpos
]
1517 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1519 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1520 (current_frame
->enable
[vpos
] ?
1521 current_frame
->used
[vpos
] : 0));
1522 current_frame
->enable
[vpos
] = 0;
1525 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1527 if (! current_frame
->enable
[vpos
])
1533 obody
= current_frame
->glyphs
[vpos
];
1534 olen
= current_frame
->used
[vpos
];
1535 if (! current_frame
->highlight
[vpos
])
1537 if (!must_write_spaces
)
1538 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1543 /* For an inverse-video line, remember we gave it
1544 spaces all the way to the frame edge
1545 so that the reverse video extends all the way across. */
1547 while (olen
< FRAME_WIDTH (frame
) - 1)
1548 obody
[olen
++] = SPACEGLYPH
;
1552 /* One way or another, this will enable the line being updated. */
1553 current_frame
->enable
[vpos
] = 1;
1554 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1555 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1556 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1558 #ifdef HAVE_X_WINDOWS
1559 if (FRAME_X_P (frame
))
1561 current_frame
->pix_width
[vpos
]
1562 = current_frame
->used
[vpos
]
1563 * FONT_WIDTH (frame
->display
.x
->font
);
1564 current_frame
->pix_height
[vpos
]
1565 = frame
->display
.x
->line_height
;
1567 #endif /* HAVE_X_WINDOWS */
1569 if (!desired_frame
->enable
[vpos
])
1575 nbody
= desired_frame
->glyphs
[vpos
];
1576 nlen
= desired_frame
->used
[vpos
];
1578 /* Pretend trailing spaces are not there at all,
1579 unless for one reason or another we must write all spaces. */
1580 if (! desired_frame
->highlight
[vpos
])
1582 if (!must_write_spaces
)
1583 /* We know that the previous character byte contains 0. */
1584 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1589 /* For an inverse-video line, give it extra trailing spaces
1590 all the way to the frame edge
1591 so that the reverse video extends all the way across. */
1593 while (nlen
< FRAME_WIDTH (frame
) - 1)
1594 nbody
[nlen
++] = SPACEGLYPH
;
1597 /* If there's no i/d char, quickly do the best we can without it. */
1598 if (!char_ins_del_ok
)
1603 if (FRAME_X_P (frame
))
1605 /* Under X, erase everything we are going to rewrite,
1606 and rewrite everything from the first char that's changed.
1607 This is part of supporting fonts like Courier
1608 whose chars can overlap outside the char width. */
1609 for (i
= 0; i
< nlen
; i
++)
1610 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1613 cursor_to (vpos
, i
);
1615 clear_end_of_line (olen
);
1616 write_glyphs (nbody
+ i
, nlen
- i
);
1621 for (i
= 0; i
< nlen
; i
++)
1623 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1625 cursor_to (vpos
, i
);
1626 for (j
= 1; (i
+ j
< nlen
&&
1627 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1630 /* Output this run of non-matching chars. */
1631 write_glyphs (nbody
+ i
, j
);
1634 /* Now find the next non-match. */
1638 /* Clear the rest of the line, or the non-clear part of it. */
1641 cursor_to (vpos
, nlen
);
1642 clear_end_of_line (olen
);
1645 /* Exchange contents between current_frame and new_frame. */
1646 temp
= desired_frame
->glyphs
[vpos
];
1647 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1648 current_frame
->glyphs
[vpos
] = temp
;
1650 /* Exchange charstarts between current_frame and new_frame. */
1651 temp1
= desired_frame
->charstarts
[vpos
];
1652 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1653 current_frame
->charstarts
[vpos
] = temp1
;
1660 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1661 ? 0 : count_blanks (nbody
);
1664 cursor_to (vpos
, nsp
);
1665 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1668 /* Exchange contents between current_frame and new_frame. */
1669 temp
= desired_frame
->glyphs
[vpos
];
1670 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1671 current_frame
->glyphs
[vpos
] = temp
;
1673 /* Exchange charstarts between current_frame and new_frame. */
1674 temp1
= desired_frame
->charstarts
[vpos
];
1675 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1676 current_frame
->charstarts
[vpos
] = temp1
;
1685 /* Compute number of leading blanks in old and new contents. */
1686 osp
= count_blanks (obody
);
1687 if (!desired_frame
->highlight
[vpos
])
1688 nsp
= count_blanks (nbody
);
1692 /* Compute number of matching chars starting with first nonblank. */
1693 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1695 /* Spaces in new match implicit space past the end of old. */
1696 /* A bug causing this to be a no-op was fixed in 18.29. */
1697 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1700 while (np1
[begmatch
] == SPACEGLYPH
)
1704 /* Avoid doing insert/delete char
1705 just cause number of leading spaces differs
1706 when the following text does not match. */
1707 if (begmatch
== 0 && osp
!= nsp
)
1708 osp
= nsp
= min (osp
, nsp
);
1710 /* Find matching characters at end of line */
1713 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1714 while (op1
> op2
&& op1
[-1] == np1
[-1])
1719 endmatch
= obody
+ olen
- op1
;
1721 /* Put correct value back in nbody[nlen].
1722 This is important because direct_output_for_insert
1723 can write into the line at a later point.
1724 If this screws up the zero at the end of the line, re-establish it. */
1728 /* tem gets the distance to insert or delete.
1729 endmatch is how many characters we save by doing so.
1732 tem
= (nlen
- nsp
) - (olen
- osp
);
1734 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1737 /* nsp - osp is the distance to insert or delete.
1738 If that is nonzero, begmatch is known to be nonzero also.
1739 begmatch + endmatch is how much we save by doing the ins/del.
1743 && (!char_ins_del_ok
1744 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1748 osp
= nsp
= min (osp
, nsp
);
1751 /* Now go through the line, inserting, writing and
1752 deleting as appropriate. */
1756 cursor_to (vpos
, nsp
);
1757 delete_glyphs (osp
- nsp
);
1761 /* If going to delete chars later in line
1762 and insert earlier in the line,
1763 must delete first to avoid losing data in the insert */
1764 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1766 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1767 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1768 olen
= nlen
- (nsp
- osp
);
1770 cursor_to (vpos
, osp
);
1771 insert_glyphs ((char *)0, nsp
- osp
);
1775 tem
= nsp
+ begmatch
+ endmatch
;
1776 if (nlen
!= tem
|| olen
!= tem
)
1778 cursor_to (vpos
, nsp
+ begmatch
);
1779 if (!endmatch
|| nlen
== olen
)
1781 /* If new text being written reaches right margin,
1782 there is no need to do clear-to-eol at the end.
1783 (and it would not be safe, since cursor is not
1784 going to be "at the margin" after the text is done) */
1785 if (nlen
== FRAME_WIDTH (frame
))
1787 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1791 /* the following code loses disastrously if tem == nlen.
1792 Rather than trying to fix that case, I am trying the simpler
1793 solution found above. */
1795 /* If the text reaches to the right margin,
1796 it will lose one way or another (depending on AutoWrap)
1797 to clear to end of line after outputting all the text.
1798 So pause with one character to go and clear the line then. */
1799 if (nlen
== FRAME_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1801 /* endmatch must be zero, and tem must equal nsp + begmatch */
1802 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1803 clear_end_of_line (olen
);
1804 olen
= 0; /* Don't let it be cleared again later */
1805 write_glyphs (nbody
+ nlen
- 1, 1);
1808 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1809 #endif /* OBSOLETE */
1812 else if (nlen
> olen
)
1814 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1815 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1818 else if (olen
> nlen
)
1820 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1821 delete_glyphs (olen
- nlen
);
1827 /* If any unerased characters remain after the new line, erase them. */
1830 cursor_to (vpos
, nlen
);
1831 clear_end_of_line (olen
);
1834 /* Exchange contents between current_frame and new_frame. */
1835 temp
= desired_frame
->glyphs
[vpos
];
1836 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1837 current_frame
->glyphs
[vpos
] = temp
;
1839 /* Exchange charstarts between current_frame and new_frame. */
1840 temp1
= desired_frame
->charstarts
[vpos
];
1841 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1842 current_frame
->charstarts
[vpos
] = temp1
;
1845 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1846 1, 1, "FOpen termscript file: ",
1847 "Start writing all terminal output to FILE as well as the terminal.\n\
1848 FILE = nil means just close any termscript file currently open.")
1852 if (termscript
!= 0) fclose (termscript
);
1857 file
= Fexpand_file_name (file
, Qnil
);
1858 termscript
= fopen (XSTRING (file
)->data
, "w");
1859 if (termscript
== 0)
1860 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1868 window_change_signal ()
1872 int old_errno
= errno
;
1874 get_frame_size (&width
, &height
);
1876 /* The frame size change obviously applies to a termcap-controlled
1877 frame. Find such a frame in the list, and assume it's the only
1878 one (since the redisplay code always writes to stdout, not a
1879 FILE * specified in the frame structure). Record the new size,
1880 but don't reallocate the data structures now. Let that be done
1881 later outside of the signal handler. */
1884 Lisp_Object tail
, frame
;
1886 FOR_EACH_FRAME (tail
, frame
)
1888 if (FRAME_TERMCAP_P (XFRAME (frame
)))
1890 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
1896 signal (SIGWINCH
, window_change_signal
);
1899 #endif /* SIGWINCH */
1902 /* Do any change in frame size that was requested by a signal. */
1904 do_pending_window_change ()
1906 /* If window_change_signal should have run before, run it now. */
1907 while (delayed_size_change
)
1909 Lisp_Object tail
, frame
;
1911 delayed_size_change
= 0;
1913 FOR_EACH_FRAME (tail
, frame
)
1915 FRAME_PTR f
= XFRAME (frame
);
1917 int height
= FRAME_NEW_HEIGHT (f
);
1918 int width
= FRAME_NEW_WIDTH (f
);
1920 if (height
!= 0 || width
!= 0)
1921 change_frame_size (f
, height
, width
, 0, 0);
1927 /* Change the frame height and/or width. Values may be given as zero to
1928 indicate no change is to take place.
1930 If DELAY is non-zero, then assume we're being called from a signal
1931 handler, and queue the change for later - perhaps the next
1932 redisplay. Since this tries to resize windows, we can't call it
1933 from a signal handler. */
1935 change_frame_size (frame
, newheight
, newwidth
, pretend
, delay
)
1936 register FRAME_PTR frame
;
1937 int newheight
, newwidth
, pretend
;
1939 /* If we can't deal with the change now, queue it for later. */
1942 FRAME_NEW_HEIGHT (frame
) = newheight
;
1943 FRAME_NEW_WIDTH (frame
) = newwidth
;
1944 delayed_size_change
= 1;
1948 /* This size-change overrides any pending one for this frame. */
1949 FRAME_NEW_HEIGHT (frame
) = 0;
1950 FRAME_NEW_WIDTH (frame
) = 0;
1952 /* If an argument is zero, set it to the current value. */
1953 newheight
|| (newheight
= FRAME_HEIGHT (frame
));
1954 newwidth
|| (newwidth
= FRAME_WIDTH (frame
));
1956 /* Round up to the smallest acceptable size. */
1957 check_frame_size (frame
, &newheight
, &newwidth
);
1959 /* If we're not changing the frame size, quit now. */
1960 if (newheight
== FRAME_HEIGHT (frame
)
1961 && newwidth
== FRAME_WIDTH (frame
))
1964 if (newheight
!= FRAME_HEIGHT (frame
))
1966 if (FRAME_HAS_MINIBUF_P (frame
)
1967 && ! FRAME_MINIBUF_ONLY_P (frame
))
1969 /* Frame has both root and minibuffer. */
1970 set_window_height (FRAME_ROOT_WINDOW (frame
),
1971 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
1972 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
)
1974 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
1977 /* Frame has just one top-level window. */
1978 set_window_height (FRAME_ROOT_WINDOW (frame
),
1979 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
1981 if (FRAME_TERMCAP_P (frame
) && !pretend
)
1982 FrameRows
= newheight
;
1985 if (frame
->output_method
== output_termcap
)
1987 frame_height
= newheight
;
1989 FrameRows
= newheight
;
1994 if (newwidth
!= FRAME_WIDTH (frame
))
1996 set_window_width (FRAME_ROOT_WINDOW (frame
), newwidth
, 0);
1997 if (FRAME_HAS_MINIBUF_P (frame
))
1998 set_window_width (FRAME_MINIBUF_WINDOW (frame
), newwidth
, 0);
2000 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2001 FrameCols
= newwidth
;
2003 if (frame
->output_method
== output_termcap
)
2005 frame_width
= newwidth
;
2007 FrameCols
= newwidth
;
2012 FRAME_HEIGHT (frame
) = newheight
;
2013 FRAME_WIDTH (frame
) = newwidth
;
2015 remake_frame_glyphs (frame
);
2016 calculate_costs (frame
);
2019 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
2020 Ssend_string_to_terminal
, 1, 1, 0,
2021 "Send STRING to the terminal without alteration.\n\
2022 Control characters in STRING will have terminal-dependent effects.")
2026 CHECK_STRING (str
, 0);
2027 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
2031 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
2032 fflush (termscript
);
2037 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
2038 "Beep, or flash the screen.\n\
2039 Also, unless an argument is given,\n\
2040 terminate any keyboard macro currently executing.")
2062 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
2063 error ("Keyboard macro terminated by a command ringing the bell");
2069 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
2070 "Pause, without updating display, for SECONDS seconds.\n\
2071 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2072 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2073 additional wait period, in milliseconds; this may be useful if your\n\
2074 Emacs was built without floating point support.\n\
2075 \(Not all operating systems support waiting for a fraction of a second.)")
2076 (seconds
, milliseconds
)
2077 Lisp_Object seconds
, milliseconds
;
2081 if (NILP (milliseconds
))
2082 XSET (milliseconds
, Lisp_Int
, 0);
2084 CHECK_NUMBER (milliseconds
, 1);
2085 usec
= XINT (milliseconds
) * 1000;
2087 #ifdef LISP_FLOAT_TYPE
2089 double duration
= extract_float (seconds
);
2090 sec
= (int) duration
;
2091 usec
+= (duration
- sec
) * 1000000;
2094 CHECK_NUMBER (seconds
, 0);
2095 sec
= XINT (seconds
);
2098 #ifndef EMACS_HAS_USECS
2099 if (sec
== 0 && usec
!= 0)
2100 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2103 /* Assure that 0 <= usec < 1000000. */
2106 /* We can't rely on the rounding being correct if user is negative. */
2107 if (-1000000 < usec
)
2108 sec
--, usec
+= 1000000;
2110 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2113 sec
+= usec
/ 1000000, usec
%= 1000000;
2121 XFASTINT (zero
) = 0;
2122 wait_reading_process_input (sec
, usec
, zero
, 0);
2125 /* We should always have wait_reading_process_input; we have a dummy
2126 implementation for systems which don't support subprocesses. */
2128 /* No wait_reading_process_input */
2135 /* The reason this is done this way
2136 (rather than defined (H_S) && defined (H_T))
2137 is because the VMS preprocessor doesn't grok `defined' */
2139 EMACS_GET_TIME (end_time
);
2140 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2141 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2145 EMACS_GET_TIME (timeout
);
2146 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2147 if (EMACS_TIME_NEG_P (timeout
)
2148 || !select (1, 0, 0, 0, &timeout
))
2151 #else /* not HAVE_SELECT */
2153 #endif /* HAVE_SELECT */
2154 #endif /* not VMS */
2157 #endif /* no subprocesses */
2162 /* This is just like wait_reading_process_input, except that
2163 it does the redisplay.
2165 It's also much like Fsit_for, except that it can be used for
2166 waiting for input as well. One differnce is that sit_for
2167 does not call prepare_menu_bars; Fsit_for does call that. */
2170 sit_for (sec
, usec
, reading
, display
)
2171 int sec
, usec
, reading
, display
;
2173 Lisp_Object read_kbd
;
2175 if (detect_input_pending ())
2179 redisplay_preserve_echo_area ();
2181 if (sec
== 0 && usec
== 0)
2188 XSET (read_kbd
, Lisp_Int
, reading
? -1 : 1);
2189 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2192 /* wait_reading_process_input should always be available now; it is
2193 simulated in a simple way on systems that don't support
2196 /* No wait_reading_process_input available. */
2202 input_wait_timeout (XINT (arg
));
2204 #ifndef HAVE_TIMEVAL
2206 select (1, &waitchannels
, 0, 0, &timeout_sec
);
2207 #else /* HAVE_TIMEVAL */
2208 timeout
.tv_sec
= sec
;
2209 timeout
.tv_usec
= usec
;
2210 select (1, &waitchannels
, 0, 0, &timeout
);
2211 #endif /* HAVE_TIMEVAL */
2212 #endif /* not VMS */
2217 return detect_input_pending () ? Qnil
: Qt
;
2220 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2221 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2222 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2223 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2224 additional wait period, in milliseconds; this may be useful if your\n\
2225 Emacs was built without floating point support.\n\
2226 \(Not all operating systems support waiting for a fraction of a second.)\n\
2227 Optional third arg non-nil means don't redisplay, just wait for input.\n\
2228 Redisplay is preempted as always if input arrives, and does not happen\n\
2229 if input is available before it starts.\n\
2230 Value is t if waited the full time with no input arriving.")
2231 (seconds
, milliseconds
, nodisp
)
2232 Lisp_Object seconds
, milliseconds
, nodisp
;
2236 if (NILP (milliseconds
))
2237 XSET (milliseconds
, Lisp_Int
, 0);
2239 CHECK_NUMBER (milliseconds
, 1);
2240 usec
= XINT (milliseconds
) * 1000;
2242 #ifdef LISP_FLOAT_TYPE
2244 double duration
= extract_float (seconds
);
2245 sec
= (int) duration
;
2246 usec
+= (duration
- sec
) * 1000000;
2249 CHECK_NUMBER (seconds
, 0);
2250 sec
= XINT (seconds
);
2253 #ifndef EMACS_HAS_USECS
2254 if (usec
!= 0 && sec
== 0)
2255 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2259 prepare_menu_bars ();
2260 return sit_for (sec
, usec
, 0, NILP (nodisp
));
2263 char *terminal_type
;
2265 /* Initialization done when Emacs fork is started, before doing stty. */
2266 /* Determine terminal type and set terminal_driver */
2267 /* Then invoke its decoding routine to set up variables
2268 in the terminal package */
2272 #ifdef HAVE_X_WINDOWS
2273 extern int display_arg
;
2278 cursor_in_echo_area
= 0;
2279 terminal_type
= (char *) 0;
2281 /* Now is the time to initialize this; it's used by init_sys_modes
2283 Vwindow_system
= Qnil
;
2285 /* If the user wants to use a window system, we shouldn't bother
2286 initializing the terminal. This is especially important when the
2287 terminal is so dumb that emacs gives up before and doesn't bother
2288 using the window system.
2290 If the DISPLAY environment variable is set, try to use X, and die
2291 with an error message if that doesn't work. */
2293 #ifdef HAVE_X_WINDOWS
2297 display_arg
= (getenv ("DECW$DISPLAY") != 0);
2299 display_arg
= (getenv ("DISPLAY") != 0);
2303 if (!inhibit_window_system
&& display_arg
)
2305 Vwindow_system
= intern ("x");
2307 Vwindow_system_version
= make_number (11);
2309 Vwindow_system_version
= make_number (10);
2313 #endif /* HAVE_X_WINDOWS */
2315 /* If no window system has been specified, try to use the terminal. */
2318 fprintf (stderr
, "emacs: standard input is not a tty\n");
2322 /* Look at the TERM variable */
2323 terminal_type
= (char *) getenv ("TERM");
2327 fprintf (stderr
, "Please specify your terminal type.\n\
2328 For types defined in VMS, use set term /device=TYPE.\n\
2329 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2330 \(The quotation marks are necessary since terminal types are lower case.)\n");
2332 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2338 /* VMS DCL tends to upcase things, so downcase term type.
2339 Hardly any uppercase letters in terminal types; should be none. */
2341 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2344 strcpy (new, terminal_type
);
2346 for (p
= new; *p
; p
++)
2350 terminal_type
= new;
2354 term_init (terminal_type
);
2356 remake_frame_glyphs (selected_frame
);
2357 calculate_costs (selected_frame
);
2359 /* X and Y coordinates of the cursor between updates. */
2360 FRAME_CURSOR_X (selected_frame
) = 0;
2361 FRAME_CURSOR_Y (selected_frame
) = 0;
2366 #endif /* CANNOT_DUMP */
2367 signal (SIGWINCH
, window_change_signal
);
2368 #endif /* SIGWINCH */
2374 defsubr (&Sredraw_frame
);
2376 defsubr (&Sredraw_display
);
2377 defsubr (&Sopen_termscript
);
2379 defsubr (&Ssit_for
);
2380 defsubr (&Ssleep_for
);
2381 defsubr (&Ssend_string_to_terminal
);
2383 DEFVAR_INT ("baud-rate", &baud_rate
,
2384 "The output baud rate of the terminal.\n\
2385 On most systems, changing this value will affect the amount of padding\n\
2386 and the other strategic decisions made during redisplay.");
2387 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2388 "*Non-nil means invert the entire frame display.\n\
2389 This means everything is in inverse video which otherwise would not be.");
2390 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2391 "*Non-nil means try to flash the frame to represent a bell.");
2392 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2393 "*Non-nil means no need to redraw entire frame after suspending.\n\
2394 A non-nil value is useful if the terminal can automatically preserve\n\
2395 Emacs's frame display when you reenter Emacs.\n\
2396 It is up to you to set this variable if your terminal can do that.");
2397 DEFVAR_LISP ("window-system", &Vwindow_system
,
2398 "A symbol naming the window-system under which Emacs is running\n\
2399 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2400 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2401 "The version number of the window system in use.\n\
2402 For X windows, this is 10 or 11.");
2403 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2404 "Non-nil means put cursor in minibuffer, at end of any message there.");
2405 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2406 "Table defining how to output a glyph code to the frame.\n\
2407 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2408 Each element can be:\n\
2409 integer: a glyph code which this glyph is an alias for.\n\
2410 string: output this glyph using that string (not impl. in X windows).\n\
2411 nil: this glyph mod 256 is char code to output,\n\
2412 and this glyph / 256 is face code for X windows (see `x-set-face').");
2413 Vglyph_table
= Qnil
;
2415 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2416 "Display table to use for buffers that specify none.\n\
2417 See `buffer-display-table' for more information.");
2418 Vstandard_display_table
= Qnil
;
2420 /* Initialize `window-system', unless init_display already decided it. */
2425 Vwindow_system
= Qnil
;
2426 Vwindow_system_version
= Qnil
;