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