This source file includes following definitions.
- add_window_display_history
- add_frame_display_history
- DEFUN
- __executable_start
- new_glyph_matrix
- free_glyph_matrix
- margin_glyphs_to_reserve
- verify_row_hash
- adjust_glyph_matrix
- reverse_rows
- rotate_matrix
- increment_matrix_positions
- clear_glyph_matrix_rows
- clear_glyph_matrix
- shift_glyph_matrix
- clear_current_matrices
- clear_desired_matrices
- clear_window_matrices
- clear_glyph_row
- blank_row
- increment_row_positions
- swap_glyphs_in_rows
- swap_glyph_pointers
- copy_row_except_pointers
- assign_row
- glyph_row_slice_p
- find_glyph_row_slice
- prepare_desired_row
- line_hash_code
- line_draw_cost
- row_equal_p
- new_glyph_pool
- free_glyph_pool
- realloc_glyph_pool
- flush_stdout
- check_matrix_pointer_lossage
- matrix_row
- check_matrix_invariants
- allocate_matrices_for_frame_redisplay
- required_matrix_height
- required_matrix_width
- allocate_matrices_for_window_redisplay
- adjust_frame_glyphs
- showing_window_margins_p
- fake_current_matrices
- save_current_matrix
- restore_current_matrix
- adjust_frame_glyphs_for_frame_redisplay
- adjust_frame_glyphs_for_window_redisplay
- adjust_decode_mode_spec_buffer
- free_glyphs
- free_window_matrices
- check_glyph_memory
- build_frame_matrix
- build_frame_matrix_from_window_tree
- build_frame_matrix_from_leaf_window
- spec_glyph_lookup_face
- fill_up_glyph_row_with_spaces
- fill_up_glyph_row_area_with_spaces
- fill_up_frame_row_with_spaces
- set_frame_matrix_frame
- make_current
- mirror_make_current
- mirrored_line_dance
- sync_window_with_frame_matrix_rows
- frame_row_to_window
- mirror_line_dance
- check_window_matrix_pointers
- check_matrix_pointers
- window_to_frame_vpos
- window_to_frame_hpos
- redraw_frame
- DEFUN
- DEFUN
- update_frame
- update_frame_with_menu
- update_mouse_position
- update_window_tree
- update_single_window
- redraw_overlapped_rows
- redraw_overlapping_rows
- check_current_matrix_flags
- update_window
- gui_update_window_begin
- gui_update_window_end
- update_marginal_area
- update_text_area
- update_window_line
- set_window_cursor_after_update
- set_window_update_flags
- add_row_entry
- scrolling_window
- update_frame_1
- scrolling
- count_blanks
- count_match
- update_frame_line
- buffer_posn_from_coords
- mode_line_string
- marginal_area_string
- handle_window_change_signal
- deliver_window_change_signal
- do_pending_window_change
- change_frame_size_1
- change_frame_size
- DEFUN
- DEFUN
- bitch_at_user
- sit_for
- DEFUN
- DEFUN
- init_faces_initial
- init_display_interactive
- init_display
- DEFUN
- syms_of_display
- syms_of_display_for_pdumper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23 #include "sysstdio.h"
24 #include <stdlib.h>
25 #include <unistd.h>
26
27 #include "lisp.h"
28 #include "termchar.h"
29
30 #include "dispextern.h"
31 #include "cm.h"
32 #include "buffer.h"
33 #include "keyboard.h"
34 #include "frame.h"
35 #include "termhooks.h"
36 #include "window.h"
37 #include "commands.h"
38 #include "disptab.h"
39 #include "blockinput.h"
40 #include "syssignal.h"
41 #include "systime.h"
42 #include "tparam.h"
43 #include "xwidget.h"
44 #include "pdumper.h"
45
46 #ifdef HAVE_WINDOW_SYSTEM
47 #include TERM_HEADER
48 #endif
49
50 #include <errno.h>
51
52 #include <fpending.h>
53
54 #ifdef WINDOWSNT
55 #include "w32.h"
56 #endif
57
58
59
60
61 struct dim
62 {
63 int width;
64 int height;
65 };
66
67
68
69
70 static void update_frame_line (struct frame *, int, bool);
71 static int required_matrix_height (struct window *);
72 static int required_matrix_width (struct window *);
73 static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
74 static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
75 struct window *);
76 static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
77 struct window *);
78 static void adjust_decode_mode_spec_buffer (struct frame *);
79 static void fill_up_glyph_row_with_spaces (struct glyph_row *);
80 static void clear_window_matrices (struct window *, bool);
81 static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int);
82 static int scrolling_window (struct window *, int);
83 static bool update_window_line (struct window *, int, bool *);
84 static void mirror_make_current (struct window *, int);
85 #ifdef GLYPH_DEBUG
86 static void check_matrix_pointers (struct glyph_matrix *,
87 struct glyph_matrix *);
88 #endif
89 static void mirror_line_dance (struct window *, int, int, int *, char *);
90 static bool update_window_tree (struct window *, bool);
91 static bool update_window (struct window *, bool);
92 static bool update_frame_1 (struct frame *, bool, bool, bool, bool);
93 static bool scrolling (struct frame *);
94 static void set_window_cursor_after_update (struct window *);
95 static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
96 static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
97 static void set_window_update_flags (struct window *w, bool on_p);
98
99
100
101 bool display_completed;
102
103
104
105 static bool delayed_size_change;
106
107
108
109 struct glyph space_glyph;
110
111 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
112
113
114
115
116 static int glyph_matrix_count;
117 static int glyph_pool_count;
118
119 #endif
120
121
122
123
124 static struct frame *frame_matrix_frame;
125
126
127
128
129 #ifdef GLYPH_DEBUG
130
131 static int window_to_frame_vpos (struct window *, int);
132 static int window_to_frame_hpos (struct window *, int);
133 #define WINDOW_TO_FRAME_VPOS(W, VPOS) window_to_frame_vpos ((W), (VPOS))
134 #define WINDOW_TO_FRAME_HPOS(W, HPOS) window_to_frame_hpos ((W), (HPOS))
135
136
137
138
139 struct redisplay_history
140 {
141 char trace[512 + 100];
142 };
143
144
145
146 #define REDISPLAY_HISTORY_SIZE 30
147
148
149
150 static struct redisplay_history redisplay_history[REDISPLAY_HISTORY_SIZE];
151
152
153
154 static int history_idx;
155
156
157
158
159 static uintmax_t history_tick;
160
161
162
163
164
165
166 static void
167 add_window_display_history (struct window *w, const char *msg, bool paused_p)
168 {
169 char *buf;
170 void *ptr = w;
171
172 if (history_idx >= REDISPLAY_HISTORY_SIZE)
173 history_idx = 0;
174 buf = redisplay_history[history_idx].trace;
175 ++history_idx;
176
177 snprintf (buf, sizeof redisplay_history[0].trace,
178 "%"PRIuMAX": window %p (%s)%s\n%s",
179 history_tick++,
180 ptr,
181 ((BUFFERP (w->contents)
182 && STRINGP (BVAR (XBUFFER (w->contents), name)))
183 ? SSDATA (BVAR (XBUFFER (w->contents), name))
184 : "???"),
185 paused_p ? " ***paused***" : "",
186 msg);
187 }
188
189
190
191
192
193
194 static void
195 add_frame_display_history (struct frame *f, bool paused_p)
196 {
197 char *buf;
198 void *ptr = f;
199
200 if (history_idx >= REDISPLAY_HISTORY_SIZE)
201 history_idx = 0;
202 buf = redisplay_history[history_idx].trace;
203 ++history_idx;
204
205 sprintf (buf, "%"PRIuMAX": update frame %p%s",
206 history_tick++,
207 ptr, paused_p ? " ***paused***" : "");
208 }
209
210
211 DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
212 Sdump_redisplay_history, 0, 0, "",
213 doc: )
214 (void)
215 {
216 int i;
217
218 for (i = history_idx - 1; i != history_idx; --i)
219 {
220 if (i < 0)
221 i = REDISPLAY_HISTORY_SIZE - 1;
222 fprintf (stderr, "%s\n", redisplay_history[i].trace);
223 }
224
225 return Qnil;
226 }
227
228
229 #else
230
231 #define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + WINDOW_TOP_EDGE_LINE (W))
232 #define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + WINDOW_LEFT_EDGE_COL (W))
233
234 #endif
235
236
237 #if defined PROFILING && !HAVE___EXECUTABLE_START
238
239
240 void
241 __executable_start (void)
242 {
243 emacs_abort ();
244 }
245 #endif
246
247
248
249
250
251
252
253
254
255
256
257 static struct glyph_matrix *
258 new_glyph_matrix (struct glyph_pool *pool)
259 {
260 struct glyph_matrix *result = xzalloc (sizeof *result);
261
262 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
263
264
265 ++glyph_matrix_count;
266 #endif
267
268
269 result->pool = pool;
270 return result;
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285 static void
286 free_glyph_matrix (struct glyph_matrix *matrix)
287 {
288 if (matrix)
289 {
290 int i;
291
292 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
293
294
295 --glyph_matrix_count;
296 eassert (glyph_matrix_count >= 0);
297 #endif
298
299
300 if (matrix->pool == NULL)
301 for (i = 0; i < matrix->rows_allocated; ++i)
302 xfree (matrix->rows[i].glyphs[LEFT_MARGIN_AREA]);
303
304
305 xfree (matrix->rows);
306 xfree (matrix);
307 }
308 }
309
310
311
312
313
314
315
316 static int
317 margin_glyphs_to_reserve (struct window *w, int total_glyphs, int margin)
318 {
319 if (margin > 0)
320 {
321 int width = w->total_cols;
322 double d = max (0, margin);
323 d = min (width / 2 - 1, d);
324
325
326 return max (1, (int) ((double) total_glyphs / width * d));
327 }
328 return 0;
329 }
330
331
332
333
334 static bool
335 verify_row_hash (struct glyph_row *row)
336 {
337 return row->hash == row_hash (row);
338 }
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362 static void
363 adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y, struct dim dim)
364 {
365 int i;
366 int new_rows;
367 bool marginal_areas_changed_p = 0;
368 bool tab_line_changed_p = 0;
369 bool tab_line_p = 0;
370 bool header_line_changed_p = 0;
371 bool header_line_p = 0;
372 int left = -1, right = -1;
373 int window_width = -1, window_height = -1;
374
375
376
377 if (w)
378 {
379 window_box (w, ANY_AREA, 0, 0, &window_width, &window_height);
380
381 tab_line_p = window_wants_tab_line (w);
382 tab_line_changed_p = tab_line_p != matrix->tab_line_p;
383
384 header_line_p = window_wants_header_line (w);
385 header_line_changed_p = header_line_p != matrix->header_line_p;
386 }
387 matrix->tab_line_p = tab_line_p;
388 matrix->header_line_p = header_line_p;
389
390
391
392
393
394 eassume (w != NULL || matrix->pool != NULL);
395 if (matrix->pool == NULL)
396 {
397 left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_cols);
398 right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_cols);
399 eassert (left >= 0 && right >= 0);
400 marginal_areas_changed_p = (left != matrix->left_margin_glyphs
401 || right != matrix->right_margin_glyphs);
402
403 if (!marginal_areas_changed_p
404 && !XFRAME (w->frame)->fonts_changed
405 && !tab_line_changed_p
406 && !header_line_changed_p
407 && matrix->window_pixel_left == WINDOW_LEFT_PIXEL_EDGE (w)
408 && matrix->window_pixel_top == WINDOW_TOP_PIXEL_EDGE (w)
409 && matrix->window_height == window_height
410 && matrix->window_vscroll == w->vscroll
411 && matrix->window_width == window_width)
412 return;
413 }
414
415
416 if (matrix->rows_allocated < dim.height)
417 {
418 int old_alloc = matrix->rows_allocated;
419 new_rows = dim.height - matrix->rows_allocated;
420 matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
421 new_rows, INT_MAX, sizeof *matrix->rows);
422 memset (matrix->rows + old_alloc, 0,
423 (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows);
424 }
425 else
426 new_rows = 0;
427
428
429
430
431 if (matrix->pool)
432 {
433 eassert (matrix->pool->glyphs);
434
435 if (w)
436 {
437 left = margin_glyphs_to_reserve (w, dim.width,
438 w->left_margin_cols);
439 right = margin_glyphs_to_reserve (w, dim.width,
440 w->right_margin_cols);
441 }
442 else
443 left = right = 0;
444
445 for (i = 0; i < dim.height; ++i)
446 {
447 struct glyph_row *row = &matrix->rows[i];
448
449 row->glyphs[LEFT_MARGIN_AREA]
450 = (matrix->pool->glyphs
451 + (y + i) * matrix->pool->ncolumns
452 + x);
453
454 if (w == NULL
455 || (row == matrix->rows + dim.height - 1
456 && window_wants_mode_line (w))
457 || (row == matrix->rows && matrix->tab_line_p)
458 || (row == matrix->rows
459 && !matrix->tab_line_p && matrix->header_line_p)
460 || (row == (matrix->rows + 1)
461 && matrix->tab_line_p && matrix->header_line_p))
462 {
463 row->glyphs[TEXT_AREA]
464 = row->glyphs[LEFT_MARGIN_AREA];
465 row->glyphs[RIGHT_MARGIN_AREA]
466 = row->glyphs[TEXT_AREA] + dim.width;
467 row->glyphs[LAST_AREA]
468 = row->glyphs[RIGHT_MARGIN_AREA];
469 }
470 else
471 {
472 row->glyphs[TEXT_AREA]
473 = row->glyphs[LEFT_MARGIN_AREA] + left;
474 row->glyphs[RIGHT_MARGIN_AREA]
475 = row->glyphs[TEXT_AREA] + dim.width - left - right;
476
477 if (!FRAME_WINDOW_P (XFRAME (w->frame))
478 && !WINDOW_RIGHTMOST_P (w)
479 && right > 0)
480 row->glyphs[RIGHT_MARGIN_AREA] -= 1;
481 row->glyphs[LAST_AREA]
482 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
483 }
484 }
485
486 matrix->left_margin_glyphs = left;
487 matrix->right_margin_glyphs = right;
488 }
489 else
490 {
491
492
493
494 if (dim.width > matrix->matrix_w
495 || new_rows
496 || tab_line_changed_p
497 || header_line_changed_p
498 || marginal_areas_changed_p)
499 {
500 struct glyph_row *row = matrix->rows;
501 struct glyph_row *end = row + matrix->rows_allocated;
502
503 while (row < end)
504 {
505 row->glyphs[LEFT_MARGIN_AREA]
506 = xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
507 dim.width, sizeof (struct glyph));
508
509
510 if ((row == matrix->rows + dim.height - 1
511 && !(w && window_wants_mode_line (w)))
512 || (row == matrix->rows && matrix->tab_line_p)
513 || (row == matrix->rows
514 && !matrix->tab_line_p && matrix->header_line_p)
515 || (row == (matrix->rows + 1)
516 && matrix->tab_line_p && matrix->header_line_p))
517 {
518 row->glyphs[TEXT_AREA]
519 = row->glyphs[LEFT_MARGIN_AREA];
520 row->glyphs[RIGHT_MARGIN_AREA]
521 = row->glyphs[TEXT_AREA] + dim.width;
522 row->glyphs[LAST_AREA]
523 = row->glyphs[RIGHT_MARGIN_AREA];
524 }
525 else
526 {
527 row->glyphs[TEXT_AREA]
528 = row->glyphs[LEFT_MARGIN_AREA] + left;
529 row->glyphs[RIGHT_MARGIN_AREA]
530 = row->glyphs[TEXT_AREA] + dim.width - left - right;
531 row->glyphs[LAST_AREA]
532 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
533 }
534 ++row;
535 }
536 }
537
538 eassert (left >= 0 && right >= 0);
539 matrix->left_margin_glyphs = left;
540 matrix->right_margin_glyphs = right;
541
542
543
544 if (w && matrix == w->current_matrix
545 && matrix->nrows > 0
546 && dim.height != matrix->nrows
547 && matrix->nrows <= matrix->rows_allocated)
548 MATRIX_MODE_LINE_ROW (matrix)->mode_line_p = false;
549 }
550
551
552 matrix->nrows = dim.height;
553 eassert (matrix->nrows >= 0);
554
555 if (w)
556 {
557 if (matrix == w->current_matrix)
558 {
559
560
561
562
563 if (window_width < 0)
564 window_width = window_box_width (w, -1);
565
566
567
568
569 if (!marginal_areas_changed_p
570 && !tab_line_changed_p
571 && !header_line_changed_p
572 && new_rows == 0
573 && dim.width == matrix->matrix_w
574 && matrix->window_pixel_left == WINDOW_LEFT_PIXEL_EDGE (w)
575 && matrix->window_pixel_top == WINDOW_TOP_PIXEL_EDGE (w)
576 && matrix->window_width == window_width)
577 {
578
579 for (i = 0; i < matrix->nrows && matrix->rows[i].enabled_p; ++i)
580 if (MATRIX_ROW_BOTTOM_Y (matrix->rows + i) >= window_height)
581 {
582 ++i;
583 break;
584 }
585
586
587
588 if (w->window_end_vpos >= i)
589 w->window_end_valid = 0;
590
591 while (i < matrix->nrows)
592 matrix->rows[i++].enabled_p = false;
593 }
594 else
595 {
596 for (i = 0; i < matrix->nrows; ++i)
597 matrix->rows[i].enabled_p = false;
598 }
599
600
601
602
603 if (window_wants_mode_line (w))
604 w->update_mode_line = 1;
605 }
606 else if (matrix == w->desired_matrix)
607 {
608
609
610
611
612 for (i = 0; i < matrix->nrows; ++i)
613 matrix->rows[i].enabled_p = false;
614 }
615 }
616
617
618
619 matrix->matrix_x = x;
620 matrix->matrix_y = y;
621 matrix->matrix_w = dim.width;
622 matrix->matrix_h = dim.height;
623
624
625
626 if (w)
627 {
628 matrix->window_pixel_left = WINDOW_LEFT_PIXEL_EDGE (w);
629 matrix->window_pixel_top = WINDOW_TOP_PIXEL_EDGE (w);
630 matrix->window_height = window_height;
631 matrix->window_width = window_width;
632 matrix->window_vscroll = w->vscroll;
633 }
634 }
635
636
637
638
639
640
641
642 static void
643 reverse_rows (struct glyph_matrix *matrix, int start, int end)
644 {
645 int i, j;
646
647 for (i = start, j = end - 1; i < j; ++i, --j)
648 {
649
650
651 struct glyph_row temp;
652 temp = matrix->rows[i];
653 matrix->rows[i] = matrix->rows[j];
654 matrix->rows[j] = temp;
655 }
656 }
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671 void
672 rotate_matrix (struct glyph_matrix *matrix, int first, int last, int by)
673 {
674 if (by < 0)
675 {
676
677 by = -by;
678 reverse_rows (matrix, first, first + by);
679 reverse_rows (matrix, first + by, last);
680 reverse_rows (matrix, first, last);
681 }
682 else if (by > 0)
683 {
684
685 reverse_rows (matrix, last - by, last);
686 reverse_rows (matrix, first, last - by);
687 reverse_rows (matrix, first, last);
688 }
689 }
690
691
692
693
694
695
696 void
697 increment_matrix_positions (struct glyph_matrix *matrix, int start, int end,
698 ptrdiff_t delta, ptrdiff_t delta_bytes)
699 {
700
701 eassert (start >= 0 && start <= matrix->nrows);
702 eassert (end >= 0 && end <= matrix->nrows);
703 eassert (start <= end);
704
705 for (; start < end; ++start)
706 increment_row_positions (matrix->rows + start, delta, delta_bytes);
707 }
708
709
710
711
712
713 void
714 clear_glyph_matrix_rows (struct glyph_matrix *matrix, int start, int end)
715 {
716 eassert (start <= end);
717 eassert (start >= 0 && (start < matrix->nrows
718
719 || (matrix->nrows == 0)));
720 eassert (end >= 0 && end <= matrix->nrows);
721
722 for (; start < end; ++start)
723 matrix->rows[start].enabled_p = false;
724 }
725
726
727
728
729
730
731
732
733
734
735
736 void
737 clear_glyph_matrix (struct glyph_matrix *matrix)
738 {
739 if (matrix)
740 {
741 clear_glyph_matrix_rows (matrix, 0, matrix->nrows);
742 matrix->no_scrolling_p = 0;
743 }
744 }
745
746
747
748
749
750
751 void
752 shift_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int start, int end, int dy)
753 {
754 int min_y, max_y;
755
756 eassert (start <= end);
757 eassert (start >= 0 && start < matrix->nrows);
758 eassert (end >= 0 && end <= matrix->nrows);
759
760 min_y = WINDOW_TAB_LINE_HEIGHT (w) + WINDOW_HEADER_LINE_HEIGHT (w);
761 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
762
763 for (; start < end; ++start)
764 {
765 struct glyph_row *row = &matrix->rows[start];
766
767 row->y += dy;
768 row->visible_height = row->height;
769
770 if (row->y < min_y)
771 row->visible_height -= min_y - row->y;
772 if (row->y + row->height > max_y)
773 row->visible_height -= row->y + row->height - max_y;
774 if (row->fringe_bitmap_periodic_p)
775 row->redraw_fringe_bitmaps_p = 1;
776 }
777 }
778
779
780
781
782
783
784 void
785 clear_current_matrices (register struct frame *f)
786 {
787
788 if (f->current_matrix)
789 clear_glyph_matrix (f->current_matrix);
790
791 #if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
792
793
794
795 if (WINDOWP (f->menu_bar_window))
796 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
797 #endif
798
799 #if defined (HAVE_WINDOW_SYSTEM)
800
801 if (WINDOWP (f->tab_bar_window))
802 clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
803 #endif
804
805 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
806
807 if (WINDOWP (f->tool_bar_window))
808 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
809 #endif
810
811
812 eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
813 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 0);
814 }
815
816
817
818
819 void
820 clear_desired_matrices (register struct frame *f)
821 {
822 if (f->desired_matrix)
823 clear_glyph_matrix (f->desired_matrix);
824
825 #if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
826 if (WINDOWP (f->menu_bar_window))
827 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
828 #endif
829
830 #if defined (HAVE_WINDOW_SYSTEM)
831 if (WINDOWP (f->tab_bar_window))
832 clear_glyph_matrix (XWINDOW (f->tab_bar_window)->desired_matrix);
833 #endif
834
835 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
836 if (WINDOWP (f->tool_bar_window))
837 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
838 #endif
839
840
841 eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
842 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
843 }
844
845
846
847
848
849 static void
850 clear_window_matrices (struct window *w, bool desired_p)
851 {
852 while (w)
853 {
854 if (WINDOWP (w->contents))
855 clear_window_matrices (XWINDOW (w->contents), desired_p);
856 else
857 {
858 if (desired_p)
859 clear_glyph_matrix (w->desired_matrix);
860 else
861 {
862 clear_glyph_matrix (w->current_matrix);
863 w->window_end_valid = 0;
864 }
865 }
866
867 w = NILP (w->next) ? 0 : XWINDOW (w->next);
868 }
869 }
870
871
872
873
874
875
876
877
878
879
880
881
882 void
883 clear_glyph_row (struct glyph_row *row)
884 {
885 enum { off = offsetof (struct glyph_row, used) };
886
887
888 memset ((char *) row + off, 0, sizeof *row - off);
889 }
890
891
892
893
894
895 void
896 blank_row (struct window *w, struct glyph_row *row, int y)
897 {
898 int min_y, max_y;
899
900 min_y = WINDOW_TAB_LINE_HEIGHT (w) + WINDOW_HEADER_LINE_HEIGHT (w);
901 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
902
903 clear_glyph_row (row);
904 row->y = y;
905 row->ascent = row->phys_ascent = 0;
906 row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (w->frame));
907 row->visible_height = row->height;
908
909 if (row->y < min_y)
910 row->visible_height -= min_y - row->y;
911 if (row->y + row->height > max_y)
912 row->visible_height -= row->y + row->height - max_y;
913
914 row->enabled_p = true;
915 }
916
917
918
919
920
921
922
923
924 static void
925 increment_row_positions (struct glyph_row *row,
926 ptrdiff_t delta, ptrdiff_t delta_bytes)
927 {
928 int area, i;
929
930
931 MATRIX_ROW_START_CHARPOS (row) += delta;
932 MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
933 MATRIX_ROW_END_CHARPOS (row) += delta;
934 MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
935 CHARPOS (row->start.pos) += delta;
936 BYTEPOS (row->start.pos) += delta_bytes;
937 CHARPOS (row->end.pos) += delta;
938 BYTEPOS (row->end.pos) += delta_bytes;
939
940 if (!row->enabled_p)
941 return;
942
943
944 for (area = 0; area < LAST_AREA; ++area)
945 for (i = 0; i < row->used[area]; ++i)
946 if (BUFFERP (row->glyphs[area][i].object)
947 && row->glyphs[area][i].charpos > 0)
948 row->glyphs[area][i].charpos += delta;
949
950
951 if (row->used[TEXT_AREA] == 0
952 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
953 row->glyphs[TEXT_AREA]->charpos += delta;
954 }
955
956
957 #if 0
958
959
960
961
962 static void
963 swap_glyphs_in_rows (struct glyph_row *a, struct glyph_row *b)
964 {
965 int area;
966
967 for (area = 0; area < LAST_AREA; ++area)
968 {
969
970 int max_used = max (a->used[area], b->used[area]);
971
972
973 struct glyph *glyph_a = a->glyphs[area];
974
975
976 struct glyph *glyph_a_end = a->glyphs[max_used];
977
978
979 struct glyph *glyph_b = b->glyphs[area];
980
981 while (glyph_a < glyph_a_end)
982 {
983
984
985 struct glyph temp;
986 temp = *glyph_a;
987 *glyph_a = *glyph_b;
988 *glyph_b = temp;
989 ++glyph_a;
990 ++glyph_b;
991 }
992 }
993 }
994
995 #endif
996
997
998
999
1000
1001
1002 static void
1003 swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
1004 {
1005 int i;
1006 unsigned hash_tem = a->hash;
1007
1008 for (i = 0; i < LAST_AREA + 1; ++i)
1009 {
1010 struct glyph *temp = a->glyphs[i];
1011
1012 a->glyphs[i] = b->glyphs[i];
1013 b->glyphs[i] = temp;
1014 if (i < LAST_AREA)
1015 {
1016 short used_tem = a->used[i];
1017
1018 a->used[i] = b->used[i];
1019 b->used[i] = used_tem;
1020 }
1021 }
1022 a->hash = b->hash;
1023 b->hash = hash_tem;
1024 }
1025
1026
1027
1028
1029
1030
1031
1032 static void
1033 copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
1034 {
1035 enum { off = offsetof (struct glyph_row, x) };
1036
1037 memcpy ((char *) to + off, (char *) from + off, sizeof *to - off);
1038 }
1039
1040
1041
1042
1043
1044
1045
1046 static void
1047 assign_row (struct glyph_row *to, struct glyph_row *from)
1048 {
1049 swap_glyph_pointers (to, from);
1050 copy_row_except_pointers (to, from);
1051 }
1052
1053
1054
1055
1056
1057
1058
1059
1060 #ifdef GLYPH_DEBUG
1061
1062 static bool
1063 glyph_row_slice_p (struct glyph_row *window_row, struct glyph_row *frame_row)
1064 {
1065 struct glyph *window_glyph_start = window_row->glyphs[0];
1066 struct glyph *frame_glyph_start = frame_row->glyphs[0];
1067 struct glyph *frame_glyph_end = frame_row->glyphs[LAST_AREA];
1068
1069 return (frame_glyph_start <= window_glyph_start
1070 && window_glyph_start < frame_glyph_end);
1071 }
1072
1073 #endif
1074
1075 #if 0
1076
1077
1078
1079
1080
1081 static struct glyph_row *
1082 find_glyph_row_slice (struct glyph_matrix *window_matrix,
1083 struct glyph_matrix *frame_matrix, int row)
1084 {
1085 int i;
1086
1087 eassert (row >= 0 && row < frame_matrix->nrows);
1088
1089 for (i = 0; i < window_matrix->nrows; ++i)
1090 if (glyph_row_slice_p (window_matrix->rows + i,
1091 frame_matrix->rows + row))
1092 break;
1093
1094 return i < window_matrix->nrows ? window_matrix->rows + i : 0;
1095 }
1096
1097 #endif
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107 void
1108 prepare_desired_row (struct window *w, struct glyph_row *row, bool mode_line_p)
1109 {
1110 if (!row->enabled_p)
1111 {
1112 bool rp = row->reversed_p;
1113
1114 clear_glyph_row (row);
1115 row->enabled_p = true;
1116 row->reversed_p = rp;
1117 }
1118 if (mode_line_p)
1119 {
1120
1121
1122
1123
1124
1125
1126 if (w->left_margin_cols > 0)
1127 row->glyphs[TEXT_AREA] = row->glyphs[LEFT_MARGIN_AREA];
1128 if (w->right_margin_cols > 0)
1129 row->glyphs[RIGHT_MARGIN_AREA] = row->glyphs[LAST_AREA];
1130 }
1131 else
1132 {
1133
1134
1135
1136
1137 int left = w->desired_matrix->left_margin_glyphs;
1138 int right = w->desired_matrix->right_margin_glyphs;
1139
1140
1141
1142
1143 if (w->left_margin_cols > 0
1144 && (left != row->glyphs[TEXT_AREA] - row->glyphs[LEFT_MARGIN_AREA]))
1145 row->glyphs[TEXT_AREA] = row->glyphs[LEFT_MARGIN_AREA] + left;
1146 if (w->right_margin_cols > 0
1147 && (right != row->glyphs[LAST_AREA] - row->glyphs[RIGHT_MARGIN_AREA]))
1148 {
1149 row->glyphs[RIGHT_MARGIN_AREA] = row->glyphs[LAST_AREA] - right;
1150
1151 if (!FRAME_WINDOW_P (XFRAME (w->frame))
1152 && !WINDOW_RIGHTMOST_P (w)
1153 && right > 0)
1154 row->glyphs[RIGHT_MARGIN_AREA] -= 1;
1155 }
1156 }
1157 }
1158
1159
1160
1161
1162
1163 static unsigned
1164 line_hash_code (struct frame *f, struct glyph_row *row)
1165 {
1166 unsigned hash = 0;
1167
1168 if (row->enabled_p)
1169 {
1170 struct glyph *glyph = row->glyphs[TEXT_AREA];
1171 struct glyph *end = glyph + row->used[TEXT_AREA];
1172
1173 while (glyph < end)
1174 {
1175 int c = glyph->u.ch;
1176 int face_id = glyph->face_id;
1177 if (FRAME_MUST_WRITE_SPACES (f))
1178 c -= SPACEGLYPH;
1179 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
1180 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
1181 ++glyph;
1182 }
1183
1184 if (hash == 0)
1185 hash = 1;
1186 }
1187
1188 return hash;
1189 }
1190
1191
1192
1193
1194
1195
1196
1197 static int
1198 line_draw_cost (struct frame *f, struct glyph_matrix *matrix, int vpos)
1199 {
1200 struct glyph_row *row = matrix->rows + vpos;
1201 struct glyph *beg = row->glyphs[TEXT_AREA];
1202 struct glyph *end = beg + row->used[TEXT_AREA];
1203 int len;
1204 Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
1205 ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH;
1206
1207
1208 if (!FRAME_MUST_WRITE_SPACES (f))
1209 {
1210
1211 while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1)))
1212 --end;
1213
1214
1215 if (end == beg)
1216 return 0;
1217
1218
1219 while (CHAR_GLYPH_SPACE_P (*beg))
1220 ++beg;
1221 }
1222
1223
1224
1225 if (glyph_table_base == 0)
1226 len = end - beg;
1227 else
1228 {
1229
1230
1231 len = 0;
1232 while (beg < end)
1233 {
1234 GLYPH g;
1235
1236 SET_GLYPH_FROM_CHAR_GLYPH (g, *beg);
1237
1238 if (GLYPH_INVALID_P (g)
1239 || GLYPH_SIMPLE_P (glyph_table_base, glyph_table_len, g))
1240 len += 1;
1241 else
1242 len += GLYPH_LENGTH (glyph_table_base, g);
1243
1244 ++beg;
1245 }
1246 }
1247
1248 return len;
1249 }
1250
1251
1252
1253
1254
1255 static bool
1256 row_equal_p (struct glyph_row *a, struct glyph_row *b, bool mouse_face_p)
1257 {
1258 eassert (verify_row_hash (a));
1259 eassert (verify_row_hash (b));
1260
1261 if (a == b)
1262 return 1;
1263 else if (a->hash != b->hash)
1264 return 0;
1265 else
1266 {
1267 struct glyph *a_glyph, *b_glyph, *a_end;
1268 int area;
1269
1270 if (mouse_face_p && a->mouse_face_p != b->mouse_face_p)
1271 return 0;
1272
1273
1274 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
1275 {
1276 if (a->used[area] != b->used[area])
1277 return 0;
1278
1279 a_glyph = a->glyphs[area];
1280 a_end = a_glyph + a->used[area];
1281 b_glyph = b->glyphs[area];
1282
1283 while (a_glyph < a_end
1284 && GLYPH_EQUAL_P (a_glyph, b_glyph))
1285 ++a_glyph, ++b_glyph;
1286
1287 if (a_glyph != a_end)
1288 return 0;
1289 }
1290
1291 if (a->fill_line_p != b->fill_line_p
1292 || a->cursor_in_fringe_p != b->cursor_in_fringe_p
1293 || a->left_fringe_bitmap != b->left_fringe_bitmap
1294 || a->left_fringe_face_id != b->left_fringe_face_id
1295 || a->left_fringe_offset != b->left_fringe_offset
1296 || a->right_fringe_bitmap != b->right_fringe_bitmap
1297 || a->right_fringe_face_id != b->right_fringe_face_id
1298 || a->right_fringe_offset != b->right_fringe_offset
1299 || a->fringe_bitmap_periodic_p != b->fringe_bitmap_periodic_p
1300 || a->overlay_arrow_bitmap != b->overlay_arrow_bitmap
1301 || a->exact_window_width_line_p != b->exact_window_width_line_p
1302 || a->overlapped_p != b->overlapped_p
1303 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
1304 != MATRIX_ROW_CONTINUATION_LINE_P (b))
1305 || a->reversed_p != b->reversed_p
1306
1307 || a->x != b->x
1308
1309 || a->ascent != b->ascent
1310 || a->phys_ascent != b->phys_ascent
1311 || a->phys_height != b->phys_height
1312 || a->visible_height != b->visible_height)
1313 return 0;
1314 }
1315
1316 return 1;
1317 }
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 static struct glyph_pool * ATTRIBUTE_MALLOC
1332 new_glyph_pool (void)
1333 {
1334 struct glyph_pool *result = xzalloc (sizeof *result);
1335
1336 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
1337
1338 ++glyph_pool_count;
1339 #endif
1340
1341 return result;
1342 }
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352 static void
1353 free_glyph_pool (struct glyph_pool *pool)
1354 {
1355 if (pool)
1356 {
1357 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
1358
1359 --glyph_pool_count;
1360 eassert (glyph_pool_count >= 0);
1361 #endif
1362 xfree (pool->glyphs);
1363 xfree (pool);
1364 }
1365 }
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377 static bool
1378 realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
1379 {
1380 ptrdiff_t needed;
1381 bool changed_p;
1382
1383 changed_p = (pool->glyphs == 0
1384 || matrix_dim.height != pool->nrows
1385 || matrix_dim.width != pool->ncolumns);
1386
1387
1388 if (INT_MULTIPLY_WRAPV (matrix_dim.height, matrix_dim.width, &needed))
1389 memory_full (SIZE_MAX);
1390 if (needed > pool->nglyphs)
1391 {
1392 ptrdiff_t old_nglyphs = pool->nglyphs;
1393 pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs,
1394 needed - old_nglyphs, -1, sizeof *pool->glyphs);
1395 memclear (pool->glyphs + old_nglyphs,
1396 (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
1397 }
1398
1399
1400
1401
1402
1403 pool->nrows = matrix_dim.height;
1404 pool->ncolumns = matrix_dim.width;
1405
1406 return changed_p;
1407 }
1408
1409
1410
1411
1412
1413
1414
1415 #ifdef GLYPH_DEBUG
1416
1417
1418
1419
1420
1421
1422
1423 void flush_stdout (void) EXTERNALLY_VISIBLE;
1424
1425 void
1426 flush_stdout (void)
1427 {
1428 fflush (stdout);
1429 }
1430
1431
1432
1433
1434
1435
1436
1437 void
1438 check_matrix_pointer_lossage (struct glyph_matrix *matrix)
1439 {
1440 int i, j;
1441
1442 for (i = 0; i < matrix->nrows; ++i)
1443 for (j = 0; j < matrix->nrows; ++j)
1444 eassert (i == j
1445 || (matrix->rows[i].glyphs[TEXT_AREA]
1446 != matrix->rows[j].glyphs[TEXT_AREA]));
1447 }
1448
1449
1450
1451
1452 struct glyph_row *
1453 matrix_row (struct glyph_matrix *matrix, int row)
1454 {
1455 eassert (matrix && matrix->rows);
1456 eassert (row >= 0 && row < matrix->nrows);
1457
1458
1459
1460
1461 #if 0
1462 check_matrix_pointer_lossage (matrix);
1463 #endif
1464
1465 return matrix->rows + row;
1466 }
1467
1468
1469 #if 0
1470
1471
1472
1473
1474
1475
1476 static void
1477 check_matrix_invariants (struct window *w)
1478 {
1479 struct glyph_matrix *matrix = w->current_matrix;
1480 int yb = window_text_bottom_y (w);
1481 struct glyph_row *row = matrix->rows;
1482 struct glyph_row *last_text_row = NULL;
1483 struct buffer *saved = current_buffer;
1484 struct buffer *buffer = XBUFFER (w->contents);
1485 int c;
1486
1487
1488 if (matrix->nrows < 2)
1489 return;
1490
1491 set_buffer_temp (buffer);
1492
1493
1494 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
1495 && MATRIX_ROW_BOTTOM_Y (row) < yb)
1496 {
1497 struct glyph_row *next = row + 1;
1498
1499 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
1500 last_text_row = row;
1501
1502
1503 eassert (MATRIX_ROW_START_BYTEPOS (row)
1504 == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
1505 eassert (BYTEPOS (row->start.pos)
1506 == CHAR_TO_BYTE (CHARPOS (row->start.pos)));
1507
1508
1509
1510
1511 if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
1512 {
1513 eassert (MATRIX_ROW_END_BYTEPOS (row)
1514 == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
1515 eassert (BYTEPOS (row->end.pos)
1516 == CHAR_TO_BYTE (CHARPOS (row->end.pos)));
1517 }
1518
1519
1520
1521 if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next))
1522 {
1523 eassert (MATRIX_ROW_END_CHARPOS (row)
1524 == MATRIX_ROW_START_CHARPOS (next));
1525 eassert (MATRIX_ROW_END_BYTEPOS (row)
1526 == MATRIX_ROW_START_BYTEPOS (next));
1527 eassert (CHARPOS (row->end.pos) == CHARPOS (next->start.pos));
1528 eassert (BYTEPOS (row->end.pos) == BYTEPOS (next->start.pos));
1529 }
1530 row = next;
1531 }
1532
1533 eassert (w->current_matrix->nrows == w->desired_matrix->nrows);
1534 eassert (w->desired_matrix->rows != NULL);
1535 set_buffer_temp (saved);
1536 }
1537
1538 #endif
1539
1540 #endif
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621 #define NEW_LEAF_MATRIX (1 << 0)
1622
1623
1624
1625
1626 #define CHANGED_LEAF_MATRIX (1 << 1)
1627
1628 static struct dim
1629 allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
1630 bool dim_only_p, int *window_change_flags)
1631 {
1632 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1633 int x0 = x, y0 = y;
1634 int wmax = 0, hmax = 0;
1635 struct dim total;
1636 struct dim dim;
1637 struct window *w;
1638 bool in_horz_combination_p;
1639
1640
1641
1642
1643
1644
1645
1646 in_horz_combination_p
1647 = (!NILP (XWINDOW (window)->parent)
1648 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (XWINDOW (window)->parent)));
1649
1650
1651 do
1652 {
1653 w = XWINDOW (window);
1654
1655
1656
1657 if (WINDOWP (w->contents))
1658 dim = allocate_matrices_for_frame_redisplay (w->contents, x, y,
1659 dim_only_p,
1660 window_change_flags);
1661 else
1662 {
1663
1664 if (w->desired_matrix == NULL)
1665 {
1666 w->desired_matrix = new_glyph_matrix (f->desired_pool);
1667 w->current_matrix = new_glyph_matrix (f->current_pool);
1668 *window_change_flags |= NEW_LEAF_MATRIX;
1669 }
1670
1671
1672
1673 dim.width = required_matrix_width (w);
1674 dim.height = required_matrix_height (w);
1675
1676
1677 if (x != w->desired_matrix->matrix_x
1678 || y != w->desired_matrix->matrix_y
1679 || dim.width != w->desired_matrix->matrix_w
1680 || dim.height != w->desired_matrix->matrix_h
1681 || (margin_glyphs_to_reserve (w, dim.width,
1682 w->left_margin_cols)
1683 != w->desired_matrix->left_margin_glyphs)
1684 || (margin_glyphs_to_reserve (w, dim.width,
1685 w->right_margin_cols)
1686 != w->desired_matrix->right_margin_glyphs))
1687 *window_change_flags |= CHANGED_LEAF_MATRIX;
1688
1689
1690
1691
1692
1693
1694 if (!dim_only_p)
1695 {
1696 adjust_glyph_matrix (w, w->desired_matrix, x, y, dim);
1697 adjust_glyph_matrix (w, w->current_matrix, x, y, dim);
1698 }
1699 }
1700
1701
1702
1703
1704 if (in_horz_combination_p)
1705 x += dim.width;
1706 else
1707 y += dim.height;
1708
1709
1710 wmax = max (wmax, dim.width);
1711 hmax = max (hmax, dim.height);
1712
1713
1714 window = w->next;
1715 }
1716 while (!NILP (window));
1717
1718
1719
1720
1721
1722
1723
1724 if (in_horz_combination_p)
1725 {
1726 total.width = x - x0;
1727 total.height = hmax;
1728 }
1729 else
1730 {
1731 total.width = wmax;
1732 total.height = y - y0;
1733 }
1734
1735 return total;
1736 }
1737
1738
1739
1740
1741 static int
1742 required_matrix_height (struct window *w)
1743 {
1744 #ifdef HAVE_WINDOW_SYSTEM
1745 struct frame *f = XFRAME (w->frame);
1746
1747 if (FRAME_WINDOW_P (f))
1748 {
1749
1750 int ch_height = max (FRAME_SMALLEST_FONT_HEIGHT (f), 1);
1751 int window_pixel_height = window_box_height (w) + eabs (w->vscroll);
1752
1753 return (((window_pixel_height + ch_height - 1)
1754 / ch_height) * w->nrows_scale_factor
1755
1756
1757 + 2
1758
1759 + 3);
1760 }
1761 #endif
1762
1763 return WINDOW_TOTAL_LINES (w);
1764 }
1765
1766
1767
1768
1769 static int
1770 required_matrix_width (struct window *w)
1771 {
1772 #ifdef HAVE_WINDOW_SYSTEM
1773 struct frame *f = XFRAME (w->frame);
1774 if (FRAME_WINDOW_P (f))
1775 {
1776
1777 int ch_width = max (FRAME_SMALLEST_CHAR_WIDTH (f), 1);
1778
1779
1780 return (((WINDOW_PIXEL_WIDTH (w) + ch_width - 1)
1781 / ch_width) * w->ncols_scale_factor
1782
1783 + 2
1784
1785
1786 + 1 + 1);
1787 }
1788 #endif
1789
1790 return w->total_cols;
1791 }
1792
1793
1794
1795
1796
1797 static void
1798 allocate_matrices_for_window_redisplay (struct window *w)
1799 {
1800 while (w)
1801 {
1802 if (WINDOWP (w->contents))
1803 allocate_matrices_for_window_redisplay (XWINDOW (w->contents));
1804 else
1805 {
1806
1807 struct dim dim;
1808
1809
1810 if (w->desired_matrix == NULL)
1811 {
1812 w->desired_matrix = new_glyph_matrix (NULL);
1813 eassert (w->current_matrix == NULL);
1814 }
1815
1816 if (w->current_matrix == NULL)
1817 w->current_matrix = new_glyph_matrix (NULL);
1818
1819 dim.width = required_matrix_width (w);
1820 dim.height = required_matrix_height (w);
1821 adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
1822 adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
1823 }
1824
1825 w = NILP (w->next) ? NULL : XWINDOW (w->next);
1826 }
1827 }
1828
1829
1830
1831
1832
1833 void
1834 adjust_frame_glyphs (struct frame *f)
1835 {
1836
1837
1838 block_input ();
1839
1840 if (FRAME_WINDOW_P (f))
1841 adjust_frame_glyphs_for_window_redisplay (f);
1842 else
1843 {
1844 adjust_frame_glyphs_for_frame_redisplay (f);
1845 eassert (FRAME_INITIAL_P (f)
1846 || noninteractive
1847 || !initialized
1848 || (f->current_matrix
1849 && f->current_matrix->nrows > 0
1850 && f->current_matrix->rows
1851 && f->desired_matrix
1852 && f->desired_matrix->nrows > 0
1853 && f->desired_matrix->rows));
1854 }
1855
1856
1857 adjust_decode_mode_spec_buffer (f);
1858
1859 f->glyphs_initialized_p = true;
1860
1861 unblock_input ();
1862 }
1863
1864
1865
1866 static bool
1867 showing_window_margins_p (struct window *w)
1868 {
1869 while (w)
1870 {
1871 if (WINDOWP (w->contents))
1872 {
1873 if (showing_window_margins_p (XWINDOW (w->contents)))
1874 return 1;
1875 }
1876 else if (w->left_margin_cols > 0 || w->right_margin_cols > 0)
1877 return 1;
1878
1879 w = NILP (w->next) ? 0 : XWINDOW (w->next);
1880 }
1881 return 0;
1882 }
1883
1884
1885
1886
1887
1888 static void
1889 fake_current_matrices (Lisp_Object window)
1890 {
1891 struct window *w;
1892
1893 for (; !NILP (window); window = w->next)
1894 {
1895 w = XWINDOW (window);
1896
1897 if (WINDOWP (w->contents))
1898 fake_current_matrices (w->contents);
1899 else
1900 {
1901 int i;
1902 struct frame *f = XFRAME (w->frame);
1903 struct glyph_matrix *m = w->current_matrix;
1904 struct glyph_matrix *fm = f->current_matrix;
1905
1906 eassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
1907 eassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
1908
1909 for (i = 0; i < m->matrix_h; ++i)
1910 {
1911 struct glyph_row *r = m->rows + i;
1912 struct glyph_row *fr = fm->rows + i + WINDOW_TOP_EDGE_LINE (w);
1913
1914 eassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
1915 && r->glyphs[LAST_AREA] <= fr->glyphs[LAST_AREA]);
1916
1917 r->enabled_p = fr->enabled_p;
1918 if (r->enabled_p)
1919 {
1920 r->used[LEFT_MARGIN_AREA] = m->left_margin_glyphs;
1921 r->used[RIGHT_MARGIN_AREA] = m->right_margin_glyphs;
1922 r->used[TEXT_AREA] = (m->matrix_w
1923 - r->used[LEFT_MARGIN_AREA]
1924 - r->used[RIGHT_MARGIN_AREA]);
1925 r->mode_line_p = 0;
1926 r->tab_line_p = 0;
1927 }
1928 }
1929 }
1930 }
1931 }
1932
1933
1934
1935
1936
1937 static struct glyph_matrix *
1938 save_current_matrix (struct frame *f)
1939 {
1940 int i;
1941 struct glyph_matrix *saved = xzalloc (sizeof *saved);
1942 saved->nrows = f->current_matrix->nrows;
1943 saved->rows = xzalloc (saved->nrows * sizeof *saved->rows);
1944
1945 for (i = 0; i < saved->nrows; ++i)
1946 {
1947 struct glyph_row *from = f->current_matrix->rows + i;
1948 struct glyph_row *to = saved->rows + i;
1949 ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
1950
1951 to->glyphs[TEXT_AREA] = xmalloc (nbytes);
1952 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
1953 to->used[TEXT_AREA] = from->used[TEXT_AREA];
1954 to->enabled_p = from->enabled_p;
1955 to->hash = from->hash;
1956 if (from->used[LEFT_MARGIN_AREA])
1957 {
1958 nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
1959 to->glyphs[LEFT_MARGIN_AREA] = xmalloc (nbytes);
1960 memcpy (to->glyphs[LEFT_MARGIN_AREA],
1961 from->glyphs[LEFT_MARGIN_AREA], nbytes);
1962 to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
1963 }
1964 if (from->used[RIGHT_MARGIN_AREA])
1965 {
1966 nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
1967 to->glyphs[RIGHT_MARGIN_AREA] = xmalloc (nbytes);
1968 memcpy (to->glyphs[RIGHT_MARGIN_AREA],
1969 from->glyphs[RIGHT_MARGIN_AREA], nbytes);
1970 to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
1971 }
1972 }
1973
1974 return saved;
1975 }
1976
1977
1978
1979
1980
1981 static void
1982 restore_current_matrix (struct frame *f, struct glyph_matrix *saved)
1983 {
1984 int i;
1985
1986 for (i = 0; i < saved->nrows; ++i)
1987 {
1988 struct glyph_row *from = saved->rows + i;
1989 struct glyph_row *to = f->current_matrix->rows + i;
1990 ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
1991
1992 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
1993 to->used[TEXT_AREA] = from->used[TEXT_AREA];
1994 xfree (from->glyphs[TEXT_AREA]);
1995 nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
1996 if (nbytes)
1997 {
1998 memcpy (to->glyphs[LEFT_MARGIN_AREA],
1999 from->glyphs[LEFT_MARGIN_AREA], nbytes);
2000 to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
2001 xfree (from->glyphs[LEFT_MARGIN_AREA]);
2002 }
2003 else
2004 to->used[LEFT_MARGIN_AREA] = 0;
2005 nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
2006 if (nbytes)
2007 {
2008 memcpy (to->glyphs[RIGHT_MARGIN_AREA],
2009 from->glyphs[RIGHT_MARGIN_AREA], nbytes);
2010 to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
2011 xfree (from->glyphs[RIGHT_MARGIN_AREA]);
2012 }
2013 else
2014 to->used[RIGHT_MARGIN_AREA] = 0;
2015 }
2016
2017 xfree (saved->rows);
2018 xfree (saved);
2019 }
2020
2021
2022
2023
2024
2025
2026 static void
2027 adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
2028 {
2029 struct dim matrix_dim;
2030 bool pool_changed_p;
2031 int window_change_flags;
2032 int top_window_y;
2033
2034 if (!FRAME_LIVE_P (f))
2035 return;
2036
2037 top_window_y = FRAME_TOP_MARGIN (f);
2038
2039
2040 if (f->desired_pool == NULL)
2041 {
2042 f->desired_pool = new_glyph_pool ();
2043 f->current_pool = new_glyph_pool ();
2044 }
2045
2046
2047 if (f->desired_matrix == NULL)
2048 {
2049 f->desired_matrix = new_glyph_matrix (f->desired_pool);
2050 f->current_matrix = new_glyph_matrix (f->current_pool);
2051 }
2052
2053
2054
2055
2056
2057
2058
2059 window_change_flags = 0;
2060 matrix_dim
2061 = allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2062 0, top_window_y,
2063 1,
2064 &window_change_flags);
2065
2066
2067 matrix_dim.height += top_window_y;
2068
2069
2070 pool_changed_p = realloc_glyph_pool (f->desired_pool, matrix_dim);
2071 realloc_glyph_pool (f->current_pool, matrix_dim);
2072
2073
2074
2075 if (pool_changed_p || window_change_flags)
2076 {
2077
2078 allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2079 0, top_window_y, 0,
2080 &window_change_flags);
2081
2082
2083
2084
2085 if (matrix_dim.width != FRAME_TOTAL_COLS (f)
2086 || matrix_dim.height != FRAME_TOTAL_LINES (f))
2087 {
2088
2089
2090
2091
2092
2093
2094
2095
2096 if (!FRAME_WINDOW_P (f) && pool_changed_p)
2097 SET_FRAME_GARBAGED (f);
2098 return;
2099 }
2100
2101 eassert (matrix_dim.width == FRAME_TOTAL_COLS (f)
2102 && matrix_dim.height == FRAME_TOTAL_LINES (f));
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113 if (display_completed
2114 && !FRAME_GARBAGED_P (f)
2115 && matrix_dim.width == f->current_matrix->matrix_w
2116 && matrix_dim.height == f->current_matrix->matrix_h
2117
2118
2119
2120
2121 && !showing_window_margins_p (XWINDOW (FRAME_ROOT_WINDOW (f))))
2122 {
2123 struct glyph_matrix *copy = save_current_matrix (f);
2124 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2125 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2126 restore_current_matrix (f, copy);
2127 fake_current_matrices (FRAME_ROOT_WINDOW (f));
2128 }
2129 else
2130 {
2131 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2132 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2133 SET_FRAME_GARBAGED (f);
2134 }
2135 }
2136 else if (!FRAME_INITIAL_P (f) && !noninteractive && initialized)
2137 {
2138 if (!f->desired_matrix->nrows || !f->desired_matrix->rows)
2139 {
2140 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2141 SET_FRAME_GARBAGED (f);
2142 }
2143 if (!f->current_matrix->nrows || !f->current_matrix->rows)
2144 {
2145 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2146 SET_FRAME_GARBAGED (f);
2147 }
2148 }
2149 }
2150
2151
2152
2153
2154
2155 static void
2156 adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2157 {
2158 eassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
2159
2160
2161 allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
2162
2163 #if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
2164
2165
2166 {
2167
2168 struct window *w;
2169 if (NILP (f->menu_bar_window))
2170 {
2171 Lisp_Object frame;
2172 fset_menu_bar_window (f, make_window ());
2173 w = XWINDOW (f->menu_bar_window);
2174 XSETFRAME (frame, f);
2175 wset_frame (w, frame);
2176 w->pseudo_window_p = 1;
2177 }
2178 else
2179 w = XWINDOW (f->menu_bar_window);
2180
2181
2182
2183 w->pixel_left = 0;
2184 w->left_col = 0;
2185 w->pixel_top = 0;
2186 w->top_line = 0;
2187 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2188 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
2189 w->total_cols = FRAME_TOTAL_COLS (f);
2190 w->pixel_height = FRAME_MENU_BAR_HEIGHT (f);
2191 w->total_lines = FRAME_MENU_BAR_LINES (f);
2192 allocate_matrices_for_window_redisplay (w);
2193 }
2194 #endif
2195
2196 #if defined (HAVE_WINDOW_SYSTEM)
2197 {
2198
2199
2200 struct window *w;
2201 if (NILP (f->tab_bar_window))
2202 {
2203 Lisp_Object frame;
2204 fset_tab_bar_window (f, make_window ());
2205 w = XWINDOW (f->tab_bar_window);
2206 XSETFRAME (frame, f);
2207 wset_frame (w, frame);
2208 w->pseudo_window_p = 1;
2209 }
2210 else
2211 w = XWINDOW (f->tab_bar_window);
2212
2213 w->pixel_left = 0;
2214 w->left_col = 0;
2215 w->pixel_top = FRAME_MENU_BAR_HEIGHT (f)
2216 + (!NILP (Vtab_bar_position) ? FRAME_TOOL_BAR_HEIGHT (f) : 0);
2217 w->top_line = FRAME_MENU_BAR_LINES (f)
2218 + (!NILP (Vtab_bar_position) ? FRAME_TOOL_BAR_LINES (f) : 0);
2219 w->total_cols = FRAME_TOTAL_COLS (f);
2220 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2221 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
2222 w->total_lines = FRAME_TAB_BAR_LINES (f);
2223 w->pixel_height = FRAME_TAB_BAR_HEIGHT (f);
2224 allocate_matrices_for_window_redisplay (w);
2225 }
2226 #endif
2227
2228 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
2229 {
2230
2231
2232 struct window *w;
2233 if (NILP (f->tool_bar_window))
2234 {
2235 Lisp_Object frame;
2236 fset_tool_bar_window (f, make_window ());
2237 w = XWINDOW (f->tool_bar_window);
2238 XSETFRAME (frame, f);
2239 wset_frame (w, frame);
2240 w->pseudo_window_p = 1;
2241 }
2242 else
2243 w = XWINDOW (f->tool_bar_window);
2244
2245 w->pixel_left = 0;
2246 w->left_col = 0;
2247 w->pixel_top = FRAME_MENU_BAR_HEIGHT (f)
2248 + (NILP (Vtab_bar_position) ? FRAME_TAB_BAR_HEIGHT (f) : 0);
2249 w->top_line = FRAME_MENU_BAR_LINES (f)
2250 + (NILP (Vtab_bar_position) ? FRAME_TAB_BAR_LINES (f) : 0);
2251 w->total_cols = FRAME_TOTAL_COLS (f);
2252 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2253 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
2254 w->total_lines = FRAME_TOOL_BAR_LINES (f);
2255 w->pixel_height = FRAME_TOOL_BAR_HEIGHT (f);
2256 allocate_matrices_for_window_redisplay (w);
2257 }
2258 #endif
2259 }
2260
2261
2262
2263
2264 static void
2265 adjust_decode_mode_spec_buffer (struct frame *f)
2266 {
2267 int frame_message_buf_size = FRAME_MESSAGE_BUF_SIZE (f);
2268
2269 eassert (frame_message_buf_size >= 0);
2270 f->decode_mode_spec_buffer = xrealloc (f->decode_mode_spec_buffer,
2271 frame_message_buf_size + 1);
2272 }
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285 void
2286 free_glyphs (struct frame *f)
2287 {
2288 if (f && f->glyphs_initialized_p)
2289 {
2290
2291
2292 block_input ();
2293 f->glyphs_initialized_p = false;
2294
2295
2296 if (!NILP (f->root_window))
2297 free_window_matrices (XWINDOW (f->root_window));
2298
2299 #if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
2300
2301
2302 if (!NILP (f->menu_bar_window))
2303 {
2304 struct window *w = XWINDOW (f->menu_bar_window);
2305 free_glyph_matrix (w->desired_matrix);
2306 free_glyph_matrix (w->current_matrix);
2307 w->desired_matrix = w->current_matrix = NULL;
2308 fset_menu_bar_window (f, Qnil);
2309 }
2310 #endif
2311
2312 #if defined (HAVE_WINDOW_SYSTEM)
2313
2314 if (!NILP (f->tab_bar_window))
2315 {
2316 struct window *w = XWINDOW (f->tab_bar_window);
2317 free_glyph_matrix (w->desired_matrix);
2318 free_glyph_matrix (w->current_matrix);
2319 w->desired_matrix = w->current_matrix = NULL;
2320 fset_tab_bar_window (f, Qnil);
2321 }
2322 #endif
2323
2324 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
2325
2326 if (!NILP (f->tool_bar_window))
2327 {
2328 struct window *w = XWINDOW (f->tool_bar_window);
2329 free_glyph_matrix (w->desired_matrix);
2330 free_glyph_matrix (w->current_matrix);
2331 w->desired_matrix = w->current_matrix = NULL;
2332 fset_tool_bar_window (f, Qnil);
2333 }
2334 #endif
2335
2336
2337
2338 if (f->desired_matrix)
2339 {
2340 free_glyph_matrix (f->desired_matrix);
2341 free_glyph_matrix (f->current_matrix);
2342 f->desired_matrix = f->current_matrix = NULL;
2343 }
2344
2345
2346 if (f->desired_pool)
2347 {
2348 free_glyph_pool (f->desired_pool);
2349 free_glyph_pool (f->current_pool);
2350 f->desired_pool = f->current_pool = NULL;
2351 }
2352
2353 unblock_input ();
2354 }
2355 }
2356
2357
2358
2359
2360
2361
2362 void
2363 free_window_matrices (struct window *w)
2364 {
2365 while (w)
2366 {
2367 if (WINDOWP (w->contents))
2368 free_window_matrices (XWINDOW (w->contents));
2369 else
2370 {
2371
2372
2373
2374 free_glyph_matrix (w->current_matrix);
2375 free_glyph_matrix (w->desired_matrix);
2376 w->current_matrix = w->desired_matrix = NULL;
2377 }
2378
2379
2380 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2381 }
2382 }
2383
2384
2385
2386
2387
2388
2389
2390 void
2391 check_glyph_memory (void)
2392 {
2393 Lisp_Object tail, frame;
2394
2395
2396 FOR_EACH_FRAME (tail, frame)
2397 free_glyphs (XFRAME (frame));
2398
2399 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2400
2401 eassert (glyph_matrix_count == 0);
2402 eassert (glyph_pool_count == 0);
2403 #endif
2404 }
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474 static void
2475 build_frame_matrix (struct frame *f)
2476 {
2477 int i;
2478
2479
2480 eassert (!FRAME_WINDOW_P (f));
2481
2482
2483
2484 for (i = FRAME_TOP_MARGIN (f); i < f->desired_matrix->nrows; ++i)
2485 clear_glyph_row (MATRIX_ROW (f->desired_matrix, i));
2486
2487
2488 build_frame_matrix_from_window_tree (f->desired_matrix,
2489 XWINDOW (FRAME_ROOT_WINDOW (f)));
2490 }
2491
2492
2493
2494
2495
2496 static void
2497 build_frame_matrix_from_window_tree (struct glyph_matrix *matrix, struct window *w)
2498 {
2499 while (w)
2500 {
2501 if (WINDOWP (w->contents))
2502 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->contents));
2503 else
2504 build_frame_matrix_from_leaf_window (matrix, w);
2505
2506 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2507 }
2508 }
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522 static void
2523 build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct window *w)
2524 {
2525 struct glyph_matrix *window_matrix;
2526 int window_y, frame_y;
2527
2528 GLYPH right_border_glyph;
2529
2530 SET_GLYPH_FROM_CHAR (right_border_glyph, 0);
2531
2532
2533 if (w->must_be_updated_p)
2534 {
2535 window_matrix = w->desired_matrix;
2536
2537
2538 if (!WINDOW_RIGHTMOST_P (w))
2539 {
2540 struct Lisp_Char_Table *dp = window_display_table (w);
2541 Lisp_Object gc;
2542
2543 SET_GLYPH_FROM_CHAR (right_border_glyph, '|');
2544 if (dp
2545 && (gc = DISP_BORDER_GLYPH (dp), GLYPH_CODE_P (gc)))
2546 {
2547 SET_GLYPH_FROM_GLYPH_CODE (right_border_glyph, gc);
2548 spec_glyph_lookup_face (w, &right_border_glyph);
2549 }
2550
2551 if (GLYPH_FACE (right_border_glyph) <= 0)
2552 SET_GLYPH_FACE (right_border_glyph, VERTICAL_BORDER_FACE_ID);
2553 }
2554 }
2555 else
2556 window_matrix = w->current_matrix;
2557
2558
2559
2560 window_y = 0;
2561 frame_y = window_matrix->matrix_y;
2562 while (window_y < window_matrix->nrows)
2563 {
2564 struct glyph_row *frame_row = frame_matrix->rows + frame_y;
2565 struct glyph_row *window_row = window_matrix->rows + window_y;
2566 bool current_row_p = window_matrix == w->current_matrix;
2567
2568
2569
2570 fill_up_frame_row_with_spaces (frame_row, window_matrix->matrix_x);
2571
2572
2573 fill_up_glyph_row_with_spaces (window_row);
2574
2575
2576
2577
2578 if (window_matrix == w->desired_matrix
2579 && !window_row->enabled_p)
2580 {
2581 window_row = w->current_matrix->rows + window_y;
2582 current_row_p = 1;
2583 }
2584
2585 if (current_row_p)
2586 {
2587
2588 memcpy (frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
2589 window_row->glyphs[0],
2590 window_matrix->matrix_w * sizeof (struct glyph));
2591 }
2592 else
2593 {
2594 eassert (window_row->enabled_p);
2595
2596
2597
2598 frame_row->enabled_p = true;
2599
2600
2601
2602 if (GLYPH_CHAR (right_border_glyph) != 0)
2603 {
2604 struct glyph *border = window_row->glyphs[LAST_AREA] - 1;
2605
2606
2607 eassert (border->type == CHAR_GLYPH);
2608 border->type = CHAR_GLYPH;
2609 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
2610 }
2611
2612 #ifdef GLYPH_DEBUG
2613
2614
2615 eassert (glyph_row_slice_p (window_row, frame_row));
2616
2617
2618
2619
2620 strcpy (w->current_matrix->method, w->desired_matrix->method);
2621 add_window_display_history (w, w->current_matrix->method, 0);
2622 #endif
2623 }
2624
2625
2626
2627
2628 frame_row->used[TEXT_AREA]
2629 = window_matrix->matrix_x + window_matrix->matrix_w;
2630
2631
2632 ++window_y;
2633 ++frame_y;
2634 }
2635 }
2636
2637
2638
2639
2640
2641
2642 void
2643 spec_glyph_lookup_face (struct window *w, GLYPH *glyph)
2644 {
2645 int lface_id = GLYPH_FACE (*glyph);
2646
2647 if (lface_id > 0)
2648 {
2649 int face_id = merge_faces (w, Qt, lface_id, DEFAULT_FACE_ID);
2650 SET_GLYPH_FACE (*glyph, face_id);
2651 }
2652 }
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670 static void
2671 fill_up_glyph_row_with_spaces (struct glyph_row *row)
2672 {
2673 fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA);
2674 fill_up_glyph_row_area_with_spaces (row, TEXT_AREA);
2675 fill_up_glyph_row_area_with_spaces (row, RIGHT_MARGIN_AREA);
2676 }
2677
2678
2679
2680
2681
2682 static void
2683 fill_up_glyph_row_area_with_spaces (struct glyph_row *row, int area)
2684 {
2685 if (row->glyphs[area] < row->glyphs[area + 1])
2686 {
2687 struct glyph *end = row->glyphs[area + 1];
2688 struct glyph *text = row->glyphs[area] + row->used[area];
2689
2690 while (text < end)
2691 *text++ = space_glyph;
2692 row->used[area] = text - row->glyphs[area];
2693 }
2694 }
2695
2696
2697
2698
2699
2700 void
2701 fill_up_frame_row_with_spaces (struct glyph_row *row, int upto)
2702 {
2703 int i = row->used[TEXT_AREA];
2704 struct glyph *glyph = row->glyphs[TEXT_AREA];
2705
2706 while (i < upto)
2707 glyph[i++] = space_glyph;
2708
2709 row->used[TEXT_AREA] = i;
2710 }
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722 static void
2723 set_frame_matrix_frame (struct frame *f)
2724 {
2725 frame_matrix_frame = f;
2726 }
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737 static void
2738 make_current (struct glyph_matrix *desired_matrix,
2739 struct glyph_matrix *current_matrix, int row)
2740 {
2741 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2742 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
2743 bool mouse_face_p = current_row->mouse_face_p;
2744
2745
2746
2747
2748
2749 if (!desired_row->hash
2750
2751
2752 && !(!desired_row->used[0]
2753 && !desired_row->used[1]
2754 && !desired_row->used[2]))
2755 desired_row->hash = row_hash (desired_row);
2756
2757
2758
2759 assign_row (current_row, desired_row);
2760
2761
2762 current_row->enabled_p = true;
2763 current_row->mouse_face_p = mouse_face_p;
2764
2765
2766
2767 if (frame_matrix_frame)
2768 mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row);
2769 }
2770
2771
2772
2773
2774
2775
2776
2777 static void
2778 mirror_make_current (struct window *w, int frame_row)
2779 {
2780 while (w)
2781 {
2782 if (WINDOWP (w->contents))
2783 mirror_make_current (XWINDOW (w->contents), frame_row);
2784 else
2785 {
2786
2787
2788
2789 int row = frame_row - w->desired_matrix->matrix_y;
2790
2791
2792
2793 if (row >= 0 && row < w->desired_matrix->matrix_h)
2794 {
2795 struct glyph_row *current_row
2796 = MATRIX_ROW (w->current_matrix, row);
2797 struct glyph_row *desired_row
2798 = MATRIX_ROW (w->desired_matrix, row);
2799
2800 if (desired_row->enabled_p)
2801 assign_row (current_row, desired_row);
2802 else
2803 swap_glyph_pointers (desired_row, current_row);
2804 current_row->enabled_p = true;
2805
2806
2807
2808
2809
2810
2811 if (current_row->mode_line_p)
2812 current_row->y = row;
2813 }
2814 }
2815
2816 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2817 }
2818 }
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831 void
2832 mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlines,
2833 int *copy_from, char *retained_p)
2834 {
2835
2836 struct glyph_row *old_rows;
2837
2838
2839 struct glyph_row *new_rows = MATRIX_ROW (matrix, unchanged_at_top);
2840
2841 int i;
2842
2843
2844 USE_SAFE_ALLOCA;
2845 SAFE_NALLOCA (old_rows, 1, nlines);
2846 memcpy (old_rows, new_rows, nlines * sizeof *old_rows);
2847
2848
2849 for (i = 0; i < nlines; ++i)
2850 {
2851 bool enabled_before_p = new_rows[i].enabled_p;
2852
2853 eassert (i + unchanged_at_top < matrix->nrows);
2854 eassert (unchanged_at_top + copy_from[i] < matrix->nrows);
2855 new_rows[i] = old_rows[copy_from[i]];
2856 new_rows[i].enabled_p = enabled_before_p;
2857
2858
2859 if (!retained_p[copy_from[i]])
2860 new_rows[i].enabled_p = false;
2861 }
2862
2863
2864 if (frame_matrix_frame)
2865 mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
2866 unchanged_at_top, nlines, copy_from, retained_p);
2867
2868 SAFE_FREE ();
2869 }
2870
2871
2872
2873
2874
2875 static void
2876 sync_window_with_frame_matrix_rows (struct window *w)
2877 {
2878 struct frame *f = XFRAME (w->frame);
2879 struct glyph_row *window_row, *window_row_end, *frame_row;
2880 int left, right, x, width;
2881
2882
2883 eassert (BUFFERP (w->contents));
2884 eassert (!FRAME_WINDOW_P (f));
2885
2886 left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
2887 right = margin_glyphs_to_reserve (w, 1, w->right_margin_cols);
2888 x = w->current_matrix->matrix_x;
2889 width = w->current_matrix->matrix_w;
2890
2891 window_row = w->current_matrix->rows;
2892 window_row_end = window_row + w->current_matrix->nrows;
2893 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
2894
2895 for (; window_row < window_row_end; ++window_row, ++frame_row)
2896 {
2897 window_row->glyphs[LEFT_MARGIN_AREA]
2898 = frame_row->glyphs[0] + x;
2899 window_row->glyphs[TEXT_AREA]
2900 = window_row->glyphs[LEFT_MARGIN_AREA] + left;
2901 window_row->glyphs[LAST_AREA]
2902 = window_row->glyphs[LEFT_MARGIN_AREA] + width;
2903 window_row->glyphs[RIGHT_MARGIN_AREA]
2904 = window_row->glyphs[LAST_AREA] - right;
2905 }
2906 }
2907
2908
2909
2910
2911
2912 static struct window *
2913 frame_row_to_window (struct window *w, int row)
2914 {
2915 struct window *found = NULL;
2916
2917 while (w && !found)
2918 {
2919 if (WINDOWP (w->contents))
2920 found = frame_row_to_window (XWINDOW (w->contents), row);
2921 else if (row >= WINDOW_TOP_EDGE_LINE (w)
2922 && row < WINDOW_BOTTOM_EDGE_LINE (w))
2923 found = w;
2924
2925 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2926 }
2927
2928 return found;
2929 }
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943 static void
2944 mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy_from, char *retained_p)
2945 {
2946 while (w)
2947 {
2948 if (WINDOWP (w->contents))
2949 mirror_line_dance (XWINDOW (w->contents), unchanged_at_top,
2950 nlines, copy_from, retained_p);
2951 else
2952 {
2953
2954
2955 struct glyph_matrix *m = w->current_matrix;
2956 int i;
2957 bool sync_p = 0;
2958 struct glyph_row *old_rows;
2959
2960
2961 USE_SAFE_ALLOCA;
2962 SAFE_NALLOCA (old_rows, 1, m->nrows);
2963 memcpy (old_rows, m->rows, m->nrows * sizeof *old_rows);
2964
2965 for (i = 0; i < nlines; ++i)
2966 {
2967
2968 int frame_to = i + unchanged_at_top;
2969
2970
2971 int frame_from = copy_from[i] + unchanged_at_top;
2972
2973
2974 int window_to = frame_to - m->matrix_y;
2975
2976
2977 int window_from = frame_from - m->matrix_y;
2978
2979
2980 bool from_inside_window_p
2981 = window_from >= 0 && window_from < m->matrix_h;
2982
2983
2984 bool to_inside_window_p
2985 = window_to >= 0 && window_to < m->matrix_h;
2986
2987 if (from_inside_window_p && to_inside_window_p)
2988 {
2989
2990
2991
2992 bool enabled_before_p = m->rows[window_to].enabled_p;
2993 m->rows[window_to] = old_rows[window_from];
2994 m->rows[window_to].enabled_p = enabled_before_p;
2995
2996
2997 if (!retained_p[copy_from[i]])
2998 m->rows[window_to].enabled_p = false;
2999 }
3000 else if (to_inside_window_p)
3001 {
3002
3003
3004 struct frame *f = XFRAME (w->frame);
3005 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
3006 struct window *w2;
3007 struct glyph_matrix *m2;
3008 int m2_from;
3009
3010 w2 = frame_row_to_window (root, frame_from);
3011
3012
3013
3014 if (w2)
3015 {
3016 m2 = w2->current_matrix;
3017 m2_from = frame_from - m2->matrix_y;
3018 copy_row_except_pointers (m->rows + window_to,
3019 m2->rows + m2_from);
3020
3021
3022 if (!retained_p[copy_from[i]])
3023 m->rows[window_to].enabled_p = false;
3024 }
3025 sync_p = 1;
3026 }
3027 else if (from_inside_window_p)
3028 sync_p = 1;
3029 }
3030
3031
3032
3033 if (sync_p)
3034 sync_window_with_frame_matrix_rows (w);
3035
3036
3037 CHECK_MATRIX (m);
3038
3039 SAFE_FREE ();
3040 }
3041
3042
3043 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3044 }
3045 }
3046
3047
3048 #ifdef GLYPH_DEBUG
3049
3050
3051
3052
3053
3054
3055
3056 static void
3057 check_window_matrix_pointers (struct window *w)
3058 {
3059 while (w)
3060 {
3061 if (WINDOWP (w->contents))
3062 check_window_matrix_pointers (XWINDOW (w->contents));
3063 else
3064 {
3065 struct frame *f = XFRAME (w->frame);
3066 check_matrix_pointers (w->desired_matrix, f->desired_matrix);
3067 check_matrix_pointers (w->current_matrix, f->current_matrix);
3068 }
3069
3070 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3071 }
3072 }
3073
3074
3075
3076
3077
3078
3079
3080 static void
3081 check_matrix_pointers (struct glyph_matrix *window_matrix,
3082 struct glyph_matrix *frame_matrix)
3083 {
3084
3085 int i = 0;
3086
3087
3088 int j = window_matrix->matrix_y;
3089
3090
3091
3092
3093 while (i < window_matrix->nrows)
3094 {
3095 if (!glyph_row_slice_p (window_matrix->rows + i,
3096 frame_matrix->rows + j))
3097 emacs_abort ();
3098 ++i, ++j;
3099 }
3100 }
3101
3102 #endif
3103
3104
3105
3106
3107
3108
3109
3110 #ifdef GLYPH_DEBUG
3111
3112
3113
3114
3115 static int
3116 window_to_frame_vpos (struct window *w, int vpos)
3117 {
3118 eassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
3119 eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
3120 vpos += WINDOW_TOP_EDGE_LINE (w);
3121 eassert (vpos >= 0 && vpos <= FRAME_TOTAL_LINES (XFRAME (w->frame)));
3122 return vpos;
3123 }
3124
3125
3126
3127
3128
3129 static int
3130 window_to_frame_hpos (struct window *w, int hpos)
3131 {
3132 eassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
3133 hpos += WINDOW_LEFT_EDGE_COL (w);
3134 return hpos;
3135 }
3136
3137 #endif
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147 void
3148 redraw_frame (struct frame *f)
3149 {
3150
3151 eassert (f->glyphs_initialized_p);
3152 update_begin (f);
3153 if (FRAME_MSDOS_P (f))
3154 FRAME_TERMINAL (f)->set_terminal_modes_hook (FRAME_TERMINAL (f));
3155
3156 if (FRAME_WINDOW_P (f))
3157
3158
3159
3160
3161 SET_FRAME_GARBAGED (f);
3162
3163 clear_frame (f);
3164 clear_current_matrices (f);
3165 update_end (f);
3166 fset_redisplay (f);
3167
3168
3169
3170 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
3171 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), true);
3172 f->garbaged = false;
3173 }
3174
3175 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 0, 1, 0,
3176 doc:
3177 )
3178 (Lisp_Object frame)
3179 {
3180 redraw_frame (decode_live_frame (frame));
3181 return Qnil;
3182 }
3183
3184 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3185 doc: )
3186 (void)
3187 {
3188 Lisp_Object tail, frame;
3189
3190 FOR_EACH_FRAME (tail, frame)
3191 if (FRAME_VISIBLE_P (XFRAME (frame)))
3192 redraw_frame (XFRAME (frame));
3193
3194 return Qnil;
3195 }
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210 bool
3211 update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
3212 {
3213
3214 bool paused_p;
3215 struct window *root_window = XWINDOW (f->root_window);
3216
3217 if (redisplay_dont_pause)
3218 force_p = true;
3219 else if (!force_p && detect_input_pending_ignore_squeezables ())
3220 {
3221 paused_p = true;
3222 goto do_pause;
3223 }
3224
3225 if (FRAME_WINDOW_P (f))
3226 {
3227
3228
3229
3230
3231 set_frame_matrix_frame (NULL);
3232
3233
3234
3235 update_begin (f);
3236
3237 #if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
3238
3239
3240 if (WINDOWP (f->menu_bar_window))
3241 update_window (XWINDOW (f->menu_bar_window), true);
3242 #endif
3243
3244 #if defined (HAVE_WINDOW_SYSTEM)
3245
3246 if (WINDOWP (f->tab_bar_window))
3247 {
3248 struct window *w = XWINDOW (f->tab_bar_window);
3249
3250
3251 if (w->must_be_updated_p)
3252 {
3253 Lisp_Object tem;
3254
3255 update_window (w, true);
3256 w->must_be_updated_p = false;
3257
3258
3259
3260 tem = f->current_tab_bar_string;
3261 fset_current_tab_bar_string (f, f->desired_tab_bar_string);
3262 fset_desired_tab_bar_string (f, tem);
3263 }
3264 }
3265 #endif
3266
3267 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
3268
3269 if (WINDOWP (f->tool_bar_window))
3270 {
3271 struct window *w = XWINDOW (f->tool_bar_window);
3272
3273
3274 if (w->must_be_updated_p)
3275 {
3276 Lisp_Object tem;
3277
3278 update_window (w, true);
3279 w->must_be_updated_p = false;
3280
3281
3282
3283 tem = f->current_tool_bar_string;
3284 fset_current_tool_bar_string (f, f->desired_tool_bar_string);
3285 fset_desired_tool_bar_string (f, tem);
3286 }
3287 }
3288 #endif
3289
3290
3291 paused_p = update_window_tree (root_window, force_p);
3292 update_end (f);
3293 }
3294 else
3295 {
3296
3297
3298 set_frame_matrix_frame (f);
3299
3300
3301 build_frame_matrix (f);
3302
3303
3304 if (FRAME_INITIAL_P (f))
3305
3306
3307 paused_p = false;
3308 else
3309 {
3310 update_begin (f);
3311 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p, 1, false);
3312 update_end (f);
3313 }
3314
3315 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
3316 {
3317 if (FRAME_TTY (f)->termscript)
3318 fflush (FRAME_TTY (f)->termscript);
3319 if (FRAME_TERMCAP_P (f))
3320 fflush (FRAME_TTY (f)->output);
3321 }
3322
3323
3324 #ifdef GLYPH_DEBUG
3325 check_window_matrix_pointers (root_window);
3326 add_frame_display_history (f, paused_p);
3327 #endif
3328 }
3329
3330 do_pause:
3331
3332 set_window_update_flags (root_window, false);
3333
3334 display_completed = !paused_p;
3335 return paused_p;
3336 }
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348 void
3349 update_frame_with_menu (struct frame *f, int row, int col)
3350 {
3351 struct window *root_window = XWINDOW (f->root_window);
3352 bool paused_p, cursor_at_point_p;
3353
3354 eassert (FRAME_TERMCAP_P (f));
3355
3356
3357
3358 set_frame_matrix_frame (f);
3359
3360
3361 update_begin (f);
3362 cursor_at_point_p = !(row >= 0 && col >= 0);
3363
3364
3365 paused_p = update_frame_1 (f, 1, 1, cursor_at_point_p, true);
3366
3367
3368 if (!cursor_at_point_p)
3369 cursor_to (f, row, col);
3370 update_end (f);
3371
3372 if (FRAME_TTY (f)->termscript)
3373 fflush (FRAME_TTY (f)->termscript);
3374 fflush (FRAME_TTY (f)->output);
3375
3376 #if GLYPH_DEBUG
3377 #if 0
3378
3379
3380
3381 check_window_matrix_pointers (root_window);
3382 #endif
3383 add_frame_display_history (f, paused_p);
3384 #endif
3385
3386
3387 set_window_update_flags (root_window, false);
3388 display_completed = !paused_p;
3389 }
3390
3391
3392
3393
3394
3395
3396 int
3397 update_mouse_position (struct frame *f, int x, int y)
3398 {
3399 previous_help_echo_string = help_echo_string;
3400 help_echo_string = Qnil;
3401
3402 note_mouse_highlight (f, x, y);
3403
3404
3405
3406 if (!NILP (help_echo_string)
3407 || !NILP (previous_help_echo_string))
3408 {
3409 Lisp_Object frame;
3410 XSETFRAME (frame, f);
3411
3412 gen_help_event (help_echo_string, frame, help_echo_window,
3413 help_echo_object, help_echo_pos);
3414 return 1;
3415 }
3416
3417 return 0;
3418 }
3419
3420 DEFUN ("display--update-for-mouse-movement", Fdisplay__update_for_mouse_movement,
3421 Sdisplay__update_for_mouse_movement, 2, 2, 0,
3422 doc:
3423
3424
3425
3426
3427 )
3428 (Lisp_Object mouse_x, Lisp_Object mouse_y)
3429 {
3430 CHECK_FIXNUM (mouse_x);
3431 CHECK_FIXNUM (mouse_y);
3432
3433 update_mouse_position (SELECTED_FRAME (), XFIXNUM (mouse_x),
3434 XFIXNUM (mouse_y));
3435 return Qnil;
3436 }
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446 static bool
3447 update_window_tree (struct window *w, bool force_p)
3448 {
3449 bool paused_p = 0;
3450
3451 while (w && !paused_p)
3452 {
3453 if (WINDOWP (w->contents))
3454 paused_p |= update_window_tree (XWINDOW (w->contents), force_p);
3455 else if (w->must_be_updated_p)
3456 paused_p |= update_window (w, force_p);
3457
3458 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3459 }
3460
3461 return paused_p;
3462 }
3463
3464
3465
3466
3467
3468 void
3469 update_single_window (struct window *w)
3470 {
3471 if (w->must_be_updated_p)
3472 {
3473 struct frame *f = XFRAME (WINDOW_FRAME (w));
3474
3475
3476 set_frame_matrix_frame (NULL);
3477
3478
3479 update_begin (f);
3480 update_window (w, true);
3481 update_end (f);
3482
3483
3484 w->must_be_updated_p = false;
3485 }
3486 }
3487
3488 #ifdef HAVE_WINDOW_SYSTEM
3489
3490
3491
3492
3493 static void
3494 redraw_overlapped_rows (struct window *w, int yb)
3495 {
3496 int i;
3497 struct frame *f = XFRAME (WINDOW_FRAME (w));
3498
3499
3500
3501
3502
3503
3504 for (i = 0; i < w->current_matrix->nrows; ++i)
3505 {
3506 struct glyph_row *row = w->current_matrix->rows + i;
3507
3508 if (!row->enabled_p)
3509 break;
3510 else if (row->mode_line_p)
3511 continue;
3512
3513 if (row->overlapped_p)
3514 {
3515 enum glyph_row_area area;
3516
3517 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
3518 {
3519 output_cursor_to (w, i, 0, row->y,
3520 area == TEXT_AREA ? row->x : 0);
3521 if (row->used[area])
3522 FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area],
3523 area, row->used[area]);
3524 FRAME_RIF (f)->clear_end_of_line (w, row, area, -1);
3525 }
3526
3527 row->overlapped_p = 0;
3528 }
3529
3530 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3531 break;
3532 }
3533 }
3534
3535
3536
3537
3538
3539 static void
3540 redraw_overlapping_rows (struct window *w, int yb)
3541 {
3542 int i, bottom_y;
3543 struct glyph_row *row;
3544 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3545
3546 for (i = 0; i < w->current_matrix->nrows; ++i)
3547 {
3548 row = w->current_matrix->rows + i;
3549
3550 if (!row->enabled_p)
3551 break;
3552 else if (row->mode_line_p)
3553 continue;
3554
3555 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3556
3557 if (row->overlapping_p)
3558 {
3559 int overlaps = 0;
3560
3561 if (MATRIX_ROW_OVERLAPS_PRED_P (row) && i > 0
3562 && !MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p)
3563 overlaps |= OVERLAPS_PRED;
3564 if (MATRIX_ROW_OVERLAPS_SUCC_P (row) && bottom_y < yb
3565 && !MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p)
3566 overlaps |= OVERLAPS_SUCC;
3567
3568 if (overlaps)
3569 {
3570 if (row->used[LEFT_MARGIN_AREA])
3571 rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA, overlaps);
3572
3573 if (row->used[TEXT_AREA])
3574 rif->fix_overlapping_area (w, row, TEXT_AREA, overlaps);
3575
3576 if (row->used[RIGHT_MARGIN_AREA])
3577 rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps);
3578
3579
3580
3581 if (overlaps & OVERLAPS_PRED)
3582 MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
3583 if (overlaps & OVERLAPS_SUCC)
3584 MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
3585 }
3586 }
3587
3588 if (bottom_y >= yb)
3589 break;
3590 }
3591 }
3592
3593 #endif
3594
3595
3596 #if defined GLYPH_DEBUG && 0
3597
3598
3599
3600
3601 static void
3602 check_current_matrix_flags (struct window *w)
3603 {
3604 bool last_seen_p = 0;
3605 int i, yb = window_text_bottom_y (w);
3606
3607 for (i = 0; i < w->current_matrix->nrows - 1; ++i)
3608 {
3609 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
3610 if (!last_seen_p && MATRIX_ROW_BOTTOM_Y (row) >= yb)
3611 last_seen_p = 1;
3612 else if (last_seen_p && row->enabled_p)
3613 emacs_abort ();
3614 }
3615 }
3616
3617 #endif
3618
3619
3620
3621
3622
3623 static bool
3624 update_window (struct window *w, bool force_p)
3625 {
3626 struct glyph_matrix *desired_matrix = w->desired_matrix;
3627 bool paused_p;
3628 int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
3629 #ifdef HAVE_WINDOW_SYSTEM
3630 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3631 #endif
3632 #ifdef GLYPH_DEBUG
3633
3634 eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
3635 #endif
3636
3637
3638 if (!force_p)
3639 detect_input_pending_ignore_squeezables ();
3640
3641
3642
3643 if (force_p || !input_pending || !NILP (track_mouse))
3644 {
3645 struct glyph_row *row, *end;
3646 struct glyph_row *mode_line_row;
3647 struct glyph_row *tab_line_row;
3648 struct glyph_row *header_line_row;
3649 int yb;
3650 bool changed_p = 0, mouse_face_overwritten_p = 0;
3651 int n_updated = 0;
3652 bool invisible_rows_marked = false;
3653
3654 #ifdef HAVE_WINDOW_SYSTEM
3655 gui_update_window_begin (w);
3656 #endif
3657 yb = window_text_bottom_y (w);
3658 row = MATRIX_ROW (desired_matrix, 0);
3659 end = MATRIX_MODE_LINE_ROW (desired_matrix);
3660
3661
3662
3663 if (row->mode_line_p && row->tab_line_p)
3664 {
3665 tab_line_row = row;
3666 ++row;
3667 }
3668 else
3669 tab_line_row = NULL;
3670
3671
3672
3673 if (row->mode_line_p)
3674 {
3675 header_line_row = row;
3676 ++row;
3677 }
3678 else
3679 header_line_row = NULL;
3680
3681
3682 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
3683 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
3684 {
3685 mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
3686 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
3687 desired_matrix),
3688 &mouse_face_overwritten_p);
3689 }
3690
3691
3692
3693
3694 while (row < end && !row->enabled_p)
3695 ++row;
3696
3697
3698 if (row < end && !desired_matrix->no_scrolling_p)
3699 {
3700 int rc = scrolling_window (w, (tab_line_row != NULL ? 1 : 0)
3701 + (header_line_row != NULL ? 1 : 0));
3702 if (rc < 0)
3703 {
3704
3705 paused_p = 0;
3706 goto set_cursor;
3707 }
3708 else if (rc > 0)
3709 {
3710
3711 force_p = 1;
3712 changed_p = 1;
3713 }
3714 }
3715
3716
3717 for (; row < end && (force_p || !input_pending); ++row)
3718
3719
3720 if (row->enabled_p)
3721 {
3722 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
3723 int i;
3724
3725
3726
3727
3728
3729 if (!force_p && ++n_updated % preempt_count == 0)
3730 detect_input_pending_ignore_squeezables ();
3731 changed_p |= update_window_line (w, vpos,
3732 &mouse_face_overwritten_p);
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3744 {
3745 for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
3746 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
3747 invisible_rows_marked = true;
3748 }
3749 }
3750
3751
3752
3753
3754
3755 if (!window_wants_mode_line (w))
3756 SET_MATRIX_ROW_ENABLED_P (w->current_matrix,
3757 w->current_matrix->nrows - 1, false);
3758
3759
3760 paused_p = row < end;
3761
3762 if (!paused_p && !invisible_rows_marked)
3763 {
3764
3765
3766
3767
3768
3769 int i;
3770 for (i = 0; i < w->current_matrix->nrows - 1; ++i)
3771 {
3772 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, i);
3773 if (current_row->enabled_p
3774 && MATRIX_ROW_BOTTOM_Y (current_row) >= yb)
3775 {
3776 for (++i ; i < w->current_matrix->nrows - 1; ++i)
3777 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
3778 }
3779 }
3780 }
3781
3782 set_cursor:
3783
3784
3785
3786
3787 if (tab_line_row && tab_line_row->enabled_p)
3788 {
3789 tab_line_row->y = 0;
3790 update_window_line (w, 0, &mouse_face_overwritten_p);
3791 }
3792
3793
3794
3795
3796 if (header_line_row && header_line_row->enabled_p)
3797 {
3798 header_line_row->y = tab_line_row ? CURRENT_TAB_LINE_HEIGHT (w) : 0;
3799 update_window_line (w, tab_line_row ? 1 : 0, &mouse_face_overwritten_p);
3800 }
3801
3802
3803 if (!paused_p && !w->pseudo_window_p)
3804 {
3805 #ifdef HAVE_WINDOW_SYSTEM
3806 if (changed_p && rif->fix_overlapping_area)
3807 {
3808 redraw_overlapped_rows (w, yb);
3809 redraw_overlapping_rows (w, yb);
3810 }
3811 #endif
3812
3813
3814 set_window_cursor_after_update (w);
3815
3816 #if 0
3817
3818 IF_DEBUG (check_matrix_invariants (w));
3819 #endif
3820 }
3821
3822 #ifdef GLYPH_DEBUG
3823
3824 strcpy (w->current_matrix->method, w->desired_matrix->method);
3825 #endif
3826
3827 #ifdef HAVE_WINDOW_SYSTEM
3828 update_window_fringes (w, 0);
3829
3830
3831
3832
3833
3834 gui_update_window_end (w, !paused_p, mouse_face_overwritten_p);
3835 #endif
3836
3837
3838 if (!paused_p)
3839 w->must_be_updated_p = false;
3840 }
3841 else
3842 paused_p = 1;
3843
3844 #ifdef GLYPH_DEBUG
3845
3846 add_window_display_history (w, w->current_matrix->method, paused_p);
3847 #endif
3848
3849 xwidget_end_redisplay (w, w->current_matrix);
3850 clear_glyph_matrix (desired_matrix);
3851
3852 return paused_p;
3853 }
3854
3855 #ifdef HAVE_WINDOW_SYSTEM
3856
3857
3858
3859 void
3860 gui_update_window_begin (struct window *w)
3861 {
3862 struct frame *f = XFRAME (WINDOW_FRAME (w));
3863 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
3864
3865 block_input ();
3866
3867 if (FRAME_RIF (f)->update_window_begin_hook)
3868 FRAME_RIF (f)->update_window_begin_hook (w);
3869
3870 w->output_cursor = w->cursor;
3871
3872 if (f == hlinfo->mouse_face_mouse_frame)
3873 {
3874
3875 hlinfo->mouse_face_defer = true;
3876
3877
3878
3879 if (FRAME_GARBAGED_P (f))
3880 hlinfo->mouse_face_window = Qnil;
3881 }
3882
3883 unblock_input ();
3884 }
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894 void
3895 gui_update_window_end (struct window *w, bool cursor_on_p,
3896 bool mouse_face_overwritten_p)
3897 {
3898 struct frame *f = XFRAME (WINDOW_FRAME (w));
3899
3900
3901 if (!w->pseudo_window_p)
3902 {
3903 block_input ();
3904
3905 if (cursor_on_p)
3906 display_and_set_cursor (w, true,
3907 w->output_cursor.hpos, w->output_cursor.vpos,
3908 w->output_cursor.x, w->output_cursor.y);
3909
3910 if (cursor_in_mouse_face_p (w) && cursor_on_p)
3911 mouse_face_overwritten_p = 1;
3912
3913 if (draw_window_fringes (w, true))
3914 {
3915 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
3916 gui_draw_right_divider (w);
3917 else
3918 gui_draw_vertical_border (w);
3919 }
3920 unblock_input ();
3921 }
3922
3923
3924
3925 if (mouse_face_overwritten_p)
3926 {
3927 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
3928
3929 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
3930 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
3931 hlinfo->mouse_face_window = Qnil;
3932 }
3933
3934 if (FRAME_RIF (f)->update_window_end_hook)
3935 FRAME_RIF (f)->update_window_end_hook (w,
3936 cursor_on_p,
3937 mouse_face_overwritten_p);
3938 }
3939
3940 #endif
3941
3942
3943
3944
3945 static void
3946 update_marginal_area (struct window *w, struct glyph_row *updated_row,
3947 enum glyph_row_area area, int vpos)
3948 {
3949 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3950 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3951
3952
3953
3954
3955 output_cursor_to (w, vpos, 0, desired_row->y, 0);
3956 if (desired_row->used[area])
3957 rif->write_glyphs (w, updated_row, desired_row->glyphs[area],
3958 area, desired_row->used[area]);
3959 rif->clear_end_of_line (w, updated_row, area, -1);
3960 }
3961
3962
3963
3964
3965
3966 static bool
3967 update_text_area (struct window *w, struct glyph_row *updated_row, int vpos,
3968 bool *partial_p)
3969 {
3970 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3971 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3972 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3973 bool changed_p = 0;
3974
3975
3976
3977 if (!current_row->enabled_p
3978 || desired_row->y != current_row->y
3979 || desired_row->ascent != current_row->ascent
3980 || desired_row->phys_ascent != current_row->phys_ascent
3981 || desired_row->phys_height != current_row->phys_height
3982 || desired_row->visible_height != current_row->visible_height
3983 || current_row->overlapped_p
3984
3985
3986
3987
3988
3989
3990
3991
3992 || (current_row->mouse_face_p
3993 && !(current_row->mode_line_p
3994 && (vpos > (w->current_matrix->tab_line_p
3995 && w->current_matrix->header_line_p))))
3996 || current_row->x != desired_row->x)
3997 {
3998 output_cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
3999
4000 if (desired_row->used[TEXT_AREA])
4001 rif->write_glyphs (w, updated_row, desired_row->glyphs[TEXT_AREA],
4002 TEXT_AREA, desired_row->used[TEXT_AREA]);
4003
4004
4005 rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
4006 changed_p = 1;
4007
4008
4009
4010
4011
4012
4013
4014
4015 if (vpos == w->phys_cursor.vpos)
4016 w->phys_cursor_on_p = 0;
4017 }
4018 else
4019 {
4020 int stop, i, x;
4021 struct glyph *current_glyph = current_row->glyphs[TEXT_AREA];
4022 struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
4023 bool overlapping_glyphs_p = current_row->contains_overlapping_glyphs_p;
4024 int desired_stop_pos = desired_row->used[TEXT_AREA];
4025 bool abort_skipping = 0;
4026
4027
4028
4029
4030
4031 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row)
4032 && (desired_stop_pos < current_row->used[TEXT_AREA]
4033 || (desired_stop_pos == current_row->used[TEXT_AREA]
4034 && !MATRIX_ROW_EXTENDS_FACE_P (current_row))))
4035 --desired_stop_pos;
4036
4037 stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
4038 i = 0;
4039 x = desired_row->x;
4040
4041
4042
4043 while (i < stop)
4044 {
4045 bool can_skip_p = !abort_skipping;
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055 if (overlapping_glyphs_p && i > 0)
4056 {
4057 struct glyph *glyph = ¤t_row->glyphs[TEXT_AREA][i - 1];
4058 int left, right;
4059
4060 rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
4061 &left, &right);
4062 can_skip_p = (right == 0 && !abort_skipping);
4063 }
4064
4065 if (can_skip_p)
4066 {
4067 int start_hpos = i;
4068
4069 while (i < stop
4070 && GLYPH_EQUAL_P (desired_glyph, current_glyph))
4071 {
4072 x += desired_glyph->pixel_width;
4073 ++desired_glyph, ++current_glyph, ++i;
4074
4075
4076
4077
4078
4079
4080 *partial_p = true;
4081 }
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091 if (overlapping_glyphs_p
4092 && i > 0
4093 && i < current_row->used[TEXT_AREA]
4094 && (current_row->used[TEXT_AREA]
4095 != desired_row->used[TEXT_AREA]))
4096 {
4097 int left, right;
4098
4099 rif->get_glyph_overhangs (current_glyph,
4100 XFRAME (w->frame),
4101 &left, &right);
4102 while (left > 0 && i > 0)
4103 {
4104 --i, --desired_glyph, --current_glyph;
4105 x -= desired_glyph->pixel_width;
4106 left -= desired_glyph->pixel_width;
4107 }
4108
4109
4110
4111
4112
4113 abort_skipping = (i < start_hpos);
4114 }
4115 }
4116
4117
4118
4119
4120
4121 if (i < desired_row->used[TEXT_AREA])
4122 {
4123 int start_x = x, start_hpos = i;
4124 struct glyph *start = desired_glyph;
4125 int current_x = x;
4126 bool skip_first_p = !can_skip_p;
4127
4128
4129 while (i < stop
4130 && (skip_first_p
4131 || !GLYPH_EQUAL_P (desired_glyph, current_glyph))
4132 && x == current_x)
4133 {
4134 x += desired_glyph->pixel_width;
4135 current_x += current_glyph->pixel_width;
4136 ++desired_glyph, ++current_glyph, ++i;
4137 skip_first_p = 0;
4138 }
4139
4140 if (i == start_hpos || x != current_x)
4141 {
4142 i = start_hpos;
4143 x = start_x;
4144 desired_glyph = start;
4145 break;
4146 }
4147
4148 output_cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
4149 rif->write_glyphs (w, updated_row, start,
4150 TEXT_AREA, i - start_hpos);
4151 changed_p = 1;
4152 *partial_p = true;
4153 }
4154 }
4155
4156
4157
4158 if (!i)
4159 *partial_p = false;
4160
4161
4162 if (i < desired_row->used[TEXT_AREA])
4163 {
4164 output_cursor_to (w, vpos, i, desired_row->y, x);
4165 rif->write_glyphs (w, updated_row, desired_glyph,
4166 TEXT_AREA, desired_row->used[TEXT_AREA] - i);
4167 changed_p = 1;
4168 }
4169
4170
4171 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
4172 {
4173
4174
4175
4176
4177 eassert (i < desired_row->used[TEXT_AREA]
4178 || ((desired_row->used[TEXT_AREA]
4179 == current_row->used[TEXT_AREA])
4180 && MATRIX_ROW_EXTENDS_FACE_P (current_row)));
4181 }
4182 else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
4183 {
4184
4185 if (i >= desired_row->used[TEXT_AREA])
4186 output_cursor_to (w, vpos, i, desired_row->y,
4187 desired_row->pixel_width);
4188 rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
4189 changed_p = 1;
4190 }
4191 else if (desired_row->pixel_width < current_row->pixel_width)
4192 {
4193
4194
4195 int xlim;
4196
4197 if (i >= desired_row->used[TEXT_AREA])
4198 output_cursor_to (w, vpos, i, desired_row->y,
4199 desired_row->pixel_width);
4200
4201
4202
4203
4204
4205
4206 if (vpos == w->phys_cursor.vpos
4207 && (desired_row->reversed_p
4208 ? (w->phys_cursor.hpos < 0)
4209 : (w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])))
4210 {
4211 w->phys_cursor_on_p = 0;
4212 xlim = -1;
4213 }
4214 else
4215 xlim = current_row->pixel_width;
4216 rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim);
4217 changed_p = 1;
4218 }
4219 }
4220
4221 return changed_p;
4222 }
4223
4224
4225
4226
4227 static bool
4228 update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
4229 {
4230 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
4231 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
4232 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
4233
4234
4235 bool changed_p = 0, partial_p = 0, was_stipple;
4236
4237
4238
4239
4240
4241 if (desired_row->mode_line_p
4242 || desired_row->visible_height > 0)
4243 {
4244 eassert (desired_row->enabled_p);
4245
4246
4247 if (!desired_row->full_width_p && w->left_margin_cols > 0)
4248 {
4249 changed_p = 1;
4250 update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos);
4251
4252
4253
4254
4255 current_row->redraw_fringe_bitmaps_p = 1;
4256 }
4257
4258
4259 if (update_text_area (w, desired_row, vpos, &partial_p))
4260 {
4261 changed_p = 1;
4262 if (current_row->mouse_face_p)
4263 *mouse_face_overwritten_p = 1;
4264 }
4265
4266
4267 if (!desired_row->full_width_p && w->right_margin_cols > 0)
4268 {
4269 changed_p = 1;
4270 update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos);
4271 }
4272
4273
4274 if (!current_row->enabled_p
4275 || desired_row->y != current_row->y
4276 || desired_row->visible_height != current_row->visible_height
4277 || desired_row->cursor_in_fringe_p != current_row->cursor_in_fringe_p
4278 || desired_row->overlay_arrow_bitmap != current_row->overlay_arrow_bitmap
4279 || current_row->redraw_fringe_bitmaps_p
4280 || desired_row->mode_line_p != current_row->mode_line_p
4281 || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
4282 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
4283 != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
4284 rif->after_update_window_line_hook (w, desired_row);
4285 }
4286
4287
4288 was_stipple = current_row->stipple_p;
4289 make_current (w->desired_matrix, w->current_matrix, vpos);
4290
4291
4292
4293
4294
4295
4296 if (partial_p && was_stipple)
4297 current_row->stipple_p = true;
4298
4299 return changed_p;
4300 }
4301
4302
4303
4304
4305
4306 static void
4307 set_window_cursor_after_update (struct window *w)
4308 {
4309 struct frame *f = XFRAME (w->frame);
4310 int cx, cy, vpos, hpos;
4311
4312
4313 eassert (FRAME_WINDOW_P (f));
4314
4315 if (cursor_in_echo_area
4316 && !NILP (echo_area_buffer[0])
4317
4318
4319 && XWINDOW (minibuf_window) == w
4320 && BASE_EQ (minibuf_window, echo_area_window)
4321
4322
4323 && FRAME_HAS_MINIBUF_P (f)
4324 && BASE_EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4325 {
4326 cx = cy = vpos = hpos = 0;
4327
4328
4329
4330
4331
4332 struct glyph_row *last_row = NULL;
4333 int yb = window_text_bottom_y (w);
4334
4335 for (struct glyph_row *row = w->current_matrix->rows;
4336 row->enabled_p && (!last_row || MATRIX_ROW_BOTTOM_Y (row) <= yb);
4337 row++)
4338 if (row->used[TEXT_AREA] && row->glyphs[TEXT_AREA][0].charpos >= 0)
4339 last_row = row;
4340
4341 if (last_row)
4342 {
4343 struct glyph *start = last_row->glyphs[TEXT_AREA];
4344 struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
4345
4346 while (last > start && last->charpos < 0)
4347 --last;
4348
4349 for (struct glyph *glyph = start; glyph < last; glyph++)
4350 {
4351 cx += glyph->pixel_width;
4352 hpos++;
4353 }
4354
4355 cy = last_row->y;
4356 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
4357 }
4358 }
4359 else
4360 {
4361 cx = w->cursor.x;
4362 cy = w->cursor.y;
4363 hpos = w->cursor.hpos;
4364 vpos = w->cursor.vpos;
4365 }
4366
4367
4368
4369 hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1);
4370 vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1);
4371 output_cursor_to (w, vpos, hpos, cy, cx);
4372 }
4373
4374
4375
4376
4377
4378 static void
4379 set_window_update_flags (struct window *w, bool on_p)
4380 {
4381 while (w)
4382 {
4383 if (WINDOWP (w->contents))
4384 set_window_update_flags (XWINDOW (w->contents), on_p);
4385 else
4386 w->must_be_updated_p = on_p;
4387
4388 w = NILP (w->next) ? 0 : XWINDOW (w->next);
4389 }
4390 }
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400 struct row_entry
4401 {
4402
4403 int old_uses, new_uses;
4404
4405
4406 int new_line_number;
4407
4408
4409 ptrdiff_t bucket;
4410
4411
4412 struct glyph_row *row;
4413
4414
4415 struct row_entry *next;
4416 };
4417
4418
4419
4420
4421
4422 static struct row_entry *row_entry_pool;
4423 static ptrdiff_t row_entry_pool_size;
4424
4425
4426
4427 static ptrdiff_t row_entry_idx;
4428
4429
4430
4431
4432
4433 static struct row_entry **row_table;
4434 static ptrdiff_t row_table_size;
4435
4436
4437
4438
4439 static struct row_entry **old_lines, **new_lines;
4440 static ptrdiff_t old_lines_size, new_lines_size;
4441
4442
4443
4444 static struct run *run_pool;
4445 static ptrdiff_t runs_size;
4446
4447
4448
4449 static struct run **runs;
4450
4451
4452
4453 static struct row_entry *
4454 add_row_entry (struct glyph_row *row)
4455 {
4456 struct row_entry *entry;
4457 ptrdiff_t i = row->hash % row_table_size;
4458
4459 entry = row_table[i];
4460 eassert (entry || verify_row_hash (row));
4461 while (entry && !row_equal_p (entry->row, row, 1))
4462 entry = entry->next;
4463
4464 if (entry == NULL)
4465 {
4466 entry = row_entry_pool + row_entry_idx++;
4467 entry->row = row;
4468 entry->old_uses = entry->new_uses = 0;
4469 entry->new_line_number = 0;
4470 entry->bucket = i;
4471 entry->next = row_table[i];
4472 row_table[i] = entry;
4473 }
4474
4475 return entry;
4476 }
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504 static int
4505 scrolling_window (struct window *w, int tab_line_p)
4506 {
4507 struct glyph_matrix *desired_matrix = w->desired_matrix;
4508 struct glyph_matrix *current_matrix = w->current_matrix;
4509 int yb = window_text_bottom_y (w);
4510 ptrdiff_t i;
4511 int j, first_old, first_new, last_old, last_new;
4512 int nruns, run_idx;
4513 ptrdiff_t n;
4514 struct row_entry *entry;
4515 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
4516
4517
4518 for (i = tab_line_p; i < current_matrix->nrows - 1; ++i)
4519 {
4520 struct glyph_row *d = MATRIX_ROW (desired_matrix, i);
4521 struct glyph_row *c = MATRIX_ROW (current_matrix, i);
4522
4523
4524
4525
4526
4527
4528 if (c->stipple_p)
4529 return 0;
4530
4531 if (c->enabled_p
4532 && d->enabled_p
4533 && !d->redraw_fringe_bitmaps_p
4534 && c->y == d->y
4535 && MATRIX_ROW_BOTTOM_Y (c) <= yb
4536 && MATRIX_ROW_BOTTOM_Y (d) <= yb
4537 && row_equal_p (c, d, 1))
4538 {
4539 assign_row (c, d);
4540 d->enabled_p = false;
4541 }
4542 else
4543 break;
4544 }
4545
4546
4547
4548
4549 #ifdef HAVE_NTGUI
4550 if (w32_use_visible_system_caret)
4551 return 0;
4552 #endif
4553
4554
4555 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
4556 return -1;
4557
4558 first_old = first_new = i;
4559
4560 while (i < current_matrix->nrows - 1)
4561 {
4562
4563
4564 if (MATRIX_ROW (current_matrix, i)->stipple_p)
4565 return 0;
4566
4567 ++i;
4568 }
4569
4570
4571
4572
4573 i = first_new + 1;
4574 while (i < desired_matrix->nrows - 1)
4575 {
4576 int bottom;
4577
4578 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
4579 return 0;
4580 bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i));
4581 if (bottom <= yb)
4582 ++i;
4583 if (bottom >= yb)
4584 break;
4585 }
4586
4587 last_new = i;
4588
4589
4590
4591
4592
4593 i = first_old + 1;
4594 while (i < current_matrix->nrows - 1)
4595 {
4596 int bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i));
4597 if (bottom <= yb)
4598 ++i;
4599 if (bottom >= yb)
4600 break;
4601 }
4602
4603 last_old = i;
4604
4605
4606 i = last_new;
4607 j = last_old;
4608 while (i - 1 > first_new
4609 && j - 1 > first_old
4610 && MATRIX_ROW_ENABLED_P (current_matrix, j - 1)
4611 && (MATRIX_ROW (current_matrix, j - 1)->y
4612 == MATRIX_ROW (desired_matrix, i - 1)->y)
4613 && !MATRIX_ROW (desired_matrix, i - 1)->redraw_fringe_bitmaps_p
4614 && row_equal_p (MATRIX_ROW (desired_matrix, i - 1),
4615 MATRIX_ROW (current_matrix, j - 1), 1))
4616 --i, --j;
4617 last_new = i;
4618 last_old = j;
4619
4620
4621 if (last_new == first_new)
4622 return 0;
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634 {
4635 verify (NEXT_ALMOST_PRIME_LIMIT == 11);
4636 enum { next_almost_prime_increment_max = 10 };
4637 ptrdiff_t row_table_max =
4638 (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table)
4639 - next_almost_prime_increment_max);
4640 ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows;
4641 if (current_nrows_max < current_matrix->nrows)
4642 memory_full (SIZE_MAX);
4643 }
4644
4645
4646
4647 if (current_matrix->nrows > old_lines_size)
4648 old_lines = xpalloc (old_lines, &old_lines_size,
4649 current_matrix->nrows - old_lines_size,
4650 INT_MAX, sizeof *old_lines);
4651
4652 if (desired_matrix->nrows > new_lines_size)
4653 new_lines = xpalloc (new_lines, &new_lines_size,
4654 desired_matrix->nrows - new_lines_size,
4655 INT_MAX, sizeof *new_lines);
4656
4657 n = desired_matrix->nrows;
4658 n += current_matrix->nrows;
4659 if (row_table_size < 3 * n)
4660 {
4661 ptrdiff_t size = next_almost_prime (3 * n);
4662 row_table = xnrealloc (row_table, size, sizeof *row_table);
4663 row_table_size = size;
4664 memset (row_table, 0, size * sizeof *row_table);
4665 }
4666
4667 if (n > row_entry_pool_size)
4668 row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size,
4669 n - row_entry_pool_size,
4670 -1, sizeof *row_entry_pool);
4671
4672 if (desired_matrix->nrows > runs_size)
4673 {
4674 runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs);
4675 run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool);
4676 runs_size = desired_matrix->nrows;
4677 }
4678
4679 nruns = run_idx = 0;
4680 row_entry_idx = 0;
4681
4682
4683
4684
4685 for (i = first_old; i < last_old; ++i)
4686 {
4687 if (MATRIX_ROW_ENABLED_P (current_matrix, i))
4688 {
4689 entry = add_row_entry (MATRIX_ROW (current_matrix, i));
4690 old_lines[i] = entry;
4691 ++entry->old_uses;
4692 }
4693 else
4694 old_lines[i] = NULL;
4695 }
4696
4697 for (i = first_new; i < last_new; ++i)
4698 {
4699 eassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
4700 entry = add_row_entry (MATRIX_ROW (desired_matrix, i));
4701 ++entry->new_uses;
4702 entry->new_line_number = i;
4703 new_lines[i] = entry;
4704 }
4705
4706
4707
4708 for (i = first_old; i < last_old;)
4709 if (old_lines[i]
4710 && old_lines[i]->old_uses == 1
4711 && old_lines[i]->new_uses == 1)
4712 {
4713 int p, q;
4714 int new_line = old_lines[i]->new_line_number;
4715 struct run *run = run_pool + run_idx++;
4716
4717
4718 run->current_vpos = i;
4719 run->current_y = MATRIX_ROW (current_matrix, i)->y;
4720 run->desired_vpos = new_line;
4721 run->desired_y = MATRIX_ROW (desired_matrix, new_line)->y;
4722 run->nrows = 1;
4723 run->height = MATRIX_ROW (current_matrix, i)->height;
4724
4725
4726 p = i - 1;
4727 q = new_line - 1;
4728 while (p > first_old
4729 && q > first_new
4730 && old_lines[p] == new_lines[q])
4731 {
4732 int h = MATRIX_ROW (current_matrix, p)->height;
4733 --run->current_vpos;
4734 --run->desired_vpos;
4735 ++run->nrows;
4736 run->height += h;
4737 run->desired_y -= h;
4738 run->current_y -= h;
4739 --p, --q;
4740 }
4741
4742
4743 p = i + 1;
4744 q = new_line + 1;
4745 while (p < last_old
4746 && q < last_new
4747 && old_lines[p] == new_lines[q])
4748 {
4749 int h = MATRIX_ROW (current_matrix, p)->height;
4750 ++run->nrows;
4751 run->height += h;
4752 ++p, ++q;
4753 }
4754
4755
4756
4757
4758
4759
4760 for (p = 0; p < nruns && runs[p]->height > run->height; ++p)
4761 ;
4762 for (q = nruns; q > p; --q)
4763 runs[q] = runs[q - 1];
4764 runs[p] = run;
4765 ++nruns;
4766
4767 i += run->nrows;
4768 }
4769 else
4770 ++i;
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786 for (i = 0; i < nruns; ++i)
4787 if (runs[i]->nrows > 0)
4788 {
4789 struct run *r = runs[i];
4790
4791
4792 if (r->current_y != r->desired_y)
4793 {
4794 rif->clear_window_mouse_face (w);
4795 rif->scroll_run_hook (w, r);
4796 }
4797
4798
4799
4800 for (j = nruns - 1; j > i; --j)
4801 {
4802 struct run *p = runs[j];
4803 bool truncated_p = 0;
4804
4805 if (p->nrows > 0
4806 && p->desired_y < r->desired_y + r->height
4807 && p->desired_y + p->height > r->desired_y)
4808 {
4809 if (p->desired_y < r->desired_y)
4810 {
4811 p->nrows = r->desired_vpos - p->desired_vpos;
4812 p->height = r->desired_y - p->desired_y;
4813 truncated_p = 1;
4814 }
4815 else
4816 {
4817 int nrows_copied = (r->desired_vpos + r->nrows
4818 - p->desired_vpos);
4819
4820 if (p->nrows <= nrows_copied)
4821 p->nrows = 0;
4822 else
4823 {
4824 int height_copied = (r->desired_y + r->height
4825 - p->desired_y);
4826
4827 p->current_vpos += nrows_copied;
4828 p->desired_vpos += nrows_copied;
4829 p->nrows -= nrows_copied;
4830 p->current_y += height_copied;
4831 p->desired_y += height_copied;
4832 p->height -= height_copied;
4833 truncated_p = 1;
4834 }
4835 }
4836 }
4837
4838 if (r->current_y != r->desired_y
4839
4840
4841
4842
4843
4844
4845
4846 && p->current_y < r->desired_y + r->height
4847 && p->current_y + p->height > r->desired_y)
4848 p->nrows = 0;
4849
4850
4851 if (truncated_p && p->nrows > 0)
4852 {
4853 int k = nruns - 1;
4854
4855 while (runs[k]->nrows == 0 || runs[k]->height < p->height)
4856 k--;
4857 memmove (runs + j, runs + j + 1, (k - j) * sizeof (*runs));
4858 runs[k] = p;
4859 }
4860 }
4861
4862
4863 for (j = 0; j < r->nrows; ++j)
4864 {
4865 struct glyph_row *from, *to;
4866 bool to_overlapped_p;
4867
4868 to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
4869 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
4870 to_overlapped_p = to->overlapped_p;
4871 from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
4872 assign_row (to, from);
4873
4874
4875
4876
4877
4878
4879 eassert (to->enabled_p);
4880 from->enabled_p = false;
4881 to->overlapped_p = to_overlapped_p;
4882 }
4883 }
4884
4885
4886 for (i = 0; i < row_entry_idx; ++i)
4887 row_table[row_entry_pool[i].bucket] = NULL;
4888
4889
4890 return nruns > 0;
4891 }
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907 static bool
4908 update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
4909 bool set_cursor_p, bool updating_menu_p)
4910 {
4911
4912 struct glyph_matrix *current_matrix = f->current_matrix;
4913 struct glyph_matrix *desired_matrix = f->desired_matrix;
4914 int i;
4915 bool pause_p;
4916 int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
4917
4918 eassert (current_matrix && desired_matrix);
4919
4920 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4921 calculate_costs (f);
4922
4923 if (!force_p && detect_input_pending_ignore_squeezables ())
4924 {
4925 pause_p = 1;
4926 goto do_pause;
4927 }
4928
4929
4930 if (!FRAME_LINE_INS_DEL_OK (f))
4931 inhibit_id_p = 1;
4932
4933
4934
4935 for (i = 0; i < desired_matrix->nrows; i++)
4936 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4937 break;
4938
4939
4940 if (!inhibit_id_p && i < desired_matrix->nrows)
4941 force_p |= scrolling (f);
4942
4943
4944 if (MATRIX_ROW_ENABLED_P (desired_matrix, desired_matrix->nrows - 1))
4945 update_frame_line (f, desired_matrix->nrows - 1, updating_menu_p);
4946
4947
4948 for (i = 0; i < desired_matrix->nrows - 1 && (force_p || !input_pending); i++)
4949 {
4950 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4951 {
4952
4953
4954 if (FRAME_TERMCAP_P (f) && FRAME_TTY (f)->output_buffer_size == 0)
4955 {
4956
4957
4958
4959
4960 FILE *display_output = FRAME_TTY (f)->output;
4961 if (display_output)
4962 {
4963 ptrdiff_t outq = __fpending (display_output);
4964 if (outq > 900
4965 || (outq > 20 && ((i - 1) % preempt_count == 0)))
4966 fflush (display_output);
4967 }
4968 }
4969
4970 if (!force_p && (i - 1) % preempt_count == 0)
4971 detect_input_pending_ignore_squeezables ();
4972
4973 update_frame_line (f, i, updating_menu_p);
4974 }
4975 }
4976
4977 pause_p = 0 < i && i < FRAME_TOTAL_LINES (f) - 1;
4978
4979
4980 if (!pause_p && set_cursor_p)
4981 {
4982 if ((cursor_in_echo_area
4983
4984
4985
4986 || (BASE_EQ (minibuf_window, selected_window)
4987 && BASE_EQ (minibuf_window, echo_area_window)
4988 && !NILP (echo_area_buffer[0])))
4989
4990
4991 && FRAME_HAS_MINIBUF_P (f)
4992 && BASE_EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4993 {
4994 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
4995 int col;
4996
4997
4998
4999
5000 int row = FRAME_TOTAL_LINES (f);
5001 do
5002 {
5003 row--;
5004 col = 0;
5005
5006 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
5007 {
5008
5009
5010 struct glyph_row *r = MATRIX_ROW (current_matrix, row);
5011 struct glyph *start = r->glyphs[TEXT_AREA];
5012
5013 col = r->used[TEXT_AREA];
5014 while (0 < col && start[col - 1].charpos < 0)
5015 col--;
5016 }
5017 }
5018 while (row > top && col == 0);
5019
5020
5021 if (col > 0)
5022 col--;
5023
5024
5025 if (col >= FRAME_CURSOR_X_LIMIT (f))
5026 {
5027
5028 if (row < FRAME_TOTAL_LINES (f) - 1)
5029 {
5030 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
5031 row++;
5032 }
5033
5034 else
5035 col = FRAME_CURSOR_X_LIMIT (f) - 1;
5036 }
5037
5038 cursor_to (f, row, col);
5039 }
5040 else
5041 {
5042
5043
5044 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5045 if (w->cursor.vpos >= 0
5046
5047
5048
5049
5050
5051 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
5052 {
5053 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
5054 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
5055
5056 x += max (0, w->left_margin_cols);
5057 cursor_to (f, y, x);
5058 }
5059 }
5060 }
5061
5062 do_pause:
5063
5064 clear_desired_matrices (f);
5065 return pause_p;
5066 }
5067
5068
5069
5070
5071 static bool
5072 scrolling (struct frame *frame)
5073 {
5074 int unchanged_at_top, unchanged_at_bottom;
5075 int window_size;
5076 int changed_lines;
5077 int i;
5078 int height = FRAME_TOTAL_LINES (frame);
5079 int free_at_end_vpos = height;
5080 struct glyph_matrix *current_matrix = frame->current_matrix;
5081 struct glyph_matrix *desired_matrix = frame->desired_matrix;
5082 verify (sizeof (int) <= sizeof (unsigned));
5083 verify (alignof (unsigned) % alignof (int) == 0);
5084 unsigned *old_hash;
5085 USE_SAFE_ALLOCA;
5086 SAFE_NALLOCA (old_hash, 4, height);
5087 unsigned *new_hash = old_hash + height;
5088 int *draw_cost = (int *) (new_hash + height);
5089 int *old_draw_cost = draw_cost + height;
5090 eassert (current_matrix);
5091
5092
5093
5094
5095 changed_lines = 0;
5096 unchanged_at_top = 0;
5097 unchanged_at_bottom = height;
5098 for (i = 0; i < height; i++)
5099 {
5100
5101 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
5102 {
5103 SAFE_FREE ();
5104 return false;
5105 }
5106 old_hash[i] = line_hash_code (frame, MATRIX_ROW (current_matrix, i));
5107 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
5108 {
5109
5110 new_hash[i] = old_hash[i];
5111 draw_cost[i] = SCROLL_INFINITY;
5112 }
5113 else
5114 {
5115 new_hash[i] = line_hash_code (frame, MATRIX_ROW (desired_matrix, i));
5116 draw_cost[i] = line_draw_cost (frame, desired_matrix, i);
5117 }
5118
5119 if (old_hash[i] != new_hash[i])
5120 {
5121 changed_lines++;
5122 unchanged_at_bottom = height - i - 1;
5123 }
5124 else if (i == unchanged_at_top)
5125 unchanged_at_top++;
5126 old_draw_cost[i] = line_draw_cost (frame, current_matrix, i);
5127 }
5128
5129
5130 if ((!FRAME_SCROLL_REGION_OK (frame)
5131 && changed_lines < baud_rate / 2400)
5132 || unchanged_at_bottom == height)
5133 {
5134 SAFE_FREE ();
5135 return true;
5136 }
5137
5138 window_size = (height - unchanged_at_top
5139 - unchanged_at_bottom);
5140
5141 if (FRAME_SCROLL_REGION_OK (frame))
5142 free_at_end_vpos -= unchanged_at_bottom;
5143 else if (FRAME_MEMORY_BELOW_FRAME (frame))
5144 free_at_end_vpos = -1;
5145
5146
5147
5148
5149 if ((FRAME_SCROLL_REGION_OK (frame)
5150 || window_size < 18 || baud_rate <= 2400
5151 || (window_size
5152 < 10 * scrolling_max_lines_saved (unchanged_at_top,
5153 height - unchanged_at_bottom,
5154 old_hash, new_hash, draw_cost)))
5155 && 2 <= window_size)
5156 scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
5157 draw_cost + unchanged_at_top - 1,
5158 old_draw_cost + unchanged_at_top - 1,
5159 old_hash + unchanged_at_top - 1,
5160 new_hash + unchanged_at_top - 1,
5161 free_at_end_vpos - unchanged_at_top);
5162
5163 SAFE_FREE ();
5164 return false;
5165 }
5166
5167
5168
5169
5170
5171 static int
5172 count_blanks (struct glyph *r, int len)
5173 {
5174 int i;
5175
5176 for (i = 0; i < len; ++i)
5177 if (!CHAR_GLYPH_SPACE_P (r[i]))
5178 break;
5179
5180 return i;
5181 }
5182
5183
5184
5185
5186
5187
5188 static int
5189 count_match (struct glyph *str1, struct glyph *end1, struct glyph *str2, struct glyph *end2)
5190 {
5191 struct glyph *p1 = str1;
5192 struct glyph *p2 = str2;
5193
5194 while (p1 < end1
5195 && p2 < end2
5196 && GLYPH_CHAR_AND_FACE_EQUAL_P (p1, p2))
5197 ++p1, ++p2;
5198
5199 return p1 - str1;
5200 }
5201
5202
5203
5204
5205 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS ((f))])
5206
5207
5208
5209
5210 static void
5211 update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5212 {
5213 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
5214 int tem;
5215 int osp, nsp, begmatch, endmatch, olen, nlen;
5216 struct glyph_matrix *current_matrix = f->current_matrix;
5217 struct glyph_matrix *desired_matrix = f->desired_matrix;
5218 struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
5219 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
5220 bool must_write_whole_line_p;
5221 bool write_spaces_p = FRAME_MUST_WRITE_SPACES (f);
5222 bool colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
5223 != FACE_TTY_DEFAULT_BG_COLOR);
5224
5225 if (colored_spaces_p)
5226 write_spaces_p = 1;
5227
5228
5229
5230 must_write_whole_line_p = !current_row->enabled_p;
5231 if (must_write_whole_line_p)
5232 {
5233 obody = 0;
5234 olen = 0;
5235 }
5236 else
5237 {
5238 obody = MATRIX_ROW_GLYPH_START (current_matrix, vpos);
5239 olen = current_row->used[TEXT_AREA];
5240
5241
5242 if (!write_spaces_p)
5243 while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
5244 olen--;
5245 }
5246
5247 current_row->enabled_p = true;
5248 current_row->used[TEXT_AREA] = desired_row->used[TEXT_AREA];
5249
5250
5251
5252
5253 if (updating_menu_p)
5254 cursor_to (f, 0, 0);
5255
5256
5257 if (!desired_row->enabled_p)
5258 {
5259 nlen = 0;
5260 goto just_erase;
5261 }
5262
5263 nbody = desired_row->glyphs[TEXT_AREA];
5264 nlen = desired_row->used[TEXT_AREA];
5265 nend = nbody + nlen;
5266
5267
5268 if (must_write_whole_line_p)
5269 {
5270
5271 if (!write_spaces_p)
5272 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
5273 --nlen;
5274
5275
5276 if (nlen)
5277 {
5278 cursor_to (f, vpos, 0);
5279 write_glyphs (f, nbody, nlen);
5280 }
5281
5282
5283
5284
5285 if (nlen < FRAME_TOTAL_COLS (f))
5286 {
5287 cursor_to (f, vpos, nlen);
5288 clear_end_of_line (f, FRAME_TOTAL_COLS (f));
5289 }
5290 else
5291
5292
5293 cursor_to (f, vpos, 0);
5294
5295 make_current (desired_matrix, current_matrix, vpos);
5296 return;
5297 }
5298
5299
5300
5301 if (!write_spaces_p)
5302 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
5303 nlen--;
5304
5305
5306 if (!FRAME_CHAR_INS_DEL_OK (f))
5307 {
5308 int i, j;
5309
5310
5311
5312 for (i = 0; i < nlen; i++)
5313 {
5314 if (i >= olen || !GLYPH_EQUAL_P (nbody + i, obody + i))
5315 {
5316
5317 j = i + 1;
5318 while (j < nlen
5319 && (j >= olen
5320 || !GLYPH_EQUAL_P (nbody + j, obody + j)
5321 || CHAR_GLYPH_PADDING_P (nbody[j])))
5322 ++j;
5323
5324
5325 cursor_to (f, vpos, i);
5326 write_glyphs (f, nbody + i, j - i);
5327 i = j - 1;
5328
5329
5330 }
5331 }
5332
5333
5334 if (olen > nlen)
5335 {
5336 cursor_to (f, vpos, nlen);
5337 clear_end_of_line (f, olen);
5338 }
5339
5340
5341 make_current (desired_matrix, current_matrix, vpos);
5342 return;
5343 }
5344
5345
5346
5347
5348 if (!olen)
5349 {
5350
5351
5352 if (write_spaces_p)
5353 nsp = 0;
5354 else
5355 nsp = count_blanks (nbody, nlen);
5356
5357 if (nlen > nsp)
5358 {
5359 cursor_to (f, vpos, nsp);
5360 write_glyphs (f, nbody + nsp, nlen - nsp);
5361 }
5362
5363
5364 make_current (desired_matrix, current_matrix, vpos);
5365 return;
5366 }
5367
5368
5369 osp = count_blanks (obody, olen);
5370 nsp = (colored_spaces_p ? 0 : count_blanks (nbody, nlen));
5371
5372
5373 begmatch = count_match (obody + osp, obody + olen,
5374 nbody + nsp, nbody + nlen);
5375
5376
5377
5378 if (!write_spaces_p && osp + begmatch == olen)
5379 {
5380 np1 = nbody + nsp;
5381 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (np1[begmatch]))
5382 ++begmatch;
5383 }
5384
5385
5386
5387
5388 if (begmatch == 0 && osp != nsp)
5389 osp = nsp = min (osp, nsp);
5390
5391
5392 op1 = obody + olen;
5393 np1 = nbody + nlen;
5394 op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
5395 while (op1 > op2
5396 && GLYPH_EQUAL_P (op1 - 1, np1 - 1))
5397 {
5398 op1--;
5399 np1--;
5400 }
5401 endmatch = obody + olen - op1;
5402
5403
5404
5405
5406
5407 tem = (nlen - nsp) - (olen - osp);
5408 if (endmatch && tem
5409 && (!FRAME_CHAR_INS_DEL_OK (f)
5410 || endmatch <= char_ins_del_cost (f)[tem]))
5411 endmatch = 0;
5412
5413
5414
5415
5416
5417
5418 if (nsp != osp
5419 && (!FRAME_CHAR_INS_DEL_OK (f)
5420 || begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]))
5421 {
5422 begmatch = 0;
5423 endmatch = 0;
5424 osp = nsp = min (osp, nsp);
5425 }
5426
5427
5428
5429
5430 if (osp > nsp)
5431 {
5432 cursor_to (f, vpos, nsp);
5433 delete_glyphs (f, osp - nsp);
5434 }
5435 else if (nsp > osp)
5436 {
5437
5438
5439
5440 if (endmatch && nlen < olen + nsp - osp)
5441 {
5442 cursor_to (f, vpos, nlen - endmatch + osp - nsp);
5443 delete_glyphs (f, olen + nsp - osp - nlen);
5444 olen = nlen - (nsp - osp);
5445 }
5446 cursor_to (f, vpos, osp);
5447 insert_glyphs (f, 0, nsp - osp);
5448 }
5449 olen += nsp - osp;
5450
5451 tem = nsp + begmatch + endmatch;
5452 if (nlen != tem || olen != tem)
5453 {
5454 if (!endmatch || nlen == olen)
5455 {
5456
5457
5458
5459
5460 if (nlen == FRAME_TOTAL_COLS (f))
5461 olen = 0;
5462
5463
5464
5465
5466 if (nlen - tem > 0)
5467 {
5468 cursor_to (f, vpos, nsp + begmatch);
5469 write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
5470 }
5471 }
5472 else if (nlen > olen)
5473 {
5474
5475
5476
5477
5478
5479
5480
5481 int out = olen - tem;
5482 int del;
5483
5484 cursor_to (f, vpos, nsp + begmatch);
5485
5486
5487 while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out]))
5488 out--;
5489 write_glyphs (f, nbody + nsp + begmatch, out);
5490
5491
5492 del = olen - tem - out;
5493 if (del > 0)
5494 delete_glyphs (f, del);
5495
5496
5497 insert_glyphs (f, nbody + nsp + begmatch + out, nlen - olen + del);
5498 olen = nlen;
5499 }
5500 else if (olen > nlen)
5501 {
5502 cursor_to (f, vpos, nsp + begmatch);
5503 write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
5504 delete_glyphs (f, olen - nlen);
5505 olen = nlen;
5506 }
5507 }
5508
5509 just_erase:
5510
5511 if (olen > nlen)
5512 {
5513 cursor_to (f, vpos, nlen);
5514 clear_end_of_line (f, olen);
5515 }
5516
5517
5518 make_current (desired_matrix, current_matrix, vpos);
5519 }
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540 Lisp_Object
5541 buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *pos, Lisp_Object *object, int *dx, int *dy, int *width, int *height)
5542 {
5543 struct it it;
5544 Lisp_Object old_current_buffer = Fcurrent_buffer ();
5545 struct text_pos startp;
5546 Lisp_Object string;
5547 struct glyph_row *row;
5548 #ifdef HAVE_WINDOW_SYSTEM
5549 struct image *img = 0;
5550 #endif
5551 int x0, x1, to_x, it_vpos;
5552 void *itdata = NULL;
5553
5554
5555
5556 Fset_buffer (w->contents);
5557 itdata = bidi_shelve_cache ();
5558 CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
5559 start_display (&it, w, startp);
5560 x0 = *x;
5561
5562
5563
5564
5565 move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y);
5566
5567
5568
5569 to_x = x0;
5570 if (it.bidi_it.paragraph_dir == R2L)
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581 to_x = window_box_width (w, TEXT_AREA) - to_x - 1;
5582
5583
5584
5585 to_x += it.first_visible_x;
5586
5587
5588
5589
5590 if (it.line_wrap == TRUNCATE
5591 && EQ (automatic_hscrolling, Qcurrent_line) && IT_CHARPOS (it) < PT)
5592 {
5593 struct it it2 = it;
5594 void *it2data = bidi_shelve_cache ();
5595 it2.last_visible_x = 1000000;
5596
5597
5598 move_it_in_display_line (&it2, PT, -1, MOVE_TO_POS);
5599 if (IT_CHARPOS (it2) >= PT)
5600 {
5601 to_x += (w->hscroll - w->min_hscroll) * FRAME_COLUMN_WIDTH (it.f);
5602
5603
5604 it.first_visible_x += w->hscroll * FRAME_COLUMN_WIDTH (it.f);
5605 it.last_visible_x += w->hscroll * FRAME_COLUMN_WIDTH (it.f);
5606 }
5607 bidi_unshelve_cache (it2data, 0);
5608 }
5609
5610
5611
5612
5613 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
5614 bidi_unshelve_cache (itdata, 0);
5615
5616 Fset_buffer (old_current_buffer);
5617
5618 *dx = to_x - it.current_x;
5619 *dy = *y - it.current_y;
5620
5621 string = w->contents;
5622 if (STRINGP (it.string))
5623 string = it.string;
5624 *pos = it.current;
5625 if (it.what == IT_COMPOSITION
5626 && it.cmp_it.nchars > 1
5627 && it.cmp_it.reversed_p)
5628 {
5629
5630
5631
5632
5633
5634
5635 CHARPOS (pos->pos) -= it.cmp_it.nchars - 1;
5636 if (STRINGP (it.string))
5637 BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
5638 else
5639 BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->contents),
5640 CHARPOS (pos->pos));
5641 }
5642
5643 #ifdef HAVE_WINDOW_SYSTEM
5644 if (it.what == IT_IMAGE)
5645 {
5646
5647
5648
5649
5650
5651 img = IMAGE_OPT_FROM_ID (it.f, it.image_id);
5652 if (img && !NILP (img->spec))
5653 *object = img->spec;
5654 }
5655 #endif
5656
5657
5658
5659
5660
5661 it_vpos = it.vpos + window_wants_header_line (w)
5662 + window_wants_tab_line (w);
5663 if (it_vpos < w->current_matrix->nrows
5664 && (row = MATRIX_ROW (w->current_matrix, it_vpos),
5665 row->enabled_p))
5666 {
5667 if (it.hpos < row->used[TEXT_AREA])
5668 {
5669 struct glyph *glyph = row->glyphs[TEXT_AREA] + it.hpos;
5670 #ifdef HAVE_WINDOW_SYSTEM
5671 if (img)
5672 {
5673 *dy -= row->ascent - glyph->ascent;
5674 *dx += glyph->slice.img.x;
5675 *dy += glyph->slice.img.y;
5676
5677 *width = img->width;
5678 *height = img->height;
5679 }
5680 else
5681 #endif
5682 {
5683 *width = glyph->pixel_width;
5684 *height = glyph->ascent + glyph->descent;
5685 }
5686 }
5687 else
5688 {
5689 *width = 0;
5690 *height = row->height;
5691 }
5692 }
5693 else
5694 {
5695 *width = *height = 0;
5696 }
5697
5698
5699 x1 = max (0, it.current_x + it.pixel_width);
5700 if (to_x > x1)
5701 it.hpos += (to_x - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
5702
5703 *x = it.hpos;
5704 *y = it.vpos;
5705
5706 return string;
5707 }
5708
5709
5710
5711
5712
5713
5714 Lisp_Object
5715 mode_line_string (struct window *w, enum window_part part,
5716 int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
5717 int *dx, int *dy, int *width, int *height)
5718 {
5719 struct glyph_row *row;
5720 struct glyph *glyph, *end;
5721 int x0, y0;
5722 Lisp_Object string = Qnil;
5723
5724 if (part == ON_MODE_LINE)
5725 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
5726 else if (part == ON_TAB_LINE)
5727 row = MATRIX_TAB_LINE_ROW (w->current_matrix);
5728 else
5729 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
5730 y0 = *y - row->y;
5731 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5732
5733 if (row->mode_line_p && row->enabled_p)
5734 {
5735
5736
5737 glyph = row->glyphs[TEXT_AREA];
5738 end = glyph + row->used[TEXT_AREA];
5739 for (x0 = *x; glyph < end && x0 >= glyph->pixel_width; ++glyph)
5740 x0 -= glyph->pixel_width;
5741 *x = glyph - row->glyphs[TEXT_AREA];
5742 if (glyph < end)
5743 {
5744 string = glyph->object;
5745 *charpos = glyph->charpos;
5746 *width = glyph->pixel_width;
5747 *height = glyph->ascent + glyph->descent;
5748 #ifdef HAVE_WINDOW_SYSTEM
5749 if (glyph->type == IMAGE_GLYPH)
5750 {
5751 struct image *img;
5752 img = IMAGE_OPT_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
5753 if (img != NULL)
5754 *object = img->spec;
5755 y0 -= row->ascent - glyph->ascent;
5756 }
5757 #endif
5758 }
5759 else
5760 {
5761
5762 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5763 *width = 0;
5764 *height = row->height;
5765 }
5766 }
5767 else
5768 {
5769 *x = 0;
5770 x0 = 0;
5771 *width = *height = 0;
5772 }
5773
5774 *dx = x0;
5775 *dy = y0;
5776
5777 return string;
5778 }
5779
5780
5781
5782
5783
5784
5785 Lisp_Object
5786 marginal_area_string (struct window *w, enum window_part part,
5787 int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
5788 int *dx, int *dy, int *width, int *height)
5789 {
5790 struct glyph_row *row = w->current_matrix->rows;
5791 struct glyph *glyph, *end;
5792 int x0, y0, i, wy = *y;
5793 int area;
5794 Lisp_Object string = Qnil;
5795
5796 if (part == ON_LEFT_MARGIN)
5797 area = LEFT_MARGIN_AREA;
5798 else if (part == ON_RIGHT_MARGIN)
5799 area = RIGHT_MARGIN_AREA;
5800 else
5801 emacs_abort ();
5802
5803 for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row)
5804 if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row))
5805 break;
5806 y0 = *y - row->y;
5807 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5808
5809 if (row->enabled_p)
5810 {
5811
5812
5813 if (area == RIGHT_MARGIN_AREA)
5814 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5815 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5816 : WINDOW_FRINGES_WIDTH (w))
5817 + window_box_width (w, LEFT_MARGIN_AREA)
5818 + window_box_width (w, TEXT_AREA));
5819 else
5820 x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5821 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5822 : 0);
5823
5824 glyph = row->glyphs[area];
5825 end = glyph + row->used[area];
5826 for (x0 = *x - x0; glyph < end && x0 >= glyph->pixel_width; ++glyph)
5827 x0 -= glyph->pixel_width;
5828 *x = glyph - row->glyphs[area];
5829 if (glyph < end)
5830 {
5831 string = glyph->object;
5832 *charpos = glyph->charpos;
5833 *width = glyph->pixel_width;
5834 *height = glyph->ascent + glyph->descent;
5835 #ifdef HAVE_WINDOW_SYSTEM
5836 if (glyph->type == IMAGE_GLYPH)
5837 {
5838 struct image *img;
5839 img = IMAGE_OPT_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
5840 if (img != NULL)
5841 *object = img->spec;
5842 y0 -= row->ascent - glyph->ascent;
5843 x0 += glyph->slice.img.x;
5844 y0 += glyph->slice.img.y;
5845 }
5846 #endif
5847 }
5848 else
5849 {
5850
5851 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5852 *width = 0;
5853 *height = row->height;
5854 }
5855 }
5856 else
5857 {
5858 x0 = 0;
5859 *x = 0;
5860 *width = *height = 0;
5861 }
5862
5863 *dx = x0;
5864 *dy = y0;
5865
5866 return string;
5867 }
5868
5869
5870
5871
5872
5873
5874 #ifdef SIGWINCH
5875
5876 static void deliver_window_change_signal (int);
5877
5878 static void
5879 handle_window_change_signal (int sig)
5880 {
5881 int width, height;
5882 struct tty_display_info *tty;
5883
5884
5885
5886
5887
5888 for (tty = tty_list; tty; tty = tty->next)
5889 {
5890 if (! tty->term_initted)
5891 continue;
5892
5893
5894
5895 if (!tty->input)
5896 continue;
5897
5898 get_tty_size (fileno (tty->input), &width, &height);
5899
5900 if (width > 5 && height > 2)
5901 {
5902 Lisp_Object tail, frame;
5903
5904 FOR_EACH_FRAME (tail, frame)
5905 {
5906 struct frame *f = XFRAME (frame);
5907
5908 if (FRAME_TERMCAP_P (f) && FRAME_TTY (f) == tty)
5909
5910
5911
5912 change_frame_size (f, width, height, false, true, false);
5913 }
5914 }
5915 }
5916 }
5917
5918 static void
5919 deliver_window_change_signal (int sig)
5920 {
5921 deliver_process_signal (sig, handle_window_change_signal);
5922 }
5923 #endif
5924
5925
5926
5927
5928
5929
5930 void
5931 do_pending_window_change (bool safe)
5932 {
5933 if (redisplaying_p && !safe)
5934 return;
5935
5936 while (delayed_size_change)
5937 {
5938 Lisp_Object tail, frame;
5939
5940 delayed_size_change = false;
5941
5942 FOR_EACH_FRAME (tail, frame)
5943 {
5944 struct frame *f = XFRAME (frame);
5945
5946
5947
5948
5949
5950
5951 if (f->new_size_p && (f->new_height >= 0 || f->new_width >= 0))
5952 change_frame_size (f, f->new_width, f->new_height,
5953 false, false, safe);
5954 }
5955 }
5956 }
5957
5958
5959 static void
5960 change_frame_size_1 (struct frame *f, int new_width, int new_height,
5961 bool pretend, bool delay, bool safe)
5962 {
5963 if (delay || (redisplaying_p && !safe))
5964 {
5965 if (CONSP (frame_size_history)
5966 && ((new_width != f->new_width
5967 || new_height != f->new_height
5968 || new_width != FRAME_PIXEL_WIDTH (f)
5969 || new_height != FRAME_PIXEL_HEIGHT (f))))
5970 frame_size_history_extra
5971 (f, build_string ("change_frame_size_1, delayed"),
5972 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
5973 new_width, new_height, f->new_width, f->new_height);
5974
5975
5976 f->new_width = new_width;
5977 f->new_height = new_height;
5978 f->new_size_p = true;
5979 delayed_size_change = true;
5980 }
5981 else
5982 {
5983
5984
5985
5986 f->new_height = -1;
5987 f->new_width = -1;
5988 f->new_size_p = false;
5989
5990
5991
5992 adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, new_width),
5993 FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_height), 5,
5994 pretend, Qchange_frame_size);
5995 }
5996 }
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008 void
6009 change_frame_size (struct frame *f, int new_width, int new_height,
6010 bool pretend, bool delay, bool safe)
6011 {
6012 Lisp_Object tail, frame;
6013
6014 if (FRAME_MSDOS_P (f))
6015 {
6016
6017
6018
6019 FOR_EACH_FRAME (tail, frame)
6020 if (!FRAME_WINDOW_P (XFRAME (frame)))
6021 change_frame_size_1 (XFRAME (frame), new_width, new_height,
6022 pretend, delay, safe);
6023 }
6024 else
6025 change_frame_size_1 (f, new_width, new_height, pretend, delay, safe);
6026 }
6027
6028
6029
6030
6031
6032 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
6033 1, 1, "FOpen termscript file: ",
6034 doc:
6035 )
6036 (Lisp_Object file)
6037 {
6038 struct tty_display_info *tty;
6039
6040 if (! FRAME_TERMCAP_P (SELECTED_FRAME ())
6041 && ! FRAME_MSDOS_P (SELECTED_FRAME ()))
6042 error ("Current frame is not on a tty device");
6043
6044 tty = CURTTY ();
6045
6046 if (tty->termscript != 0)
6047 {
6048 block_input ();
6049 fclose (tty->termscript);
6050 tty->termscript = 0;
6051 unblock_input ();
6052 }
6053
6054 if (! NILP (file))
6055 {
6056 file = Fexpand_file_name (file, Qnil);
6057 tty->termscript = emacs_fopen (SSDATA (file), "w");
6058 if (tty->termscript == 0)
6059 report_file_error ("Opening termscript", file);
6060 }
6061 return Qnil;
6062 }
6063
6064
6065 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
6066 Ssend_string_to_terminal, 1, 2, 0,
6067 doc:
6068
6069
6070
6071
6072
6073 )
6074 (Lisp_Object string, Lisp_Object terminal)
6075 {
6076 struct terminal *t = decode_live_terminal (terminal);
6077 FILE *out;
6078
6079
6080 CHECK_STRING (string);
6081 block_input ();
6082
6083 if (t->type == output_initial)
6084 out = stdout;
6085 else if (t->type != output_termcap && t->type != output_msdos_raw)
6086 error ("Device %d is not a termcap terminal device", t->id);
6087 else
6088 {
6089 struct tty_display_info *tty = t->display_info.tty;
6090
6091 if (! tty->output)
6092 error ("Terminal is currently suspended");
6093
6094 if (tty->termscript)
6095 {
6096 fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
6097 fflush (tty->termscript);
6098 }
6099 out = tty->output;
6100 }
6101
6102
6103 unrequest_sigio ();
6104 fwrite (SDATA (string), 1, SBYTES (string), out);
6105 fflush (out);
6106 request_sigio ();
6107 unblock_input ();
6108 return Qnil;
6109 }
6110
6111
6112 DEFUN ("ding", Fding, Sding, 0, 1, 0,
6113 doc:
6114
6115 )
6116 (Lisp_Object arg)
6117 {
6118 if (!NILP (arg))
6119 {
6120 if (noninteractive)
6121 putchar (07);
6122 else
6123 ring_bell (XFRAME (selected_frame));
6124 }
6125 else
6126 bitch_at_user ();
6127
6128 return Qnil;
6129 }
6130
6131 void
6132 bitch_at_user (void)
6133 {
6134 if (noninteractive)
6135 putchar (07);
6136 else if (!INTERACTIVE)
6137 {
6138 const char *msg
6139 = "Keyboard macro terminated by a command ringing the bell";
6140 Fsignal (Quser_error, list1 (build_string (msg)));
6141 }
6142 else
6143 ring_bell (XFRAME (selected_frame));
6144 }
6145
6146
6147
6148
6149
6150
6151
6152 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
6153 doc:
6154
6155
6156
6157 )
6158 (Lisp_Object seconds, Lisp_Object milliseconds)
6159 {
6160 double duration = extract_float (seconds);
6161
6162 if (!NILP (milliseconds))
6163 {
6164 CHECK_FIXNUM (milliseconds);
6165 duration += XFIXNUM (milliseconds) / 1000.0;
6166 }
6167
6168 if (duration > 0)
6169 {
6170 struct timespec t = dtotimespec (duration);
6171 struct timespec tend = timespec_add (current_timespec (), t);
6172
6173
6174
6175
6176 do {
6177 wait_reading_process_output (min (t.tv_sec, WAIT_READING_MAX),
6178 t.tv_nsec, 0, 0, Qnil, NULL, 0);
6179 t = timespec_sub (tend, current_timespec ());
6180 } while (timespec_sign (t) > 0);
6181 }
6182
6183 return Qnil;
6184 }
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204 Lisp_Object
6205 sit_for (Lisp_Object timeout, bool reading, int display_option)
6206 {
6207 intmax_t sec;
6208 int nsec;
6209 bool do_display = display_option > 0;
6210 bool curbuf_eq_winbuf
6211 = (current_buffer == XBUFFER (XWINDOW (selected_window)->contents));
6212
6213 swallow_events (do_display);
6214
6215 if ((detect_input_pending_run_timers (do_display))
6216 || !NILP (Vexecuting_kbd_macro))
6217 return Qnil;
6218
6219 if (display_option > 1)
6220 redisplay_preserve_echo_area (2);
6221
6222 if (INTEGERP (timeout))
6223 {
6224 if (integer_to_intmax (timeout, &sec))
6225 {
6226 if (sec <= 0)
6227 return Qt;
6228 sec = min (sec, WAIT_READING_MAX);
6229 }
6230 else
6231 {
6232 if (NILP (Fnatnump (timeout)))
6233 return Qt;
6234 sec = WAIT_READING_MAX;
6235 }
6236 nsec = 0;
6237 }
6238 else if (FLOATP (timeout))
6239 {
6240 double seconds = XFLOAT_DATA (timeout);
6241 if (! (0 < seconds))
6242 return Qt;
6243 else
6244 {
6245 struct timespec t = dtotimespec (seconds);
6246 sec = min (t.tv_sec, WAIT_READING_MAX);
6247 nsec = t.tv_nsec;
6248 }
6249 }
6250 else if (EQ (timeout, Qt))
6251 {
6252 sec = 0;
6253 nsec = 0;
6254 }
6255 else
6256 wrong_type_argument (Qnumberp, timeout);
6257
6258
6259 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
6260 gobble_input ();
6261 #endif
6262
6263 int nbytes
6264 = wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display,
6265 Qnil, NULL, 0);
6266
6267 if (reading && curbuf_eq_winbuf)
6268
6269
6270
6271
6272 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
6273
6274 return (nbytes > 0 || detect_input_pending ()) ? Qnil : Qt;
6275 }
6276
6277
6278 DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0,
6279 doc:
6280
6281
6282
6283
6284
6285
6286 )
6287 (Lisp_Object force)
6288 {
6289 swallow_events (true);
6290 if ((detect_input_pending_run_timers (1)
6291 && NILP (force) && !redisplay_dont_pause)
6292 || !NILP (Vexecuting_kbd_macro))
6293 return Qnil;
6294
6295 specpdl_ref count = SPECPDL_INDEX ();
6296 if (!NILP (force) && !redisplay_dont_pause)
6297 specbind (Qredisplay_dont_pause, Qt);
6298 redisplay_preserve_echo_area (2);
6299 return unbind_to (count, Qt);
6300 }
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312 static Lisp_Object frame_and_buffer_state;
6313
6314
6315 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
6316 Sframe_or_buffer_changed_p, 0, 1, 0,
6317 doc:
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327 )
6328 (Lisp_Object variable)
6329 {
6330 Lisp_Object state, tail, frame, buf;
6331 ptrdiff_t n, idx;
6332
6333 if (! NILP (variable))
6334 {
6335 CHECK_SYMBOL (variable);
6336 state = Fsymbol_value (variable);
6337 if (! VECTORP (state))
6338 goto changed;
6339 }
6340 else
6341 state = frame_and_buffer_state;
6342
6343 idx = 0;
6344 FOR_EACH_FRAME (tail, frame)
6345 {
6346 if (idx == ASIZE (state))
6347 goto changed;
6348 if (!BASE_EQ (AREF (state, idx++), frame))
6349 goto changed;
6350 if (idx == ASIZE (state))
6351 goto changed;
6352 if (!EQ (AREF (state, idx++), XFRAME (frame)->name))
6353 goto changed;
6354 }
6355
6356 FOR_EACH_LIVE_BUFFER (tail, buf)
6357 {
6358
6359 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
6360 continue;
6361 if (idx == ASIZE (state))
6362 goto changed;
6363 if (!BASE_EQ (AREF (state, idx++), buf))
6364 goto changed;
6365 if (idx == ASIZE (state))
6366 goto changed;
6367 if (!EQ (AREF (state, idx++), BVAR (XBUFFER (buf), read_only)))
6368 goto changed;
6369 if (idx == ASIZE (state))
6370 goto changed;
6371 if (!EQ (AREF (state, idx++), Fbuffer_modified_p (buf)))
6372 goto changed;
6373 }
6374 if (idx == ASIZE (state))
6375 goto changed;
6376
6377 if (EQ (AREF (state, idx), Qlambda))
6378 return Qnil;
6379
6380
6381 changed:
6382
6383
6384 n = 1;
6385 FOR_EACH_FRAME (tail, frame)
6386 n += 2;
6387 FOR_EACH_LIVE_BUFFER (tail, buf)
6388 n += 3;
6389
6390
6391 if (! VECTORP (state)
6392 || n > ASIZE (state)
6393 || n + 20 < ASIZE (state) / 2)
6394
6395 {
6396 state = make_vector (n + 20, Qlambda);
6397 if (! NILP (variable))
6398 Fset (variable, state);
6399 else
6400 frame_and_buffer_state = state;
6401 }
6402
6403
6404 idx = 0;
6405 FOR_EACH_FRAME (tail, frame)
6406 {
6407 ASET (state, idx, frame);
6408 idx++;
6409 ASET (state, idx, XFRAME (frame)->name);
6410 idx++;
6411 }
6412 FOR_EACH_LIVE_BUFFER (tail, buf)
6413 {
6414
6415 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
6416 continue;
6417 ASET (state, idx, buf);
6418 idx++;
6419 ASET (state, idx, BVAR (XBUFFER (buf), read_only));
6420 idx++;
6421 ASET (state, idx, Fbuffer_modified_p (buf));
6422 idx++;
6423 }
6424
6425 ASET (state, idx, Qlambda);
6426 idx++;
6427 while (idx < ASIZE (state))
6428 {
6429 ASET (state, idx, Qlambda);
6430 idx++;
6431 }
6432
6433 eassert (idx <= ASIZE (state));
6434 return Qt;
6435 }
6436
6437
6438
6439
6440
6441
6442
6443 static void
6444 init_faces_initial (void)
6445 {
6446
6447
6448 struct frame *sf = SELECTED_FRAME ();
6449
6450 FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
6451 FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;
6452 call0 (intern ("tty-set-up-initial-frame-faces"));
6453 }
6454
6455
6456
6457
6458
6459 static void
6460 init_display_interactive (void)
6461 {
6462 char *terminal_type;
6463
6464
6465 space_glyph.type = CHAR_GLYPH;
6466 SET_CHAR_GLYPH (space_glyph, ' ', DEFAULT_FACE_ID, 0);
6467 space_glyph.charpos = -1;
6468
6469 inverse_video = 0;
6470 cursor_in_echo_area = false;
6471
6472
6473
6474 Vinitial_window_system = Qnil;
6475
6476
6477
6478
6479 #ifdef SIGWINCH
6480 if (!will_dump_p ())
6481 {
6482 struct sigaction action;
6483 emacs_sigaction_init (&action, deliver_window_change_signal);
6484 sigaction (SIGWINCH, &action, 0);
6485 }
6486 #endif
6487
6488
6489
6490 if (IS_DAEMON)
6491 {
6492
6493
6494
6495
6496
6497
6498
6499 if (dumped_with_pdumper_p ())
6500 init_faces_initial ();
6501 #ifndef WINDOWSNT
6502 return;
6503 #endif
6504 }
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515 #ifdef HAVE_X_WINDOWS
6516 if (! inhibit_window_system && ! display_arg)
6517 {
6518 char *display;
6519 display = getenv ("DISPLAY");
6520 display_arg = (display != 0 && *display != 0);
6521
6522 if (display_arg && !x_display_ok (display))
6523 {
6524 fprintf (stderr, "Display %s unavailable, simulating -nw\n",
6525 display);
6526 inhibit_window_system = 1;
6527 }
6528 }
6529
6530 if (!inhibit_window_system && display_arg)
6531 {
6532 Vinitial_window_system = Qx;
6533 #ifdef USE_NCURSES
6534
6535
6536
6537 { char b[2044]; tgetent (b, "xterm");}
6538 #endif
6539 return;
6540 }
6541 #endif
6542
6543 #ifdef HAVE_NTGUI
6544 if (!inhibit_window_system)
6545 {
6546 Vinitial_window_system = Qw32;
6547 return;
6548 }
6549 #endif
6550
6551 #ifdef HAVE_NS
6552 if (!inhibit_window_system && !will_dump_p ())
6553 {
6554 Vinitial_window_system = Qns;
6555 return;
6556 }
6557 #endif
6558
6559 #ifdef HAVE_PGTK
6560 if (!inhibit_window_system && !will_dump_p ())
6561 {
6562 Vinitial_window_system = Qpgtk;
6563 return;
6564 }
6565 #endif
6566
6567 #ifdef HAVE_HAIKU
6568 if (!inhibit_window_system && !will_dump_p ())
6569 {
6570 Vinitial_window_system = Qhaiku;
6571 return;
6572 }
6573 #endif
6574
6575
6576 if (! isatty (STDIN_FILENO))
6577 fatal ("standard input is not a tty");
6578
6579 #ifdef WINDOWSNT
6580 terminal_type = (char *)"w32console";
6581 #else
6582 terminal_type = getenv ("TERM");
6583 #endif
6584 if (!terminal_type)
6585 {
6586 char const *msg
6587 = "Please set the environment variable TERM; see 'tset'.\n";
6588 #ifdef HAVE_WINDOW_SYSTEM
6589 if (! inhibit_window_system)
6590 msg = ("Please set the environment variable DISPLAY or TERM; "
6591 "see 'tset'.\n");
6592 #endif
6593 fputs (msg, stderr);
6594 exit (1);
6595 }
6596
6597 {
6598 struct terminal *t;
6599 struct frame *f = XFRAME (selected_frame);
6600
6601 init_foreground_group ();
6602
6603
6604 t = init_tty (0, terminal_type, 1);
6605
6606
6607 if (f->output_method != output_initial)
6608 emacs_abort ();
6609 f->output_method = t->type;
6610 f->terminal = t;
6611
6612 t->reference_count++;
6613 #ifdef MSDOS
6614 f->output_data.tty = &the_only_tty_output;
6615 f->output_data.tty->display_info = &the_only_display_info;
6616 #else
6617 if (f->output_method == output_termcap)
6618 create_tty_output (f);
6619 #endif
6620 t->display_info.tty->top_frame = selected_frame;
6621 change_frame_size (XFRAME (selected_frame),
6622 FrameCols (t->display_info.tty),
6623 FrameRows (t->display_info.tty),
6624 false, false, true);
6625
6626
6627 if (--initial_terminal->reference_count == 0
6628 && initial_terminal->delete_terminal_hook)
6629 (*initial_terminal->delete_terminal_hook) (initial_terminal);
6630
6631
6632 AUTO_FRAME_ARG (tty_type_arg, Qtty_type, Ftty_type (selected_frame));
6633 Fmodify_frame_parameters (selected_frame, tty_type_arg);
6634 AUTO_FRAME_ARG (tty_arg, Qtty, (t->display_info.tty->name
6635 ? build_string (t->display_info.tty->name)
6636 : Qnil));
6637 Fmodify_frame_parameters (selected_frame, tty_arg);
6638 }
6639
6640 {
6641 struct frame *sf = SELECTED_FRAME ();
6642 int width = FRAME_TOTAL_COLS (sf);
6643 int height = FRAME_TOTAL_LINES (sf);
6644 int area;
6645
6646
6647
6648
6649
6650 if (INT_ADD_WRAPV (width, 2, &area)
6651 || INT_MULTIPLY_WRAPV (height, area, &area)
6652 || min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) < area)
6653 fatal ("screen size %dx%d too big", width, height);
6654 }
6655
6656 calculate_costs (XFRAME (selected_frame));
6657
6658
6659 if (initialized && !noninteractive && NILP (Vinitial_window_system))
6660 init_faces_initial ();
6661 }
6662
6663 void
6664 init_display (void)
6665 {
6666 if (noninteractive)
6667 {
6668 if (dumped_with_pdumper_p ())
6669 init_faces_initial ();
6670 }
6671 else
6672 init_display_interactive ();
6673 }
6674
6675
6676
6677
6678
6679
6680 DEFUN ("internal-show-cursor", Finternal_show_cursor,
6681 Sinternal_show_cursor, 2, 2, 0,
6682 doc:
6683
6684
6685 )
6686 (Lisp_Object window, Lisp_Object show)
6687 {
6688
6689
6690 if (!redisplaying_p)
6691 decode_any_window (window)->cursor_off_p = NILP (show);
6692 return Qnil;
6693 }
6694
6695
6696 DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
6697 Sinternal_show_cursor_p, 0, 1, 0,
6698 doc:
6699 )
6700 (Lisp_Object window)
6701 {
6702 return decode_any_window (window)->cursor_off_p ? Qnil : Qt;
6703 }
6704
6705
6706
6707
6708
6709 static void syms_of_display_for_pdumper (void);
6710
6711 void
6712 syms_of_display (void)
6713 {
6714 defsubr (&Sredraw_frame);
6715 defsubr (&Sredraw_display);
6716 defsubr (&Sdisplay__update_for_mouse_movement);
6717 defsubr (&Sframe_or_buffer_changed_p);
6718 defsubr (&Sopen_termscript);
6719 defsubr (&Sding);
6720 defsubr (&Sredisplay);
6721 defsubr (&Ssleep_for);
6722 defsubr (&Ssend_string_to_terminal);
6723 defsubr (&Sinternal_show_cursor);
6724 defsubr (&Sinternal_show_cursor_p);
6725
6726 #ifdef GLYPH_DEBUG
6727 defsubr (&Sdump_redisplay_history);
6728 #endif
6729
6730 frame_and_buffer_state = make_vector (20, Qlambda);
6731 staticpro (&frame_and_buffer_state);
6732
6733
6734 DEFSYM (Qdisplay_table, "display-table");
6735
6736 DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
6737
6738 DEFVAR_INT ("baud-rate", baud_rate,
6739 doc:
6740
6741 );
6742
6743 DEFVAR_BOOL ("inverse-video", inverse_video,
6744 doc:
6745 );
6746
6747 DEFVAR_BOOL ("visible-bell", visible_bell,
6748 doc:
6749
6750 );
6751
6752 DEFVAR_BOOL ("no-redraw-on-reenter", no_redraw_on_reenter,
6753 doc:
6754
6755
6756 );
6757
6758 DEFVAR_LISP ("initial-window-system", Vinitial_window_system,
6759 doc:
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771 );
6772
6773 DEFVAR_KBOARD ("window-system", Vwindow_system,
6774 doc:
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786 );
6787
6788 DEFVAR_BOOL ("cursor-in-echo-area", cursor_in_echo_area,
6789 doc: );
6790
6791 DEFVAR_LISP ("glyph-table", Vglyph_table,
6792 doc:
6793
6794
6795
6796
6797
6798
6799 );
6800 Vglyph_table = Qnil;
6801
6802 DEFVAR_LISP ("standard-display-table", Vstandard_display_table,
6803 doc:
6804
6805 );
6806 Vstandard_display_table = Qnil;
6807
6808 DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause,
6809 doc: );
6810
6811
6812
6813
6814
6815
6816
6817 redisplay_dont_pause = true;
6818
6819 DEFVAR_LISP ("x-show-tooltip-timeout", Vx_show_tooltip_timeout,
6820 doc: );
6821 Vx_show_tooltip_timeout = make_fixnum (5);
6822
6823 DEFVAR_LISP ("tab-bar-position", Vtab_bar_position,
6824 doc:
6825
6826 );
6827
6828 pdumper_do_now_and_after_load (syms_of_display_for_pdumper);
6829 }
6830
6831 static void
6832 syms_of_display_for_pdumper (void)
6833 {
6834 Vinitial_window_system = Qnil;
6835 }