aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/dispnew.c191
1 files changed, 174 insertions, 17 deletions
diff --git a/src/dispnew.c b/src/dispnew.c
index a7e3363e674..cac7a051767 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -109,6 +109,8 @@ struct dim
109 109
110/* Function prototypes. */ 110/* Function prototypes. */
111 111
112static void redraw_overlapping_rows P_ ((struct window *, int));
113static void redraw_overlapped_rows P_ ((struct window *, int));
112static int count_blanks P_ ((struct glyph *, int)); 114static int count_blanks P_ ((struct glyph *, int));
113static int count_match P_ ((struct glyph *, struct glyph *, 115static int count_match P_ ((struct glyph *, struct glyph *,
114 struct glyph *, struct glyph *)); 116 struct glyph *, struct glyph *));
@@ -146,9 +148,9 @@ void scroll_glyph_matrix_range P_ ((struct glyph_matrix *, int, int,
146static void clear_window_matrices P_ ((struct window *, int)); 148static void clear_window_matrices P_ ((struct window *, int));
147static void fill_up_glyph_row_area_with_spaces P_ ((struct glyph_row *, int)); 149static void fill_up_glyph_row_area_with_spaces P_ ((struct glyph_row *, int));
148static int scrolling_window P_ ((struct window *, int)); 150static int scrolling_window P_ ((struct window *, int));
149static void update_window_line P_ ((struct window *, int)); 151static int update_window_line P_ ((struct window *, int));
150static void update_marginal_area P_ ((struct window *, int, int)); 152static void update_marginal_area P_ ((struct window *, int, int));
151static void update_text_area P_ ((struct window *, int)); 153static int update_text_area P_ ((struct window *, int));
152static void make_current P_ ((struct glyph_matrix *, struct glyph_matrix *, 154static void make_current P_ ((struct glyph_matrix *, struct glyph_matrix *,
153 int)); 155 int));
154static void mirror_make_current P_ ((struct window *, int)); 156static void mirror_make_current P_ ((struct window *, int));
@@ -999,8 +1001,8 @@ blank_row (w, row, y)
999 1001
1000 clear_glyph_row (row); 1002 clear_glyph_row (row);
1001 row->y = y; 1003 row->y = y;
1002 row->ascent = 0; 1004 row->ascent = row->phys_ascent = 0;
1003 row->height = CANON_Y_UNIT (XFRAME (WINDOW_FRAME (w))); 1005 row->height = row->phys_height = CANON_Y_UNIT (XFRAME (w->frame));
1004 1006
1005 if (row->y < min_y) 1007 if (row->y < min_y)
1006 row->visible_height = row->height - (min_y - row->y); 1008 row->visible_height = row->height - (min_y - row->y);
@@ -1361,12 +1363,15 @@ row_equal_p (w, a, b)
1361 || a->overlay_arrow_p != b->overlay_arrow_p 1363 || a->overlay_arrow_p != b->overlay_arrow_p
1362 || a->continued_p != b->continued_p 1364 || a->continued_p != b->continued_p
1363 || a->indicate_empty_line_p != b->indicate_empty_line_p 1365 || a->indicate_empty_line_p != b->indicate_empty_line_p
1366 || a->overlapped_p != b->overlapped_p
1364 || (MATRIX_ROW_CONTINUATION_LINE_P (a) 1367 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
1365 != MATRIX_ROW_CONTINUATION_LINE_P (b)) 1368 != MATRIX_ROW_CONTINUATION_LINE_P (b))
1366 /* Different partially visible characters on left margin. */ 1369 /* Different partially visible characters on left margin. */
1367 || a->x != b->x 1370 || a->x != b->x
1368 /* Different height. */ 1371 /* Different height. */
1369 || a->ascent != b->ascent 1372 || a->ascent != b->ascent
1373 || a->phys_ascent != b->phys_ascent
1374 || a->phys_height != b->phys_height
1370 || a->visible_height != b->visible_height) 1375 || a->visible_height != b->visible_height)
1371 return 0; 1376 return 0;
1372 } 1377 }
@@ -1863,6 +1868,10 @@ void
1863adjust_glyphs (f) 1868adjust_glyphs (f)
1864 struct frame *f; 1869 struct frame *f;
1865{ 1870{
1871 /* Block input so that expose events and other events that access
1872 glyph matrices are not processed while we are changing them. */
1873 BLOCK_INPUT;
1874
1866 if (f) 1875 if (f)
1867 adjust_frame_glyphs (f); 1876 adjust_frame_glyphs (f);
1868 else 1877 else
@@ -1872,6 +1881,8 @@ adjust_glyphs (f)
1872 FOR_EACH_FRAME (tail, lisp_frame) 1881 FOR_EACH_FRAME (tail, lisp_frame)
1873 adjust_frame_glyphs (XFRAME (lisp_frame)); 1882 adjust_frame_glyphs (XFRAME (lisp_frame));
1874 } 1883 }
1884
1885 UNBLOCK_INPUT;
1875} 1886}
1876 1887
1877 1888
@@ -3025,9 +3036,15 @@ direct_output_for_insert (g)
3025 || g == '\r' 3036 || g == '\r'
3026 /* Give up if unable to display the cursor in the window. */ 3037 /* Give up if unable to display the cursor in the window. */
3027 || w->cursor.vpos < 0 3038 || w->cursor.vpos < 0
3028 /* Can't do it in a continued line because continuation lines 3039 || (glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos),
3029 will change. */ 3040 /* Can't do it in a continued line because continuation
3030 || MATRIX_ROW (w->current_matrix, w->cursor.vpos)->continued_p 3041 lines would change. */
3042 (glyph_row->continued_p
3043 /* Can't use this method if the line overlaps others or is
3044 overlapped by others because these other lines would
3045 have to be redisplayed. */
3046 || glyph_row->overlapping_p
3047 || glyph_row->overlapped_p))
3031 /* Can't do it for partial width windows on terminal frames 3048 /* Can't do it for partial width windows on terminal frames
3032 because we can't clear to eol in such a window. */ 3049 because we can't clear to eol in such a window. */
3033 || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w))) 3050 || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w)))
@@ -3088,6 +3105,8 @@ direct_output_for_insert (g)
3088 the original row, or if it is not a character glyph. */ 3105 the original row, or if it is not a character glyph. */
3089 if (glyph_row->ascent != it.ascent 3106 if (glyph_row->ascent != it.ascent
3090 || glyph_row->height != it.ascent + it.descent 3107 || glyph_row->height != it.ascent + it.descent
3108 || glyph_row->phys_ascent != it.phys_ascent
3109 || glyph_row->phys_height != it.phys_ascent + it.phys_descent
3091 || it.what != IT_CHARACTER) 3110 || it.what != IT_CHARACTER)
3092 return 0; 3111 return 0;
3093 3112
@@ -3450,6 +3469,104 @@ update_single_window (w, force_p)
3450} 3469}
3451 3470
3452 3471
3472/* Redraw lines from the current matrix of window W that are
3473 overlapped by other rows. YB is bottom-most y-position in W. */
3474
3475static void
3476redraw_overlapped_rows (w, yb)
3477 struct window *w;
3478 int yb;
3479{
3480 int i, bottom_y;
3481 struct glyph_row *row;
3482
3483 /* If rows overlapping others have been changed, the rows being
3484 overlapped have to be redrawn. This won't draw lines that have
3485 already been drawn in update_window_line because overlapped_p in
3486 desired rows is 0, so after row assignment overlapped_p in
3487 current rows is 0. */
3488 for (i = 0; i < w->current_matrix->nrows; ++i)
3489 {
3490 row = w->current_matrix->rows + i;
3491
3492 if (!row->enabled_p)
3493 break;
3494 else if (row->mode_line_p)
3495 continue;
3496
3497 if (row->overlapped_p)
3498 {
3499 enum glyph_row_area area;
3500
3501 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
3502 {
3503 updated_row = row;
3504 updated_area = area;
3505 rif->cursor_to (i, 0, row->y, area == TEXT_AREA ? row->x : 0);
3506 if (row->used[area])
3507 rif->write_glyphs (row->glyphs[area], row->used[area]);
3508 rif->clear_end_of_line (-1);
3509 }
3510
3511 row->overlapped_p = 0;
3512 }
3513
3514 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3515 if (bottom_y >= yb)
3516 break;
3517 }
3518}
3519
3520
3521/* Redraw lines from the current matrix of window W that overlap
3522 others. YB is bottom-most y-position in W. */
3523
3524static void
3525redraw_overlapping_rows (w, yb)
3526 struct window *w;
3527 int yb;
3528{
3529 int i, bottom_y;
3530 struct glyph_row *row;
3531
3532 for (i = 0; i < w->current_matrix->nrows; ++i)
3533 {
3534 row = w->current_matrix->rows + i;
3535
3536 if (!row->enabled_p)
3537 break;
3538 else if (row->mode_line_p)
3539 continue;
3540
3541 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3542
3543 if (row->overlapping_p && i > 0 && bottom_y < yb)
3544 {
3545 if (row->used[LEFT_MARGIN_AREA])
3546 rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
3547
3548 if (row->used[TEXT_AREA])
3549 rif->fix_overlapping_area (w, row, TEXT_AREA);
3550
3551 if (row->used[RIGHT_MARGIN_AREA])
3552 rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
3553
3554 /* Record in neighbor rows that ROW overwrites part of their
3555 display. */
3556 if (row->phys_ascent > row->ascent && i > 0)
3557 MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
3558 if ((row->phys_height - row->phys_ascent
3559 > row->height - row->ascent)
3560 && bottom_y < yb)
3561 MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
3562 }
3563
3564 if (bottom_y >= yb)
3565 break;
3566 }
3567}
3568
3569
3453/* Update display of window W. FORCE_P non-zero means that we should 3570/* Update display of window W. FORCE_P non-zero means that we should
3454 not stop when detecting pending input. */ 3571 not stop when detecting pending input. */
3455 3572
@@ -3482,7 +3599,7 @@ update_window (w, force_p)
3482 struct glyph_row *row, *end; 3599 struct glyph_row *row, *end;
3483 struct glyph_row *mode_line_row; 3600 struct glyph_row *mode_line_row;
3484 struct glyph_row *top_line_row = NULL; 3601 struct glyph_row *top_line_row = NULL;
3485 int yb; 3602 int yb, changed_p = 0;
3486 3603
3487 rif->update_window_begin_hook (w); 3604 rif->update_window_begin_hook (w);
3488 yb = window_text_bottom_y (w); 3605 yb = window_text_bottom_y (w);
@@ -3501,6 +3618,7 @@ update_window (w, force_p)
3501 mode_line_row->y = yb; 3618 mode_line_row->y = yb;
3502 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row, 3619 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
3503 desired_matrix)); 3620 desired_matrix));
3621 changed_p = 1;
3504 } 3622 }
3505 3623
3506 /* Find first enabled row. Optimizations in redisplay_internal 3624 /* Find first enabled row. Optimizations in redisplay_internal
@@ -3521,6 +3639,7 @@ update_window (w, force_p)
3521 } 3639 }
3522 else if (rc > 0) 3640 else if (rc > 0)
3523 force_p = 1; 3641 force_p = 1;
3642 changed_p = 1;
3524 } 3643 }
3525 3644
3526 /* Update the top mode line after scrolling because a new top 3645 /* Update the top mode line after scrolling because a new top
@@ -3530,6 +3649,7 @@ update_window (w, force_p)
3530 { 3649 {
3531 top_line_row->y = 0; 3650 top_line_row->y = 0;
3532 update_window_line (w, 0); 3651 update_window_line (w, 0);
3652 changed_p = 1;
3533 } 3653 }
3534 3654
3535 /* Update the rest of the lines. */ 3655 /* Update the rest of the lines. */
@@ -3550,7 +3670,7 @@ update_window (w, force_p)
3550 if (!force_p && vpos % preempt_count == 0) 3670 if (!force_p && vpos % preempt_count == 0)
3551 detect_input_pending (); 3671 detect_input_pending ();
3552 3672
3553 update_window_line (w, vpos); 3673 changed_p |= update_window_line (w, vpos);
3554 3674
3555 /* Mark all rows below the last visible one in the current 3675 /* Mark all rows below the last visible one in the current
3556 matrix as invalid. This is necessary because of 3676 matrix as invalid. This is necessary because of
@@ -3571,6 +3691,16 @@ update_window (w, force_p)
3571 3691
3572 set_cursor: 3692 set_cursor:
3573 3693
3694 /* Fix the appearance of overlapping(overlapped rows. */
3695 if (rif->fix_overlapping_area
3696 && !w->pseudo_window_p
3697 && changed_p
3698 && !paused_p)
3699 {
3700 redraw_overlapped_rows (w, yb);
3701 redraw_overlapping_rows (w, yb);
3702 }
3703
3574 if (!paused_p && !w->pseudo_window_p) 3704 if (!paused_p && !w->pseudo_window_p)
3575 { 3705 {
3576 /* Make cursor visible at cursor position of W. */ 3706 /* Make cursor visible at cursor position of W. */
@@ -3588,14 +3718,16 @@ update_window (w, force_p)
3588 /* Remember the redisplay method used to display the matrix. */ 3718 /* Remember the redisplay method used to display the matrix. */
3589 strcpy (w->current_matrix->method, w->desired_matrix->method); 3719 strcpy (w->current_matrix->method, w->desired_matrix->method);
3590#endif 3720#endif
3591 3721
3592 /* End of update of window W. */ 3722 /* End of update of window W. */
3593 rif->update_window_end_hook (w, 1); 3723 rif->update_window_end_hook (w, 1);
3724
3594 } 3725 }
3595 else 3726 else
3596 paused_p = 1; 3727 paused_p = 1;
3597 3728
3598 clear_glyph_matrix (desired_matrix); 3729 clear_glyph_matrix (desired_matrix);
3730
3599 return paused_p; 3731 return paused_p;
3600} 3732}
3601 3733
@@ -3624,15 +3756,17 @@ update_marginal_area (w, area, vpos)
3624} 3756}
3625 3757
3626 3758
3627/* Update the display of the text area of row VPOS in window W. */ 3759/* Update the display of the text area of row VPOS in window W.
3760 Value is non-zero if display has changed. */
3628 3761
3629static void 3762static int
3630update_text_area (w, vpos) 3763update_text_area (w, vpos)
3631 struct window *w; 3764 struct window *w;
3632 int vpos; 3765 int vpos;
3633{ 3766{
3634 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); 3767 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3635 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); 3768 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3769 int changed_p = 0;
3636 3770
3637 /* Let functions in xterm.c know what area subsequent X positions 3771 /* Let functions in xterm.c know what area subsequent X positions
3638 will be relative to. */ 3772 will be relative to. */
@@ -3643,7 +3777,10 @@ update_text_area (w, vpos)
3643 if (!current_row->enabled_p 3777 if (!current_row->enabled_p
3644 || desired_row->y != current_row->y 3778 || desired_row->y != current_row->y
3645 || desired_row->ascent != current_row->ascent 3779 || desired_row->ascent != current_row->ascent
3780 || desired_row->phys_ascent != current_row->phys_ascent
3781 || desired_row->phys_height != current_row->phys_height
3646 || desired_row->visible_height != current_row->visible_height 3782 || desired_row->visible_height != current_row->visible_height
3783 || current_row->overlapped_p
3647 || current_row->x != desired_row->x) 3784 || current_row->x != desired_row->x)
3648 { 3785 {
3649 rif->cursor_to (vpos, 0, desired_row->y, desired_row->x); 3786 rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
@@ -3654,6 +3791,7 @@ update_text_area (w, vpos)
3654 3791
3655 /* Clear to end of window. */ 3792 /* Clear to end of window. */
3656 rif->clear_end_of_line (-1); 3793 rif->clear_end_of_line (-1);
3794 changed_p = 1;
3657 } 3795 }
3658 else 3796 else
3659 { 3797 {
@@ -3736,6 +3874,7 @@ update_text_area (w, vpos)
3736 3874
3737 rif->cursor_to (vpos, start_hpos, desired_row->y, start_x); 3875 rif->cursor_to (vpos, start_hpos, desired_row->y, start_x);
3738 rif->write_glyphs (start, i - start_hpos); 3876 rif->write_glyphs (start, i - start_hpos);
3877 changed_p = 1;
3739 } 3878 }
3740 } 3879 }
3741 3880
@@ -3744,6 +3883,7 @@ update_text_area (w, vpos)
3744 { 3883 {
3745 rif->cursor_to (vpos, i, desired_row->y, x); 3884 rif->cursor_to (vpos, i, desired_row->y, x);
3746 rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i); 3885 rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
3886 changed_p = 1;
3747 } 3887 }
3748 3888
3749 /* Maybe clear to end of line. */ 3889 /* Maybe clear to end of line. */
@@ -3762,6 +3902,7 @@ update_text_area (w, vpos)
3762 rif->cursor_to (vpos, i, desired_row->y, 3902 rif->cursor_to (vpos, i, desired_row->y,
3763 desired_row->x + desired_row->pixel_width); 3903 desired_row->x + desired_row->pixel_width);
3764 rif->clear_end_of_line (-1); 3904 rif->clear_end_of_line (-1);
3905 changed_p = 1;
3765 } 3906 }
3766 else if (desired_row->pixel_width < current_row->pixel_width) 3907 else if (desired_row->pixel_width < current_row->pixel_width)
3767 { 3908 {
@@ -3787,20 +3928,25 @@ update_text_area (w, vpos)
3787 else 3928 else
3788 x = current_row->x + current_row->pixel_width; 3929 x = current_row->x + current_row->pixel_width;
3789 rif->clear_end_of_line (x); 3930 rif->clear_end_of_line (x);
3931 changed_p = 1;
3790 } 3932 }
3791 } 3933 }
3934
3935 return changed_p;
3792} 3936}
3793 3937
3794 3938
3795/* Update row VPOS in window W. */ 3939/* Update row VPOS in window W. Value is non-zero if display has been
3940 changed. */
3796 3941
3797static void 3942static int
3798update_window_line (w, vpos) 3943update_window_line (w, vpos)
3799 struct window *w; 3944 struct window *w;
3800 int vpos; 3945 int vpos;
3801{ 3946{
3802 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); 3947 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3803 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); 3948 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3949 int changed_p = 0;
3804 3950
3805 xassert (desired_row->enabled_p); 3951 xassert (desired_row->enabled_p);
3806 3952
@@ -3811,15 +3957,21 @@ update_window_line (w, vpos)
3811 /* Update display of the left margin area, if there is one. */ 3957 /* Update display of the left margin area, if there is one. */
3812 if (!desired_row->full_width_p 3958 if (!desired_row->full_width_p
3813 && !NILP (w->left_margin_width)) 3959 && !NILP (w->left_margin_width))
3814 update_marginal_area (w, LEFT_MARGIN_AREA, vpos); 3960 {
3961 update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
3962 changed_p = 1;
3963 }
3815 3964
3816 /* Update the display of the text area. */ 3965 /* Update the display of the text area. */
3817 update_text_area (w, vpos); 3966 changed_p |= update_text_area (w, vpos);
3818 3967
3819 /* Update display of the right margin area, if there is one. */ 3968 /* Update display of the right margin area, if there is one. */
3820 if (!desired_row->full_width_p 3969 if (!desired_row->full_width_p
3821 && !NILP (w->right_margin_width)) 3970 && !NILP (w->right_margin_width))
3822 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos); 3971 {
3972 changed_p = 1;
3973 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
3974 }
3823 3975
3824 /* Draw truncation marks etc. */ 3976 /* Draw truncation marks etc. */
3825 if (!current_row->enabled_p 3977 if (!current_row->enabled_p
@@ -3839,6 +3991,7 @@ update_window_line (w, vpos)
3839 /* Update current_row from desired_row. */ 3991 /* Update current_row from desired_row. */
3840 make_current (w->desired_matrix, w->current_matrix, vpos); 3992 make_current (w->desired_matrix, w->current_matrix, vpos);
3841 updated_row = NULL; 3993 updated_row = NULL;
3994 return changed_p;
3842} 3995}
3843 3996
3844 3997
@@ -4207,10 +4360,14 @@ scrolling_window (w, top_line_p)
4207 for (j = 0; j < r->nrows; ++j) 4360 for (j = 0; j < r->nrows; ++j)
4208 { 4361 {
4209 struct glyph_row *from, *to; 4362 struct glyph_row *from, *to;
4363 int to_overlapped_p;
4364
4210 to = MATRIX_ROW (current_matrix, r->desired_vpos + j); 4365 to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
4366 to_overlapped_p = to->overlapped_p;
4211 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j); 4367 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
4212 assign_row (to, from); 4368 assign_row (to, from);
4213 to->enabled_p = 1, from->enabled_p = 0; 4369 to->enabled_p = 1, from->enabled_p = 0;
4370 to->overlapped_p = to_overlapped_p;
4214 } 4371 }
4215 } 4372 }
4216 4373