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