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