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