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