Add view-mode to local variables.
[emacs.git] / src / dispnew.c
blobf0d7d3ea6dcbde68b4961f0931e38bfd1c7d309b
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__ */
103 #if defined (LINUX) && defined (HAVE_LIBNCURSES)
104 #include <term.h> /* for tgetent */
105 #endif
107 /* Structure to pass dimensions around. Used for character bounding
108 boxes, glyph matrix dimensions and alike. */
110 struct dim
112 int width;
113 int height;
117 /* Function prototypes. */
119 static void redraw_overlapping_rows P_ ((struct window *, int));
120 static void redraw_overlapped_rows P_ ((struct window *, int));
121 static int count_blanks P_ ((struct glyph *, int));
122 static int count_match P_ ((struct glyph *, struct glyph *,
123 struct glyph *, struct glyph *));
124 static unsigned line_draw_cost P_ ((struct glyph_matrix *, int));
125 static void update_frame_line P_ ((struct frame *, int));
126 static struct dim allocate_matrices_for_frame_redisplay
127 P_ ((Lisp_Object, int, int, struct dim, int, int *));
128 static void allocate_matrices_for_window_redisplay P_ ((struct window *,
129 struct dim));
130 static int realloc_glyph_pool P_ ((struct glyph_pool *, struct dim));
131 static void adjust_frame_glyphs P_ ((struct frame *));
132 struct glyph_matrix *new_glyph_matrix P_ ((struct glyph_pool *));
133 static void free_glyph_matrix P_ ((struct glyph_matrix *));
134 static void adjust_glyph_matrix P_ ((struct window *, struct glyph_matrix *,
135 int, int, struct dim));
136 static void change_frame_size_1 P_ ((struct frame *, int, int, int, int, int));
137 static void swap_glyph_pointers P_ ((struct glyph_row *, struct glyph_row *));
138 static int glyph_row_slice_p P_ ((struct glyph_row *, struct glyph_row *));
139 static void fill_up_frame_row_with_spaces P_ ((struct glyph_row *, int));
140 static void build_frame_matrix_from_window_tree P_ ((struct glyph_matrix *,
141 struct window *));
142 static void build_frame_matrix_from_leaf_window P_ ((struct glyph_matrix *,
143 struct window *));
144 static struct glyph_pool *new_glyph_pool P_ ((void));
145 static void free_glyph_pool P_ ((struct glyph_pool *));
146 static void adjust_frame_glyphs_initially P_ ((void));
147 static void adjust_frame_message_buffer P_ ((struct frame *));
148 static void adjust_decode_mode_spec_buffer P_ ((struct frame *));
149 static void fill_up_glyph_row_with_spaces P_ ((struct glyph_row *));
150 static void build_frame_matrix P_ ((struct frame *));
151 void clear_current_matrices P_ ((struct frame *));
152 void scroll_glyph_matrix_range P_ ((struct glyph_matrix *, int, int,
153 int, int));
154 static void clear_window_matrices P_ ((struct window *, int));
155 static void fill_up_glyph_row_area_with_spaces P_ ((struct glyph_row *, int));
156 static int scrolling_window P_ ((struct window *, int));
157 static int update_window_line P_ ((struct window *, int, int *));
158 static void update_marginal_area P_ ((struct window *, int, int));
159 static int update_text_area P_ ((struct window *, int));
160 static void make_current P_ ((struct glyph_matrix *, struct glyph_matrix *,
161 int));
162 static void mirror_make_current P_ ((struct window *, int));
163 void check_window_matrix_pointers P_ ((struct window *));
164 #if GLYPH_DEBUG
165 static void check_matrix_pointers P_ ((struct glyph_matrix *,
166 struct glyph_matrix *));
167 #endif
168 static void mirror_line_dance P_ ((struct window *, int, int, int *, char *));
169 static int update_window_tree P_ ((struct window *, int));
170 static int update_window P_ ((struct window *, int));
171 static int update_frame_1 P_ ((struct frame *, int, int));
172 static void set_window_cursor_after_update P_ ((struct window *));
173 static int row_equal_p P_ ((struct window *, struct glyph_row *,
174 struct glyph_row *, int));
175 static void adjust_frame_glyphs_for_window_redisplay P_ ((struct frame *));
176 static void adjust_frame_glyphs_for_frame_redisplay P_ ((struct frame *));
177 static void reverse_rows P_ ((struct glyph_matrix *, int, int));
178 static int margin_glyphs_to_reserve P_ ((struct window *, int, Lisp_Object));
179 static void sync_window_with_frame_matrix_rows P_ ((struct window *));
180 struct window *frame_row_to_window P_ ((struct window *, int));
184 /* Non-zero means don't pause redisplay for pending input. (This is
185 for debugging and for a future implementation of EDT-like
186 scrolling. */
188 int redisplay_dont_pause;
190 /* Nonzero upon entry to redisplay means do not assume anything about
191 current contents of actual terminal frame; clear and redraw it. */
193 int frame_garbaged;
195 /* Nonzero means last display completed. Zero means it was preempted. */
197 int display_completed;
199 /* Lisp variable visible-bell; enables use of screen-flash instead of
200 audible bell. */
202 int visible_bell;
204 /* Invert the color of the whole frame, at a low level. */
206 int inverse_video;
208 /* Line speed of the terminal. */
210 int baud_rate;
212 /* Either nil or a symbol naming the window system under which Emacs
213 is running. */
215 Lisp_Object Vwindow_system;
217 /* Version number of X windows: 10, 11 or nil. */
219 Lisp_Object Vwindow_system_version;
221 /* Vector of glyph definitions. Indexed by glyph number, the contents
222 are a string which is how to output the glyph.
224 If Vglyph_table is nil, a glyph is output by using its low 8 bits
225 as a character code.
227 This is an obsolete feature that is no longer used. The variable
228 is retained for compatibility. */
230 Lisp_Object Vglyph_table;
232 /* Display table to use for vectors that don't specify their own. */
234 Lisp_Object Vstandard_display_table;
236 /* Nonzero means reading single-character input with prompt so put
237 cursor on mini-buffer after the prompt. positive means at end of
238 text in echo area; negative means at beginning of line. */
240 int cursor_in_echo_area;
242 Lisp_Object Qdisplay_table;
245 /* The currently selected frame. In a single-frame version, this
246 variable always equals the_only_frame. */
248 Lisp_Object selected_frame;
250 /* A frame which is not just a mini-buffer, or 0 if there are no such
251 frames. This is usually the most recent such frame that was
252 selected. In a single-frame version, this variable always holds
253 the address of the_only_frame. */
255 struct frame *last_nonminibuf_frame;
257 /* Stdio stream being used for copy of all output. */
259 FILE *termscript;
261 /* Structure for info on cursor positioning. */
263 struct cm Wcm;
265 /* 1 means SIGWINCH happened when not safe. */
267 int delayed_size_change;
269 /* 1 means glyph initialization has been completed at startup. */
271 static int glyphs_initialized_initially_p;
273 /* Updated window if != 0. Set by update_window. */
275 struct window *updated_window;
277 /* Glyph row updated in update_window_line, and area that is updated. */
279 struct glyph_row *updated_row;
280 int updated_area;
282 /* A glyph for a space. */
284 struct glyph space_glyph;
286 /* Non-zero means update has been performed directly, so that there's
287 no need for redisplay_internal to do much work. Set by
288 direct_output_for_insert. */
290 int redisplay_performed_directly_p;
292 /* Counts of allocated structures. These counts serve to diagnose
293 memory leaks and double frees. */
295 int glyph_matrix_count;
296 int glyph_pool_count;
298 /* If non-null, the frame whose frame matrices are manipulated. If
299 null, window matrices are worked on. */
301 static struct frame *frame_matrix_frame;
303 /* Current interface for window-based redisplay. Set from init_xterm.
304 A null value means we are not using window-based redisplay. */
306 struct redisplay_interface *rif;
308 /* Non-zero means that fonts have been loaded since the last glyph
309 matrix adjustments. Redisplay must stop, and glyph matrices must
310 be adjusted when this flag becomes non-zero during display. The
311 reason fonts can be loaded so late is that fonts of fontsets are
312 loaded on demand. */
314 int fonts_changed_p;
316 /* Convert vpos and hpos from frame to window and vice versa.
317 This may only be used for terminal frames. */
319 #if GLYPH_DEBUG
321 static int window_to_frame_vpos P_ ((struct window *, int));
322 static int window_to_frame_hpos P_ ((struct window *, int));
323 #define WINDOW_TO_FRAME_VPOS(W, VPOS) window_to_frame_vpos ((W), (VPOS))
324 #define WINDOW_TO_FRAME_HPOS(W, HPOS) window_to_frame_hpos ((W), (HPOS))
326 #else /* GLYPH_DEBUG == 0 */
328 #define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + XFASTINT ((W)->top))
329 #define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + XFASTINT ((W)->left))
331 #endif /* GLYPH_DEBUG == 0 */
334 /* Like bcopy except never gets confused by overlap. Let this be the
335 first function defined in this file, or change emacs.c where the
336 address of this function is used. */
338 void
339 safe_bcopy (from, to, size)
340 char *from, *to;
341 int size;
343 if (size <= 0 || from == to)
344 return;
346 /* If the source and destination don't overlap, then bcopy can
347 handle it. If they do overlap, but the destination is lower in
348 memory than the source, we'll assume bcopy can handle that. */
349 if (to < from || from + size <= to)
350 bcopy (from, to, size);
352 /* Otherwise, we'll copy from the end. */
353 else
355 register char *endf = from + size;
356 register char *endt = to + size;
358 /* If TO - FROM is large, then we should break the copy into
359 nonoverlapping chunks of TO - FROM bytes each. However, if
360 TO - FROM is small, then the bcopy function call overhead
361 makes this not worth it. The crossover point could be about
362 anywhere. Since I don't think the obvious copy loop is too
363 bad, I'm trying to err in its favor. */
364 if (to - from < 64)
367 *--endt = *--endf;
368 while (endf != from);
370 else
372 for (;;)
374 endt -= (to - from);
375 endf -= (to - from);
377 if (endt < to)
378 break;
380 bcopy (endf, endt, to - from);
383 /* If SIZE wasn't a multiple of TO - FROM, there will be a
384 little left over. The amount left over is (endt + (to -
385 from)) - to, which is endt - from. */
386 bcopy (from, to, endt - from);
393 /***********************************************************************
394 Glyph Matrices
395 ***********************************************************************/
397 /* Allocate and return a glyph_matrix structure. POOL is the glyph
398 pool from which memory for the matrix should be allocated, or null
399 for window-based redisplay where no glyph pools are used. The
400 member `pool' of the glyph matrix structure returned is set to
401 POOL, the structure is otherwise zeroed. */
403 struct glyph_matrix *
404 new_glyph_matrix (pool)
405 struct glyph_pool *pool;
407 struct glyph_matrix *result;
409 /* Allocate and clear. */
410 result = (struct glyph_matrix *) xmalloc (sizeof *result);
411 bzero (result, sizeof *result);
413 /* Increment number of allocated matrices. This count is used
414 to detect memory leaks. */
415 ++glyph_matrix_count;
417 /* Set pool and return. */
418 result->pool = pool;
419 return result;
423 /* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed.
425 The global counter glyph_matrix_count is decremented when a matrix
426 is freed. If the count gets negative, more structures were freed
427 than allocated, i.e. one matrix was freed more than once or a bogus
428 pointer was passed to this function.
430 If MATRIX->pool is null, this means that the matrix manages its own
431 glyph memory---this is done for matrices on X frames. Freeing the
432 matrix also frees the glyph memory in this case. */
434 static void
435 free_glyph_matrix (matrix)
436 struct glyph_matrix *matrix;
438 if (matrix)
440 int i;
442 /* Detect the case that more matrices are freed than were
443 allocated. */
444 if (--glyph_matrix_count < 0)
445 abort ();
447 /* Free glyph memory if MATRIX owns it. */
448 if (matrix->pool == NULL)
449 for (i = 0; i < matrix->rows_allocated; ++i)
450 xfree (matrix->rows[i].glyphs[LEFT_MARGIN_AREA]);
452 /* Free row structures and the matrix itself. */
453 xfree (matrix->rows);
454 xfree (matrix);
459 /* Return the number of glyphs to reserve for a marginal area of
460 window W. TOTAL_GLYPHS is the number of glyphs in a complete
461 display line of window W. MARGIN gives the width of the marginal
462 area in canonical character units. MARGIN should be an integer
463 or a float. */
465 static int
466 margin_glyphs_to_reserve (w, total_glyphs, margin)
467 struct window *w;
468 int total_glyphs;
469 Lisp_Object margin;
471 int n;
473 if (NUMBERP (margin))
475 int width = XFASTINT (w->width);
476 double d = max (0, XFLOATINT (margin));
477 d = min (width / 2 - 1, d);
478 n = (int) ((double) total_glyphs / width * d);
480 else
481 n = 0;
483 return n;
487 /* Adjust glyph matrix MATRIX on window W or on a frame to changed
488 window sizes.
490 W is null if the function is called for a frame glyph matrix.
491 Otherwise it is the window MATRIX is a member of. X and Y are the
492 indices of the first column and row of MATRIX within the frame
493 matrix, if such a matrix exists. They are zero for purely
494 window-based redisplay. DIM is the needed size of the matrix.
496 In window-based redisplay, where no frame matrices exist, glyph
497 matrices manage their own glyph storage. Otherwise, they allocate
498 storage from a common frame glyph pool which can be found in
499 MATRIX->pool.
501 The reason for this memory management strategy is to avoid complete
502 frame redraws if possible. When we allocate from a common pool, a
503 change of the location or size of a sub-matrix within the pool
504 requires a complete redisplay of the frame because we cannot easily
505 make sure that the current matrices of all windows still agree with
506 what is displayed on the screen. While this is usually fast, it
507 leads to screen flickering. */
509 static void
510 adjust_glyph_matrix (w, matrix, x, y, dim)
511 struct window *w;
512 struct glyph_matrix *matrix;
513 int x, y;
514 struct dim dim;
516 int i;
517 int new_rows;
518 int marginal_areas_changed_p = 0;
519 int header_line_changed_p = 0;
520 int header_line_p = 0;
521 int left = -1, right = -1;
522 int window_x, window_y, window_width, window_height;
524 /* See if W had a top line that has disappeared now, or vice versa. */
525 if (w)
527 header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
528 header_line_changed_p = header_line_p != matrix->header_line_p;
530 matrix->header_line_p = header_line_p;
532 /* Do nothing if MATRIX' size, position, vscroll, and marginal areas
533 haven't changed. This optimization is important because preserving
534 the matrix means preventing redisplay. */
535 if (matrix->pool == NULL)
537 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
538 left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_width);
539 right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_width);
540 xassert (left >= 0 && right >= 0);
541 marginal_areas_changed_p = (left != matrix->left_margin_glyphs
542 || right != matrix->right_margin_glyphs);
544 if (!marginal_areas_changed_p
545 && !fonts_changed_p
546 && !header_line_changed_p
547 && matrix->window_top_y == XFASTINT (w->top)
548 && matrix->window_height == window_height
549 && matrix->window_vscroll == w->vscroll
550 && matrix->window_width == window_width)
551 return;
554 /* Enlarge MATRIX->rows if necessary. New rows are cleared. */
555 if (matrix->rows_allocated < dim.height)
557 int size = dim.height * sizeof (struct glyph_row);
558 new_rows = dim.height - matrix->rows_allocated;
559 matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
560 bzero (matrix->rows + matrix->rows_allocated,
561 new_rows * sizeof *matrix->rows);
562 matrix->rows_allocated = dim.height;
564 else
565 new_rows = 0;
567 /* If POOL is not null, MATRIX is a frame matrix or a window matrix
568 on a frame not using window-based redisplay. Set up pointers for
569 each row into the glyph pool. */
570 if (matrix->pool)
572 xassert (matrix->pool->glyphs);
574 if (w)
576 left = margin_glyphs_to_reserve (w, dim.width,
577 w->left_margin_width);
578 right = margin_glyphs_to_reserve (w, dim.width,
579 w->right_margin_width);
581 else
582 left = right = 0;
584 for (i = 0; i < dim.height; ++i)
586 struct glyph_row *row = &matrix->rows[i];
588 row->glyphs[LEFT_MARGIN_AREA]
589 = (matrix->pool->glyphs
590 + (y + i) * matrix->pool->ncolumns
591 + x);
593 if (w == NULL
594 || row == matrix->rows + dim.height - 1
595 || (row == matrix->rows && matrix->header_line_p))
597 row->glyphs[TEXT_AREA]
598 = row->glyphs[LEFT_MARGIN_AREA];
599 row->glyphs[RIGHT_MARGIN_AREA]
600 = row->glyphs[TEXT_AREA] + dim.width;
601 row->glyphs[LAST_AREA]
602 = row->glyphs[RIGHT_MARGIN_AREA];
604 else
606 row->glyphs[TEXT_AREA]
607 = row->glyphs[LEFT_MARGIN_AREA] + left;
608 row->glyphs[RIGHT_MARGIN_AREA]
609 = row->glyphs[TEXT_AREA] + dim.width - left - right;
610 row->glyphs[LAST_AREA]
611 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
615 matrix->left_margin_glyphs = left;
616 matrix->right_margin_glyphs = right;
618 else
620 /* If MATRIX->pool is null, MATRIX is responsible for managing
621 its own memory. Allocate glyph memory from the heap. */
622 if (dim.width > matrix->matrix_w
623 || new_rows
624 || header_line_changed_p
625 || marginal_areas_changed_p)
627 struct glyph_row *row = matrix->rows;
628 struct glyph_row *end = row + matrix->rows_allocated;
630 while (row < end)
632 row->glyphs[LEFT_MARGIN_AREA]
633 = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA],
634 (dim.width
635 * sizeof (struct glyph)));
637 /* The mode line never has marginal areas. */
638 if (row == matrix->rows + dim.height - 1
639 || (row == matrix->rows && matrix->header_line_p))
641 row->glyphs[TEXT_AREA]
642 = row->glyphs[LEFT_MARGIN_AREA];
643 row->glyphs[RIGHT_MARGIN_AREA]
644 = row->glyphs[TEXT_AREA] + dim.width;
645 row->glyphs[LAST_AREA]
646 = row->glyphs[RIGHT_MARGIN_AREA];
648 else
650 row->glyphs[TEXT_AREA]
651 = row->glyphs[LEFT_MARGIN_AREA] + left;
652 row->glyphs[RIGHT_MARGIN_AREA]
653 = row->glyphs[TEXT_AREA] + dim.width - left - right;
654 row->glyphs[LAST_AREA]
655 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
657 ++row;
661 xassert (left >= 0 && right >= 0);
662 matrix->left_margin_glyphs = left;
663 matrix->right_margin_glyphs = right;
666 /* Number of rows to be used by MATRIX. */
667 matrix->nrows = dim.height;
669 /* Mark rows in a current matrix of a window as not having valid
670 contents. It's important to not do this for desired matrices.
671 When Emacs starts, it may already be building desired matrices
672 when this function runs. */
673 if (w && matrix == w->current_matrix)
675 /* Optimize the case that only the height has changed (C-x 2,
676 upper window). Invalidate all rows that are no longer part
677 of the window. */
678 if (!marginal_areas_changed_p
679 && matrix->window_top_y == XFASTINT (w->top)
680 && matrix->window_width == window_width)
682 i = 0;
683 while (matrix->rows[i].enabled_p
684 && (MATRIX_ROW_BOTTOM_Y (matrix->rows + i)
685 < matrix->window_height))
686 ++i;
688 /* Window end is invalid, if inside of the rows that
689 are invalidated. */
690 if (INTEGERP (w->window_end_vpos)
691 && XFASTINT (w->window_end_vpos) >= i)
692 w->window_end_valid = Qnil;
694 while (i < matrix->nrows)
695 matrix->rows[i++].enabled_p = 0;
697 else
699 for (i = 0; i < matrix->nrows; ++i)
700 matrix->rows[i].enabled_p = 0;
704 /* Remember last values to be able to optimize frame redraws. */
705 matrix->matrix_x = x;
706 matrix->matrix_y = y;
707 matrix->matrix_w = dim.width;
708 matrix->matrix_h = dim.height;
710 /* Record the top y location and height of W at the time the matrix
711 was last adjusted. This is used to optimize redisplay above. */
712 if (w)
714 matrix->window_top_y = XFASTINT (w->top);
715 matrix->window_height = window_height;
716 matrix->window_width = window_width;
717 matrix->window_vscroll = w->vscroll;
722 /* Reverse the contents of rows in MATRIX between START and END. The
723 contents of the row at END - 1 end up at START, END - 2 at START +
724 1 etc. This is part of the implementation of rotate_matrix (see
725 below). */
727 static void
728 reverse_rows (matrix, start, end)
729 struct glyph_matrix *matrix;
730 int start, end;
732 int i, j;
734 for (i = start, j = end - 1; i < j; ++i, --j)
736 /* Non-ISO HP/UX compiler doesn't like auto struct
737 initialization. */
738 struct glyph_row temp;
739 temp = matrix->rows[i];
740 matrix->rows[i] = matrix->rows[j];
741 matrix->rows[j] = temp;
746 /* Rotate the contents of rows in MATRIX in the range FIRST .. LAST -
747 1 by BY positions. BY < 0 means rotate left, i.e. towards lower
748 indices. (Note: this does not copy glyphs, only glyph pointers in
749 row structures are moved around).
751 The algorithm used for rotating the vector was, I believe, first
752 described by Kernighan. See the vector R as consisting of two
753 sub-vectors AB, where A has length BY for BY >= 0. The result
754 after rotating is then BA. Reverse both sub-vectors to get ArBr
755 and reverse the result to get (ArBr)r which is BA. Similar for
756 rotating right. */
758 void
759 rotate_matrix (matrix, first, last, by)
760 struct glyph_matrix *matrix;
761 int first, last, by;
763 if (by < 0)
765 /* Up (rotate left, i.e. towards lower indices). */
766 by = -by;
767 reverse_rows (matrix, first, first + by);
768 reverse_rows (matrix, first + by, last);
769 reverse_rows (matrix, first, last);
771 else if (by > 0)
773 /* Down (rotate right, i.e. towards higher indices). */
774 reverse_rows (matrix, last - by, last);
775 reverse_rows (matrix, first, last - by);
776 reverse_rows (matrix, first, last);
781 /* Increment buffer positions in glyph rows of MATRIX. Do it for rows
782 with indices START <= index < END. Increment positions by DELTA/
783 DELTA_BYTES. */
785 void
786 increment_matrix_positions (matrix, start, end, delta, delta_bytes)
787 struct glyph_matrix *matrix;
788 int start, end, delta, delta_bytes;
790 /* Check that START and END are reasonable values. */
791 xassert (start >= 0 && start <= matrix->nrows);
792 xassert (end >= 0 && end <= matrix->nrows);
793 xassert (start <= end);
795 for (; start < end; ++start)
796 increment_row_positions (matrix->rows + start, 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];
994 #if 0 /* At some point, some bit-fields of struct glyph were not set,
995 which made glyphs unequal when compared with GLYPH_EQUAL_P.
996 Redisplay outputs such glyphs, and flickering effects were
997 the result. This also depended on the contents of memory
998 returned by xmalloc. If flickering happens again, activate
999 the code below If the flickering is gone with that, chances
1000 are that the flickering has the same reason as here. */
1001 bzero (p[0], (char *) p[LAST_AREA] - (char *) p[0]);
1002 #endif
1006 /* Make ROW an empty, enabled row of canonical character height,
1007 in window W starting at y-position Y. */
1009 void
1010 blank_row (w, row, y)
1011 struct window *w;
1012 struct glyph_row *row;
1013 int y;
1015 int min_y, max_y;
1017 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
1018 max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w);
1020 clear_glyph_row (row);
1021 row->y = y;
1022 row->ascent = row->phys_ascent = 0;
1023 row->height = row->phys_height = CANON_Y_UNIT (XFRAME (w->frame));
1025 if (row->y < min_y)
1026 row->visible_height = row->height - (min_y - row->y);
1027 else if (row->y + row->height > max_y)
1028 row->visible_height = row->height - (row->y + row->height - max_y);
1029 else
1030 row->visible_height = row->height;
1032 row->enabled_p = 1;
1036 /* Increment buffer positions in glyph row ROW. DELTA and DELTA_BYTES
1037 are the amounts by which to change positions. Note that the first
1038 glyph of the text area of a row can have a buffer position even if
1039 the used count of the text area is zero. Such rows display line
1040 ends. */
1042 void
1043 increment_row_positions (row, delta, delta_bytes)
1044 struct glyph_row *row;
1045 int delta, delta_bytes;
1047 int area, i;
1049 /* Increment start and end positions. */
1050 MATRIX_ROW_START_CHARPOS (row) += delta;
1051 MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
1052 MATRIX_ROW_END_CHARPOS (row) += delta;
1053 MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
1055 /* Increment positions in glyphs. */
1056 for (area = 0; area < LAST_AREA; ++area)
1057 for (i = 0; i < row->used[area]; ++i)
1058 if (BUFFERP (row->glyphs[area][i].object)
1059 && row->glyphs[area][i].charpos > 0)
1060 row->glyphs[area][i].charpos += delta;
1062 /* Capture the case of rows displaying a line end. */
1063 if (row->used[TEXT_AREA] == 0
1064 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
1065 row->glyphs[TEXT_AREA]->charpos += delta;
1069 #if 0
1070 /* Swap glyphs between two glyph rows A and B. This exchanges glyph
1071 contents, i.e. glyph structure contents are exchanged between A and
1072 B without changing glyph pointers in A and B. */
1074 static void
1075 swap_glyphs_in_rows (a, b)
1076 struct glyph_row *a, *b;
1078 int area;
1080 for (area = 0; area < LAST_AREA; ++area)
1082 /* Number of glyphs to swap. */
1083 int max_used = max (a->used[area], b->used[area]);
1085 /* Start of glyphs in area of row A. */
1086 struct glyph *glyph_a = a->glyphs[area];
1088 /* End + 1 of glyphs in area of row A. */
1089 struct glyph *glyph_a_end = a->glyphs[max_used];
1091 /* Start of glyphs in area of row B. */
1092 struct glyph *glyph_b = b->glyphs[area];
1094 while (glyph_a < glyph_a_end)
1096 /* Non-ISO HP/UX compiler doesn't like auto struct
1097 initialization. */
1098 struct glyph temp;
1099 temp = *glyph_a;
1100 *glyph_a = *glyph_b;
1101 *glyph_b = temp;
1102 ++glyph_a;
1103 ++glyph_b;
1108 #endif /* 0 */
1110 /* Exchange pointers to glyph memory between glyph rows A and B. */
1112 static INLINE void
1113 swap_glyph_pointers (a, b)
1114 struct glyph_row *a, *b;
1116 int i;
1117 for (i = 0; i < LAST_AREA + 1; ++i)
1119 struct glyph *temp = a->glyphs[i];
1120 a->glyphs[i] = b->glyphs[i];
1121 b->glyphs[i] = temp;
1126 /* Copy glyph row structure FROM to glyph row structure TO, except
1127 that glyph pointers in the structures are left unchanged. */
1129 INLINE void
1130 copy_row_except_pointers (to, from)
1131 struct glyph_row *to, *from;
1133 struct glyph *pointers[1 + LAST_AREA];
1135 /* Save glyph pointers of TO. */
1136 bcopy (to->glyphs, pointers, sizeof to->glyphs);
1138 /* Do a structure assignment. */
1139 *to = *from;
1141 /* Restore original pointers of TO. */
1142 bcopy (pointers, to->glyphs, sizeof to->glyphs);
1146 /* Copy contents of glyph row FROM to glyph row TO. Glyph pointers in
1147 TO and FROM are left unchanged. Glyph contents are copied from the
1148 glyph memory of FROM to the glyph memory of TO. Increment buffer
1149 positions in row TO by DELTA/ DELTA_BYTES. */
1151 void
1152 copy_glyph_row_contents (to, from, delta, delta_bytes)
1153 struct glyph_row *to, *from;
1154 int delta, delta_bytes;
1156 int area;
1158 /* This is like a structure assignment TO = FROM, except that
1159 glyph pointers in the rows are left unchanged. */
1160 copy_row_except_pointers (to, from);
1162 /* Copy glyphs from FROM to TO. */
1163 for (area = 0; area < LAST_AREA; ++area)
1164 if (from->used[area])
1165 bcopy (from->glyphs[area], to->glyphs[area],
1166 from->used[area] * sizeof (struct glyph));
1168 /* Increment buffer positions in TO by DELTA. */
1169 increment_row_positions (to, delta, delta_bytes);
1173 /* Assign glyph row FROM to glyph row TO. This works like a structure
1174 assignment TO = FROM, except that glyph pointers are not copied but
1175 exchanged between TO and FROM. Pointers must be exchanged to avoid
1176 a memory leak. */
1178 static INLINE void
1179 assign_row (to, from)
1180 struct glyph_row *to, *from;
1182 swap_glyph_pointers (to, from);
1183 copy_row_except_pointers (to, from);
1187 /* Test whether the glyph memory of the glyph row WINDOW_ROW, which is
1188 a row in a window matrix, is a slice of the glyph memory of the
1189 glyph row FRAME_ROW which is a row in a frame glyph matrix. Value
1190 is non-zero if the glyph memory of WINDOW_ROW is part of the glyph
1191 memory of FRAME_ROW. */
1193 static int
1194 glyph_row_slice_p (window_row, frame_row)
1195 struct glyph_row *window_row, *frame_row;
1197 struct glyph *window_glyph_start = window_row->glyphs[0];
1198 struct glyph *frame_glyph_start = frame_row->glyphs[0];
1199 struct glyph *frame_glyph_end = frame_row->glyphs[LAST_AREA];
1201 return (frame_glyph_start <= window_glyph_start
1202 && window_glyph_start < frame_glyph_end);
1206 #if 0
1208 /* Find the row in the window glyph matrix WINDOW_MATRIX being a slice
1209 of ROW in the frame matrix FRAME_MATRIX. Value is null if no row
1210 in WINDOW_MATRIX is found satisfying the condition. */
1212 static struct glyph_row *
1213 find_glyph_row_slice (window_matrix, frame_matrix, row)
1214 struct glyph_matrix *window_matrix, *frame_matrix;
1215 int row;
1217 int i;
1219 xassert (row >= 0 && row < frame_matrix->nrows);
1221 for (i = 0; i < window_matrix->nrows; ++i)
1222 if (glyph_row_slice_p (window_matrix->rows + i,
1223 frame_matrix->rows + row))
1224 break;
1226 return i < window_matrix->nrows ? window_matrix->rows + i : 0;
1229 #endif /* 0 */
1231 /* Prepare ROW for display. Desired rows are cleared lazily,
1232 i.e. they are only marked as to be cleared by setting their
1233 enabled_p flag to zero. When a row is to be displayed, a prior
1234 call to this function really clears it. */
1236 void
1237 prepare_desired_row (row)
1238 struct glyph_row *row;
1240 if (!row->enabled_p)
1242 clear_glyph_row (row);
1243 row->enabled_p = 1;
1248 /* Return a hash code for glyph row ROW. */
1251 line_hash_code (row)
1252 struct glyph_row *row;
1254 int hash = 0;
1256 if (row->enabled_p)
1258 if (row->inverse_p)
1260 /* Give all highlighted lines the same hash code
1261 so as to encourage scrolling to leave them in place. */
1262 hash = -1;
1264 else
1266 struct glyph *glyph = row->glyphs[TEXT_AREA];
1267 struct glyph *end = glyph + row->used[TEXT_AREA];
1269 while (glyph < end)
1271 int c = glyph->u.ch;
1272 int face_id = glyph->face_id;
1273 if (must_write_spaces)
1274 c -= SPACEGLYPH;
1275 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
1276 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
1277 ++glyph;
1280 if (hash == 0)
1281 hash = 1;
1285 return hash;
1289 /* Return the cost of drawing line VPOS In MATRIX. The cost equals
1290 the number of characters in the line. If must_write_spaces is
1291 zero, leading and trailing spaces are ignored. */
1293 static unsigned int
1294 line_draw_cost (matrix, vpos)
1295 struct glyph_matrix *matrix;
1296 int vpos;
1298 struct glyph_row *row = matrix->rows + vpos;
1299 struct glyph *beg = row->glyphs[TEXT_AREA];
1300 struct glyph *end = beg + row->used[TEXT_AREA];
1301 int len;
1302 Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
1303 int glyph_table_len = GLYPH_TABLE_LENGTH;
1305 /* Ignore trailing and leading spaces if we can. */
1306 if (!must_write_spaces)
1308 /* Skip from the end over trailing spaces. */
1309 while (end != beg && CHAR_GLYPH_SPACE_P (*end))
1310 --end;
1312 /* All blank line. */
1313 if (end == beg)
1314 return 0;
1316 /* Skip over leading spaces. */
1317 while (CHAR_GLYPH_SPACE_P (*beg))
1318 ++beg;
1321 /* If we don't have a glyph-table, each glyph is one character,
1322 so return the number of glyphs. */
1323 if (glyph_table_base == 0)
1324 len = end - beg;
1325 else
1327 /* Otherwise, scan the glyphs and accumulate their total length
1328 in LEN. */
1329 len = 0;
1330 while (beg < end)
1332 GLYPH g = GLYPH_FROM_CHAR_GLYPH (*beg);
1334 if (g < 0
1335 || GLYPH_SIMPLE_P (glyph_table_base, glyph_table_len, g))
1336 len += 1;
1337 else
1338 len += GLYPH_LENGTH (glyph_table_base, g);
1340 ++beg;
1344 return len;
1348 /* Test two glyph rows A and B for equality. Value is non-zero if A
1349 and B have equal contents. W is the window to which the glyphs
1350 rows A and B belong. It is needed here to test for partial row
1351 visibility. MOUSE_FACE_P non-zero means compare the mouse_face_p
1352 flags of A and B, too. */
1354 static INLINE int
1355 row_equal_p (w, a, b, mouse_face_p)
1356 struct window *w;
1357 struct glyph_row *a, *b;
1358 int mouse_face_p;
1360 if (a == b)
1361 return 1;
1362 else if (a->hash != b->hash)
1363 return 0;
1364 else
1366 struct glyph *a_glyph, *b_glyph, *a_end;
1367 int area;
1369 if (mouse_face_p && a->mouse_face_p != b->mouse_face_p)
1370 return 0;
1372 /* Compare glyphs. */
1373 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
1375 if (a->used[area] != b->used[area])
1376 return 0;
1378 a_glyph = a->glyphs[area];
1379 a_end = a_glyph + a->used[area];
1380 b_glyph = b->glyphs[area];
1382 while (a_glyph < a_end
1383 && GLYPH_EQUAL_P (a_glyph, b_glyph))
1384 ++a_glyph, ++b_glyph;
1386 if (a_glyph != a_end)
1387 return 0;
1390 if (a->truncated_on_left_p != b->truncated_on_left_p
1391 || a->inverse_p != b->inverse_p
1392 || a->fill_line_p != b->fill_line_p
1393 || a->truncated_on_right_p != b->truncated_on_right_p
1394 || a->overlay_arrow_p != b->overlay_arrow_p
1395 || a->continued_p != b->continued_p
1396 || a->indicate_empty_line_p != b->indicate_empty_line_p
1397 || a->overlapped_p != b->overlapped_p
1398 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
1399 != MATRIX_ROW_CONTINUATION_LINE_P (b))
1400 /* Different partially visible characters on left margin. */
1401 || a->x != b->x
1402 /* Different height. */
1403 || a->ascent != b->ascent
1404 || a->phys_ascent != b->phys_ascent
1405 || a->phys_height != b->phys_height
1406 || a->visible_height != b->visible_height)
1407 return 0;
1410 return 1;
1415 /***********************************************************************
1416 Glyph Pool
1418 See dispextern.h for an overall explanation of glyph pools.
1419 ***********************************************************************/
1421 /* Allocate a glyph_pool structure. The structure returned is
1422 initialized with zeros. The global variable glyph_pool_count is
1423 incremented for each pool allocated. */
1425 static struct glyph_pool *
1426 new_glyph_pool ()
1428 struct glyph_pool *result;
1430 /* Allocate a new glyph_pool and clear it. */
1431 result = (struct glyph_pool *) xmalloc (sizeof *result);
1432 bzero (result, sizeof *result);
1434 /* For memory leak and double deletion checking. */
1435 ++glyph_pool_count;
1437 return result;
1441 /* Free a glyph_pool structure POOL. The function may be called with
1442 a null POOL pointer. The global variable glyph_pool_count is
1443 decremented with every pool structure freed. If this count gets
1444 negative, more structures were freed than allocated, i.e. one
1445 structure must have been freed more than once or a bogus pointer
1446 was passed to free_glyph_pool. */
1448 static void
1449 free_glyph_pool (pool)
1450 struct glyph_pool *pool;
1452 if (pool)
1454 /* More freed than allocated? */
1455 --glyph_pool_count;
1456 xassert (glyph_pool_count >= 0);
1458 xfree (pool->glyphs);
1459 xfree (pool);
1464 /* Enlarge a glyph pool POOL. MATRIX_DIM gives the number of rows and
1465 columns we need. This function never shrinks a pool. The only
1466 case in which this would make sense, would be when a frame's size
1467 is changed from a large value to a smaller one. But, if someone
1468 does it once, we can expect that he will do it again.
1470 Value is non-zero if the pool changed in a way which makes
1471 re-adjusting window glyph matrices necessary. */
1473 static int
1474 realloc_glyph_pool (pool, matrix_dim)
1475 struct glyph_pool *pool;
1476 struct dim matrix_dim;
1478 int needed;
1479 int changed_p;
1481 changed_p = (pool->glyphs == 0
1482 || matrix_dim.height != pool->nrows
1483 || matrix_dim.width != pool->ncolumns);
1485 /* Enlarge the glyph pool. */
1486 needed = matrix_dim.width * matrix_dim.height;
1487 if (needed > pool->nglyphs)
1489 int size = needed * sizeof (struct glyph);
1491 if (pool->glyphs)
1492 pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size);
1493 else
1495 pool->glyphs = (struct glyph *) xmalloc (size);
1496 bzero (pool->glyphs, size);
1499 pool->nglyphs = needed;
1502 /* Remember the number of rows and columns because (a) we use then
1503 to do sanity checks, and (b) the number of columns determines
1504 where rows in the frame matrix start---this must be available to
1505 determine pointers to rows of window sub-matrices. */
1506 pool->nrows = matrix_dim.height;
1507 pool->ncolumns = matrix_dim.width;
1509 return changed_p;
1514 /***********************************************************************
1515 Debug Code
1516 ***********************************************************************/
1518 #if GLYPH_DEBUG
1521 /* Flush standard output. This is sometimes useful to call from
1522 the debugger. */
1524 void
1525 flush_stdout ()
1527 fflush (stdout);
1531 /* Check that no glyph pointers have been lost in MATRIX. If a
1532 pointer has been lost, e.g. by using a structure assignment between
1533 rows, at least one pointer must occur more than once in the rows of
1534 MATRIX. */
1536 void
1537 check_matrix_pointer_lossage (matrix)
1538 struct glyph_matrix *matrix;
1540 int i, j;
1542 for (i = 0; i < matrix->nrows; ++i)
1543 for (j = 0; j < matrix->nrows; ++j)
1544 xassert (i == j
1545 || (matrix->rows[i].glyphs[TEXT_AREA]
1546 != matrix->rows[j].glyphs[TEXT_AREA]));
1550 /* Get a pointer to glyph row ROW in MATRIX, with bounds checks. */
1552 struct glyph_row *
1553 matrix_row (matrix, row)
1554 struct glyph_matrix *matrix;
1555 int row;
1557 xassert (matrix && matrix->rows);
1558 xassert (row >= 0 && row < matrix->nrows);
1560 /* That's really too slow for normal testing because this function
1561 is called almost everywhere. Although---it's still astonishingly
1562 fast, so it is valuable to have for debugging purposes. */
1563 #if 0
1564 check_matrix_pointer_lossage (matrix);
1565 #endif
1567 return matrix->rows + row;
1571 #if 0 /* This function makes invalid assumptions when text is
1572 partially invisible. But it might come handy for debugging
1573 nevertheless. */
1575 /* Check invariants that must hold for an up to date current matrix of
1576 window W. */
1578 static void
1579 check_matrix_invariants (w)
1580 struct window *w;
1582 struct glyph_matrix *matrix = w->current_matrix;
1583 int yb = window_text_bottom_y (w);
1584 struct glyph_row *row = matrix->rows;
1585 struct glyph_row *last_text_row = NULL;
1586 struct buffer *saved = current_buffer;
1587 struct buffer *buffer = XBUFFER (w->buffer);
1588 int c;
1590 /* This can sometimes happen for a fresh window. */
1591 if (matrix->nrows < 2)
1592 return;
1594 set_buffer_temp (buffer);
1596 /* Note: last row is always reserved for the mode line. */
1597 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
1598 && MATRIX_ROW_BOTTOM_Y (row) < yb)
1600 struct glyph_row *next = row + 1;
1602 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
1603 last_text_row = row;
1605 /* Check that character and byte positions are in sync. */
1606 xassert (MATRIX_ROW_START_BYTEPOS (row)
1607 == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
1609 /* CHAR_TO_BYTE aborts when invoked for a position > Z. We can
1610 have such a position temporarily in case of a minibuffer
1611 displaying something like `[Sole completion]' at its end. */
1612 if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
1613 xassert (MATRIX_ROW_END_BYTEPOS (row)
1614 == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
1616 /* Check that end position of `row' is equal to start position
1617 of next row. */
1618 if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next))
1620 xassert (MATRIX_ROW_END_CHARPOS (row)
1621 == MATRIX_ROW_START_CHARPOS (next));
1622 xassert (MATRIX_ROW_END_BYTEPOS (row)
1623 == MATRIX_ROW_START_BYTEPOS (next));
1625 row = next;
1628 xassert (w->current_matrix->nrows == w->desired_matrix->nrows);
1629 xassert (w->desired_matrix->rows != NULL);
1630 set_buffer_temp (saved);
1633 #endif /* 0 */
1635 #endif /* GLYPH_DEBUG != 0 */
1639 /**********************************************************************
1640 Allocating/ Adjusting Glyph Matrices
1641 **********************************************************************/
1643 /* Allocate glyph matrices over a window tree for a frame-based
1644 redisplay
1646 X and Y are column/row within the frame glyph matrix where
1647 sub-matrices for the window tree rooted at WINDOW must be
1648 allocated. CH_DIM contains the dimensions of the smallest
1649 character that could be used during display. DIM_ONLY_P non-zero
1650 means that the caller of this function is only interested in the
1651 result matrix dimension, and matrix adjustments should not be
1652 performed.
1654 The function returns the total width/height of the sub-matrices of
1655 the window tree. If called on a frame root window, the computation
1656 will take the mini-buffer window into account.
1658 *WINDOW_CHANGE_FLAGS is set to a bit mask with bits
1660 NEW_LEAF_MATRIX set if any window in the tree did not have a
1661 glyph matrices yet, and
1663 CHANGED_LEAF_MATRIX set if the dimension or location of a matrix of
1664 any window in the tree will be changed or have been changed (see
1665 DIM_ONLY_P).
1667 *WINDOW_CHANGE_FLAGS must be initialized by the caller of this
1668 function.
1670 Windows are arranged into chains of windows on the same level
1671 through the next fields of window structures. Such a level can be
1672 either a sequence of horizontally adjacent windows from left to
1673 right, or a sequence of vertically adjacent windows from top to
1674 bottom. Each window in a horizontal sequence can be either a leaf
1675 window or a vertical sequence; a window in a vertical sequence can
1676 be either a leaf or a horizontal sequence. All windows in a
1677 horizontal sequence have the same height, and all windows in a
1678 vertical sequence have the same width.
1680 This function uses, for historical reasons, a more general
1681 algorithm to determine glyph matrix dimensions that would be
1682 necessary.
1684 The matrix height of a horizontal sequence is determined by the
1685 maximum height of any matrix in the sequence. The matrix width of
1686 a horizontal sequence is computed by adding up matrix widths of
1687 windows in the sequence.
1689 |<------- result width ------->|
1690 +---------+----------+---------+ ---
1691 | | | | |
1692 | | | |
1693 +---------+ | | result height
1694 | +---------+
1695 | | |
1696 +----------+ ---
1698 The matrix width of a vertical sequence is the maximum matrix width
1699 of any window in the sequence. Its height is computed by adding up
1700 matrix heights of windows in the sequence.
1702 |<---- result width -->|
1703 +---------+ ---
1704 | | |
1705 | | |
1706 +---------+--+ |
1707 | | |
1708 | | result height
1710 +------------+---------+ |
1711 | | |
1712 | | |
1713 +------------+---------+ --- */
1715 /* Bit indicating that a new matrix will be allocated or has been
1716 allocated. */
1718 #define NEW_LEAF_MATRIX (1 << 0)
1720 /* Bit indicating that a matrix will or has changed its location or
1721 size. */
1723 #define CHANGED_LEAF_MATRIX (1 << 1)
1725 static struct dim
1726 allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
1727 dim_only_p, window_change_flags)
1728 Lisp_Object window;
1729 int x, y;
1730 struct dim ch_dim;
1731 int dim_only_p;
1732 int *window_change_flags;
1734 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1735 int x0 = x, y0 = y;
1736 int wmax = 0, hmax = 0;
1737 struct dim total;
1738 struct dim dim;
1739 struct window *w;
1740 int in_horz_combination_p;
1742 /* What combination is WINDOW part of? Compute this once since the
1743 result is the same for all windows in the `next' chain. The
1744 special case of a root window (parent equal to nil) is treated
1745 like a vertical combination because a root window's `next'
1746 points to the mini-buffer window, if any, which is arranged
1747 vertically below other windows. */
1748 in_horz_combination_p
1749 = (!NILP (XWINDOW (window)->parent)
1750 && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
1752 /* For WINDOW and all windows on the same level. */
1755 w = XWINDOW (window);
1757 /* Get the dimension of the window sub-matrix for W, depending
1758 on whether this a combination or a leaf window. */
1759 if (!NILP (w->hchild))
1760 dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y, ch_dim,
1761 dim_only_p,
1762 window_change_flags);
1763 else if (!NILP (w->vchild))
1764 dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y, ch_dim,
1765 dim_only_p,
1766 window_change_flags);
1767 else
1769 /* If not already done, allocate sub-matrix structures. */
1770 if (w->desired_matrix == NULL)
1772 w->desired_matrix = new_glyph_matrix (f->desired_pool);
1773 w->current_matrix = new_glyph_matrix (f->current_pool);
1774 *window_change_flags |= NEW_LEAF_MATRIX;
1777 /* Width and height MUST be chosen so that there are no
1778 holes in the frame matrix. */
1779 dim.width = XINT (w->width);
1780 dim.height = XINT (w->height);
1782 /* Will matrix be re-allocated? */
1783 if (x != w->desired_matrix->matrix_x
1784 || y != w->desired_matrix->matrix_y
1785 || dim.width != w->desired_matrix->matrix_w
1786 || dim.height != w->desired_matrix->matrix_h
1787 || (margin_glyphs_to_reserve (w, dim.width,
1788 w->right_margin_width)
1789 != w->desired_matrix->left_margin_glyphs)
1790 || (margin_glyphs_to_reserve (w, dim.width,
1791 w->left_margin_width)
1792 != w->desired_matrix->right_margin_glyphs))
1793 *window_change_flags |= CHANGED_LEAF_MATRIX;
1795 /* Actually change matrices, if allowed. Do not consider
1796 CHANGED_LEAF_MATRIX computed above here because the pool
1797 may have been changed which we don't now here. We trust
1798 that we only will be called with DIM_ONLY_P != 0 when
1799 necessary. */
1800 if (!dim_only_p)
1802 adjust_glyph_matrix (w, w->desired_matrix, x, y, dim);
1803 adjust_glyph_matrix (w, w->current_matrix, x, y, dim);
1807 /* If we are part of a horizontal combination, advance x for
1808 windows to the right of W; otherwise advance y for windows
1809 below W. */
1810 if (in_horz_combination_p)
1811 x += dim.width;
1812 else
1813 y += dim.height;
1815 /* Remember maximum glyph matrix dimensions. */
1816 wmax = max (wmax, dim.width);
1817 hmax = max (hmax, dim.height);
1819 /* Next window on same level. */
1820 window = w->next;
1822 while (!NILP (window));
1824 /* Set `total' to the total glyph matrix dimension of this window
1825 level. In a vertical combination, the width is the width of the
1826 widest window; the height is the y we finally reached, corrected
1827 by the y we started with. In a horizontal combination, the total
1828 height is the height of the tallest window, and the width is the
1829 x we finally reached, corrected by the x we started with. */
1830 if (in_horz_combination_p)
1832 total.width = x - x0;
1833 total.height = hmax;
1835 else
1837 total.width = wmax;
1838 total.height = y - y0;
1841 return total;
1845 /* Allocate window matrices for window-based redisplay. W is the
1846 window whose matrices must be allocated/reallocated. CH_DIM is the
1847 size of the smallest character that could potentially be used on W. */
1849 static void
1850 allocate_matrices_for_window_redisplay (w, ch_dim)
1851 struct window *w;
1852 struct dim ch_dim;
1854 struct frame *f = XFRAME (w->frame);
1856 while (w)
1858 if (!NILP (w->vchild))
1859 allocate_matrices_for_window_redisplay (XWINDOW (w->vchild), ch_dim);
1860 else if (!NILP (w->hchild))
1861 allocate_matrices_for_window_redisplay (XWINDOW (w->hchild), ch_dim);
1862 else
1864 /* W is a leaf window. */
1865 int window_pixel_width = XFLOATINT (w->width) * CANON_X_UNIT (f);
1866 int window_pixel_height = window_box_height (w) + abs (w->vscroll);
1867 struct dim dim;
1869 /* If matrices are not yet allocated, allocate them now. */
1870 if (w->desired_matrix == NULL)
1872 w->desired_matrix = new_glyph_matrix (NULL);
1873 w->current_matrix = new_glyph_matrix (NULL);
1876 /* Compute number of glyphs needed in a glyph row. */
1877 dim.width = (((window_pixel_width + ch_dim.width - 1)
1878 / ch_dim.width)
1879 /* 2 partially visible columns in the text area. */
1881 /* One partially visible column at the right
1882 edge of each marginal area. */
1883 + 1 + 1);
1885 /* Compute number of glyph rows needed. */
1886 dim.height = (((window_pixel_height + ch_dim.height - 1)
1887 / ch_dim.height)
1888 /* One partially visible line at the top and
1889 bottom of the window. */
1891 /* 2 for top and mode line. */
1892 + 2);
1894 /* Change matrices. */
1895 adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
1896 adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
1899 w = NILP (w->next) ? NULL : XWINDOW (w->next);
1904 /* Re-allocate/ re-compute glyph matrices on frame F. If F is null,
1905 do it for all frames; otherwise do it just for the given frame.
1906 This function must be called when a new frame is created, its size
1907 changes, or its window configuration changes. */
1909 void
1910 adjust_glyphs (f)
1911 struct frame *f;
1913 /* Block input so that expose events and other events that access
1914 glyph matrices are not processed while we are changing them. */
1915 BLOCK_INPUT;
1917 if (f)
1918 adjust_frame_glyphs (f);
1919 else
1921 Lisp_Object tail, lisp_frame;
1923 FOR_EACH_FRAME (tail, lisp_frame)
1924 adjust_frame_glyphs (XFRAME (lisp_frame));
1927 UNBLOCK_INPUT;
1931 /* Adjust frame glyphs when Emacs is initialized.
1933 To be called from init_display.
1935 We need a glyph matrix because redraw will happen soon.
1936 Unfortunately, window sizes on selected_frame are not yet set to
1937 meaningful values. I believe we can assume that there are only two
1938 windows on the frame---the mini-buffer and the root window. Frame
1939 height and width seem to be correct so far. So, set the sizes of
1940 windows to estimated values. */
1942 static void
1943 adjust_frame_glyphs_initially ()
1945 struct frame *sf = SELECTED_FRAME ();
1946 struct window *root = XWINDOW (sf->root_window);
1947 struct window *mini = XWINDOW (root->next);
1948 int frame_height = FRAME_HEIGHT (sf);
1949 int frame_width = FRAME_WIDTH (sf);
1950 int top_margin = FRAME_TOP_MARGIN (sf);
1952 /* Do it for the root window. */
1953 XSETFASTINT (root->top, top_margin);
1954 XSETFASTINT (root->width, frame_width);
1955 set_window_height (sf->root_window, frame_height - 1 - top_margin, 0);
1957 /* Do it for the mini-buffer window. */
1958 XSETFASTINT (mini->top, frame_height - 1);
1959 XSETFASTINT (mini->width, frame_width);
1960 set_window_height (root->next, 1, 0);
1962 adjust_frame_glyphs (sf);
1963 glyphs_initialized_initially_p = 1;
1967 /* Allocate/reallocate glyph matrices of a single frame F. */
1969 static void
1970 adjust_frame_glyphs (f)
1971 struct frame *f;
1973 if (FRAME_WINDOW_P (f))
1974 adjust_frame_glyphs_for_window_redisplay (f);
1975 else
1976 adjust_frame_glyphs_for_frame_redisplay (f);
1978 /* Don't forget the message buffer and the buffer for
1979 decode_mode_spec. */
1980 adjust_frame_message_buffer (f);
1981 adjust_decode_mode_spec_buffer (f);
1983 f->glyphs_initialized_p = 1;
1987 /* Allocate/reallocate glyph matrices of a single frame F for
1988 frame-based redisplay. */
1990 static void
1991 adjust_frame_glyphs_for_frame_redisplay (f)
1992 struct frame *f;
1994 struct dim ch_dim;
1995 struct dim matrix_dim;
1996 int pool_changed_p;
1997 int window_change_flags;
1998 int top_window_y;
2000 if (!FRAME_LIVE_P (f))
2001 return;
2003 /* Determine the smallest character in any font for F. On
2004 console windows, all characters have dimension (1, 1). */
2005 ch_dim.width = ch_dim.height = 1;
2007 top_window_y = FRAME_TOP_MARGIN (f);
2009 /* Allocate glyph pool structures if not already done. */
2010 if (f->desired_pool == NULL)
2012 f->desired_pool = new_glyph_pool ();
2013 f->current_pool = new_glyph_pool ();
2016 /* Allocate frames matrix structures if needed. */
2017 if (f->desired_matrix == NULL)
2019 f->desired_matrix = new_glyph_matrix (f->desired_pool);
2020 f->current_matrix = new_glyph_matrix (f->current_pool);
2023 /* Compute window glyph matrices. (This takes the mini-buffer
2024 window into account). The result is the size of the frame glyph
2025 matrix needed. The variable window_change_flags is set to a bit
2026 mask indicating whether new matrices will be allocated or
2027 existing matrices change their size or location within the frame
2028 matrix. */
2029 window_change_flags = 0;
2030 matrix_dim
2031 = allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2032 0, top_window_y,
2033 ch_dim, 1,
2034 &window_change_flags);
2036 /* Add in menu bar lines, if any. */
2037 matrix_dim.height += top_window_y;
2039 /* Enlarge pools as necessary. */
2040 pool_changed_p = realloc_glyph_pool (f->desired_pool, matrix_dim);
2041 realloc_glyph_pool (f->current_pool, matrix_dim);
2043 /* Set up glyph pointers within window matrices. Do this only if
2044 absolutely necessary since it requires a frame redraw. */
2045 if (pool_changed_p || window_change_flags)
2047 /* Do it for window matrices. */
2048 allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2049 0, top_window_y, ch_dim, 0,
2050 &window_change_flags);
2052 /* Size of frame matrices must equal size of frame. Note
2053 that we are called for X frames with window widths NOT equal
2054 to the frame width (from CHANGE_FRAME_SIZE_1). */
2055 xassert (matrix_dim.width == FRAME_WIDTH (f)
2056 && matrix_dim.height == FRAME_HEIGHT (f));
2058 /* Resize frame matrices. */
2059 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2060 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2062 /* Since location and size of sub-matrices within the pool may
2063 have changed, and current matrices don't have meaningful
2064 contents anymore, mark the frame garbaged. */
2065 SET_FRAME_GARBAGED (f);
2070 /* Allocate/reallocate glyph matrices of a single frame F for
2071 window-based redisplay. */
2073 static void
2074 adjust_frame_glyphs_for_window_redisplay (f)
2075 struct frame *f;
2077 struct dim ch_dim;
2078 struct window *w;
2080 xassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
2082 /* Get minimum sizes. */
2083 #ifdef HAVE_WINDOW_SYSTEM
2084 ch_dim.width = FRAME_SMALLEST_CHAR_WIDTH (f);
2085 ch_dim.height = FRAME_SMALLEST_FONT_HEIGHT (f);
2086 #else
2087 ch_dim.width = ch_dim.height = 1;
2088 #endif
2090 /* Allocate/reallocate window matrices. */
2091 allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)),
2092 ch_dim);
2094 /* Allocate/ reallocate matrices of the dummy window used to display
2095 the menu bar under X when no X toolkit support is available. */
2096 #ifndef USE_X_TOOLKIT
2098 /* Allocate a dummy window if not already done. */
2099 if (NILP (f->menu_bar_window))
2101 f->menu_bar_window = make_window ();
2102 w = XWINDOW (f->menu_bar_window);
2103 XSETFRAME (w->frame, f);
2104 w->pseudo_window_p = 1;
2106 else
2107 w = XWINDOW (f->menu_bar_window);
2109 /* Set window dimensions to frame dimensions and allocate or
2110 adjust glyph matrices of W. */
2111 XSETFASTINT (w->top, 0);
2112 XSETFASTINT (w->left, 0);
2113 XSETFASTINT (w->height, FRAME_MENU_BAR_LINES (f));
2114 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
2115 allocate_matrices_for_window_redisplay (w, ch_dim);
2117 #endif /* not USE_X_TOOLKIT */
2119 /* Allocate/ reallocate matrices of the tool bar window. If we
2120 don't have a tool bar window yet, make one. */
2121 if (NILP (f->tool_bar_window))
2123 f->tool_bar_window = make_window ();
2124 w = XWINDOW (f->tool_bar_window);
2125 XSETFRAME (w->frame, f);
2126 w->pseudo_window_p = 1;
2128 else
2129 w = XWINDOW (f->tool_bar_window);
2131 XSETFASTINT (w->top, FRAME_MENU_BAR_LINES (f));
2132 XSETFASTINT (w->left, 0);
2133 XSETFASTINT (w->height, FRAME_TOOL_BAR_LINES (f));
2134 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
2135 allocate_matrices_for_window_redisplay (w, ch_dim);
2139 /* Adjust/ allocate message buffer of frame F.
2141 Note that the message buffer is never freed. Since I could not
2142 find a free in 19.34, I assume that freeing it would be
2143 problematic in some way and don't do it either.
2145 (Implementation note: It should be checked if we can free it
2146 eventually without causing trouble). */
2148 static void
2149 adjust_frame_message_buffer (f)
2150 struct frame *f;
2152 int size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
2154 if (FRAME_MESSAGE_BUF (f))
2156 char *buffer = FRAME_MESSAGE_BUF (f);
2157 char *new_buffer = (char *) xrealloc (buffer, size);
2158 FRAME_MESSAGE_BUF (f) = new_buffer;
2160 else
2161 FRAME_MESSAGE_BUF (f) = (char *) xmalloc (size);
2165 /* Re-allocate buffer for decode_mode_spec on frame F. */
2167 static void
2168 adjust_decode_mode_spec_buffer (f)
2169 struct frame *f;
2171 f->decode_mode_spec_buffer
2172 = (char *) xrealloc (f->decode_mode_spec_buffer,
2173 FRAME_MESSAGE_BUF_SIZE (f) + 1);
2178 /**********************************************************************
2179 Freeing Glyph Matrices
2180 **********************************************************************/
2182 /* Free glyph memory for a frame F. F may be null. This function can
2183 be called for the same frame more than once. The root window of
2184 F may be nil when this function is called. This is the case when
2185 the function is called when F is destroyed. */
2187 void
2188 free_glyphs (f)
2189 struct frame *f;
2191 if (f && f->glyphs_initialized_p)
2193 /* Block interrupt input so that we don't get surprised by an X
2194 event while we're in an inconsistent state. */
2195 BLOCK_INPUT;
2196 f->glyphs_initialized_p = 0;
2198 /* Release window sub-matrices. */
2199 if (!NILP (f->root_window))
2200 free_window_matrices (XWINDOW (f->root_window));
2202 /* Free the dummy window for menu bars without X toolkit and its
2203 glyph matrices. */
2204 if (!NILP (f->menu_bar_window))
2206 struct window *w = XWINDOW (f->menu_bar_window);
2207 free_glyph_matrix (w->desired_matrix);
2208 free_glyph_matrix (w->current_matrix);
2209 w->desired_matrix = w->current_matrix = NULL;
2210 f->menu_bar_window = Qnil;
2213 /* Free the tool bar window and its glyph matrices. */
2214 if (!NILP (f->tool_bar_window))
2216 struct window *w = XWINDOW (f->tool_bar_window);
2217 free_glyph_matrix (w->desired_matrix);
2218 free_glyph_matrix (w->current_matrix);
2219 w->desired_matrix = w->current_matrix = NULL;
2220 f->tool_bar_window = Qnil;
2223 /* Release frame glyph matrices. Reset fields to zero in
2224 case we are called a second time. */
2225 if (f->desired_matrix)
2227 free_glyph_matrix (f->desired_matrix);
2228 free_glyph_matrix (f->current_matrix);
2229 f->desired_matrix = f->current_matrix = NULL;
2232 /* Release glyph pools. */
2233 if (f->desired_pool)
2235 free_glyph_pool (f->desired_pool);
2236 free_glyph_pool (f->current_pool);
2237 f->desired_pool = f->current_pool = NULL;
2240 UNBLOCK_INPUT;
2245 /* Free glyph sub-matrices in the window tree rooted at W. This
2246 function may be called with a null pointer, and it may be called on
2247 the same tree more than once. */
2249 void
2250 free_window_matrices (w)
2251 struct window *w;
2253 while (w)
2255 if (!NILP (w->hchild))
2256 free_window_matrices (XWINDOW (w->hchild));
2257 else if (!NILP (w->vchild))
2258 free_window_matrices (XWINDOW (w->vchild));
2259 else
2261 /* This is a leaf window. Free its memory and reset fields
2262 to zero in case this function is called a second time for
2263 W. */
2264 free_glyph_matrix (w->current_matrix);
2265 free_glyph_matrix (w->desired_matrix);
2266 w->current_matrix = w->desired_matrix = NULL;
2269 /* Next window on same level. */
2270 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2275 /* Check glyph memory leaks. This function is called from
2276 shut_down_emacs. Note that frames are not destroyed when Emacs
2277 exits. We therefore free all glyph memory for all active frames
2278 explicitly and check that nothing is left allocated. */
2280 void
2281 check_glyph_memory ()
2283 Lisp_Object tail, frame;
2285 /* Free glyph memory for all frames. */
2286 FOR_EACH_FRAME (tail, frame)
2287 free_glyphs (XFRAME (frame));
2289 /* Check that nothing is left allocated. */
2290 if (glyph_matrix_count)
2291 abort ();
2292 if (glyph_pool_count)
2293 abort ();
2298 /**********************************************************************
2299 Building a Frame Matrix
2300 **********************************************************************/
2302 /* Most of the redisplay code works on glyph matrices attached to
2303 windows. This is a good solution most of the time, but it is not
2304 suitable for terminal code. Terminal output functions cannot rely
2305 on being able to set an arbitrary terminal window. Instead they
2306 must be provided with a view of the whole frame, i.e. the whole
2307 screen. We build such a view by constructing a frame matrix from
2308 window matrices in this section.
2310 Windows that must be updated have their must_be_update_p flag set.
2311 For all such windows, their desired matrix is made part of the
2312 desired frame matrix. For other windows, their current matrix is
2313 made part of the desired frame matrix.
2315 +-----------------+----------------+
2316 | desired | desired |
2317 | | |
2318 +-----------------+----------------+
2319 | current |
2321 +----------------------------------+
2323 Desired window matrices can be made part of the frame matrix in a
2324 cheap way: We exploit the fact that the desired frame matrix and
2325 desired window matrices share their glyph memory. This is not
2326 possible for current window matrices. Their glyphs are copied to
2327 the desired frame matrix. The latter is equivalent to
2328 preserve_other_columns in the old redisplay.
2330 Used glyphs counters for frame matrix rows are the result of adding
2331 up glyph lengths of the window matrices. A line in the frame
2332 matrix is enabled, if a corresponding line in a window matrix is
2333 enabled.
2335 After building the desired frame matrix, it will be passed to
2336 terminal code, which will manipulate both the desired and current
2337 frame matrix. Changes applied to the frame's current matrix have
2338 to be visible in current window matrices afterwards, of course.
2340 This problem is solved like this:
2342 1. Window and frame matrices share glyphs. Window matrices are
2343 constructed in a way that their glyph contents ARE the glyph
2344 contents needed in a frame matrix. Thus, any modification of
2345 glyphs done in terminal code will be reflected in window matrices
2346 automatically.
2348 2. Exchanges of rows in a frame matrix done by terminal code are
2349 intercepted by hook functions so that corresponding row operations
2350 on window matrices can be performed. This is necessary because we
2351 use pointers to glyphs in glyph row structures. To satisfy the
2352 assumption of point 1 above that glyphs are updated implicitly in
2353 window matrices when they are manipulated via the frame matrix,
2354 window and frame matrix must of course agree where to find the
2355 glyphs for their rows. Possible manipulations that must be
2356 mirrored are assignments of rows of the desired frame matrix to the
2357 current frame matrix and scrolling the current frame matrix. */
2359 /* Build frame F's desired matrix from window matrices. Only windows
2360 which have the flag must_be_updated_p set have to be updated. Menu
2361 bar lines of a frame are not covered by window matrices, so make
2362 sure not to touch them in this function. */
2364 static void
2365 build_frame_matrix (f)
2366 struct frame *f;
2368 int i;
2370 /* F must have a frame matrix when this function is called. */
2371 xassert (!FRAME_WINDOW_P (f));
2373 /* Clear all rows in the frame matrix covered by window matrices.
2374 Menu bar lines are not covered by windows. */
2375 for (i = FRAME_TOP_MARGIN (f); i < f->desired_matrix->nrows; ++i)
2376 clear_glyph_row (MATRIX_ROW (f->desired_matrix, i));
2378 /* Build the matrix by walking the window tree. */
2379 build_frame_matrix_from_window_tree (f->desired_matrix,
2380 XWINDOW (FRAME_ROOT_WINDOW (f)));
2384 /* Walk a window tree, building a frame matrix MATRIX from window
2385 matrices. W is the root of a window tree. */
2387 static void
2388 build_frame_matrix_from_window_tree (matrix, w)
2389 struct glyph_matrix *matrix;
2390 struct window *w;
2392 while (w)
2394 if (!NILP (w->hchild))
2395 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->hchild));
2396 else if (!NILP (w->vchild))
2397 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->vchild));
2398 else
2399 build_frame_matrix_from_leaf_window (matrix, w);
2401 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2406 /* Add a window's matrix to a frame matrix. FRAME_MATRIX is the
2407 desired frame matrix built. W is a leaf window whose desired or
2408 current matrix is to be added to FRAME_MATRIX. W's flag
2409 must_be_updated_p determines which matrix it contributes to
2410 FRAME_MATRIX. If must_be_updated_p is non-zero, W's desired matrix
2411 is added to FRAME_MATRIX, otherwise W's current matrix is added.
2412 Adding a desired matrix means setting up used counters and such in
2413 frame rows, while adding a current window matrix to FRAME_MATRIX
2414 means copying glyphs. The latter case corresponds to
2415 preserve_other_columns in the old redisplay. */
2417 static void
2418 build_frame_matrix_from_leaf_window (frame_matrix, w)
2419 struct glyph_matrix *frame_matrix;
2420 struct window *w;
2422 struct glyph_matrix *window_matrix;
2423 int window_y, frame_y;
2424 /* If non-zero, a glyph to insert at the right border of W. */
2425 GLYPH right_border_glyph = 0;
2427 /* Set window_matrix to the matrix we have to add to FRAME_MATRIX. */
2428 if (w->must_be_updated_p)
2430 window_matrix = w->desired_matrix;
2432 /* Decide whether we want to add a vertical border glyph. */
2433 if (!WINDOW_RIGHTMOST_P (w))
2435 struct Lisp_Char_Table *dp = window_display_table (w);
2436 right_border_glyph = (dp && INTEGERP (DISP_BORDER_GLYPH (dp))
2437 ? XINT (DISP_BORDER_GLYPH (dp))
2438 : '|');
2441 else
2442 window_matrix = w->current_matrix;
2444 /* For all rows in the window matrix and corresponding rows in the
2445 frame matrix. */
2446 window_y = 0;
2447 frame_y = window_matrix->matrix_y;
2448 while (window_y < window_matrix->nrows)
2450 struct glyph_row *frame_row = frame_matrix->rows + frame_y;
2451 struct glyph_row *window_row = window_matrix->rows + window_y;
2453 /* Fill up the frame row with spaces up to the left margin of the
2454 window row. */
2455 fill_up_frame_row_with_spaces (frame_row, window_matrix->matrix_x);
2457 /* Fill up areas in the window matrix row with spaces. */
2458 fill_up_glyph_row_with_spaces (window_row);
2460 if (window_matrix == w->current_matrix)
2462 /* We have to copy W's current matrix. Copy window
2463 row to frame row. */
2464 bcopy (window_row->glyphs[0],
2465 frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
2466 window_matrix->matrix_w * sizeof (struct glyph));
2468 else
2470 /* Copy W's desired matrix. */
2472 /* Maybe insert a vertical border between horizontally adjacent
2473 windows. */
2474 if (right_border_glyph)
2476 struct glyph *border = window_row->glyphs[LAST_AREA] - 1;
2477 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
2480 #if 0 /* This shouldn't be necessary. Let's check it. */
2481 /* Due to hooks installed, it normally doesn't happen that
2482 window rows and frame rows of the same matrix are out of
2483 sync, i.e. have a different understanding of where to
2484 find glyphs for the row. The following is a safety-belt
2485 that doesn't cost much and makes absolutely sure that
2486 window and frame matrices are in sync. */
2487 if (!glyph_row_slice_p (window_row, frame_row))
2489 /* Find the row in the window being a slice. There
2490 should exist one from program logic. */
2491 struct glyph_row *slice_row
2492 = find_glyph_row_slice (window_matrix, frame_matrix, frame_y);
2493 xassert (slice_row != 0);
2495 /* Exchange glyphs between both window rows. */
2496 swap_glyphs_in_rows (window_row, slice_row);
2498 /* Exchange pointers between both rows. */
2499 swap_glyph_pointers (window_row, slice_row);
2501 #endif
2503 /* Window row window_y must be a slice of frame row
2504 frame_y. */
2505 xassert (glyph_row_slice_p (window_row, frame_row));
2507 /* If rows are in sync, we don't have to copy glyphs because
2508 frame and window share glyphs. */
2510 #if GLYPH_DEBUG
2511 strcpy (w->current_matrix->method, w->desired_matrix->method);
2512 #endif
2515 /* Set number of used glyphs in the frame matrix. Since we fill
2516 up with spaces, and visit leaf windows from left to right it
2517 can be done simply. */
2518 frame_row->used[TEXT_AREA]
2519 = window_matrix->matrix_x + window_matrix->matrix_w;
2521 /* Or in flags. */
2522 frame_row->enabled_p |= window_row->enabled_p;
2523 frame_row->inverse_p |= window_row->inverse_p;
2525 /* Next row. */
2526 ++window_y;
2527 ++frame_y;
2532 /* Add spaces to a glyph row ROW in a window matrix.
2534 Each row has the form:
2536 +---------+-----------------------------+------------+
2537 | left | text | right |
2538 +---------+-----------------------------+------------+
2540 Left and right marginal areas are optional. This function adds
2541 spaces to areas so that there are no empty holes between areas.
2542 In other words: If the right area is not empty, the text area
2543 is filled up with spaces up to the right area. If the text area
2544 is not empty, the left area is filled up.
2546 To be called for frame-based redisplay, only. */
2548 static void
2549 fill_up_glyph_row_with_spaces (row)
2550 struct glyph_row *row;
2552 fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA);
2553 fill_up_glyph_row_area_with_spaces (row, TEXT_AREA);
2554 fill_up_glyph_row_area_with_spaces (row, RIGHT_MARGIN_AREA);
2558 /* Fill area AREA of glyph row ROW with spaces. To be called for
2559 frame-based redisplay only. */
2561 static void
2562 fill_up_glyph_row_area_with_spaces (row, area)
2563 struct glyph_row *row;
2564 int area;
2566 if (row->glyphs[area] < row->glyphs[area + 1])
2568 struct glyph *end = row->glyphs[area + 1];
2569 struct glyph *text = row->glyphs[area] + row->used[area];
2571 while (text < end)
2572 *text++ = space_glyph;
2573 row->used[area] = text - row->glyphs[area];
2578 /* Add spaces to the end of ROW in a frame matrix until index UPTO is
2579 reached. In frame matrices only one area, TEXT_AREA, is used. */
2581 static void
2582 fill_up_frame_row_with_spaces (row, upto)
2583 struct glyph_row *row;
2584 int upto;
2586 int i = row->used[TEXT_AREA];
2587 struct glyph *glyph = row->glyphs[TEXT_AREA];
2589 while (i < upto)
2590 glyph[i++] = space_glyph;
2592 row->used[TEXT_AREA] = i;
2597 /**********************************************************************
2598 Mirroring operations on frame matrices in window matrices
2599 **********************************************************************/
2601 /* Set frame being updated via frame-based redisplay to F. This
2602 function must be called before updates to make explicit that we are
2603 working on frame matrices or not. */
2605 static INLINE void
2606 set_frame_matrix_frame (f)
2607 struct frame *f;
2609 frame_matrix_frame = f;
2613 /* Make sure glyph row ROW in CURRENT_MATRIX is up to date.
2614 DESIRED_MATRIX is the desired matrix corresponding to
2615 CURRENT_MATRIX. The update is done by exchanging glyph pointers
2616 between rows in CURRENT_MATRIX and DESIRED_MATRIX. If
2617 frame_matrix_frame is non-null, this indicates that the exchange is
2618 done in frame matrices, and that we have to perform analogous
2619 operations in window matrices of frame_matrix_frame. */
2621 static INLINE void
2622 make_current (desired_matrix, current_matrix, row)
2623 struct glyph_matrix *desired_matrix, *current_matrix;
2624 int row;
2626 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2627 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
2628 int mouse_face_p = current_row->mouse_face_p;
2630 /* Do current_row = desired_row. This exchanges glyph pointers
2631 between both rows, and does a structure assignment otherwise. */
2632 assign_row (current_row, desired_row);
2634 /* Enable current_row to mark it as valid. */
2635 current_row->enabled_p = 1;
2636 current_row->mouse_face_p = mouse_face_p;
2638 /* If we are called on frame matrices, perform analogous operations
2639 for window matrices. */
2640 if (frame_matrix_frame)
2641 mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row);
2645 /* W is the root of a window tree. FRAME_ROW is the index of a row in
2646 W's frame which has been made current (by swapping pointers between
2647 current and desired matrix). Perform analogous operations in the
2648 matrices of leaf windows in the window tree rooted at W. */
2650 static void
2651 mirror_make_current (w, frame_row)
2652 struct window *w;
2653 int frame_row;
2655 while (w)
2657 if (!NILP (w->hchild))
2658 mirror_make_current (XWINDOW (w->hchild), frame_row);
2659 else if (!NILP (w->vchild))
2660 mirror_make_current (XWINDOW (w->vchild), frame_row);
2661 else
2663 /* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS
2664 here because the checks performed in debug mode there
2665 will not allow the conversion. */
2666 int row = frame_row - w->desired_matrix->matrix_y;
2668 /* If FRAME_ROW is within W, assign the desired row to the
2669 current row (exchanging glyph pointers). */
2670 if (row >= 0 && row < w->desired_matrix->matrix_h)
2672 struct glyph_row *current_row
2673 = MATRIX_ROW (w->current_matrix, row);
2674 struct glyph_row *desired_row
2675 = MATRIX_ROW (w->desired_matrix, row);
2677 if (desired_row->enabled_p)
2678 assign_row (current_row, desired_row);
2679 else
2680 swap_glyph_pointers (desired_row, current_row);
2681 current_row->enabled_p = 1;
2685 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2690 /* Perform row dance after scrolling. We are working on the range of
2691 lines UNCHANGED_AT_TOP + 1 to UNCHANGED_AT_TOP + NLINES (not
2692 including) in MATRIX. COPY_FROM is a vector containing, for each
2693 row I in the range 0 <= I < NLINES, the index of the original line
2694 to move to I. This index is relative to the row range, i.e. 0 <=
2695 index < NLINES. RETAINED_P is a vector containing zero for each
2696 row 0 <= I < NLINES which is empty.
2698 This function is called from do_scrolling and do_direct_scrolling. */
2700 void
2701 mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
2702 retained_p)
2703 struct glyph_matrix *matrix;
2704 int unchanged_at_top, nlines;
2705 int *copy_from;
2706 char *retained_p;
2708 /* A copy of original rows. */
2709 struct glyph_row *old_rows;
2711 /* Rows to assign to. */
2712 struct glyph_row *new_rows = MATRIX_ROW (matrix, unchanged_at_top);
2714 int i;
2716 /* Make a copy of the original rows. */
2717 old_rows = (struct glyph_row *) alloca (nlines * sizeof *old_rows);
2718 bcopy (new_rows, old_rows, nlines * sizeof *old_rows);
2720 /* Assign new rows, maybe clear lines. */
2721 for (i = 0; i < nlines; ++i)
2723 int enabled_before_p = new_rows[i].enabled_p;
2725 xassert (i + unchanged_at_top < matrix->nrows);
2726 xassert (unchanged_at_top + copy_from[i] < matrix->nrows);
2727 new_rows[i] = old_rows[copy_from[i]];
2728 new_rows[i].enabled_p = enabled_before_p;
2730 /* RETAINED_P is zero for empty lines. */
2731 if (!retained_p[copy_from[i]])
2732 new_rows[i].enabled_p = 0;
2735 /* Do the same for window matrices, if MATRIX Is a frame matrix. */
2736 if (frame_matrix_frame)
2737 mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
2738 unchanged_at_top, nlines, copy_from, retained_p);
2742 /* Synchronize glyph pointers in the current matrix of window W with
2743 the current frame matrix. W must be full-width, and be on a tty
2744 frame. */
2746 static void
2747 sync_window_with_frame_matrix_rows (w)
2748 struct window *w;
2750 struct frame *f = XFRAME (w->frame);
2751 struct glyph_row *window_row, *window_row_end, *frame_row;
2753 /* Preconditions: W must be a leaf window and full-width. Its frame
2754 must have a frame matrix. */
2755 xassert (NILP (w->hchild) && NILP (w->vchild));
2756 xassert (WINDOW_FULL_WIDTH_P (w));
2757 xassert (!FRAME_WINDOW_P (f));
2759 /* If W is a full-width window, glyph pointers in W's current matrix
2760 have, by definition, to be the same as glyph pointers in the
2761 corresponding frame matrix. */
2762 window_row = w->current_matrix->rows;
2763 window_row_end = window_row + w->current_matrix->nrows;
2764 frame_row = f->current_matrix->rows + XFASTINT (w->top);
2765 while (window_row < window_row_end)
2767 int area;
2769 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
2770 window_row->glyphs[area] = frame_row->glyphs[area];
2772 ++window_row, ++frame_row;
2777 /* Return the window in the window tree rooted in W containing frame
2778 row ROW. Value is null if none is found. */
2780 struct window *
2781 frame_row_to_window (w, row)
2782 struct window *w;
2783 int row;
2785 struct window *found = NULL;
2787 while (w && !found)
2789 if (!NILP (w->hchild))
2790 found = frame_row_to_window (XWINDOW (w->hchild), row);
2791 else if (!NILP (w->vchild))
2792 found = frame_row_to_window (XWINDOW (w->vchild), row);
2793 else if (row >= XFASTINT (w->top)
2794 && row < XFASTINT (w->top) + XFASTINT (w->height))
2795 found = w;
2797 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2800 return found;
2804 /* Perform a line dance in the window tree rooted at W, after
2805 scrolling a frame matrix in mirrored_line_dance.
2807 We are working on the range of lines UNCHANGED_AT_TOP + 1 to
2808 UNCHANGED_AT_TOP + NLINES (not including) in W's frame matrix.
2809 COPY_FROM is a vector containing, for each row I in the range 0 <=
2810 I < NLINES, the index of the original line to move to I. This
2811 index is relative to the row range, i.e. 0 <= index < NLINES.
2812 RETAINED_P is a vector containing zero for each row 0 <= I < NLINES
2813 which is empty. */
2815 static void
2816 mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
2817 struct window *w;
2818 int unchanged_at_top, nlines;
2819 int *copy_from;
2820 char *retained_p;
2822 while (w)
2824 if (!NILP (w->hchild))
2825 mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top,
2826 nlines, copy_from, retained_p);
2827 else if (!NILP (w->vchild))
2828 mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
2829 nlines, copy_from, retained_p);
2830 else
2832 /* W is a leaf window, and we are working on its current
2833 matrix m. */
2834 struct glyph_matrix *m = w->current_matrix;
2835 int i, sync_p = 0;
2836 struct glyph_row *old_rows;
2838 /* Make a copy of the original rows of matrix m. */
2839 old_rows = (struct glyph_row *) alloca (m->nrows * sizeof *old_rows);
2840 bcopy (m->rows, old_rows, m->nrows * sizeof *old_rows);
2842 for (i = 0; i < nlines; ++i)
2844 /* Frame relative line assigned to. */
2845 int frame_to = i + unchanged_at_top;
2847 /* Frame relative line assigned. */
2848 int frame_from = copy_from[i] + unchanged_at_top;
2850 /* Window relative line assigned to. */
2851 int window_to = frame_to - m->matrix_y;
2853 /* Window relative line assigned. */
2854 int window_from = frame_from - m->matrix_y;
2856 /* Is assigned line inside window? */
2857 int from_inside_window_p
2858 = window_from >= 0 && window_from < m->matrix_h;
2860 /* Is assigned to line inside window? */
2861 int to_inside_window_p
2862 = window_to >= 0 && window_to < m->matrix_h;
2864 if (from_inside_window_p && to_inside_window_p)
2866 /* Enabled setting before assignment. */
2867 int enabled_before_p;
2869 /* Do the assignment. The enabled_p flag is saved
2870 over the assignment because the old redisplay did
2871 that. */
2872 enabled_before_p = m->rows[window_to].enabled_p;
2873 m->rows[window_to] = old_rows[window_from];
2874 m->rows[window_to].enabled_p = enabled_before_p;
2876 /* If frame line is empty, window line is empty, too. */
2877 if (!retained_p[copy_from[i]])
2878 m->rows[window_to].enabled_p = 0;
2880 else if (to_inside_window_p)
2882 /* A copy between windows. This is an infrequent
2883 case not worth optimizing. */
2884 struct frame *f = XFRAME (w->frame);
2885 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
2886 struct window *w2;
2887 struct glyph_matrix *m2;
2888 int m2_from;
2890 w2 = frame_row_to_window (root, frame_to);
2891 m2 = w2->current_matrix;
2892 m2_from = frame_from - m2->matrix_y;
2893 copy_row_except_pointers (m->rows + window_to,
2894 m2->rows + m2_from);
2896 /* If frame line is empty, window line is empty, too. */
2897 if (!retained_p[copy_from[i]])
2898 m->rows[window_to].enabled_p = 0;
2899 sync_p = 1;
2901 else if (from_inside_window_p)
2902 sync_p = 1;
2905 /* If there was a copy between windows, make sure glyph
2906 pointers are in sync with the frame matrix. */
2907 if (sync_p)
2908 sync_window_with_frame_matrix_rows (w);
2910 /* Check that no pointers are lost. */
2911 CHECK_MATRIX (m);
2914 /* Next window on same level. */
2915 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2920 #if GLYPH_DEBUG
2922 /* Check that window and frame matrices agree about their
2923 understanding where glyphs of the rows are to find. For each
2924 window in the window tree rooted at W, check that rows in the
2925 matrices of leaf window agree with their frame matrices about
2926 glyph pointers. */
2928 void
2929 check_window_matrix_pointers (w)
2930 struct window *w;
2932 while (w)
2934 if (!NILP (w->hchild))
2935 check_window_matrix_pointers (XWINDOW (w->hchild));
2936 else if (!NILP (w->vchild))
2937 check_window_matrix_pointers (XWINDOW (w->vchild));
2938 else
2940 struct frame *f = XFRAME (w->frame);
2941 check_matrix_pointers (w->desired_matrix, f->desired_matrix);
2942 check_matrix_pointers (w->current_matrix, f->current_matrix);
2945 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2950 /* Check that window rows are slices of frame rows. WINDOW_MATRIX is
2951 a window and FRAME_MATRIX is the corresponding frame matrix. For
2952 each row in WINDOW_MATRIX check that it's a slice of the
2953 corresponding frame row. If it isn't, abort. */
2955 static void
2956 check_matrix_pointers (window_matrix, frame_matrix)
2957 struct glyph_matrix *window_matrix, *frame_matrix;
2959 /* Row number in WINDOW_MATRIX. */
2960 int i = 0;
2962 /* Row number corresponding to I in FRAME_MATRIX. */
2963 int j = window_matrix->matrix_y;
2965 /* For all rows check that the row in the window matrix is a
2966 slice of the row in the frame matrix. If it isn't we didn't
2967 mirror an operation on the frame matrix correctly. */
2968 while (i < window_matrix->nrows)
2970 if (!glyph_row_slice_p (window_matrix->rows + i,
2971 frame_matrix->rows + j))
2972 abort ();
2973 ++i, ++j;
2977 #endif /* GLYPH_DEBUG != 0 */
2981 /**********************************************************************
2982 VPOS and HPOS translations
2983 **********************************************************************/
2985 #if GLYPH_DEBUG
2987 /* Translate vertical position VPOS which is relative to window W to a
2988 vertical position relative to W's frame. */
2990 static int
2991 window_to_frame_vpos (w, vpos)
2992 struct window *w;
2993 int vpos;
2995 struct frame *f = XFRAME (w->frame);
2997 xassert (!FRAME_WINDOW_P (f));
2998 xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
2999 vpos += XFASTINT (w->top);
3000 xassert (vpos >= 0 && vpos <= FRAME_HEIGHT (f));
3001 return vpos;
3005 /* Translate horizontal position HPOS which is relative to window W to
3006 a vertical position relative to W's frame. */
3008 static int
3009 window_to_frame_hpos (w, hpos)
3010 struct window *w;
3011 int hpos;
3013 struct frame *f = XFRAME (w->frame);
3015 xassert (!FRAME_WINDOW_P (f));
3016 hpos += XFASTINT (w->left);
3017 return hpos;
3020 #endif /* GLYPH_DEBUG */
3024 /**********************************************************************
3025 Redrawing Frames
3026 **********************************************************************/
3028 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
3029 "Clear frame FRAME and output again what is supposed to appear on it.")
3030 (frame)
3031 Lisp_Object frame;
3033 struct frame *f;
3035 CHECK_LIVE_FRAME (frame, 0);
3036 f = XFRAME (frame);
3038 /* Ignore redraw requests, if frame has no glyphs yet.
3039 (Implementation note: It still has to be checked why we are
3040 called so early here). */
3041 if (!glyphs_initialized_initially_p)
3042 return Qnil;
3044 update_begin (f);
3045 if (FRAME_MSDOS_P (f))
3046 set_terminal_modes ();
3047 clear_frame ();
3048 clear_current_matrices (f);
3049 update_end (f);
3050 fflush (stdout);
3051 windows_or_buffers_changed++;
3052 /* Mark all windows as inaccurate, so that every window will have
3053 its redisplay done. */
3054 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
3055 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
3056 f->garbaged = 0;
3057 return Qnil;
3061 /* Redraw frame F. This is nothing more than a call to the Lisp
3062 function redraw-frame. */
3064 void
3065 redraw_frame (f)
3066 struct frame *f;
3068 Lisp_Object frame;
3069 XSETFRAME (frame, f);
3070 Fredraw_frame (frame);
3074 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3075 "Clear and redisplay all visible frames.")
3078 Lisp_Object tail, frame;
3080 FOR_EACH_FRAME (tail, frame)
3081 if (FRAME_VISIBLE_P (XFRAME (frame)))
3082 Fredraw_frame (frame);
3084 return Qnil;
3088 /* This is used when frame_garbaged is set. Call Fredraw_frame on all
3089 visible frames marked as garbaged. */
3091 void
3092 redraw_garbaged_frames ()
3094 Lisp_Object tail, frame;
3096 FOR_EACH_FRAME (tail, frame)
3097 if (FRAME_VISIBLE_P (XFRAME (frame))
3098 && FRAME_GARBAGED_P (XFRAME (frame)))
3099 Fredraw_frame (frame);
3104 /***********************************************************************
3105 Direct Operations
3106 ***********************************************************************/
3108 /* Try to update display and current glyph matrix directly.
3110 This function is called after a character G has been inserted into
3111 current_buffer. It tries to update the current glyph matrix and
3112 perform appropriate screen output to reflect the insertion. If it
3113 succeeds, the global flag redisplay_performed_directly_p will be
3114 set to 1, and thereby prevent the more costly general redisplay
3115 from running (see redisplay_internal).
3117 This function is not called for `hairy' character insertions.
3118 In particular, it is not called when after or before change
3119 functions exist, like they are used by font-lock. See keyboard.c
3120 for details where this function is called. */
3123 direct_output_for_insert (g)
3124 int g;
3126 register struct frame *f = SELECTED_FRAME ();
3127 struct window *w = XWINDOW (selected_window);
3128 struct it it, it2;
3129 struct glyph_row *glyph_row;
3130 struct glyph *glyphs, *glyph, *end;
3131 int n;
3132 /* Non-null means that Redisplay of W is based on window matrices. */
3133 int window_redisplay_p = FRAME_WINDOW_P (f);
3134 /* Non-null means we are in overwrite mode. */
3135 int overwrite_p = !NILP (current_buffer->overwrite_mode);
3136 int added_width;
3137 struct text_pos pos;
3138 int delta, delta_bytes;
3139 int mouse_face_overwritten_p;
3141 /* Not done directly. */
3142 redisplay_performed_directly_p = 0;
3144 /* Quickly give up for some common cases. */
3145 if (cursor_in_echo_area
3146 /* Give up if fonts have changed. */
3147 || fonts_changed_p
3148 /* Give up if face attributes have been changed. */
3149 || face_change_count
3150 /* Give up if cursor position not really known. */
3151 || !display_completed
3152 /* Give up if buffer appears in two places. */
3153 || buffer_shared > 1
3154 /* Give up if w is mini-buffer and a message is being displayed there */
3155 || (MINI_WINDOW_P (w) && !NILP (echo_area_buffer[0]))
3156 /* Give up for hscrolled mini-buffer because display of the prompt
3157 is handled specially there (see display_line). */
3158 || (MINI_WINDOW_P (w) && XFASTINT (w->hscroll))
3159 /* Give up if overwriting in the middle of a line. */
3160 || (overwrite_p
3161 && PT != ZV
3162 && FETCH_BYTE (PT) != '\n')
3163 /* Give up for tabs and line ends. */
3164 || g == '\t'
3165 || g == '\n'
3166 || g == '\r'
3167 /* Give up if unable to display the cursor in the window. */
3168 || w->cursor.vpos < 0
3169 || (glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos),
3170 /* Can't do it in a continued line because continuation
3171 lines would change. */
3172 (glyph_row->continued_p
3173 /* Can't use this method if the line overlaps others or is
3174 overlapped by others because these other lines would
3175 have to be redisplayed. */
3176 || glyph_row->overlapping_p
3177 || glyph_row->overlapped_p))
3178 /* Can't do it for partial width windows on terminal frames
3179 because we can't clear to eol in such a window. */
3180 || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w)))
3181 return 0;
3183 /* Set up a display iterator structure for W. Glyphs will be
3184 produced in scratch_glyph_row. Current position is W's cursor
3185 position. */
3186 clear_glyph_row (&scratch_glyph_row);
3187 SET_TEXT_POS (pos, PT, PT_BYTE);
3188 DEC_TEXT_POS (pos, !NILP (current_buffer->enable_multibyte_characters));
3189 init_iterator (&it, w, CHARPOS (pos), BYTEPOS (pos), &scratch_glyph_row,
3190 DEFAULT_FACE_ID);
3192 glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
3193 if (glyph_row->mouse_face_p)
3194 return 0;
3196 /* Give up if highlighting trailing whitespace and we have trailing
3197 whitespace in glyph_row. We would have to remove the trailing
3198 whitespace face in that case. */
3199 if (!NILP (Vshow_trailing_whitespace)
3200 && glyph_row->used[TEXT_AREA])
3202 struct glyph *last;
3204 last = glyph_row->glyphs[TEXT_AREA] + glyph_row->used[TEXT_AREA] - 1;
3205 if (last->type == STRETCH_GLYPH
3206 || (last->type == CHAR_GLYPH
3207 && last->u.ch == ' '))
3208 return 0;
3211 /* Give up if there are overlay strings at pos. This would fail
3212 if the overlay string has newlines in it. */
3213 if (STRINGP (it.string))
3214 return 0;
3216 it.hpos = w->cursor.hpos;
3217 it.vpos = w->cursor.vpos;
3218 it.current_x = w->cursor.x + it.first_visible_x;
3219 it.current_y = w->cursor.y;
3220 it.end_charpos = PT;
3221 it.stop_charpos = min (PT, it.stop_charpos);
3223 /* More than one display element may be returned for PT - 1 if
3224 (i) it's a control character which is translated into `\003' or
3225 `^C', or (ii) it has a display table entry, or (iii) it's a
3226 combination of both. */
3227 delta = delta_bytes = 0;
3228 while (get_next_display_element (&it))
3230 PRODUCE_GLYPHS (&it);
3232 /* Give up if glyph doesn't fit completely on the line. */
3233 if (it.current_x >= it.last_visible_x)
3234 return 0;
3236 /* Give up if new glyph has different ascent or descent than
3237 the original row, or if it is not a character glyph. */
3238 if (glyph_row->ascent != it.ascent
3239 || glyph_row->height != it.ascent + it.descent
3240 || glyph_row->phys_ascent != it.phys_ascent
3241 || glyph_row->phys_height != it.phys_ascent + it.phys_descent
3242 || it.what != IT_CHARACTER)
3243 return 0;
3245 delta += 1;
3246 delta_bytes += it.len;
3247 set_iterator_to_next (&it);
3250 /* Give up if we hit the right edge of the window. We would have
3251 to insert truncation or continuation glyphs. */
3252 added_width = it.current_x - (w->cursor.x + it.first_visible_x);
3253 if (glyph_row->pixel_width + added_width >= it.last_visible_x)
3254 return 0;
3256 /* Give up if there is a \t following in the line. */
3257 it2 = it;
3258 it2.end_charpos = ZV;
3259 it2.stop_charpos = min (it2.stop_charpos, ZV);
3260 while (get_next_display_element (&it2)
3261 && !ITERATOR_AT_END_OF_LINE_P (&it2))
3263 if (it2.c == '\t')
3264 return 0;
3265 set_iterator_to_next (&it2);
3268 /* Number of new glyphs produced. */
3269 n = it.glyph_row->used[TEXT_AREA];
3271 /* Start and end of glyphs in original row. */
3272 glyphs = glyph_row->glyphs[TEXT_AREA] + w->cursor.hpos;
3273 end = glyph_row->glyphs[1 + TEXT_AREA];
3275 /* Make room for new glyphs, then insert them. */
3276 xassert (end - glyphs - n >= 0);
3277 safe_bcopy ((char *) glyphs, (char *) (glyphs + n),
3278 (end - glyphs - n) * sizeof (*end));
3279 bcopy (it.glyph_row->glyphs[TEXT_AREA], glyphs, n * sizeof *glyphs);
3280 glyph_row->used[TEXT_AREA] = min (glyph_row->used[TEXT_AREA] + n,
3281 end - glyph_row->glyphs[TEXT_AREA]);
3283 /* Compute new line width. */
3284 glyph = glyph_row->glyphs[TEXT_AREA];
3285 end = glyph + glyph_row->used[TEXT_AREA];
3286 glyph_row->pixel_width = glyph_row->x;
3287 while (glyph < end)
3289 glyph_row->pixel_width += glyph->pixel_width;
3290 ++glyph;
3293 /* Increment buffer positions for glyphs following the newly
3294 inserted ones. */
3295 for (glyph = glyphs + n; glyph < end; ++glyph)
3296 if (glyph->charpos > 0 && BUFFERP (glyph->object))
3297 glyph->charpos += delta;
3299 if (MATRIX_ROW_END_CHARPOS (glyph_row) > 0)
3301 MATRIX_ROW_END_CHARPOS (glyph_row) += delta;
3302 MATRIX_ROW_END_BYTEPOS (glyph_row) += delta_bytes;
3305 /* Adjust positions in lines following the one we are in. */
3306 increment_matrix_positions (w->current_matrix,
3307 w->cursor.vpos + 1,
3308 w->current_matrix->nrows,
3309 delta, delta_bytes);
3311 glyph_row->contains_overlapping_glyphs_p
3312 |= it.glyph_row->contains_overlapping_glyphs_p;
3314 glyph_row->displays_text_p = 1;
3315 w->window_end_vpos = make_number (max (w->cursor.vpos,
3316 XFASTINT (w->window_end_vpos)));
3318 if (!NILP (Vshow_trailing_whitespace))
3319 highlight_trailing_whitespace (it.f, glyph_row);
3321 /* Write glyphs. If at end of row, we can simply call write_glyphs.
3322 In the middle, we have to insert glyphs. Note that this is now
3323 implemented for X frames. The implementation uses updated_window
3324 and updated_row. */
3325 updated_row = glyph_row;
3326 update_begin (f);
3327 if (rif)
3329 rif->update_window_begin_hook (w);
3331 if (glyphs == end - n)
3332 rif->write_glyphs (glyphs, n);
3333 else
3334 rif->insert_glyphs (glyphs, n);
3336 else
3338 if (glyphs == end - n)
3339 write_glyphs (glyphs, n);
3340 else
3341 insert_glyphs (glyphs, n);
3344 w->cursor.hpos += n;
3345 w->cursor.x = it.current_x - it.first_visible_x;
3346 xassert (w->cursor.hpos >= 0
3347 && w->cursor.hpos < w->desired_matrix->matrix_w);
3349 /* How to set the cursor differs depending on whether we are
3350 using a frame matrix or a window matrix. Note that when
3351 a frame matrix is used, cursor_to expects frame coordinates,
3352 and the X and Y parameters are not used. */
3353 if (window_redisplay_p)
3354 rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
3355 w->cursor.y, w->cursor.x);
3356 else
3358 int x, y;
3359 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3360 + (INTEGERP (w->left_margin_width)
3361 ? XFASTINT (w->left_margin_width)
3362 : 0));
3363 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3364 cursor_to (y, x);
3367 if (rif)
3368 rif->update_window_end_hook (w, 1, 0);
3369 update_end (f);
3370 updated_row = NULL;
3371 fflush (stdout);
3373 TRACE ((stderr, "direct output for insert\n"));
3375 UNCHANGED_MODIFIED = MODIFF;
3376 BEG_UNCHANGED = GPT - BEG;
3377 XSETFASTINT (w->last_point, PT);
3378 w->last_cursor = w->cursor;
3379 XSETFASTINT (w->last_modified, MODIFF);
3380 XSETFASTINT (w->last_overlay_modified, OVERLAY_MODIFF);
3382 redisplay_performed_directly_p = 1;
3383 return 1;
3387 /* Perform a direct display update for moving PT by N positions
3388 left or right. N < 0 means a movement backwards. This function
3389 is currently only called for N == 1 or N == -1. */
3392 direct_output_forward_char (n)
3393 int n;
3395 struct frame *f = SELECTED_FRAME ();
3396 struct window *w = XWINDOW (selected_window);
3397 struct glyph_row *row;
3399 /* Give up if point moved out of or into a composition. */
3400 if (check_point_in_composition (current_buffer, XINT (w->last_point),
3401 current_buffer, PT))
3402 return 0;
3404 /* Give up if face attributes have been changed. */
3405 if (face_change_count)
3406 return 0;
3408 /* Give up if current matrix is not up to date or we are
3409 displaying a message. */
3410 if (!display_completed || cursor_in_echo_area)
3411 return 0;
3413 /* Give up if the buffer's direction is reversed. */
3414 if (!NILP (XBUFFER (w->buffer)->direction_reversed))
3415 return 0;
3417 /* Can't use direct output if highlighting a region. */
3418 if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
3419 return 0;
3421 /* Can't use direct output if highlighting trailing whitespace. */
3422 if (!NILP (Vshow_trailing_whitespace))
3423 return 0;
3425 /* Give up if we are showing a message or just cleared the message
3426 because we might need to resize the echo area window. */
3427 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
3428 return 0;
3430 /* Give up if currently displaying a message instead of the
3431 minibuffer contents. */
3432 if (XWINDOW (minibuf_window) == w
3433 && EQ (minibuf_window, echo_area_window))
3434 return 0;
3436 /* Give up if we don't know where the cursor is. */
3437 if (w->cursor.vpos < 0)
3438 return 0;
3440 row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
3442 if (PT <= MATRIX_ROW_START_BYTEPOS (row)
3443 || PT >= MATRIX_ROW_END_BYTEPOS (row))
3444 return 0;
3446 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
3447 w->last_cursor = w->cursor;
3448 XSETFASTINT (w->last_point, PT);
3450 xassert (w->cursor.hpos >= 0
3451 && w->cursor.hpos < w->desired_matrix->matrix_w);
3453 if (FRAME_WINDOW_P (f))
3454 rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
3455 w->cursor.y, w->cursor.x);
3456 else
3458 int x, y;
3459 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3460 + (INTEGERP (w->left_margin_width)
3461 ? XFASTINT (w->left_margin_width)
3462 : 0));
3463 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3464 cursor_to (y, x);
3467 fflush (stdout);
3468 redisplay_performed_directly_p = 1;
3469 return 1;
3474 /***********************************************************************
3475 Frame Update
3476 ***********************************************************************/
3478 /* Update frame F based on the data in desired matrices.
3480 If FORCE_P is non-zero, don't let redisplay be stopped by detecting
3481 pending input. If INHIBIT_HAIRY_ID_P is non-zero, don't try
3482 scrolling.
3484 Value is non-zero if redisplay was stopped due to pending input. */
3487 update_frame (f, force_p, inhibit_hairy_id_p)
3488 struct frame *f;
3489 int force_p;
3490 int inhibit_hairy_id_p;
3492 /* 1 means display has been paused because of pending input. */
3493 int paused_p;
3494 struct window *root_window = XWINDOW (f->root_window);
3496 if (FRAME_WINDOW_P (f))
3498 /* We are working on window matrix basis. All windows whose
3499 flag must_be_updated_p is set have to be updated. */
3501 /* Record that we are not working on frame matrices. */
3502 set_frame_matrix_frame (NULL);
3504 /* Update all windows in the window tree of F, maybe stopping
3505 when pending input is detected. */
3506 update_begin (f);
3508 /* Update the menu bar on X frames that don't have toolkit
3509 support. */
3510 if (WINDOWP (f->menu_bar_window))
3511 update_window (XWINDOW (f->menu_bar_window), 1);
3513 /* Update the tool-bar window, if present. */
3514 if (WINDOWP (f->tool_bar_window))
3516 Lisp_Object tem;
3517 struct window *w = XWINDOW (f->tool_bar_window);
3519 /* Update tool-bar window. */
3520 if (w->must_be_updated_p)
3522 update_window (w, 1);
3523 w->must_be_updated_p = 0;
3525 /* Swap tool-bar strings. We swap because we want to
3526 reuse strings. */
3527 tem = f->current_tool_bar_string;
3528 f->current_tool_bar_string = f->desired_tool_bar_string;
3529 f->desired_tool_bar_string = tem;
3530 f->n_current_tool_bar_items = f->n_desired_tool_bar_items;
3532 /* Swap tool-bar items. We swap because we want to
3533 reuse vectors. */
3534 tem = f->current_tool_bar_items;
3535 f->current_tool_bar_items = f->desired_tool_bar_items;
3536 f->desired_tool_bar_items = tem;
3541 /* Update windows. */
3542 paused_p = update_window_tree (root_window, force_p);
3543 update_end (f);
3544 display_completed = !paused_p;
3546 /* The flush is a performance bottleneck under X. */
3547 #if 0
3548 rif->flush_display (f);
3549 #endif
3551 else
3553 /* We are working on frame matrix basis. Set the frame on whose
3554 frame matrix we operate. */
3555 set_frame_matrix_frame (f);
3557 /* Build F's desired matrix from window matrices. For windows
3558 whose must_be_updated_p flag is set, desired matrices are
3559 made part of the desired frame matrix. For other windows,
3560 the current matrix is copied. */
3561 build_frame_matrix (f);
3563 /* Do the update on the frame desired matrix. */
3564 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
3566 /* Check window matrices for lost pointers. */
3567 IF_DEBUG (check_window_matrix_pointers (root_window));
3570 /* Reset flags indicating that a window should be updated. */
3571 set_window_update_flags (root_window, 0);
3572 return paused_p;
3577 /************************************************************************
3578 Window-based updates
3579 ************************************************************************/
3581 /* Perform updates in window tree rooted at W. FORCE_P non-zero means
3582 don't stop updating when input is pending. */
3584 static int
3585 update_window_tree (w, force_p)
3586 struct window *w;
3587 int force_p;
3589 int paused_p = 0;
3591 while (w && !paused_p)
3593 if (!NILP (w->hchild))
3594 paused_p |= update_window_tree (XWINDOW (w->hchild), force_p);
3595 else if (!NILP (w->vchild))
3596 paused_p |= update_window_tree (XWINDOW (w->vchild), force_p);
3597 else if (w->must_be_updated_p)
3598 paused_p |= update_window (w, force_p);
3600 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3603 return paused_p;
3607 /* Update window W if its flag must_be_updated_p is non-zero. If
3608 FORCE_P is non-zero, don't stop updating if input is pending. */
3610 void
3611 update_single_window (w, force_p)
3612 struct window *w;
3613 int force_p;
3615 if (w->must_be_updated_p)
3617 struct frame *f = XFRAME (WINDOW_FRAME (w));
3619 /* Record that this is not a frame-based redisplay. */
3620 set_frame_matrix_frame (NULL);
3622 /* Update W. */
3623 update_begin (f);
3624 update_window (w, force_p);
3625 update_end (f);
3627 /* Reset flag in W. */
3628 w->must_be_updated_p = 0;
3633 /* Redraw lines from the current matrix of window W that are
3634 overlapped by other rows. YB is bottom-most y-position in W. */
3636 static void
3637 redraw_overlapped_rows (w, yb)
3638 struct window *w;
3639 int yb;
3641 int i;
3643 /* If rows overlapping others have been changed, the rows being
3644 overlapped have to be redrawn. This won't draw lines that have
3645 already been drawn in update_window_line because overlapped_p in
3646 desired rows is 0, so after row assignment overlapped_p in
3647 current rows is 0. */
3648 for (i = 0; i < w->current_matrix->nrows; ++i)
3650 struct glyph_row *row = w->current_matrix->rows + i;
3652 if (!row->enabled_p)
3653 break;
3654 else if (row->mode_line_p)
3655 continue;
3657 if (row->overlapped_p)
3659 enum glyph_row_area area;
3661 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
3663 updated_row = row;
3664 updated_area = area;
3665 rif->cursor_to (i, 0, row->y, area == TEXT_AREA ? row->x : 0);
3666 if (row->used[area])
3667 rif->write_glyphs (row->glyphs[area], row->used[area]);
3668 rif->clear_end_of_line (-1);
3671 row->overlapped_p = 0;
3674 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3675 break;
3680 /* Redraw lines from the current matrix of window W that overlap
3681 others. YB is bottom-most y-position in W. */
3683 static void
3684 redraw_overlapping_rows (w, yb)
3685 struct window *w;
3686 int yb;
3688 int i, bottom_y;
3689 struct glyph_row *row;
3691 for (i = 0; i < w->current_matrix->nrows; ++i)
3693 row = w->current_matrix->rows + i;
3695 if (!row->enabled_p)
3696 break;
3697 else if (row->mode_line_p)
3698 continue;
3700 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3702 if (row->overlapping_p && i > 0 && bottom_y < yb)
3704 if (row->used[LEFT_MARGIN_AREA])
3705 rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
3707 if (row->used[TEXT_AREA])
3708 rif->fix_overlapping_area (w, row, TEXT_AREA);
3710 if (row->used[RIGHT_MARGIN_AREA])
3711 rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
3713 /* Record in neighbor rows that ROW overwrites part of their
3714 display. */
3715 if (row->phys_ascent > row->ascent && i > 0)
3716 MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
3717 if ((row->phys_height - row->phys_ascent
3718 > row->height - row->ascent)
3719 && bottom_y < yb)
3720 MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
3723 if (bottom_y >= yb)
3724 break;
3729 /* Update display of window W. FORCE_P non-zero means that we should
3730 not stop when detecting pending input. */
3732 static int
3733 update_window (w, force_p)
3734 struct window *w;
3735 int force_p;
3737 struct glyph_matrix *desired_matrix = w->desired_matrix;
3738 int paused_p;
3739 int preempt_count = baud_rate / 2400 + 1;
3740 extern int input_pending;
3741 #if GLYPH_DEBUG
3742 struct frame *f = XFRAME (WINDOW_FRAME (w));
3743 extern struct frame *updating_frame;
3744 #endif
3746 /* Check that W's frame doesn't have glyph matrices. */
3747 xassert (FRAME_WINDOW_P (f));
3748 xassert (updating_frame != NULL);
3750 /* Check pending input the first time so that we can quickly return. */
3751 if (redisplay_dont_pause)
3752 force_p = 1;
3753 else
3754 detect_input_pending ();
3756 /* If forced to complete the update, or if no input is pending, do
3757 the update. */
3758 if (force_p || !input_pending)
3760 struct glyph_row *row, *end;
3761 struct glyph_row *mode_line_row;
3762 struct glyph_row *header_line_row = NULL;
3763 int yb, changed_p = 0, mouse_face_overwritten_p = 0;
3765 rif->update_window_begin_hook (w);
3766 yb = window_text_bottom_y (w);
3768 /* If window has a top line, update it before everything else.
3769 Adjust y-positions of other rows by the top line height. */
3770 row = desired_matrix->rows;
3771 end = row + desired_matrix->nrows - 1;
3772 if (row->mode_line_p)
3773 header_line_row = row++;
3775 /* Update the mode line, if necessary. */
3776 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
3777 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
3779 mode_line_row->y = yb;
3780 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
3781 desired_matrix),
3782 &mouse_face_overwritten_p);
3783 changed_p = 1;
3786 /* Find first enabled row. Optimizations in redisplay_internal
3787 may lead to an update with only one row enabled. There may
3788 be also completely empty matrices. */
3789 while (row < end && !row->enabled_p)
3790 ++row;
3792 /* Try reusing part of the display by inserting/deleting lines. */
3793 if (row < end && !desired_matrix->no_scrolling_p)
3795 int rc = scrolling_window (w, header_line_row != NULL);
3796 if (rc < 0)
3798 /* All rows were found to be equal. */
3799 paused_p = 0;
3800 goto set_cursor;
3802 else if (rc > 0)
3803 force_p = 1;
3804 changed_p = 1;
3807 /* Update the top mode line after scrolling because a new top
3808 line would otherwise overwrite lines at the top of the window
3809 that can be scrolled. */
3810 if (header_line_row && header_line_row->enabled_p)
3812 header_line_row->y = 0;
3813 update_window_line (w, 0, &mouse_face_overwritten_p);
3814 changed_p = 1;
3817 /* Update the rest of the lines. */
3818 for (; row < end && (force_p || !input_pending); ++row)
3819 if (row->enabled_p
3820 /* A row can be completely invisible in case a desired
3821 matrix was built with a vscroll and then
3822 make_cursor_line_fully_visible shifts the matrix. */
3823 && row->visible_height > 0)
3825 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
3826 int i;
3828 /* We'll Have to play a little bit with when to
3829 detect_input_pending. If it's done too often,
3830 scrolling large windows with repeated scroll-up
3831 commands will too quickly pause redisplay. */
3832 if (!force_p && vpos % preempt_count == 0)
3833 detect_input_pending ();
3835 changed_p |= update_window_line (w, vpos,
3836 &mouse_face_overwritten_p);
3838 /* Mark all rows below the last visible one in the current
3839 matrix as invalid. This is necessary because of
3840 variable line heights. Consider the case of three
3841 successive redisplays, where the first displays 5
3842 lines, the second 3 lines, and the third 5 lines again.
3843 If the second redisplay wouldn't mark rows in the
3844 current matrix invalid, the third redisplay might be
3845 tempted to optimize redisplay based on lines displayed
3846 in the first redisplay. */
3847 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3848 for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
3849 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
3852 /* Was display preempted? */
3853 paused_p = row < end;
3855 set_cursor:
3857 /* Fix the appearance of overlapping(overlapped rows. */
3858 if (!paused_p && !w->pseudo_window_p)
3860 if (changed_p && rif->fix_overlapping_area)
3862 redraw_overlapped_rows (w, yb);
3863 redraw_overlapping_rows (w, yb);
3866 /* Make cursor visible at cursor position of W. */
3867 set_window_cursor_after_update (w);
3869 #if 0 /* Check that current matrix invariants are satisfied. This is
3870 for debugging only. See the comment of check_matrix_invariants. */
3871 IF_DEBUG (check_matrix_invariants (w));
3872 #endif
3875 #if GLYPH_DEBUG
3876 /* Remember the redisplay method used to display the matrix. */
3877 strcpy (w->current_matrix->method, w->desired_matrix->method);
3878 #endif
3880 /* End of update of window W. */
3881 rif->update_window_end_hook (w, 1, mouse_face_overwritten_p);
3883 else
3884 paused_p = 1;
3886 clear_glyph_matrix (desired_matrix);
3888 return paused_p;
3892 /* Update the display of area AREA in window W, row number VPOS.
3893 AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
3895 static void
3896 update_marginal_area (w, area, vpos)
3897 struct window *w;
3898 int area, vpos;
3900 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3902 /* Let functions in xterm.c know what area subsequent X positions
3903 will be relative to. */
3904 updated_area = area;
3906 /* Set cursor to start of glyphs, write them, and clear to the end
3907 of the area. I don't think that something more sophisticated is
3908 necessary here, since marginal areas will not be the default. */
3909 rif->cursor_to (vpos, 0, desired_row->y, 0);
3910 if (desired_row->used[area])
3911 rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]);
3912 rif->clear_end_of_line (-1);
3916 /* Update the display of the text area of row VPOS in window W.
3917 Value is non-zero if display has changed. */
3919 static int
3920 update_text_area (w, vpos)
3921 struct window *w;
3922 int vpos;
3924 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3925 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3926 int changed_p = 0;
3928 /* Let functions in xterm.c know what area subsequent X positions
3929 will be relative to. */
3930 updated_area = TEXT_AREA;
3932 /* If rows are at different X or Y, or rows have different height,
3933 or the current row is marked invalid, write the entire line. */
3934 if (!current_row->enabled_p
3935 || desired_row->y != current_row->y
3936 || desired_row->ascent != current_row->ascent
3937 || desired_row->phys_ascent != current_row->phys_ascent
3938 || desired_row->phys_height != current_row->phys_height
3939 || desired_row->visible_height != current_row->visible_height
3940 || current_row->overlapped_p
3941 || current_row->x != desired_row->x)
3943 rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
3945 if (desired_row->used[TEXT_AREA])
3946 rif->write_glyphs (desired_row->glyphs[TEXT_AREA],
3947 desired_row->used[TEXT_AREA]);
3949 /* Clear to end of window. */
3950 rif->clear_end_of_line (-1);
3951 changed_p = 1;
3953 else
3955 int stop, i, x;
3956 struct glyph *current_glyph = current_row->glyphs[TEXT_AREA];
3957 struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
3959 /* If the desired row extends its face to the text area end,
3960 make sure we write at least one glyph, so that the face
3961 extension actually takes place. */
3962 int desired_stop_pos = (desired_row->used[TEXT_AREA]
3963 - (MATRIX_ROW_EXTENDS_FACE_P (desired_row)
3964 ? 1 : 0));
3966 stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
3967 i = 0;
3968 x = desired_row->x;
3970 while (i < stop)
3972 /* Skip over glyphs that both rows have in common. These
3973 don't have to be written. */
3974 while (i < stop
3975 && GLYPH_EQUAL_P (desired_glyph, current_glyph))
3977 x += desired_glyph->pixel_width;
3978 ++desired_glyph, ++current_glyph, ++i;
3981 /* Consider the case that the current row contains "xxx ppp
3982 ggg" in italic Courier font, and the desired row is "xxx
3983 ggg". The character `p' has lbearing, `g' has not. The
3984 loop above will stop in front of the first `p' in the
3985 current row. If we would start writing glyphs there, we
3986 wouldn't erase the lbearing of the `p'. The rest of the
3987 lbearing problem is then taken care of by x_draw_glyphs. */
3988 if (current_row->contains_overlapping_glyphs_p
3989 && i > 0
3990 && i < current_row->used[TEXT_AREA]
3991 && current_row->used[TEXT_AREA] != desired_row->used[TEXT_AREA])
3993 int left, right;
3994 rif->get_glyph_overhangs (current_glyph, XFRAME (w->frame),
3995 &left, &right);
3996 while (left > 0 && i > 0)
3998 --i, --desired_glyph, --current_glyph;
3999 x -= desired_glyph->pixel_width;
4000 left -= desired_glyph->pixel_width;
4004 /* Try to avoid writing the entire rest of the desired row
4005 by looking for a resync point. This mainly prevents
4006 mode line flickering in the case the mode line is in
4007 fixed-pitch font, which it usually will be. */
4008 if (i < desired_row->used[TEXT_AREA])
4010 int start_x = x, start_hpos = i;
4011 struct glyph *start = desired_glyph;
4012 int current_x = x;
4014 /* Find the next glyph that's equal again. */
4015 while (i < stop
4016 && !GLYPH_EQUAL_P (desired_glyph, current_glyph)
4017 && x == current_x)
4019 x += desired_glyph->pixel_width;
4020 current_x += current_glyph->pixel_width;
4021 ++desired_glyph, ++current_glyph, ++i;
4024 if (i == start_hpos || x != current_x)
4026 i = start_hpos;
4027 x = start_x;
4028 desired_glyph = start;
4029 break;
4032 rif->cursor_to (vpos, start_hpos, desired_row->y, start_x);
4033 rif->write_glyphs (start, i - start_hpos);
4034 changed_p = 1;
4038 /* Write the rest. */
4039 if (i < desired_row->used[TEXT_AREA])
4041 rif->cursor_to (vpos, i, desired_row->y, x);
4042 rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
4043 changed_p = 1;
4046 /* Maybe clear to end of line. */
4047 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
4049 /* If new row extends to the end of the text area, nothing
4050 has to be cleared, if and only if we did a write_glyphs
4051 above. This is made sure by setting desired_stop_pos
4052 appropriately above. */
4053 xassert (i < desired_row->used[TEXT_AREA]);
4055 else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
4057 /* If old row extends to the end of the text area, clear. */
4058 if (i >= desired_row->used[TEXT_AREA])
4059 rif->cursor_to (vpos, i, desired_row->y,
4060 desired_row->x + desired_row->pixel_width);
4061 rif->clear_end_of_line (-1);
4062 changed_p = 1;
4064 else if (desired_row->pixel_width < current_row->pixel_width)
4066 /* Otherwise clear to the end of the old row. Everything
4067 after that position should be clear already. */
4068 int x;
4070 if (i >= desired_row->used[TEXT_AREA])
4071 rif->cursor_to (vpos, i, desired_row->y,
4072 desired_row->x + desired_row->pixel_width);
4074 /* If cursor is displayed at the end of the line, make sure
4075 it's cleared. Nowadays we don't have a phys_cursor_glyph
4076 with which to erase the cursor (because this method
4077 doesn't work with lbearing/rbearing), so we must do it
4078 this way. */
4079 if (vpos == w->phys_cursor.vpos
4080 && w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])
4082 w->phys_cursor_on_p = 0;
4083 x = -1;
4085 else
4086 x = current_row->x + current_row->pixel_width;
4087 rif->clear_end_of_line (x);
4088 changed_p = 1;
4092 return changed_p;
4096 /* Update row VPOS in window W. Value is non-zero if display has been
4097 changed. */
4099 static int
4100 update_window_line (w, vpos, mouse_face_overwritten_p)
4101 struct window *w;
4102 int vpos, *mouse_face_overwritten_p;
4104 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
4105 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
4106 int changed_p = 0;
4108 xassert (desired_row->enabled_p);
4110 /* Set the row being updated. This is important to let xterm.c
4111 know what line height values are in effect. */
4112 updated_row = desired_row;
4114 /* Update display of the left margin area, if there is one. */
4115 if (!desired_row->full_width_p
4116 && !NILP (w->left_margin_width))
4118 changed_p = 1;
4119 update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
4122 /* Update the display of the text area. */
4123 if (update_text_area (w, vpos))
4125 changed_p = 1;
4126 if (current_row->mouse_face_p)
4127 *mouse_face_overwritten_p = 1;
4130 /* Update display of the right margin area, if there is one. */
4131 if (!desired_row->full_width_p
4132 && !NILP (w->right_margin_width))
4134 changed_p = 1;
4135 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
4138 /* Draw truncation marks etc. */
4139 if (!current_row->enabled_p
4140 || desired_row->y != current_row->y
4141 || desired_row->visible_height != current_row->visible_height
4142 || desired_row->overlay_arrow_p != current_row->overlay_arrow_p
4143 || desired_row->truncated_on_left_p != current_row->truncated_on_left_p
4144 || desired_row->truncated_on_right_p != current_row->truncated_on_right_p
4145 || desired_row->continued_p != current_row->continued_p
4146 || desired_row->mode_line_p != current_row->mode_line_p
4147 || (desired_row->indicate_empty_line_p
4148 != current_row->indicate_empty_line_p)
4149 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
4150 != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
4151 rif->after_update_window_line_hook (desired_row);
4153 /* Update current_row from desired_row. */
4154 make_current (w->desired_matrix, w->current_matrix, vpos);
4155 updated_row = NULL;
4156 return changed_p;
4160 /* Set the cursor after an update of window W. This function may only
4161 be called from update_window. */
4163 static void
4164 set_window_cursor_after_update (w)
4165 struct window *w;
4167 struct frame *f = XFRAME (w->frame);
4168 int cx, cy, vpos, hpos;
4170 /* Not intended for frame matrix updates. */
4171 xassert (FRAME_WINDOW_P (f));
4173 if (cursor_in_echo_area
4174 && !NILP (echo_area_buffer[0])
4175 /* If we are showing a message instead of the mini-buffer,
4176 show the cursor for the message instead. */
4177 && XWINDOW (minibuf_window) == w
4178 && EQ (minibuf_window, echo_area_window)
4179 /* These cases apply only to the frame that contains
4180 the active mini-buffer window. */
4181 && FRAME_HAS_MINIBUF_P (f)
4182 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4184 cx = cy = vpos = hpos = 0;
4186 if (cursor_in_echo_area >= 0)
4188 /* If the mini-buffer is several lines high, find the last
4189 line that has any text on it. Note: either all lines
4190 are enabled or none. Otherwise we wouldn't be able to
4191 determine Y. */
4192 struct glyph_row *row, *last_row;
4193 struct glyph *glyph;
4194 int yb = window_text_bottom_y (w);
4196 last_row = NULL;
4197 for (row = MATRIX_ROW (w->current_matrix, 0);
4198 row->enabled_p;
4199 ++row)
4201 if (row->used[TEXT_AREA]
4202 && row->glyphs[TEXT_AREA][0].charpos >= 0)
4203 last_row = row;
4205 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
4206 break;
4209 if (last_row)
4211 struct glyph *start = row->glyphs[TEXT_AREA];
4212 struct glyph *last = start + row->used[TEXT_AREA] - 1;
4214 while (last > start && last->charpos < 0)
4215 --last;
4217 for (glyph = start; glyph < last; ++glyph)
4219 cx += glyph->pixel_width;
4220 ++hpos;
4223 cy = last_row->y;
4224 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
4228 else
4230 cx = w->cursor.x;
4231 cy = w->cursor.y;
4232 hpos = w->cursor.hpos;
4233 vpos = w->cursor.vpos;
4236 /* Window cursor can be out of sync for horizontally split windows. */
4237 hpos = max (0, hpos);
4238 hpos = min (w->current_matrix->matrix_w - 1, hpos);
4239 vpos = max (0, vpos);
4240 vpos = min (w->current_matrix->nrows - 1, vpos);
4241 rif->cursor_to (vpos, hpos, cy, cx);
4245 /* Set WINDOW->must_be_updated_p to ON_P for all windows in the window
4246 tree rooted at W. */
4248 void
4249 set_window_update_flags (w, on_p)
4250 struct window *w;
4251 int on_p;
4253 while (w)
4255 if (!NILP (w->hchild))
4256 set_window_update_flags (XWINDOW (w->hchild), on_p);
4257 else if (!NILP (w->vchild))
4258 set_window_update_flags (XWINDOW (w->vchild), on_p);
4259 else
4260 w->must_be_updated_p = on_p;
4262 w = NILP (w->next) ? 0 : XWINDOW (w->next);
4268 /***********************************************************************
4269 Window-Based Scrolling
4270 ***********************************************************************/
4272 /* Structure describing rows in scrolling_window. */
4274 struct row_entry
4276 /* Number of occurrences of this row in desired and current matrix. */
4277 int old_uses, new_uses;
4279 /* Vpos of row in new matrix. */
4280 int new_line_number;
4282 /* Bucket index of this row_entry in the hash table row_table. */
4283 int bucket;
4285 /* The row described by this entry. */
4286 struct glyph_row *row;
4288 /* Hash collision chain. */
4289 struct row_entry *next;
4292 /* A pool to allocate row_entry structures from, and the size of the
4293 pool. The pool is reallocated in scrolling_window when we find
4294 that we need a larger one. */
4296 static struct row_entry *row_entry_pool;
4297 static int row_entry_pool_size;
4299 /* Index of next free entry in row_entry_pool. */
4301 static int row_entry_idx;
4303 /* The hash table used during scrolling, and the table's size. This
4304 table is used to quickly identify equal rows in the desired and
4305 current matrix. */
4307 static struct row_entry **row_table;
4308 static int row_table_size;
4310 /* Vectors of pointers to row_entry structures belonging to the
4311 current and desired matrix, and the size of the vectors. */
4313 static struct row_entry **old_lines, **new_lines;
4314 static int old_lines_size, new_lines_size;
4316 /* A pool to allocate run structures from, and its size. */
4318 static struct run *run_pool;
4319 static int runs_size;
4321 /* A vector of runs of lines found during scrolling. */
4323 static struct run **runs;
4325 static struct row_entry *add_row_entry P_ ((struct window *,
4326 struct glyph_row *));
4329 /* Add glyph row ROW to the scrolling hash table during the scrolling
4330 of window W. */
4332 static INLINE struct row_entry *
4333 add_row_entry (w, row)
4334 struct window *w;
4335 struct glyph_row *row;
4337 struct row_entry *entry;
4338 int i = row->hash % row_table_size;
4340 entry = row_table[i];
4341 while (entry && !row_equal_p (w, entry->row, row, 1))
4342 entry = entry->next;
4344 if (entry == NULL)
4346 entry = row_entry_pool + row_entry_idx++;
4347 entry->row = row;
4348 entry->old_uses = entry->new_uses = 0;
4349 entry->new_line_number = 0;
4350 entry->bucket = i;
4351 entry->next = row_table[i];
4352 row_table[i] = entry;
4355 return entry;
4359 /* Try to reuse part of the current display of W by scrolling lines.
4360 HEADER_LINE_P non-zero means W has a top mode line.
4362 The algorithm is taken from Communications of the ACM, Apr78 "A
4363 Technique for Isolating Differences Between Files." It should take
4364 O(N) time.
4366 A short outline of the steps of the algorithm
4368 1. Skip lines equal at the start and end of both matrices.
4370 2. Enter rows in the current and desired matrix into a symbol
4371 table, counting how often they appear in both matrices.
4373 3. Rows that appear exactly once in both matrices serve as anchors,
4374 i.e. we assume that such lines are likely to have been moved.
4376 4. Starting from anchor lines, extend regions to be scrolled both
4377 forward and backward.
4379 Value is
4381 -1 if all rows were found to be equal.
4382 0 to indicate that we did not scroll the display, or
4383 1 if we did scroll. */
4385 static int
4386 scrolling_window (w, header_line_p)
4387 struct window *w;
4388 int header_line_p;
4390 struct glyph_matrix *desired_matrix = w->desired_matrix;
4391 struct glyph_matrix *current_matrix = w->current_matrix;
4392 int yb = window_text_bottom_y (w);
4393 int i, j, first_old, first_new, last_old, last_new;
4394 int nruns, nbytes, n, run_idx;
4395 struct row_entry *entry;
4397 /* Skip over rows equal at the start. */
4398 i = header_line_p ? 1 : 0;
4399 while (i < current_matrix->nrows - 1
4400 && MATRIX_ROW_ENABLED_P (current_matrix, i)
4401 && MATRIX_ROW_ENABLED_P (desired_matrix, i)
4402 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i)) <= yb
4403 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i)) <= yb
4404 && row_equal_p (w,
4405 MATRIX_ROW (desired_matrix, i),
4406 MATRIX_ROW (current_matrix, i), 1))
4408 assign_row (MATRIX_ROW (current_matrix, i),
4409 MATRIX_ROW (desired_matrix, i));
4410 MATRIX_ROW (desired_matrix, i)->enabled_p = 0;
4411 ++i;
4414 /* Give up if some rows in the desired matrix are not enabled. */
4415 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
4416 return -1;
4418 first_old = first_new = i;
4420 /* Set last_new to the index + 1 of the last enabled row in the
4421 desired matrix. */
4422 i = first_new + 1;
4423 while (i < desired_matrix->nrows - 1
4424 && MATRIX_ROW (desired_matrix, i)->enabled_p
4425 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i)) <= yb)
4426 ++i;
4428 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
4429 return 0;
4431 last_new = i;
4433 /* Set last_old to the index + 1 of the last enabled row in the
4434 current matrix. We don't look at the enabled flag here because
4435 we plan to reuse part of the display even if other parts are
4436 disabled. */
4437 i = first_old + 1;
4438 while (i < current_matrix->nrows - 1
4439 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i)) <= yb)
4440 ++i;
4441 last_old = i;
4443 /* Skip over rows equal at the bottom. */
4444 i = last_new;
4445 j = last_old;
4446 while (i - 1 > first_new
4447 && j - 1 > first_old
4448 && MATRIX_ROW (current_matrix, i - 1)->enabled_p
4449 && (MATRIX_ROW (current_matrix, i - 1)->y
4450 == MATRIX_ROW (desired_matrix, j - 1)->y)
4451 && row_equal_p (w,
4452 MATRIX_ROW (desired_matrix, i - 1),
4453 MATRIX_ROW (current_matrix, j - 1), 1))
4454 --i, --j;
4455 last_new = i;
4456 last_old = j;
4458 /* Nothing to do if all rows are equal. */
4459 if (last_new == first_new)
4460 return 0;
4462 /* Reallocate vectors, tables etc. if necessary. */
4464 if (current_matrix->nrows > old_lines_size)
4466 old_lines_size = current_matrix->nrows;
4467 nbytes = old_lines_size * sizeof *old_lines;
4468 old_lines = (struct row_entry **) xrealloc (old_lines, nbytes);
4471 if (desired_matrix->nrows > new_lines_size)
4473 new_lines_size = desired_matrix->nrows;
4474 nbytes = new_lines_size * sizeof *new_lines;
4475 new_lines = (struct row_entry **) xrealloc (new_lines, nbytes);
4478 n = desired_matrix->nrows + current_matrix->nrows;
4479 if (3 * n > row_table_size)
4481 row_table_size = next_almost_prime (3 * n);
4482 nbytes = row_table_size * sizeof *row_table;
4483 row_table = (struct row_entry **) xrealloc (row_table, nbytes);
4484 bzero (row_table, nbytes);
4487 if (n > row_entry_pool_size)
4489 row_entry_pool_size = n;
4490 nbytes = row_entry_pool_size * sizeof *row_entry_pool;
4491 row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes);
4494 if (desired_matrix->nrows > runs_size)
4496 runs_size = desired_matrix->nrows;
4497 nbytes = runs_size * sizeof *runs;
4498 runs = (struct run **) xrealloc (runs, nbytes);
4499 nbytes = runs_size * sizeof *run_pool;
4500 run_pool = (struct run *) xrealloc (run_pool, nbytes);
4503 nruns = run_idx = 0;
4504 row_entry_idx = 0;
4506 /* Add rows from the current and desired matrix to the hash table
4507 row_hash_table to be able to find equal ones quickly. */
4509 for (i = first_old; i < last_old; ++i)
4511 if (MATRIX_ROW (current_matrix, i)->enabled_p)
4513 entry = add_row_entry (w, MATRIX_ROW (current_matrix, i));
4514 old_lines[i] = entry;
4515 ++entry->old_uses;
4517 else
4518 old_lines[i] = NULL;
4521 for (i = first_new; i < last_new; ++i)
4523 xassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
4524 entry = add_row_entry (w, MATRIX_ROW (desired_matrix, i));
4525 ++entry->new_uses;
4526 entry->new_line_number = i;
4527 new_lines[i] = entry;
4530 /* Identify moves based on lines that are unique and equal
4531 in both matrices. */
4532 for (i = first_old; i < last_old;)
4533 if (old_lines[i]
4534 && old_lines[i]->old_uses == 1
4535 && old_lines[i]->new_uses == 1)
4537 int j, k;
4538 int new_line = old_lines[i]->new_line_number;
4539 struct run *run = run_pool + run_idx++;
4541 /* Record move. */
4542 run->current_vpos = i;
4543 run->current_y = MATRIX_ROW (current_matrix, i)->y;
4544 run->desired_vpos = new_line;
4545 run->desired_y = MATRIX_ROW (desired_matrix, new_line)->y;
4546 run->nrows = 1;
4547 run->height = MATRIX_ROW (current_matrix, i)->height;
4549 /* Extend backward. */
4550 j = i - 1;
4551 k = new_line - 1;
4552 while (j > first_old
4553 && k > first_new
4554 && old_lines[j] == new_lines[k])
4556 int h = MATRIX_ROW (current_matrix, j)->height;
4557 --run->current_vpos;
4558 --run->desired_vpos;
4559 ++run->nrows;
4560 run->height += h;
4561 run->desired_y -= h;
4562 run->current_y -= h;
4563 --j, --k;
4566 /* Extend forward. */
4567 j = i + 1;
4568 k = new_line + 1;
4569 while (j < last_old
4570 && k < last_new
4571 && old_lines[j] == new_lines[k])
4573 int h = MATRIX_ROW (current_matrix, j)->height;
4574 ++run->nrows;
4575 run->height += h;
4576 ++j, ++k;
4579 /* Insert run into list of all runs. Order runs by copied
4580 pixel lines. Note that we record runs that don't have to
4581 be copied because they are already in place. This is done
4582 because we can avoid calling update_window_line in this
4583 case. */
4584 for (j = 0; j < nruns && runs[j]->height > run->height; ++j)
4586 for (k = nruns; k >= j; --k)
4587 runs[k] = runs[k - 1];
4588 runs[j] = run;
4589 ++nruns;
4591 i += run->nrows;
4593 else
4594 ++i;
4596 /* Do the moves. Do it in a way that we don't overwrite something
4597 we want to copy later on. This is not solvable in general
4598 because there is only one display and we don't have a way to
4599 exchange areas on this display. Example:
4601 +-----------+ +-----------+
4602 | A | | B |
4603 +-----------+ --> +-----------+
4604 | B | | A |
4605 +-----------+ +-----------+
4607 Instead, prefer bigger moves, and invalidate moves that would
4608 copy from where we copied to. */
4610 for (i = 0; i < nruns; ++i)
4611 if (runs[i]->nrows > 0)
4613 struct run *r = runs[i];
4615 /* Copy on the display. */
4616 if (r->current_y != r->desired_y)
4618 rif->scroll_run_hook (w, r);
4620 /* Invalidate runs that copy from where we copied to. */
4621 for (j = i + 1; j < nruns; ++j)
4623 struct run *p = runs[j];
4625 if ((p->current_y >= r->desired_y
4626 && p->current_y < r->desired_y + r->height)
4627 || (p->current_y + p->height >= r->desired_y
4628 && (p->current_y + p->height
4629 < r->desired_y + r->height)))
4630 p->nrows = 0;
4634 /* Assign matrix rows. */
4635 for (j = 0; j < r->nrows; ++j)
4637 struct glyph_row *from, *to;
4638 int to_overlapped_p;
4640 to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
4641 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
4642 to_overlapped_p = to->overlapped_p;
4643 assign_row (to, from);
4644 to->enabled_p = 1, from->enabled_p = 0;
4645 to->overlapped_p = to_overlapped_p;
4649 /* Clear the hash table, for the next time. */
4650 for (i = 0; i < row_entry_idx; ++i)
4651 row_table[row_entry_pool[i].bucket] = NULL;
4653 /* Value is non-zero to indicate that we scrolled the display. */
4654 return 1;
4659 /************************************************************************
4660 Frame-Based Updates
4661 ************************************************************************/
4663 /* Update the desired frame matrix of frame F.
4665 FORCE_P non-zero means that the update should not be stopped by
4666 pending input. INHIBIT_HAIRY_ID_P non-zero means that scrolling
4667 should not be tried.
4669 Value is non-zero if update was stopped due to pending input. */
4671 static int
4672 update_frame_1 (f, force_p, inhibit_id_p)
4673 struct frame *f;
4674 int force_p;
4675 int inhibit_id_p;
4677 /* Frame matrices to work on. */
4678 struct glyph_matrix *current_matrix = f->current_matrix;
4679 struct glyph_matrix *desired_matrix = f->desired_matrix;
4680 int i;
4681 int pause;
4682 int preempt_count = baud_rate / 2400 + 1;
4683 extern int input_pending;
4685 xassert (current_matrix && desired_matrix);
4687 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4688 calculate_costs (f);
4690 if (preempt_count <= 0)
4691 preempt_count = 1;
4693 detect_input_pending ();
4694 if (input_pending && !force_p)
4696 pause = 1;
4697 goto do_pause;
4700 update_begin (f);
4702 /* If we cannot insert/delete lines, it's no use trying it. */
4703 if (!line_ins_del_ok)
4704 inhibit_id_p = 1;
4706 /* See if any of the desired lines are enabled; don't compute for
4707 i/d line if just want cursor motion. */
4708 for (i = 0; i < desired_matrix->nrows; i++)
4709 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4710 break;
4712 /* Try doing i/d line, if not yet inhibited. */
4713 if (!inhibit_id_p && i < desired_matrix->nrows)
4714 force_p |= scrolling (f);
4716 /* Update the individual lines as needed. Do bottom line first. */
4717 if (MATRIX_ROW_ENABLED_P (desired_matrix, desired_matrix->nrows - 1))
4718 update_frame_line (f, desired_matrix->nrows - 1);
4720 /* Now update the rest of the lines. */
4721 for (i = 0; i < desired_matrix->nrows - 1 && (force_p || !input_pending); i++)
4723 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4725 if (FRAME_TERMCAP_P (f))
4727 /* Flush out every so many lines.
4728 Also flush out if likely to have more than 1k buffered
4729 otherwise. I'm told that some telnet connections get
4730 really screwed by more than 1k output at once. */
4731 int outq = PENDING_OUTPUT_COUNT (stdout);
4732 if (outq > 900
4733 || (outq > 20 && ((i - 1) % preempt_count == 0)))
4735 fflush (stdout);
4736 if (preempt_count == 1)
4738 #ifdef EMACS_OUTQSIZE
4739 if (EMACS_OUTQSIZE (0, &outq) < 0)
4740 /* Probably not a tty. Ignore the error and reset
4741 * the outq count. */
4742 outq = PENDING_OUTPUT_COUNT (stdout);
4743 #endif
4744 outq *= 10;
4745 if (baud_rate <= outq && baud_rate > 0)
4746 sleep (outq / baud_rate);
4751 if ((i - 1) % preempt_count == 0)
4752 detect_input_pending ();
4754 update_frame_line (f, i);
4758 pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0;
4760 /* Now just clean up termcap drivers and set cursor, etc. */
4761 if (!pause)
4763 if ((cursor_in_echo_area
4764 /* If we are showing a message instead of the mini-buffer,
4765 show the cursor for the message instead of for the
4766 (now hidden) mini-buffer contents. */
4767 || (EQ (minibuf_window, selected_window)
4768 && EQ (minibuf_window, echo_area_window)
4769 && !NILP (echo_area_buffer[0])))
4770 /* These cases apply only to the frame that contains
4771 the active mini-buffer window. */
4772 && FRAME_HAS_MINIBUF_P (f)
4773 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4775 int top = XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top);
4776 int row, col;
4778 if (cursor_in_echo_area < 0)
4780 /* Negative value of cursor_in_echo_area means put
4781 cursor at beginning of line. */
4782 row = top;
4783 col = 0;
4785 else
4787 /* Positive value of cursor_in_echo_area means put
4788 cursor at the end of the prompt. If the mini-buffer
4789 is several lines high, find the last line that has
4790 any text on it. */
4791 row = FRAME_HEIGHT (f);
4794 --row;
4795 col = 0;
4797 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
4799 /* Frame rows are filled up with spaces that
4800 must be ignored here. */
4801 struct glyph_row *r = MATRIX_ROW (current_matrix,
4802 row);
4803 struct glyph *start = r->glyphs[TEXT_AREA];
4804 struct glyph *last = start + r->used[TEXT_AREA];
4806 while (last > start
4807 && (last - 1)->charpos < 0)
4808 --last;
4810 col = last - start;
4813 while (row > top && col == 0);
4815 /* Make sure COL is not out of range. */
4816 if (col >= FRAME_CURSOR_X_LIMIT (f))
4818 /* If we have another row, advance cursor into it. */
4819 if (row < FRAME_HEIGHT (f) - 1)
4821 col = FRAME_LEFT_SCROLL_BAR_WIDTH (f);
4822 row++;
4824 /* Otherwise move it back in range. */
4825 else
4826 col = FRAME_CURSOR_X_LIMIT (f) - 1;
4830 cursor_to (row, col);
4832 else
4834 /* We have only one cursor on terminal frames. Use it to
4835 display the cursor of the selected window. */
4836 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
4837 if (w->cursor.vpos >= 0
4838 /* The cursor vpos may be temporarily out of bounds
4839 in the following situation: There is one window,
4840 with the cursor in the lower half of it. The window
4841 is split, and a message causes a redisplay before
4842 a new cursor position has been computed. */
4843 && w->cursor.vpos < XFASTINT (w->height))
4845 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
4846 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
4848 if (INTEGERP (w->left_margin_width))
4849 x += XFASTINT (w->left_margin_width);
4851 /* x = max (min (x, FRAME_WINDOW_WIDTH (f) - 1), 0); */
4852 cursor_to (y, x);
4857 update_end (f);
4859 if (termscript)
4860 fflush (termscript);
4861 fflush (stdout);
4863 do_pause:
4865 display_completed = !pause;
4866 clear_desired_matrices (f);
4867 return pause;
4871 /* Do line insertions/deletions on frame F for frame-based redisplay. */
4874 scrolling (frame)
4875 struct frame *frame;
4877 int unchanged_at_top, unchanged_at_bottom;
4878 int window_size;
4879 int changed_lines;
4880 int *old_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4881 int *new_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4882 int *draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4883 int *old_draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4884 register int i;
4885 int free_at_end_vpos = FRAME_HEIGHT (frame);
4886 struct glyph_matrix *current_matrix = frame->current_matrix;
4887 struct glyph_matrix *desired_matrix = frame->desired_matrix;
4889 if (!current_matrix)
4890 abort ();
4892 /* Compute hash codes of all the lines. Also calculate number of
4893 changed lines, number of unchanged lines at the beginning, and
4894 number of unchanged lines at the end. */
4895 changed_lines = 0;
4896 unchanged_at_top = 0;
4897 unchanged_at_bottom = FRAME_HEIGHT (frame);
4898 for (i = 0; i < FRAME_HEIGHT (frame); i++)
4900 /* Give up on this scrolling if some old lines are not enabled. */
4901 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
4902 return 0;
4903 old_hash[i] = line_hash_code (MATRIX_ROW (current_matrix, i));
4904 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
4906 /* This line cannot be redrawn, so don't let scrolling mess it. */
4907 new_hash[i] = old_hash[i];
4908 #define INFINITY 1000000 /* Taken from scroll.c */
4909 draw_cost[i] = INFINITY;
4911 else
4913 new_hash[i] = line_hash_code (MATRIX_ROW (desired_matrix, i));
4914 draw_cost[i] = line_draw_cost (desired_matrix, i);
4917 if (old_hash[i] != new_hash[i])
4919 changed_lines++;
4920 unchanged_at_bottom = FRAME_HEIGHT (frame) - i - 1;
4922 else if (i == unchanged_at_top)
4923 unchanged_at_top++;
4924 old_draw_cost[i] = line_draw_cost (current_matrix, i);
4927 /* If changed lines are few, don't allow preemption, don't scroll. */
4928 if ((!scroll_region_ok && changed_lines < baud_rate / 2400)
4929 || unchanged_at_bottom == FRAME_HEIGHT (frame))
4930 return 1;
4932 window_size = (FRAME_HEIGHT (frame) - unchanged_at_top
4933 - unchanged_at_bottom);
4935 if (scroll_region_ok)
4936 free_at_end_vpos -= unchanged_at_bottom;
4937 else if (memory_below_frame)
4938 free_at_end_vpos = -1;
4940 /* If large window, fast terminal and few lines in common between
4941 current frame and desired frame, don't bother with i/d calc. */
4942 if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400
4943 && (window_size >=
4944 10 * scrolling_max_lines_saved (unchanged_at_top,
4945 FRAME_HEIGHT (frame) - unchanged_at_bottom,
4946 old_hash, new_hash, draw_cost)))
4947 return 0;
4949 if (window_size < 2)
4950 return 0;
4952 scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
4953 draw_cost + unchanged_at_top - 1,
4954 old_draw_cost + unchanged_at_top - 1,
4955 old_hash + unchanged_at_top - 1,
4956 new_hash + unchanged_at_top - 1,
4957 free_at_end_vpos - unchanged_at_top);
4959 return 0;
4963 /* Count the number of blanks at the start of the vector of glyphs R
4964 which is LEN glyphs long. */
4966 static int
4967 count_blanks (r, len)
4968 struct glyph *r;
4969 int len;
4971 int i;
4973 for (i = 0; i < len; ++i)
4974 if (!CHAR_GLYPH_SPACE_P (r[i]))
4975 break;
4977 return i;
4981 /* Count the number of glyphs in common at the start of the glyph
4982 vectors STR1 and STR2. END1 is the end of STR1 and END2 is the end
4983 of STR2. Value is the number of equal glyphs equal at the start. */
4985 static int
4986 count_match (str1, end1, str2, end2)
4987 struct glyph *str1, *end1, *str2, *end2;
4989 struct glyph *p1 = str1;
4990 struct glyph *p2 = str2;
4992 while (p1 < end1
4993 && p2 < end2
4994 && GLYPH_CHAR_AND_FACE_EQUAL_P (p1, p2))
4995 ++p1, ++p2;
4997 return p1 - str1;
5001 /* Char insertion/deletion cost vector, from term.c */
5003 extern int *char_ins_del_vector;
5004 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))])
5007 /* Perform a frame-based update on line VPOS in frame FRAME. */
5009 static void
5010 update_frame_line (frame, vpos)
5011 register struct frame *frame;
5012 int vpos;
5014 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
5015 int tem;
5016 int osp, nsp, begmatch, endmatch, olen, nlen;
5017 struct glyph_matrix *current_matrix = frame->current_matrix;
5018 struct glyph_matrix *desired_matrix = frame->desired_matrix;
5019 struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
5020 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
5021 int must_write_whole_line_p;
5023 if (desired_row->inverse_p
5024 != (current_row->enabled_p && current_row->inverse_p))
5026 int n = current_row->enabled_p ? current_row->used[TEXT_AREA] : 0;
5027 change_line_highlight (desired_row->inverse_p, vpos, vpos, n);
5028 current_row->enabled_p = 0;
5030 else
5031 reassert_line_highlight (desired_row->inverse_p, vpos);
5033 /* Current row not enabled means it has unknown contents. We must
5034 write the whole desired line in that case. */
5035 must_write_whole_line_p = !current_row->enabled_p;
5036 if (must_write_whole_line_p)
5038 obody = 0;
5039 olen = 0;
5041 else
5043 obody = MATRIX_ROW_GLYPH_START (current_matrix, vpos);
5044 olen = current_row->used[TEXT_AREA];
5046 if (! current_row->inverse_p)
5048 /* Ignore trailing spaces, if we can. */
5049 if (!must_write_spaces)
5050 while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
5051 olen--;
5053 else
5055 /* For an inverse-video line, make sure it's filled with
5056 spaces all the way to the frame edge so that the reverse
5057 video extends all the way across. */
5058 while (olen < FRAME_WIDTH (frame) - 1)
5059 obody[olen++] = space_glyph;
5063 current_row->enabled_p = 1;
5064 current_row->used[TEXT_AREA] = desired_row->used[TEXT_AREA];
5065 current_row->inverse_p = desired_row->inverse_p;
5067 /* If desired line is empty, just clear the line. */
5068 if (!desired_row->enabled_p)
5070 nlen = 0;
5071 goto just_erase;
5074 nbody = desired_row->glyphs[TEXT_AREA];
5075 nlen = desired_row->used[TEXT_AREA];
5076 nend = nbody + nlen;
5078 /* If display line has unknown contents, write the whole line. */
5079 if (must_write_whole_line_p)
5081 /* Ignore spaces at the end, if we can. */
5082 if (!must_write_spaces)
5083 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
5084 --nlen;
5086 /* Write the contents of the desired line. */
5087 if (nlen)
5089 cursor_to (vpos, 0);
5090 write_glyphs (nbody, nlen);
5093 /* Don't call clear_end_of_line if we already wrote the whole
5094 line. The cursor will not be at the right margin in that
5095 case but in the line below. */
5096 if (nlen < FRAME_WINDOW_WIDTH (frame))
5098 cursor_to (vpos, nlen);
5099 clear_end_of_line (FRAME_WINDOW_WIDTH (frame));
5101 else
5102 /* Make sure we are in the right row, otherwise cursor movement
5103 with cmgoto might use `ch' in the wrong row. */
5104 cursor_to (vpos, 0);
5106 make_current (desired_matrix, current_matrix, vpos);
5107 return;
5110 /* Pretend trailing spaces are not there at all,
5111 unless for one reason or another we must write all spaces. */
5112 if (!desired_row->inverse_p)
5114 if (!must_write_spaces)
5115 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
5116 nlen--;
5118 else
5120 /* For an inverse-video line, give it extra trailing spaces all
5121 the way to the frame edge so that the reverse video extends
5122 all the way across. */
5123 while (nlen < FRAME_WIDTH (frame) - 1)
5124 nbody[nlen++] = space_glyph;
5127 /* If there's no i/d char, quickly do the best we can without it. */
5128 if (!char_ins_del_ok)
5130 int i, j;
5132 /* Find the first glyph in desired row that doesn't agree with
5133 a glyph in the current row, and write the rest from there on. */
5134 for (i = 0; i < nlen; i++)
5136 if (i >= olen || !GLYPH_EQUAL_P (nbody + i, obody + i))
5138 /* Find the end of the run of different glyphs. */
5139 j = i + 1;
5140 while (j < nlen
5141 && (j >= olen
5142 || !GLYPH_EQUAL_P (nbody + j, obody + j)
5143 || CHAR_GLYPH_PADDING_P (nbody[j])))
5144 ++j;
5146 /* Output this run of non-matching chars. */
5147 cursor_to (vpos, i);
5148 write_glyphs (nbody + i, j - i);
5149 i = j - 1;
5151 /* Now find the next non-match. */
5155 /* Clear the rest of the line, or the non-clear part of it. */
5156 if (olen > nlen)
5158 cursor_to (vpos, nlen);
5159 clear_end_of_line (olen);
5162 /* Make current row = desired row. */
5163 make_current (desired_matrix, current_matrix, vpos);
5164 return;
5167 /* Here when CHAR_INS_DEL_OK != 0, i.e. we can insert or delete
5168 characters in a row. */
5170 if (!olen)
5172 /* If current line is blank, skip over initial spaces, if
5173 possible, and write the rest. */
5174 if (must_write_spaces || desired_row->inverse_p)
5175 nsp = 0;
5176 else
5177 nsp = count_blanks (nbody, nlen);
5179 if (nlen > nsp)
5181 cursor_to (vpos, nsp);
5182 write_glyphs (nbody + nsp, nlen - nsp);
5185 /* Exchange contents between current_frame and new_frame. */
5186 make_current (desired_matrix, current_matrix, vpos);
5187 return;
5190 /* Compute number of leading blanks in old and new contents. */
5191 osp = count_blanks (obody, olen);
5192 nsp = desired_row->inverse_p ? 0 : count_blanks (nbody, nlen);
5194 /* Compute number of matching chars starting with first non-blank. */
5195 begmatch = count_match (obody + osp, obody + olen,
5196 nbody + nsp, nbody + nlen);
5198 /* Spaces in new match implicit space past the end of old. */
5199 /* A bug causing this to be a no-op was fixed in 18.29. */
5200 if (!must_write_spaces && osp + begmatch == olen)
5202 np1 = nbody + nsp;
5203 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (np1[begmatch]))
5204 ++begmatch;
5207 /* Avoid doing insert/delete char
5208 just cause number of leading spaces differs
5209 when the following text does not match. */
5210 if (begmatch == 0 && osp != nsp)
5211 osp = nsp = min (osp, nsp);
5213 /* Find matching characters at end of line */
5214 op1 = obody + olen;
5215 np1 = nbody + nlen;
5216 op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
5217 while (op1 > op2
5218 && GLYPH_EQUAL_P (op1 - 1, np1 - 1))
5220 op1--;
5221 np1--;
5223 endmatch = obody + olen - op1;
5225 /* tem gets the distance to insert or delete.
5226 endmatch is how many characters we save by doing so.
5227 Is it worth it? */
5229 tem = (nlen - nsp) - (olen - osp);
5230 if (endmatch && tem
5231 && (!char_ins_del_ok || endmatch <= char_ins_del_cost (frame)[tem]))
5232 endmatch = 0;
5234 /* nsp - osp is the distance to insert or delete.
5235 If that is nonzero, begmatch is known to be nonzero also.
5236 begmatch + endmatch is how much we save by doing the ins/del.
5237 Is it worth it? */
5239 if (nsp != osp
5240 && (!char_ins_del_ok
5241 || begmatch + endmatch <= char_ins_del_cost (frame)[nsp - osp]))
5243 begmatch = 0;
5244 endmatch = 0;
5245 osp = nsp = min (osp, nsp);
5248 /* Now go through the line, inserting, writing and
5249 deleting as appropriate. */
5251 if (osp > nsp)
5253 cursor_to (vpos, nsp);
5254 delete_glyphs (osp - nsp);
5256 else if (nsp > osp)
5258 /* If going to delete chars later in line
5259 and insert earlier in the line,
5260 must delete first to avoid losing data in the insert */
5261 if (endmatch && nlen < olen + nsp - osp)
5263 cursor_to (vpos, nlen - endmatch + osp - nsp);
5264 delete_glyphs (olen + nsp - osp - nlen);
5265 olen = nlen - (nsp - osp);
5267 cursor_to (vpos, osp);
5268 insert_glyphs (0, nsp - osp);
5270 olen += nsp - osp;
5272 tem = nsp + begmatch + endmatch;
5273 if (nlen != tem || olen != tem)
5275 cursor_to (vpos, nsp + begmatch);
5276 if (!endmatch || nlen == olen)
5278 /* If new text being written reaches right margin,
5279 there is no need to do clear-to-eol at the end.
5280 (and it would not be safe, since cursor is not
5281 going to be "at the margin" after the text is done) */
5282 if (nlen == FRAME_WINDOW_WIDTH (frame))
5283 olen = 0;
5284 write_glyphs (nbody + nsp + begmatch, nlen - tem);
5286 else if (nlen > olen)
5288 /* Here, we used to have the following simple code:
5289 ----------------------------------------
5290 write_glyphs (nbody + nsp + begmatch, olen - tem);
5291 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
5292 ----------------------------------------
5293 but it doesn't work if nbody[nsp + begmatch + olen - tem]
5294 is a padding glyph. */
5295 int out = olen - tem; /* Columns to be overwritten originally. */
5296 int del;
5298 /* Calculate columns we can actually overwrite. */
5299 while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out])) out--;
5300 write_glyphs (nbody + nsp + begmatch, out);
5301 /* If we left columns to be overwritten, we must delete them. */
5302 del = olen - tem - out;
5303 if (del > 0) delete_glyphs (del);
5304 /* At last, we insert columns not yet written out. */
5305 insert_glyphs (nbody + nsp + begmatch + out, nlen - olen + del);
5306 olen = nlen;
5308 else if (olen > nlen)
5310 write_glyphs (nbody + nsp + begmatch, nlen - tem);
5311 delete_glyphs (olen - nlen);
5312 olen = nlen;
5316 just_erase:
5317 /* If any unerased characters remain after the new line, erase them. */
5318 if (olen > nlen)
5320 cursor_to (vpos, nlen);
5321 clear_end_of_line (olen);
5324 /* Exchange contents between current_frame and new_frame. */
5325 make_current (desired_matrix, current_matrix, vpos);
5330 /***********************************************************************
5331 X/Y Position -> Buffer Position
5332 ***********************************************************************/
5334 /* Return the character position of the character at window relative
5335 pixel position (*X, *Y). *X and *Y are adjusted to character
5336 boundaries. */
5339 buffer_posn_from_coords (w, x, y)
5340 struct window *w;
5341 int *x, *y;
5343 struct it it;
5344 struct buffer *old_current_buffer = current_buffer;
5345 struct text_pos startp;
5346 int left_area_width;
5348 current_buffer = XBUFFER (w->buffer);
5349 SET_TEXT_POS_FROM_MARKER (startp, w->start);
5350 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
5351 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
5352 start_display (&it, w, startp);
5354 left_area_width = WINDOW_DISPLAY_LEFT_AREA_PIXEL_WIDTH (w);
5355 move_it_to (&it, -1, *x + it.first_visible_x - left_area_width, *y, -1,
5356 MOVE_TO_X | MOVE_TO_Y);
5358 *x = it.current_x - it.first_visible_x + left_area_width;
5359 *y = it.current_y;
5360 current_buffer = old_current_buffer;
5361 return IT_CHARPOS (it);
5365 /* Value is the string under window-relative coordinates X/Y in the
5366 mode or top line of window W, or nil if none. MODE_LINE_P non-zero
5367 means look at the mode line. *CHARPOS is set to the position in
5368 the string returned. */
5370 Lisp_Object
5371 mode_line_string (w, x, y, mode_line_p, charpos)
5372 struct window *w;
5373 int x, y;
5374 int *charpos;
5376 struct glyph_row *row;
5377 struct glyph *glyph, *end;
5378 struct frame *f = XFRAME (w->frame);
5379 int x0;
5380 Lisp_Object string = Qnil;
5382 if (mode_line_p)
5383 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
5384 else
5385 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
5387 if (row->mode_line_p && row->enabled_p)
5389 /* The mode lines are displayed over scroll bars and bitmap
5390 areas, and X is window-relative. Correct X by the scroll bar
5391 and bitmap area width. */
5392 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
5393 x += FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
5394 x += FRAME_LEFT_FLAGS_AREA_WIDTH (f);
5396 /* Find the glyph under X. If we find one with a string object,
5397 it's the one we were looking for. */
5398 glyph = row->glyphs[TEXT_AREA];
5399 end = glyph + row->used[TEXT_AREA];
5400 for (x0 = 0; glyph < end; x0 += glyph->pixel_width, ++glyph)
5401 if (x >= x0 && x < x0 + glyph->pixel_width)
5403 string = glyph->object;
5404 *charpos = glyph->charpos;
5405 break;
5409 return string;
5413 /***********************************************************************
5414 Changing Frame Sizes
5415 ***********************************************************************/
5417 #ifdef SIGWINCH
5419 SIGTYPE
5420 window_change_signal (signalnum) /* If we don't have an argument, */
5421 int signalnum; /* some compilers complain in signal calls. */
5423 int width, height;
5424 extern int errno;
5425 int old_errno = errno;
5427 get_frame_size (&width, &height);
5429 /* The frame size change obviously applies to a termcap-controlled
5430 frame. Find such a frame in the list, and assume it's the only
5431 one (since the redisplay code always writes to stdout, not a
5432 FILE * specified in the frame structure). Record the new size,
5433 but don't reallocate the data structures now. Let that be done
5434 later outside of the signal handler. */
5437 Lisp_Object tail, frame;
5439 FOR_EACH_FRAME (tail, frame)
5441 if (FRAME_TERMCAP_P (XFRAME (frame)))
5443 change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
5444 break;
5449 signal (SIGWINCH, window_change_signal);
5450 errno = old_errno;
5452 #endif /* SIGWINCH */
5455 /* Do any change in frame size that was requested by a signal. SAFE
5456 non-zero means this function is called from a place where it is
5457 safe to change frame sizes while a redisplay is in progress. */
5459 void
5460 do_pending_window_change (safe)
5461 int safe;
5463 /* If window_change_signal should have run before, run it now. */
5464 if (redisplaying_p && !safe)
5465 return;
5467 while (delayed_size_change)
5469 Lisp_Object tail, frame;
5471 delayed_size_change = 0;
5473 FOR_EACH_FRAME (tail, frame)
5475 struct frame *f = XFRAME (frame);
5477 int height = FRAME_NEW_HEIGHT (f);
5478 int width = FRAME_NEW_WIDTH (f);
5480 if (height != 0 || width != 0)
5481 change_frame_size (f, height, width, 0, 0, safe);
5487 /* Change the frame height and/or width. Values may be given as zero to
5488 indicate no change is to take place.
5490 If DELAY is non-zero, then assume we're being called from a signal
5491 handler, and queue the change for later - perhaps the next
5492 redisplay. Since this tries to resize windows, we can't call it
5493 from a signal handler.
5495 SAFE non-zero means this function is called from a place where it's
5496 safe to change frame sizes while a redisplay is in progress. */
5498 void
5499 change_frame_size (f, newheight, newwidth, pretend, delay, safe)
5500 register struct frame *f;
5501 int newheight, newwidth, pretend, delay, safe;
5503 Lisp_Object tail, frame;
5505 if (! FRAME_WINDOW_P (f))
5507 /* When using termcap, or on MS-DOS, all frames use
5508 the same screen, so a change in size affects all frames. */
5509 FOR_EACH_FRAME (tail, frame)
5510 if (! FRAME_WINDOW_P (XFRAME (frame)))
5511 change_frame_size_1 (XFRAME (frame), newheight, newwidth,
5512 pretend, delay, safe);
5514 else
5515 change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe);
5518 static void
5519 change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
5520 register struct frame *f;
5521 int newheight, newwidth, pretend, delay, safe;
5523 int new_frame_window_width;
5524 int count = specpdl_ptr - specpdl;
5526 /* If we can't deal with the change now, queue it for later. */
5527 if (delay || (redisplaying_p && !safe))
5529 FRAME_NEW_HEIGHT (f) = newheight;
5530 FRAME_NEW_WIDTH (f) = newwidth;
5531 delayed_size_change = 1;
5532 return;
5535 /* This size-change overrides any pending one for this frame. */
5536 FRAME_NEW_HEIGHT (f) = 0;
5537 FRAME_NEW_WIDTH (f) = 0;
5539 /* If an argument is zero, set it to the current value. */
5540 if (newheight == 0)
5541 newheight = FRAME_HEIGHT (f);
5542 if (newwidth == 0)
5543 newwidth = FRAME_WIDTH (f);
5545 /* Compute width of windows in F.
5546 This is the width of the frame without vertical scroll bars. */
5547 new_frame_window_width = FRAME_WINDOW_WIDTH_ARG (f, newwidth);
5549 /* Round up to the smallest acceptable size. */
5550 check_frame_size (f, &newheight, &newwidth);
5552 /* If we're not changing the frame size, quit now. */
5553 if (newheight == FRAME_HEIGHT (f)
5554 && new_frame_window_width == FRAME_WINDOW_WIDTH (f))
5555 return;
5557 BLOCK_INPUT;
5559 #ifdef MSDOS
5560 /* We only can set screen dimensions to certain values supported
5561 by our video hardware. Try to find the smallest size greater
5562 or equal to the requested dimensions. */
5563 dos_set_window_size (&newheight, &newwidth);
5564 #endif
5566 if (newheight != FRAME_HEIGHT (f))
5568 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
5570 /* Frame has both root and mini-buffer. */
5571 XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top,
5572 FRAME_TOP_MARGIN (f));
5573 set_window_height (FRAME_ROOT_WINDOW (f),
5574 (newheight
5576 - FRAME_TOP_MARGIN (f)),
5578 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top,
5579 newheight - 1);
5580 set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
5582 else
5583 /* Frame has just one top-level window. */
5584 set_window_height (FRAME_ROOT_WINDOW (f),
5585 newheight - FRAME_TOP_MARGIN (f), 0);
5587 if (FRAME_TERMCAP_P (f) && !pretend)
5588 FrameRows = newheight;
5591 if (new_frame_window_width != FRAME_WINDOW_WIDTH (f))
5593 set_window_width (FRAME_ROOT_WINDOW (f), new_frame_window_width, 0);
5594 if (FRAME_HAS_MINIBUF_P (f))
5595 set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_window_width, 0);
5597 if (FRAME_TERMCAP_P (f) && !pretend)
5598 FrameCols = newwidth;
5600 if (WINDOWP (f->tool_bar_window))
5601 XSETFASTINT (XWINDOW (f->tool_bar_window)->width, newwidth);
5604 FRAME_HEIGHT (f) = newheight;
5605 SET_FRAME_WIDTH (f, newwidth);
5608 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5609 int text_area_x, text_area_y, text_area_width, text_area_height;
5611 window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width,
5612 &text_area_height);
5613 if (w->cursor.x >= text_area_x + text_area_width)
5614 w->cursor.hpos = w->cursor.x = 0;
5615 if (w->cursor.y >= text_area_y + text_area_height)
5616 w->cursor.vpos = w->cursor.y = 0;
5619 adjust_glyphs (f);
5620 SET_FRAME_GARBAGED (f);
5621 calculate_costs (f);
5623 UNBLOCK_INPUT;
5625 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
5627 /* This isn't quite a no-op: it runs window-configuration-change-hook. */
5628 Fset_window_buffer (FRAME_SELECTED_WINDOW (f),
5629 XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer);
5631 unbind_to (count, Qnil);
5636 /***********************************************************************
5637 Terminal Related Lisp Functions
5638 ***********************************************************************/
5640 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
5641 1, 1, "FOpen termscript file: ",
5642 "Start writing all terminal output to FILE as well as the terminal.\n\
5643 FILE = nil means just close any termscript file currently open.")
5644 (file)
5645 Lisp_Object file;
5647 if (termscript != 0) fclose (termscript);
5648 termscript = 0;
5650 if (! NILP (file))
5652 file = Fexpand_file_name (file, Qnil);
5653 termscript = fopen (XSTRING (file)->data, "w");
5654 if (termscript == 0)
5655 report_file_error ("Opening termscript", Fcons (file, Qnil));
5657 return Qnil;
5661 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
5662 Ssend_string_to_terminal, 1, 1, 0,
5663 "Send STRING to the terminal without alteration.\n\
5664 Control characters in STRING will have terminal-dependent effects.")
5665 (string)
5666 Lisp_Object string;
5668 /* ??? Perhaps we should do something special for multibyte strings here. */
5669 CHECK_STRING (string, 0);
5670 fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)), stdout);
5671 fflush (stdout);
5672 if (termscript)
5674 fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)),
5675 termscript);
5676 fflush (termscript);
5678 return Qnil;
5682 DEFUN ("ding", Fding, Sding, 0, 1, 0,
5683 "Beep, or flash the screen.\n\
5684 Also, unless an argument is given,\n\
5685 terminate any keyboard macro currently executing.")
5686 (arg)
5687 Lisp_Object arg;
5689 if (!NILP (arg))
5691 if (noninteractive)
5692 putchar (07);
5693 else
5694 ring_bell ();
5695 fflush (stdout);
5697 else
5698 bitch_at_user ();
5700 return Qnil;
5703 void
5704 bitch_at_user ()
5706 if (noninteractive)
5707 putchar (07);
5708 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
5709 error ("Keyboard macro terminated by a command ringing the bell");
5710 else
5711 ring_bell ();
5712 fflush (stdout);
5717 /***********************************************************************
5718 Sleeping, Waiting
5719 ***********************************************************************/
5721 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
5722 "Pause, without updating display, for SECONDS seconds.\n\
5723 SECONDS may be a floating-point value, meaning that you can wait for a\n\
5724 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
5725 additional wait period, in milliseconds; this may be useful if your\n\
5726 Emacs was built without floating point support.\n\
5727 \(Not all operating systems support waiting for a fraction of a second.)")
5728 (seconds, milliseconds)
5729 Lisp_Object seconds, milliseconds;
5731 int sec, usec;
5733 if (NILP (milliseconds))
5734 XSETINT (milliseconds, 0);
5735 else
5736 CHECK_NUMBER (milliseconds, 1);
5737 usec = XINT (milliseconds) * 1000;
5740 double duration = extract_float (seconds);
5741 sec = (int) duration;
5742 usec += (duration - sec) * 1000000;
5745 #ifndef EMACS_HAS_USECS
5746 if (sec == 0 && usec != 0)
5747 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
5748 #endif
5750 /* Assure that 0 <= usec < 1000000. */
5751 if (usec < 0)
5753 /* We can't rely on the rounding being correct if user is negative. */
5754 if (-1000000 < usec)
5755 sec--, usec += 1000000;
5756 else
5757 sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
5759 else
5760 sec += usec / 1000000, usec %= 1000000;
5762 if (sec < 0 || (sec == 0 && usec == 0))
5763 return Qnil;
5766 Lisp_Object zero;
5768 XSETFASTINT (zero, 0);
5769 wait_reading_process_input (sec, usec, zero, 0);
5772 /* We should always have wait_reading_process_input; we have a dummy
5773 implementation for systems which don't support subprocesses. */
5774 #if 0
5775 /* No wait_reading_process_input */
5776 immediate_quit = 1;
5777 QUIT;
5779 #ifdef VMS
5780 sys_sleep (sec);
5781 #else /* not VMS */
5782 /* The reason this is done this way
5783 (rather than defined (H_S) && defined (H_T))
5784 is because the VMS preprocessor doesn't grok `defined' */
5785 #ifdef HAVE_SELECT
5786 EMACS_GET_TIME (end_time);
5787 EMACS_SET_SECS_USECS (timeout, sec, usec);
5788 EMACS_ADD_TIME (end_time, end_time, timeout);
5790 while (1)
5792 EMACS_GET_TIME (timeout);
5793 EMACS_SUB_TIME (timeout, end_time, timeout);
5794 if (EMACS_TIME_NEG_P (timeout)
5795 || !select (1, 0, 0, 0, &timeout))
5796 break;
5798 #else /* not HAVE_SELECT */
5799 sleep (sec);
5800 #endif /* HAVE_SELECT */
5801 #endif /* not VMS */
5803 immediate_quit = 0;
5804 #endif /* no subprocesses */
5806 return Qnil;
5810 /* This is just like wait_reading_process_input, except that
5811 it does the redisplay.
5813 It's also much like Fsit_for, except that it can be used for
5814 waiting for input as well. */
5816 Lisp_Object
5817 sit_for (sec, usec, reading, display, initial_display)
5818 int sec, usec, reading, display, initial_display;
5820 Lisp_Object read_kbd;
5822 swallow_events (display);
5824 if (detect_input_pending_run_timers (display))
5825 return Qnil;
5827 if (initial_display)
5828 redisplay_preserve_echo_area ();
5830 if (sec == 0 && usec == 0)
5831 return Qt;
5833 #ifdef SIGIO
5834 gobble_input (0);
5835 #endif
5837 XSETINT (read_kbd, reading ? -1 : 1);
5838 wait_reading_process_input (sec, usec, read_kbd, display);
5840 return detect_input_pending () ? Qnil : Qt;
5844 DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
5845 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
5846 SECONDS may be a floating-point value, meaning that you can wait for a\n\
5847 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
5848 additional wait period, in milliseconds; this may be useful if your\n\
5849 Emacs was built without floating point support.\n\
5850 \(Not all operating systems support waiting for a fraction of a second.)\n\
5851 Optional third arg NODISP non-nil means don't redisplay, just wait for input.\n\
5852 Redisplay is preempted as always if input arrives, and does not happen\n\
5853 if input is available before it starts.\n\
5854 Value is t if waited the full time with no input arriving.")
5855 (seconds, milliseconds, nodisp)
5856 Lisp_Object seconds, milliseconds, nodisp;
5858 int sec, usec;
5860 if (NILP (milliseconds))
5861 XSETINT (milliseconds, 0);
5862 else
5863 CHECK_NUMBER (milliseconds, 1);
5864 usec = XINT (milliseconds) * 1000;
5867 double duration = extract_float (seconds);
5868 sec = (int) duration;
5869 usec += (duration - sec) * 1000000;
5872 #ifndef EMACS_HAS_USECS
5873 if (usec != 0 && sec == 0)
5874 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE);
5875 #endif
5877 return sit_for (sec, usec, 0, NILP (nodisp), NILP (nodisp));
5882 /***********************************************************************
5883 Other Lisp Functions
5884 ***********************************************************************/
5886 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
5887 session's frames, frame names, buffers, buffer-read-only flags, and
5888 buffer-modified-flags, and a trailing sentinel (so we don't need to
5889 add length checks). */
5891 static Lisp_Object frame_and_buffer_state;
5894 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
5895 Sframe_or_buffer_changed_p, 0, 0, 0,
5896 "Return non-nil if the frame and buffer state appears to have changed.\n\
5897 The state variable is an internal vector containing all frames and buffers,\n\
5898 aside from buffers whose names start with space,\n\
5899 along with the buffers' read-only and modified flags, which allows a fast\n\
5900 check to see whether the menu bars might need to be recomputed.\n\
5901 If this function returns non-nil, it updates the internal vector to reflect\n\
5902 the current state.\n")
5905 Lisp_Object tail, frame, buf;
5906 Lisp_Object *vecp;
5907 int n;
5909 vecp = XVECTOR (frame_and_buffer_state)->contents;
5910 FOR_EACH_FRAME (tail, frame)
5912 if (!EQ (*vecp++, frame))
5913 goto changed;
5914 if (!EQ (*vecp++, XFRAME (frame)->name))
5915 goto changed;
5917 /* Check that the buffer info matches.
5918 No need to test for the end of the vector
5919 because the last element of the vector is lambda
5920 and that will always cause a mismatch. */
5921 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
5923 buf = XCDR (XCAR (tail));
5924 /* Ignore buffers that aren't included in buffer lists. */
5925 if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
5926 continue;
5927 if (!EQ (*vecp++, buf))
5928 goto changed;
5929 if (!EQ (*vecp++, XBUFFER (buf)->read_only))
5930 goto changed;
5931 if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
5932 goto changed;
5934 /* Detect deletion of a buffer at the end of the list. */
5935 if (EQ (*vecp, Qlambda))
5936 return Qnil;
5937 changed:
5938 /* Start with 1 so there is room for at least one lambda at the end. */
5939 n = 1;
5940 FOR_EACH_FRAME (tail, frame)
5941 n += 2;
5942 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
5943 n += 3;
5944 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
5945 if (n > XVECTOR (frame_and_buffer_state)->size
5946 || n + 20 < XVECTOR (frame_and_buffer_state)->size / 2)
5947 /* Add 20 extra so we grow it less often. */
5948 frame_and_buffer_state = Fmake_vector (make_number (n + 20), Qlambda);
5949 vecp = XVECTOR (frame_and_buffer_state)->contents;
5950 FOR_EACH_FRAME (tail, frame)
5952 *vecp++ = frame;
5953 *vecp++ = XFRAME (frame)->name;
5955 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
5957 buf = XCDR (XCAR (tail));
5958 /* Ignore buffers that aren't included in buffer lists. */
5959 if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
5960 continue;
5961 *vecp++ = buf;
5962 *vecp++ = XBUFFER (buf)->read_only;
5963 *vecp++ = Fbuffer_modified_p (buf);
5965 /* Fill up the vector with lambdas (always at least one). */
5966 *vecp++ = Qlambda;
5967 while (vecp - XVECTOR (frame_and_buffer_state)->contents
5968 < XVECTOR (frame_and_buffer_state)->size)
5969 *vecp++ = Qlambda;
5970 /* Make sure we didn't overflow the vector. */
5971 if (vecp - XVECTOR (frame_and_buffer_state)->contents
5972 > XVECTOR (frame_and_buffer_state)->size)
5973 abort ();
5974 return Qt;
5979 /***********************************************************************
5980 Initialization
5981 ***********************************************************************/
5983 char *terminal_type;
5985 /* Initialization done when Emacs fork is started, before doing stty.
5986 Determine terminal type and set terminal_driver. Then invoke its
5987 decoding routine to set up variables in the terminal package. */
5989 void
5990 init_display ()
5992 #ifdef HAVE_X_WINDOWS
5993 extern int display_arg;
5994 #endif
5996 /* Construct the space glyph. */
5997 space_glyph.type = CHAR_GLYPH;
5998 SET_CHAR_GLYPH_FROM_GLYPH (space_glyph, ' ');
5999 space_glyph.charpos = -1;
6001 meta_key = 0;
6002 inverse_video = 0;
6003 cursor_in_echo_area = 0;
6004 terminal_type = (char *) 0;
6006 /* Now is the time to initialize this; it's used by init_sys_modes
6007 during startup. */
6008 Vwindow_system = Qnil;
6010 /* If the user wants to use a window system, we shouldn't bother
6011 initializing the terminal. This is especially important when the
6012 terminal is so dumb that emacs gives up before and doesn't bother
6013 using the window system.
6015 If the DISPLAY environment variable is set and nonempty,
6016 try to use X, and die with an error message if that doesn't work. */
6018 #ifdef HAVE_X_WINDOWS
6019 if (! display_arg)
6021 char *display;
6022 #ifdef VMS
6023 display = getenv ("DECW$DISPLAY");
6024 #else
6025 display = getenv ("DISPLAY");
6026 #endif
6028 display_arg = (display != 0 && *display != 0);
6031 if (!inhibit_window_system && display_arg
6032 #ifndef CANNOT_DUMP
6033 && initialized
6034 #endif
6037 Vwindow_system = intern ("x");
6038 #ifdef HAVE_X11
6039 Vwindow_system_version = make_number (11);
6040 #else
6041 Vwindow_system_version = make_number (10);
6042 #endif
6043 #if defined (LINUX) && defined (HAVE_LIBNCURSES)
6044 /* In some versions of ncurses,
6045 tputs crashes if we have not called tgetent.
6046 So call tgetent. */
6047 { char b[2044]; tgetent (b, "xterm");}
6048 #endif
6049 adjust_frame_glyphs_initially ();
6050 return;
6052 #endif /* HAVE_X_WINDOWS */
6054 #ifdef HAVE_NTGUI
6055 if (!inhibit_window_system)
6057 Vwindow_system = intern ("w32");
6058 Vwindow_system_version = make_number (1);
6059 adjust_frame_glyphs_initially ();
6060 return;
6062 #endif /* HAVE_NTGUI */
6064 /* If no window system has been specified, try to use the terminal. */
6065 if (! isatty (0))
6067 fatal ("standard input is not a tty");
6068 exit (1);
6071 /* Look at the TERM variable */
6072 terminal_type = (char *) getenv ("TERM");
6073 if (!terminal_type)
6075 #ifdef VMS
6076 fprintf (stderr, "Please specify your terminal type.\n\
6077 For types defined in VMS, use set term /device=TYPE.\n\
6078 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
6079 \(The quotation marks are necessary since terminal types are lower case.)\n");
6080 #else
6081 fprintf (stderr, "Please set the environment variable TERM; see tset(1).\n");
6082 #endif
6083 exit (1);
6086 #ifdef VMS
6087 /* VMS DCL tends to up-case things, so down-case term type.
6088 Hardly any uppercase letters in terminal types; should be none. */
6090 char *new = (char *) xmalloc (strlen (terminal_type) + 1);
6091 char *p;
6093 strcpy (new, terminal_type);
6095 for (p = new; *p; p++)
6096 if (isupper (*p))
6097 *p = tolower (*p);
6099 terminal_type = new;
6101 #endif /* VMS */
6103 term_init (terminal_type);
6106 struct frame *sf = SELECTED_FRAME ();
6107 int width = FRAME_WINDOW_WIDTH (sf);
6108 int height = FRAME_HEIGHT (sf);
6110 unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
6112 /* If these sizes are so big they cause overflow, just ignore the
6113 change. It's not clear what better we could do. */
6114 if (total_glyphs / sizeof (struct glyph) / height != width + 2)
6115 fatal ("screen size %dx%d too big", width, height);
6118 adjust_frame_glyphs_initially ();
6119 calculate_costs (XFRAME (selected_frame));
6121 #ifdef SIGWINCH
6122 #ifndef CANNOT_DUMP
6123 if (initialized)
6124 #endif /* CANNOT_DUMP */
6125 signal (SIGWINCH, window_change_signal);
6126 #endif /* SIGWINCH */
6128 /* Set up faces of the initial terminal frame of a dumped Emacs. */
6129 if (initialized
6130 && !noninteractive
6131 #ifdef MSDOS
6132 /* The MSDOS terminal turns on its ``window system'' relatively
6133 late into the startup, so we cannot do the frame faces'
6134 initialization just yet. It will be done later by pc-win.el
6135 and internal_terminal_init. */
6136 && (strcmp (terminal_type, "internal") != 0 || inhibit_window_system)
6137 #endif
6138 && NILP (Vwindow_system))
6140 /* For the initial frame, we don't have any way of knowing what
6141 are the foreground and background colors of the terminal. */
6142 struct frame *sf = SELECTED_FRAME();
6144 FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
6145 FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;
6146 call0 (intern ("tty-set-up-initial-frame-faces"));
6152 /***********************************************************************
6153 Blinking cursor
6154 ***********************************************************************/
6156 DEFUN ("internal-show-cursor", Finternal_show_cursor,
6157 Sinternal_show_cursor, 2, 2, 0,
6158 "Set the cursor-visibility flag of WINDOW to SHOW.\n\
6159 WINDOW nil means use the selected window. SHOW non-nil means\n\
6160 show a cursor in WINDOW in the next redisplay. SHOW nil means\n\
6161 don't show a cursor.")
6162 (window, show)
6163 Lisp_Object window, show;
6165 /* Don't change cursor state while redisplaying. This could confuse
6166 output routines. */
6167 if (!redisplaying_p)
6169 if (NILP (window))
6170 window = selected_window;
6171 else
6172 CHECK_WINDOW (window, 2);
6174 XWINDOW (window)->cursor_off_p = NILP (show);
6177 return Qnil;
6181 DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
6182 Sinternal_show_cursor_p, 0, 1, 0,
6183 "Value is non-nil if next redisplay will display a cursor in WINDOW.\n\
6184 WINDOW nil or omitted means report on the selected window.")
6185 (window)
6186 Lisp_Object window;
6188 struct window *w;
6190 if (NILP (window))
6191 window = selected_window;
6192 else
6193 CHECK_WINDOW (window, 2);
6195 w = XWINDOW (window);
6196 return w->cursor_off_p ? Qnil : Qt;
6200 /***********************************************************************
6201 Initialization
6202 ***********************************************************************/
6204 void
6205 syms_of_display ()
6207 defsubr (&Sredraw_frame);
6208 defsubr (&Sredraw_display);
6209 defsubr (&Sframe_or_buffer_changed_p);
6210 defsubr (&Sopen_termscript);
6211 defsubr (&Sding);
6212 defsubr (&Ssit_for);
6213 defsubr (&Ssleep_for);
6214 defsubr (&Ssend_string_to_terminal);
6215 defsubr (&Sinternal_show_cursor);
6216 defsubr (&Sinternal_show_cursor_p);
6218 frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
6219 staticpro (&frame_and_buffer_state);
6221 Qdisplay_table = intern ("display-table");
6222 staticpro (&Qdisplay_table);
6224 DEFVAR_INT ("baud-rate", &baud_rate,
6225 "*The output baud rate of the terminal.\n\
6226 On most systems, changing this value will affect the amount of padding\n\
6227 and the other strategic decisions made during redisplay.");
6229 DEFVAR_BOOL ("inverse-video", &inverse_video,
6230 "*Non-nil means invert the entire frame display.\n\
6231 This means everything is in inverse video which otherwise would not be.");
6233 DEFVAR_BOOL ("visible-bell", &visible_bell,
6234 "*Non-nil means try to flash the frame to represent a bell.");
6236 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
6237 "*Non-nil means no need to redraw entire frame after suspending.\n\
6238 A non-nil value is useful if the terminal can automatically preserve\n\
6239 Emacs's frame display when you reenter Emacs.\n\
6240 It is up to you to set this variable if your terminal can do that.");
6242 DEFVAR_LISP ("window-system", &Vwindow_system,
6243 "A symbol naming the window-system under which Emacs is running\n\
6244 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
6246 DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
6247 "The version number of the window system in use.\n\
6248 For X windows, this is 10 or 11.");
6250 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
6251 "Non-nil means put cursor in minibuffer, at end of any message there.");
6253 DEFVAR_LISP ("glyph-table", &Vglyph_table,
6254 "Table defining how to output a glyph code to the frame.\n\
6255 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
6256 Each element can be:\n\
6257 integer: a glyph code which this glyph is an alias for.\n\
6258 string: output this glyph using that string (not impl. in X windows).\n\
6259 nil: this glyph mod 256 is char code to output,\n\
6260 and this glyph / 256 is face code for X windows (see `face-id').");
6261 Vglyph_table = Qnil;
6263 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
6264 "Display table to use for buffers that specify none.\n\
6265 See `buffer-display-table' for more information.");
6266 Vstandard_display_table = Qnil;
6268 DEFVAR_BOOL ("redisplay-dont-pause", &redisplay_dont_pause,
6269 "*Non-nil means update isn't paused when input is detected.");
6270 redisplay_dont_pause = 0;
6272 /* Initialize `window-system', unless init_display already decided it. */
6273 #ifdef CANNOT_DUMP
6274 if (noninteractive)
6275 #endif
6277 Vwindow_system = Qnil;
6278 Vwindow_system_version = Qnil;