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