Doc fixes.
[emacs.git] / src / dispnew.c
blobdddee0eef8df66869e6b3c92092a05af3c0f8926
1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 1999
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)
10 any later version.
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. */
22 #include <config.h>
23 #include <signal.h>
24 #include <stdio.h>
25 #include <ctype.h>
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
31 #include "lisp.h"
32 #include "termchar.h"
33 #include "termopts.h"
34 #include "termhooks.h"
35 /* cm.h must come after dispextern.h on Windows. */
36 #include "dispextern.h"
37 #include "cm.h"
38 #include "buffer.h"
39 #include "charset.h"
40 #include "frame.h"
41 #include "window.h"
42 #include "commands.h"
43 #include "disptab.h"
44 #include "indent.h"
45 #include "intervals.h"
46 #include "blockinput.h"
47 #include "process.h"
48 #include "keyboard.h"
50 /* I don't know why DEC Alpha OSF1 fail to compile this file if we
51 include the following file. */
52 /* #include "systty.h" */
53 #include "syssignal.h"
55 #ifdef HAVE_X_WINDOWS
56 #include "xterm.h"
57 #endif /* HAVE_X_WINDOWS */
59 #ifdef HAVE_NTGUI
60 #include "w32term.h"
61 #endif /* HAVE_NTGUI */
63 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
65 #include "systime.h"
66 #include <errno.h>
68 /* To get the prototype for `sleep'. */
70 #ifdef HAVE_UNISTD_H
71 #include <unistd.h>
72 #endif
74 #define max(a, b) ((a) > (b) ? (a) : (b))
75 #define min(a, b) ((a) < (b) ? (a) : (b))
77 /* Get number of chars of output now in the buffer of a stdio stream.
78 This ought to be built in in stdio, but it isn't. Some s- files
79 override this because their stdio internals differ. */
81 #ifdef __GNU_LIBRARY__
83 /* The s- file might have overridden the definition with one that
84 works for the system's C library. But we are using the GNU C
85 library, so this is the right definition for every system. */
87 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
88 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
89 #else
90 #undef PENDING_OUTPUT_COUNT
91 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
92 #endif
93 #else /* not __GNU_LIBRARY__ */
94 #if !defined (PENDING_OUTPUT_COUNT) && HAVE_STDIO_EXT_H && HAVE___FPENDING
95 #include <stdio_ext.h>
96 #define PENDING_OUTPUT_COUNT(FILE) __fpending (FILE)
97 #endif
98 #ifndef PENDING_OUTPUT_COUNT
99 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
100 #endif
101 #endif /* not __GNU_LIBRARY__ */
104 /* Structure to pass dimensions around. Used for character bounding
105 boxes, glyph matrix dimensions and alike. */
107 struct dim
109 int width;
110 int height;
114 /* Function prototypes. */
116 static void redraw_overlapping_rows P_ ((struct window *, int));
117 static void redraw_overlapped_rows P_ ((struct window *, int));
118 static int count_blanks P_ ((struct glyph *, int));
119 static int count_match P_ ((struct glyph *, struct glyph *,
120 struct glyph *, struct glyph *));
121 static unsigned line_draw_cost P_ ((struct glyph_matrix *, int));
122 static void update_frame_line P_ ((struct frame *, int));
123 static struct dim allocate_matrices_for_frame_redisplay
124 P_ ((Lisp_Object, int, int, struct dim, int, int *));
125 static void allocate_matrices_for_window_redisplay P_ ((struct window *,
126 struct dim));
127 static int realloc_glyph_pool P_ ((struct glyph_pool *, struct dim));
128 static void adjust_frame_glyphs P_ ((struct frame *));
129 struct glyph_matrix *new_glyph_matrix P_ ((struct glyph_pool *));
130 static void free_glyph_matrix P_ ((struct glyph_matrix *));
131 static void adjust_glyph_matrix P_ ((struct window *, struct glyph_matrix *,
132 int, int, struct dim));
133 static void change_frame_size_1 P_ ((struct frame *, int, int, int, int, int));
134 static void swap_glyphs_in_rows P_ ((struct glyph_row *, struct glyph_row *));
135 static void swap_glyph_pointers P_ ((struct glyph_row *, struct glyph_row *));
136 static int glyph_row_slice_p P_ ((struct glyph_row *, struct glyph_row *));
137 static void fill_up_frame_row_with_spaces P_ ((struct glyph_row *, int));
138 static void build_frame_matrix_from_window_tree P_ ((struct glyph_matrix *,
139 struct window *));
140 static void build_frame_matrix_from_leaf_window P_ ((struct glyph_matrix *,
141 struct window *));
142 static struct glyph_pool *new_glyph_pool P_ ((void));
143 static void free_glyph_pool P_ ((struct glyph_pool *));
144 static void adjust_frame_glyphs_initially P_ ((void));
145 static void adjust_frame_message_buffer P_ ((struct frame *));
146 static void adjust_decode_mode_spec_buffer P_ ((struct frame *));
147 static void fill_up_glyph_row_with_spaces P_ ((struct glyph_row *));
148 static void build_frame_matrix P_ ((struct frame *));
149 void clear_current_matrices P_ ((struct frame *));
150 void scroll_glyph_matrix_range P_ ((struct glyph_matrix *, int, int,
151 int, int));
152 static void clear_window_matrices P_ ((struct window *, int));
153 static void fill_up_glyph_row_area_with_spaces P_ ((struct glyph_row *, int));
154 static int scrolling_window P_ ((struct window *, int));
155 static int update_window_line P_ ((struct window *, int));
156 static void update_marginal_area P_ ((struct window *, int, int));
157 static int update_text_area P_ ((struct window *, int));
158 static void make_current P_ ((struct glyph_matrix *, struct glyph_matrix *,
159 int));
160 static void mirror_make_current P_ ((struct window *, int));
161 void check_window_matrix_pointers P_ ((struct window *));
162 #if GLYPH_DEBUG
163 static void check_matrix_pointers P_ ((struct glyph_matrix *,
164 struct glyph_matrix *));
165 #endif
166 static void mirror_line_dance P_ ((struct window *, int, int, int *, char *));
167 static int update_window_tree P_ ((struct window *, int));
168 static int update_window P_ ((struct window *, int));
169 static int update_frame_1 P_ ((struct frame *, int, int));
170 static void set_window_cursor_after_update P_ ((struct window *));
171 static int row_equal_p P_ ((struct window *, struct glyph_row *,
172 struct glyph_row *));
173 static void adjust_frame_glyphs_for_window_redisplay P_ ((struct frame *));
174 static void adjust_frame_glyphs_for_frame_redisplay P_ ((struct frame *));
175 static void reverse_rows P_ ((struct glyph_matrix *, int, int));
176 static int margin_glyphs_to_reserve P_ ((struct window *, int, Lisp_Object));
177 static void sync_window_with_frame_matrix_rows P_ ((struct window *));
178 struct window *frame_row_to_window P_ ((struct window *, int));
182 /* Non-zero means don't pause redisplay for pending input. (This is
183 for debugging and for a future implementation of EDT-like
184 scrolling. */
186 int redisplay_dont_pause;
188 /* Nonzero upon entry to redisplay means do not assume anything about
189 current contents of actual terminal frame; clear and redraw it. */
191 int frame_garbaged;
193 /* Nonzero means last display completed. Zero means it was preempted. */
195 int display_completed;
197 /* Lisp variable visible-bell; enables use of screen-flash instead of
198 audible bell. */
200 int visible_bell;
202 /* Invert the color of the whole frame, at a low level. */
204 int inverse_video;
206 /* Line speed of the terminal. */
208 int baud_rate;
210 /* Either nil or a symbol naming the window system under which Emacs
211 is running. */
213 Lisp_Object Vwindow_system;
215 /* Version number of X windows: 10, 11 or nil. */
217 Lisp_Object Vwindow_system_version;
219 /* Vector of glyph definitions. Indexed by glyph number, the contents
220 are a string which is how to output the glyph.
222 If Vglyph_table is nil, a glyph is output by using its low 8 bits
223 as a character code.
225 This is an obsolete feature that is no longer used. The variable
226 is retained for compatibility. */
228 Lisp_Object Vglyph_table;
230 /* Display table to use for vectors that don't specify their own. */
232 Lisp_Object Vstandard_display_table;
234 /* Nonzero means reading single-character input with prompt so put
235 cursor on mini-buffer after the prompt. positive means at end of
236 text in echo area; negative means at beginning of line. */
238 int cursor_in_echo_area;
240 Lisp_Object Qdisplay_table;
243 /* The currently selected frame. In a single-frame version, this
244 variable always equals the_only_frame. */
246 Lisp_Object selected_frame;
248 /* A frame which is not just a mini-buffer, or 0 if there are no such
249 frames. This is usually the most recent such frame that was
250 selected. In a single-frame version, this variable always holds
251 the address of the_only_frame. */
253 struct frame *last_nonminibuf_frame;
255 /* Stdio stream being used for copy of all output. */
257 FILE *termscript;
259 /* Structure for info on cursor positioning. */
261 struct cm Wcm;
263 /* 1 means SIGWINCH happened when not safe. */
265 int delayed_size_change;
267 /* 1 means glyph initialization has been completed at startup. */
269 static int glyphs_initialized_initially_p;
271 /* Updated window if != 0. Set by update_window. */
273 struct window *updated_window;
275 /* Glyph row updated in update_window_line, and area that is updated. */
277 struct glyph_row *updated_row;
278 int updated_area;
280 /* A glyph for a space. */
282 struct glyph space_glyph;
284 /* Non-zero means update has been performed directly, so that there's
285 no need for redisplay_internal to do much work. Set by
286 direct_output_for_insert. */
288 int redisplay_performed_directly_p;
290 /* Counts of allocated structures. These counts serve to diagnose
291 memory leaks and double frees. */
293 int glyph_matrix_count;
294 int glyph_pool_count;
296 /* If non-null, the frame whose frame matrices are manipulated. If
297 null, window matrices are worked on. */
299 static struct frame *frame_matrix_frame;
301 /* Current interface for window-based redisplay. Set from init_xterm.
302 A null value means we are not using window-based redisplay. */
304 struct redisplay_interface *rif;
306 /* Non-zero means that fonts have been loaded since the last glyph
307 matrix adjustments. Redisplay must stop, and glyph matrices must
308 be adjusted when this flag becomes non-zero during display. The
309 reason fonts can be loaded so late is that fonts of fontsets are
310 loaded on demand. */
312 int fonts_changed_p;
314 /* Convert vpos and hpos from frame to window and vice versa.
315 This may only be used for terminal frames. */
317 #if GLYPH_DEBUG
319 static int window_to_frame_vpos P_ ((struct window *, int));
320 static int window_to_frame_hpos P_ ((struct window *, int));
321 #define WINDOW_TO_FRAME_VPOS(W, VPOS) window_to_frame_vpos ((W), (VPOS))
322 #define WINDOW_TO_FRAME_HPOS(W, HPOS) window_to_frame_hpos ((W), (HPOS))
324 #else /* GLYPH_DEBUG == 0 */
326 #define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + XFASTINT ((W)->top))
327 #define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + XFASTINT ((W)->left))
329 #endif /* GLYPH_DEBUG == 0 */
332 /* Like bcopy except never gets confused by overlap. Let this be the
333 first function defined in this file, or change emacs.c where the
334 address of this function is used. */
336 void
337 safe_bcopy (from, to, size)
338 char *from, *to;
339 int size;
341 if (size <= 0 || from == to)
342 return;
344 /* If the source and destination don't overlap, then bcopy can
345 handle it. If they do overlap, but the destination is lower in
346 memory than the source, we'll assume bcopy can handle that. */
347 if (to < from || from + size <= to)
348 bcopy (from, to, size);
350 /* Otherwise, we'll copy from the end. */
351 else
353 register char *endf = from + size;
354 register char *endt = to + size;
356 /* If TO - FROM is large, then we should break the copy into
357 nonoverlapping chunks of TO - FROM bytes each. However, if
358 TO - FROM is small, then the bcopy function call overhead
359 makes this not worth it. The crossover point could be about
360 anywhere. Since I don't think the obvious copy loop is too
361 bad, I'm trying to err in its favor. */
362 if (to - from < 64)
365 *--endt = *--endf;
366 while (endf != from);
368 else
370 for (;;)
372 endt -= (to - from);
373 endf -= (to - from);
375 if (endt < to)
376 break;
378 bcopy (endf, endt, to - from);
381 /* If SIZE wasn't a multiple of TO - FROM, there will be a
382 little left over. The amount left over is (endt + (to -
383 from)) - to, which is endt - from. */
384 bcopy (from, to, endt - from);
391 /***********************************************************************
392 Glyph Matrices
393 ***********************************************************************/
395 /* Allocate and return a glyph_matrix structure. POOL is the glyph
396 pool from which memory for the matrix should be allocated, or null
397 for window-based redisplay where no glyph pools are used. The
398 member `pool' of the glyph matrix structure returned is set to
399 POOL, the structure is otherwise zeroed. */
401 struct glyph_matrix *
402 new_glyph_matrix (pool)
403 struct glyph_pool *pool;
405 struct glyph_matrix *result;
407 /* Allocate and clear. */
408 result = (struct glyph_matrix *) xmalloc (sizeof *result);
409 bzero (result, sizeof *result);
411 /* Increment number of allocated matrices. This count is used
412 to detect memory leaks. */
413 ++glyph_matrix_count;
415 /* Set pool and return. */
416 result->pool = pool;
417 return result;
421 /* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed.
423 The global counter glyph_matrix_count is decremented when a matrix
424 is freed. If the count gets negative, more structures were freed
425 than allocated, i.e. one matrix was freed more than once or a bogus
426 pointer was passed to this function.
428 If MATRIX->pool is null, this means that the matrix manages its own
429 glyph memory---this is done for matrices on X frames. Freeing the
430 matrix also frees the glyph memory in this case. */
432 static void
433 free_glyph_matrix (matrix)
434 struct glyph_matrix *matrix;
436 if (matrix)
438 int i;
440 /* Detect the case that more matrices are freed than were
441 allocated. */
442 if (--glyph_matrix_count < 0)
443 abort ();
445 /* Free glyph memory if MATRIX owns it. */
446 if (matrix->pool == NULL)
447 for (i = 0; i < matrix->rows_allocated; ++i)
448 xfree (matrix->rows[i].glyphs[LEFT_MARGIN_AREA]);
450 /* Free row structures and the matrix itself. */
451 xfree (matrix->rows);
452 xfree (matrix);
457 /* Return the number of glyphs to reserve for a marginal area of
458 window W. TOTAL_GLYPHS is the number of glyphs in a complete
459 display line of window W. MARGIN gives the width of the marginal
460 area in canonical character units. MARGIN should be an integer
461 or a float. */
463 static int
464 margin_glyphs_to_reserve (w, total_glyphs, margin)
465 struct window *w;
466 int total_glyphs;
467 Lisp_Object margin;
469 int n;
471 if (NUMBERP (margin))
473 int width = XFASTINT (w->width);
474 double d = max (0, XFLOATINT (margin));
475 d = min (width / 2 - 1, d);
476 n = (int) ((double) total_glyphs / width * d);
478 else
479 n = 0;
481 return n;
485 /* Adjust glyph matrix MATRIX on window W or on a frame to changed
486 window sizes.
488 W is null if the function is called for a frame glyph matrix.
489 Otherwise it is the window MATRIX is a member of. X and Y are the
490 indices of the first column and row of MATRIX within the frame
491 matrix, if such a matrix exists. They are zero for purely
492 window-based redisplay. DIM is the needed size of the matrix.
494 In window-based redisplay, where no frame matrices exist, glyph
495 matrices manage their own glyph storage. Otherwise, they allocate
496 storage from a common frame glyph pool which can be found in
497 MATRIX->pool.
499 The reason for this memory management strategy is to avoid complete
500 frame redraws if possible. When we allocate from a common pool, a
501 change of the location or size of a sub-matrix within the pool
502 requires a complete redisplay of the frame because we cannot easily
503 make sure that the current matrices of all windows still agree with
504 what is displayed on the screen. While this is usually fast, it
505 leads to screen flickering. */
507 static void
508 adjust_glyph_matrix (w, matrix, x, y, dim)
509 struct window *w;
510 struct glyph_matrix *matrix;
511 int x, y;
512 struct dim dim;
514 int i;
515 int new_rows;
516 int marginal_areas_changed_p = 0;
517 int header_line_changed_p = 0;
518 int header_line_p = 0;
519 int left = -1, right = -1;
520 int window_x, window_y, window_width, window_height;
522 /* See if W had a top line that has disappeared now, or vice versa. */
523 if (w)
525 header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
526 header_line_changed_p = header_line_p != matrix->header_line_p;
528 matrix->header_line_p = header_line_p;
530 /* Do nothing if MATRIX' size, position, vscroll, and marginal areas
531 haven't changed. This optimization is important because preserving
532 the matrix means preventing redisplay. */
533 if (matrix->pool == NULL)
535 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
536 left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_width);
537 right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_width);
538 xassert (left >= 0 && right >= 0);
539 marginal_areas_changed_p = (left != matrix->left_margin_glyphs
540 || right != matrix->right_margin_glyphs);
542 if (!marginal_areas_changed_p
543 && !fonts_changed_p
544 && !header_line_changed_p
545 && matrix->window_top_y == XFASTINT (w->top)
546 && matrix->window_height == window_height
547 && matrix->window_vscroll == w->vscroll
548 && matrix->window_width == window_width)
549 return;
552 /* Enlarge MATRIX->rows if necessary. New rows are cleared. */
553 if (matrix->rows_allocated < dim.height)
555 int size = dim.height * sizeof (struct glyph_row);
556 new_rows = dim.height - matrix->rows_allocated;
557 matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
558 bzero (matrix->rows + matrix->rows_allocated,
559 new_rows * sizeof *matrix->rows);
560 matrix->rows_allocated = dim.height;
562 else
563 new_rows = 0;
565 /* If POOL is not null, MATRIX is a frame matrix or a window matrix
566 on a frame not using window-based redisplay. Set up pointers for
567 each row into the glyph pool. */
568 if (matrix->pool)
570 xassert (matrix->pool->glyphs);
572 if (w)
574 left = margin_glyphs_to_reserve (w, dim.width,
575 w->left_margin_width);
576 right = margin_glyphs_to_reserve (w, dim.width,
577 w->right_margin_width);
579 else
580 left = right = 0;
582 for (i = 0; i < dim.height; ++i)
584 struct glyph_row *row = &matrix->rows[i];
586 row->glyphs[LEFT_MARGIN_AREA]
587 = (matrix->pool->glyphs
588 + (y + i) * matrix->pool->ncolumns
589 + x);
591 if (w == NULL
592 || row == matrix->rows + dim.height - 1
593 || (row == matrix->rows && matrix->header_line_p))
595 row->glyphs[TEXT_AREA]
596 = row->glyphs[LEFT_MARGIN_AREA];
597 row->glyphs[RIGHT_MARGIN_AREA]
598 = row->glyphs[TEXT_AREA] + dim.width;
599 row->glyphs[LAST_AREA]
600 = row->glyphs[RIGHT_MARGIN_AREA];
602 else
604 row->glyphs[TEXT_AREA]
605 = row->glyphs[LEFT_MARGIN_AREA] + left;
606 row->glyphs[RIGHT_MARGIN_AREA]
607 = row->glyphs[TEXT_AREA] + dim.width - left - right;
608 row->glyphs[LAST_AREA]
609 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
613 matrix->left_margin_glyphs = left;
614 matrix->right_margin_glyphs = right;
616 else
618 /* If MATRIX->pool is null, MATRIX is responsible for managing
619 its own memory. Allocate glyph memory from the heap. */
620 if (dim.width > matrix->matrix_w
621 || new_rows
622 || header_line_changed_p
623 || marginal_areas_changed_p)
625 struct glyph_row *row = matrix->rows;
626 struct glyph_row *end = row + matrix->rows_allocated;
628 while (row < end)
630 row->glyphs[LEFT_MARGIN_AREA]
631 = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA],
632 (dim.width
633 * sizeof (struct glyph)));
635 /* The mode line never has marginal areas. */
636 if (row == matrix->rows + dim.height - 1
637 || (row == matrix->rows && matrix->header_line_p))
639 row->glyphs[TEXT_AREA]
640 = row->glyphs[LEFT_MARGIN_AREA];
641 row->glyphs[RIGHT_MARGIN_AREA]
642 = row->glyphs[TEXT_AREA] + dim.width;
643 row->glyphs[LAST_AREA]
644 = row->glyphs[RIGHT_MARGIN_AREA];
646 else
648 row->glyphs[TEXT_AREA]
649 = row->glyphs[LEFT_MARGIN_AREA] + left;
650 row->glyphs[RIGHT_MARGIN_AREA]
651 = row->glyphs[TEXT_AREA] + dim.width - left - right;
652 row->glyphs[LAST_AREA]
653 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
655 ++row;
659 xassert (left >= 0 && right >= 0);
660 matrix->left_margin_glyphs = left;
661 matrix->right_margin_glyphs = right;
664 /* Number of rows to be used by MATRIX. */
665 matrix->nrows = dim.height;
667 /* Mark rows in a current matrix of a window as not having valid
668 contents. It's important to not do this for desired matrices.
669 When Emacs starts, it may already be building desired matrices
670 when this function runs. */
671 if (w && matrix == w->current_matrix)
673 /* Optimize the case that only the height has changed (C-x 2,
674 upper window). Invalidate all rows that are no longer part
675 of the window. */
676 if (!marginal_areas_changed_p
677 && matrix->window_top_y == XFASTINT (w->top)
678 && matrix->window_width == window_width)
680 i = 0;
681 while (matrix->rows[i].enabled_p
682 && (MATRIX_ROW_BOTTOM_Y (matrix->rows + i)
683 < matrix->window_height))
684 ++i;
686 /* Window end is invalid, if inside of the rows that
687 are invalidated. */
688 if (INTEGERP (w->window_end_vpos)
689 && XFASTINT (w->window_end_vpos) >= i)
690 w->window_end_valid = Qnil;
692 while (i < matrix->nrows)
693 matrix->rows[i++].enabled_p = 0;
695 else
697 for (i = 0; i < matrix->nrows; ++i)
698 matrix->rows[i].enabled_p = 0;
702 /* Remember last values to be able to optimize frame redraws. */
703 matrix->matrix_x = x;
704 matrix->matrix_y = y;
705 matrix->matrix_w = dim.width;
706 matrix->matrix_h = dim.height;
708 /* Record the top y location and height of W at the time the matrix
709 was last adjusted. This is used to optimize redisplay above. */
710 if (w)
712 matrix->window_top_y = XFASTINT (w->top);
713 matrix->window_height = window_height;
714 matrix->window_width = window_width;
715 matrix->window_vscroll = w->vscroll;
720 /* Reverse the contents of rows in MATRIX between START and END. The
721 contents of the row at END - 1 end up at START, END - 2 at START +
722 1 etc. This is part of the implementation of rotate_matrix (see
723 below). */
725 static void
726 reverse_rows (matrix, start, end)
727 struct glyph_matrix *matrix;
728 int start, end;
730 int i, j;
732 for (i = start, j = end - 1; i < j; ++i, --j)
734 /* Non-ISO HP/UX compiler doesn't like auto struct
735 initialization. */
736 struct glyph_row temp;
737 temp = matrix->rows[i];
738 matrix->rows[i] = matrix->rows[j];
739 matrix->rows[j] = temp;
744 /* Rotate the contents of rows in MATRIX in the range FIRST .. LAST -
745 1 by BY positions. BY < 0 means rotate left, i.e. towards lower
746 indices. (Note: this does not copy glyphs, only glyph pointers in
747 row structures are moved around).
749 The algorithm used for rotating the vector was, I believe, first
750 described by Kernighan. See the vector R as consisting of two
751 sub-vectors AB, where A has length BY for BY >= 0. The result
752 after rotating is then BA. Reverse both sub-vectors to get ArBr
753 and reverse the result to get (ArBr)r which is BA. Similar for
754 rotating right. */
756 void
757 rotate_matrix (matrix, first, last, by)
758 struct glyph_matrix *matrix;
759 int first, last, by;
761 if (by < 0)
763 /* Up (rotate left, i.e. towards lower indices). */
764 by = -by;
765 reverse_rows (matrix, first, first + by);
766 reverse_rows (matrix, first + by, last);
767 reverse_rows (matrix, first, last);
769 else if (by > 0)
771 /* Down (rotate right, i.e. towards higher indices). */
772 reverse_rows (matrix, last - by, last);
773 reverse_rows (matrix, first, last - by);
774 reverse_rows (matrix, first, last);
779 /* Increment buffer positions in glyph rows of MATRIX. Do it for rows
780 with indices START <= index < END. Increment positions by DELTA/
781 DELTA_BYTES. */
783 void
784 increment_glyph_matrix_buffer_positions (matrix, start, end, delta,
785 delta_bytes)
786 struct glyph_matrix *matrix;
787 int start, end, delta, delta_bytes;
789 /* Check that START and END are reasonable values. */
790 xassert (start >= 0 && start <= matrix->nrows);
791 xassert (end >= 0 && end <= matrix->nrows);
792 xassert (start <= end);
794 for (; start < end; ++start)
795 increment_glyph_row_buffer_positions (matrix->rows + start,
796 delta, delta_bytes);
800 /* Enable a range of rows in glyph matrix MATRIX. START and END are
801 the row indices of the first and last + 1 row to enable. If
802 ENABLED_P is non-zero, enabled_p flags in rows will be set to 1. */
804 void
805 enable_glyph_matrix_rows (matrix, start, end, enabled_p)
806 struct glyph_matrix *matrix;
807 int start, end;
808 int enabled_p;
810 xassert (start <= end);
811 xassert (start >= 0 && start < matrix->nrows);
812 xassert (end >= 0 && end <= matrix->nrows);
814 for (; start < end; ++start)
815 matrix->rows[start].enabled_p = enabled_p != 0;
819 /* Clear MATRIX.
821 This empties all rows in MATRIX by setting the enabled_p flag for
822 all rows of the matrix to zero. The function prepare_desired_row
823 will eventually really clear a row when it sees one with a zero
824 enabled_p flag.
826 Resets update hints to defaults value. The only update hint
827 currently present is the flag MATRIX->no_scrolling_p. */
829 void
830 clear_glyph_matrix (matrix)
831 struct glyph_matrix *matrix;
833 if (matrix)
835 enable_glyph_matrix_rows (matrix, 0, matrix->nrows, 0);
836 matrix->no_scrolling_p = 0;
841 /* Shift part of the glyph matrix MATRIX of window W up or down.
842 Increment y-positions in glyph rows between START and END by DY,
843 and recompute their visible height. */
845 void
846 shift_glyph_matrix (w, matrix, start, end, dy)
847 struct window *w;
848 struct glyph_matrix *matrix;
849 int start, end, dy;
851 int min_y, max_y;
853 xassert (start <= end);
854 xassert (start >= 0 && start < matrix->nrows);
855 xassert (end >= 0 && end <= matrix->nrows);
857 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
858 max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w);
860 for (; start < end; ++start)
862 struct glyph_row *row = &matrix->rows[start];
864 row->y += dy;
866 if (row->y < min_y)
867 row->visible_height = row->height - (min_y - row->y);
868 else if (row->y + row->height > max_y)
869 row->visible_height = row->height - (row->y + row->height - max_y);
870 else
871 row->visible_height = row->height;
876 /* Mark all rows in current matrices of frame F as invalid. Marking
877 invalid is done by setting enabled_p to zero for all rows in a
878 current matrix. */
880 void
881 clear_current_matrices (f)
882 register struct frame *f;
884 /* Clear frame current matrix, if we have one. */
885 if (f->current_matrix)
886 clear_glyph_matrix (f->current_matrix);
888 /* Clear the matrix of the menu bar window, if such a window exists.
889 The menu bar window is currently used to display menus on X when
890 no toolkit support is compiled in. */
891 if (WINDOWP (f->menu_bar_window))
892 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
894 /* Clear the matrix of the tool-bar window, if any. */
895 if (WINDOWP (f->tool_bar_window))
896 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
898 /* Clear current window matrices. */
899 xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
900 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 0);
904 /* Clear out all display lines of F for a coming redisplay. */
906 void
907 clear_desired_matrices (f)
908 register struct frame *f;
910 if (f->desired_matrix)
911 clear_glyph_matrix (f->desired_matrix);
913 if (WINDOWP (f->menu_bar_window))
914 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
916 if (WINDOWP (f->tool_bar_window))
917 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
919 /* Do it for window matrices. */
920 xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
921 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
925 /* Clear matrices in window tree rooted in W. If DESIRED_P is
926 non-zero clear desired matrices, otherwise clear current matrices. */
928 static void
929 clear_window_matrices (w, desired_p)
930 struct window *w;
931 int desired_p;
933 while (w)
935 if (!NILP (w->hchild))
937 xassert (WINDOWP (w->hchild));
938 clear_window_matrices (XWINDOW (w->hchild), desired_p);
940 else if (!NILP (w->vchild))
942 xassert (WINDOWP (w->vchild));
943 clear_window_matrices (XWINDOW (w->vchild), desired_p);
945 else
947 if (desired_p)
948 clear_glyph_matrix (w->desired_matrix);
949 else
951 clear_glyph_matrix (w->current_matrix);
952 w->window_end_valid = Qnil;
956 w = NILP (w->next) ? 0 : XWINDOW (w->next);
962 /***********************************************************************
963 Glyph Rows
965 See dispextern.h for an overall explanation of glyph rows.
966 ***********************************************************************/
968 /* Clear glyph row ROW. Do it in a way that makes it robust against
969 changes in the glyph_row structure, i.e. addition or removal of
970 structure members. */
972 void
973 clear_glyph_row (row)
974 struct glyph_row *row;
976 struct glyph *p[1 + LAST_AREA];
977 static struct glyph_row null_row;
979 /* Save pointers. */
980 p[LEFT_MARGIN_AREA] = row->glyphs[LEFT_MARGIN_AREA];
981 p[TEXT_AREA] = row->glyphs[TEXT_AREA];
982 p[RIGHT_MARGIN_AREA] = row->glyphs[RIGHT_MARGIN_AREA];
983 p[LAST_AREA] = row->glyphs[LAST_AREA];
985 /* Clear. */
986 *row = null_row;
988 /* Restore pointers. */
989 row->glyphs[LEFT_MARGIN_AREA] = p[LEFT_MARGIN_AREA];
990 row->glyphs[TEXT_AREA] = p[TEXT_AREA];
991 row->glyphs[RIGHT_MARGIN_AREA] = p[RIGHT_MARGIN_AREA];
992 row->glyphs[LAST_AREA] = p[LAST_AREA];
996 /* Make ROW an empty, enabled row of canonical character height,
997 in window W starting at y-position Y. */
999 void
1000 blank_row (w, row, y)
1001 struct window *w;
1002 struct glyph_row *row;
1003 int y;
1005 int min_y, max_y;
1007 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
1008 max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w);
1010 clear_glyph_row (row);
1011 row->y = y;
1012 row->ascent = row->phys_ascent = 0;
1013 row->height = row->phys_height = CANON_Y_UNIT (XFRAME (w->frame));
1015 if (row->y < min_y)
1016 row->visible_height = row->height - (min_y - row->y);
1017 else if (row->y + row->height > max_y)
1018 row->visible_height = row->height - (row->y + row->height - max_y);
1019 else
1020 row->visible_height = row->height;
1022 row->enabled_p = 1;
1026 /* Increment buffer positions in glyph row ROW. DELTA and DELTA_BYTES
1027 are the amounts by which to change positions. Note that the first
1028 glyph of the text area of a row can have a buffer position even if
1029 the used count of the text area is zero. Such rows display line
1030 ends. */
1032 void
1033 increment_glyph_row_buffer_positions (row, delta, delta_bytes)
1034 struct glyph_row *row;
1035 int delta, delta_bytes;
1037 int area, i;
1039 /* Increment start and end positions. */
1040 MATRIX_ROW_START_CHARPOS (row) += delta;
1041 MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
1042 MATRIX_ROW_END_CHARPOS (row) += delta;
1043 MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
1045 /* Increment positions in glyphs. */
1046 for (area = 0; area < LAST_AREA; ++area)
1047 for (i = 0; i < row->used[area]; ++i)
1048 if (BUFFERP (row->glyphs[area][i].object)
1049 && row->glyphs[area][i].charpos > 0)
1050 row->glyphs[area][i].charpos += delta;
1052 /* Capture the case of rows displaying a line end. */
1053 if (row->used[TEXT_AREA] == 0
1054 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
1055 row->glyphs[TEXT_AREA]->charpos += delta;
1059 /* Swap glyphs between two glyph rows A and B. This exchanges glyph
1060 contents, i.e. glyph structure contents are exchanged between A and
1061 B without changing glyph pointers in A and B. */
1063 static void
1064 swap_glyphs_in_rows (a, b)
1065 struct glyph_row *a, *b;
1067 int area;
1069 for (area = 0; area < LAST_AREA; ++area)
1071 /* Number of glyphs to swap. */
1072 int max_used = max (a->used[area], b->used[area]);
1074 /* Start of glyphs in area of row A. */
1075 struct glyph *glyph_a = a->glyphs[area];
1077 /* End + 1 of glyphs in area of row A. */
1078 struct glyph *glyph_a_end = a->glyphs[max_used];
1080 /* Start of glyphs in area of row B. */
1081 struct glyph *glyph_b = b->glyphs[area];
1083 while (glyph_a < glyph_a_end)
1085 /* Non-ISO HP/UX compiler doesn't like auto struct
1086 initialization. */
1087 struct glyph temp;
1088 temp = *glyph_a;
1089 *glyph_a = *glyph_b;
1090 *glyph_b = temp;
1091 ++glyph_a;
1092 ++glyph_b;
1098 /* Exchange pointers to glyph memory between glyph rows A and B. */
1100 static INLINE void
1101 swap_glyph_pointers (a, b)
1102 struct glyph_row *a, *b;
1104 int i;
1105 for (i = 0; i < LAST_AREA + 1; ++i)
1107 struct glyph *temp = a->glyphs[i];
1108 a->glyphs[i] = b->glyphs[i];
1109 b->glyphs[i] = temp;
1114 /* Copy glyph row structure FROM to glyph row structure TO, except
1115 that glyph pointers in the structures are left unchanged. */
1117 INLINE void
1118 copy_row_except_pointers (to, from)
1119 struct glyph_row *to, *from;
1121 struct glyph *pointers[1 + LAST_AREA];
1123 /* Save glyph pointers of TO. */
1124 bcopy (to->glyphs, pointers, sizeof to->glyphs);
1126 /* Do a structure assignment. */
1127 *to = *from;
1129 /* Restore original pointers of TO. */
1130 bcopy (pointers, to->glyphs, sizeof to->glyphs);
1134 /* Copy contents of glyph row FROM to glyph row TO. Glyph pointers in
1135 TO and FROM are left unchanged. Glyph contents are copied from the
1136 glyph memory of FROM to the glyph memory of TO. Increment buffer
1137 positions in row TO by DELTA/ DELTA_BYTES. */
1139 void
1140 copy_glyph_row_contents (to, from, delta, delta_bytes)
1141 struct glyph_row *to, *from;
1142 int delta, delta_bytes;
1144 int area;
1146 /* This is like a structure assignment TO = FROM, except that
1147 glyph pointers in the rows are left unchanged. */
1148 copy_row_except_pointers (to, from);
1150 /* Copy glyphs from FROM to TO. */
1151 for (area = 0; area < LAST_AREA; ++area)
1152 if (from->used[area])
1153 bcopy (from->glyphs[area], to->glyphs[area],
1154 from->used[area] * sizeof (struct glyph));
1156 /* Increment buffer positions in TO by DELTA. */
1157 increment_glyph_row_buffer_positions (to, delta, delta_bytes);
1161 /* Assign glyph row FROM to glyph row TO. This works like a structure
1162 assignment TO = FROM, except that glyph pointers are not copied but
1163 exchanged between TO and FROM. Pointers must be exchanged to avoid
1164 a memory leak. */
1166 static INLINE void
1167 assign_row (to, from)
1168 struct glyph_row *to, *from;
1170 swap_glyph_pointers (to, from);
1171 copy_row_except_pointers (to, from);
1175 /* Test whether the glyph memory of the glyph row WINDOW_ROW, which is
1176 a row in a window matrix, is a slice of the glyph memory of the
1177 glyph row FRAME_ROW which is a row in a frame glyph matrix. Value
1178 is non-zero if the glyph memory of WINDOW_ROW is part of the glyph
1179 memory of FRAME_ROW. */
1181 static int
1182 glyph_row_slice_p (window_row, frame_row)
1183 struct glyph_row *window_row, *frame_row;
1185 struct glyph *window_glyph_start = window_row->glyphs[0];
1186 struct glyph *frame_glyph_start = frame_row->glyphs[0];
1187 struct glyph *frame_glyph_end = frame_row->glyphs[LAST_AREA];
1189 return (frame_glyph_start <= window_glyph_start
1190 && window_glyph_start < frame_glyph_end);
1194 /* Find the row in the window glyph matrix WINDOW_MATRIX being a slice
1195 of ROW in the frame matrix FRAME_MATRIX. Value is null if no row
1196 in WINDOW_MATRIX is found satisfying the condition. */
1198 static struct glyph_row *
1199 find_glyph_row_slice (window_matrix, frame_matrix, row)
1200 struct glyph_matrix *window_matrix, *frame_matrix;
1201 int row;
1203 int i;
1205 xassert (row >= 0 && row < frame_matrix->nrows);
1207 for (i = 0; i < window_matrix->nrows; ++i)
1208 if (glyph_row_slice_p (window_matrix->rows + i,
1209 frame_matrix->rows + row))
1210 break;
1212 return i < window_matrix->nrows ? window_matrix->rows + i : 0;
1216 /* Prepare ROW for display. Desired rows are cleared lazily,
1217 i.e. they are only marked as to be cleared by setting their
1218 enabled_p flag to zero. When a row is to be displayed, a prior
1219 call to this function really clears it. */
1221 void
1222 prepare_desired_row (row)
1223 struct glyph_row *row;
1225 if (!row->enabled_p)
1227 clear_glyph_row (row);
1228 row->enabled_p = 1;
1233 /* Return a hash code for glyph row ROW. */
1236 line_hash_code (row)
1237 struct glyph_row *row;
1239 int hash = 0;
1241 if (row->enabled_p)
1243 if (row->inverse_p)
1245 /* Give all highlighted lines the same hash code
1246 so as to encourage scrolling to leave them in place. */
1247 hash = -1;
1249 else
1251 struct glyph *glyph = row->glyphs[TEXT_AREA];
1252 struct glyph *end = glyph + row->used[TEXT_AREA];
1254 while (glyph < end)
1256 int c = glyph->u.ch;
1257 int face_id = glyph->face_id;
1258 if (must_write_spaces)
1259 c -= SPACEGLYPH;
1260 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
1261 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
1262 ++glyph;
1265 if (hash == 0)
1266 hash = 1;
1270 return hash;
1274 /* Return the cost of drawing line VPOS In MATRIX. The cost equals
1275 the number of characters in the line. If must_write_spaces is
1276 zero, leading and trailing spaces are ignored. */
1278 static unsigned int
1279 line_draw_cost (matrix, vpos)
1280 struct glyph_matrix *matrix;
1281 int vpos;
1283 struct glyph_row *row = matrix->rows + vpos;
1284 struct glyph *beg = row->glyphs[TEXT_AREA];
1285 struct glyph *end = beg + row->used[TEXT_AREA];
1286 int len;
1287 Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
1288 int glyph_table_len = GLYPH_TABLE_LENGTH;
1290 /* Ignore trailing and leading spaces if we can. */
1291 if (!must_write_spaces)
1293 /* Skip from the end over trailing spaces. */
1294 while (end != beg && CHAR_GLYPH_SPACE_P (*end))
1295 --end;
1297 /* All blank line. */
1298 if (end == beg)
1299 return 0;
1301 /* Skip over leading spaces. */
1302 while (CHAR_GLYPH_SPACE_P (*beg))
1303 ++beg;
1306 /* If we don't have a glyph-table, each glyph is one character,
1307 so return the number of glyphs. */
1308 if (glyph_table_base == 0)
1309 len = end - beg;
1310 else
1312 /* Otherwise, scan the glyphs and accumulate their total length
1313 in LEN. */
1314 len = 0;
1315 while (beg < end)
1317 GLYPH g = GLYPH_FROM_CHAR_GLYPH (*beg);
1319 if (g < 0
1320 || GLYPH_SIMPLE_P (glyph_table_base, glyph_table_len, g))
1321 len += 1;
1322 else
1323 len += GLYPH_LENGTH (glyph_table_base, g);
1325 ++beg;
1329 return len;
1333 /* Test two glyph rows A and B for equality. Value is non-zero if A
1334 and B have equal contents. W is the window to which the glyphs
1335 rows A and B belong. It is needed here to test for partial row
1336 visibility. */
1338 static INLINE int
1339 row_equal_p (w, a, b)
1340 struct window *w;
1341 struct glyph_row *a, *b;
1343 if (a == b)
1344 return 1;
1345 else if (a->hash != b->hash)
1346 return 0;
1347 else
1349 struct glyph *a_glyph, *b_glyph, *a_end;
1350 int area;
1352 /* Compare glyphs. */
1353 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
1355 if (a->used[area] != b->used[area])
1356 return 0;
1358 a_glyph = a->glyphs[area];
1359 a_end = a_glyph + a->used[area];
1360 b_glyph = b->glyphs[area];
1362 while (a_glyph < a_end
1363 && GLYPH_EQUAL_P (a_glyph, b_glyph))
1364 ++a_glyph, ++b_glyph;
1366 if (a_glyph != a_end)
1367 return 0;
1370 if (a->truncated_on_left_p != b->truncated_on_left_p
1371 || a->inverse_p != b->inverse_p
1372 || a->fill_line_p != b->fill_line_p
1373 || a->truncated_on_right_p != b->truncated_on_right_p
1374 || a->overlay_arrow_p != b->overlay_arrow_p
1375 || a->continued_p != b->continued_p
1376 || a->indicate_empty_line_p != b->indicate_empty_line_p
1377 || a->overlapped_p != b->overlapped_p
1378 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
1379 != MATRIX_ROW_CONTINUATION_LINE_P (b))
1380 /* Different partially visible characters on left margin. */
1381 || a->x != b->x
1382 /* Different height. */
1383 || a->ascent != b->ascent
1384 || a->phys_ascent != b->phys_ascent
1385 || a->phys_height != b->phys_height
1386 || a->visible_height != b->visible_height)
1387 return 0;
1390 return 1;
1395 /***********************************************************************
1396 Glyph Pool
1398 See dispextern.h for an overall explanation of glyph pools.
1399 ***********************************************************************/
1401 /* Allocate a glyph_pool structure. The structure returned is
1402 initialized with zeros. The global variable glyph_pool_count is
1403 incremented for each pool allocated. */
1405 static struct glyph_pool *
1406 new_glyph_pool ()
1408 struct glyph_pool *result;
1410 /* Allocate a new glyph_pool and clear it. */
1411 result = (struct glyph_pool *) xmalloc (sizeof *result);
1412 bzero (result, sizeof *result);
1414 /* For memory leak and double deletion checking. */
1415 ++glyph_pool_count;
1417 return result;
1421 /* Free a glyph_pool structure POOL. The function may be called with
1422 a null POOL pointer. The global variable glyph_pool_count is
1423 decremented with every pool structure freed. If this count gets
1424 negative, more structures were freed than allocated, i.e. one
1425 structure must have been freed more than once or a bogus pointer
1426 was passed to free_glyph_pool. */
1428 static void
1429 free_glyph_pool (pool)
1430 struct glyph_pool *pool;
1432 if (pool)
1434 /* More freed than allocated? */
1435 --glyph_pool_count;
1436 xassert (glyph_pool_count >= 0);
1438 xfree (pool->glyphs);
1439 xfree (pool);
1444 /* Enlarge a glyph pool POOL. MATRIX_DIM gives the number of rows and
1445 columns we need. This function never shrinks a pool. The only
1446 case in which this would make sense, would be when a frame's size
1447 is changed from a large value to a smaller one. But, if someone
1448 does it once, we can expect that he will do it again.
1450 Value is non-zero if the pool changed in a way which makes
1451 re-adjusting window glyph matrices necessary. */
1453 static int
1454 realloc_glyph_pool (pool, matrix_dim)
1455 struct glyph_pool *pool;
1456 struct dim matrix_dim;
1458 int needed;
1459 int changed_p;
1461 changed_p = (pool->glyphs == 0
1462 || matrix_dim.height != pool->nrows
1463 || matrix_dim.width != pool->ncolumns);
1465 /* Enlarge the glyph pool. */
1466 needed = matrix_dim.width * matrix_dim.height;
1467 if (needed > pool->nglyphs)
1469 int size = needed * sizeof (struct glyph);
1471 if (pool->glyphs)
1472 pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size);
1473 else
1475 pool->glyphs = (struct glyph *) xmalloc (size);
1476 bzero (pool->glyphs, size);
1479 pool->nglyphs = needed;
1482 /* Remember the number of rows and columns because (a) we use then
1483 to do sanity checks, and (b) the number of columns determines
1484 where rows in the frame matrix start---this must be available to
1485 determine pointers to rows of window sub-matrices. */
1486 pool->nrows = matrix_dim.height;
1487 pool->ncolumns = matrix_dim.width;
1489 return changed_p;
1494 /***********************************************************************
1495 Debug Code
1496 ***********************************************************************/
1498 #if GLYPH_DEBUG
1501 /* Flush standard output. This is sometimes useful to call from
1502 the debugger. */
1504 void
1505 flush_stdout ()
1507 fflush (stdout);
1511 /* Check that no glyph pointers have been lost in MATRIX. If a
1512 pointer has been lost, e.g. by using a structure assignment between
1513 rows, at least one pointer must occur more than once in the rows of
1514 MATRIX. */
1516 void
1517 check_matrix_pointer_lossage (matrix)
1518 struct glyph_matrix *matrix;
1520 int i, j;
1522 for (i = 0; i < matrix->nrows; ++i)
1523 for (j = 0; j < matrix->nrows; ++j)
1524 xassert (i == j
1525 || (matrix->rows[i].glyphs[TEXT_AREA]
1526 != matrix->rows[j].glyphs[TEXT_AREA]));
1530 /* Get a pointer to glyph row ROW in MATRIX, with bounds checks. */
1532 struct glyph_row *
1533 matrix_row (matrix, row)
1534 struct glyph_matrix *matrix;
1535 int row;
1537 xassert (matrix && matrix->rows);
1538 xassert (row >= 0 && row < matrix->nrows);
1540 /* That's really too slow for normal testing because this function
1541 is called almost everywhere. Although---it's still astonishingly
1542 fast, so it is valuable to have for debugging purposes. */
1543 #if 0
1544 check_matrix_pointer_lossage (matrix);
1545 #endif
1547 return matrix->rows + row;
1551 #if 0 /* This function makes invalid assumptions when text is
1552 partially invisible. But it might come handy for debugging
1553 nevertheless. */
1555 /* Check invariants that must hold for an up to date current matrix of
1556 window W. */
1558 static void
1559 check_matrix_invariants (w)
1560 struct window *w;
1562 struct glyph_matrix *matrix = w->current_matrix;
1563 int yb = window_text_bottom_y (w);
1564 struct glyph_row *row = matrix->rows;
1565 struct glyph_row *last_text_row = NULL;
1566 struct buffer *saved = current_buffer;
1567 struct buffer *buffer = XBUFFER (w->buffer);
1568 int c;
1570 /* This can sometimes happen for a fresh window. */
1571 if (matrix->nrows < 2)
1572 return;
1574 set_buffer_temp (buffer);
1576 /* Note: last row is always reserved for the mode line. */
1577 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
1578 && MATRIX_ROW_BOTTOM_Y (row) < yb)
1580 struct glyph_row *next = row + 1;
1582 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
1583 last_text_row = row;
1585 /* Check that character and byte positions are in sync. */
1586 xassert (MATRIX_ROW_START_BYTEPOS (row)
1587 == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
1589 /* CHAR_TO_BYTE aborts when invoked for a position > Z. We can
1590 have such a position temporarily in case of a minibuffer
1591 displaying something like `[Sole completion]' at its end. */
1592 if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
1593 xassert (MATRIX_ROW_END_BYTEPOS (row)
1594 == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
1596 /* Check that end position of `row' is equal to start position
1597 of next row. */
1598 if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next))
1600 xassert (MATRIX_ROW_END_CHARPOS (row)
1601 == MATRIX_ROW_START_CHARPOS (next));
1602 xassert (MATRIX_ROW_END_BYTEPOS (row)
1603 == MATRIX_ROW_START_BYTEPOS (next));
1605 row = next;
1608 xassert (w->current_matrix->nrows == w->desired_matrix->nrows);
1609 xassert (w->desired_matrix->rows != NULL);
1610 set_buffer_temp (saved);
1613 #endif /* 0 */
1615 #endif /* GLYPH_DEBUG != 0 */
1619 /**********************************************************************
1620 Allocating/ Adjusting Glyph Matrices
1621 **********************************************************************/
1623 /* Allocate glyph matrices over a window tree for a frame-based
1624 redisplay
1626 X and Y are column/row within the frame glyph matrix where
1627 sub-matrices for the window tree rooted at WINDOW must be
1628 allocated. CH_DIM contains the dimensions of the smallest
1629 character that could be used during display. DIM_ONLY_P non-zero
1630 means that the caller of this function is only interested in the
1631 result matrix dimension, and matrix adjustments should not be
1632 performed.
1634 The function returns the total width/height of the sub-matrices of
1635 the window tree. If called on a frame root window, the computation
1636 will take the mini-buffer window into account.
1638 *WINDOW_CHANGE_FLAGS is set to a bit mask with bits
1640 NEW_LEAF_MATRIX set if any window in the tree did not have a
1641 glyph matrices yet, and
1643 CHANGED_LEAF_MATRIX set if the dimension or location of a matrix of
1644 any window in the tree will be changed or have been changed (see
1645 DIM_ONLY_P).
1647 *WINDOW_CHANGE_FLAGS must be initialized by the caller of this
1648 function.
1650 Windows are arranged into chains of windows on the same level
1651 through the next fields of window structures. Such a level can be
1652 either a sequence of horizontally adjacent windows from left to
1653 right, or a sequence of vertically adjacent windows from top to
1654 bottom. Each window in a horizontal sequence can be either a leaf
1655 window or a vertical sequence; a window in a vertical sequence can
1656 be either a leaf or a horizontal sequence. All windows in a
1657 horizontal sequence have the same height, and all windows in a
1658 vertical sequence have the same width.
1660 This function uses, for historical reasons, a more general
1661 algorithm to determine glyph matrix dimensions that would be
1662 necessary.
1664 The matrix height of a horizontal sequence is determined by the
1665 maximum height of any matrix in the sequence. The matrix width of
1666 a horizontal sequence is computed by adding up matrix widths of
1667 windows in the sequence.
1669 |<------- result width ------->|
1670 +---------+----------+---------+ ---
1671 | | | | |
1672 | | | |
1673 +---------+ | | result height
1674 | +---------+
1675 | | |
1676 +----------+ ---
1678 The matrix width of a vertical sequence is the maximum matrix width
1679 of any window in the sequence. Its height is computed by adding up
1680 matrix heights of windows in the sequence.
1682 |<---- result width -->|
1683 +---------+ ---
1684 | | |
1685 | | |
1686 +---------+--+ |
1687 | | |
1688 | | result height
1690 +------------+---------+ |
1691 | | |
1692 | | |
1693 +------------+---------+ --- */
1695 /* Bit indicating that a new matrix will be allocated or has been
1696 allocated. */
1698 #define NEW_LEAF_MATRIX (1 << 0)
1700 /* Bit indicating that a matrix will or has changed its location or
1701 size. */
1703 #define CHANGED_LEAF_MATRIX (1 << 1)
1705 static struct dim
1706 allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
1707 dim_only_p, window_change_flags)
1708 Lisp_Object window;
1709 int x, y;
1710 struct dim ch_dim;
1711 int dim_only_p;
1712 int *window_change_flags;
1714 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1715 int x0 = x, y0 = y;
1716 int wmax = 0, hmax = 0;
1717 struct dim total;
1718 struct dim dim;
1719 struct window *w;
1720 int in_horz_combination_p;
1722 /* What combination is WINDOW part of? Compute this once since the
1723 result is the same for all windows in the `next' chain. The
1724 special case of a root window (parent equal to nil) is treated
1725 like a vertical combination because a root window's `next'
1726 points to the mini-buffer window, if any, which is arranged
1727 vertically below other windows. */
1728 in_horz_combination_p
1729 = (!NILP (XWINDOW (window)->parent)
1730 && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
1732 /* For WINDOW and all windows on the same level. */
1735 w = XWINDOW (window);
1737 /* Get the dimension of the window sub-matrix for W, depending
1738 on whether this a combination or a leaf window. */
1739 if (!NILP (w->hchild))
1740 dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y, ch_dim,
1741 dim_only_p,
1742 window_change_flags);
1743 else if (!NILP (w->vchild))
1744 dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y, ch_dim,
1745 dim_only_p,
1746 window_change_flags);
1747 else
1749 /* If not already done, allocate sub-matrix structures. */
1750 if (w->desired_matrix == NULL)
1752 w->desired_matrix = new_glyph_matrix (f->desired_pool);
1753 w->current_matrix = new_glyph_matrix (f->current_pool);
1754 *window_change_flags |= NEW_LEAF_MATRIX;
1757 /* Width and height MUST be chosen so that there are no
1758 holes in the frame matrix. */
1759 dim.width = w->width;
1760 dim.height = w->height;
1762 /* Will matrix be re-allocated? */
1763 if (x != w->desired_matrix->matrix_x
1764 || y != w->desired_matrix->matrix_y
1765 || dim.width != w->desired_matrix->matrix_w
1766 || dim.height != w->desired_matrix->matrix_h
1767 || (margin_glyphs_to_reserve (w, dim.width,
1768 w->right_margin_width)
1769 != w->desired_matrix->left_margin_glyphs)
1770 || (margin_glyphs_to_reserve (w, dim.width,
1771 w->left_margin_width)
1772 != w->desired_matrix->right_margin_glyphs))
1773 *window_change_flags |= CHANGED_LEAF_MATRIX;
1775 /* Actually change matrices, if allowed. Do not consider
1776 CHANGED_LEAF_MATRIX computed above here because the pool
1777 may have been changed which we don't now here. We trust
1778 that we only will be called with DIM_ONLY_P != 0 when
1779 necessary. */
1780 if (!dim_only_p)
1782 adjust_glyph_matrix (w, w->desired_matrix, x, y, dim);
1783 adjust_glyph_matrix (w, w->current_matrix, x, y, dim);
1787 /* If we are part of a horizontal combination, advance x for
1788 windows to the right of W; otherwise advance y for windows
1789 below W. */
1790 if (in_horz_combination_p)
1791 x += dim.width;
1792 else
1793 y += dim.height;
1795 /* Remember maximum glyph matrix dimensions. */
1796 wmax = max (wmax, dim.width);
1797 hmax = max (hmax, dim.height);
1799 /* Next window on same level. */
1800 window = w->next;
1802 while (!NILP (window));
1804 /* Set `total' to the total glyph matrix dimension of this window
1805 level. In a vertical combination, the width is the width of the
1806 widest window; the height is the y we finally reached, corrected
1807 by the y we started with. In a horizontal combination, the total
1808 height is the height of the tallest window, and the width is the
1809 x we finally reached, corrected by the x we started with. */
1810 if (in_horz_combination_p)
1812 total.width = x - x0;
1813 total.height = hmax;
1815 else
1817 total.width = wmax;
1818 total.height = y - y0;
1821 return total;
1825 /* Allocate window matrices for window-based redisplay. W is the
1826 window whose matrices must be allocated/reallocated. CH_DIM is the
1827 size of the smallest character that could potentially be used on W. */
1829 static void
1830 allocate_matrices_for_window_redisplay (w, ch_dim)
1831 struct window *w;
1832 struct dim ch_dim;
1834 struct frame *f = XFRAME (w->frame);
1836 while (w)
1838 if (!NILP (w->vchild))
1839 allocate_matrices_for_window_redisplay (XWINDOW (w->vchild), ch_dim);
1840 else if (!NILP (w->hchild))
1841 allocate_matrices_for_window_redisplay (XWINDOW (w->hchild), ch_dim);
1842 else
1844 /* W is a leaf window. */
1845 int window_pixel_width = XFLOATINT (w->width) * CANON_X_UNIT (f);
1846 int window_pixel_height = window_box_height (w) + abs (w->vscroll);
1847 struct dim dim;
1849 /* If matrices are not yet allocated, allocate them now. */
1850 if (w->desired_matrix == NULL)
1852 w->desired_matrix = new_glyph_matrix (NULL);
1853 w->current_matrix = new_glyph_matrix (NULL);
1856 /* Compute number of glyphs needed in a glyph row. */
1857 dim.width = (((window_pixel_width + ch_dim.width - 1)
1858 / ch_dim.width)
1859 /* 2 partially visible columns in the text area. */
1861 /* One partially visible column at the right
1862 edge of each marginal area. */
1863 + 1 + 1);
1865 /* Compute number of glyph rows needed. */
1866 dim.height = (((window_pixel_height + ch_dim.height - 1)
1867 / ch_dim.height)
1868 /* One partially visible line at the top and
1869 bottom of the window. */
1871 /* 2 for top and mode line. */
1872 + 2);
1874 /* Change matrices. */
1875 adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
1876 adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
1879 w = NILP (w->next) ? NULL : XWINDOW (w->next);
1884 /* Re-allocate/ re-compute glyph matrices on frame F. If F is null,
1885 do it for all frames; otherwise do it just for the given frame.
1886 This function must be called when a new frame is created, its size
1887 changes, or its window configuration changes. */
1889 void
1890 adjust_glyphs (f)
1891 struct frame *f;
1893 /* Block input so that expose events and other events that access
1894 glyph matrices are not processed while we are changing them. */
1895 BLOCK_INPUT;
1897 if (f)
1898 adjust_frame_glyphs (f);
1899 else
1901 Lisp_Object tail, lisp_frame;
1903 FOR_EACH_FRAME (tail, lisp_frame)
1904 adjust_frame_glyphs (XFRAME (lisp_frame));
1907 UNBLOCK_INPUT;
1911 /* Adjust frame glyphs when Emacs is initialized.
1913 To be called from init_display.
1915 We need a glyph matrix because redraw will happen soon.
1916 Unfortunately, window sizes on selected_frame are not yet set to
1917 meaningful values. I believe we can assume that there are only two
1918 windows on the frame---the mini-buffer and the root window. Frame
1919 height and width seem to be correct so far. So, set the sizes of
1920 windows to estimated values. */
1922 static void
1923 adjust_frame_glyphs_initially ()
1925 struct frame *sf = SELECTED_FRAME ();
1926 struct window *root = XWINDOW (sf->root_window);
1927 struct window *mini = XWINDOW (root->next);
1928 int frame_height = FRAME_HEIGHT (sf);
1929 int frame_width = FRAME_WIDTH (sf);
1930 int top_margin = FRAME_TOP_MARGIN (sf);
1932 /* Do it for the root window. */
1933 XSETFASTINT (root->top, top_margin);
1934 XSETFASTINT (root->width, frame_width);
1935 set_window_height (sf->root_window, frame_height - 1 - top_margin, 0);
1937 /* Do it for the mini-buffer window. */
1938 XSETFASTINT (mini->top, frame_height - 1);
1939 XSETFASTINT (mini->width, frame_width);
1940 set_window_height (root->next, 1, 0);
1942 adjust_frame_glyphs (sf);
1943 glyphs_initialized_initially_p = 1;
1947 /* Allocate/reallocate glyph matrices of a single frame F. */
1949 static void
1950 adjust_frame_glyphs (f)
1951 struct frame *f;
1953 if (FRAME_WINDOW_P (f))
1954 adjust_frame_glyphs_for_window_redisplay (f);
1955 else
1956 adjust_frame_glyphs_for_frame_redisplay (f);
1958 /* Don't forget the message buffer and the buffer for
1959 decode_mode_spec. */
1960 adjust_frame_message_buffer (f);
1961 adjust_decode_mode_spec_buffer (f);
1963 f->glyphs_initialized_p = 1;
1967 /* Allocate/reallocate glyph matrices of a single frame F for
1968 frame-based redisplay. */
1970 static void
1971 adjust_frame_glyphs_for_frame_redisplay (f)
1972 struct frame *f;
1974 struct dim ch_dim;
1975 struct dim matrix_dim;
1976 int pool_changed_p;
1977 int window_change_flags;
1978 int top_window_y;
1980 if (!FRAME_LIVE_P (f))
1981 return;
1983 /* Determine the smallest character in any font for F. On
1984 console windows, all characters have dimension (1, 1). */
1985 ch_dim.width = ch_dim.height = 1;
1987 top_window_y = FRAME_TOP_MARGIN (f);
1989 /* Allocate glyph pool structures if not already done. */
1990 if (f->desired_pool == NULL)
1992 f->desired_pool = new_glyph_pool ();
1993 f->current_pool = new_glyph_pool ();
1996 /* Allocate frames matrix structures if needed. */
1997 if (f->desired_matrix == NULL)
1999 f->desired_matrix = new_glyph_matrix (f->desired_pool);
2000 f->current_matrix = new_glyph_matrix (f->current_pool);
2003 /* Compute window glyph matrices. (This takes the mini-buffer
2004 window into account). The result is the size of the frame glyph
2005 matrix needed. The variable window_change_flags is set to a bit
2006 mask indicating whether new matrices will be allocated or
2007 existing matrices change their size or location within the frame
2008 matrix. */
2009 window_change_flags = 0;
2010 matrix_dim
2011 = allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2012 0, top_window_y,
2013 ch_dim, 1,
2014 &window_change_flags);
2016 /* Add in menu bar lines, if any. */
2017 matrix_dim.height += top_window_y;
2019 /* Enlarge pools as necessary. */
2020 pool_changed_p = realloc_glyph_pool (f->desired_pool, matrix_dim);
2021 realloc_glyph_pool (f->current_pool, matrix_dim);
2023 /* Set up glyph pointers within window matrices. Do this only if
2024 absolutely necessary since it requires a frame redraw. */
2025 if (pool_changed_p || window_change_flags)
2027 /* Do it for window matrices. */
2028 allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2029 0, top_window_y, ch_dim, 0,
2030 &window_change_flags);
2032 /* Size of frame matrices must equal size of frame. Note
2033 that we are called for X frames with window widths NOT equal
2034 to the frame width (from CHANGE_FRAME_SIZE_1). */
2035 xassert (matrix_dim.width == FRAME_WIDTH (f)
2036 && matrix_dim.height == FRAME_HEIGHT (f));
2038 /* Resize frame matrices. */
2039 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2040 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2042 /* Since location and size of sub-matrices within the pool may
2043 have changed, and current matrices don't have meaningful
2044 contents anymore, mark the frame garbaged. */
2045 SET_FRAME_GARBAGED (f);
2050 /* Allocate/reallocate glyph matrices of a single frame F for
2051 window-based redisplay. */
2053 static void
2054 adjust_frame_glyphs_for_window_redisplay (f)
2055 struct frame *f;
2057 struct dim ch_dim;
2058 struct window *w;
2060 xassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
2062 /* Get minimum sizes. */
2063 #ifdef HAVE_WINDOW_SYSTEM
2064 ch_dim.width = FRAME_SMALLEST_CHAR_WIDTH (f);
2065 ch_dim.height = FRAME_SMALLEST_FONT_HEIGHT (f);
2066 #else
2067 ch_dim.width = ch_dim.height = 1;
2068 #endif
2070 /* Allocate/reallocate window matrices. */
2071 allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)),
2072 ch_dim);
2074 /* Allocate/ reallocate matrices of the dummy window used to display
2075 the menu bar under X when no X toolkit support is available. */
2076 #ifndef USE_X_TOOLKIT
2078 /* Allocate a dummy window if not already done. */
2079 if (NILP (f->menu_bar_window))
2081 f->menu_bar_window = make_window ();
2082 w = XWINDOW (f->menu_bar_window);
2083 XSETFRAME (w->frame, f);
2084 w->pseudo_window_p = 1;
2086 else
2087 w = XWINDOW (f->menu_bar_window);
2089 /* Set window dimensions to frame dimensions and allocate or
2090 adjust glyph matrices of W. */
2091 XSETFASTINT (w->top, 0);
2092 XSETFASTINT (w->left, 0);
2093 XSETFASTINT (w->height, FRAME_MENU_BAR_LINES (f));
2094 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
2095 allocate_matrices_for_window_redisplay (w, ch_dim);
2097 #endif /* not USE_X_TOOLKIT */
2099 /* Allocate/ reallocate matrices of the tool bar window. If we
2100 don't have a tool bar window yet, make one. */
2101 if (NILP (f->tool_bar_window))
2103 f->tool_bar_window = make_window ();
2104 w = XWINDOW (f->tool_bar_window);
2105 XSETFRAME (w->frame, f);
2106 w->pseudo_window_p = 1;
2108 else
2109 w = XWINDOW (f->tool_bar_window);
2111 XSETFASTINT (w->top, FRAME_MENU_BAR_LINES (f));
2112 XSETFASTINT (w->left, 0);
2113 XSETFASTINT (w->height, FRAME_TOOL_BAR_LINES (f));
2114 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
2115 allocate_matrices_for_window_redisplay (w, ch_dim);
2119 /* Adjust/ allocate message buffer of frame F.
2121 Note that the message buffer is never freed. Since I could not
2122 find a free in 19.34, I assume that freeing it would be
2123 problematic in some way and don't do it either.
2125 (Implementation note: It should be checked if we can free it
2126 eventually without causing trouble). */
2128 static void
2129 adjust_frame_message_buffer (f)
2130 struct frame *f;
2132 int size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
2134 if (FRAME_MESSAGE_BUF (f))
2136 char *buffer = FRAME_MESSAGE_BUF (f);
2137 char *new_buffer = (char *) xrealloc (buffer, size);
2138 FRAME_MESSAGE_BUF (f) = new_buffer;
2140 else
2141 FRAME_MESSAGE_BUF (f) = (char *) xmalloc (size);
2145 /* Re-allocate buffer for decode_mode_spec on frame F. */
2147 static void
2148 adjust_decode_mode_spec_buffer (f)
2149 struct frame *f;
2151 f->decode_mode_spec_buffer
2152 = (char *) xrealloc (f->decode_mode_spec_buffer,
2153 FRAME_MESSAGE_BUF_SIZE (f) + 1);
2158 /**********************************************************************
2159 Freeing Glyph Matrices
2160 **********************************************************************/
2162 /* Free glyph memory for a frame F. F may be null. This function can
2163 be called for the same frame more than once. The root window of
2164 F may be nil when this function is called. This is the case when
2165 the function is called when F is destroyed. */
2167 void
2168 free_glyphs (f)
2169 struct frame *f;
2171 if (f && f->glyphs_initialized_p)
2173 /* Block interrupt input so that we don't get surprised by an X
2174 event while we're in an inconsistent state. */
2175 BLOCK_INPUT;
2176 f->glyphs_initialized_p = 0;
2178 /* Release window sub-matrices. */
2179 if (!NILP (f->root_window))
2180 free_window_matrices (XWINDOW (f->root_window));
2182 /* Free the dummy window for menu bars without X toolkit and its
2183 glyph matrices. */
2184 if (!NILP (f->menu_bar_window))
2186 struct window *w = XWINDOW (f->menu_bar_window);
2187 free_glyph_matrix (w->desired_matrix);
2188 free_glyph_matrix (w->current_matrix);
2189 w->desired_matrix = w->current_matrix = NULL;
2190 f->menu_bar_window = Qnil;
2193 /* Free the tool bar window and its glyph matrices. */
2194 if (!NILP (f->tool_bar_window))
2196 struct window *w = XWINDOW (f->tool_bar_window);
2197 free_glyph_matrix (w->desired_matrix);
2198 free_glyph_matrix (w->current_matrix);
2199 w->desired_matrix = w->current_matrix = NULL;
2200 f->tool_bar_window = Qnil;
2203 /* Release frame glyph matrices. Reset fields to zero in
2204 case we are called a second time. */
2205 if (f->desired_matrix)
2207 free_glyph_matrix (f->desired_matrix);
2208 free_glyph_matrix (f->current_matrix);
2209 f->desired_matrix = f->current_matrix = NULL;
2212 /* Release glyph pools. */
2213 if (f->desired_pool)
2215 free_glyph_pool (f->desired_pool);
2216 free_glyph_pool (f->current_pool);
2217 f->desired_pool = f->current_pool = NULL;
2220 UNBLOCK_INPUT;
2225 /* Free glyph sub-matrices in the window tree rooted at W. This
2226 function may be called with a null pointer, and it may be called on
2227 the same tree more than once. */
2229 void
2230 free_window_matrices (w)
2231 struct window *w;
2233 while (w)
2235 if (!NILP (w->hchild))
2236 free_window_matrices (XWINDOW (w->hchild));
2237 else if (!NILP (w->vchild))
2238 free_window_matrices (XWINDOW (w->vchild));
2239 else
2241 /* This is a leaf window. Free its memory and reset fields
2242 to zero in case this function is called a second time for
2243 W. */
2244 free_glyph_matrix (w->current_matrix);
2245 free_glyph_matrix (w->desired_matrix);
2246 w->current_matrix = w->desired_matrix = NULL;
2249 /* Next window on same level. */
2250 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2255 /* Check glyph memory leaks. This function is called from
2256 shut_down_emacs. Note that frames are not destroyed when Emacs
2257 exits. We therefore free all glyph memory for all active frames
2258 explicitly and check that nothing is left allocated. */
2260 void
2261 check_glyph_memory ()
2263 Lisp_Object tail, frame;
2265 /* Free glyph memory for all frames. */
2266 FOR_EACH_FRAME (tail, frame)
2267 free_glyphs (XFRAME (frame));
2269 /* Check that nothing is left allocated. */
2270 if (glyph_matrix_count)
2271 abort ();
2272 if (glyph_pool_count)
2273 abort ();
2278 /**********************************************************************
2279 Building a Frame Matrix
2280 **********************************************************************/
2282 /* Most of the redisplay code works on glyph matrices attached to
2283 windows. This is a good solution most of the time, but it is not
2284 suitable for terminal code. Terminal output functions cannot rely
2285 on being able to set an arbitrary terminal window. Instead they
2286 must be provided with a view of the whole frame, i.e. the whole
2287 screen. We build such a view by constructing a frame matrix from
2288 window matrices in this section.
2290 Windows that must be updated have their must_be_update_p flag set.
2291 For all such windows, their desired matrix is made part of the
2292 desired frame matrix. For other windows, their current matrix is
2293 made part of the desired frame matrix.
2295 +-----------------+----------------+
2296 | desired | desired |
2297 | | |
2298 +-----------------+----------------+
2299 | current |
2301 +----------------------------------+
2303 Desired window matrices can be made part of the frame matrix in a
2304 cheap way: We exploit the fact that the desired frame matrix and
2305 desired window matrices share their glyph memory. This is not
2306 possible for current window matrices. Their glyphs are copied to
2307 the desired frame matrix. The latter is equivalent to
2308 preserve_other_columns in the old redisplay.
2310 Used glyphs counters for frame matrix rows are the result of adding
2311 up glyph lengths of the window matrices. A line in the frame
2312 matrix is enabled, if a corresponding line in a window matrix is
2313 enabled.
2315 After building the desired frame matrix, it will be passed to
2316 terminal code, which will manipulate both the desired and current
2317 frame matrix. Changes applied to the frame's current matrix have
2318 to be visible in current window matrices afterwards, of course.
2320 This problem is solved like this:
2322 1. Window and frame matrices share glyphs. Window matrices are
2323 constructed in a way that their glyph contents ARE the glyph
2324 contents needed in a frame matrix. Thus, any modification of
2325 glyphs done in terminal code will be reflected in window matrices
2326 automatically.
2328 2. Exchanges of rows in a frame matrix done by terminal code are
2329 intercepted by hook functions so that corresponding row operations
2330 on window matrices can be performed. This is necessary because we
2331 use pointers to glyphs in glyph row structures. To satisfy the
2332 assumption of point 1 above that glyphs are updated implicitly in
2333 window matrices when they are manipulated via the frame matrix,
2334 window and frame matrix must of course agree where to find the
2335 glyphs for their rows. Possible manipulations that must be
2336 mirrored are assignments of rows of the desired frame matrix to the
2337 current frame matrix and scrolling the current frame matrix. */
2339 /* Build frame F's desired matrix from window matrices. Only windows
2340 which have the flag must_be_updated_p set have to be updated. Menu
2341 bar lines of a frame are not covered by window matrices, so make
2342 sure not to touch them in this function. */
2344 static void
2345 build_frame_matrix (f)
2346 struct frame *f;
2348 int i;
2350 /* F must have a frame matrix when this function is called. */
2351 xassert (!FRAME_WINDOW_P (f));
2353 /* Clear all rows in the frame matrix covered by window matrices.
2354 Menu bar lines are not covered by windows. */
2355 for (i = FRAME_TOP_MARGIN (f); i < f->desired_matrix->nrows; ++i)
2356 clear_glyph_row (MATRIX_ROW (f->desired_matrix, i));
2358 /* Build the matrix by walking the window tree. */
2359 build_frame_matrix_from_window_tree (f->desired_matrix,
2360 XWINDOW (FRAME_ROOT_WINDOW (f)));
2364 /* Walk a window tree, building a frame matrix MATRIX from window
2365 matrices. W is the root of a window tree. */
2367 static void
2368 build_frame_matrix_from_window_tree (matrix, w)
2369 struct glyph_matrix *matrix;
2370 struct window *w;
2372 while (w)
2374 if (!NILP (w->hchild))
2375 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->hchild));
2376 else if (!NILP (w->vchild))
2377 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->vchild));
2378 else
2379 build_frame_matrix_from_leaf_window (matrix, w);
2381 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2386 /* Add a window's matrix to a frame matrix. FRAME_MATRIX is the
2387 desired frame matrix built. W is a leaf window whose desired or
2388 current matrix is to be added to FRAME_MATRIX. W's flag
2389 must_be_updated_p determines which matrix it contributes to
2390 FRAME_MATRIX. If must_be_updated_p is non-zero, W's desired matrix
2391 is added to FRAME_MATRIX, otherwise W's current matrix is added.
2392 Adding a desired matrix means setting up used counters and such in
2393 frame rows, while adding a current window matrix to FRAME_MATRIX
2394 means copying glyphs. The latter case corresponds to
2395 preserve_other_columns in the old redisplay. */
2397 static void
2398 build_frame_matrix_from_leaf_window (frame_matrix, w)
2399 struct glyph_matrix *frame_matrix;
2400 struct window *w;
2402 struct glyph_matrix *window_matrix;
2403 int window_y, frame_y;
2404 /* If non-zero, a glyph to insert at the right border of W. */
2405 GLYPH right_border_glyph = 0;
2407 /* Set window_matrix to the matrix we have to add to FRAME_MATRIX. */
2408 if (w->must_be_updated_p)
2410 window_matrix = w->desired_matrix;
2412 /* Decide whether we want to add a vertical border glyph. */
2413 if (!WINDOW_RIGHTMOST_P (w))
2415 struct Lisp_Char_Table *dp = window_display_table (w);
2416 right_border_glyph = (dp && INTEGERP (DISP_BORDER_GLYPH (dp))
2417 ? XINT (DISP_BORDER_GLYPH (dp))
2418 : '|');
2421 else
2422 window_matrix = w->current_matrix;
2424 /* For all rows in the window matrix and corresponding rows in the
2425 frame matrix. */
2426 window_y = 0;
2427 frame_y = window_matrix->matrix_y;
2428 while (window_y < window_matrix->nrows)
2430 struct glyph_row *frame_row = frame_matrix->rows + frame_y;
2431 struct glyph_row *window_row = window_matrix->rows + window_y;
2433 /* Fill up the frame row with spaces up to the left margin of the
2434 window row. */
2435 fill_up_frame_row_with_spaces (frame_row, window_matrix->matrix_x);
2437 /* Fill up areas in the window matrix row with spaces. */
2438 fill_up_glyph_row_with_spaces (window_row);
2440 if (window_matrix == w->current_matrix)
2442 /* We have to copy W's current matrix. Copy window
2443 row to frame row. */
2444 bcopy (window_row->glyphs[0],
2445 frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
2446 window_matrix->matrix_w * sizeof (struct glyph));
2448 else
2450 /* Copy W's desired matrix. */
2452 /* Maybe insert a vertical border between horizontally adjacent
2453 windows. */
2454 if (right_border_glyph)
2456 struct glyph *border = window_row->glyphs[LAST_AREA] - 1;
2457 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
2460 #if 0 /* This shouldn't be necessary. Let's check it. */
2461 /* Due to hooks installed, it normally doesn't happen that
2462 window rows and frame rows of the same matrix are out of
2463 sync, i.e. have a different understanding of where to
2464 find glyphs for the row. The following is a safety-belt
2465 that doesn't cost much and makes absolutely sure that
2466 window and frame matrices are in sync. */
2467 if (!glyph_row_slice_p (window_row, frame_row))
2469 /* Find the row in the window being a slice. There
2470 should exist one from program logic. */
2471 struct glyph_row *slice_row
2472 = find_glyph_row_slice (window_matrix, frame_matrix, frame_y);
2473 xassert (slice_row != 0);
2475 /* Exchange glyphs between both window rows. */
2476 swap_glyphs_in_rows (window_row, slice_row);
2478 /* Exchange pointers between both rows. */
2479 swap_glyph_pointers (window_row, slice_row);
2481 #endif
2483 /* Window row window_y must be a slice of frame row
2484 frame_y. */
2485 xassert (glyph_row_slice_p (window_row, frame_row));
2487 /* If rows are in sync, we don't have to copy glyphs because
2488 frame and window share glyphs. */
2490 #if GLYPH_DEBUG
2491 strcpy (w->current_matrix->method, w->desired_matrix->method);
2492 #endif
2495 /* Set number of used glyphs in the frame matrix. Since we fill
2496 up with spaces, and visit leaf windows from left to right it
2497 can be done simply. */
2498 frame_row->used[TEXT_AREA]
2499 = window_matrix->matrix_x + window_matrix->matrix_w;
2501 /* Or in flags. */
2502 frame_row->enabled_p |= window_row->enabled_p;
2503 frame_row->inverse_p |= window_row->inverse_p;
2505 /* Next row. */
2506 ++window_y;
2507 ++frame_y;
2512 /* Add spaces to a glyph row ROW in a window matrix.
2514 Each row has the form:
2516 +---------+-----------------------------+------------+
2517 | left | text | right |
2518 +---------+-----------------------------+------------+
2520 Left and right marginal areas are optional. This function adds
2521 spaces to areas so that there are no empty holes between areas.
2522 In other words: If the right area is not empty, the text area
2523 is filled up with spaces up to the right area. If the text area
2524 is not empty, the left area is filled up.
2526 To be called for frame-based redisplay, only. */
2528 static void
2529 fill_up_glyph_row_with_spaces (row)
2530 struct glyph_row *row;
2532 fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA);
2533 fill_up_glyph_row_area_with_spaces (row, TEXT_AREA);
2534 fill_up_glyph_row_area_with_spaces (row, RIGHT_MARGIN_AREA);
2538 /* Fill area AREA of glyph row ROW with spaces. To be called for
2539 frame-based redisplay only. */
2541 static void
2542 fill_up_glyph_row_area_with_spaces (row, area)
2543 struct glyph_row *row;
2544 int area;
2546 if (row->glyphs[area] < row->glyphs[area + 1])
2548 struct glyph *end = row->glyphs[area + 1];
2549 struct glyph *text = row->glyphs[area] + row->used[area];
2551 while (text < end)
2552 *text++ = space_glyph;
2553 row->used[area] = text - row->glyphs[area];
2558 /* Add spaces to the end of ROW in a frame matrix until index UPTO is
2559 reached. In frame matrices only one area, TEXT_AREA, is used. */
2561 static void
2562 fill_up_frame_row_with_spaces (row, upto)
2563 struct glyph_row *row;
2564 int upto;
2566 int i = row->used[TEXT_AREA];
2567 struct glyph *glyph = row->glyphs[TEXT_AREA];
2569 while (i < upto)
2570 glyph[i++] = space_glyph;
2572 row->used[TEXT_AREA] = i;
2577 /**********************************************************************
2578 Mirroring operations on frame matrices in window matrices
2579 **********************************************************************/
2581 /* Set frame being updated via frame-based redisplay to F. This
2582 function must be called before updates to make explicit that we are
2583 working on frame matrices or not. */
2585 static INLINE void
2586 set_frame_matrix_frame (f)
2587 struct frame *f;
2589 frame_matrix_frame = f;
2593 /* Make sure glyph row ROW in CURRENT_MATRIX is up to date.
2594 DESIRED_MATRIX is the desired matrix corresponding to
2595 CURRENT_MATRIX. The update is done by exchanging glyph pointers
2596 between rows in CURRENT_MATRIX and DESIRED_MATRIX. If
2597 frame_matrix_frame is non-null, this indicates that the exchange is
2598 done in frame matrices, and that we have to perform analogous
2599 operations in window matrices of frame_matrix_frame. */
2601 static INLINE void
2602 make_current (desired_matrix, current_matrix, row)
2603 struct glyph_matrix *desired_matrix, *current_matrix;
2604 int row;
2606 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2607 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
2609 /* Do current_row = desired_row. This exchanges glyph pointers
2610 between both rows, and does a structure assignment otherwise. */
2611 assign_row (current_row, desired_row);
2613 /* Enable current_row to mark it as valid. */
2614 current_row->enabled_p = 1;
2616 /* If we are called on frame matrices, perform analogous operations
2617 for window matrices. */
2618 if (frame_matrix_frame)
2619 mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row);
2623 /* W is the root of a window tree. FRAME_ROW is the index of a row in
2624 W's frame which has been made current (by swapping pointers between
2625 current and desired matrix). Perform analogous operations in the
2626 matrices of leaf windows in the window tree rooted at W. */
2628 static void
2629 mirror_make_current (w, frame_row)
2630 struct window *w;
2631 int frame_row;
2633 while (w)
2635 if (!NILP (w->hchild))
2636 mirror_make_current (XWINDOW (w->hchild), frame_row);
2637 else if (!NILP (w->vchild))
2638 mirror_make_current (XWINDOW (w->vchild), frame_row);
2639 else
2641 /* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS
2642 here because the checks performed in debug mode there
2643 will not allow the conversion. */
2644 int row = frame_row - w->desired_matrix->matrix_y;
2646 /* If FRAME_ROW is within W, assign the desired row to the
2647 current row (exchanging glyph pointers). */
2648 if (row >= 0 && row < w->desired_matrix->matrix_h)
2650 struct glyph_row *current_row
2651 = MATRIX_ROW (w->current_matrix, row);
2652 struct glyph_row *desired_row
2653 = MATRIX_ROW (w->desired_matrix, row);
2655 if (desired_row->enabled_p)
2656 assign_row (current_row, desired_row);
2657 else
2658 swap_glyph_pointers (desired_row, current_row);
2659 current_row->enabled_p = 1;
2663 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2668 /* Perform row dance after scrolling. We are working on the range of
2669 lines UNCHANGED_AT_TOP + 1 to UNCHANGED_AT_TOP + NLINES (not
2670 including) in MATRIX. COPY_FROM is a vector containing, for each
2671 row I in the range 0 <= I < NLINES, the index of the original line
2672 to move to I. This index is relative to the row range, i.e. 0 <=
2673 index < NLINES. RETAINED_P is a vector containing zero for each
2674 row 0 <= I < NLINES which is empty.
2676 This function is called from do_scrolling and do_direct_scrolling. */
2678 void
2679 mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
2680 retained_p)
2681 struct glyph_matrix *matrix;
2682 int unchanged_at_top, nlines;
2683 int *copy_from;
2684 char *retained_p;
2686 /* A copy of original rows. */
2687 struct glyph_row *old_rows;
2689 /* Rows to assign to. */
2690 struct glyph_row *new_rows = MATRIX_ROW (matrix, unchanged_at_top);
2692 int i;
2694 /* Make a copy of the original rows. */
2695 old_rows = (struct glyph_row *) alloca (nlines * sizeof *old_rows);
2696 bcopy (new_rows, old_rows, nlines * sizeof *old_rows);
2698 /* Assign new rows, maybe clear lines. */
2699 for (i = 0; i < nlines; ++i)
2701 int enabled_before_p = new_rows[i].enabled_p;
2703 xassert (i + unchanged_at_top < matrix->nrows);
2704 xassert (unchanged_at_top + copy_from[i] < matrix->nrows);
2705 new_rows[i] = old_rows[copy_from[i]];
2706 new_rows[i].enabled_p = enabled_before_p;
2708 /* RETAINED_P is zero for empty lines. */
2709 if (!retained_p[copy_from[i]])
2710 new_rows[i].enabled_p = 0;
2713 /* Do the same for window matrices, if MATRIX Is a frame matrix. */
2714 if (frame_matrix_frame)
2715 mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
2716 unchanged_at_top, nlines, copy_from, retained_p);
2720 /* Synchronize glyph pointers in the current matrix of window W with
2721 the current frame matrix. W must be full-width, and be on a tty
2722 frame. */
2724 static void
2725 sync_window_with_frame_matrix_rows (w)
2726 struct window *w;
2728 struct frame *f = XFRAME (w->frame);
2729 struct glyph_row *window_row, *window_row_end, *frame_row;
2731 /* Preconditions: W must be a leaf window and full-width. Its frame
2732 must have a frame matrix. */
2733 xassert (NILP (w->hchild) && NILP (w->vchild));
2734 xassert (WINDOW_FULL_WIDTH_P (w));
2735 xassert (!FRAME_WINDOW_P (f));
2737 /* If W is a full-width window, glyph pointers in W's current matrix
2738 have, by definition, to be the same as glyph pointers in the
2739 corresponding frame matrix. */
2740 window_row = w->current_matrix->rows;
2741 window_row_end = window_row + w->current_matrix->nrows;
2742 frame_row = f->current_matrix->rows + XFASTINT (w->top);
2743 while (window_row < window_row_end)
2745 int area;
2747 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
2748 window_row->glyphs[area] = frame_row->glyphs[area];
2750 ++window_row, ++frame_row;
2755 /* Return the window in the window tree rooted in W containing frame
2756 row ROW. Value is null if none is found. */
2758 struct window *
2759 frame_row_to_window (w, row)
2760 struct window *w;
2761 int row;
2763 struct window *found = NULL;
2765 while (w && !found)
2767 if (!NILP (w->hchild))
2768 found = frame_row_to_window (XWINDOW (w->hchild), row);
2769 else if (!NILP (w->vchild))
2770 found = frame_row_to_window (XWINDOW (w->vchild), row);
2771 else if (row >= XFASTINT (w->top)
2772 && row < XFASTINT (w->top) + XFASTINT (w->height))
2773 found = w;
2775 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2778 return found;
2782 /* Perform a line dance in the window tree rooted at W, after
2783 scrolling a frame matrix in mirrored_line_dance.
2785 We are working on the range of lines UNCHANGED_AT_TOP + 1 to
2786 UNCHANGED_AT_TOP + NLINES (not including) in W's frame matrix.
2787 COPY_FROM is a vector containing, for each row I in the range 0 <=
2788 I < NLINES, the index of the original line to move to I. This
2789 index is relative to the row range, i.e. 0 <= index < NLINES.
2790 RETAINED_P is a vector containing zero for each row 0 <= I < NLINES
2791 which is empty. */
2793 static void
2794 mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
2795 struct window *w;
2796 int unchanged_at_top, nlines;
2797 int *copy_from;
2798 char *retained_p;
2800 while (w)
2802 if (!NILP (w->hchild))
2803 mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top,
2804 nlines, copy_from, retained_p);
2805 else if (!NILP (w->vchild))
2806 mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
2807 nlines, copy_from, retained_p);
2808 else
2810 /* W is a leaf window, and we are working on its current
2811 matrix m. */
2812 struct glyph_matrix *m = w->current_matrix;
2813 int i, sync_p = 0;
2814 struct glyph_row *old_rows;
2816 /* Make a copy of the original rows of matrix m. */
2817 old_rows = (struct glyph_row *) alloca (m->nrows * sizeof *old_rows);
2818 bcopy (m->rows, old_rows, m->nrows * sizeof *old_rows);
2820 for (i = 0; i < nlines; ++i)
2822 /* Frame relative line assigned to. */
2823 int frame_to = i + unchanged_at_top;
2825 /* Frame relative line assigned. */
2826 int frame_from = copy_from[i] + unchanged_at_top;
2828 /* Window relative line assigned to. */
2829 int window_to = frame_to - m->matrix_y;
2831 /* Window relative line assigned. */
2832 int window_from = frame_from - m->matrix_y;
2834 /* Is assigned line inside window? */
2835 int from_inside_window_p
2836 = window_from >= 0 && window_from < m->matrix_h;
2838 /* Is assigned to line inside window? */
2839 int to_inside_window_p
2840 = window_to >= 0 && window_to < m->matrix_h;
2842 if (from_inside_window_p && to_inside_window_p)
2844 /* Enabled setting before assignment. */
2845 int enabled_before_p;
2847 /* Do the assignment. The enabled_p flag is saved
2848 over the assignment because the old redisplay did
2849 that. */
2850 enabled_before_p = m->rows[window_to].enabled_p;
2851 m->rows[window_to] = old_rows[window_from];
2852 m->rows[window_to].enabled_p = enabled_before_p;
2854 /* If frame line is empty, window line is empty, too. */
2855 if (!retained_p[copy_from[i]])
2856 m->rows[window_to].enabled_p = 0;
2858 else if (to_inside_window_p)
2860 /* A copy between windows. This is an infrequent
2861 case not worth optimizing. */
2862 struct frame *f = XFRAME (w->frame);
2863 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
2864 struct window *w2;
2865 struct glyph_matrix *m2;
2866 int m2_from;
2868 w2 = frame_row_to_window (root, frame_to);
2869 m2 = w2->current_matrix;
2870 m2_from = frame_from - m2->matrix_y;
2871 copy_row_except_pointers (m->rows + window_to,
2872 m2->rows + m2_from);
2874 /* If frame line is empty, window line is empty, too. */
2875 if (!retained_p[copy_from[i]])
2876 m->rows[window_to].enabled_p = 0;
2877 sync_p = 1;
2879 else if (from_inside_window_p)
2880 sync_p = 1;
2883 /* If there was a copy between windows, make sure glyph
2884 pointers are in sync with the frame matrix. */
2885 if (sync_p)
2886 sync_window_with_frame_matrix_rows (w);
2888 /* Check that no pointers are lost. */
2889 CHECK_MATRIX (m);
2892 /* Next window on same level. */
2893 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2898 #if GLYPH_DEBUG
2900 /* Check that window and frame matrices agree about their
2901 understanding where glyphs of the rows are to find. For each
2902 window in the window tree rooted at W, check that rows in the
2903 matrices of leaf window agree with their frame matrices about
2904 glyph pointers. */
2906 void
2907 check_window_matrix_pointers (w)
2908 struct window *w;
2910 while (w)
2912 if (!NILP (w->hchild))
2913 check_window_matrix_pointers (XWINDOW (w->hchild));
2914 else if (!NILP (w->vchild))
2915 check_window_matrix_pointers (XWINDOW (w->vchild));
2916 else
2918 struct frame *f = XFRAME (w->frame);
2919 check_matrix_pointers (w->desired_matrix, f->desired_matrix);
2920 check_matrix_pointers (w->current_matrix, f->current_matrix);
2923 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2928 /* Check that window rows are slices of frame rows. WINDOW_MATRIX is
2929 a window and FRAME_MATRIX is the corresponding frame matrix. For
2930 each row in WINDOW_MATRIX check that it's a slice of the
2931 corresponding frame row. If it isn't, abort. */
2933 static void
2934 check_matrix_pointers (window_matrix, frame_matrix)
2935 struct glyph_matrix *window_matrix, *frame_matrix;
2937 /* Row number in WINDOW_MATRIX. */
2938 int i = 0;
2940 /* Row number corresponding to I in FRAME_MATRIX. */
2941 int j = window_matrix->matrix_y;
2943 /* For all rows check that the row in the window matrix is a
2944 slice of the row in the frame matrix. If it isn't we didn't
2945 mirror an operation on the frame matrix correctly. */
2946 while (i < window_matrix->nrows)
2948 if (!glyph_row_slice_p (window_matrix->rows + i,
2949 frame_matrix->rows + j))
2950 abort ();
2951 ++i, ++j;
2955 #endif /* GLYPH_DEBUG != 0 */
2959 /**********************************************************************
2960 VPOS and HPOS translations
2961 **********************************************************************/
2963 #if GLYPH_DEBUG
2965 /* Translate vertical position VPOS which is relative to window W to a
2966 vertical position relative to W's frame. */
2968 static int
2969 window_to_frame_vpos (w, vpos)
2970 struct window *w;
2971 int vpos;
2973 struct frame *f = XFRAME (w->frame);
2975 xassert (!FRAME_WINDOW_P (f));
2976 xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
2977 vpos += XFASTINT (w->top);
2978 xassert (vpos >= 0 && vpos <= FRAME_HEIGHT (f));
2979 return vpos;
2983 /* Translate horizontal position HPOS which is relative to window W to
2984 a vertical position relative to W's frame. */
2986 static int
2987 window_to_frame_hpos (w, hpos)
2988 struct window *w;
2989 int hpos;
2991 struct frame *f = XFRAME (w->frame);
2993 xassert (!FRAME_WINDOW_P (f));
2994 hpos += XFASTINT (w->left);
2995 return hpos;
2998 #endif /* GLYPH_DEBUG */
3002 /**********************************************************************
3003 Redrawing Frames
3004 **********************************************************************/
3006 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
3007 "Clear frame FRAME and output again what is supposed to appear on it.")
3008 (frame)
3009 Lisp_Object frame;
3011 struct frame *f;
3013 CHECK_LIVE_FRAME (frame, 0);
3014 f = XFRAME (frame);
3016 /* Ignore redraw requests, if frame has no glyphs yet.
3017 (Implementation note: It still has to be checked why we are
3018 called so early here). */
3019 if (!glyphs_initialized_initially_p)
3020 return Qnil;
3022 update_begin (f);
3023 if (FRAME_MSDOS_P (f))
3024 set_terminal_modes ();
3025 clear_frame ();
3026 clear_current_matrices (f);
3027 update_end (f);
3028 fflush (stdout);
3029 windows_or_buffers_changed++;
3030 /* Mark all windows as inaccurate, so that every window will have
3031 its redisplay done. */
3032 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
3033 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
3034 f->garbaged = 0;
3035 return Qnil;
3039 /* Redraw frame F. This is nothing more than a call to the Lisp
3040 function redraw-frame. */
3042 void
3043 redraw_frame (f)
3044 struct frame *f;
3046 Lisp_Object frame;
3047 XSETFRAME (frame, f);
3048 Fredraw_frame (frame);
3052 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3053 "Clear and redisplay all visible frames.")
3056 Lisp_Object tail, frame;
3058 FOR_EACH_FRAME (tail, frame)
3059 if (FRAME_VISIBLE_P (XFRAME (frame)))
3060 Fredraw_frame (frame);
3062 return Qnil;
3066 /* This is used when frame_garbaged is set. Call Fredraw_frame on all
3067 visible frames marked as garbaged. */
3069 void
3070 redraw_garbaged_frames ()
3072 Lisp_Object tail, frame;
3074 FOR_EACH_FRAME (tail, frame)
3075 if (FRAME_VISIBLE_P (XFRAME (frame))
3076 && FRAME_GARBAGED_P (XFRAME (frame)))
3077 Fredraw_frame (frame);
3082 /***********************************************************************
3083 Direct Operations
3084 ***********************************************************************/
3086 /* Try to update display and current glyph matrix directly.
3088 This function is called after a character G has been inserted into
3089 current_buffer. It tries to update the current glyph matrix and
3090 perform appropriate screen output to reflect the insertion. If it
3091 succeeds, the global flag redisplay_performed_directly_p will be
3092 set to 1, and thereby prevent the more costly general redisplay
3093 from running (see redisplay_internal).
3095 This function is not called for `hairy' character insertions.
3096 In particular, it is not called when after or before change
3097 functions exist, like they are used by font-lock. See keyboard.c
3098 for details where this function is called. */
3101 direct_output_for_insert (g)
3102 int g;
3104 register struct frame *f = SELECTED_FRAME ();
3105 struct window *w = XWINDOW (selected_window);
3106 struct it it, it2;
3107 struct glyph_row *glyph_row;
3108 struct glyph *glyphs, *glyph, *end;
3109 int n;
3110 /* Non-null means that Redisplay of W is based on window matrices. */
3111 int window_redisplay_p = FRAME_WINDOW_P (f);
3112 /* Non-null means we are in overwrite mode. */
3113 int overwrite_p = !NILP (current_buffer->overwrite_mode);
3114 int added_width;
3115 struct text_pos pos;
3116 int delta, delta_bytes;
3118 /* Not done directly. */
3119 redisplay_performed_directly_p = 0;
3121 /* Quickly give up for some common cases. */
3122 if (cursor_in_echo_area
3123 /* Give up if fonts have changed. */
3124 || fonts_changed_p
3125 /* Give up if face attributes have been changed. */
3126 || face_change_count
3127 /* Give up if cursor position not really known. */
3128 || !display_completed
3129 /* Give up if buffer appears in two places. */
3130 || buffer_shared > 1
3131 /* Give up if w is mini-buffer and a message is being displayed there */
3132 || (MINI_WINDOW_P (w) && !NILP (echo_area_buffer[0]))
3133 /* Give up for hscrolled mini-buffer because display of the prompt
3134 is handled specially there (see display_line). */
3135 || (MINI_WINDOW_P (w) && XFASTINT (w->hscroll))
3136 /* Give up if overwriting in the middle of a line. */
3137 || (overwrite_p
3138 && PT != ZV
3139 && FETCH_BYTE (PT) != '\n')
3140 /* Give up for tabs and line ends. */
3141 || g == '\t'
3142 || g == '\n'
3143 || g == '\r'
3144 /* Give up if unable to display the cursor in the window. */
3145 || w->cursor.vpos < 0
3146 || (glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos),
3147 /* Can't do it in a continued line because continuation
3148 lines would change. */
3149 (glyph_row->continued_p
3150 /* Can't use this method if the line overlaps others or is
3151 overlapped by others because these other lines would
3152 have to be redisplayed. */
3153 || glyph_row->overlapping_p
3154 || glyph_row->overlapped_p))
3155 /* Can't do it for partial width windows on terminal frames
3156 because we can't clear to eol in such a window. */
3157 || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w)))
3158 return 0;
3160 /* Set up a display iterator structure for W. Glyphs will be
3161 produced in scratch_glyph_row. Current position is W's cursor
3162 position. */
3163 clear_glyph_row (&scratch_glyph_row);
3164 SET_TEXT_POS (pos, PT, PT_BYTE);
3165 DEC_TEXT_POS (pos);
3166 init_iterator (&it, w, CHARPOS (pos), BYTEPOS (pos), &scratch_glyph_row,
3167 DEFAULT_FACE_ID);
3169 glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
3171 /* Give up if highlighting trailing whitespace and we have trailing
3172 whitespace in glyph_row. We would have to remove the trailing
3173 whitespace face in that case. */
3174 if (!NILP (Vshow_trailing_whitespace)
3175 && glyph_row->used[TEXT_AREA])
3177 struct glyph *last;
3179 last = glyph_row->glyphs[TEXT_AREA] + glyph_row->used[TEXT_AREA] - 1;
3180 if (last->type == STRETCH_GLYPH
3181 || (last->type == CHAR_GLYPH
3182 && last->u.ch == ' '))
3183 return 0;
3186 /* Give up if there are overlay strings at pos. This would fail
3187 if the overlay string has newlines in it. */
3188 if (STRINGP (it.string))
3189 return 0;
3191 it.hpos = w->cursor.hpos;
3192 it.vpos = w->cursor.vpos;
3193 it.current_x = w->cursor.x + it.first_visible_x;
3194 it.current_y = w->cursor.y;
3195 it.end_charpos = PT;
3196 it.stop_charpos = min (PT, it.stop_charpos);
3198 /* More than one display element may be returned for PT - 1 if
3199 (i) it's a control character which is translated into `\003' or
3200 `^C', or (ii) it has a display table entry, or (iii) it's a
3201 combination of both. */
3202 delta = delta_bytes = 0;
3203 while (get_next_display_element (&it))
3205 PRODUCE_GLYPHS (&it);
3207 /* Give up if glyph doesn't fit completely on the line. */
3208 if (it.current_x >= it.last_visible_x)
3209 return 0;
3211 /* Give up if new glyph has different ascent or descent than
3212 the original row, or if it is not a character glyph. */
3213 if (glyph_row->ascent != it.ascent
3214 || glyph_row->height != it.ascent + it.descent
3215 || glyph_row->phys_ascent != it.phys_ascent
3216 || glyph_row->phys_height != it.phys_ascent + it.phys_descent
3217 || it.what != IT_CHARACTER)
3218 return 0;
3220 delta += 1;
3221 delta_bytes += it.len;
3222 set_iterator_to_next (&it);
3225 /* Give up if we hit the right edge of the window. We would have
3226 to insert truncation or continuation glyphs. */
3227 added_width = it.current_x - (w->cursor.x + it.first_visible_x);
3228 if (glyph_row->pixel_width + added_width >= it.last_visible_x)
3229 return 0;
3231 /* Give up if there is a \t following in the line. */
3232 it2 = it;
3233 it2.end_charpos = ZV;
3234 it2.stop_charpos = min (it2.stop_charpos, ZV);
3235 while (get_next_display_element (&it2)
3236 && !ITERATOR_AT_END_OF_LINE_P (&it2))
3238 if (it2.c == '\t')
3239 return 0;
3240 set_iterator_to_next (&it2);
3243 /* Number of new glyphs produced. */
3244 n = it.glyph_row->used[TEXT_AREA];
3246 /* Start and end of glyphs in original row. */
3247 glyphs = glyph_row->glyphs[TEXT_AREA] + w->cursor.hpos;
3248 end = glyph_row->glyphs[1 + TEXT_AREA];
3250 /* Make room for new glyphs, then insert them. */
3251 xassert (end - glyphs - n >= 0);
3252 safe_bcopy ((char *) glyphs, (char *) (glyphs + n),
3253 (end - glyphs - n) * sizeof (*end));
3254 bcopy (it.glyph_row->glyphs[TEXT_AREA], glyphs, n * sizeof *glyphs);
3255 glyph_row->used[TEXT_AREA] = min (glyph_row->used[TEXT_AREA] + n,
3256 end - glyph_row->glyphs[TEXT_AREA]);
3258 /* Compute new line width. */
3259 glyph = glyph_row->glyphs[TEXT_AREA];
3260 end = glyph + glyph_row->used[TEXT_AREA];
3261 glyph_row->pixel_width = glyph_row->x;
3262 while (glyph < end)
3264 glyph_row->pixel_width += glyph->pixel_width;
3265 ++glyph;
3268 /* Increment buffer positions for glyphs following the newly
3269 inserted ones. */
3270 for (glyph = glyphs + n; glyph < end; ++glyph)
3271 if (glyph->charpos > 0 && BUFFERP (glyph->object))
3272 glyph->charpos += delta;
3274 if (MATRIX_ROW_END_CHARPOS (glyph_row) > 0)
3276 MATRIX_ROW_END_CHARPOS (glyph_row) += delta;
3277 MATRIX_ROW_END_BYTEPOS (glyph_row) += delta_bytes;
3280 /* Adjust positions in lines following the one we are in. */
3281 increment_glyph_matrix_buffer_positions (w->current_matrix,
3282 w->cursor.vpos + 1,
3283 w->current_matrix->nrows,
3284 delta, delta_bytes);
3286 glyph_row->contains_overlapping_glyphs_p
3287 |= it.glyph_row->contains_overlapping_glyphs_p;
3289 glyph_row->displays_text_p = 1;
3290 w->window_end_vpos = make_number (max (w->cursor.vpos,
3291 XFASTINT (w->window_end_vpos)));
3293 if (!NILP (Vshow_trailing_whitespace))
3294 highlight_trailing_whitespace (it.f, glyph_row);
3296 /* Write glyphs. If at end of row, we can simply call write_glyphs.
3297 In the middle, we have to insert glyphs. Note that this is now
3298 implemented for X frames. The implementation uses updated_window
3299 and updated_row. */
3300 updated_row = glyph_row;
3301 update_begin (f);
3302 if (rif)
3304 rif->update_window_begin_hook (w);
3306 if (glyphs == end - n)
3307 rif->write_glyphs (glyphs, n);
3308 else
3309 rif->insert_glyphs (glyphs, n);
3311 else
3313 if (glyphs == end - n)
3314 write_glyphs (glyphs, n);
3315 else
3316 insert_glyphs (glyphs, n);
3319 w->cursor.hpos += n;
3320 w->cursor.x = it.current_x - it.first_visible_x;
3321 xassert (w->cursor.hpos >= 0
3322 && w->cursor.hpos < w->desired_matrix->matrix_w);
3324 /* How to set the cursor differs depending on whether we are
3325 using a frame matrix or a window matrix. Note that when
3326 a frame matrix is used, cursor_to expects frame coordinates,
3327 and the X and Y parameters are not used. */
3328 if (window_redisplay_p)
3329 rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
3330 w->cursor.y, w->cursor.x);
3331 else
3333 int x, y;
3334 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3335 + (INTEGERP (w->left_margin_width)
3336 ? XFASTINT (w->left_margin_width)
3337 : 0));
3338 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3339 cursor_to (y, x);
3342 if (rif)
3343 rif->update_window_end_hook (w, 1);
3344 update_end (f);
3345 updated_row = NULL;
3346 fflush (stdout);
3348 TRACE ((stderr, "direct output for insert\n"));
3350 UNCHANGED_MODIFIED = MODIFF;
3351 BEG_UNCHANGED = GPT - BEG;
3352 XSETFASTINT (w->last_point, PT);
3353 w->last_cursor = w->cursor;
3354 XSETFASTINT (w->last_modified, MODIFF);
3355 XSETFASTINT (w->last_overlay_modified, OVERLAY_MODIFF);
3357 redisplay_performed_directly_p = 1;
3358 return 1;
3362 /* Perform a direct display update for moving PT by N positions
3363 left or right. N < 0 means a movement backwards. This function
3364 is currently only called for N == 1 or N == -1. */
3367 direct_output_forward_char (n)
3368 int n;
3370 struct frame *f = SELECTED_FRAME ();
3371 struct window *w = XWINDOW (selected_window);
3372 struct glyph_row *row;
3374 /* Give up if point moved out of or into a composition. */
3375 if (check_point_in_composition (current_buffer, w->last_point,
3376 current_buffer, PT))
3377 return 0;
3379 /* Give up if face attributes have been changed. */
3380 if (face_change_count)
3381 return 0;
3383 /* Give up if current matrix is not up to date or we are
3384 displaying a message. */
3385 if (!display_completed || cursor_in_echo_area)
3386 return 0;
3388 /* Give up if the buffer's direction is reversed. */
3389 if (!NILP (XBUFFER (w->buffer)->direction_reversed))
3390 return 0;
3392 /* Can't use direct output if highlighting a region. */
3393 if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
3394 return 0;
3396 /* Can't use direct output if highlighting trailing whitespace. */
3397 if (!NILP (Vshow_trailing_whitespace))
3398 return 0;
3400 /* Give up if we are showing a message or just cleared the message
3401 because we might need to resize the echo area window. */
3402 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
3403 return 0;
3405 /* Give up if we don't know where the cursor is. */
3406 if (w->cursor.vpos < 0)
3407 return 0;
3409 row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
3411 if (PT <= MATRIX_ROW_START_BYTEPOS (row)
3412 || PT >= MATRIX_ROW_END_BYTEPOS (row))
3413 return 0;
3415 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
3416 w->last_cursor = w->cursor;
3417 XSETFASTINT (w->last_point, PT);
3419 xassert (w->cursor.hpos >= 0
3420 && w->cursor.hpos < w->desired_matrix->matrix_w);
3422 if (FRAME_WINDOW_P (f))
3423 rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
3424 w->cursor.y, w->cursor.x);
3425 else
3427 int x, y;
3428 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3429 + (INTEGERP (w->left_margin_width)
3430 ? XFASTINT (w->left_margin_width)
3431 : 0));
3432 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3433 cursor_to (y, x);
3436 fflush (stdout);
3437 redisplay_performed_directly_p = 1;
3438 return 1;
3443 /***********************************************************************
3444 Frame Update
3445 ***********************************************************************/
3447 /* Update frame F based on the data in desired matrices.
3449 If FORCE_P is non-zero, don't let redisplay be stopped by detecting
3450 pending input. If INHIBIT_HAIRY_ID_P is non-zero, don't try
3451 scrolling.
3453 Value is non-zero if redisplay was stopped due to pending input. */
3456 update_frame (f, force_p, inhibit_hairy_id_p)
3457 struct frame *f;
3458 int force_p;
3459 int inhibit_hairy_id_p;
3461 /* 1 means display has been paused because of pending input. */
3462 int paused_p;
3463 struct window *root_window = XWINDOW (f->root_window);
3465 if (FRAME_WINDOW_P (f))
3467 /* We are working on window matrix basis. All windows whose
3468 flag must_be_updated_p is set have to be updated. */
3470 /* Record that we are not working on frame matrices. */
3471 set_frame_matrix_frame (NULL);
3473 /* Update all windows in the window tree of F, maybe stopping
3474 when pending input is detected. */
3475 update_begin (f);
3477 /* Update the menu bar on X frames that don't have toolkit
3478 support. */
3479 if (WINDOWP (f->menu_bar_window))
3480 update_window (XWINDOW (f->menu_bar_window), 1);
3482 /* Update the tool-bar window, if present. */
3483 if (WINDOWP (f->tool_bar_window))
3485 Lisp_Object tem;
3486 struct window *w = XWINDOW (f->tool_bar_window);
3488 /* Update tool-bar window. */
3489 if (w->must_be_updated_p)
3491 update_window (w, 1);
3492 w->must_be_updated_p = 0;
3494 /* Swap tool-bar strings. We swap because we want to
3495 reuse strings. */
3496 tem = f->current_tool_bar_string;
3497 f->current_tool_bar_string = f->desired_tool_bar_string;
3498 f->desired_tool_bar_string = tem;
3499 f->n_current_tool_bar_items = f->n_desired_tool_bar_items;
3501 /* Swap tool-bar items. We swap because we want to
3502 reuse vectors. */
3503 tem = f->current_tool_bar_items;
3504 f->current_tool_bar_items = f->desired_tool_bar_items;
3505 f->desired_tool_bar_items = tem;
3510 /* Update windows. */
3511 paused_p = update_window_tree (root_window, force_p);
3512 update_end (f);
3513 display_completed = !paused_p;
3515 /* The flush is a performance bottleneck under X. */
3516 #if 0
3517 rif->flush_display (f);
3518 #endif
3520 else
3522 /* We are working on frame matrix basis. Set the frame on whose
3523 frame matrix we operate. */
3524 set_frame_matrix_frame (f);
3526 /* Build F's desired matrix from window matrices. For windows
3527 whose must_be_updated_p flag is set, desired matrices are
3528 made part of the desired frame matrix. For other windows,
3529 the current matrix is copied. */
3530 build_frame_matrix (f);
3532 /* Do the update on the frame desired matrix. */
3533 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
3535 /* Check window matrices for lost pointers. */
3536 IF_DEBUG (check_window_matrix_pointers (root_window));
3539 /* Reset flags indicating that a window should be updated. */
3540 set_window_update_flags (root_window, 0);
3541 return paused_p;
3546 /************************************************************************
3547 Window-based updates
3548 ************************************************************************/
3550 /* Perform updates in window tree rooted at W. FORCE_P non-zero means
3551 don't stop updating when input is pending. */
3553 static int
3554 update_window_tree (w, force_p)
3555 struct window *w;
3556 int force_p;
3558 int paused_p = 0;
3560 while (w && !paused_p)
3562 if (!NILP (w->hchild))
3563 paused_p |= update_window_tree (XWINDOW (w->hchild), force_p);
3564 else if (!NILP (w->vchild))
3565 paused_p |= update_window_tree (XWINDOW (w->vchild), force_p);
3566 else if (w->must_be_updated_p)
3567 paused_p |= update_window (w, force_p);
3569 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3572 return paused_p;
3576 /* Update window W if its flag must_be_updated_p is non-zero. If
3577 FORCE_P is non-zero, don't stop updating if input is pending. */
3579 void
3580 update_single_window (w, force_p)
3581 struct window *w;
3582 int force_p;
3584 if (w->must_be_updated_p)
3586 struct frame *f = XFRAME (WINDOW_FRAME (w));
3588 /* Record that this is not a frame-based redisplay. */
3589 set_frame_matrix_frame (NULL);
3591 /* Update W. */
3592 update_begin (f);
3593 update_window (w, force_p);
3594 update_end (f);
3596 /* Reset flag in W. */
3597 w->must_be_updated_p = 0;
3602 /* Redraw lines from the current matrix of window W that are
3603 overlapped by other rows. YB is bottom-most y-position in W. */
3605 static void
3606 redraw_overlapped_rows (w, yb)
3607 struct window *w;
3608 int yb;
3610 int i, bottom_y;
3611 struct glyph_row *row;
3613 /* If rows overlapping others have been changed, the rows being
3614 overlapped have to be redrawn. This won't draw lines that have
3615 already been drawn in update_window_line because overlapped_p in
3616 desired rows is 0, so after row assignment overlapped_p in
3617 current rows is 0. */
3618 for (i = 0; i < w->current_matrix->nrows; ++i)
3620 row = w->current_matrix->rows + i;
3622 if (!row->enabled_p)
3623 break;
3624 else if (row->mode_line_p)
3625 continue;
3627 if (row->overlapped_p)
3629 enum glyph_row_area area;
3631 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
3633 updated_row = row;
3634 updated_area = area;
3635 rif->cursor_to (i, 0, row->y, area == TEXT_AREA ? row->x : 0);
3636 if (row->used[area])
3637 rif->write_glyphs (row->glyphs[area], row->used[area]);
3638 rif->clear_end_of_line (-1);
3641 row->overlapped_p = 0;
3644 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3645 if (bottom_y >= yb)
3646 break;
3651 /* Redraw lines from the current matrix of window W that overlap
3652 others. YB is bottom-most y-position in W. */
3654 static void
3655 redraw_overlapping_rows (w, yb)
3656 struct window *w;
3657 int yb;
3659 int i, bottom_y;
3660 struct glyph_row *row;
3662 for (i = 0; i < w->current_matrix->nrows; ++i)
3664 row = w->current_matrix->rows + i;
3666 if (!row->enabled_p)
3667 break;
3668 else if (row->mode_line_p)
3669 continue;
3671 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3673 if (row->overlapping_p && i > 0 && bottom_y < yb)
3675 if (row->used[LEFT_MARGIN_AREA])
3676 rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
3678 if (row->used[TEXT_AREA])
3679 rif->fix_overlapping_area (w, row, TEXT_AREA);
3681 if (row->used[RIGHT_MARGIN_AREA])
3682 rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
3684 /* Record in neighbor rows that ROW overwrites part of their
3685 display. */
3686 if (row->phys_ascent > row->ascent && i > 0)
3687 MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
3688 if ((row->phys_height - row->phys_ascent
3689 > row->height - row->ascent)
3690 && bottom_y < yb)
3691 MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
3694 if (bottom_y >= yb)
3695 break;
3700 /* Update display of window W. FORCE_P non-zero means that we should
3701 not stop when detecting pending input. */
3703 static int
3704 update_window (w, force_p)
3705 struct window *w;
3706 int force_p;
3708 struct glyph_matrix *desired_matrix = w->desired_matrix;
3709 int paused_p;
3710 int preempt_count = baud_rate / 2400 + 1;
3711 extern int input_pending;
3712 #if GLYPH_DEBUG
3713 struct frame *f = XFRAME (WINDOW_FRAME (w));
3714 extern struct frame *updating_frame;
3715 #endif
3717 /* Check that W's frame doesn't have glyph matrices. */
3718 xassert (FRAME_WINDOW_P (f));
3719 xassert (updating_frame != NULL);
3721 /* Check pending input the first time so that we can quickly return. */
3722 if (redisplay_dont_pause)
3723 force_p = 1;
3724 else
3725 detect_input_pending ();
3727 /* If forced to complete the update, or if no input is pending, do
3728 the update. */
3729 if (force_p || !input_pending)
3731 struct glyph_row *row, *end;
3732 struct glyph_row *mode_line_row;
3733 struct glyph_row *header_line_row = NULL;
3734 int yb, changed_p = 0;
3736 rif->update_window_begin_hook (w);
3737 yb = window_text_bottom_y (w);
3739 /* If window has a top line, update it before everything else.
3740 Adjust y-positions of other rows by the top line height. */
3741 row = desired_matrix->rows;
3742 end = row + desired_matrix->nrows - 1;
3743 if (row->mode_line_p)
3744 header_line_row = row++;
3746 /* Update the mode line, if necessary. */
3747 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
3748 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
3750 mode_line_row->y = yb;
3751 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
3752 desired_matrix));
3753 changed_p = 1;
3756 /* Find first enabled row. Optimizations in redisplay_internal
3757 may lead to an update with only one row enabled. There may
3758 be also completely empty matrices. */
3759 while (row < end && !row->enabled_p)
3760 ++row;
3762 /* Try reusing part of the display by inserting/deleting lines. */
3763 if (row < end && !desired_matrix->no_scrolling_p)
3765 int rc = scrolling_window (w, header_line_row != NULL);
3766 if (rc < 0)
3768 /* All rows were found to be equal. */
3769 paused_p = 0;
3770 goto set_cursor;
3772 else if (rc > 0)
3773 force_p = 1;
3774 changed_p = 1;
3777 /* Update the top mode line after scrolling because a new top
3778 line would otherwise overwrite lines at the top of the window
3779 that can be scrolled. */
3780 if (header_line_row && header_line_row->enabled_p)
3782 header_line_row->y = 0;
3783 update_window_line (w, 0);
3784 changed_p = 1;
3787 /* Update the rest of the lines. */
3788 for (; row < end && (force_p || !input_pending); ++row)
3789 if (row->enabled_p
3790 /* A row can be completely invisible in case a desired
3791 matrix was built with a vscroll and then
3792 make_cursor_line_fully_visible shifts the matrix. */
3793 && row->visible_height > 0)
3795 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
3796 int i;
3798 /* We'll Have to play a little bit with when to
3799 detect_input_pending. If it's done too often,
3800 scrolling large windows with repeated scroll-up
3801 commands will too quickly pause redisplay. */
3802 if (!force_p && vpos % preempt_count == 0)
3803 detect_input_pending ();
3805 changed_p |= update_window_line (w, vpos);
3807 /* Mark all rows below the last visible one in the current
3808 matrix as invalid. This is necessary because of
3809 variable line heights. Consider the case of three
3810 successive redisplays, where the first displays 5
3811 lines, the second 3 lines, and the third 5 lines again.
3812 If the second redisplay wouldn't mark rows in the
3813 current matrix invalid, the third redisplay might be
3814 tempted to optimize redisplay based on lines displayed
3815 in the first redisplay. */
3816 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3817 for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
3818 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
3821 /* Was display preempted? */
3822 paused_p = row < end;
3824 set_cursor:
3826 /* Fix the appearance of overlapping(overlapped rows. */
3827 if (rif->fix_overlapping_area
3828 && !w->pseudo_window_p
3829 && changed_p
3830 && !paused_p)
3832 redraw_overlapped_rows (w, yb);
3833 redraw_overlapping_rows (w, yb);
3836 if (!paused_p && !w->pseudo_window_p)
3838 /* Make cursor visible at cursor position of W. */
3839 set_window_cursor_after_update (w);
3841 #if 0
3842 /* Check that current matrix invariants are satisfied. This
3843 is for debugging only. See the comment around
3844 check_matrix_invariants. */
3845 IF_DEBUG (check_matrix_invariants (w));
3846 #endif
3849 #if GLYPH_DEBUG
3850 /* Remember the redisplay method used to display the matrix. */
3851 strcpy (w->current_matrix->method, w->desired_matrix->method);
3852 #endif
3854 /* End of update of window W. */
3855 rif->update_window_end_hook (w, 1);
3858 else
3859 paused_p = 1;
3861 clear_glyph_matrix (desired_matrix);
3863 return paused_p;
3867 /* Update the display of area AREA in window W, row number VPOS.
3868 AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
3870 static void
3871 update_marginal_area (w, area, vpos)
3872 struct window *w;
3873 int area, vpos;
3875 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3877 /* Let functions in xterm.c know what area subsequent X positions
3878 will be relative to. */
3879 updated_area = area;
3881 /* Set cursor to start of glyphs, write them, and clear to the end
3882 of the area. I don't think that something more sophisticated is
3883 necessary here, since marginal areas will not be the default. */
3884 rif->cursor_to (vpos, 0, desired_row->y, 0);
3885 if (desired_row->used[area])
3886 rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]);
3887 rif->clear_end_of_line (-1);
3891 /* Update the display of the text area of row VPOS in window W.
3892 Value is non-zero if display has changed. */
3894 static int
3895 update_text_area (w, vpos)
3896 struct window *w;
3897 int vpos;
3899 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3900 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3901 int changed_p = 0;
3903 /* Let functions in xterm.c know what area subsequent X positions
3904 will be relative to. */
3905 updated_area = TEXT_AREA;
3907 /* If rows are at different X or Y, or rows have different height,
3908 or the current row is marked invalid, write the entire line. */
3909 if (!current_row->enabled_p
3910 || desired_row->y != current_row->y
3911 || desired_row->ascent != current_row->ascent
3912 || desired_row->phys_ascent != current_row->phys_ascent
3913 || desired_row->phys_height != current_row->phys_height
3914 || desired_row->visible_height != current_row->visible_height
3915 || current_row->overlapped_p
3916 || current_row->x != desired_row->x)
3918 rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
3920 if (desired_row->used[TEXT_AREA])
3921 rif->write_glyphs (desired_row->glyphs[TEXT_AREA],
3922 desired_row->used[TEXT_AREA]);
3924 /* Clear to end of window. */
3925 rif->clear_end_of_line (-1);
3926 changed_p = 1;
3928 else
3930 int stop, i, x;
3931 struct glyph *current_glyph = current_row->glyphs[TEXT_AREA];
3932 struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
3934 /* If the desired row extends its face to the text area end,
3935 make sure we write at least one glyph, so that the face
3936 extension actually takes place. */
3937 int desired_stop_pos = (desired_row->used[TEXT_AREA]
3938 - (MATRIX_ROW_EXTENDS_FACE_P (desired_row)
3939 ? 1 : 0));
3941 stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
3942 i = 0;
3943 x = desired_row->x;
3945 while (i < stop)
3947 /* Skip over glyphs that both rows have in common. These
3948 don't have to be written. */
3949 while (i < stop
3950 && GLYPH_EQUAL_P (desired_glyph, current_glyph))
3952 x += desired_glyph->pixel_width;
3953 ++desired_glyph, ++current_glyph, ++i;
3956 /* Consider the case that the current row contains "xxx ppp
3957 ggg" in italic Courier font, and the desired row is "xxx
3958 ggg". The character `p' has lbearing, `g' has not. The
3959 loop above will stop in front of the first `p' in the
3960 current row. If we would start writing glyphs there, we
3961 wouldn't erase the lbearing of the `p'. The rest of the
3962 lbearing problem is then taken care of by x_draw_glyphs. */
3963 if (current_row->contains_overlapping_glyphs_p
3964 && i > 0
3965 && i < current_row->used[TEXT_AREA]
3966 && current_row->used[TEXT_AREA] != desired_row->used[TEXT_AREA])
3968 int left, right;
3969 rif->get_glyph_overhangs (current_glyph, XFRAME (w->frame),
3970 &left, &right);
3971 while (left > 0 && i > 0)
3973 --i, --desired_glyph, --current_glyph;
3974 x -= desired_glyph->pixel_width;
3975 left -= desired_glyph->pixel_width;
3979 /* Try to avoid writing the entire rest of the desired row
3980 by looking for a resync point. This mainly prevents
3981 mode line flickering in the case the mode line is in
3982 fixed-pitch font, which it usually will be. */
3983 if (i < desired_row->used[TEXT_AREA])
3985 int start_x = x, start_hpos = i;
3986 struct glyph *start = desired_glyph;
3987 int current_x = x;
3989 /* Find the next glyph that's equal again. */
3990 while (i < stop
3991 && !GLYPH_EQUAL_P (desired_glyph, current_glyph)
3992 && x == current_x)
3994 x += desired_glyph->pixel_width;
3995 current_x += current_glyph->pixel_width;
3996 ++desired_glyph, ++current_glyph, ++i;
3999 if (i == start_hpos || x != current_x)
4001 i = start_hpos;
4002 x = start_x;
4003 desired_glyph = start;
4004 break;
4007 rif->cursor_to (vpos, start_hpos, desired_row->y, start_x);
4008 rif->write_glyphs (start, i - start_hpos);
4009 changed_p = 1;
4013 /* Write the rest. */
4014 if (i < desired_row->used[TEXT_AREA])
4016 rif->cursor_to (vpos, i, desired_row->y, x);
4017 rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
4018 changed_p = 1;
4021 /* Maybe clear to end of line. */
4022 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
4024 /* If new row extends to the end of the text area, nothing
4025 has to be cleared, if and only if we did a write_glyphs
4026 above. This is made sure by setting desired_stop_pos
4027 appropriately above. */
4028 xassert (i < desired_row->used[TEXT_AREA]);
4030 else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
4032 /* If old row extends to the end of the text area, clear. */
4033 if (i >= desired_row->used[TEXT_AREA])
4034 rif->cursor_to (vpos, i, desired_row->y,
4035 desired_row->x + desired_row->pixel_width);
4036 rif->clear_end_of_line (-1);
4037 changed_p = 1;
4039 else if (desired_row->pixel_width < current_row->pixel_width)
4041 /* Otherwise clear to the end of the old row. Everything
4042 after that position should be clear already. */
4043 int x;
4045 if (i >= desired_row->used[TEXT_AREA])
4046 rif->cursor_to (vpos, i, desired_row->y,
4047 desired_row->x + desired_row->pixel_width);
4049 /* If cursor is displayed at the end of the line, make sure
4050 it's cleared. Nowadays we don't have a phys_cursor_glyph
4051 with which to erase the cursor (because this method
4052 doesn't work with lbearing/rbearing), so we must do it
4053 this way. */
4054 if (vpos == w->phys_cursor.vpos
4055 && w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])
4057 w->phys_cursor_on_p = 0;
4058 x = -1;
4060 else
4061 x = current_row->x + current_row->pixel_width;
4062 rif->clear_end_of_line (x);
4063 changed_p = 1;
4067 return changed_p;
4071 /* Update row VPOS in window W. Value is non-zero if display has been
4072 changed. */
4074 static int
4075 update_window_line (w, vpos)
4076 struct window *w;
4077 int vpos;
4079 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
4080 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
4081 int changed_p = 0;
4083 xassert (desired_row->enabled_p);
4085 /* Set the row being updated. This is important to let xterm.c
4086 know what line height values are in effect. */
4087 updated_row = desired_row;
4089 /* Update display of the left margin area, if there is one. */
4090 if (!desired_row->full_width_p
4091 && !NILP (w->left_margin_width))
4093 update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
4094 changed_p = 1;
4097 /* Update the display of the text area. */
4098 changed_p |= update_text_area (w, vpos);
4100 /* Update display of the right margin area, if there is one. */
4101 if (!desired_row->full_width_p
4102 && !NILP (w->right_margin_width))
4104 changed_p = 1;
4105 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
4108 /* Draw truncation marks etc. */
4109 if (!current_row->enabled_p
4110 || desired_row->y != current_row->y
4111 || desired_row->visible_height != current_row->visible_height
4112 || desired_row->overlay_arrow_p != current_row->overlay_arrow_p
4113 || desired_row->truncated_on_left_p != current_row->truncated_on_left_p
4114 || desired_row->truncated_on_right_p != current_row->truncated_on_right_p
4115 || desired_row->continued_p != current_row->continued_p
4116 || desired_row->mode_line_p != current_row->mode_line_p
4117 || (desired_row->indicate_empty_line_p
4118 != current_row->indicate_empty_line_p)
4119 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
4120 != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
4121 rif->after_update_window_line_hook (desired_row);
4123 /* Update current_row from desired_row. */
4124 make_current (w->desired_matrix, w->current_matrix, vpos);
4125 updated_row = NULL;
4126 return changed_p;
4130 /* Set the cursor after an update of window W. This function may only
4131 be called from update_window. */
4133 static void
4134 set_window_cursor_after_update (w)
4135 struct window *w;
4137 struct frame *f = XFRAME (w->frame);
4138 int cx, cy, vpos, hpos;
4140 /* Not intended for frame matrix updates. */
4141 xassert (FRAME_WINDOW_P (f));
4143 if (cursor_in_echo_area
4144 && !NILP (echo_area_buffer[0])
4145 /* If we are showing a message instead of the mini-buffer,
4146 show the cursor for the message instead. */
4147 && XWINDOW (minibuf_window) == w
4148 && EQ (minibuf_window, echo_area_window)
4149 /* These cases apply only to the frame that contains
4150 the active mini-buffer window. */
4151 && FRAME_HAS_MINIBUF_P (f)
4152 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4154 cx = cy = vpos = hpos = 0;
4156 if (cursor_in_echo_area >= 0)
4158 /* If the mini-buffer is several lines high, find the last
4159 line that has any text on it. Note: either all lines
4160 are enabled or none. Otherwise we wouldn't be able to
4161 determine Y. */
4162 struct glyph_row *row, *last_row;
4163 struct glyph *glyph;
4164 int yb = window_text_bottom_y (w);
4166 last_row = NULL;
4167 for (row = MATRIX_ROW (w->current_matrix, 0);
4168 row->enabled_p;
4169 ++row)
4171 if (row->used[TEXT_AREA]
4172 && row->glyphs[TEXT_AREA][0].charpos >= 0)
4173 last_row = row;
4175 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
4176 break;
4179 if (last_row)
4181 struct glyph *start = row->glyphs[TEXT_AREA];
4182 struct glyph *last = start + row->used[TEXT_AREA] - 1;
4184 while (last > start && last->charpos < 0)
4185 --last;
4187 for (glyph = start; glyph < last; ++glyph)
4189 cx += glyph->pixel_width;
4190 ++hpos;
4193 cy = last_row->y;
4194 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
4198 else
4200 cx = w->cursor.x;
4201 cy = w->cursor.y;
4202 hpos = w->cursor.hpos;
4203 vpos = w->cursor.vpos;
4206 /* Window cursor can be out of sync for horizontally split windows. */
4207 hpos = max (0, hpos);
4208 hpos = min (w->current_matrix->matrix_w - 1, hpos);
4209 vpos = max (0, vpos);
4210 vpos = min (w->current_matrix->nrows - 1, vpos);
4211 rif->cursor_to (vpos, hpos, cy, cx);
4215 /* Try to reuse part of the current display of W by scrolling lines.
4216 HEADER_LINE_P non-zero means W has a top mode line.
4218 The algorithm is taken from Communications of the ACM, Apr78 "A
4219 Technique for Isolating Differences Between Files." It should take
4220 O(N) time.
4222 A short outline of the steps of the algorithm
4224 1. Skip lines equal at the start and end of both matrices.
4226 2. Enter rows in the current and desired matrix into a symbol
4227 table, counting how often they appear in both matrices.
4229 3. Rows that appear exactly once in both matrices serve as anchors,
4230 i.e. we assume that such lines are likely to have been moved.
4232 4. Starting from anchor lines, extend regions to be scrolled both
4233 forward and backward.
4235 Value is
4237 -1 if all rows were found to be equal.
4238 0 to indicate that we did not scroll the display, or
4239 1 if we did scroll. */
4241 static int
4242 scrolling_window (w, header_line_p)
4243 struct window *w;
4244 int header_line_p;
4246 struct symbol
4248 /* Number of occurrences of this line in old and new matrix. */
4249 short old_uses, new_uses;
4251 /* Vpos of line in new matrix. */
4252 short new_line_number;
4254 /* The line itself. */
4255 struct glyph_row *row;
4257 /* Hash collision chain. */
4258 struct symbol *next;
4261 int SYMBOL_TABLE_SIZE = 101;
4262 struct symbol **table;
4263 struct symbol **old_line_syms, **new_line_syms;
4264 int i, j, first_old, first_new, last_old, last_new;
4265 struct symbol *sym;
4266 struct run **runs;
4267 int nruns;
4268 struct glyph_matrix *desired_matrix = w->desired_matrix;
4269 struct glyph_matrix *current_matrix = w->current_matrix;
4270 int yb = window_text_bottom_y (w);
4272 /* Skip over rows equal at the start. */
4273 i = header_line_p ? 1 : 0;
4274 while (i < current_matrix->nrows - 1
4275 && MATRIX_ROW_ENABLED_P (current_matrix, i)
4276 && MATRIX_ROW_ENABLED_P (desired_matrix, i)
4277 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i)) < yb
4278 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i)) < yb
4279 && row_equal_p (w,
4280 MATRIX_ROW (desired_matrix, i),
4281 MATRIX_ROW (current_matrix, i)))
4283 assign_row (MATRIX_ROW (current_matrix, i),
4284 MATRIX_ROW (desired_matrix, i));
4285 MATRIX_ROW (desired_matrix, i)->enabled_p = 0;
4286 ++i;
4289 /* Give up if some rows in the desired matrix are not enabled. */
4290 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
4291 return -1;
4293 first_old = first_new = i;
4295 /* Set last_new to the index + 1 of the last enabled row in the
4296 desired matrix. */
4297 i = first_new + 1;
4298 while (i < desired_matrix->nrows - 1
4299 && MATRIX_ROW (desired_matrix, i)->enabled_p
4300 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i)) < yb)
4301 ++i;
4303 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
4304 return 0;
4306 last_new = i;
4308 /* Set last_old to the index + 1 of the last enabled row in the
4309 current matrix. We don't look at the enabled flag here because
4310 we plan to reuse part of the display even if other parts are
4311 disabled. */
4312 i = first_old + 1;
4313 while (i < current_matrix->nrows - 1
4314 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i)) < yb)
4315 ++i;
4316 last_old = i;
4318 /* Skip over rows equal at the bottom. */
4319 i = last_new;
4320 j = last_old;
4321 while (i - 1 > first_new
4322 && j - 1 > first_old
4323 && MATRIX_ROW (current_matrix, i - 1)->enabled_p
4324 && (MATRIX_ROW (current_matrix, i - 1)->y
4325 == MATRIX_ROW (desired_matrix, j - 1)->y)
4326 && row_equal_p (w,
4327 MATRIX_ROW (desired_matrix, i - 1),
4328 MATRIX_ROW (current_matrix, j - 1)))
4329 --i, --j;
4330 last_new = i;
4331 last_old = j;
4333 /* Nothing to do if all rows are equal. */
4334 if (last_new == first_new)
4335 return 0;
4337 /* Allocate a hash table in which all rows will be inserted. */
4338 table = (struct symbol **) alloca (SYMBOL_TABLE_SIZE * sizeof *table);
4339 bzero (table, SYMBOL_TABLE_SIZE * sizeof *table);
4341 /* For each row in the current matrix, record the symbol belonging
4342 to the row in OLD_LINE_SYMS. */
4343 old_line_syms = (struct symbol **) alloca (current_matrix->nrows
4344 * sizeof *old_line_syms);
4345 new_line_syms = (struct symbol **) alloca (desired_matrix->nrows
4346 * sizeof *new_line_syms);
4348 #define ADDSYM(ROW) \
4349 do \
4351 struct glyph_row *row_ = (ROW); \
4352 int i_ = row_->hash % SYMBOL_TABLE_SIZE; \
4353 sym = table[i_]; \
4354 while (sym && !row_equal_p (w, sym->row, row_)) \
4355 sym = sym->next; \
4356 if (sym == NULL) \
4358 sym = (struct symbol *) alloca (sizeof *sym); \
4359 sym->row = row_; \
4360 sym->old_uses = sym->new_uses = 0; \
4361 sym->next = table[i_]; \
4362 table[i_] = sym; \
4365 while (0)
4367 /* Add current rows to the symbol table. */
4368 for (i = first_old; i < last_old; ++i)
4370 if (MATRIX_ROW (current_matrix, i)->enabled_p)
4372 ADDSYM (MATRIX_ROW (current_matrix, i));
4373 old_line_syms[i] = sym;
4374 ++sym->old_uses;
4376 else
4377 old_line_syms[i] = NULL;
4380 /* Add desired rows to the symbol table. */
4381 for (i = first_new; i < last_new; ++i)
4383 xassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
4384 ADDSYM (MATRIX_ROW (desired_matrix, i));
4385 ++sym->new_uses;
4386 new_line_syms[i] = sym;
4387 sym->new_line_number = i;
4390 #undef ADDSYM
4392 /* Record in runs which moves were found, ordered by pixel
4393 height of copied areas. */
4394 nruns = 0;
4395 runs = (struct run **) alloca (desired_matrix->nrows * sizeof *runs);
4397 /* Identify moves based on lines that are unique and equal
4398 in both matrices. */
4399 for (i = first_old; i < last_old;)
4400 if (old_line_syms[i]
4401 && old_line_syms[i]->old_uses == 1
4402 && old_line_syms[i]->new_uses == 1)
4404 int j, k;
4405 int new_line = old_line_syms[i]->new_line_number;
4406 struct run *run = (struct run *) alloca (sizeof *run);
4408 /* Record move. */
4409 run->current_vpos = i;
4410 run->current_y = MATRIX_ROW (current_matrix, i)->y;
4411 run->desired_vpos = new_line;
4412 run->desired_y = MATRIX_ROW (desired_matrix, new_line)->y;
4413 run->nrows = 1;
4414 run->height = MATRIX_ROW (current_matrix, i)->height;
4416 /* Extend backward. */
4417 j = i - 1;
4418 k = new_line - 1;
4419 while (j > first_old
4420 && k > first_new
4421 && old_line_syms[j] == new_line_syms[k])
4423 int h = MATRIX_ROW (current_matrix, j)->height;
4424 --run->current_vpos;
4425 --run->desired_vpos;
4426 ++run->nrows;
4427 run->height += h;
4428 run->desired_y -= h;
4429 run->current_y -= h;
4430 --j, --k;
4433 /* Extend forward. */
4434 j = i + 1;
4435 k = new_line + 1;
4436 while (j < last_old
4437 && k < last_new
4438 && old_line_syms[j] == new_line_syms[k])
4440 int h = MATRIX_ROW (current_matrix, j)->height;
4441 ++run->nrows;
4442 run->height += h;
4443 ++j, ++k;
4446 /* Insert run into list of all runs. Order runs by copied
4447 pixel lines. Note that we record runs that don't have to
4448 be copied because they are already in place. This is done
4449 because we can avoid calling update_window_line in this
4450 case. */
4451 for (j = 0; j < nruns && runs[j]->height > run->height; ++j)
4453 for (k = nruns; k >= j; --k)
4454 runs[k] = runs[k - 1];
4455 runs[j] = run;
4456 ++nruns;
4458 i += run->nrows;
4460 else
4461 ++i;
4463 /* Do the moves. Do it in a way that we don't overwrite something
4464 we want to copy later on. This is not solvable in general
4465 because there is only one display and we don't have a way to
4466 exchange areas on this display. Example:
4468 +-----------+ +-----------+
4469 | A | | B |
4470 +-----------+ --> +-----------+
4471 | B | | A |
4472 +-----------+ +-----------+
4474 Instead, prefer bigger moves, and invalidate moves that would
4475 copy from where we copied to. */
4477 for (i = 0; i < nruns; ++i)
4478 if (runs[i]->nrows > 0)
4480 struct run *r = runs[i];
4482 /* Copy on the display. */
4483 if (r->current_y != r->desired_y)
4485 rif->scroll_run_hook (w, r);
4487 /* Invalidate runs that copy from where we copied to. */
4488 for (j = i + 1; j < nruns; ++j)
4490 struct run *p = runs[j];
4492 if ((p->current_y >= r->desired_y
4493 && p->current_y < r->desired_y + r->height)
4494 || (p->current_y + p->height >= r->desired_y
4495 && (p->current_y + p->height
4496 < r->desired_y + r->height)))
4497 p->nrows = 0;
4501 /* Assign matrix rows. */
4502 for (j = 0; j < r->nrows; ++j)
4504 struct glyph_row *from, *to;
4505 int to_overlapped_p;
4507 to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
4508 to_overlapped_p = to->overlapped_p;
4509 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
4510 assign_row (to, from);
4511 to->enabled_p = 1, from->enabled_p = 0;
4512 to->overlapped_p = to_overlapped_p;
4516 /* Value is non-zero to indicate that we scrolled the display. */
4517 return 1;
4521 /* Set WINDOW->must_be_updated_p TO ON_P for all windows WINDOW in the
4522 window tree rooted at W. */
4524 void
4525 set_window_update_flags (w, on_p)
4526 struct window *w;
4527 int on_p;
4529 while (w)
4531 if (!NILP (w->hchild))
4532 set_window_update_flags (XWINDOW (w->hchild), on_p);
4533 else if (!NILP (w->vchild))
4534 set_window_update_flags (XWINDOW (w->vchild), on_p);
4535 else
4536 w->must_be_updated_p = on_p;
4538 w = NILP (w->next) ? 0 : XWINDOW (w->next);
4544 /************************************************************************
4545 Frame-Based Updates
4546 ************************************************************************/
4548 /* Update the desired frame matrix of frame F.
4550 FORCE_P non-zero means that the update should not be stopped by
4551 pending input. INHIBIT_HAIRY_ID_P non-zero means that scrolling
4552 should not be tried.
4554 Value is non-zero if update was stopped due to pending input. */
4556 static int
4557 update_frame_1 (f, force_p, inhibit_id_p)
4558 struct frame *f;
4559 int force_p;
4560 int inhibit_id_p;
4562 /* Frame matrices to work on. */
4563 struct glyph_matrix *current_matrix = f->current_matrix;
4564 struct glyph_matrix *desired_matrix = f->desired_matrix;
4565 int i;
4566 int pause;
4567 int preempt_count = baud_rate / 2400 + 1;
4568 extern int input_pending;
4570 xassert (current_matrix && desired_matrix);
4572 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4573 calculate_costs (f);
4575 if (preempt_count <= 0)
4576 preempt_count = 1;
4578 detect_input_pending ();
4579 if (input_pending && !force_p)
4581 pause = 1;
4582 goto do_pause;
4585 update_begin (f);
4587 /* If we cannot insert/delete lines, it's no use trying it. */
4588 if (!line_ins_del_ok)
4589 inhibit_id_p = 1;
4591 /* See if any of the desired lines are enabled; don't compute for
4592 i/d line if just want cursor motion. */
4593 for (i = 0; i < desired_matrix->nrows; i++)
4594 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4595 break;
4597 /* Try doing i/d line, if not yet inhibited. */
4598 if (!inhibit_id_p && i < desired_matrix->nrows)
4599 force_p |= scrolling (f);
4601 /* Update the individual lines as needed. Do bottom line first. */
4602 if (MATRIX_ROW_ENABLED_P (desired_matrix, desired_matrix->nrows - 1))
4603 update_frame_line (f, desired_matrix->nrows - 1);
4605 /* Now update the rest of the lines. */
4606 for (i = 0; i < desired_matrix->nrows - 1 && (force_p || !input_pending); i++)
4608 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4610 if (FRAME_TERMCAP_P (f))
4612 /* Flush out every so many lines.
4613 Also flush out if likely to have more than 1k buffered
4614 otherwise. I'm told that some telnet connections get
4615 really screwed by more than 1k output at once. */
4616 int outq = PENDING_OUTPUT_COUNT (stdout);
4617 if (outq > 900
4618 || (outq > 20 && ((i - 1) % preempt_count == 0)))
4620 fflush (stdout);
4621 if (preempt_count == 1)
4623 #ifdef EMACS_OUTQSIZE
4624 if (EMACS_OUTQSIZE (0, &outq) < 0)
4625 /* Probably not a tty. Ignore the error and reset
4626 * the outq count. */
4627 outq = PENDING_OUTPUT_COUNT (stdout);
4628 #endif
4629 outq *= 10;
4630 if (baud_rate <= outq && baud_rate > 0)
4631 sleep (outq / baud_rate);
4636 if ((i - 1) % preempt_count == 0)
4637 detect_input_pending ();
4639 update_frame_line (f, i);
4643 pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0;
4645 /* Now just clean up termcap drivers and set cursor, etc. */
4646 if (!pause)
4648 if ((cursor_in_echo_area
4649 /* If we are showing a message instead of the mini-buffer,
4650 show the cursor for the message instead of for the
4651 (now hidden) mini-buffer contents. */
4652 || (EQ (minibuf_window, selected_window)
4653 && EQ (minibuf_window, echo_area_window)
4654 && !NILP (echo_area_buffer[0])))
4655 /* These cases apply only to the frame that contains
4656 the active mini-buffer window. */
4657 && FRAME_HAS_MINIBUF_P (f)
4658 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4660 int top = XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top);
4661 int row, col;
4663 if (cursor_in_echo_area < 0)
4665 /* Negative value of cursor_in_echo_area means put
4666 cursor at beginning of line. */
4667 row = top;
4668 col = 0;
4670 else
4672 /* Positive value of cursor_in_echo_area means put
4673 cursor at the end of the prompt. If the mini-buffer
4674 is several lines high, find the last line that has
4675 any text on it. */
4676 row = FRAME_HEIGHT (f);
4679 --row;
4680 col = 0;
4682 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
4684 /* Frame rows are filled up with spaces that
4685 must be ignored here. */
4686 struct glyph_row *r = MATRIX_ROW (current_matrix,
4687 row);
4688 struct glyph *start = r->glyphs[TEXT_AREA];
4689 struct glyph *last = start + r->used[TEXT_AREA];
4691 while (last > start
4692 && (last - 1)->charpos < 0)
4693 --last;
4695 col = last - start;
4698 while (row > top && col == 0);
4700 /* Make sure COL is not out of range. */
4701 if (col >= FRAME_CURSOR_X_LIMIT (f))
4703 /* If we have another row, advance cursor into it. */
4704 if (row < FRAME_HEIGHT (f) - 1)
4706 col = FRAME_LEFT_SCROLL_BAR_WIDTH (f);
4707 row++;
4709 /* Otherwise move it back in range. */
4710 else
4711 col = FRAME_CURSOR_X_LIMIT (f) - 1;
4715 cursor_to (row, col);
4717 else
4719 /* We have only one cursor on terminal frames. Use it to
4720 display the cursor of the selected window. */
4721 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
4722 if (w->cursor.vpos >= 0)
4724 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
4725 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
4727 if (INTEGERP (w->left_margin_width))
4728 x += XFASTINT (w->left_margin_width);
4730 /* x = max (min (x, FRAME_WINDOW_WIDTH (f) - 1), 0); */
4731 cursor_to (y, x);
4736 update_end (f);
4738 if (termscript)
4739 fflush (termscript);
4740 fflush (stdout);
4742 do_pause:
4744 display_completed = !pause;
4745 clear_desired_matrices (f);
4746 return pause;
4750 /* Do line insertions/deletions on frame F for frame-based redisplay. */
4753 scrolling (frame)
4754 struct frame *frame;
4756 int unchanged_at_top, unchanged_at_bottom;
4757 int window_size;
4758 int changed_lines;
4759 int *old_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4760 int *new_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4761 int *draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4762 int *old_draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4763 register int i;
4764 int free_at_end_vpos = FRAME_HEIGHT (frame);
4765 struct glyph_matrix *current_matrix = frame->current_matrix;
4766 struct glyph_matrix *desired_matrix = frame->desired_matrix;
4768 if (!current_matrix)
4769 abort ();
4771 /* Compute hash codes of all the lines. Also calculate number of
4772 changed lines, number of unchanged lines at the beginning, and
4773 number of unchanged lines at the end. */
4774 changed_lines = 0;
4775 unchanged_at_top = 0;
4776 unchanged_at_bottom = FRAME_HEIGHT (frame);
4777 for (i = 0; i < FRAME_HEIGHT (frame); i++)
4779 /* Give up on this scrolling if some old lines are not enabled. */
4780 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
4781 return 0;
4782 old_hash[i] = line_hash_code (MATRIX_ROW (current_matrix, i));
4783 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
4785 /* This line cannot be redrawn, so don't let scrolling mess it. */
4786 new_hash[i] = old_hash[i];
4787 #define INFINITY 1000000 /* Taken from scroll.c */
4788 draw_cost[i] = INFINITY;
4790 else
4792 new_hash[i] = line_hash_code (MATRIX_ROW (desired_matrix, i));
4793 draw_cost[i] = line_draw_cost (desired_matrix, i);
4796 if (old_hash[i] != new_hash[i])
4798 changed_lines++;
4799 unchanged_at_bottom = FRAME_HEIGHT (frame) - i - 1;
4801 else if (i == unchanged_at_top)
4802 unchanged_at_top++;
4803 old_draw_cost[i] = line_draw_cost (current_matrix, i);
4806 /* If changed lines are few, don't allow preemption, don't scroll. */
4807 if ((!scroll_region_ok && changed_lines < baud_rate / 2400)
4808 || unchanged_at_bottom == FRAME_HEIGHT (frame))
4809 return 1;
4811 window_size = (FRAME_HEIGHT (frame) - unchanged_at_top
4812 - unchanged_at_bottom);
4814 if (scroll_region_ok)
4815 free_at_end_vpos -= unchanged_at_bottom;
4816 else if (memory_below_frame)
4817 free_at_end_vpos = -1;
4819 /* If large window, fast terminal and few lines in common between
4820 current frame and desired frame, don't bother with i/d calc. */
4821 if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400
4822 && (window_size >=
4823 10 * scrolling_max_lines_saved (unchanged_at_top,
4824 FRAME_HEIGHT (frame) - unchanged_at_bottom,
4825 old_hash, new_hash, draw_cost)))
4826 return 0;
4828 if (window_size < 2)
4829 return 0;
4831 scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
4832 draw_cost + unchanged_at_top - 1,
4833 old_draw_cost + unchanged_at_top - 1,
4834 old_hash + unchanged_at_top - 1,
4835 new_hash + unchanged_at_top - 1,
4836 free_at_end_vpos - unchanged_at_top);
4838 return 0;
4842 /* Count the number of blanks at the start of the vector of glyphs R
4843 which is LEN glyphs long. */
4845 static int
4846 count_blanks (r, len)
4847 struct glyph *r;
4848 int len;
4850 int i;
4852 for (i = 0; i < len; ++i)
4853 if (!CHAR_GLYPH_SPACE_P (r[i]))
4854 break;
4856 return i;
4860 /* Count the number of glyphs in common at the start of the glyph
4861 vectors STR1 and STR2. END1 is the end of STR1 and END2 is the end
4862 of STR2. Value is the number of equal glyphs equal at the start. */
4864 static int
4865 count_match (str1, end1, str2, end2)
4866 struct glyph *str1, *end1, *str2, *end2;
4868 struct glyph *p1 = str1;
4869 struct glyph *p2 = str2;
4871 while (p1 < end1
4872 && p2 < end2
4873 && GLYPH_CHAR_AND_FACE_EQUAL_P (p1, p2))
4874 ++p1, ++p2;
4876 return p1 - str1;
4880 /* Char insertion/deletion cost vector, from term.c */
4882 extern int *char_ins_del_vector;
4883 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))])
4886 /* Perform a frame-based update on line VPOS in frame FRAME. */
4888 static void
4889 update_frame_line (frame, vpos)
4890 register struct frame *frame;
4891 int vpos;
4893 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
4894 int tem;
4895 int osp, nsp, begmatch, endmatch, olen, nlen;
4896 struct glyph_matrix *current_matrix = frame->current_matrix;
4897 struct glyph_matrix *desired_matrix = frame->desired_matrix;
4898 struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
4899 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
4900 int must_write_whole_line_p;
4902 if (desired_row->inverse_p
4903 != (current_row->enabled_p && current_row->inverse_p))
4905 int n = current_row->enabled_p ? current_row->used[TEXT_AREA] : 0;
4906 change_line_highlight (desired_row->inverse_p, vpos, vpos, n);
4907 current_row->enabled_p = 0;
4909 else
4910 reassert_line_highlight (desired_row->inverse_p, vpos);
4912 /* Current row not enabled means it has unknown contents. We must
4913 write the whole desired line in that case. */
4914 must_write_whole_line_p = !current_row->enabled_p;
4915 if (must_write_whole_line_p)
4917 obody = 0;
4918 olen = 0;
4920 else
4922 obody = MATRIX_ROW_GLYPH_START (current_matrix, vpos);
4923 olen = current_row->used[TEXT_AREA];
4925 if (! current_row->inverse_p)
4927 /* Ignore trailing spaces, if we can. */
4928 if (!must_write_spaces)
4929 while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
4930 olen--;
4932 else
4934 /* For an inverse-video line, make sure it's filled with
4935 spaces all the way to the frame edge so that the reverse
4936 video extends all the way across. */
4937 while (olen < FRAME_WIDTH (frame) - 1)
4938 obody[olen++] = space_glyph;
4942 current_row->enabled_p = 1;
4943 current_row->used[TEXT_AREA] = desired_row->used[TEXT_AREA];
4944 current_row->inverse_p = desired_row->inverse_p;
4946 /* If desired line is empty, just clear the line. */
4947 if (!desired_row->enabled_p)
4949 nlen = 0;
4950 goto just_erase;
4953 nbody = desired_row->glyphs[TEXT_AREA];
4954 nlen = desired_row->used[TEXT_AREA];
4955 nend = nbody + nlen;
4957 /* If display line has unknown contents, write the whole line. */
4958 if (must_write_whole_line_p)
4960 /* Ignore spaces at the end, if we can. */
4961 if (!must_write_spaces)
4962 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
4963 --nlen;
4965 /* Write the contents of the desired line. */
4966 if (nlen)
4968 cursor_to (vpos, 0);
4969 write_glyphs (nbody, nlen);
4972 /* Don't call clear_end_of_line if we already wrote the whole
4973 line. The cursor will not be at the right margin in that
4974 case but in the line below. */
4975 if (nlen < FRAME_WINDOW_WIDTH (frame))
4977 cursor_to (vpos, nlen);
4978 clear_end_of_line (FRAME_WINDOW_WIDTH (frame));
4981 make_current (desired_matrix, current_matrix, vpos);
4982 return;
4985 /* Pretend trailing spaces are not there at all,
4986 unless for one reason or another we must write all spaces. */
4987 if (!desired_row->inverse_p)
4989 if (!must_write_spaces)
4990 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
4991 nlen--;
4993 else
4995 /* For an inverse-video line, give it extra trailing spaces all
4996 the way to the frame edge so that the reverse video extends
4997 all the way across. */
4998 while (nlen < FRAME_WIDTH (frame) - 1)
4999 nbody[nlen++] = space_glyph;
5002 /* If there's no i/d char, quickly do the best we can without it. */
5003 if (!char_ins_del_ok)
5005 int i, j;
5007 /* Find the first glyph in desired row that doesn't agree with
5008 a glyph in the current row, and write the rest from there on. */
5009 for (i = 0; i < nlen; i++)
5011 if (i >= olen || !GLYPH_EQUAL_P (nbody + i, obody + i))
5013 /* Find the end of the run of different glyphs. */
5014 j = i + 1;
5015 while (j < nlen
5016 && (j >= olen
5017 || !GLYPH_EQUAL_P (nbody + j, obody + j)
5018 || CHAR_GLYPH_PADDING_P (nbody[j])))
5019 ++j;
5021 /* Output this run of non-matching chars. */
5022 cursor_to (vpos, i);
5023 write_glyphs (nbody + i, j - i);
5024 i = j - 1;
5026 /* Now find the next non-match. */
5030 /* Clear the rest of the line, or the non-clear part of it. */
5031 if (olen > nlen)
5033 cursor_to (vpos, nlen);
5034 clear_end_of_line (olen);
5037 /* Make current row = desired row. */
5038 make_current (desired_matrix, current_matrix, vpos);
5039 return;
5042 /* Here when CHAR_INS_DEL_OK != 0, i.e. we can insert or delete
5043 characters in a row. */
5045 if (!olen)
5047 /* If current line is blank, skip over initial spaces, if
5048 possible, and write the rest. */
5049 if (must_write_spaces || desired_row->inverse_p)
5050 nsp = 0;
5051 else
5052 nsp = count_blanks (nbody, nlen);
5054 if (nlen > nsp)
5056 cursor_to (vpos, nsp);
5057 write_glyphs (nbody + nsp, nlen - nsp);
5060 /* Exchange contents between current_frame and new_frame. */
5061 make_current (desired_matrix, current_matrix, vpos);
5062 return;
5065 /* Compute number of leading blanks in old and new contents. */
5066 osp = count_blanks (obody, olen);
5067 nsp = desired_row->inverse_p ? 0 : count_blanks (nbody, nlen);
5069 /* Compute number of matching chars starting with first non-blank. */
5070 begmatch = count_match (obody + osp, obody + olen,
5071 nbody + nsp, nbody + nlen);
5073 /* Spaces in new match implicit space past the end of old. */
5074 /* A bug causing this to be a no-op was fixed in 18.29. */
5075 if (!must_write_spaces && osp + begmatch == olen)
5077 np1 = nbody + nsp;
5078 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (np1[begmatch]))
5079 ++begmatch;
5082 /* Avoid doing insert/delete char
5083 just cause number of leading spaces differs
5084 when the following text does not match. */
5085 if (begmatch == 0 && osp != nsp)
5086 osp = nsp = min (osp, nsp);
5088 /* Find matching characters at end of line */
5089 op1 = obody + olen;
5090 np1 = nbody + nlen;
5091 op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
5092 while (op1 > op2
5093 && GLYPH_EQUAL_P (op1 - 1, np1 - 1))
5095 op1--;
5096 np1--;
5098 endmatch = obody + olen - op1;
5100 /* tem gets the distance to insert or delete.
5101 endmatch is how many characters we save by doing so.
5102 Is it worth it? */
5104 tem = (nlen - nsp) - (olen - osp);
5105 if (endmatch && tem
5106 && (!char_ins_del_ok || endmatch <= char_ins_del_cost (frame)[tem]))
5107 endmatch = 0;
5109 /* nsp - osp is the distance to insert or delete.
5110 If that is nonzero, begmatch is known to be nonzero also.
5111 begmatch + endmatch is how much we save by doing the ins/del.
5112 Is it worth it? */
5114 if (nsp != osp
5115 && (!char_ins_del_ok
5116 || begmatch + endmatch <= char_ins_del_cost (frame)[nsp - osp]))
5118 begmatch = 0;
5119 endmatch = 0;
5120 osp = nsp = min (osp, nsp);
5123 /* Now go through the line, inserting, writing and
5124 deleting as appropriate. */
5126 if (osp > nsp)
5128 cursor_to (vpos, nsp);
5129 delete_glyphs (osp - nsp);
5131 else if (nsp > osp)
5133 /* If going to delete chars later in line
5134 and insert earlier in the line,
5135 must delete first to avoid losing data in the insert */
5136 if (endmatch && nlen < olen + nsp - osp)
5138 cursor_to (vpos, nlen - endmatch + osp - nsp);
5139 delete_glyphs (olen + nsp - osp - nlen);
5140 olen = nlen - (nsp - osp);
5142 cursor_to (vpos, osp);
5143 insert_glyphs (0, nsp - osp);
5145 olen += nsp - osp;
5147 tem = nsp + begmatch + endmatch;
5148 if (nlen != tem || olen != tem)
5150 cursor_to (vpos, nsp + begmatch);
5151 if (!endmatch || nlen == olen)
5153 /* If new text being written reaches right margin,
5154 there is no need to do clear-to-eol at the end.
5155 (and it would not be safe, since cursor is not
5156 going to be "at the margin" after the text is done) */
5157 if (nlen == FRAME_WINDOW_WIDTH (frame))
5158 olen = 0;
5159 write_glyphs (nbody + nsp + begmatch, nlen - tem);
5161 else if (nlen > olen)
5163 /* Here, we used to have the following simple code:
5164 ----------------------------------------
5165 write_glyphs (nbody + nsp + begmatch, olen - tem);
5166 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
5167 ----------------------------------------
5168 but it doesn't work if nbody[nsp + begmatch + olen - tem]
5169 is a padding glyph. */
5170 int out = olen - tem; /* Columns to be overwritten originally. */
5171 int del;
5173 /* Calculate columns we can actually overwrite. */
5174 while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out])) out--;
5175 write_glyphs (nbody + nsp + begmatch, out);
5176 /* If we left columns to be overwritten, we must delete them. */
5177 del = olen - tem - out;
5178 if (del > 0) delete_glyphs (del);
5179 /* At last, we insert columns not yet written out. */
5180 insert_glyphs (nbody + nsp + begmatch + out, nlen - olen + del);
5181 olen = nlen;
5183 else if (olen > nlen)
5185 write_glyphs (nbody + nsp + begmatch, nlen - tem);
5186 delete_glyphs (olen - nlen);
5187 olen = nlen;
5191 just_erase:
5192 /* If any unerased characters remain after the new line, erase them. */
5193 if (olen > nlen)
5195 cursor_to (vpos, nlen);
5196 clear_end_of_line (olen);
5199 /* Exchange contents between current_frame and new_frame. */
5200 make_current (desired_matrix, current_matrix, vpos);
5205 /***********************************************************************
5206 X/Y Position -> Buffer Position
5207 ***********************************************************************/
5209 /* Return the character position of the character at window relative
5210 pixel position (*X, *Y). *X and *Y are adjusted to character
5211 boundaries. */
5214 buffer_posn_from_coords (w, x, y)
5215 struct window *w;
5216 int *x, *y;
5218 struct it it;
5219 struct buffer *old_current_buffer = current_buffer;
5220 struct text_pos startp;
5221 int left_area_width;
5223 current_buffer = XBUFFER (w->buffer);
5224 SET_TEXT_POS_FROM_MARKER (startp, w->start);
5225 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
5226 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
5227 start_display (&it, w, startp);
5229 left_area_width = WINDOW_DISPLAY_LEFT_AREA_PIXEL_WIDTH (w);
5230 move_it_to (&it, -1, *x + it.first_visible_x - left_area_width, *y, -1,
5231 MOVE_TO_X | MOVE_TO_Y);
5233 *x = it.current_x - it.first_visible_x + left_area_width;
5234 *y = it.current_y;
5235 current_buffer = old_current_buffer;
5236 return IT_CHARPOS (it);
5240 /* Value is the string under window-relative coordinates X/Y in the
5241 mode or top line of window W, or nil if none. MODE_LINE_P non-zero
5242 means look at the mode line. *CHARPOS is set to the position in
5243 the string returned. */
5245 Lisp_Object
5246 mode_line_string (w, x, y, mode_line_p, charpos)
5247 struct window *w;
5248 int x, y;
5249 int *charpos;
5251 struct glyph_row *row;
5252 struct glyph *glyph, *end;
5253 struct frame *f = XFRAME (w->frame);
5254 int x0;
5255 Lisp_Object string = Qnil;
5257 if (mode_line_p)
5258 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
5259 else
5260 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
5262 if (row->mode_line_p && row->enabled_p)
5264 /* The mode lines are displayed over scroll bars and bitmap
5265 areas, and X is window-relative. Correct X by the scroll bar
5266 and bitmap area width. */
5267 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
5268 x += FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
5269 x += FRAME_LEFT_FLAGS_AREA_WIDTH (f);
5271 /* Find the glyph under X. If we find one with a string object,
5272 it's the one we were looking for. */
5273 glyph = row->glyphs[TEXT_AREA];
5274 end = glyph + row->used[TEXT_AREA];
5275 for (x0 = 0; glyph < end; x0 += glyph->pixel_width, ++glyph)
5276 if (x >= x0 && x < x0 + glyph->pixel_width)
5278 string = glyph->object;
5279 *charpos = glyph->charpos;
5280 break;
5284 return string;
5288 /***********************************************************************
5289 Changing Frame Sizes
5290 ***********************************************************************/
5292 #ifdef SIGWINCH
5294 SIGTYPE
5295 window_change_signal (signalnum) /* If we don't have an argument, */
5296 int signalnum; /* some compilers complain in signal calls. */
5298 int width, height;
5299 extern int errno;
5300 int old_errno = errno;
5302 get_frame_size (&width, &height);
5304 /* The frame size change obviously applies to a termcap-controlled
5305 frame. Find such a frame in the list, and assume it's the only
5306 one (since the redisplay code always writes to stdout, not a
5307 FILE * specified in the frame structure). Record the new size,
5308 but don't reallocate the data structures now. Let that be done
5309 later outside of the signal handler. */
5312 Lisp_Object tail, frame;
5314 FOR_EACH_FRAME (tail, frame)
5316 if (FRAME_TERMCAP_P (XFRAME (frame)))
5318 change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
5319 break;
5324 signal (SIGWINCH, window_change_signal);
5325 errno = old_errno;
5327 #endif /* SIGWINCH */
5330 /* Do any change in frame size that was requested by a signal. SAFE
5331 non-zero means this function is called from a place where it is
5332 safe to change frame sizes while a redisplay is in progress. */
5334 void
5335 do_pending_window_change (safe)
5336 int safe;
5338 /* If window_change_signal should have run before, run it now. */
5339 if (redisplaying_p && !safe)
5340 return;
5342 while (delayed_size_change)
5344 Lisp_Object tail, frame;
5346 delayed_size_change = 0;
5348 FOR_EACH_FRAME (tail, frame)
5350 struct frame *f = XFRAME (frame);
5352 int height = FRAME_NEW_HEIGHT (f);
5353 int width = FRAME_NEW_WIDTH (f);
5355 if (height != 0 || width != 0)
5356 change_frame_size (f, height, width, 0, 0, safe);
5362 /* Change the frame height and/or width. Values may be given as zero to
5363 indicate no change is to take place.
5365 If DELAY is non-zero, then assume we're being called from a signal
5366 handler, and queue the change for later - perhaps the next
5367 redisplay. Since this tries to resize windows, we can't call it
5368 from a signal handler.
5370 SAFE non-zero means this function is called from a place where it's
5371 safe to change frame sizes while a redisplay is in progress. */
5373 void
5374 change_frame_size (f, newheight, newwidth, pretend, delay, safe)
5375 register struct frame *f;
5376 int newheight, newwidth, pretend, delay, safe;
5378 Lisp_Object tail, frame;
5380 if (! FRAME_WINDOW_P (f))
5382 /* When using termcap, or on MS-DOS, all frames use
5383 the same screen, so a change in size affects all frames. */
5384 FOR_EACH_FRAME (tail, frame)
5385 if (! FRAME_WINDOW_P (XFRAME (frame)))
5386 change_frame_size_1 (XFRAME (frame), newheight, newwidth,
5387 pretend, delay, safe);
5389 else
5390 change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe);
5393 static void
5394 change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
5395 register struct frame *f;
5396 int newheight, newwidth, pretend, delay, safe;
5398 int new_frame_window_width;
5399 int count = specpdl_ptr - specpdl;
5401 /* If we can't deal with the change now, queue it for later. */
5402 if (delay || (redisplaying_p && !safe))
5404 FRAME_NEW_HEIGHT (f) = newheight;
5405 FRAME_NEW_WIDTH (f) = newwidth;
5406 delayed_size_change = 1;
5407 return;
5410 /* This size-change overrides any pending one for this frame. */
5411 FRAME_NEW_HEIGHT (f) = 0;
5412 FRAME_NEW_WIDTH (f) = 0;
5414 /* If an argument is zero, set it to the current value. */
5415 if (newheight == 0)
5416 newheight = FRAME_HEIGHT (f);
5417 if (newwidth == 0)
5418 newwidth = FRAME_WIDTH (f);
5420 /* Compute width of windows in F.
5421 This is the width of the frame without vertical scroll bars. */
5422 new_frame_window_width = FRAME_WINDOW_WIDTH_ARG (f, newwidth);
5424 /* Round up to the smallest acceptable size. */
5425 check_frame_size (f, &newheight, &newwidth);
5427 /* If we're not changing the frame size, quit now. */
5428 if (newheight == FRAME_HEIGHT (f)
5429 && new_frame_window_width == FRAME_WINDOW_WIDTH (f))
5430 return;
5432 BLOCK_INPUT;
5434 #ifdef MSDOS
5435 /* We only can set screen dimensions to certain values supported
5436 by our video hardware. Try to find the smallest size greater
5437 or equal to the requested dimensions. */
5438 dos_set_window_size (&newheight, &newwidth);
5439 #endif
5441 if (newheight != FRAME_HEIGHT (f))
5443 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
5445 /* Frame has both root and mini-buffer. */
5446 XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top,
5447 FRAME_TOP_MARGIN (f));
5448 set_window_height (FRAME_ROOT_WINDOW (f),
5449 (newheight
5451 - FRAME_TOP_MARGIN (f)),
5453 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top,
5454 newheight - 1);
5455 set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
5457 else
5458 /* Frame has just one top-level window. */
5459 set_window_height (FRAME_ROOT_WINDOW (f),
5460 newheight - FRAME_TOP_MARGIN (f), 0);
5462 if (FRAME_TERMCAP_P (f) && !pretend)
5463 FrameRows = newheight;
5466 if (new_frame_window_width != FRAME_WINDOW_WIDTH (f))
5468 set_window_width (FRAME_ROOT_WINDOW (f), new_frame_window_width, 0);
5469 if (FRAME_HAS_MINIBUF_P (f))
5470 set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_window_width, 0);
5472 if (FRAME_TERMCAP_P (f) && !pretend)
5473 FrameCols = newwidth;
5475 if (WINDOWP (f->tool_bar_window))
5476 XSETFASTINT (XWINDOW (f->tool_bar_window)->width, newwidth);
5479 FRAME_HEIGHT (f) = newheight;
5480 SET_FRAME_WIDTH (f, newwidth);
5483 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5484 int text_area_x, text_area_y, text_area_width, text_area_height;
5486 window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width,
5487 &text_area_height);
5488 if (w->cursor.x >= text_area_x + text_area_width)
5489 w->cursor.hpos = w->cursor.x = 0;
5490 if (w->cursor.y >= text_area_y + text_area_height)
5491 w->cursor.vpos = w->cursor.y = 0;
5494 adjust_glyphs (f);
5495 SET_FRAME_GARBAGED (f);
5496 calculate_costs (f);
5498 UNBLOCK_INPUT;
5500 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
5502 /* This isn't quite a no-op: it runs window-configuration-change-hook. */
5503 Fset_window_buffer (FRAME_SELECTED_WINDOW (f),
5504 XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer);
5506 unbind_to (count, Qnil);
5511 /***********************************************************************
5512 Terminal Related Lisp Functions
5513 ***********************************************************************/
5515 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
5516 1, 1, "FOpen termscript file: ",
5517 "Start writing all terminal output to FILE as well as the terminal.\n\
5518 FILE = nil means just close any termscript file currently open.")
5519 (file)
5520 Lisp_Object file;
5522 if (termscript != 0) fclose (termscript);
5523 termscript = 0;
5525 if (! NILP (file))
5527 file = Fexpand_file_name (file, Qnil);
5528 termscript = fopen (XSTRING (file)->data, "w");
5529 if (termscript == 0)
5530 report_file_error ("Opening termscript", Fcons (file, Qnil));
5532 return Qnil;
5536 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
5537 Ssend_string_to_terminal, 1, 1, 0,
5538 "Send STRING to the terminal without alteration.\n\
5539 Control characters in STRING will have terminal-dependent effects.")
5540 (string)
5541 Lisp_Object string;
5543 /* ??? Perhaps we should do something special for multibyte strings here. */
5544 CHECK_STRING (string, 0);
5545 fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)), stdout);
5546 fflush (stdout);
5547 if (termscript)
5549 fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)),
5550 termscript);
5551 fflush (termscript);
5553 return Qnil;
5557 DEFUN ("ding", Fding, Sding, 0, 1, 0,
5558 "Beep, or flash the screen.\n\
5559 Also, unless an argument is given,\n\
5560 terminate any keyboard macro currently executing.")
5561 (arg)
5562 Lisp_Object arg;
5564 if (!NILP (arg))
5566 if (noninteractive)
5567 putchar (07);
5568 else
5569 ring_bell ();
5570 fflush (stdout);
5572 else
5573 bitch_at_user ();
5575 return Qnil;
5578 void
5579 bitch_at_user ()
5581 if (noninteractive)
5582 putchar (07);
5583 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
5584 error ("Keyboard macro terminated by a command ringing the bell");
5585 else
5586 ring_bell ();
5587 fflush (stdout);
5592 /***********************************************************************
5593 Sleeping, Waiting
5594 ***********************************************************************/
5596 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
5597 "Pause, without updating display, for SECONDS seconds.\n\
5598 SECONDS may be a floating-point value, meaning that you can wait for a\n\
5599 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
5600 additional wait period, in milliseconds; this may be useful if your\n\
5601 Emacs was built without floating point support.\n\
5602 \(Not all operating systems support waiting for a fraction of a second.)")
5603 (seconds, milliseconds)
5604 Lisp_Object seconds, milliseconds;
5606 int sec, usec;
5608 if (NILP (milliseconds))
5609 XSETINT (milliseconds, 0);
5610 else
5611 CHECK_NUMBER (milliseconds, 1);
5612 usec = XINT (milliseconds) * 1000;
5615 double duration = extract_float (seconds);
5616 sec = (int) duration;
5617 usec += (duration - sec) * 1000000;
5620 #ifndef EMACS_HAS_USECS
5621 if (sec == 0 && usec != 0)
5622 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
5623 #endif
5625 /* Assure that 0 <= usec < 1000000. */
5626 if (usec < 0)
5628 /* We can't rely on the rounding being correct if user is negative. */
5629 if (-1000000 < usec)
5630 sec--, usec += 1000000;
5631 else
5632 sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
5634 else
5635 sec += usec / 1000000, usec %= 1000000;
5637 if (sec < 0 || (sec == 0 && usec == 0))
5638 return Qnil;
5641 Lisp_Object zero;
5643 XSETFASTINT (zero, 0);
5644 wait_reading_process_input (sec, usec, zero, 0);
5647 /* We should always have wait_reading_process_input; we have a dummy
5648 implementation for systems which don't support subprocesses. */
5649 #if 0
5650 /* No wait_reading_process_input */
5651 immediate_quit = 1;
5652 QUIT;
5654 #ifdef VMS
5655 sys_sleep (sec);
5656 #else /* not VMS */
5657 /* The reason this is done this way
5658 (rather than defined (H_S) && defined (H_T))
5659 is because the VMS preprocessor doesn't grok `defined' */
5660 #ifdef HAVE_SELECT
5661 EMACS_GET_TIME (end_time);
5662 EMACS_SET_SECS_USECS (timeout, sec, usec);
5663 EMACS_ADD_TIME (end_time, end_time, timeout);
5665 while (1)
5667 EMACS_GET_TIME (timeout);
5668 EMACS_SUB_TIME (timeout, end_time, timeout);
5669 if (EMACS_TIME_NEG_P (timeout)
5670 || !select (1, 0, 0, 0, &timeout))
5671 break;
5673 #else /* not HAVE_SELECT */
5674 sleep (sec);
5675 #endif /* HAVE_SELECT */
5676 #endif /* not VMS */
5678 immediate_quit = 0;
5679 #endif /* no subprocesses */
5681 return Qnil;
5685 /* This is just like wait_reading_process_input, except that
5686 it does the redisplay.
5688 It's also much like Fsit_for, except that it can be used for
5689 waiting for input as well. */
5691 Lisp_Object
5692 sit_for (sec, usec, reading, display, initial_display)
5693 int sec, usec, reading, display, initial_display;
5695 Lisp_Object read_kbd;
5697 swallow_events (display);
5699 if (detect_input_pending_run_timers (display))
5700 return Qnil;
5702 if (initial_display)
5703 redisplay_preserve_echo_area ();
5705 if (sec == 0 && usec == 0)
5706 return Qt;
5708 #ifdef SIGIO
5709 gobble_input (0);
5710 #endif
5712 XSETINT (read_kbd, reading ? -1 : 1);
5713 wait_reading_process_input (sec, usec, read_kbd, display);
5715 return detect_input_pending () ? Qnil : Qt;
5719 DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
5720 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
5721 SECONDS may be a floating-point value, meaning that you can wait for a\n\
5722 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
5723 additional wait period, in milliseconds; this may be useful if your\n\
5724 Emacs was built without floating point support.\n\
5725 \(Not all operating systems support waiting for a fraction of a second.)\n\
5726 Optional third arg NODISP non-nil means don't redisplay, just wait for input.\n\
5727 Redisplay is preempted as always if input arrives, and does not happen\n\
5728 if input is available before it starts.\n\
5729 Value is t if waited the full time with no input arriving.")
5730 (seconds, milliseconds, nodisp)
5731 Lisp_Object seconds, milliseconds, nodisp;
5733 int sec, usec;
5735 if (NILP (milliseconds))
5736 XSETINT (milliseconds, 0);
5737 else
5738 CHECK_NUMBER (milliseconds, 1);
5739 usec = XINT (milliseconds) * 1000;
5742 double duration = extract_float (seconds);
5743 sec = (int) duration;
5744 usec += (duration - sec) * 1000000;
5747 #ifndef EMACS_HAS_USECS
5748 if (usec != 0 && sec == 0)
5749 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE);
5750 #endif
5752 return sit_for (sec, usec, 0, NILP (nodisp), NILP (nodisp));
5757 /***********************************************************************
5758 Other Lisp Functions
5759 ***********************************************************************/
5761 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
5762 session's frames, frame names, buffers, buffer-read-only flags, and
5763 buffer-modified-flags, and a trailing sentinel (so we don't need to
5764 add length checks). */
5766 static Lisp_Object frame_and_buffer_state;
5769 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
5770 Sframe_or_buffer_changed_p, 0, 0, 0,
5771 "Return non-nil if the frame and buffer state appears to have changed.\n\
5772 The state variable is an internal vector containing all frames and buffers,\n\
5773 aside from buffers whose names start with space,\n\
5774 along with the buffers' read-only and modified flags, which allows a fast\n\
5775 check to see whether the menu bars might need to be recomputed.\n\
5776 If this function returns non-nil, it updates the internal vector to reflect\n\
5777 the current state.\n")
5780 Lisp_Object tail, frame, buf;
5781 Lisp_Object *vecp;
5782 int n;
5784 vecp = XVECTOR (frame_and_buffer_state)->contents;
5785 FOR_EACH_FRAME (tail, frame)
5787 if (!EQ (*vecp++, frame))
5788 goto changed;
5789 if (!EQ (*vecp++, XFRAME (frame)->name))
5790 goto changed;
5792 /* Check that the buffer info matches.
5793 No need to test for the end of the vector
5794 because the last element of the vector is lambda
5795 and that will always cause a mismatch. */
5796 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
5798 buf = XCDR (XCAR (tail));
5799 /* Ignore buffers that aren't included in buffer lists. */
5800 if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
5801 continue;
5802 if (!EQ (*vecp++, buf))
5803 goto changed;
5804 if (!EQ (*vecp++, XBUFFER (buf)->read_only))
5805 goto changed;
5806 if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
5807 goto changed;
5809 /* Detect deletion of a buffer at the end of the list. */
5810 if (EQ (*vecp, Qlambda))
5811 return Qnil;
5812 changed:
5813 /* Start with 1 so there is room for at least one lambda at the end. */
5814 n = 1;
5815 FOR_EACH_FRAME (tail, frame)
5816 n += 2;
5817 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
5818 n += 3;
5819 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
5820 if (n > XVECTOR (frame_and_buffer_state)->size
5821 || n + 20 < XVECTOR (frame_and_buffer_state)->size / 2)
5822 /* Add 20 extra so we grow it less often. */
5823 frame_and_buffer_state = Fmake_vector (make_number (n + 20), Qlambda);
5824 vecp = XVECTOR (frame_and_buffer_state)->contents;
5825 FOR_EACH_FRAME (tail, frame)
5827 *vecp++ = frame;
5828 *vecp++ = XFRAME (frame)->name;
5830 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
5832 buf = XCDR (XCAR (tail));
5833 /* Ignore buffers that aren't included in buffer lists. */
5834 if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
5835 continue;
5836 *vecp++ = buf;
5837 *vecp++ = XBUFFER (buf)->read_only;
5838 *vecp++ = Fbuffer_modified_p (buf);
5840 /* Fill up the vector with lambdas (always at least one). */
5841 *vecp++ = Qlambda;
5842 while (vecp - XVECTOR (frame_and_buffer_state)->contents
5843 < XVECTOR (frame_and_buffer_state)->size)
5844 *vecp++ = Qlambda;
5845 /* Make sure we didn't overflow the vector. */
5846 if (vecp - XVECTOR (frame_and_buffer_state)->contents
5847 > XVECTOR (frame_and_buffer_state)->size)
5848 abort ();
5849 return Qt;
5854 /***********************************************************************
5855 Initialization
5856 ***********************************************************************/
5858 char *terminal_type;
5860 /* Initialization done when Emacs fork is started, before doing stty.
5861 Determine terminal type and set terminal_driver. Then invoke its
5862 decoding routine to set up variables in the terminal package. */
5864 void
5865 init_display ()
5867 #ifdef HAVE_X_WINDOWS
5868 extern int display_arg;
5869 #endif
5871 /* Construct the space glyph. */
5872 space_glyph.type = CHAR_GLYPH;
5873 SET_CHAR_GLYPH_FROM_GLYPH (space_glyph, ' ');
5874 space_glyph.charpos = -1;
5876 meta_key = 0;
5877 inverse_video = 0;
5878 cursor_in_echo_area = 0;
5879 terminal_type = (char *) 0;
5881 /* Now is the time to initialize this; it's used by init_sys_modes
5882 during startup. */
5883 Vwindow_system = Qnil;
5885 /* If the user wants to use a window system, we shouldn't bother
5886 initializing the terminal. This is especially important when the
5887 terminal is so dumb that emacs gives up before and doesn't bother
5888 using the window system.
5890 If the DISPLAY environment variable is set and nonempty,
5891 try to use X, and die with an error message if that doesn't work. */
5893 #ifdef HAVE_X_WINDOWS
5894 if (! display_arg)
5896 char *display;
5897 #ifdef VMS
5898 display = getenv ("DECW$DISPLAY");
5899 #else
5900 display = getenv ("DISPLAY");
5901 #endif
5903 display_arg = (display != 0 && *display != 0);
5906 if (!inhibit_window_system && display_arg
5907 #ifndef CANNOT_DUMP
5908 && initialized
5909 #endif
5912 Vwindow_system = intern ("x");
5913 #ifdef HAVE_X11
5914 Vwindow_system_version = make_number (11);
5915 #else
5916 Vwindow_system_version = make_number (10);
5917 #endif
5918 #if defined (LINUX) && defined (HAVE_LIBNCURSES)
5919 /* In some versions of ncurses,
5920 tputs crashes if we have not called tgetent.
5921 So call tgetent. */
5922 { char b[2044]; tgetent (b, "xterm");}
5923 #endif
5924 adjust_frame_glyphs_initially ();
5925 return;
5927 #endif /* HAVE_X_WINDOWS */
5929 #ifdef HAVE_NTGUI
5930 if (!inhibit_window_system)
5932 Vwindow_system = intern ("w32");
5933 Vwindow_system_version = make_number (1);
5934 adjust_frame_glyphs_initially ();
5935 return;
5937 #endif /* HAVE_NTGUI */
5939 /* If no window system has been specified, try to use the terminal. */
5940 if (! isatty (0))
5942 fatal ("standard input is not a tty");
5943 exit (1);
5946 /* Look at the TERM variable */
5947 terminal_type = (char *) getenv ("TERM");
5948 if (!terminal_type)
5950 #ifdef VMS
5951 fprintf (stderr, "Please specify your terminal type.\n\
5952 For types defined in VMS, use set term /device=TYPE.\n\
5953 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
5954 \(The quotation marks are necessary since terminal types are lower case.)\n");
5955 #else
5956 fprintf (stderr, "Please set the environment variable TERM; see tset(1).\n");
5957 #endif
5958 exit (1);
5961 #ifdef VMS
5962 /* VMS DCL tends to up-case things, so down-case term type.
5963 Hardly any uppercase letters in terminal types; should be none. */
5965 char *new = (char *) xmalloc (strlen (terminal_type) + 1);
5966 char *p;
5968 strcpy (new, terminal_type);
5970 for (p = new; *p; p++)
5971 if (isupper (*p))
5972 *p = tolower (*p);
5974 terminal_type = new;
5976 #endif /* VMS */
5978 term_init (terminal_type);
5981 struct frame *sf = SELECTED_FRAME ();
5982 int width = FRAME_WINDOW_WIDTH (sf);
5983 int height = FRAME_HEIGHT (sf);
5985 unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
5987 /* If these sizes are so big they cause overflow, just ignore the
5988 change. It's not clear what better we could do. */
5989 if (total_glyphs / sizeof (struct glyph) / height != width + 2)
5990 fatal ("screen size %dx%d too big", width, height);
5993 adjust_frame_glyphs_initially ();
5994 calculate_costs (XFRAME (selected_frame));
5996 #ifdef SIGWINCH
5997 #ifndef CANNOT_DUMP
5998 if (initialized)
5999 #endif /* CANNOT_DUMP */
6000 signal (SIGWINCH, window_change_signal);
6001 #endif /* SIGWINCH */
6003 /* Set up faces of the initial terminal frame of a dumped Emacs. */
6004 if (initialized
6005 && !noninteractive
6006 #ifdef MSDOS
6007 /* The MSDOS terminal turns on its ``window system'' relatively
6008 late into the startup, so we cannot do the frame faces'
6009 initialization just yet. It will be done later by pc-win.el
6010 and internal_terminal_init. */
6011 && (strcmp (terminal_type, "internal") != 0 || inhibit_window_system)
6012 #endif
6013 && NILP (Vwindow_system))
6015 /* For the initial frame, we don't have any way of knowing what
6016 are the foreground and background colors of the terminal. */
6017 struct frame *sf = SELECTED_FRAME();
6019 FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
6020 FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;
6021 call0 (intern ("tty-set-up-initial-frame-faces"));
6027 /***********************************************************************
6028 Blinking cursor
6029 ***********************************************************************/
6031 DEFUN ("internal-show-cursor", Finternal_show_cursor,
6032 Sinternal_show_cursor, 2, 2, 0,
6033 "Set the cursor-visibility flag of WINDOW to SHOW.\n\
6034 WINDOW nil means use the selected window. SHOW non-nil means\n\
6035 show a cursor in WINDOW in the next redisplay. SHOW nil means\n\
6036 don't show a cursor.")
6037 (window, show)
6038 Lisp_Object window, show;
6040 /* Don't change cursor state while redisplaying. This could confuse
6041 output routines. */
6042 if (!redisplaying_p)
6044 if (NILP (window))
6045 window = selected_window;
6046 else
6047 CHECK_WINDOW (window, 2);
6049 XWINDOW (window)->cursor_off_p = NILP (show);
6052 return Qnil;
6056 DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
6057 Sinternal_show_cursor_p, 0, 1, 0,
6058 "Value is non-nil if next redisplay will display a cursor in WINDOW.\n\
6059 WINDOW nil or omitted means report on the selected window.")
6060 (window)
6061 Lisp_Object window;
6063 struct window *w;
6065 if (NILP (window))
6066 window = selected_window;
6067 else
6068 CHECK_WINDOW (window, 2);
6070 w = XWINDOW (window);
6071 return w->cursor_off_p ? Qnil : Qt;
6075 /***********************************************************************
6076 Initialization
6077 ***********************************************************************/
6079 void
6080 syms_of_display ()
6082 defsubr (&Sredraw_frame);
6083 defsubr (&Sredraw_display);
6084 defsubr (&Sframe_or_buffer_changed_p);
6085 defsubr (&Sopen_termscript);
6086 defsubr (&Sding);
6087 defsubr (&Ssit_for);
6088 defsubr (&Ssleep_for);
6089 defsubr (&Ssend_string_to_terminal);
6090 defsubr (&Sinternal_show_cursor);
6091 defsubr (&Sinternal_show_cursor_p);
6093 frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
6094 staticpro (&frame_and_buffer_state);
6096 Qdisplay_table = intern ("display-table");
6097 staticpro (&Qdisplay_table);
6099 DEFVAR_INT ("baud-rate", &baud_rate,
6100 "*The output baud rate of the terminal.\n\
6101 On most systems, changing this value will affect the amount of padding\n\
6102 and the other strategic decisions made during redisplay.");
6104 DEFVAR_BOOL ("inverse-video", &inverse_video,
6105 "*Non-nil means invert the entire frame display.\n\
6106 This means everything is in inverse video which otherwise would not be.");
6108 DEFVAR_BOOL ("visible-bell", &visible_bell,
6109 "*Non-nil means try to flash the frame to represent a bell.");
6111 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
6112 "*Non-nil means no need to redraw entire frame after suspending.\n\
6113 A non-nil value is useful if the terminal can automatically preserve\n\
6114 Emacs's frame display when you reenter Emacs.\n\
6115 It is up to you to set this variable if your terminal can do that.");
6117 DEFVAR_LISP ("window-system", &Vwindow_system,
6118 "A symbol naming the window-system under which Emacs is running\n\
6119 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
6121 DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
6122 "The version number of the window system in use.\n\
6123 For X windows, this is 10 or 11.");
6125 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
6126 "Non-nil means put cursor in minibuffer, at end of any message there.");
6128 DEFVAR_LISP ("glyph-table", &Vglyph_table,
6129 "Table defining how to output a glyph code to the frame.\n\
6130 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
6131 Each element can be:\n\
6132 integer: a glyph code which this glyph is an alias for.\n\
6133 string: output this glyph using that string (not impl. in X windows).\n\
6134 nil: this glyph mod 256 is char code to output,\n\
6135 and this glyph / 256 is face code for X windows (see `face-id').");
6136 Vglyph_table = Qnil;
6138 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
6139 "Display table to use for buffers that specify none.\n\
6140 See `buffer-display-table' for more information.");
6141 Vstandard_display_table = Qnil;
6143 DEFVAR_BOOL ("redisplay-dont-pause", &redisplay_dont_pause,
6144 "*Non-nil means update isn't paused when input is detected.");
6145 redisplay_dont_pause = 0;
6147 /* Initialize `window-system', unless init_display already decided it. */
6148 #ifdef CANNOT_DUMP
6149 if (noninteractive)
6150 #endif
6152 Vwindow_system = Qnil;
6153 Vwindow_system_version = Qnil;