Fix handling of internal borders (Bug#16348).
[bpt/emacs.git] / src / xdisp.c
index 0d3f473..de553a7 100644 (file)
@@ -1,6 +1,7 @@
 /* Display generation from window structure and buffer text.
 
-Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation, Inc.
+Copyright (C) 1985-1988, 1993-1995, 1997-2014 Free Software Foundation,
+Inc.
 
 This file is part of GNU Emacs.
 
@@ -12057,8 +12058,8 @@ display_tool_bar_line (struct it *it, int height)
 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
   ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
 
-/* Value is the number of screen lines needed to make all tool-bar
-   items of frame F visible.  The number of actual rows needed is
+/* Value is the number of pixels needed to make all tool-bar items of
+   frame F visible.  The actual number of glyph rows needed is
    returned in *N_ROWS if non-NULL.  */
 
 static int
@@ -12075,8 +12076,7 @@ tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
      F->desired_tool_bar_string in the tool-bar window of frame F.  */
   init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
   it.first_visible_x = 0;
-  /* PXW: Use FRAME_PIXEL_WIDTH (f) here?  */
-  it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
+  it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
   reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
   it.paragraph_embedding = L2R;
 
@@ -12109,7 +12109,7 @@ DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
        0, 2, 0,
        doc: /* Return the number of lines occupied by the tool bar of FRAME.
 If FRAME is nil or omitted, use the selected frame.  Optional argument
-PIXELWISE non-nil means return the height of the tool bar inpixels.  */)
+PIXELWISE non-nil means return the height of the tool bar in pixels.  */)
   (Lisp_Object frame, Lisp_Object pixelwise)
 {
   int height = 0;
@@ -12254,6 +12254,10 @@ redisplay_tool_bar (struct frame *f)
          && it.current_y < max_tool_bar_height)
        change_height_p = 1;
 
+      /* We subtract 1 because display_tool_bar_line advances the
+        glyph_row pointer before returning to its caller.  We want to
+        examine the last glyph row produced by
+        display_tool_bar_line.  */
       row = it.glyph_row - 1;
 
       /* If there are blank lines at the end, except for a partially
@@ -12286,18 +12290,35 @@ redisplay_tool_bar (struct frame *f)
 
          if (change_height_p)
            {
+             /* Current size of the tool-bar window in canonical line
+                units.  */
+             int old_lines = WINDOW_TOTAL_LINES (w);
+             /* Required size of the tool-bar window in canonical
+                line units. */
              int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
                               / FRAME_LINE_HEIGHT (f));
-
-             XSETFRAME (frame, f);
-             Fmodify_frame_parameters (frame,
-                                       list1 (Fcons (Qtool_bar_lines,
-                                                     make_number (new_lines))));
-             /* Always do that now.  */
-             clear_glyph_matrix (w->desired_matrix);
-             f->n_tool_bar_rows = nrows;
-             f->fonts_changed = 1;
-             return 1;
+             /* Maximum size of the tool-bar window in canonical line
+                units that this frame can allow. */
+             int max_lines =
+               WINDOW_TOTAL_LINES (XWINDOW (FRAME_ROOT_WINDOW (f))) - 1;
+
+             /* Don't try to change the tool-bar window size and set
+                the fonts_changed flag unless really necessary.  That
+                flag causes redisplay to give up and retry
+                redisplaying the frame from scratch, so setting it
+                unnecessarily can lead to nasty redisplay loops.  */
+             if (new_lines <= max_lines
+                 && eabs (new_lines - old_lines) >= 1)
+               {
+                 XSETFRAME (frame, f);
+                 Fmodify_frame_parameters (frame,
+                                           list1 (Fcons (Qtool_bar_lines,
+                                                         make_number (new_lines))));
+                 clear_glyph_matrix (w->desired_matrix);
+                 f->n_tool_bar_rows = nrows;
+                 f->fonts_changed = 1;
+                 return 1;
+               }
            }
        }
     }
@@ -12607,15 +12628,25 @@ hscroll_window_tree (Lisp_Object window)
        {
          int h_margin;
          int text_area_width;
-         struct glyph_row *current_cursor_row
-           = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
-         struct glyph_row *desired_cursor_row
-           = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
-         struct glyph_row *cursor_row
-           = (desired_cursor_row->enabled_p
-              ? desired_cursor_row
-              : current_cursor_row);
-         int row_r2l_p = cursor_row->reversed_p;
+         struct glyph_row *cursor_row;
+         struct glyph_row *bottom_row;
+         int row_r2l_p;
+
+         bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
+         if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
+           cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
+         else
+           cursor_row = bottom_row - 1;
+
+         if (!cursor_row->enabled_p)
+           {
+             bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
+             if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
+               cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
+             else
+               cursor_row = bottom_row - 1;
+           }
+         row_r2l_p = cursor_row->reversed_p;
 
          text_area_width = window_box_width (w, TEXT_AREA);
 
@@ -15590,7 +15621,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
       && REDISPLAY_SOME_P ()
       && !w->redisplay
       && !f->redisplay
-      && !buffer->text->redisplay)
+      && !buffer->text->redisplay
+      && BUF_PT (buffer) == w->last_point)
     return;
 
   /* Make sure that both W's markers are valid.  */
@@ -15736,16 +15768,20 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
      this may be a bit late to catch such changes, but the rest of
      redisplay goes (non-fatally) haywire when the display table is
      changed, so why should we worry about doing any better?  */
-  if (current_buffer->width_run_cache)
+  if (current_buffer->width_run_cache
+      || (current_buffer->base_buffer
+         && current_buffer->base_buffer->width_run_cache))
     {
       struct Lisp_Char_Table *disptab = buffer_display_table ();
 
       if (! disptab_matches_widthtab
          (disptab, XVECTOR (BVAR (current_buffer, width_table))))
         {
-          invalidate_region_cache (current_buffer,
-                                   current_buffer->width_run_cache,
-                                   BEG, Z);
+         struct buffer *buf = current_buffer;
+
+         if (buf->base_buffer)
+           buf = buf->base_buffer;
+          invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
           recompute_width_table (current_buffer, disptab);
         }
     }
@@ -18876,14 +18912,16 @@ extend_face_to_end_of_line (struct it *it)
              && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
            {
              it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
-             it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id = face->id;
+             it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
+               default_face->id;
              it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
            }
          if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
              && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
            {
              it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
-             it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id = face->id;
+             it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
+               default_face->id;
              it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
            }
        }
@@ -18952,20 +18990,12 @@ extend_face_to_end_of_line (struct it *it)
       it->object = make_number (0);
       it->c = it->char_to_display = ' ';
       it->len = 1;
-      /* The last row's blank glyphs should get the default face, to
-        avoid painting the rest of the window with the region face,
-        if the region ends at ZV.  */
-      if (it->glyph_row->ends_at_zv_p)
-       it->face_id = default_face->id;
-      else
-       it->face_id = face->id;
 
-      face = FACE_FROM_ID (f, it->face_id);
       if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
          && (it->glyph_row->used[LEFT_MARGIN_AREA]
              < WINDOW_LEFT_MARGIN_WIDTH (it->w))
          && !it->glyph_row->mode_line_p
-         && face && face->background != FRAME_BACKGROUND_PIXEL (f))
+         && default_face->background != FRAME_BACKGROUND_PIXEL (f))
        {
          struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
          struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
@@ -18974,6 +19004,7 @@ extend_face_to_end_of_line (struct it *it)
            it->current_x += g->pixel_width;
 
          it->area = LEFT_MARGIN_AREA;
+         it->face_id = default_face->id;
          while (it->glyph_row->used[LEFT_MARGIN_AREA]
                 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
            {
@@ -18987,6 +19018,13 @@ extend_face_to_end_of_line (struct it *it)
          it->area = TEXT_AREA;
        }
 
+      /* The last row's blank glyphs should get the default face, to
+        avoid painting the rest of the window with the region face,
+        if the region ends at ZV.  */
+      if (it->glyph_row->ends_at_zv_p)
+       it->face_id = default_face->id;
+      else
+       it->face_id = face->id;
       PRODUCE_GLYPHS (it);
 
       while (it->current_x <= it->last_visible_x)
@@ -18996,7 +19034,7 @@ extend_face_to_end_of_line (struct it *it)
          && (it->glyph_row->used[RIGHT_MARGIN_AREA]
              < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
          && !it->glyph_row->mode_line_p
-         && face && face->background != FRAME_BACKGROUND_PIXEL (f))
+         && default_face->background != FRAME_BACKGROUND_PIXEL (f))
        {
          struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
          struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
@@ -19005,6 +19043,7 @@ extend_face_to_end_of_line (struct it *it)
            it->current_x += g->pixel_width;
 
          it->area = RIGHT_MARGIN_AREA;
+         it->face_id = default_face->id;
          while (it->glyph_row->used[RIGHT_MARGIN_AREA]
                 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
            {
@@ -20849,8 +20888,7 @@ display_menu_bar (struct window *w)
   eassert (!FRAME_WINDOW_P (f));
   init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
   it.first_visible_x = 0;
-  /* PXW: Use FRAME_PIXEL_WIDTH (f) here?  */
-  it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
+  it.last_visible_x = FRAME_PIXEL_WIDTH (f);
 #elif defined (HAVE_X_WINDOWS) /* X without toolkit.  */
   if (FRAME_WINDOW_P (f))
     {
@@ -20861,8 +20899,7 @@ display_menu_bar (struct window *w)
       init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
                     MENU_FACE_ID);
       it.first_visible_x = 0;
-      /* PXW: Use FRAME_PIXEL_WIDTH (f) here?  */
-      it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
+      it.last_visible_x = FRAME_PIXEL_WIDTH (f);
     }
   else
 #endif /* not USE_X_TOOLKIT and not USE_GTK */