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