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