lisp/progmodes/js.el: Silence byte-compiler warning.
[bpt/emacs.git] / src / dispnew.c
CommitLineData
4588ec20 1/* Updating of data structures for redisplay.
9311dcff 2
ab422c4d
PE
3Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
4Inc.
4588ec20
JB
5
6This file is part of GNU Emacs.
7
9ec0b715 8GNU Emacs is free software: you can redistribute it and/or modify
4588ec20 9it under the terms of the GNU General Public License as published by
9ec0b715
GM
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
4588ec20
JB
12
13GNU Emacs is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
9ec0b715 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
4588ec20 20
18160b98 21#include <config.h>
f162bcc3
PE
22
23#define DISPEXTERN_INLINE EXTERN_INLINE
24
565620a5 25#include <stdio.h>
dfcf069d 26#include <unistd.h>
dfcf069d 27
47099d6f 28#include "lisp.h"
4588ec20 29#include "termchar.h"
a0879520 30/* cm.h must come after dispextern.h on Windows. */
fd2e066a
GV
31#include "dispextern.h"
32#include "cm.h"
83be827a 33#include "character.h"
e5560ff7 34#include "buffer.h"
d43721a2 35#include "keyboard.h"
502b9b64 36#include "frame.h"
428a555e 37#include "termhooks.h"
4588ec20
JB
38#include "window.h"
39#include "commands.h"
40#include "disptab.h"
41#include "indent.h"
d169fe39 42#include "intervals.h"
97cf50e7 43#include "blockinput.h"
dfcf069d 44#include "process.h"
4588ec20 45
58b2bb63 46#include "syssignal.h"
a41f8bed 47
17a2cbbd
DC
48#ifdef HAVE_WINDOW_SYSTEM
49#include TERM_HEADER
50#endif /* HAVE_WINDOW_SYSTEM */
edfda783 51
5f5c8ee5 52/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
6cbd1643 53
5f5c8ee5 54#include "systime.h"
3883a901
RS
55#include <errno.h>
56
8148369c 57#include <fpending.h>
c59592b3 58
9311dcff 59#if defined (HAVE_TERM_H) && defined (GNU_LINUX)
fa0ec9f4
DL
60#include <term.h> /* for tgetent */
61#endif
a68089e4
EZ
62
63#ifdef WINDOWSNT
64#include "w32.h"
65#endif
5f5c8ee5
GM
66\f
67/* Structure to pass dimensions around. Used for character bounding
68 boxes, glyph matrix dimensions and alike. */
69
70struct dim
71{
72 int width;
73 int height;
74};
75
76\f
77/* Function prototypes. */
78
f57e2426 79static void update_frame_line (struct frame *, int);
2f7c71a1
AS
80static int required_matrix_height (struct window *);
81static int required_matrix_width (struct window *);
f57e2426 82static void adjust_frame_glyphs (struct frame *);
59ea14cd 83static void change_frame_size_1 (struct frame *, int, int, bool, bool, bool);
d311d28c 84static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
f57e2426
J
85static void fill_up_frame_row_with_spaces (struct glyph_row *, int);
86static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
87 struct window *);
88static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
89 struct window *);
f57e2426
J
90static void adjust_decode_mode_spec_buffer (struct frame *);
91static void fill_up_glyph_row_with_spaces (struct glyph_row *);
59ea14cd 92static void clear_window_matrices (struct window *, bool);
f57e2426 93static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int);
59ea14cd
PE
94static int scrolling_window (struct window *, bool);
95static bool update_window_line (struct window *, int, bool *);
f57e2426 96static void mirror_make_current (struct window *, int);
e509cfa6 97#ifdef GLYPH_DEBUG
f57e2426
J
98static void check_matrix_pointers (struct glyph_matrix *,
99 struct glyph_matrix *);
b96fd3e8 100#endif
f57e2426 101static void mirror_line_dance (struct window *, int, int, int *, char *);
59ea14cd
PE
102static bool update_window_tree (struct window *, bool);
103static bool update_window (struct window *, bool);
104static bool update_frame_1 (struct frame *, bool, bool);
105static bool scrolling (struct frame *);
f57e2426 106static void set_window_cursor_after_update (struct window *);
f57e2426
J
107static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
108static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
5f5c8ee5 109
59ea14cd 110/* True upon entry to redisplay means do not assume anything about
502b9b64 111 current contents of actual terminal frame; clear and redraw it. */
4588ec20 112
59ea14cd 113bool frame_garbaged;
4588ec20 114
59ea14cd 115/* True means last display completed. False means it was preempted. */
4588ec20 116
59ea14cd 117bool display_completed;
4588ec20 118
e7067d00 119Lisp_Object Qdisplay_table, Qredisplay_dont_pause;
5f5c8ee5 120
4588ec20 121\f
5f5c8ee5 122/* The currently selected frame. In a single-frame version, this
91fb7e1b 123 variable always equals the_only_frame. */
4588ec20 124
91fb7e1b 125Lisp_Object selected_frame;
4588ec20 126
5f5c8ee5 127/* A frame which is not just a mini-buffer, or 0 if there are no such
502b9b64 128 frames. This is usually the most recent such frame that was
87485d6f
MW
129 selected. In a single-frame version, this variable always holds
130 the address of the_only_frame. */
4588ec20 131
5f5c8ee5 132struct frame *last_nonminibuf_frame;
d52bad65 133
59ea14cd 134/* True means SIGWINCH happened when not safe. */
4588ec20 135
59ea14cd 136static bool delayed_size_change;
4588ec20 137
5f5c8ee5 138/* Updated window if != 0. Set by update_window. */
4588ec20 139
5f5c8ee5 140struct window *updated_window;
4588ec20 141
5f5c8ee5 142/* Glyph row updated in update_window_line, and area that is updated. */
4588ec20 143
5f5c8ee5
GM
144struct glyph_row *updated_row;
145int updated_area;
4588ec20 146
5f5c8ee5 147/* A glyph for a space. */
4588ec20 148
5f5c8ee5 149struct glyph space_glyph;
4588ec20 150
5f5c8ee5
GM
151/* Counts of allocated structures. These counts serve to diagnose
152 memory leaks and double frees. */
4588ec20 153
5bf46f05
PE
154static int glyph_matrix_count;
155static int glyph_pool_count;
4588ec20 156
5f5c8ee5
GM
157/* If non-null, the frame whose frame matrices are manipulated. If
158 null, window matrices are worked on. */
4588ec20 159
5f5c8ee5 160static struct frame *frame_matrix_frame;
4588ec20 161
59ea14cd 162/* True means that fonts have been loaded since the last glyph
5f5c8ee5 163 matrix adjustments. Redisplay must stop, and glyph matrices must
59ea14cd 164 be adjusted when this flag becomes true during display. The
5f5c8ee5 165 reason fonts can be loaded so late is that fonts of fontsets are
3aa9f0c4
KH
166 loaded on demand. Another reason is that a line contains many
167 characters displayed by zero width or very narrow glyphs of
168 variable-width fonts. */
836d2cde 169
59ea14cd 170bool fonts_changed_p;
836d2cde 171
177c0ea7 172/* Convert vpos and hpos from frame to window and vice versa.
5f5c8ee5 173 This may only be used for terminal frames. */
836d2cde 174
e509cfa6 175#ifdef GLYPH_DEBUG
4588ec20 176
f57e2426
J
177static int window_to_frame_vpos (struct window *, int);
178static int window_to_frame_hpos (struct window *, int);
5f5c8ee5
GM
179#define WINDOW_TO_FRAME_VPOS(W, VPOS) window_to_frame_vpos ((W), (VPOS))
180#define WINDOW_TO_FRAME_HPOS(W, HPOS) window_to_frame_hpos ((W), (HPOS))
4588ec20 181
9b0e97aa
GM
182/* One element of the ring buffer containing redisplay history
183 information. */
184
185struct redisplay_history
186{
187 char trace[512 + 100];
188};
189
190/* The size of the history buffer. */
191
192#define REDISPLAY_HISTORY_SIZE 30
193
194/* The redisplay history buffer. */
195
196static struct redisplay_history redisplay_history[REDISPLAY_HISTORY_SIZE];
197
198/* Next free entry in redisplay_history. */
199
200static int history_idx;
201
202/* A tick that's incremented each time something is added to the
203 history. */
204
dfd153ae 205static uprintmax_t history_tick;
6a8aec41 206\f
9b0e97aa
GM
207/* Add to the redisplay history how window W has been displayed.
208 MSG is a trace containing the information how W's glyph matrix
59ea14cd 209 has been constructed. PAUSED_P means that the update
9b0e97aa
GM
210 has been interrupted for pending input. */
211
212static void
59ea14cd 213add_window_display_history (struct window *w, const char *msg, bool paused_p)
9b0e97aa
GM
214{
215 char *buf;
177c0ea7 216
9b0e97aa
GM
217 if (history_idx >= REDISPLAY_HISTORY_SIZE)
218 history_idx = 0;
219 buf = redisplay_history[history_idx].trace;
220 ++history_idx;
177c0ea7 221
8666506e
PE
222 snprintf (buf, sizeof redisplay_history[0].trace,
223 "%"pMu": window %p (`%s')%s\n%s",
224 history_tick++,
225 w,
d3d50620
DA
226 ((BUFFERP (w->buffer)
227 && STRINGP (BVAR (XBUFFER (w->buffer), name)))
228 ? SSDATA (BVAR (XBUFFER (w->buffer), name))
8666506e
PE
229 : "???"),
230 paused_p ? " ***paused***" : "",
231 msg);
9b0e97aa
GM
232}
233
234
235/* Add to the redisplay history that frame F has been displayed.
59ea14cd 236 PAUSED_P means that the update has been interrupted for
9b0e97aa
GM
237 pending input. */
238
239static void
59ea14cd 240add_frame_display_history (struct frame *f, bool paused_p)
9b0e97aa
GM
241{
242 char *buf;
177c0ea7 243
9b0e97aa
GM
244 if (history_idx >= REDISPLAY_HISTORY_SIZE)
245 history_idx = 0;
246 buf = redisplay_history[history_idx].trace;
247 ++history_idx;
177c0ea7 248
dfd153ae 249 sprintf (buf, "%"pMu": update frame %p%s",
9b0e97aa
GM
250 history_tick++,
251 f, paused_p ? " ***paused***" : "");
252}
253
254
a7ca3326 255DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
9b0e97aa 256 Sdump_redisplay_history, 0, 0, "",
7ee72033 257 doc: /* Dump redisplay history to stderr. */)
5842a27b 258 (void)
9b0e97aa
GM
259{
260 int i;
261
262 for (i = history_idx - 1; i != history_idx; --i)
263 {
264 if (i < 0)
265 i = REDISPLAY_HISTORY_SIZE - 1;
266 fprintf (stderr, "%s\n", redisplay_history[i].trace);
267 }
268
269 return Qnil;
270}
271
272
e509cfa6 273#else /* not GLYPH_DEBUG */
4588ec20 274
7df02016
KS
275#define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + WINDOW_TOP_EDGE_LINE (W))
276#define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + WINDOW_LEFT_EDGE_COL (W))
4588ec20 277
e509cfa6 278#endif /* GLYPH_DEBUG */
4588ec20 279
4588ec20 280
9e4bf381
PE
281#if (defined PROFILING \
282 && (defined __FreeBSD__ || defined GNU_LINUX || defined __MINGW32__) \
283 && !HAVE___EXECUTABLE_START)
284/* This function comes first in the Emacs executable and is used only
285 to estimate the text start for profiling. */
4588ec20 286void
9e4bf381 287__executable_start (void)
4588ec20 288{
1088b922 289 emacs_abort ();
177c0ea7 290}
72af86bd 291#endif
5f5c8ee5
GM
292\f
293/***********************************************************************
294 Glyph Matrices
295 ***********************************************************************/
296
297/* Allocate and return a glyph_matrix structure. POOL is the glyph
298 pool from which memory for the matrix should be allocated, or null
299 for window-based redisplay where no glyph pools are used. The
300 member `pool' of the glyph matrix structure returned is set to
301 POOL, the structure is otherwise zeroed. */
302
5bf46f05 303static struct glyph_matrix *
971de7fb 304new_glyph_matrix (struct glyph_pool *pool)
4588ec20 305{
23f86fce 306 struct glyph_matrix *result = xzalloc (sizeof *result);
4588ec20 307
5f5c8ee5
GM
308 /* Increment number of allocated matrices. This count is used
309 to detect memory leaks. */
310 ++glyph_matrix_count;
4588ec20 311
5f5c8ee5
GM
312 /* Set pool and return. */
313 result->pool = pool;
314 return result;
4588ec20
JB
315}
316
4588ec20 317
5f5c8ee5
GM
318/* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed.
319
320 The global counter glyph_matrix_count is decremented when a matrix
321 is freed. If the count gets negative, more structures were freed
322 than allocated, i.e. one matrix was freed more than once or a bogus
323 pointer was passed to this function.
177c0ea7 324
5f5c8ee5
GM
325 If MATRIX->pool is null, this means that the matrix manages its own
326 glyph memory---this is done for matrices on X frames. Freeing the
327 matrix also frees the glyph memory in this case. */
328
329static void
971de7fb 330free_glyph_matrix (struct glyph_matrix *matrix)
4588ec20 331{
5f5c8ee5
GM
332 if (matrix)
333 {
334 int i;
335
336 /* Detect the case that more matrices are freed than were
337 allocated. */
338 if (--glyph_matrix_count < 0)
1088b922 339 emacs_abort ();
5f5c8ee5
GM
340
341 /* Free glyph memory if MATRIX owns it. */
342 if (matrix->pool == NULL)
343 for (i = 0; i < matrix->rows_allocated; ++i)
344 xfree (matrix->rows[i].glyphs[LEFT_MARGIN_AREA]);
177c0ea7 345
5f5c8ee5
GM
346 /* Free row structures and the matrix itself. */
347 xfree (matrix->rows);
348 xfree (matrix);
349 }
350}
4588ec20 351
4588ec20 352
5f5c8ee5
GM
353/* Return the number of glyphs to reserve for a marginal area of
354 window W. TOTAL_GLYPHS is the number of glyphs in a complete
355 display line of window W. MARGIN gives the width of the marginal
356 area in canonical character units. MARGIN should be an integer
357 or a float. */
358
359static int
971de7fb 360margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin)
5f5c8ee5
GM
361{
362 int n;
4588ec20 363
5f5c8ee5 364 if (NUMBERP (margin))
4588ec20 365 {
d3d50620 366 int width = XFASTINT (w->total_cols);
5f5c8ee5
GM
367 double d = max (0, XFLOATINT (margin));
368 d = min (width / 2 - 1, d);
35ec832e 369 n = (int) ((double) total_glyphs / width * d);
5f5c8ee5
GM
370 }
371 else
372 n = 0;
373
374 return n;
375}
376
59ea14cd 377/* Return true if ROW's hash value is correct.
e509cfa6
DA
378 Optimized away if ENABLE_CHECKING is not defined. */
379
59ea14cd 380static bool
7a7270dd
EZ
381verify_row_hash (struct glyph_row *row)
382{
015137db 383 return row->hash == row_hash (row);
7a7270dd 384}
4588ec20 385
5f5c8ee5
GM
386/* Adjust glyph matrix MATRIX on window W or on a frame to changed
387 window sizes.
4588ec20 388
5f5c8ee5
GM
389 W is null if the function is called for a frame glyph matrix.
390 Otherwise it is the window MATRIX is a member of. X and Y are the
391 indices of the first column and row of MATRIX within the frame
392 matrix, if such a matrix exists. They are zero for purely
393 window-based redisplay. DIM is the needed size of the matrix.
d52bad65 394
5f5c8ee5
GM
395 In window-based redisplay, where no frame matrices exist, glyph
396 matrices manage their own glyph storage. Otherwise, they allocate
397 storage from a common frame glyph pool which can be found in
398 MATRIX->pool.
23b0200c 399
5f5c8ee5
GM
400 The reason for this memory management strategy is to avoid complete
401 frame redraws if possible. When we allocate from a common pool, a
402 change of the location or size of a sub-matrix within the pool
403 requires a complete redisplay of the frame because we cannot easily
404 make sure that the current matrices of all windows still agree with
405 what is displayed on the screen. While this is usually fast, it
406 leads to screen flickering. */
23b0200c 407
5f5c8ee5 408static void
971de7fb 409adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y, struct dim dim)
5f5c8ee5
GM
410{
411 int i;
412 int new_rows;
59ea14cd
PE
413 bool marginal_areas_changed_p = 0;
414 bool header_line_changed_p = 0;
415 bool header_line_p = 0;
5f5c8ee5 416 int left = -1, right = -1;
ca8a12a7 417 int window_width = -1, window_height = -1;
5f5c8ee5 418
6b61353c
KH
419 /* See if W had a header line that has disappeared now, or vice versa.
420 Get W's size. */
5f5c8ee5
GM
421 if (w)
422 {
6b61353c
KH
423 window_box (w, -1, 0, 0, &window_width, &window_height);
424
045dee35
GM
425 header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
426 header_line_changed_p = header_line_p != matrix->header_line_p;
5f5c8ee5 427 }
045dee35 428 matrix->header_line_p = header_line_p;
23b0200c 429
6b61353c
KH
430 /* If POOL is null, MATRIX is a window matrix for window-based redisplay.
431 Do nothing if MATRIX' size, position, vscroll, and marginal areas
5f5c8ee5
GM
432 haven't changed. This optimization is important because preserving
433 the matrix means preventing redisplay. */
434 if (matrix->pool == NULL)
435 {
d3d50620
DA
436 left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_cols);
437 right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_cols);
a54e2c05 438 eassert (left >= 0 && right >= 0);
5f5c8ee5
GM
439 marginal_areas_changed_p = (left != matrix->left_margin_glyphs
440 || right != matrix->right_margin_glyphs);
441
442 if (!marginal_areas_changed_p
443 && !fonts_changed_p
045dee35 444 && !header_line_changed_p
7df02016
KS
445 && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
446 && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
5f5c8ee5
GM
447 && matrix->window_height == window_height
448 && matrix->window_vscroll == w->vscroll
449 && matrix->window_width == window_width)
450 return;
451 }
177c0ea7 452
5f5c8ee5
GM
453 /* Enlarge MATRIX->rows if necessary. New rows are cleared. */
454 if (matrix->rows_allocated < dim.height)
455 {
0065d054 456 int old_alloc = matrix->rows_allocated;
5f5c8ee5 457 new_rows = dim.height - matrix->rows_allocated;
0065d054
PE
458 matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
459 new_rows, INT_MAX, sizeof *matrix->rows);
460 memset (matrix->rows + old_alloc, 0,
461 (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows);
5f5c8ee5
GM
462 }
463 else
464 new_rows = 0;
60a8948a 465
5f5c8ee5
GM
466 /* If POOL is not null, MATRIX is a frame matrix or a window matrix
467 on a frame not using window-based redisplay. Set up pointers for
468 each row into the glyph pool. */
469 if (matrix->pool)
470 {
a54e2c05 471 eassert (matrix->pool->glyphs);
177c0ea7 472
5f5c8ee5 473 if (w)
60a8948a 474 {
5f5c8ee5 475 left = margin_glyphs_to_reserve (w, dim.width,
d3d50620 476 w->left_margin_cols);
5f5c8ee5 477 right = margin_glyphs_to_reserve (w, dim.width,
d3d50620 478 w->right_margin_cols);
60a8948a 479 }
5f5c8ee5
GM
480 else
481 left = right = 0;
177c0ea7 482
5f5c8ee5 483 for (i = 0; i < dim.height; ++i)
60a8948a 484 {
5f5c8ee5 485 struct glyph_row *row = &matrix->rows[i];
177c0ea7
JB
486
487 row->glyphs[LEFT_MARGIN_AREA]
5f5c8ee5
GM
488 = (matrix->pool->glyphs
489 + (y + i) * matrix->pool->ncolumns
490 + x);
177c0ea7 491
5f5c8ee5
GM
492 if (w == NULL
493 || row == matrix->rows + dim.height - 1
045dee35 494 || (row == matrix->rows && matrix->header_line_p))
5f5c8ee5
GM
495 {
496 row->glyphs[TEXT_AREA]
497 = row->glyphs[LEFT_MARGIN_AREA];
498 row->glyphs[RIGHT_MARGIN_AREA]
499 = row->glyphs[TEXT_AREA] + dim.width;
500 row->glyphs[LAST_AREA]
501 = row->glyphs[RIGHT_MARGIN_AREA];
502 }
503 else
504 {
505 row->glyphs[TEXT_AREA]
506 = row->glyphs[LEFT_MARGIN_AREA] + left;
507 row->glyphs[RIGHT_MARGIN_AREA]
508 = row->glyphs[TEXT_AREA] + dim.width - left - right;
509 row->glyphs[LAST_AREA]
510 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
511 }
60a8948a 512 }
177c0ea7 513
5f5c8ee5
GM
514 matrix->left_margin_glyphs = left;
515 matrix->right_margin_glyphs = right;
516 }
517 else
518 {
519 /* If MATRIX->pool is null, MATRIX is responsible for managing
6b61353c
KH
520 its own memory. It is a window matrix for window-based redisplay.
521 Allocate glyph memory from the heap. */
5f5c8ee5
GM
522 if (dim.width > matrix->matrix_w
523 || new_rows
045dee35 524 || header_line_changed_p
5f5c8ee5 525 || marginal_areas_changed_p)
4588ec20 526 {
5f5c8ee5
GM
527 struct glyph_row *row = matrix->rows;
528 struct glyph_row *end = row + matrix->rows_allocated;
177c0ea7 529
5f5c8ee5
GM
530 while (row < end)
531 {
532 row->glyphs[LEFT_MARGIN_AREA]
0065d054
PE
533 = xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
534 dim.width, sizeof (struct glyph));
177c0ea7 535
5f5c8ee5
GM
536 /* The mode line never has marginal areas. */
537 if (row == matrix->rows + dim.height - 1
045dee35 538 || (row == matrix->rows && matrix->header_line_p))
5f5c8ee5
GM
539 {
540 row->glyphs[TEXT_AREA]
541 = row->glyphs[LEFT_MARGIN_AREA];
542 row->glyphs[RIGHT_MARGIN_AREA]
543 = row->glyphs[TEXT_AREA] + dim.width;
544 row->glyphs[LAST_AREA]
545 = row->glyphs[RIGHT_MARGIN_AREA];
546 }
547 else
548 {
549 row->glyphs[TEXT_AREA]
550 = row->glyphs[LEFT_MARGIN_AREA] + left;
551 row->glyphs[RIGHT_MARGIN_AREA]
552 = row->glyphs[TEXT_AREA] + dim.width - left - right;
553 row->glyphs[LAST_AREA]
554 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
555 }
556 ++row;
557 }
4588ec20
JB
558 }
559
a54e2c05 560 eassert (left >= 0 && right >= 0);
5f5c8ee5
GM
561 matrix->left_margin_glyphs = left;
562 matrix->right_margin_glyphs = right;
563 }
177c0ea7 564
5f5c8ee5
GM
565 /* Number of rows to be used by MATRIX. */
566 matrix->nrows = dim.height;
a54e2c05 567 eassert (matrix->nrows >= 0);
5f5c8ee5 568
b7b20fbd 569 if (w)
5f5c8ee5 570 {
b7b20fbd 571 if (matrix == w->current_matrix)
4588ec20 572 {
b7b20fbd
GM
573 /* Mark rows in a current matrix of a window as not having
574 valid contents. It's important to not do this for
575 desired matrices. When Emacs starts, it may already be
576 building desired matrices when this function runs. */
577 if (window_width < 0)
578 window_width = window_box_width (w, -1);
177c0ea7 579
b7b20fbd
GM
580 /* Optimize the case that only the height has changed (C-x 2,
581 upper window). Invalidate all rows that are no longer part
582 of the window. */
583 if (!marginal_areas_changed_p
73d75a62
GM
584 && !header_line_changed_p
585 && new_rows == 0
586 && dim.width == matrix->matrix_w
7df02016
KS
587 && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
588 && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
73d75a62 589 && matrix->window_width == window_width)
b7b20fbd 590 {
dd42b31a
GM
591 /* Find the last row in the window. */
592 for (i = 0; i < matrix->nrows && matrix->rows[i].enabled_p; ++i)
593 if (MATRIX_ROW_BOTTOM_Y (matrix->rows + i) >= window_height)
594 {
26447967 595 ++i;
dd42b31a
GM
596 break;
597 }
b7b20fbd
GM
598
599 /* Window end is invalid, if inside of the rows that
dd42b31a 600 are invalidated below. */
d3d50620
DA
601 if (INTEGERP (w->window_end_vpos)
602 && XFASTINT (w->window_end_vpos) >= i)
9d93ce29 603 w->window_end_valid = 0;
177c0ea7 604
b7b20fbd
GM
605 while (i < matrix->nrows)
606 matrix->rows[i++].enabled_p = 0;
607 }
608 else
609 {
610 for (i = 0; i < matrix->nrows; ++i)
611 matrix->rows[i].enabled_p = 0;
612 }
5f5c8ee5 613 }
b7b20fbd 614 else if (matrix == w->desired_matrix)
5f5c8ee5 615 {
b7b20fbd
GM
616 /* Rows in desired matrices always have to be cleared;
617 redisplay expects this is the case when it runs, so it
618 had better be the case when we adjust matrices between
619 redisplays. */
5f5c8ee5
GM
620 for (i = 0; i < matrix->nrows; ++i)
621 matrix->rows[i].enabled_p = 0;
4588ec20 622 }
4588ec20 623 }
177c0ea7
JB
624
625
5f5c8ee5
GM
626 /* Remember last values to be able to optimize frame redraws. */
627 matrix->matrix_x = x;
628 matrix->matrix_y = y;
629 matrix->matrix_w = dim.width;
630 matrix->matrix_h = dim.height;
631
632 /* Record the top y location and height of W at the time the matrix
633 was last adjusted. This is used to optimize redisplay above. */
634 if (w)
4588ec20 635 {
7df02016
KS
636 matrix->window_left_col = WINDOW_LEFT_EDGE_COL (w);
637 matrix->window_top_line = WINDOW_TOP_EDGE_LINE (w);
5f5c8ee5
GM
638 matrix->window_height = window_height;
639 matrix->window_width = window_width;
640 matrix->window_vscroll = w->vscroll;
641 }
642}
4588ec20 643
4588ec20 644
5f5c8ee5
GM
645/* Reverse the contents of rows in MATRIX between START and END. The
646 contents of the row at END - 1 end up at START, END - 2 at START +
647 1 etc. This is part of the implementation of rotate_matrix (see
648 below). */
d52bad65 649
5f5c8ee5 650static void
971de7fb 651reverse_rows (struct glyph_matrix *matrix, int start, int end)
5f5c8ee5
GM
652{
653 int i, j;
23b0200c 654
5f5c8ee5
GM
655 for (i = start, j = end - 1; i < j; ++i, --j)
656 {
657 /* Non-ISO HP/UX compiler doesn't like auto struct
658 initialization. */
659 struct glyph_row temp;
660 temp = matrix->rows[i];
661 matrix->rows[i] = matrix->rows[j];
662 matrix->rows[j] = temp;
663 }
664}
23b0200c 665
23b0200c 666
5f5c8ee5
GM
667/* Rotate the contents of rows in MATRIX in the range FIRST .. LAST -
668 1 by BY positions. BY < 0 means rotate left, i.e. towards lower
669 indices. (Note: this does not copy glyphs, only glyph pointers in
670 row structures are moved around).
60a8948a 671
5f5c8ee5
GM
672 The algorithm used for rotating the vector was, I believe, first
673 described by Kernighan. See the vector R as consisting of two
674 sub-vectors AB, where A has length BY for BY >= 0. The result
675 after rotating is then BA. Reverse both sub-vectors to get ArBr
676 and reverse the result to get (ArBr)r which is BA. Similar for
677 rotating right. */
678
679void
971de7fb 680rotate_matrix (struct glyph_matrix *matrix, int first, int last, int by)
5f5c8ee5
GM
681{
682 if (by < 0)
683 {
684 /* Up (rotate left, i.e. towards lower indices). */
685 by = -by;
686 reverse_rows (matrix, first, first + by);
687 reverse_rows (matrix, first + by, last);
688 reverse_rows (matrix, first, last);
689 }
690 else if (by > 0)
691 {
692 /* Down (rotate right, i.e. towards higher indices). */
693 reverse_rows (matrix, last - by, last);
694 reverse_rows (matrix, first, last - by);
695 reverse_rows (matrix, first, last);
696 }
697}
698
699
700/* Increment buffer positions in glyph rows of MATRIX. Do it for rows
701 with indices START <= index < END. Increment positions by DELTA/
702 DELTA_BYTES. */
703
704void
ace1712c 705increment_matrix_positions (struct glyph_matrix *matrix, int start, int end,
d311d28c 706 ptrdiff_t delta, ptrdiff_t delta_bytes)
5f5c8ee5
GM
707{
708 /* Check that START and END are reasonable values. */
a54e2c05
DA
709 eassert (start >= 0 && start <= matrix->nrows);
710 eassert (end >= 0 && end <= matrix->nrows);
711 eassert (start <= end);
5f5c8ee5
GM
712
713 for (; start < end; ++start)
86c11ba1 714 increment_row_positions (matrix->rows + start, delta, delta_bytes);
5f5c8ee5
GM
715}
716
717
59ea14cd
PE
718/* Clear the enable_p flags in a range of rows in glyph matrix MATRIX.
719 START and END are the row indices of the first and last + 1 row to clear. */
5f5c8ee5
GM
720
721void
59ea14cd 722clear_glyph_matrix_rows (struct glyph_matrix *matrix, int start, int end)
5f5c8ee5 723{
a54e2c05
DA
724 eassert (start <= end);
725 eassert (start >= 0 && start < matrix->nrows);
726 eassert (end >= 0 && end <= matrix->nrows);
177c0ea7 727
5f5c8ee5 728 for (; start < end; ++start)
59ea14cd 729 matrix->rows[start].enabled_p = 0;
5f5c8ee5
GM
730}
731
732
733/* Clear MATRIX.
734
59ea14cd
PE
735 Empty all rows in MATRIX by clearing their enabled_p flags.
736 The function prepare_desired_row will eventually really clear a row
737 when it sees one with a false enabled_p flag.
5f5c8ee5 738
59ea14cd 739 Reset update hints to default values. The only update hint
5f5c8ee5
GM
740 currently present is the flag MATRIX->no_scrolling_p. */
741
742void
971de7fb 743clear_glyph_matrix (struct glyph_matrix *matrix)
5f5c8ee5
GM
744{
745 if (matrix)
746 {
59ea14cd 747 clear_glyph_matrix_rows (matrix, 0, matrix->nrows);
5f5c8ee5
GM
748 matrix->no_scrolling_p = 0;
749 }
750}
177c0ea7 751
5f5c8ee5
GM
752
753/* Shift part of the glyph matrix MATRIX of window W up or down.
754 Increment y-positions in glyph rows between START and END by DY,
755 and recompute their visible height. */
756
757void
971de7fb 758shift_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int start, int end, int dy)
5f5c8ee5
GM
759{
760 int min_y, max_y;
177c0ea7 761
a54e2c05
DA
762 eassert (start <= end);
763 eassert (start >= 0 && start < matrix->nrows);
764 eassert (end >= 0 && end <= matrix->nrows);
177c0ea7 765
7df02016
KS
766 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
767 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
177c0ea7 768
5f5c8ee5
GM
769 for (; start < end; ++start)
770 {
771 struct glyph_row *row = &matrix->rows[start];
177c0ea7 772
5f5c8ee5 773 row->y += dy;
d6c747a4 774 row->visible_height = row->height;
177c0ea7 775
5f5c8ee5 776 if (row->y < min_y)
d6c747a4
GM
777 row->visible_height -= min_y - row->y;
778 if (row->y + row->height > max_y)
779 row->visible_height -= row->y + row->height - max_y;
e61124cd
YM
780 if (row->fringe_bitmap_periodic_p)
781 row->redraw_fringe_bitmaps_p = 1;
5f5c8ee5
GM
782 }
783}
784
785
786/* Mark all rows in current matrices of frame F as invalid. Marking
787 invalid is done by setting enabled_p to zero for all rows in a
788 current matrix. */
789
790void
971de7fb 791clear_current_matrices (register struct frame *f)
5f5c8ee5
GM
792{
793 /* Clear frame current matrix, if we have one. */
794 if (f->current_matrix)
795 clear_glyph_matrix (f->current_matrix);
796
797 /* Clear the matrix of the menu bar window, if such a window exists.
798 The menu bar window is currently used to display menus on X when
799 no toolkit support is compiled in. */
e69b0960
DA
800 if (WINDOWP (f->menu_bar_window))
801 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
5f5c8ee5 802
9ea173e8 803 /* Clear the matrix of the tool-bar window, if any. */
e69b0960
DA
804 if (WINDOWP (f->tool_bar_window))
805 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
5f5c8ee5
GM
806
807 /* Clear current window matrices. */
a54e2c05 808 eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
5f5c8ee5
GM
809 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 0);
810}
811
812
813/* Clear out all display lines of F for a coming redisplay. */
814
815void
971de7fb 816clear_desired_matrices (register struct frame *f)
5f5c8ee5
GM
817{
818 if (f->desired_matrix)
819 clear_glyph_matrix (f->desired_matrix);
177c0ea7 820
e69b0960
DA
821 if (WINDOWP (f->menu_bar_window))
822 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
5f5c8ee5 823
e69b0960
DA
824 if (WINDOWP (f->tool_bar_window))
825 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
5f5c8ee5
GM
826
827 /* Do it for window matrices. */
a54e2c05 828 eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
5f5c8ee5
GM
829 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
830}
831
832
59ea14cd
PE
833/* Clear matrices in window tree rooted in W. If DESIRED_P,
834 clear desired matrices, otherwise clear current matrices. */
5f5c8ee5
GM
835
836static void
59ea14cd 837clear_window_matrices (struct window *w, bool desired_p)
5f5c8ee5
GM
838{
839 while (w)
840 {
d3d50620 841 if (!NILP (w->hchild))
5f5c8ee5 842 {
d3d50620
DA
843 eassert (WINDOWP (w->hchild));
844 clear_window_matrices (XWINDOW (w->hchild), desired_p);
5f5c8ee5 845 }
d3d50620 846 else if (!NILP (w->vchild))
5f5c8ee5 847 {
d3d50620
DA
848 eassert (WINDOWP (w->vchild));
849 clear_window_matrices (XWINDOW (w->vchild), desired_p);
5f5c8ee5
GM
850 }
851 else
852 {
853 if (desired_p)
854 clear_glyph_matrix (w->desired_matrix);
855 else
856 {
857 clear_glyph_matrix (w->current_matrix);
9d93ce29 858 w->window_end_valid = 0;
5f5c8ee5
GM
859 }
860 }
861
d3d50620 862 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5f5c8ee5
GM
863 }
864}
865
866
867\f
868/***********************************************************************
869 Glyph Rows
870
871 See dispextern.h for an overall explanation of glyph rows.
872 ***********************************************************************/
873
874/* Clear glyph row ROW. Do it in a way that makes it robust against
875 changes in the glyph_row structure, i.e. addition or removal of
876 structure members. */
877
2cca872d
KH
878static struct glyph_row null_row;
879
5f5c8ee5 880void
971de7fb 881clear_glyph_row (struct glyph_row *row)
5f5c8ee5
GM
882{
883 struct glyph *p[1 + LAST_AREA];
5f5c8ee5
GM
884
885 /* Save pointers. */
886 p[LEFT_MARGIN_AREA] = row->glyphs[LEFT_MARGIN_AREA];
887 p[TEXT_AREA] = row->glyphs[TEXT_AREA];
888 p[RIGHT_MARGIN_AREA] = row->glyphs[RIGHT_MARGIN_AREA];
889 p[LAST_AREA] = row->glyphs[LAST_AREA];
890
891 /* Clear. */
892 *row = null_row;
893
894 /* Restore pointers. */
895 row->glyphs[LEFT_MARGIN_AREA] = p[LEFT_MARGIN_AREA];
896 row->glyphs[TEXT_AREA] = p[TEXT_AREA];
897 row->glyphs[RIGHT_MARGIN_AREA] = p[RIGHT_MARGIN_AREA];
898 row->glyphs[LAST_AREA] = p[LAST_AREA];
45560b1a
GM
899
900#if 0 /* At some point, some bit-fields of struct glyph were not set,
901 which made glyphs unequal when compared with GLYPH_EQUAL_P.
902 Redisplay outputs such glyphs, and flickering effects were
903 the result. This also depended on the contents of memory
904 returned by xmalloc. If flickering happens again, activate
153a073c 905 the code below. If the flickering is gone with that, chances
45560b1a 906 are that the flickering has the same reason as here. */
72af86bd 907 memset (p[0], 0, (char *) p[LAST_AREA] - (char *) p[0]);
45560b1a 908#endif
5f5c8ee5
GM
909}
910
911
912/* Make ROW an empty, enabled row of canonical character height,
913 in window W starting at y-position Y. */
914
915void
971de7fb 916blank_row (struct window *w, struct glyph_row *row, int y)
5f5c8ee5
GM
917{
918 int min_y, max_y;
177c0ea7 919
7df02016
KS
920 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
921 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
177c0ea7 922
5f5c8ee5
GM
923 clear_glyph_row (row);
924 row->y = y;
408f5064 925 row->ascent = row->phys_ascent = 0;
d3d50620 926 row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (w->frame));
d6c747a4 927 row->visible_height = row->height;
177c0ea7 928
5f5c8ee5 929 if (row->y < min_y)
d6c747a4
GM
930 row->visible_height -= min_y - row->y;
931 if (row->y + row->height > max_y)
932 row->visible_height -= row->y + row->height - max_y;
5f5c8ee5
GM
933
934 row->enabled_p = 1;
935}
936
937
938/* Increment buffer positions in glyph row ROW. DELTA and DELTA_BYTES
939 are the amounts by which to change positions. Note that the first
940 glyph of the text area of a row can have a buffer position even if
941 the used count of the text area is zero. Such rows display line
942 ends. */
943
5bf46f05 944static void
ace1712c 945increment_row_positions (struct glyph_row *row,
d311d28c 946 ptrdiff_t delta, ptrdiff_t delta_bytes)
5f5c8ee5
GM
947{
948 int area, i;
949
950 /* Increment start and end positions. */
951 MATRIX_ROW_START_CHARPOS (row) += delta;
952 MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
953 MATRIX_ROW_END_CHARPOS (row) += delta;
954 MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
d36fe237
EZ
955 CHARPOS (row->start.pos) += delta;
956 BYTEPOS (row->start.pos) += delta_bytes;
957 CHARPOS (row->end.pos) += delta;
958 BYTEPOS (row->end.pos) += delta_bytes;
5f5c8ee5 959
5cacdcfd
KS
960 if (!row->enabled_p)
961 return;
962
5f5c8ee5
GM
963 /* Increment positions in glyphs. */
964 for (area = 0; area < LAST_AREA; ++area)
965 for (i = 0; i < row->used[area]; ++i)
966 if (BUFFERP (row->glyphs[area][i].object)
967 && row->glyphs[area][i].charpos > 0)
968 row->glyphs[area][i].charpos += delta;
969
970 /* Capture the case of rows displaying a line end. */
971 if (row->used[TEXT_AREA] == 0
972 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
973 row->glyphs[TEXT_AREA]->charpos += delta;
974}
975
976
9af3e742 977#if 0
5f5c8ee5
GM
978/* Swap glyphs between two glyph rows A and B. This exchanges glyph
979 contents, i.e. glyph structure contents are exchanged between A and
980 B without changing glyph pointers in A and B. */
981
982static void
1dae0f0a 983swap_glyphs_in_rows (struct glyph_row *a, struct glyph_row *b)
5f5c8ee5
GM
984{
985 int area;
986
987 for (area = 0; area < LAST_AREA; ++area)
988 {
989 /* Number of glyphs to swap. */
990 int max_used = max (a->used[area], b->used[area]);
991
992 /* Start of glyphs in area of row A. */
993 struct glyph *glyph_a = a->glyphs[area];
994
995 /* End + 1 of glyphs in area of row A. */
996 struct glyph *glyph_a_end = a->glyphs[max_used];
997
998 /* Start of glyphs in area of row B. */
999 struct glyph *glyph_b = b->glyphs[area];
1000
1001 while (glyph_a < glyph_a_end)
1002 {
1003 /* Non-ISO HP/UX compiler doesn't like auto struct
1004 initialization. */
1005 struct glyph temp;
1006 temp = *glyph_a;
1007 *glyph_a = *glyph_b;
1008 *glyph_b = temp;
1009 ++glyph_a;
1010 ++glyph_b;
1011 }
1012 }
1013}
1014
9af3e742 1015#endif /* 0 */
5f5c8ee5 1016
015137db
EZ
1017/* Exchange pointers to glyph memory between glyph rows A and B. Also
1018 exchange the used[] array and the hash values of the rows, because
1019 these should all go together for the row's hash value to be
1020 correct. */
5f5c8ee5 1021
b0ab8123 1022static void
971de7fb 1023swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
5f5c8ee5
GM
1024{
1025 int i;
015137db
EZ
1026 unsigned hash_tem = a->hash;
1027
5f5c8ee5
GM
1028 for (i = 0; i < LAST_AREA + 1; ++i)
1029 {
1030 struct glyph *temp = a->glyphs[i];
015137db 1031
5f5c8ee5
GM
1032 a->glyphs[i] = b->glyphs[i];
1033 b->glyphs[i] = temp;
73055685
EZ
1034 if (i < LAST_AREA)
1035 {
1036 short used_tem = a->used[i];
1037
1038 a->used[i] = b->used[i];
1039 b->used[i] = used_tem;
1040 }
5f5c8ee5 1041 }
015137db
EZ
1042 a->hash = b->hash;
1043 b->hash = hash_tem;
5f5c8ee5
GM
1044}
1045
1046
1047/* Copy glyph row structure FROM to glyph row structure TO, except
015137db
EZ
1048 that glyph pointers, the `used' counts, and the hash values in the
1049 structures are left unchanged. */
5f5c8ee5 1050
b0ab8123 1051static void
971de7fb 1052copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
5f5c8ee5
GM
1053{
1054 struct glyph *pointers[1 + LAST_AREA];
73055685 1055 short used[LAST_AREA];
015137db 1056 unsigned hashval;
5f5c8ee5
GM
1057
1058 /* Save glyph pointers of TO. */
72af86bd 1059 memcpy (pointers, to->glyphs, sizeof to->glyphs);
015137db
EZ
1060 memcpy (used, to->used, sizeof to->used);
1061 hashval = to->hash;
5f5c8ee5
GM
1062
1063 /* Do a structure assignment. */
1064 *to = *from;
1065
1066 /* Restore original pointers of TO. */
72af86bd 1067 memcpy (to->glyphs, pointers, sizeof to->glyphs);
015137db
EZ
1068 memcpy (to->used, used, sizeof to->used);
1069 to->hash = hashval;
5f5c8ee5
GM
1070}
1071
1072
5f5c8ee5
GM
1073/* Assign glyph row FROM to glyph row TO. This works like a structure
1074 assignment TO = FROM, except that glyph pointers are not copied but
1075 exchanged between TO and FROM. Pointers must be exchanged to avoid
1076 a memory leak. */
1077
b0ab8123 1078static void
971de7fb 1079assign_row (struct glyph_row *to, struct glyph_row *from)
5f5c8ee5
GM
1080{
1081 swap_glyph_pointers (to, from);
1082 copy_row_except_pointers (to, from);
1083}
1084
1085
1086/* Test whether the glyph memory of the glyph row WINDOW_ROW, which is
1087 a row in a window matrix, is a slice of the glyph memory of the
1088 glyph row FRAME_ROW which is a row in a frame glyph matrix. Value
59ea14cd 1089 is true if the glyph memory of WINDOW_ROW is part of the glyph
5f5c8ee5
GM
1090 memory of FRAME_ROW. */
1091
e509cfa6 1092#ifdef GLYPH_DEBUG
9339e87f 1093
59ea14cd 1094static bool
59fc5cf9 1095glyph_row_slice_p (struct glyph_row *window_row, struct glyph_row *frame_row)
5f5c8ee5
GM
1096{
1097 struct glyph *window_glyph_start = window_row->glyphs[0];
1098 struct glyph *frame_glyph_start = frame_row->glyphs[0];
1099 struct glyph *frame_glyph_end = frame_row->glyphs[LAST_AREA];
1100
1101 return (frame_glyph_start <= window_glyph_start
1102 && window_glyph_start < frame_glyph_end);
1103}
1104
9339e87f 1105#endif /* GLYPH_DEBUG */
5f5c8ee5 1106
9af3e742
GM
1107#if 0
1108
5f5c8ee5
GM
1109/* Find the row in the window glyph matrix WINDOW_MATRIX being a slice
1110 of ROW in the frame matrix FRAME_MATRIX. Value is null if no row
1111 in WINDOW_MATRIX is found satisfying the condition. */
1112
1113static struct glyph_row *
59fc5cf9
AS
1114find_glyph_row_slice (struct glyph_matrix *window_matrix,
1115 struct glyph_matrix *frame_matrix, int row)
5f5c8ee5
GM
1116{
1117 int i;
1118
a54e2c05 1119 eassert (row >= 0 && row < frame_matrix->nrows);
5f5c8ee5
GM
1120
1121 for (i = 0; i < window_matrix->nrows; ++i)
1122 if (glyph_row_slice_p (window_matrix->rows + i,
1123 frame_matrix->rows + row))
1124 break;
1125
1126 return i < window_matrix->nrows ? window_matrix->rows + i : 0;
1127}
1128
9af3e742 1129#endif /* 0 */
5f5c8ee5
GM
1130
1131/* Prepare ROW for display. Desired rows are cleared lazily,
1132 i.e. they are only marked as to be cleared by setting their
1133 enabled_p flag to zero. When a row is to be displayed, a prior
1134 call to this function really clears it. */
1135
1136void
971de7fb 1137prepare_desired_row (struct glyph_row *row)
5f5c8ee5
GM
1138{
1139 if (!row->enabled_p)
1140 {
59ea14cd 1141 bool rp = row->reversed_p;
5009f85e 1142
5f5c8ee5
GM
1143 clear_glyph_row (row);
1144 row->enabled_p = 1;
5009f85e 1145 row->reversed_p = rp;
5f5c8ee5
GM
1146 }
1147}
1148
1149
1150/* Return a hash code for glyph row ROW. */
1151
2f7c71a1 1152static int
971de7fb 1153line_hash_code (struct glyph_row *row)
5f5c8ee5
GM
1154{
1155 int hash = 0;
177c0ea7 1156
5f5c8ee5
GM
1157 if (row->enabled_p)
1158 {
4cecaab8
MB
1159 struct glyph *glyph = row->glyphs[TEXT_AREA];
1160 struct glyph *end = glyph + row->used[TEXT_AREA];
1161
1162 while (glyph < end)
1163 {
1164 int c = glyph->u.ch;
1165 int face_id = glyph->face_id;
daf01701 1166 if (FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
4cecaab8
MB
1167 c -= SPACEGLYPH;
1168 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
1169 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
1170 ++glyph;
1171 }
5f5c8ee5 1172
4cecaab8
MB
1173 if (hash == 0)
1174 hash = 1;
5f5c8ee5
GM
1175 }
1176
1177 return hash;
1178}
1179
1180
153a073c 1181/* Return the cost of drawing line VPOS in MATRIX. The cost equals
5f5c8ee5
GM
1182 the number of characters in the line. If must_write_spaces is
1183 zero, leading and trailing spaces are ignored. */
1184
dfd153ae 1185static int
971de7fb 1186line_draw_cost (struct glyph_matrix *matrix, int vpos)
5f5c8ee5
GM
1187{
1188 struct glyph_row *row = matrix->rows + vpos;
1189 struct glyph *beg = row->glyphs[TEXT_AREA];
1190 struct glyph *end = beg + row->used[TEXT_AREA];
1191 int len;
1192 Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
ca9ce8f2 1193 ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH;
5f5c8ee5
GM
1194
1195 /* Ignore trailing and leading spaces if we can. */
daf01701 1196 if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
5f5c8ee5
GM
1197 {
1198 /* Skip from the end over trailing spaces. */
2b4ec4d7 1199 while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1)))
5f5c8ee5
GM
1200 --end;
1201
177c0ea7 1202 /* All blank line. */
5f5c8ee5
GM
1203 if (end == beg)
1204 return 0;
1205
1206 /* Skip over leading spaces. */
1207 while (CHAR_GLYPH_SPACE_P (*beg))
1208 ++beg;
1209 }
1210
1211 /* If we don't have a glyph-table, each glyph is one character,
1212 so return the number of glyphs. */
1213 if (glyph_table_base == 0)
1214 len = end - beg;
1215 else
1216 {
1217 /* Otherwise, scan the glyphs and accumulate their total length
1218 in LEN. */
1219 len = 0;
1220 while (beg < end)
1221 {
3fc809e2 1222 GLYPH g;
177c0ea7 1223
3fc809e2
KS
1224 SET_GLYPH_FROM_CHAR_GLYPH (g, *beg);
1225
565b39a8 1226 if (GLYPH_INVALID_P (g)
42186983 1227 || GLYPH_SIMPLE_P (glyph_table_base, glyph_table_len, g))
5f5c8ee5
GM
1228 len += 1;
1229 else
1230 len += GLYPH_LENGTH (glyph_table_base, g);
177c0ea7 1231
5f5c8ee5
GM
1232 ++beg;
1233 }
1234 }
177c0ea7 1235
5f5c8ee5
GM
1236 return len;
1237}
1238
1239
59ea14cd
PE
1240/* Return true if the glyph rows A and B have equal contents.
1241 MOUSE_FACE_P means compare the mouse_face_p flags of A and B, too. */
5f5c8ee5 1242
b0ab8123 1243static bool
59ea14cd 1244row_equal_p (struct glyph_row *a, struct glyph_row *b, bool mouse_face_p)
5f5c8ee5 1245{
a54e2c05
DA
1246 eassert (verify_row_hash (a));
1247 eassert (verify_row_hash (b));
7a7270dd 1248
5f5c8ee5
GM
1249 if (a == b)
1250 return 1;
1251 else if (a->hash != b->hash)
1252 return 0;
1253 else
1254 {
1255 struct glyph *a_glyph, *b_glyph, *a_end;
1256 int area;
1257
e4e0bee9
GM
1258 if (mouse_face_p && a->mouse_face_p != b->mouse_face_p)
1259 return 0;
1260
5f5c8ee5
GM
1261 /* Compare glyphs. */
1262 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
1263 {
1264 if (a->used[area] != b->used[area])
1265 return 0;
177c0ea7 1266
5f5c8ee5
GM
1267 a_glyph = a->glyphs[area];
1268 a_end = a_glyph + a->used[area];
1269 b_glyph = b->glyphs[area];
177c0ea7 1270
5f5c8ee5
GM
1271 while (a_glyph < a_end
1272 && GLYPH_EQUAL_P (a_glyph, b_glyph))
1273 ++a_glyph, ++b_glyph;
177c0ea7 1274
5f5c8ee5
GM
1275 if (a_glyph != a_end)
1276 return 0;
1277 }
1278
6b61353c
KH
1279 if (a->fill_line_p != b->fill_line_p
1280 || a->cursor_in_fringe_p != b->cursor_in_fringe_p
1281 || a->left_fringe_bitmap != b->left_fringe_bitmap
1282 || a->left_fringe_face_id != b->left_fringe_face_id
e61124cd 1283 || a->left_fringe_offset != b->left_fringe_offset
6b61353c
KH
1284 || a->right_fringe_bitmap != b->right_fringe_bitmap
1285 || a->right_fringe_face_id != b->right_fringe_face_id
e61124cd
YM
1286 || a->right_fringe_offset != b->right_fringe_offset
1287 || a->fringe_bitmap_periodic_p != b->fringe_bitmap_periodic_p
3d4a365f 1288 || a->overlay_arrow_bitmap != b->overlay_arrow_bitmap
6b61353c 1289 || a->exact_window_width_line_p != b->exact_window_width_line_p
408f5064 1290 || a->overlapped_p != b->overlapped_p
5f5c8ee5
GM
1291 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
1292 != MATRIX_ROW_CONTINUATION_LINE_P (b))
918f4159 1293 || a->reversed_p != b->reversed_p
5f5c8ee5
GM
1294 /* Different partially visible characters on left margin. */
1295 || a->x != b->x
1296 /* Different height. */
1297 || a->ascent != b->ascent
408f5064
GM
1298 || a->phys_ascent != b->phys_ascent
1299 || a->phys_height != b->phys_height
5f5c8ee5
GM
1300 || a->visible_height != b->visible_height)
1301 return 0;
1302 }
1303
1304 return 1;
1305}
1306
1307
1308\f
1309/***********************************************************************
1310 Glyph Pool
1311
1312 See dispextern.h for an overall explanation of glyph pools.
1313 ***********************************************************************/
1314
1315/* Allocate a glyph_pool structure. The structure returned is
1316 initialized with zeros. The global variable glyph_pool_count is
1317 incremented for each pool allocated. */
1318
1319static struct glyph_pool *
971de7fb 1320new_glyph_pool (void)
5f5c8ee5 1321{
23f86fce 1322 struct glyph_pool *result = xzalloc (sizeof *result);
177c0ea7 1323
5f5c8ee5
GM
1324 /* For memory leak and double deletion checking. */
1325 ++glyph_pool_count;
177c0ea7 1326
5f5c8ee5
GM
1327 return result;
1328}
1329
1330
1331/* Free a glyph_pool structure POOL. The function may be called with
1332 a null POOL pointer. The global variable glyph_pool_count is
1333 decremented with every pool structure freed. If this count gets
1334 negative, more structures were freed than allocated, i.e. one
1335 structure must have been freed more than once or a bogus pointer
1336 was passed to free_glyph_pool. */
1337
1338static void
971de7fb 1339free_glyph_pool (struct glyph_pool *pool)
5f5c8ee5
GM
1340{
1341 if (pool)
1342 {
153a073c 1343 /* More freed than allocated? */
5f5c8ee5 1344 --glyph_pool_count;
a54e2c05 1345 eassert (glyph_pool_count >= 0);
5f5c8ee5
GM
1346
1347 xfree (pool->glyphs);
1348 xfree (pool);
1349 }
1350}
1351
1352
1353/* Enlarge a glyph pool POOL. MATRIX_DIM gives the number of rows and
1354 columns we need. This function never shrinks a pool. The only
1355 case in which this would make sense, would be when a frame's size
1356 is changed from a large value to a smaller one. But, if someone
1357 does it once, we can expect that he will do it again.
1358
59ea14cd 1359 Return true if the pool changed in a way which makes
5f5c8ee5
GM
1360 re-adjusting window glyph matrices necessary. */
1361
59ea14cd 1362static bool
971de7fb 1363realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
5f5c8ee5 1364{
ca9ce8f2 1365 ptrdiff_t needed;
59ea14cd 1366 bool changed_p;
5f5c8ee5
GM
1367
1368 changed_p = (pool->glyphs == 0
1369 || matrix_dim.height != pool->nrows
1370 || matrix_dim.width != pool->ncolumns);
1371
1372 /* Enlarge the glyph pool. */
ca9ce8f2 1373 needed = matrix_dim.width;
0065d054
PE
1374 if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height))
1375 memory_full (SIZE_MAX);
ca9ce8f2 1376 needed *= matrix_dim.height;
5f5c8ee5
GM
1377 if (needed > pool->nglyphs)
1378 {
0065d054
PE
1379 ptrdiff_t old_nglyphs = pool->nglyphs;
1380 pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs,
1381 needed - old_nglyphs, -1, sizeof *pool->glyphs);
1382 memset (pool->glyphs + old_nglyphs, 0,
1383 (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
5f5c8ee5
GM
1384 }
1385
153a073c 1386 /* Remember the number of rows and columns because (a) we use them
5f5c8ee5
GM
1387 to do sanity checks, and (b) the number of columns determines
1388 where rows in the frame matrix start---this must be available to
1389 determine pointers to rows of window sub-matrices. */
1390 pool->nrows = matrix_dim.height;
1391 pool->ncolumns = matrix_dim.width;
177c0ea7 1392
5f5c8ee5
GM
1393 return changed_p;
1394}
1395
1396
1397\f
1398/***********************************************************************
1399 Debug Code
1400 ***********************************************************************/
1401
e509cfa6 1402#ifdef GLYPH_DEBUG
5f5c8ee5 1403
a13396c9 1404
28d440ab
KL
1405/* Flush standard output. This is sometimes useful to call from the debugger.
1406 XXX Maybe this should be changed to flush the current terminal instead of
1407 stdout.
1408*/
a13396c9 1409
85fece3e
PE
1410void flush_stdout (void) EXTERNALLY_VISIBLE;
1411
a13396c9 1412void
59fc5cf9 1413flush_stdout (void)
a13396c9
GM
1414{
1415 fflush (stdout);
1416}
1417
1418
5f5c8ee5
GM
1419/* Check that no glyph pointers have been lost in MATRIX. If a
1420 pointer has been lost, e.g. by using a structure assignment between
1421 rows, at least one pointer must occur more than once in the rows of
1422 MATRIX. */
1423
1424void
59fc5cf9 1425check_matrix_pointer_lossage (struct glyph_matrix *matrix)
5f5c8ee5
GM
1426{
1427 int i, j;
177c0ea7 1428
5f5c8ee5
GM
1429 for (i = 0; i < matrix->nrows; ++i)
1430 for (j = 0; j < matrix->nrows; ++j)
a54e2c05 1431 eassert (i == j
5f5c8ee5
GM
1432 || (matrix->rows[i].glyphs[TEXT_AREA]
1433 != matrix->rows[j].glyphs[TEXT_AREA]));
1434}
1435
1436
1437/* Get a pointer to glyph row ROW in MATRIX, with bounds checks. */
1438
1439struct glyph_row *
59fc5cf9 1440matrix_row (struct glyph_matrix *matrix, int row)
5f5c8ee5 1441{
a54e2c05
DA
1442 eassert (matrix && matrix->rows);
1443 eassert (row >= 0 && row < matrix->nrows);
5f5c8ee5
GM
1444
1445 /* That's really too slow for normal testing because this function
1446 is called almost everywhere. Although---it's still astonishingly
1447 fast, so it is valuable to have for debugging purposes. */
1448#if 0
1449 check_matrix_pointer_lossage (matrix);
1450#endif
177c0ea7 1451
5f5c8ee5
GM
1452 return matrix->rows + row;
1453}
1454
1455
1456#if 0 /* This function makes invalid assumptions when text is
1457 partially invisible. But it might come handy for debugging
1458 nevertheless. */
1459
1460/* Check invariants that must hold for an up to date current matrix of
1461 window W. */
1462
1463static void
59fc5cf9 1464check_matrix_invariants (struct window *w)
5f5c8ee5
GM
1465{
1466 struct glyph_matrix *matrix = w->current_matrix;
1467 int yb = window_text_bottom_y (w);
1468 struct glyph_row *row = matrix->rows;
1469 struct glyph_row *last_text_row = NULL;
1470 struct buffer *saved = current_buffer;
d3d50620 1471 struct buffer *buffer = XBUFFER (w->buffer);
5f5c8ee5 1472 int c;
177c0ea7 1473
5f5c8ee5
GM
1474 /* This can sometimes happen for a fresh window. */
1475 if (matrix->nrows < 2)
1476 return;
1477
1478 set_buffer_temp (buffer);
1479
1480 /* Note: last row is always reserved for the mode line. */
1481 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
1482 && MATRIX_ROW_BOTTOM_Y (row) < yb)
1483 {
1484 struct glyph_row *next = row + 1;
1485
1486 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
1487 last_text_row = row;
1488
1489 /* Check that character and byte positions are in sync. */
a54e2c05 1490 eassert (MATRIX_ROW_START_BYTEPOS (row)
5f5c8ee5 1491 == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
a54e2c05 1492 eassert (BYTEPOS (row->start.pos)
d36fe237 1493 == CHAR_TO_BYTE (CHARPOS (row->start.pos)));
5f5c8ee5
GM
1494
1495 /* CHAR_TO_BYTE aborts when invoked for a position > Z. We can
1496 have such a position temporarily in case of a minibuffer
1497 displaying something like `[Sole completion]' at its end. */
1498 if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
d36fe237 1499 {
a54e2c05 1500 eassert (MATRIX_ROW_END_BYTEPOS (row)
d36fe237 1501 == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
a54e2c05 1502 eassert (BYTEPOS (row->end.pos)
d36fe237
EZ
1503 == CHAR_TO_BYTE (CHARPOS (row->end.pos)));
1504 }
5f5c8ee5
GM
1505
1506 /* Check that end position of `row' is equal to start position
1507 of next row. */
1508 if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next))
1509 {
a54e2c05 1510 eassert (MATRIX_ROW_END_CHARPOS (row)
5f5c8ee5 1511 == MATRIX_ROW_START_CHARPOS (next));
a54e2c05 1512 eassert (MATRIX_ROW_END_BYTEPOS (row)
5f5c8ee5 1513 == MATRIX_ROW_START_BYTEPOS (next));
a54e2c05
DA
1514 eassert (CHARPOS (row->end.pos) == CHARPOS (next->start.pos));
1515 eassert (BYTEPOS (row->end.pos) == BYTEPOS (next->start.pos));
5f5c8ee5
GM
1516 }
1517 row = next;
1518 }
1519
a54e2c05
DA
1520 eassert (w->current_matrix->nrows == w->desired_matrix->nrows);
1521 eassert (w->desired_matrix->rows != NULL);
5f5c8ee5
GM
1522 set_buffer_temp (saved);
1523}
1524
1525#endif /* 0 */
1526
e509cfa6 1527#endif /* GLYPH_DEBUG */
5f5c8ee5
GM
1528
1529
1530\f
1531/**********************************************************************
1532 Allocating/ Adjusting Glyph Matrices
1533 **********************************************************************/
1534
1535/* Allocate glyph matrices over a window tree for a frame-based
1536 redisplay
1537
1538 X and Y are column/row within the frame glyph matrix where
1539 sub-matrices for the window tree rooted at WINDOW must be
59ea14cd 1540 allocated. DIM_ONLY_P means that the caller of this
8ce2650d
YM
1541 function is only interested in the result matrix dimension, and
1542 matrix adjustments should not be performed.
5f5c8ee5
GM
1543
1544 The function returns the total width/height of the sub-matrices of
1545 the window tree. If called on a frame root window, the computation
1546 will take the mini-buffer window into account.
1547
1548 *WINDOW_CHANGE_FLAGS is set to a bit mask with bits
1549
1550 NEW_LEAF_MATRIX set if any window in the tree did not have a
1551 glyph matrices yet, and
1552
1553 CHANGED_LEAF_MATRIX set if the dimension or location of a matrix of
1554 any window in the tree will be changed or have been changed (see
153a073c 1555 DIM_ONLY_P)
5f5c8ee5
GM
1556
1557 *WINDOW_CHANGE_FLAGS must be initialized by the caller of this
1558 function.
1559
1560 Windows are arranged into chains of windows on the same level
1561 through the next fields of window structures. Such a level can be
1562 either a sequence of horizontally adjacent windows from left to
1563 right, or a sequence of vertically adjacent windows from top to
1564 bottom. Each window in a horizontal sequence can be either a leaf
1565 window or a vertical sequence; a window in a vertical sequence can
1566 be either a leaf or a horizontal sequence. All windows in a
1567 horizontal sequence have the same height, and all windows in a
1568 vertical sequence have the same width.
1569
1570 This function uses, for historical reasons, a more general
1571 algorithm to determine glyph matrix dimensions that would be
1572 necessary.
1573
1574 The matrix height of a horizontal sequence is determined by the
1575 maximum height of any matrix in the sequence. The matrix width of
1576 a horizontal sequence is computed by adding up matrix widths of
1577 windows in the sequence.
1578
1579 |<------- result width ------->|
1580 +---------+----------+---------+ ---
1581 | | | | |
1582 | | | |
1583 +---------+ | | result height
1584 | +---------+
1585 | | |
1586 +----------+ ---
1587
1588 The matrix width of a vertical sequence is the maximum matrix width
1589 of any window in the sequence. Its height is computed by adding up
1590 matrix heights of windows in the sequence.
1591
1592 |<---- result width -->|
1593 +---------+ ---
1594 | | |
1595 | | |
1596 +---------+--+ |
1597 | | |
1598 | | result height
1599 | |
1600 +------------+---------+ |
1601 | | |
1602 | | |
1603 +------------+---------+ --- */
1604
1605/* Bit indicating that a new matrix will be allocated or has been
1606 allocated. */
1607
1608#define NEW_LEAF_MATRIX (1 << 0)
1609
1610/* Bit indicating that a matrix will or has changed its location or
1611 size. */
1612
1613#define CHANGED_LEAF_MATRIX (1 << 1)
1614
1615static struct dim
6f704c76 1616allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
59ea14cd 1617 bool dim_only_p, int *window_change_flags)
5f5c8ee5
GM
1618{
1619 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1620 int x0 = x, y0 = y;
1621 int wmax = 0, hmax = 0;
1622 struct dim total;
1623 struct dim dim;
1624 struct window *w;
59ea14cd 1625 bool in_horz_combination_p;
5f5c8ee5
GM
1626
1627 /* What combination is WINDOW part of? Compute this once since the
1628 result is the same for all windows in the `next' chain. The
1629 special case of a root window (parent equal to nil) is treated
1630 like a vertical combination because a root window's `next'
1631 points to the mini-buffer window, if any, which is arranged
1632 vertically below other windows. */
1633 in_horz_combination_p
d3d50620
DA
1634 = (!NILP (XWINDOW (window)->parent)
1635 && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
5f5c8ee5
GM
1636
1637 /* For WINDOW and all windows on the same level. */
177c0ea7 1638 do
5f5c8ee5
GM
1639 {
1640 w = XWINDOW (window);
1641
1642 /* Get the dimension of the window sub-matrix for W, depending
153a073c 1643 on whether this is a combination or a leaf window. */
d3d50620
DA
1644 if (!NILP (w->hchild))
1645 dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y,
5f5c8ee5
GM
1646 dim_only_p,
1647 window_change_flags);
d3d50620
DA
1648 else if (!NILP (w->vchild))
1649 dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y,
5f5c8ee5
GM
1650 dim_only_p,
1651 window_change_flags);
1652 else
1653 {
1654 /* If not already done, allocate sub-matrix structures. */
1655 if (w->desired_matrix == NULL)
1656 {
1657 w->desired_matrix = new_glyph_matrix (f->desired_pool);
1658 w->current_matrix = new_glyph_matrix (f->current_pool);
1659 *window_change_flags |= NEW_LEAF_MATRIX;
1660 }
177c0ea7 1661
5f5c8ee5
GM
1662 /* Width and height MUST be chosen so that there are no
1663 holes in the frame matrix. */
5d3cc43c
GM
1664 dim.width = required_matrix_width (w);
1665 dim.height = required_matrix_height (w);
5f5c8ee5
GM
1666
1667 /* Will matrix be re-allocated? */
1668 if (x != w->desired_matrix->matrix_x
1669 || y != w->desired_matrix->matrix_y
1670 || dim.width != w->desired_matrix->matrix_w
1671 || dim.height != w->desired_matrix->matrix_h
1672 || (margin_glyphs_to_reserve (w, dim.width,
d3d50620 1673 w->left_margin_cols)
5f5c8ee5
GM
1674 != w->desired_matrix->left_margin_glyphs)
1675 || (margin_glyphs_to_reserve (w, dim.width,
d3d50620 1676 w->right_margin_cols)
5f5c8ee5
GM
1677 != w->desired_matrix->right_margin_glyphs))
1678 *window_change_flags |= CHANGED_LEAF_MATRIX;
1679
1680 /* Actually change matrices, if allowed. Do not consider
1681 CHANGED_LEAF_MATRIX computed above here because the pool
1682 may have been changed which we don't now here. We trust
59ea14cd 1683 that we only will be called with DIM_ONLY_P when
5f5c8ee5
GM
1684 necessary. */
1685 if (!dim_only_p)
1686 {
1687 adjust_glyph_matrix (w, w->desired_matrix, x, y, dim);
1688 adjust_glyph_matrix (w, w->current_matrix, x, y, dim);
1689 }
1690 }
1691
1692 /* If we are part of a horizontal combination, advance x for
1693 windows to the right of W; otherwise advance y for windows
1694 below W. */
1695 if (in_horz_combination_p)
1696 x += dim.width;
177c0ea7 1697 else
5f5c8ee5
GM
1698 y += dim.height;
1699
1700 /* Remember maximum glyph matrix dimensions. */
1701 wmax = max (wmax, dim.width);
1702 hmax = max (hmax, dim.height);
1703
1704 /* Next window on same level. */
d3d50620 1705 window = w->next;
5f5c8ee5
GM
1706 }
1707 while (!NILP (window));
1708
1709 /* Set `total' to the total glyph matrix dimension of this window
1710 level. In a vertical combination, the width is the width of the
1711 widest window; the height is the y we finally reached, corrected
1712 by the y we started with. In a horizontal combination, the total
1713 height is the height of the tallest window, and the width is the
1714 x we finally reached, corrected by the x we started with. */
1715 if (in_horz_combination_p)
1716 {
1717 total.width = x - x0;
1718 total.height = hmax;
1719 }
177c0ea7 1720 else
5f5c8ee5
GM
1721 {
1722 total.width = wmax;
1723 total.height = y - y0;
1724 }
1725
1726 return total;
1727}
1728
1729
5d3cc43c
GM
1730/* Return the required height of glyph matrices for window W. */
1731
2f7c71a1 1732static int
971de7fb 1733required_matrix_height (struct window *w)
5d3cc43c
GM
1734{
1735#ifdef HAVE_WINDOW_SYSTEM
d3d50620 1736 struct frame *f = XFRAME (w->frame);
177c0ea7 1737
5d3cc43c
GM
1738 if (FRAME_WINDOW_P (f))
1739 {
1740 int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f);
1ea40aa2 1741 int window_pixel_height = window_box_height (w) + eabs (w->vscroll);
5d3cc43c 1742 return (((window_pixel_height + ch_height - 1)
cc834cf9 1743 / ch_height) * w->nrows_scale_factor
5d3cc43c
GM
1744 /* One partially visible line at the top and
1745 bottom of the window. */
1746 + 2
153a073c 1747 /* 2 for header and mode line. */
5d3cc43c
GM
1748 + 2);
1749 }
1750#endif /* HAVE_WINDOW_SYSTEM */
177c0ea7 1751
7df02016 1752 return WINDOW_TOTAL_LINES (w);
5d3cc43c
GM
1753}
1754
1755
1756/* Return the required width of glyph matrices for window W. */
1757
2f7c71a1 1758static int
971de7fb 1759required_matrix_width (struct window *w)
5d3cc43c
GM
1760{
1761#ifdef HAVE_WINDOW_SYSTEM
d3d50620 1762 struct frame *f = XFRAME (w->frame);
5d3cc43c
GM
1763 if (FRAME_WINDOW_P (f))
1764 {
1765 int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
7df02016 1766 int window_pixel_width = WINDOW_TOTAL_WIDTH (w);
177c0ea7 1767
5d3cc43c
GM
1768 /* Compute number of glyphs needed in a glyph row. */
1769 return (((window_pixel_width + ch_width - 1)
cc834cf9 1770 / ch_width) * w->ncols_scale_factor
5d3cc43c
GM
1771 /* 2 partially visible columns in the text area. */
1772 + 2
1773 /* One partially visible column at the right
1774 edge of each marginal area. */
1775 + 1 + 1);
1776 }
1777#endif /* HAVE_WINDOW_SYSTEM */
1778
d3d50620 1779 return XINT (w->total_cols);
5d3cc43c
GM
1780}
1781
1782
5f5c8ee5 1783/* Allocate window matrices for window-based redisplay. W is the
8ce2650d 1784 window whose matrices must be allocated/reallocated. */
177c0ea7 1785
5f5c8ee5 1786static void
971de7fb 1787allocate_matrices_for_window_redisplay (struct window *w)
5f5c8ee5 1788{
5f5c8ee5
GM
1789 while (w)
1790 {
d3d50620
DA
1791 if (!NILP (w->vchild))
1792 allocate_matrices_for_window_redisplay (XWINDOW (w->vchild));
1793 else if (!NILP (w->hchild))
1794 allocate_matrices_for_window_redisplay (XWINDOW (w->hchild));
5f5c8ee5
GM
1795 else
1796 {
1797 /* W is a leaf window. */
5f5c8ee5
GM
1798 struct dim dim;
1799
1800 /* If matrices are not yet allocated, allocate them now. */
1801 if (w->desired_matrix == NULL)
1802 {
1803 w->desired_matrix = new_glyph_matrix (NULL);
1804 w->current_matrix = new_glyph_matrix (NULL);
1805 }
1806
5d3cc43c
GM
1807 dim.width = required_matrix_width (w);
1808 dim.height = required_matrix_height (w);
5f5c8ee5
GM
1809 adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
1810 adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
1811 }
177c0ea7 1812
d3d50620 1813 w = NILP (w->next) ? NULL : XWINDOW (w->next);
5f5c8ee5
GM
1814 }
1815}
1816
1817
1818/* Re-allocate/ re-compute glyph matrices on frame F. If F is null,
1819 do it for all frames; otherwise do it just for the given frame.
1820 This function must be called when a new frame is created, its size
1821 changes, or its window configuration changes. */
1822
1823void
971de7fb 1824adjust_glyphs (struct frame *f)
5f5c8ee5 1825{
408f5064
GM
1826 /* Block input so that expose events and other events that access
1827 glyph matrices are not processed while we are changing them. */
4d7e6e51 1828 block_input ();
408f5064 1829
5f5c8ee5
GM
1830 if (f)
1831 adjust_frame_glyphs (f);
1832 else
1833 {
1834 Lisp_Object tail, lisp_frame;
177c0ea7 1835
5f5c8ee5
GM
1836 FOR_EACH_FRAME (tail, lisp_frame)
1837 adjust_frame_glyphs (XFRAME (lisp_frame));
1838 }
408f5064 1839
4d7e6e51 1840 unblock_input ();
5f5c8ee5
GM
1841}
1842
5f5c8ee5
GM
1843/* Allocate/reallocate glyph matrices of a single frame F. */
1844
1845static void
971de7fb 1846adjust_frame_glyphs (struct frame *f)
5f5c8ee5
GM
1847{
1848 if (FRAME_WINDOW_P (f))
1849 adjust_frame_glyphs_for_window_redisplay (f);
1850 else
1851 adjust_frame_glyphs_for_frame_redisplay (f);
177c0ea7 1852
b09cca6a 1853 /* Don't forget the buffer for decode_mode_spec. */
5f5c8ee5
GM
1854 adjust_decode_mode_spec_buffer (f);
1855
1856 f->glyphs_initialized_p = 1;
1857}
1858
59ea14cd 1859/* Return true if any window in the tree has nonzero window margins. See
075757cc 1860 the hack at the end of adjust_frame_glyphs_for_frame_redisplay. */
59ea14cd 1861static bool
971de7fb 1862showing_window_margins_p (struct window *w)
075757cc
CY
1863{
1864 while (w)
1865 {
d3d50620 1866 if (!NILP (w->hchild))
075757cc 1867 {
d3d50620 1868 if (showing_window_margins_p (XWINDOW (w->hchild)))
075757cc
CY
1869 return 1;
1870 }
d3d50620 1871 else if (!NILP (w->vchild))
075757cc 1872 {
d3d50620 1873 if (showing_window_margins_p (XWINDOW (w->vchild)))
075757cc
CY
1874 return 1;
1875 }
d3d50620
DA
1876 else if (!NILP (w->left_margin_cols)
1877 || !NILP (w->right_margin_cols))
075757cc 1878 return 1;
3fc809e2 1879
d3d50620 1880 w = NILP (w->next) ? 0 : XWINDOW (w->next);
075757cc
CY
1881 }
1882 return 0;
1883}
1884
5f5c8ee5 1885
c9f00270
GM
1886/* In the window tree with root W, build current matrices of leaf
1887 windows from the frame's current matrix. */
1888
1889static void
971de7fb 1890fake_current_matrices (Lisp_Object window)
c9f00270
GM
1891{
1892 struct window *w;
177c0ea7 1893
d3d50620 1894 for (; !NILP (window); window = w->next)
c9f00270
GM
1895 {
1896 w = XWINDOW (window);
177c0ea7 1897
d3d50620
DA
1898 if (!NILP (w->hchild))
1899 fake_current_matrices (w->hchild);
1900 else if (!NILP (w->vchild))
1901 fake_current_matrices (w->vchild);
c9f00270
GM
1902 else
1903 {
1904 int i;
d3d50620 1905 struct frame *f = XFRAME (w->frame);
c9f00270
GM
1906 struct glyph_matrix *m = w->current_matrix;
1907 struct glyph_matrix *fm = f->current_matrix;
1908
a54e2c05
DA
1909 eassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
1910 eassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
177c0ea7 1911
c9f00270
GM
1912 for (i = 0; i < m->matrix_h; ++i)
1913 {
1914 struct glyph_row *r = m->rows + i;
7df02016 1915 struct glyph_row *fr = fm->rows + i + WINDOW_TOP_EDGE_LINE (w);
c9f00270 1916
a54e2c05 1917 eassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
c9f00270
GM
1918 && r->glyphs[LAST_AREA] <= fr->glyphs[LAST_AREA]);
1919
1920 r->enabled_p = fr->enabled_p;
1921 if (r->enabled_p)
1922 {
1923 r->used[LEFT_MARGIN_AREA] = m->left_margin_glyphs;
1924 r->used[RIGHT_MARGIN_AREA] = m->right_margin_glyphs;
1925 r->used[TEXT_AREA] = (m->matrix_w
1926 - r->used[LEFT_MARGIN_AREA]
1927 - r->used[RIGHT_MARGIN_AREA]);
1928 r->mode_line_p = 0;
c9f00270
GM
1929 }
1930 }
1931 }
1932 }
1933}
1934
1935
bccee4f2 1936/* Save away the contents of frame F's current frame matrix. Value is
153a073c 1937 a glyph matrix holding the contents of F's current frame matrix. */
c9f00270 1938
bccee4f2 1939static struct glyph_matrix *
971de7fb 1940save_current_matrix (struct frame *f)
c9f00270 1941{
bccee4f2 1942 int i;
38182d90 1943 struct glyph_matrix *saved = xzalloc (sizeof *saved);
bccee4f2 1944 saved->nrows = f->current_matrix->nrows;
23f86fce 1945 saved->rows = xzalloc (saved->nrows * sizeof *saved->rows);
bccee4f2
GM
1946
1947 for (i = 0; i < saved->nrows; ++i)
31798cfe 1948 {
bccee4f2
GM
1949 struct glyph_row *from = f->current_matrix->rows + i;
1950 struct glyph_row *to = saved->rows + i;
dfd153ae 1951 ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
23f86fce 1952 to->glyphs[TEXT_AREA] = xmalloc (nbytes);
72af86bd 1953 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
bccee4f2 1954 to->used[TEXT_AREA] = from->used[TEXT_AREA];
e797dea6 1955 }
bccee4f2
GM
1956
1957 return saved;
1958}
1959
1960
1961/* Restore the contents of frame F's current frame matrix from SAVED,
1962 and free memory associated with SAVED. */
1963
1964static void
971de7fb 1965restore_current_matrix (struct frame *f, struct glyph_matrix *saved)
bccee4f2
GM
1966{
1967 int i;
1968
1969 for (i = 0; i < saved->nrows; ++i)
e797dea6 1970 {
bccee4f2
GM
1971 struct glyph_row *from = saved->rows + i;
1972 struct glyph_row *to = f->current_matrix->rows + i;
dfd153ae 1973 ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
72af86bd 1974 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
e797dea6 1975 to->used[TEXT_AREA] = from->used[TEXT_AREA];
bccee4f2 1976 xfree (from->glyphs[TEXT_AREA]);
e797dea6 1977 }
177c0ea7 1978
bccee4f2
GM
1979 xfree (saved->rows);
1980 xfree (saved);
c9f00270
GM
1981}
1982
1983
bccee4f2 1984
5f5c8ee5
GM
1985/* Allocate/reallocate glyph matrices of a single frame F for
1986 frame-based redisplay. */
1987
1988static void
971de7fb 1989adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
5f5c8ee5 1990{
5f5c8ee5 1991 struct dim matrix_dim;
59ea14cd 1992 bool pool_changed_p;
5f5c8ee5
GM
1993 int window_change_flags;
1994 int top_window_y;
1995
1996 if (!FRAME_LIVE_P (f))
1997 return;
1998
5f5c8ee5
GM
1999 top_window_y = FRAME_TOP_MARGIN (f);
2000
2001 /* Allocate glyph pool structures if not already done. */
2002 if (f->desired_pool == NULL)
2003 {
2004 f->desired_pool = new_glyph_pool ();
2005 f->current_pool = new_glyph_pool ();
2006 }
2007
2008 /* Allocate frames matrix structures if needed. */
2009 if (f->desired_matrix == NULL)
2010 {
2011 f->desired_matrix = new_glyph_matrix (f->desired_pool);
2012 f->current_matrix = new_glyph_matrix (f->current_pool);
2013 }
177c0ea7 2014
5f5c8ee5
GM
2015 /* Compute window glyph matrices. (This takes the mini-buffer
2016 window into account). The result is the size of the frame glyph
2017 matrix needed. The variable window_change_flags is set to a bit
2018 mask indicating whether new matrices will be allocated or
2019 existing matrices change their size or location within the frame
2020 matrix. */
2021 window_change_flags = 0;
2022 matrix_dim
2023 = allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2024 0, top_window_y,
5d3cc43c 2025 1,
5f5c8ee5
GM
2026 &window_change_flags);
2027
2028 /* Add in menu bar lines, if any. */
2029 matrix_dim.height += top_window_y;
2030
2031 /* Enlarge pools as necessary. */
2032 pool_changed_p = realloc_glyph_pool (f->desired_pool, matrix_dim);
2033 realloc_glyph_pool (f->current_pool, matrix_dim);
2034
177c0ea7 2035 /* Set up glyph pointers within window matrices. Do this only if
5f5c8ee5
GM
2036 absolutely necessary since it requires a frame redraw. */
2037 if (pool_changed_p || window_change_flags)
2038 {
2039 /* Do it for window matrices. */
2040 allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
5d3cc43c 2041 0, top_window_y, 0,
5f5c8ee5
GM
2042 &window_change_flags);
2043
2044 /* Size of frame matrices must equal size of frame. Note
2045 that we are called for X frames with window widths NOT equal
2046 to the frame width (from CHANGE_FRAME_SIZE_1). */
a54e2c05 2047 eassert (matrix_dim.width == FRAME_COLS (f)
7df02016 2048 && matrix_dim.height == FRAME_LINES (f));
177c0ea7 2049
e797dea6
GM
2050 /* Pointers to glyph memory in glyph rows are exchanged during
2051 the update phase of redisplay, which means in general that a
2052 frame's current matrix consists of pointers into both the
2053 desired and current glyph pool of the frame. Adjusting a
2054 matrix sets the frame matrix up so that pointers are all into
2055 the same pool. If we want to preserve glyph contents of the
2056 current matrix over a call to adjust_glyph_matrix, we must
2057 make a copy of the current glyphs, and restore the current
2058 matrix' contents from that copy. */
2059 if (display_completed
2060 && !FRAME_GARBAGED_P (f)
2061 && matrix_dim.width == f->current_matrix->matrix_w
075757cc
CY
2062 && matrix_dim.height == f->current_matrix->matrix_h
2063 /* For some reason, the frame glyph matrix gets corrupted if
2064 any of the windows contain margins. I haven't been able
2065 to hunt down the reason, but for the moment this prevents
2066 the problem from manifesting. -- cyd */
d5c20fe8 2067 && !showing_window_margins_p (XWINDOW (FRAME_ROOT_WINDOW (f))))
e797dea6 2068 {
bccee4f2
GM
2069 struct glyph_matrix *copy = save_current_matrix (f);
2070 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
e797dea6 2071 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
bccee4f2 2072 restore_current_matrix (f, copy);
e797dea6
GM
2073 fake_current_matrices (FRAME_ROOT_WINDOW (f));
2074 }
c9f00270 2075 else
e797dea6 2076 {
bccee4f2 2077 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
e797dea6
GM
2078 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2079 SET_FRAME_GARBAGED (f);
2080 }
5f5c8ee5
GM
2081 }
2082}
2083
2084
2085/* Allocate/reallocate glyph matrices of a single frame F for
2086 window-based redisplay. */
2087
2088static void
971de7fb 2089adjust_frame_glyphs_for_window_redisplay (struct frame *f)
5f5c8ee5 2090{
a54e2c05 2091 eassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
177c0ea7 2092
5f5c8ee5 2093 /* Allocate/reallocate window matrices. */
5d3cc43c 2094 allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
5f5c8ee5 2095
8ce2650d 2096#ifdef HAVE_X_WINDOWS
5f5c8ee5
GM
2097 /* Allocate/ reallocate matrices of the dummy window used to display
2098 the menu bar under X when no X toolkit support is available. */
488dd4c4 2099#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
5f5c8ee5
GM
2100 {
2101 /* Allocate a dummy window if not already done. */
d2d37ddc 2102 struct window *w;
e69b0960 2103 if (NILP (f->menu_bar_window))
5f5c8ee5 2104 {
077288cf 2105 Lisp_Object frame;
f00af5b1 2106 fset_menu_bar_window (f, make_window ());
e69b0960 2107 w = XWINDOW (f->menu_bar_window);
077288cf 2108 XSETFRAME (frame, f);
e8c17b81 2109 wset_frame (w, frame);
5f5c8ee5
GM
2110 w->pseudo_window_p = 1;
2111 }
2112 else
e69b0960 2113 w = XWINDOW (f->menu_bar_window);
5f5c8ee5
GM
2114
2115 /* Set window dimensions to frame dimensions and allocate or
2116 adjust glyph matrices of W. */
e8c17b81
PE
2117 wset_top_line (w, make_number (0));
2118 wset_left_col (w, make_number (0));
2119 wset_total_lines (w, make_number (FRAME_MENU_BAR_LINES (f)));
2120 wset_total_cols (w, make_number (FRAME_TOTAL_COLS (f)));
5d3cc43c 2121 allocate_matrices_for_window_redisplay (w);
5f5c8ee5 2122 }
57714a86
YM
2123#endif /* not USE_X_TOOLKIT && not USE_GTK */
2124#endif /* HAVE_X_WINDOWS */
5f5c8ee5 2125
488dd4c4 2126#ifndef USE_GTK
d2d37ddc
PE
2127 {
2128 /* Allocate/ reallocate matrices of the tool bar window. If we
2129 don't have a tool bar window yet, make one. */
2130 struct window *w;
e69b0960 2131 if (NILP (f->tool_bar_window))
d2d37ddc 2132 {
077288cf 2133 Lisp_Object frame;
f00af5b1 2134 fset_tool_bar_window (f, make_window ());
e69b0960 2135 w = XWINDOW (f->tool_bar_window);
077288cf 2136 XSETFRAME (frame, f);
e8c17b81 2137 wset_frame (w, frame);
d2d37ddc
PE
2138 w->pseudo_window_p = 1;
2139 }
2140 else
e69b0960 2141 w = XWINDOW (f->tool_bar_window);
5f5c8ee5 2142
e8c17b81
PE
2143 wset_top_line (w, make_number (FRAME_MENU_BAR_LINES (f)));
2144 wset_left_col (w, make_number (0));
2145 wset_total_lines (w, make_number (FRAME_TOOL_BAR_LINES (f)));
2146 wset_total_cols (w, make_number (FRAME_TOTAL_COLS (f)));
d2d37ddc
PE
2147 allocate_matrices_for_window_redisplay (w);
2148 }
488dd4c4 2149#endif
5f5c8ee5
GM
2150}
2151
2152
5f5c8ee5
GM
2153/* Re-allocate buffer for decode_mode_spec on frame F. */
2154
2155static void
971de7fb 2156adjust_decode_mode_spec_buffer (struct frame *f)
5f5c8ee5 2157{
38182d90
PE
2158 f->decode_mode_spec_buffer = xrealloc (f->decode_mode_spec_buffer,
2159 FRAME_MESSAGE_BUF_SIZE (f) + 1);
5f5c8ee5
GM
2160}
2161
2162
2163\f
2164/**********************************************************************
2165 Freeing Glyph Matrices
2166 **********************************************************************/
2167
2168/* Free glyph memory for a frame F. F may be null. This function can
2169 be called for the same frame more than once. The root window of
2170 F may be nil when this function is called. This is the case when
2171 the function is called when F is destroyed. */
2172
2173void
971de7fb 2174free_glyphs (struct frame *f)
5f5c8ee5
GM
2175{
2176 if (f && f->glyphs_initialized_p)
2177 {
42f55fe0
GM
2178 /* Block interrupt input so that we don't get surprised by an X
2179 event while we're in an inconsistent state. */
4d7e6e51 2180 block_input ();
5f5c8ee5 2181 f->glyphs_initialized_p = 0;
177c0ea7 2182
5f5c8ee5 2183 /* Release window sub-matrices. */
e69b0960
DA
2184 if (!NILP (f->root_window))
2185 free_window_matrices (XWINDOW (f->root_window));
5f5c8ee5
GM
2186
2187 /* Free the dummy window for menu bars without X toolkit and its
2188 glyph matrices. */
e69b0960 2189 if (!NILP (f->menu_bar_window))
5f5c8ee5 2190 {
e69b0960 2191 struct window *w = XWINDOW (f->menu_bar_window);
5f5c8ee5
GM
2192 free_glyph_matrix (w->desired_matrix);
2193 free_glyph_matrix (w->current_matrix);
2194 w->desired_matrix = w->current_matrix = NULL;
f00af5b1 2195 fset_menu_bar_window (f, Qnil);
5f5c8ee5
GM
2196 }
2197
9ea173e8 2198 /* Free the tool bar window and its glyph matrices. */
e69b0960 2199 if (!NILP (f->tool_bar_window))
5f5c8ee5 2200 {
e69b0960 2201 struct window *w = XWINDOW (f->tool_bar_window);
5f5c8ee5
GM
2202 free_glyph_matrix (w->desired_matrix);
2203 free_glyph_matrix (w->current_matrix);
2204 w->desired_matrix = w->current_matrix = NULL;
f00af5b1 2205 fset_tool_bar_window (f, Qnil);
5f5c8ee5
GM
2206 }
2207
2208 /* Release frame glyph matrices. Reset fields to zero in
2209 case we are called a second time. */
2210 if (f->desired_matrix)
2211 {
2212 free_glyph_matrix (f->desired_matrix);
2213 free_glyph_matrix (f->current_matrix);
2214 f->desired_matrix = f->current_matrix = NULL;
2215 }
2216
2217 /* Release glyph pools. */
2218 if (f->desired_pool)
2219 {
2220 free_glyph_pool (f->desired_pool);
2221 free_glyph_pool (f->current_pool);
2222 f->desired_pool = f->current_pool = NULL;
2223 }
177c0ea7 2224
4d7e6e51 2225 unblock_input ();
5f5c8ee5
GM
2226 }
2227}
2228
2229
2230/* Free glyph sub-matrices in the window tree rooted at W. This
2231 function may be called with a null pointer, and it may be called on
2232 the same tree more than once. */
2233
2234void
971de7fb 2235free_window_matrices (struct window *w)
5f5c8ee5
GM
2236{
2237 while (w)
2238 {
d3d50620
DA
2239 if (!NILP (w->hchild))
2240 free_window_matrices (XWINDOW (w->hchild));
2241 else if (!NILP (w->vchild))
2242 free_window_matrices (XWINDOW (w->vchild));
177c0ea7 2243 else
5f5c8ee5
GM
2244 {
2245 /* This is a leaf window. Free its memory and reset fields
2246 to zero in case this function is called a second time for
2247 W. */
2248 free_glyph_matrix (w->current_matrix);
2249 free_glyph_matrix (w->desired_matrix);
2250 w->current_matrix = w->desired_matrix = NULL;
2251 }
2252
2253 /* Next window on same level. */
d3d50620 2254 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5f5c8ee5
GM
2255 }
2256}
2257
2258
2259/* Check glyph memory leaks. This function is called from
2260 shut_down_emacs. Note that frames are not destroyed when Emacs
2261 exits. We therefore free all glyph memory for all active frames
2262 explicitly and check that nothing is left allocated. */
2263
2264void
971de7fb 2265check_glyph_memory (void)
5f5c8ee5
GM
2266{
2267 Lisp_Object tail, frame;
2268
2269 /* Free glyph memory for all frames. */
2270 FOR_EACH_FRAME (tail, frame)
2271 free_glyphs (XFRAME (frame));
2272
2273 /* Check that nothing is left allocated. */
2274 if (glyph_matrix_count)
1088b922 2275 emacs_abort ();
5f5c8ee5 2276 if (glyph_pool_count)
1088b922 2277 emacs_abort ();
5f5c8ee5
GM
2278}
2279
2280
2281\f
2282/**********************************************************************
2283 Building a Frame Matrix
2284 **********************************************************************/
2285
2286/* Most of the redisplay code works on glyph matrices attached to
2287 windows. This is a good solution most of the time, but it is not
2288 suitable for terminal code. Terminal output functions cannot rely
2289 on being able to set an arbitrary terminal window. Instead they
2290 must be provided with a view of the whole frame, i.e. the whole
2291 screen. We build such a view by constructing a frame matrix from
2292 window matrices in this section.
2293
2294 Windows that must be updated have their must_be_update_p flag set.
2295 For all such windows, their desired matrix is made part of the
2296 desired frame matrix. For other windows, their current matrix is
2297 made part of the desired frame matrix.
2298
2299 +-----------------+----------------+
2300 | desired | desired |
2301 | | |
2302 +-----------------+----------------+
2303 | current |
2304 | |
2305 +----------------------------------+
2306
2307 Desired window matrices can be made part of the frame matrix in a
2308 cheap way: We exploit the fact that the desired frame matrix and
2309 desired window matrices share their glyph memory. This is not
2310 possible for current window matrices. Their glyphs are copied to
2311 the desired frame matrix. The latter is equivalent to
2312 preserve_other_columns in the old redisplay.
2313
2314 Used glyphs counters for frame matrix rows are the result of adding
2315 up glyph lengths of the window matrices. A line in the frame
2316 matrix is enabled, if a corresponding line in a window matrix is
2317 enabled.
177c0ea7 2318
5f5c8ee5
GM
2319 After building the desired frame matrix, it will be passed to
2320 terminal code, which will manipulate both the desired and current
2321 frame matrix. Changes applied to the frame's current matrix have
2322 to be visible in current window matrices afterwards, of course.
2323
2324 This problem is solved like this:
2325
2326 1. Window and frame matrices share glyphs. Window matrices are
2327 constructed in a way that their glyph contents ARE the glyph
2328 contents needed in a frame matrix. Thus, any modification of
2329 glyphs done in terminal code will be reflected in window matrices
2330 automatically.
177c0ea7 2331
5f5c8ee5
GM
2332 2. Exchanges of rows in a frame matrix done by terminal code are
2333 intercepted by hook functions so that corresponding row operations
2334 on window matrices can be performed. This is necessary because we
2335 use pointers to glyphs in glyph row structures. To satisfy the
2336 assumption of point 1 above that glyphs are updated implicitly in
2337 window matrices when they are manipulated via the frame matrix,
2338 window and frame matrix must of course agree where to find the
2339 glyphs for their rows. Possible manipulations that must be
2340 mirrored are assignments of rows of the desired frame matrix to the
2341 current frame matrix and scrolling the current frame matrix. */
2342
2343/* Build frame F's desired matrix from window matrices. Only windows
2344 which have the flag must_be_updated_p set have to be updated. Menu
2345 bar lines of a frame are not covered by window matrices, so make
2346 sure not to touch them in this function. */
2347
2348static void
971de7fb 2349build_frame_matrix (struct frame *f)
5f5c8ee5
GM
2350{
2351 int i;
2352
2353 /* F must have a frame matrix when this function is called. */
a54e2c05 2354 eassert (!FRAME_WINDOW_P (f));
177c0ea7 2355
5f5c8ee5
GM
2356 /* Clear all rows in the frame matrix covered by window matrices.
2357 Menu bar lines are not covered by windows. */
2358 for (i = FRAME_TOP_MARGIN (f); i < f->desired_matrix->nrows; ++i)
2359 clear_glyph_row (MATRIX_ROW (f->desired_matrix, i));
2360
2361 /* Build the matrix by walking the window tree. */
2362 build_frame_matrix_from_window_tree (f->desired_matrix,
2363 XWINDOW (FRAME_ROOT_WINDOW (f)));
2364}
2365
2366
2367/* Walk a window tree, building a frame matrix MATRIX from window
2368 matrices. W is the root of a window tree. */
2369
2370static void
971de7fb 2371build_frame_matrix_from_window_tree (struct glyph_matrix *matrix, struct window *w)
5f5c8ee5
GM
2372{
2373 while (w)
2374 {
d3d50620
DA
2375 if (!NILP (w->hchild))
2376 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->hchild));
2377 else if (!NILP (w->vchild))
2378 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->vchild));
5f5c8ee5
GM
2379 else
2380 build_frame_matrix_from_leaf_window (matrix, w);
2381
d3d50620 2382 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5f5c8ee5
GM
2383 }
2384}
2385
2386
2387/* Add a window's matrix to a frame matrix. FRAME_MATRIX is the
2388 desired frame matrix built. W is a leaf window whose desired or
2389 current matrix is to be added to FRAME_MATRIX. W's flag
2390 must_be_updated_p determines which matrix it contributes to
59ea14cd 2391 FRAME_MATRIX. If W->must_be_updated_p, W's desired matrix
5f5c8ee5
GM
2392 is added to FRAME_MATRIX, otherwise W's current matrix is added.
2393 Adding a desired matrix means setting up used counters and such in
2394 frame rows, while adding a current window matrix to FRAME_MATRIX
2395 means copying glyphs. The latter case corresponds to
2396 preserve_other_columns in the old redisplay. */
2397
2398static void
971de7fb 2399build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct window *w)
5f5c8ee5
GM
2400{
2401 struct glyph_matrix *window_matrix;
2402 int window_y, frame_y;
2403 /* If non-zero, a glyph to insert at the right border of W. */
3fc809e2
KS
2404 GLYPH right_border_glyph;
2405
2406 SET_GLYPH_FROM_CHAR (right_border_glyph, 0);
5f5c8ee5
GM
2407
2408 /* Set window_matrix to the matrix we have to add to FRAME_MATRIX. */
2409 if (w->must_be_updated_p)
2410 {
2411 window_matrix = w->desired_matrix;
2412
2413 /* Decide whether we want to add a vertical border glyph. */
2414 if (!WINDOW_RIGHTMOST_P (w))
2415 {
2416 struct Lisp_Char_Table *dp = window_display_table (w);
3fc809e2 2417 Lisp_Object gc;
b4e49aee 2418
3fc809e2
KS
2419 SET_GLYPH_FROM_CHAR (right_border_glyph, '|');
2420 if (dp
d311d28c 2421 && (gc = DISP_BORDER_GLYPH (dp), GLYPH_CODE_P (gc)))
3fc809e2
KS
2422 {
2423 SET_GLYPH_FROM_GLYPH_CODE (right_border_glyph, gc);
2424 spec_glyph_lookup_face (w, &right_border_glyph);
2425 }
b4e49aee 2426
3fc809e2
KS
2427 if (GLYPH_FACE (right_border_glyph) <= 0)
2428 SET_GLYPH_FACE (right_border_glyph, VERTICAL_BORDER_FACE_ID);
5f5c8ee5
GM
2429 }
2430 }
2431 else
2432 window_matrix = w->current_matrix;
2433
2434 /* For all rows in the window matrix and corresponding rows in the
2435 frame matrix. */
2436 window_y = 0;
2437 frame_y = window_matrix->matrix_y;
2438 while (window_y < window_matrix->nrows)
2439 {
2440 struct glyph_row *frame_row = frame_matrix->rows + frame_y;
2441 struct glyph_row *window_row = window_matrix->rows + window_y;
59ea14cd 2442 bool current_row_p = window_matrix == w->current_matrix;
5f5c8ee5
GM
2443
2444 /* Fill up the frame row with spaces up to the left margin of the
2445 window row. */
2446 fill_up_frame_row_with_spaces (frame_row, window_matrix->matrix_x);
2447
2448 /* Fill up areas in the window matrix row with spaces. */
2449 fill_up_glyph_row_with_spaces (window_row);
2a8bd25f
GM
2450
2451 /* If only part of W's desired matrix has been built, and
2452 window_row wasn't displayed, use the corresponding current
2453 row instead. */
2454 if (window_matrix == w->desired_matrix
2455 && !window_row->enabled_p)
2456 {
2457 window_row = w->current_matrix->rows + window_y;
2458 current_row_p = 1;
2459 }
177c0ea7 2460
2a8bd25f 2461 if (current_row_p)
5f5c8ee5 2462 {
2a8bd25f 2463 /* Copy window row to frame row. */
72af86bd
AS
2464 memcpy (frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
2465 window_row->glyphs[0],
2466 window_matrix->matrix_w * sizeof (struct glyph));
5f5c8ee5
GM
2467 }
2468 else
2469 {
a54e2c05 2470 eassert (window_row->enabled_p);
177c0ea7 2471
2a8bd25f
GM
2472 /* Only when a desired row has been displayed, we want
2473 the corresponding frame row to be updated. */
2474 frame_row->enabled_p = 1;
177c0ea7 2475
5f5c8ee5
GM
2476 /* Maybe insert a vertical border between horizontally adjacent
2477 windows. */
3fc809e2 2478 if (GLYPH_CHAR (right_border_glyph) != 0)
5f5c8ee5
GM
2479 {
2480 struct glyph *border = window_row->glyphs[LAST_AREA] - 1;
2481 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
2482 }
2483
e509cfa6 2484#ifdef GLYPH_DEBUG
a13396c9
GM
2485 /* Window row window_y must be a slice of frame row
2486 frame_y. */
a54e2c05 2487 eassert (glyph_row_slice_p (window_row, frame_row));
177c0ea7 2488
5f5c8ee5
GM
2489 /* If rows are in sync, we don't have to copy glyphs because
2490 frame and window share glyphs. */
177c0ea7 2491
a38634ff 2492 strcpy (w->current_matrix->method, w->desired_matrix->method);
9b0e97aa 2493 add_window_display_history (w, w->current_matrix->method, 0);
a38634ff 2494#endif
5f5c8ee5
GM
2495 }
2496
2497 /* Set number of used glyphs in the frame matrix. Since we fill
2498 up with spaces, and visit leaf windows from left to right it
2499 can be done simply. */
177c0ea7 2500 frame_row->used[TEXT_AREA]
5f5c8ee5
GM
2501 = window_matrix->matrix_x + window_matrix->matrix_w;
2502
5f5c8ee5
GM
2503 /* Next row. */
2504 ++window_y;
2505 ++frame_y;
2506 }
2507}
2508
5f81871e
RS
2509/* Given a user-specified glyph, possibly including a Lisp-level face
2510 ID, return a glyph that has a realized face ID.
2511 This is used for glyphs displayed specially and not part of the text;
2512 for instance, vertical separators, truncation markers, etc. */
2513
3fc809e2 2514void
971de7fb 2515spec_glyph_lookup_face (struct window *w, GLYPH *glyph)
5f81871e 2516{
3fc809e2 2517 int lface_id = GLYPH_FACE (*glyph);
5f81871e
RS
2518 /* Convert the glyph's specified face to a realized (cache) face. */
2519 if (lface_id > 0)
2520 {
d3d50620 2521 int face_id = merge_faces (XFRAME (w->frame),
5f81871e 2522 Qt, lface_id, DEFAULT_FACE_ID);
3fc809e2 2523 SET_GLYPH_FACE (*glyph, face_id);
5f81871e 2524 }
5f81871e 2525}
5f5c8ee5
GM
2526
2527/* Add spaces to a glyph row ROW in a window matrix.
2528
2529 Each row has the form:
2530
2531 +---------+-----------------------------+------------+
2532 | left | text | right |
2533 +---------+-----------------------------+------------+
2534
2535 Left and right marginal areas are optional. This function adds
2536 spaces to areas so that there are no empty holes between areas.
2537 In other words: If the right area is not empty, the text area
2538 is filled up with spaces up to the right area. If the text area
2539 is not empty, the left area is filled up.
2540
2541 To be called for frame-based redisplay, only. */
2542
2543static void
971de7fb 2544fill_up_glyph_row_with_spaces (struct glyph_row *row)
5f5c8ee5
GM
2545{
2546 fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA);
2547 fill_up_glyph_row_area_with_spaces (row, TEXT_AREA);
2548 fill_up_glyph_row_area_with_spaces (row, RIGHT_MARGIN_AREA);
2549}
2550
2551
2552/* Fill area AREA of glyph row ROW with spaces. To be called for
2553 frame-based redisplay only. */
2554
2555static void
971de7fb 2556fill_up_glyph_row_area_with_spaces (struct glyph_row *row, int area)
5f5c8ee5
GM
2557{
2558 if (row->glyphs[area] < row->glyphs[area + 1])
2559 {
2560 struct glyph *end = row->glyphs[area + 1];
2561 struct glyph *text = row->glyphs[area] + row->used[area];
2562
2563 while (text < end)
2564 *text++ = space_glyph;
2565 row->used[area] = text - row->glyphs[area];
2566 }
2567}
2568
2569
2570/* Add spaces to the end of ROW in a frame matrix until index UPTO is
2571 reached. In frame matrices only one area, TEXT_AREA, is used. */
2572
2573static void
971de7fb 2574fill_up_frame_row_with_spaces (struct glyph_row *row, int upto)
5f5c8ee5
GM
2575{
2576 int i = row->used[TEXT_AREA];
2577 struct glyph *glyph = row->glyphs[TEXT_AREA];
177c0ea7 2578
5f5c8ee5
GM
2579 while (i < upto)
2580 glyph[i++] = space_glyph;
2581
2582 row->used[TEXT_AREA] = i;
2583}
2584
2585
2586\f
2587/**********************************************************************
2588 Mirroring operations on frame matrices in window matrices
2589 **********************************************************************/
2590
2591/* Set frame being updated via frame-based redisplay to F. This
2592 function must be called before updates to make explicit that we are
2593 working on frame matrices or not. */
2594
b0ab8123 2595static void
971de7fb 2596set_frame_matrix_frame (struct frame *f)
5f5c8ee5
GM
2597{
2598 frame_matrix_frame = f;
2599}
2600
2601
2602/* Make sure glyph row ROW in CURRENT_MATRIX is up to date.
2603 DESIRED_MATRIX is the desired matrix corresponding to
2604 CURRENT_MATRIX. The update is done by exchanging glyph pointers
2605 between rows in CURRENT_MATRIX and DESIRED_MATRIX. If
2606 frame_matrix_frame is non-null, this indicates that the exchange is
2607 done in frame matrices, and that we have to perform analogous
2608 operations in window matrices of frame_matrix_frame. */
2609
b0ab8123 2610static void
971de7fb 2611make_current (struct glyph_matrix *desired_matrix, struct glyph_matrix *current_matrix, int row)
5f5c8ee5
GM
2612{
2613 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2614 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
59ea14cd 2615 bool mouse_face_p = current_row->mouse_face_p;
5f5c8ee5
GM
2616
2617 /* Do current_row = desired_row. This exchanges glyph pointers
2618 between both rows, and does a structure assignment otherwise. */
2619 assign_row (current_row, desired_row);
2620
2621 /* Enable current_row to mark it as valid. */
2622 current_row->enabled_p = 1;
e876ff42 2623 current_row->mouse_face_p = mouse_face_p;
5f5c8ee5
GM
2624
2625 /* If we are called on frame matrices, perform analogous operations
2626 for window matrices. */
2627 if (frame_matrix_frame)
e69b0960 2628 mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row);
5f5c8ee5
GM
2629}
2630
2631
2632/* W is the root of a window tree. FRAME_ROW is the index of a row in
2633 W's frame which has been made current (by swapping pointers between
2634 current and desired matrix). Perform analogous operations in the
2635 matrices of leaf windows in the window tree rooted at W. */
2636
2637static void
971de7fb 2638mirror_make_current (struct window *w, int frame_row)
5f5c8ee5
GM
2639{
2640 while (w)
2641 {
d3d50620
DA
2642 if (!NILP (w->hchild))
2643 mirror_make_current (XWINDOW (w->hchild), frame_row);
2644 else if (!NILP (w->vchild))
2645 mirror_make_current (XWINDOW (w->vchild), frame_row);
5f5c8ee5
GM
2646 else
2647 {
2648 /* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS
2649 here because the checks performed in debug mode there
2650 will not allow the conversion. */
2651 int row = frame_row - w->desired_matrix->matrix_y;
2652
2653 /* If FRAME_ROW is within W, assign the desired row to the
2654 current row (exchanging glyph pointers). */
2655 if (row >= 0 && row < w->desired_matrix->matrix_h)
2656 {
2657 struct glyph_row *current_row
2658 = MATRIX_ROW (w->current_matrix, row);
2659 struct glyph_row *desired_row
2660 = MATRIX_ROW (w->desired_matrix, row);
a38634ff
GM
2661
2662 if (desired_row->enabled_p)
2663 assign_row (current_row, desired_row);
2664 else
2665 swap_glyph_pointers (desired_row, current_row);
5f5c8ee5 2666 current_row->enabled_p = 1;
d009ae66
EZ
2667
2668 /* Set the Y coordinate of the mode/header line's row.
2669 It is needed in draw_row_with_mouse_face to find the
2670 screen coordinates. (Window-based redisplay sets
2671 this in update_window, but no one seems to do that
2672 for frame-based redisplay.) */
2673 if (current_row->mode_line_p)
2674 current_row->y = row;
5f5c8ee5
GM
2675 }
2676 }
177c0ea7 2677
d3d50620 2678 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5f5c8ee5
GM
2679 }
2680}
2681
2682
2683/* Perform row dance after scrolling. We are working on the range of
2684 lines UNCHANGED_AT_TOP + 1 to UNCHANGED_AT_TOP + NLINES (not
2685 including) in MATRIX. COPY_FROM is a vector containing, for each
2686 row I in the range 0 <= I < NLINES, the index of the original line
2687 to move to I. This index is relative to the row range, i.e. 0 <=
2688 index < NLINES. RETAINED_P is a vector containing zero for each
2689 row 0 <= I < NLINES which is empty.
2690
2691 This function is called from do_scrolling and do_direct_scrolling. */
177c0ea7 2692
5f5c8ee5 2693void
6f704c76
DN
2694mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlines,
2695 int *copy_from, char *retained_p)
5f5c8ee5
GM
2696{
2697 /* A copy of original rows. */
2698 struct glyph_row *old_rows;
2699
2700 /* Rows to assign to. */
2701 struct glyph_row *new_rows = MATRIX_ROW (matrix, unchanged_at_top);
177c0ea7 2702
5f5c8ee5
GM
2703 int i;
2704
2705 /* Make a copy of the original rows. */
38182d90 2706 old_rows = alloca (nlines * sizeof *old_rows);
72af86bd 2707 memcpy (old_rows, new_rows, nlines * sizeof *old_rows);
5f5c8ee5
GM
2708
2709 /* Assign new rows, maybe clear lines. */
2710 for (i = 0; i < nlines; ++i)
2711 {
59ea14cd 2712 bool enabled_before_p = new_rows[i].enabled_p;
5f5c8ee5 2713
a54e2c05
DA
2714 eassert (i + unchanged_at_top < matrix->nrows);
2715 eassert (unchanged_at_top + copy_from[i] < matrix->nrows);
5f5c8ee5
GM
2716 new_rows[i] = old_rows[copy_from[i]];
2717 new_rows[i].enabled_p = enabled_before_p;
2718
2719 /* RETAINED_P is zero for empty lines. */
2720 if (!retained_p[copy_from[i]])
2721 new_rows[i].enabled_p = 0;
2722 }
2723
153a073c 2724 /* Do the same for window matrices, if MATRIX is a frame matrix. */
5f5c8ee5 2725 if (frame_matrix_frame)
e69b0960 2726 mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
5f5c8ee5
GM
2727 unchanged_at_top, nlines, copy_from, retained_p);
2728}
2729
2730
a13396c9 2731/* Synchronize glyph pointers in the current matrix of window W with
5cb88111 2732 the current frame matrix. */
a13396c9
GM
2733
2734static void
971de7fb 2735sync_window_with_frame_matrix_rows (struct window *w)
a13396c9 2736{
d3d50620 2737 struct frame *f = XFRAME (w->frame);
a13396c9 2738 struct glyph_row *window_row, *window_row_end, *frame_row;
075c507b 2739 int left, right, x, width;
a13396c9 2740
5cb88111 2741 /* Preconditions: W must be a leaf window on a tty frame. */
d3d50620 2742 eassert (NILP (w->hchild) && NILP (w->vchild));
a54e2c05 2743 eassert (!FRAME_WINDOW_P (f));
a13396c9 2744
d3d50620
DA
2745 left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
2746 right = margin_glyphs_to_reserve (w, 1, w->right_margin_cols);
5cb88111
GM
2747 x = w->current_matrix->matrix_x;
2748 width = w->current_matrix->matrix_w;
2749
a13396c9
GM
2750 window_row = w->current_matrix->rows;
2751 window_row_end = window_row + w->current_matrix->nrows;
7df02016 2752 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
177c0ea7 2753
5cb88111 2754 for (; window_row < window_row_end; ++window_row, ++frame_row)
a13396c9 2755 {
5cb88111
GM
2756 window_row->glyphs[LEFT_MARGIN_AREA]
2757 = frame_row->glyphs[0] + x;
2758 window_row->glyphs[TEXT_AREA]
2759 = window_row->glyphs[LEFT_MARGIN_AREA] + left;
2760 window_row->glyphs[LAST_AREA]
2761 = window_row->glyphs[LEFT_MARGIN_AREA] + width;
2762 window_row->glyphs[RIGHT_MARGIN_AREA]
2763 = window_row->glyphs[LAST_AREA] - right;
a13396c9
GM
2764 }
2765}
2766
2767
2768/* Return the window in the window tree rooted in W containing frame
2769 row ROW. Value is null if none is found. */
2770
09ad5a91 2771static struct window *
971de7fb 2772frame_row_to_window (struct window *w, int row)
a13396c9
GM
2773{
2774 struct window *found = NULL;
177c0ea7 2775
a13396c9
GM
2776 while (w && !found)
2777 {
d3d50620
DA
2778 if (!NILP (w->hchild))
2779 found = frame_row_to_window (XWINDOW (w->hchild), row);
2780 else if (!NILP (w->vchild))
2781 found = frame_row_to_window (XWINDOW (w->vchild), row);
7df02016
KS
2782 else if (row >= WINDOW_TOP_EDGE_LINE (w)
2783 && row < WINDOW_BOTTOM_EDGE_LINE (w))
a13396c9 2784 found = w;
177c0ea7 2785
d3d50620 2786 w = NILP (w->next) ? 0 : XWINDOW (w->next);
a13396c9
GM
2787 }
2788
2789 return found;
2790}
2791
2792
5f5c8ee5
GM
2793/* Perform a line dance in the window tree rooted at W, after
2794 scrolling a frame matrix in mirrored_line_dance.
2795
2796 We are working on the range of lines UNCHANGED_AT_TOP + 1 to
2797 UNCHANGED_AT_TOP + NLINES (not including) in W's frame matrix.
2798 COPY_FROM is a vector containing, for each row I in the range 0 <=
2799 I < NLINES, the index of the original line to move to I. This
2800 index is relative to the row range, i.e. 0 <= index < NLINES.
2801 RETAINED_P is a vector containing zero for each row 0 <= I < NLINES
2802 which is empty. */
2803
2804static void
971de7fb 2805mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy_from, char *retained_p)
5f5c8ee5
GM
2806{
2807 while (w)
2808 {
d3d50620
DA
2809 if (!NILP (w->hchild))
2810 mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top,
5f5c8ee5 2811 nlines, copy_from, retained_p);
d3d50620
DA
2812 else if (!NILP (w->vchild))
2813 mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
5f5c8ee5
GM
2814 nlines, copy_from, retained_p);
2815 else
2816 {
2817 /* W is a leaf window, and we are working on its current
2818 matrix m. */
2819 struct glyph_matrix *m = w->current_matrix;
59ea14cd
PE
2820 int i;
2821 bool sync_p = 0;
5f5c8ee5
GM
2822 struct glyph_row *old_rows;
2823
2824 /* Make a copy of the original rows of matrix m. */
38182d90 2825 old_rows = alloca (m->nrows * sizeof *old_rows);
72af86bd 2826 memcpy (old_rows, m->rows, m->nrows * sizeof *old_rows);
5f5c8ee5
GM
2827
2828 for (i = 0; i < nlines; ++i)
2829 {
2830 /* Frame relative line assigned to. */
2831 int frame_to = i + unchanged_at_top;
177c0ea7 2832
5f5c8ee5
GM
2833 /* Frame relative line assigned. */
2834 int frame_from = copy_from[i] + unchanged_at_top;
177c0ea7 2835
5f5c8ee5
GM
2836 /* Window relative line assigned to. */
2837 int window_to = frame_to - m->matrix_y;
177c0ea7 2838
5f5c8ee5
GM
2839 /* Window relative line assigned. */
2840 int window_from = frame_from - m->matrix_y;
177c0ea7 2841
5f5c8ee5 2842 /* Is assigned line inside window? */
59ea14cd 2843 bool from_inside_window_p
5f5c8ee5 2844 = window_from >= 0 && window_from < m->matrix_h;
177c0ea7 2845
a13396c9 2846 /* Is assigned to line inside window? */
59ea14cd 2847 bool to_inside_window_p
a13396c9 2848 = window_to >= 0 && window_to < m->matrix_h;
177c0ea7 2849
a13396c9 2850 if (from_inside_window_p && to_inside_window_p)
5f5c8ee5 2851 {
5f5c8ee5
GM
2852 /* Do the assignment. The enabled_p flag is saved
2853 over the assignment because the old redisplay did
2854 that. */
59ea14cd 2855 bool enabled_before_p = m->rows[window_to].enabled_p;
5f5c8ee5
GM
2856 m->rows[window_to] = old_rows[window_from];
2857 m->rows[window_to].enabled_p = enabled_before_p;
177c0ea7 2858
5f5c8ee5
GM
2859 /* If frame line is empty, window line is empty, too. */
2860 if (!retained_p[copy_from[i]])
2861 m->rows[window_to].enabled_p = 0;
2862 }
a13396c9
GM
2863 else if (to_inside_window_p)
2864 {
2865 /* A copy between windows. This is an infrequent
2866 case not worth optimizing. */
d3d50620 2867 struct frame *f = XFRAME (w->frame);
a13396c9
GM
2868 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
2869 struct window *w2;
2870 struct glyph_matrix *m2;
2871 int m2_from;
2872
fe8b8401 2873 w2 = frame_row_to_window (root, frame_from);
6183d842
RS
2874 /* ttn@surf.glug.org: when enabling menu bar using `emacs
2875 -nw', FROM_FRAME sometimes has no associated window.
2876 This check avoids a segfault if W2 is null. */
2877 if (w2)
2878 {
2879 m2 = w2->current_matrix;
2880 m2_from = frame_from - m2->matrix_y;
2881 copy_row_except_pointers (m->rows + window_to,
2882 m2->rows + m2_from);
2883
2884 /* If frame line is empty, window line is empty, too. */
2885 if (!retained_p[copy_from[i]])
2886 m->rows[window_to].enabled_p = 0;
2887 }
a13396c9
GM
2888 sync_p = 1;
2889 }
2890 else if (from_inside_window_p)
2891 sync_p = 1;
5f5c8ee5 2892 }
a13396c9
GM
2893
2894 /* If there was a copy between windows, make sure glyph
2895 pointers are in sync with the frame matrix. */
2896 if (sync_p)
2897 sync_window_with_frame_matrix_rows (w);
177c0ea7 2898
5f5c8ee5
GM
2899 /* Check that no pointers are lost. */
2900 CHECK_MATRIX (m);
2901 }
2902
2903 /* Next window on same level. */
d3d50620 2904 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5f5c8ee5
GM
2905 }
2906}
2907
2908
e509cfa6 2909#ifdef GLYPH_DEBUG
5f5c8ee5
GM
2910
2911/* Check that window and frame matrices agree about their
2912 understanding where glyphs of the rows are to find. For each
2913 window in the window tree rooted at W, check that rows in the
2914 matrices of leaf window agree with their frame matrices about
2915 glyph pointers. */
2916
85fece3e 2917static void
59fc5cf9 2918check_window_matrix_pointers (struct window *w)
5f5c8ee5
GM
2919{
2920 while (w)
2921 {
d3d50620
DA
2922 if (!NILP (w->hchild))
2923 check_window_matrix_pointers (XWINDOW (w->hchild));
2924 else if (!NILP (w->vchild))
2925 check_window_matrix_pointers (XWINDOW (w->vchild));
5f5c8ee5 2926 else
60a8948a 2927 {
d3d50620 2928 struct frame *f = XFRAME (w->frame);
5f5c8ee5
GM
2929 check_matrix_pointers (w->desired_matrix, f->desired_matrix);
2930 check_matrix_pointers (w->current_matrix, f->current_matrix);
60a8948a 2931 }
177c0ea7 2932
d3d50620 2933 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5f5c8ee5
GM
2934 }
2935}
2936
2937
2938/* Check that window rows are slices of frame rows. WINDOW_MATRIX is
2939 a window and FRAME_MATRIX is the corresponding frame matrix. For
2940 each row in WINDOW_MATRIX check that it's a slice of the
2941 corresponding frame row. If it isn't, abort. */
2942
2943static void
59fc5cf9
AS
2944check_matrix_pointers (struct glyph_matrix *window_matrix,
2945 struct glyph_matrix *frame_matrix)
5f5c8ee5
GM
2946{
2947 /* Row number in WINDOW_MATRIX. */
2948 int i = 0;
2949
2950 /* Row number corresponding to I in FRAME_MATRIX. */
2951 int j = window_matrix->matrix_y;
2952
177c0ea7 2953 /* For all rows check that the row in the window matrix is a
5f5c8ee5
GM
2954 slice of the row in the frame matrix. If it isn't we didn't
2955 mirror an operation on the frame matrix correctly. */
2956 while (i < window_matrix->nrows)
2957 {
2958 if (!glyph_row_slice_p (window_matrix->rows + i,
2959 frame_matrix->rows + j))
1088b922 2960 emacs_abort ();
5f5c8ee5
GM
2961 ++i, ++j;
2962 }
2963}
2964
e509cfa6 2965#endif /* GLYPH_DEBUG */
5f5c8ee5
GM
2966
2967
2968\f
2969/**********************************************************************
2970 VPOS and HPOS translations
2971 **********************************************************************/
2972
e509cfa6 2973#ifdef GLYPH_DEBUG
5f5c8ee5
GM
2974
2975/* Translate vertical position VPOS which is relative to window W to a
2976 vertical position relative to W's frame. */
2977
2978static int
59fc5cf9 2979window_to_frame_vpos (struct window *w, int vpos)
5f5c8ee5 2980{
d3d50620 2981 eassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
a54e2c05 2982 eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
7df02016 2983 vpos += WINDOW_TOP_EDGE_LINE (w);
d3d50620 2984 eassert (vpos >= 0 && vpos <= FRAME_LINES (XFRAME (w->frame)));
5f5c8ee5
GM
2985 return vpos;
2986}
2987
2988
2989/* Translate horizontal position HPOS which is relative to window W to
153a073c 2990 a horizontal position relative to W's frame. */
5f5c8ee5
GM
2991
2992static int
59fc5cf9 2993window_to_frame_hpos (struct window *w, int hpos)
5f5c8ee5 2994{
d3d50620 2995 eassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
7df02016 2996 hpos += WINDOW_LEFT_EDGE_COL (w);
5f5c8ee5
GM
2997 return hpos;
2998}
177c0ea7 2999
5f5c8ee5
GM
3000#endif /* GLYPH_DEBUG */
3001
3002
3003\f
3004/**********************************************************************
3005 Redrawing Frames
3006 **********************************************************************/
3007
2a14f83b 3008/* Redraw frame F. */
5f5c8ee5 3009
2a14f83b
DA
3010void
3011redraw_frame (struct frame *f)
3012{
3013 /* Error if F has no glyphs. */
3014 eassert (f->glyphs_initialized_p);
5f5c8ee5 3015 update_begin (f);
3224dac1 3016#ifdef MSDOS
f2adda5e 3017 if (FRAME_MSDOS_P (f))
79d39b69 3018 FRAME_TERMINAL (f)->set_terminal_modes_hook (FRAME_TERMINAL (f));
3224dac1 3019#endif
385ed61f 3020 clear_frame (f);
5f5c8ee5
GM
3021 clear_current_matrices (f);
3022 update_end (f);
daf01701 3023 if (FRAME_TERMCAP_P (f))
0b0d3e0b 3024 fflush (FRAME_TTY (f)->output);
5f5c8ee5
GM
3025 windows_or_buffers_changed++;
3026 /* Mark all windows as inaccurate, so that every window will have
3027 its redisplay done. */
3028 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
3029 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
3030 f->garbaged = 0;
5f5c8ee5
GM
3031}
3032
2a14f83b
DA
3033DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 0, 1, 0,
3034 doc: /* Clear frame FRAME and output again what is supposed to appear on it.
3035If FRAME is omitted or nil, the selected frame is used. */)
3036 (Lisp_Object frame)
5f5c8ee5 3037{
2a14f83b
DA
3038 redraw_frame (decode_live_frame (frame));
3039 return Qnil;
5f5c8ee5
GM
3040}
3041
5f5c8ee5 3042DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
7ee72033 3043 doc: /* Clear and redisplay all visible frames. */)
5842a27b 3044 (void)
5f5c8ee5
GM
3045{
3046 Lisp_Object tail, frame;
3047
3048 FOR_EACH_FRAME (tail, frame)
3049 if (FRAME_VISIBLE_P (XFRAME (frame)))
2a14f83b 3050 redraw_frame (XFRAME (frame));
5f5c8ee5
GM
3051
3052 return Qnil;
3053}
3054
3055
5f5c8ee5 3056\f
5f5c8ee5
GM
3057/***********************************************************************
3058 Frame Update
3059 ***********************************************************************/
4588ec20 3060
5f5c8ee5 3061/* Update frame F based on the data in desired matrices.
4588ec20 3062
59ea14cd
PE
3063 If FORCE_P, don't let redisplay be stopped by detecting pending input.
3064 If INHIBIT_HAIRY_ID_P, don't try scrolling.
177c0ea7 3065
59ea14cd 3066 Value is true if redisplay was stopped due to pending input. */
4588ec20 3067
59ea14cd
PE
3068bool
3069update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
5f5c8ee5 3070{
59ea14cd
PE
3071 /* True means display has been paused because of pending input. */
3072 bool paused_p;
e69b0960 3073 struct window *root_window = XWINDOW (f->root_window);
5f5c8ee5 3074
a2130dbb
KS
3075 if (redisplay_dont_pause)
3076 force_p = 1;
6fd326b7 3077 else if (!force_p && detect_input_pending_ignore_squeezables ())
d012c62b 3078 {
6fd326b7
DA
3079 paused_p = 1;
3080 goto do_pause;
d012c62b 3081 }
d012c62b 3082
5f5c8ee5 3083 if (FRAME_WINDOW_P (f))
4588ec20 3084 {
5f5c8ee5
GM
3085 /* We are working on window matrix basis. All windows whose
3086 flag must_be_updated_p is set have to be updated. */
3087
3088 /* Record that we are not working on frame matrices. */
3089 set_frame_matrix_frame (NULL);
3090
3091 /* Update all windows in the window tree of F, maybe stopping
3092 when pending input is detected. */
3093 update_begin (f);
3094
3095 /* Update the menu bar on X frames that don't have toolkit
3096 support. */
e69b0960
DA
3097 if (WINDOWP (f->menu_bar_window))
3098 update_window (XWINDOW (f->menu_bar_window), 1);
5f5c8ee5
GM
3099
3100 /* Update the tool-bar window, if present. */
e69b0960 3101 if (WINDOWP (f->tool_bar_window))
4588ec20 3102 {
e69b0960 3103 struct window *w = XWINDOW (f->tool_bar_window);
5f5c8ee5
GM
3104
3105 /* Update tool-bar window. */
3106 if (w->must_be_updated_p)
4588ec20 3107 {
153a073c
PJ
3108 Lisp_Object tem;
3109
5f5c8ee5
GM
3110 update_window (w, 1);
3111 w->must_be_updated_p = 0;
3112
3113 /* Swap tool-bar strings. We swap because we want to
3114 reuse strings. */
e69b0960 3115 tem = f->current_tool_bar_string;
f00af5b1
PE
3116 fset_current_tool_bar_string (f, f->desired_tool_bar_string);
3117 fset_desired_tool_bar_string (f, tem);
4588ec20
JB
3118 }
3119 }
177c0ea7 3120
5f5c8ee5
GM
3121
3122 /* Update windows. */
3123 paused_p = update_window_tree (root_window, force_p);
3124 update_end (f);
177c0ea7 3125
6b61353c 3126 /* This flush is a performance bottleneck under X,
e581a466 3127 and it doesn't seem to be necessary anyway (in general).
6b61353c 3128 It is necessary when resizing the window with the mouse, or
e581a466 3129 at least the fringes are not redrawn in a timely manner. ++kfs */
6b61353c 3130 if (f->force_flush_display_p)
e581a466
KL
3131 {
3132 FRAME_RIF (f)->flush_display (f);
3133 f->force_flush_display_p = 0;
3134 }
4588ec20 3135 }
5f5c8ee5
GM
3136 else
3137 {
3138 /* We are working on frame matrix basis. Set the frame on whose
3139 frame matrix we operate. */
3140 set_frame_matrix_frame (f);
3141
868dd24b 3142 /* Build F's desired matrix from window matrices. */
5f5c8ee5 3143 build_frame_matrix (f);
177c0ea7 3144
868dd24b
GM
3145 /* Update the display */
3146 update_begin (f);
5f5c8ee5 3147 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
868dd24b
GM
3148 update_end (f);
3149
7d2f1216 3150 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
3224dac1 3151 {
0b0d3e0b
KL
3152 if (FRAME_TTY (f)->termscript)
3153 fflush (FRAME_TTY (f)->termscript);
7d2f1216
EZ
3154 if (FRAME_TERMCAP_P (f))
3155 fflush (FRAME_TTY (f)->output);
3224dac1 3156 }
868dd24b 3157
5f5c8ee5 3158 /* Check window matrices for lost pointers. */
e509cfa6 3159#ifdef GLYPH_DEBUG
9b0e97aa
GM
3160 check_window_matrix_pointers (root_window);
3161 add_frame_display_history (f, paused_p);
3162#endif
5f5c8ee5
GM
3163 }
3164
993d4ab6 3165 do_pause:
5f5c8ee5
GM
3166 /* Reset flags indicating that a window should be updated. */
3167 set_window_update_flags (root_window, 0);
177c0ea7 3168
868dd24b 3169 display_completed = !paused_p;
5f5c8ee5 3170 return paused_p;
4588ec20 3171}
5f5c8ee5
GM
3172
3173
4588ec20 3174\f
5f5c8ee5
GM
3175/************************************************************************
3176 Window-based updates
3177 ************************************************************************/
3178
59ea14cd
PE
3179/* Perform updates in window tree rooted at W.
3180 If FORCE_P, don't stop updating if input is pending. */
5f5c8ee5 3181
59ea14cd
PE
3182static bool
3183update_window_tree (struct window *w, bool force_p)
5f5c8ee5 3184{
59ea14cd 3185 bool paused_p = 0;
177c0ea7 3186
5f5c8ee5
GM
3187 while (w && !paused_p)
3188 {
d3d50620
DA
3189 if (!NILP (w->hchild))
3190 paused_p |= update_window_tree (XWINDOW (w->hchild), force_p);
3191 else if (!NILP (w->vchild))
3192 paused_p |= update_window_tree (XWINDOW (w->vchild), force_p);
5f5c8ee5
GM
3193 else if (w->must_be_updated_p)
3194 paused_p |= update_window (w, force_p);
3195
d3d50620 3196 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5f5c8ee5
GM
3197 }
3198
3199 return paused_p;
3200}
3201
3202
59ea14cd
PE
3203/* Update window W if its flag must_be_updated_p is set.
3204 If FORCE_P, don't stop updating if input is pending. */
5f5c8ee5
GM
3205
3206void
59ea14cd 3207update_single_window (struct window *w, bool force_p)
5f5c8ee5
GM
3208{
3209 if (w->must_be_updated_p)
3210 {
3211 struct frame *f = XFRAME (WINDOW_FRAME (w));
3212
3213 /* Record that this is not a frame-based redisplay. */
3214 set_frame_matrix_frame (NULL);
3215
a2130dbb
KS
3216 if (redisplay_dont_pause)
3217 force_p = 1;
d012c62b 3218
5f5c8ee5
GM
3219 /* Update W. */
3220 update_begin (f);
3221 update_window (w, force_p);
3222 update_end (f);
4588ec20 3223
5f5c8ee5
GM
3224 /* Reset flag in W. */
3225 w->must_be_updated_p = 0;
3226 }
3227}
4588ec20 3228
93e023fc 3229#ifdef HAVE_WINDOW_SYSTEM
4588ec20 3230
408f5064
GM
3231/* Redraw lines from the current matrix of window W that are
3232 overlapped by other rows. YB is bottom-most y-position in W. */
3233
3234static void
971de7fb 3235redraw_overlapped_rows (struct window *w, int yb)
408f5064 3236{
d8ee7803 3237 int i;
fa971ac3 3238 struct frame *f = XFRAME (WINDOW_FRAME (w));
3fc809e2 3239
408f5064
GM
3240 /* If rows overlapping others have been changed, the rows being
3241 overlapped have to be redrawn. This won't draw lines that have
3242 already been drawn in update_window_line because overlapped_p in
3243 desired rows is 0, so after row assignment overlapped_p in
3244 current rows is 0. */
3245 for (i = 0; i < w->current_matrix->nrows; ++i)
3246 {
e876ff42 3247 struct glyph_row *row = w->current_matrix->rows + i;
408f5064
GM
3248
3249 if (!row->enabled_p)
3250 break;
3251 else if (row->mode_line_p)
3252 continue;
177c0ea7 3253
408f5064
GM
3254 if (row->overlapped_p)
3255 {
3256 enum glyph_row_area area;
177c0ea7 3257
408f5064
GM
3258 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
3259 {
3260 updated_row = row;
3261 updated_area = area;
fa971ac3
KL
3262 FRAME_RIF (f)->cursor_to (i, 0, row->y,
3263 area == TEXT_AREA ? row->x : 0);
408f5064 3264 if (row->used[area])
fa971ac3
KL
3265 FRAME_RIF (f)->write_glyphs (row->glyphs[area],
3266 row->used[area]);
3267 FRAME_RIF (f)->clear_end_of_line (-1);
408f5064 3268 }
177c0ea7 3269
408f5064
GM
3270 row->overlapped_p = 0;
3271 }
3272
e876ff42 3273 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
408f5064
GM
3274 break;
3275 }
3276}
3277
3278
3279/* Redraw lines from the current matrix of window W that overlap
3280 others. YB is bottom-most y-position in W. */
3281
3282static void
971de7fb 3283redraw_overlapping_rows (struct window *w, int yb)
408f5064
GM
3284{
3285 int i, bottom_y;
3286 struct glyph_row *row;
fa971ac3 3287 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3fc809e2 3288
408f5064
GM
3289 for (i = 0; i < w->current_matrix->nrows; ++i)
3290 {
3291 row = w->current_matrix->rows + i;
3292
3293 if (!row->enabled_p)
3294 break;
3295 else if (row->mode_line_p)
3296 continue;
177c0ea7 3297
408f5064
GM
3298 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3299
b4b2c2ca 3300 if (row->overlapping_p)
408f5064 3301 {
41124e06
YM
3302 int overlaps = 0;
3303
b4b2c2ca 3304 if (MATRIX_ROW_OVERLAPS_PRED_P (row) && i > 0
41124e06
YM
3305 && !MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p)
3306 overlaps |= OVERLAPS_PRED;
b4b2c2ca 3307 if (MATRIX_ROW_OVERLAPS_SUCC_P (row) && bottom_y < yb
41124e06
YM
3308 && !MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p)
3309 overlaps |= OVERLAPS_SUCC;
3310
3311 if (overlaps)
3312 {
3313 if (row->used[LEFT_MARGIN_AREA])
3314 rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA, overlaps);
3315
3316 if (row->used[TEXT_AREA])
3317 rif->fix_overlapping_area (w, row, TEXT_AREA, overlaps);
3318
3319 if (row->used[RIGHT_MARGIN_AREA])
3320 rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps);
3321
c5e87d10 3322 /* Record in neighbor rows that ROW overwrites part of
41124e06
YM
3323 their display. */
3324 if (overlaps & OVERLAPS_PRED)
3325 MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
3326 if (overlaps & OVERLAPS_SUCC)
3327 MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
3328 }
408f5064
GM
3329 }
3330
3331 if (bottom_y >= yb)
3332 break;
3333 }
3334}
3335
93e023fc
KS
3336#endif /* HAVE_WINDOW_SYSTEM */
3337
408f5064 3338
09ad5a91 3339#if defined GLYPH_DEBUG && 0
93962bfa
GM
3340
3341/* Check that no row in the current matrix of window W is enabled
3342 which is below what's displayed in the window. */
3343
09ad5a91 3344static void
971de7fb 3345check_current_matrix_flags (struct window *w)
93962bfa 3346{
59ea14cd 3347 bool last_seen_p = 0;
93962bfa
GM
3348 int i, yb = window_text_bottom_y (w);
3349
3350 for (i = 0; i < w->current_matrix->nrows - 1; ++i)
3351 {
3352 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
3353 if (!last_seen_p && MATRIX_ROW_BOTTOM_Y (row) >= yb)
3354 last_seen_p = 1;
3355 else if (last_seen_p && row->enabled_p)
1088b922 3356 emacs_abort ();
93962bfa
GM
3357 }
3358}
3359
3360#endif /* GLYPH_DEBUG */
3361
3362
59ea14cd
PE
3363/* Update display of window W.
3364 If FORCE_P, don't stop updating when input is pending. */
5f5c8ee5 3365
59ea14cd
PE
3366static bool
3367update_window (struct window *w, bool force_p)
4588ec20 3368{
5f5c8ee5 3369 struct glyph_matrix *desired_matrix = w->desired_matrix;
59ea14cd 3370 bool paused_p;
5f5c8ee5 3371 int preempt_count = baud_rate / 2400 + 1;
597cfb3f 3372 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
e509cfa6 3373#ifdef GLYPH_DEBUG
5f5c8ee5 3374 /* Check that W's frame doesn't have glyph matrices. */
a54e2c05 3375 eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
4a34b529 3376#endif
5f5c8ee5
GM
3377
3378 /* Check pending input the first time so that we can quickly return. */
a2130dbb 3379 if (!force_p)
a2d5fca0 3380 detect_input_pending_ignore_squeezables ();
4588ec20 3381
5f5c8ee5
GM
3382 /* If forced to complete the update, or if no input is pending, do
3383 the update. */
8fd9a666 3384 if (force_p || !input_pending || !NILP (do_mouse_tracking))
4588ec20 3385 {
5f5c8ee5
GM
3386 struct glyph_row *row, *end;
3387 struct glyph_row *mode_line_row;
56974e03 3388 struct glyph_row *header_line_row;
59ea14cd
PE
3389 int yb;
3390 bool changed_p = 0, mouse_face_overwritten_p = 0;
0bc32927 3391 int n_updated = 0;
5f5c8ee5
GM
3392
3393 rif->update_window_begin_hook (w);
3394 yb = window_text_bottom_y (w);
5f5c8ee5
GM
3395 row = desired_matrix->rows;
3396 end = row + desired_matrix->nrows - 1;
177c0ea7 3397
394305db
EZ
3398 /* Take note of the header line, if there is one. We will
3399 update it below, after updating all of the window's lines. */
5f5c8ee5 3400 if (row->mode_line_p)
56974e03
GM
3401 {
3402 header_line_row = row;
3403 ++row;
3404 }
3405 else
3406 header_line_row = NULL;
5f5c8ee5
GM
3407
3408 /* Update the mode line, if necessary. */
3409 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
3410 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
3411 {
3412 mode_line_row->y = yb;
3413 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
e876ff42
GM
3414 desired_matrix),
3415 &mouse_face_overwritten_p);
5f5c8ee5
GM
3416 }
3417
3418 /* Find first enabled row. Optimizations in redisplay_internal
3419 may lead to an update with only one row enabled. There may
3420 be also completely empty matrices. */
3421 while (row < end && !row->enabled_p)
3422 ++row;
177c0ea7 3423
bfdcafe1 3424 /* Try reusing part of the display by copying. */
5f5c8ee5 3425 if (row < end && !desired_matrix->no_scrolling_p)
56974e03
GM
3426 {
3427 int rc = scrolling_window (w, header_line_row != NULL);
3428 if (rc < 0)
3429 {
3430 /* All rows were found to be equal. */
3431 paused_p = 0;
3432 goto set_cursor;
3433 }
3434 else if (rc > 0)
6b61353c
KH
3435 {
3436 /* We've scrolled the display. */
3437 force_p = 1;
3438 changed_p = 1;
3439 }
5f5c8ee5
GM
3440 }
3441
3442 /* Update the rest of the lines. */
0bc32927 3443 for (; row < end && (force_p || !input_pending); ++row)
394305db
EZ
3444 /* scrolling_window resets the enabled_p flag of the rows it
3445 reuses from current_matrix. */
b7412313 3446 if (row->enabled_p)
5f5c8ee5
GM
3447 {
3448 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
3449 int i;
177c0ea7 3450
153a073c 3451 /* We'll have to play a little bit with when to
5f5c8ee5
GM
3452 detect_input_pending. If it's done too often,
3453 scrolling large windows with repeated scroll-up
3454 commands will too quickly pause redisplay. */
e87b8809 3455 if (!force_p && ++n_updated % preempt_count == 0)
a2d5fca0 3456 detect_input_pending_ignore_squeezables ();
e876ff42
GM
3457 changed_p |= update_window_line (w, vpos,
3458 &mouse_face_overwritten_p);
5f5c8ee5
GM
3459
3460 /* Mark all rows below the last visible one in the current
3461 matrix as invalid. This is necessary because of
3462 variable line heights. Consider the case of three
3463 successive redisplays, where the first displays 5
3464 lines, the second 3 lines, and the third 5 lines again.
3465 If the second redisplay wouldn't mark rows in the
3466 current matrix invalid, the third redisplay might be
3467 tempted to optimize redisplay based on lines displayed
3468 in the first redisplay. */
3469 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3470 for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
3471 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
3472 }
3473
3474 /* Was display preempted? */
3475 paused_p = row < end;
177c0ea7 3476
56974e03 3477 set_cursor:
177c0ea7 3478
6b61353c
KH
3479 /* Update the header line after scrolling because a new header
3480 line would otherwise overwrite lines at the top of the window
3481 that can be scrolled. */
3482 if (header_line_row && header_line_row->enabled_p)
3483 {
3484 header_line_row->y = 0;
3485 update_window_line (w, 0, &mouse_face_overwritten_p);
6b61353c
KH
3486 }
3487
153a073c 3488 /* Fix the appearance of overlapping/overlapped rows. */
5f5c8ee5
GM
3489 if (!paused_p && !w->pseudo_window_p)
3490 {
93e023fc 3491#ifdef HAVE_WINDOW_SYSTEM
e876ff42
GM
3492 if (changed_p && rif->fix_overlapping_area)
3493 {
3494 redraw_overlapped_rows (w, yb);
3495 redraw_overlapping_rows (w, yb);
3496 }
93e023fc 3497#endif
177c0ea7 3498
5f5c8ee5
GM
3499 /* Make cursor visible at cursor position of W. */
3500 set_window_cursor_after_update (w);
3501
e876ff42
GM
3502#if 0 /* Check that current matrix invariants are satisfied. This is
3503 for debugging only. See the comment of check_matrix_invariants. */
5f5c8ee5
GM
3504 IF_DEBUG (check_matrix_invariants (w));
3505#endif
4588ec20 3506 }
5f5c8ee5 3507
e509cfa6 3508#ifdef GLYPH_DEBUG
5f5c8ee5
GM
3509 /* Remember the redisplay method used to display the matrix. */
3510 strcpy (w->current_matrix->method, w->desired_matrix->method);
3511#endif
408f5064 3512
6b61353c
KH
3513#ifdef HAVE_WINDOW_SYSTEM
3514 update_window_fringes (w, 0);
3515#endif
3516
56974e03
GM
3517 /* End the update of window W. Don't set the cursor if we
3518 paused updating the display because in this case,
3519 set_window_cursor_after_update hasn't been called, and
3520 output_cursor doesn't contain the cursor location. */
3521 rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
4588ec20 3522 }
5f5c8ee5
GM
3523 else
3524 paused_p = 1;
3525
e509cfa6 3526#ifdef GLYPH_DEBUG
0cffd9d8 3527 /* check_current_matrix_flags (w); */
9b0e97aa
GM
3528 add_window_display_history (w, w->current_matrix->method, paused_p);
3529#endif
177c0ea7 3530
5f5c8ee5 3531 clear_glyph_matrix (desired_matrix);
408f5064 3532
5f5c8ee5 3533 return paused_p;
4588ec20
JB
3534}
3535
b64b3980 3536
5f5c8ee5
GM
3537/* Update the display of area AREA in window W, row number VPOS.
3538 AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
3539
3540static void
971de7fb 3541update_marginal_area (struct window *w, int area, int vpos)
b64b3980 3542{
5f5c8ee5 3543 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
fa971ac3 3544 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
5f5c8ee5
GM
3545
3546 /* Let functions in xterm.c know what area subsequent X positions
3547 will be relative to. */
3548 updated_area = area;
3549
3550 /* Set cursor to start of glyphs, write them, and clear to the end
3551 of the area. I don't think that something more sophisticated is
3552 necessary here, since marginal areas will not be the default. */
3553 rif->cursor_to (vpos, 0, desired_row->y, 0);
3554 if (desired_row->used[area])
3555 rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]);
3556 rif->clear_end_of_line (-1);
b64b3980 3557}
23b0200c 3558
352f1545 3559
408f5064 3560/* Update the display of the text area of row VPOS in window W.
59ea14cd 3561 Value is true if display has changed. */
5f5c8ee5 3562
59ea14cd 3563static bool
971de7fb 3564update_text_area (struct window *w, int vpos)
23b0200c 3565{
5f5c8ee5
GM
3566 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3567 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
fa971ac3 3568 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
59ea14cd 3569 bool changed_p = 0;
5f5c8ee5
GM
3570
3571 /* Let functions in xterm.c know what area subsequent X positions
3572 will be relative to. */
3573 updated_area = TEXT_AREA;
177c0ea7 3574
5f5c8ee5
GM
3575 /* If rows are at different X or Y, or rows have different height,
3576 or the current row is marked invalid, write the entire line. */
3577 if (!current_row->enabled_p
3578 || desired_row->y != current_row->y
3579 || desired_row->ascent != current_row->ascent
408f5064
GM
3580 || desired_row->phys_ascent != current_row->phys_ascent
3581 || desired_row->phys_height != current_row->phys_height
5f5c8ee5 3582 || desired_row->visible_height != current_row->visible_height
408f5064 3583 || current_row->overlapped_p
fee8b690
CY
3584 /* This next line is necessary for correctly redrawing
3585 mouse-face areas after scrolling and other operations.
3586 However, it causes excessive flickering when mouse is moved
3587 across the mode line. Luckily, turning it off for the mode
a75b65c4
KS
3588 line doesn't seem to hurt anything. -- cyd.
3589 But it is still needed for the header line. -- kfs. */
3590 || (current_row->mouse_face_p
3591 && !(current_row->mode_line_p && vpos > 0))
5f5c8ee5
GM
3592 || current_row->x != desired_row->x)
3593 {
3594 rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
177c0ea7 3595
5f5c8ee5
GM
3596 if (desired_row->used[TEXT_AREA])
3597 rif->write_glyphs (desired_row->glyphs[TEXT_AREA],
3598 desired_row->used[TEXT_AREA]);
177c0ea7 3599
5f5c8ee5
GM
3600 /* Clear to end of window. */
3601 rif->clear_end_of_line (-1);
408f5064 3602 changed_p = 1;
60f2f3f1
GM
3603
3604 /* This erases the cursor. We do this here because
3605 notice_overwritten_cursor cannot easily check this, which
3606 might indicate that the whole functionality of
3607 notice_overwritten_cursor would better be implemented here.
3608 On the other hand, we need notice_overwritten_cursor as long
3609 as mouse highlighting is done asynchronously outside of
3610 redisplay. */
3611 if (vpos == w->phys_cursor.vpos)
3612 w->phys_cursor_on_p = 0;
5f5c8ee5
GM
3613 }
3614 else
3615 {
3616 int stop, i, x;
3617 struct glyph *current_glyph = current_row->glyphs[TEXT_AREA];
3618 struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
59ea14cd 3619 bool overlapping_glyphs_p = current_row->contains_overlapping_glyphs_p;
074b781a 3620 int desired_stop_pos = desired_row->used[TEXT_AREA];
59ea14cd 3621 bool abort_skipping = 0;
5f5c8ee5 3622
78897758
YM
3623 /* If the desired row extends its face to the text area end, and
3624 unless the current row also does so at the same position,
5f5c8ee5
GM
3625 make sure we write at least one glyph, so that the face
3626 extension actually takes place. */
78897758
YM
3627 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row)
3628 && (desired_stop_pos < current_row->used[TEXT_AREA]
3629 || (desired_stop_pos == current_row->used[TEXT_AREA]
3630 && !MATRIX_ROW_EXTENDS_FACE_P (current_row))))
074b781a 3631 --desired_stop_pos;
177c0ea7 3632
5f5c8ee5
GM
3633 stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
3634 i = 0;
3635 x = desired_row->x;
8399f8a0
GM
3636
3637 /* Loop over glyphs that current and desired row may have
3638 in common. */
5f5c8ee5 3639 while (i < stop)
352f1545 3640 {
59ea14cd 3641 bool can_skip_p = !abort_skipping;
177c0ea7 3642
5f5c8ee5 3643 /* Skip over glyphs that both rows have in common. These
e47306e6
GM
3644 don't have to be written. We can't skip if the last
3645 current glyph overlaps the glyph to its right. For
3646 example, consider a current row of `if ' with the `f' in
3647 Courier bold so that it overlaps the ` ' to its right.
3648 If the desired row is ` ', we would skip over the space
3649 after the `if' and there would remain a pixel from the
3650 `f' on the screen. */
3651 if (overlapping_glyphs_p && i > 0)
352f1545 3652 {
e47306e6
GM
3653 struct glyph *glyph = &current_row->glyphs[TEXT_AREA][i - 1];
3654 int left, right;
177c0ea7 3655
d3d50620 3656 rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
e47306e6 3657 &left, &right);
91d227d9 3658 can_skip_p = (right == 0 && !abort_skipping);
352f1545 3659 }
177c0ea7 3660
6d950f4c 3661 if (can_skip_p)
352f1545 3662 {
91d227d9
CY
3663 int start_hpos = i;
3664
6d950f4c
GM
3665 while (i < stop
3666 && GLYPH_EQUAL_P (desired_glyph, current_glyph))
3667 {
3668 x += desired_glyph->pixel_width;
3669 ++desired_glyph, ++current_glyph, ++i;
3670 }
3671
3672 /* Consider the case that the current row contains "xxx
3673 ppp ggg" in italic Courier font, and the desired row
3674 is "xxx ggg". The character `p' has lbearing, `g'
3675 has not. The loop above will stop in front of the
3676 first `p' in the current row. If we would start
3677 writing glyphs there, we wouldn't erase the lbearing
3678 of the `p'. The rest of the lbearing problem is then
641bdbf3 3679 taken care of by draw_glyphs. */
6d950f4c
GM
3680 if (overlapping_glyphs_p
3681 && i > 0
3682 && i < current_row->used[TEXT_AREA]
3683 && (current_row->used[TEXT_AREA]
3684 != desired_row->used[TEXT_AREA]))
5f5c8ee5 3685 {
6d950f4c 3686 int left, right;
177c0ea7 3687
3a45383a 3688 rif->get_glyph_overhangs (current_glyph,
d3d50620 3689 XFRAME (w->frame),
6d950f4c
GM
3690 &left, &right);
3691 while (left > 0 && i > 0)
3692 {
3693 --i, --desired_glyph, --current_glyph;
3694 x -= desired_glyph->pixel_width;
3695 left -= desired_glyph->pixel_width;
3696 }
91d227d9
CY
3697
3698 /* Abort the skipping algorithm if we end up before
3699 our starting point, to avoid looping (bug#1070).
3700 This can happen when the lbearing is larger than
3701 the pixel width. */
3702 abort_skipping = (i < start_hpos);
5f5c8ee5 3703 }
352f1545 3704 }
177c0ea7 3705
5f5c8ee5
GM
3706 /* Try to avoid writing the entire rest of the desired row
3707 by looking for a resync point. This mainly prevents
3708 mode line flickering in the case the mode line is in
3709 fixed-pitch font, which it usually will be. */
3710 if (i < desired_row->used[TEXT_AREA])
3711 {
3712 int start_x = x, start_hpos = i;
3713 struct glyph *start = desired_glyph;
3714 int current_x = x;
59ea14cd 3715 bool skip_first_p = !can_skip_p;
6d950f4c 3716
5f5c8ee5
GM
3717 /* Find the next glyph that's equal again. */
3718 while (i < stop
6d950f4c
GM
3719 && (skip_first_p
3720 || !GLYPH_EQUAL_P (desired_glyph, current_glyph))
5f5c8ee5
GM
3721 && x == current_x)
3722 {
3723 x += desired_glyph->pixel_width;
3724 current_x += current_glyph->pixel_width;
3725 ++desired_glyph, ++current_glyph, ++i;
6d950f4c 3726 skip_first_p = 0;
5f5c8ee5 3727 }
23b0200c 3728
5f5c8ee5
GM
3729 if (i == start_hpos || x != current_x)
3730 {
3731 i = start_hpos;
3732 x = start_x;
3733 desired_glyph = start;
3734 break;
3735 }
e47306e6 3736
5f5c8ee5
GM
3737 rif->cursor_to (vpos, start_hpos, desired_row->y, start_x);
3738 rif->write_glyphs (start, i - start_hpos);
408f5064 3739 changed_p = 1;
5f5c8ee5
GM
3740 }
3741 }
177c0ea7 3742
5f5c8ee5
GM
3743 /* Write the rest. */
3744 if (i < desired_row->used[TEXT_AREA])
3745 {
3746 rif->cursor_to (vpos, i, desired_row->y, x);
3747 rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
408f5064 3748 changed_p = 1;
5f5c8ee5 3749 }
177c0ea7 3750
5f5c8ee5
GM
3751 /* Maybe clear to end of line. */
3752 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
3753 {
3754 /* If new row extends to the end of the text area, nothing
3755 has to be cleared, if and only if we did a write_glyphs
3756 above. This is made sure by setting desired_stop_pos
3757 appropriately above. */
a54e2c05 3758 eassert (i < desired_row->used[TEXT_AREA]
78897758
YM
3759 || ((desired_row->used[TEXT_AREA]
3760 == current_row->used[TEXT_AREA])
3761 && MATRIX_ROW_EXTENDS_FACE_P (current_row)));
5f5c8ee5
GM
3762 }
3763 else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
3764 {
3765 /* If old row extends to the end of the text area, clear. */
3766 if (i >= desired_row->used[TEXT_AREA])
3767 rif->cursor_to (vpos, i, desired_row->y,
6b61353c 3768 desired_row->pixel_width);
5f5c8ee5 3769 rif->clear_end_of_line (-1);
408f5064 3770 changed_p = 1;
5f5c8ee5
GM
3771 }
3772 else if (desired_row->pixel_width < current_row->pixel_width)
2e8907d3 3773 {
5f5c8ee5
GM
3774 /* Otherwise clear to the end of the old row. Everything
3775 after that position should be clear already. */
27786b2f 3776 int xlim;
177c0ea7 3777
5f5c8ee5
GM
3778 if (i >= desired_row->used[TEXT_AREA])
3779 rif->cursor_to (vpos, i, desired_row->y,
6b61353c 3780 desired_row->pixel_width);
5f5c8ee5
GM
3781
3782 /* If cursor is displayed at the end of the line, make sure
3783 it's cleared. Nowadays we don't have a phys_cursor_glyph
3784 with which to erase the cursor (because this method
3785 doesn't work with lbearing/rbearing), so we must do it
3786 this way. */
3787 if (vpos == w->phys_cursor.vpos
f951a506
EZ
3788 && (desired_row->reversed_p
3789 ? (w->phys_cursor.hpos < 0)
3790 : (w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])))
5f5c8ee5
GM
3791 {
3792 w->phys_cursor_on_p = 0;
27786b2f 3793 xlim = -1;
5f5c8ee5
GM
3794 }
3795 else
27786b2f
PE
3796 xlim = current_row->pixel_width;
3797 rif->clear_end_of_line (xlim);
408f5064 3798 changed_p = 1;
2e8907d3 3799 }
23b0200c 3800 }
408f5064
GM
3801
3802 return changed_p;
23b0200c 3803}
4588ec20 3804
5f5c8ee5 3805
59ea14cd 3806/* Update row VPOS in window W. Value is true if display has been changed. */
5f5c8ee5 3807
59ea14cd
PE
3808static bool
3809update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
5f5c8ee5
GM
3810{
3811 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3812 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
fa971ac3 3813 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
59ea14cd 3814 bool changed_p = 0;
5f5c8ee5 3815
5f5c8ee5
GM
3816 /* Set the row being updated. This is important to let xterm.c
3817 know what line height values are in effect. */
3818 updated_row = desired_row;
3819
177c0ea7
JB
3820 /* A row can be completely invisible in case a desired matrix was
3821 built with a vscroll and then make_cursor_line_fully_visible shifts
504805ac
GM
3822 the matrix. Make sure to make such rows current anyway, since
3823 we need the correct y-position, for example, in the current matrix. */
001f93f3
GM
3824 if (desired_row->mode_line_p
3825 || desired_row->visible_height > 0)
408f5064 3826 {
a54e2c05 3827 eassert (desired_row->enabled_p);
504805ac
GM
3828
3829 /* Update display of the left margin area, if there is one. */
3830 if (!desired_row->full_width_p
d3d50620 3831 && !NILP (w->left_margin_cols))
504805ac
GM
3832 {
3833 changed_p = 1;
3834 update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
e9957956
EZ
3835 /* Setting this flag will ensure the vertical border, if
3836 any, between this window and the one on its left will be
3837 redrawn. This is necessary because updating the left
3838 margin area can potentially draw over the border. */
3839 current_row->redraw_fringe_bitmaps_p = 1;
504805ac 3840 }
177c0ea7 3841
504805ac
GM
3842 /* Update the display of the text area. */
3843 if (update_text_area (w, vpos))
3844 {
3845 changed_p = 1;
3846 if (current_row->mouse_face_p)
3847 *mouse_face_overwritten_p = 1;
3848 }
177c0ea7 3849
504805ac
GM
3850 /* Update display of the right margin area, if there is one. */
3851 if (!desired_row->full_width_p
d3d50620 3852 && !NILP (w->right_margin_cols))
504805ac
GM
3853 {
3854 changed_p = 1;
3855 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
3856 }
177c0ea7 3857
504805ac
GM
3858 /* Draw truncation marks etc. */
3859 if (!current_row->enabled_p
3860 || desired_row->y != current_row->y
3861 || desired_row->visible_height != current_row->visible_height
6b61353c 3862 || desired_row->cursor_in_fringe_p != current_row->cursor_in_fringe_p
3d4a365f 3863 || desired_row->overlay_arrow_bitmap != current_row->overlay_arrow_bitmap
6b61353c 3864 || current_row->redraw_fringe_bitmaps_p
504805ac 3865 || desired_row->mode_line_p != current_row->mode_line_p
6b61353c 3866 || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
504805ac
GM
3867 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
3868 != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
3869 rif->after_update_window_line_hook (desired_row);
408f5064 3870 }
177c0ea7 3871
5f5c8ee5
GM
3872 /* Update current_row from desired_row. */
3873 make_current (w->desired_matrix, w->current_matrix, vpos);
3874 updated_row = NULL;
408f5064 3875 return changed_p;
5f5c8ee5
GM
3876}
3877
3878
3879/* Set the cursor after an update of window W. This function may only
3880 be called from update_window. */
3881
3882static void
971de7fb 3883set_window_cursor_after_update (struct window *w)
4588ec20 3884{
d3d50620 3885 struct frame *f = XFRAME (w->frame);
fa971ac3 3886 struct redisplay_interface *rif = FRAME_RIF (f);
5f5c8ee5
GM
3887 int cx, cy, vpos, hpos;
3888
3889 /* Not intended for frame matrix updates. */
a54e2c05 3890 eassert (FRAME_WINDOW_P (f));
177c0ea7 3891
b96fd3e8
GM
3892 if (cursor_in_echo_area
3893 && !NILP (echo_area_buffer[0])
3894 /* If we are showing a message instead of the mini-buffer,
3895 show the cursor for the message instead. */
3896 && XWINDOW (minibuf_window) == w
3897 && EQ (minibuf_window, echo_area_window)
5f5c8ee5
GM
3898 /* These cases apply only to the frame that contains
3899 the active mini-buffer window. */
3900 && FRAME_HAS_MINIBUF_P (f)
3901 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
3902 {
3903 cx = cy = vpos = hpos = 0;
3904
3905 if (cursor_in_echo_area >= 0)
3906 {
3907 /* If the mini-buffer is several lines high, find the last
3908 line that has any text on it. Note: either all lines
3909 are enabled or none. Otherwise we wouldn't be able to
3910 determine Y. */
862b4790
GM
3911 struct glyph_row *row, *last_row;
3912 struct glyph *glyph;
3913 int yb = window_text_bottom_y (w);
5f5c8ee5 3914
862b4790 3915 last_row = NULL;
6206f8ce
GM
3916 row = w->current_matrix->rows;
3917 while (row->enabled_p
3918 && (last_row == NULL
3919 || MATRIX_ROW_BOTTOM_Y (row) <= yb))
5f5c8ee5 3920 {
862b4790
GM
3921 if (row->used[TEXT_AREA]
3922 && row->glyphs[TEXT_AREA][0].charpos >= 0)
3923 last_row = row;
6206f8ce 3924 ++row;
862b4790 3925 }
177c0ea7 3926
5f5c8ee5
GM
3927 if (last_row)
3928 {
6206f8ce
GM
3929 struct glyph *start = last_row->glyphs[TEXT_AREA];
3930 struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
862b4790 3931
b96fd3e8 3932 while (last > start && last->charpos < 0)
862b4790 3933 --last;
177c0ea7 3934
862b4790
GM
3935 for (glyph = start; glyph < last; ++glyph)
3936 {
3937 cx += glyph->pixel_width;
3938 ++hpos;
3939 }
3940
5f5c8ee5 3941 cy = last_row->y;
862b4790 3942 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
5f5c8ee5
GM
3943 }
3944 }
3945 }
3946 else
3947 {
3948 cx = w->cursor.x;
3949 cy = w->cursor.y;
3950 hpos = w->cursor.hpos;
3951 vpos = w->cursor.vpos;
3952 }
4588ec20 3953
2dd61a9b 3954 /* Window cursor can be out of sync for horizontally split windows.
cccaebd2 3955 Horizontal position is -1 when cursor is on the left fringe. */
2dd61a9b
DA
3956 hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1);
3957 vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1);
5f5c8ee5 3958 rif->cursor_to (vpos, hpos, cy, cx);
4588ec20 3959}
4588ec20 3960
5f5c8ee5 3961
6df5d75f
GM
3962/* Set WINDOW->must_be_updated_p to ON_P for all windows in the window
3963 tree rooted at W. */
3964
3965void
59ea14cd 3966set_window_update_flags (struct window *w, bool on_p)
6df5d75f
GM
3967{
3968 while (w)
3969 {
d3d50620
DA
3970 if (!NILP (w->hchild))
3971 set_window_update_flags (XWINDOW (w->hchild), on_p);
3972 else if (!NILP (w->vchild))
3973 set_window_update_flags (XWINDOW (w->vchild), on_p);
6df5d75f
GM
3974 else
3975 w->must_be_updated_p = on_p;
3976
d3d50620 3977 w = NILP (w->next) ? 0 : XWINDOW (w->next);
6df5d75f 3978 }
177c0ea7 3979}
6df5d75f
GM
3980
3981
3982\f
3983/***********************************************************************
3984 Window-Based Scrolling
3985 ***********************************************************************/
3986
3987/* Structure describing rows in scrolling_window. */
3988
3989struct row_entry
3990{
3991 /* Number of occurrences of this row in desired and current matrix. */
3992 int old_uses, new_uses;
177c0ea7 3993
6df5d75f
GM
3994 /* Vpos of row in new matrix. */
3995 int new_line_number;
3996
3997 /* Bucket index of this row_entry in the hash table row_table. */
ca9ce8f2 3998 ptrdiff_t bucket;
177c0ea7 3999
6df5d75f
GM
4000 /* The row described by this entry. */
4001 struct glyph_row *row;
177c0ea7 4002
6df5d75f
GM
4003 /* Hash collision chain. */
4004 struct row_entry *next;
4005};
4006
4007/* A pool to allocate row_entry structures from, and the size of the
4008 pool. The pool is reallocated in scrolling_window when we find
4009 that we need a larger one. */
4010
4011static struct row_entry *row_entry_pool;
ca9ce8f2 4012static ptrdiff_t row_entry_pool_size;
6df5d75f
GM
4013
4014/* Index of next free entry in row_entry_pool. */
4015
ca9ce8f2 4016static ptrdiff_t row_entry_idx;
6df5d75f
GM
4017
4018/* The hash table used during scrolling, and the table's size. This
4019 table is used to quickly identify equal rows in the desired and
4020 current matrix. */
4021
4022static struct row_entry **row_table;
ca9ce8f2 4023static ptrdiff_t row_table_size;
6df5d75f
GM
4024
4025/* Vectors of pointers to row_entry structures belonging to the
4026 current and desired matrix, and the size of the vectors. */
4027
4028static struct row_entry **old_lines, **new_lines;
0065d054 4029static ptrdiff_t old_lines_size, new_lines_size;
6df5d75f
GM
4030
4031/* A pool to allocate run structures from, and its size. */
4032
4033static struct run *run_pool;
0065d054 4034static ptrdiff_t runs_size;
6df5d75f
GM
4035
4036/* A vector of runs of lines found during scrolling. */
4037
4038static struct run **runs;
4039
6b1f9ba4 4040/* Add glyph row ROW to the scrolling hash table. */
6df5d75f 4041
b0ab8123 4042static struct row_entry *
6b1f9ba4 4043add_row_entry (struct glyph_row *row)
6df5d75f
GM
4044{
4045 struct row_entry *entry;
ca9ce8f2 4046 ptrdiff_t i = row->hash % row_table_size;
177c0ea7 4047
6df5d75f 4048 entry = row_table[i];
a54e2c05 4049 eassert (entry || verify_row_hash (row));
6b1f9ba4 4050 while (entry && !row_equal_p (entry->row, row, 1))
6df5d75f 4051 entry = entry->next;
177c0ea7 4052
6df5d75f
GM
4053 if (entry == NULL)
4054 {
4055 entry = row_entry_pool + row_entry_idx++;
4056 entry->row = row;
4057 entry->old_uses = entry->new_uses = 0;
4058 entry->new_line_number = 0;
4059 entry->bucket = i;
4060 entry->next = row_table[i];
4061 row_table[i] = entry;
4062 }
4063
4064 return entry;
4065}
4066
4067
5f5c8ee5 4068/* Try to reuse part of the current display of W by scrolling lines.
59ea14cd 4069 HEADER_LINE_P means W has a header line.
5f5c8ee5
GM
4070
4071 The algorithm is taken from Communications of the ACM, Apr78 "A
4072 Technique for Isolating Differences Between Files." It should take
4073 O(N) time.
4074
4075 A short outline of the steps of the algorithm
4076
4077 1. Skip lines equal at the start and end of both matrices.
4078
4079 2. Enter rows in the current and desired matrix into a symbol
4080 table, counting how often they appear in both matrices.
4081
4082 3. Rows that appear exactly once in both matrices serve as anchors,
4083 i.e. we assume that such lines are likely to have been moved.
4084
4085 4. Starting from anchor lines, extend regions to be scrolled both
4086 forward and backward.
4087
4088 Value is
4089
4090 -1 if all rows were found to be equal.
4091 0 to indicate that we did not scroll the display, or
4092 1 if we did scroll. */
4093
4094static int
59ea14cd 4095scrolling_window (struct window *w, bool header_line_p)
4588ec20 4096{
5f5c8ee5
GM
4097 struct glyph_matrix *desired_matrix = w->desired_matrix;
4098 struct glyph_matrix *current_matrix = w->current_matrix;
4099 int yb = window_text_bottom_y (w);
ca9ce8f2
PE
4100 ptrdiff_t i;
4101 int j, first_old, first_new, last_old, last_new;
4102 int nruns, run_idx;
0065d054 4103 ptrdiff_t n;
6df5d75f 4104 struct row_entry *entry;
fa971ac3 4105 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
5f5c8ee5
GM
4106
4107 /* Skip over rows equal at the start. */
59ea14cd 4108 for (i = header_line_p; i < current_matrix->nrows - 1; ++i)
5f5c8ee5 4109 {
bfdcafe1
GM
4110 struct glyph_row *d = MATRIX_ROW (desired_matrix, i);
4111 struct glyph_row *c = MATRIX_ROW (current_matrix, i);
4112
4113 if (c->enabled_p
4114 && d->enabled_p
6b61353c 4115 && !d->redraw_fringe_bitmaps_p
bfdcafe1
GM
4116 && c->y == d->y
4117 && MATRIX_ROW_BOTTOM_Y (c) <= yb
4118 && MATRIX_ROW_BOTTOM_Y (d) <= yb
6b1f9ba4 4119 && row_equal_p (c, d, 1))
bfdcafe1
GM
4120 {
4121 assign_row (c, d);
4122 d->enabled_p = 0;
4123 }
4124 else
4125 break;
5f5c8ee5 4126 }
4588ec20 4127
5f5c8ee5
GM
4128 /* Give up if some rows in the desired matrix are not enabled. */
4129 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
4130 return -1;
177c0ea7 4131
5f5c8ee5
GM
4132 first_old = first_new = i;
4133
4d8ade89
YM
4134 /* Set last_new to the index + 1 of the row that reaches the
4135 bottom boundary in the desired matrix. Give up if we find a
4136 disabled row before we reach the bottom boundary. */
5f5c8ee5 4137 i = first_new + 1;
4d8ade89
YM
4138 while (i < desired_matrix->nrows - 1)
4139 {
4140 int bottom;
5f5c8ee5 4141
4d8ade89
YM
4142 if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
4143 return 0;
4144 bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i));
4145 if (bottom <= yb)
4146 ++i;
4147 if (bottom >= yb)
4148 break;
4149 }
5f5c8ee5
GM
4150
4151 last_new = i;
4152
4d8ade89
YM
4153 /* Set last_old to the index + 1 of the row that reaches the bottom
4154 boundary in the current matrix. We don't look at the enabled
4155 flag here because we plan to reuse part of the display even if
4156 other parts are disabled. */
5f5c8ee5 4157 i = first_old + 1;
93962bfa
GM
4158 while (i < current_matrix->nrows - 1)
4159 {
4160 int bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i));
4161 if (bottom <= yb)
4162 ++i;
4163 if (bottom >= yb)
4164 break;
4165 }
4166
5f5c8ee5
GM
4167 last_old = i;
4168
4169 /* Skip over rows equal at the bottom. */
4170 i = last_new;
4171 j = last_old;
4172 while (i - 1 > first_new
4173 && j - 1 > first_old
1e5b2111
EZ
4174 && MATRIX_ROW (current_matrix, j - 1)->enabled_p
4175 && (MATRIX_ROW (current_matrix, j - 1)->y
4176 == MATRIX_ROW (desired_matrix, i - 1)->y)
4177 && !MATRIX_ROW (desired_matrix, i - 1)->redraw_fringe_bitmaps_p
6b1f9ba4 4178 && row_equal_p (MATRIX_ROW (desired_matrix, i - 1),
e4e0bee9 4179 MATRIX_ROW (current_matrix, j - 1), 1))
5f5c8ee5
GM
4180 --i, --j;
4181 last_new = i;
4182 last_old = j;
4183
4184 /* Nothing to do if all rows are equal. */
4185 if (last_new == first_new)
4186 return 0;
4187
0065d054 4188 /* Check for integer overflow in size calculation.
ca9ce8f2
PE
4189
4190 If next_almost_prime checks (N) for divisibility by 2..10, then
4191 it can return at most N + 10, e.g., next_almost_prime (1) == 11.
4192 So, set next_almost_prime_increment_max to 10.
4193
4194 It's just a coincidence that next_almost_prime_increment_max ==
4195 NEXT_ALMOST_PRIME_LIMIT - 1. If NEXT_ALMOST_PRIME_LIMIT were
4196 13, then next_almost_prime_increment_max would be 14, e.g.,
4197 because next_almost_prime (113) would be 127. */
4198 {
4199 verify (NEXT_ALMOST_PRIME_LIMIT == 11);
4200 enum { next_almost_prime_increment_max = 10 };
ca9ce8f2 4201 ptrdiff_t row_table_max =
0065d054
PE
4202 (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table)
4203 - next_almost_prime_increment_max);
4204 ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows;
4205 if (current_nrows_max < current_matrix->nrows)
ca9ce8f2
PE
4206 memory_full (SIZE_MAX);
4207 }
4208
6df5d75f 4209 /* Reallocate vectors, tables etc. if necessary. */
177c0ea7 4210
6df5d75f 4211 if (current_matrix->nrows > old_lines_size)
0065d054
PE
4212 old_lines = xpalloc (old_lines, &old_lines_size,
4213 current_matrix->nrows - old_lines_size,
4214 INT_MAX, sizeof *old_lines);
177c0ea7 4215
6df5d75f 4216 if (desired_matrix->nrows > new_lines_size)
0065d054
PE
4217 new_lines = xpalloc (new_lines, &new_lines_size,
4218 desired_matrix->nrows - new_lines_size,
4219 INT_MAX, sizeof *new_lines);
6df5d75f 4220
ca9ce8f2
PE
4221 n = desired_matrix->nrows;
4222 n += current_matrix->nrows;
0065d054 4223 if (row_table_size < 3 * n)
6df5d75f 4224 {
ca9ce8f2 4225 ptrdiff_t size = next_almost_prime (3 * n);
0065d054 4226 row_table = xnrealloc (row_table, size, sizeof *row_table);
ca9ce8f2 4227 row_table_size = size;
0065d054 4228 memset (row_table, 0, size * sizeof *row_table);
6df5d75f
GM
4229 }
4230
4231 if (n > row_entry_pool_size)
0065d054
PE
4232 row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size,
4233 n - row_entry_pool_size,
4234 -1, sizeof *row_entry_pool);
6df5d75f
GM
4235
4236 if (desired_matrix->nrows > runs_size)
4237 {
0065d054
PE
4238 runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs);
4239 run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool);
ca9ce8f2 4240 runs_size = desired_matrix->nrows;
6df5d75f
GM
4241 }
4242
4243 nruns = run_idx = 0;
4244 row_entry_idx = 0;
4245
4246 /* Add rows from the current and desired matrix to the hash table
4247 row_hash_table to be able to find equal ones quickly. */
177c0ea7 4248
5f5c8ee5
GM
4249 for (i = first_old; i < last_old; ++i)
4250 {
4251 if (MATRIX_ROW (current_matrix, i)->enabled_p)
4252 {
6b1f9ba4 4253 entry = add_row_entry (MATRIX_ROW (current_matrix, i));
6df5d75f
GM
4254 old_lines[i] = entry;
4255 ++entry->old_uses;
5f5c8ee5
GM
4256 }
4257 else
6df5d75f 4258 old_lines[i] = NULL;
5f5c8ee5
GM
4259 }
4260
5f5c8ee5
GM
4261 for (i = first_new; i < last_new; ++i)
4262 {
a54e2c05 4263 eassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
6b1f9ba4 4264 entry = add_row_entry (MATRIX_ROW (desired_matrix, i));
6df5d75f
GM
4265 ++entry->new_uses;
4266 entry->new_line_number = i;
4267 new_lines[i] = entry;
5f5c8ee5 4268 }
4588ec20 4269
5f5c8ee5
GM
4270 /* Identify moves based on lines that are unique and equal
4271 in both matrices. */
4272 for (i = first_old; i < last_old;)
6df5d75f
GM
4273 if (old_lines[i]
4274 && old_lines[i]->old_uses == 1
4275 && old_lines[i]->new_uses == 1)
5f5c8ee5 4276 {
27786b2f 4277 int p, q;
6df5d75f
GM
4278 int new_line = old_lines[i]->new_line_number;
4279 struct run *run = run_pool + run_idx++;
5f5c8ee5
GM
4280
4281 /* Record move. */
4282 run->current_vpos = i;
4283 run->current_y = MATRIX_ROW (current_matrix, i)->y;
4284 run->desired_vpos = new_line;
4285 run->desired_y = MATRIX_ROW (desired_matrix, new_line)->y;
4286 run->nrows = 1;
4287 run->height = MATRIX_ROW (current_matrix, i)->height;
4288
4289 /* Extend backward. */
27786b2f
PE
4290 p = i - 1;
4291 q = new_line - 1;
4292 while (p > first_old
4293 && q > first_new
4294 && old_lines[p] == new_lines[q])
5f5c8ee5 4295 {
27786b2f 4296 int h = MATRIX_ROW (current_matrix, p)->height;
177c0ea7
JB
4297 --run->current_vpos;
4298 --run->desired_vpos;
5f5c8ee5
GM
4299 ++run->nrows;
4300 run->height += h;
4301 run->desired_y -= h;
4302 run->current_y -= h;
27786b2f 4303 --p, --q;
5f5c8ee5 4304 }
4588ec20 4305
5f5c8ee5 4306 /* Extend forward. */
27786b2f
PE
4307 p = i + 1;
4308 q = new_line + 1;
4309 while (p < last_old
4310 && q < last_new
4311 && old_lines[p] == new_lines[q])
5f5c8ee5 4312 {
27786b2f 4313 int h = MATRIX_ROW (current_matrix, p)->height;
177c0ea7 4314 ++run->nrows;
5f5c8ee5 4315 run->height += h;
27786b2f 4316 ++p, ++q;
5f5c8ee5 4317 }
19dff8dc 4318
5f5c8ee5
GM
4319 /* Insert run into list of all runs. Order runs by copied
4320 pixel lines. Note that we record runs that don't have to
4321 be copied because they are already in place. This is done
4322 because we can avoid calling update_window_line in this
4323 case. */
27786b2f 4324 for (p = 0; p < nruns && runs[p]->height > run->height; ++p)
5f5c8ee5 4325 ;
27786b2f
PE
4326 for (q = nruns; q > p; --q)
4327 runs[q] = runs[q - 1];
4328 runs[p] = run;
5f5c8ee5
GM
4329 ++nruns;
4330
4331 i += run->nrows;
4332 }
4333 else
4334 ++i;
4588ec20 4335
5f5c8ee5
GM
4336 /* Do the moves. Do it in a way that we don't overwrite something
4337 we want to copy later on. This is not solvable in general
4338 because there is only one display and we don't have a way to
4339 exchange areas on this display. Example:
4588ec20 4340
5f5c8ee5
GM
4341 +-----------+ +-----------+
4342 | A | | B |
4343 +-----------+ --> +-----------+
4344 | B | | A |
4345 +-----------+ +-----------+
4588ec20 4346
5f5c8ee5
GM
4347 Instead, prefer bigger moves, and invalidate moves that would
4348 copy from where we copied to. */
ea0d86af 4349
5f5c8ee5
GM
4350 for (i = 0; i < nruns; ++i)
4351 if (runs[i]->nrows > 0)
4352 {
4353 struct run *r = runs[i];
24e86043 4354
5f5c8ee5
GM
4355 /* Copy on the display. */
4356 if (r->current_y != r->desired_y)
4357 {
989b42d2 4358 rif->clear_window_mouse_face (w);
5f5c8ee5 4359 rif->scroll_run_hook (w, r);
1305621b 4360 }
5f5c8ee5 4361
1305621b
YM
4362 /* Truncate runs that copy to where we copied to, and
4363 invalidate runs that copy from where we copied to. */
4364 for (j = nruns - 1; j > i; --j)
4365 {
4366 struct run *p = runs[j];
59ea14cd 4367 bool truncated_p = 0;
5f5c8ee5 4368
1305621b
YM
4369 if (p->nrows > 0
4370 && p->desired_y < r->desired_y + r->height
4371 && p->desired_y + p->height > r->desired_y)
5f5c8ee5 4372 {
1305621b
YM
4373 if (p->desired_y < r->desired_y)
4374 {
4375 p->nrows = r->desired_vpos - p->desired_vpos;
4376 p->height = r->desired_y - p->desired_y;
4377 truncated_p = 1;
4378 }
4379 else
4380 {
4381 int nrows_copied = (r->desired_vpos + r->nrows
4382 - p->desired_vpos);
4383
4384 if (p->nrows <= nrows_copied)
4385 p->nrows = 0;
4386 else
4387 {
4388 int height_copied = (r->desired_y + r->height
4389 - p->desired_y);
4390
4391 p->current_vpos += nrows_copied;
4392 p->desired_vpos += nrows_copied;
4393 p->nrows -= nrows_copied;
4394 p->current_y += height_copied;
4395 p->desired_y += height_copied;
4396 p->height -= height_copied;
4397 truncated_p = 1;
4398 }
4399 }
4400 }
177c0ea7 4401
1305621b
YM
4402 if (r->current_y != r->desired_y
4403 /* The condition below is equivalent to
4404 ((p->current_y >= r->desired_y
5f5c8ee5 4405 && p->current_y < r->desired_y + r->height)
1305621b 4406 || (p->current_y + p->height > r->desired_y
5f5c8ee5 4407 && (p->current_y + p->height
1305621b
YM
4408 <= r->desired_y + r->height)))
4409 because we have 0 < p->height <= r->height. */
4410 && p->current_y < r->desired_y + r->height
4411 && p->current_y + p->height > r->desired_y)
4412 p->nrows = 0;
4413
4414 /* Reorder runs by copied pixel lines if truncated. */
4415 if (truncated_p && p->nrows > 0)
4416 {
4417 int k = nruns - 1;
4418
4419 while (runs[k]->nrows == 0 || runs[k]->height < p->height)
4420 k--;
4421 memmove (runs + j, runs + j + 1, (k - j) * sizeof (*runs));
4422 runs[k] = p;
5f5c8ee5
GM
4423 }
4424 }
ea0d86af 4425
5f5c8ee5
GM
4426 /* Assign matrix rows. */
4427 for (j = 0; j < r->nrows; ++j)
4428 {
4429 struct glyph_row *from, *to;
59ea14cd 4430 bool to_overlapped_p;
e876ff42 4431
5f5c8ee5
GM
4432 to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
4433 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
e876ff42 4434 to_overlapped_p = to->overlapped_p;
e61124cd 4435 from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
5f5c8ee5 4436 assign_row (to, from);
1305621b
YM
4437 /* The above `assign_row' actually does swap, so if we had
4438 an overlap in the copy destination of two runs, then
4439 the second run would assign a previously disabled bogus
4440 row. But thanks to the truncation code in the
4441 preceding for-loop, we no longer have such an overlap,
4442 and thus the assigned row should always be enabled. */
a54e2c05 4443 eassert (to->enabled_p);
1305621b 4444 from->enabled_p = 0;
408f5064 4445 to->overlapped_p = to_overlapped_p;
5f5c8ee5
GM
4446 }
4447 }
15874c59 4448
6df5d75f
GM
4449 /* Clear the hash table, for the next time. */
4450 for (i = 0; i < row_entry_idx; ++i)
4451 row_table[row_entry_pool[i].bucket] = NULL;
4452
aec1708a
PE
4453 /* Value is 1 to indicate that we scrolled the display. */
4454 return 0 < nruns;
5f5c8ee5 4455}
de83c314 4456
15874c59 4457
4588ec20 4458\f
5f5c8ee5
GM
4459/************************************************************************
4460 Frame-Based Updates
4461 ************************************************************************/
4588ec20 4462
5f5c8ee5 4463/* Update the desired frame matrix of frame F.
4588ec20 4464
59ea14cd
PE
4465 FORCE_P means that the update should not be stopped by pending input.
4466 INHIBIT_HAIRY_ID_P means that scrolling should not be tried.
5f5c8ee5 4467
59ea14cd 4468 Value is true if update was stopped due to pending input. */
5f5c8ee5 4469
59ea14cd
PE
4470static bool
4471update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p)
4588ec20 4472{
5f5c8ee5
GM
4473 /* Frame matrices to work on. */
4474 struct glyph_matrix *current_matrix = f->current_matrix;
4475 struct glyph_matrix *desired_matrix = f->desired_matrix;
4476 int i;
59ea14cd 4477 bool pause_p;
4588ec20 4478 int preempt_count = baud_rate / 2400 + 1;
5f5c8ee5 4479
a54e2c05 4480 eassert (current_matrix && desired_matrix);
4588ec20 4481
c37e4889
RS
4482 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4483 calculate_costs (f);
4484
d88c2b9e
RS
4485 if (preempt_count <= 0)
4486 preempt_count = 1;
4487
a2130dbb 4488 if (!force_p && detect_input_pending_ignore_squeezables ())
4588ec20 4489 {
27786b2f 4490 pause_p = 1;
4588ec20
JB
4491 goto do_pause;
4492 }
4493
5f5c8ee5 4494 /* If we cannot insert/delete lines, it's no use trying it. */
daf01701 4495 if (!FRAME_LINE_INS_DEL_OK (f))
5f5c8ee5 4496 inhibit_id_p = 1;
7098a0fa 4497
efb859b4 4498 /* See if any of the desired lines are enabled; don't compute for
5f5c8ee5
GM
4499 i/d line if just want cursor motion. */
4500 for (i = 0; i < desired_matrix->nrows; i++)
4501 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4588ec20
JB
4502 break;
4503
4504 /* Try doing i/d line, if not yet inhibited. */
5f5c8ee5
GM
4505 if (!inhibit_id_p && i < desired_matrix->nrows)
4506 force_p |= scrolling (f);
4588ec20
JB
4507
4508 /* Update the individual lines as needed. Do bottom line first. */
5f5c8ee5
GM
4509 if (MATRIX_ROW_ENABLED_P (desired_matrix, desired_matrix->nrows - 1))
4510 update_frame_line (f, desired_matrix->nrows - 1);
4588ec20 4511
5f5c8ee5
GM
4512 /* Now update the rest of the lines. */
4513 for (i = 0; i < desired_matrix->nrows - 1 && (force_p || !input_pending); i++)
4588ec20 4514 {
5f5c8ee5 4515 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4588ec20 4516 {
b6a65ac2 4517 if (FRAME_TERMCAP_P (f))
4588ec20
JB
4518 {
4519 /* Flush out every so many lines.
4520 Also flush out if likely to have more than 1k buffered
4521 otherwise. I'm told that some telnet connections get
4522 really screwed by more than 1k output at once. */
fced92f1
CY
4523 FILE *display_output = FRAME_TTY (f)->output;
4524 if (display_output)
4588ec20 4525 {
8148369c 4526 ptrdiff_t outq = __fpending (display_output);
fced92f1
CY
4527 if (outq > 900
4528 || (outq > 20 && ((i - 1) % preempt_count == 0)))
06b63c9b 4529 fflush (display_output);
4588ec20 4530 }
4588ec20
JB
4531 }
4532
d012c62b 4533 if (!force_p && (i - 1) % preempt_count == 0)
a2d5fca0 4534 detect_input_pending_ignore_squeezables ();
a2960116 4535
5f5c8ee5 4536 update_frame_line (f, i);
4588ec20 4537 }
4588ec20 4538 }
177c0ea7 4539
b98521db 4540 lint_assume (0 <= FRAME_LINES (f));
59ea14cd 4541 pause_p = 0 < i && i < FRAME_LINES (f) - 1;
4588ec20
JB
4542
4543 /* Now just clean up termcap drivers and set cursor, etc. */
27786b2f 4544 if (!pause_p)
4588ec20 4545 {
48cf7030 4546 if ((cursor_in_echo_area
5f5c8ee5 4547 /* If we are showing a message instead of the mini-buffer,
2577053b 4548 show the cursor for the message instead of for the
5f5c8ee5 4549 (now hidden) mini-buffer contents. */
2577053b
RS
4550 || (EQ (minibuf_window, selected_window)
4551 && EQ (minibuf_window, echo_area_window)
b96fd3e8 4552 && !NILP (echo_area_buffer[0])))
2577053b 4553 /* These cases apply only to the frame that contains
5f5c8ee5 4554 the active mini-buffer window. */
2577053b 4555 && FRAME_HAS_MINIBUF_P (f)
140f8645 4556 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
1113d9db 4557 {
7df02016 4558 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
648fa17d
JB
4559 int row, col;
4560
4561 if (cursor_in_echo_area < 0)
4562 {
5f5c8ee5
GM
4563 /* Negative value of cursor_in_echo_area means put
4564 cursor at beginning of line. */
648fa17d
JB
4565 row = top;
4566 col = 0;
4567 }
1113d9db 4568 else
648fa17d 4569 {
5f5c8ee5
GM
4570 /* Positive value of cursor_in_echo_area means put
4571 cursor at the end of the prompt. If the mini-buffer
4572 is several lines high, find the last line that has
4573 any text on it. */
7df02016 4574 row = FRAME_LINES (f);
177c0ea7 4575 do
648fa17d 4576 {
5f5c8ee5
GM
4577 --row;
4578 col = 0;
177c0ea7 4579
5f5c8ee5
GM
4580 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
4581 {
4582 /* Frame rows are filled up with spaces that
4583 must be ignored here. */
5f5c8ee5
GM
4584 struct glyph_row *r = MATRIX_ROW (current_matrix,
4585 row);
4586 struct glyph *start = r->glyphs[TEXT_AREA];
4587 struct glyph *last = start + r->used[TEXT_AREA];
4588
4589 while (last > start
4590 && (last - 1)->charpos < 0)
4591 --last;
177c0ea7 4592
5f5c8ee5
GM
4593 col = last - start;
4594 }
648fa17d
JB
4595 }
4596 while (row > top && col == 0);
4597
6395da5c 4598 /* Make sure COL is not out of range. */
868e640e 4599 if (col >= FRAME_CURSOR_X_LIMIT (f))
648fa17d 4600 {
6395da5c 4601 /* If we have another row, advance cursor into it. */
7df02016 4602 if (row < FRAME_LINES (f) - 1)
6395da5c 4603 {
7df02016 4604 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
6395da5c
RS
4605 row++;
4606 }
4607 /* Otherwise move it back in range. */
4608 else
868e640e 4609 col = FRAME_CURSOR_X_LIMIT (f) - 1;
648fa17d
JB
4610 }
4611 }
4612
385ed61f 4613 cursor_to (f, row, col);
1113d9db 4614 }
4588ec20 4615 else
5f5c8ee5
GM
4616 {
4617 /* We have only one cursor on terminal frames. Use it to
4618 display the cursor of the selected window. */
4619 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
a871441d
GM
4620 if (w->cursor.vpos >= 0
4621 /* The cursor vpos may be temporarily out of bounds
4622 in the following situation: There is one window,
4623 with the cursor in the lower half of it. The window
4624 is split, and a message causes a redisplay before
4625 a new cursor position has been computed. */
7df02016 4626 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
5f5c8ee5
GM
4627 {
4628 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
4629 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
4630
d3d50620
DA
4631 if (INTEGERP (w->left_margin_cols))
4632 x += XFASTINT (w->left_margin_cols);
177c0ea7 4633
7df02016 4634 /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
385ed61f 4635 cursor_to (f, y, x);
5f5c8ee5
GM
4636 }
4637 }
4588ec20
JB
4638 }
4639
4588ec20
JB
4640 do_pause:
4641
5f5c8ee5 4642 clear_desired_matrices (f);
27786b2f 4643 return pause_p;
4588ec20
JB
4644}
4645
4588ec20 4646
5f5c8ee5 4647/* Do line insertions/deletions on frame F for frame-based redisplay. */
4588ec20 4648
59ea14cd 4649static bool
971de7fb 4650scrolling (struct frame *frame)
4588ec20
JB
4651{
4652 int unchanged_at_top, unchanged_at_bottom;
4653 int window_size;
4654 int changed_lines;
38182d90
PE
4655 int *old_hash = alloca (FRAME_LINES (frame) * sizeof (int));
4656 int *new_hash = alloca (FRAME_LINES (frame) * sizeof (int));
4657 int *draw_cost = alloca (FRAME_LINES (frame) * sizeof (int));
4658 int *old_draw_cost = alloca (FRAME_LINES (frame) * sizeof (int));
4588ec20 4659 register int i;
7df02016 4660 int free_at_end_vpos = FRAME_LINES (frame);
5f5c8ee5
GM
4661 struct glyph_matrix *current_matrix = frame->current_matrix;
4662 struct glyph_matrix *desired_matrix = frame->desired_matrix;
4588ec20 4663
5f5c8ee5 4664 if (!current_matrix)
1088b922 4665 emacs_abort ();
4588ec20 4666
5f5c8ee5
GM
4667 /* Compute hash codes of all the lines. Also calculate number of
4668 changed lines, number of unchanged lines at the beginning, and
4669 number of unchanged lines at the end. */
4588ec20
JB
4670 changed_lines = 0;
4671 unchanged_at_top = 0;
7df02016
KS
4672 unchanged_at_bottom = FRAME_LINES (frame);
4673 for (i = 0; i < FRAME_LINES (frame); i++)
4588ec20
JB
4674 {
4675 /* Give up on this scrolling if some old lines are not enabled. */
5f5c8ee5 4676 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
4588ec20 4677 return 0;
5f5c8ee5
GM
4678 old_hash[i] = line_hash_code (MATRIX_ROW (current_matrix, i));
4679 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
f188b3c4
RS
4680 {
4681 /* This line cannot be redrawn, so don't let scrolling mess it. */
4682 new_hash[i] = old_hash[i];
4683#define INFINITY 1000000 /* Taken from scroll.c */
4684 draw_cost[i] = INFINITY;
4685 }
4588ec20 4686 else
f188b3c4 4687 {
5f5c8ee5
GM
4688 new_hash[i] = line_hash_code (MATRIX_ROW (desired_matrix, i));
4689 draw_cost[i] = line_draw_cost (desired_matrix, i);
f188b3c4 4690 }
4588ec20
JB
4691
4692 if (old_hash[i] != new_hash[i])
4693 {
4694 changed_lines++;
7df02016 4695 unchanged_at_bottom = FRAME_LINES (frame) - i - 1;
4588ec20
JB
4696 }
4697 else if (i == unchanged_at_top)
4698 unchanged_at_top++;
5f5c8ee5 4699 old_draw_cost[i] = line_draw_cost (current_matrix, i);
4588ec20
JB
4700 }
4701
4702 /* If changed lines are few, don't allow preemption, don't scroll. */
daf01701 4703 if ((!FRAME_SCROLL_REGION_OK (frame)
8a56675d 4704 && changed_lines < baud_rate / 2400)
7df02016 4705 || unchanged_at_bottom == FRAME_LINES (frame))
4588ec20
JB
4706 return 1;
4707
7df02016 4708 window_size = (FRAME_LINES (frame) - unchanged_at_top
4588ec20
JB
4709 - unchanged_at_bottom);
4710
daf01701 4711 if (FRAME_SCROLL_REGION_OK (frame))
4588ec20 4712 free_at_end_vpos -= unchanged_at_bottom;
daf01701 4713 else if (FRAME_MEMORY_BELOW_FRAME (frame))
4588ec20
JB
4714 free_at_end_vpos = -1;
4715
4716 /* If large window, fast terminal and few lines in common between
5f5c8ee5 4717 current frame and desired frame, don't bother with i/d calc. */
daf01701 4718 if (!FRAME_SCROLL_REGION_OK (frame)
8a56675d 4719 && window_size >= 18 && baud_rate > 2400
4588ec20
JB
4720 && (window_size >=
4721 10 * scrolling_max_lines_saved (unchanged_at_top,
7df02016 4722 FRAME_LINES (frame) - unchanged_at_bottom,
4588ec20
JB
4723 old_hash, new_hash, draw_cost)))
4724 return 0;
4725
5f5c8ee5
GM
4726 if (window_size < 2)
4727 return 0;
4728
502b9b64 4729 scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
4588ec20 4730 draw_cost + unchanged_at_top - 1,
190bb91a 4731 old_draw_cost + unchanged_at_top - 1,
4588ec20
JB
4732 old_hash + unchanged_at_top - 1,
4733 new_hash + unchanged_at_top - 1,
4734 free_at_end_vpos - unchanged_at_top);
4735
4736 return 0;
4737}
4588ec20 4738
4588ec20 4739
5f5c8ee5
GM
4740/* Count the number of blanks at the start of the vector of glyphs R
4741 which is LEN glyphs long. */
4588ec20 4742
4588ec20 4743static int
971de7fb 4744count_blanks (struct glyph *r, int len)
4588ec20 4745{
5f5c8ee5 4746 int i;
177c0ea7 4747
5f5c8ee5
GM
4748 for (i = 0; i < len; ++i)
4749 if (!CHAR_GLYPH_SPACE_P (r[i]))
4750 break;
4751
4752 return i;
4588ec20
JB
4753}
4754
5f5c8ee5
GM
4755
4756/* Count the number of glyphs in common at the start of the glyph
4757 vectors STR1 and STR2. END1 is the end of STR1 and END2 is the end
4758 of STR2. Value is the number of equal glyphs equal at the start. */
4759
4588ec20 4760static int
971de7fb 4761count_match (struct glyph *str1, struct glyph *end1, struct glyph *str2, struct glyph *end2)
4588ec20 4762{
5f5c8ee5
GM
4763 struct glyph *p1 = str1;
4764 struct glyph *p2 = str2;
177c0ea7 4765
5f5c8ee5
GM
4766 while (p1 < end1
4767 && p2 < end2
42186983 4768 && GLYPH_CHAR_AND_FACE_EQUAL_P (p1, p2))
5f5c8ee5 4769 ++p1, ++p2;
177c0ea7 4770
5f5c8ee5 4771 return p1 - str1;
4588ec20
JB
4772}
4773
5f5c8ee5 4774
4588ec20 4775/* Char insertion/deletion cost vector, from term.c */
4588ec20 4776
5e617bc2 4777#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS ((f))])
4588ec20 4778
5f5c8ee5
GM
4779
4780/* Perform a frame-based update on line VPOS in frame FRAME. */
4781
4588ec20 4782static void
971de7fb 4783update_frame_line (struct frame *f, int vpos)
4588ec20 4784{
5f5c8ee5 4785 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
4588ec20
JB
4786 int tem;
4787 int osp, nsp, begmatch, endmatch, olen, nlen;
c363a1d6
GM
4788 struct glyph_matrix *current_matrix = f->current_matrix;
4789 struct glyph_matrix *desired_matrix = f->desired_matrix;
5f5c8ee5
GM
4790 struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
4791 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
59ea14cd
PE
4792 bool must_write_whole_line_p;
4793 bool write_spaces_p = FRAME_MUST_WRITE_SPACES (f);
4794 bool colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
4795 != FACE_TTY_DEFAULT_BG_COLOR);
0a894bad
GM
4796
4797 if (colored_spaces_p)
4798 write_spaces_p = 1;
5f5c8ee5 4799
26c63686
GM
4800 /* Current row not enabled means it has unknown contents. We must
4801 write the whole desired line in that case. */
5f5c8ee5
GM
4802 must_write_whole_line_p = !current_row->enabled_p;
4803 if (must_write_whole_line_p)
4588ec20 4804 {
5f5c8ee5 4805 obody = 0;
4588ec20
JB
4806 olen = 0;
4807 }
4808 else
4809 {
5f5c8ee5
GM
4810 obody = MATRIX_ROW_GLYPH_START (current_matrix, vpos);
4811 olen = current_row->used[TEXT_AREA];
177c0ea7 4812
4cecaab8
MB
4813 /* Ignore trailing spaces, if we can. */
4814 if (!write_spaces_p)
4815 while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
4816 olen--;
4588ec20
JB
4817 }
4818
5f5c8ee5
GM
4819 current_row->enabled_p = 1;
4820 current_row->used[TEXT_AREA] = desired_row->used[TEXT_AREA];
4588ec20 4821
5f5c8ee5
GM
4822 /* If desired line is empty, just clear the line. */
4823 if (!desired_row->enabled_p)
4588ec20
JB
4824 {
4825 nlen = 0;
4826 goto just_erase;
4827 }
4828
5f5c8ee5
GM
4829 nbody = desired_row->glyphs[TEXT_AREA];
4830 nlen = desired_row->used[TEXT_AREA];
4831 nend = nbody + nlen;
4832
4833 /* If display line has unknown contents, write the whole line. */
4834 if (must_write_whole_line_p)
4835 {
26c63686 4836 /* Ignore spaces at the end, if we can. */
0a894bad 4837 if (!write_spaces_p)
74ca462f
GM
4838 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
4839 --nlen;
4840
26c63686 4841 /* Write the contents of the desired line. */
74ca462f 4842 if (nlen)
26c63686 4843 {
385ed61f
KL
4844 cursor_to (f, vpos, 0);
4845 write_glyphs (f, nbody, nlen);
26c63686 4846 }
177c0ea7 4847
26c63686
GM
4848 /* Don't call clear_end_of_line if we already wrote the whole
4849 line. The cursor will not be at the right margin in that
4850 case but in the line below. */
7df02016 4851 if (nlen < FRAME_TOTAL_COLS (f))
26c63686 4852 {
385ed61f
KL
4853 cursor_to (f, vpos, nlen);
4854 clear_end_of_line (f, FRAME_TOTAL_COLS (f));
26c63686 4855 }
58827478
GM
4856 else
4857 /* Make sure we are in the right row, otherwise cursor movement
4858 with cmgoto might use `ch' in the wrong row. */
385ed61f 4859 cursor_to (f, vpos, 0);
177c0ea7 4860
5f5c8ee5
GM
4861 make_current (desired_matrix, current_matrix, vpos);
4862 return;
4863 }
4588ec20
JB
4864
4865 /* Pretend trailing spaces are not there at all,
4866 unless for one reason or another we must write all spaces. */
4cecaab8
MB
4867 if (!write_spaces_p)
4868 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
4869 nlen--;
4588ec20
JB
4870
4871 /* If there's no i/d char, quickly do the best we can without it. */
daf01701 4872 if (!FRAME_CHAR_INS_DEL_OK (f))
4588ec20 4873 {
5f5c8ee5 4874 int i, j;
4588ec20 4875
5f5c8ee5
GM
4876 /* Find the first glyph in desired row that doesn't agree with
4877 a glyph in the current row, and write the rest from there on. */
4588ec20
JB
4878 for (i = 0; i < nlen; i++)
4879 {
5f5c8ee5 4880 if (i >= olen || !GLYPH_EQUAL_P (nbody + i, obody + i))
4588ec20 4881 {
5f5c8ee5
GM
4882 /* Find the end of the run of different glyphs. */
4883 j = i + 1;
4884 while (j < nlen
4885 && (j >= olen
4886 || !GLYPH_EQUAL_P (nbody + j, obody + j)
4887 || CHAR_GLYPH_PADDING_P (nbody[j])))
4888 ++j;
177c0ea7
JB
4889
4890 /* Output this run of non-matching chars. */
385ed61f
KL
4891 cursor_to (f, vpos, i);
4892 write_glyphs (f, nbody + i, j - i);
5f5c8ee5 4893 i = j - 1;
4588ec20
JB
4894
4895 /* Now find the next non-match. */
4896 }
4897 }
4898
4899 /* Clear the rest of the line, or the non-clear part of it. */
4900 if (olen > nlen)
4901 {
385ed61f
KL
4902 cursor_to (f, vpos, nlen);
4903 clear_end_of_line (f, olen);
4588ec20
JB
4904 }
4905
5f5c8ee5
GM
4906 /* Make current row = desired row. */
4907 make_current (desired_matrix, current_matrix, vpos);
4588ec20
JB
4908 return;
4909 }
4910
5f5c8ee5
GM
4911 /* Here when CHAR_INS_DEL_OK != 0, i.e. we can insert or delete
4912 characters in a row. */
4913
4588ec20
JB
4914 if (!olen)
4915 {
5f5c8ee5
GM
4916 /* If current line is blank, skip over initial spaces, if
4917 possible, and write the rest. */
4cecaab8 4918 if (write_spaces_p)
5f5c8ee5
GM
4919 nsp = 0;
4920 else
4921 nsp = count_blanks (nbody, nlen);
4922
4588ec20
JB
4923 if (nlen > nsp)
4924 {
385ed61f
KL
4925 cursor_to (f, vpos, nsp);
4926 write_glyphs (f, nbody + nsp, nlen - nsp);
4588ec20
JB
4927 }
4928
502b9b64 4929 /* Exchange contents between current_frame and new_frame. */
5f5c8ee5 4930 make_current (desired_matrix, current_matrix, vpos);
4588ec20
JB
4931 return;
4932 }
4933
4588ec20 4934 /* Compute number of leading blanks in old and new contents. */
5f5c8ee5 4935 osp = count_blanks (obody, olen);
4cecaab8 4936 nsp = (colored_spaces_p ? 0 : count_blanks (nbody, nlen));
4588ec20 4937
5f5c8ee5
GM
4938 /* Compute number of matching chars starting with first non-blank. */
4939 begmatch = count_match (obody + osp, obody + olen,
4940 nbody + nsp, nbody + nlen);
4588ec20
JB
4941
4942 /* Spaces in new match implicit space past the end of old. */
4943 /* A bug causing this to be a no-op was fixed in 18.29. */
0a894bad 4944 if (!write_spaces_p && osp + begmatch == olen)
4588ec20
JB
4945 {
4946 np1 = nbody + nsp;
5f5c8ee5
GM
4947 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (np1[begmatch]))
4948 ++begmatch;
4588ec20
JB
4949 }
4950
4951 /* Avoid doing insert/delete char
4952 just cause number of leading spaces differs
5f5c8ee5 4953 when the following text does not match. */
4588ec20
JB
4954 if (begmatch == 0 && osp != nsp)
4955 osp = nsp = min (osp, nsp);
4956
4957 /* Find matching characters at end of line */
4958 op1 = obody + olen;
4959 np1 = nbody + nlen;
4960 op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
5f5c8ee5
GM
4961 while (op1 > op2
4962 && GLYPH_EQUAL_P (op1 - 1, np1 - 1))
4588ec20
JB
4963 {
4964 op1--;
4965 np1--;
4966 }
4967 endmatch = obody + olen - op1;
4968
4588ec20
JB
4969 /* tem gets the distance to insert or delete.
4970 endmatch is how many characters we save by doing so.
4971 Is it worth it? */
4972
4973 tem = (nlen - nsp) - (olen - osp);
4974 if (endmatch && tem
daf01701 4975 && (!FRAME_CHAR_INS_DEL_OK (f)
8a56675d 4976 || endmatch <= char_ins_del_cost (f)[tem]))
4588ec20
JB
4977 endmatch = 0;
4978
4979 /* nsp - osp is the distance to insert or delete.
4980 If that is nonzero, begmatch is known to be nonzero also.
4981 begmatch + endmatch is how much we save by doing the ins/del.
4982 Is it worth it? */
4983
4984 if (nsp != osp
daf01701 4985 && (!FRAME_CHAR_INS_DEL_OK (f)
c363a1d6 4986 || begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]))
4588ec20
JB
4987 {
4988 begmatch = 0;
4989 endmatch = 0;
4990 osp = nsp = min (osp, nsp);
4991 }
4992
4993 /* Now go through the line, inserting, writing and
4994 deleting as appropriate. */
4995
4996 if (osp > nsp)
4997 {
385ed61f
KL
4998 cursor_to (f, vpos, nsp);
4999 delete_glyphs (f, osp - nsp);
4588ec20
JB
5000 }
5001 else if (nsp > osp)
5002 {
5003 /* If going to delete chars later in line
5004 and insert earlier in the line,
5005 must delete first to avoid losing data in the insert */
5006 if (endmatch && nlen < olen + nsp - osp)
5007 {
385ed61f
KL
5008 cursor_to (f, vpos, nlen - endmatch + osp - nsp);
5009 delete_glyphs (f, olen + nsp - osp - nlen);
4588ec20
JB
5010 olen = nlen - (nsp - osp);
5011 }
385ed61f
KL
5012 cursor_to (f, vpos, osp);
5013 insert_glyphs (f, 0, nsp - osp);
4588ec20
JB
5014 }
5015 olen += nsp - osp;
5016
5017 tem = nsp + begmatch + endmatch;
5018 if (nlen != tem || olen != tem)
5019 {
4588ec20
JB
5020 if (!endmatch || nlen == olen)
5021 {
c363a1d6
GM
5022 /* If new text being written reaches right margin, there is
5023 no need to do clear-to-eol at the end of this function
5024 (and it would not be safe, since cursor is not going to
5025 be "at the margin" after the text is done). */
7df02016 5026 if (nlen == FRAME_TOTAL_COLS (f))
4588ec20 5027 olen = 0;
c363a1d6
GM
5028
5029 /* Function write_glyphs is prepared to do nothing
5030 if passed a length <= 0. Check it here to avoid
5031 unnecessary cursor movement. */
5032 if (nlen - tem > 0)
5033 {
385ed61f
KL
5034 cursor_to (f, vpos, nsp + begmatch);
5035 write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
c363a1d6 5036 }
4588ec20
JB
5037 }
5038 else if (nlen > olen)
5039 {
24e86043
KH
5040 /* Here, we used to have the following simple code:
5041 ----------------------------------------
5042 write_glyphs (nbody + nsp + begmatch, olen - tem);
5043 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
5044 ----------------------------------------
5045 but it doesn't work if nbody[nsp + begmatch + olen - tem]
5046 is a padding glyph. */
5047 int out = olen - tem; /* Columns to be overwritten originally. */
5048 int del;
5f5c8ee5 5049
385ed61f 5050 cursor_to (f, vpos, nsp + begmatch);
177c0ea7 5051
5f5c8ee5 5052 /* Calculate columns we can actually overwrite. */
c363a1d6
GM
5053 while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out]))
5054 out--;
385ed61f 5055 write_glyphs (f, nbody + nsp + begmatch, out);
177c0ea7 5056
5f5c8ee5
GM
5057 /* If we left columns to be overwritten, we must delete them. */
5058 del = olen - tem - out;
c363a1d6 5059 if (del > 0)
385ed61f 5060 delete_glyphs (f, del);
177c0ea7 5061
5f5c8ee5 5062 /* At last, we insert columns not yet written out. */
385ed61f 5063 insert_glyphs (f, nbody + nsp + begmatch + out, nlen - olen + del);
5f5c8ee5
GM
5064 olen = nlen;
5065 }
5066 else if (olen > nlen)
5067 {
385ed61f
KL
5068 cursor_to (f, vpos, nsp + begmatch);
5069 write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
5070 delete_glyphs (f, olen - nlen);
5f5c8ee5
GM
5071 olen = nlen;
5072 }
bd9e3e75 5073 }
5f5c8ee5
GM
5074
5075 just_erase:
5076 /* If any unerased characters remain after the new line, erase them. */
5077 if (olen > nlen)
078b3696 5078 {
385ed61f
KL
5079 cursor_to (f, vpos, nlen);
5080 clear_end_of_line (f, olen);
078b3696 5081 }
5f5c8ee5
GM
5082
5083 /* Exchange contents between current_frame and new_frame. */
5084 make_current (desired_matrix, current_matrix, vpos);
078b3696 5085}
5f5c8ee5
GM
5086
5087
078b3696 5088\f
5f5c8ee5
GM
5089/***********************************************************************
5090 X/Y Position -> Buffer Position
5091 ***********************************************************************/
5092
a1b0a6db 5093/* Determine what's under window-relative pixel position (*X, *Y).
2396cbba 5094 Return the OBJECT (string or buffer) that's there.
6b61353c 5095 Return in *POS the position in that object.
2396cbba
EZ
5096 Adjust *X and *Y to character positions.
5097 Return in *DX and *DY the pixel coordinates of the click,
5098 relative to the top left corner of OBJECT, or relative to
5099 the top left corner of the character glyph at (*X, *Y)
5100 if OBJECT is nil.
5101 Return WIDTH and HEIGHT of the object at (*X, *Y), or zero
5102 if the coordinates point to an empty area of the display. */
5f5c8ee5 5103
6b61353c 5104Lisp_Object
971de7fb 5105buffer_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)
4588ec20 5106{
5f5c8ee5 5107 struct it it;
707ea971 5108 Lisp_Object old_current_buffer = Fcurrent_buffer ();
5f5c8ee5 5109 struct text_pos startp;
6b61353c
KH
5110 Lisp_Object string;
5111 struct glyph_row *row;
cedd7cd9
KS
5112#ifdef HAVE_WINDOW_SYSTEM
5113 struct image *img = 0;
5114#endif
2396cbba 5115 int x0, x1, to_x;
57b3e30b 5116 void *itdata = NULL;
5f5c8ee5 5117
707ea971
CY
5118 /* We used to set current_buffer directly here, but that does the
5119 wrong thing with `face-remapping-alist' (bug#2044). */
d3d50620 5120 Fset_buffer (w->buffer);
57b3e30b 5121 itdata = bidi_shelve_cache ();
d3d50620 5122 SET_TEXT_POS_FROM_MARKER (startp, w->start);
5f5c8ee5
GM
5123 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
5124 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
5125 start_display (&it, w, startp);
352ec8ff
EZ
5126 /* start_display takes into account the header-line row, but IT's
5127 vpos still counts from the glyph row that includes the window's
5128 start position. Adjust for a possible header-line row. */
59ea14cd 5129 it.vpos += WINDOW_WANTS_HEADER_LINE_P (w);
177c0ea7 5130
9173a8fb 5131 x0 = *x;
2396cbba
EZ
5132
5133 /* First, move to the beginning of the row corresponding to *Y. We
5134 need to be in that row to get the correct value of base paragraph
40629f17 5135 direction for the text at (*X, *Y). */
2396cbba
EZ
5136 move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y);
5137
5138 /* TO_X is the pixel position that the iterator will compute for the
40629f17
EZ
5139 glyph at *X. We add it.first_visible_x because iterator
5140 positions include the hscroll. */
2396cbba
EZ
5141 to_x = x0 + it.first_visible_x;
5142 if (it.bidi_it.paragraph_dir == R2L)
5143 /* For lines in an R2L paragraph, we need to mirror TO_X wrt the
5144 text area. This is because the iterator, even in R2L
5145 paragraphs, delivers glyphs as if they started at the left
5146 margin of the window. (When we actually produce glyphs for
5147 display, we reverse their order in PRODUCE_GLYPHS, but the
5148 iterator doesn't know about that.) The following line adjusts
5149 the pixel position to the iterator geometry, which is what
40629f17
EZ
5150 move_it_* routines use. (The -1 is because in a window whose
5151 text-area width is W, the rightmost pixel position is W-1, and
5152 it should be mirrored into zero pixel position.) */
5153 to_x = window_box_width (w, TEXT_AREA) - to_x - 1;
5154
5155 /* Now move horizontally in the row to the glyph under *X. Second
5156 argument is ZV to prevent move_it_in_display_line from matching
5157 based on buffer positions. */
2396cbba 5158 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
35928349 5159 bidi_unshelve_cache (itdata, 0);
177c0ea7 5160
707ea971 5161 Fset_buffer (old_current_buffer);
a1b0a6db 5162
6b61353c
KH
5163 *dx = x0 + it.first_visible_x - it.current_x;
5164 *dy = *y - it.current_y;
5165
d3d50620 5166 string = w->buffer;
6b61353c
KH
5167 if (STRINGP (it.string))
5168 string = it.string;
a1b0a6db 5169 *pos = it.current;
86282aab
KH
5170 if (it.what == IT_COMPOSITION
5171 && it.cmp_it.nchars > 1
5172 && it.cmp_it.reversed_p)
5173 {
5174 /* The current display element is a grapheme cluster in a
5175 composition. In that case, we need the position of the first
5176 character of the cluster. But, as it.cmp_it.reversed_p is 1,
5177 it.current points to the last character of the cluster, thus
5178 we must move back to the first character of the same
5179 cluster. */
5180 CHARPOS (pos->pos) -= it.cmp_it.nchars - 1;
5181 if (STRINGP (it.string))
5182 BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
5183 else
d3d50620 5184 BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->buffer),
425cc014 5185 CHARPOS (pos->pos));
86282aab 5186 }
6b61353c
KH
5187
5188#ifdef HAVE_WINDOW_SYSTEM
5189 if (it.what == IT_IMAGE)
5190 {
6b61353c
KH
5191 if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL
5192 && !NILP (img->spec))
5193 *object = img->spec;
5194 }
5195#endif
5196
b70d98e1
KS
5197 if (it.vpos < w->current_matrix->nrows
5198 && (row = MATRIX_ROW (w->current_matrix, it.vpos),
5199 row->enabled_p))
6b61353c
KH
5200 {
5201 if (it.hpos < row->used[TEXT_AREA])
5202 {
5203 struct glyph *glyph = row->glyphs[TEXT_AREA] + it.hpos;
6b61353c 5204#ifdef HAVE_WINDOW_SYSTEM
cedd7cd9
KS
5205 if (img)
5206 {
5207 *dy -= row->ascent - glyph->ascent;
4be9765d
KH
5208 *dx += glyph->slice.img.x;
5209 *dy += glyph->slice.img.y;
cedd7cd9
KS
5210 /* Image slices positions are still relative to the entire image */
5211 *width = img->width;
5212 *height = img->height;
5213 }
5214 else
6b61353c 5215#endif
cedd7cd9
KS
5216 {
5217 *width = glyph->pixel_width;
5218 *height = glyph->ascent + glyph->descent;
5219 }
6b61353c
KH
5220 }
5221 else
5222 {
5223 *width = 0;
5224 *height = row->height;
5225 }
5226 }
5227 else
5228 {
5229 *width = *height = 0;
5230 }
5231
5232 /* Add extra (default width) columns if clicked after EOL. */
5e617bc2 5233 x1 = max (0, it.current_x + it.pixel_width - it.first_visible_x);
6b61353c
KH
5234 if (x0 > x1)
5235 it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
5236
5237 *x = it.hpos;
5238 *y = it.vpos;
5239
5240 return string;
5f5c8ee5 5241}
4588ec20 5242
5f5c8ee5
GM
5243
5244/* Value is the string under window-relative coordinates X/Y in the
6b61353c
KH
5245 mode line or header line (PART says which) of window W, or nil if none.
5246 *CHARPOS is set to the position in the string returned. */
5f5c8ee5
GM
5247
5248Lisp_Object
ace1712c 5249mode_line_string (struct window *w, enum window_part part,
d311d28c 5250 int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
ace1712c 5251 int *dx, int *dy, int *width, int *height)
5f5c8ee5
GM
5252{
5253 struct glyph_row *row;
5254 struct glyph *glyph, *end;
6b61353c 5255 int x0, y0;
5f5c8ee5
GM
5256 Lisp_Object string = Qnil;
5257
641bdbf3 5258 if (part == ON_MODE_LINE)
5f5c8ee5
GM
5259 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
5260 else
045dee35 5261 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
6b61353c
KH
5262 y0 = *y - row->y;
5263 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5f5c8ee5
GM
5264
5265 if (row->mode_line_p && row->enabled_p)
4588ec20 5266 {
5f5c8ee5
GM
5267 /* Find the glyph under X. If we find one with a string object,
5268 it's the one we were looking for. */
5269 glyph = row->glyphs[TEXT_AREA];
5270 end = glyph + row->used[TEXT_AREA];
cfde341f 5271 for (x0 = *x; glyph < end && x0 >= glyph->pixel_width; ++glyph)
6b61353c
KH
5272 x0 -= glyph->pixel_width;
5273 *x = glyph - row->glyphs[TEXT_AREA];
5274 if (glyph < end)
5275 {
5276 string = glyph->object;
5277 *charpos = glyph->charpos;
5278 *width = glyph->pixel_width;
5279 *height = glyph->ascent + glyph->descent;
5280#ifdef HAVE_WINDOW_SYSTEM
5281 if (glyph->type == IMAGE_GLYPH)
5282 {
5283 struct image *img;
5284 img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
5285 if (img != NULL)
5286 *object = img->spec;
5287 y0 -= row->ascent - glyph->ascent;
5288 }
5289#endif
5290 }
5291 else
5292 {
5293 /* Add extra (default width) columns if clicked after EOL. */
5294 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5295 *width = 0;
5296 *height = row->height;
5297 }
5298 }
5299 else
5300 {
5301 *x = 0;
5302 x0 = 0;
5303 *width = *height = 0;
4588ec20 5304 }
5f5c8ee5 5305
6b61353c
KH
5306 *dx = x0;
5307 *dy = y0;
5308
5f5c8ee5 5309 return string;
4588ec20 5310}
5f5c8ee5
GM
5311
5312
db1db309
GM
5313/* Value is the string under window-relative coordinates X/Y in either
5314 marginal area, or nil if none. *CHARPOS is set to the position in
5315 the string returned. */
5316
5317Lisp_Object
ace1712c 5318marginal_area_string (struct window *w, enum window_part part,
d311d28c 5319 int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
ace1712c 5320 int *dx, int *dy, int *width, int *height)
db1db309
GM
5321{
5322 struct glyph_row *row = w->current_matrix->rows;
5323 struct glyph *glyph, *end;
6b61353c 5324 int x0, y0, i, wy = *y;
641bdbf3 5325 int area;
db1db309
GM
5326 Lisp_Object string = Qnil;
5327
641bdbf3 5328 if (part == ON_LEFT_MARGIN)
db1db309 5329 area = LEFT_MARGIN_AREA;
641bdbf3 5330 else if (part == ON_RIGHT_MARGIN)
db1db309
GM
5331 area = RIGHT_MARGIN_AREA;
5332 else
1088b922 5333 emacs_abort ();
db1db309
GM
5334
5335 for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row)
5336 if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row))
5337 break;
6b61353c
KH
5338 y0 = *y - row->y;
5339 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
db1db309
GM
5340
5341 if (row->enabled_p)
5342 {
5343 /* Find the glyph under X. If we find one with a string object,
5344 it's the one we were looking for. */
db1db309 5345 if (area == RIGHT_MARGIN_AREA)
7df02016 5346 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
6b61353c 5347 ? WINDOW_LEFT_FRINGE_WIDTH (w)
7df02016
KS
5348 : WINDOW_TOTAL_FRINGE_WIDTH (w))
5349 + window_box_width (w, LEFT_MARGIN_AREA)
5350 + window_box_width (w, TEXT_AREA));
db1db309 5351 else
7df02016 5352 x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
6b61353c 5353 ? WINDOW_LEFT_FRINGE_WIDTH (w)
7df02016
KS
5354 : 0);
5355
6b61353c
KH
5356 glyph = row->glyphs[area];
5357 end = glyph + row->used[area];
cfde341f 5358 for (x0 = *x - x0; glyph < end && x0 >= glyph->pixel_width; ++glyph)
6b61353c
KH
5359 x0 -= glyph->pixel_width;
5360 *x = glyph - row->glyphs[area];
5361 if (glyph < end)
5362 {
5363 string = glyph->object;
5364 *charpos = glyph->charpos;
5365 *width = glyph->pixel_width;
5366 *height = glyph->ascent + glyph->descent;
5367#ifdef HAVE_WINDOW_SYSTEM
5368 if (glyph->type == IMAGE_GLYPH)
5369 {
5370 struct image *img;
5371 img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
5372 if (img != NULL)
5373 *object = img->spec;
5374 y0 -= row->ascent - glyph->ascent;
4be9765d
KH
5375 x0 += glyph->slice.img.x;
5376 y0 += glyph->slice.img.y;
6b61353c
KH
5377 }
5378#endif
5379 }
5380 else
5381 {
5382 /* Add extra (default width) columns if clicked after EOL. */
5383 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5384 *width = 0;
5385 *height = row->height;
5386 }
db1db309 5387 }
6b61353c
KH
5388 else
5389 {
5390 x0 = 0;
5391 *x = 0;
5392 *width = *height = 0;
5393 }
5394
5395 *dx = x0;
5396 *dy = y0;
db1db309
GM
5397
5398 return string;
5399}
5400
5401
5f5c8ee5
GM
5402/***********************************************************************
5403 Changing Frame Sizes
5404 ***********************************************************************/
4588ec20
JB
5405
5406#ifdef SIGWINCH
5f5c8ee5 5407
20ef56db
PE
5408static void deliver_window_change_signal (int);
5409
9af30bdf 5410static void
20ef56db 5411handle_window_change_signal (int sig)
4588ec20
JB
5412{
5413 int width, height;
28d7d09f 5414 struct tty_display_info *tty;
4d553a13 5415
9628b887
KL
5416 /* The frame size change obviously applies to a single
5417 termcap-controlled terminal, but we can't decide which.
5418 Therefore, we resize the frames corresponding to each tty.
9628b887
KL
5419 */
5420 for (tty = tty_list; tty; tty = tty->next) {
4588ec20 5421
0a125897
KL
5422 if (! tty->term_initted)
5423 continue;
4588ec20 5424
db878925
DN
5425 /* Suspended tty frames have tty->input == NULL avoid trying to
5426 use it. */
5427 if (!tty->input)
5428 continue;
5429
0b0d3e0b 5430 get_tty_size (fileno (tty->input), &width, &height);
3fc809e2 5431
bedeffcf 5432 if (width > 5 && height > 2) {
9628b887 5433 Lisp_Object tail, frame;
3fc809e2 5434
9628b887 5435 FOR_EACH_FRAME (tail, frame)
4d553a13
KL
5436 if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
5437 /* Record the new sizes, but don't reallocate the data
5438 structures now. Let that be done later outside of the
5439 signal handler. */
5440 change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
9628b887 5441 }
4588ec20 5442 }
20ef56db 5443}
3fc809e2 5444
20ef56db
PE
5445static void
5446deliver_window_change_signal (int sig)
5447{
4d7e6e51 5448 deliver_process_signal (sig, handle_window_change_signal);
4588ec20
JB
5449}
5450#endif /* SIGWINCH */
5451
5452
59ea14cd
PE
5453/* Do any change in frame size that was requested by a signal.
5454 SAFE means this function is called from a place where it is
5455 safe to change frame sizes while a redisplay is in progress. */
4588ec20 5456
dfcf069d 5457void
59ea14cd 5458do_pending_window_change (bool safe)
4588ec20 5459{
20ef56db 5460 /* If window change signal handler should have run before, run it now. */
b96fd3e8
GM
5461 if (redisplaying_p && !safe)
5462 return;
177c0ea7 5463
4588ec20
JB
5464 while (delayed_size_change)
5465 {
35f56f96 5466 Lisp_Object tail, frame;
4588ec20
JB
5467
5468 delayed_size_change = 0;
5469
35f56f96 5470 FOR_EACH_FRAME (tail, frame)
4588ec20 5471 {
5f5c8ee5 5472 struct frame *f = XFRAME (frame);
35f56f96 5473
7df02016
KS
5474 if (f->new_text_lines != 0 || f->new_text_cols != 0)
5475 change_frame_size (f, f->new_text_lines, f->new_text_cols,
5476 0, 0, safe);
4588ec20
JB
5477 }
5478 }
5479}
5480
5481
502b9b64 5482/* Change the frame height and/or width. Values may be given as zero to
177c0ea7 5483 indicate no change is to take place.
4588ec20 5484
59ea14cd
PE
5485 If DELAY, assume we're being called from a signal handler, and
5486 queue the change for later - perhaps the next redisplay.
5487 Since this tries to resize windows, we can't call it
b96fd3e8
GM
5488 from a signal handler.
5489
59ea14cd 5490 SAFE means this function is called from a place where it's
b96fd3e8 5491 safe to change frame sizes while a redisplay is in progress. */
b6a65ac2 5492
dfcf069d 5493void
59ea14cd
PE
5494change_frame_size (struct frame *f, int newheight, int newwidth,
5495 bool pretend, bool delay, bool safe)
45140e01
RS
5496{
5497 Lisp_Object tail, frame;
3826ea1a 5498
9628b887 5499 if (FRAME_MSDOS_P (f))
45140e01 5500 {
9628b887
KL
5501 /* On MS-DOS, all frames use the same screen, so a change in
5502 size affects all frames. Termcap now supports multiple
5503 ttys. */
45140e01 5504 FOR_EACH_FRAME (tail, frame)
8a376b3b 5505 if (! FRAME_WINDOW_P (XFRAME (frame)))
45140e01 5506 change_frame_size_1 (XFRAME (frame), newheight, newwidth,
b96fd3e8 5507 pretend, delay, safe);
45140e01
RS
5508 }
5509 else
b96fd3e8 5510 change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe);
45140e01
RS
5511}
5512
5513static void
59ea14cd
PE
5514change_frame_size_1 (struct frame *f, int newheight, int newwidth,
5515 bool pretend, bool delay, bool safe)
4588ec20 5516{
7df02016 5517 int new_frame_total_cols;
d311d28c 5518 ptrdiff_t count = SPECPDL_INDEX ();
3826ea1a 5519
4588ec20 5520 /* If we can't deal with the change now, queue it for later. */
b96fd3e8 5521 if (delay || (redisplaying_p && !safe))
4588ec20 5522 {
7df02016
KS
5523 f->new_text_lines = newheight;
5524 f->new_text_cols = newwidth;
4588ec20
JB
5525 delayed_size_change = 1;
5526 return;
5527 }
5528
502b9b64 5529 /* This size-change overrides any pending one for this frame. */
7df02016
KS
5530 f->new_text_lines = 0;
5531 f->new_text_cols = 0;
b6a65ac2 5532
08f7aa3e 5533 /* If an argument is zero, set it to the current value. */
ae19c6f2 5534 if (newheight == 0)
7df02016 5535 newheight = FRAME_LINES (f);
ae19c6f2 5536 if (newwidth == 0)
7df02016 5537 newwidth = FRAME_COLS (f);
3826ea1a 5538
3b95a6f9 5539 /* Compute width of windows in F. */
b6a65ac2 5540 /* Round up to the smallest acceptable size. */
5f5c8ee5 5541 check_frame_size (f, &newheight, &newwidth);
b6a65ac2 5542
3b95a6f9
MR
5543 /* This is the width of the frame with vertical scroll bars and fringe
5544 columns. Do this after rounding - see discussion of bug#9723. */
5545 new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth);
5546
b6a65ac2 5547 /* If we're not changing the frame size, quit now. */
3b95a6f9
MR
5548 /* Frame width may be unchanged but the text portion may change, for
5549 example, fullscreen and remove/add scroll bar. */
7df02016 5550 if (newheight == FRAME_LINES (f)
3b95a6f9
MR
5551 /* Text portion unchanged? */
5552 && newwidth == FRAME_COLS (f)
5553 /* Frame width unchanged? */
5554 && new_frame_total_cols == FRAME_TOTAL_COLS (f))
4588ec20
JB
5555 return;
5556
4d7e6e51 5557 block_input ();
cbb95688 5558
886a8a6c
KH
5559#ifdef MSDOS
5560 /* We only can set screen dimensions to certain values supported
5561 by our video hardware. Try to find the smallest size greater
5562 or equal to the requested dimensions. */
5563 dos_set_window_size (&newheight, &newwidth);
5564#endif
5565
7df02016 5566 if (newheight != FRAME_LINES (f))
4588ec20 5567 {
562dd5e9 5568 resize_frame_windows (f, newheight, 0);
b6a65ac2 5569
48e482e6
EZ
5570 /* MSDOS frames cannot PRETEND, as they change frame size by
5571 manipulating video hardware. */
5572 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
6548cf00 5573 FrameRows (FRAME_TTY (f)) = newheight;
4588ec20
JB
5574 }
5575
7df02016 5576 if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
4588ec20 5577 {
562dd5e9 5578 resize_frame_windows (f, new_frame_total_cols, 1);
4588ec20 5579
48e482e6
EZ
5580 /* MSDOS frames cannot PRETEND, as they change frame size by
5581 manipulating video hardware. */
5582 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
6548cf00 5583 FrameCols (FRAME_TTY (f)) = newwidth;
5f5c8ee5 5584
e69b0960 5585 if (WINDOWP (f->tool_bar_window))
e8c17b81 5586 wset_total_cols (XWINDOW (f->tool_bar_window), make_number (newwidth));
4588ec20
JB
5587 }
5588
7df02016
KS
5589 FRAME_LINES (f) = newheight;
5590 SET_FRAME_COLS (f, newwidth);
986e61b8 5591
5f5c8ee5
GM
5592 {
5593 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5594 int text_area_x, text_area_y, text_area_width, text_area_height;
177c0ea7 5595
5f5c8ee5
GM
5596 window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width,
5597 &text_area_height);
5598 if (w->cursor.x >= text_area_x + text_area_width)
5599 w->cursor.hpos = w->cursor.x = 0;
5600 if (w->cursor.y >= text_area_y + text_area_height)
5601 w->cursor.vpos = w->cursor.y = 0;
5602 }
986e61b8 5603
5f5c8ee5 5604 adjust_glyphs (f);
5f5c8ee5 5605 calculate_costs (f);
cb02fa39
GM
5606 SET_FRAME_GARBAGED (f);
5607 f->resized_p = 1;
97cf50e7 5608
4d7e6e51 5609 unblock_input ();
61730a69 5610
66322887 5611 record_unwind_current_buffer ();
e523f7e5 5612
ef264c42 5613 run_window_configuration_change_hook (f);
e523f7e5
RS
5614
5615 unbind_to (count, Qnil);
4588ec20 5616}
5f5c8ee5
GM
5617
5618
4588ec20 5619\f
5f5c8ee5
GM
5620/***********************************************************************
5621 Terminal Related Lisp Functions
5622 ***********************************************************************/
5623
5624DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
228299fa 5625 1, 1, "FOpen termscript file: ",
7ee72033
MB
5626 doc: /* Start writing all terminal output to FILE as well as the terminal.
5627FILE = nil means just close any termscript file currently open. */)
5842a27b 5628 (Lisp_Object file)
5f5c8ee5 5629{
0b0d3e0b
KL
5630 struct tty_display_info *tty;
5631
7d2f1216
EZ
5632 if (! FRAME_TERMCAP_P (SELECTED_FRAME ())
5633 && ! FRAME_MSDOS_P (SELECTED_FRAME ()))
0b0d3e0b
KL
5634 error ("Current frame is not on a tty device");
5635
5636 tty = CURTTY ();
5637
5638 if (tty->termscript != 0)
e18c7093 5639 {
4d7e6e51 5640 block_input ();
0b0d3e0b 5641 fclose (tty->termscript);
4d7e6e51 5642 unblock_input ();
e18c7093 5643 }
0b0d3e0b 5644 tty->termscript = 0;
5f5c8ee5
GM
5645
5646 if (! NILP (file))
5647 {
5648 file = Fexpand_file_name (file, Qnil);
42a5b22f 5649 tty->termscript = fopen (SSDATA (file), "w");
0b0d3e0b 5650 if (tty->termscript == 0)
5f5c8ee5
GM
5651 report_file_error ("Opening termscript", Fcons (file, Qnil));
5652 }
5653 return Qnil;
5654}
5655
5656
4588ec20 5657DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
62af879c 5658 Ssend_string_to_terminal, 1, 2, 0,
7ee72033 5659 doc: /* Send STRING to the terminal without alteration.
62af879c
KL
5660Control characters in STRING will have terminal-dependent effects.
5661
6ed8eeff 5662Optional parameter TERMINAL specifies the tty terminal device to use.
558759e4
AM
5663It may be a terminal object, a frame, or nil for the terminal used by
5664the currently selected frame. In batch mode, STRING is sent to stdout
5665when TERMINAL is nil. */)
5842a27b 5666 (Lisp_Object string, Lisp_Object terminal)
4588ec20 5667{
7cef7ce3
SM
5668 struct terminal *t = get_terminal (terminal, 1);
5669 FILE *out;
0b0d3e0b 5670
94f3db62 5671 /* ??? Perhaps we should do something special for multibyte strings here. */
b7826503 5672 CHECK_STRING (string);
4d7e6e51 5673 block_input ();
0b0d3e0b 5674
6ed8eeff
KL
5675 if (!t)
5676 error ("Unknown terminal device");
0b0d3e0b 5677
7cef7ce3
SM
5678 if (t->type == output_initial)
5679 out = stdout;
5680 else if (t->type != output_termcap && t->type != output_msdos_raw)
5681 error ("Device %d is not a termcap terminal device", t->id);
5682 else
5683 {
5684 struct tty_display_info *tty = t->display_info.tty;
3fc809e2 5685
7cef7ce3
SM
5686 if (! tty->output)
5687 error ("Terminal is currently suspended");
cecfdea6 5688
7cef7ce3
SM
5689 if (tty->termscript)
5690 {
5691 fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
5692 fflush (tty->termscript);
5693 }
5694 out = tty->output;
4588ec20 5695 }
7cef7ce3
SM
5696 fwrite (SDATA (string), 1, SBYTES (string), out);
5697 fflush (out);
4d7e6e51 5698 unblock_input ();
4588ec20
JB
5699 return Qnil;
5700}
5701
5f5c8ee5 5702
a7ca3326 5703DEFUN ("ding", Fding, Sding, 0, 1, 0,
7ee72033 5704 doc: /* Beep, or flash the screen.
228299fa 5705Also, unless an argument is given,
7ee72033 5706terminate any keyboard macro currently executing. */)
5842a27b 5707 (Lisp_Object arg)
4588ec20 5708{
efb859b4 5709 if (!NILP (arg))
4588ec20 5710 {
7fa788da
RS
5711 if (noninteractive)
5712 putchar (07);
5713 else
385ed61f 5714 ring_bell (XFRAME (selected_frame));
4588ec20
JB
5715 }
5716 else
5717 bitch_at_user ();
5718
5719 return Qnil;
5720}
5721
dfcf069d 5722void
971de7fb 5723bitch_at_user (void)
4588ec20
JB
5724{
5725 if (noninteractive)
5726 putchar (07);
5f5c8ee5 5727 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
4588ec20
JB
5728 error ("Keyboard macro terminated by a command ringing the bell");
5729 else
385ed61f 5730 ring_bell (XFRAME (selected_frame));
4588ec20
JB
5731}
5732
5f5c8ee5
GM
5733
5734\f
5735/***********************************************************************
5736 Sleeping, Waiting
5737 ***********************************************************************/
5738
a7ca3326 5739DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
7ee72033 5740 doc: /* Pause, without updating display, for SECONDS seconds.
228299fa
GM
5741SECONDS may be a floating-point value, meaning that you can wait for a
5742fraction of a second. Optional second arg MILLISECONDS specifies an
d35af63c 5743additional wait period, in milliseconds; this is for backwards compatibility.
7ee72033 5744\(Not all operating systems support waiting for a fraction of a second.) */)
5842a27b 5745 (Lisp_Object seconds, Lisp_Object milliseconds)
4588ec20 5746{
d311d28c 5747 double duration = extract_float (seconds);
4588ec20 5748
d311d28c
PE
5749 if (!NILP (milliseconds))
5750 {
5751 CHECK_NUMBER (milliseconds);
5752 duration += XINT (milliseconds) / 1000.0;
5753 }
b07646f5 5754
d35af63c
PE
5755 if (0 < duration)
5756 {
5757 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration);
f1dd8073 5758 wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX),
d35af63c
PE
5759 EMACS_NSECS (t), 0, 0, Qnil, NULL, 0);
5760 }
4588ec20
JB
5761
5762 return Qnil;
5763}
5764
5f5c8ee5 5765
dcd1ca45 5766/* This is just like wait_reading_process_output, except that
902b9b6d 5767 it does redisplay.
f76475ad 5768
2bcac766
CY
5769 TIMEOUT is number of seconds to wait (float or integer),
5770 or t to wait forever.
59ea14cd 5771 READING is true if reading input.
9fa1de30
PE
5772 If DISPLAY_OPTION is >0 display process output while waiting.
5773 If DISPLAY_OPTION is >1 perform an initial redisplay before waiting.
902b9b6d 5774*/
4588ec20 5775
f76475ad 5776Lisp_Object
9fa1de30 5777sit_for (Lisp_Object timeout, bool reading, int display_option)
f76475ad 5778{
d35af63c
PE
5779 intmax_t sec;
5780 int nsec;
9fa1de30 5781 bool do_display = display_option > 0;
f222369e 5782
902b9b6d 5783 swallow_events (do_display);
ccddf474 5784
902b9b6d 5785 if ((detect_input_pending_run_timers (do_display))
29bcbe54 5786 || !NILP (Vexecuting_kbd_macro))
4588ec20 5787 return Qnil;
4588ec20 5788
9fa1de30 5789 if (display_option > 1)
902b9b6d
KS
5790 redisplay_preserve_echo_area (2);
5791
d35af63c 5792 if (INTEGERP (timeout))
2bcac766 5793 {
d35af63c
PE
5794 sec = XINT (timeout);
5795 if (! (0 < sec))
5796 return Qt;
5797 nsec = 0;
2bcac766 5798 }
d35af63c 5799 else if (FLOATP (timeout))
d311d28c 5800 {
d35af63c
PE
5801 double seconds = XFLOAT_DATA (timeout);
5802 if (! (0 < seconds))
d311d28c 5803 return Qt;
d35af63c
PE
5804 else
5805 {
5806 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds);
f1dd8073 5807 sec = min (EMACS_SECS (t), WAIT_READING_MAX);
d35af63c
PE
5808 nsec = EMACS_NSECS (t);
5809 }
5810 }
5811 else if (EQ (timeout, Qt))
5812 {
5813 sec = 0;
5814 nsec = 0;
d311d28c 5815 }
d35af63c
PE
5816 else
5817 wrong_type_argument (Qnumberp, timeout);
5818
dfdb645c 5819
4a4bbad2 5820#ifdef USABLE_SIGIO
f75beb47 5821 gobble_input ();
f76475ad
JB
5822#endif
5823
d35af63c 5824 wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display,
dcd1ca45 5825 Qnil, NULL, 0);
f76475ad 5826
4588ec20
JB
5827 return detect_input_pending () ? Qnil : Qt;
5828}
5829
5f5c8ee5 5830
a7ca3326 5831DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0,
025de85b
CY
5832 doc: /* Perform redisplay.
5833Optional arg FORCE, if non-nil, prevents redisplay from being
5834preempted by arriving input, even if `redisplay-dont-pause' is nil.
5835If `redisplay-dont-pause' is non-nil (the default), redisplay is never
5836preempted by arriving input, so FORCE does nothing.
5837
5838Return t if redisplay was performed, nil if redisplay was preempted
5839immediately by pending input. */)
5842a27b 5840 (Lisp_Object force)
f76475ad 5841{
d311d28c 5842 ptrdiff_t count;
659d9874 5843
902b9b6d
KS
5844 swallow_events (1);
5845 if ((detect_input_pending_run_timers (1)
01327edf 5846 && NILP (force) && !redisplay_dont_pause)
7ba07a1a
CY
5847 || !NILP (Vexecuting_kbd_macro))
5848 return Qnil;
f76475ad 5849
01327edf
KS
5850 count = SPECPDL_INDEX ();
5851 if (!NILP (force) && !redisplay_dont_pause)
5852 specbind (Qredisplay_dont_pause, Qt);
7ba07a1a 5853 redisplay_preserve_echo_area (2);
01327edf 5854 unbind_to (count, Qnil);
7ba07a1a 5855 return Qt;
f76475ad 5856}
5f5c8ee5
GM
5857
5858
5859\f
5860/***********************************************************************
5861 Other Lisp Functions
5862 ***********************************************************************/
5863
5864/* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
5865 session's frames, frame names, buffers, buffer-read-only flags, and
44edd521 5866 buffer-modified-flags. */
5f5c8ee5
GM
5867
5868static Lisp_Object frame_and_buffer_state;
5869
5870
5871DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
44edd521 5872 Sframe_or_buffer_changed_p, 0, 1, 0,
bacf09b4 5873 doc: /* Return non-nil if the frame and buffer state appears to have changed.
44edd521
RS
5874VARIABLE is a variable name whose value is either nil or a state vector
5875that will be updated to contain all frames and buffers,
228299fa 5876aside from buffers whose names start with space,
44edd521
RS
5877along with the buffers' read-only and modified flags. This allows a fast
5878check to see whether buffer menus might need to be recomputed.
228299fa 5879If this function returns non-nil, it updates the internal vector to reflect
44edd521
RS
5880the current state.
5881
5882If VARIABLE is nil, an internal variable is used. Users should not
5883pass nil for VARIABLE. */)
5842a27b 5884 (Lisp_Object variable)
5f5c8ee5 5885{
44edd521 5886 Lisp_Object state, tail, frame, buf;
086ca913 5887 ptrdiff_t n, idx;
5f5c8ee5 5888
44edd521
RS
5889 if (! NILP (variable))
5890 {
5891 CHECK_SYMBOL (variable);
5892 state = Fsymbol_value (variable);
5893 if (! VECTORP (state))
5894 goto changed;
5895 }
5896 else
5897 state = frame_and_buffer_state;
5898
086ca913 5899 idx = 0;
5f5c8ee5
GM
5900 FOR_EACH_FRAME (tail, frame)
5901 {
086ca913 5902 if (idx == ASIZE (state))
44edd521 5903 goto changed;
086ca913 5904 if (!EQ (AREF (state, idx++), frame))
5f5c8ee5 5905 goto changed;
086ca913 5906 if (idx == ASIZE (state))
44edd521 5907 goto changed;
086ca913 5908 if (!EQ (AREF (state, idx++), XFRAME (frame)->name))
5f5c8ee5
GM
5909 goto changed;
5910 }
44edd521 5911 /* Check that the buffer info matches. */
7539e11f 5912 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
5f5c8ee5 5913 {
7539e11f 5914 buf = XCDR (XCAR (tail));
5f5c8ee5 5915 /* Ignore buffers that aren't included in buffer lists. */
4b4deea2 5916 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
5f5c8ee5 5917 continue;
086ca913 5918 if (idx == ASIZE (state))
44edd521 5919 goto changed;
086ca913 5920 if (!EQ (AREF (state, idx++), buf))
5f5c8ee5 5921 goto changed;
086ca913 5922 if (idx == ASIZE (state))
44edd521 5923 goto changed;
086ca913 5924 if (!EQ (AREF (state, idx++), BVAR (XBUFFER (buf), read_only)))
5f5c8ee5 5925 goto changed;
086ca913 5926 if (idx == ASIZE (state))
44edd521 5927 goto changed;
086ca913 5928 if (!EQ (AREF (state, idx++), Fbuffer_modified_p (buf)))
5f5c8ee5
GM
5929 goto changed;
5930 }
086ca913 5931 if (idx == ASIZE (state))
44edd521 5932 goto changed;
5f5c8ee5 5933 /* Detect deletion of a buffer at the end of the list. */
086ca913 5934 if (EQ (AREF (state, idx), Qlambda))
5f5c8ee5 5935 return Qnil;
44edd521
RS
5936
5937 /* Come here if we decide the data has changed. */
5f5c8ee5 5938 changed:
44edd521
RS
5939 /* Count the size we will need.
5940 Start with 1 so there is room for at least one lambda at the end. */
5f5c8ee5
GM
5941 n = 1;
5942 FOR_EACH_FRAME (tail, frame)
5943 n += 2;
7539e11f 5944 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
5f5c8ee5 5945 n += 3;
44edd521
RS
5946 /* Reallocate the vector if data has grown to need it,
5947 or if it has shrunk a lot. */
5948 if (! VECTORP (state)
77b37c05
PE
5949 || n > ASIZE (state)
5950 || n + 20 < ASIZE (state) / 2)
5f5c8ee5 5951 /* Add 20 extra so we grow it less often. */
44edd521
RS
5952 {
5953 state = Fmake_vector (make_number (n + 20), Qlambda);
5954 if (! NILP (variable))
5955 Fset (variable, state);
5956 else
5957 frame_and_buffer_state = state;
5958 }
5959
5960 /* Record the new data in the (possibly reallocated) vector. */
086ca913 5961 idx = 0;
5f5c8ee5
GM
5962 FOR_EACH_FRAME (tail, frame)
5963 {
086ca913
DA
5964 ASET (state, idx, frame);
5965 idx++;
5966 ASET (state, idx, XFRAME (frame)->name);
5967 idx++;
5f5c8ee5 5968 }
7539e11f 5969 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
5f5c8ee5 5970 {
7539e11f 5971 buf = XCDR (XCAR (tail));
5f5c8ee5 5972 /* Ignore buffers that aren't included in buffer lists. */
4b4deea2 5973 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
5f5c8ee5 5974 continue;
086ca913
DA
5975 ASET (state, idx, buf);
5976 idx++;
5977 ASET (state, idx, BVAR (XBUFFER (buf), read_only));
5978 idx++;
5979 ASET (state, idx, Fbuffer_modified_p (buf));
5980 idx++;
5f5c8ee5
GM
5981 }
5982 /* Fill up the vector with lambdas (always at least one). */
086ca913
DA
5983 ASET (state, idx, Qlambda);
5984 idx++;
5985 while (idx < ASIZE (state))
5986 {
5987 ASET (state, idx, Qlambda);
5988 idx++;
5989 }
5f5c8ee5 5990 /* Make sure we didn't overflow the vector. */
086ca913 5991 eassert (idx <= ASIZE (state));
5f5c8ee5
GM
5992 return Qt;
5993}
5994
5995
4588ec20 5996\f
5f5c8ee5
GM
5997/***********************************************************************
5998 Initialization
5999***********************************************************************/
6000
5f5c8ee5
GM
6001/* Initialization done when Emacs fork is started, before doing stty.
6002 Determine terminal type and set terminal_driver. Then invoke its
6003 decoding routine to set up variables in the terminal package. */
4588ec20 6004
dfcf069d 6005void
971de7fb 6006init_display (void)
4588ec20 6007{
28d440ab
KL
6008 char *terminal_type;
6009
5f5c8ee5
GM
6010 /* Construct the space glyph. */
6011 space_glyph.type = CHAR_GLYPH;
3fc809e2 6012 SET_CHAR_GLYPH (space_glyph, ' ', DEFAULT_FACE_ID, 0);
5f5c8ee5
GM
6013 space_glyph.charpos = -1;
6014
4588ec20
JB
6015 inverse_video = 0;
6016 cursor_in_echo_area = 0;
6017 terminal_type = (char *) 0;
6018
1315c181
JB
6019 /* Now is the time to initialize this; it's used by init_sys_modes
6020 during startup. */
2246281f 6021 Vinitial_window_system = Qnil;
4588ec20 6022
4181ad9c
KL
6023 /* SIGWINCH needs to be handled no matter what display we start
6024 with. Otherwise newly opened tty frames will not resize
6025 automatically. */
6026#ifdef SIGWINCH
6027#ifndef CANNOT_DUMP
6028 if (initialized)
6029#endif /* CANNOT_DUMP */
2fe28299
PE
6030 {
6031 struct sigaction action;
6032 emacs_sigaction_init (&action, deliver_window_change_signal);
6033 sigaction (SIGWINCH, &action, 0);
6034 }
4181ad9c 6035#endif /* SIGWINCH */
4588ec20 6036
d6ef42b9 6037 /* If running as a daemon, no need to initialize any frames/terminal. */
ff808935
DN
6038 if (IS_DAEMON)
6039 return;
d6ef42b9 6040
1315c181
JB
6041 /* If the user wants to use a window system, we shouldn't bother
6042 initializing the terminal. This is especially important when the
6043 terminal is so dumb that emacs gives up before and doesn't bother
6044 using the window system.
4588ec20 6045
36bbad1d
KH
6046 If the DISPLAY environment variable is set and nonempty,
6047 try to use X, and die with an error message if that doesn't work. */
4588ec20
JB
6048
6049#ifdef HAVE_X_WINDOWS
00d70d57 6050 if (! inhibit_window_system && ! display_arg)
d460af17 6051 {
36bbad1d 6052 char *display;
36bbad1d 6053 display = getenv ("DISPLAY");
36bbad1d 6054 display_arg = (display != 0 && *display != 0);
c1fc674b
AS
6055
6056 if (display_arg && !x_display_ok (display))
6057 {
6058 fprintf (stderr, "Display %s unavailable, simulating -nw\n",
6059 display);
6060 inhibit_window_system = 1;
6061 }
f040093a 6062 }
d460af17 6063
4fcc2638 6064 if (!inhibit_window_system && display_arg)
4588ec20 6065 {
111d9af3 6066 Vinitial_window_system = Qx;
4588ec20
JB
6067#ifdef HAVE_X11
6068 Vwindow_system_version = make_number (11);
039e5d71 6069#endif
9311dcff 6070#ifdef GNU_LINUX
039e5d71 6071 /* In some versions of ncurses,
6a428f77 6072 tputs crashes if we have not called tgetent.
039e5d71
KH
6073 So call tgetent. */
6074 { char b[2044]; tgetent (b, "xterm");}
4588ec20
JB
6075#endif
6076 return;
6077 }
6078#endif /* HAVE_X_WINDOWS */
6079
fd2e066a 6080#ifdef HAVE_NTGUI
177c0ea7 6081 if (!inhibit_window_system)
fd2e066a 6082 {
111d9af3 6083 Vinitial_window_system = Qw32;
fd2e066a
GV
6084 Vwindow_system_version = make_number (1);
6085 return;
6086 }
6087#endif /* HAVE_NTGUI */
6088
edfda783
AR
6089#ifdef HAVE_NS
6090 if (!inhibit_window_system
6091#ifndef CANNOT_DUMP
6092 && initialized
6093#endif
6094 )
6095 {
111d9af3 6096 Vinitial_window_system = Qns;
5e617bc2 6097 Vwindow_system_version = make_number (10);
edfda783
AR
6098 return;
6099 }
6100#endif
6101
4588ec20
JB
6102 /* If no window system has been specified, try to use the terminal. */
6103 if (! isatty (0))
6104 {
1559a86d 6105 fatal ("standard input is not a tty");
4588ec20
JB
6106 exit (1);
6107 }
6108
6152361f
JR
6109#ifdef WINDOWSNT
6110 terminal_type = "w32console";
6111#else
153a073c 6112 /* Look at the TERM variable. */
4588ec20 6113 terminal_type = (char *) getenv ("TERM");
6152361f 6114#endif
4588ec20
JB
6115 if (!terminal_type)
6116 {
5d12ff0b 6117#ifdef HAVE_WINDOW_SYSTEM
b9e590fc
RS
6118 if (! inhibit_window_system)
6119 fprintf (stderr, "Please set the environment variable DISPLAY or TERM (see `tset').\n");
5d12ff0b
RS
6120 else
6121#endif /* HAVE_WINDOW_SYSTEM */
b9e590fc 6122 fprintf (stderr, "Please set the environment variable TERM; see `tset'.\n");
4588ec20
JB
6123 exit (1);
6124 }
6125
0a125897 6126 {
6ed8eeff 6127 struct terminal *t;
3224dac1
KL
6128 struct frame *f = XFRAME (selected_frame);
6129
322aea6d
PE
6130 init_foreground_group ();
6131
3224dac1 6132 /* Open a display on the controlling tty. */
6ed8eeff 6133 t = init_tty (0, terminal_type, 1); /* Errors are fatal. */
3224dac1
KL
6134
6135 /* Convert the initial frame to use the new display. */
b04f5ad2 6136 if (f->output_method != output_initial)
1088b922 6137 emacs_abort ();
6ed8eeff
KL
6138 f->output_method = t->type;
6139 f->terminal = t;
3224dac1 6140
6ed8eeff 6141 t->reference_count++;
7ac5dac9
EZ
6142#ifdef MSDOS
6143 f->output_data.tty->display_info = &the_only_display_info;
6144#else
6145 if (f->output_method == output_termcap)
6146 create_tty_output (f);
6147#endif
6ed8eeff 6148 t->display_info.tty->top_frame = selected_frame;
5b65d888 6149 change_frame_size (XFRAME (selected_frame),
6ed8eeff
KL
6150 FrameRows (t->display_info.tty),
6151 FrameCols (t->display_info.tty), 0, 0, 1);
3224dac1 6152
6ed8eeff
KL
6153 /* Delete the initial terminal. */
6154 if (--initial_terminal->reference_count == 0
6155 && initial_terminal->delete_terminal_hook)
6156 (*initial_terminal->delete_terminal_hook) (initial_terminal);
2666355c
KL
6157
6158 /* Update frame parameters to reflect the new type. */
6159 Fmodify_frame_parameters
6160 (selected_frame, Fcons (Fcons (Qtty_type,
6ed8eeff 6161 Ftty_type (selected_frame)), Qnil));
657ceaa0
EZ
6162 if (t->display_info.tty->name)
6163 Fmodify_frame_parameters (selected_frame,
6164 Fcons (Fcons (Qtty, build_string (t->display_info.tty->name)),
6165 Qnil));
6166 else
6167 Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qtty, Qnil),
6168 Qnil));
0a125897 6169 }
3fc809e2 6170
d86c299a 6171 {
91fb7e1b 6172 struct frame *sf = SELECTED_FRAME ();
7df02016
KS
6173 int width = FRAME_TOTAL_COLS (sf);
6174 int height = FRAME_LINES (sf);
d86c299a 6175
5f5c8ee5 6176 /* If these sizes are so big they cause overflow, just ignore the
dfd153ae
PE
6177 change. It's not clear what better we could do. The rest of
6178 the code assumes that (width + 2) * height * sizeof (struct glyph)
6179 does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX. */
e3c25c68
PE
6180 if (INT_ADD_RANGE_OVERFLOW (width, 2, INT_MIN, INT_MAX)
6181 || INT_MULTIPLY_RANGE_OVERFLOW (width + 2, height, INT_MIN, INT_MAX)
dfd153ae
PE
6182 || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph)
6183 < (width + 2) * height))
1559a86d 6184 fatal ("screen size %dx%d too big", width, height);
d86c299a
RS
6185 }
6186
91fb7e1b 6187 calculate_costs (XFRAME (selected_frame));
4588ec20 6188
5f5c8ee5
GM
6189 /* Set up faces of the initial terminal frame of a dumped Emacs. */
6190 if (initialized
6191 && !noninteractive
2246281f 6192 && NILP (Vinitial_window_system))
2d764c78
EZ
6193 {
6194 /* For the initial frame, we don't have any way of knowing what
6195 are the foreground and background colors of the terminal. */
5e617bc2 6196 struct frame *sf = SELECTED_FRAME ();
2d764c78 6197
f9d2fdc4
EZ
6198 FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
6199 FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;
2d764c78
EZ
6200 call0 (intern ("tty-set-up-initial-frame-faces"));
6201 }
5f5c8ee5
GM
6202}
6203
6204
6205\f
6206/***********************************************************************
6207 Blinking cursor
6208 ***********************************************************************/
6209
c3f13540 6210DEFUN ("internal-show-cursor", Finternal_show_cursor,
5d7791b3 6211 Sinternal_show_cursor, 2, 2, 0,
7ee72033 6212 doc: /* Set the cursor-visibility flag of WINDOW to SHOW.
228299fa
GM
6213WINDOW nil means use the selected window. SHOW non-nil means
6214show a cursor in WINDOW in the next redisplay. SHOW nil means
7ee72033 6215don't show a cursor. */)
5842a27b 6216 (Lisp_Object window, Lisp_Object show)
5f5c8ee5 6217{
5f5c8ee5
GM
6218 /* Don't change cursor state while redisplaying. This could confuse
6219 output routines. */
6220 if (!redisplaying_p)
b9e9df47 6221 decode_any_window (window)->cursor_off_p = NILP (show);
5f5c8ee5 6222 return Qnil;
4588ec20 6223}
5f5c8ee5
GM
6224
6225
5d7791b3
GM
6226DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
6227 Sinternal_show_cursor_p, 0, 1, 0,
bacf09b4 6228 doc: /* Value is non-nil if next redisplay will display a cursor in WINDOW.
7ee72033 6229WINDOW nil or omitted means report on the selected window. */)
5842a27b 6230 (Lisp_Object window)
5d7791b3 6231{
b9e9df47 6232 return decode_any_window (window)->cursor_off_p ? Qnil : Qt;
5d7791b3
GM
6233}
6234
87478b52
SM
6235DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
6236 Slast_nonminibuf_frame, 0, 0, 0,
6237 doc: /* Value is last nonminibuffer frame. */)
5842a27b 6238 (void)
87478b52 6239{
4958ed94 6240 Lisp_Object frame = Qnil;
87478b52 6241
4958ed94
SM
6242 if (last_nonminibuf_frame)
6243 XSETFRAME (frame, last_nonminibuf_frame);
87478b52
SM
6244
6245 return frame;
6246}
4588ec20 6247\f
5f5c8ee5
GM
6248/***********************************************************************
6249 Initialization
6250 ***********************************************************************/
6251
dfcf069d 6252void
971de7fb 6253syms_of_display (void)
4588ec20 6254{
502b9b64 6255 defsubr (&Sredraw_frame);
4588ec20 6256 defsubr (&Sredraw_display);
078b3696 6257 defsubr (&Sframe_or_buffer_changed_p);
4588ec20
JB
6258 defsubr (&Sopen_termscript);
6259 defsubr (&Sding);
7ba07a1a 6260 defsubr (&Sredisplay);
4588ec20
JB
6261 defsubr (&Ssleep_for);
6262 defsubr (&Ssend_string_to_terminal);
c3f13540 6263 defsubr (&Sinternal_show_cursor);
5d7791b3 6264 defsubr (&Sinternal_show_cursor_p);
87478b52 6265 defsubr (&Slast_nonminibuf_frame);
4588ec20 6266
e509cfa6 6267#ifdef GLYPH_DEBUG
9b0e97aa
GM
6268 defsubr (&Sdump_redisplay_history);
6269#endif
6270
d1dad759 6271 frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
078b3696
KH
6272 staticpro (&frame_and_buffer_state);
6273
cd3520a4
JB
6274 DEFSYM (Qdisplay_table, "display-table");
6275 DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
9cda4f7c 6276
29208e82 6277 DEFVAR_INT ("baud-rate", baud_rate,
025de85b 6278 doc: /* The output baud rate of the terminal.
228299fa
GM
6279On most systems, changing this value will affect the amount of padding
6280and the other strategic decisions made during redisplay. */);
177c0ea7 6281
29208e82 6282 DEFVAR_BOOL ("inverse-video", inverse_video,
025de85b 6283 doc: /* Non-nil means invert the entire frame display.
228299fa 6284This means everything is in inverse video which otherwise would not be. */);
177c0ea7 6285
29208e82 6286 DEFVAR_BOOL ("visible-bell", visible_bell,
025de85b 6287 doc: /* Non-nil means try to flash the frame to represent a bell.
552b1b01
EZ
6288
6289See also `ring-bell-function'. */);
177c0ea7 6290
29208e82 6291 DEFVAR_BOOL ("no-redraw-on-reenter", no_redraw_on_reenter,
025de85b 6292 doc: /* Non-nil means no need to redraw entire frame after suspending.
228299fa
GM
6293A non-nil value is useful if the terminal can automatically preserve
6294Emacs's frame display when you reenter Emacs.
6295It is up to you to set this variable if your terminal can do that. */);
177c0ea7 6296
29208e82 6297 DEFVAR_LISP ("initial-window-system", Vinitial_window_system,
2246281f 6298 doc: /* Name of the window system that Emacs uses for the first frame.
89baa1df
EZ
6299The value is a symbol:
6300 nil for a termcap frame (a character-only terminal),
6301 'x' for an Emacs frame that is really an X window,
6302 'w32' for an Emacs frame that is a window on MS-Windows display,
6303 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
6304 'pc' for a direct-write MS-DOS frame.
6305
6306Use of this variable as a boolean is deprecated. Instead,
6307use `display-graphic-p' or any of the other `display-*-p'
6308predicates which report frame's specific UI-related capabilities. */);
177c0ea7 6309
70b8d0a4
SM
6310 DEFVAR_KBOARD ("window-system", Vwindow_system,
6311 doc: /* Name of window system through which the selected frame is displayed.
89baa1df
EZ
6312The value is a symbol:
6313 nil for a termcap frame (a character-only terminal),
6314 'x' for an Emacs frame that is really an X window,
6315 'w32' for an Emacs frame that is a window on MS-Windows display,
6316 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
6317 'pc' for a direct-write MS-DOS frame.
6318
6319Use of this variable as a boolean is deprecated. Instead,
6320use `display-graphic-p' or any of the other `display-*-p'
6321predicates which report frame's specific UI-related capabilities. */);
70b8d0a4 6322
29208e82 6323 DEFVAR_LISP ("window-system-version", Vwindow_system_version,
bacf09b4 6324 doc: /* The version number of the window system in use.
c22140f6 6325For X windows, this is 11. */);
177c0ea7 6326
29208e82 6327 DEFVAR_BOOL ("cursor-in-echo-area", cursor_in_echo_area,
bacf09b4 6328 doc: /* Non-nil means put cursor in minibuffer, at end of any message there. */);
177c0ea7 6329
29208e82 6330 DEFVAR_LISP ("glyph-table", Vglyph_table,
bacf09b4 6331 doc: /* Table defining how to output a glyph code to the frame.
228299fa
GM
6332If not nil, this is a vector indexed by glyph code to define the glyph.
6333Each element can be:
6334 integer: a glyph code which this glyph is an alias for.
6335 string: output this glyph using that string (not impl. in X windows).
6336 nil: this glyph mod 524288 is the code of a character to output,
6337 and this glyph / 524288 is the face number (see `face-id') to use
6338 while outputting it. */);
4588ec20
JB
6339 Vglyph_table = Qnil;
6340
29208e82 6341 DEFVAR_LISP ("standard-display-table", Vstandard_display_table,
bacf09b4 6342 doc: /* Display table to use for buffers that specify none.
228299fa 6343See `buffer-display-table' for more information. */);
4588ec20
JB
6344 Vstandard_display_table = Qnil;
6345
29208e82 6346 DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause,
025de85b 6347 doc: /* Non-nil means display update isn't paused when input is detected. */);
6bf7006f 6348 redisplay_dont_pause = 1;
5f5c8ee5 6349
4588ec20
JB
6350#ifdef CANNOT_DUMP
6351 if (noninteractive)
6352#endif
6353 {
2246281f 6354 Vinitial_window_system = Qnil;
4588ec20
JB
6355 Vwindow_system_version = Qnil;
6356 }
6357}