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