upstream
[emacs.git] / src / dispnew.c
blob6459884a2e4637808e71a4b075f5fffed88b2cab
1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985-1988, 1993-1995, 1997-2011 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18 #include <config.h>
19 #include <signal.h>
20 #include <stdio.h>
21 #include <ctype.h>
22 #include <setjmp.h>
23 #include <unistd.h>
25 #include "lisp.h"
26 #include "termchar.h"
27 #include "termopts.h"
28 /* cm.h must come after dispextern.h on Windows. */
29 #include "dispextern.h"
30 #include "cm.h"
31 #include "buffer.h"
32 #include "character.h"
33 #include "keyboard.h"
34 #include "frame.h"
35 #include "termhooks.h"
36 #include "window.h"
37 #include "commands.h"
38 #include "disptab.h"
39 #include "indent.h"
40 #include "intervals.h"
41 #include "blockinput.h"
42 #include "process.h"
44 #include "syssignal.h"
46 #ifdef HAVE_X_WINDOWS
47 #include "xterm.h"
48 #endif /* HAVE_X_WINDOWS */
50 #ifdef HAVE_NTGUI
51 #include "w32term.h"
52 #endif /* HAVE_NTGUI */
54 #ifdef HAVE_NS
55 #include "nsterm.h"
56 #endif
58 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
60 #include "systime.h"
61 #include <errno.h>
63 /* Get number of chars of output now in the buffer of a stdio stream.
64 This ought to be built in in stdio, but it isn't. Some s- files
65 override this because their stdio internals differ. */
67 #ifdef __GNU_LIBRARY__
69 /* The s- file might have overridden the definition with one that
70 works for the system's C library. But we are using the GNU C
71 library, so this is the right definition for every system. */
73 #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
74 #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
75 #else
76 #undef PENDING_OUTPUT_COUNT
77 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
78 #endif
79 #else /* not __GNU_LIBRARY__ */
80 #if !defined (PENDING_OUTPUT_COUNT) && HAVE_STDIO_EXT_H && HAVE___FPENDING
81 #include <stdio_ext.h>
82 #define PENDING_OUTPUT_COUNT(FILE) __fpending (FILE)
83 #endif
84 #ifndef PENDING_OUTPUT_COUNT
85 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
86 #endif
87 #endif /* not __GNU_LIBRARY__ */
89 #if defined(HAVE_TERM_H) && defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
90 #include <term.h> /* for tgetent */
91 #endif
93 /* Structure to pass dimensions around. Used for character bounding
94 boxes, glyph matrix dimensions and alike. */
96 struct dim
98 int width;
99 int height;
103 /* Function prototypes. */
105 static void update_frame_line (struct frame *, int);
106 static int required_matrix_height (struct window *);
107 static int required_matrix_width (struct window *);
108 static void adjust_frame_glyphs (struct frame *);
109 static void change_frame_size_1 (struct frame *, int, int, int, int, int);
110 static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT);
111 static void fill_up_frame_row_with_spaces (struct glyph_row *, int);
112 static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
113 struct window *);
114 static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
115 struct window *);
116 static void adjust_frame_message_buffer (struct frame *);
117 static void adjust_decode_mode_spec_buffer (struct frame *);
118 static void fill_up_glyph_row_with_spaces (struct glyph_row *);
119 static void clear_window_matrices (struct window *, int);
120 static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int);
121 static int scrolling_window (struct window *, int);
122 static int update_window_line (struct window *, int, int *);
123 static void mirror_make_current (struct window *, int);
124 #if GLYPH_DEBUG
125 static void check_matrix_pointers (struct glyph_matrix *,
126 struct glyph_matrix *);
127 #endif
128 static void mirror_line_dance (struct window *, int, int, int *, char *);
129 static int update_window_tree (struct window *, int);
130 static int update_window (struct window *, int);
131 static int update_frame_1 (struct frame *, int, int);
132 static int scrolling (struct frame *);
133 static void set_window_cursor_after_update (struct window *);
134 static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
135 static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
138 /* Define PERIODIC_PREEMPTION_CHECKING to 1, if micro-second timers
139 are supported, so we can check for input during redisplay at
140 regular intervals. */
141 #ifdef EMACS_HAS_USECS
142 #define PERIODIC_PREEMPTION_CHECKING 1
143 #else
144 #define PERIODIC_PREEMPTION_CHECKING 0
145 #endif
147 #if PERIODIC_PREEMPTION_CHECKING
149 /* Redisplay preemption timers. */
151 static EMACS_TIME preemption_period;
152 static EMACS_TIME preemption_next_check;
154 #endif
156 /* Nonzero upon entry to redisplay means do not assume anything about
157 current contents of actual terminal frame; clear and redraw it. */
159 int frame_garbaged;
161 /* Nonzero means last display completed. Zero means it was preempted. */
163 int display_completed;
165 Lisp_Object Qdisplay_table, Qredisplay_dont_pause;
168 /* The currently selected frame. In a single-frame version, this
169 variable always equals the_only_frame. */
171 Lisp_Object selected_frame;
173 /* A frame which is not just a mini-buffer, or 0 if there are no such
174 frames. This is usually the most recent such frame that was
175 selected. In a single-frame version, this variable always holds
176 the address of the_only_frame. */
178 struct frame *last_nonminibuf_frame;
180 /* 1 means SIGWINCH happened when not safe. */
182 static int delayed_size_change;
184 /* 1 means glyph initialization has been completed at startup. */
186 static int glyphs_initialized_initially_p;
188 /* Updated window if != 0. Set by update_window. */
190 struct window *updated_window;
192 /* Glyph row updated in update_window_line, and area that is updated. */
194 struct glyph_row *updated_row;
195 int updated_area;
197 /* A glyph for a space. */
199 struct glyph space_glyph;
201 /* Counts of allocated structures. These counts serve to diagnose
202 memory leaks and double frees. */
204 static int glyph_matrix_count;
205 static int glyph_pool_count;
207 /* If non-null, the frame whose frame matrices are manipulated. If
208 null, window matrices are worked on. */
210 static struct frame *frame_matrix_frame;
212 /* Non-zero means that fonts have been loaded since the last glyph
213 matrix adjustments. Redisplay must stop, and glyph matrices must
214 be adjusted when this flag becomes non-zero during display. The
215 reason fonts can be loaded so late is that fonts of fontsets are
216 loaded on demand. Another reason is that a line contains many
217 characters displayed by zero width or very narrow glyphs of
218 variable-width fonts. */
220 int fonts_changed_p;
222 /* Convert vpos and hpos from frame to window and vice versa.
223 This may only be used for terminal frames. */
225 #if GLYPH_DEBUG
227 static int window_to_frame_vpos (struct window *, int);
228 static int window_to_frame_hpos (struct window *, int);
229 #define WINDOW_TO_FRAME_VPOS(W, VPOS) window_to_frame_vpos ((W), (VPOS))
230 #define WINDOW_TO_FRAME_HPOS(W, HPOS) window_to_frame_hpos ((W), (HPOS))
232 /* One element of the ring buffer containing redisplay history
233 information. */
235 struct redisplay_history
237 char trace[512 + 100];
240 /* The size of the history buffer. */
242 #define REDISPLAY_HISTORY_SIZE 30
244 /* The redisplay history buffer. */
246 static struct redisplay_history redisplay_history[REDISPLAY_HISTORY_SIZE];
248 /* Next free entry in redisplay_history. */
250 static int history_idx;
252 /* A tick that's incremented each time something is added to the
253 history. */
255 static uprintmax_t history_tick;
257 static void add_frame_display_history (struct frame *, int);
259 /* Add to the redisplay history how window W has been displayed.
260 MSG is a trace containing the information how W's glyph matrix
261 has been constructed. PAUSED_P non-zero means that the update
262 has been interrupted for pending input. */
264 static void
265 add_window_display_history (struct window *w, const char *msg, int paused_p)
267 char *buf;
269 if (history_idx >= REDISPLAY_HISTORY_SIZE)
270 history_idx = 0;
271 buf = redisplay_history[history_idx].trace;
272 ++history_idx;
274 snprintf (buf, sizeof redisplay_history[0].trace,
275 "%"pMu": window %p (`%s')%s\n%s",
276 history_tick++,
278 ((BUFFERP (w->buffer)
279 && STRINGP (BVAR (XBUFFER (w->buffer), name)))
280 ? SSDATA (BVAR (XBUFFER (w->buffer), name))
281 : "???"),
282 paused_p ? " ***paused***" : "",
283 msg);
287 /* Add to the redisplay history that frame F has been displayed.
288 PAUSED_P non-zero means that the update has been interrupted for
289 pending input. */
291 static void add_frame_display_history (struct frame *f, int paused_p)
293 char *buf;
295 if (history_idx >= REDISPLAY_HISTORY_SIZE)
296 history_idx = 0;
297 buf = redisplay_history[history_idx].trace;
298 ++history_idx;
300 sprintf (buf, "%"pMu": update frame %p%s",
301 history_tick++,
302 f, paused_p ? " ***paused***" : "");
306 DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
307 Sdump_redisplay_history, 0, 0, "",
308 doc: /* Dump redisplay history to stderr. */)
309 (void)
311 int i;
313 for (i = history_idx - 1; i != history_idx; --i)
315 if (i < 0)
316 i = REDISPLAY_HISTORY_SIZE - 1;
317 fprintf (stderr, "%s\n", redisplay_history[i].trace);
320 return Qnil;
324 #else /* GLYPH_DEBUG == 0 */
326 #define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + WINDOW_TOP_EDGE_LINE (W))
327 #define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + WINDOW_LEFT_EDGE_COL (W))
329 #endif /* GLYPH_DEBUG == 0 */
332 #if defined PROFILING && !HAVE___EXECUTABLE_START
333 /* FIXME: only used to find text start for profiling. */
335 void
336 safe_bcopy (const char *from, char *to, int size)
338 abort ();
340 #endif
342 /***********************************************************************
343 Glyph Matrices
344 ***********************************************************************/
346 /* Allocate and return a glyph_matrix structure. POOL is the glyph
347 pool from which memory for the matrix should be allocated, or null
348 for window-based redisplay where no glyph pools are used. The
349 member `pool' of the glyph matrix structure returned is set to
350 POOL, the structure is otherwise zeroed. */
352 static struct glyph_matrix *
353 new_glyph_matrix (struct glyph_pool *pool)
355 struct glyph_matrix *result;
357 /* Allocate and clear. */
358 result = (struct glyph_matrix *) xmalloc (sizeof *result);
359 memset (result, 0, sizeof *result);
361 /* Increment number of allocated matrices. This count is used
362 to detect memory leaks. */
363 ++glyph_matrix_count;
365 /* Set pool and return. */
366 result->pool = pool;
367 return result;
371 /* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed.
373 The global counter glyph_matrix_count is decremented when a matrix
374 is freed. If the count gets negative, more structures were freed
375 than allocated, i.e. one matrix was freed more than once or a bogus
376 pointer was passed to this function.
378 If MATRIX->pool is null, this means that the matrix manages its own
379 glyph memory---this is done for matrices on X frames. Freeing the
380 matrix also frees the glyph memory in this case. */
382 static void
383 free_glyph_matrix (struct glyph_matrix *matrix)
385 if (matrix)
387 int i;
389 /* Detect the case that more matrices are freed than were
390 allocated. */
391 if (--glyph_matrix_count < 0)
392 abort ();
394 /* Free glyph memory if MATRIX owns it. */
395 if (matrix->pool == NULL)
396 for (i = 0; i < matrix->rows_allocated; ++i)
397 xfree (matrix->rows[i].glyphs[LEFT_MARGIN_AREA]);
399 /* Free row structures and the matrix itself. */
400 xfree (matrix->rows);
401 xfree (matrix);
406 /* Return the number of glyphs to reserve for a marginal area of
407 window W. TOTAL_GLYPHS is the number of glyphs in a complete
408 display line of window W. MARGIN gives the width of the marginal
409 area in canonical character units. MARGIN should be an integer
410 or a float. */
412 static int
413 margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin)
415 int n;
417 if (NUMBERP (margin))
419 int width = XFASTINT (w->total_cols);
420 double d = max (0, XFLOATINT (margin));
421 d = min (width / 2 - 1, d);
422 n = (int) ((double) total_glyphs / width * d);
424 else
425 n = 0;
427 return n;
431 /* Adjust glyph matrix MATRIX on window W or on a frame to changed
432 window sizes.
434 W is null if the function is called for a frame glyph matrix.
435 Otherwise it is the window MATRIX is a member of. X and Y are the
436 indices of the first column and row of MATRIX within the frame
437 matrix, if such a matrix exists. They are zero for purely
438 window-based redisplay. DIM is the needed size of the matrix.
440 In window-based redisplay, where no frame matrices exist, glyph
441 matrices manage their own glyph storage. Otherwise, they allocate
442 storage from a common frame glyph pool which can be found in
443 MATRIX->pool.
445 The reason for this memory management strategy is to avoid complete
446 frame redraws if possible. When we allocate from a common pool, a
447 change of the location or size of a sub-matrix within the pool
448 requires a complete redisplay of the frame because we cannot easily
449 make sure that the current matrices of all windows still agree with
450 what is displayed on the screen. While this is usually fast, it
451 leads to screen flickering. */
453 static void
454 adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y, struct dim dim)
456 int i;
457 int new_rows;
458 int marginal_areas_changed_p = 0;
459 int header_line_changed_p = 0;
460 int header_line_p = 0;
461 int left = -1, right = -1;
462 int window_width = -1, window_height = -1;
464 /* See if W had a header line that has disappeared now, or vice versa.
465 Get W's size. */
466 if (w)
468 window_box (w, -1, 0, 0, &window_width, &window_height);
470 header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
471 header_line_changed_p = header_line_p != matrix->header_line_p;
473 matrix->header_line_p = header_line_p;
475 /* If POOL is null, MATRIX is a window matrix for window-based redisplay.
476 Do nothing if MATRIX' size, position, vscroll, and marginal areas
477 haven't changed. This optimization is important because preserving
478 the matrix means preventing redisplay. */
479 if (matrix->pool == NULL)
481 left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_cols);
482 right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_cols);
483 xassert (left >= 0 && right >= 0);
484 marginal_areas_changed_p = (left != matrix->left_margin_glyphs
485 || right != matrix->right_margin_glyphs);
487 if (!marginal_areas_changed_p
488 && !fonts_changed_p
489 && !header_line_changed_p
490 && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
491 && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
492 && matrix->window_height == window_height
493 && matrix->window_vscroll == w->vscroll
494 && matrix->window_width == window_width)
495 return;
498 /* Enlarge MATRIX->rows if necessary. New rows are cleared. */
499 if (matrix->rows_allocated < dim.height)
501 int old_alloc = matrix->rows_allocated;
502 new_rows = dim.height - matrix->rows_allocated;
503 matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
504 new_rows, INT_MAX, sizeof *matrix->rows);
505 memset (matrix->rows + old_alloc, 0,
506 (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows);
508 else
509 new_rows = 0;
511 /* If POOL is not null, MATRIX is a frame matrix or a window matrix
512 on a frame not using window-based redisplay. Set up pointers for
513 each row into the glyph pool. */
514 if (matrix->pool)
516 xassert (matrix->pool->glyphs);
518 if (w)
520 left = margin_glyphs_to_reserve (w, dim.width,
521 w->left_margin_cols);
522 right = margin_glyphs_to_reserve (w, dim.width,
523 w->right_margin_cols);
525 else
526 left = right = 0;
528 for (i = 0; i < dim.height; ++i)
530 struct glyph_row *row = &matrix->rows[i];
532 row->glyphs[LEFT_MARGIN_AREA]
533 = (matrix->pool->glyphs
534 + (y + i) * matrix->pool->ncolumns
535 + x);
537 if (w == NULL
538 || row == matrix->rows + dim.height - 1
539 || (row == matrix->rows && matrix->header_line_p))
541 row->glyphs[TEXT_AREA]
542 = row->glyphs[LEFT_MARGIN_AREA];
543 row->glyphs[RIGHT_MARGIN_AREA]
544 = row->glyphs[TEXT_AREA] + dim.width;
545 row->glyphs[LAST_AREA]
546 = row->glyphs[RIGHT_MARGIN_AREA];
548 else
550 row->glyphs[TEXT_AREA]
551 = row->glyphs[LEFT_MARGIN_AREA] + left;
552 row->glyphs[RIGHT_MARGIN_AREA]
553 = row->glyphs[TEXT_AREA] + dim.width - left - right;
554 row->glyphs[LAST_AREA]
555 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
559 matrix->left_margin_glyphs = left;
560 matrix->right_margin_glyphs = right;
562 else
564 /* If MATRIX->pool is null, MATRIX is responsible for managing
565 its own memory. It is a window matrix for window-based redisplay.
566 Allocate glyph memory from the heap. */
567 if (dim.width > matrix->matrix_w
568 || new_rows
569 || header_line_changed_p
570 || marginal_areas_changed_p)
572 struct glyph_row *row = matrix->rows;
573 struct glyph_row *end = row + matrix->rows_allocated;
575 while (row < end)
577 row->glyphs[LEFT_MARGIN_AREA]
578 = xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
579 dim.width, sizeof (struct glyph));
581 /* The mode line never has marginal areas. */
582 if (row == matrix->rows + dim.height - 1
583 || (row == matrix->rows && matrix->header_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;
601 ++row;
605 xassert (left >= 0 && right >= 0);
606 matrix->left_margin_glyphs = left;
607 matrix->right_margin_glyphs = right;
610 /* Number of rows to be used by MATRIX. */
611 matrix->nrows = dim.height;
612 xassert (matrix->nrows >= 0);
614 if (w)
616 if (matrix == w->current_matrix)
618 /* Mark rows in a current matrix of a window as not having
619 valid contents. It's important to not do this for
620 desired matrices. When Emacs starts, it may already be
621 building desired matrices when this function runs. */
622 if (window_width < 0)
623 window_width = window_box_width (w, -1);
625 /* Optimize the case that only the height has changed (C-x 2,
626 upper window). Invalidate all rows that are no longer part
627 of the window. */
628 if (!marginal_areas_changed_p
629 && !header_line_changed_p
630 && new_rows == 0
631 && dim.width == matrix->matrix_w
632 && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
633 && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
634 && matrix->window_width == window_width)
636 /* Find the last row in the window. */
637 for (i = 0; i < matrix->nrows && matrix->rows[i].enabled_p; ++i)
638 if (MATRIX_ROW_BOTTOM_Y (matrix->rows + i) >= window_height)
640 ++i;
641 break;
644 /* Window end is invalid, if inside of the rows that
645 are invalidated below. */
646 if (INTEGERP (w->window_end_vpos)
647 && XFASTINT (w->window_end_vpos) >= i)
648 w->window_end_valid = Qnil;
650 while (i < matrix->nrows)
651 matrix->rows[i++].enabled_p = 0;
653 else
655 for (i = 0; i < matrix->nrows; ++i)
656 matrix->rows[i].enabled_p = 0;
659 else if (matrix == w->desired_matrix)
661 /* Rows in desired matrices always have to be cleared;
662 redisplay expects this is the case when it runs, so it
663 had better be the case when we adjust matrices between
664 redisplays. */
665 for (i = 0; i < matrix->nrows; ++i)
666 matrix->rows[i].enabled_p = 0;
671 /* Remember last values to be able to optimize frame redraws. */
672 matrix->matrix_x = x;
673 matrix->matrix_y = y;
674 matrix->matrix_w = dim.width;
675 matrix->matrix_h = dim.height;
677 /* Record the top y location and height of W at the time the matrix
678 was last adjusted. This is used to optimize redisplay above. */
679 if (w)
681 matrix->window_left_col = WINDOW_LEFT_EDGE_COL (w);
682 matrix->window_top_line = WINDOW_TOP_EDGE_LINE (w);
683 matrix->window_height = window_height;
684 matrix->window_width = window_width;
685 matrix->window_vscroll = w->vscroll;
690 /* Reverse the contents of rows in MATRIX between START and END. The
691 contents of the row at END - 1 end up at START, END - 2 at START +
692 1 etc. This is part of the implementation of rotate_matrix (see
693 below). */
695 static void
696 reverse_rows (struct glyph_matrix *matrix, int start, int end)
698 int i, j;
700 for (i = start, j = end - 1; i < j; ++i, --j)
702 /* Non-ISO HP/UX compiler doesn't like auto struct
703 initialization. */
704 struct glyph_row temp;
705 temp = matrix->rows[i];
706 matrix->rows[i] = matrix->rows[j];
707 matrix->rows[j] = temp;
712 /* Rotate the contents of rows in MATRIX in the range FIRST .. LAST -
713 1 by BY positions. BY < 0 means rotate left, i.e. towards lower
714 indices. (Note: this does not copy glyphs, only glyph pointers in
715 row structures are moved around).
717 The algorithm used for rotating the vector was, I believe, first
718 described by Kernighan. See the vector R as consisting of two
719 sub-vectors AB, where A has length BY for BY >= 0. The result
720 after rotating is then BA. Reverse both sub-vectors to get ArBr
721 and reverse the result to get (ArBr)r which is BA. Similar for
722 rotating right. */
724 void
725 rotate_matrix (struct glyph_matrix *matrix, int first, int last, int by)
727 if (by < 0)
729 /* Up (rotate left, i.e. towards lower indices). */
730 by = -by;
731 reverse_rows (matrix, first, first + by);
732 reverse_rows (matrix, first + by, last);
733 reverse_rows (matrix, first, last);
735 else if (by > 0)
737 /* Down (rotate right, i.e. towards higher indices). */
738 reverse_rows (matrix, last - by, last);
739 reverse_rows (matrix, first, last - by);
740 reverse_rows (matrix, first, last);
745 /* Increment buffer positions in glyph rows of MATRIX. Do it for rows
746 with indices START <= index < END. Increment positions by DELTA/
747 DELTA_BYTES. */
749 void
750 increment_matrix_positions (struct glyph_matrix *matrix, int start, int end,
751 EMACS_INT delta, EMACS_INT delta_bytes)
753 /* Check that START and END are reasonable values. */
754 xassert (start >= 0 && start <= matrix->nrows);
755 xassert (end >= 0 && end <= matrix->nrows);
756 xassert (start <= end);
758 for (; start < end; ++start)
759 increment_row_positions (matrix->rows + start, delta, delta_bytes);
763 /* Enable a range of rows in glyph matrix MATRIX. START and END are
764 the row indices of the first and last + 1 row to enable. If
765 ENABLED_P is non-zero, enabled_p flags in rows will be set to 1. */
767 void
768 enable_glyph_matrix_rows (struct glyph_matrix *matrix, int start, int end, int enabled_p)
770 xassert (start <= end);
771 xassert (start >= 0 && start < matrix->nrows);
772 xassert (end >= 0 && end <= matrix->nrows);
774 for (; start < end; ++start)
775 matrix->rows[start].enabled_p = enabled_p != 0;
779 /* Clear MATRIX.
781 This empties all rows in MATRIX by setting the enabled_p flag for
782 all rows of the matrix to zero. The function prepare_desired_row
783 will eventually really clear a row when it sees one with a zero
784 enabled_p flag.
786 Resets update hints to defaults value. The only update hint
787 currently present is the flag MATRIX->no_scrolling_p. */
789 void
790 clear_glyph_matrix (struct glyph_matrix *matrix)
792 if (matrix)
794 enable_glyph_matrix_rows (matrix, 0, matrix->nrows, 0);
795 matrix->no_scrolling_p = 0;
800 /* Shift part of the glyph matrix MATRIX of window W up or down.
801 Increment y-positions in glyph rows between START and END by DY,
802 and recompute their visible height. */
804 void
805 shift_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int start, int end, int dy)
807 int min_y, max_y;
809 xassert (start <= end);
810 xassert (start >= 0 && start < matrix->nrows);
811 xassert (end >= 0 && end <= matrix->nrows);
813 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
814 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
816 for (; start < end; ++start)
818 struct glyph_row *row = &matrix->rows[start];
820 row->y += dy;
821 row->visible_height = row->height;
823 if (row->y < min_y)
824 row->visible_height -= min_y - row->y;
825 if (row->y + row->height > max_y)
826 row->visible_height -= row->y + row->height - max_y;
827 if (row->fringe_bitmap_periodic_p)
828 row->redraw_fringe_bitmaps_p = 1;
833 /* Mark all rows in current matrices of frame F as invalid. Marking
834 invalid is done by setting enabled_p to zero for all rows in a
835 current matrix. */
837 void
838 clear_current_matrices (register struct frame *f)
840 /* Clear frame current matrix, if we have one. */
841 if (f->current_matrix)
842 clear_glyph_matrix (f->current_matrix);
844 /* Clear the matrix of the menu bar window, if such a window exists.
845 The menu bar window is currently used to display menus on X when
846 no toolkit support is compiled in. */
847 if (WINDOWP (f->menu_bar_window))
848 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
850 /* Clear the matrix of the tool-bar window, if any. */
851 if (WINDOWP (f->tool_bar_window))
852 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
854 /* Clear current window matrices. */
855 xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
856 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 0);
860 /* Clear out all display lines of F for a coming redisplay. */
862 void
863 clear_desired_matrices (register struct frame *f)
865 if (f->desired_matrix)
866 clear_glyph_matrix (f->desired_matrix);
868 if (WINDOWP (f->menu_bar_window))
869 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
871 if (WINDOWP (f->tool_bar_window))
872 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
874 /* Do it for window matrices. */
875 xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
876 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
880 /* Clear matrices in window tree rooted in W. If DESIRED_P is
881 non-zero clear desired matrices, otherwise clear current matrices. */
883 static void
884 clear_window_matrices (struct window *w, int desired_p)
886 while (w)
888 if (!NILP (w->hchild))
890 xassert (WINDOWP (w->hchild));
891 clear_window_matrices (XWINDOW (w->hchild), desired_p);
893 else if (!NILP (w->vchild))
895 xassert (WINDOWP (w->vchild));
896 clear_window_matrices (XWINDOW (w->vchild), desired_p);
898 else
900 if (desired_p)
901 clear_glyph_matrix (w->desired_matrix);
902 else
904 clear_glyph_matrix (w->current_matrix);
905 w->window_end_valid = Qnil;
909 w = NILP (w->next) ? 0 : XWINDOW (w->next);
915 /***********************************************************************
916 Glyph Rows
918 See dispextern.h for an overall explanation of glyph rows.
919 ***********************************************************************/
921 /* Clear glyph row ROW. Do it in a way that makes it robust against
922 changes in the glyph_row structure, i.e. addition or removal of
923 structure members. */
925 static struct glyph_row null_row;
927 void
928 clear_glyph_row (struct glyph_row *row)
930 struct glyph *p[1 + LAST_AREA];
932 /* Save pointers. */
933 p[LEFT_MARGIN_AREA] = row->glyphs[LEFT_MARGIN_AREA];
934 p[TEXT_AREA] = row->glyphs[TEXT_AREA];
935 p[RIGHT_MARGIN_AREA] = row->glyphs[RIGHT_MARGIN_AREA];
936 p[LAST_AREA] = row->glyphs[LAST_AREA];
938 /* Clear. */
939 *row = null_row;
941 /* Restore pointers. */
942 row->glyphs[LEFT_MARGIN_AREA] = p[LEFT_MARGIN_AREA];
943 row->glyphs[TEXT_AREA] = p[TEXT_AREA];
944 row->glyphs[RIGHT_MARGIN_AREA] = p[RIGHT_MARGIN_AREA];
945 row->glyphs[LAST_AREA] = p[LAST_AREA];
947 #if 0 /* At some point, some bit-fields of struct glyph were not set,
948 which made glyphs unequal when compared with GLYPH_EQUAL_P.
949 Redisplay outputs such glyphs, and flickering effects were
950 the result. This also depended on the contents of memory
951 returned by xmalloc. If flickering happens again, activate
952 the code below. If the flickering is gone with that, chances
953 are that the flickering has the same reason as here. */
954 memset (p[0], 0, (char *) p[LAST_AREA] - (char *) p[0]);
955 #endif
959 /* Make ROW an empty, enabled row of canonical character height,
960 in window W starting at y-position Y. */
962 void
963 blank_row (struct window *w, struct glyph_row *row, int y)
965 int min_y, max_y;
967 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
968 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
970 clear_glyph_row (row);
971 row->y = y;
972 row->ascent = row->phys_ascent = 0;
973 row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (w->frame));
974 row->visible_height = row->height;
976 if (row->y < min_y)
977 row->visible_height -= min_y - row->y;
978 if (row->y + row->height > max_y)
979 row->visible_height -= row->y + row->height - max_y;
981 row->enabled_p = 1;
985 /* Increment buffer positions in glyph row ROW. DELTA and DELTA_BYTES
986 are the amounts by which to change positions. Note that the first
987 glyph of the text area of a row can have a buffer position even if
988 the used count of the text area is zero. Such rows display line
989 ends. */
991 static void
992 increment_row_positions (struct glyph_row *row,
993 EMACS_INT delta, EMACS_INT delta_bytes)
995 int area, i;
997 /* Increment start and end positions. */
998 MATRIX_ROW_START_CHARPOS (row) += delta;
999 MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
1000 MATRIX_ROW_END_CHARPOS (row) += delta;
1001 MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
1002 CHARPOS (row->start.pos) += delta;
1003 BYTEPOS (row->start.pos) += delta_bytes;
1004 CHARPOS (row->end.pos) += delta;
1005 BYTEPOS (row->end.pos) += delta_bytes;
1007 if (!row->enabled_p)
1008 return;
1010 /* Increment positions in glyphs. */
1011 for (area = 0; area < LAST_AREA; ++area)
1012 for (i = 0; i < row->used[area]; ++i)
1013 if (BUFFERP (row->glyphs[area][i].object)
1014 && row->glyphs[area][i].charpos > 0)
1015 row->glyphs[area][i].charpos += delta;
1017 /* Capture the case of rows displaying a line end. */
1018 if (row->used[TEXT_AREA] == 0
1019 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
1020 row->glyphs[TEXT_AREA]->charpos += delta;
1024 #if 0
1025 /* Swap glyphs between two glyph rows A and B. This exchanges glyph
1026 contents, i.e. glyph structure contents are exchanged between A and
1027 B without changing glyph pointers in A and B. */
1029 static void
1030 swap_glyphs_in_rows (struct glyph_row *a, struct glyph_row *b)
1032 int area;
1034 for (area = 0; area < LAST_AREA; ++area)
1036 /* Number of glyphs to swap. */
1037 int max_used = max (a->used[area], b->used[area]);
1039 /* Start of glyphs in area of row A. */
1040 struct glyph *glyph_a = a->glyphs[area];
1042 /* End + 1 of glyphs in area of row A. */
1043 struct glyph *glyph_a_end = a->glyphs[max_used];
1045 /* Start of glyphs in area of row B. */
1046 struct glyph *glyph_b = b->glyphs[area];
1048 while (glyph_a < glyph_a_end)
1050 /* Non-ISO HP/UX compiler doesn't like auto struct
1051 initialization. */
1052 struct glyph temp;
1053 temp = *glyph_a;
1054 *glyph_a = *glyph_b;
1055 *glyph_b = temp;
1056 ++glyph_a;
1057 ++glyph_b;
1062 #endif /* 0 */
1064 /* Exchange pointers to glyph memory between glyph rows A and B. */
1066 static inline void
1067 swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
1069 int i;
1070 for (i = 0; i < LAST_AREA + 1; ++i)
1072 struct glyph *temp = a->glyphs[i];
1073 a->glyphs[i] = b->glyphs[i];
1074 b->glyphs[i] = temp;
1079 /* Copy glyph row structure FROM to glyph row structure TO, except
1080 that glyph pointers in the structures are left unchanged. */
1082 static inline void
1083 copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
1085 struct glyph *pointers[1 + LAST_AREA];
1087 /* Save glyph pointers of TO. */
1088 memcpy (pointers, to->glyphs, sizeof to->glyphs);
1090 /* Do a structure assignment. */
1091 *to = *from;
1093 /* Restore original pointers of TO. */
1094 memcpy (to->glyphs, pointers, sizeof to->glyphs);
1098 /* Assign glyph row FROM to glyph row TO. This works like a structure
1099 assignment TO = FROM, except that glyph pointers are not copied but
1100 exchanged between TO and FROM. Pointers must be exchanged to avoid
1101 a memory leak. */
1103 static inline void
1104 assign_row (struct glyph_row *to, struct glyph_row *from)
1106 swap_glyph_pointers (to, from);
1107 copy_row_except_pointers (to, from);
1111 /* Test whether the glyph memory of the glyph row WINDOW_ROW, which is
1112 a row in a window matrix, is a slice of the glyph memory of the
1113 glyph row FRAME_ROW which is a row in a frame glyph matrix. Value
1114 is non-zero if the glyph memory of WINDOW_ROW is part of the glyph
1115 memory of FRAME_ROW. */
1117 #if GLYPH_DEBUG
1119 static int
1120 glyph_row_slice_p (struct glyph_row *window_row, struct glyph_row *frame_row)
1122 struct glyph *window_glyph_start = window_row->glyphs[0];
1123 struct glyph *frame_glyph_start = frame_row->glyphs[0];
1124 struct glyph *frame_glyph_end = frame_row->glyphs[LAST_AREA];
1126 return (frame_glyph_start <= window_glyph_start
1127 && window_glyph_start < frame_glyph_end);
1130 #endif /* GLYPH_DEBUG */
1132 #if 0
1134 /* Find the row in the window glyph matrix WINDOW_MATRIX being a slice
1135 of ROW in the frame matrix FRAME_MATRIX. Value is null if no row
1136 in WINDOW_MATRIX is found satisfying the condition. */
1138 static struct glyph_row *
1139 find_glyph_row_slice (struct glyph_matrix *window_matrix,
1140 struct glyph_matrix *frame_matrix, int row)
1142 int i;
1144 xassert (row >= 0 && row < frame_matrix->nrows);
1146 for (i = 0; i < window_matrix->nrows; ++i)
1147 if (glyph_row_slice_p (window_matrix->rows + i,
1148 frame_matrix->rows + row))
1149 break;
1151 return i < window_matrix->nrows ? window_matrix->rows + i : 0;
1154 #endif /* 0 */
1156 /* Prepare ROW for display. Desired rows are cleared lazily,
1157 i.e. they are only marked as to be cleared by setting their
1158 enabled_p flag to zero. When a row is to be displayed, a prior
1159 call to this function really clears it. */
1161 void
1162 prepare_desired_row (struct glyph_row *row)
1164 if (!row->enabled_p)
1166 int rp = row->reversed_p;
1168 clear_glyph_row (row);
1169 row->enabled_p = 1;
1170 row->reversed_p = rp;
1175 /* Return a hash code for glyph row ROW. */
1177 static int
1178 line_hash_code (struct glyph_row *row)
1180 int hash = 0;
1182 if (row->enabled_p)
1184 struct glyph *glyph = row->glyphs[TEXT_AREA];
1185 struct glyph *end = glyph + row->used[TEXT_AREA];
1187 while (glyph < end)
1189 int c = glyph->u.ch;
1190 int face_id = glyph->face_id;
1191 if (FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
1192 c -= SPACEGLYPH;
1193 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
1194 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
1195 ++glyph;
1198 if (hash == 0)
1199 hash = 1;
1202 return hash;
1206 /* Return the cost of drawing line VPOS in MATRIX. The cost equals
1207 the number of characters in the line. If must_write_spaces is
1208 zero, leading and trailing spaces are ignored. */
1210 static int
1211 line_draw_cost (struct glyph_matrix *matrix, int vpos)
1213 struct glyph_row *row = matrix->rows + vpos;
1214 struct glyph *beg = row->glyphs[TEXT_AREA];
1215 struct glyph *end = beg + row->used[TEXT_AREA];
1216 int len;
1217 Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
1218 ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH;
1220 /* Ignore trailing and leading spaces if we can. */
1221 if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
1223 /* Skip from the end over trailing spaces. */
1224 while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1)))
1225 --end;
1227 /* All blank line. */
1228 if (end == beg)
1229 return 0;
1231 /* Skip over leading spaces. */
1232 while (CHAR_GLYPH_SPACE_P (*beg))
1233 ++beg;
1236 /* If we don't have a glyph-table, each glyph is one character,
1237 so return the number of glyphs. */
1238 if (glyph_table_base == 0)
1239 len = end - beg;
1240 else
1242 /* Otherwise, scan the glyphs and accumulate their total length
1243 in LEN. */
1244 len = 0;
1245 while (beg < end)
1247 GLYPH g;
1249 SET_GLYPH_FROM_CHAR_GLYPH (g, *beg);
1251 if (GLYPH_INVALID_P (g)
1252 || GLYPH_SIMPLE_P (glyph_table_base, glyph_table_len, g))
1253 len += 1;
1254 else
1255 len += GLYPH_LENGTH (glyph_table_base, g);
1257 ++beg;
1261 return len;
1265 /* Test two glyph rows A and B for equality. Value is non-zero if A
1266 and B have equal contents. MOUSE_FACE_P non-zero means compare the
1267 mouse_face_p flags of A and B, too. */
1269 static inline int
1270 row_equal_p (struct glyph_row *a, struct glyph_row *b, int mouse_face_p)
1272 if (a == b)
1273 return 1;
1274 else if (a->hash != b->hash)
1275 return 0;
1276 else
1278 struct glyph *a_glyph, *b_glyph, *a_end;
1279 int area;
1281 if (mouse_face_p && a->mouse_face_p != b->mouse_face_p)
1282 return 0;
1284 /* Compare glyphs. */
1285 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
1287 if (a->used[area] != b->used[area])
1288 return 0;
1290 a_glyph = a->glyphs[area];
1291 a_end = a_glyph + a->used[area];
1292 b_glyph = b->glyphs[area];
1294 while (a_glyph < a_end
1295 && GLYPH_EQUAL_P (a_glyph, b_glyph))
1296 ++a_glyph, ++b_glyph;
1298 if (a_glyph != a_end)
1299 return 0;
1302 if (a->fill_line_p != b->fill_line_p
1303 || a->cursor_in_fringe_p != b->cursor_in_fringe_p
1304 || a->left_fringe_bitmap != b->left_fringe_bitmap
1305 || a->left_fringe_face_id != b->left_fringe_face_id
1306 || a->left_fringe_offset != b->left_fringe_offset
1307 || a->right_fringe_bitmap != b->right_fringe_bitmap
1308 || a->right_fringe_face_id != b->right_fringe_face_id
1309 || a->right_fringe_offset != b->right_fringe_offset
1310 || a->fringe_bitmap_periodic_p != b->fringe_bitmap_periodic_p
1311 || a->overlay_arrow_bitmap != b->overlay_arrow_bitmap
1312 || a->exact_window_width_line_p != b->exact_window_width_line_p
1313 || a->overlapped_p != b->overlapped_p
1314 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
1315 != MATRIX_ROW_CONTINUATION_LINE_P (b))
1316 || a->reversed_p != b->reversed_p
1317 /* Different partially visible characters on left margin. */
1318 || a->x != b->x
1319 /* Different height. */
1320 || a->ascent != b->ascent
1321 || a->phys_ascent != b->phys_ascent
1322 || a->phys_height != b->phys_height
1323 || a->visible_height != b->visible_height)
1324 return 0;
1327 return 1;
1332 /***********************************************************************
1333 Glyph Pool
1335 See dispextern.h for an overall explanation of glyph pools.
1336 ***********************************************************************/
1338 /* Allocate a glyph_pool structure. The structure returned is
1339 initialized with zeros. The global variable glyph_pool_count is
1340 incremented for each pool allocated. */
1342 static struct glyph_pool *
1343 new_glyph_pool (void)
1345 struct glyph_pool *result;
1347 /* Allocate a new glyph_pool and clear it. */
1348 result = (struct glyph_pool *) xmalloc (sizeof *result);
1349 memset (result, 0, sizeof *result);
1351 /* For memory leak and double deletion checking. */
1352 ++glyph_pool_count;
1354 return result;
1358 /* Free a glyph_pool structure POOL. The function may be called with
1359 a null POOL pointer. The global variable glyph_pool_count is
1360 decremented with every pool structure freed. If this count gets
1361 negative, more structures were freed than allocated, i.e. one
1362 structure must have been freed more than once or a bogus pointer
1363 was passed to free_glyph_pool. */
1365 static void
1366 free_glyph_pool (struct glyph_pool *pool)
1368 if (pool)
1370 /* More freed than allocated? */
1371 --glyph_pool_count;
1372 xassert (glyph_pool_count >= 0);
1374 xfree (pool->glyphs);
1375 xfree (pool);
1380 /* Enlarge a glyph pool POOL. MATRIX_DIM gives the number of rows and
1381 columns we need. This function never shrinks a pool. The only
1382 case in which this would make sense, would be when a frame's size
1383 is changed from a large value to a smaller one. But, if someone
1384 does it once, we can expect that he will do it again.
1386 Value is non-zero if the pool changed in a way which makes
1387 re-adjusting window glyph matrices necessary. */
1389 static int
1390 realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
1392 ptrdiff_t needed;
1393 int changed_p;
1395 changed_p = (pool->glyphs == 0
1396 || matrix_dim.height != pool->nrows
1397 || matrix_dim.width != pool->ncolumns);
1399 /* Enlarge the glyph pool. */
1400 needed = matrix_dim.width;
1401 if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height))
1402 memory_full (SIZE_MAX);
1403 needed *= matrix_dim.height;
1404 if (needed > pool->nglyphs)
1406 ptrdiff_t old_nglyphs = pool->nglyphs;
1407 pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs,
1408 needed - old_nglyphs, -1, sizeof *pool->glyphs);
1409 memset (pool->glyphs + old_nglyphs, 0,
1410 (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
1413 /* Remember the number of rows and columns because (a) we use them
1414 to do sanity checks, and (b) the number of columns determines
1415 where rows in the frame matrix start---this must be available to
1416 determine pointers to rows of window sub-matrices. */
1417 pool->nrows = matrix_dim.height;
1418 pool->ncolumns = matrix_dim.width;
1420 return changed_p;
1425 /***********************************************************************
1426 Debug Code
1427 ***********************************************************************/
1429 #if GLYPH_DEBUG
1432 /* Flush standard output. This is sometimes useful to call from the debugger.
1433 XXX Maybe this should be changed to flush the current terminal instead of
1434 stdout.
1437 void flush_stdout (void) EXTERNALLY_VISIBLE;
1439 void
1440 flush_stdout (void)
1442 fflush (stdout);
1446 /* Check that no glyph pointers have been lost in MATRIX. If a
1447 pointer has been lost, e.g. by using a structure assignment between
1448 rows, at least one pointer must occur more than once in the rows of
1449 MATRIX. */
1451 void
1452 check_matrix_pointer_lossage (struct glyph_matrix *matrix)
1454 int i, j;
1456 for (i = 0; i < matrix->nrows; ++i)
1457 for (j = 0; j < matrix->nrows; ++j)
1458 xassert (i == j
1459 || (matrix->rows[i].glyphs[TEXT_AREA]
1460 != matrix->rows[j].glyphs[TEXT_AREA]));
1464 /* Get a pointer to glyph row ROW in MATRIX, with bounds checks. */
1466 struct glyph_row *
1467 matrix_row (struct glyph_matrix *matrix, int row)
1469 xassert (matrix && matrix->rows);
1470 xassert (row >= 0 && row < matrix->nrows);
1472 /* That's really too slow for normal testing because this function
1473 is called almost everywhere. Although---it's still astonishingly
1474 fast, so it is valuable to have for debugging purposes. */
1475 #if 0
1476 check_matrix_pointer_lossage (matrix);
1477 #endif
1479 return matrix->rows + row;
1483 #if 0 /* This function makes invalid assumptions when text is
1484 partially invisible. But it might come handy for debugging
1485 nevertheless. */
1487 /* Check invariants that must hold for an up to date current matrix of
1488 window W. */
1490 static void
1491 check_matrix_invariants (struct window *w)
1493 struct glyph_matrix *matrix = w->current_matrix;
1494 int yb = window_text_bottom_y (w);
1495 struct glyph_row *row = matrix->rows;
1496 struct glyph_row *last_text_row = NULL;
1497 struct buffer *saved = current_buffer;
1498 struct buffer *buffer = XBUFFER (w->buffer);
1499 int c;
1501 /* This can sometimes happen for a fresh window. */
1502 if (matrix->nrows < 2)
1503 return;
1505 set_buffer_temp (buffer);
1507 /* Note: last row is always reserved for the mode line. */
1508 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
1509 && MATRIX_ROW_BOTTOM_Y (row) < yb)
1511 struct glyph_row *next = row + 1;
1513 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
1514 last_text_row = row;
1516 /* Check that character and byte positions are in sync. */
1517 xassert (MATRIX_ROW_START_BYTEPOS (row)
1518 == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
1519 xassert (BYTEPOS (row->start.pos)
1520 == CHAR_TO_BYTE (CHARPOS (row->start.pos)));
1522 /* CHAR_TO_BYTE aborts when invoked for a position > Z. We can
1523 have such a position temporarily in case of a minibuffer
1524 displaying something like `[Sole completion]' at its end. */
1525 if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
1527 xassert (MATRIX_ROW_END_BYTEPOS (row)
1528 == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
1529 xassert (BYTEPOS (row->end.pos)
1530 == CHAR_TO_BYTE (CHARPOS (row->end.pos)));
1533 /* Check that end position of `row' is equal to start position
1534 of next row. */
1535 if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next))
1537 xassert (MATRIX_ROW_END_CHARPOS (row)
1538 == MATRIX_ROW_START_CHARPOS (next));
1539 xassert (MATRIX_ROW_END_BYTEPOS (row)
1540 == MATRIX_ROW_START_BYTEPOS (next));
1541 xassert (CHARPOS (row->end.pos) == CHARPOS (next->start.pos));
1542 xassert (BYTEPOS (row->end.pos) == BYTEPOS (next->start.pos));
1544 row = next;
1547 xassert (w->current_matrix->nrows == w->desired_matrix->nrows);
1548 xassert (w->desired_matrix->rows != NULL);
1549 set_buffer_temp (saved);
1552 #endif /* 0 */
1554 #endif /* GLYPH_DEBUG != 0 */
1558 /**********************************************************************
1559 Allocating/ Adjusting Glyph Matrices
1560 **********************************************************************/
1562 /* Allocate glyph matrices over a window tree for a frame-based
1563 redisplay
1565 X and Y are column/row within the frame glyph matrix where
1566 sub-matrices for the window tree rooted at WINDOW must be
1567 allocated. DIM_ONLY_P non-zero means that the caller of this
1568 function is only interested in the result matrix dimension, and
1569 matrix adjustments should not be performed.
1571 The function returns the total width/height of the sub-matrices of
1572 the window tree. If called on a frame root window, the computation
1573 will take the mini-buffer window into account.
1575 *WINDOW_CHANGE_FLAGS is set to a bit mask with bits
1577 NEW_LEAF_MATRIX set if any window in the tree did not have a
1578 glyph matrices yet, and
1580 CHANGED_LEAF_MATRIX set if the dimension or location of a matrix of
1581 any window in the tree will be changed or have been changed (see
1582 DIM_ONLY_P)
1584 *WINDOW_CHANGE_FLAGS must be initialized by the caller of this
1585 function.
1587 Windows are arranged into chains of windows on the same level
1588 through the next fields of window structures. Such a level can be
1589 either a sequence of horizontally adjacent windows from left to
1590 right, or a sequence of vertically adjacent windows from top to
1591 bottom. Each window in a horizontal sequence can be either a leaf
1592 window or a vertical sequence; a window in a vertical sequence can
1593 be either a leaf or a horizontal sequence. All windows in a
1594 horizontal sequence have the same height, and all windows in a
1595 vertical sequence have the same width.
1597 This function uses, for historical reasons, a more general
1598 algorithm to determine glyph matrix dimensions that would be
1599 necessary.
1601 The matrix height of a horizontal sequence is determined by the
1602 maximum height of any matrix in the sequence. The matrix width of
1603 a horizontal sequence is computed by adding up matrix widths of
1604 windows in the sequence.
1606 |<------- result width ------->|
1607 +---------+----------+---------+ ---
1608 | | | | |
1609 | | | |
1610 +---------+ | | result height
1611 | +---------+
1612 | | |
1613 +----------+ ---
1615 The matrix width of a vertical sequence is the maximum matrix width
1616 of any window in the sequence. Its height is computed by adding up
1617 matrix heights of windows in the sequence.
1619 |<---- result width -->|
1620 +---------+ ---
1621 | | |
1622 | | |
1623 +---------+--+ |
1624 | | |
1625 | | result height
1627 +------------+---------+ |
1628 | | |
1629 | | |
1630 +------------+---------+ --- */
1632 /* Bit indicating that a new matrix will be allocated or has been
1633 allocated. */
1635 #define NEW_LEAF_MATRIX (1 << 0)
1637 /* Bit indicating that a matrix will or has changed its location or
1638 size. */
1640 #define CHANGED_LEAF_MATRIX (1 << 1)
1642 static struct dim
1643 allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
1644 int dim_only_p, int *window_change_flags)
1646 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1647 int x0 = x, y0 = y;
1648 int wmax = 0, hmax = 0;
1649 struct dim total;
1650 struct dim dim;
1651 struct window *w;
1652 int in_horz_combination_p;
1654 /* What combination is WINDOW part of? Compute this once since the
1655 result is the same for all windows in the `next' chain. The
1656 special case of a root window (parent equal to nil) is treated
1657 like a vertical combination because a root window's `next'
1658 points to the mini-buffer window, if any, which is arranged
1659 vertically below other windows. */
1660 in_horz_combination_p
1661 = (!NILP (XWINDOW (window)->parent)
1662 && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
1664 /* For WINDOW and all windows on the same level. */
1667 w = XWINDOW (window);
1669 /* Get the dimension of the window sub-matrix for W, depending
1670 on whether this is a combination or a leaf window. */
1671 if (!NILP (w->hchild))
1672 dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y,
1673 dim_only_p,
1674 window_change_flags);
1675 else if (!NILP (w->vchild))
1676 dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y,
1677 dim_only_p,
1678 window_change_flags);
1679 else
1681 /* If not already done, allocate sub-matrix structures. */
1682 if (w->desired_matrix == NULL)
1684 w->desired_matrix = new_glyph_matrix (f->desired_pool);
1685 w->current_matrix = new_glyph_matrix (f->current_pool);
1686 *window_change_flags |= NEW_LEAF_MATRIX;
1689 /* Width and height MUST be chosen so that there are no
1690 holes in the frame matrix. */
1691 dim.width = required_matrix_width (w);
1692 dim.height = required_matrix_height (w);
1694 /* Will matrix be re-allocated? */
1695 if (x != w->desired_matrix->matrix_x
1696 || y != w->desired_matrix->matrix_y
1697 || dim.width != w->desired_matrix->matrix_w
1698 || dim.height != w->desired_matrix->matrix_h
1699 || (margin_glyphs_to_reserve (w, dim.width,
1700 w->left_margin_cols)
1701 != w->desired_matrix->left_margin_glyphs)
1702 || (margin_glyphs_to_reserve (w, dim.width,
1703 w->right_margin_cols)
1704 != w->desired_matrix->right_margin_glyphs))
1705 *window_change_flags |= CHANGED_LEAF_MATRIX;
1707 /* Actually change matrices, if allowed. Do not consider
1708 CHANGED_LEAF_MATRIX computed above here because the pool
1709 may have been changed which we don't now here. We trust
1710 that we only will be called with DIM_ONLY_P != 0 when
1711 necessary. */
1712 if (!dim_only_p)
1714 adjust_glyph_matrix (w, w->desired_matrix, x, y, dim);
1715 adjust_glyph_matrix (w, w->current_matrix, x, y, dim);
1719 /* If we are part of a horizontal combination, advance x for
1720 windows to the right of W; otherwise advance y for windows
1721 below W. */
1722 if (in_horz_combination_p)
1723 x += dim.width;
1724 else
1725 y += dim.height;
1727 /* Remember maximum glyph matrix dimensions. */
1728 wmax = max (wmax, dim.width);
1729 hmax = max (hmax, dim.height);
1731 /* Next window on same level. */
1732 window = w->next;
1734 while (!NILP (window));
1736 /* Set `total' to the total glyph matrix dimension of this window
1737 level. In a vertical combination, the width is the width of the
1738 widest window; the height is the y we finally reached, corrected
1739 by the y we started with. In a horizontal combination, the total
1740 height is the height of the tallest window, and the width is the
1741 x we finally reached, corrected by the x we started with. */
1742 if (in_horz_combination_p)
1744 total.width = x - x0;
1745 total.height = hmax;
1747 else
1749 total.width = wmax;
1750 total.height = y - y0;
1753 return total;
1757 /* Return the required height of glyph matrices for window W. */
1759 static int
1760 required_matrix_height (struct window *w)
1762 #ifdef HAVE_WINDOW_SYSTEM
1763 struct frame *f = XFRAME (w->frame);
1765 if (FRAME_WINDOW_P (f))
1767 int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f);
1768 int window_pixel_height = window_box_height (w) + eabs (w->vscroll);
1769 return (((window_pixel_height + ch_height - 1)
1770 / ch_height) * w->nrows_scale_factor
1771 /* One partially visible line at the top and
1772 bottom of the window. */
1774 /* 2 for header and mode line. */
1775 + 2);
1777 #endif /* HAVE_WINDOW_SYSTEM */
1779 return WINDOW_TOTAL_LINES (w);
1783 /* Return the required width of glyph matrices for window W. */
1785 static int
1786 required_matrix_width (struct window *w)
1788 #ifdef HAVE_WINDOW_SYSTEM
1789 struct frame *f = XFRAME (w->frame);
1790 if (FRAME_WINDOW_P (f))
1792 int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
1793 int window_pixel_width = WINDOW_TOTAL_WIDTH (w);
1795 /* Compute number of glyphs needed in a glyph row. */
1796 return (((window_pixel_width + ch_width - 1)
1797 / ch_width) * w->ncols_scale_factor
1798 /* 2 partially visible columns in the text area. */
1800 /* One partially visible column at the right
1801 edge of each marginal area. */
1802 + 1 + 1);
1804 #endif /* HAVE_WINDOW_SYSTEM */
1806 return XINT (w->total_cols);
1810 /* Allocate window matrices for window-based redisplay. W is the
1811 window whose matrices must be allocated/reallocated. */
1813 static void
1814 allocate_matrices_for_window_redisplay (struct window *w)
1816 while (w)
1818 if (!NILP (w->vchild))
1819 allocate_matrices_for_window_redisplay (XWINDOW (w->vchild));
1820 else if (!NILP (w->hchild))
1821 allocate_matrices_for_window_redisplay (XWINDOW (w->hchild));
1822 else
1824 /* W is a leaf window. */
1825 struct dim dim;
1827 /* If matrices are not yet allocated, allocate them now. */
1828 if (w->desired_matrix == NULL)
1830 w->desired_matrix = new_glyph_matrix (NULL);
1831 w->current_matrix = new_glyph_matrix (NULL);
1834 dim.width = required_matrix_width (w);
1835 dim.height = required_matrix_height (w);
1836 adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
1837 adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
1840 w = NILP (w->next) ? NULL : XWINDOW (w->next);
1845 /* Re-allocate/ re-compute glyph matrices on frame F. If F is null,
1846 do it for all frames; otherwise do it just for the given frame.
1847 This function must be called when a new frame is created, its size
1848 changes, or its window configuration changes. */
1850 void
1851 adjust_glyphs (struct frame *f)
1853 /* Block input so that expose events and other events that access
1854 glyph matrices are not processed while we are changing them. */
1855 BLOCK_INPUT;
1857 if (f)
1858 adjust_frame_glyphs (f);
1859 else
1861 Lisp_Object tail, lisp_frame;
1863 FOR_EACH_FRAME (tail, lisp_frame)
1864 adjust_frame_glyphs (XFRAME (lisp_frame));
1867 UNBLOCK_INPUT;
1871 /* Adjust frame glyphs when Emacs is initialized.
1873 To be called from init_display.
1875 We need a glyph matrix because redraw will happen soon.
1876 Unfortunately, window sizes on selected_frame are not yet set to
1877 meaningful values. I believe we can assume that there are only two
1878 windows on the frame---the mini-buffer and the root window. Frame
1879 height and width seem to be correct so far. So, set the sizes of
1880 windows to estimated values. */
1882 static void
1883 adjust_frame_glyphs_initially (void)
1885 struct frame *sf = SELECTED_FRAME ();
1886 struct window *root = XWINDOW (sf->root_window);
1887 struct window *mini = XWINDOW (root->next);
1888 int frame_lines = FRAME_LINES (sf);
1889 int frame_cols = FRAME_COLS (sf);
1890 int top_margin = FRAME_TOP_MARGIN (sf);
1892 /* Do it for the root window. */
1893 XSETFASTINT (root->top_line, top_margin);
1894 XSETFASTINT (root->total_lines, frame_lines - 1 - top_margin);
1895 XSETFASTINT (root->total_cols, frame_cols);
1897 /* Do it for the mini-buffer window. */
1898 XSETFASTINT (mini->top_line, frame_lines - 1);
1899 XSETFASTINT (mini->total_lines, 1);
1900 XSETFASTINT (mini->total_cols, frame_cols);
1902 adjust_frame_glyphs (sf);
1903 glyphs_initialized_initially_p = 1;
1907 /* Allocate/reallocate glyph matrices of a single frame F. */
1909 static void
1910 adjust_frame_glyphs (struct frame *f)
1912 if (FRAME_WINDOW_P (f))
1913 adjust_frame_glyphs_for_window_redisplay (f);
1914 else
1915 adjust_frame_glyphs_for_frame_redisplay (f);
1917 /* Don't forget the message buffer and the buffer for
1918 decode_mode_spec. */
1919 adjust_frame_message_buffer (f);
1920 adjust_decode_mode_spec_buffer (f);
1922 f->glyphs_initialized_p = 1;
1925 /* Return 1 if any window in the tree has nonzero window margins. See
1926 the hack at the end of adjust_frame_glyphs_for_frame_redisplay. */
1927 static int
1928 showing_window_margins_p (struct window *w)
1930 while (w)
1932 if (!NILP (w->hchild))
1934 if (showing_window_margins_p (XWINDOW (w->hchild)))
1935 return 1;
1937 else if (!NILP (w->vchild))
1939 if (showing_window_margins_p (XWINDOW (w->vchild)))
1940 return 1;
1942 else if (!NILP (w->left_margin_cols)
1943 || !NILP (w->right_margin_cols))
1944 return 1;
1946 w = NILP (w->next) ? 0 : XWINDOW (w->next);
1948 return 0;
1952 /* In the window tree with root W, build current matrices of leaf
1953 windows from the frame's current matrix. */
1955 static void
1956 fake_current_matrices (Lisp_Object window)
1958 struct window *w;
1960 for (; !NILP (window); window = w->next)
1962 w = XWINDOW (window);
1964 if (!NILP (w->hchild))
1965 fake_current_matrices (w->hchild);
1966 else if (!NILP (w->vchild))
1967 fake_current_matrices (w->vchild);
1968 else
1970 int i;
1971 struct frame *f = XFRAME (w->frame);
1972 struct glyph_matrix *m = w->current_matrix;
1973 struct glyph_matrix *fm = f->current_matrix;
1975 xassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
1976 xassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
1978 for (i = 0; i < m->matrix_h; ++i)
1980 struct glyph_row *r = m->rows + i;
1981 struct glyph_row *fr = fm->rows + i + WINDOW_TOP_EDGE_LINE (w);
1983 xassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
1984 && r->glyphs[LAST_AREA] <= fr->glyphs[LAST_AREA]);
1986 r->enabled_p = fr->enabled_p;
1987 if (r->enabled_p)
1989 r->used[LEFT_MARGIN_AREA] = m->left_margin_glyphs;
1990 r->used[RIGHT_MARGIN_AREA] = m->right_margin_glyphs;
1991 r->used[TEXT_AREA] = (m->matrix_w
1992 - r->used[LEFT_MARGIN_AREA]
1993 - r->used[RIGHT_MARGIN_AREA]);
1994 r->mode_line_p = 0;
2002 /* Save away the contents of frame F's current frame matrix. Value is
2003 a glyph matrix holding the contents of F's current frame matrix. */
2005 static struct glyph_matrix *
2006 save_current_matrix (struct frame *f)
2008 int i;
2009 struct glyph_matrix *saved;
2011 saved = (struct glyph_matrix *) xmalloc (sizeof *saved);
2012 memset (saved, 0, sizeof *saved);
2013 saved->nrows = f->current_matrix->nrows;
2014 saved->rows = (struct glyph_row *) xmalloc (saved->nrows
2015 * sizeof *saved->rows);
2016 memset (saved->rows, 0, saved->nrows * sizeof *saved->rows);
2018 for (i = 0; i < saved->nrows; ++i)
2020 struct glyph_row *from = f->current_matrix->rows + i;
2021 struct glyph_row *to = saved->rows + i;
2022 ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
2023 to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes);
2024 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
2025 to->used[TEXT_AREA] = from->used[TEXT_AREA];
2028 return saved;
2032 /* Restore the contents of frame F's current frame matrix from SAVED,
2033 and free memory associated with SAVED. */
2035 static void
2036 restore_current_matrix (struct frame *f, struct glyph_matrix *saved)
2038 int i;
2040 for (i = 0; i < saved->nrows; ++i)
2042 struct glyph_row *from = saved->rows + i;
2043 struct glyph_row *to = f->current_matrix->rows + i;
2044 ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
2045 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
2046 to->used[TEXT_AREA] = from->used[TEXT_AREA];
2047 xfree (from->glyphs[TEXT_AREA]);
2050 xfree (saved->rows);
2051 xfree (saved);
2056 /* Allocate/reallocate glyph matrices of a single frame F for
2057 frame-based redisplay. */
2059 static void
2060 adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
2062 struct dim matrix_dim;
2063 int pool_changed_p;
2064 int window_change_flags;
2065 int top_window_y;
2067 if (!FRAME_LIVE_P (f))
2068 return;
2070 top_window_y = FRAME_TOP_MARGIN (f);
2072 /* Allocate glyph pool structures if not already done. */
2073 if (f->desired_pool == NULL)
2075 f->desired_pool = new_glyph_pool ();
2076 f->current_pool = new_glyph_pool ();
2079 /* Allocate frames matrix structures if needed. */
2080 if (f->desired_matrix == NULL)
2082 f->desired_matrix = new_glyph_matrix (f->desired_pool);
2083 f->current_matrix = new_glyph_matrix (f->current_pool);
2086 /* Compute window glyph matrices. (This takes the mini-buffer
2087 window into account). The result is the size of the frame glyph
2088 matrix needed. The variable window_change_flags is set to a bit
2089 mask indicating whether new matrices will be allocated or
2090 existing matrices change their size or location within the frame
2091 matrix. */
2092 window_change_flags = 0;
2093 matrix_dim
2094 = allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2095 0, top_window_y,
2097 &window_change_flags);
2099 /* Add in menu bar lines, if any. */
2100 matrix_dim.height += top_window_y;
2102 /* Enlarge pools as necessary. */
2103 pool_changed_p = realloc_glyph_pool (f->desired_pool, matrix_dim);
2104 realloc_glyph_pool (f->current_pool, matrix_dim);
2106 /* Set up glyph pointers within window matrices. Do this only if
2107 absolutely necessary since it requires a frame redraw. */
2108 if (pool_changed_p || window_change_flags)
2110 /* Do it for window matrices. */
2111 allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2112 0, top_window_y, 0,
2113 &window_change_flags);
2115 /* Size of frame matrices must equal size of frame. Note
2116 that we are called for X frames with window widths NOT equal
2117 to the frame width (from CHANGE_FRAME_SIZE_1). */
2118 xassert (matrix_dim.width == FRAME_COLS (f)
2119 && matrix_dim.height == FRAME_LINES (f));
2121 /* Pointers to glyph memory in glyph rows are exchanged during
2122 the update phase of redisplay, which means in general that a
2123 frame's current matrix consists of pointers into both the
2124 desired and current glyph pool of the frame. Adjusting a
2125 matrix sets the frame matrix up so that pointers are all into
2126 the same pool. If we want to preserve glyph contents of the
2127 current matrix over a call to adjust_glyph_matrix, we must
2128 make a copy of the current glyphs, and restore the current
2129 matrix' contents from that copy. */
2130 if (display_completed
2131 && !FRAME_GARBAGED_P (f)
2132 && matrix_dim.width == f->current_matrix->matrix_w
2133 && matrix_dim.height == f->current_matrix->matrix_h
2134 /* For some reason, the frame glyph matrix gets corrupted if
2135 any of the windows contain margins. I haven't been able
2136 to hunt down the reason, but for the moment this prevents
2137 the problem from manifesting. -- cyd */
2138 && !showing_window_margins_p (XWINDOW (FRAME_ROOT_WINDOW (f))))
2140 struct glyph_matrix *copy = save_current_matrix (f);
2141 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2142 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2143 restore_current_matrix (f, copy);
2144 fake_current_matrices (FRAME_ROOT_WINDOW (f));
2146 else
2148 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2149 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2150 SET_FRAME_GARBAGED (f);
2156 /* Allocate/reallocate glyph matrices of a single frame F for
2157 window-based redisplay. */
2159 static void
2160 adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2162 xassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
2164 /* Allocate/reallocate window matrices. */
2165 allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
2167 #ifdef HAVE_X_WINDOWS
2168 /* Allocate/ reallocate matrices of the dummy window used to display
2169 the menu bar under X when no X toolkit support is available. */
2170 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
2172 /* Allocate a dummy window if not already done. */
2173 struct window *w;
2174 if (NILP (f->menu_bar_window))
2176 f->menu_bar_window = make_window ();
2177 w = XWINDOW (f->menu_bar_window);
2178 XSETFRAME (w->frame, f);
2179 w->pseudo_window_p = 1;
2181 else
2182 w = XWINDOW (f->menu_bar_window);
2184 /* Set window dimensions to frame dimensions and allocate or
2185 adjust glyph matrices of W. */
2186 XSETFASTINT (w->top_line, 0);
2187 XSETFASTINT (w->left_col, 0);
2188 XSETFASTINT (w->total_lines, FRAME_MENU_BAR_LINES (f));
2189 XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
2190 allocate_matrices_for_window_redisplay (w);
2192 #endif /* not USE_X_TOOLKIT && not USE_GTK */
2193 #endif /* HAVE_X_WINDOWS */
2195 #ifndef USE_GTK
2197 /* Allocate/ reallocate matrices of the tool bar window. If we
2198 don't have a tool bar window yet, make one. */
2199 struct window *w;
2200 if (NILP (f->tool_bar_window))
2202 f->tool_bar_window = make_window ();
2203 w = XWINDOW (f->tool_bar_window);
2204 XSETFRAME (w->frame, f);
2205 w->pseudo_window_p = 1;
2207 else
2208 w = XWINDOW (f->tool_bar_window);
2210 XSETFASTINT (w->top_line, FRAME_MENU_BAR_LINES (f));
2211 XSETFASTINT (w->left_col, 0);
2212 XSETFASTINT (w->total_lines, FRAME_TOOL_BAR_LINES (f));
2213 XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
2214 allocate_matrices_for_window_redisplay (w);
2216 #endif
2220 /* Adjust/ allocate message buffer of frame F.
2222 Note that the message buffer is never freed. Since I could not
2223 find a free in 19.34, I assume that freeing it would be
2224 problematic in some way and don't do it either.
2226 (Implementation note: It should be checked if we can free it
2227 eventually without causing trouble). */
2229 static void
2230 adjust_frame_message_buffer (struct frame *f)
2232 ptrdiff_t size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
2234 if (FRAME_MESSAGE_BUF (f))
2236 char *buffer = FRAME_MESSAGE_BUF (f);
2237 char *new_buffer = (char *) xrealloc (buffer, size);
2238 FRAME_MESSAGE_BUF (f) = new_buffer;
2240 else
2241 FRAME_MESSAGE_BUF (f) = (char *) xmalloc (size);
2245 /* Re-allocate buffer for decode_mode_spec on frame F. */
2247 static void
2248 adjust_decode_mode_spec_buffer (struct frame *f)
2250 f->decode_mode_spec_buffer
2251 = (char *) xrealloc (f->decode_mode_spec_buffer,
2252 FRAME_MESSAGE_BUF_SIZE (f) + 1);
2257 /**********************************************************************
2258 Freeing Glyph Matrices
2259 **********************************************************************/
2261 /* Free glyph memory for a frame F. F may be null. This function can
2262 be called for the same frame more than once. The root window of
2263 F may be nil when this function is called. This is the case when
2264 the function is called when F is destroyed. */
2266 void
2267 free_glyphs (struct frame *f)
2269 if (f && f->glyphs_initialized_p)
2271 /* Block interrupt input so that we don't get surprised by an X
2272 event while we're in an inconsistent state. */
2273 BLOCK_INPUT;
2274 f->glyphs_initialized_p = 0;
2276 /* Release window sub-matrices. */
2277 if (!NILP (f->root_window))
2278 free_window_matrices (XWINDOW (f->root_window));
2280 /* Free the dummy window for menu bars without X toolkit and its
2281 glyph matrices. */
2282 if (!NILP (f->menu_bar_window))
2284 struct window *w = XWINDOW (f->menu_bar_window);
2285 free_glyph_matrix (w->desired_matrix);
2286 free_glyph_matrix (w->current_matrix);
2287 w->desired_matrix = w->current_matrix = NULL;
2288 f->menu_bar_window = Qnil;
2291 /* Free the tool bar window and its glyph matrices. */
2292 if (!NILP (f->tool_bar_window))
2294 struct window *w = XWINDOW (f->tool_bar_window);
2295 free_glyph_matrix (w->desired_matrix);
2296 free_glyph_matrix (w->current_matrix);
2297 w->desired_matrix = w->current_matrix = NULL;
2298 f->tool_bar_window = Qnil;
2301 /* Release frame glyph matrices. Reset fields to zero in
2302 case we are called a second time. */
2303 if (f->desired_matrix)
2305 free_glyph_matrix (f->desired_matrix);
2306 free_glyph_matrix (f->current_matrix);
2307 f->desired_matrix = f->current_matrix = NULL;
2310 /* Release glyph pools. */
2311 if (f->desired_pool)
2313 free_glyph_pool (f->desired_pool);
2314 free_glyph_pool (f->current_pool);
2315 f->desired_pool = f->current_pool = NULL;
2318 UNBLOCK_INPUT;
2323 /* Free glyph sub-matrices in the window tree rooted at W. This
2324 function may be called with a null pointer, and it may be called on
2325 the same tree more than once. */
2327 void
2328 free_window_matrices (struct window *w)
2330 while (w)
2332 if (!NILP (w->hchild))
2333 free_window_matrices (XWINDOW (w->hchild));
2334 else if (!NILP (w->vchild))
2335 free_window_matrices (XWINDOW (w->vchild));
2336 else
2338 /* This is a leaf window. Free its memory and reset fields
2339 to zero in case this function is called a second time for
2340 W. */
2341 free_glyph_matrix (w->current_matrix);
2342 free_glyph_matrix (w->desired_matrix);
2343 w->current_matrix = w->desired_matrix = NULL;
2346 /* Next window on same level. */
2347 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2352 /* Check glyph memory leaks. This function is called from
2353 shut_down_emacs. Note that frames are not destroyed when Emacs
2354 exits. We therefore free all glyph memory for all active frames
2355 explicitly and check that nothing is left allocated. */
2357 void
2358 check_glyph_memory (void)
2360 Lisp_Object tail, frame;
2362 /* Free glyph memory for all frames. */
2363 FOR_EACH_FRAME (tail, frame)
2364 free_glyphs (XFRAME (frame));
2366 /* Check that nothing is left allocated. */
2367 if (glyph_matrix_count)
2368 abort ();
2369 if (glyph_pool_count)
2370 abort ();
2375 /**********************************************************************
2376 Building a Frame Matrix
2377 **********************************************************************/
2379 /* Most of the redisplay code works on glyph matrices attached to
2380 windows. This is a good solution most of the time, but it is not
2381 suitable for terminal code. Terminal output functions cannot rely
2382 on being able to set an arbitrary terminal window. Instead they
2383 must be provided with a view of the whole frame, i.e. the whole
2384 screen. We build such a view by constructing a frame matrix from
2385 window matrices in this section.
2387 Windows that must be updated have their must_be_update_p flag set.
2388 For all such windows, their desired matrix is made part of the
2389 desired frame matrix. For other windows, their current matrix is
2390 made part of the desired frame matrix.
2392 +-----------------+----------------+
2393 | desired | desired |
2394 | | |
2395 +-----------------+----------------+
2396 | current |
2398 +----------------------------------+
2400 Desired window matrices can be made part of the frame matrix in a
2401 cheap way: We exploit the fact that the desired frame matrix and
2402 desired window matrices share their glyph memory. This is not
2403 possible for current window matrices. Their glyphs are copied to
2404 the desired frame matrix. The latter is equivalent to
2405 preserve_other_columns in the old redisplay.
2407 Used glyphs counters for frame matrix rows are the result of adding
2408 up glyph lengths of the window matrices. A line in the frame
2409 matrix is enabled, if a corresponding line in a window matrix is
2410 enabled.
2412 After building the desired frame matrix, it will be passed to
2413 terminal code, which will manipulate both the desired and current
2414 frame matrix. Changes applied to the frame's current matrix have
2415 to be visible in current window matrices afterwards, of course.
2417 This problem is solved like this:
2419 1. Window and frame matrices share glyphs. Window matrices are
2420 constructed in a way that their glyph contents ARE the glyph
2421 contents needed in a frame matrix. Thus, any modification of
2422 glyphs done in terminal code will be reflected in window matrices
2423 automatically.
2425 2. Exchanges of rows in a frame matrix done by terminal code are
2426 intercepted by hook functions so that corresponding row operations
2427 on window matrices can be performed. This is necessary because we
2428 use pointers to glyphs in glyph row structures. To satisfy the
2429 assumption of point 1 above that glyphs are updated implicitly in
2430 window matrices when they are manipulated via the frame matrix,
2431 window and frame matrix must of course agree where to find the
2432 glyphs for their rows. Possible manipulations that must be
2433 mirrored are assignments of rows of the desired frame matrix to the
2434 current frame matrix and scrolling the current frame matrix. */
2436 /* Build frame F's desired matrix from window matrices. Only windows
2437 which have the flag must_be_updated_p set have to be updated. Menu
2438 bar lines of a frame are not covered by window matrices, so make
2439 sure not to touch them in this function. */
2441 static void
2442 build_frame_matrix (struct frame *f)
2444 int i;
2446 /* F must have a frame matrix when this function is called. */
2447 xassert (!FRAME_WINDOW_P (f));
2449 /* Clear all rows in the frame matrix covered by window matrices.
2450 Menu bar lines are not covered by windows. */
2451 for (i = FRAME_TOP_MARGIN (f); i < f->desired_matrix->nrows; ++i)
2452 clear_glyph_row (MATRIX_ROW (f->desired_matrix, i));
2454 /* Build the matrix by walking the window tree. */
2455 build_frame_matrix_from_window_tree (f->desired_matrix,
2456 XWINDOW (FRAME_ROOT_WINDOW (f)));
2460 /* Walk a window tree, building a frame matrix MATRIX from window
2461 matrices. W is the root of a window tree. */
2463 static void
2464 build_frame_matrix_from_window_tree (struct glyph_matrix *matrix, struct window *w)
2466 while (w)
2468 if (!NILP (w->hchild))
2469 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->hchild));
2470 else if (!NILP (w->vchild))
2471 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->vchild));
2472 else
2473 build_frame_matrix_from_leaf_window (matrix, w);
2475 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2480 /* Add a window's matrix to a frame matrix. FRAME_MATRIX is the
2481 desired frame matrix built. W is a leaf window whose desired or
2482 current matrix is to be added to FRAME_MATRIX. W's flag
2483 must_be_updated_p determines which matrix it contributes to
2484 FRAME_MATRIX. If must_be_updated_p is non-zero, W's desired matrix
2485 is added to FRAME_MATRIX, otherwise W's current matrix is added.
2486 Adding a desired matrix means setting up used counters and such in
2487 frame rows, while adding a current window matrix to FRAME_MATRIX
2488 means copying glyphs. The latter case corresponds to
2489 preserve_other_columns in the old redisplay. */
2491 static void
2492 build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct window *w)
2494 struct glyph_matrix *window_matrix;
2495 int window_y, frame_y;
2496 /* If non-zero, a glyph to insert at the right border of W. */
2497 GLYPH right_border_glyph;
2499 SET_GLYPH_FROM_CHAR (right_border_glyph, 0);
2501 /* Set window_matrix to the matrix we have to add to FRAME_MATRIX. */
2502 if (w->must_be_updated_p)
2504 window_matrix = w->desired_matrix;
2506 /* Decide whether we want to add a vertical border glyph. */
2507 if (!WINDOW_RIGHTMOST_P (w))
2509 struct Lisp_Char_Table *dp = window_display_table (w);
2510 Lisp_Object gc;
2512 SET_GLYPH_FROM_CHAR (right_border_glyph, '|');
2513 if (dp
2514 && (gc = DISP_BORDER_GLYPH (dp), GLYPH_CODE_P (gc))
2515 && GLYPH_CODE_CHAR_VALID_P (gc))
2517 SET_GLYPH_FROM_GLYPH_CODE (right_border_glyph, gc);
2518 spec_glyph_lookup_face (w, &right_border_glyph);
2521 if (GLYPH_FACE (right_border_glyph) <= 0)
2522 SET_GLYPH_FACE (right_border_glyph, VERTICAL_BORDER_FACE_ID);
2525 else
2526 window_matrix = w->current_matrix;
2528 /* For all rows in the window matrix and corresponding rows in the
2529 frame matrix. */
2530 window_y = 0;
2531 frame_y = window_matrix->matrix_y;
2532 while (window_y < window_matrix->nrows)
2534 struct glyph_row *frame_row = frame_matrix->rows + frame_y;
2535 struct glyph_row *window_row = window_matrix->rows + window_y;
2536 int current_row_p = window_matrix == w->current_matrix;
2538 /* Fill up the frame row with spaces up to the left margin of the
2539 window row. */
2540 fill_up_frame_row_with_spaces (frame_row, window_matrix->matrix_x);
2542 /* Fill up areas in the window matrix row with spaces. */
2543 fill_up_glyph_row_with_spaces (window_row);
2545 /* If only part of W's desired matrix has been built, and
2546 window_row wasn't displayed, use the corresponding current
2547 row instead. */
2548 if (window_matrix == w->desired_matrix
2549 && !window_row->enabled_p)
2551 window_row = w->current_matrix->rows + window_y;
2552 current_row_p = 1;
2555 if (current_row_p)
2557 /* Copy window row to frame row. */
2558 memcpy (frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
2559 window_row->glyphs[0],
2560 window_matrix->matrix_w * sizeof (struct glyph));
2562 else
2564 xassert (window_row->enabled_p);
2566 /* Only when a desired row has been displayed, we want
2567 the corresponding frame row to be updated. */
2568 frame_row->enabled_p = 1;
2570 /* Maybe insert a vertical border between horizontally adjacent
2571 windows. */
2572 if (GLYPH_CHAR (right_border_glyph) != 0)
2574 struct glyph *border = window_row->glyphs[LAST_AREA] - 1;
2575 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
2578 #if GLYPH_DEBUG
2579 /* Window row window_y must be a slice of frame row
2580 frame_y. */
2581 xassert (glyph_row_slice_p (window_row, frame_row));
2583 /* If rows are in sync, we don't have to copy glyphs because
2584 frame and window share glyphs. */
2586 strcpy (w->current_matrix->method, w->desired_matrix->method);
2587 add_window_display_history (w, w->current_matrix->method, 0);
2588 #endif
2591 /* Set number of used glyphs in the frame matrix. Since we fill
2592 up with spaces, and visit leaf windows from left to right it
2593 can be done simply. */
2594 frame_row->used[TEXT_AREA]
2595 = window_matrix->matrix_x + window_matrix->matrix_w;
2597 /* Next row. */
2598 ++window_y;
2599 ++frame_y;
2603 /* Given a user-specified glyph, possibly including a Lisp-level face
2604 ID, return a glyph that has a realized face ID.
2605 This is used for glyphs displayed specially and not part of the text;
2606 for instance, vertical separators, truncation markers, etc. */
2608 void
2609 spec_glyph_lookup_face (struct window *w, GLYPH *glyph)
2611 int lface_id = GLYPH_FACE (*glyph);
2612 /* Convert the glyph's specified face to a realized (cache) face. */
2613 if (lface_id > 0)
2615 int face_id = merge_faces (XFRAME (w->frame),
2616 Qt, lface_id, DEFAULT_FACE_ID);
2617 SET_GLYPH_FACE (*glyph, face_id);
2621 /* Add spaces to a glyph row ROW in a window matrix.
2623 Each row has the form:
2625 +---------+-----------------------------+------------+
2626 | left | text | right |
2627 +---------+-----------------------------+------------+
2629 Left and right marginal areas are optional. This function adds
2630 spaces to areas so that there are no empty holes between areas.
2631 In other words: If the right area is not empty, the text area
2632 is filled up with spaces up to the right area. If the text area
2633 is not empty, the left area is filled up.
2635 To be called for frame-based redisplay, only. */
2637 static void
2638 fill_up_glyph_row_with_spaces (struct glyph_row *row)
2640 fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA);
2641 fill_up_glyph_row_area_with_spaces (row, TEXT_AREA);
2642 fill_up_glyph_row_area_with_spaces (row, RIGHT_MARGIN_AREA);
2646 /* Fill area AREA of glyph row ROW with spaces. To be called for
2647 frame-based redisplay only. */
2649 static void
2650 fill_up_glyph_row_area_with_spaces (struct glyph_row *row, int area)
2652 if (row->glyphs[area] < row->glyphs[area + 1])
2654 struct glyph *end = row->glyphs[area + 1];
2655 struct glyph *text = row->glyphs[area] + row->used[area];
2657 while (text < end)
2658 *text++ = space_glyph;
2659 row->used[area] = text - row->glyphs[area];
2664 /* Add spaces to the end of ROW in a frame matrix until index UPTO is
2665 reached. In frame matrices only one area, TEXT_AREA, is used. */
2667 static void
2668 fill_up_frame_row_with_spaces (struct glyph_row *row, int upto)
2670 int i = row->used[TEXT_AREA];
2671 struct glyph *glyph = row->glyphs[TEXT_AREA];
2673 while (i < upto)
2674 glyph[i++] = space_glyph;
2676 row->used[TEXT_AREA] = i;
2681 /**********************************************************************
2682 Mirroring operations on frame matrices in window matrices
2683 **********************************************************************/
2685 /* Set frame being updated via frame-based redisplay to F. This
2686 function must be called before updates to make explicit that we are
2687 working on frame matrices or not. */
2689 static inline void
2690 set_frame_matrix_frame (struct frame *f)
2692 frame_matrix_frame = f;
2696 /* Make sure glyph row ROW in CURRENT_MATRIX is up to date.
2697 DESIRED_MATRIX is the desired matrix corresponding to
2698 CURRENT_MATRIX. The update is done by exchanging glyph pointers
2699 between rows in CURRENT_MATRIX and DESIRED_MATRIX. If
2700 frame_matrix_frame is non-null, this indicates that the exchange is
2701 done in frame matrices, and that we have to perform analogous
2702 operations in window matrices of frame_matrix_frame. */
2704 static inline void
2705 make_current (struct glyph_matrix *desired_matrix, struct glyph_matrix *current_matrix, int row)
2707 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2708 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
2709 int mouse_face_p = current_row->mouse_face_p;
2711 /* Do current_row = desired_row. This exchanges glyph pointers
2712 between both rows, and does a structure assignment otherwise. */
2713 assign_row (current_row, desired_row);
2715 /* Enable current_row to mark it as valid. */
2716 current_row->enabled_p = 1;
2717 current_row->mouse_face_p = mouse_face_p;
2719 /* If we are called on frame matrices, perform analogous operations
2720 for window matrices. */
2721 if (frame_matrix_frame)
2722 mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row);
2726 /* W is the root of a window tree. FRAME_ROW is the index of a row in
2727 W's frame which has been made current (by swapping pointers between
2728 current and desired matrix). Perform analogous operations in the
2729 matrices of leaf windows in the window tree rooted at W. */
2731 static void
2732 mirror_make_current (struct window *w, int frame_row)
2734 while (w)
2736 if (!NILP (w->hchild))
2737 mirror_make_current (XWINDOW (w->hchild), frame_row);
2738 else if (!NILP (w->vchild))
2739 mirror_make_current (XWINDOW (w->vchild), frame_row);
2740 else
2742 /* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS
2743 here because the checks performed in debug mode there
2744 will not allow the conversion. */
2745 int row = frame_row - w->desired_matrix->matrix_y;
2747 /* If FRAME_ROW is within W, assign the desired row to the
2748 current row (exchanging glyph pointers). */
2749 if (row >= 0 && row < w->desired_matrix->matrix_h)
2751 struct glyph_row *current_row
2752 = MATRIX_ROW (w->current_matrix, row);
2753 struct glyph_row *desired_row
2754 = MATRIX_ROW (w->desired_matrix, row);
2756 if (desired_row->enabled_p)
2757 assign_row (current_row, desired_row);
2758 else
2759 swap_glyph_pointers (desired_row, current_row);
2760 current_row->enabled_p = 1;
2762 /* Set the Y coordinate of the mode/header line's row.
2763 It is needed in draw_row_with_mouse_face to find the
2764 screen coordinates. (Window-based redisplay sets
2765 this in update_window, but no one seems to do that
2766 for frame-based redisplay.) */
2767 if (current_row->mode_line_p)
2768 current_row->y = row;
2772 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2777 /* Perform row dance after scrolling. We are working on the range of
2778 lines UNCHANGED_AT_TOP + 1 to UNCHANGED_AT_TOP + NLINES (not
2779 including) in MATRIX. COPY_FROM is a vector containing, for each
2780 row I in the range 0 <= I < NLINES, the index of the original line
2781 to move to I. This index is relative to the row range, i.e. 0 <=
2782 index < NLINES. RETAINED_P is a vector containing zero for each
2783 row 0 <= I < NLINES which is empty.
2785 This function is called from do_scrolling and do_direct_scrolling. */
2787 void
2788 mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlines,
2789 int *copy_from, char *retained_p)
2791 /* A copy of original rows. */
2792 struct glyph_row *old_rows;
2794 /* Rows to assign to. */
2795 struct glyph_row *new_rows = MATRIX_ROW (matrix, unchanged_at_top);
2797 int i;
2799 /* Make a copy of the original rows. */
2800 old_rows = (struct glyph_row *) alloca (nlines * sizeof *old_rows);
2801 memcpy (old_rows, new_rows, nlines * sizeof *old_rows);
2803 /* Assign new rows, maybe clear lines. */
2804 for (i = 0; i < nlines; ++i)
2806 int enabled_before_p = new_rows[i].enabled_p;
2808 xassert (i + unchanged_at_top < matrix->nrows);
2809 xassert (unchanged_at_top + copy_from[i] < matrix->nrows);
2810 new_rows[i] = old_rows[copy_from[i]];
2811 new_rows[i].enabled_p = enabled_before_p;
2813 /* RETAINED_P is zero for empty lines. */
2814 if (!retained_p[copy_from[i]])
2815 new_rows[i].enabled_p = 0;
2818 /* Do the same for window matrices, if MATRIX is a frame matrix. */
2819 if (frame_matrix_frame)
2820 mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
2821 unchanged_at_top, nlines, copy_from, retained_p);
2825 /* Synchronize glyph pointers in the current matrix of window W with
2826 the current frame matrix. */
2828 static void
2829 sync_window_with_frame_matrix_rows (struct window *w)
2831 struct frame *f = XFRAME (w->frame);
2832 struct glyph_row *window_row, *window_row_end, *frame_row;
2833 int left, right, x, width;
2835 /* Preconditions: W must be a leaf window on a tty frame. */
2836 xassert (NILP (w->hchild) && NILP (w->vchild));
2837 xassert (!FRAME_WINDOW_P (f));
2839 left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
2840 right = margin_glyphs_to_reserve (w, 1, w->right_margin_cols);
2841 x = w->current_matrix->matrix_x;
2842 width = w->current_matrix->matrix_w;
2844 window_row = w->current_matrix->rows;
2845 window_row_end = window_row + w->current_matrix->nrows;
2846 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
2848 for (; window_row < window_row_end; ++window_row, ++frame_row)
2850 window_row->glyphs[LEFT_MARGIN_AREA]
2851 = frame_row->glyphs[0] + x;
2852 window_row->glyphs[TEXT_AREA]
2853 = window_row->glyphs[LEFT_MARGIN_AREA] + left;
2854 window_row->glyphs[LAST_AREA]
2855 = window_row->glyphs[LEFT_MARGIN_AREA] + width;
2856 window_row->glyphs[RIGHT_MARGIN_AREA]
2857 = window_row->glyphs[LAST_AREA] - right;
2862 /* Return the window in the window tree rooted in W containing frame
2863 row ROW. Value is null if none is found. */
2865 static struct window *
2866 frame_row_to_window (struct window *w, int row)
2868 struct window *found = NULL;
2870 while (w && !found)
2872 if (!NILP (w->hchild))
2873 found = frame_row_to_window (XWINDOW (w->hchild), row);
2874 else if (!NILP (w->vchild))
2875 found = frame_row_to_window (XWINDOW (w->vchild), row);
2876 else if (row >= WINDOW_TOP_EDGE_LINE (w)
2877 && row < WINDOW_BOTTOM_EDGE_LINE (w))
2878 found = w;
2880 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2883 return found;
2887 /* Perform a line dance in the window tree rooted at W, after
2888 scrolling a frame matrix in mirrored_line_dance.
2890 We are working on the range of lines UNCHANGED_AT_TOP + 1 to
2891 UNCHANGED_AT_TOP + NLINES (not including) in W's frame matrix.
2892 COPY_FROM is a vector containing, for each row I in the range 0 <=
2893 I < NLINES, the index of the original line to move to I. This
2894 index is relative to the row range, i.e. 0 <= index < NLINES.
2895 RETAINED_P is a vector containing zero for each row 0 <= I < NLINES
2896 which is empty. */
2898 static void
2899 mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy_from, char *retained_p)
2901 while (w)
2903 if (!NILP (w->hchild))
2904 mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top,
2905 nlines, copy_from, retained_p);
2906 else if (!NILP (w->vchild))
2907 mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
2908 nlines, copy_from, retained_p);
2909 else
2911 /* W is a leaf window, and we are working on its current
2912 matrix m. */
2913 struct glyph_matrix *m = w->current_matrix;
2914 int i, sync_p = 0;
2915 struct glyph_row *old_rows;
2917 /* Make a copy of the original rows of matrix m. */
2918 old_rows = (struct glyph_row *) alloca (m->nrows * sizeof *old_rows);
2919 memcpy (old_rows, m->rows, m->nrows * sizeof *old_rows);
2921 for (i = 0; i < nlines; ++i)
2923 /* Frame relative line assigned to. */
2924 int frame_to = i + unchanged_at_top;
2926 /* Frame relative line assigned. */
2927 int frame_from = copy_from[i] + unchanged_at_top;
2929 /* Window relative line assigned to. */
2930 int window_to = frame_to - m->matrix_y;
2932 /* Window relative line assigned. */
2933 int window_from = frame_from - m->matrix_y;
2935 /* Is assigned line inside window? */
2936 int from_inside_window_p
2937 = window_from >= 0 && window_from < m->matrix_h;
2939 /* Is assigned to line inside window? */
2940 int to_inside_window_p
2941 = window_to >= 0 && window_to < m->matrix_h;
2943 if (from_inside_window_p && to_inside_window_p)
2945 /* Enabled setting before assignment. */
2946 int enabled_before_p;
2948 /* Do the assignment. The enabled_p flag is saved
2949 over the assignment because the old redisplay did
2950 that. */
2951 enabled_before_p = m->rows[window_to].enabled_p;
2952 m->rows[window_to] = old_rows[window_from];
2953 m->rows[window_to].enabled_p = enabled_before_p;
2955 /* If frame line is empty, window line is empty, too. */
2956 if (!retained_p[copy_from[i]])
2957 m->rows[window_to].enabled_p = 0;
2959 else if (to_inside_window_p)
2961 /* A copy between windows. This is an infrequent
2962 case not worth optimizing. */
2963 struct frame *f = XFRAME (w->frame);
2964 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
2965 struct window *w2;
2966 struct glyph_matrix *m2;
2967 int m2_from;
2969 w2 = frame_row_to_window (root, frame_from);
2970 /* ttn@surf.glug.org: when enabling menu bar using `emacs
2971 -nw', FROM_FRAME sometimes has no associated window.
2972 This check avoids a segfault if W2 is null. */
2973 if (w2)
2975 m2 = w2->current_matrix;
2976 m2_from = frame_from - m2->matrix_y;
2977 copy_row_except_pointers (m->rows + window_to,
2978 m2->rows + m2_from);
2980 /* If frame line is empty, window line is empty, too. */
2981 if (!retained_p[copy_from[i]])
2982 m->rows[window_to].enabled_p = 0;
2984 sync_p = 1;
2986 else if (from_inside_window_p)
2987 sync_p = 1;
2990 /* If there was a copy between windows, make sure glyph
2991 pointers are in sync with the frame matrix. */
2992 if (sync_p)
2993 sync_window_with_frame_matrix_rows (w);
2995 /* Check that no pointers are lost. */
2996 CHECK_MATRIX (m);
2999 /* Next window on same level. */
3000 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3005 #if GLYPH_DEBUG
3007 /* Check that window and frame matrices agree about their
3008 understanding where glyphs of the rows are to find. For each
3009 window in the window tree rooted at W, check that rows in the
3010 matrices of leaf window agree with their frame matrices about
3011 glyph pointers. */
3013 static void
3014 check_window_matrix_pointers (struct window *w)
3016 while (w)
3018 if (!NILP (w->hchild))
3019 check_window_matrix_pointers (XWINDOW (w->hchild));
3020 else if (!NILP (w->vchild))
3021 check_window_matrix_pointers (XWINDOW (w->vchild));
3022 else
3024 struct frame *f = XFRAME (w->frame);
3025 check_matrix_pointers (w->desired_matrix, f->desired_matrix);
3026 check_matrix_pointers (w->current_matrix, f->current_matrix);
3029 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3034 /* Check that window rows are slices of frame rows. WINDOW_MATRIX is
3035 a window and FRAME_MATRIX is the corresponding frame matrix. For
3036 each row in WINDOW_MATRIX check that it's a slice of the
3037 corresponding frame row. If it isn't, abort. */
3039 static void
3040 check_matrix_pointers (struct glyph_matrix *window_matrix,
3041 struct glyph_matrix *frame_matrix)
3043 /* Row number in WINDOW_MATRIX. */
3044 int i = 0;
3046 /* Row number corresponding to I in FRAME_MATRIX. */
3047 int j = window_matrix->matrix_y;
3049 /* For all rows check that the row in the window matrix is a
3050 slice of the row in the frame matrix. If it isn't we didn't
3051 mirror an operation on the frame matrix correctly. */
3052 while (i < window_matrix->nrows)
3054 if (!glyph_row_slice_p (window_matrix->rows + i,
3055 frame_matrix->rows + j))
3056 abort ();
3057 ++i, ++j;
3061 #endif /* GLYPH_DEBUG != 0 */
3065 /**********************************************************************
3066 VPOS and HPOS translations
3067 **********************************************************************/
3069 #if GLYPH_DEBUG
3071 /* Translate vertical position VPOS which is relative to window W to a
3072 vertical position relative to W's frame. */
3074 static int
3075 window_to_frame_vpos (struct window *w, int vpos)
3077 xassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
3078 xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
3079 vpos += WINDOW_TOP_EDGE_LINE (w);
3080 xassert (vpos >= 0 && vpos <= FRAME_LINES (XFRAME (w->frame)));
3081 return vpos;
3085 /* Translate horizontal position HPOS which is relative to window W to
3086 a horizontal position relative to W's frame. */
3088 static int
3089 window_to_frame_hpos (struct window *w, int hpos)
3091 xassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
3092 hpos += WINDOW_LEFT_EDGE_COL (w);
3093 return hpos;
3096 #endif /* GLYPH_DEBUG */
3100 /**********************************************************************
3101 Redrawing Frames
3102 **********************************************************************/
3104 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
3105 doc: /* Clear frame FRAME and output again what is supposed to appear on it. */)
3106 (Lisp_Object frame)
3108 struct frame *f;
3110 CHECK_LIVE_FRAME (frame);
3111 f = XFRAME (frame);
3113 /* Ignore redraw requests, if frame has no glyphs yet.
3114 (Implementation note: It still has to be checked why we are
3115 called so early here). */
3116 if (!glyphs_initialized_initially_p)
3117 return Qnil;
3119 update_begin (f);
3120 #ifdef MSDOS
3121 if (FRAME_MSDOS_P (f))
3122 FRAME_TERMINAL (f)->set_terminal_modes_hook (FRAME_TERMINAL (f));
3123 #endif
3124 clear_frame (f);
3125 clear_current_matrices (f);
3126 update_end (f);
3127 if (FRAME_TERMCAP_P (f))
3128 fflush (FRAME_TTY (f)->output);
3129 windows_or_buffers_changed++;
3130 /* Mark all windows as inaccurate, so that every window will have
3131 its redisplay done. */
3132 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
3133 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
3134 f->garbaged = 0;
3135 return Qnil;
3139 /* Redraw frame F. This is nothing more than a call to the Lisp
3140 function redraw-frame. */
3142 void
3143 redraw_frame (struct frame *f)
3145 Lisp_Object frame;
3146 XSETFRAME (frame, f);
3147 Fredraw_frame (frame);
3151 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3152 doc: /* Clear and redisplay all visible frames. */)
3153 (void)
3155 Lisp_Object tail, frame;
3157 FOR_EACH_FRAME (tail, frame)
3158 if (FRAME_VISIBLE_P (XFRAME (frame)))
3159 Fredraw_frame (frame);
3161 return Qnil;
3166 /***********************************************************************
3167 Frame Update
3168 ***********************************************************************/
3170 /* Update frame F based on the data in desired matrices.
3172 If FORCE_P is non-zero, don't let redisplay be stopped by detecting
3173 pending input. If INHIBIT_HAIRY_ID_P is non-zero, don't try
3174 scrolling.
3176 Value is non-zero if redisplay was stopped due to pending input. */
3179 update_frame (struct frame *f, int force_p, int inhibit_hairy_id_p)
3181 /* 1 means display has been paused because of pending input. */
3182 int paused_p;
3183 struct window *root_window = XWINDOW (f->root_window);
3185 if (redisplay_dont_pause)
3186 force_p = 1;
3187 #if PERIODIC_PREEMPTION_CHECKING
3188 else if (NILP (Vredisplay_preemption_period))
3189 force_p = 1;
3190 else if (!force_p && NUMBERP (Vredisplay_preemption_period))
3192 EMACS_TIME tm;
3193 double p = XFLOATINT (Vredisplay_preemption_period);
3194 int sec, usec;
3196 if (detect_input_pending_ignore_squeezables ())
3198 paused_p = 1;
3199 goto do_pause;
3202 sec = (int) p;
3203 usec = (p - sec) * 1000000;
3205 EMACS_GET_TIME (tm);
3206 EMACS_SET_SECS_USECS (preemption_period, sec, usec);
3207 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
3209 #endif
3211 if (FRAME_WINDOW_P (f))
3213 /* We are working on window matrix basis. All windows whose
3214 flag must_be_updated_p is set have to be updated. */
3216 /* Record that we are not working on frame matrices. */
3217 set_frame_matrix_frame (NULL);
3219 /* Update all windows in the window tree of F, maybe stopping
3220 when pending input is detected. */
3221 update_begin (f);
3223 /* Update the menu bar on X frames that don't have toolkit
3224 support. */
3225 if (WINDOWP (f->menu_bar_window))
3226 update_window (XWINDOW (f->menu_bar_window), 1);
3228 /* Update the tool-bar window, if present. */
3229 if (WINDOWP (f->tool_bar_window))
3231 struct window *w = XWINDOW (f->tool_bar_window);
3233 /* Update tool-bar window. */
3234 if (w->must_be_updated_p)
3236 Lisp_Object tem;
3238 update_window (w, 1);
3239 w->must_be_updated_p = 0;
3241 /* Swap tool-bar strings. We swap because we want to
3242 reuse strings. */
3243 tem = f->current_tool_bar_string;
3244 f->current_tool_bar_string = f->desired_tool_bar_string;
3245 f->desired_tool_bar_string = tem;
3250 /* Update windows. */
3251 paused_p = update_window_tree (root_window, force_p);
3252 update_end (f);
3254 /* This flush is a performance bottleneck under X,
3255 and it doesn't seem to be necessary anyway (in general).
3256 It is necessary when resizing the window with the mouse, or
3257 at least the fringes are not redrawn in a timely manner. ++kfs */
3258 if (f->force_flush_display_p)
3260 FRAME_RIF (f)->flush_display (f);
3261 f->force_flush_display_p = 0;
3264 else
3266 /* We are working on frame matrix basis. Set the frame on whose
3267 frame matrix we operate. */
3268 set_frame_matrix_frame (f);
3270 /* Build F's desired matrix from window matrices. */
3271 build_frame_matrix (f);
3273 /* Update the display */
3274 update_begin (f);
3275 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
3276 update_end (f);
3278 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
3280 if (FRAME_TTY (f)->termscript)
3281 fflush (FRAME_TTY (f)->termscript);
3282 if (FRAME_TERMCAP_P (f))
3283 fflush (FRAME_TTY (f)->output);
3286 /* Check window matrices for lost pointers. */
3287 #if GLYPH_DEBUG
3288 check_window_matrix_pointers (root_window);
3289 add_frame_display_history (f, paused_p);
3290 #endif
3293 #if PERIODIC_PREEMPTION_CHECKING
3294 do_pause:
3295 #endif
3296 /* Reset flags indicating that a window should be updated. */
3297 set_window_update_flags (root_window, 0);
3299 display_completed = !paused_p;
3300 return paused_p;
3305 /************************************************************************
3306 Window-based updates
3307 ************************************************************************/
3309 /* Perform updates in window tree rooted at W. FORCE_P non-zero means
3310 don't stop updating when input is pending. */
3312 static int
3313 update_window_tree (struct window *w, int force_p)
3315 int paused_p = 0;
3317 while (w && !paused_p)
3319 if (!NILP (w->hchild))
3320 paused_p |= update_window_tree (XWINDOW (w->hchild), force_p);
3321 else if (!NILP (w->vchild))
3322 paused_p |= update_window_tree (XWINDOW (w->vchild), force_p);
3323 else if (w->must_be_updated_p)
3324 paused_p |= update_window (w, force_p);
3326 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3329 return paused_p;
3333 /* Update window W if its flag must_be_updated_p is non-zero. If
3334 FORCE_P is non-zero, don't stop updating if input is pending. */
3336 void
3337 update_single_window (struct window *w, int force_p)
3339 if (w->must_be_updated_p)
3341 struct frame *f = XFRAME (WINDOW_FRAME (w));
3343 /* Record that this is not a frame-based redisplay. */
3344 set_frame_matrix_frame (NULL);
3346 if (redisplay_dont_pause)
3347 force_p = 1;
3348 #if PERIODIC_PREEMPTION_CHECKING
3349 else if (NILP (Vredisplay_preemption_period))
3350 force_p = 1;
3351 else if (!force_p && NUMBERP (Vredisplay_preemption_period))
3353 EMACS_TIME tm;
3354 double p = XFLOATINT (Vredisplay_preemption_period);
3355 int sec, usec;
3357 sec = (int) p;
3358 usec = (p - sec) * 1000000;
3360 EMACS_GET_TIME (tm);
3361 EMACS_SET_SECS_USECS (preemption_period, sec, usec);
3362 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
3364 #endif
3366 /* Update W. */
3367 update_begin (f);
3368 update_window (w, force_p);
3369 update_end (f);
3371 /* Reset flag in W. */
3372 w->must_be_updated_p = 0;
3376 #ifdef HAVE_WINDOW_SYSTEM
3378 /* Redraw lines from the current matrix of window W that are
3379 overlapped by other rows. YB is bottom-most y-position in W. */
3381 static void
3382 redraw_overlapped_rows (struct window *w, int yb)
3384 int i;
3385 struct frame *f = XFRAME (WINDOW_FRAME (w));
3387 /* If rows overlapping others have been changed, the rows being
3388 overlapped have to be redrawn. This won't draw lines that have
3389 already been drawn in update_window_line because overlapped_p in
3390 desired rows is 0, so after row assignment overlapped_p in
3391 current rows is 0. */
3392 for (i = 0; i < w->current_matrix->nrows; ++i)
3394 struct glyph_row *row = w->current_matrix->rows + i;
3396 if (!row->enabled_p)
3397 break;
3398 else if (row->mode_line_p)
3399 continue;
3401 if (row->overlapped_p)
3403 enum glyph_row_area area;
3405 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
3407 updated_row = row;
3408 updated_area = area;
3409 FRAME_RIF (f)->cursor_to (i, 0, row->y,
3410 area == TEXT_AREA ? row->x : 0);
3411 if (row->used[area])
3412 FRAME_RIF (f)->write_glyphs (row->glyphs[area],
3413 row->used[area]);
3414 FRAME_RIF (f)->clear_end_of_line (-1);
3417 row->overlapped_p = 0;
3420 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3421 break;
3426 /* Redraw lines from the current matrix of window W that overlap
3427 others. YB is bottom-most y-position in W. */
3429 static void
3430 redraw_overlapping_rows (struct window *w, int yb)
3432 int i, bottom_y;
3433 struct glyph_row *row;
3434 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3436 for (i = 0; i < w->current_matrix->nrows; ++i)
3438 row = w->current_matrix->rows + i;
3440 if (!row->enabled_p)
3441 break;
3442 else if (row->mode_line_p)
3443 continue;
3445 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3447 if (row->overlapping_p)
3449 int overlaps = 0;
3451 if (MATRIX_ROW_OVERLAPS_PRED_P (row) && i > 0
3452 && !MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p)
3453 overlaps |= OVERLAPS_PRED;
3454 if (MATRIX_ROW_OVERLAPS_SUCC_P (row) && bottom_y < yb
3455 && !MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p)
3456 overlaps |= OVERLAPS_SUCC;
3458 if (overlaps)
3460 if (row->used[LEFT_MARGIN_AREA])
3461 rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA, overlaps);
3463 if (row->used[TEXT_AREA])
3464 rif->fix_overlapping_area (w, row, TEXT_AREA, overlaps);
3466 if (row->used[RIGHT_MARGIN_AREA])
3467 rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps);
3469 /* Record in neighbour rows that ROW overwrites part of
3470 their display. */
3471 if (overlaps & OVERLAPS_PRED)
3472 MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
3473 if (overlaps & OVERLAPS_SUCC)
3474 MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
3478 if (bottom_y >= yb)
3479 break;
3483 #endif /* HAVE_WINDOW_SYSTEM */
3486 #if defined GLYPH_DEBUG && 0
3488 /* Check that no row in the current matrix of window W is enabled
3489 which is below what's displayed in the window. */
3491 static void
3492 check_current_matrix_flags (struct window *w)
3494 int last_seen_p = 0;
3495 int i, yb = window_text_bottom_y (w);
3497 for (i = 0; i < w->current_matrix->nrows - 1; ++i)
3499 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
3500 if (!last_seen_p && MATRIX_ROW_BOTTOM_Y (row) >= yb)
3501 last_seen_p = 1;
3502 else if (last_seen_p && row->enabled_p)
3503 abort ();
3507 #endif /* GLYPH_DEBUG */
3510 /* Update display of window W. FORCE_P non-zero means that we should
3511 not stop when detecting pending input. */
3513 static int
3514 update_window (struct window *w, int force_p)
3516 struct glyph_matrix *desired_matrix = w->desired_matrix;
3517 int paused_p;
3518 #if !PERIODIC_PREEMPTION_CHECKING
3519 int preempt_count = baud_rate / 2400 + 1;
3520 #endif
3521 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3522 #if GLYPH_DEBUG
3523 /* Check that W's frame doesn't have glyph matrices. */
3524 xassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
3525 #endif
3527 /* Check pending input the first time so that we can quickly return. */
3528 #if !PERIODIC_PREEMPTION_CHECKING
3529 if (!force_p)
3530 detect_input_pending_ignore_squeezables ();
3531 #endif
3533 /* If forced to complete the update, or if no input is pending, do
3534 the update. */
3535 if (force_p || !input_pending || !NILP (do_mouse_tracking))
3537 struct glyph_row *row, *end;
3538 struct glyph_row *mode_line_row;
3539 struct glyph_row *header_line_row;
3540 int yb, changed_p = 0, mouse_face_overwritten_p = 0;
3541 #if ! PERIODIC_PREEMPTION_CHECKING
3542 int n_updated = 0;
3543 #endif
3545 rif->update_window_begin_hook (w);
3546 yb = window_text_bottom_y (w);
3548 /* If window has a header line, update it before everything else.
3549 Adjust y-positions of other rows by the header line height. */
3550 row = desired_matrix->rows;
3551 end = row + desired_matrix->nrows - 1;
3553 if (row->mode_line_p)
3555 header_line_row = row;
3556 ++row;
3558 else
3559 header_line_row = NULL;
3561 /* Update the mode line, if necessary. */
3562 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
3563 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
3565 mode_line_row->y = yb;
3566 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
3567 desired_matrix),
3568 &mouse_face_overwritten_p);
3571 /* Find first enabled row. Optimizations in redisplay_internal
3572 may lead to an update with only one row enabled. There may
3573 be also completely empty matrices. */
3574 while (row < end && !row->enabled_p)
3575 ++row;
3577 /* Try reusing part of the display by copying. */
3578 if (row < end && !desired_matrix->no_scrolling_p)
3580 int rc = scrolling_window (w, header_line_row != NULL);
3581 if (rc < 0)
3583 /* All rows were found to be equal. */
3584 paused_p = 0;
3585 goto set_cursor;
3587 else if (rc > 0)
3589 /* We've scrolled the display. */
3590 force_p = 1;
3591 changed_p = 1;
3595 /* Update the rest of the lines. */
3596 for (; row < end && (force_p || !input_pending); ++row)
3597 if (row->enabled_p)
3599 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
3600 int i;
3602 /* We'll have to play a little bit with when to
3603 detect_input_pending. If it's done too often,
3604 scrolling large windows with repeated scroll-up
3605 commands will too quickly pause redisplay. */
3606 #if PERIODIC_PREEMPTION_CHECKING
3607 if (!force_p)
3609 EMACS_TIME tm, dif;
3610 EMACS_GET_TIME (tm);
3611 EMACS_SUB_TIME (dif, preemption_next_check, tm);
3612 if (EMACS_TIME_NEG_P (dif))
3614 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
3615 if (detect_input_pending_ignore_squeezables ())
3616 break;
3619 #else
3620 if (!force_p && ++n_updated % preempt_count == 0)
3621 detect_input_pending_ignore_squeezables ();
3622 #endif
3623 changed_p |= update_window_line (w, vpos,
3624 &mouse_face_overwritten_p);
3626 /* Mark all rows below the last visible one in the current
3627 matrix as invalid. This is necessary because of
3628 variable line heights. Consider the case of three
3629 successive redisplays, where the first displays 5
3630 lines, the second 3 lines, and the third 5 lines again.
3631 If the second redisplay wouldn't mark rows in the
3632 current matrix invalid, the third redisplay might be
3633 tempted to optimize redisplay based on lines displayed
3634 in the first redisplay. */
3635 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3636 for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
3637 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
3640 /* Was display preempted? */
3641 paused_p = row < end;
3643 set_cursor:
3645 /* Update the header line after scrolling because a new header
3646 line would otherwise overwrite lines at the top of the window
3647 that can be scrolled. */
3648 if (header_line_row && header_line_row->enabled_p)
3650 header_line_row->y = 0;
3651 update_window_line (w, 0, &mouse_face_overwritten_p);
3654 /* Fix the appearance of overlapping/overlapped rows. */
3655 if (!paused_p && !w->pseudo_window_p)
3657 #ifdef HAVE_WINDOW_SYSTEM
3658 if (changed_p && rif->fix_overlapping_area)
3660 redraw_overlapped_rows (w, yb);
3661 redraw_overlapping_rows (w, yb);
3663 #endif
3665 /* Make cursor visible at cursor position of W. */
3666 set_window_cursor_after_update (w);
3668 #if 0 /* Check that current matrix invariants are satisfied. This is
3669 for debugging only. See the comment of check_matrix_invariants. */
3670 IF_DEBUG (check_matrix_invariants (w));
3671 #endif
3674 #if GLYPH_DEBUG
3675 /* Remember the redisplay method used to display the matrix. */
3676 strcpy (w->current_matrix->method, w->desired_matrix->method);
3677 #endif
3679 #ifdef HAVE_WINDOW_SYSTEM
3680 update_window_fringes (w, 0);
3681 #endif
3683 /* End the update of window W. Don't set the cursor if we
3684 paused updating the display because in this case,
3685 set_window_cursor_after_update hasn't been called, and
3686 output_cursor doesn't contain the cursor location. */
3687 rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
3689 else
3690 paused_p = 1;
3692 #if GLYPH_DEBUG
3693 /* check_current_matrix_flags (w); */
3694 add_window_display_history (w, w->current_matrix->method, paused_p);
3695 #endif
3697 #ifdef HAVE_XWIDGETS
3698 xwidget_end_redisplay(w, w->current_matrix);
3699 #endif
3700 clear_glyph_matrix (desired_matrix);
3702 return paused_p;
3706 /* Update the display of area AREA in window W, row number VPOS.
3707 AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
3709 static void
3710 update_marginal_area (struct window *w, int area, int vpos)
3712 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3713 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3715 /* Let functions in xterm.c know what area subsequent X positions
3716 will be relative to. */
3717 updated_area = area;
3719 /* Set cursor to start of glyphs, write them, and clear to the end
3720 of the area. I don't think that something more sophisticated is
3721 necessary here, since marginal areas will not be the default. */
3722 rif->cursor_to (vpos, 0, desired_row->y, 0);
3723 if (desired_row->used[area])
3724 rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]);
3725 rif->clear_end_of_line (-1);
3729 /* Update the display of the text area of row VPOS in window W.
3730 Value is non-zero if display has changed. */
3732 static int
3733 update_text_area (struct window *w, int vpos)
3735 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3736 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3737 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3738 int changed_p = 0;
3740 /* Let functions in xterm.c know what area subsequent X positions
3741 will be relative to. */
3742 updated_area = TEXT_AREA;
3744 /* If rows are at different X or Y, or rows have different height,
3745 or the current row is marked invalid, write the entire line. */
3746 if (!current_row->enabled_p
3747 || desired_row->y != current_row->y
3748 || desired_row->ascent != current_row->ascent
3749 || desired_row->phys_ascent != current_row->phys_ascent
3750 || desired_row->phys_height != current_row->phys_height
3751 || desired_row->visible_height != current_row->visible_height
3752 || current_row->overlapped_p
3753 /* This next line is necessary for correctly redrawing
3754 mouse-face areas after scrolling and other operations.
3755 However, it causes excessive flickering when mouse is moved
3756 across the mode line. Luckily, turning it off for the mode
3757 line doesn't seem to hurt anything. -- cyd.
3758 But it is still needed for the header line. -- kfs. */
3759 || (current_row->mouse_face_p
3760 && !(current_row->mode_line_p && vpos > 0))
3761 || current_row->x != desired_row->x)
3763 rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
3765 if (desired_row->used[TEXT_AREA])
3766 rif->write_glyphs (desired_row->glyphs[TEXT_AREA],
3767 desired_row->used[TEXT_AREA]);
3769 /* Clear to end of window. */
3770 rif->clear_end_of_line (-1);
3771 changed_p = 1;
3773 /* This erases the cursor. We do this here because
3774 notice_overwritten_cursor cannot easily check this, which
3775 might indicate that the whole functionality of
3776 notice_overwritten_cursor would better be implemented here.
3777 On the other hand, we need notice_overwritten_cursor as long
3778 as mouse highlighting is done asynchronously outside of
3779 redisplay. */
3780 if (vpos == w->phys_cursor.vpos)
3781 w->phys_cursor_on_p = 0;
3783 else
3785 int stop, i, x;
3786 struct glyph *current_glyph = current_row->glyphs[TEXT_AREA];
3787 struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
3788 int overlapping_glyphs_p = current_row->contains_overlapping_glyphs_p;
3789 int desired_stop_pos = desired_row->used[TEXT_AREA];
3790 int abort_skipping = 0;
3792 /* If the desired row extends its face to the text area end, and
3793 unless the current row also does so at the same position,
3794 make sure we write at least one glyph, so that the face
3795 extension actually takes place. */
3796 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row)
3797 && (desired_stop_pos < current_row->used[TEXT_AREA]
3798 || (desired_stop_pos == current_row->used[TEXT_AREA]
3799 && !MATRIX_ROW_EXTENDS_FACE_P (current_row))))
3800 --desired_stop_pos;
3802 stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
3803 i = 0;
3804 x = desired_row->x;
3806 /* Loop over glyphs that current and desired row may have
3807 in common. */
3808 while (i < stop)
3810 int can_skip_p = !abort_skipping;
3812 /* Skip over glyphs that both rows have in common. These
3813 don't have to be written. We can't skip if the last
3814 current glyph overlaps the glyph to its right. For
3815 example, consider a current row of `if ' with the `f' in
3816 Courier bold so that it overlaps the ` ' to its right.
3817 If the desired row is ` ', we would skip over the space
3818 after the `if' and there would remain a pixel from the
3819 `f' on the screen. */
3820 if (overlapping_glyphs_p && i > 0)
3822 struct glyph *glyph = &current_row->glyphs[TEXT_AREA][i - 1];
3823 int left, right;
3825 rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
3826 &left, &right);
3827 can_skip_p = (right == 0 && !abort_skipping);
3830 if (can_skip_p)
3832 int start_hpos = i;
3834 while (i < stop
3835 && GLYPH_EQUAL_P (desired_glyph, current_glyph))
3837 x += desired_glyph->pixel_width;
3838 ++desired_glyph, ++current_glyph, ++i;
3841 /* Consider the case that the current row contains "xxx
3842 ppp ggg" in italic Courier font, and the desired row
3843 is "xxx ggg". The character `p' has lbearing, `g'
3844 has not. The loop above will stop in front of the
3845 first `p' in the current row. If we would start
3846 writing glyphs there, we wouldn't erase the lbearing
3847 of the `p'. The rest of the lbearing problem is then
3848 taken care of by draw_glyphs. */
3849 if (overlapping_glyphs_p
3850 && i > 0
3851 && i < current_row->used[TEXT_AREA]
3852 && (current_row->used[TEXT_AREA]
3853 != desired_row->used[TEXT_AREA]))
3855 int left, right;
3857 rif->get_glyph_overhangs (current_glyph, XFRAME (w->frame),
3858 &left, &right);
3859 while (left > 0 && i > 0)
3861 --i, --desired_glyph, --current_glyph;
3862 x -= desired_glyph->pixel_width;
3863 left -= desired_glyph->pixel_width;
3866 /* Abort the skipping algorithm if we end up before
3867 our starting point, to avoid looping (bug#1070).
3868 This can happen when the lbearing is larger than
3869 the pixel width. */
3870 abort_skipping = (i < start_hpos);
3874 /* Try to avoid writing the entire rest of the desired row
3875 by looking for a resync point. This mainly prevents
3876 mode line flickering in the case the mode line is in
3877 fixed-pitch font, which it usually will be. */
3878 if (i < desired_row->used[TEXT_AREA])
3880 int start_x = x, start_hpos = i;
3881 struct glyph *start = desired_glyph;
3882 int current_x = x;
3883 int skip_first_p = !can_skip_p;
3885 /* Find the next glyph that's equal again. */
3886 while (i < stop
3887 && (skip_first_p
3888 || !GLYPH_EQUAL_P (desired_glyph, current_glyph))
3889 && x == current_x)
3891 x += desired_glyph->pixel_width;
3892 current_x += current_glyph->pixel_width;
3893 ++desired_glyph, ++current_glyph, ++i;
3894 skip_first_p = 0;
3897 if (i == start_hpos || x != current_x)
3899 i = start_hpos;
3900 x = start_x;
3901 desired_glyph = start;
3902 break;
3905 rif->cursor_to (vpos, start_hpos, desired_row->y, start_x);
3906 rif->write_glyphs (start, i - start_hpos);
3907 changed_p = 1;
3911 /* Write the rest. */
3912 if (i < desired_row->used[TEXT_AREA])
3914 rif->cursor_to (vpos, i, desired_row->y, x);
3915 rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
3916 changed_p = 1;
3919 /* Maybe clear to end of line. */
3920 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
3922 /* If new row extends to the end of the text area, nothing
3923 has to be cleared, if and only if we did a write_glyphs
3924 above. This is made sure by setting desired_stop_pos
3925 appropriately above. */
3926 xassert (i < desired_row->used[TEXT_AREA]
3927 || ((desired_row->used[TEXT_AREA]
3928 == current_row->used[TEXT_AREA])
3929 && MATRIX_ROW_EXTENDS_FACE_P (current_row)));
3931 else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
3933 /* If old row extends to the end of the text area, clear. */
3934 if (i >= desired_row->used[TEXT_AREA])
3935 rif->cursor_to (vpos, i, desired_row->y,
3936 desired_row->pixel_width);
3937 rif->clear_end_of_line (-1);
3938 changed_p = 1;
3940 else if (desired_row->pixel_width < current_row->pixel_width)
3942 /* Otherwise clear to the end of the old row. Everything
3943 after that position should be clear already. */
3944 int xlim;
3946 if (i >= desired_row->used[TEXT_AREA])
3947 rif->cursor_to (vpos, i, desired_row->y,
3948 desired_row->pixel_width);
3950 /* If cursor is displayed at the end of the line, make sure
3951 it's cleared. Nowadays we don't have a phys_cursor_glyph
3952 with which to erase the cursor (because this method
3953 doesn't work with lbearing/rbearing), so we must do it
3954 this way. */
3955 if (vpos == w->phys_cursor.vpos
3956 && (desired_row->reversed_p
3957 ? (w->phys_cursor.hpos < 0)
3958 : (w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])))
3960 w->phys_cursor_on_p = 0;
3961 xlim = -1;
3963 else
3964 xlim = current_row->pixel_width;
3965 rif->clear_end_of_line (xlim);
3966 changed_p = 1;
3970 return changed_p;
3974 /* Update row VPOS in window W. Value is non-zero if display has been
3975 changed. */
3977 static int
3978 update_window_line (struct window *w, int vpos, int *mouse_face_overwritten_p)
3980 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3981 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3982 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3983 int changed_p = 0;
3985 /* Set the row being updated. This is important to let xterm.c
3986 know what line height values are in effect. */
3987 updated_row = desired_row;
3989 /* A row can be completely invisible in case a desired matrix was
3990 built with a vscroll and then make_cursor_line_fully_visible shifts
3991 the matrix. Make sure to make such rows current anyway, since
3992 we need the correct y-position, for example, in the current matrix. */
3993 if (desired_row->mode_line_p
3994 || desired_row->visible_height > 0)
3996 xassert (desired_row->enabled_p);
3998 /* Update display of the left margin area, if there is one. */
3999 if (!desired_row->full_width_p
4000 && !NILP (w->left_margin_cols))
4002 changed_p = 1;
4003 update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
4006 /* Update the display of the text area. */
4007 if (update_text_area (w, vpos))
4009 changed_p = 1;
4010 if (current_row->mouse_face_p)
4011 *mouse_face_overwritten_p = 1;
4014 /* Update display of the right margin area, if there is one. */
4015 if (!desired_row->full_width_p
4016 && !NILP (w->right_margin_cols))
4018 changed_p = 1;
4019 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
4022 /* Draw truncation marks etc. */
4023 if (!current_row->enabled_p
4024 || desired_row->y != current_row->y
4025 || desired_row->visible_height != current_row->visible_height
4026 || desired_row->cursor_in_fringe_p != current_row->cursor_in_fringe_p
4027 || desired_row->overlay_arrow_bitmap != current_row->overlay_arrow_bitmap
4028 || current_row->redraw_fringe_bitmaps_p
4029 || desired_row->mode_line_p != current_row->mode_line_p
4030 || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
4031 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
4032 != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
4033 rif->after_update_window_line_hook (desired_row);
4036 /* Update current_row from desired_row. */
4037 make_current (w->desired_matrix, w->current_matrix, vpos);
4038 updated_row = NULL;
4039 return changed_p;
4043 /* Set the cursor after an update of window W. This function may only
4044 be called from update_window. */
4046 static void
4047 set_window_cursor_after_update (struct window *w)
4049 struct frame *f = XFRAME (w->frame);
4050 struct redisplay_interface *rif = FRAME_RIF (f);
4051 int cx, cy, vpos, hpos;
4053 /* Not intended for frame matrix updates. */
4054 xassert (FRAME_WINDOW_P (f));
4056 if (cursor_in_echo_area
4057 && !NILP (echo_area_buffer[0])
4058 /* If we are showing a message instead of the mini-buffer,
4059 show the cursor for the message instead. */
4060 && XWINDOW (minibuf_window) == w
4061 && EQ (minibuf_window, echo_area_window)
4062 /* These cases apply only to the frame that contains
4063 the active mini-buffer window. */
4064 && FRAME_HAS_MINIBUF_P (f)
4065 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4067 cx = cy = vpos = hpos = 0;
4069 if (cursor_in_echo_area >= 0)
4071 /* If the mini-buffer is several lines high, find the last
4072 line that has any text on it. Note: either all lines
4073 are enabled or none. Otherwise we wouldn't be able to
4074 determine Y. */
4075 struct glyph_row *row, *last_row;
4076 struct glyph *glyph;
4077 int yb = window_text_bottom_y (w);
4079 last_row = NULL;
4080 row = w->current_matrix->rows;
4081 while (row->enabled_p
4082 && (last_row == NULL
4083 || MATRIX_ROW_BOTTOM_Y (row) <= yb))
4085 if (row->used[TEXT_AREA]
4086 && row->glyphs[TEXT_AREA][0].charpos >= 0)
4087 last_row = row;
4088 ++row;
4091 if (last_row)
4093 struct glyph *start = last_row->glyphs[TEXT_AREA];
4094 struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
4096 while (last > start && last->charpos < 0)
4097 --last;
4099 for (glyph = start; glyph < last; ++glyph)
4101 cx += glyph->pixel_width;
4102 ++hpos;
4105 cy = last_row->y;
4106 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
4110 else
4112 cx = w->cursor.x;
4113 cy = w->cursor.y;
4114 hpos = w->cursor.hpos;
4115 vpos = w->cursor.vpos;
4118 /* Window cursor can be out of sync for horizontally split windows. */
4119 hpos = max (-1, hpos); /* -1 is for when cursor is on the left fringe */
4120 hpos = min (w->current_matrix->matrix_w - 1, hpos);
4121 vpos = max (0, vpos);
4122 vpos = min (w->current_matrix->nrows - 1, vpos);
4123 rif->cursor_to (vpos, hpos, cy, cx);
4127 /* Set WINDOW->must_be_updated_p to ON_P for all windows in the window
4128 tree rooted at W. */
4130 void
4131 set_window_update_flags (struct window *w, int on_p)
4133 while (w)
4135 if (!NILP (w->hchild))
4136 set_window_update_flags (XWINDOW (w->hchild), on_p);
4137 else if (!NILP (w->vchild))
4138 set_window_update_flags (XWINDOW (w->vchild), on_p);
4139 else
4140 w->must_be_updated_p = on_p;
4142 w = NILP (w->next) ? 0 : XWINDOW (w->next);
4148 /***********************************************************************
4149 Window-Based Scrolling
4150 ***********************************************************************/
4152 /* Structure describing rows in scrolling_window. */
4154 struct row_entry
4156 /* Number of occurrences of this row in desired and current matrix. */
4157 int old_uses, new_uses;
4159 /* Vpos of row in new matrix. */
4160 int new_line_number;
4162 /* Bucket index of this row_entry in the hash table row_table. */
4163 ptrdiff_t bucket;
4165 /* The row described by this entry. */
4166 struct glyph_row *row;
4168 /* Hash collision chain. */
4169 struct row_entry *next;
4172 /* A pool to allocate row_entry structures from, and the size of the
4173 pool. The pool is reallocated in scrolling_window when we find
4174 that we need a larger one. */
4176 static struct row_entry *row_entry_pool;
4177 static ptrdiff_t row_entry_pool_size;
4179 /* Index of next free entry in row_entry_pool. */
4181 static ptrdiff_t row_entry_idx;
4183 /* The hash table used during scrolling, and the table's size. This
4184 table is used to quickly identify equal rows in the desired and
4185 current matrix. */
4187 static struct row_entry **row_table;
4188 static ptrdiff_t row_table_size;
4190 /* Vectors of pointers to row_entry structures belonging to the
4191 current and desired matrix, and the size of the vectors. */
4193 static struct row_entry **old_lines, **new_lines;
4194 static ptrdiff_t old_lines_size, new_lines_size;
4196 /* A pool to allocate run structures from, and its size. */
4198 static struct run *run_pool;
4199 static ptrdiff_t runs_size;
4201 /* A vector of runs of lines found during scrolling. */
4203 static struct run **runs;
4205 /* Add glyph row ROW to the scrolling hash table. */
4207 static inline struct row_entry *
4208 add_row_entry (struct glyph_row *row)
4210 struct row_entry *entry;
4211 ptrdiff_t i = row->hash % row_table_size;
4213 entry = row_table[i];
4214 while (entry && !row_equal_p (entry->row, row, 1))
4215 entry = entry->next;
4217 if (entry == NULL)
4219 entry = row_entry_pool + row_entry_idx++;
4220 entry->row = row;
4221 entry->old_uses = entry->new_uses = 0;
4222 entry->new_line_number = 0;
4223 entry->bucket = i;
4224 entry->next = row_table[i];
4225 row_table[i] = entry;
4228 return entry;
4232 /* Try to reuse part of the current display of W by scrolling lines.
4233 HEADER_LINE_P non-zero means W has a header line.
4235 The algorithm is taken from Communications of the ACM, Apr78 "A
4236 Technique for Isolating Differences Between Files." It should take
4237 O(N) time.
4239 A short outline of the steps of the algorithm
4241 1. Skip lines equal at the start and end of both matrices.
4243 2. Enter rows in the current and desired matrix into a symbol
4244 table, counting how often they appear in both matrices.
4246 3. Rows that appear exactly once in both matrices serve as anchors,
4247 i.e. we assume that such lines are likely to have been moved.
4249 4. Starting from anchor lines, extend regions to be scrolled both
4250 forward and backward.
4252 Value is
4254 -1 if all rows were found to be equal.
4255 0 to indicate that we did not scroll the display, or
4256 1 if we did scroll. */
4258 static int
4259 scrolling_window (struct window *w, int header_line_p)
4261 struct glyph_matrix *desired_matrix = w->desired_matrix;
4262 struct glyph_matrix *current_matrix = w->current_matrix;
4263 int yb = window_text_bottom_y (w);
4264 ptrdiff_t i;
4265 int j, first_old, first_new, last_old, last_new;
4266 int nruns, run_idx;
4267 ptrdiff_t n;
4268 struct row_entry *entry;
4269 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
4271 /* Skip over rows equal at the start. */
4272 for (i = header_line_p ? 1 : 0; i < current_matrix->nrows - 1; ++i)
4274 struct glyph_row *d = MATRIX_ROW (desired_matrix, i);
4275 struct glyph_row *c = MATRIX_ROW (current_matrix, i);
4277 if (c->enabled_p
4278 && d->enabled_p
4279 && !d->redraw_fringe_bitmaps_p
4280 && c->y == d->y
4281 && MATRIX_ROW_BOTTOM_Y (c) <= yb
4282 && MATRIX_ROW_BOTTOM_Y (d) <= yb
4283 && row_equal_p (c, d, 1))
4285 assign_row (c, d);
4286 d->enabled_p = 0;
4288 else
4289 break;
4292 #ifdef HAVE_XWIDGETS
4293 //currently this is needed to detect xwidget movement reliably. or probably not.
4294 printf("scrolling_window\n");
4295 return 0;
4296 #endif
4298 /* Give up if some rows in the desired matrix are not enabled. */
4299 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
4300 return -1;
4302 first_old = first_new = i;
4304 /* Set last_new to the index + 1 of the row that reaches the
4305 bottom boundary in the desired matrix. Give up if we find a
4306 disabled row before we reach the bottom boundary. */
4307 i = first_new + 1;
4308 while (i < desired_matrix->nrows - 1)
4310 int bottom;
4312 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
4313 return 0;
4314 bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i));
4315 if (bottom <= yb)
4316 ++i;
4317 if (bottom >= yb)
4318 break;
4321 last_new = i;
4323 /* Set last_old to the index + 1 of the row that reaches the bottom
4324 boundary in the current matrix. We don't look at the enabled
4325 flag here because we plan to reuse part of the display even if
4326 other parts are disabled. */
4327 i = first_old + 1;
4328 while (i < current_matrix->nrows - 1)
4330 int bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i));
4331 if (bottom <= yb)
4332 ++i;
4333 if (bottom >= yb)
4334 break;
4337 last_old = i;
4339 /* Skip over rows equal at the bottom. */
4340 i = last_new;
4341 j = last_old;
4342 while (i - 1 > first_new
4343 && j - 1 > first_old
4344 && MATRIX_ROW (current_matrix, i - 1)->enabled_p
4345 && (MATRIX_ROW (current_matrix, i - 1)->y
4346 == MATRIX_ROW (desired_matrix, j - 1)->y)
4347 && !MATRIX_ROW (desired_matrix, j - 1)->redraw_fringe_bitmaps_p
4348 && row_equal_p (MATRIX_ROW (desired_matrix, i - 1),
4349 MATRIX_ROW (current_matrix, j - 1), 1))
4350 --i, --j;
4351 last_new = i;
4352 last_old = j;
4354 /* Nothing to do if all rows are equal. */
4355 if (last_new == first_new)
4356 return 0;
4358 /* Check for integer overflow in size calculation.
4360 If next_almost_prime checks (N) for divisibility by 2..10, then
4361 it can return at most N + 10, e.g., next_almost_prime (1) == 11.
4362 So, set next_almost_prime_increment_max to 10.
4364 It's just a coincidence that next_almost_prime_increment_max ==
4365 NEXT_ALMOST_PRIME_LIMIT - 1. If NEXT_ALMOST_PRIME_LIMIT were
4366 13, then next_almost_prime_increment_max would be 14, e.g.,
4367 because next_almost_prime (113) would be 127. */
4369 verify (NEXT_ALMOST_PRIME_LIMIT == 11);
4370 enum { next_almost_prime_increment_max = 10 };
4371 ptrdiff_t row_table_max =
4372 (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table)
4373 - next_almost_prime_increment_max);
4374 ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows;
4375 if (current_nrows_max < current_matrix->nrows)
4376 memory_full (SIZE_MAX);
4379 /* Reallocate vectors, tables etc. if necessary. */
4381 if (current_matrix->nrows > old_lines_size)
4382 old_lines = xpalloc (old_lines, &old_lines_size,
4383 current_matrix->nrows - old_lines_size,
4384 INT_MAX, sizeof *old_lines);
4386 if (desired_matrix->nrows > new_lines_size)
4387 new_lines = xpalloc (new_lines, &new_lines_size,
4388 desired_matrix->nrows - new_lines_size,
4389 INT_MAX, sizeof *new_lines);
4391 n = desired_matrix->nrows;
4392 n += current_matrix->nrows;
4393 if (row_table_size < 3 * n)
4395 ptrdiff_t size = next_almost_prime (3 * n);
4396 row_table = xnrealloc (row_table, size, sizeof *row_table);
4397 row_table_size = size;
4398 memset (row_table, 0, size * sizeof *row_table);
4401 if (n > row_entry_pool_size)
4402 row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size,
4403 n - row_entry_pool_size,
4404 -1, sizeof *row_entry_pool);
4406 if (desired_matrix->nrows > runs_size)
4408 runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs);
4409 run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool);
4410 runs_size = desired_matrix->nrows;
4413 nruns = run_idx = 0;
4414 row_entry_idx = 0;
4416 /* Add rows from the current and desired matrix to the hash table
4417 row_hash_table to be able to find equal ones quickly. */
4419 for (i = first_old; i < last_old; ++i)
4421 if (MATRIX_ROW (current_matrix, i)->enabled_p)
4423 entry = add_row_entry (MATRIX_ROW (current_matrix, i));
4424 old_lines[i] = entry;
4425 ++entry->old_uses;
4427 else
4428 old_lines[i] = NULL;
4431 for (i = first_new; i < last_new; ++i)
4433 xassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
4434 entry = add_row_entry (MATRIX_ROW (desired_matrix, i));
4435 ++entry->new_uses;
4436 entry->new_line_number = i;
4437 new_lines[i] = entry;
4440 /* Identify moves based on lines that are unique and equal
4441 in both matrices. */
4442 for (i = first_old; i < last_old;)
4443 if (old_lines[i]
4444 && old_lines[i]->old_uses == 1
4445 && old_lines[i]->new_uses == 1)
4447 int p, q;
4448 int new_line = old_lines[i]->new_line_number;
4449 struct run *run = run_pool + run_idx++;
4451 /* Record move. */
4452 run->current_vpos = i;
4453 run->current_y = MATRIX_ROW (current_matrix, i)->y;
4454 run->desired_vpos = new_line;
4455 run->desired_y = MATRIX_ROW (desired_matrix, new_line)->y;
4456 run->nrows = 1;
4457 run->height = MATRIX_ROW (current_matrix, i)->height;
4459 /* Extend backward. */
4460 p = i - 1;
4461 q = new_line - 1;
4462 while (p > first_old
4463 && q > first_new
4464 && old_lines[p] == new_lines[q])
4466 int h = MATRIX_ROW (current_matrix, p)->height;
4467 --run->current_vpos;
4468 --run->desired_vpos;
4469 ++run->nrows;
4470 run->height += h;
4471 run->desired_y -= h;
4472 run->current_y -= h;
4473 --p, --q;
4476 /* Extend forward. */
4477 p = i + 1;
4478 q = new_line + 1;
4479 while (p < last_old
4480 && q < last_new
4481 && old_lines[p] == new_lines[q])
4483 int h = MATRIX_ROW (current_matrix, p)->height;
4484 ++run->nrows;
4485 run->height += h;
4486 ++p, ++q;
4489 /* Insert run into list of all runs. Order runs by copied
4490 pixel lines. Note that we record runs that don't have to
4491 be copied because they are already in place. This is done
4492 because we can avoid calling update_window_line in this
4493 case. */
4494 for (p = 0; p < nruns && runs[p]->height > run->height; ++p)
4496 for (q = nruns; q > p; --q)
4497 runs[q] = runs[q - 1];
4498 runs[p] = run;
4499 ++nruns;
4501 i += run->nrows;
4503 else
4504 ++i;
4506 /* Do the moves. Do it in a way that we don't overwrite something
4507 we want to copy later on. This is not solvable in general
4508 because there is only one display and we don't have a way to
4509 exchange areas on this display. Example:
4511 +-----------+ +-----------+
4512 | A | | B |
4513 +-----------+ --> +-----------+
4514 | B | | A |
4515 +-----------+ +-----------+
4517 Instead, prefer bigger moves, and invalidate moves that would
4518 copy from where we copied to. */
4520 for (i = 0; i < nruns; ++i)
4521 if (runs[i]->nrows > 0)
4523 struct run *r = runs[i];
4525 /* Copy on the display. */
4526 if (r->current_y != r->desired_y)
4528 rif->clear_window_mouse_face (w);
4529 rif->scroll_run_hook (w, r);
4531 /* Invalidate runs that copy from where we copied to. */
4532 for (j = i + 1; j < nruns; ++j)
4534 struct run *p = runs[j];
4536 if ((p->current_y >= r->desired_y
4537 && p->current_y < r->desired_y + r->height)
4538 || (p->current_y + p->height >= r->desired_y
4539 && (p->current_y + p->height
4540 < r->desired_y + r->height)))
4541 p->nrows = 0;
4545 /* Assign matrix rows. */
4546 for (j = 0; j < r->nrows; ++j)
4548 struct glyph_row *from, *to;
4549 int to_overlapped_p;
4551 to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
4552 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
4553 to_overlapped_p = to->overlapped_p;
4554 from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
4555 assign_row (to, from);
4556 to->enabled_p = 1, from->enabled_p = 0;
4557 to->overlapped_p = to_overlapped_p;
4561 /* Clear the hash table, for the next time. */
4562 for (i = 0; i < row_entry_idx; ++i)
4563 row_table[row_entry_pool[i].bucket] = NULL;
4565 /* Value is 1 to indicate that we scrolled the display. */
4566 return 0 < nruns;
4571 /************************************************************************
4572 Frame-Based Updates
4573 ************************************************************************/
4575 /* Update the desired frame matrix of frame F.
4577 FORCE_P non-zero means that the update should not be stopped by
4578 pending input. INHIBIT_HAIRY_ID_P non-zero means that scrolling
4579 should not be tried.
4581 Value is non-zero if update was stopped due to pending input. */
4583 static int
4584 update_frame_1 (struct frame *f, int force_p, int inhibit_id_p)
4586 /* Frame matrices to work on. */
4587 struct glyph_matrix *current_matrix = f->current_matrix;
4588 struct glyph_matrix *desired_matrix = f->desired_matrix;
4589 int i;
4590 int pause_p;
4591 int preempt_count = baud_rate / 2400 + 1;
4593 xassert (current_matrix && desired_matrix);
4595 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4596 calculate_costs (f);
4598 if (preempt_count <= 0)
4599 preempt_count = 1;
4601 #if !PERIODIC_PREEMPTION_CHECKING
4602 if (!force_p && detect_input_pending_ignore_squeezables ())
4604 pause_p = 1;
4605 goto do_pause;
4607 #endif
4609 /* If we cannot insert/delete lines, it's no use trying it. */
4610 if (!FRAME_LINE_INS_DEL_OK (f))
4611 inhibit_id_p = 1;
4613 /* See if any of the desired lines are enabled; don't compute for
4614 i/d line if just want cursor motion. */
4615 for (i = 0; i < desired_matrix->nrows; i++)
4616 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4617 break;
4619 /* Try doing i/d line, if not yet inhibited. */
4620 if (!inhibit_id_p && i < desired_matrix->nrows)
4621 force_p |= scrolling (f);
4623 /* Update the individual lines as needed. Do bottom line first. */
4624 if (MATRIX_ROW_ENABLED_P (desired_matrix, desired_matrix->nrows - 1))
4625 update_frame_line (f, desired_matrix->nrows - 1);
4627 /* Now update the rest of the lines. */
4628 for (i = 0; i < desired_matrix->nrows - 1 && (force_p || !input_pending); i++)
4630 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4632 if (FRAME_TERMCAP_P (f))
4634 /* Flush out every so many lines.
4635 Also flush out if likely to have more than 1k buffered
4636 otherwise. I'm told that some telnet connections get
4637 really screwed by more than 1k output at once. */
4638 FILE *display_output = FRAME_TTY (f)->output;
4639 if (display_output)
4641 int outq = PENDING_OUTPUT_COUNT (display_output);
4642 if (outq > 900
4643 || (outq > 20 && ((i - 1) % preempt_count == 0)))
4645 fflush (display_output);
4646 if (preempt_count == 1)
4648 #ifdef EMACS_OUTQSIZE
4649 if (EMACS_OUTQSIZE (0, &outq) < 0)
4650 /* Probably not a tty. Ignore the error and reset
4651 the outq count. */
4652 outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f->output));
4653 #endif
4654 outq *= 10;
4655 if (baud_rate <= outq && baud_rate > 0)
4656 sleep (outq / baud_rate);
4662 #if PERIODIC_PREEMPTION_CHECKING
4663 if (!force_p)
4665 EMACS_TIME tm, dif;
4666 EMACS_GET_TIME (tm);
4667 EMACS_SUB_TIME (dif, preemption_next_check, tm);
4668 if (EMACS_TIME_NEG_P (dif))
4670 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
4671 if (detect_input_pending_ignore_squeezables ())
4672 break;
4675 #else
4676 if (!force_p && (i - 1) % preempt_count == 0)
4677 detect_input_pending_ignore_squeezables ();
4678 #endif
4680 update_frame_line (f, i);
4684 pause_p = (i < FRAME_LINES (f) - 1) ? i : 0;
4686 /* Now just clean up termcap drivers and set cursor, etc. */
4687 if (!pause_p)
4689 if ((cursor_in_echo_area
4690 /* If we are showing a message instead of the mini-buffer,
4691 show the cursor for the message instead of for the
4692 (now hidden) mini-buffer contents. */
4693 || (EQ (minibuf_window, selected_window)
4694 && EQ (minibuf_window, echo_area_window)
4695 && !NILP (echo_area_buffer[0])))
4696 /* These cases apply only to the frame that contains
4697 the active mini-buffer window. */
4698 && FRAME_HAS_MINIBUF_P (f)
4699 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4701 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
4702 int row, col;
4704 if (cursor_in_echo_area < 0)
4706 /* Negative value of cursor_in_echo_area means put
4707 cursor at beginning of line. */
4708 row = top;
4709 col = 0;
4711 else
4713 /* Positive value of cursor_in_echo_area means put
4714 cursor at the end of the prompt. If the mini-buffer
4715 is several lines high, find the last line that has
4716 any text on it. */
4717 row = FRAME_LINES (f);
4720 --row;
4721 col = 0;
4723 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
4725 /* Frame rows are filled up with spaces that
4726 must be ignored here. */
4727 struct glyph_row *r = MATRIX_ROW (current_matrix,
4728 row);
4729 struct glyph *start = r->glyphs[TEXT_AREA];
4730 struct glyph *last = start + r->used[TEXT_AREA];
4732 while (last > start
4733 && (last - 1)->charpos < 0)
4734 --last;
4736 col = last - start;
4739 while (row > top && col == 0);
4741 /* Make sure COL is not out of range. */
4742 if (col >= FRAME_CURSOR_X_LIMIT (f))
4744 /* If we have another row, advance cursor into it. */
4745 if (row < FRAME_LINES (f) - 1)
4747 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
4748 row++;
4750 /* Otherwise move it back in range. */
4751 else
4752 col = FRAME_CURSOR_X_LIMIT (f) - 1;
4756 cursor_to (f, row, col);
4758 else
4760 /* We have only one cursor on terminal frames. Use it to
4761 display the cursor of the selected window. */
4762 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
4763 if (w->cursor.vpos >= 0
4764 /* The cursor vpos may be temporarily out of bounds
4765 in the following situation: There is one window,
4766 with the cursor in the lower half of it. The window
4767 is split, and a message causes a redisplay before
4768 a new cursor position has been computed. */
4769 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
4771 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
4772 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
4774 if (INTEGERP (w->left_margin_cols))
4775 x += XFASTINT (w->left_margin_cols);
4777 /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
4778 cursor_to (f, y, x);
4783 #if !PERIODIC_PREEMPTION_CHECKING
4784 do_pause:
4785 #endif
4787 clear_desired_matrices (f);
4788 return pause_p;
4792 /* Do line insertions/deletions on frame F for frame-based redisplay. */
4794 static int
4795 scrolling (struct frame *frame)
4797 int unchanged_at_top, unchanged_at_bottom;
4798 int window_size;
4799 int changed_lines;
4800 int *old_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
4801 int *new_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
4802 int *draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
4803 int *old_draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
4804 register int i;
4805 int free_at_end_vpos = FRAME_LINES (frame);
4806 struct glyph_matrix *current_matrix = frame->current_matrix;
4807 struct glyph_matrix *desired_matrix = frame->desired_matrix;
4809 if (!current_matrix)
4810 abort ();
4812 /* Compute hash codes of all the lines. Also calculate number of
4813 changed lines, number of unchanged lines at the beginning, and
4814 number of unchanged lines at the end. */
4815 changed_lines = 0;
4816 unchanged_at_top = 0;
4817 unchanged_at_bottom = FRAME_LINES (frame);
4818 for (i = 0; i < FRAME_LINES (frame); i++)
4820 /* Give up on this scrolling if some old lines are not enabled. */
4821 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
4822 return 0;
4823 old_hash[i] = line_hash_code (MATRIX_ROW (current_matrix, i));
4824 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
4826 /* This line cannot be redrawn, so don't let scrolling mess it. */
4827 new_hash[i] = old_hash[i];
4828 #define INFINITY 1000000 /* Taken from scroll.c */
4829 draw_cost[i] = INFINITY;
4831 else
4833 new_hash[i] = line_hash_code (MATRIX_ROW (desired_matrix, i));
4834 draw_cost[i] = line_draw_cost (desired_matrix, i);
4837 if (old_hash[i] != new_hash[i])
4839 changed_lines++;
4840 unchanged_at_bottom = FRAME_LINES (frame) - i - 1;
4842 else if (i == unchanged_at_top)
4843 unchanged_at_top++;
4844 old_draw_cost[i] = line_draw_cost (current_matrix, i);
4847 /* If changed lines are few, don't allow preemption, don't scroll. */
4848 if ((!FRAME_SCROLL_REGION_OK (frame)
4849 && changed_lines < baud_rate / 2400)
4850 || unchanged_at_bottom == FRAME_LINES (frame))
4851 return 1;
4853 window_size = (FRAME_LINES (frame) - unchanged_at_top
4854 - unchanged_at_bottom);
4856 if (FRAME_SCROLL_REGION_OK (frame))
4857 free_at_end_vpos -= unchanged_at_bottom;
4858 else if (FRAME_MEMORY_BELOW_FRAME (frame))
4859 free_at_end_vpos = -1;
4861 /* If large window, fast terminal and few lines in common between
4862 current frame and desired frame, don't bother with i/d calc. */
4863 if (!FRAME_SCROLL_REGION_OK (frame)
4864 && window_size >= 18 && baud_rate > 2400
4865 && (window_size >=
4866 10 * scrolling_max_lines_saved (unchanged_at_top,
4867 FRAME_LINES (frame) - unchanged_at_bottom,
4868 old_hash, new_hash, draw_cost)))
4869 return 0;
4871 if (window_size < 2)
4872 return 0;
4874 scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
4875 draw_cost + unchanged_at_top - 1,
4876 old_draw_cost + unchanged_at_top - 1,
4877 old_hash + unchanged_at_top - 1,
4878 new_hash + unchanged_at_top - 1,
4879 free_at_end_vpos - unchanged_at_top);
4881 return 0;
4885 /* Count the number of blanks at the start of the vector of glyphs R
4886 which is LEN glyphs long. */
4888 static int
4889 count_blanks (struct glyph *r, int len)
4891 int i;
4893 for (i = 0; i < len; ++i)
4894 if (!CHAR_GLYPH_SPACE_P (r[i]))
4895 break;
4897 return i;
4901 /* Count the number of glyphs in common at the start of the glyph
4902 vectors STR1 and STR2. END1 is the end of STR1 and END2 is the end
4903 of STR2. Value is the number of equal glyphs equal at the start. */
4905 static int
4906 count_match (struct glyph *str1, struct glyph *end1, struct glyph *str2, struct glyph *end2)
4908 struct glyph *p1 = str1;
4909 struct glyph *p2 = str2;
4911 while (p1 < end1
4912 && p2 < end2
4913 && GLYPH_CHAR_AND_FACE_EQUAL_P (p1, p2))
4914 ++p1, ++p2;
4916 return p1 - str1;
4920 /* Char insertion/deletion cost vector, from term.c */
4922 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS((f))])
4925 /* Perform a frame-based update on line VPOS in frame FRAME. */
4927 static void
4928 update_frame_line (struct frame *f, int vpos)
4930 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
4931 int tem;
4932 int osp, nsp, begmatch, endmatch, olen, nlen;
4933 struct glyph_matrix *current_matrix = f->current_matrix;
4934 struct glyph_matrix *desired_matrix = f->desired_matrix;
4935 struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
4936 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
4937 int must_write_whole_line_p;
4938 int write_spaces_p = FRAME_MUST_WRITE_SPACES (f);
4939 int colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
4940 != FACE_TTY_DEFAULT_BG_COLOR);
4942 if (colored_spaces_p)
4943 write_spaces_p = 1;
4945 /* Current row not enabled means it has unknown contents. We must
4946 write the whole desired line in that case. */
4947 must_write_whole_line_p = !current_row->enabled_p;
4948 if (must_write_whole_line_p)
4950 obody = 0;
4951 olen = 0;
4953 else
4955 obody = MATRIX_ROW_GLYPH_START (current_matrix, vpos);
4956 olen = current_row->used[TEXT_AREA];
4958 /* Ignore trailing spaces, if we can. */
4959 if (!write_spaces_p)
4960 while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
4961 olen--;
4964 current_row->enabled_p = 1;
4965 current_row->used[TEXT_AREA] = desired_row->used[TEXT_AREA];
4967 /* If desired line is empty, just clear the line. */
4968 if (!desired_row->enabled_p)
4970 nlen = 0;
4971 goto just_erase;
4974 nbody = desired_row->glyphs[TEXT_AREA];
4975 nlen = desired_row->used[TEXT_AREA];
4976 nend = nbody + nlen;
4978 /* If display line has unknown contents, write the whole line. */
4979 if (must_write_whole_line_p)
4981 /* Ignore spaces at the end, if we can. */
4982 if (!write_spaces_p)
4983 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
4984 --nlen;
4986 /* Write the contents of the desired line. */
4987 if (nlen)
4989 cursor_to (f, vpos, 0);
4990 write_glyphs (f, nbody, nlen);
4993 /* Don't call clear_end_of_line if we already wrote the whole
4994 line. The cursor will not be at the right margin in that
4995 case but in the line below. */
4996 if (nlen < FRAME_TOTAL_COLS (f))
4998 cursor_to (f, vpos, nlen);
4999 clear_end_of_line (f, FRAME_TOTAL_COLS (f));
5001 else
5002 /* Make sure we are in the right row, otherwise cursor movement
5003 with cmgoto might use `ch' in the wrong row. */
5004 cursor_to (f, vpos, 0);
5006 make_current (desired_matrix, current_matrix, vpos);
5007 return;
5010 /* Pretend trailing spaces are not there at all,
5011 unless for one reason or another we must write all spaces. */
5012 if (!write_spaces_p)
5013 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
5014 nlen--;
5016 /* If there's no i/d char, quickly do the best we can without it. */
5017 if (!FRAME_CHAR_INS_DEL_OK (f))
5019 int i, j;
5021 /* Find the first glyph in desired row that doesn't agree with
5022 a glyph in the current row, and write the rest from there on. */
5023 for (i = 0; i < nlen; i++)
5025 if (i >= olen || !GLYPH_EQUAL_P (nbody + i, obody + i))
5027 /* Find the end of the run of different glyphs. */
5028 j = i + 1;
5029 while (j < nlen
5030 && (j >= olen
5031 || !GLYPH_EQUAL_P (nbody + j, obody + j)
5032 || CHAR_GLYPH_PADDING_P (nbody[j])))
5033 ++j;
5035 /* Output this run of non-matching chars. */
5036 cursor_to (f, vpos, i);
5037 write_glyphs (f, nbody + i, j - i);
5038 i = j - 1;
5040 /* Now find the next non-match. */
5044 /* Clear the rest of the line, or the non-clear part of it. */
5045 if (olen > nlen)
5047 cursor_to (f, vpos, nlen);
5048 clear_end_of_line (f, olen);
5051 /* Make current row = desired row. */
5052 make_current (desired_matrix, current_matrix, vpos);
5053 return;
5056 /* Here when CHAR_INS_DEL_OK != 0, i.e. we can insert or delete
5057 characters in a row. */
5059 if (!olen)
5061 /* If current line is blank, skip over initial spaces, if
5062 possible, and write the rest. */
5063 if (write_spaces_p)
5064 nsp = 0;
5065 else
5066 nsp = count_blanks (nbody, nlen);
5068 if (nlen > nsp)
5070 cursor_to (f, vpos, nsp);
5071 write_glyphs (f, nbody + nsp, nlen - nsp);
5074 /* Exchange contents between current_frame and new_frame. */
5075 make_current (desired_matrix, current_matrix, vpos);
5076 return;
5079 /* Compute number of leading blanks in old and new contents. */
5080 osp = count_blanks (obody, olen);
5081 nsp = (colored_spaces_p ? 0 : count_blanks (nbody, nlen));
5083 /* Compute number of matching chars starting with first non-blank. */
5084 begmatch = count_match (obody + osp, obody + olen,
5085 nbody + nsp, nbody + nlen);
5087 /* Spaces in new match implicit space past the end of old. */
5088 /* A bug causing this to be a no-op was fixed in 18.29. */
5089 if (!write_spaces_p && osp + begmatch == olen)
5091 np1 = nbody + nsp;
5092 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (np1[begmatch]))
5093 ++begmatch;
5096 /* Avoid doing insert/delete char
5097 just cause number of leading spaces differs
5098 when the following text does not match. */
5099 if (begmatch == 0 && osp != nsp)
5100 osp = nsp = min (osp, nsp);
5102 /* Find matching characters at end of line */
5103 op1 = obody + olen;
5104 np1 = nbody + nlen;
5105 op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
5106 while (op1 > op2
5107 && GLYPH_EQUAL_P (op1 - 1, np1 - 1))
5109 op1--;
5110 np1--;
5112 endmatch = obody + olen - op1;
5114 /* tem gets the distance to insert or delete.
5115 endmatch is how many characters we save by doing so.
5116 Is it worth it? */
5118 tem = (nlen - nsp) - (olen - osp);
5119 if (endmatch && tem
5120 && (!FRAME_CHAR_INS_DEL_OK (f)
5121 || endmatch <= char_ins_del_cost (f)[tem]))
5122 endmatch = 0;
5124 /* nsp - osp is the distance to insert or delete.
5125 If that is nonzero, begmatch is known to be nonzero also.
5126 begmatch + endmatch is how much we save by doing the ins/del.
5127 Is it worth it? */
5129 if (nsp != osp
5130 && (!FRAME_CHAR_INS_DEL_OK (f)
5131 || begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]))
5133 begmatch = 0;
5134 endmatch = 0;
5135 osp = nsp = min (osp, nsp);
5138 /* Now go through the line, inserting, writing and
5139 deleting as appropriate. */
5141 if (osp > nsp)
5143 cursor_to (f, vpos, nsp);
5144 delete_glyphs (f, osp - nsp);
5146 else if (nsp > osp)
5148 /* If going to delete chars later in line
5149 and insert earlier in the line,
5150 must delete first to avoid losing data in the insert */
5151 if (endmatch && nlen < olen + nsp - osp)
5153 cursor_to (f, vpos, nlen - endmatch + osp - nsp);
5154 delete_glyphs (f, olen + nsp - osp - nlen);
5155 olen = nlen - (nsp - osp);
5157 cursor_to (f, vpos, osp);
5158 insert_glyphs (f, 0, nsp - osp);
5160 olen += nsp - osp;
5162 tem = nsp + begmatch + endmatch;
5163 if (nlen != tem || olen != tem)
5165 if (!endmatch || nlen == olen)
5167 /* If new text being written reaches right margin, there is
5168 no need to do clear-to-eol at the end of this function
5169 (and it would not be safe, since cursor is not going to
5170 be "at the margin" after the text is done). */
5171 if (nlen == FRAME_TOTAL_COLS (f))
5172 olen = 0;
5174 /* Function write_glyphs is prepared to do nothing
5175 if passed a length <= 0. Check it here to avoid
5176 unnecessary cursor movement. */
5177 if (nlen - tem > 0)
5179 cursor_to (f, vpos, nsp + begmatch);
5180 write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
5183 else if (nlen > olen)
5185 /* Here, we used to have the following simple code:
5186 ----------------------------------------
5187 write_glyphs (nbody + nsp + begmatch, olen - tem);
5188 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
5189 ----------------------------------------
5190 but it doesn't work if nbody[nsp + begmatch + olen - tem]
5191 is a padding glyph. */
5192 int out = olen - tem; /* Columns to be overwritten originally. */
5193 int del;
5195 cursor_to (f, vpos, nsp + begmatch);
5197 /* Calculate columns we can actually overwrite. */
5198 while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out]))
5199 out--;
5200 write_glyphs (f, nbody + nsp + begmatch, out);
5202 /* If we left columns to be overwritten, we must delete them. */
5203 del = olen - tem - out;
5204 if (del > 0)
5205 delete_glyphs (f, del);
5207 /* At last, we insert columns not yet written out. */
5208 insert_glyphs (f, nbody + nsp + begmatch + out, nlen - olen + del);
5209 olen = nlen;
5211 else if (olen > nlen)
5213 cursor_to (f, vpos, nsp + begmatch);
5214 write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
5215 delete_glyphs (f, olen - nlen);
5216 olen = nlen;
5220 just_erase:
5221 /* If any unerased characters remain after the new line, erase them. */
5222 if (olen > nlen)
5224 cursor_to (f, vpos, nlen);
5225 clear_end_of_line (f, olen);
5228 /* Exchange contents between current_frame and new_frame. */
5229 make_current (desired_matrix, current_matrix, vpos);
5234 /***********************************************************************
5235 X/Y Position -> Buffer Position
5236 ***********************************************************************/
5238 /* Determine what's under window-relative pixel position (*X, *Y).
5239 Return the OBJECT (string or buffer) that's there.
5240 Return in *POS the position in that object.
5241 Adjust *X and *Y to character positions.
5242 Return in *DX and *DY the pixel coordinates of the click,
5243 relative to the top left corner of OBJECT, or relative to
5244 the top left corner of the character glyph at (*X, *Y)
5245 if OBJECT is nil.
5246 Return WIDTH and HEIGHT of the object at (*X, *Y), or zero
5247 if the coordinates point to an empty area of the display. */
5249 Lisp_Object
5250 buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *pos, Lisp_Object *object, int *dx, int *dy, int *width, int *height)
5252 struct it it;
5253 Lisp_Object old_current_buffer = Fcurrent_buffer ();
5254 struct text_pos startp;
5255 Lisp_Object string;
5256 struct glyph_row *row;
5257 #ifdef HAVE_WINDOW_SYSTEM
5258 struct image *img = 0;
5259 #endif
5260 int x0, x1, to_x;
5261 void *itdata = NULL;
5263 /* We used to set current_buffer directly here, but that does the
5264 wrong thing with `face-remapping-alist' (bug#2044). */
5265 Fset_buffer (w->buffer);
5266 itdata = bidi_shelve_cache ();
5267 SET_TEXT_POS_FROM_MARKER (startp, w->start);
5268 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
5269 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
5270 start_display (&it, w, startp);
5272 x0 = *x;
5274 /* First, move to the beginning of the row corresponding to *Y. We
5275 need to be in that row to get the correct value of base paragraph
5276 direction for the text at (*X, *Y). */
5277 move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y);
5279 /* TO_X is the pixel position that the iterator will compute for the
5280 glyph at *X. We add it.first_visible_x because iterator
5281 positions include the hscroll. */
5282 to_x = x0 + it.first_visible_x;
5283 if (it.bidi_it.paragraph_dir == R2L)
5284 /* For lines in an R2L paragraph, we need to mirror TO_X wrt the
5285 text area. This is because the iterator, even in R2L
5286 paragraphs, delivers glyphs as if they started at the left
5287 margin of the window. (When we actually produce glyphs for
5288 display, we reverse their order in PRODUCE_GLYPHS, but the
5289 iterator doesn't know about that.) The following line adjusts
5290 the pixel position to the iterator geometry, which is what
5291 move_it_* routines use. (The -1 is because in a window whose
5292 text-area width is W, the rightmost pixel position is W-1, and
5293 it should be mirrored into zero pixel position.) */
5294 to_x = window_box_width (w, TEXT_AREA) - to_x - 1;
5296 /* Now move horizontally in the row to the glyph under *X. Second
5297 argument is ZV to prevent move_it_in_display_line from matching
5298 based on buffer positions. */
5299 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
5300 bidi_unshelve_cache (itdata, 0);
5302 Fset_buffer (old_current_buffer);
5304 *dx = x0 + it.first_visible_x - it.current_x;
5305 *dy = *y - it.current_y;
5307 string = w->buffer;
5308 if (STRINGP (it.string))
5309 string = it.string;
5310 *pos = it.current;
5311 if (it.what == IT_COMPOSITION
5312 && it.cmp_it.nchars > 1
5313 && it.cmp_it.reversed_p)
5315 /* The current display element is a grapheme cluster in a
5316 composition. In that case, we need the position of the first
5317 character of the cluster. But, as it.cmp_it.reversed_p is 1,
5318 it.current points to the last character of the cluster, thus
5319 we must move back to the first character of the same
5320 cluster. */
5321 CHARPOS (pos->pos) -= it.cmp_it.nchars - 1;
5322 if (STRINGP (it.string))
5323 BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
5324 else
5325 BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->buffer),
5326 CHARPOS (pos->pos));
5329 #ifdef HAVE_WINDOW_SYSTEM
5330 if (it.what == IT_IMAGE)
5332 if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL
5333 && !NILP (img->spec))
5334 *object = img->spec;
5336 #endif
5338 if (it.vpos < w->current_matrix->nrows
5339 && (row = MATRIX_ROW (w->current_matrix, it.vpos),
5340 row->enabled_p))
5342 if (it.hpos < row->used[TEXT_AREA])
5344 struct glyph *glyph = row->glyphs[TEXT_AREA] + it.hpos;
5345 #ifdef HAVE_WINDOW_SYSTEM
5346 if (img)
5348 *dy -= row->ascent - glyph->ascent;
5349 *dx += glyph->slice.img.x;
5350 *dy += glyph->slice.img.y;
5351 /* Image slices positions are still relative to the entire image */
5352 *width = img->width;
5353 *height = img->height;
5355 else
5356 #endif
5358 *width = glyph->pixel_width;
5359 *height = glyph->ascent + glyph->descent;
5362 else
5364 *width = 0;
5365 *height = row->height;
5368 else
5370 *width = *height = 0;
5373 /* Add extra (default width) columns if clicked after EOL. */
5374 x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
5375 if (x0 > x1)
5376 it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
5378 *x = it.hpos;
5379 *y = it.vpos;
5381 return string;
5385 /* Value is the string under window-relative coordinates X/Y in the
5386 mode line or header line (PART says which) of window W, or nil if none.
5387 *CHARPOS is set to the position in the string returned. */
5389 Lisp_Object
5390 mode_line_string (struct window *w, enum window_part part,
5391 int *x, int *y, EMACS_INT *charpos, Lisp_Object *object,
5392 int *dx, int *dy, int *width, int *height)
5394 struct glyph_row *row;
5395 struct glyph *glyph, *end;
5396 int x0, y0;
5397 Lisp_Object string = Qnil;
5399 if (part == ON_MODE_LINE)
5400 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
5401 else
5402 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
5403 y0 = *y - row->y;
5404 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5406 if (row->mode_line_p && row->enabled_p)
5408 /* Find the glyph under X. If we find one with a string object,
5409 it's the one we were looking for. */
5410 glyph = row->glyphs[TEXT_AREA];
5411 end = glyph + row->used[TEXT_AREA];
5412 for (x0 = *x; glyph < end && x0 >= glyph->pixel_width; ++glyph)
5413 x0 -= glyph->pixel_width;
5414 *x = glyph - row->glyphs[TEXT_AREA];
5415 if (glyph < end)
5417 string = glyph->object;
5418 *charpos = glyph->charpos;
5419 *width = glyph->pixel_width;
5420 *height = glyph->ascent + glyph->descent;
5421 #ifdef HAVE_WINDOW_SYSTEM
5422 if (glyph->type == IMAGE_GLYPH)
5424 struct image *img;
5425 img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
5426 if (img != NULL)
5427 *object = img->spec;
5428 y0 -= row->ascent - glyph->ascent;
5430 #endif
5432 else
5434 /* Add extra (default width) columns if clicked after EOL. */
5435 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5436 *width = 0;
5437 *height = row->height;
5440 else
5442 *x = 0;
5443 x0 = 0;
5444 *width = *height = 0;
5447 *dx = x0;
5448 *dy = y0;
5450 return string;
5454 /* Value is the string under window-relative coordinates X/Y in either
5455 marginal area, or nil if none. *CHARPOS is set to the position in
5456 the string returned. */
5458 Lisp_Object
5459 marginal_area_string (struct window *w, enum window_part part,
5460 int *x, int *y, EMACS_INT *charpos, Lisp_Object *object,
5461 int *dx, int *dy, int *width, int *height)
5463 struct glyph_row *row = w->current_matrix->rows;
5464 struct glyph *glyph, *end;
5465 int x0, y0, i, wy = *y;
5466 int area;
5467 Lisp_Object string = Qnil;
5469 if (part == ON_LEFT_MARGIN)
5470 area = LEFT_MARGIN_AREA;
5471 else if (part == ON_RIGHT_MARGIN)
5472 area = RIGHT_MARGIN_AREA;
5473 else
5474 abort ();
5476 for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row)
5477 if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row))
5478 break;
5479 y0 = *y - row->y;
5480 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5482 if (row->enabled_p)
5484 /* Find the glyph under X. If we find one with a string object,
5485 it's the one we were looking for. */
5486 if (area == RIGHT_MARGIN_AREA)
5487 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5488 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5489 : WINDOW_TOTAL_FRINGE_WIDTH (w))
5490 + window_box_width (w, LEFT_MARGIN_AREA)
5491 + window_box_width (w, TEXT_AREA));
5492 else
5493 x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5494 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5495 : 0);
5497 glyph = row->glyphs[area];
5498 end = glyph + row->used[area];
5499 for (x0 = *x - x0; glyph < end && x0 >= glyph->pixel_width; ++glyph)
5500 x0 -= glyph->pixel_width;
5501 *x = glyph - row->glyphs[area];
5502 if (glyph < end)
5504 string = glyph->object;
5505 *charpos = glyph->charpos;
5506 *width = glyph->pixel_width;
5507 *height = glyph->ascent + glyph->descent;
5508 #ifdef HAVE_WINDOW_SYSTEM
5509 if (glyph->type == IMAGE_GLYPH)
5511 struct image *img;
5512 img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
5513 if (img != NULL)
5514 *object = img->spec;
5515 y0 -= row->ascent - glyph->ascent;
5516 x0 += glyph->slice.img.x;
5517 y0 += glyph->slice.img.y;
5519 #endif
5521 else
5523 /* Add extra (default width) columns if clicked after EOL. */
5524 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5525 *width = 0;
5526 *height = row->height;
5529 else
5531 x0 = 0;
5532 *x = 0;
5533 *width = *height = 0;
5536 *dx = x0;
5537 *dy = y0;
5539 return string;
5543 /***********************************************************************
5544 Changing Frame Sizes
5545 ***********************************************************************/
5547 #ifdef SIGWINCH
5549 static void
5550 window_change_signal (int signalnum) /* If we don't have an argument, */
5551 /* some compilers complain in signal calls. */
5553 int width, height;
5554 int old_errno = errno;
5556 struct tty_display_info *tty;
5558 signal (SIGWINCH, window_change_signal);
5559 SIGNAL_THREAD_CHECK (signalnum);
5561 /* The frame size change obviously applies to a single
5562 termcap-controlled terminal, but we can't decide which.
5563 Therefore, we resize the frames corresponding to each tty.
5565 for (tty = tty_list; tty; tty = tty->next) {
5567 if (! tty->term_initted)
5568 continue;
5570 /* Suspended tty frames have tty->input == NULL avoid trying to
5571 use it. */
5572 if (!tty->input)
5573 continue;
5575 get_tty_size (fileno (tty->input), &width, &height);
5577 if (width > 5 && height > 2) {
5578 Lisp_Object tail, frame;
5580 FOR_EACH_FRAME (tail, frame)
5581 if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
5582 /* Record the new sizes, but don't reallocate the data
5583 structures now. Let that be done later outside of the
5584 signal handler. */
5585 change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
5589 errno = old_errno;
5591 #endif /* SIGWINCH */
5594 /* Do any change in frame size that was requested by a signal. SAFE
5595 non-zero means this function is called from a place where it is
5596 safe to change frame sizes while a redisplay is in progress. */
5598 void
5599 do_pending_window_change (int safe)
5601 /* If window_change_signal should have run before, run it now. */
5602 if (redisplaying_p && !safe)
5603 return;
5605 while (delayed_size_change)
5607 Lisp_Object tail, frame;
5609 delayed_size_change = 0;
5611 FOR_EACH_FRAME (tail, frame)
5613 struct frame *f = XFRAME (frame);
5615 if (f->new_text_lines != 0 || f->new_text_cols != 0)
5616 change_frame_size (f, f->new_text_lines, f->new_text_cols,
5617 0, 0, safe);
5623 /* Change the frame height and/or width. Values may be given as zero to
5624 indicate no change is to take place.
5626 If DELAY is non-zero, then assume we're being called from a signal
5627 handler, and queue the change for later - perhaps the next
5628 redisplay. Since this tries to resize windows, we can't call it
5629 from a signal handler.
5631 SAFE non-zero means this function is called from a place where it's
5632 safe to change frame sizes while a redisplay is in progress. */
5634 void
5635 change_frame_size (register struct frame *f, int newheight, int newwidth, int pretend, int delay, int safe)
5637 Lisp_Object tail, frame;
5639 if (FRAME_MSDOS_P (f))
5641 /* On MS-DOS, all frames use the same screen, so a change in
5642 size affects all frames. Termcap now supports multiple
5643 ttys. */
5644 FOR_EACH_FRAME (tail, frame)
5645 if (! FRAME_WINDOW_P (XFRAME (frame)))
5646 change_frame_size_1 (XFRAME (frame), newheight, newwidth,
5647 pretend, delay, safe);
5649 else
5650 change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe);
5653 static void
5654 change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int pretend, int delay, int safe)
5656 int new_frame_total_cols;
5657 int count = SPECPDL_INDEX ();
5659 /* If we can't deal with the change now, queue it for later. */
5660 if (delay || (redisplaying_p && !safe))
5662 f->new_text_lines = newheight;
5663 f->new_text_cols = newwidth;
5664 delayed_size_change = 1;
5665 return;
5668 /* This size-change overrides any pending one for this frame. */
5669 f->new_text_lines = 0;
5670 f->new_text_cols = 0;
5672 /* If an argument is zero, set it to the current value. */
5673 if (newheight == 0)
5674 newheight = FRAME_LINES (f);
5675 if (newwidth == 0)
5676 newwidth = FRAME_COLS (f);
5678 /* Compute width of windows in F.
5679 This is the width of the frame without vertical scroll bars. */
5680 new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth);
5682 /* Round up to the smallest acceptable size. */
5683 check_frame_size (f, &newheight, &newwidth);
5685 /* If we're not changing the frame size, quit now. */
5686 /* Frame width may be unchanged but the text portion may change, for example,
5687 fullscreen and remove/add scroll bar. */
5688 if (newheight == FRAME_LINES (f)
5689 && newwidth == FRAME_COLS (f) // text portion unchanged
5690 && new_frame_total_cols == FRAME_TOTAL_COLS (f)) // frame width unchanged
5691 return;
5693 BLOCK_INPUT;
5695 #ifdef MSDOS
5696 /* We only can set screen dimensions to certain values supported
5697 by our video hardware. Try to find the smallest size greater
5698 or equal to the requested dimensions. */
5699 dos_set_window_size (&newheight, &newwidth);
5700 #endif
5702 if (newheight != FRAME_LINES (f))
5704 resize_frame_windows (f, newheight, 0);
5706 /* MSDOS frames cannot PRETEND, as they change frame size by
5707 manipulating video hardware. */
5708 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
5709 FrameRows (FRAME_TTY (f)) = newheight;
5712 if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
5714 resize_frame_windows (f, new_frame_total_cols, 1);
5716 /* MSDOS frames cannot PRETEND, as they change frame size by
5717 manipulating video hardware. */
5718 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
5719 FrameCols (FRAME_TTY (f)) = newwidth;
5721 if (WINDOWP (f->tool_bar_window))
5722 XSETFASTINT (XWINDOW (f->tool_bar_window)->total_cols, newwidth);
5725 FRAME_LINES (f) = newheight;
5726 SET_FRAME_COLS (f, newwidth);
5729 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5730 int text_area_x, text_area_y, text_area_width, text_area_height;
5732 window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width,
5733 &text_area_height);
5734 if (w->cursor.x >= text_area_x + text_area_width)
5735 w->cursor.hpos = w->cursor.x = 0;
5736 if (w->cursor.y >= text_area_y + text_area_height)
5737 w->cursor.vpos = w->cursor.y = 0;
5740 adjust_glyphs (f);
5741 calculate_costs (f);
5742 SET_FRAME_GARBAGED (f);
5743 f->resized_p = 1;
5745 UNBLOCK_INPUT;
5747 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
5749 run_window_configuration_change_hook (f);
5751 unbind_to (count, Qnil);
5756 /***********************************************************************
5757 Terminal Related Lisp Functions
5758 ***********************************************************************/
5760 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
5761 1, 1, "FOpen termscript file: ",
5762 doc: /* Start writing all terminal output to FILE as well as the terminal.
5763 FILE = nil means just close any termscript file currently open. */)
5764 (Lisp_Object file)
5766 struct tty_display_info *tty;
5768 if (! FRAME_TERMCAP_P (SELECTED_FRAME ())
5769 && ! FRAME_MSDOS_P (SELECTED_FRAME ()))
5770 error ("Current frame is not on a tty device");
5772 tty = CURTTY ();
5774 if (tty->termscript != 0)
5776 BLOCK_INPUT;
5777 fclose (tty->termscript);
5778 UNBLOCK_INPUT;
5780 tty->termscript = 0;
5782 if (! NILP (file))
5784 file = Fexpand_file_name (file, Qnil);
5785 tty->termscript = fopen (SSDATA (file), "w");
5786 if (tty->termscript == 0)
5787 report_file_error ("Opening termscript", Fcons (file, Qnil));
5789 return Qnil;
5793 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
5794 Ssend_string_to_terminal, 1, 2, 0,
5795 doc: /* Send STRING to the terminal without alteration.
5796 Control characters in STRING will have terminal-dependent effects.
5798 Optional parameter TERMINAL specifies the tty terminal device to use.
5799 It may be a terminal object, a frame, or nil for the terminal used by
5800 the currently selected frame. In batch mode, STRING is sent to stdout
5801 when TERMINAL is nil. */)
5802 (Lisp_Object string, Lisp_Object terminal)
5804 struct terminal *t = get_terminal (terminal, 1);
5805 FILE *out;
5807 /* ??? Perhaps we should do something special for multibyte strings here. */
5808 CHECK_STRING (string);
5809 BLOCK_INPUT;
5811 if (!t)
5812 error ("Unknown terminal device");
5814 if (t->type == output_initial)
5815 out = stdout;
5816 else if (t->type != output_termcap && t->type != output_msdos_raw)
5817 error ("Device %d is not a termcap terminal device", t->id);
5818 else
5820 struct tty_display_info *tty = t->display_info.tty;
5822 if (! tty->output)
5823 error ("Terminal is currently suspended");
5825 if (tty->termscript)
5827 fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
5828 fflush (tty->termscript);
5830 out = tty->output;
5832 fwrite (SDATA (string), 1, SBYTES (string), out);
5833 fflush (out);
5834 UNBLOCK_INPUT;
5835 return Qnil;
5839 DEFUN ("ding", Fding, Sding, 0, 1, 0,
5840 doc: /* Beep, or flash the screen.
5841 Also, unless an argument is given,
5842 terminate any keyboard macro currently executing. */)
5843 (Lisp_Object arg)
5845 if (!NILP (arg))
5847 if (noninteractive)
5848 putchar (07);
5849 else
5850 ring_bell (XFRAME (selected_frame));
5852 else
5853 bitch_at_user ();
5855 return Qnil;
5858 void
5859 bitch_at_user (void)
5861 if (noninteractive)
5862 putchar (07);
5863 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
5864 error ("Keyboard macro terminated by a command ringing the bell");
5865 else
5866 ring_bell (XFRAME (selected_frame));
5871 /***********************************************************************
5872 Sleeping, Waiting
5873 ***********************************************************************/
5875 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
5876 doc: /* Pause, without updating display, for SECONDS seconds.
5877 SECONDS may be a floating-point value, meaning that you can wait for a
5878 fraction of a second. Optional second arg MILLISECONDS specifies an
5879 additional wait period, in milliseconds; this may be useful if your
5880 Emacs was built without floating point support.
5881 \(Not all operating systems support waiting for a fraction of a second.) */)
5882 (Lisp_Object seconds, Lisp_Object milliseconds)
5884 int sec, usec;
5886 if (NILP (milliseconds))
5887 XSETINT (milliseconds, 0);
5888 else
5889 CHECK_NUMBER (milliseconds);
5890 usec = XINT (milliseconds) * 1000;
5893 double duration = extract_float (seconds);
5894 sec = (int) duration;
5895 usec += (duration - sec) * 1000000;
5898 #ifndef EMACS_HAS_USECS
5899 if (sec == 0 && usec != 0)
5900 error ("Millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
5901 #endif
5903 /* Assure that 0 <= usec < 1000000. */
5904 if (usec < 0)
5906 /* We can't rely on the rounding being correct if usec is negative. */
5907 if (-1000000 < usec)
5908 sec--, usec += 1000000;
5909 else
5910 sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
5912 else
5913 sec += usec / 1000000, usec %= 1000000;
5915 if (sec < 0 || (sec == 0 && usec == 0))
5916 return Qnil;
5918 wait_reading_process_output (sec, usec, 0, 0, Qnil, NULL, 0);
5920 return Qnil;
5924 /* This is just like wait_reading_process_output, except that
5925 it does redisplay.
5927 TIMEOUT is number of seconds to wait (float or integer),
5928 or t to wait forever.
5929 READING is 1 if reading input.
5930 If DO_DISPLAY is >0 display process output while waiting.
5931 If DO_DISPLAY is >1 perform an initial redisplay before waiting.
5934 Lisp_Object
5935 sit_for (Lisp_Object timeout, int reading, int do_display)
5937 int sec, usec;
5939 swallow_events (do_display);
5941 if ((detect_input_pending_run_timers (do_display))
5942 || !NILP (Vexecuting_kbd_macro))
5943 return Qnil;
5945 if (do_display >= 2)
5946 redisplay_preserve_echo_area (2);
5948 if (INTEGERP (timeout))
5950 sec = XINT (timeout);
5951 usec = 0;
5953 else if (FLOATP (timeout))
5955 double seconds = XFLOAT_DATA (timeout);
5956 sec = (int) seconds;
5957 usec = (int) ((seconds - sec) * 1000000);
5959 else if (EQ (timeout, Qt))
5961 sec = 0;
5962 usec = 0;
5964 else
5965 wrong_type_argument (Qnumberp, timeout);
5967 if (sec == 0 && usec == 0 && !EQ (timeout, Qt))
5968 return Qt;
5970 #ifdef SIGIO
5971 gobble_input (0);
5972 #endif
5974 wait_reading_process_output (sec, usec, reading ? -1 : 1, do_display,
5975 Qnil, NULL, 0);
5977 return detect_input_pending () ? Qnil : Qt;
5981 DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0,
5982 doc: /* Perform redisplay if no input is available.
5983 If optional arg FORCE is non-nil or `redisplay-dont-pause' is non-nil,
5984 perform a full redisplay even if input is available.
5985 Return t if redisplay was performed, nil otherwise. */)
5986 (Lisp_Object force)
5988 int count;
5990 swallow_events (1);
5991 if ((detect_input_pending_run_timers (1)
5992 && NILP (force) && !redisplay_dont_pause)
5993 || !NILP (Vexecuting_kbd_macro))
5994 return Qnil;
5996 count = SPECPDL_INDEX ();
5997 if (!NILP (force) && !redisplay_dont_pause)
5998 specbind (Qredisplay_dont_pause, Qt);
5999 redisplay_preserve_echo_area (2);
6000 unbind_to (count, Qnil);
6001 return Qt;
6006 /***********************************************************************
6007 Other Lisp Functions
6008 ***********************************************************************/
6010 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
6011 session's frames, frame names, buffers, buffer-read-only flags, and
6012 buffer-modified-flags. */
6014 static Lisp_Object frame_and_buffer_state;
6017 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
6018 Sframe_or_buffer_changed_p, 0, 1, 0,
6019 doc: /* Return non-nil if the frame and buffer state appears to have changed.
6020 VARIABLE is a variable name whose value is either nil or a state vector
6021 that will be updated to contain all frames and buffers,
6022 aside from buffers whose names start with space,
6023 along with the buffers' read-only and modified flags. This allows a fast
6024 check to see whether buffer menus might need to be recomputed.
6025 If this function returns non-nil, it updates the internal vector to reflect
6026 the current state.
6028 If VARIABLE is nil, an internal variable is used. Users should not
6029 pass nil for VARIABLE. */)
6030 (Lisp_Object variable)
6032 Lisp_Object state, tail, frame, buf;
6033 Lisp_Object *vecp, *end;
6034 int n;
6036 if (! NILP (variable))
6038 CHECK_SYMBOL (variable);
6039 state = Fsymbol_value (variable);
6040 if (! VECTORP (state))
6041 goto changed;
6043 else
6044 state = frame_and_buffer_state;
6046 vecp = XVECTOR (state)->contents;
6047 end = vecp + ASIZE (state);
6049 FOR_EACH_FRAME (tail, frame)
6051 if (vecp == end)
6052 goto changed;
6053 if (!EQ (*vecp++, frame))
6054 goto changed;
6055 if (vecp == end)
6056 goto changed;
6057 if (!EQ (*vecp++, XFRAME (frame)->name))
6058 goto changed;
6060 /* Check that the buffer info matches. */
6061 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
6063 buf = XCDR (XCAR (tail));
6064 /* Ignore buffers that aren't included in buffer lists. */
6065 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
6066 continue;
6067 if (vecp == end)
6068 goto changed;
6069 if (!EQ (*vecp++, buf))
6070 goto changed;
6071 if (vecp == end)
6072 goto changed;
6073 if (!EQ (*vecp++, BVAR (XBUFFER (buf), read_only)))
6074 goto changed;
6075 if (vecp == end)
6076 goto changed;
6077 if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
6078 goto changed;
6080 if (vecp == end)
6081 goto changed;
6082 /* Detect deletion of a buffer at the end of the list. */
6083 if (EQ (*vecp, Qlambda))
6084 return Qnil;
6086 /* Come here if we decide the data has changed. */
6087 changed:
6088 /* Count the size we will need.
6089 Start with 1 so there is room for at least one lambda at the end. */
6090 n = 1;
6091 FOR_EACH_FRAME (tail, frame)
6092 n += 2;
6093 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
6094 n += 3;
6095 /* Reallocate the vector if data has grown to need it,
6096 or if it has shrunk a lot. */
6097 if (! VECTORP (state)
6098 || n > ASIZE (state)
6099 || n + 20 < ASIZE (state) / 2)
6100 /* Add 20 extra so we grow it less often. */
6102 state = Fmake_vector (make_number (n + 20), Qlambda);
6103 if (! NILP (variable))
6104 Fset (variable, state);
6105 else
6106 frame_and_buffer_state = state;
6109 /* Record the new data in the (possibly reallocated) vector. */
6110 vecp = XVECTOR (state)->contents;
6111 FOR_EACH_FRAME (tail, frame)
6113 *vecp++ = frame;
6114 *vecp++ = XFRAME (frame)->name;
6116 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
6118 buf = XCDR (XCAR (tail));
6119 /* Ignore buffers that aren't included in buffer lists. */
6120 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
6121 continue;
6122 *vecp++ = buf;
6123 *vecp++ = BVAR (XBUFFER (buf), read_only);
6124 *vecp++ = Fbuffer_modified_p (buf);
6126 /* Fill up the vector with lambdas (always at least one). */
6127 *vecp++ = Qlambda;
6128 while (vecp - XVECTOR (state)->contents
6129 < ASIZE (state))
6130 *vecp++ = Qlambda;
6131 /* Make sure we didn't overflow the vector. */
6132 if (vecp - XVECTOR (state)->contents
6133 > ASIZE (state))
6134 abort ();
6135 return Qt;
6140 /***********************************************************************
6141 Initialization
6142 ***********************************************************************/
6144 /* Initialization done when Emacs fork is started, before doing stty.
6145 Determine terminal type and set terminal_driver. Then invoke its
6146 decoding routine to set up variables in the terminal package. */
6148 void
6149 init_display (void)
6151 char *terminal_type;
6153 /* Construct the space glyph. */
6154 space_glyph.type = CHAR_GLYPH;
6155 SET_CHAR_GLYPH (space_glyph, ' ', DEFAULT_FACE_ID, 0);
6156 space_glyph.charpos = -1;
6158 inverse_video = 0;
6159 cursor_in_echo_area = 0;
6160 terminal_type = (char *) 0;
6162 /* Now is the time to initialize this; it's used by init_sys_modes
6163 during startup. */
6164 Vinitial_window_system = Qnil;
6166 /* SIGWINCH needs to be handled no matter what display we start
6167 with. Otherwise newly opened tty frames will not resize
6168 automatically. */
6169 #ifdef SIGWINCH
6170 #ifndef CANNOT_DUMP
6171 if (initialized)
6172 #endif /* CANNOT_DUMP */
6173 signal (SIGWINCH, window_change_signal);
6174 #endif /* SIGWINCH */
6176 /* If running as a daemon, no need to initialize any frames/terminal. */
6177 if (IS_DAEMON)
6178 return;
6180 /* If the user wants to use a window system, we shouldn't bother
6181 initializing the terminal. This is especially important when the
6182 terminal is so dumb that emacs gives up before and doesn't bother
6183 using the window system.
6185 If the DISPLAY environment variable is set and nonempty,
6186 try to use X, and die with an error message if that doesn't work. */
6188 #ifdef HAVE_X_WINDOWS
6189 if (! inhibit_window_system && ! display_arg)
6191 char *display;
6192 display = getenv ("DISPLAY");
6193 display_arg = (display != 0 && *display != 0);
6195 if (display_arg && !x_display_ok (display))
6197 fprintf (stderr, "Display %s unavailable, simulating -nw\n",
6198 display);
6199 inhibit_window_system = 1;
6203 if (!inhibit_window_system && display_arg)
6205 Vinitial_window_system = Qx;
6206 #ifdef HAVE_X11
6207 Vwindow_system_version = make_number (11);
6208 #endif
6209 #if defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
6210 /* In some versions of ncurses,
6211 tputs crashes if we have not called tgetent.
6212 So call tgetent. */
6213 { char b[2044]; tgetent (b, "xterm");}
6214 #endif
6215 adjust_frame_glyphs_initially ();
6216 return;
6218 #endif /* HAVE_X_WINDOWS */
6220 #ifdef HAVE_NTGUI
6221 if (!inhibit_window_system)
6223 Vinitial_window_system = Qw32;
6224 Vwindow_system_version = make_number (1);
6225 adjust_frame_glyphs_initially ();
6226 return;
6228 #endif /* HAVE_NTGUI */
6230 #ifdef HAVE_NS
6231 if (!inhibit_window_system
6232 #ifndef CANNOT_DUMP
6233 && initialized
6234 #endif
6237 Vinitial_window_system = Qns;
6238 Vwindow_system_version = make_number(10);
6239 adjust_frame_glyphs_initially ();
6240 return;
6242 #endif
6244 /* If no window system has been specified, try to use the terminal. */
6245 if (! isatty (0))
6247 fatal ("standard input is not a tty");
6248 exit (1);
6251 #ifdef WINDOWSNT
6252 terminal_type = "w32console";
6253 #else
6254 /* Look at the TERM variable. */
6255 terminal_type = (char *) getenv ("TERM");
6256 #endif
6257 if (!terminal_type)
6259 #ifdef HAVE_WINDOW_SYSTEM
6260 if (! inhibit_window_system)
6261 fprintf (stderr, "Please set the environment variable DISPLAY or TERM (see `tset').\n");
6262 else
6263 #endif /* HAVE_WINDOW_SYSTEM */
6264 fprintf (stderr, "Please set the environment variable TERM; see `tset'.\n");
6265 exit (1);
6269 struct terminal *t;
6270 struct frame *f = XFRAME (selected_frame);
6272 /* Open a display on the controlling tty. */
6273 t = init_tty (0, terminal_type, 1); /* Errors are fatal. */
6275 /* Convert the initial frame to use the new display. */
6276 if (f->output_method != output_initial)
6277 abort ();
6278 f->output_method = t->type;
6279 f->terminal = t;
6281 t->reference_count++;
6282 #ifdef MSDOS
6283 f->output_data.tty->display_info = &the_only_display_info;
6284 #else
6285 if (f->output_method == output_termcap)
6286 create_tty_output (f);
6287 #endif
6288 t->display_info.tty->top_frame = selected_frame;
6289 change_frame_size (XFRAME (selected_frame),
6290 FrameRows (t->display_info.tty),
6291 FrameCols (t->display_info.tty), 0, 0, 1);
6293 /* Delete the initial terminal. */
6294 if (--initial_terminal->reference_count == 0
6295 && initial_terminal->delete_terminal_hook)
6296 (*initial_terminal->delete_terminal_hook) (initial_terminal);
6298 /* Update frame parameters to reflect the new type. */
6299 Fmodify_frame_parameters
6300 (selected_frame, Fcons (Fcons (Qtty_type,
6301 Ftty_type (selected_frame)), Qnil));
6302 if (t->display_info.tty->name)
6303 Fmodify_frame_parameters (selected_frame,
6304 Fcons (Fcons (Qtty, build_string (t->display_info.tty->name)),
6305 Qnil));
6306 else
6307 Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qtty, Qnil),
6308 Qnil));
6312 struct frame *sf = SELECTED_FRAME ();
6313 int width = FRAME_TOTAL_COLS (sf);
6314 int height = FRAME_LINES (sf);
6316 /* If these sizes are so big they cause overflow, just ignore the
6317 change. It's not clear what better we could do. The rest of
6318 the code assumes that (width + 2) * height * sizeof (struct glyph)
6319 does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX. */
6320 if (INT_ADD_RANGE_OVERFLOW (width, 2, INT_MIN, INT_MAX)
6321 || INT_MULTIPLY_RANGE_OVERFLOW (width + 2, height, INT_MIN, INT_MAX)
6322 || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph)
6323 < (width + 2) * height))
6324 fatal ("screen size %dx%d too big", width, height);
6327 adjust_frame_glyphs_initially ();
6328 calculate_costs (XFRAME (selected_frame));
6330 /* Set up faces of the initial terminal frame of a dumped Emacs. */
6331 if (initialized
6332 && !noninteractive
6333 && NILP (Vinitial_window_system))
6335 /* For the initial frame, we don't have any way of knowing what
6336 are the foreground and background colors of the terminal. */
6337 struct frame *sf = SELECTED_FRAME();
6339 FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
6340 FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;
6341 call0 (intern ("tty-set-up-initial-frame-faces"));
6347 /***********************************************************************
6348 Blinking cursor
6349 ***********************************************************************/
6351 DEFUN ("internal-show-cursor", Finternal_show_cursor,
6352 Sinternal_show_cursor, 2, 2, 0,
6353 doc: /* Set the cursor-visibility flag of WINDOW to SHOW.
6354 WINDOW nil means use the selected window. SHOW non-nil means
6355 show a cursor in WINDOW in the next redisplay. SHOW nil means
6356 don't show a cursor. */)
6357 (Lisp_Object window, Lisp_Object show)
6359 /* Don't change cursor state while redisplaying. This could confuse
6360 output routines. */
6361 if (!redisplaying_p)
6363 if (NILP (window))
6364 window = selected_window;
6365 else
6366 CHECK_WINDOW (window);
6368 XWINDOW (window)->cursor_off_p = NILP (show);
6371 return Qnil;
6375 DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
6376 Sinternal_show_cursor_p, 0, 1, 0,
6377 doc: /* Value is non-nil if next redisplay will display a cursor in WINDOW.
6378 WINDOW nil or omitted means report on the selected window. */)
6379 (Lisp_Object window)
6381 struct window *w;
6383 if (NILP (window))
6384 window = selected_window;
6385 else
6386 CHECK_WINDOW (window);
6388 w = XWINDOW (window);
6389 return w->cursor_off_p ? Qnil : Qt;
6392 DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
6393 Slast_nonminibuf_frame, 0, 0, 0,
6394 doc: /* Value is last nonminibuffer frame. */)
6395 (void)
6397 Lisp_Object frame = Qnil;
6399 if (last_nonminibuf_frame)
6400 XSETFRAME (frame, last_nonminibuf_frame);
6402 return frame;
6405 /***********************************************************************
6406 Initialization
6407 ***********************************************************************/
6409 void
6410 syms_of_display (void)
6412 defsubr (&Sredraw_frame);
6413 defsubr (&Sredraw_display);
6414 defsubr (&Sframe_or_buffer_changed_p);
6415 defsubr (&Sopen_termscript);
6416 defsubr (&Sding);
6417 defsubr (&Sredisplay);
6418 defsubr (&Ssleep_for);
6419 defsubr (&Ssend_string_to_terminal);
6420 defsubr (&Sinternal_show_cursor);
6421 defsubr (&Sinternal_show_cursor_p);
6422 defsubr (&Slast_nonminibuf_frame);
6424 #if GLYPH_DEBUG
6425 defsubr (&Sdump_redisplay_history);
6426 #endif
6428 frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
6429 staticpro (&frame_and_buffer_state);
6431 DEFSYM (Qdisplay_table, "display-table");
6432 DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
6434 DEFVAR_INT ("baud-rate", baud_rate,
6435 doc: /* *The output baud rate of the terminal.
6436 On most systems, changing this value will affect the amount of padding
6437 and the other strategic decisions made during redisplay. */);
6439 DEFVAR_BOOL ("inverse-video", inverse_video,
6440 doc: /* *Non-nil means invert the entire frame display.
6441 This means everything is in inverse video which otherwise would not be. */);
6443 DEFVAR_BOOL ("visible-bell", visible_bell,
6444 doc: /* *Non-nil means try to flash the frame to represent a bell.
6446 See also `ring-bell-function'. */);
6448 DEFVAR_BOOL ("no-redraw-on-reenter", no_redraw_on_reenter,
6449 doc: /* *Non-nil means no need to redraw entire frame after suspending.
6450 A non-nil value is useful if the terminal can automatically preserve
6451 Emacs's frame display when you reenter Emacs.
6452 It is up to you to set this variable if your terminal can do that. */);
6454 DEFVAR_LISP ("initial-window-system", Vinitial_window_system,
6455 doc: /* Name of the window system that Emacs uses for the first frame.
6456 The value is a symbol:
6457 nil for a termcap frame (a character-only terminal),
6458 'x' for an Emacs frame that is really an X window,
6459 'w32' for an Emacs frame that is a window on MS-Windows display,
6460 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
6461 'pc' for a direct-write MS-DOS frame.
6463 Use of this variable as a boolean is deprecated. Instead,
6464 use `display-graphic-p' or any of the other `display-*-p'
6465 predicates which report frame's specific UI-related capabilities. */);
6467 DEFVAR_KBOARD ("window-system", Vwindow_system,
6468 doc: /* Name of window system through which the selected frame is displayed.
6469 The value is a symbol:
6470 nil for a termcap frame (a character-only terminal),
6471 'x' for an Emacs frame that is really an X window,
6472 'w32' for an Emacs frame that is a window on MS-Windows display,
6473 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
6474 'pc' for a direct-write MS-DOS frame.
6476 Use of this variable as a boolean is deprecated. Instead,
6477 use `display-graphic-p' or any of the other `display-*-p'
6478 predicates which report frame's specific UI-related capabilities. */);
6480 DEFVAR_LISP ("window-system-version", Vwindow_system_version,
6481 doc: /* The version number of the window system in use.
6482 For X windows, this is 11. */);
6484 DEFVAR_BOOL ("cursor-in-echo-area", cursor_in_echo_area,
6485 doc: /* Non-nil means put cursor in minibuffer, at end of any message there. */);
6487 DEFVAR_LISP ("glyph-table", Vglyph_table,
6488 doc: /* Table defining how to output a glyph code to the frame.
6489 If not nil, this is a vector indexed by glyph code to define the glyph.
6490 Each element can be:
6491 integer: a glyph code which this glyph is an alias for.
6492 string: output this glyph using that string (not impl. in X windows).
6493 nil: this glyph mod 524288 is the code of a character to output,
6494 and this glyph / 524288 is the face number (see `face-id') to use
6495 while outputting it. */);
6496 Vglyph_table = Qnil;
6498 DEFVAR_LISP ("standard-display-table", Vstandard_display_table,
6499 doc: /* Display table to use for buffers that specify none.
6500 See `buffer-display-table' for more information. */);
6501 Vstandard_display_table = Qnil;
6503 DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause,
6504 doc: /* *Non-nil means update isn't paused when input is detected. */);
6505 redisplay_dont_pause = 0;
6507 #if PERIODIC_PREEMPTION_CHECKING
6508 DEFVAR_LISP ("redisplay-preemption-period", Vredisplay_preemption_period,
6509 doc: /* *The period in seconds between checking for input during redisplay.
6510 If input is detected, redisplay is pre-empted, and the input is processed.
6511 If nil, never pre-empt redisplay. */);
6512 Vredisplay_preemption_period = make_float (0.10);
6513 #endif
6515 #ifdef CANNOT_DUMP
6516 if (noninteractive)
6517 #endif
6519 Vinitial_window_system = Qnil;
6520 Vwindow_system_version = Qnil;