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