(fill-individual-paragraphs): Calculate new
[emacs.git] / src / dispnew.c
bloba7e3363e674cd3b7899e7648cd3adfc9bcdd80e2
1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 1998
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 <signal.h>
23 #include <config.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 #ifndef PENDING_OUTPUT_COUNT
95 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
96 #endif
97 #endif /* not __GNU_LIBRARY__ */
100 /* Structure to pass dimensions around. Used for character bounding
101 boxes, glyph matrix dimensions and alike. */
103 struct dim
105 int width;
106 int height;
110 /* Function prototypes. */
112 static int count_blanks P_ ((struct glyph *, int));
113 static int count_match P_ ((struct glyph *, struct glyph *,
114 struct glyph *, struct glyph *));
115 static unsigned line_draw_cost P_ ((struct glyph_matrix *, int));
116 static void update_frame_line P_ ((struct frame *, int));
117 static struct dim allocate_matrices_for_frame_redisplay
118 P_ ((Lisp_Object, int, int, struct dim, int, int *));
119 static void allocate_matrices_for_window_redisplay P_ ((struct window *,
120 struct dim));
121 static int realloc_glyph_pool P_ ((struct glyph_pool *, struct dim));
122 static void adjust_frame_glyphs P_ ((struct frame *));
123 struct glyph_matrix *new_glyph_matrix P_ ((struct glyph_pool *));
124 static void free_glyph_matrix P_ ((struct glyph_matrix *));
125 static void adjust_glyph_matrix P_ ((struct window *, struct glyph_matrix *,
126 int, int, struct dim));
127 static void change_frame_size_1 P_ ((struct frame *, int, int, int, int));
128 static void swap_glyphs_in_rows P_ ((struct glyph_row *, struct glyph_row *));
129 static void swap_glyph_pointers P_ ((struct glyph_row *, struct glyph_row *));
130 static int glyph_row_slice_p P_ ((struct glyph_row *, struct glyph_row *));
131 static void fill_up_frame_row_with_spaces P_ ((struct glyph_row *, int));
132 static void build_frame_matrix_from_window_tree P_ ((struct glyph_matrix *,
133 struct window *));
134 static void build_frame_matrix_from_leaf_window P_ ((struct glyph_matrix *,
135 struct window *));
136 static struct glyph_pool *new_glyph_pool P_ ((void));
137 static void free_glyph_pool P_ ((struct glyph_pool *));
138 static void adjust_frame_glyphs_initially P_ ((void));
139 static void adjust_frame_message_buffer P_ ((struct frame *));
140 static void adjust_decode_mode_spec_buffer P_ ((struct frame *));
141 static void fill_up_glyph_row_with_spaces P_ ((struct glyph_row *));
142 static void build_frame_matrix P_ ((struct frame *));
143 void clear_current_matrices P_ ((struct frame *));
144 void scroll_glyph_matrix_range P_ ((struct glyph_matrix *, int, int,
145 int, int));
146 static void clear_window_matrices P_ ((struct window *, int));
147 static void fill_up_glyph_row_area_with_spaces P_ ((struct glyph_row *, int));
148 static int scrolling_window P_ ((struct window *, int));
149 static void update_window_line P_ ((struct window *, int));
150 static void update_marginal_area P_ ((struct window *, int, int));
151 static void update_text_area P_ ((struct window *, int));
152 static void make_current P_ ((struct glyph_matrix *, struct glyph_matrix *,
153 int));
154 static void mirror_make_current P_ ((struct window *, int));
155 void check_window_matrix_pointers P_ ((struct window *));
156 static void check_matrix_pointers P_ ((struct glyph_matrix *,
157 struct glyph_matrix *));
158 static void mirror_line_dance P_ ((struct window *, int, int, int *, char *));
159 static int update_window_tree P_ ((struct window *, int));
160 static int update_window P_ ((struct window *, int));
161 static int update_frame_1 P_ ((struct frame *, int, int));
162 static void set_window_cursor_after_update P_ ((struct window *));
163 static int row_equal_p P_ ((struct window *, struct glyph_row *,
164 struct glyph_row *));
165 static void adjust_frame_glyphs_for_window_redisplay P_ ((struct frame *));
166 static void adjust_frame_glyphs_for_frame_redisplay P_ ((struct frame *));
167 static void reverse_rows P_ ((struct glyph_matrix *, int, int));
168 static int margin_glyphs_to_reserve P_ ((struct window *, int, Lisp_Object));
172 /* Non-zero means don't pause redisplay for pending input. (This is
173 for debugging and for a future implementation of EDT-like
174 scrolling. */
176 int redisplay_dont_pause;
178 /* Nonzero upon entry to redisplay means do not assume anything about
179 current contents of actual terminal frame; clear and redraw it. */
181 int frame_garbaged;
183 /* Nonzero means last display completed. Zero means it was preempted. */
185 int display_completed;
187 /* Lisp variable visible-bell; enables use of screen-flash instead of
188 audible bell. */
190 int visible_bell;
192 /* Invert the color of the whole frame, at a low level. */
194 int inverse_video;
196 /* Line speed of the terminal. */
198 int baud_rate;
200 /* Either nil or a symbol naming the window system under which Emacs
201 is running. */
203 Lisp_Object Vwindow_system;
205 /* Version number of X windows: 10, 11 or nil. */
207 Lisp_Object Vwindow_system_version;
209 /* Vector of glyph definitions. Indexed by glyph number, the contents
210 are a string which is how to output the glyph.
212 If Vglyph_table is nil, a glyph is output by using its low 8 bits
213 as a character code.
215 This is an obsolete feature that is no longer used. The variable
216 is retained for compatibility. */
218 Lisp_Object Vglyph_table;
220 /* Display table to use for vectors that don't specify their own. */
222 Lisp_Object Vstandard_display_table;
224 /* Nonzero means reading single-character input with prompt so put
225 cursor on mini-buffer after the prompt. positive means at end of
226 text in echo area; negative means at beginning of line. */
228 int cursor_in_echo_area;
230 Lisp_Object Qdisplay_table;
233 /* The currently selected frame. In a single-frame version, this
234 variable always holds the address of the_only_frame. */
236 struct frame *selected_frame;
238 /* A frame which is not just a mini-buffer, or 0 if there are no such
239 frames. This is usually the most recent such frame that was
240 selected. In a single-frame version, this variable always holds
241 the address of the_only_frame. */
243 struct frame *last_nonminibuf_frame;
245 /* Stdio stream being used for copy of all output. */
247 FILE *termscript;
249 /* Structure for info on cursor positioning. */
251 struct cm Wcm;
253 /* 1 means SIGWINCH happened when not safe. */
255 int delayed_size_change;
257 /* 1 means glyph initialization has been completed at startup. */
259 static int glyphs_initialized_initially_p;
261 /* Updated window if != 0. Set by update_window. */
263 struct window *updated_window;
265 /* Glyph row updated in update_window_line, and area that is updated. */
267 struct glyph_row *updated_row;
268 int updated_area;
270 /* A glyph for a space. */
272 struct glyph space_glyph;
274 /* Non-zero means update has been performed directly, so that there's
275 no need for redisplay_internal to do much work. Set by
276 direct_output_for_insert. */
278 int redisplay_performed_directly_p;
280 /* Counts of allocated structures. These counts serve to diagnose
281 memory leaks and double frees. */
283 int glyph_matrix_count;
284 int glyph_pool_count;
286 /* If non-null, the frame whose frame matrices are manipulated. If
287 null, window matrices are worked on. */
289 static struct frame *frame_matrix_frame;
291 /* Current interface for window-based redisplay. Set from init_xterm.
292 A null value means we are not using window-based redisplay. */
294 struct redisplay_interface *rif;
296 /* Non-zero means that fonts have been loaded since the last glyph
297 matrix adjustments. Redisplay must stop, and glyph matrices must
298 be adjusted when this flag becomes non-zero during display. The
299 reason fonts can be loaded so late is that fonts of fontsets are
300 loaded on demand. */
302 int fonts_changed_p;
304 /* Convert vpos and hpos from frame to window and vice versa.
305 This may only be used for terminal frames. */
307 #if GLYPH_DEBUG
309 static int window_to_frame_vpos P_ ((struct window *, int));
310 static int window_to_frame_hpos P_ ((struct window *, int));
311 #define WINDOW_TO_FRAME_VPOS(W, VPOS) window_to_frame_vpos ((W), (VPOS))
312 #define WINDOW_TO_FRAME_HPOS(W, HPOS) window_to_frame_hpos ((W), (HPOS))
314 #else /* GLYPH_DEBUG == 0 */
316 #define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + XFASTINT ((W)->top))
317 #define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + XFASTINT ((W)->left))
319 #endif /* GLYPH_DEBUG == 0 */
322 /* Like bcopy except never gets confused by overlap. Let this be the
323 first function defined in this file, or change emacs.c where the
324 address of this function is used. */
326 void
327 safe_bcopy (from, to, size)
328 char *from, *to;
329 int size;
331 if (size <= 0 || from == to)
332 return;
334 /* If the source and destination don't overlap, then bcopy can
335 handle it. If they do overlap, but the destination is lower in
336 memory than the source, we'll assume bcopy can handle that. */
337 if (to < from || from + size <= to)
338 bcopy (from, to, size);
340 /* Otherwise, we'll copy from the end. */
341 else
343 register char *endf = from + size;
344 register char *endt = to + size;
346 /* If TO - FROM is large, then we should break the copy into
347 nonoverlapping chunks of TO - FROM bytes each. However, if
348 TO - FROM is small, then the bcopy function call overhead
349 makes this not worth it. The crossover point could be about
350 anywhere. Since I don't think the obvious copy loop is too
351 bad, I'm trying to err in its favor. */
352 if (to - from < 64)
355 *--endt = *--endf;
356 while (endf != from);
358 else
360 for (;;)
362 endt -= (to - from);
363 endf -= (to - from);
365 if (endt < to)
366 break;
368 bcopy (endf, endt, to - from);
371 /* If SIZE wasn't a multiple of TO - FROM, there will be a
372 little left over. The amount left over is (endt + (to -
373 from)) - to, which is endt - from. */
374 bcopy (from, to, endt - from);
381 /***********************************************************************
382 Glyph Matrices
383 ***********************************************************************/
385 /* Allocate and return a glyph_matrix structure. POOL is the glyph
386 pool from which memory for the matrix should be allocated, or null
387 for window-based redisplay where no glyph pools are used. The
388 member `pool' of the glyph matrix structure returned is set to
389 POOL, the structure is otherwise zeroed. */
391 struct glyph_matrix *
392 new_glyph_matrix (pool)
393 struct glyph_pool *pool;
395 struct glyph_matrix *result;
397 /* Allocate and clear. */
398 result = (struct glyph_matrix *) xmalloc (sizeof *result);
399 bzero (result, sizeof *result);
401 /* Increment number of allocated matrices. This count is used
402 to detect memory leaks. */
403 ++glyph_matrix_count;
405 /* Set pool and return. */
406 result->pool = pool;
407 return result;
411 /* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed.
413 The global counter glyph_matrix_count is decremented when a matrix
414 is freed. If the count gets negative, more structures were freed
415 than allocated, i.e. one matrix was freed more than once or a bogus
416 pointer was passed to this function.
418 If MATRIX->pool is null, this means that the matrix manages its own
419 glyph memory---this is done for matrices on X frames. Freeing the
420 matrix also frees the glyph memory in this case. */
422 static void
423 free_glyph_matrix (matrix)
424 struct glyph_matrix *matrix;
426 if (matrix)
428 int i;
430 /* Detect the case that more matrices are freed than were
431 allocated. */
432 if (--glyph_matrix_count < 0)
433 abort ();
435 /* Free glyph memory if MATRIX owns it. */
436 if (matrix->pool == NULL)
437 for (i = 0; i < matrix->rows_allocated; ++i)
438 xfree (matrix->rows[i].glyphs[LEFT_MARGIN_AREA]);
440 /* Free row structures and the matrix itself. */
441 xfree (matrix->rows);
442 xfree (matrix);
447 /* Return the number of glyphs to reserve for a marginal area of
448 window W. TOTAL_GLYPHS is the number of glyphs in a complete
449 display line of window W. MARGIN gives the width of the marginal
450 area in canonical character units. MARGIN should be an integer
451 or a float. */
453 static int
454 margin_glyphs_to_reserve (w, total_glyphs, margin)
455 struct window *w;
456 int total_glyphs;
457 Lisp_Object margin;
459 int n;
461 if (NUMBERP (margin))
463 int width = XFASTINT (w->width);
464 double d = max (0, XFLOATINT (margin));
465 d = min (width / 2 - 1, d);
466 n = (int) ((double) total_glyphs / width * d);
468 else
469 n = 0;
471 return n;
475 /* Adjust glyph matrix MATRIX on window W or on a frame to changed
476 window sizes.
478 W is null if the function is called for a frame glyph matrix.
479 Otherwise it is the window MATRIX is a member of. X and Y are the
480 indices of the first column and row of MATRIX within the frame
481 matrix, if such a matrix exists. They are zero for purely
482 window-based redisplay. DIM is the needed size of the matrix.
484 In window-based redisplay, where no frame matrices exist, glyph
485 matrices manage their own glyph storage. Otherwise, they allocate
486 storage from a common frame glyph pool which can be found in
487 MATRIX->pool.
489 The reason for this memory management strategy is to avoid complete
490 frame redraws if possible. When we allocate from a common pool, a
491 change of the location or size of a sub-matrix within the pool
492 requires a complete redisplay of the frame because we cannot easily
493 make sure that the current matrices of all windows still agree with
494 what is displayed on the screen. While this is usually fast, it
495 leads to screen flickering. */
497 static void
498 adjust_glyph_matrix (w, matrix, x, y, dim)
499 struct window *w;
500 struct glyph_matrix *matrix;
501 int x, y;
502 struct dim dim;
504 int i;
505 int new_rows;
506 int marginal_areas_changed_p = 0;
507 int top_line_changed_p = 0;
508 int top_line_p = 0;
509 int left = -1, right = -1;
510 int window_x, window_y, window_width, window_height;
512 /* See if W had a top line that has disappeared now, or vice versa. */
513 if (w)
515 top_line_p = WINDOW_WANTS_TOP_LINE_P (w);
516 top_line_changed_p = top_line_p != matrix->top_line_p;
518 matrix->top_line_p = top_line_p;
520 /* Do nothing if MATRIX' size, position, vscroll, and marginal areas
521 haven't changed. This optimization is important because preserving
522 the matrix means preventing redisplay. */
523 if (matrix->pool == NULL)
525 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
526 left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_width);
527 right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_width);
528 xassert (left >= 0 && right >= 0);
529 marginal_areas_changed_p = (left != matrix->left_margin_glyphs
530 || right != matrix->right_margin_glyphs);
532 if (!marginal_areas_changed_p
533 && !fonts_changed_p
534 && !top_line_changed_p
535 && matrix->window_top_y == XFASTINT (w->top)
536 && matrix->window_height == window_height
537 && matrix->window_vscroll == w->vscroll
538 && matrix->window_width == window_width)
539 return;
542 /* Enlarge MATRIX->rows if necessary. New rows are cleared. */
543 if (matrix->rows_allocated < dim.height)
545 int size = dim.height * sizeof (struct glyph_row);
546 new_rows = dim.height - matrix->rows_allocated;
547 matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
548 bzero (matrix->rows + matrix->rows_allocated,
549 new_rows * sizeof *matrix->rows);
550 matrix->rows_allocated = dim.height;
552 else
553 new_rows = 0;
555 /* If POOL is not null, MATRIX is a frame matrix or a window matrix
556 on a frame not using window-based redisplay. Set up pointers for
557 each row into the glyph pool. */
558 if (matrix->pool)
560 xassert (matrix->pool->glyphs);
562 if (w)
564 left = margin_glyphs_to_reserve (w, dim.width,
565 w->left_margin_width);
566 right = margin_glyphs_to_reserve (w, dim.width,
567 w->right_margin_width);
569 else
570 left = right = 0;
572 for (i = 0; i < dim.height; ++i)
574 struct glyph_row *row = &matrix->rows[i];
576 row->glyphs[LEFT_MARGIN_AREA]
577 = (matrix->pool->glyphs
578 + (y + i) * matrix->pool->ncolumns
579 + x);
581 if (w == NULL
582 || row == matrix->rows + dim.height - 1
583 || (row == matrix->rows && matrix->top_line_p))
585 row->glyphs[TEXT_AREA]
586 = row->glyphs[LEFT_MARGIN_AREA];
587 row->glyphs[RIGHT_MARGIN_AREA]
588 = row->glyphs[TEXT_AREA] + dim.width;
589 row->glyphs[LAST_AREA]
590 = row->glyphs[RIGHT_MARGIN_AREA];
592 else
594 row->glyphs[TEXT_AREA]
595 = row->glyphs[LEFT_MARGIN_AREA] + left;
596 row->glyphs[RIGHT_MARGIN_AREA]
597 = row->glyphs[TEXT_AREA] + dim.width - left - right;
598 row->glyphs[LAST_AREA]
599 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
603 matrix->left_margin_glyphs = left;
604 matrix->right_margin_glyphs = right;
606 else
608 /* If MATRIX->pool is null, MATRIX is responsible for managing
609 its own memory. Allocate glyph memory from the heap. */
610 if (dim.width > matrix->matrix_w
611 || new_rows
612 || top_line_changed_p
613 || marginal_areas_changed_p)
615 struct glyph_row *row = matrix->rows;
616 struct glyph_row *end = row + matrix->rows_allocated;
618 while (row < end)
620 row->glyphs[LEFT_MARGIN_AREA]
621 = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA],
622 (dim.width
623 * sizeof (struct glyph)));
625 /* The mode line never has marginal areas. */
626 if (row == matrix->rows + dim.height - 1
627 || (row == matrix->rows && matrix->top_line_p))
629 row->glyphs[TEXT_AREA]
630 = row->glyphs[LEFT_MARGIN_AREA];
631 row->glyphs[RIGHT_MARGIN_AREA]
632 = row->glyphs[TEXT_AREA] + dim.width;
633 row->glyphs[LAST_AREA]
634 = row->glyphs[RIGHT_MARGIN_AREA];
636 else
638 row->glyphs[TEXT_AREA]
639 = row->glyphs[LEFT_MARGIN_AREA] + left;
640 row->glyphs[RIGHT_MARGIN_AREA]
641 = row->glyphs[TEXT_AREA] + dim.width - left - right;
642 row->glyphs[LAST_AREA]
643 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
645 ++row;
649 xassert (left >= 0 && right >= 0);
650 matrix->left_margin_glyphs = left;
651 matrix->right_margin_glyphs = right;
654 /* Number of rows to be used by MATRIX. */
655 matrix->nrows = dim.height;
657 /* Mark rows in a current matrix of a window as not having valid
658 contents. It's important to not do this for desired matrices.
659 When Emacs starts, it may already be building desired matrices
660 when this function runs. */
661 if (w && matrix == w->current_matrix)
663 /* Optimize the case that only the height has changed (C-x 2,
664 upper window). Invalidate all rows that are no longer part
665 of the window. */
666 if (!marginal_areas_changed_p
667 && matrix->window_top_y == XFASTINT (w->top)
668 && matrix->window_width == window_width)
670 i = 0;
671 while (matrix->rows[i].enabled_p
672 && (MATRIX_ROW_BOTTOM_Y (matrix->rows + i)
673 < matrix->window_height))
674 ++i;
676 /* Window end is invalid, if inside of the rows that
677 are invalidated. */
678 if (INTEGERP (w->window_end_vpos)
679 && XFASTINT (w->window_end_vpos) >= i)
680 w->window_end_valid = Qnil;
682 while (i < matrix->nrows)
683 matrix->rows[i++].enabled_p = 0;
685 else
687 for (i = 0; i < matrix->nrows; ++i)
688 matrix->rows[i].enabled_p = 0;
692 /* Remember last values to be able to optimize frame redraws. */
693 matrix->matrix_x = x;
694 matrix->matrix_y = y;
695 matrix->matrix_w = dim.width;
696 matrix->matrix_h = dim.height;
698 /* Record the top y location and height of W at the time the matrix
699 was last adjusted. This is used to optimize redisplay above. */
700 if (w)
702 matrix->window_top_y = XFASTINT (w->top);
703 matrix->window_height = window_height;
704 matrix->window_width = window_width;
705 matrix->window_vscroll = w->vscroll;
710 /* Reverse the contents of rows in MATRIX between START and END. The
711 contents of the row at END - 1 end up at START, END - 2 at START +
712 1 etc. This is part of the implementation of rotate_matrix (see
713 below). */
715 static void
716 reverse_rows (matrix, start, end)
717 struct glyph_matrix *matrix;
718 int start, end;
720 int i, j;
722 for (i = start, j = end - 1; i < j; ++i, --j)
724 /* Non-ISO HP/UX compiler doesn't like auto struct
725 initialization. */
726 struct glyph_row temp;
727 temp = matrix->rows[i];
728 matrix->rows[i] = matrix->rows[j];
729 matrix->rows[j] = temp;
734 /* Rotate the contents of rows in MATRIX in the range FIRST .. LAST -
735 1 by BY positions. BY < 0 means rotate left, i.e. towards lower
736 indices. (Note: this does not copy glyphs, only glyph pointers in
737 row structures are moved around).
739 The algorithm used for rotating the vector was, I believe, first
740 described by Kernighan. See the vector R as consisting of two
741 sub-vectors AB, where A has length BY for BY >= 0. The result
742 after rotating is then BA. Reverse both sub-vectors to get ArBr
743 and reverse the result to get (ArBr)r which is BA. Similar for
744 rotating right. */
746 void
747 rotate_matrix (matrix, first, last, by)
748 struct glyph_matrix *matrix;
749 int first, last, by;
751 if (by < 0)
753 /* Up (rotate left, i.e. towards lower indices). */
754 by = -by;
755 reverse_rows (matrix, first, first + by);
756 reverse_rows (matrix, first + by, last);
757 reverse_rows (matrix, first, last);
759 else if (by > 0)
761 /* Down (rotate right, i.e. towards higher indices). */
762 reverse_rows (matrix, last - by, last);
763 reverse_rows (matrix, first, last - by);
764 reverse_rows (matrix, first, last);
769 /* Increment buffer positions in glyph rows of MATRIX. Do it for rows
770 with indices START <= index < END. Increment positions by DELTA/
771 DELTA_BYTES. */
773 void
774 increment_glyph_matrix_buffer_positions (matrix, start, end, delta,
775 delta_bytes)
776 struct glyph_matrix *matrix;
777 int start, end, delta, delta_bytes;
779 /* Check that START and END are reasonable values. */
780 xassert (start >= 0 && start <= matrix->nrows);
781 xassert (end >= 0 && end <= matrix->nrows);
782 xassert (start <= end);
784 for (; start < end; ++start)
785 increment_glyph_row_buffer_positions (matrix->rows + start,
786 delta, delta_bytes);
790 /* Enable a range of rows in glyph matrix MATRIX. START and END are
791 the row indices of the first and last + 1 row to enable. If
792 ENABLED_P is non-zero, enabled_p flags in rows will be set to 1. */
794 void
795 enable_glyph_matrix_rows (matrix, start, end, enabled_p)
796 struct glyph_matrix *matrix;
797 int start, end;
798 int enabled_p;
800 xassert (start <= end);
801 xassert (start >= 0 && start < matrix->nrows);
802 xassert (end >= 0 && end <= matrix->nrows);
804 for (; start < end; ++start)
805 matrix->rows[start].enabled_p = enabled_p != 0;
809 /* Clear MATRIX.
811 This empties all rows in MATRIX by setting the enabled_p flag for
812 all rows of the matrix to zero. The function prepare_desired_row
813 will eventually really clear a row when it sees one with a zero
814 enabled_p flag.
816 Resets update hints to defaults value. The only update hint
817 currently present is the flag MATRIX->no_scrolling_p. */
819 void
820 clear_glyph_matrix (matrix)
821 struct glyph_matrix *matrix;
823 if (matrix)
825 enable_glyph_matrix_rows (matrix, 0, matrix->nrows, 0);
826 matrix->no_scrolling_p = 0;
831 /* Shift part of the glyph matrix MATRIX of window W up or down.
832 Increment y-positions in glyph rows between START and END by DY,
833 and recompute their visible height. */
835 void
836 shift_glyph_matrix (w, matrix, start, end, dy)
837 struct window *w;
838 struct glyph_matrix *matrix;
839 int start, end, dy;
841 int min_y, max_y;
843 xassert (start <= end);
844 xassert (start >= 0 && start < matrix->nrows);
845 xassert (end >= 0 && end <= matrix->nrows);
847 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
848 max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w);
850 for (; start < end; ++start)
852 struct glyph_row *row = &matrix->rows[start];
854 row->y += dy;
856 if (row->y < min_y)
857 row->visible_height = row->height - (min_y - row->y);
858 else if (row->y + row->height > max_y)
859 row->visible_height = row->height - (row->y + row->height - max_y);
860 else
861 row->visible_height = row->height;
866 /* Mark all rows in current matrices of frame F as invalid. Marking
867 invalid is done by setting enabled_p to zero for all rows in a
868 current matrix. */
870 void
871 clear_current_matrices (f)
872 register struct frame *f;
874 /* Clear frame current matrix, if we have one. */
875 if (f->current_matrix)
876 clear_glyph_matrix (f->current_matrix);
878 /* Clear the matrix of the menu bar window, if such a window exists.
879 The menu bar window is currently used to display menus on X when
880 no toolkit support is compiled in. */
881 if (WINDOWP (f->menu_bar_window))
882 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
884 /* Clear the matrix of the toolbar window, if any. */
885 if (WINDOWP (f->toolbar_window))
886 clear_glyph_matrix (XWINDOW (f->toolbar_window)->current_matrix);
888 /* Clear current window matrices. */
889 xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
890 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 0);
894 /* Clear out all display lines of F for a coming redisplay. */
896 void
897 clear_desired_matrices (f)
898 register struct frame *f;
900 if (f->desired_matrix)
901 clear_glyph_matrix (f->desired_matrix);
903 if (WINDOWP (f->menu_bar_window))
904 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
906 if (WINDOWP (f->toolbar_window))
907 clear_glyph_matrix (XWINDOW (f->toolbar_window)->desired_matrix);
909 /* Do it for window matrices. */
910 xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
911 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
915 /* Clear matrices in window tree rooted in W. If DESIRED_P is
916 non-zero clear desired matrices, otherwise clear current matrices. */
918 static void
919 clear_window_matrices (w, desired_p)
920 struct window *w;
921 int desired_p;
923 while (w)
925 if (!NILP (w->hchild))
927 xassert (WINDOWP (w->hchild));
928 clear_window_matrices (XWINDOW (w->hchild), desired_p);
930 else if (!NILP (w->vchild))
932 xassert (WINDOWP (w->vchild));
933 clear_window_matrices (XWINDOW (w->vchild), desired_p);
935 else
937 if (desired_p)
938 clear_glyph_matrix (w->desired_matrix);
939 else
941 clear_glyph_matrix (w->current_matrix);
942 w->window_end_valid = Qnil;
946 w = NILP (w->next) ? 0 : XWINDOW (w->next);
952 /***********************************************************************
953 Glyph Rows
955 See dispextern.h for an overall explanation of glyph rows.
956 ***********************************************************************/
958 /* Clear glyph row ROW. Do it in a way that makes it robust against
959 changes in the glyph_row structure, i.e. addition or removal of
960 structure members. */
962 void
963 clear_glyph_row (row)
964 struct glyph_row *row;
966 struct glyph *p[1 + LAST_AREA];
967 static struct glyph_row null_row;
969 /* Save pointers. */
970 p[LEFT_MARGIN_AREA] = row->glyphs[LEFT_MARGIN_AREA];
971 p[TEXT_AREA] = row->glyphs[TEXT_AREA];
972 p[RIGHT_MARGIN_AREA] = row->glyphs[RIGHT_MARGIN_AREA];
973 p[LAST_AREA] = row->glyphs[LAST_AREA];
975 /* Clear. */
976 *row = null_row;
978 /* Restore pointers. */
979 row->glyphs[LEFT_MARGIN_AREA] = p[LEFT_MARGIN_AREA];
980 row->glyphs[TEXT_AREA] = p[TEXT_AREA];
981 row->glyphs[RIGHT_MARGIN_AREA] = p[RIGHT_MARGIN_AREA];
982 row->glyphs[LAST_AREA] = p[LAST_AREA];
986 /* Make ROW an empty, enabled row of canonical character height,
987 in window W starting at y-position Y. */
989 void
990 blank_row (w, row, y)
991 struct window *w;
992 struct glyph_row *row;
993 int y;
995 int min_y, max_y;
997 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
998 max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w);
1000 clear_glyph_row (row);
1001 row->y = y;
1002 row->ascent = 0;
1003 row->height = CANON_Y_UNIT (XFRAME (WINDOW_FRAME (w)));
1005 if (row->y < min_y)
1006 row->visible_height = row->height - (min_y - row->y);
1007 else if (row->y + row->height > max_y)
1008 row->visible_height = row->height - (row->y + row->height - max_y);
1009 else
1010 row->visible_height = row->height;
1012 row->enabled_p = 1;
1016 /* Increment buffer positions in glyph row ROW. DELTA and DELTA_BYTES
1017 are the amounts by which to change positions. Note that the first
1018 glyph of the text area of a row can have a buffer position even if
1019 the used count of the text area is zero. Such rows display line
1020 ends. */
1022 void
1023 increment_glyph_row_buffer_positions (row, delta, delta_bytes)
1024 struct glyph_row *row;
1025 int delta, delta_bytes;
1027 int area, i;
1029 /* Increment start and end positions. */
1030 MATRIX_ROW_START_CHARPOS (row) += delta;
1031 MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
1032 MATRIX_ROW_END_CHARPOS (row) += delta;
1033 MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
1035 /* Increment positions in glyphs. */
1036 for (area = 0; area < LAST_AREA; ++area)
1037 for (i = 0; i < row->used[area]; ++i)
1038 if (BUFFERP (row->glyphs[area][i].object)
1039 && row->glyphs[area][i].charpos > 0)
1040 row->glyphs[area][i].charpos += delta;
1042 /* Capture the case of rows displaying a line end. */
1043 if (row->used[TEXT_AREA] == 0
1044 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
1045 row->glyphs[TEXT_AREA]->charpos += delta;
1049 /* Swap glyphs between two glyph rows A and B. This exchanges glyph
1050 contents, i.e. glyph structure contents are exchanged between A and
1051 B without changing glyph pointers in A and B. */
1053 static void
1054 swap_glyphs_in_rows (a, b)
1055 struct glyph_row *a, *b;
1057 int area;
1059 for (area = 0; area < LAST_AREA; ++area)
1061 /* Number of glyphs to swap. */
1062 int max_used = max (a->used[area], b->used[area]);
1064 /* Start of glyphs in area of row A. */
1065 struct glyph *glyph_a = a->glyphs[area];
1067 /* End + 1 of glyphs in area of row A. */
1068 struct glyph *glyph_a_end = a->glyphs[max_used];
1070 /* Start of glyphs in area of row B. */
1071 struct glyph *glyph_b = b->glyphs[area];
1073 while (glyph_a < glyph_a_end)
1075 /* Non-ISO HP/UX compiler doesn't like auto struct
1076 initialization. */
1077 struct glyph temp;
1078 temp = *glyph_a;
1079 *glyph_a = *glyph_b;
1080 *glyph_b = temp;
1081 ++glyph_a;
1082 ++glyph_b;
1088 /* Exchange pointers to glyph memory between glyph rows A and B. */
1090 static INLINE void
1091 swap_glyph_pointers (a, b)
1092 struct glyph_row *a, *b;
1094 int i;
1095 for (i = 0; i < LAST_AREA + 1; ++i)
1097 struct glyph *temp = a->glyphs[i];
1098 a->glyphs[i] = b->glyphs[i];
1099 b->glyphs[i] = temp;
1104 /* Copy glyph row structure FROM to glyph row structure TO, except
1105 that glyph pointers in the structures are left unchanged. */
1107 INLINE void
1108 copy_row_except_pointers (to, from)
1109 struct glyph_row *to, *from;
1111 struct glyph *pointers[1 + LAST_AREA];
1113 /* Save glyph pointers of TO. */
1114 bcopy (to->glyphs, pointers, sizeof to->glyphs);
1116 /* Do a structure assignment. */
1117 *to = *from;
1119 /* Restore original pointers of TO. */
1120 bcopy (pointers, to->glyphs, sizeof to->glyphs);
1124 /* Copy contents of glyph row FROM to glyph row TO. Glyph pointers in
1125 TO and FROM are left unchanged. Glyph contents are copied from the
1126 glyph memory of FROM to the glyph memory of TO. Increment buffer
1127 positions in row TO by DELTA/ DELTA_BYTES. */
1129 void
1130 copy_glyph_row_contents (to, from, delta, delta_bytes)
1131 struct glyph_row *to, *from;
1132 int delta, delta_bytes;
1134 int area;
1136 /* This is like a structure assignment TO = FROM, except that
1137 glyph pointers in the rows are left unchanged. */
1138 copy_row_except_pointers (to, from);
1140 /* Copy glyphs from FROM to TO. */
1141 for (area = 0; area < LAST_AREA; ++area)
1142 if (from->used[area])
1143 bcopy (from->glyphs[area], to->glyphs[area],
1144 from->used[area] * sizeof (struct glyph));
1146 /* Increment buffer positions in TO by DELTA. */
1147 increment_glyph_row_buffer_positions (to, delta, delta_bytes);
1151 /* Assign glyph row FROM to glyph row TO. This works like a structure
1152 assignment TO = FROM, except that glyph pointers are not copied but
1153 exchanged between TO and FROM. Pointers must be exchanged to avoid
1154 a memory leak. */
1156 static INLINE void
1157 assign_row (to, from)
1158 struct glyph_row *to, *from;
1160 swap_glyph_pointers (to, from);
1161 copy_row_except_pointers (to, from);
1165 /* Test whether the glyph memory of the glyph row WINDOW_ROW, which is
1166 a row in a window matrix, is a slice of the glyph memory of the
1167 glyph row FRAME_ROW which is a row in a frame glyph matrix. Value
1168 is non-zero if the glyph memory of WINDOW_ROW is part of the glyph
1169 memory of FRAME_ROW. */
1171 static int
1172 glyph_row_slice_p (window_row, frame_row)
1173 struct glyph_row *window_row, *frame_row;
1175 struct glyph *window_glyph_start = window_row->glyphs[0];
1176 struct glyph *frame_glyph_start = frame_row->glyphs[0];
1177 struct glyph *frame_glyph_end = frame_row->glyphs[LAST_AREA];
1179 return (frame_glyph_start <= window_glyph_start
1180 && window_glyph_start < frame_glyph_end);
1184 /* Find the row in the window glyph matrix WINDOW_MATRIX being a slice
1185 of ROW in the frame matrix FRAME_MATRIX. Value is null if no row
1186 in WINDOW_MATRIX is found satisfying the condition. */
1188 static struct glyph_row *
1189 find_glyph_row_slice (window_matrix, frame_matrix, row)
1190 struct glyph_matrix *window_matrix, *frame_matrix;
1191 int row;
1193 int i;
1195 xassert (row >= 0 && row < frame_matrix->nrows);
1197 for (i = 0; i < window_matrix->nrows; ++i)
1198 if (glyph_row_slice_p (window_matrix->rows + i,
1199 frame_matrix->rows + row))
1200 break;
1202 return i < window_matrix->nrows ? window_matrix->rows + i : 0;
1206 /* Prepare ROW for display. Desired rows are cleared lazily,
1207 i.e. they are only marked as to be cleared by setting their
1208 enabled_p flag to zero. When a row is to be displayed, a prior
1209 call to this function really clears it. */
1211 void
1212 prepare_desired_row (row)
1213 struct glyph_row *row;
1215 if (!row->enabled_p)
1217 clear_glyph_row (row);
1218 row->enabled_p = 1;
1223 /* Return a hash code for glyph row ROW. */
1226 line_hash_code (row)
1227 struct glyph_row *row;
1229 int hash = 0;
1231 if (row->enabled_p)
1233 if (row->inverse_p)
1235 /* Give all highlighted lines the same hash code
1236 so as to encourage scrolling to leave them in place. */
1237 hash = -1;
1239 else
1241 struct glyph *glyph = row->glyphs[TEXT_AREA];
1242 struct glyph *end = glyph + row->used[TEXT_AREA];
1244 while (glyph < end)
1246 GLYPH g = GLYPH_FROM_CHAR_GLYPH (*glyph);
1247 if (must_write_spaces)
1248 g -= SPACEGLYPH;
1249 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + g;
1250 ++glyph;
1253 if (hash == 0)
1254 hash = 1;
1258 return hash;
1262 /* Return the cost of drawing line VPOS In MATRIX. The cost equals
1263 the number of characters in the line. If must_write_spaces is
1264 zero, leading and trailing spaces are ignored. */
1266 static unsigned int
1267 line_draw_cost (matrix, vpos)
1268 struct glyph_matrix *matrix;
1269 int vpos;
1271 struct glyph_row *row = matrix->rows + vpos;
1272 struct glyph *beg = row->glyphs[TEXT_AREA];
1273 struct glyph *end = beg + row->used[TEXT_AREA];
1274 int len;
1275 Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
1276 int glyph_table_len = GLYPH_TABLE_LENGTH;
1278 /* Ignore trailing and leading spaces if we can. */
1279 if (!must_write_spaces)
1281 /* Skip from the end over trailing spaces. */
1282 while (end != beg && CHAR_GLYPH_SPACE_P (*end))
1283 --end;
1285 /* All blank line. */
1286 if (end == beg)
1287 return 0;
1289 /* Skip over leading spaces. */
1290 while (CHAR_GLYPH_SPACE_P (*beg))
1291 ++beg;
1294 /* If we don't have a glyph-table, each glyph is one character,
1295 so return the number of glyphs. */
1296 if (glyph_table_base == 0)
1297 len = end - beg;
1298 else
1300 /* Otherwise, scan the glyphs and accumulate their total length
1301 in LEN. */
1302 len = 0;
1303 while (beg < end)
1305 GLYPH g = GLYPH_FROM_CHAR_GLYPH (*beg);
1307 if (GLYPH_SIMPLE_P (glyph_table_base, glyph_table_len, g))
1308 len += 1;
1309 else
1310 len += GLYPH_LENGTH (glyph_table_base, g);
1312 ++beg;
1316 return len;
1320 /* Test two glyph rows A and B for equality. Value is non-zero if A
1321 and B have equal contents. W is the window to which the glyphs
1322 rows A and B belong. It is needed here to test for partial row
1323 visibility. */
1325 static INLINE int
1326 row_equal_p (w, a, b)
1327 struct window *w;
1328 struct glyph_row *a, *b;
1330 if (a == b)
1331 return 1;
1332 else if (a->hash != b->hash)
1333 return 0;
1334 else
1336 struct glyph *a_glyph, *b_glyph, *a_end;
1337 int area;
1339 /* Compare glyphs. */
1340 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
1342 if (a->used[area] != b->used[area])
1343 return 0;
1345 a_glyph = a->glyphs[area];
1346 a_end = a_glyph + a->used[area];
1347 b_glyph = b->glyphs[area];
1349 while (a_glyph < a_end
1350 && GLYPH_EQUAL_P (a_glyph, b_glyph))
1351 ++a_glyph, ++b_glyph;
1353 if (a_glyph != a_end)
1354 return 0;
1357 if (a->truncated_on_left_p != b->truncated_on_left_p
1358 || a->inverse_p != b->inverse_p
1359 || a->fill_line_p != b->fill_line_p
1360 || a->truncated_on_right_p != b->truncated_on_right_p
1361 || a->overlay_arrow_p != b->overlay_arrow_p
1362 || a->continued_p != b->continued_p
1363 || a->indicate_empty_line_p != b->indicate_empty_line_p
1364 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
1365 != MATRIX_ROW_CONTINUATION_LINE_P (b))
1366 /* Different partially visible characters on left margin. */
1367 || a->x != b->x
1368 /* Different height. */
1369 || a->ascent != b->ascent
1370 || a->visible_height != b->visible_height)
1371 return 0;
1374 return 1;
1379 /***********************************************************************
1380 Glyph Pool
1382 See dispextern.h for an overall explanation of glyph pools.
1383 ***********************************************************************/
1385 /* Allocate a glyph_pool structure. The structure returned is
1386 initialized with zeros. The global variable glyph_pool_count is
1387 incremented for each pool allocated. */
1389 static struct glyph_pool *
1390 new_glyph_pool ()
1392 struct glyph_pool *result;
1394 /* Allocate a new glyph_pool and clear it. */
1395 result = (struct glyph_pool *) xmalloc (sizeof *result);
1396 bzero (result, sizeof *result);
1398 /* For memory leak and double deletion checking. */
1399 ++glyph_pool_count;
1401 return result;
1405 /* Free a glyph_pool structure POOL. The function may be called with
1406 a null POOL pointer. The global variable glyph_pool_count is
1407 decremented with every pool structure freed. If this count gets
1408 negative, more structures were freed than allocated, i.e. one
1409 structure must have been freed more than once or a bogus pointer
1410 was passed to free_glyph_pool. */
1412 static void
1413 free_glyph_pool (pool)
1414 struct glyph_pool *pool;
1416 if (pool)
1418 /* More freed than allocated? */
1419 --glyph_pool_count;
1420 xassert (glyph_pool_count >= 0);
1422 xfree (pool->glyphs);
1423 xfree (pool);
1428 /* Enlarge a glyph pool POOL. MATRIX_DIM gives the number of rows and
1429 columns we need. This function never shrinks a pool. The only
1430 case in which this would make sense, would be when a frame's size
1431 is changed from a large value to a smaller one. But, if someone
1432 does it once, we can expect that he will do it again.
1434 Value is non-zero if the pool changed in a way which makes
1435 re-adjusting window glyph matrices necessary. */
1437 static int
1438 realloc_glyph_pool (pool, matrix_dim)
1439 struct glyph_pool *pool;
1440 struct dim matrix_dim;
1442 int needed;
1443 int changed_p;
1445 changed_p = (pool->glyphs == 0
1446 || matrix_dim.height != pool->nrows
1447 || matrix_dim.width != pool->ncolumns);
1449 /* Enlarge the glyph pool. */
1450 needed = matrix_dim.width * matrix_dim.height;
1451 if (needed > pool->nglyphs)
1453 int size = needed * sizeof (struct glyph);
1455 if (pool->glyphs)
1456 pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size);
1457 else
1459 pool->glyphs = (struct glyph *) xmalloc (size);
1460 bzero (pool->glyphs, size);
1463 pool->nglyphs = needed;
1466 /* Remember the number of rows and columns because (a) we use then
1467 to do sanity checks, and (b) the number of columns determines
1468 where rows in the frame matrix start---this must be available to
1469 determine pointers to rows of window sub-matrices. */
1470 pool->nrows = matrix_dim.height;
1471 pool->ncolumns = matrix_dim.width;
1473 return changed_p;
1478 /***********************************************************************
1479 Debug Code
1480 ***********************************************************************/
1482 #if GLYPH_DEBUG
1484 /* Check that no glyph pointers have been lost in MATRIX. If a
1485 pointer has been lost, e.g. by using a structure assignment between
1486 rows, at least one pointer must occur more than once in the rows of
1487 MATRIX. */
1489 void
1490 check_matrix_pointer_lossage (matrix)
1491 struct glyph_matrix *matrix;
1493 int i, j;
1495 for (i = 0; i < matrix->nrows; ++i)
1496 for (j = 0; j < matrix->nrows; ++j)
1497 xassert (i == j
1498 || (matrix->rows[i].glyphs[TEXT_AREA]
1499 != matrix->rows[j].glyphs[TEXT_AREA]));
1503 /* Get a pointer to glyph row ROW in MATRIX, with bounds checks. */
1505 struct glyph_row *
1506 matrix_row (matrix, row)
1507 struct glyph_matrix *matrix;
1508 int row;
1510 xassert (matrix && matrix->rows);
1511 xassert (row >= 0 && row < matrix->nrows);
1513 /* That's really too slow for normal testing because this function
1514 is called almost everywhere. Although---it's still astonishingly
1515 fast, so it is valuable to have for debugging purposes. */
1516 #if 0
1517 check_matrix_pointer_lossage (matrix);
1518 #endif
1520 return matrix->rows + row;
1524 #if 0 /* This function makes invalid assumptions when text is
1525 partially invisible. But it might come handy for debugging
1526 nevertheless. */
1528 /* Check invariants that must hold for an up to date current matrix of
1529 window W. */
1531 static void
1532 check_matrix_invariants (w)
1533 struct window *w;
1535 struct glyph_matrix *matrix = w->current_matrix;
1536 int yb = window_text_bottom_y (w);
1537 struct glyph_row *row = matrix->rows;
1538 struct glyph_row *last_text_row = NULL;
1539 struct buffer *saved = current_buffer;
1540 struct buffer *buffer = XBUFFER (w->buffer);
1541 int c;
1543 /* This can sometimes happen for a fresh window. */
1544 if (matrix->nrows < 2)
1545 return;
1547 set_buffer_temp (buffer);
1549 /* Note: last row is always reserved for the mode line. */
1550 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
1551 && MATRIX_ROW_BOTTOM_Y (row) < yb)
1553 struct glyph_row *next = row + 1;
1555 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
1556 last_text_row = row;
1558 /* Check that character and byte positions are in sync. */
1559 xassert (MATRIX_ROW_START_BYTEPOS (row)
1560 == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
1562 /* CHAR_TO_BYTE aborts when invoked for a position > Z. We can
1563 have such a position temporarily in case of a minibuffer
1564 displaying something like `[Sole completion]' at its end. */
1565 if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
1566 xassert (MATRIX_ROW_END_BYTEPOS (row)
1567 == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
1569 /* Check that end position of `row' is equal to start position
1570 of next row. */
1571 if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next))
1573 xassert (MATRIX_ROW_END_CHARPOS (row)
1574 == MATRIX_ROW_START_CHARPOS (next));
1575 xassert (MATRIX_ROW_END_BYTEPOS (row)
1576 == MATRIX_ROW_START_BYTEPOS (next));
1578 row = next;
1581 xassert (w->current_matrix->nrows == w->desired_matrix->nrows);
1582 xassert (w->desired_matrix->rows != NULL);
1583 set_buffer_temp (saved);
1586 #endif /* 0 */
1588 #endif /* GLYPH_DEBUG != 0 */
1592 /**********************************************************************
1593 Allocating/ Adjusting Glyph Matrices
1594 **********************************************************************/
1596 /* Allocate glyph matrices over a window tree for a frame-based
1597 redisplay
1599 X and Y are column/row within the frame glyph matrix where
1600 sub-matrices for the window tree rooted at WINDOW must be
1601 allocated. CH_DIM contains the dimensions of the smallest
1602 character that could be used during display. DIM_ONLY_P non-zero
1603 means that the caller of this function is only interested in the
1604 result matrix dimension, and matrix adjustments should not be
1605 performed.
1607 The function returns the total width/height of the sub-matrices of
1608 the window tree. If called on a frame root window, the computation
1609 will take the mini-buffer window into account.
1611 *WINDOW_CHANGE_FLAGS is set to a bit mask with bits
1613 NEW_LEAF_MATRIX set if any window in the tree did not have a
1614 glyph matrices yet, and
1616 CHANGED_LEAF_MATRIX set if the dimension or location of a matrix of
1617 any window in the tree will be changed or have been changed (see
1618 DIM_ONLY_P).
1620 *WINDOW_CHANGE_FLAGS must be initialized by the caller of this
1621 function.
1623 Windows are arranged into chains of windows on the same level
1624 through the next fields of window structures. Such a level can be
1625 either a sequence of horizontally adjacent windows from left to
1626 right, or a sequence of vertically adjacent windows from top to
1627 bottom. Each window in a horizontal sequence can be either a leaf
1628 window or a vertical sequence; a window in a vertical sequence can
1629 be either a leaf or a horizontal sequence. All windows in a
1630 horizontal sequence have the same height, and all windows in a
1631 vertical sequence have the same width.
1633 This function uses, for historical reasons, a more general
1634 algorithm to determine glyph matrix dimensions that would be
1635 necessary.
1637 The matrix height of a horizontal sequence is determined by the
1638 maximum height of any matrix in the sequence. The matrix width of
1639 a horizontal sequence is computed by adding up matrix widths of
1640 windows in the sequence.
1642 |<------- result width ------->|
1643 +---------+----------+---------+ ---
1644 | | | | |
1645 | | | |
1646 +---------+ | | result height
1647 | +---------+
1648 | | |
1649 +----------+ ---
1651 The matrix width of a vertical sequence is the maximum matrix width
1652 of any window in the sequence. Its height is computed by adding up
1653 matrix heights of windows in the sequence.
1655 |<---- result width -->|
1656 +---------+ ---
1657 | | |
1658 | | |
1659 +---------+--+ |
1660 | | |
1661 | | result height
1663 +------------+---------+ |
1664 | | |
1665 | | |
1666 +------------+---------+ --- */
1668 /* Bit indicating that a new matrix will be allocated or has been
1669 allocated. */
1671 #define NEW_LEAF_MATRIX (1 << 0)
1673 /* Bit indicating that a matrix will or has changed its location or
1674 size. */
1676 #define CHANGED_LEAF_MATRIX (1 << 1)
1678 static struct dim
1679 allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
1680 dim_only_p, window_change_flags)
1681 Lisp_Object window;
1682 int x, y;
1683 struct dim ch_dim;
1684 int dim_only_p;
1685 int *window_change_flags;
1687 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1688 int x0 = x, y0 = y;
1689 int wmax = 0, hmax = 0;
1690 struct dim total;
1691 struct dim dim;
1692 struct window *w;
1693 int in_horz_combination_p;
1695 /* What combination is WINDOW part of? Compute this once since the
1696 result is the same for all windows in the `next' chain. The
1697 special case of a root window (parent equal to nil) is treated
1698 like a vertical combination because a root window's `next'
1699 points to the mini-buffer window, if any, which is arranged
1700 vertically below other windows. */
1701 in_horz_combination_p
1702 = (!NILP (XWINDOW (window)->parent)
1703 && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
1705 /* For WINDOW and all windows on the same level. */
1708 w = XWINDOW (window);
1710 /* Get the dimension of the window sub-matrix for W, depending
1711 on whether this a combination or a leaf window. */
1712 if (!NILP (w->hchild))
1713 dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y, ch_dim,
1714 dim_only_p,
1715 window_change_flags);
1716 else if (!NILP (w->vchild))
1717 dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y, ch_dim,
1718 dim_only_p,
1719 window_change_flags);
1720 else
1722 /* If not already done, allocate sub-matrix structures. */
1723 if (w->desired_matrix == NULL)
1725 w->desired_matrix = new_glyph_matrix (f->desired_pool);
1726 w->current_matrix = new_glyph_matrix (f->current_pool);
1727 *window_change_flags |= NEW_LEAF_MATRIX;
1730 /* Width and height MUST be chosen so that there are no
1731 holes in the frame matrix. */
1732 dim.width = w->width;
1733 dim.height = w->height;
1735 /* Will matrix be re-allocated? */
1736 if (x != w->desired_matrix->matrix_x
1737 || y != w->desired_matrix->matrix_y
1738 || dim.width != w->desired_matrix->matrix_w
1739 || dim.height != w->desired_matrix->matrix_h
1740 || (margin_glyphs_to_reserve (w, dim.width,
1741 w->right_margin_width)
1742 != w->desired_matrix->left_margin_glyphs)
1743 || (margin_glyphs_to_reserve (w, dim.width,
1744 w->left_margin_width)
1745 != w->desired_matrix->right_margin_glyphs))
1746 *window_change_flags |= CHANGED_LEAF_MATRIX;
1748 /* Actually change matrices, if allowed. Do not consider
1749 CHANGED_LEAF_MATRIX computed above here because the pool
1750 may have been changed which we don't now here. We trust
1751 that we only will be called with DIM_ONLY_P != 0 when
1752 necessary. */
1753 if (!dim_only_p)
1755 adjust_glyph_matrix (w, w->desired_matrix, x, y, dim);
1756 adjust_glyph_matrix (w, w->current_matrix, x, y, dim);
1760 /* If we are part of a horizontal combination, advance x for
1761 windows to the right of W; otherwise advance y for windows
1762 below W. */
1763 if (in_horz_combination_p)
1764 x += dim.width;
1765 else
1766 y += dim.height;
1768 /* Remember maximum glyph matrix dimensions. */
1769 wmax = max (wmax, dim.width);
1770 hmax = max (hmax, dim.height);
1772 /* Next window on same level. */
1773 window = w->next;
1775 while (!NILP (window));
1777 /* Set `total' to the total glyph matrix dimension of this window
1778 level. In a vertical combination, the width is the width of the
1779 widest window; the height is the y we finally reached, corrected
1780 by the y we started with. In a horizontal combination, the total
1781 height is the height of the tallest window, and the width is the
1782 x we finally reached, corrected by the x we started with. */
1783 if (in_horz_combination_p)
1785 total.width = x - x0;
1786 total.height = hmax;
1788 else
1790 total.width = wmax;
1791 total.height = y - y0;
1794 return total;
1798 /* Allocate window matrices for window-based redisplay. W is the
1799 window whose matrices must be allocated/reallocated. CH_DIM is the
1800 size of the smallest character that could potentially be used on W. */
1802 static void
1803 allocate_matrices_for_window_redisplay (w, ch_dim)
1804 struct window *w;
1805 struct dim ch_dim;
1807 struct frame *f = XFRAME (w->frame);
1809 while (w)
1811 if (!NILP (w->vchild))
1812 allocate_matrices_for_window_redisplay (XWINDOW (w->vchild), ch_dim);
1813 else if (!NILP (w->hchild))
1814 allocate_matrices_for_window_redisplay (XWINDOW (w->hchild), ch_dim);
1815 else
1817 /* W is a leaf window. */
1818 int window_pixel_width = XFLOATINT (w->width) * CANON_X_UNIT (f);
1819 int window_pixel_height = window_box_height (w) + abs (w->vscroll);
1820 struct dim dim;
1822 /* If matrices are not yet allocated, allocate them now. */
1823 if (w->desired_matrix == NULL)
1825 w->desired_matrix = new_glyph_matrix (NULL);
1826 w->current_matrix = new_glyph_matrix (NULL);
1829 /* Compute number of glyphs needed in a glyph row. */
1830 dim.width = (((window_pixel_width + ch_dim.width - 1)
1831 / ch_dim.width)
1832 /* 2 partially visible columns in the text area. */
1834 /* One partially visible column at the right
1835 edge of each marginal area. */
1836 + 1 + 1);
1838 /* Compute number of glyph rows needed. */
1839 dim.height = (((window_pixel_height + ch_dim.height - 1)
1840 / ch_dim.height)
1841 /* One partially visible line at the top and
1842 bottom of the window. */
1844 /* 2 for top and mode line. */
1845 + 2);
1847 /* Change matrices. */
1848 adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
1849 adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
1852 w = NILP (w->next) ? NULL : XWINDOW (w->next);
1857 /* Re-allocate/ re-compute glyph matrices on frame F. If F is null,
1858 do it for all frames; otherwise do it just for the given frame.
1859 This function must be called when a new frame is created, its size
1860 changes, or its window configuration changes. */
1862 void
1863 adjust_glyphs (f)
1864 struct frame *f;
1866 if (f)
1867 adjust_frame_glyphs (f);
1868 else
1870 Lisp_Object tail, lisp_frame;
1872 FOR_EACH_FRAME (tail, lisp_frame)
1873 adjust_frame_glyphs (XFRAME (lisp_frame));
1878 /* Adjust frame glyphs when Emacs is initialized.
1880 To be called from init_display.
1882 We need a glyph matrix because redraw will happen soon.
1883 Unfortunately, window sizes on selected_frame are not yet set to
1884 meaningful values. I believe we can assume that there are only two
1885 windows on the frame---the mini-buffer and the root window. Frame
1886 height and width seem to be correct so far. So, set the sizes of
1887 windows to estimated values. */
1889 static void
1890 adjust_frame_glyphs_initially ()
1892 struct window *root = XWINDOW (selected_frame->root_window);
1893 struct window *mini = XWINDOW (root->next);
1894 int frame_height = FRAME_HEIGHT (selected_frame);
1895 int frame_width = FRAME_WIDTH (selected_frame);
1896 int top_margin = FRAME_TOP_MARGIN (selected_frame);
1898 /* Do it for the root window. */
1899 XSETFASTINT (root->top, top_margin);
1900 XSETFASTINT (root->width, frame_width);
1901 set_window_height (selected_frame->root_window,
1902 frame_height - 1 - top_margin, 0);
1904 /* Do it for the mini-buffer window. */
1905 XSETFASTINT (mini->top, frame_height - 1);
1906 XSETFASTINT (mini->width, frame_width);
1907 set_window_height (root->next, 1, 0);
1909 adjust_frame_glyphs (selected_frame);
1910 glyphs_initialized_initially_p = 1;
1914 /* Allocate/reallocate glyph matrices of a single frame F. */
1916 static void
1917 adjust_frame_glyphs (f)
1918 struct frame *f;
1920 if (FRAME_WINDOW_P (f))
1921 adjust_frame_glyphs_for_window_redisplay (f);
1922 else
1923 adjust_frame_glyphs_for_frame_redisplay (f);
1925 /* Don't forget the message buffer and the buffer for
1926 decode_mode_spec. */
1927 adjust_frame_message_buffer (f);
1928 adjust_decode_mode_spec_buffer (f);
1930 f->glyphs_initialized_p = 1;
1934 /* Allocate/reallocate glyph matrices of a single frame F for
1935 frame-based redisplay. */
1937 static void
1938 adjust_frame_glyphs_for_frame_redisplay (f)
1939 struct frame *f;
1941 struct dim ch_dim;
1942 struct dim matrix_dim;
1943 int pool_changed_p;
1944 int window_change_flags;
1945 int top_window_y;
1947 if (!FRAME_LIVE_P (f))
1948 return;
1950 /* Determine the smallest character in any font for F. On
1951 console windows, all characters have dimension (1, 1). */
1952 ch_dim.width = ch_dim.height = 1;
1954 top_window_y = FRAME_TOP_MARGIN (f);
1956 /* Allocate glyph pool structures if not already done. */
1957 if (f->desired_pool == NULL)
1959 f->desired_pool = new_glyph_pool ();
1960 f->current_pool = new_glyph_pool ();
1963 /* Allocate frames matrix structures if needed. */
1964 if (f->desired_matrix == NULL)
1966 f->desired_matrix = new_glyph_matrix (f->desired_pool);
1967 f->current_matrix = new_glyph_matrix (f->current_pool);
1970 /* Compute window glyph matrices. (This takes the mini-buffer
1971 window into account). The result is the size of the frame glyph
1972 matrix needed. The variable window_change_flags is set to a bit
1973 mask indicating whether new matrices will be allocated or
1974 existing matrices change their size or location within the frame
1975 matrix. */
1976 window_change_flags = 0;
1977 matrix_dim
1978 = allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
1979 0, top_window_y,
1980 ch_dim, 1,
1981 &window_change_flags);
1983 /* Add in menu bar lines, if any. */
1984 matrix_dim.height += top_window_y;
1986 /* Enlarge pools as necessary. */
1987 pool_changed_p = realloc_glyph_pool (f->desired_pool, matrix_dim);
1988 realloc_glyph_pool (f->current_pool, matrix_dim);
1990 /* Set up glyph pointers within window matrices. Do this only if
1991 absolutely necessary since it requires a frame redraw. */
1992 if (pool_changed_p || window_change_flags)
1994 /* Do it for window matrices. */
1995 allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
1996 0, top_window_y, ch_dim, 0,
1997 &window_change_flags);
1999 /* Size of frame matrices must equal size of frame. Note
2000 that we are called for X frames with window widths NOT equal
2001 to the frame width (from CHANGE_FRAME_SIZE_1). */
2002 xassert (matrix_dim.width == FRAME_WIDTH (f)
2003 && matrix_dim.height == FRAME_HEIGHT (f));
2005 /* Resize frame matrices. */
2006 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2007 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2009 /* Since location and size of sub-matrices within the pool may
2010 have changed, and current matrices don't have meaningful
2011 contents anymore, mark the frame garbaged. */
2012 SET_FRAME_GARBAGED (f);
2017 /* Allocate/reallocate glyph matrices of a single frame F for
2018 window-based redisplay. */
2020 static void
2021 adjust_frame_glyphs_for_window_redisplay (f)
2022 struct frame *f;
2024 struct dim ch_dim;
2025 struct window *w;
2027 xassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
2029 /* Get minimum sizes. */
2030 #ifdef HAVE_WINDOW_SYSTEM
2031 ch_dim.width = FRAME_SMALLEST_CHAR_WIDTH (f);
2032 ch_dim.height = FRAME_SMALLEST_FONT_HEIGHT (f);
2033 #else
2034 ch_dim.width = ch_dim.height = 1;
2035 #endif
2037 /* Allocate/reallocate window matrices. */
2038 allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)),
2039 ch_dim);
2041 /* Allocate/ reallocate matrices of the dummy window used to display
2042 the menu bar under X when no X toolkit support is available. */
2043 #ifndef USE_X_TOOLKIT
2045 /* Allocate a dummy window if not already done. */
2046 if (NILP (f->menu_bar_window))
2048 f->menu_bar_window = make_window ();
2049 w = XWINDOW (f->menu_bar_window);
2050 XSETFRAME (w->frame, f);
2051 w->pseudo_window_p = 1;
2053 else
2054 w = XWINDOW (f->menu_bar_window);
2056 /* Set window dimensions to frame dimensions and allocate or
2057 adjust glyph matrices of W. */
2058 XSETFASTINT (w->top, 0);
2059 XSETFASTINT (w->left, 0);
2060 XSETFASTINT (w->height, FRAME_MENU_BAR_LINES (f));
2061 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
2062 allocate_matrices_for_window_redisplay (w, ch_dim);
2064 #endif /* not USE_X_TOOLKIT */
2066 /* Allocate/ reallocate matrices of the toolbar window. If we don't
2067 have a toolbar window yet, make one. */
2068 if (NILP (f->toolbar_window))
2070 f->toolbar_window = make_window ();
2071 w = XWINDOW (f->toolbar_window);
2072 XSETFRAME (w->frame, f);
2073 w->pseudo_window_p = 1;
2075 else
2076 w = XWINDOW (f->toolbar_window);
2078 XSETFASTINT (w->top, FRAME_MENU_BAR_LINES (f));
2079 XSETFASTINT (w->left, 0);
2080 XSETFASTINT (w->height, FRAME_TOOLBAR_LINES (f));
2081 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
2082 allocate_matrices_for_window_redisplay (w, ch_dim);
2086 /* Adjust/ allocate message buffer of frame F.
2088 The global variables echo_area_glyphs and previous_echo_area_glyphs
2089 may be pointing to the frames message buffer and must be relocated
2090 if the buffer is reallocated.
2092 Note that the message buffer is never freed. Since I could not
2093 find a free in 19.34, I assume that freeing it would be
2094 problematic in some way and don't do it either.
2096 (Implementation note: It should be checked if we can free it
2097 eventually without causing trouble). */
2099 static void
2100 adjust_frame_message_buffer (f)
2101 struct frame *f;
2103 int size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
2105 if (FRAME_MESSAGE_BUF (f))
2107 char *buffer = FRAME_MESSAGE_BUF (f);
2108 char *new_buffer = (char *) xrealloc (buffer, size);
2110 if (buffer == echo_area_glyphs)
2111 echo_area_glyphs = new_buffer;
2112 if (buffer == previous_echo_glyphs)
2113 previous_echo_glyphs = new_buffer;
2115 FRAME_MESSAGE_BUF (f) = new_buffer;
2117 else
2118 FRAME_MESSAGE_BUF (f) = (char *) xmalloc (size);
2122 /* Re-allocate buffer for decode_mode_spec on frame F. */
2124 static void
2125 adjust_decode_mode_spec_buffer (f)
2126 struct frame *f;
2128 f->decode_mode_spec_buffer
2129 = (char *) xrealloc (f->decode_mode_spec_buffer,
2130 FRAME_MESSAGE_BUF_SIZE (f) + 1);
2135 /**********************************************************************
2136 Freeing Glyph Matrices
2137 **********************************************************************/
2139 /* Free glyph memory for a frame F. F may be null. This function can
2140 be called for the same frame more than once. The root window of
2141 F may be nil when this function is called. This is the case when
2142 the function is called when F is destroyed. */
2144 void
2145 free_glyphs (f)
2146 struct frame *f;
2148 if (f && f->glyphs_initialized_p)
2150 f->glyphs_initialized_p = 0;
2152 /* Release window sub-matrices. */
2153 if (!NILP (f->root_window))
2154 free_window_matrices (XWINDOW (f->root_window));
2156 /* Free the dummy window for menu bars without X toolkit and its
2157 glyph matrices. */
2158 if (!NILP (f->menu_bar_window))
2160 struct window *w = XWINDOW (f->menu_bar_window);
2161 free_glyph_matrix (w->desired_matrix);
2162 free_glyph_matrix (w->current_matrix);
2163 w->desired_matrix = w->current_matrix = NULL;
2164 f->menu_bar_window = Qnil;
2167 /* Free the toolbar window and its glyph matrices. */
2168 if (!NILP (f->toolbar_window))
2170 struct window *w = XWINDOW (f->toolbar_window);
2171 free_glyph_matrix (w->desired_matrix);
2172 free_glyph_matrix (w->current_matrix);
2173 w->desired_matrix = w->current_matrix = NULL;
2174 f->toolbar_window = Qnil;
2177 /* Release frame glyph matrices. Reset fields to zero in
2178 case we are called a second time. */
2179 if (f->desired_matrix)
2181 free_glyph_matrix (f->desired_matrix);
2182 free_glyph_matrix (f->current_matrix);
2183 f->desired_matrix = f->current_matrix = NULL;
2186 /* Release glyph pools. */
2187 if (f->desired_pool)
2189 free_glyph_pool (f->desired_pool);
2190 free_glyph_pool (f->current_pool);
2191 f->desired_pool = f->current_pool = NULL;
2197 /* Free glyph sub-matrices in the window tree rooted at W. This
2198 function may be called with a null pointer, and it may be called on
2199 the same tree more than once. */
2201 void
2202 free_window_matrices (w)
2203 struct window *w;
2205 while (w)
2207 if (!NILP (w->hchild))
2208 free_window_matrices (XWINDOW (w->hchild));
2209 else if (!NILP (w->vchild))
2210 free_window_matrices (XWINDOW (w->vchild));
2211 else
2213 /* This is a leaf window. Free its memory and reset fields
2214 to zero in case this function is called a second time for
2215 W. */
2216 free_glyph_matrix (w->current_matrix);
2217 free_glyph_matrix (w->desired_matrix);
2218 w->current_matrix = w->desired_matrix = NULL;
2221 /* Next window on same level. */
2222 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2227 /* Check glyph memory leaks. This function is called from
2228 shut_down_emacs. Note that frames are not destroyed when Emacs
2229 exits. We therefore free all glyph memory for all active frames
2230 explicitly and check that nothing is left allocated. */
2232 void
2233 check_glyph_memory ()
2235 Lisp_Object tail, frame;
2237 /* Free glyph memory for all frames. */
2238 FOR_EACH_FRAME (tail, frame)
2239 free_glyphs (XFRAME (frame));
2241 /* Check that nothing is left allocated. */
2242 if (glyph_matrix_count)
2243 abort ();
2244 if (glyph_pool_count)
2245 abort ();
2250 /**********************************************************************
2251 Building a Frame Matrix
2252 **********************************************************************/
2254 /* Most of the redisplay code works on glyph matrices attached to
2255 windows. This is a good solution most of the time, but it is not
2256 suitable for terminal code. Terminal output functions cannot rely
2257 on being able to set an arbitrary terminal window. Instead they
2258 must be provided with a view of the whole frame, i.e. the whole
2259 screen. We build such a view by constructing a frame matrix from
2260 window matrices in this section.
2262 Windows that must be updated have their must_be_update_p flag set.
2263 For all such windows, their desired matrix is made part of the
2264 desired frame matrix. For other windows, their current matrix is
2265 made part of the desired frame matrix.
2267 +-----------------+----------------+
2268 | desired | desired |
2269 | | |
2270 +-----------------+----------------+
2271 | current |
2273 +----------------------------------+
2275 Desired window matrices can be made part of the frame matrix in a
2276 cheap way: We exploit the fact that the desired frame matrix and
2277 desired window matrices share their glyph memory. This is not
2278 possible for current window matrices. Their glyphs are copied to
2279 the desired frame matrix. The latter is equivalent to
2280 preserve_other_columns in the old redisplay.
2282 Used glyphs counters for frame matrix rows are the result of adding
2283 up glyph lengths of the window matrices. A line in the frame
2284 matrix is enabled, if a corresponding line in a window matrix is
2285 enabled.
2287 After building the desired frame matrix, it will be passed to
2288 terminal code, which will manipulate both the desired and current
2289 frame matrix. Changes applied to the frame's current matrix have
2290 to be visible in current window matrices afterwards, of course.
2292 This problem is solved like this:
2294 1. Window and frame matrices share glyphs. Window matrices are
2295 constructed in a way that their glyph contents ARE the glyph
2296 contents needed in a frame matrix. Thus, any modification of
2297 glyphs done in terminal code will be reflected in window matrices
2298 automatically.
2300 2. Exchanges of rows in a frame matrix done by terminal code are
2301 intercepted by hook functions so that corresponding row operations
2302 on window matrices can be performed. This is necessary because we
2303 use pointers to glyphs in glyph row structures. To satisfy the
2304 assumption of point 1 above that glyphs are updated implicitly in
2305 window matrices when they are manipulated via the frame matrix,
2306 window and frame matrix must of course agree where to find the
2307 glyphs for their rows. Possible manipulations that must be
2308 mirrored are assignments of rows of the desired frame matrix to the
2309 current frame matrix and scrolling the current frame matrix. */
2311 /* Build frame F's desired matrix from window matrices. Only windows
2312 which have the flag must_be_updated_p set have to be updated. Menu
2313 bar lines of a frame are not covered by window matrices, so make
2314 sure not to touch them in this function. */
2316 static void
2317 build_frame_matrix (f)
2318 struct frame *f;
2320 int i;
2322 /* F must have a frame matrix when this function is called. */
2323 xassert (!FRAME_WINDOW_P (f));
2325 /* Clear all rows in the frame matrix covered by window matrices.
2326 Menu bar lines are not covered by windows. */
2327 for (i = FRAME_TOP_MARGIN (f); i < f->desired_matrix->nrows; ++i)
2328 clear_glyph_row (MATRIX_ROW (f->desired_matrix, i));
2330 /* Build the matrix by walking the window tree. */
2331 build_frame_matrix_from_window_tree (f->desired_matrix,
2332 XWINDOW (FRAME_ROOT_WINDOW (f)));
2336 /* Walk a window tree, building a frame matrix MATRIX from window
2337 matrices. W is the root of a window tree. */
2339 static void
2340 build_frame_matrix_from_window_tree (matrix, w)
2341 struct glyph_matrix *matrix;
2342 struct window *w;
2344 while (w)
2346 if (!NILP (w->hchild))
2347 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->hchild));
2348 else if (!NILP (w->vchild))
2349 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->vchild));
2350 else
2351 build_frame_matrix_from_leaf_window (matrix, w);
2353 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2358 /* Add a window's matrix to a frame matrix. FRAME_MATRIX is the
2359 desired frame matrix built. W is a leaf window whose desired or
2360 current matrix is to be added to FRAME_MATRIX. W's flag
2361 must_be_updated_p determines which matrix it contributes to
2362 FRAME_MATRIX. If must_be_updated_p is non-zero, W's desired matrix
2363 is added to FRAME_MATRIX, otherwise W's current matrix is added.
2364 Adding a desired matrix means setting up used counters and such in
2365 frame rows, while adding a current window matrix to FRAME_MATRIX
2366 means copying glyphs. The latter case corresponds to
2367 preserve_other_columns in the old redisplay. */
2369 static void
2370 build_frame_matrix_from_leaf_window (frame_matrix, w)
2371 struct glyph_matrix *frame_matrix;
2372 struct window *w;
2374 struct glyph_matrix *window_matrix;
2375 int window_y, frame_y;
2376 /* If non-zero, a glyph to insert at the right border of W. */
2377 GLYPH right_border_glyph = 0;
2379 /* Set window_matrix to the matrix we have to add to FRAME_MATRIX. */
2380 if (w->must_be_updated_p)
2382 window_matrix = w->desired_matrix;
2384 /* Decide whether we want to add a vertical border glyph. */
2385 if (!WINDOW_RIGHTMOST_P (w))
2387 struct Lisp_Char_Table *dp = window_display_table (w);
2388 right_border_glyph = (dp && INTEGERP (DISP_BORDER_GLYPH (dp))
2389 ? XINT (DISP_BORDER_GLYPH (dp))
2390 : '|');
2393 else
2394 window_matrix = w->current_matrix;
2396 /* For all rows in the window matrix and corresponding rows in the
2397 frame matrix. */
2398 window_y = 0;
2399 frame_y = window_matrix->matrix_y;
2400 while (window_y < window_matrix->nrows)
2402 struct glyph_row *frame_row = frame_matrix->rows + frame_y;
2403 struct glyph_row *window_row = window_matrix->rows + window_y;
2405 /* Fill up the frame row with spaces up to the left margin of the
2406 window row. */
2407 fill_up_frame_row_with_spaces (frame_row, window_matrix->matrix_x);
2409 /* Fill up areas in the window matrix row with spaces. */
2410 fill_up_glyph_row_with_spaces (window_row);
2412 if (window_matrix == w->current_matrix)
2414 /* We have to copy W's current matrix. Copy window
2415 row to frame row. */
2416 bcopy (window_row->glyphs[0],
2417 frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
2418 window_matrix->matrix_w * sizeof (struct glyph));
2420 else
2422 /* Copy W's desired matrix. */
2424 /* Maybe insert a vertical border between horizontally adjacent
2425 windows. */
2426 if (right_border_glyph)
2428 struct glyph *border = window_row->glyphs[LAST_AREA] - 1;
2429 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
2432 /* Due to hooks installed, it normally doesn't happen that
2433 window rows and frame rows of the same matrix are out of
2434 sync, i.e. have a different understanding of where to
2435 find glyphs for the row. The following is a safety-belt
2436 that doesn't cost much and makes absolutely sure that
2437 window and frame matrices are in sync. */
2438 if (!glyph_row_slice_p (window_row, frame_row))
2440 /* Find the row in the window being a slice. There
2441 should exist one from program logic. */
2442 struct glyph_row *slice_row
2443 = find_glyph_row_slice (window_matrix, frame_matrix, frame_y);
2444 xassert (slice_row != 0);
2446 /* Exchange glyphs between both window rows. */
2447 swap_glyphs_in_rows (window_row, slice_row);
2449 /* Exchange pointers between both rows. */
2450 swap_glyph_pointers (window_row, slice_row);
2453 /* Now, we are sure that window row window_y is a slice of
2454 the frame row frame_y. But, lets check that assumption. */
2455 xassert (glyph_row_slice_p (window_row, frame_row));
2457 /* If rows are in sync, we don't have to copy glyphs because
2458 frame and window share glyphs. */
2461 /* Set number of used glyphs in the frame matrix. Since we fill
2462 up with spaces, and visit leaf windows from left to right it
2463 can be done simply. */
2464 frame_row->used[TEXT_AREA]
2465 = window_matrix->matrix_x + window_matrix->matrix_w;
2467 /* Or in flags. */
2468 frame_row->enabled_p |= window_row->enabled_p;
2469 frame_row->inverse_p |= window_row->inverse_p;
2471 /* Next row. */
2472 ++window_y;
2473 ++frame_y;
2478 /* Add spaces to a glyph row ROW in a window matrix.
2480 Each row has the form:
2482 +---------+-----------------------------+------------+
2483 | left | text | right |
2484 +---------+-----------------------------+------------+
2486 Left and right marginal areas are optional. This function adds
2487 spaces to areas so that there are no empty holes between areas.
2488 In other words: If the right area is not empty, the text area
2489 is filled up with spaces up to the right area. If the text area
2490 is not empty, the left area is filled up.
2492 To be called for frame-based redisplay, only. */
2494 static void
2495 fill_up_glyph_row_with_spaces (row)
2496 struct glyph_row *row;
2498 fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA);
2499 fill_up_glyph_row_area_with_spaces (row, TEXT_AREA);
2500 fill_up_glyph_row_area_with_spaces (row, RIGHT_MARGIN_AREA);
2504 /* Fill area AREA of glyph row ROW with spaces. To be called for
2505 frame-based redisplay only. */
2507 static void
2508 fill_up_glyph_row_area_with_spaces (row, area)
2509 struct glyph_row *row;
2510 int area;
2512 if (row->glyphs[area] < row->glyphs[area + 1])
2514 struct glyph *end = row->glyphs[area + 1];
2515 struct glyph *text = row->glyphs[area] + row->used[area];
2517 while (text < end)
2518 *text++ = space_glyph;
2519 row->used[area] = text - row->glyphs[area];
2524 /* Add spaces to the end of ROW in a frame matrix until index UPTO is
2525 reached. In frame matrices only one area, TEXT_AREA, is used. */
2527 static void
2528 fill_up_frame_row_with_spaces (row, upto)
2529 struct glyph_row *row;
2530 int upto;
2532 int i = row->used[TEXT_AREA];
2533 struct glyph *glyph = row->glyphs[TEXT_AREA];
2535 while (i < upto)
2536 glyph[i++] = space_glyph;
2538 row->used[TEXT_AREA] = i;
2543 /**********************************************************************
2544 Mirroring operations on frame matrices in window matrices
2545 **********************************************************************/
2547 /* Set frame being updated via frame-based redisplay to F. This
2548 function must be called before updates to make explicit that we are
2549 working on frame matrices or not. */
2551 static INLINE void
2552 set_frame_matrix_frame (f)
2553 struct frame *f;
2555 frame_matrix_frame = f;
2559 /* Make sure glyph row ROW in CURRENT_MATRIX is up to date.
2560 DESIRED_MATRIX is the desired matrix corresponding to
2561 CURRENT_MATRIX. The update is done by exchanging glyph pointers
2562 between rows in CURRENT_MATRIX and DESIRED_MATRIX. If
2563 frame_matrix_frame is non-null, this indicates that the exchange is
2564 done in frame matrices, and that we have to perform analogous
2565 operations in window matrices of frame_matrix_frame. */
2567 static INLINE void
2568 make_current (desired_matrix, current_matrix, row)
2569 struct glyph_matrix *desired_matrix, *current_matrix;
2570 int row;
2572 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2573 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
2575 /* Do current_row = desired_row. This exchanges glyph pointers
2576 between both rows, and does a structure assignment otherwise. */
2577 assign_row (current_row, desired_row);
2579 /* Enable current_row to mark it as valid. */
2580 current_row->enabled_p = 1;
2582 /* If we are called on frame matrices, perform analogous operations
2583 for window matrices. */
2584 if (frame_matrix_frame)
2585 mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row);
2589 /* W is the root of a window tree. FRAME_ROW is the index of a row in
2590 W's frame which has been made current (by swapping pointers between
2591 current and desired matrix). Perform analogous operations in the
2592 matrices of leaf windows in the window tree rooted at W. */
2594 static void
2595 mirror_make_current (w, frame_row)
2596 struct window *w;
2597 int frame_row;
2599 while (w)
2601 if (!NILP (w->hchild))
2602 mirror_make_current (XWINDOW (w->hchild), frame_row);
2603 else if (!NILP (w->vchild))
2604 mirror_make_current (XWINDOW (w->vchild), frame_row);
2605 else
2607 /* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS
2608 here because the checks performed in debug mode there
2609 will not allow the conversion. */
2610 int row = frame_row - w->desired_matrix->matrix_y;
2612 /* If FRAME_ROW is within W, assign the desired row to the
2613 current row (exchanging glyph pointers). */
2614 if (row >= 0 && row < w->desired_matrix->matrix_h)
2616 struct glyph_row *current_row
2617 = MATRIX_ROW (w->current_matrix, row);
2618 struct glyph_row *desired_row
2619 = MATRIX_ROW (w->desired_matrix, row);
2621 assign_row (current_row, desired_row);
2622 current_row->enabled_p = 1;
2626 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2631 /* Perform row dance after scrolling. We are working on the range of
2632 lines UNCHANGED_AT_TOP + 1 to UNCHANGED_AT_TOP + NLINES (not
2633 including) in MATRIX. COPY_FROM is a vector containing, for each
2634 row I in the range 0 <= I < NLINES, the index of the original line
2635 to move to I. This index is relative to the row range, i.e. 0 <=
2636 index < NLINES. RETAINED_P is a vector containing zero for each
2637 row 0 <= I < NLINES which is empty.
2639 This function is called from do_scrolling and do_direct_scrolling. */
2641 void
2642 mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
2643 retained_p)
2644 struct glyph_matrix *matrix;
2645 int unchanged_at_top, nlines;
2646 int *copy_from;
2647 char *retained_p;
2649 /* A copy of original rows. */
2650 struct glyph_row *old_rows;
2652 /* Rows to assign to. */
2653 struct glyph_row *new_rows = MATRIX_ROW (matrix, unchanged_at_top);
2655 int i;
2657 /* Make a copy of the original rows. */
2658 old_rows = (struct glyph_row *) alloca (nlines * sizeof *old_rows);
2659 bcopy (new_rows, old_rows, nlines * sizeof *old_rows);
2661 /* Assign new rows, maybe clear lines. */
2662 for (i = 0; i < nlines; ++i)
2664 int enabled_before_p = new_rows[i].enabled_p;
2666 xassert (i + unchanged_at_top < matrix->nrows);
2667 xassert (unchanged_at_top + copy_from[i] < matrix->nrows);
2668 new_rows[i] = old_rows[copy_from[i]];
2669 new_rows[i].enabled_p = enabled_before_p;
2671 /* RETAINED_P is zero for empty lines. */
2672 if (!retained_p[copy_from[i]])
2673 new_rows[i].enabled_p = 0;
2676 /* Do the same for window matrices, if MATRIX Is a frame matrix. */
2677 if (frame_matrix_frame)
2678 mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
2679 unchanged_at_top, nlines, copy_from, retained_p);
2683 /* Perform a line dance in the window tree rooted at W, after
2684 scrolling a frame matrix in mirrored_line_dance.
2686 We are working on the range of lines UNCHANGED_AT_TOP + 1 to
2687 UNCHANGED_AT_TOP + NLINES (not including) in W's frame matrix.
2688 COPY_FROM is a vector containing, for each row I in the range 0 <=
2689 I < NLINES, the index of the original line to move to I. This
2690 index is relative to the row range, i.e. 0 <= index < NLINES.
2691 RETAINED_P is a vector containing zero for each row 0 <= I < NLINES
2692 which is empty. */
2694 static void
2695 mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
2696 struct window *w;
2697 int unchanged_at_top, nlines;
2698 int *copy_from;
2699 char *retained_p;
2701 while (w)
2703 if (!NILP (w->hchild))
2704 mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top,
2705 nlines, copy_from, retained_p);
2706 else if (!NILP (w->vchild))
2707 mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
2708 nlines, copy_from, retained_p);
2709 else
2711 /* W is a leaf window, and we are working on its current
2712 matrix m. */
2713 struct glyph_matrix *m = w->current_matrix;
2715 int i;
2717 struct glyph_row *old_rows;
2719 /* Make a copy of the original rows of matrix m. */
2720 old_rows = (struct glyph_row *) alloca (m->nrows * sizeof *old_rows);
2721 bcopy (m->rows, old_rows, m->nrows * sizeof *old_rows);
2723 for (i = 0; i < nlines; ++i)
2725 /* Frame relative line assigned to. */
2726 int frame_to = i + unchanged_at_top;
2728 /* Frame relative line assigned. */
2729 int frame_from = copy_from[i] + unchanged_at_top;
2731 /* Window relative line assigned to. */
2732 int window_to = frame_to - m->matrix_y;
2734 /* Window relative line assigned. */
2735 int window_from = frame_from - m->matrix_y;
2737 /* Is assigned line inside window? */
2738 int from_inside_window_p
2739 = window_from >= 0 && window_from < m->matrix_h;
2741 if (from_inside_window_p)
2743 #if GLYPH_DEBUG
2744 /* Is assigned to line inside window? */
2745 int to_inside_window_p
2746 = window_to >= 0 && window_to < m->matrix_h;
2747 #endif
2749 /* Enabled setting before assignment. */
2750 int enabled_before_p;
2752 /* If not both lines inside the window, we have a
2753 serious problem. */
2754 xassert (to_inside_window_p);
2756 /* Do the assignment. The enabled_p flag is saved
2757 over the assignment because the old redisplay did
2758 that. */
2759 enabled_before_p = m->rows[window_to].enabled_p;
2760 m->rows[window_to] = old_rows[window_from];
2761 m->rows[window_to].enabled_p = enabled_before_p;
2763 /* If frame line is empty, window line is empty, too. */
2764 if (!retained_p[copy_from[i]])
2765 m->rows[window_to].enabled_p = 0;
2769 /* Check that no pointers are lost. */
2770 CHECK_MATRIX (m);
2773 /* Next window on same level. */
2774 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2779 #if GLYPH_DEBUG
2781 /* Check that window and frame matrices agree about their
2782 understanding where glyphs of the rows are to find. For each
2783 window in the window tree rooted at W, check that rows in the
2784 matrices of leaf window agree with their frame matrices about
2785 glyph pointers. */
2787 void
2788 check_window_matrix_pointers (w)
2789 struct window *w;
2791 while (w)
2793 if (!NILP (w->hchild))
2794 check_window_matrix_pointers (XWINDOW (w->hchild));
2795 else if (!NILP (w->vchild))
2796 check_window_matrix_pointers (XWINDOW (w->vchild));
2797 else
2799 struct frame *f = XFRAME (w->frame);
2800 check_matrix_pointers (w->desired_matrix, f->desired_matrix);
2801 check_matrix_pointers (w->current_matrix, f->current_matrix);
2804 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2809 /* Check that window rows are slices of frame rows. WINDOW_MATRIX is
2810 a window and FRAME_MATRIX is the corresponding frame matrix. For
2811 each row in WINDOW_MATRIX check that it's a slice of the
2812 corresponding frame row. If it isn't, abort. */
2814 static void
2815 check_matrix_pointers (window_matrix, frame_matrix)
2816 struct glyph_matrix *window_matrix, *frame_matrix;
2818 /* Row number in WINDOW_MATRIX. */
2819 int i = 0;
2821 /* Row number corresponding to I in FRAME_MATRIX. */
2822 int j = window_matrix->matrix_y;
2824 /* For all rows check that the row in the window matrix is a
2825 slice of the row in the frame matrix. If it isn't we didn't
2826 mirror an operation on the frame matrix correctly. */
2827 while (i < window_matrix->nrows)
2829 if (!glyph_row_slice_p (window_matrix->rows + i,
2830 frame_matrix->rows + j))
2831 abort ();
2832 ++i, ++j;
2836 #endif /* GLYPH_DEBUG != 0 */
2840 /**********************************************************************
2841 VPOS and HPOS translations
2842 **********************************************************************/
2844 #if GLYPH_DEBUG
2846 /* Translate vertical position VPOS which is relative to window W to a
2847 vertical position relative to W's frame. */
2849 static int
2850 window_to_frame_vpos (w, vpos)
2851 struct window *w;
2852 int vpos;
2854 struct frame *f = XFRAME (w->frame);
2856 xassert (!FRAME_WINDOW_P (f));
2857 xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
2858 vpos += XFASTINT (w->top);
2859 xassert (vpos >= 0 && vpos <= FRAME_HEIGHT (f));
2860 return vpos;
2864 /* Translate horizontal position HPOS which is relative to window W to
2865 a vertical position relative to W's frame. */
2867 static int
2868 window_to_frame_hpos (w, hpos)
2869 struct window *w;
2870 int hpos;
2872 struct frame *f = XFRAME (w->frame);
2874 xassert (!FRAME_WINDOW_P (f));
2875 hpos += XFASTINT (w->left);
2876 return hpos;
2879 #endif /* GLYPH_DEBUG */
2883 /**********************************************************************
2884 Redrawing Frames
2885 **********************************************************************/
2887 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
2888 "Clear frame FRAME and output again what is supposed to appear on it.")
2889 (frame)
2890 Lisp_Object frame;
2892 struct frame *f;
2894 CHECK_LIVE_FRAME (frame, 0);
2895 f = XFRAME (frame);
2897 /* Ignore redraw requests, if frame has no glyphs yet.
2898 (Implementation note: It still has to be checked why we are
2899 called so early here). */
2900 if (!glyphs_initialized_initially_p)
2901 return Qnil;
2903 update_begin (f);
2904 if (FRAME_MSDOS_P (f))
2905 set_terminal_modes ();
2906 clear_frame ();
2907 clear_current_matrices (f);
2908 update_end (f);
2909 fflush (stdout);
2910 windows_or_buffers_changed++;
2911 /* Mark all windows as inaccurate, so that every window will have
2912 its redisplay done. */
2913 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
2914 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
2915 f->garbaged = 0;
2916 return Qnil;
2920 /* Redraw frame F. This is nothing more than a call to the Lisp
2921 function redraw-frame. */
2923 void
2924 redraw_frame (f)
2925 struct frame *f;
2927 Lisp_Object frame;
2928 XSETFRAME (frame, f);
2929 Fredraw_frame (frame);
2933 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
2934 "Clear and redisplay all visible frames.")
2937 Lisp_Object tail, frame;
2939 FOR_EACH_FRAME (tail, frame)
2940 if (FRAME_VISIBLE_P (XFRAME (frame)))
2941 Fredraw_frame (frame);
2943 return Qnil;
2947 /* This is used when frame_garbaged is set. Call Fredraw_frame on all
2948 visible frames marked as garbaged. */
2950 void
2951 redraw_garbaged_frames ()
2953 Lisp_Object tail, frame;
2955 FOR_EACH_FRAME (tail, frame)
2956 if (FRAME_VISIBLE_P (XFRAME (frame))
2957 && FRAME_GARBAGED_P (XFRAME (frame)))
2958 Fredraw_frame (frame);
2963 /***********************************************************************
2964 Direct Operations
2965 ***********************************************************************/
2967 /* Try to update display and current glyph matrix directly.
2969 This function is called after a character G has been inserted into
2970 current_buffer. It tries to update the current glyph matrix and
2971 perform appropriate screen output to reflect the insertion. If it
2972 succeeds, the global flag redisplay_performed_directly_p will be
2973 set to 1, and thereby prevent the more costly general redisplay
2974 from running (see redisplay_internal).
2976 This function is not called for `hairy' character insertions.
2977 In particular, it is not called when after or before change
2978 functions exist, like they are used by font-lock. See keyboard.c
2979 for details where this function is called. */
2982 direct_output_for_insert (g)
2983 int g;
2985 register struct frame *f = selected_frame;
2986 struct window *w = XWINDOW (selected_window);
2987 struct it it, it2;
2988 struct glyph_row *glyph_row;
2989 struct glyph *glyphs, *glyph, *end;
2990 int n;
2991 /* Non-null means that Redisplay of W is based on window matrices. */
2992 int window_redisplay_p = FRAME_WINDOW_P (f);
2993 /* Non-null means we are in overwrite mode. */
2994 int overwrite_p = !NILP (current_buffer->overwrite_mode);
2995 int added_width;
2996 struct text_pos pos;
2997 int delta, delta_bytes;
2999 /* Not done directly. */
3000 redisplay_performed_directly_p = 0;
3002 /* Quickly give up for some common cases. */
3003 if (cursor_in_echo_area
3004 /* Give up if fonts have changed. */
3005 || fonts_changed_p
3006 /* Give up if face attributes have been changed. */
3007 || face_change_count
3008 /* Give up if cursor position not really known. */
3009 || !display_completed
3010 /* Give up if buffer appears in two places. */
3011 || buffer_shared > 1
3012 /* Give up if w is mini-buffer and a message is being displayed there */
3013 || (MINI_WINDOW_P (w)
3014 && (echo_area_glyphs || STRINGP (echo_area_message)))
3015 /* Give up for hscrolled mini-buffer because display of the prompt
3016 is handled specially there (see display_line). */
3017 || (MINI_WINDOW_P (w) && XFASTINT (w->hscroll))
3018 /* Give up if overwriting in the middle of a line. */
3019 || (overwrite_p
3020 && PT != ZV
3021 && FETCH_BYTE (PT) != '\n')
3022 /* Give up for tabs and line ends. */
3023 || g == '\t'
3024 || g == '\n'
3025 || g == '\r'
3026 /* Give up if unable to display the cursor in the window. */
3027 || w->cursor.vpos < 0
3028 /* Can't do it in a continued line because continuation lines
3029 will change. */
3030 || MATRIX_ROW (w->current_matrix, w->cursor.vpos)->continued_p
3031 /* Can't do it for partial width windows on terminal frames
3032 because we can't clear to eol in such a window. */
3033 || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w)))
3034 return 0;
3036 /* Set up a display iterator structure for W. Glyphs will be
3037 produced in scratch_glyph_row. Current position is W's cursor
3038 position. */
3039 clear_glyph_row (&scratch_glyph_row);
3040 SET_TEXT_POS (pos, PT, PT_BYTE);
3041 DEC_TEXT_POS (pos);
3042 init_iterator (&it, w, CHARPOS (pos), BYTEPOS (pos), &scratch_glyph_row,
3043 DEFAULT_FACE_ID);
3045 glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
3047 /* Give up if highlighting trailing whitespace and we have trailing
3048 whitespace in glyph_row. We would have to remove the trailing
3049 whitespace face in that case. */
3050 if (it.show_trailing_whitespace_p
3051 && glyph_row->used[TEXT_AREA])
3053 struct glyph *last;
3055 last = glyph_row->glyphs[TEXT_AREA] + glyph_row->used[TEXT_AREA] - 1;
3056 if (last->type == STRETCH_GLYPH
3057 || (last->type == CHAR_GLYPH
3058 && last->u.ch.code == ' '))
3059 return 0;
3062 /* Give up if there are overlay strings at pos. This would fail
3063 if the overlay string has newlines in it. */
3064 if (STRINGP (it.string))
3065 return 0;
3067 it.hpos = w->cursor.hpos;
3068 it.vpos = w->cursor.vpos;
3069 it.current_x = w->cursor.x + it.first_visible_x;
3070 it.current_y = w->cursor.y;
3071 it.end_charpos = PT;
3072 it.stop_charpos = min (PT, it.stop_charpos);
3074 /* More than one display element may be returned for PT - 1 if
3075 (i) it's a control character which is translated into `\003' or
3076 `^C', or (ii) it has a display table entry, or (iii) it's a
3077 combination of both. */
3078 delta = delta_bytes = 0;
3079 while (get_next_display_element (&it))
3081 PRODUCE_GLYPHS (&it);
3083 /* Give up if glyph doesn't fit completely on the line. */
3084 if (it.current_x >= it.last_visible_x)
3085 return 0;
3087 /* Give up if new glyph has different ascent or descent than
3088 the original row, or if it is not a character glyph. */
3089 if (glyph_row->ascent != it.ascent
3090 || glyph_row->height != it.ascent + it.descent
3091 || it.what != IT_CHARACTER)
3092 return 0;
3094 delta += 1;
3095 delta_bytes += it.len;
3096 set_iterator_to_next (&it);
3099 /* Give up if we hit the right edge of the window. We would have
3100 to insert truncation or continuation glyphs. */
3101 added_width = it.current_x - (w->cursor.x + it.first_visible_x);
3102 if (glyph_row->pixel_width + added_width >= it.last_visible_x)
3103 return 0;
3105 /* Give up if there is a \t following in the line. */
3106 it2 = it;
3107 it2.end_charpos = ZV;
3108 it2.stop_charpos = min (it2.stop_charpos, ZV);
3109 while (get_next_display_element (&it2)
3110 && !ITERATOR_AT_END_OF_LINE_P (&it2))
3112 if (it2.c == '\t')
3113 return 0;
3114 set_iterator_to_next (&it2);
3117 /* Number of new glyphs produced. */
3118 n = it.glyph_row->used[TEXT_AREA];
3120 /* Start and end of glyphs in original row. */
3121 glyphs = glyph_row->glyphs[TEXT_AREA] + w->cursor.hpos;
3122 end = glyph_row->glyphs[1 + TEXT_AREA];
3124 /* Make room for new glyphs, then insert them. */
3125 xassert (end - glyphs - n >= 0);
3126 safe_bcopy (glyphs, glyphs + n, (end - glyphs - n) * sizeof (*end));
3127 bcopy (it.glyph_row->glyphs[TEXT_AREA], glyphs, n * sizeof *glyphs);
3128 glyph_row->used[TEXT_AREA] = min (glyph_row->used[TEXT_AREA] + n,
3129 end - glyph_row->glyphs[TEXT_AREA]);
3131 /* Compute new line width. */
3132 glyph = glyph_row->glyphs[TEXT_AREA];
3133 end = glyph + glyph_row->used[TEXT_AREA];
3134 glyph_row->pixel_width = glyph_row->x;
3135 while (glyph < end)
3137 glyph_row->pixel_width += glyph->pixel_width;
3138 ++glyph;
3141 /* Increment buffer positions for glyphs following the newly
3142 inserted ones. */
3143 for (glyph = glyphs + n; glyph < end; ++glyph)
3144 if (glyph->charpos > 0)
3145 glyph->charpos += delta;
3147 if (MATRIX_ROW_END_CHARPOS (glyph_row) > 0)
3149 MATRIX_ROW_END_CHARPOS (glyph_row) += delta;
3150 MATRIX_ROW_END_BYTEPOS (glyph_row) += delta_bytes;
3153 /* Adjust positions in lines following the one we are in. */
3154 increment_glyph_matrix_buffer_positions (w->current_matrix,
3155 w->cursor.vpos + 1,
3156 w->current_matrix->nrows,
3157 delta, delta_bytes);
3159 glyph_row->contains_overlapping_glyphs_p
3160 |= it.glyph_row->contains_overlapping_glyphs_p;
3162 if (it.show_trailing_whitespace_p)
3163 highlight_trailing_whitespace (it.f, glyph_row);
3165 /* Write glyphs. If at end of row, we can simply call write_glyphs.
3166 In the middle, we have to insert glyphs. Note that this is now
3167 implemented for X frames. The implementation uses updated_window
3168 and updated_row. */
3169 updated_row = glyph_row;
3170 update_begin (f);
3171 if (rif)
3173 rif->update_window_begin_hook (w);
3175 if (glyphs == end - n)
3176 rif->write_glyphs (glyphs, n);
3177 else
3178 rif->insert_glyphs (glyphs, n);
3180 else
3182 if (glyphs == end - n)
3183 write_glyphs (glyphs, n);
3184 else
3185 insert_glyphs (glyphs, n);
3188 w->cursor.hpos += n;
3189 w->cursor.x = it.current_x - it.first_visible_x;
3190 xassert (w->cursor.hpos >= 0
3191 && w->cursor.hpos < w->desired_matrix->matrix_w);
3193 /* How to set the cursor differs depending on whether we are
3194 using a frame matrix or a window matrix. Note that when
3195 a frame matrix is used, cursor_to expects frame coordinates,
3196 and the X and Y parameters are not used. */
3197 if (window_redisplay_p)
3198 rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
3199 w->cursor.y, w->cursor.x);
3200 else
3202 int x, y;
3203 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3204 + (INTEGERP (w->left_margin_width)
3205 ? XFASTINT (w->left_margin_width)
3206 : 0));
3207 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3208 cursor_to (y, x);
3211 if (rif)
3212 rif->update_window_end_hook (w, 1);
3213 update_end (f);
3214 updated_row = NULL;
3215 fflush (stdout);
3217 TRACE ((stderr, "direct output for insert\n"));
3219 unchanged_modified = MODIFF;
3220 beg_unchanged = GPT - BEG;
3221 XSETFASTINT (w->last_point, PT);
3222 w->last_cursor = w->cursor;
3223 XSETFASTINT (w->last_modified, MODIFF);
3224 XSETFASTINT (w->last_overlay_modified, OVERLAY_MODIFF);
3226 redisplay_performed_directly_p = 1;
3227 return 1;
3231 /* Perform a direct display update for moving PT by N positions
3232 left or right. N < 0 means a movement backwards. This function
3233 is currently only called for N == 1 or N == -1. */
3236 direct_output_forward_char (n)
3237 int n;
3239 struct frame *f = selected_frame;
3240 struct window *w = XWINDOW (selected_window);
3241 struct glyph_row *row;
3243 /* Give up if face attributes have been changed. */
3244 if (face_change_count)
3245 return 0;
3247 /* Give up if current matrix is not up to date or we are
3248 displaying a message. */
3249 if (!display_completed || cursor_in_echo_area)
3250 return 0;
3252 /* Give up if the buffer's direction is reversed. */
3253 if (!NILP (XBUFFER (w->buffer)->direction_reversed))
3254 return 0;
3256 /* Can't use direct output if highlighting a region. */
3257 if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
3258 return 0;
3260 row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
3262 if (PT <= MATRIX_ROW_START_BYTEPOS (row)
3263 || PT >= MATRIX_ROW_END_BYTEPOS (row))
3264 return 0;
3266 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
3267 w->last_cursor = w->cursor;
3268 XSETFASTINT (w->last_point, PT);
3270 xassert (w->cursor.hpos >= 0
3271 && w->cursor.hpos < w->desired_matrix->matrix_w);
3273 if (FRAME_WINDOW_P (f))
3274 rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
3275 w->cursor.y, w->cursor.x);
3276 else
3278 int x, y;
3279 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3280 + (INTEGERP (w->left_margin_width)
3281 ? XFASTINT (w->left_margin_width)
3282 : 0));
3283 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3284 cursor_to (y, x);
3287 fflush (stdout);
3288 redisplay_performed_directly_p = 1;
3289 return 1;
3294 /***********************************************************************
3295 Frame Update
3296 ***********************************************************************/
3298 /* Update frame F based on the data in desired matrices.
3300 If FORCE_P is non-zero, don't let redisplay be stopped by detecting
3301 pending input. If INHIBIT_HAIRY_ID_P is non-zero, don't try
3302 scrolling.
3304 Value is non-zero if redisplay was stopped due to pending input. */
3307 update_frame (f, force_p, inhibit_hairy_id_p)
3308 struct frame *f;
3309 int force_p;
3310 int inhibit_hairy_id_p;
3312 /* 1 means display has been paused because of pending input. */
3313 int paused_p;
3314 struct window *root_window = XWINDOW (f->root_window);
3316 if (FRAME_WINDOW_P (f))
3318 /* We are working on window matrix basis. All windows whose
3319 flag must_be_updated_p is set have to be updated. */
3321 /* Record that we are not working on frame matrices. */
3322 set_frame_matrix_frame (NULL);
3324 /* Update all windows in the window tree of F, maybe stopping
3325 when pending input is detected. */
3326 update_begin (f);
3328 /* Update the menu bar on X frames that don't have toolkit
3329 support. */
3330 if (WINDOWP (f->menu_bar_window))
3331 update_window (XWINDOW (f->menu_bar_window), 1);
3333 /* Update the tool-bar window, if present. */
3334 if (WINDOWP (f->toolbar_window))
3336 Lisp_Object tem;
3337 struct window *w = XWINDOW (f->toolbar_window);
3339 /* Update tool-bar window. */
3340 if (w->must_be_updated_p)
3342 update_window (w, 1);
3343 w->must_be_updated_p = 0;
3345 /* Swap tool-bar strings. We swap because we want to
3346 reuse strings. */
3347 tem = f->current_toolbar_string;
3348 f->current_toolbar_string = f->desired_toolbar_string;
3349 f->desired_toolbar_string = tem;
3350 f->n_current_toolbar_items = f->n_desired_toolbar_items;
3352 /* Swap tool-bar items. We swap because we want to
3353 reuse vectors. */
3354 tem = f->current_toolbar_items;
3355 f->current_toolbar_items = f->desired_toolbar_items;
3356 f->desired_toolbar_items = tem;
3361 /* Update windows. */
3362 paused_p = update_window_tree (root_window, force_p);
3363 update_end (f);
3364 display_completed = !paused_p;
3366 /* The flush is a performance bottleneck under X. */
3367 #if 0
3368 rif->flush_display (f);
3369 #endif
3371 else
3373 /* We are working on frame matrix basis. Set the frame on whose
3374 frame matrix we operate. */
3375 set_frame_matrix_frame (f);
3377 /* Build F's desired matrix from window matrices. For windows
3378 whose must_be_updated_p flag is set, desired matrices are
3379 made part of the desired frame matrix. For other windows,
3380 the current matrix is copied. */
3381 build_frame_matrix (f);
3383 /* Do the update on the frame desired matrix. */
3384 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
3386 /* Check window matrices for lost pointers. */
3387 IF_DEBUG (check_window_matrix_pointers (root_window));
3390 /* Reset flags indicating that a window should be updated. */
3391 set_window_update_flags (root_window, 0);
3392 return paused_p;
3397 /************************************************************************
3398 Window-based updates
3399 ************************************************************************/
3401 /* Perform updates in window tree rooted at W. FORCE_P non-zero means
3402 don't stop updating when input is pending. */
3404 static int
3405 update_window_tree (w, force_p)
3406 struct window *w;
3407 int force_p;
3409 int paused_p = 0;
3411 while (w && !paused_p)
3413 if (!NILP (w->hchild))
3414 paused_p |= update_window_tree (XWINDOW (w->hchild), force_p);
3415 else if (!NILP (w->vchild))
3416 paused_p |= update_window_tree (XWINDOW (w->vchild), force_p);
3417 else if (w->must_be_updated_p)
3418 paused_p |= update_window (w, force_p);
3420 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3423 return paused_p;
3427 /* Update window W if its flag must_be_updated_p is non-zero. If
3428 FORCE_P is non-zero, don't stop updating if input is pending. */
3430 void
3431 update_single_window (w, force_p)
3432 struct window *w;
3433 int force_p;
3435 if (w->must_be_updated_p)
3437 struct frame *f = XFRAME (WINDOW_FRAME (w));
3439 /* Record that this is not a frame-based redisplay. */
3440 set_frame_matrix_frame (NULL);
3442 /* Update W. */
3443 update_begin (f);
3444 update_window (w, force_p);
3445 update_end (f);
3447 /* Reset flag in W. */
3448 w->must_be_updated_p = 0;
3453 /* Update display of window W. FORCE_P non-zero means that we should
3454 not stop when detecting pending input. */
3456 static int
3457 update_window (w, force_p)
3458 struct window *w;
3459 int force_p;
3461 struct frame *f = XFRAME (WINDOW_FRAME (w));
3462 struct glyph_matrix *desired_matrix = w->desired_matrix;
3463 int paused_p;
3464 int preempt_count = baud_rate / 2400 + 1;
3465 extern int input_pending;
3466 extern struct frame *updating_frame;
3468 /* Check that W's frame doesn't have glyph matrices. */
3469 xassert (FRAME_WINDOW_P (f));
3470 xassert (updating_frame != NULL);
3472 /* Check pending input the first time so that we can quickly return. */
3473 if (redisplay_dont_pause)
3474 force_p = 1;
3475 else
3476 detect_input_pending ();
3478 /* If forced to complete the update, or if no input is pending, do
3479 the update. */
3480 if (force_p || !input_pending)
3482 struct glyph_row *row, *end;
3483 struct glyph_row *mode_line_row;
3484 struct glyph_row *top_line_row = NULL;
3485 int yb;
3487 rif->update_window_begin_hook (w);
3488 yb = window_text_bottom_y (w);
3490 /* If window has a top line, update it before everything else.
3491 Adjust y-positions of other rows by the top line height. */
3492 row = desired_matrix->rows;
3493 end = row + desired_matrix->nrows - 1;
3494 if (row->mode_line_p)
3495 top_line_row = row++;
3497 /* Update the mode line, if necessary. */
3498 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
3499 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
3501 mode_line_row->y = yb;
3502 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
3503 desired_matrix));
3506 /* Find first enabled row. Optimizations in redisplay_internal
3507 may lead to an update with only one row enabled. There may
3508 be also completely empty matrices. */
3509 while (row < end && !row->enabled_p)
3510 ++row;
3512 /* Try reusing part of the display by inserting/deleting lines. */
3513 if (row < end && !desired_matrix->no_scrolling_p)
3515 int rc = scrolling_window (w, top_line_row != NULL);
3516 if (rc < 0)
3518 /* All rows were found to be equal. */
3519 paused_p = 0;
3520 goto set_cursor;
3522 else if (rc > 0)
3523 force_p = 1;
3526 /* Update the top mode line after scrolling because a new top
3527 line would otherwise overwrite lines at the top of the window
3528 that can be scrolled. */
3529 if (top_line_row && top_line_row->enabled_p)
3531 top_line_row->y = 0;
3532 update_window_line (w, 0);
3535 /* Update the rest of the lines. */
3536 for (; row < end && (force_p || !input_pending); ++row)
3537 if (row->enabled_p
3538 /* A row can be completely invisible in case a desired
3539 matrix was built with a vscroll and then
3540 make_cursor_line_fully_visible shifts the matrix. */
3541 && row->visible_height > 0)
3543 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
3544 int i;
3546 /* We'll Have to play a little bit with when to
3547 detect_input_pending. If it's done too often,
3548 scrolling large windows with repeated scroll-up
3549 commands will too quickly pause redisplay. */
3550 if (!force_p && vpos % preempt_count == 0)
3551 detect_input_pending ();
3553 update_window_line (w, vpos);
3555 /* Mark all rows below the last visible one in the current
3556 matrix as invalid. This is necessary because of
3557 variable line heights. Consider the case of three
3558 successive redisplays, where the first displays 5
3559 lines, the second 3 lines, and the third 5 lines again.
3560 If the second redisplay wouldn't mark rows in the
3561 current matrix invalid, the third redisplay might be
3562 tempted to optimize redisplay based on lines displayed
3563 in the first redisplay. */
3564 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3565 for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
3566 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
3569 /* Was display preempted? */
3570 paused_p = row < end;
3572 set_cursor:
3574 if (!paused_p && !w->pseudo_window_p)
3576 /* Make cursor visible at cursor position of W. */
3577 set_window_cursor_after_update (w);
3579 #if 0
3580 /* Check that current matrix invariants are satisfied. This
3581 is for debugging only. See the comment around
3582 check_matrix_invariants. */
3583 IF_DEBUG (check_matrix_invariants (w));
3584 #endif
3587 #if GLYPH_DEBUG
3588 /* Remember the redisplay method used to display the matrix. */
3589 strcpy (w->current_matrix->method, w->desired_matrix->method);
3590 #endif
3592 /* End of update of window W. */
3593 rif->update_window_end_hook (w, 1);
3595 else
3596 paused_p = 1;
3598 clear_glyph_matrix (desired_matrix);
3599 return paused_p;
3603 /* Update the display of area AREA in window W, row number VPOS.
3604 AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
3606 static void
3607 update_marginal_area (w, area, vpos)
3608 struct window *w;
3609 int area, vpos;
3611 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3613 /* Let functions in xterm.c know what area subsequent X positions
3614 will be relative to. */
3615 updated_area = area;
3617 /* Set cursor to start of glyphs, write them, and clear to the end
3618 of the area. I don't think that something more sophisticated is
3619 necessary here, since marginal areas will not be the default. */
3620 rif->cursor_to (vpos, 0, desired_row->y, 0);
3621 if (desired_row->used[area])
3622 rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]);
3623 rif->clear_end_of_line (-1);
3627 /* Update the display of the text area of row VPOS in window W. */
3629 static void
3630 update_text_area (w, vpos)
3631 struct window *w;
3632 int vpos;
3634 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3635 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3637 /* Let functions in xterm.c know what area subsequent X positions
3638 will be relative to. */
3639 updated_area = TEXT_AREA;
3641 /* If rows are at different X or Y, or rows have different height,
3642 or the current row is marked invalid, write the entire line. */
3643 if (!current_row->enabled_p
3644 || desired_row->y != current_row->y
3645 || desired_row->ascent != current_row->ascent
3646 || desired_row->visible_height != current_row->visible_height
3647 || current_row->x != desired_row->x)
3649 rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
3651 if (desired_row->used[TEXT_AREA])
3652 rif->write_glyphs (desired_row->glyphs[TEXT_AREA],
3653 desired_row->used[TEXT_AREA]);
3655 /* Clear to end of window. */
3656 rif->clear_end_of_line (-1);
3658 else
3660 int stop, i, x;
3661 struct glyph *current_glyph = current_row->glyphs[TEXT_AREA];
3662 struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
3664 /* If the desired row extends its face to the text area end,
3665 make sure we write at least one glyph, so that the face
3666 extension actually takes place. */
3667 int desired_stop_pos = (desired_row->used[TEXT_AREA]
3668 - (MATRIX_ROW_EXTENDS_FACE_P (desired_row)
3669 ? 1 : 0));
3671 stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
3672 i = 0;
3673 x = desired_row->x;
3675 while (i < stop)
3677 /* Skip over glyphs that both rows have in common. These
3678 don't have to be written. */
3679 while (i < stop
3680 && GLYPH_EQUAL_P (desired_glyph, current_glyph))
3682 x += desired_glyph->pixel_width;
3683 ++desired_glyph, ++current_glyph, ++i;
3686 /* Consider the case that the current row contains "xxx ppp
3687 ggg" in italic Courier font, and the desired row is "xxx
3688 ggg". The character `p' has lbearing, `g' has not. The
3689 loop above will stop in front of the first `p' in the
3690 current row. If we would start writing glyphs there, we
3691 wouldn't erase the lbearing of the `p'. The rest of the
3692 lbearing problem is then taken care of by x_draw_glyphs. */
3693 if (current_row->contains_overlapping_glyphs_p
3694 && i > 0
3695 && i < current_row->used[TEXT_AREA]
3696 && current_row->used[TEXT_AREA] != desired_row->used[TEXT_AREA])
3698 int left, right;
3699 rif->get_glyph_overhangs (current_glyph, XFRAME (w->frame),
3700 &left, &right);
3701 while (left > 0 && i > 0)
3703 --i, --desired_glyph, --current_glyph;
3704 x -= desired_glyph->pixel_width;
3705 left -= desired_glyph->pixel_width;
3709 /* Try to avoid writing the entire rest of the desired row
3710 by looking for a resync point. This mainly prevents
3711 mode line flickering in the case the mode line is in
3712 fixed-pitch font, which it usually will be. */
3713 if (i < desired_row->used[TEXT_AREA])
3715 int start_x = x, start_hpos = i;
3716 struct glyph *start = desired_glyph;
3717 int current_x = x;
3719 /* Find the next glyph that's equal again. */
3720 while (i < stop
3721 && !GLYPH_EQUAL_P (desired_glyph, current_glyph)
3722 && x == current_x)
3724 x += desired_glyph->pixel_width;
3725 current_x += current_glyph->pixel_width;
3726 ++desired_glyph, ++current_glyph, ++i;
3729 if (i == start_hpos || x != current_x)
3731 i = start_hpos;
3732 x = start_x;
3733 desired_glyph = start;
3734 break;
3737 rif->cursor_to (vpos, start_hpos, desired_row->y, start_x);
3738 rif->write_glyphs (start, i - start_hpos);
3742 /* Write the rest. */
3743 if (i < desired_row->used[TEXT_AREA])
3745 rif->cursor_to (vpos, i, desired_row->y, x);
3746 rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
3749 /* Maybe clear to end of line. */
3750 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
3752 /* If new row extends to the end of the text area, nothing
3753 has to be cleared, if and only if we did a write_glyphs
3754 above. This is made sure by setting desired_stop_pos
3755 appropriately above. */
3756 xassert (i < desired_row->used[TEXT_AREA]);
3758 else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
3760 /* If old row extends to the end of the text area, clear. */
3761 if (i >= desired_row->used[TEXT_AREA])
3762 rif->cursor_to (vpos, i, desired_row->y,
3763 desired_row->x + desired_row->pixel_width);
3764 rif->clear_end_of_line (-1);
3766 else if (desired_row->pixel_width < current_row->pixel_width)
3768 /* Otherwise clear to the end of the old row. Everything
3769 after that position should be clear already. */
3770 int x;
3772 if (i >= desired_row->used[TEXT_AREA])
3773 rif->cursor_to (vpos, i, desired_row->y,
3774 desired_row->x + desired_row->pixel_width);
3776 /* If cursor is displayed at the end of the line, make sure
3777 it's cleared. Nowadays we don't have a phys_cursor_glyph
3778 with which to erase the cursor (because this method
3779 doesn't work with lbearing/rbearing), so we must do it
3780 this way. */
3781 if (vpos == w->phys_cursor.vpos
3782 && w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])
3784 w->phys_cursor_on_p = 0;
3785 x = -1;
3787 else
3788 x = current_row->x + current_row->pixel_width;
3789 rif->clear_end_of_line (x);
3795 /* Update row VPOS in window W. */
3797 static void
3798 update_window_line (w, vpos)
3799 struct window *w;
3800 int vpos;
3802 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3803 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3805 xassert (desired_row->enabled_p);
3807 /* Set the row being updated. This is important to let xterm.c
3808 know what line height values are in effect. */
3809 updated_row = desired_row;
3811 /* Update display of the left margin area, if there is one. */
3812 if (!desired_row->full_width_p
3813 && !NILP (w->left_margin_width))
3814 update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
3816 /* Update the display of the text area. */
3817 update_text_area (w, vpos);
3819 /* Update display of the right margin area, if there is one. */
3820 if (!desired_row->full_width_p
3821 && !NILP (w->right_margin_width))
3822 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
3824 /* Draw truncation marks etc. */
3825 if (!current_row->enabled_p
3826 || desired_row->y != current_row->y
3827 || desired_row->visible_height != current_row->visible_height
3828 || desired_row->overlay_arrow_p != current_row->overlay_arrow_p
3829 || desired_row->truncated_on_left_p != current_row->truncated_on_left_p
3830 || desired_row->truncated_on_right_p != current_row->truncated_on_right_p
3831 || desired_row->continued_p != current_row->continued_p
3832 || desired_row->mode_line_p != current_row->mode_line_p
3833 || (desired_row->indicate_empty_line_p
3834 != current_row->indicate_empty_line_p)
3835 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
3836 != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
3837 rif->after_update_window_line_hook (desired_row);
3839 /* Update current_row from desired_row. */
3840 make_current (w->desired_matrix, w->current_matrix, vpos);
3841 updated_row = NULL;
3845 /* Set the cursor after an update of window W. This function may only
3846 be called from update_window. */
3848 static void
3849 set_window_cursor_after_update (w)
3850 struct window *w;
3852 struct frame *f = XFRAME (w->frame);
3853 int cx, cy, vpos, hpos;
3855 /* Not intended for frame matrix updates. */
3856 xassert (FRAME_WINDOW_P (f));
3858 if ((cursor_in_echo_area
3859 /* If we are showing a message instead of the mini-buffer,
3860 show the cursor for the message instead of for the
3861 (now hidden) mini-buffer contents. */
3862 || (XWINDOW (minibuf_window) == w
3863 && EQ (minibuf_window, echo_area_window)
3864 && (echo_area_glyphs || STRINGP (echo_area_message))))
3865 /* These cases apply only to the frame that contains
3866 the active mini-buffer window. */
3867 && FRAME_HAS_MINIBUF_P (f)
3868 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
3870 cx = cy = vpos = hpos = 0;
3872 if (cursor_in_echo_area >= 0)
3874 /* If the mini-buffer is several lines high, find the last
3875 line that has any text on it. Note: either all lines
3876 are enabled or none. Otherwise we wouldn't be able to
3877 determine Y. */
3878 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0);
3879 int vpos, last_row_vpos;
3880 struct glyph_row *last_row = NULL;
3882 vpos = 0;
3883 while (vpos < w->current_matrix->nrows)
3885 if (row->enabled_p && row->used[TEXT_AREA])
3887 last_row = row;
3888 last_row_vpos = vpos;
3890 ++row;
3891 ++vpos;
3894 if (last_row)
3896 cx = last_row->pixel_width;
3897 hpos = last_row->used[TEXT_AREA];
3898 cy = last_row->y;
3899 vpos = last_row_vpos;
3903 else
3905 cx = w->cursor.x;
3906 cy = w->cursor.y;
3907 hpos = w->cursor.hpos;
3908 vpos = w->cursor.vpos;
3911 /* Window cursor can be out of sync for horizontally split windows. */
3912 hpos = max (0, hpos);
3913 hpos = min (w->current_matrix->matrix_w - 1, hpos);
3914 vpos = max (0, vpos);
3915 vpos = min (w->current_matrix->nrows - 1, vpos);
3916 rif->cursor_to (vpos, hpos, cy, cx);
3920 /* Try to reuse part of the current display of W by scrolling lines.
3921 TOP_LINE_P non-zero means W has a top mode line.
3923 The algorithm is taken from Communications of the ACM, Apr78 "A
3924 Technique for Isolating Differences Between Files." It should take
3925 O(N) time.
3927 A short outline of the steps of the algorithm
3929 1. Skip lines equal at the start and end of both matrices.
3931 2. Enter rows in the current and desired matrix into a symbol
3932 table, counting how often they appear in both matrices.
3934 3. Rows that appear exactly once in both matrices serve as anchors,
3935 i.e. we assume that such lines are likely to have been moved.
3937 4. Starting from anchor lines, extend regions to be scrolled both
3938 forward and backward.
3940 Value is
3942 -1 if all rows were found to be equal.
3943 0 to indicate that we did not scroll the display, or
3944 1 if we did scroll. */
3946 static int
3947 scrolling_window (w, top_line_p)
3948 struct window *w;
3949 int top_line_p;
3951 struct symbol
3953 /* Number of occurrences of this line in old and new matrix. */
3954 short old_uses, new_uses;
3956 /* Vpos of line in new matrix. */
3957 short new_line_number;
3959 /* The line itself. */
3960 struct glyph_row *row;
3962 /* Hash collision chain. */
3963 struct symbol *next;
3966 int SYMBOL_TABLE_SIZE = 101;
3967 struct symbol **table;
3968 struct symbol **old_line_syms, **new_line_syms;
3969 int i, j, first_old, first_new, last_old, last_new;
3970 struct symbol *sym;
3971 struct run **runs;
3972 int nruns;
3973 struct glyph_matrix *desired_matrix = w->desired_matrix;
3974 struct glyph_matrix *current_matrix = w->current_matrix;
3975 int yb = window_text_bottom_y (w);
3977 /* Skip over rows equal at the start. */
3978 i = top_line_p ? 1 : 0;
3979 while (i < current_matrix->nrows - 1
3980 && MATRIX_ROW_ENABLED_P (current_matrix, i)
3981 && MATRIX_ROW_ENABLED_P (desired_matrix, i)
3982 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i)) < yb
3983 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i)) < yb
3984 && row_equal_p (w,
3985 MATRIX_ROW (desired_matrix, i),
3986 MATRIX_ROW (current_matrix, i)))
3988 assign_row (MATRIX_ROW (current_matrix, i),
3989 MATRIX_ROW (desired_matrix, i));
3990 MATRIX_ROW (desired_matrix, i)->enabled_p = 0;
3991 ++i;
3994 /* Give up if some rows in the desired matrix are not enabled. */
3995 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
3996 return -1;
3998 first_old = first_new = i;
4000 /* Set last_new to the index + 1 of the last enabled row in the
4001 desired matrix. */
4002 i = first_new + 1;
4003 while (i < desired_matrix->nrows - 1
4004 && MATRIX_ROW (desired_matrix, i)->enabled_p
4005 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i)) < yb)
4006 ++i;
4008 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
4009 return 0;
4011 last_new = i;
4013 /* Set last_old to the index + 1 of the last enabled row in the
4014 current matrix. We don't look at the enabled flag here because
4015 we plan to reuse part of the display even if other parts are
4016 disabled. */
4017 i = first_old + 1;
4018 while (i < current_matrix->nrows - 1
4019 && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i)) < yb)
4020 ++i;
4021 last_old = i;
4023 /* Skip over rows equal at the bottom. */
4024 i = last_new;
4025 j = last_old;
4026 while (i - 1 > first_new
4027 && j - 1 > first_old
4028 && MATRIX_ROW (current_matrix, i - 1)->enabled_p
4029 && (MATRIX_ROW (current_matrix, i - 1)->y
4030 == MATRIX_ROW (desired_matrix, j - 1)->y)
4031 && row_equal_p (w,
4032 MATRIX_ROW (desired_matrix, i - 1),
4033 MATRIX_ROW (current_matrix, j - 1)))
4034 --i, --j;
4035 last_new = i;
4036 last_old = j;
4038 /* Nothing to do if all rows are equal. */
4039 if (last_new == first_new)
4040 return 0;
4042 /* Allocate a hash table in which all rows will be inserted. */
4043 table = (struct symbol **) alloca (SYMBOL_TABLE_SIZE * sizeof *table);
4044 bzero (table, SYMBOL_TABLE_SIZE * sizeof *table);
4046 /* For each row in the current matrix, record the symbol belonging
4047 to the row in OLD_LINE_SYMS. */
4048 old_line_syms = (struct symbol **) alloca (current_matrix->nrows
4049 * sizeof *old_line_syms);
4050 new_line_syms = (struct symbol **) alloca (desired_matrix->nrows
4051 * sizeof *new_line_syms);
4053 #define ADDSYM(ROW) \
4054 do \
4056 struct glyph_row *row_ = (ROW); \
4057 int i_ = row_->hash % SYMBOL_TABLE_SIZE; \
4058 sym = table[i_]; \
4059 while (sym && !row_equal_p (w, sym->row, row_)) \
4060 sym = sym->next; \
4061 if (sym == NULL) \
4063 sym = (struct symbol *) alloca (sizeof *sym); \
4064 sym->row = row_; \
4065 sym->old_uses = sym->new_uses = 0; \
4066 sym->next = table[i_]; \
4067 table[i_] = sym; \
4070 while (0)
4072 /* Add current rows to the symbol table. */
4073 for (i = first_old; i < last_old; ++i)
4075 if (MATRIX_ROW (current_matrix, i)->enabled_p)
4077 ADDSYM (MATRIX_ROW (current_matrix, i));
4078 old_line_syms[i] = sym;
4079 ++sym->old_uses;
4081 else
4082 old_line_syms[i] = NULL;
4085 /* Add desired rows to the symbol table. */
4086 for (i = first_new; i < last_new; ++i)
4088 xassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
4089 ADDSYM (MATRIX_ROW (desired_matrix, i));
4090 ++sym->new_uses;
4091 new_line_syms[i] = sym;
4092 sym->new_line_number = i;
4095 #undef ADDSYM
4097 /* Record in runs which moves were found, ordered by pixel
4098 height of copied areas. */
4099 nruns = 0;
4100 runs = (struct run **) alloca (desired_matrix->nrows * sizeof *runs);
4102 /* Identify moves based on lines that are unique and equal
4103 in both matrices. */
4104 for (i = first_old; i < last_old;)
4105 if (old_line_syms[i]
4106 && old_line_syms[i]->old_uses == 1
4107 && old_line_syms[i]->new_uses == 1)
4109 int j, k;
4110 int new_line = old_line_syms[i]->new_line_number;
4111 struct run *run = (struct run *) alloca (sizeof *run);
4113 /* Record move. */
4114 run->current_vpos = i;
4115 run->current_y = MATRIX_ROW (current_matrix, i)->y;
4116 run->desired_vpos = new_line;
4117 run->desired_y = MATRIX_ROW (desired_matrix, new_line)->y;
4118 run->nrows = 1;
4119 run->height = MATRIX_ROW (current_matrix, i)->height;
4121 /* Extend backward. */
4122 j = i - 1;
4123 k = new_line - 1;
4124 while (j > first_old
4125 && k > first_new
4126 && old_line_syms[j] == new_line_syms[k])
4128 int h = MATRIX_ROW (current_matrix, j)->height;
4129 --run->current_vpos;
4130 --run->desired_vpos;
4131 ++run->nrows;
4132 run->height += h;
4133 run->desired_y -= h;
4134 run->current_y -= h;
4135 --j, --k;
4138 /* Extend forward. */
4139 j = i + 1;
4140 k = new_line + 1;
4141 while (j < last_old
4142 && k < last_new
4143 && old_line_syms[j] == new_line_syms[k])
4145 int h = MATRIX_ROW (current_matrix, j)->height;
4146 ++run->nrows;
4147 run->height += h;
4148 ++j, ++k;
4151 /* Insert run into list of all runs. Order runs by copied
4152 pixel lines. Note that we record runs that don't have to
4153 be copied because they are already in place. This is done
4154 because we can avoid calling update_window_line in this
4155 case. */
4156 for (j = 0; j < nruns && runs[j]->height > run->height; ++j)
4158 for (k = nruns; k >= j; --k)
4159 runs[k] = runs[k - 1];
4160 runs[j] = run;
4161 ++nruns;
4163 i += run->nrows;
4165 else
4166 ++i;
4168 /* Do the moves. Do it in a way that we don't overwrite something
4169 we want to copy later on. This is not solvable in general
4170 because there is only one display and we don't have a way to
4171 exchange areas on this display. Example:
4173 +-----------+ +-----------+
4174 | A | | B |
4175 +-----------+ --> +-----------+
4176 | B | | A |
4177 +-----------+ +-----------+
4179 Instead, prefer bigger moves, and invalidate moves that would
4180 copy from where we copied to. */
4182 for (i = 0; i < nruns; ++i)
4183 if (runs[i]->nrows > 0)
4185 struct run *r = runs[i];
4187 /* Copy on the display. */
4188 if (r->current_y != r->desired_y)
4190 rif->scroll_run_hook (w, r);
4192 /* Invalidate runs that copy from where we copied to. */
4193 for (j = i + 1; j < nruns; ++j)
4195 struct run *p = runs[j];
4197 if ((p->current_y >= r->desired_y
4198 && p->current_y < r->desired_y + r->height)
4199 || (p->current_y + p->height >= r->desired_y
4200 && (p->current_y + p->height
4201 < r->desired_y + r->height)))
4202 p->nrows = 0;
4206 /* Assign matrix rows. */
4207 for (j = 0; j < r->nrows; ++j)
4209 struct glyph_row *from, *to;
4210 to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
4211 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
4212 assign_row (to, from);
4213 to->enabled_p = 1, from->enabled_p = 0;
4217 /* Value is non-zero to indicate that we scrolled the display. */
4218 return 1;
4222 /* Set WINDOW->must_be_updated_p TO ON_P for all windows WINDOW in the
4223 window tree rooted at W. */
4225 void
4226 set_window_update_flags (w, on_p)
4227 struct window *w;
4228 int on_p;
4230 while (w)
4232 if (!NILP (w->hchild))
4233 set_window_update_flags (XWINDOW (w->hchild), on_p);
4234 else if (!NILP (w->vchild))
4235 set_window_update_flags (XWINDOW (w->vchild), on_p);
4236 else
4237 w->must_be_updated_p = on_p;
4239 w = NILP (w->next) ? 0 : XWINDOW (w->next);
4245 /************************************************************************
4246 Frame-Based Updates
4247 ************************************************************************/
4249 /* Update the desired frame matrix of frame F.
4251 FORCE_P non-zero means that the update should not be stopped by
4252 pending input. INHIBIT_HAIRY_ID_P non-zero means that scrolling
4253 should not be tried.
4255 Value is non-zero if update was stopped due to pending input. */
4257 static int
4258 update_frame_1 (f, force_p, inhibit_id_p)
4259 struct frame *f;
4260 int force_p;
4261 int inhibit_id_p;
4263 /* Frame matrices to work on. */
4264 struct glyph_matrix *current_matrix = f->current_matrix;
4265 struct glyph_matrix *desired_matrix = f->desired_matrix;
4266 int i;
4267 int pause;
4268 int preempt_count = baud_rate / 2400 + 1;
4269 extern int input_pending;
4271 xassert (current_matrix && desired_matrix);
4273 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4274 calculate_costs (f);
4276 if (preempt_count <= 0)
4277 preempt_count = 1;
4279 detect_input_pending ();
4280 if (input_pending && !force_p)
4282 pause = 1;
4283 goto do_pause;
4286 update_begin (f);
4288 /* If we cannot insert/delete lines, it's no use trying it. */
4289 if (!line_ins_del_ok)
4290 inhibit_id_p = 1;
4292 /* See if any of the desired lines are enabled; don't compute for
4293 i/d line if just want cursor motion. */
4294 for (i = 0; i < desired_matrix->nrows; i++)
4295 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4296 break;
4298 /* Try doing i/d line, if not yet inhibited. */
4299 if (!inhibit_id_p && i < desired_matrix->nrows)
4300 force_p |= scrolling (f);
4302 /* Update the individual lines as needed. Do bottom line first. */
4303 if (MATRIX_ROW_ENABLED_P (desired_matrix, desired_matrix->nrows - 1))
4304 update_frame_line (f, desired_matrix->nrows - 1);
4306 /* Now update the rest of the lines. */
4307 for (i = 0; i < desired_matrix->nrows - 1 && (force_p || !input_pending); i++)
4309 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4311 if (FRAME_TERMCAP_P (f))
4313 /* Flush out every so many lines.
4314 Also flush out if likely to have more than 1k buffered
4315 otherwise. I'm told that some telnet connections get
4316 really screwed by more than 1k output at once. */
4317 int outq = PENDING_OUTPUT_COUNT (stdout);
4318 if (outq > 900
4319 || (outq > 20 && ((i - 1) % preempt_count == 0)))
4321 fflush (stdout);
4322 if (preempt_count == 1)
4324 #ifdef EMACS_OUTQSIZE
4325 if (EMACS_OUTQSIZE (0, &outq) < 0)
4326 /* Probably not a tty. Ignore the error and reset
4327 * the outq count. */
4328 outq = PENDING_OUTPUT_COUNT (stdout);
4329 #endif
4330 outq *= 10;
4331 if (baud_rate <= outq && baud_rate > 0)
4332 sleep (outq / baud_rate);
4337 if ((i - 1) % preempt_count == 0)
4338 detect_input_pending ();
4340 update_frame_line (f, i);
4344 pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0;
4346 /* Now just clean up termcap drivers and set cursor, etc. */
4347 if (!pause)
4349 if ((cursor_in_echo_area
4350 /* If we are showing a message instead of the mini-buffer,
4351 show the cursor for the message instead of for the
4352 (now hidden) mini-buffer contents. */
4353 || (EQ (minibuf_window, selected_window)
4354 && EQ (minibuf_window, echo_area_window)
4355 && (echo_area_glyphs || STRINGP (echo_area_message))))
4356 /* These cases apply only to the frame that contains
4357 the active mini-buffer window. */
4358 && FRAME_HAS_MINIBUF_P (f)
4359 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4361 int top = XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top);
4362 int row, col;
4364 if (cursor_in_echo_area < 0)
4366 /* Negative value of cursor_in_echo_area means put
4367 cursor at beginning of line. */
4368 row = top;
4369 col = 0;
4371 else
4373 /* Positive value of cursor_in_echo_area means put
4374 cursor at the end of the prompt. If the mini-buffer
4375 is several lines high, find the last line that has
4376 any text on it. */
4377 row = FRAME_HEIGHT (f);
4380 --row;
4381 col = 0;
4383 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
4385 /* Frame rows are filled up with spaces that
4386 must be ignored here. */
4387 int i;
4388 struct glyph_row *r = MATRIX_ROW (current_matrix,
4389 row);
4390 struct glyph *start = r->glyphs[TEXT_AREA];
4391 struct glyph *last = start + r->used[TEXT_AREA];
4393 while (last > start
4394 && (last - 1)->charpos < 0)
4395 --last;
4397 col = last - start;
4400 while (row > top && col == 0);
4402 /* Make sure COL is not out of range. */
4403 if (col >= FRAME_CURSOR_X_LIMIT (f))
4405 /* If we have another row, advance cursor into it. */
4406 if (row < FRAME_HEIGHT (f) - 1)
4408 col = FRAME_LEFT_SCROLL_BAR_WIDTH (f);
4409 row++;
4411 /* Otherwise move it back in range. */
4412 else
4413 col = FRAME_CURSOR_X_LIMIT (f) - 1;
4417 cursor_to (row, col);
4419 else
4421 /* We have only one cursor on terminal frames. Use it to
4422 display the cursor of the selected window. */
4423 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
4424 if (w->cursor.vpos >= 0)
4426 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
4427 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
4429 if (INTEGERP (w->left_margin_width))
4430 x += XFASTINT (w->left_margin_width);
4432 /* x = max (min (x, FRAME_WINDOW_WIDTH (f) - 1), 0); */
4433 cursor_to (y, x);
4438 update_end (f);
4440 if (termscript)
4441 fflush (termscript);
4442 fflush (stdout);
4444 do_pause:
4446 display_completed = !pause;
4447 clear_desired_matrices (f);
4448 return pause;
4452 /* Do line insertions/deletions on frame F for frame-based redisplay. */
4455 scrolling (frame)
4456 struct frame *frame;
4458 int unchanged_at_top, unchanged_at_bottom;
4459 int window_size;
4460 int changed_lines;
4461 int *old_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4462 int *new_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4463 int *draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4464 int *old_draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
4465 register int i;
4466 int free_at_end_vpos = FRAME_HEIGHT (frame);
4467 struct glyph_matrix *current_matrix = frame->current_matrix;
4468 struct glyph_matrix *desired_matrix = frame->desired_matrix;
4470 if (!current_matrix)
4471 abort ();
4473 /* Compute hash codes of all the lines. Also calculate number of
4474 changed lines, number of unchanged lines at the beginning, and
4475 number of unchanged lines at the end. */
4476 changed_lines = 0;
4477 unchanged_at_top = 0;
4478 unchanged_at_bottom = FRAME_HEIGHT (frame);
4479 for (i = 0; i < FRAME_HEIGHT (frame); i++)
4481 /* Give up on this scrolling if some old lines are not enabled. */
4482 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
4483 return 0;
4484 old_hash[i] = line_hash_code (MATRIX_ROW (current_matrix, i));
4485 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
4487 /* This line cannot be redrawn, so don't let scrolling mess it. */
4488 new_hash[i] = old_hash[i];
4489 #define INFINITY 1000000 /* Taken from scroll.c */
4490 draw_cost[i] = INFINITY;
4492 else
4494 new_hash[i] = line_hash_code (MATRIX_ROW (desired_matrix, i));
4495 draw_cost[i] = line_draw_cost (desired_matrix, i);
4498 if (old_hash[i] != new_hash[i])
4500 changed_lines++;
4501 unchanged_at_bottom = FRAME_HEIGHT (frame) - i - 1;
4503 else if (i == unchanged_at_top)
4504 unchanged_at_top++;
4505 old_draw_cost[i] = line_draw_cost (current_matrix, i);
4508 /* If changed lines are few, don't allow preemption, don't scroll. */
4509 if ((!scroll_region_ok && changed_lines < baud_rate / 2400)
4510 || unchanged_at_bottom == FRAME_HEIGHT (frame))
4511 return 1;
4513 window_size = (FRAME_HEIGHT (frame) - unchanged_at_top
4514 - unchanged_at_bottom);
4516 if (scroll_region_ok)
4517 free_at_end_vpos -= unchanged_at_bottom;
4518 else if (memory_below_frame)
4519 free_at_end_vpos = -1;
4521 /* If large window, fast terminal and few lines in common between
4522 current frame and desired frame, don't bother with i/d calc. */
4523 if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400
4524 && (window_size >=
4525 10 * scrolling_max_lines_saved (unchanged_at_top,
4526 FRAME_HEIGHT (frame) - unchanged_at_bottom,
4527 old_hash, new_hash, draw_cost)))
4528 return 0;
4530 if (window_size < 2)
4531 return 0;
4533 scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
4534 draw_cost + unchanged_at_top - 1,
4535 old_draw_cost + unchanged_at_top - 1,
4536 old_hash + unchanged_at_top - 1,
4537 new_hash + unchanged_at_top - 1,
4538 free_at_end_vpos - unchanged_at_top);
4540 return 0;
4544 /* Count the number of blanks at the start of the vector of glyphs R
4545 which is LEN glyphs long. */
4547 static int
4548 count_blanks (r, len)
4549 struct glyph *r;
4550 int len;
4552 int i;
4554 for (i = 0; i < len; ++i)
4555 if (!CHAR_GLYPH_SPACE_P (r[i]))
4556 break;
4558 return i;
4562 /* Count the number of glyphs in common at the start of the glyph
4563 vectors STR1 and STR2. END1 is the end of STR1 and END2 is the end
4564 of STR2. Value is the number of equal glyphs equal at the start. */
4566 static int
4567 count_match (str1, end1, str2, end2)
4568 struct glyph *str1, *end1, *str2, *end2;
4570 struct glyph *p1 = str1;
4571 struct glyph *p2 = str2;
4573 while (p1 < end1
4574 && p2 < end2
4575 && GLYPH_FROM_CHAR_GLYPH (*p1) == GLYPH_FROM_CHAR_GLYPH (*p2))
4576 ++p1, ++p2;
4578 return p1 - str1;
4582 /* Char insertion/deletion cost vector, from term.c */
4584 extern int *char_ins_del_vector;
4585 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))])
4588 /* Perform a frame-based update on line VPOS in frame FRAME. */
4590 static void
4591 update_frame_line (frame, vpos)
4592 register struct frame *frame;
4593 int vpos;
4595 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
4596 int tem;
4597 int osp, nsp, begmatch, endmatch, olen, nlen;
4598 struct glyph_matrix *current_matrix = frame->current_matrix;
4599 struct glyph_matrix *desired_matrix = frame->desired_matrix;
4600 struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
4601 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
4602 int must_write_whole_line_p;
4604 if (desired_row->inverse_p
4605 != (current_row->enabled_p && current_row->inverse_p))
4607 int n = current_row->enabled_p ? current_row->used[TEXT_AREA] : 0;
4608 change_line_highlight (desired_row->inverse_p, vpos, vpos, n);
4609 current_row->enabled_p = 0;
4611 else
4612 reassert_line_highlight (desired_row->inverse_p, vpos);
4614 must_write_whole_line_p = !current_row->enabled_p;
4615 if (must_write_whole_line_p)
4617 /* A line that is not enabled is empty. */
4618 obody = 0;
4619 olen = 0;
4621 else
4623 /* A line not empty in the current matrix. */
4624 obody = MATRIX_ROW_GLYPH_START (current_matrix, vpos);
4625 olen = current_row->used[TEXT_AREA];
4627 if (! current_row->inverse_p)
4629 /* Ignore trailing spaces. */
4630 if (!must_write_spaces)
4631 while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
4632 olen--;
4634 else
4636 /* For an inverse-video line, remember we gave it spaces all
4637 the way to the frame edge so that the reverse video
4638 extends all the way across. */
4639 while (olen < FRAME_WIDTH (frame) - 1)
4640 obody[olen++] = space_glyph;
4644 current_row->enabled_p = 1;
4645 current_row->used[TEXT_AREA] = desired_row->used[TEXT_AREA];
4646 current_row->inverse_p = desired_row->inverse_p;
4648 /* If desired line is empty, just clear the line. */
4649 if (!desired_row->enabled_p)
4651 nlen = 0;
4652 goto just_erase;
4655 nbody = desired_row->glyphs[TEXT_AREA];
4656 nlen = desired_row->used[TEXT_AREA];
4657 nend = nbody + nlen;
4659 /* If display line has unknown contents, write the whole line. */
4660 if (must_write_whole_line_p)
4662 cursor_to (vpos, 0);
4663 write_glyphs (nbody, nlen);
4664 cursor_to (vpos, nlen);
4665 clear_end_of_line (-1);
4666 make_current (desired_matrix, current_matrix, vpos);
4667 return;
4670 /* Pretend trailing spaces are not there at all,
4671 unless for one reason or another we must write all spaces. */
4672 if (!desired_row->inverse_p)
4674 if (!must_write_spaces)
4675 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
4676 nlen--;
4678 else
4680 /* For an inverse-video line, give it extra trailing spaces all
4681 the way to the frame edge so that the reverse video extends
4682 all the way across. */
4683 while (nlen < FRAME_WIDTH (frame) - 1)
4684 nbody[nlen++] = space_glyph;
4687 /* If there's no i/d char, quickly do the best we can without it. */
4688 if (!char_ins_del_ok)
4690 int i, j;
4692 /* Find the first glyph in desired row that doesn't agree with
4693 a glyph in the current row, and write the rest from there on. */
4694 for (i = 0; i < nlen; i++)
4696 if (i >= olen || !GLYPH_EQUAL_P (nbody + i, obody + i))
4698 /* Find the end of the run of different glyphs. */
4699 j = i + 1;
4700 while (j < nlen
4701 && (j >= olen
4702 || !GLYPH_EQUAL_P (nbody + j, obody + j)
4703 || CHAR_GLYPH_PADDING_P (nbody[j])))
4704 ++j;
4706 /* Output this run of non-matching chars. */
4707 cursor_to (vpos, i);
4708 write_glyphs (nbody + i, j - i);
4709 i = j - 1;
4711 /* Now find the next non-match. */
4715 /* Clear the rest of the line, or the non-clear part of it. */
4716 if (olen > nlen)
4718 cursor_to (vpos, nlen);
4719 clear_end_of_line (olen);
4722 /* Make current row = desired row. */
4723 make_current (desired_matrix, current_matrix, vpos);
4724 return;
4727 /* Here when CHAR_INS_DEL_OK != 0, i.e. we can insert or delete
4728 characters in a row. */
4730 if (!olen)
4732 /* If current line is blank, skip over initial spaces, if
4733 possible, and write the rest. */
4734 if (must_write_spaces || desired_row->inverse_p)
4735 nsp = 0;
4736 else
4737 nsp = count_blanks (nbody, nlen);
4739 if (nlen > nsp)
4741 cursor_to (vpos, nsp);
4742 write_glyphs (nbody + nsp, nlen - nsp);
4745 /* Exchange contents between current_frame and new_frame. */
4746 make_current (desired_matrix, current_matrix, vpos);
4747 return;
4750 /* Compute number of leading blanks in old and new contents. */
4751 osp = count_blanks (obody, olen);
4752 nsp = desired_row->inverse_p ? 0 : count_blanks (nbody, nlen);
4754 /* Compute number of matching chars starting with first non-blank. */
4755 begmatch = count_match (obody + osp, obody + olen,
4756 nbody + nsp, nbody + nlen);
4758 /* Spaces in new match implicit space past the end of old. */
4759 /* A bug causing this to be a no-op was fixed in 18.29. */
4760 if (!must_write_spaces && osp + begmatch == olen)
4762 np1 = nbody + nsp;
4763 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (np1[begmatch]))
4764 ++begmatch;
4767 /* Avoid doing insert/delete char
4768 just cause number of leading spaces differs
4769 when the following text does not match. */
4770 if (begmatch == 0 && osp != nsp)
4771 osp = nsp = min (osp, nsp);
4773 /* Find matching characters at end of line */
4774 op1 = obody + olen;
4775 np1 = nbody + nlen;
4776 op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
4777 while (op1 > op2
4778 && GLYPH_EQUAL_P (op1 - 1, np1 - 1))
4780 op1--;
4781 np1--;
4783 endmatch = obody + olen - op1;
4785 /* tem gets the distance to insert or delete.
4786 endmatch is how many characters we save by doing so.
4787 Is it worth it? */
4789 tem = (nlen - nsp) - (olen - osp);
4790 if (endmatch && tem
4791 && (!char_ins_del_ok || endmatch <= char_ins_del_cost (frame)[tem]))
4792 endmatch = 0;
4794 /* nsp - osp is the distance to insert or delete.
4795 If that is nonzero, begmatch is known to be nonzero also.
4796 begmatch + endmatch is how much we save by doing the ins/del.
4797 Is it worth it? */
4799 if (nsp != osp
4800 && (!char_ins_del_ok
4801 || begmatch + endmatch <= char_ins_del_cost (frame)[nsp - osp]))
4803 begmatch = 0;
4804 endmatch = 0;
4805 osp = nsp = min (osp, nsp);
4808 /* Now go through the line, inserting, writing and
4809 deleting as appropriate. */
4811 if (osp > nsp)
4813 cursor_to (vpos, nsp);
4814 delete_glyphs (osp - nsp);
4816 else if (nsp > osp)
4818 /* If going to delete chars later in line
4819 and insert earlier in the line,
4820 must delete first to avoid losing data in the insert */
4821 if (endmatch && nlen < olen + nsp - osp)
4823 cursor_to (vpos, nlen - endmatch + osp - nsp);
4824 delete_glyphs (olen + nsp - osp - nlen);
4825 olen = nlen - (nsp - osp);
4827 cursor_to (vpos, osp);
4828 insert_glyphs (0, nsp - osp);
4830 olen += nsp - osp;
4832 tem = nsp + begmatch + endmatch;
4833 if (nlen != tem || olen != tem)
4835 cursor_to (vpos, nsp + begmatch);
4836 if (!endmatch || nlen == olen)
4838 /* If new text being written reaches right margin,
4839 there is no need to do clear-to-eol at the end.
4840 (and it would not be safe, since cursor is not
4841 going to be "at the margin" after the text is done) */
4842 if (nlen == FRAME_WINDOW_WIDTH (frame))
4843 olen = 0;
4844 write_glyphs (nbody + nsp + begmatch, nlen - tem);
4846 else if (nlen > olen)
4848 /* Here, we used to have the following simple code:
4849 ----------------------------------------
4850 write_glyphs (nbody + nsp + begmatch, olen - tem);
4851 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
4852 ----------------------------------------
4853 but it doesn't work if nbody[nsp + begmatch + olen - tem]
4854 is a padding glyph. */
4855 int out = olen - tem; /* Columns to be overwritten originally. */
4856 int del;
4858 /* Calculate columns we can actually overwrite. */
4859 while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out])) out--;
4860 write_glyphs (nbody + nsp + begmatch, out);
4861 /* If we left columns to be overwritten, we must delete them. */
4862 del = olen - tem - out;
4863 if (del > 0) delete_glyphs (del);
4864 /* At last, we insert columns not yet written out. */
4865 insert_glyphs (nbody + nsp + begmatch + out, nlen - olen + del);
4866 olen = nlen;
4868 else if (olen > nlen)
4870 write_glyphs (nbody + nsp + begmatch, nlen - tem);
4871 delete_glyphs (olen - nlen);
4872 olen = nlen;
4876 just_erase:
4877 /* If any unerased characters remain after the new line, erase them. */
4878 if (olen > nlen)
4880 cursor_to (vpos, nlen);
4881 clear_end_of_line (olen);
4884 /* Exchange contents between current_frame and new_frame. */
4885 make_current (desired_matrix, current_matrix, vpos);
4890 /***********************************************************************
4891 X/Y Position -> Buffer Position
4892 ***********************************************************************/
4894 /* Return the character position of the character at window relative
4895 pixel position (*X, *Y). *X and *Y are adjusted to character
4896 boundaries. */
4899 buffer_posn_from_coords (w, x, y)
4900 struct window *w;
4901 int *x, *y;
4903 struct it it;
4904 struct buffer *old_current_buffer = current_buffer;
4905 struct text_pos startp;
4906 int left_area_width;
4908 current_buffer = XBUFFER (w->buffer);
4909 SET_TEXT_POS_FROM_MARKER (startp, w->start);
4910 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
4911 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
4912 start_display (&it, w, startp);
4914 left_area_width = WINDOW_DISPLAY_LEFT_AREA_PIXEL_WIDTH (w);
4915 move_it_to (&it, -1, *x + it.first_visible_x - left_area_width, *y, -1,
4916 MOVE_TO_X | MOVE_TO_Y);
4918 *x = it.current_x - it.first_visible_x + left_area_width;
4919 *y = it.current_y;
4920 current_buffer = old_current_buffer;
4921 return IT_CHARPOS (it);
4925 /* Value is the string under window-relative coordinates X/Y in the
4926 mode or top line of window W, or nil if none. MODE_LINE_P non-zero
4927 means look at the mode line. *CHARPOS is set to the position in
4928 the string returned. */
4930 Lisp_Object
4931 mode_line_string (w, x, y, mode_line_p, charpos)
4932 struct window *w;
4933 int x, y;
4934 int *charpos;
4936 struct glyph_row *row;
4937 struct glyph *glyph, *end;
4938 struct frame *f = XFRAME (w->frame);
4939 int x0;
4940 Lisp_Object string = Qnil;
4942 /* Only do this for frames under a window system. */
4943 if (!FRAME_WINDOW_P (f))
4944 return Qnil;
4946 if (mode_line_p)
4947 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
4948 else
4949 row = MATRIX_TOP_LINE_ROW (w->current_matrix);
4951 if (row->mode_line_p && row->enabled_p)
4953 /* The mode lines are displayed over scroll bars and bitmap
4954 areas, and X is window-relative. Correct X by the scroll bar
4955 and bitmap area width. */
4956 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
4957 x += FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
4958 x += FRAME_FLAGS_AREA_WIDTH (f);
4960 /* Find the glyph under X. If we find one with a string object,
4961 it's the one we were looking for. */
4962 glyph = row->glyphs[TEXT_AREA];
4963 end = glyph + row->used[TEXT_AREA];
4964 for (x0 = 0; glyph < end; x0 += glyph->pixel_width, ++glyph)
4965 if (x >= x0 && x < x0 + glyph->pixel_width)
4967 string = glyph->object;
4968 *charpos = glyph->charpos;
4969 break;
4973 return string;
4977 /***********************************************************************
4978 Changing Frame Sizes
4979 ***********************************************************************/
4981 #ifdef SIGWINCH
4983 SIGTYPE
4984 window_change_signal (signalnum) /* If we don't have an argument, */
4985 int signalnum; /* some compilers complain in signal calls. */
4987 int width, height;
4988 extern int errno;
4989 int old_errno = errno;
4991 get_frame_size (&width, &height);
4993 /* The frame size change obviously applies to a termcap-controlled
4994 frame. Find such a frame in the list, and assume it's the only
4995 one (since the redisplay code always writes to stdout, not a
4996 FILE * specified in the frame structure). Record the new size,
4997 but don't reallocate the data structures now. Let that be done
4998 later outside of the signal handler. */
5001 Lisp_Object tail, frame;
5003 FOR_EACH_FRAME (tail, frame)
5005 if (FRAME_TERMCAP_P (XFRAME (frame)))
5007 change_frame_size (XFRAME (frame), height, width, 0, 1);
5008 break;
5013 signal (SIGWINCH, window_change_signal);
5014 errno = old_errno;
5016 #endif /* SIGWINCH */
5019 /* Do any change in frame size that was requested by a signal. */
5021 void
5022 do_pending_window_change ()
5024 /* If window_change_signal should have run before, run it now. */
5025 while (delayed_size_change)
5027 Lisp_Object tail, frame;
5029 delayed_size_change = 0;
5031 FOR_EACH_FRAME (tail, frame)
5033 struct frame *f = XFRAME (frame);
5035 int height = FRAME_NEW_HEIGHT (f);
5036 int width = FRAME_NEW_WIDTH (f);
5038 if (height != 0 || width != 0)
5039 change_frame_size (f, height, width, 0, 0);
5045 /* Change the frame height and/or width. Values may be given as zero to
5046 indicate no change is to take place.
5048 If DELAY is non-zero, then assume we're being called from a signal
5049 handler, and queue the change for later - perhaps the next
5050 redisplay. Since this tries to resize windows, we can't call it
5051 from a signal handler. */
5053 void
5054 change_frame_size (f, newheight, newwidth, pretend, delay)
5055 register struct frame *f;
5056 int newheight, newwidth, pretend, delay;
5058 Lisp_Object tail, frame;
5060 if (! FRAME_WINDOW_P (f))
5062 /* When using termcap, or on MS-DOS, all frames use
5063 the same screen, so a change in size affects all frames. */
5064 FOR_EACH_FRAME (tail, frame)
5065 if (! FRAME_WINDOW_P (XFRAME (frame)))
5066 change_frame_size_1 (XFRAME (frame), newheight, newwidth,
5067 pretend, delay);
5069 else
5070 change_frame_size_1 (f, newheight, newwidth, pretend, delay);
5073 static void
5074 change_frame_size_1 (f, newheight, newwidth, pretend, delay)
5075 register struct frame *f;
5076 int newheight, newwidth, pretend, delay;
5078 int new_frame_window_width;
5079 unsigned int total_glyphs;
5080 int count = specpdl_ptr - specpdl;
5082 /* If we can't deal with the change now, queue it for later. */
5083 if (delay)
5085 FRAME_NEW_HEIGHT (f) = newheight;
5086 FRAME_NEW_WIDTH (f) = newwidth;
5087 delayed_size_change = 1;
5088 return;
5091 /* This size-change overrides any pending one for this frame. */
5092 FRAME_NEW_HEIGHT (f) = 0;
5093 FRAME_NEW_WIDTH (f) = 0;
5095 /* If an argument is zero, set it to the current value. */
5096 if (newheight == 0)
5097 newheight = FRAME_HEIGHT (f);
5098 if (newwidth == 0)
5099 newwidth = FRAME_WIDTH (f);
5101 /* Compute width of windows in F.
5102 This is the width of the frame without vertical scroll bars. */
5103 new_frame_window_width = FRAME_WINDOW_WIDTH_ARG (f, newwidth);
5105 /* Round up to the smallest acceptable size. */
5106 check_frame_size (f, &newheight, &newwidth);
5108 /* If we're not changing the frame size, quit now. */
5109 if (newheight == FRAME_HEIGHT (f)
5110 && new_frame_window_width == FRAME_WINDOW_WIDTH (f))
5111 return;
5113 BLOCK_INPUT;
5115 #ifdef MSDOS
5116 /* We only can set screen dimensions to certain values supported
5117 by our video hardware. Try to find the smallest size greater
5118 or equal to the requested dimensions. */
5119 dos_set_window_size (&newheight, &newwidth);
5120 #endif
5122 if (newheight != FRAME_HEIGHT (f))
5124 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
5126 /* Frame has both root and mini-buffer. */
5127 XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top,
5128 FRAME_TOP_MARGIN (f));
5129 set_window_height (FRAME_ROOT_WINDOW (f),
5130 (newheight
5132 - FRAME_TOP_MARGIN (f)),
5134 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top,
5135 newheight - 1);
5136 set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
5138 else
5139 /* Frame has just one top-level window. */
5140 set_window_height (FRAME_ROOT_WINDOW (f),
5141 newheight - FRAME_TOP_MARGIN (f), 0);
5143 if (FRAME_TERMCAP_P (f) && !pretend)
5144 FrameRows = newheight;
5147 if (new_frame_window_width != FRAME_WINDOW_WIDTH (f))
5149 set_window_width (FRAME_ROOT_WINDOW (f), new_frame_window_width, 0);
5150 if (FRAME_HAS_MINIBUF_P (f))
5151 set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_window_width, 0);
5153 if (FRAME_TERMCAP_P (f) && !pretend)
5154 FrameCols = newwidth;
5156 if (WINDOWP (f->toolbar_window))
5157 XSETFASTINT (XWINDOW (f->toolbar_window)->width, newwidth);
5160 FRAME_HEIGHT (f) = newheight;
5161 SET_FRAME_WIDTH (f, newwidth);
5164 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5165 int text_area_x, text_area_y, text_area_width, text_area_height;
5167 window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width,
5168 &text_area_height);
5169 if (w->cursor.x >= text_area_x + text_area_width)
5170 w->cursor.hpos = w->cursor.x = 0;
5171 if (w->cursor.y >= text_area_y + text_area_height)
5172 w->cursor.vpos = w->cursor.y = 0;
5175 adjust_glyphs (f);
5176 SET_FRAME_GARBAGED (f);
5177 calculate_costs (f);
5179 UNBLOCK_INPUT;
5181 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
5183 /* This isn't quite a no-op: it runs window-configuration-change-hook. */
5184 Fset_window_buffer (FRAME_SELECTED_WINDOW (f),
5185 XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer);
5187 unbind_to (count, Qnil);
5192 /***********************************************************************
5193 Terminal Related Lisp Functions
5194 ***********************************************************************/
5196 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
5197 1, 1, "FOpen termscript file: ",
5198 "Start writing all terminal output to FILE as well as the terminal.\n\
5199 FILE = nil means just close any termscript file currently open.")
5200 (file)
5201 Lisp_Object file;
5203 if (termscript != 0) fclose (termscript);
5204 termscript = 0;
5206 if (! NILP (file))
5208 file = Fexpand_file_name (file, Qnil);
5209 termscript = fopen (XSTRING (file)->data, "w");
5210 if (termscript == 0)
5211 report_file_error ("Opening termscript", Fcons (file, Qnil));
5213 return Qnil;
5217 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
5218 Ssend_string_to_terminal, 1, 1, 0,
5219 "Send STRING to the terminal without alteration.\n\
5220 Control characters in STRING will have terminal-dependent effects.")
5221 (string)
5222 Lisp_Object string;
5224 /* ??? Perhaps we should do something special for multibyte strings here. */
5225 CHECK_STRING (string, 0);
5226 fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)), stdout);
5227 fflush (stdout);
5228 if (termscript)
5230 fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)),
5231 termscript);
5232 fflush (termscript);
5234 return Qnil;
5238 DEFUN ("ding", Fding, Sding, 0, 1, 0,
5239 "Beep, or flash the screen.\n\
5240 Also, unless an argument is given,\n\
5241 terminate any keyboard macro currently executing.")
5242 (arg)
5243 Lisp_Object arg;
5245 if (!NILP (arg))
5247 if (noninteractive)
5248 putchar (07);
5249 else
5250 ring_bell ();
5251 fflush (stdout);
5253 else
5254 bitch_at_user ();
5256 return Qnil;
5259 void
5260 bitch_at_user ()
5262 if (noninteractive)
5263 putchar (07);
5264 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
5265 error ("Keyboard macro terminated by a command ringing the bell");
5266 else
5267 ring_bell ();
5268 fflush (stdout);
5273 /***********************************************************************
5274 Sleeping, Waiting
5275 ***********************************************************************/
5277 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
5278 "Pause, without updating display, for SECONDS seconds.\n\
5279 SECONDS may be a floating-point value, meaning that you can wait for a\n\
5280 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
5281 additional wait period, in milliseconds; this may be useful if your\n\
5282 Emacs was built without floating point support.\n\
5283 \(Not all operating systems support waiting for a fraction of a second.)")
5284 (seconds, milliseconds)
5285 Lisp_Object seconds, milliseconds;
5287 int sec, usec;
5289 if (NILP (milliseconds))
5290 XSETINT (milliseconds, 0);
5291 else
5292 CHECK_NUMBER (milliseconds, 1);
5293 usec = XINT (milliseconds) * 1000;
5295 #ifdef LISP_FLOAT_TYPE
5297 double duration = extract_float (seconds);
5298 sec = (int) duration;
5299 usec += (duration - sec) * 1000000;
5301 #else
5302 CHECK_NUMBER (seconds, 0);
5303 sec = XINT (seconds);
5304 #endif
5306 #ifndef EMACS_HAS_USECS
5307 if (sec == 0 && usec != 0)
5308 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
5309 #endif
5311 /* Assure that 0 <= usec < 1000000. */
5312 if (usec < 0)
5314 /* We can't rely on the rounding being correct if user is negative. */
5315 if (-1000000 < usec)
5316 sec--, usec += 1000000;
5317 else
5318 sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
5320 else
5321 sec += usec / 1000000, usec %= 1000000;
5323 if (sec < 0 || (sec == 0 && usec == 0))
5324 return Qnil;
5327 Lisp_Object zero;
5329 XSETFASTINT (zero, 0);
5330 wait_reading_process_input (sec, usec, zero, 0);
5333 /* We should always have wait_reading_process_input; we have a dummy
5334 implementation for systems which don't support subprocesses. */
5335 #if 0
5336 /* No wait_reading_process_input */
5337 immediate_quit = 1;
5338 QUIT;
5340 #ifdef VMS
5341 sys_sleep (sec);
5342 #else /* not VMS */
5343 /* The reason this is done this way
5344 (rather than defined (H_S) && defined (H_T))
5345 is because the VMS preprocessor doesn't grok `defined' */
5346 #ifdef HAVE_SELECT
5347 EMACS_GET_TIME (end_time);
5348 EMACS_SET_SECS_USECS (timeout, sec, usec);
5349 EMACS_ADD_TIME (end_time, end_time, timeout);
5351 while (1)
5353 EMACS_GET_TIME (timeout);
5354 EMACS_SUB_TIME (timeout, end_time, timeout);
5355 if (EMACS_TIME_NEG_P (timeout)
5356 || !select (1, 0, 0, 0, &timeout))
5357 break;
5359 #else /* not HAVE_SELECT */
5360 sleep (sec);
5361 #endif /* HAVE_SELECT */
5362 #endif /* not VMS */
5364 immediate_quit = 0;
5365 #endif /* no subprocesses */
5367 return Qnil;
5371 /* This is just like wait_reading_process_input, except that
5372 it does the redisplay.
5374 It's also much like Fsit_for, except that it can be used for
5375 waiting for input as well. */
5377 Lisp_Object
5378 sit_for (sec, usec, reading, display, initial_display)
5379 int sec, usec, reading, display, initial_display;
5381 Lisp_Object read_kbd;
5383 swallow_events (display);
5385 if (detect_input_pending_run_timers (display))
5386 return Qnil;
5388 if (initial_display)
5389 redisplay_preserve_echo_area ();
5391 if (sec == 0 && usec == 0)
5392 return Qt;
5394 #ifdef SIGIO
5395 gobble_input (0);
5396 #endif
5398 XSETINT (read_kbd, reading ? -1 : 1);
5399 wait_reading_process_input (sec, usec, read_kbd, display);
5401 return detect_input_pending () ? Qnil : Qt;
5405 DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
5406 "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
5407 SECONDS may be a floating-point value, meaning that you can wait for a\n\
5408 fraction of a second. Optional second arg MILLISECONDS specifies an\n\
5409 additional wait period, in milliseconds; this may be useful if your\n\
5410 Emacs was built without floating point support.\n\
5411 \(Not all operating systems support waiting for a fraction of a second.)\n\
5412 Optional third arg NODISP non-nil means don't redisplay, just wait for input.\n\
5413 Redisplay is preempted as always if input arrives, and does not happen\n\
5414 if input is available before it starts.\n\
5415 Value is t if waited the full time with no input arriving.")
5416 (seconds, milliseconds, nodisp)
5417 Lisp_Object seconds, milliseconds, nodisp;
5419 int sec, usec;
5421 if (NILP (milliseconds))
5422 XSETINT (milliseconds, 0);
5423 else
5424 CHECK_NUMBER (milliseconds, 1);
5425 usec = XINT (milliseconds) * 1000;
5427 #ifdef LISP_FLOAT_TYPE
5429 double duration = extract_float (seconds);
5430 sec = (int) duration;
5431 usec += (duration - sec) * 1000000;
5433 #else
5434 CHECK_NUMBER (seconds, 0);
5435 sec = XINT (seconds);
5436 #endif
5438 #ifndef EMACS_HAS_USECS
5439 if (usec != 0 && sec == 0)
5440 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE);
5441 #endif
5443 return sit_for (sec, usec, 0, NILP (nodisp), NILP (nodisp));
5448 /***********************************************************************
5449 Other Lisp Functions
5450 ***********************************************************************/
5452 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
5453 session's frames, frame names, buffers, buffer-read-only flags, and
5454 buffer-modified-flags, and a trailing sentinel (so we don't need to
5455 add length checks). */
5457 static Lisp_Object frame_and_buffer_state;
5460 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
5461 Sframe_or_buffer_changed_p, 0, 0, 0,
5462 "Return non-nil if the frame and buffer state appears to have changed.\n\
5463 The state variable is an internal vector containing all frames and buffers,\n\
5464 aside from buffers whose names start with space,\n\
5465 along with the buffers' read-only and modified flags, which allows a fast\n\
5466 check to see whether the menu bars might need to be recomputed.\n\
5467 If this function returns non-nil, it updates the internal vector to reflect\n\
5468 the current state.\n")
5471 Lisp_Object tail, frame, buf;
5472 Lisp_Object *vecp;
5473 int n;
5475 vecp = XVECTOR (frame_and_buffer_state)->contents;
5476 FOR_EACH_FRAME (tail, frame)
5478 if (!EQ (*vecp++, frame))
5479 goto changed;
5480 if (!EQ (*vecp++, XFRAME (frame)->name))
5481 goto changed;
5483 /* Check that the buffer info matches.
5484 No need to test for the end of the vector
5485 because the last element of the vector is lambda
5486 and that will always cause a mismatch. */
5487 for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
5489 buf = XCONS (XCONS (tail)->car)->cdr;
5490 /* Ignore buffers that aren't included in buffer lists. */
5491 if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
5492 continue;
5493 if (!EQ (*vecp++, buf))
5494 goto changed;
5495 if (!EQ (*vecp++, XBUFFER (buf)->read_only))
5496 goto changed;
5497 if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
5498 goto changed;
5500 /* Detect deletion of a buffer at the end of the list. */
5501 if (EQ (*vecp, Qlambda))
5502 return Qnil;
5503 changed:
5504 /* Start with 1 so there is room for at least one lambda at the end. */
5505 n = 1;
5506 FOR_EACH_FRAME (tail, frame)
5507 n += 2;
5508 for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
5509 n += 3;
5510 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */
5511 if (n > XVECTOR (frame_and_buffer_state)->size
5512 || n + 20 < XVECTOR (frame_and_buffer_state)->size / 2)
5513 /* Add 20 extra so we grow it less often. */
5514 frame_and_buffer_state = Fmake_vector (make_number (n + 20), Qlambda);
5515 vecp = XVECTOR (frame_and_buffer_state)->contents;
5516 FOR_EACH_FRAME (tail, frame)
5518 *vecp++ = frame;
5519 *vecp++ = XFRAME (frame)->name;
5521 for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
5523 buf = XCONS (XCONS (tail)->car)->cdr;
5524 /* Ignore buffers that aren't included in buffer lists. */
5525 if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
5526 continue;
5527 *vecp++ = buf;
5528 *vecp++ = XBUFFER (buf)->read_only;
5529 *vecp++ = Fbuffer_modified_p (buf);
5531 /* Fill up the vector with lambdas (always at least one). */
5532 *vecp++ = Qlambda;
5533 while (vecp - XVECTOR (frame_and_buffer_state)->contents
5534 < XVECTOR (frame_and_buffer_state)->size)
5535 *vecp++ = Qlambda;
5536 /* Make sure we didn't overflow the vector. */
5537 if (vecp - XVECTOR (frame_and_buffer_state)->contents
5538 > XVECTOR (frame_and_buffer_state)->size)
5539 abort ();
5540 return Qt;
5545 /***********************************************************************
5546 Initialization
5547 ***********************************************************************/
5549 char *terminal_type;
5551 /* Initialization done when Emacs fork is started, before doing stty.
5552 Determine terminal type and set terminal_driver. Then invoke its
5553 decoding routine to set up variables in the terminal package. */
5555 void
5556 init_display ()
5558 #ifdef HAVE_X_WINDOWS
5559 extern int display_arg;
5560 #endif
5562 /* Construct the space glyph. */
5563 space_glyph.type = CHAR_GLYPH;
5564 SET_CHAR_GLYPH_FROM_GLYPH (space_glyph, ' ');
5565 space_glyph.charpos = -1;
5567 meta_key = 0;
5568 inverse_video = 0;
5569 cursor_in_echo_area = 0;
5570 terminal_type = (char *) 0;
5572 /* Now is the time to initialize this; it's used by init_sys_modes
5573 during startup. */
5574 Vwindow_system = Qnil;
5576 /* If the user wants to use a window system, we shouldn't bother
5577 initializing the terminal. This is especially important when the
5578 terminal is so dumb that emacs gives up before and doesn't bother
5579 using the window system.
5581 If the DISPLAY environment variable is set and nonempty,
5582 try to use X, and die with an error message if that doesn't work. */
5584 #ifdef HAVE_X_WINDOWS
5585 if (! display_arg)
5587 char *display;
5588 #ifdef VMS
5589 display = getenv ("DECW$DISPLAY");
5590 #else
5591 display = getenv ("DISPLAY");
5592 #endif
5594 display_arg = (display != 0 && *display != 0);
5597 if (!inhibit_window_system && display_arg
5598 #ifndef CANNOT_DUMP
5599 && initialized
5600 #endif
5603 Vwindow_system = intern ("x");
5604 #ifdef HAVE_X11
5605 Vwindow_system_version = make_number (11);
5606 #else
5607 Vwindow_system_version = make_number (10);
5608 #endif
5609 #if defined (LINUX) && defined (HAVE_LIBNCURSES)
5610 /* In some versions of ncurses,
5611 tputs crashes if we have not called tgetent.
5612 So call tgetent. */
5613 { char b[2044]; tgetent (b, "xterm");}
5614 #endif
5615 adjust_frame_glyphs_initially ();
5616 return;
5618 #endif /* HAVE_X_WINDOWS */
5620 #ifdef HAVE_NTGUI
5621 if (!inhibit_window_system)
5623 Vwindow_system = intern ("w32");
5624 Vwindow_system_version = make_number (1);
5625 adjust_frame_glyphs_initially ();
5626 return;
5628 #endif /* HAVE_NTGUI */
5630 /* If no window system has been specified, try to use the terminal. */
5631 if (! isatty (0))
5633 fatal ("standard input is not a tty");
5634 exit (1);
5637 /* Look at the TERM variable */
5638 terminal_type = (char *) getenv ("TERM");
5639 if (!terminal_type)
5641 #ifdef VMS
5642 fprintf (stderr, "Please specify your terminal type.\n\
5643 For types defined in VMS, use set term /device=TYPE.\n\
5644 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
5645 \(The quotation marks are necessary since terminal types are lower case.)\n");
5646 #else
5647 fprintf (stderr, "Please set the environment variable TERM; see tset(1).\n");
5648 #endif
5649 exit (1);
5652 #ifdef VMS
5653 /* VMS DCL tends to up-case things, so down-case term type.
5654 Hardly any uppercase letters in terminal types; should be none. */
5656 char *new = (char *) xmalloc (strlen (terminal_type) + 1);
5657 char *p;
5659 strcpy (new, terminal_type);
5661 for (p = new; *p; p++)
5662 if (isupper (*p))
5663 *p = tolower (*p);
5665 terminal_type = new;
5667 #endif /* VMS */
5669 term_init (terminal_type);
5672 int width = FRAME_WINDOW_WIDTH (selected_frame);
5673 int height = FRAME_HEIGHT (selected_frame);
5675 unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
5677 /* If these sizes are so big they cause overflow, just ignore the
5678 change. It's not clear what better we could do. */
5679 if (total_glyphs / sizeof (struct glyph) / height != width + 2)
5680 fatal ("screen size %dx%d too big", width, height);
5683 adjust_frame_glyphs_initially ();
5684 calculate_costs (selected_frame);
5686 #ifdef SIGWINCH
5687 #ifndef CANNOT_DUMP
5688 if (initialized)
5689 #endif /* CANNOT_DUMP */
5690 signal (SIGWINCH, window_change_signal);
5691 #endif /* SIGWINCH */
5693 /* Set up faces of the initial terminal frame of a dumped Emacs. */
5694 if (initialized
5695 && !noninteractive
5696 #ifdef MSDOS
5697 /* The MSDOS terminal turns on its ``window system'' relatively
5698 late into the startup, so we cannot do the frame faces'
5699 initialization just yet. It will be done later by pc-win.el
5700 and internal_terminal_init. */
5701 && (strcmp (terminal_type, "internal") != 0 || inhibit_window_system)
5702 #endif
5703 && NILP (Vwindow_system))
5704 call0 (intern ("tty-set-up-initial-frame-faces"));
5709 /***********************************************************************
5710 Blinking cursor
5711 ***********************************************************************/
5713 DEFUN ("show-cursor", Fshow_cursor, Sshow_cursor, 0, 2, 0,
5714 "Change visibility flag of the text cursor of WINDOW.\n\
5715 ON_P nil means toggle the flag. Otherwise, ON_P must be an integer,\n\
5716 and the flag is set according to the value of ON_P. WINDOW nil or\n\
5717 omitted means use the selected window. The new cursor state takes effect\n\
5718 with the next redisplay.")
5719 (on_p, window)
5720 Lisp_Object on_p, window;
5722 struct window *w;
5724 /* Don't change cursor state while redisplaying. This could confuse
5725 output routines. */
5726 if (!redisplaying_p)
5728 if (NILP (window))
5729 window = selected_window;
5730 else
5731 CHECK_WINDOW (window, 2);
5732 w = XWINDOW (window);
5734 if (NILP (on_p))
5735 w->cursor_off_p = !w->cursor_off_p;
5736 else
5738 CHECK_NUMBER (on_p, 1);
5739 w->cursor_off_p = XINT (on_p) != 0;
5743 return Qnil;
5748 /***********************************************************************
5749 Initialization
5750 ***********************************************************************/
5752 void
5753 syms_of_display ()
5755 defsubr (&Sredraw_frame);
5756 defsubr (&Sredraw_display);
5757 defsubr (&Sframe_or_buffer_changed_p);
5758 defsubr (&Sopen_termscript);
5759 defsubr (&Sding);
5760 defsubr (&Ssit_for);
5761 defsubr (&Ssleep_for);
5762 defsubr (&Ssend_string_to_terminal);
5763 defsubr (&Sshow_cursor);
5765 frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
5766 staticpro (&frame_and_buffer_state);
5768 Qdisplay_table = intern ("display-table");
5769 staticpro (&Qdisplay_table);
5771 DEFVAR_INT ("baud-rate", &baud_rate,
5772 "*The output baud rate of the terminal.\n\
5773 On most systems, changing this value will affect the amount of padding\n\
5774 and the other strategic decisions made during redisplay.");
5776 DEFVAR_BOOL ("inverse-video", &inverse_video,
5777 "*Non-nil means invert the entire frame display.\n\
5778 This means everything is in inverse video which otherwise would not be.");
5780 DEFVAR_BOOL ("visible-bell", &visible_bell,
5781 "*Non-nil means try to flash the frame to represent a bell.");
5783 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
5784 "*Non-nil means no need to redraw entire frame after suspending.\n\
5785 A non-nil value is useful if the terminal can automatically preserve\n\
5786 Emacs's frame display when you reenter Emacs.\n\
5787 It is up to you to set this variable if your terminal can do that.");
5789 DEFVAR_LISP ("window-system", &Vwindow_system,
5790 "A symbol naming the window-system under which Emacs is running\n\
5791 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
5793 DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
5794 "The version number of the window system in use.\n\
5795 For X windows, this is 10 or 11.");
5797 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
5798 "Non-nil means put cursor in minibuffer, at end of any message there.");
5800 DEFVAR_LISP ("glyph-table", &Vglyph_table,
5801 "Table defining how to output a glyph code to the frame.\n\
5802 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
5803 Each element can be:\n\
5804 integer: a glyph code which this glyph is an alias for.\n\
5805 string: output this glyph using that string (not impl. in X windows).\n\
5806 nil: this glyph mod 256 is char code to output,\n\
5807 and this glyph / 256 is face code for X windows (see `face-id').");
5808 Vglyph_table = Qnil;
5810 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
5811 "Display table to use for buffers that specify none.\n\
5812 See `buffer-display-table' for more information.");
5813 Vstandard_display_table = Qnil;
5815 DEFVAR_BOOL ("redisplay-dont-pause", &redisplay_dont_pause,
5816 "*Non-nil means update isn't paused when input is detected.");
5817 redisplay_dont_pause = 0;
5819 /* Initialize `window-system', unless init_display already decided it. */
5820 #ifdef CANNOT_DUMP
5821 if (noninteractive)
5822 #endif
5824 Vwindow_system = Qnil;
5825 Vwindow_system_version = Qnil;