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