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