1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 1997
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
33 #include "termhooks.h"
34 /* cm.h must come after dispextern.h on Windows. */
35 #include "dispextern.h"
44 #include "intervals.h"
45 #include "blockinput.h"
47 /* I don't know why DEC Alpha OSF1 fail to compile this file if we
48 include the following file. */
49 /* #include "systty.h" */
50 #include "syssignal.h"
54 #endif /* HAVE_X_WINDOWS */
58 #endif /* HAVE_NTGUI */
60 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
65 #define max(a, b) ((a) > (b) ? (a) : (b))
66 #define min(a, b) ((a) < (b) ? (a) : (b))
68 /* Get number of chars of output now in the buffer of a stdio stream.
69 This ought to be built in in stdio, but it isn't.
70 Some s- files override this because their stdio internals differ. */
71 #ifdef __GNU_LIBRARY__
72 /* The s- file might have overridden the definition with one that works for
73 the system's C library. But we are using the GNU C library, so this is
74 the right definition for every system. */
75 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
76 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
78 #undef PENDING_OUTPUT_COUNT
79 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
81 #else /* not __GNU_LIBRARY__ */
82 #ifndef PENDING_OUTPUT_COUNT
83 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
87 static void change_frame_size_1 ();
89 /* Nonzero upon entry to redisplay means do not assume anything about
90 current contents of actual terminal frame; clear and redraw it. */
94 /* Nonzero means last display completed. Zero means it was preempted. */
96 int display_completed
;
98 /* Lisp variable visible-bell; enables use of screen-flash
99 instead of audible bell. */
103 /* Invert the color of the whole frame, at a low level. */
107 /* Line speed of the terminal. */
111 /* nil or a symbol naming the window system under which emacs is
112 running ('x is the only current possibility). */
114 Lisp_Object Vwindow_system
;
116 /* Version number of X windows: 10, 11 or nil. */
117 Lisp_Object Vwindow_system_version
;
119 /* Vector of glyph definitions. Indexed by glyph number,
120 the contents are a string which is how to output the glyph.
122 If Vglyph_table is nil, a glyph is output by using its low 8 bits
123 as a character code. */
125 Lisp_Object Vglyph_table
;
127 /* Display table to use for vectors that don't specify their own. */
129 Lisp_Object Vstandard_display_table
;
131 /* Nonzero means reading single-character input with prompt
132 so put cursor on minibuffer after the prompt.
133 positive means at end of text in echo area;
134 negative means at beginning of line. */
135 int cursor_in_echo_area
;
137 Lisp_Object Qdisplay_table
;
139 /* The currently selected frame.
140 In a single-frame version, this variable always holds the address of
143 FRAME_PTR selected_frame
;
145 /* A frame which is not just a minibuffer, or 0 if there are no such
146 frames. This is usually the most recent such frame that was
147 selected. In a single-frame version, this variable always holds
148 the address of the_only_frame. */
149 FRAME_PTR last_nonminibuf_frame
;
151 /* This is a vector, made larger whenever it isn't large enough,
152 which is used inside `update_frame' to hold the old contents
153 of the FRAME_PHYS_LINES of the frame being updated. */
154 struct frame_glyphs
**ophys_lines
;
155 /* Length of vector currently allocated. */
156 int ophys_lines_length
;
158 FILE *termscript
; /* Stdio stream being used for copy of all output. */
160 struct cm Wcm
; /* Structure for info on cursor positioning */
162 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
164 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
165 "Clear frame FRAME and output again what is supposed to appear on it.")
171 CHECK_LIVE_FRAME (frame
, 0);
174 if (FRAME_MSDOS_P (f
))
175 set_terminal_modes ();
177 clear_frame_records (f
);
180 windows_or_buffers_changed
++;
181 /* Mark all windows as INaccurate,
182 so that every window will have its redisplay done. */
183 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
192 XSETFRAME (frame
, f
);
193 Fredraw_frame (frame
);
196 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
197 "Clear and redisplay all visible frames.")
200 Lisp_Object tail
, frame
;
202 FOR_EACH_FRAME (tail
, frame
)
203 if (FRAME_VISIBLE_P (XFRAME (frame
)))
204 Fredraw_frame (frame
);
209 /* This is used when frame_garbaged is set.
210 Redraw the individual frames marked as garbaged. */
213 redraw_garbaged_frames ()
215 Lisp_Object tail
, frame
;
217 FOR_EACH_FRAME (tail
, frame
)
218 if (FRAME_VISIBLE_P (XFRAME (frame
))
219 && FRAME_GARBAGED_P (XFRAME (frame
)))
220 Fredraw_frame (frame
);
224 static struct frame_glyphs
*
225 make_frame_glyphs (frame
, empty
)
226 register FRAME_PTR frame
;
230 register width
= FRAME_WINDOW_WIDTH (frame
);
231 register height
= FRAME_HEIGHT (frame
);
232 register struct frame_glyphs
*new
233 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
235 SET_GLYPHS_FRAME (new, frame
);
236 new->height
= height
;
238 new->used
= (int *) xmalloc (height
* sizeof (int));
239 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
240 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
241 new->highlight
= (char *) xmalloc (height
* sizeof (char));
242 new->enable
= (char *) xmalloc (height
* sizeof (char));
243 bzero (new->enable
, height
* sizeof (char));
244 new->bufp
= (int *) xmalloc (height
* sizeof (int));
246 #ifdef HAVE_WINDOW_SYSTEM
247 if (FRAME_WINDOW_P (frame
))
249 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
250 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
251 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
252 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
253 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
255 #endif /* HAVE_WINDOW_SYSTEM */
259 /* Make the buffer used by decode_mode_spec. This buffer is also
260 used as temporary storage when updating the frame. See scroll.c. */
261 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
262 unsigned int total_charstarts
= (width
+ 2) * sizeof (int);
264 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
265 bzero (new->total_contents
, total_glyphs
);
267 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
268 bzero (new->total_charstarts
, total_charstarts
);
272 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
274 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
275 bzero (new->total_contents
, total_glyphs
);
276 for (i
= 0; i
< height
; i
++)
277 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
279 if (!FRAME_TERMCAP_P (frame
))
281 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
283 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
284 bzero (new->total_charstarts
, total_charstarts
);
285 for (i
= 0; i
< height
; i
++)
286 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
290 /* Without a window system, we don't really need charstarts.
291 So use a small amount of space to make enough data structure
292 to prevent crashes in display_text_line. */
293 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
294 for (i
= 0; i
< height
; i
++)
295 new->charstarts
[i
] = new->total_charstarts
;
303 free_frame_glyphs (frame
, glyphs
)
305 struct frame_glyphs
*glyphs
;
307 if (glyphs
->total_contents
)
308 xfree (glyphs
->total_contents
);
309 if (glyphs
->total_charstarts
)
310 xfree (glyphs
->total_charstarts
);
312 xfree (glyphs
->used
);
313 xfree (glyphs
->glyphs
);
314 xfree (glyphs
->highlight
);
315 xfree (glyphs
->enable
);
316 xfree (glyphs
->bufp
);
317 if (glyphs
->charstarts
)
318 xfree (glyphs
->charstarts
);
320 #ifdef HAVE_WINDOW_SYSTEM
321 if (FRAME_WINDOW_P (frame
))
323 xfree (glyphs
->top_left_x
);
324 xfree (glyphs
->top_left_y
);
325 xfree (glyphs
->pix_width
);
326 xfree (glyphs
->pix_height
);
327 xfree (glyphs
->max_ascent
);
329 #endif /* HAVE_WINDOW_SYSTEM */
335 remake_frame_glyphs (frame
)
338 if (FRAME_CURRENT_GLYPHS (frame
))
339 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
340 if (FRAME_DESIRED_GLYPHS (frame
))
341 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
342 if (FRAME_TEMP_GLYPHS (frame
))
343 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
345 if (FRAME_MESSAGE_BUF (frame
))
347 /* Reallocate the frame's message buffer; remember that
348 echo_area_glyphs may be pointing here. */
349 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
351 FRAME_MESSAGE_BUF (frame
)
352 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
353 FRAME_MESSAGE_BUF_SIZE (frame
) + 1);
355 if (echo_area_glyphs
== old_message_buf
)
356 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
357 if (previous_echo_glyphs
== old_message_buf
)
358 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
361 FRAME_MESSAGE_BUF (frame
)
362 = (char *) xmalloc (FRAME_MESSAGE_BUF_SIZE (frame
) + 1);
364 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
365 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
366 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
367 if (FRAME_WINDOW_P (frame
) || frame
== selected_frame
)
368 SET_FRAME_GARBAGED (frame
);
371 /* Return the hash code of contents of line VPOS in frame-matrix M. */
374 line_hash_code (m
, vpos
)
375 register struct frame_glyphs
*m
;
378 register GLYPH
*body
, *end
;
381 if (!m
->enable
[vpos
])
384 /* Give all highlighted lines the same hash code
385 so as to encourage scrolling to leave them in place. */
386 if (m
->highlight
[vpos
])
389 body
= m
->glyphs
[vpos
];
391 if (must_write_spaces
)
398 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
407 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
415 /* Return number of characters in line in M at vpos VPOS,
416 except don't count leading and trailing spaces
417 unless the terminal requires those to be explicitly output. */
420 line_draw_cost (m
, vpos
)
421 struct frame_glyphs
*m
;
424 register GLYPH
*beg
= m
->glyphs
[vpos
];
425 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
427 register int tlen
= GLYPH_TABLE_LENGTH
;
428 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
430 /* Ignore trailing and leading spaces if we can. */
431 if (!must_write_spaces
)
433 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
436 return (0); /* All blank line. */
438 while (*beg
== SPACEGLYPH
)
442 /* If we don't have a glyph-table, each glyph is one character,
443 so return the number of glyphs. */
447 /* Otherwise, scan the glyphs and accumulate their total size in I. */
449 while ((beg
<= end
) && *beg
)
451 register GLYPH g
= *beg
++;
453 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
456 i
+= GLYPH_LENGTH (tbase
, g
);
461 /* The functions on this page are the interface from xdisp.c to redisplay.
463 The only other interface into redisplay is through setting
464 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
465 and SET_FRAME_GARBAGED (frame). */
467 /* cancel_line eliminates any request to display a line at position `vpos' */
469 cancel_line (vpos
, frame
)
471 register FRAME_PTR frame
;
473 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
476 clear_frame_records (frame
)
477 register FRAME_PTR frame
;
479 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
482 /* Clear out all display lines for a coming redisplay. */
485 init_desired_glyphs (frame
)
486 register FRAME_PTR frame
;
488 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
490 int height
= FRAME_HEIGHT (frame
);
492 for (vpos
= 0; vpos
< height
; vpos
++)
493 desired_glyphs
->enable
[vpos
] = 0;
496 /* Prepare to display on line VPOS starting at HPOS within it. */
499 get_display_line (frame
, vpos
, hpos
)
500 register FRAME_PTR frame
;
504 register struct frame_glyphs
*glyphs
;
505 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
511 if (! desired_glyphs
->enable
[vpos
])
513 desired_glyphs
->used
[vpos
] = 0;
514 desired_glyphs
->highlight
[vpos
] = 0;
515 desired_glyphs
->enable
[vpos
] = 1;
518 if (hpos
> desired_glyphs
->used
[vpos
])
520 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
521 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
523 desired_glyphs
->used
[vpos
] = hpos
;
529 /* Like bcopy except never gets confused by overlap. */
532 safe_bcopy (from
, to
, size
)
536 if (size
<= 0 || from
== to
)
539 /* If the source and destination don't overlap, then bcopy can
540 handle it. If they do overlap, but the destination is lower in
541 memory than the source, we'll assume bcopy can handle that. */
542 if (to
< from
|| from
+ size
<= to
)
543 bcopy (from
, to
, size
);
545 /* Otherwise, we'll copy from the end. */
548 register char *endf
= from
+ size
;
549 register char *endt
= to
+ size
;
551 /* If TO - FROM is large, then we should break the copy into
552 nonoverlapping chunks of TO - FROM bytes each. However, if
553 TO - FROM is small, then the bcopy function call overhead
554 makes this not worth it. The crossover point could be about
555 anywhere. Since I don't think the obvious copy loop is too
556 bad, I'm trying to err in its favor. */
561 while (endf
!= from
);
573 bcopy (endf
, endt
, to
- from
);
576 /* If SIZE wasn't a multiple of TO - FROM, there will be a
577 little left over. The amount left over is
578 (endt + (to - from)) - to, which is endt - from. */
579 bcopy (from
, to
, endt
- from
);
584 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
585 DISTANCE may be negative. */
588 rotate_vector (vector
, size
, distance
)
593 char *temp
= (char *) alloca (size
);
598 bcopy (vector
, temp
+ distance
, size
- distance
);
599 bcopy (vector
+ size
- distance
, temp
, distance
);
600 bcopy (temp
, vector
, size
);
603 /* Scroll lines from vpos FROM up to but not including vpos END
604 down by AMOUNT lines (AMOUNT may be negative).
605 Returns nonzero if done, zero if terminal cannot scroll them. */
608 scroll_frame_lines (frame
, from
, end
, amount
, newpos
)
609 register FRAME_PTR frame
;
610 int from
, end
, amount
, newpos
;
613 register struct frame_glyphs
*current_frame
614 = FRAME_CURRENT_GLYPHS (frame
);
616 int width
= FRAME_WINDOW_WIDTH (frame
);
618 if (!line_ins_del_ok
)
626 update_begin (frame
);
627 set_terminal_window (end
+ amount
);
628 if (!scroll_region_ok
)
629 ins_del_lines (end
, -amount
);
630 ins_del_lines (from
, amount
);
631 set_terminal_window (0);
633 rotate_vector (current_frame
->glyphs
+ from
,
634 sizeof (GLYPH
*) * (end
+ amount
- from
),
635 amount
* sizeof (GLYPH
*));
637 rotate_vector (current_frame
->charstarts
+ from
,
638 sizeof (int *) * (end
+ amount
- from
),
639 amount
* sizeof (int *));
641 safe_bcopy (current_frame
->used
+ from
,
642 current_frame
->used
+ from
+ amount
,
643 (end
- from
) * sizeof current_frame
->used
[0]);
645 safe_bcopy (current_frame
->highlight
+ from
,
646 current_frame
->highlight
+ from
+ amount
,
647 (end
- from
) * sizeof current_frame
->highlight
[0]);
649 safe_bcopy (current_frame
->enable
+ from
,
650 current_frame
->enable
+ from
+ amount
,
651 (end
- from
) * sizeof current_frame
->enable
[0]);
653 /* Adjust the lines by an amount
654 that puts the first of them at NEWPOS. */
655 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
657 /* Offset each char position in the charstarts lines we moved
659 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
661 int *line
= current_frame
->charstarts
[i
];
663 for (col
= 0; col
< width
; col
++)
665 line
[col
] += pos_adjust
;
667 for (i
= from
; i
< from
+ amount
; i
++)
669 int *line
= current_frame
->charstarts
[i
];
672 for (col
= 0; col
< width
; col
++)
676 /* Mark the lines made empty by scrolling as enabled, empty and
678 bzero (current_frame
->used
+ from
,
679 amount
* sizeof current_frame
->used
[0]);
680 bzero (current_frame
->highlight
+ from
,
681 amount
* sizeof current_frame
->highlight
[0]);
682 for (i
= from
; i
< from
+ amount
; i
++)
684 current_frame
->glyphs
[i
][0] = '\0';
685 current_frame
->charstarts
[i
][0] = -1;
686 current_frame
->enable
[i
] = 1;
689 safe_bcopy (current_frame
->bufp
+ from
,
690 current_frame
->bufp
+ from
+ amount
,
691 (end
- from
) * sizeof current_frame
->bufp
[0]);
693 #ifdef HAVE_WINDOW_SYSTEM
694 if (FRAME_WINDOW_P (frame
))
696 safe_bcopy (current_frame
->top_left_x
+ from
,
697 current_frame
->top_left_x
+ from
+ amount
,
698 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
700 safe_bcopy (current_frame
->top_left_y
+ from
,
701 current_frame
->top_left_y
+ from
+ amount
,
702 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
704 safe_bcopy (current_frame
->pix_width
+ from
,
705 current_frame
->pix_width
+ from
+ amount
,
706 (end
- from
) * sizeof current_frame
->pix_width
[0]);
708 safe_bcopy (current_frame
->pix_height
+ from
,
709 current_frame
->pix_height
+ from
+ amount
,
710 (end
- from
) * sizeof current_frame
->pix_height
[0]);
712 safe_bcopy (current_frame
->max_ascent
+ from
,
713 current_frame
->max_ascent
+ from
+ amount
,
714 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
716 #endif /* HAVE_WINDOW_SYSTEM */
722 update_begin (frame
);
723 set_terminal_window (end
);
724 ins_del_lines (from
+ amount
, amount
);
725 if (!scroll_region_ok
)
726 ins_del_lines (end
+ amount
, -amount
);
727 set_terminal_window (0);
729 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
730 sizeof (GLYPH
*) * (end
- from
- amount
),
731 amount
* sizeof (GLYPH
*));
733 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
734 sizeof (int *) * (end
- from
- amount
),
735 amount
* sizeof (int *));
737 safe_bcopy (current_frame
->used
+ from
,
738 current_frame
->used
+ from
+ amount
,
739 (end
- from
) * sizeof current_frame
->used
[0]);
741 safe_bcopy (current_frame
->highlight
+ from
,
742 current_frame
->highlight
+ from
+ amount
,
743 (end
- from
) * sizeof current_frame
->highlight
[0]);
745 safe_bcopy (current_frame
->enable
+ from
,
746 current_frame
->enable
+ from
+ amount
,
747 (end
- from
) * sizeof current_frame
->enable
[0]);
749 /* Adjust the lines by an amount
750 that puts the first of them at NEWPOS. */
751 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
753 /* Offset each char position in the charstarts lines we moved
755 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
757 int *line
= current_frame
->charstarts
[i
];
759 for (col
= 0; col
< width
; col
++)
761 line
[col
] += pos_adjust
;
763 for (i
= end
+ amount
; i
< end
; i
++)
765 int *line
= current_frame
->charstarts
[i
];
768 for (col
= 0; col
< width
; col
++)
772 /* Mark the lines made empty by scrolling as enabled, empty and
774 bzero (current_frame
->used
+ end
+ amount
,
775 - amount
* sizeof current_frame
->used
[0]);
776 bzero (current_frame
->highlight
+ end
+ amount
,
777 - amount
* sizeof current_frame
->highlight
[0]);
778 for (i
= end
+ amount
; i
< end
; i
++)
780 current_frame
->glyphs
[i
][0] = '\0';
781 current_frame
->charstarts
[i
][0] = 0;
782 current_frame
->enable
[i
] = 1;
785 safe_bcopy (current_frame
->bufp
+ from
,
786 current_frame
->bufp
+ from
+ amount
,
787 (end
- from
) * sizeof current_frame
->bufp
[0]);
789 #ifdef HAVE_WINDOW_SYSTEM
790 if (FRAME_WINDOW_P (frame
))
792 safe_bcopy (current_frame
->top_left_x
+ from
,
793 current_frame
->top_left_x
+ from
+ amount
,
794 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
796 safe_bcopy (current_frame
->top_left_y
+ from
,
797 current_frame
->top_left_y
+ from
+ amount
,
798 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
800 safe_bcopy (current_frame
->pix_width
+ from
,
801 current_frame
->pix_width
+ from
+ amount
,
802 (end
- from
) * sizeof current_frame
->pix_width
[0]);
804 safe_bcopy (current_frame
->pix_height
+ from
,
805 current_frame
->pix_height
+ from
+ amount
,
806 (end
- from
) * sizeof current_frame
->pix_height
[0]);
808 safe_bcopy (current_frame
->max_ascent
+ from
,
809 current_frame
->max_ascent
+ from
+ amount
,
810 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
812 #endif /* HAVE_WINDOW_SYSTEM */
819 /* After updating a window W that isn't the full frame wide,
820 copy all the columns that W does not occupy
821 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
822 so that update_frame will not change those columns. */
824 preserve_other_columns (w
)
828 register struct frame_glyphs
*current_frame
, *desired_frame
;
829 register FRAME_PTR frame
= XFRAME (w
->frame
);
830 int start
= WINDOW_LEFT_MARGIN (w
);
831 int end
= WINDOW_RIGHT_EDGE (w
);
832 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
834 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
835 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
837 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
839 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
845 bcopy (current_frame
->glyphs
[vpos
],
846 desired_frame
->glyphs
[vpos
],
847 start
* sizeof (current_frame
->glyphs
[vpos
][0]));
848 bcopy (current_frame
->charstarts
[vpos
],
849 desired_frame
->charstarts
[vpos
],
850 start
* sizeof (current_frame
->charstarts
[vpos
][0]));
851 len
= min (start
, current_frame
->used
[vpos
]);
852 if (desired_frame
->used
[vpos
] < len
)
853 desired_frame
->used
[vpos
] = len
;
855 if (current_frame
->used
[vpos
] > end
856 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
858 while (desired_frame
->used
[vpos
] < end
)
860 int used
= desired_frame
->used
[vpos
]++;
861 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
862 desired_frame
->glyphs
[vpos
][used
] = 0;
864 bcopy (current_frame
->glyphs
[vpos
] + end
,
865 desired_frame
->glyphs
[vpos
] + end
,
866 ((current_frame
->used
[vpos
] - end
)
867 * sizeof (current_frame
->glyphs
[vpos
][0])));
868 bcopy (current_frame
->charstarts
[vpos
] + end
,
869 desired_frame
->charstarts
[vpos
] + end
,
870 ((current_frame
->used
[vpos
] - end
)
871 * sizeof (current_frame
->charstarts
[vpos
][0])));
872 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
880 /* If window w does not need to be updated and isn't the full frame wide,
881 copy all the columns that w does occupy
882 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
883 so that update_frame will not change those columns.
885 Have not been able to figure out how to use this correctly. */
887 preserve_my_columns (w
)
890 register int vpos
, fin
;
891 register struct frame_glyphs
*l1
, *l2
;
892 register FRAME_PTR frame
= XFRAME (w
->frame
);
893 int start
= WINDOW_LEFT_MARGIN (w
);
894 int end
= WINDOW_RIGHT_EDGE (w
);
895 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
897 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
899 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
900 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
902 if (l2
->length
> start
&& l1
->length
< l2
->length
)
905 if (fin
> end
) fin
= end
;
906 while (l1
->length
< start
)
907 l1
->body
[l1
->length
++] = ' ';
908 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
917 /* Adjust by ADJUST the charstart values in window W
918 after vpos VPOS, which counts relative to the frame
919 (not relative to W itself). */
922 adjust_window_charstarts (w
, vpos
, adjust
)
927 int left
= WINDOW_LEFT_MARGIN (w
);
928 int top
= XFASTINT (w
->top
);
929 int right
= left
+ window_internal_width (w
);
930 int bottom
= top
+ window_internal_height (w
);
933 for (i
= vpos
+ 1; i
< bottom
; i
++)
936 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
938 for (j
= left
; j
< right
; j
++)
939 if (charstart
[j
] > 0)
940 charstart
[j
] += adjust
;
944 /* Check the charstarts values in the area of window W
945 for internal consistency. We cannot check that they are "right";
946 we can only look for something nonsensical. */
948 verify_charstarts (w
)
951 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
953 int top
= XFASTINT (w
->top
);
954 int bottom
= top
+ window_internal_height (w
);
955 int left
= WINDOW_LEFT_MARGIN (w
);
956 int right
= left
+ window_internal_width (w
);
958 int truncate
= (XINT (w
->hscroll
)
959 || (truncate_partial_width_windows
960 && !WINDOW_FULL_WIDTH_P (w
))
961 || !NILP (XBUFFER (w
->buffer
)->truncate_lines
));
963 for (i
= top
; i
< bottom
; i
++)
967 int *charstart
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[i
];
973 /* If we are truncating lines, allow a jump
974 in charstarts from one line to the next. */
975 if (charstart
[left
] < next_line
)
980 if (charstart
[left
] != next_line
)
985 for (j
= left
; j
< right
; j
++)
986 if (charstart
[j
] > 0)
988 /* Record where the next line should start. */
990 if (BUF_ZV (XBUFFER (w
->buffer
)) != last
)
992 /* If there's a newline between the two lines, count that. */
993 int endchar
= *BUF_CHAR_ADDRESS (XBUFFER (w
->buffer
), last
);
1000 /* On discovering that the redisplay for a window was no good,
1001 cancel the columns of that window, so that when the window is
1002 displayed over again get_display_line will not complain. */
1004 cancel_my_columns (w
)
1008 register struct frame_glyphs
*desired_glyphs
1009 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
1010 register int start
= WINDOW_LEFT_MARGIN (w
);
1011 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
1013 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
1014 if (desired_glyphs
->enable
[vpos
]
1015 && desired_glyphs
->used
[vpos
] >= start
)
1016 desired_glyphs
->used
[vpos
] = start
;
1019 /* These functions try to perform directly and immediately on the frame
1020 the necessary output for one change in the buffer.
1021 They may return 0 meaning nothing was done if anything is difficult,
1022 or 1 meaning the output was performed properly.
1023 They assume that the frame was up to date before the buffer
1024 change being displayed. They make various other assumptions too;
1025 see command_loop_1 where these are called. */
1028 direct_output_for_insert (g
)
1031 register FRAME_PTR frame
= selected_frame
;
1032 register struct frame_glyphs
*current_frame
1033 = FRAME_CURRENT_GLYPHS (frame
);
1035 #ifndef COMPILER_REGISTER_BUG
1037 #endif /* COMPILER_REGISTER_BUG */
1038 struct window
*w
= XWINDOW (selected_window
);
1039 #ifndef COMPILER_REGISTER_BUG
1041 #endif /* COMPILER_REGISTER_BUG */
1042 int hpos
= FRAME_CURSOR_X (frame
);
1043 #ifndef COMPILER_REGISTER_BUG
1045 #endif /* COMPILER_REGISTER_BUG */
1046 int vpos
= FRAME_CURSOR_Y (frame
);
1048 /* Give up if about to continue line. */
1049 if (hpos
>= WINDOW_LEFT_MARGIN (w
) + window_internal_width (w
) - 1
1051 /* Avoid losing if cursor is in invisible text off left margin */
1052 || (XINT (w
->hscroll
) && hpos
== WINDOW_LEFT_MARGIN (w
))
1054 /* Give up if cursor outside window (in minibuf, probably) */
1055 || cursor_in_echo_area
1056 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
1057 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
1059 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
1060 || !display_completed
1062 /* Give up if buffer appears in two places. */
1063 || buffer_shared
> 1
1065 #ifdef USE_TEXT_PROPERTIES
1066 /* Intervals have already been adjusted, point is after the
1067 character that was just inserted. */
1068 /* Give up if character is invisible. */
1069 /* Give up if character has a face property.
1070 At the moment we only lose at end of line or end of buffer
1071 and only with faces that have some background */
1072 /* Instead of wasting time, give up if character has any text properties */
1073 || ! NILP (Ftext_properties_at (make_number (PT
- 1), Qnil
))
1076 /* Give up if w is minibuffer and a message is being displayed there */
1077 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1085 if (FRAME_WINDOW_P (frame
) || FRAME_MSDOS_P (frame
))
1086 face
= compute_char_face (frame
, w
, PT
- 1, -1, -1, &dummy
, PT
, 0);
1088 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1089 current_frame
->charstarts
[vpos
][hpos
] = PT
- 1;
1090 /* Record the entry for after the newly inserted character. */
1091 current_frame
->charstarts
[vpos
][hpos
+ 1] = PT
;
1092 adjust_window_charstarts (w
, vpos
, 1);
1094 unchanged_modified
= MODIFF
;
1095 beg_unchanged
= GPT
- BEG
;
1096 XSETFASTINT (w
->last_point
, PT
);
1097 XSETFASTINT (w
->last_point_x
, hpos
+ 1);
1098 XSETFASTINT (w
->last_modified
, MODIFF
);
1099 XSETFASTINT (w
->last_overlay_modified
, OVERLAY_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
);
1120 Lisp_Object position
;
1121 int hpos
= FRAME_CURSOR_X (frame
);
1123 /* Give up if in truncated text at end of line. */
1124 /* This check is not redundant. */
1125 if (hpos
>= WINDOW_LEFT_MARGIN (w
) + window_internal_width (w
) - 1)
1128 /* Give up if the buffer's direction is reversed (i.e. right-to-left). */
1129 if (!NILP (XBUFFER(w
->buffer
)->direction_reversed
))
1132 /* Avoid losing if cursor is in invisible text off left margin
1133 or about to go off either side of window. */
1134 if ((FRAME_CURSOR_X (frame
) == WINDOW_LEFT_MARGIN (w
)
1135 && (XINT (w
->hscroll
) || n
< 0))
1137 && (FRAME_CURSOR_X (frame
) + 1
1138 >= XFASTINT (w
->left
) + window_internal_width (w
) - 1))
1139 /* BUG FIX: Added "XFASTINT (w->left)". Without this,
1140 direct_output_forward_char() always fails on "the right"
1142 || cursor_in_echo_area
)
1145 /* Can't use direct output if highlighting a region. */
1146 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1149 /* Can't use direct output at an overlay boundary; it might have
1150 before-string or after-string properties. */
1151 if (overlay_touches_p (PT
) || overlay_touches_p (PT
- n
))
1154 #ifdef USE_TEXT_PROPERTIES
1155 /* Don't use direct output next to an invisible character
1156 since we might need to do something special. */
1158 XSETFASTINT (position
, PT
);
1159 if (XFASTINT (position
) < ZV
1160 && ! NILP (Fget_char_property (position
,
1165 XSETFASTINT (position
, PT
- 1);
1166 if (XFASTINT (position
) >= BEGV
1167 && ! NILP (Fget_char_property (position
,
1173 FRAME_CURSOR_X (frame
) += n
;
1174 XSETFASTINT (w
->last_point_x
, FRAME_CURSOR_X (frame
));
1175 XSETFASTINT (w
->last_point
, PT
);
1176 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1182 static void update_line ();
1184 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1185 Value is nonzero if redisplay stopped due to pending input.
1186 FORCE nonzero means do not stop for pending input. */
1189 update_frame (f
, force
, inhibit_hairy_id
)
1192 int inhibit_hairy_id
;
1194 register struct frame_glyphs
*current_frame
;
1195 register struct frame_glyphs
*desired_frame
= 0;
1198 int preempt_count
= baud_rate
/ 2400 + 1;
1199 extern input_pending
;
1200 #ifdef HAVE_WINDOW_SYSTEM
1201 register int downto
, leftmost
;
1204 if (baud_rate
!= FRAME_COST_BAUD_RATE (f
))
1205 calculate_costs (f
);
1207 if (preempt_count
<= 0)
1210 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1212 detect_input_pending ();
1213 if (input_pending
&& !force
)
1221 if (!line_ins_del_ok
)
1222 inhibit_hairy_id
= 1;
1224 /* These are separate to avoid a possible bug in the AIX C compiler. */
1225 current_frame
= FRAME_CURRENT_GLYPHS (f
);
1226 desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1228 /* See if any of the desired lines are enabled; don't compute for
1229 i/d line if just want cursor motion. */
1230 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1231 if (desired_frame
->enable
[i
])
1234 /* Try doing i/d line, if not yet inhibited. */
1235 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1236 force
|= scrolling (f
);
1238 /* Update the individual lines as needed. Do bottom line first. */
1240 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1241 update_line (f
, FRAME_HEIGHT (f
) - 1);
1243 #ifdef HAVE_WINDOW_SYSTEM
1244 if (FRAME_WINDOW_P (f
))
1246 leftmost
= downto
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1247 if (desired_frame
->enable
[0])
1249 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1250 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1251 = PIXEL_HEIGHT (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
)
1252 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1253 current_frame
->top_left_x
[0] = leftmost
;
1254 current_frame
->top_left_y
[0] = downto
;
1257 #endif /* HAVE_WINDOW_SYSTEM */
1259 /* Now update the rest of the lines. */
1260 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1262 if (desired_frame
->enable
[i
])
1264 if (FRAME_TERMCAP_P (f
))
1266 /* Flush out every so many lines.
1267 Also flush out if likely to have more than 1k buffered
1268 otherwise. I'm told that some telnet connections get
1269 really screwed by more than 1k output at once. */
1270 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1272 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1275 if (preempt_count
== 1)
1277 #ifdef EMACS_OUTQSIZE
1278 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1279 /* Probably not a tty. Ignore the error and reset
1280 * the outq count. */
1281 outq
= PENDING_OUTPUT_COUNT (stdout
);
1284 if (baud_rate
<= outq
&& baud_rate
> 0)
1285 sleep (outq
/ baud_rate
);
1290 if ((i
- 1) % preempt_count
== 0)
1291 detect_input_pending ();
1294 #ifdef HAVE_WINDOW_SYSTEM
1295 if (FRAME_WINDOW_P (f
))
1297 current_frame
->top_left_y
[i
] = downto
;
1298 current_frame
->top_left_x
[i
] = leftmost
;
1300 #endif /* HAVE_WINDOW_SYSTEM */
1303 #ifdef HAVE_WINDOW_SYSTEM
1304 if (FRAME_WINDOW_P (f
))
1305 downto
+= current_frame
->pix_height
[i
];
1306 #endif /* HAVE_WINDOW_SYSTEM */
1308 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1310 /* Now just clean up termcap drivers and set cursor, etc. */
1313 if ((cursor_in_echo_area
1314 /* If we are showing a message instead of the minibuffer,
1315 show the cursor for the message instead of for the
1316 (now hidden) minibuffer contents. */
1317 || (EQ (minibuf_window
, selected_window
)
1318 && EQ (minibuf_window
, echo_area_window
)
1319 && echo_area_glyphs
!= 0))
1320 /* These cases apply only to the frame that contains
1321 the active minibuffer window. */
1322 && FRAME_HAS_MINIBUF_P (f
)
1323 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
1325 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1328 if (cursor_in_echo_area
< 0)
1335 /* If the minibuffer is several lines high, find the last
1336 line that has any text on it. */
1337 row
= FRAME_HEIGHT (f
);
1341 if (current_frame
->enable
[row
])
1342 col
= current_frame
->used
[row
];
1346 while (row
> top
&& col
== 0);
1348 if (col
>= FRAME_WINDOW_WIDTH (f
))
1351 if (row
< FRAME_HEIGHT (f
) - 1)
1356 cursor_to (row
, col
);
1359 cursor_to (FRAME_CURSOR_Y (f
),
1360 max (min (FRAME_CURSOR_X (f
),
1361 FRAME_WINDOW_WIDTH (f
) - 1), 0));
1367 fflush (termscript
);
1370 /* Here if output is preempted because input is detected. */
1373 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1374 display_completed
= !pause
;
1376 bzero (FRAME_DESIRED_GLYPHS (f
)->enable
, FRAME_HEIGHT (f
));
1380 /* Called when about to quit, to check for doing so
1381 at an improper time. */
1387 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1389 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1391 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1396 /* Decide what insert/delete line to do, and do it */
1398 extern void scrolling_1 ();
1403 int unchanged_at_top
, unchanged_at_bottom
;
1406 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1407 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1408 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1409 int *old_draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1411 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1412 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1413 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1415 /* Compute hash codes of all the lines.
1416 Also calculate number of changed lines,
1417 number of unchanged lines at the beginning,
1418 and number of unchanged lines at the end. */
1421 unchanged_at_top
= 0;
1422 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1423 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1425 /* Give up on this scrolling if some old lines are not enabled. */
1426 if (!current_frame
->enable
[i
])
1428 old_hash
[i
] = line_hash_code (current_frame
, i
);
1429 if (! desired_frame
->enable
[i
])
1431 /* This line cannot be redrawn, so don't let scrolling mess it. */
1432 new_hash
[i
] = old_hash
[i
];
1433 #define INFINITY 1000000 /* Taken from scroll.c */
1434 draw_cost
[i
] = INFINITY
;
1438 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1439 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1442 if (old_hash
[i
] != new_hash
[i
])
1445 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1447 else if (i
== unchanged_at_top
)
1449 old_draw_cost
[i
] = line_draw_cost (current_frame
, i
);
1452 /* If changed lines are few, don't allow preemption, don't scroll. */
1453 if (!scroll_region_ok
&& changed_lines
< baud_rate
/ 2400
1454 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1457 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1458 - unchanged_at_bottom
);
1460 if (scroll_region_ok
)
1461 free_at_end_vpos
-= unchanged_at_bottom
;
1462 else if (memory_below_frame
)
1463 free_at_end_vpos
= -1;
1465 /* If large window, fast terminal and few lines in common between
1466 current frame and desired frame, don't bother with i/d calc. */
1467 if (!scroll_region_ok
&& window_size
>= 18 && baud_rate
> 2400
1469 10 * scrolling_max_lines_saved (unchanged_at_top
,
1470 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1471 old_hash
, new_hash
, draw_cost
)))
1474 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1475 draw_cost
+ unchanged_at_top
- 1,
1476 old_draw_cost
+ unchanged_at_top
- 1,
1477 old_hash
+ unchanged_at_top
- 1,
1478 new_hash
+ unchanged_at_top
- 1,
1479 free_at_end_vpos
- unchanged_at_top
);
1484 /* Return the offset in its buffer of the character at location col, line
1485 in the given window. */
1487 buffer_posn_from_coords (window
, col
, line
)
1488 struct window
*window
;
1491 int hscroll
= XINT (window
->hscroll
);
1492 int window_left
= WINDOW_LEFT_MARGIN (window
);
1494 /* The actual width of the window is window->width less one for the
1495 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1497 int window_width
= window_internal_width (window
) - 1;
1499 int startp
= marker_position (window
->start
);
1501 /* Since compute_motion will only operate on the current buffer,
1502 we need to save the old one and restore it when we're done. */
1503 struct buffer
*old_current_buffer
= current_buffer
;
1504 struct position
*posn
;
1506 current_buffer
= XBUFFER (window
->buffer
);
1508 /* We can't get a correct result in this case,
1509 but at least prevent compute_motion from crashing. */
1513 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1514 (window->frame))->bufp to avoid scanning from the very top of
1515 the window, but it isn't maintained correctly, and I'm not even
1516 sure I will keep it. */
1517 posn
= compute_motion (startp
, 0,
1518 ((window
== XWINDOW (minibuf_window
) && startp
== BEG
1519 ? minibuf_prompt_width
: 0)
1520 + (hscroll
? 1 - hscroll
: 0)),
1523 window_width
, hscroll
, 0, window
);
1525 current_buffer
= old_current_buffer
;
1527 /* compute_motion considers frame points past the end of a line
1528 to be *after* the newline, i.e. at the start of the next line.
1529 This is reasonable, but not really what we want. So if the
1530 result is on a line below LINE, back it up one character. */
1531 if (posn
->vpos
> line
)
1532 return posn
->bufpos
- 1;
1534 return posn
->bufpos
;
1541 register GLYPH
*p
= r
;
1542 while (*p
++ == SPACEGLYPH
);
1547 count_match (str1
, str2
)
1550 register GLYPH
*p1
= str1
;
1551 register GLYPH
*p2
= str2
;
1552 while (*p1
++ == *p2
++);
1553 return p1
- str1
- 1;
1556 /* Char insertion/deletion cost vector, from term.c */
1557 extern int *char_ins_del_vector
;
1559 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))])
1562 update_line (frame
, vpos
)
1563 register FRAME_PTR frame
;
1566 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1569 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1571 register struct frame_glyphs
*current_frame
1572 = FRAME_CURRENT_GLYPHS (frame
);
1573 register struct frame_glyphs
*desired_frame
1574 = FRAME_DESIRED_GLYPHS (frame
);
1576 if (desired_frame
->highlight
[vpos
]
1577 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1579 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1580 (current_frame
->enable
[vpos
] ?
1581 current_frame
->used
[vpos
] : 0));
1582 current_frame
->enable
[vpos
] = 0;
1585 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1587 if (! current_frame
->enable
[vpos
])
1593 obody
= current_frame
->glyphs
[vpos
];
1594 olen
= current_frame
->used
[vpos
];
1595 if (! current_frame
->highlight
[vpos
])
1597 if (!must_write_spaces
)
1598 while (olen
> 0 && obody
[olen
- 1] == SPACEGLYPH
)
1603 /* For an inverse-video line, remember we gave it
1604 spaces all the way to the frame edge
1605 so that the reverse video extends all the way across. */
1607 while (olen
< FRAME_WINDOW_WIDTH (frame
) - 1)
1608 obody
[olen
++] = SPACEGLYPH
;
1612 /* One way or another, this will enable the line being updated. */
1613 current_frame
->enable
[vpos
] = 1;
1614 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1615 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1616 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1618 #ifdef HAVE_WINDOW_SYSTEM
1619 if (FRAME_WINDOW_P (frame
))
1621 current_frame
->pix_width
[vpos
]
1622 = current_frame
->used
[vpos
]
1623 * FONT_WIDTH (FRAME_FONT (frame
));
1624 current_frame
->pix_height
[vpos
]
1625 = FRAME_LINE_HEIGHT (frame
);
1627 #endif /* HAVE_WINDOW_SYSTEM */
1629 if (!desired_frame
->enable
[vpos
])
1635 nbody
= desired_frame
->glyphs
[vpos
];
1636 nlen
= desired_frame
->used
[vpos
];
1638 /* Pretend trailing spaces are not there at all,
1639 unless for one reason or another we must write all spaces. */
1640 if (! desired_frame
->highlight
[vpos
])
1642 if (!must_write_spaces
)
1643 /* We know that the previous character byte contains 0. */
1644 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1649 /* For an inverse-video line, give it extra trailing spaces
1650 all the way to the frame edge
1651 so that the reverse video extends all the way across. */
1653 while (nlen
< FRAME_WINDOW_WIDTH (frame
) - 1)
1654 nbody
[nlen
++] = SPACEGLYPH
;
1657 /* If there's no i/d char, quickly do the best we can without it. */
1658 if (!char_ins_del_ok
)
1663 if (FRAME_X_P (frame
))
1665 /* Under X, erase everything we are going to rewrite,
1666 and rewrite everything from the first char that's changed.
1667 This is part of supporting fonts like Courier
1668 whose chars can overlap outside the char width. */
1669 for (i
= 0; i
< nlen
; i
++)
1670 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1673 cursor_to (vpos
, i
);
1675 clear_end_of_line (olen
);
1676 write_glyphs (nbody
+ i
, nlen
- i
);
1681 for (i
= 0; i
< nlen
; i
++)
1683 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1685 cursor_to (vpos
, i
);
1688 && (i
+ j
>= olen
|| nbody
[i
+ j
] != obody
[i
+ j
]
1689 || (nbody
[i
+ j
] & GLYPH_MASK_PADDING
)));
1692 /* Output this run of non-matching chars. */
1693 write_glyphs (nbody
+ i
, j
);
1696 /* Now find the next non-match. */
1700 /* Clear the rest of the line, or the non-clear part of it. */
1703 cursor_to (vpos
, nlen
);
1704 clear_end_of_line (olen
);
1707 /* Exchange contents between current_frame and new_frame. */
1708 temp
= desired_frame
->glyphs
[vpos
];
1709 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1710 current_frame
->glyphs
[vpos
] = temp
;
1712 /* Exchange charstarts between current_frame and new_frame. */
1713 temp1
= desired_frame
->charstarts
[vpos
];
1714 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1715 current_frame
->charstarts
[vpos
] = temp1
;
1722 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1723 ? 0 : count_blanks (nbody
);
1726 cursor_to (vpos
, nsp
);
1727 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1730 /* Exchange contents between current_frame and new_frame. */
1731 temp
= desired_frame
->glyphs
[vpos
];
1732 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1733 current_frame
->glyphs
[vpos
] = temp
;
1735 /* Exchange charstarts between current_frame and new_frame. */
1736 temp1
= desired_frame
->charstarts
[vpos
];
1737 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1738 current_frame
->charstarts
[vpos
] = temp1
;
1747 /* Compute number of leading blanks in old and new contents. */
1748 osp
= count_blanks (obody
);
1749 if (!desired_frame
->highlight
[vpos
])
1750 nsp
= count_blanks (nbody
);
1754 /* Compute number of matching chars starting with first nonblank. */
1755 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1757 /* Spaces in new match implicit space past the end of old. */
1758 /* A bug causing this to be a no-op was fixed in 18.29. */
1759 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1762 while (np1
[begmatch
] == SPACEGLYPH
)
1766 /* Avoid doing insert/delete char
1767 just cause number of leading spaces differs
1768 when the following text does not match. */
1769 if (begmatch
== 0 && osp
!= nsp
)
1770 osp
= nsp
= min (osp
, nsp
);
1772 /* Find matching characters at end of line */
1775 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1776 while (op1
> op2
&& op1
[-1] == np1
[-1])
1781 endmatch
= obody
+ olen
- op1
;
1783 /* Put correct value back in nbody[nlen].
1784 This is important because direct_output_for_insert
1785 can write into the line at a later point.
1786 If this screws up the zero at the end of the line, re-establish it. */
1790 /* tem gets the distance to insert or delete.
1791 endmatch is how many characters we save by doing so.
1794 tem
= (nlen
- nsp
) - (olen
- osp
);
1796 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1799 /* nsp - osp is the distance to insert or delete.
1800 If that is nonzero, begmatch is known to be nonzero also.
1801 begmatch + endmatch is how much we save by doing the ins/del.
1805 && (!char_ins_del_ok
1806 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1810 osp
= nsp
= min (osp
, nsp
);
1813 /* Now go through the line, inserting, writing and
1814 deleting as appropriate. */
1818 cursor_to (vpos
, nsp
);
1819 delete_glyphs (osp
- nsp
);
1823 /* If going to delete chars later in line
1824 and insert earlier in the line,
1825 must delete first to avoid losing data in the insert */
1826 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1828 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1829 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1830 olen
= nlen
- (nsp
- osp
);
1832 cursor_to (vpos
, osp
);
1833 insert_glyphs ((char *)0, nsp
- osp
);
1837 tem
= nsp
+ begmatch
+ endmatch
;
1838 if (nlen
!= tem
|| olen
!= tem
)
1840 cursor_to (vpos
, nsp
+ begmatch
);
1841 if (!endmatch
|| nlen
== olen
)
1843 /* If new text being written reaches right margin,
1844 there is no need to do clear-to-eol at the end.
1845 (and it would not be safe, since cursor is not
1846 going to be "at the margin" after the text is done) */
1847 if (nlen
== FRAME_WINDOW_WIDTH (frame
))
1849 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1853 /* the following code loses disastrously if tem == nlen.
1854 Rather than trying to fix that case, I am trying the simpler
1855 solution found above. */
1857 /* If the text reaches to the right margin,
1858 it will lose one way or another (depending on AutoWrap)
1859 to clear to end of line after outputting all the text.
1860 So pause with one character to go and clear the line then. */
1861 if (nlen
== FRAME_WINDOW_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1863 /* endmatch must be zero, and tem must equal nsp + begmatch */
1864 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1865 clear_end_of_line (olen
);
1866 olen
= 0; /* Don't let it be cleared again later */
1867 write_glyphs (nbody
+ nlen
- 1, 1);
1870 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1871 #endif /* OBSOLETE */
1874 else if (nlen
> olen
)
1876 /* Here, we used to have the following simple code:
1877 ----------------------------------------
1878 write_glyphs (nbody + nsp + begmatch, olen - tem);
1879 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
1880 ----------------------------------------
1881 but it doesn't work if nbody[nsp + begmatch + olen - tem]
1882 is a padding glyph. */
1883 int out
= olen
- tem
; /* Columns to be overwritten originally. */
1886 /* Calculate columns we can actually overwrite. */
1887 while (nbody
[nsp
+ begmatch
+ out
] & GLYPH_MASK_PADDING
) out
--;
1888 write_glyphs (nbody
+ nsp
+ begmatch
, out
);
1889 /* If we left columns to be overwritten. we must delete them. */
1890 del
= olen
- tem
- out
;
1891 if (del
> 0) delete_glyphs (del
);
1892 /* At last, we insert columns not yet written out. */
1893 insert_glyphs (nbody
+ nsp
+ begmatch
+ out
, nlen
- olen
+ del
);
1896 else if (olen
> nlen
)
1898 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1899 delete_glyphs (olen
- nlen
);
1905 /* If any unerased characters remain after the new line, erase them. */
1908 cursor_to (vpos
, nlen
);
1909 clear_end_of_line (olen
);
1912 /* Exchange contents between current_frame and new_frame. */
1913 temp
= desired_frame
->glyphs
[vpos
];
1914 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1915 current_frame
->glyphs
[vpos
] = temp
;
1917 /* Exchange charstarts between current_frame and new_frame. */
1918 temp1
= desired_frame
->charstarts
[vpos
];
1919 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1920 current_frame
->charstarts
[vpos
] = temp1
;
1923 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
1924 session's frames, frame names, buffers, buffer-read-only flags, and
1925 buffer-modified-flags, and a trailing sentinel (so we don't need to
1926 add length checks). */
1927 static Lisp_Object frame_and_buffer_state
;
1929 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p
,
1930 Sframe_or_buffer_changed_p
, 0, 0, 0,
1931 "Return non-nil if the frame and buffer state appears to have changed.\n\
1932 The state variable is an internal vector containing all frames and buffers,\n\
1933 aside from buffers whose names start with space,\n\
1934 along with the buffers' read-only and modified flags, which allows a fast\n\
1935 check to see whether the menu bars might need to be recomputed.\n\
1936 If this function returns non-nil, it updates the internal vector to reflect\n\
1937 the current state.\n")
1940 Lisp_Object tail
, frame
, buf
;
1944 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1945 FOR_EACH_FRAME (tail
, frame
)
1947 if (!EQ (*vecp
++, frame
))
1949 if (!EQ (*vecp
++, XFRAME (frame
)->name
))
1952 /* Check that the buffer info matches.
1953 No need to test for the end of the vector
1954 because the last element of the vector is lambda
1955 and that will always cause a mismatch. */
1956 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1958 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1959 /* Ignore buffers that aren't included in buffer lists. */
1960 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1962 if (!EQ (*vecp
++, buf
))
1964 if (!EQ (*vecp
++, XBUFFER (buf
)->read_only
))
1966 if (!EQ (*vecp
++, Fbuffer_modified_p (buf
)))
1969 /* Detect deletion of a buffer at the end of the list. */
1970 if (EQ (*vecp
, Qlambda
))
1973 /* Start with 1 so there is room for at least one lambda at the end. */
1975 FOR_EACH_FRAME (tail
, frame
)
1977 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1979 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
1980 if (n
> XVECTOR (frame_and_buffer_state
)->size
1981 || n
+ 20 < XVECTOR (frame_and_buffer_state
)->size
/ 2)
1982 /* Add 20 extra so we grow it less often. */
1983 frame_and_buffer_state
= Fmake_vector (make_number (n
+ 20), Qlambda
);
1984 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1985 FOR_EACH_FRAME (tail
, frame
)
1988 *vecp
++ = XFRAME (frame
)->name
;
1990 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1992 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1993 /* Ignore buffers that aren't included in buffer lists. */
1994 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1997 *vecp
++ = XBUFFER (buf
)->read_only
;
1998 *vecp
++ = Fbuffer_modified_p (buf
);
2000 /* Fill up the vector with lambdas (always at least one). */
2002 while (vecp
- XVECTOR (frame_and_buffer_state
)->contents
2003 < XVECTOR (frame_and_buffer_state
)->size
)
2005 /* Make sure we didn't overflow the vector. */
2006 if (vecp
- XVECTOR (frame_and_buffer_state
)->contents
2007 > XVECTOR (frame_and_buffer_state
)->size
)
2012 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
2013 1, 1, "FOpen termscript file: ",
2014 "Start writing all terminal output to FILE as well as the terminal.\n\
2015 FILE = nil means just close any termscript file currently open.")
2019 if (termscript
!= 0) fclose (termscript
);
2024 file
= Fexpand_file_name (file
, Qnil
);
2025 termscript
= fopen (XSTRING (file
)->data
, "w");
2026 if (termscript
== 0)
2027 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
2035 window_change_signal (signalnum
) /* If we don't have an argument, */
2036 int signalnum
; /* some compilers complain in signal calls. */
2040 int old_errno
= errno
;
2042 get_frame_size (&width
, &height
);
2044 /* The frame size change obviously applies to a termcap-controlled
2045 frame. Find such a frame in the list, and assume it's the only
2046 one (since the redisplay code always writes to stdout, not a
2047 FILE * specified in the frame structure). Record the new size,
2048 but don't reallocate the data structures now. Let that be done
2049 later outside of the signal handler. */
2052 Lisp_Object tail
, frame
;
2054 FOR_EACH_FRAME (tail
, frame
)
2056 if (FRAME_TERMCAP_P (XFRAME (frame
)))
2058 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
2064 signal (SIGWINCH
, window_change_signal
);
2067 #endif /* SIGWINCH */
2070 /* Do any change in frame size that was requested by a signal. */
2072 do_pending_window_change ()
2074 /* If window_change_signal should have run before, run it now. */
2075 while (delayed_size_change
)
2077 Lisp_Object tail
, frame
;
2079 delayed_size_change
= 0;
2081 FOR_EACH_FRAME (tail
, frame
)
2083 FRAME_PTR f
= XFRAME (frame
);
2085 int height
= FRAME_NEW_HEIGHT (f
);
2086 int width
= FRAME_NEW_WIDTH (f
);
2088 if (height
!= 0 || width
!= 0)
2089 change_frame_size (f
, height
, width
, 0, 0);
2095 /* Change the frame height and/or width. Values may be given as zero to
2096 indicate no change is to take place.
2098 If DELAY is non-zero, then assume we're being called from a signal
2099 handler, and queue the change for later - perhaps the next
2100 redisplay. Since this tries to resize windows, we can't call it
2101 from a signal handler. */
2103 change_frame_size (f
, newheight
, newwidth
, pretend
, delay
)
2104 register FRAME_PTR f
;
2105 int newheight
, newwidth
, pretend
;
2107 Lisp_Object tail
, frame
;
2109 if (! FRAME_WINDOW_P (f
))
2111 /* When using termcap, or on MS-DOS, all frames use
2112 the same screen, so a change in size affects all frames. */
2113 FOR_EACH_FRAME (tail
, frame
)
2114 if (! FRAME_WINDOW_P (XFRAME (frame
)))
2115 change_frame_size_1 (XFRAME (frame
), newheight
, newwidth
,
2119 change_frame_size_1 (f
, newheight
, newwidth
, pretend
, delay
);
2123 change_frame_size_1 (frame
, newheight
, newwidth
, pretend
, delay
)
2124 register FRAME_PTR frame
;
2125 int newheight
, newwidth
, pretend
, delay
;
2127 int new_frame_window_width
;
2128 unsigned int total_glyphs
;
2129 int count
= specpdl_ptr
- specpdl
;
2131 /* If we can't deal with the change now, queue it for later. */
2134 FRAME_NEW_HEIGHT (frame
) = newheight
;
2135 FRAME_NEW_WIDTH (frame
) = newwidth
;
2136 delayed_size_change
= 1;
2140 /* This size-change overrides any pending one for this frame. */
2141 FRAME_NEW_HEIGHT (frame
) = 0;
2142 FRAME_NEW_WIDTH (frame
) = 0;
2144 /* If an argument is zero, set it to the current value. */
2146 newheight
= FRAME_HEIGHT (frame
);
2148 newwidth
= FRAME_WIDTH (frame
);
2149 new_frame_window_width
= FRAME_WINDOW_WIDTH_ARG (frame
, newwidth
);
2151 total_glyphs
= newheight
* (newwidth
+ 2) * sizeof (GLYPH
);
2153 /* If these sizes are so big they cause overflow,
2154 just ignore the change. It's not clear what better we could do. */
2155 if (total_glyphs
/ sizeof (GLYPH
) / newheight
!= newwidth
+ 2)
2158 /* Round up to the smallest acceptable size. */
2159 check_frame_size (frame
, &newheight
, &newwidth
);
2161 /* If we're not changing the frame size, quit now. */
2162 if (newheight
== FRAME_HEIGHT (frame
)
2163 && new_frame_window_width
== FRAME_WINDOW_WIDTH (frame
))
2169 /* We only can set screen dimensions to certain values supported
2170 by our video hardware. Try to find the smallest size greater
2171 or equal to the requested dimensions. */
2172 dos_set_window_size (&newheight
, &newwidth
);
2175 if (newheight
!= FRAME_HEIGHT (frame
))
2177 if (FRAME_HAS_MINIBUF_P (frame
)
2178 && ! FRAME_MINIBUF_ONLY_P (frame
))
2180 /* Frame has both root and minibuffer. */
2181 set_window_height (FRAME_ROOT_WINDOW (frame
),
2182 newheight
- 1 - FRAME_MENU_BAR_LINES (frame
), 0);
2183 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame
))->top
,
2185 set_window_height (FRAME_MINIBUF_WINDOW (frame
), 1, 0);
2188 /* Frame has just one top-level window. */
2189 set_window_height (FRAME_ROOT_WINDOW (frame
),
2190 newheight
- FRAME_MENU_BAR_LINES (frame
), 0);
2192 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2193 FrameRows
= newheight
;
2196 if (frame
->output_method
== output_termcap
)
2198 frame_height
= newheight
;
2200 FrameRows
= newheight
;
2205 if (new_frame_window_width
!= FRAME_WINDOW_WIDTH (frame
))
2207 set_window_width (FRAME_ROOT_WINDOW (frame
), new_frame_window_width
, 0);
2208 if (FRAME_HAS_MINIBUF_P (frame
))
2209 set_window_width (FRAME_MINIBUF_WINDOW (frame
), new_frame_window_width
, 0);
2211 if (FRAME_TERMCAP_P (frame
) && !pretend
)
2212 FrameCols
= newwidth
;
2214 if (frame
->output_method
== output_termcap
)
2216 frame_width
= newwidth
;
2218 FrameCols
= newwidth
;
2223 FRAME_HEIGHT (frame
) = newheight
;
2224 SET_FRAME_WIDTH (frame
, newwidth
);
2226 if (FRAME_CURSOR_X (frame
) >= FRAME_WINDOW_WIDTH (frame
))
2227 FRAME_CURSOR_X (frame
) = FRAME_WINDOW_WIDTH (frame
) - 1;
2228 if (FRAME_CURSOR_Y (frame
) >= FRAME_HEIGHT (frame
))
2229 FRAME_CURSOR_Y (frame
) = FRAME_HEIGHT (frame
) - 1;
2231 remake_frame_glyphs (frame
);
2232 calculate_costs (frame
);
2236 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2238 /* This isn't quite a no-op: it runs window-configuration-change-hook. */
2239 Fset_window_buffer (FRAME_SELECTED_WINDOW (frame
),
2240 XWINDOW (FRAME_SELECTED_WINDOW (frame
))->buffer
);
2242 unbind_to (count
, Qnil
);
2245 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
2246 Ssend_string_to_terminal
, 1, 1, 0,
2247 "Send STRING to the terminal without alteration.\n\
2248 Control characters in STRING will have terminal-dependent effects.")
2252 CHECK_STRING (string
, 0);
2253 fwrite (XSTRING (string
)->data
, 1, XSTRING (string
)->size
, stdout
);
2257 fwrite (XSTRING (string
)->data
, 1, XSTRING (string
)->size
, termscript
);
2258 fflush (termscript
);
2263 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
2264 "Beep, or flash the screen.\n\
2265 Also, unless an argument is given,\n\
2266 terminate any keyboard macro currently executing.")
2288 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
2289 error ("Keyboard macro terminated by a command ringing the bell");
2295 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
2296 "Pause, without updating display, for SECONDS seconds.\n\
2297 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2298 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2299 additional wait period, in milliseconds; this may be useful if your\n\
2300 Emacs was built without floating point support.\n\
2301 \(Not all operating systems support waiting for a fraction of a second.)")
2302 (seconds
, milliseconds
)
2303 Lisp_Object seconds
, milliseconds
;
2307 if (NILP (milliseconds
))
2308 XSETINT (milliseconds
, 0);
2310 CHECK_NUMBER (milliseconds
, 1);
2311 usec
= XINT (milliseconds
) * 1000;
2313 #ifdef LISP_FLOAT_TYPE
2315 double duration
= extract_float (seconds
);
2316 sec
= (int) duration
;
2317 usec
+= (duration
- sec
) * 1000000;
2320 CHECK_NUMBER (seconds
, 0);
2321 sec
= XINT (seconds
);
2324 #ifndef EMACS_HAS_USECS
2325 if (sec
== 0 && usec
!= 0)
2326 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2329 /* Assure that 0 <= usec < 1000000. */
2332 /* We can't rely on the rounding being correct if user is negative. */
2333 if (-1000000 < usec
)
2334 sec
--, usec
+= 1000000;
2336 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2339 sec
+= usec
/ 1000000, usec
%= 1000000;
2341 if (sec
< 0 || (sec
== 0 && usec
== 0))
2347 XSETFASTINT (zero
, 0);
2348 wait_reading_process_input (sec
, usec
, zero
, 0);
2351 /* We should always have wait_reading_process_input; we have a dummy
2352 implementation for systems which don't support subprocesses. */
2354 /* No wait_reading_process_input */
2361 /* The reason this is done this way
2362 (rather than defined (H_S) && defined (H_T))
2363 is because the VMS preprocessor doesn't grok `defined' */
2365 EMACS_GET_TIME (end_time
);
2366 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2367 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2371 EMACS_GET_TIME (timeout
);
2372 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2373 if (EMACS_TIME_NEG_P (timeout
)
2374 || !select (1, 0, 0, 0, &timeout
))
2377 #else /* not HAVE_SELECT */
2379 #endif /* HAVE_SELECT */
2380 #endif /* not VMS */
2383 #endif /* no subprocesses */
2388 /* This is just like wait_reading_process_input, except that
2389 it does the redisplay.
2391 It's also much like Fsit_for, except that it can be used for
2392 waiting for input as well. */
2395 sit_for (sec
, usec
, reading
, display
, initial_display
)
2396 int sec
, usec
, reading
, display
, initial_display
;
2398 Lisp_Object read_kbd
;
2400 swallow_events (display
);
2402 if (detect_input_pending_run_timers (display
))
2405 if (initial_display
)
2406 redisplay_preserve_echo_area ();
2408 if (sec
== 0 && usec
== 0)
2415 XSETINT (read_kbd
, reading
? -1 : 1);
2416 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2418 return detect_input_pending () ? Qnil
: Qt
;
2421 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2422 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2423 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2424 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2425 additional wait period, in milliseconds; this may be useful if your\n\
2426 Emacs was built without floating point support.\n\
2427 \(Not all operating systems support waiting for a fraction of a second.)\n\
2428 Optional third arg NODISP non-nil means don't redisplay, just wait for input.\n\
2429 Redisplay is preempted as always if input arrives, and does not happen\n\
2430 if input is available before it starts.\n\
2431 Value is t if waited the full time with no input arriving.")
2432 (seconds
, milliseconds
, nodisp
)
2433 Lisp_Object seconds
, milliseconds
, nodisp
;
2437 if (NILP (milliseconds
))
2438 XSETINT (milliseconds
, 0);
2440 CHECK_NUMBER (milliseconds
, 1);
2441 usec
= XINT (milliseconds
) * 1000;
2443 #ifdef LISP_FLOAT_TYPE
2445 double duration
= extract_float (seconds
);
2446 sec
= (int) duration
;
2447 usec
+= (duration
- sec
) * 1000000;
2450 CHECK_NUMBER (seconds
, 0);
2451 sec
= XINT (seconds
);
2454 #ifndef EMACS_HAS_USECS
2455 if (usec
!= 0 && sec
== 0)
2456 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2459 return sit_for (sec
, usec
, 0, NILP (nodisp
), NILP (nodisp
));
2462 char *terminal_type
;
2464 /* Initialization done when Emacs fork is started, before doing stty. */
2465 /* Determine terminal type and set terminal_driver */
2466 /* Then invoke its decoding routine to set up variables
2467 in the terminal package */
2471 #ifdef HAVE_X_WINDOWS
2472 extern int display_arg
;
2477 cursor_in_echo_area
= 0;
2478 terminal_type
= (char *) 0;
2480 /* Now is the time to initialize this; it's used by init_sys_modes
2482 Vwindow_system
= Qnil
;
2484 /* If the user wants to use a window system, we shouldn't bother
2485 initializing the terminal. This is especially important when the
2486 terminal is so dumb that emacs gives up before and doesn't bother
2487 using the window system.
2489 If the DISPLAY environment variable is set and nonempty,
2490 try to use X, and die with an error message if that doesn't work. */
2492 #ifdef HAVE_X_WINDOWS
2497 display
= getenv ("DECW$DISPLAY");
2499 display
= getenv ("DISPLAY");
2502 display_arg
= (display
!= 0 && *display
!= 0);
2505 if (!inhibit_window_system
&& display_arg
2511 Vwindow_system
= intern ("x");
2513 Vwindow_system_version
= make_number (11);
2515 Vwindow_system_version
= make_number (10);
2517 #if defined (LINUX) && defined (HAVE_LIBNCURSES)
2518 /* In some versions of ncurses,
2519 tputs crashes if we have not called tgetent.
2521 { char b
[2044]; tgetent (b
, "xterm");}
2525 #endif /* HAVE_X_WINDOWS */
2528 if (!inhibit_window_system
)
2530 Vwindow_system
= intern ("w32");
2531 Vwindow_system_version
= make_number (1);
2534 #endif /* HAVE_NTGUI */
2536 /* If no window system has been specified, try to use the terminal. */
2539 fatal ("standard input is not a tty");
2543 /* Look at the TERM variable */
2544 terminal_type
= (char *) getenv ("TERM");
2548 fprintf (stderr
, "Please specify your terminal type.\n\
2549 For types defined in VMS, use set term /device=TYPE.\n\
2550 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2551 \(The quotation marks are necessary since terminal types are lower case.)\n");
2553 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2559 /* VMS DCL tends to upcase things, so downcase term type.
2560 Hardly any uppercase letters in terminal types; should be none. */
2562 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2565 strcpy (new, terminal_type
);
2567 for (p
= new; *p
; p
++)
2571 terminal_type
= new;
2575 term_init (terminal_type
);
2578 int width
= FRAME_WINDOW_WIDTH (selected_frame
);
2579 int height
= FRAME_HEIGHT (selected_frame
);
2581 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
2583 /* If these sizes are so big they cause overflow,
2584 just ignore the change. It's not clear what better we could do. */
2585 if (total_glyphs
/ sizeof (GLYPH
) / height
!= width
+ 2)
2586 fatal ("screen size %dx%d too big", width
, height
);
2589 remake_frame_glyphs (selected_frame
);
2590 calculate_costs (selected_frame
);
2592 /* X and Y coordinates of the cursor between updates. */
2593 FRAME_CURSOR_X (selected_frame
) = 0;
2594 FRAME_CURSOR_Y (selected_frame
) = 0;
2599 #endif /* CANNOT_DUMP */
2600 signal (SIGWINCH
, window_change_signal
);
2601 #endif /* SIGWINCH */
2606 defsubr (&Sredraw_frame
);
2607 defsubr (&Sredraw_display
);
2608 defsubr (&Sframe_or_buffer_changed_p
);
2609 defsubr (&Sopen_termscript
);
2611 defsubr (&Ssit_for
);
2612 defsubr (&Ssleep_for
);
2613 defsubr (&Ssend_string_to_terminal
);
2615 frame_and_buffer_state
= Fmake_vector (make_number (20), Qlambda
);
2616 staticpro (&frame_and_buffer_state
);
2618 Qdisplay_table
= intern ("display-table");
2619 staticpro (&Qdisplay_table
);
2621 DEFVAR_INT ("baud-rate", &baud_rate
,
2622 "*The output baud rate of the terminal.\n\
2623 On most systems, changing this value will affect the amount of padding\n\
2624 and the other strategic decisions made during redisplay.");
2625 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2626 "*Non-nil means invert the entire frame display.\n\
2627 This means everything is in inverse video which otherwise would not be.");
2628 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2629 "*Non-nil means try to flash the frame to represent a bell.");
2630 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2631 "*Non-nil means no need to redraw entire frame after suspending.\n\
2632 A non-nil value is useful if the terminal can automatically preserve\n\
2633 Emacs's frame display when you reenter Emacs.\n\
2634 It is up to you to set this variable if your terminal can do that.");
2635 DEFVAR_LISP ("window-system", &Vwindow_system
,
2636 "A symbol naming the window-system under which Emacs is running\n\
2637 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2638 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2639 "The version number of the window system in use.\n\
2640 For X windows, this is 10 or 11.");
2641 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2642 "Non-nil means put cursor in minibuffer, at end of any message there.");
2643 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2644 "Table defining how to output a glyph code to the frame.\n\
2645 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2646 Each element can be:\n\
2647 integer: a glyph code which this glyph is an alias for.\n\
2648 string: output this glyph using that string (not impl. in X windows).\n\
2649 nil: this glyph mod 256 is char code to output,\n\
2650 and this glyph / 256 is face code for X windows (see `face-id').");
2651 Vglyph_table
= Qnil
;
2653 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2654 "Display table to use for buffers that specify none.\n\
2655 See `buffer-display-table' for more information.");
2656 Vstandard_display_table
= Qnil
;
2658 /* Initialize `window-system', unless init_display already decided it. */
2663 Vwindow_system
= Qnil
;
2664 Vwindow_system_version
= Qnil
;