1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95 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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
32 #include "termhooks.h"
33 /* cm.h must come after dispextern.h on Windows. */
34 #include "dispextern.h"
43 #include "intervals.h"
44 #include "blockinput.h"
46 /* I don't know why DEC Alpha OSF1 fail to compile this file if we
47 include the following file. */
48 /* #include "systty.h" */
49 #include "syssignal.h"
53 #endif /* HAVE_X_WINDOWS */
57 #endif /* HAVE_NTGUI */
59 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
64 #define max(a, b) ((a) > (b) ? (a) : (b))
65 #define min(a, b) ((a) < (b) ? (a) : (b))
67 /* Get number of chars of output now in the buffer of a stdio stream.
68 This ought to be built in in stdio, but it isn't.
69 Some s- files override this because their stdio internals differ. */
70 #ifdef __GNU_LIBRARY__
71 /* The s- file might have overridden the definition with one that works for
72 the system's C library. But we are using the GNU C library, so this is
73 the right definition for every system. */
74 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
75 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
77 #undef PENDING_OUTPUT_COUNT
78 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
80 #else /* not __GNU_LIBRARY__ */
81 #ifndef PENDING_OUTPUT_COUNT
82 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
86 static void change_frame_size_1 ();
88 /* Nonzero upon entry to redisplay means do not assume anything about
89 current contents of actual terminal frame; clear and redraw it. */
93 /* Nonzero means last display completed. Zero means it was preempted. */
95 int display_completed
;
97 /* Lisp variable visible-bell; enables use of screen-flash
98 instead of audible bell. */
102 /* Invert the color of the whole frame, at a low level. */
106 /* Line speed of the terminal. */
110 /* nil or a symbol naming the window system under which emacs is
111 running ('x is the only current possibility). */
113 Lisp_Object Vwindow_system
;
115 /* Version number of X windows: 10, 11 or nil. */
116 Lisp_Object Vwindow_system_version
;
118 /* Vector of glyph definitions. Indexed by glyph number,
119 the contents are a string which is how to output the glyph.
121 If Vglyph_table is nil, a glyph is output by using its low 8 bits
122 as a character code. */
124 Lisp_Object Vglyph_table
;
126 /* Display table to use for vectors that don't specify their own. */
128 Lisp_Object Vstandard_display_table
;
130 /* Nonzero means reading single-character input with prompt
131 so put cursor on minibuffer after the prompt.
132 positive means at end of text in echo area;
133 negative means at beginning of line. */
134 int cursor_in_echo_area
;
136 Lisp_Object Qdisplay_table
;
138 /* The currently selected frame.
139 In a single-frame version, this variable always holds the address of
142 FRAME_PTR selected_frame
;
144 /* A frame which is not just a minibuffer, or 0 if there are no such
145 frames. This is usually the most recent such frame that was
146 selected. In a single-frame version, this variable always holds
147 the address of the_only_frame. */
148 FRAME_PTR last_nonminibuf_frame
;
150 /* This is a vector, made larger whenever it isn't large enough,
151 which is used inside `update_frame' to hold the old contents
152 of the FRAME_PHYS_LINES of the frame being updated. */
153 struct frame_glyphs
**ophys_lines
;
154 /* Length of vector currently allocated. */
155 int ophys_lines_length
;
157 FILE *termscript
; /* Stdio stream being used for copy of all output. */
159 struct cm Wcm
; /* Structure for info on cursor positioning */
161 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
163 DEFUN ("redraw-frame", Fredraw_frame
, Sredraw_frame
, 1, 1, 0,
164 "Clear frame FRAME and output again what is supposed to appear on it.")
170 CHECK_LIVE_FRAME (frame
, 0);
173 if (FRAME_MSDOS_P (f
))
174 set_terminal_modes ();
176 clear_frame_records (f
);
179 windows_or_buffers_changed
++;
180 /* Mark all windows as INaccurate,
181 so that every window will have its redisplay done. */
182 mark_window_display_accurate (FRAME_ROOT_WINDOW (f
), 0);
191 XSETFRAME (frame
, f
);
192 Fredraw_frame (frame
);
195 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
196 "Clear and redisplay all visible frames.")
199 Lisp_Object tail
, frame
;
201 FOR_EACH_FRAME (tail
, frame
)
202 if (FRAME_VISIBLE_P (XFRAME (frame
)))
203 Fredraw_frame (frame
);
208 /* This is used when frame_garbaged is set.
209 Redraw the individual frames marked as garbaged. */
212 redraw_garbaged_frames ()
214 Lisp_Object tail
, frame
;
216 FOR_EACH_FRAME (tail
, frame
)
217 if (FRAME_VISIBLE_P (XFRAME (frame
))
218 && FRAME_GARBAGED_P (XFRAME (frame
)))
219 Fredraw_frame (frame
);
223 static struct frame_glyphs
*
224 make_frame_glyphs (frame
, empty
)
225 register FRAME_PTR frame
;
229 register width
= FRAME_WINDOW_WIDTH (frame
);
230 register height
= FRAME_HEIGHT (frame
);
231 register struct frame_glyphs
*new
232 = (struct frame_glyphs
*) xmalloc (sizeof (struct frame_glyphs
));
234 SET_GLYPHS_FRAME (new, frame
);
235 new->height
= height
;
237 new->used
= (int *) xmalloc (height
* sizeof (int));
238 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
239 new->charstarts
= (int **) xmalloc (height
* sizeof (int *));
240 new->highlight
= (char *) xmalloc (height
* sizeof (char));
241 new->enable
= (char *) xmalloc (height
* sizeof (char));
242 bzero (new->enable
, height
* sizeof (char));
243 new->bufp
= (int *) xmalloc (height
* sizeof (int));
245 #ifdef HAVE_WINDOW_SYSTEM
246 if (FRAME_WINDOW_P (frame
))
248 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
249 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
250 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
251 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
252 new->max_ascent
= (short *) xmalloc (height
* sizeof (short));
254 #endif /* HAVE_WINDOW_SYSTEM */
258 /* Make the buffer used by decode_mode_spec. This buffer is also
259 used as temporary storage when updating the frame. See scroll.c. */
260 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
261 unsigned int total_charstarts
= (width
+ 2) * sizeof (int);
263 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
264 bzero (new->total_contents
, total_glyphs
);
266 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
267 bzero (new->total_charstarts
, total_charstarts
);
271 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
273 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
274 bzero (new->total_contents
, total_glyphs
);
275 for (i
= 0; i
< height
; i
++)
276 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
278 if (!FRAME_TERMCAP_P (frame
))
280 unsigned int total_charstarts
= height
* (width
+ 2) * sizeof (int);
282 new->total_charstarts
= (int *) xmalloc (total_charstarts
);
283 bzero (new->total_charstarts
, total_charstarts
);
284 for (i
= 0; i
< height
; i
++)
285 new->charstarts
[i
] = new->total_charstarts
+ i
* (width
+ 2) + 1;
289 /* Without a window system, we don't really need charstarts.
290 So use a small amount of space to make enough data structure
291 to prevent crashes in display_text_line. */
292 new->total_charstarts
= (int *) xmalloc ((width
+ 2) * sizeof (int));
293 for (i
= 0; i
< height
; i
++)
294 new->charstarts
[i
] = new->total_charstarts
;
302 free_frame_glyphs (frame
, glyphs
)
304 struct frame_glyphs
*glyphs
;
306 if (glyphs
->total_contents
)
307 xfree (glyphs
->total_contents
);
308 if (glyphs
->total_charstarts
)
309 xfree (glyphs
->total_charstarts
);
311 xfree (glyphs
->used
);
312 xfree (glyphs
->glyphs
);
313 xfree (glyphs
->highlight
);
314 xfree (glyphs
->enable
);
315 xfree (glyphs
->bufp
);
316 if (glyphs
->charstarts
)
317 xfree (glyphs
->charstarts
);
319 #ifdef HAVE_WINDOW_SYSTEM
320 if (FRAME_WINDOW_P (frame
))
322 xfree (glyphs
->top_left_x
);
323 xfree (glyphs
->top_left_y
);
324 xfree (glyphs
->pix_width
);
325 xfree (glyphs
->pix_height
);
326 xfree (glyphs
->max_ascent
);
328 #endif /* HAVE_WINDOW_SYSTEM */
334 remake_frame_glyphs (frame
)
337 if (FRAME_CURRENT_GLYPHS (frame
))
338 free_frame_glyphs (frame
, FRAME_CURRENT_GLYPHS (frame
));
339 if (FRAME_DESIRED_GLYPHS (frame
))
340 free_frame_glyphs (frame
, FRAME_DESIRED_GLYPHS (frame
));
341 if (FRAME_TEMP_GLYPHS (frame
))
342 free_frame_glyphs (frame
, FRAME_TEMP_GLYPHS (frame
));
344 if (FRAME_MESSAGE_BUF (frame
))
346 /* Reallocate the frame's message buffer; remember that
347 echo_area_glyphs may be pointing here. */
348 char *old_message_buf
= FRAME_MESSAGE_BUF (frame
);
350 FRAME_MESSAGE_BUF (frame
)
351 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame
),
352 FRAME_MESSAGE_BUF_SIZE (frame
) + 1);
354 if (echo_area_glyphs
== old_message_buf
)
355 echo_area_glyphs
= FRAME_MESSAGE_BUF (frame
);
356 if (previous_echo_glyphs
== old_message_buf
)
357 previous_echo_glyphs
= FRAME_MESSAGE_BUF (frame
);
360 FRAME_MESSAGE_BUF (frame
)
361 = (char *) xmalloc (FRAME_MESSAGE_BUF_SIZE (frame
) + 1);
363 FRAME_CURRENT_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
364 FRAME_DESIRED_GLYPHS (frame
) = make_frame_glyphs (frame
, 0);
365 FRAME_TEMP_GLYPHS (frame
) = make_frame_glyphs (frame
, 1);
366 if (FRAME_WINDOW_P (frame
) || frame
== selected_frame
)
367 SET_FRAME_GARBAGED (frame
);
370 /* Return the hash code of contents of line VPOS in frame-matrix M. */
373 line_hash_code (m
, vpos
)
374 register struct frame_glyphs
*m
;
377 register GLYPH
*body
, *end
;
380 if (!m
->enable
[vpos
])
383 /* Give all highlighted lines the same hash code
384 so as to encourage scrolling to leave them in place. */
385 if (m
->highlight
[vpos
])
388 body
= m
->glyphs
[vpos
];
390 if (must_write_spaces
)
397 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
406 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
414 /* Return number of characters in line in M at vpos VPOS,
415 except don't count leading and trailing spaces
416 unless the terminal requires those to be explicitly output. */
419 line_draw_cost (m
, vpos
)
420 struct frame_glyphs
*m
;
423 register GLYPH
*beg
= m
->glyphs
[vpos
];
424 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
426 register int tlen
= GLYPH_TABLE_LENGTH
;
427 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
429 /* Ignore trailing and leading spaces if we can. */
430 if (!must_write_spaces
)
432 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
435 return (0); /* All blank line. */
437 while (*beg
== SPACEGLYPH
)
441 /* If we don't have a glyph-table, each glyph is one character,
442 so return the number of glyphs. */
446 /* Otherwise, scan the glyphs and accumulate their total size in I. */
448 while ((beg
<= end
) && *beg
)
450 register GLYPH g
= *beg
++;
452 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
455 i
+= GLYPH_LENGTH (tbase
, g
);
460 /* The functions on this page are the interface from xdisp.c to redisplay.
462 The only other interface into redisplay is through setting
463 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
464 and SET_FRAME_GARBAGED (frame). */
466 /* cancel_line eliminates any request to display a line at position `vpos' */
468 cancel_line (vpos
, frame
)
470 register FRAME_PTR frame
;
472 FRAME_DESIRED_GLYPHS (frame
)->enable
[vpos
] = 0;
475 clear_frame_records (frame
)
476 register FRAME_PTR frame
;
478 bzero (FRAME_CURRENT_GLYPHS (frame
)->enable
, FRAME_HEIGHT (frame
));
481 /* Clear out all display lines for a coming redisplay. */
484 init_desired_glyphs (frame
)
485 register FRAME_PTR frame
;
487 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
489 int height
= FRAME_HEIGHT (frame
);
491 for (vpos
= 0; vpos
< height
; vpos
++)
492 desired_glyphs
->enable
[vpos
] = 0;
495 /* Prepare to display on line VPOS starting at HPOS within it. */
498 get_display_line (frame
, vpos
, hpos
)
499 register FRAME_PTR frame
;
503 register struct frame_glyphs
*glyphs
;
504 register struct frame_glyphs
*desired_glyphs
= FRAME_DESIRED_GLYPHS (frame
);
510 if (! desired_glyphs
->enable
[vpos
])
512 desired_glyphs
->used
[vpos
] = 0;
513 desired_glyphs
->highlight
[vpos
] = 0;
514 desired_glyphs
->enable
[vpos
] = 1;
517 if (hpos
> desired_glyphs
->used
[vpos
])
519 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
520 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
522 desired_glyphs
->used
[vpos
] = hpos
;
528 /* Like bcopy except never gets confused by overlap. */
531 safe_bcopy (from
, to
, size
)
535 if (size
<= 0 || from
== to
)
538 /* If the source and destination don't overlap, then bcopy can
539 handle it. If they do overlap, but the destination is lower in
540 memory than the source, we'll assume bcopy can handle that. */
541 if (to
< from
|| from
+ size
<= to
)
542 bcopy (from
, to
, size
);
544 /* Otherwise, we'll copy from the end. */
547 register char *endf
= from
+ size
;
548 register char *endt
= to
+ size
;
550 /* If TO - FROM is large, then we should break the copy into
551 nonoverlapping chunks of TO - FROM bytes each. However, if
552 TO - FROM is small, then the bcopy function call overhead
553 makes this not worth it. The crossover point could be about
554 anywhere. Since I don't think the obvious copy loop is too
555 bad, I'm trying to err in its favor. */
560 while (endf
!= from
);
572 bcopy (endf
, endt
, to
- from
);
575 /* If SIZE wasn't a multiple of TO - FROM, there will be a
576 little left over. The amount left over is
577 (endt + (to - from)) - to, which is endt - from. */
578 bcopy (from
, to
, endt
- from
);
583 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
584 DISTANCE may be negative. */
587 rotate_vector (vector
, size
, distance
)
592 char *temp
= (char *) alloca (size
);
597 bcopy (vector
, temp
+ distance
, size
- distance
);
598 bcopy (vector
+ size
- distance
, temp
, distance
);
599 bcopy (temp
, vector
, size
);
602 /* Scroll lines from vpos FROM up to but not including vpos END
603 down by AMOUNT lines (AMOUNT may be negative).
604 Returns nonzero if done, zero if terminal cannot scroll them. */
607 scroll_frame_lines (frame
, from
, end
, amount
, newpos
)
608 register FRAME_PTR frame
;
609 int from
, end
, amount
, newpos
;
612 register struct frame_glyphs
*current_frame
613 = FRAME_CURRENT_GLYPHS (frame
);
615 int width
= FRAME_WINDOW_WIDTH (frame
);
617 if (!line_ins_del_ok
)
625 update_begin (frame
);
626 set_terminal_window (end
+ amount
);
627 if (!scroll_region_ok
)
628 ins_del_lines (end
, -amount
);
629 ins_del_lines (from
, amount
);
630 set_terminal_window (0);
632 rotate_vector (current_frame
->glyphs
+ from
,
633 sizeof (GLYPH
*) * (end
+ amount
- from
),
634 amount
* sizeof (GLYPH
*));
636 rotate_vector (current_frame
->charstarts
+ from
,
637 sizeof (int *) * (end
+ amount
- from
),
638 amount
* sizeof (int *));
640 safe_bcopy (current_frame
->used
+ from
,
641 current_frame
->used
+ from
+ amount
,
642 (end
- from
) * sizeof current_frame
->used
[0]);
644 safe_bcopy (current_frame
->highlight
+ from
,
645 current_frame
->highlight
+ from
+ amount
,
646 (end
- from
) * sizeof current_frame
->highlight
[0]);
648 safe_bcopy (current_frame
->enable
+ from
,
649 current_frame
->enable
+ from
+ amount
,
650 (end
- from
) * sizeof current_frame
->enable
[0]);
652 /* Adjust the lines by an amount
653 that puts the first of them at NEWPOS. */
654 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
656 /* Offset each char position in the charstarts lines we moved
658 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
660 int *line
= current_frame
->charstarts
[i
];
662 for (col
= 0; col
< width
; col
++)
664 line
[col
] += pos_adjust
;
666 for (i
= from
; i
< from
+ amount
; i
++)
668 int *line
= current_frame
->charstarts
[i
];
671 for (col
= 0; col
< width
; col
++)
675 /* Mark the lines made empty by scrolling as enabled, empty and
677 bzero (current_frame
->used
+ from
,
678 amount
* sizeof current_frame
->used
[0]);
679 bzero (current_frame
->highlight
+ from
,
680 amount
* sizeof current_frame
->highlight
[0]);
681 for (i
= from
; i
< from
+ amount
; i
++)
683 current_frame
->glyphs
[i
][0] = '\0';
684 current_frame
->charstarts
[i
][0] = -1;
685 current_frame
->enable
[i
] = 1;
688 safe_bcopy (current_frame
->bufp
+ from
,
689 current_frame
->bufp
+ from
+ amount
,
690 (end
- from
) * sizeof current_frame
->bufp
[0]);
692 #ifdef HAVE_WINDOW_SYSTEM
693 if (FRAME_WINDOW_P (frame
))
695 safe_bcopy (current_frame
->top_left_x
+ from
,
696 current_frame
->top_left_x
+ from
+ amount
,
697 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
699 safe_bcopy (current_frame
->top_left_y
+ from
,
700 current_frame
->top_left_y
+ from
+ amount
,
701 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
703 safe_bcopy (current_frame
->pix_width
+ from
,
704 current_frame
->pix_width
+ from
+ amount
,
705 (end
- from
) * sizeof current_frame
->pix_width
[0]);
707 safe_bcopy (current_frame
->pix_height
+ from
,
708 current_frame
->pix_height
+ from
+ amount
,
709 (end
- from
) * sizeof current_frame
->pix_height
[0]);
711 safe_bcopy (current_frame
->max_ascent
+ from
,
712 current_frame
->max_ascent
+ from
+ amount
,
713 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
715 #endif /* HAVE_WINDOW_SYSTEM */
721 update_begin (frame
);
722 set_terminal_window (end
);
723 ins_del_lines (from
+ amount
, amount
);
724 if (!scroll_region_ok
)
725 ins_del_lines (end
+ amount
, -amount
);
726 set_terminal_window (0);
728 rotate_vector (current_frame
->glyphs
+ from
+ amount
,
729 sizeof (GLYPH
*) * (end
- from
- amount
),
730 amount
* sizeof (GLYPH
*));
732 rotate_vector (current_frame
->charstarts
+ from
+ amount
,
733 sizeof (int *) * (end
- from
- amount
),
734 amount
* sizeof (int *));
736 safe_bcopy (current_frame
->used
+ from
,
737 current_frame
->used
+ from
+ amount
,
738 (end
- from
) * sizeof current_frame
->used
[0]);
740 safe_bcopy (current_frame
->highlight
+ from
,
741 current_frame
->highlight
+ from
+ amount
,
742 (end
- from
) * sizeof current_frame
->highlight
[0]);
744 safe_bcopy (current_frame
->enable
+ from
,
745 current_frame
->enable
+ from
+ amount
,
746 (end
- from
) * sizeof current_frame
->enable
[0]);
748 /* Adjust the lines by an amount
749 that puts the first of them at NEWPOS. */
750 pos_adjust
= newpos
- current_frame
->charstarts
[from
+ amount
][0];
752 /* Offset each char position in the charstarts lines we moved
754 for (i
= from
+ amount
; i
< end
+ amount
; i
++)
756 int *line
= current_frame
->charstarts
[i
];
758 for (col
= 0; col
< width
; col
++)
760 line
[col
] += pos_adjust
;
762 for (i
= end
+ amount
; i
< end
; i
++)
764 int *line
= current_frame
->charstarts
[i
];
767 for (col
= 0; col
< width
; col
++)
771 /* Mark the lines made empty by scrolling as enabled, empty and
773 bzero (current_frame
->used
+ end
+ amount
,
774 - amount
* sizeof current_frame
->used
[0]);
775 bzero (current_frame
->highlight
+ end
+ amount
,
776 - amount
* sizeof current_frame
->highlight
[0]);
777 for (i
= end
+ amount
; i
< end
; i
++)
779 current_frame
->glyphs
[i
][0] = '\0';
780 current_frame
->charstarts
[i
][0] = 0;
781 current_frame
->enable
[i
] = 1;
784 safe_bcopy (current_frame
->bufp
+ from
,
785 current_frame
->bufp
+ from
+ amount
,
786 (end
- from
) * sizeof current_frame
->bufp
[0]);
788 #ifdef HAVE_WINDOW_SYSTEM
789 if (FRAME_WINDOW_P (frame
))
791 safe_bcopy (current_frame
->top_left_x
+ from
,
792 current_frame
->top_left_x
+ from
+ amount
,
793 (end
- from
) * sizeof current_frame
->top_left_x
[0]);
795 safe_bcopy (current_frame
->top_left_y
+ from
,
796 current_frame
->top_left_y
+ from
+ amount
,
797 (end
- from
) * sizeof current_frame
->top_left_y
[0]);
799 safe_bcopy (current_frame
->pix_width
+ from
,
800 current_frame
->pix_width
+ from
+ amount
,
801 (end
- from
) * sizeof current_frame
->pix_width
[0]);
803 safe_bcopy (current_frame
->pix_height
+ from
,
804 current_frame
->pix_height
+ from
+ amount
,
805 (end
- from
) * sizeof current_frame
->pix_height
[0]);
807 safe_bcopy (current_frame
->max_ascent
+ from
,
808 current_frame
->max_ascent
+ from
+ amount
,
809 (end
- from
) * sizeof current_frame
->max_ascent
[0]);
811 #endif /* HAVE_WINDOW_SYSTEM */
818 /* After updating a window W that isn't the full frame wide,
819 copy all the columns that W does not occupy
820 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
821 so that update_frame will not change those columns. */
823 preserve_other_columns (w
)
827 register struct frame_glyphs
*current_frame
, *desired_frame
;
828 register FRAME_PTR frame
= XFRAME (w
->frame
);
829 int start
= WINDOW_LEFT_MARGIN (w
);
830 int end
= WINDOW_RIGHT_EDGE (w
);
831 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
833 current_frame
= FRAME_CURRENT_GLYPHS (frame
);
834 desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
836 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
838 if (current_frame
->enable
[vpos
] && desired_frame
->enable
[vpos
])
844 bcopy (current_frame
->glyphs
[vpos
],
845 desired_frame
->glyphs
[vpos
],
846 start
* sizeof (current_frame
->glyphs
[vpos
][0]));
847 bcopy (current_frame
->charstarts
[vpos
],
848 desired_frame
->charstarts
[vpos
],
849 start
* sizeof (current_frame
->charstarts
[vpos
][0]));
850 len
= min (start
, current_frame
->used
[vpos
]);
851 if (desired_frame
->used
[vpos
] < len
)
852 desired_frame
->used
[vpos
] = len
;
854 if (current_frame
->used
[vpos
] > end
855 && desired_frame
->used
[vpos
] < current_frame
->used
[vpos
])
857 while (desired_frame
->used
[vpos
] < end
)
859 int used
= desired_frame
->used
[vpos
]++;
860 desired_frame
->glyphs
[vpos
][used
] = SPACEGLYPH
;
861 desired_frame
->glyphs
[vpos
][used
] = 0;
863 bcopy (current_frame
->glyphs
[vpos
] + end
,
864 desired_frame
->glyphs
[vpos
] + end
,
865 ((current_frame
->used
[vpos
] - end
)
866 * sizeof (current_frame
->glyphs
[vpos
][0])));
867 bcopy (current_frame
->charstarts
[vpos
] + end
,
868 desired_frame
->charstarts
[vpos
] + end
,
869 ((current_frame
->used
[vpos
] - end
)
870 * sizeof (current_frame
->charstarts
[vpos
][0])));
871 desired_frame
->used
[vpos
] = current_frame
->used
[vpos
];
879 /* If window w does not need to be updated and isn't the full frame wide,
880 copy all the columns that w does occupy
881 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
882 so that update_frame will not change those columns.
884 Have not been able to figure out how to use this correctly. */
886 preserve_my_columns (w
)
889 register int vpos
, fin
;
890 register struct frame_glyphs
*l1
, *l2
;
891 register FRAME_PTR frame
= XFRAME (w
->frame
);
892 int start
= WINDOW_LEFT_MARGIN (w
);
893 int end
= WINDOW_RIGHT_EDGE (w
);
894 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
896 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
898 if ((l1
= FRAME_DESIRED_GLYPHS (frame
)->glyphs
[vpos
+ 1])
899 && (l2
= FRAME_PHYS_GLYPHS (frame
)->glyphs
[vpos
+ 1]))
901 if (l2
->length
> start
&& l1
->length
< l2
->length
)
904 if (fin
> end
) fin
= end
;
905 while (l1
->length
< start
)
906 l1
->body
[l1
->length
++] = ' ';
907 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
916 /* Adjust by ADJUST the charstart values in window W
917 after vpos VPOS, which counts relative to the frame
918 (not relative to W itself). */
921 adjust_window_charstarts (w
, vpos
, adjust
)
926 int left
= WINDOW_LEFT_MARGIN (w
);
927 int top
= XFASTINT (w
->top
);
928 int right
= left
+ window_internal_width (w
);
929 int bottom
= top
+ window_internal_height (w
);
932 for (i
= vpos
+ 1; i
< bottom
; i
++)
935 = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w
)))->charstarts
[i
];
937 for (j
= left
; j
< right
; j
++)
938 if (charstart
[j
] > 0)
939 charstart
[j
] += adjust
;
943 /* Check the charstarts values in the area of window W
944 for internal consistency. We cannot check that they are "right";
945 we can only look for something nonsensical. */
947 verify_charstarts (w
)
950 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
952 int top
= XFASTINT (w
->top
);
953 int bottom
= top
+ window_internal_height (w
);
954 int left
= WINDOW_LEFT_MARGIN (w
);
955 int right
= left
+ window_internal_width (w
);
957 int truncate
= (XINT (w
->hscroll
)
958 || (truncate_partial_width_windows
959 && !WINDOW_FULL_WIDTH_P (w
))
960 || !NILP (XBUFFER (w
->buffer
)->truncate_lines
));
962 for (i
= top
; i
< bottom
; i
++)
966 int *charstart
= FRAME_CURRENT_GLYPHS (f
)->charstarts
[i
];
972 /* If we are truncating lines, allow a jump
973 in charstarts from one line to the next. */
974 if (charstart
[left
] < next_line
)
979 if (charstart
[left
] != next_line
)
984 for (j
= left
; j
< right
; j
++)
985 if (charstart
[j
] > 0)
987 /* Record where the next line should start. */
989 if (BUF_ZV (XBUFFER (w
->buffer
)) != last
)
991 /* If there's a newline between the two lines, count that. */
992 int endchar
= *BUF_CHAR_ADDRESS (XBUFFER (w
->buffer
), last
);
999 /* On discovering that the redisplay for a window was no good,
1000 cancel the columns of that window, so that when the window is
1001 displayed over again get_display_line will not complain. */
1003 cancel_my_columns (w
)
1007 register struct frame_glyphs
*desired_glyphs
1008 = FRAME_DESIRED_GLYPHS (XFRAME (w
->frame
));
1009 register int start
= WINDOW_LEFT_MARGIN (w
);
1010 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
1012 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
1013 if (desired_glyphs
->enable
[vpos
]
1014 && desired_glyphs
->used
[vpos
] >= start
)
1015 desired_glyphs
->used
[vpos
] = start
;
1018 /* These functions try to perform directly and immediately on the frame
1019 the necessary output for one change in the buffer.
1020 They may return 0 meaning nothing was done if anything is difficult,
1021 or 1 meaning the output was performed properly.
1022 They assume that the frame was up to date before the buffer
1023 change being displayed. They make various other assumptions too;
1024 see command_loop_1 where these are called. */
1027 direct_output_for_insert (g
)
1030 register FRAME_PTR frame
= selected_frame
;
1031 register struct frame_glyphs
*current_frame
1032 = FRAME_CURRENT_GLYPHS (frame
);
1034 #ifndef COMPILER_REGISTER_BUG
1036 #endif /* COMPILER_REGISTER_BUG */
1037 struct window
*w
= XWINDOW (selected_window
);
1038 #ifndef COMPILER_REGISTER_BUG
1040 #endif /* COMPILER_REGISTER_BUG */
1041 int hpos
= FRAME_CURSOR_X (frame
);
1042 #ifndef COMPILER_REGISTER_BUG
1044 #endif /* COMPILER_REGISTER_BUG */
1045 int vpos
= FRAME_CURSOR_Y (frame
);
1047 /* Give up if about to continue line. */
1048 if (hpos
>= WINDOW_LEFT_MARGIN (w
) + window_internal_width (w
) - 1
1050 /* Avoid losing if cursor is in invisible text off left margin */
1051 || (XINT (w
->hscroll
) && hpos
== WINDOW_LEFT_MARGIN (w
))
1053 /* Give up if cursor outside window (in minibuf, probably) */
1054 || cursor_in_echo_area
1055 || FRAME_CURSOR_Y (frame
) < XFASTINT (w
->top
)
1056 || FRAME_CURSOR_Y (frame
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
1058 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
1059 || !display_completed
1061 /* Give up if buffer appears in two places. */
1062 || buffer_shared
> 1
1064 #ifdef USE_TEXT_PROPERTIES
1065 /* Intervals have already been adjusted, point is after the
1066 character that was just inserted. */
1067 /* Give up if character is invisible. */
1068 /* Give up if character has a face property.
1069 At the moment we only lose at end of line or end of buffer
1070 and only with faces that have some background */
1071 /* Instead of wasting time, give up if character has any text properties */
1072 || ! NILP (Ftext_properties_at (make_number (PT
- 1), Qnil
))
1075 /* Give up if w is minibuffer and a message is being displayed there */
1076 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
1084 if (FRAME_WINDOW_P (frame
) || FRAME_MSDOS_P (frame
))
1085 face
= compute_char_face (frame
, w
, PT
- 1, -1, -1, &dummy
, PT
, 0);
1087 current_frame
->glyphs
[vpos
][hpos
] = MAKE_GLYPH (frame
, g
, face
);
1088 current_frame
->charstarts
[vpos
][hpos
] = PT
- 1;
1089 /* Record the entry for after the newly inserted character. */
1090 current_frame
->charstarts
[vpos
][hpos
+ 1] = PT
;
1091 adjust_window_charstarts (w
, vpos
, 1);
1093 unchanged_modified
= MODIFF
;
1094 beg_unchanged
= GPT
- BEG
;
1095 XSETFASTINT (w
->last_point
, PT
);
1096 XSETFASTINT (w
->last_point_x
, hpos
);
1097 XSETFASTINT (w
->last_modified
, MODIFF
);
1098 XSETFASTINT (w
->last_overlay_modified
, OVERLAY_MODIFF
);
1100 reassert_line_highlight (0, vpos
);
1101 write_glyphs (¤t_frame
->glyphs
[vpos
][hpos
], 1);
1103 ++FRAME_CURSOR_X (frame
);
1104 if (hpos
== current_frame
->used
[vpos
])
1106 current_frame
->used
[vpos
] = hpos
+ 1;
1107 current_frame
->glyphs
[vpos
][hpos
+ 1] = 0;
1114 direct_output_forward_char (n
)
1117 register FRAME_PTR frame
= selected_frame
;
1118 register struct window
*w
= XWINDOW (selected_window
);
1119 Lisp_Object position
;
1120 /* This check is redundant. It's checked at "losing cursor" below. */
1122 int hpos
= FRAME_CURSOR_X (frame
);
1124 /* Give up if in truncated text at end of line. */
1125 if (hpos
>= WINDOW_LEFT_MARGIN (w
) + window_internal_width (w
) - 1)
1129 /* Give up if the buffer's direction is reversed (i.e. right-to-left). */
1130 if (!NILP (XBUFFER(w
->buffer
)->direction_reversed
))
1133 /* Avoid losing if cursor is in invisible text off left margin
1134 or about to go off either side of window. */
1135 if ((FRAME_CURSOR_X (frame
) == WINDOW_LEFT_MARGIN (w
)
1136 && (XINT (w
->hscroll
) || n
< 0))
1138 && (FRAME_CURSOR_X (frame
) + 1
1139 >= XFASTINT (w
->left
) + window_internal_width (w
) - 1))
1140 /* BUG FIX: Added "XFASTINT (w->left)". Without this,
1141 direct_output_forward_char() always fails on "the right"
1143 || cursor_in_echo_area
)
1146 /* Can't use direct output if highlighting a region. */
1147 if (!NILP (Vtransient_mark_mode
) && !NILP (current_buffer
->mark_active
))
1150 /* Can't use direct output at an overlay boundary; it might have
1151 before-string or after-string properties. */
1152 if (overlay_touches_p (PT
) || overlay_touches_p (PT
- n
))
1155 #ifdef USE_TEXT_PROPERTIES
1156 /* Don't use direct output next to an invisible character
1157 since we might need to do something special. */
1159 XSETFASTINT (position
, PT
);
1160 if (XFASTINT (position
) < ZV
1161 && ! NILP (Fget_char_property (position
,
1166 XSETFASTINT (position
, PT
- 1);
1167 if (XFASTINT (position
) >= BEGV
1168 && ! NILP (Fget_char_property (position
,
1174 FRAME_CURSOR_X (frame
) += n
;
1175 XSETFASTINT (w
->last_point_x
, FRAME_CURSOR_X (frame
));
1176 XSETFASTINT (w
->last_point
, PT
);
1177 cursor_to (FRAME_CURSOR_Y (frame
), FRAME_CURSOR_X (frame
));
1183 static void update_line ();
1185 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
1186 Value is nonzero if redisplay stopped due to pending input.
1187 FORCE nonzero means do not stop for pending input. */
1190 update_frame (f
, force
, inhibit_hairy_id
)
1193 int inhibit_hairy_id
;
1195 register struct frame_glyphs
*current_frame
;
1196 register struct frame_glyphs
*desired_frame
= 0;
1199 int preempt_count
= baud_rate
/ 2400 + 1;
1200 extern input_pending
;
1201 #ifdef HAVE_WINDOW_SYSTEM
1202 register int downto
, leftmost
;
1205 if (baud_rate
!= FRAME_COST_BAUD_RATE (f
))
1206 calculate_costs (f
);
1208 if (preempt_count
<= 0)
1211 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1213 detect_input_pending ();
1214 if (input_pending
&& !force
)
1222 if (!line_ins_del_ok
)
1223 inhibit_hairy_id
= 1;
1225 /* These are separate to avoid a possible bug in the AIX C compiler. */
1226 current_frame
= FRAME_CURRENT_GLYPHS (f
);
1227 desired_frame
= FRAME_DESIRED_GLYPHS (f
);
1229 /* See if any of the desired lines are enabled; don't compute for
1230 i/d line if just want cursor motion. */
1231 for (i
= 0; i
< FRAME_HEIGHT (f
); i
++)
1232 if (desired_frame
->enable
[i
])
1235 /* Try doing i/d line, if not yet inhibited. */
1236 if (!inhibit_hairy_id
&& i
< FRAME_HEIGHT (f
))
1237 force
|= scrolling (f
);
1239 /* Update the individual lines as needed. Do bottom line first. */
1241 if (desired_frame
->enable
[FRAME_HEIGHT (f
) - 1])
1242 update_line (f
, FRAME_HEIGHT (f
) - 1);
1244 #ifdef HAVE_WINDOW_SYSTEM
1245 if (FRAME_WINDOW_P (f
))
1247 leftmost
= downto
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1248 if (desired_frame
->enable
[0])
1250 current_frame
->top_left_x
[FRAME_HEIGHT (f
) - 1] = leftmost
;
1251 current_frame
->top_left_y
[FRAME_HEIGHT (f
) - 1]
1252 = PIXEL_HEIGHT (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
)
1253 - current_frame
->pix_height
[FRAME_HEIGHT (f
) - 1];
1254 current_frame
->top_left_x
[0] = leftmost
;
1255 current_frame
->top_left_y
[0] = downto
;
1258 #endif /* HAVE_WINDOW_SYSTEM */
1260 /* Now update the rest of the lines. */
1261 for (i
= 0; i
< FRAME_HEIGHT (f
) - 1 && (force
|| !input_pending
); i
++)
1263 if (desired_frame
->enable
[i
])
1265 if (FRAME_TERMCAP_P (f
))
1267 /* Flush out every so many lines.
1268 Also flush out if likely to have more than 1k buffered
1269 otherwise. I'm told that some telnet connections get
1270 really screwed by more than 1k output at once. */
1271 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1273 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1276 if (preempt_count
== 1)
1278 #ifdef EMACS_OUTQSIZE
1279 if (EMACS_OUTQSIZE (0, &outq
) < 0)
1280 /* Probably not a tty. Ignore the error and reset
1281 * the outq count. */
1282 outq
= PENDING_OUTPUT_COUNT (stdout
);
1285 if (baud_rate
<= outq
&& baud_rate
> 0)
1286 sleep (outq
/ baud_rate
);
1291 if ((i
- 1) % preempt_count
== 0)
1292 detect_input_pending ();
1295 #ifdef HAVE_WINDOW_SYSTEM
1296 if (FRAME_WINDOW_P (f
))
1298 current_frame
->top_left_y
[i
] = downto
;
1299 current_frame
->top_left_x
[i
] = leftmost
;
1301 #endif /* HAVE_WINDOW_SYSTEM */
1304 #ifdef HAVE_WINDOW_SYSTEM
1305 if (FRAME_WINDOW_P (f
))
1306 downto
+= current_frame
->pix_height
[i
];
1307 #endif /* HAVE_WINDOW_SYSTEM */
1309 pause
= (i
< FRAME_HEIGHT (f
) - 1) ? i
: 0;
1311 /* Now just clean up termcap drivers and set cursor, etc. */
1314 if ((cursor_in_echo_area
1315 /* If we are showing a message instead of the minibuffer,
1316 show the cursor for the message instead of for the
1317 (now hidden) minibuffer contents. */
1318 || (EQ (minibuf_window
, selected_window
)
1319 && EQ (minibuf_window
, echo_area_window
)
1320 && echo_area_glyphs
!= 0))
1321 /* These cases apply only to the frame that contains
1322 the active minibuffer window. */
1323 && FRAME_HAS_MINIBUF_P (f
)
1324 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
1326 int top
= XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f
))->top
);
1329 if (cursor_in_echo_area
< 0)
1336 /* If the minibuffer is several lines high, find the last
1337 line that has any text on it. */
1338 row
= FRAME_HEIGHT (f
);
1342 if (current_frame
->enable
[row
])
1343 col
= current_frame
->used
[row
];
1347 while (row
> top
&& col
== 0);
1349 if (col
>= FRAME_WINDOW_WIDTH (f
))
1352 if (row
< FRAME_HEIGHT (f
) - 1)
1357 cursor_to (row
, col
);
1360 cursor_to (FRAME_CURSOR_Y (f
),
1361 max (min (FRAME_CURSOR_X (f
),
1362 FRAME_WINDOW_WIDTH (f
) - 1), 0));
1368 fflush (termscript
);
1371 /* Here if output is preempted because input is detected. */
1374 if (FRAME_HEIGHT (f
) == 0) abort (); /* Some bug zeros some core */
1375 display_completed
= !pause
;
1377 bzero (FRAME_DESIRED_GLYPHS (f
)->enable
, FRAME_HEIGHT (f
));
1381 /* Called when about to quit, to check for doing so
1382 at an improper time. */
1388 if (FRAME_DESIRED_GLYPHS (selected_frame
) == 0)
1390 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[0])
1392 if (FRAME_DESIRED_GLYPHS (selected_frame
)->enable
[FRAME_HEIGHT (selected_frame
) - 1])
1397 /* Decide what insert/delete line to do, and do it */
1399 extern void scrolling_1 ();
1404 int unchanged_at_top
, unchanged_at_bottom
;
1407 int *old_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1408 int *new_hash
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1409 int *draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1410 int *old_draw_cost
= (int *) alloca (FRAME_HEIGHT (frame
) * sizeof (int));
1412 int free_at_end_vpos
= FRAME_HEIGHT (frame
);
1413 register struct frame_glyphs
*current_frame
= FRAME_CURRENT_GLYPHS (frame
);
1414 register struct frame_glyphs
*desired_frame
= FRAME_DESIRED_GLYPHS (frame
);
1416 /* Compute hash codes of all the lines.
1417 Also calculate number of changed lines,
1418 number of unchanged lines at the beginning,
1419 and number of unchanged lines at the end. */
1422 unchanged_at_top
= 0;
1423 unchanged_at_bottom
= FRAME_HEIGHT (frame
);
1424 for (i
= 0; i
< FRAME_HEIGHT (frame
); i
++)
1426 /* Give up on this scrolling if some old lines are not enabled. */
1427 if (!current_frame
->enable
[i
])
1429 old_hash
[i
] = line_hash_code (current_frame
, i
);
1430 if (! desired_frame
->enable
[i
])
1432 /* This line cannot be redrawn, so don't let scrolling mess it. */
1433 new_hash
[i
] = old_hash
[i
];
1434 #define INFINITY 1000000 /* Taken from scroll.c */
1435 draw_cost
[i
] = INFINITY
;
1439 new_hash
[i
] = line_hash_code (desired_frame
, i
);
1440 draw_cost
[i
] = line_draw_cost (desired_frame
, i
);
1443 if (old_hash
[i
] != new_hash
[i
])
1446 unchanged_at_bottom
= FRAME_HEIGHT (frame
) - i
- 1;
1448 else if (i
== unchanged_at_top
)
1450 old_draw_cost
[i
] = line_draw_cost (current_frame
, i
);
1453 /* If changed lines are few, don't allow preemption, don't scroll. */
1454 if (!scroll_region_ok
&& changed_lines
< baud_rate
/ 2400
1455 || unchanged_at_bottom
== FRAME_HEIGHT (frame
))
1458 window_size
= (FRAME_HEIGHT (frame
) - unchanged_at_top
1459 - unchanged_at_bottom
);
1461 if (scroll_region_ok
)
1462 free_at_end_vpos
-= unchanged_at_bottom
;
1463 else if (memory_below_frame
)
1464 free_at_end_vpos
= -1;
1466 /* If large window, fast terminal and few lines in common between
1467 current frame and desired frame, don't bother with i/d calc. */
1468 if (!scroll_region_ok
&& window_size
>= 18 && baud_rate
> 2400
1470 10 * scrolling_max_lines_saved (unchanged_at_top
,
1471 FRAME_HEIGHT (frame
) - unchanged_at_bottom
,
1472 old_hash
, new_hash
, draw_cost
)))
1475 scrolling_1 (frame
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1476 draw_cost
+ unchanged_at_top
- 1,
1477 old_draw_cost
+ unchanged_at_top
- 1,
1478 old_hash
+ unchanged_at_top
- 1,
1479 new_hash
+ unchanged_at_top
- 1,
1480 free_at_end_vpos
- unchanged_at_top
);
1485 /* Return the offset in its buffer of the character at location col, line
1486 in the given window. */
1488 buffer_posn_from_coords (window
, col
, line
)
1489 struct window
*window
;
1492 int hscroll
= XINT (window
->hscroll
);
1493 int window_left
= WINDOW_LEFT_MARGIN (window
);
1495 /* The actual width of the window is window->width less one for the
1496 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1498 int window_width
= window_internal_width (window
) - 1;
1500 int startp
= marker_position (window
->start
);
1502 /* Since compute_motion will only operate on the current buffer,
1503 we need to save the old one and restore it when we're done. */
1504 struct buffer
*old_current_buffer
= current_buffer
;
1505 struct position
*posn
;
1507 current_buffer
= XBUFFER (window
->buffer
);
1509 /* We can't get a correct result in this case,
1510 but at least prevent compute_motion from crashing. */
1514 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
1515 (window->frame))->bufp to avoid scanning from the very top of
1516 the window, but it isn't maintained correctly, and I'm not even
1517 sure I will keep it. */
1518 posn
= compute_motion (startp
, 0,
1519 ((window
== XWINDOW (minibuf_window
) && startp
== BEG
1520 ? minibuf_prompt_width
: 0)
1521 + (hscroll
? 1 - hscroll
: 0)),
1524 window_width
, hscroll
, 0, window
);
1526 current_buffer
= old_current_buffer
;
1528 /* compute_motion considers frame points past the end of a line
1529 to be *after* the newline, i.e. at the start of the next line.
1530 This is reasonable, but not really what we want. So if the
1531 result is on a line below LINE, back it up one character. */
1532 if (posn
->vpos
> line
)
1533 return posn
->bufpos
- 1;
1535 return posn
->bufpos
;
1542 register GLYPH
*p
= r
;
1543 while (*p
++ == SPACEGLYPH
);
1548 count_match (str1
, str2
)
1551 register GLYPH
*p1
= str1
;
1552 register GLYPH
*p2
= str2
;
1553 while (*p1
++ == *p2
++);
1554 return p1
- str1
- 1;
1557 /* Char insertion/deletion cost vector, from term.c */
1558 extern int *char_ins_del_vector
;
1560 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))])
1563 update_line (frame
, vpos
)
1564 register FRAME_PTR frame
;
1567 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1570 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1572 register struct frame_glyphs
*current_frame
1573 = FRAME_CURRENT_GLYPHS (frame
);
1574 register struct frame_glyphs
*desired_frame
1575 = FRAME_DESIRED_GLYPHS (frame
);
1577 if (desired_frame
->highlight
[vpos
]
1578 != (current_frame
->enable
[vpos
] && current_frame
->highlight
[vpos
]))
1580 change_line_highlight (desired_frame
->highlight
[vpos
], vpos
,
1581 (current_frame
->enable
[vpos
] ?
1582 current_frame
->used
[vpos
] : 0));
1583 current_frame
->enable
[vpos
] = 0;
1586 reassert_line_highlight (desired_frame
->highlight
[vpos
], vpos
);
1588 if (! current_frame
->enable
[vpos
])
1594 obody
= current_frame
->glyphs
[vpos
];
1595 olen
= current_frame
->used
[vpos
];
1596 if (! current_frame
->highlight
[vpos
])
1598 if (!must_write_spaces
)
1599 while (olen
> 0 && obody
[olen
- 1] == SPACEGLYPH
)
1604 /* For an inverse-video line, remember we gave it
1605 spaces all the way to the frame edge
1606 so that the reverse video extends all the way across. */
1608 while (olen
< FRAME_WINDOW_WIDTH (frame
) - 1)
1609 obody
[olen
++] = SPACEGLYPH
;
1613 /* One way or another, this will enable the line being updated. */
1614 current_frame
->enable
[vpos
] = 1;
1615 current_frame
->used
[vpos
] = desired_frame
->used
[vpos
];
1616 current_frame
->highlight
[vpos
] = desired_frame
->highlight
[vpos
];
1617 current_frame
->bufp
[vpos
] = desired_frame
->bufp
[vpos
];
1619 #ifdef HAVE_WINDOW_SYSTEM
1620 if (FRAME_WINDOW_P (frame
))
1622 current_frame
->pix_width
[vpos
]
1623 = current_frame
->used
[vpos
]
1624 * FONT_WIDTH (FRAME_FONT (frame
));
1625 current_frame
->pix_height
[vpos
]
1626 = FRAME_LINE_HEIGHT (frame
);
1628 #endif /* HAVE_WINDOW_SYSTEM */
1630 if (!desired_frame
->enable
[vpos
])
1636 nbody
= desired_frame
->glyphs
[vpos
];
1637 nlen
= desired_frame
->used
[vpos
];
1639 /* Pretend trailing spaces are not there at all,
1640 unless for one reason or another we must write all spaces. */
1641 if (! desired_frame
->highlight
[vpos
])
1643 if (!must_write_spaces
)
1644 /* We know that the previous character byte contains 0. */
1645 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1650 /* For an inverse-video line, give it extra trailing spaces
1651 all the way to the frame edge
1652 so that the reverse video extends all the way across. */
1654 while (nlen
< FRAME_WINDOW_WIDTH (frame
) - 1)
1655 nbody
[nlen
++] = SPACEGLYPH
;
1658 /* If there's no i/d char, quickly do the best we can without it. */
1659 if (!char_ins_del_ok
)
1664 if (FRAME_X_P (frame
))
1666 /* Under X, erase everything we are going to rewrite,
1667 and rewrite everything from the first char that's changed.
1668 This is part of supporting fonts like Courier
1669 whose chars can overlap outside the char width. */
1670 for (i
= 0; i
< nlen
; i
++)
1671 if (i
>= olen
|| nbody
[i
] != obody
[i
])
1674 cursor_to (vpos
, i
);
1676 clear_end_of_line (olen
);
1677 write_glyphs (nbody
+ i
, nlen
- i
);
1682 for (i
= 0; i
< nlen
; i
++)
1684 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1686 cursor_to (vpos
, i
);
1689 && (i
+ j
>= olen
|| nbody
[i
+ j
] != obody
[i
+ j
]
1690 || (nbody
[i
+ j
] & GLYPH_MASK_PADDING
)));
1693 /* Output this run of non-matching chars. */
1694 write_glyphs (nbody
+ i
, j
);
1697 /* Now find the next non-match. */
1701 /* Clear the rest of the line, or the non-clear part of it. */
1704 cursor_to (vpos
, nlen
);
1705 clear_end_of_line (olen
);
1708 /* Exchange contents between current_frame and new_frame. */
1709 temp
= desired_frame
->glyphs
[vpos
];
1710 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1711 current_frame
->glyphs
[vpos
] = temp
;
1713 /* Exchange charstarts between current_frame and new_frame. */
1714 temp1
= desired_frame
->charstarts
[vpos
];
1715 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1716 current_frame
->charstarts
[vpos
] = temp1
;
1723 nsp
= (must_write_spaces
|| desired_frame
->highlight
[vpos
])
1724 ? 0 : count_blanks (nbody
);
1727 cursor_to (vpos
, nsp
);
1728 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1731 /* Exchange contents between current_frame and new_frame. */
1732 temp
= desired_frame
->glyphs
[vpos
];
1733 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1734 current_frame
->glyphs
[vpos
] = temp
;
1736 /* Exchange charstarts between current_frame and new_frame. */
1737 temp1
= desired_frame
->charstarts
[vpos
];
1738 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1739 current_frame
->charstarts
[vpos
] = temp1
;
1748 /* Compute number of leading blanks in old and new contents. */
1749 osp
= count_blanks (obody
);
1750 if (!desired_frame
->highlight
[vpos
])
1751 nsp
= count_blanks (nbody
);
1755 /* Compute number of matching chars starting with first nonblank. */
1756 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1758 /* Spaces in new match implicit space past the end of old. */
1759 /* A bug causing this to be a no-op was fixed in 18.29. */
1760 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1763 while (np1
[begmatch
] == SPACEGLYPH
)
1767 /* Avoid doing insert/delete char
1768 just cause number of leading spaces differs
1769 when the following text does not match. */
1770 if (begmatch
== 0 && osp
!= nsp
)
1771 osp
= nsp
= min (osp
, nsp
);
1773 /* Find matching characters at end of line */
1776 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1777 while (op1
> op2
&& op1
[-1] == np1
[-1])
1782 endmatch
= obody
+ olen
- op1
;
1784 /* Put correct value back in nbody[nlen].
1785 This is important because direct_output_for_insert
1786 can write into the line at a later point.
1787 If this screws up the zero at the end of the line, re-establish it. */
1791 /* tem gets the distance to insert or delete.
1792 endmatch is how many characters we save by doing so.
1795 tem
= (nlen
- nsp
) - (olen
- osp
);
1797 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (frame
)[tem
]))
1800 /* nsp - osp is the distance to insert or delete.
1801 If that is nonzero, begmatch is known to be nonzero also.
1802 begmatch + endmatch is how much we save by doing the ins/del.
1806 && (!char_ins_del_ok
1807 || begmatch
+ endmatch
<= char_ins_del_cost (frame
)[nsp
- osp
]))
1811 osp
= nsp
= min (osp
, nsp
);
1814 /* Now go through the line, inserting, writing and
1815 deleting as appropriate. */
1819 cursor_to (vpos
, nsp
);
1820 delete_glyphs (osp
- nsp
);
1824 /* If going to delete chars later in line
1825 and insert earlier in the line,
1826 must delete first to avoid losing data in the insert */
1827 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1829 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1830 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1831 olen
= nlen
- (nsp
- osp
);
1833 cursor_to (vpos
, osp
);
1834 insert_glyphs ((char *)0, nsp
- osp
);
1838 tem
= nsp
+ begmatch
+ endmatch
;
1839 if (nlen
!= tem
|| olen
!= tem
)
1841 cursor_to (vpos
, nsp
+ begmatch
);
1842 if (!endmatch
|| nlen
== olen
)
1844 /* If new text being written reaches right margin,
1845 there is no need to do clear-to-eol at the end.
1846 (and it would not be safe, since cursor is not
1847 going to be "at the margin" after the text is done) */
1848 if (nlen
== FRAME_WINDOW_WIDTH (frame
))
1850 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1854 /* the following code loses disastrously if tem == nlen.
1855 Rather than trying to fix that case, I am trying the simpler
1856 solution found above. */
1858 /* If the text reaches to the right margin,
1859 it will lose one way or another (depending on AutoWrap)
1860 to clear to end of line after outputting all the text.
1861 So pause with one character to go and clear the line then. */
1862 if (nlen
== FRAME_WINDOW_WIDTH (frame
) && fast_clear_end_of_line
&& olen
> nlen
)
1864 /* endmatch must be zero, and tem must equal nsp + begmatch */
1865 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1866 clear_end_of_line (olen
);
1867 olen
= 0; /* Don't let it be cleared again later */
1868 write_glyphs (nbody
+ nlen
- 1, 1);
1871 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1872 #endif /* OBSOLETE */
1875 else if (nlen
> olen
)
1877 /* Here, we used to have the following simple code:
1878 ----------------------------------------
1879 write_glyphs (nbody + nsp + begmatch, olen - tem);
1880 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
1881 ----------------------------------------
1882 but it doesn't work if nbody[nsp + begmatch + olen - tem]
1883 is a padding glyph. */
1884 int out
= olen
- tem
; /* Columns to be overwritten originally. */
1887 /* Calculate columns we can actually overwrite. */
1888 while (nbody
[nsp
+ begmatch
+ out
] & GLYPH_MASK_PADDING
) out
--;
1889 write_glyphs (nbody
+ nsp
+ begmatch
, out
);
1890 /* If we left columns to be overwritten. we must delete them. */
1891 del
= olen
- tem
- out
;
1892 if (del
> 0) delete_glyphs (del
);
1893 /* At last, we insert columns not yet written out. */
1894 insert_glyphs (nbody
+ nsp
+ begmatch
+ out
, nlen
- olen
+ del
);
1897 else if (olen
> nlen
)
1899 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1900 delete_glyphs (olen
- nlen
);
1906 /* If any unerased characters remain after the new line, erase them. */
1909 cursor_to (vpos
, nlen
);
1910 clear_end_of_line (olen
);
1913 /* Exchange contents between current_frame and new_frame. */
1914 temp
= desired_frame
->glyphs
[vpos
];
1915 desired_frame
->glyphs
[vpos
] = current_frame
->glyphs
[vpos
];
1916 current_frame
->glyphs
[vpos
] = temp
;
1918 /* Exchange charstarts between current_frame and new_frame. */
1919 temp1
= desired_frame
->charstarts
[vpos
];
1920 desired_frame
->charstarts
[vpos
] = current_frame
->charstarts
[vpos
];
1921 current_frame
->charstarts
[vpos
] = temp1
;
1924 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
1925 session's frames, frame names, buffers, buffer-read-only flags, and
1926 buffer-modified-flags, and a trailing sentinel (so we don't need to
1927 add length checks). */
1928 static Lisp_Object frame_and_buffer_state
;
1930 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p
,
1931 Sframe_or_buffer_changed_p
, 0, 0, 0,
1932 "Return non-nil if the frame and buffer state appears to have changed.\n\
1933 The state variable is an internal vector containing all frames and buffers,\n\
1934 aside from buffers whose names start with space,\n\
1935 along with the buffers' read-only and modified flags, which allows a fast\n\
1936 check to see whether the menu bars might need to be recomputed.\n\
1937 If this function returns non-nil, it updates the internal vector to reflect\n\
1938 the current state.\n")
1941 Lisp_Object tail
, frame
, buf
;
1945 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1946 FOR_EACH_FRAME (tail
, frame
)
1948 if (!EQ (*vecp
++, frame
))
1950 if (!EQ (*vecp
++, XFRAME (frame
)->name
))
1953 /* Check that the buffer info matches.
1954 No need to test for the end of the vector
1955 because the last element of the vector is lambda
1956 and that will always cause a mismatch. */
1957 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1959 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1960 /* Ignore buffers that aren't included in buffer lists. */
1961 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1963 if (!EQ (*vecp
++, buf
))
1965 if (!EQ (*vecp
++, XBUFFER (buf
)->read_only
))
1967 if (!EQ (*vecp
++, Fbuffer_modified_p (buf
)))
1970 /* Detect deletion of a buffer at the end of the list. */
1971 if (EQ (*vecp
, Qlambda
))
1974 /* Start with 1 so there is room for at least one lambda at the end. */
1976 FOR_EACH_FRAME (tail
, frame
)
1978 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1980 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
1981 if (n
> XVECTOR (frame_and_buffer_state
)->size
1982 || n
+ 20 < XVECTOR (frame_and_buffer_state
)->size
/ 2)
1983 /* Add 20 extra so we grow it less often. */
1984 frame_and_buffer_state
= Fmake_vector (make_number (n
+ 20), Qlambda
);
1985 vecp
= XVECTOR (frame_and_buffer_state
)->contents
;
1986 FOR_EACH_FRAME (tail
, frame
)
1989 *vecp
++ = XFRAME (frame
)->name
;
1991 for (tail
= Vbuffer_alist
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1993 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
1994 /* Ignore buffers that aren't included in buffer lists. */
1995 if (XSTRING (XBUFFER (buf
)->name
)->data
[0] == ' ')
1998 *vecp
++ = XBUFFER (buf
)->read_only
;
1999 *vecp
++ = Fbuffer_modified_p (buf
);
2001 /* Fill up the vector with lambdas (always at least one). */
2003 while (vecp
- XVECTOR (frame_and_buffer_state
)->contents
2004 < XVECTOR (frame_and_buffer_state
)->size
)
2006 /* Make sure we didn't overflow the vector. */
2007 if (vecp
- XVECTOR (frame_and_buffer_state
)->contents
2008 > XVECTOR (frame_and_buffer_state
)->size
)
2013 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
2014 1, 1, "FOpen termscript file: ",
2015 "Start writing all terminal output to FILE as well as the terminal.\n\
2016 FILE = nil means just close any termscript file currently open.")
2020 if (termscript
!= 0) fclose (termscript
);
2025 file
= Fexpand_file_name (file
, Qnil
);
2026 termscript
= fopen (XSTRING (file
)->data
, "w");
2027 if (termscript
== 0)
2028 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
2036 window_change_signal (signalnum
) /* If we don't have an argument, */
2037 int signalnum
; /* some compilers complain in signal calls. */
2041 int old_errno
= errno
;
2043 get_frame_size (&width
, &height
);
2045 /* The frame size change obviously applies to a termcap-controlled
2046 frame. Find such a frame in the list, and assume it's the only
2047 one (since the redisplay code always writes to stdout, not a
2048 FILE * specified in the frame structure). Record the new size,
2049 but don't reallocate the data structures now. Let that be done
2050 later outside of the signal handler. */
2053 Lisp_Object tail
, frame
;
2055 FOR_EACH_FRAME (tail
, frame
)
2057 if (FRAME_TERMCAP_P (XFRAME (frame
)))
2059 change_frame_size (XFRAME (frame
), height
, width
, 0, 1);
2065 signal (SIGWINCH
, window_change_signal
);
2068 #endif /* SIGWINCH */
2071 /* Do any change in frame size that was requested by a signal. */
2073 do_pending_window_change ()
2075 /* If window_change_signal should have run before, run it now. */
2076 while (delayed_size_change
)
2078 Lisp_Object tail
, frame
;
2080 delayed_size_change
= 0;
2082 FOR_EACH_FRAME (tail
, frame
)
2084 FRAME_PTR f
= XFRAME (frame
);
2086 int height
= FRAME_NEW_HEIGHT (f
);
2087 int width
= FRAME_NEW_WIDTH (f
);
2089 if (height
!= 0 || width
!= 0)
2090 change_frame_size (f
, height
, width
, 0, 0);
2096 /* Change the frame height and/or width. Values may be given as zero to
2097 indicate no change is to take place.
2099 If DELAY is non-zero, then assume we're being called from a signal
2100 handler, and queue the change for later - perhaps the next
2101 redisplay. Since this tries to resize windows, we can't call it
2102 from a signal handler. */
2104 change_frame_size (f
, newheight
, newwidth
, pretend
, delay
)
2105 register FRAME_PTR f
;
2106 int newheight
, newwidth
, pretend
;
2108 Lisp_Object tail
, frame
;
2110 if (! FRAME_WINDOW_P (f
))
2112 /* When using termcap, or on MS-DOS, all frames use
2113 the same screen, so a change in size affects all frames. */
2114 FOR_EACH_FRAME (tail
, frame
)
2115 if (! FRAME_WINDOW_P (XFRAME (frame
)))
2116 change_frame_size_1 (XFRAME (frame
), newheight
, newwidth
,
2120 change_frame_size_1 (f
, newheight
, newwidth
, pretend
, delay
);
2124 change_frame_size_1 (frame
, newheight
, newwidth
, pretend
, delay
)
2125 register FRAME_PTR frame
;
2126 int newheight
, newwidth
, pretend
, delay
;
2128 int new_frame_window_width
;
2129 unsigned int total_glyphs
;
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 /* This isn't quite a no-op: it runs window-configuration-change-hook. */
2237 Fset_window_buffer (FRAME_SELECTED_WINDOW (frame
),
2238 XWINDOW (FRAME_SELECTED_WINDOW (frame
))->buffer
);
2241 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
2242 Ssend_string_to_terminal
, 1, 1, 0,
2243 "Send STRING to the terminal without alteration.\n\
2244 Control characters in STRING will have terminal-dependent effects.")
2248 CHECK_STRING (string
, 0);
2249 fwrite (XSTRING (string
)->data
, 1, XSTRING (string
)->size
, stdout
);
2253 fwrite (XSTRING (string
)->data
, 1, XSTRING (string
)->size
, termscript
);
2254 fflush (termscript
);
2259 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
2260 "Beep, or flash the screen.\n\
2261 Also, unless an argument is given,\n\
2262 terminate any keyboard macro currently executing.")
2284 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
2285 error ("Keyboard macro terminated by a command ringing the bell");
2291 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
2292 "Pause, without updating display, for SECONDS seconds.\n\
2293 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2294 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2295 additional wait period, in milliseconds; this may be useful if your\n\
2296 Emacs was built without floating point support.\n\
2297 \(Not all operating systems support waiting for a fraction of a second.)")
2298 (seconds
, milliseconds
)
2299 Lisp_Object seconds
, milliseconds
;
2303 if (NILP (milliseconds
))
2304 XSETINT (milliseconds
, 0);
2306 CHECK_NUMBER (milliseconds
, 1);
2307 usec
= XINT (milliseconds
) * 1000;
2309 #ifdef LISP_FLOAT_TYPE
2311 double duration
= extract_float (seconds
);
2312 sec
= (int) duration
;
2313 usec
+= (duration
- sec
) * 1000000;
2316 CHECK_NUMBER (seconds
, 0);
2317 sec
= XINT (seconds
);
2320 #ifndef EMACS_HAS_USECS
2321 if (sec
== 0 && usec
!= 0)
2322 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE
);
2325 /* Assure that 0 <= usec < 1000000. */
2328 /* We can't rely on the rounding being correct if user is negative. */
2329 if (-1000000 < usec
)
2330 sec
--, usec
+= 1000000;
2332 sec
-= -usec
/ 1000000, usec
= 1000000 - (-usec
% 1000000);
2335 sec
+= usec
/ 1000000, usec
%= 1000000;
2337 if (sec
< 0 || (sec
== 0 && usec
== 0))
2343 XSETFASTINT (zero
, 0);
2344 wait_reading_process_input (sec
, usec
, zero
, 0);
2347 /* We should always have wait_reading_process_input; we have a dummy
2348 implementation for systems which don't support subprocesses. */
2350 /* No wait_reading_process_input */
2357 /* The reason this is done this way
2358 (rather than defined (H_S) && defined (H_T))
2359 is because the VMS preprocessor doesn't grok `defined' */
2361 EMACS_GET_TIME (end_time
);
2362 EMACS_SET_SECS_USECS (timeout
, sec
, usec
);
2363 EMACS_ADD_TIME (end_time
, end_time
, timeout
);
2367 EMACS_GET_TIME (timeout
);
2368 EMACS_SUB_TIME (timeout
, end_time
, timeout
);
2369 if (EMACS_TIME_NEG_P (timeout
)
2370 || !select (1, 0, 0, 0, &timeout
))
2373 #else /* not HAVE_SELECT */
2375 #endif /* HAVE_SELECT */
2376 #endif /* not VMS */
2379 #endif /* no subprocesses */
2384 /* This is just like wait_reading_process_input, except that
2385 it does the redisplay.
2387 It's also much like Fsit_for, except that it can be used for
2388 waiting for input as well. */
2391 sit_for (sec
, usec
, reading
, display
, initial_display
)
2392 int sec
, usec
, reading
, display
, initial_display
;
2394 Lisp_Object read_kbd
;
2396 swallow_events (display
);
2398 if (detect_input_pending_run_timers (display
))
2401 if (initial_display
)
2402 redisplay_preserve_echo_area ();
2404 if (sec
== 0 && usec
== 0)
2411 XSETINT (read_kbd
, reading
? -1 : 1);
2412 wait_reading_process_input (sec
, usec
, read_kbd
, display
);
2414 return detect_input_pending () ? Qnil
: Qt
;
2417 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
2418 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
2419 SECONDS may be a floating-point value, meaning that you can wait for a\n\
2420 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
2421 additional wait period, in milliseconds; this may be useful if your\n\
2422 Emacs was built without floating point support.\n\
2423 \(Not all operating systems support waiting for a fraction of a second.)\n\
2424 Optional third arg NODISP non-nil means don't redisplay, just wait for input.\n\
2425 Redisplay is preempted as always if input arrives, and does not happen\n\
2426 if input is available before it starts.\n\
2427 Value is t if waited the full time with no input arriving.")
2428 (seconds
, milliseconds
, nodisp
)
2429 Lisp_Object seconds
, milliseconds
, nodisp
;
2433 if (NILP (milliseconds
))
2434 XSETINT (milliseconds
, 0);
2436 CHECK_NUMBER (milliseconds
, 1);
2437 usec
= XINT (milliseconds
) * 1000;
2439 #ifdef LISP_FLOAT_TYPE
2441 double duration
= extract_float (seconds
);
2442 sec
= (int) duration
;
2443 usec
+= (duration
- sec
) * 1000000;
2446 CHECK_NUMBER (seconds
, 0);
2447 sec
= XINT (seconds
);
2450 #ifndef EMACS_HAS_USECS
2451 if (usec
!= 0 && sec
== 0)
2452 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE
);
2455 return sit_for (sec
, usec
, 0, NILP (nodisp
), NILP (nodisp
));
2458 char *terminal_type
;
2460 /* Initialization done when Emacs fork is started, before doing stty. */
2461 /* Determine terminal type and set terminal_driver */
2462 /* Then invoke its decoding routine to set up variables
2463 in the terminal package */
2467 #ifdef HAVE_X_WINDOWS
2468 extern int display_arg
;
2473 cursor_in_echo_area
= 0;
2474 terminal_type
= (char *) 0;
2476 /* Now is the time to initialize this; it's used by init_sys_modes
2478 Vwindow_system
= Qnil
;
2480 /* If the user wants to use a window system, we shouldn't bother
2481 initializing the terminal. This is especially important when the
2482 terminal is so dumb that emacs gives up before and doesn't bother
2483 using the window system.
2485 If the DISPLAY environment variable is set and nonempty,
2486 try to use X, and die with an error message if that doesn't work. */
2488 #ifdef HAVE_X_WINDOWS
2493 display
= getenv ("DECW$DISPLAY");
2495 display
= getenv ("DISPLAY");
2498 display_arg
= (display
!= 0 && *display
!= 0);
2501 if (!inhibit_window_system
&& display_arg
&& initialized
)
2503 Vwindow_system
= intern ("x");
2505 Vwindow_system_version
= make_number (11);
2507 Vwindow_system_version
= make_number (10);
2509 #if defined (LINUX) && defined (HAVE_LIBNCURSES)
2510 /* In some versions of ncurses,
2511 tputs crashes if we have not called tgetent.
2513 { char b
[2044]; tgetent (b
, "xterm");}
2517 #endif /* HAVE_X_WINDOWS */
2520 if (!inhibit_window_system
)
2522 Vwindow_system
= intern ("w32");
2523 Vwindow_system_version
= make_number (1);
2526 #endif /* HAVE_NTGUI */
2528 /* If no window system has been specified, try to use the terminal. */
2531 fatal ("standard input is not a tty");
2535 /* Look at the TERM variable */
2536 terminal_type
= (char *) getenv ("TERM");
2540 fprintf (stderr
, "Please specify your terminal type.\n\
2541 For types defined in VMS, use set term /device=TYPE.\n\
2542 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2543 \(The quotation marks are necessary since terminal types are lower case.)\n");
2545 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2551 /* VMS DCL tends to upcase things, so downcase term type.
2552 Hardly any uppercase letters in terminal types; should be none. */
2554 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2557 strcpy (new, terminal_type
);
2559 for (p
= new; *p
; p
++)
2563 terminal_type
= new;
2567 term_init (terminal_type
);
2570 int width
= FRAME_WINDOW_WIDTH (selected_frame
);
2571 int height
= FRAME_HEIGHT (selected_frame
);
2573 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
2575 /* If these sizes are so big they cause overflow,
2576 just ignore the change. It's not clear what better we could do. */
2577 if (total_glyphs
/ sizeof (GLYPH
) / height
!= width
+ 2)
2578 fatal ("screen size %dx%d too big", width
, height
);
2581 remake_frame_glyphs (selected_frame
);
2582 calculate_costs (selected_frame
);
2584 /* X and Y coordinates of the cursor between updates. */
2585 FRAME_CURSOR_X (selected_frame
) = 0;
2586 FRAME_CURSOR_Y (selected_frame
) = 0;
2591 #endif /* CANNOT_DUMP */
2592 signal (SIGWINCH
, window_change_signal
);
2593 #endif /* SIGWINCH */
2598 defsubr (&Sredraw_frame
);
2599 defsubr (&Sredraw_display
);
2600 defsubr (&Sframe_or_buffer_changed_p
);
2601 defsubr (&Sopen_termscript
);
2603 defsubr (&Ssit_for
);
2604 defsubr (&Ssleep_for
);
2605 defsubr (&Ssend_string_to_terminal
);
2607 frame_and_buffer_state
= Fmake_vector (make_number (20), Qlambda
);
2608 staticpro (&frame_and_buffer_state
);
2610 Qdisplay_table
= intern ("display-table");
2611 staticpro (&Qdisplay_table
);
2613 DEFVAR_INT ("baud-rate", &baud_rate
,
2614 "*The output baud rate of the terminal.\n\
2615 On most systems, changing this value will affect the amount of padding\n\
2616 and the other strategic decisions made during redisplay.");
2617 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2618 "*Non-nil means invert the entire frame display.\n\
2619 This means everything is in inverse video which otherwise would not be.");
2620 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2621 "*Non-nil means try to flash the frame to represent a bell.");
2622 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2623 "*Non-nil means no need to redraw entire frame after suspending.\n\
2624 A non-nil value is useful if the terminal can automatically preserve\n\
2625 Emacs's frame display when you reenter Emacs.\n\
2626 It is up to you to set this variable if your terminal can do that.");
2627 DEFVAR_LISP ("window-system", &Vwindow_system
,
2628 "A symbol naming the window-system under which Emacs is running\n\
2629 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2630 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2631 "The version number of the window system in use.\n\
2632 For X windows, this is 10 or 11.");
2633 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2634 "Non-nil means put cursor in minibuffer, at end of any message there.");
2635 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2636 "Table defining how to output a glyph code to the frame.\n\
2637 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2638 Each element can be:\n\
2639 integer: a glyph code which this glyph is an alias for.\n\
2640 string: output this glyph using that string (not impl. in X windows).\n\
2641 nil: this glyph mod 256 is char code to output,\n\
2642 and this glyph / 256 is face code for X windows (see `face-id').");
2643 Vglyph_table
= Qnil
;
2645 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2646 "Display table to use for buffers that specify none.\n\
2647 See `buffer-display-table' for more information.");
2648 Vstandard_display_table
= Qnil
;
2650 /* Initialize `window-system', unless init_display already decided it. */
2655 Vwindow_system
= Qnil
;
2656 Vwindow_system_version
= Qnil
;