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