]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Merge from emacs--devo--0
[gnu-emacs] / src / xdisp.c
index 0cb34a2fef86a9c3996570fa176129f6accea37c..0e60020f11015e87ea5cb0078e78006581cc88e7 100644 (file)
@@ -717,6 +717,10 @@ Lisp_Object Vresize_mini_windows;
 
 struct buffer *displayed_buffer;
 
+/* Space between overline and text. */
+
+EMACS_INT overline_margin;
+
 /* Value returned from text property handlers (see below).  */
 
 enum prop_handled
@@ -755,13 +759,13 @@ static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
 
 static struct props it_props[] =
 {
-  {&Qauto_composed,    AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
   {&Qfontified,                FONTIFIED_PROP_IDX,     handle_fontified_prop},
   /* Handle `face' before `display' because some sub-properties of
      `display' need to know the face.  */
   {&Qface,             FACE_PROP_IDX,          handle_face_prop},
   {&Qdisplay,          DISPLAY_PROP_IDX,       handle_display_prop},
   {&Qinvisible,                INVISIBLE_PROP_IDX,     handle_invisible_prop},
+  {&Qauto_composed,    AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
   {&Qcomposition,      COMPOSITION_PROP_IDX,   handle_composition_prop},
   {NULL,               0,                      NULL}
 };
@@ -909,7 +913,7 @@ static void redisplay_window P_ ((Lisp_Object, int));
 static Lisp_Object redisplay_window_error ();
 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
-static void update_menu_bar P_ ((struct frame *, int));
+static int update_menu_bar P_ ((struct frame *, int, int));
 static int try_window_reusing_current_matrix P_ ((struct window *));
 static int try_window_id P_ ((struct window *));
 static int display_line P_ ((struct it *));
@@ -925,6 +929,7 @@ static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
 static void compute_line_metrics P_ ((struct it *));
 static void run_redisplay_end_trigger_hook P_ ((struct it *));
 static int get_overlay_strings P_ ((struct it *, int));
+static int get_overlay_strings_1 P_ ((struct it *, int, int));
 static void next_overlay_string P_ ((struct it *));
 static void reseat P_ ((struct it *, struct text_pos, int));
 static void reseat_1 P_ ((struct it *, struct text_pos, int));
@@ -2918,8 +2923,8 @@ init_from_display_pos (it, w, pos)
         also ``processed'' overlay strings at ZV.  */
       while (it->sp)
        pop_it (it);
-      it->current.overlay_string_index = -1;
-      it->method = GET_FROM_BUFFER;
+      xassert (it->current.overlay_string_index == -1);
+      xassert (it->method == GET_FROM_BUFFER);
       if (CHARPOS (pos->pos) == ZV)
        it->overlay_strings_at_end_processed_p = 1;
     }
@@ -3030,7 +3035,19 @@ handle_stop (it)
          if (handled == HANDLED_RECOMPUTE_PROPS)
            break;
          else if (handled == HANDLED_RETURN)
-           return;
+           {
+             /* We still want to show before and after strings from
+                overlays even if the actual buffer text is replaced.  */
+             if (!handle_overlay_change_p || it->sp > 1)
+               return;
+             if (!get_overlay_strings_1 (it, 0, 0))
+               return;
+             it->ignore_overlay_strings_at_pos_p = 1;
+             it->string_from_display_prop_p = 0;
+             handle_overlay_change_p = 0;
+             handled = HANDLED_RECOMPUTE_PROPS;
+             break;
+           }
          else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
            handle_overlay_change_p = 0;
        }
@@ -3876,7 +3893,7 @@ handle_single_display_spec (it, spec, object, position,
 {
   Lisp_Object form;
   Lisp_Object location, value;
-  struct text_pos start_pos;
+  struct text_pos start_pos, save_pos;
   int valid_p;
 
   /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
@@ -4093,7 +4110,10 @@ handle_single_display_spec (it, spec, object, position,
       /* Save current settings of IT so that we can restore them
         when we are finished with the glyph property value.  */
 
+      save_pos = it->position;
+      it->position = *position;
       push_it (it);
+      it->position = save_pos;
 
       it->area = TEXT_AREA;
       it->what = IT_IMAGE;
@@ -4167,7 +4187,10 @@ handle_single_display_spec (it, spec, object, position,
     {
       /* Save current settings of IT so that we can restore them
         when we are finished with the glyph property value.  */
+      save_pos = it->position;
+      it->position = *position;
       push_it (it);
+      it->position = save_pos;
 
       if (NILP (location))
        it->area = TEXT_AREA;
@@ -4460,7 +4483,7 @@ handle_auto_composed_prop (it)
            limit = make_number (find_next_newline_no_quit (pos, 1));
 
          next = (Fnext_single_property_change
-                    (make_number (pos), Qauto_composed, it->string, limit));
+                 (make_number (pos), Qauto_composed, it->string, limit));
          if (XINT (next) < XINT (limit))
            {
              /* The current point is auto-composed, but there exist
@@ -4488,13 +4511,40 @@ handle_auto_composed_prop (it)
       if (NILP (val))
        {
          int count = SPECPDL_INDEX ();
-         Lisp_Object args[3];
+         Lisp_Object args[4];
 
          args[0] = Vauto_composition_function;
          specbind (Qauto_composition_function, Qnil);
          args[1] = make_number (pos);
          args[2] = it->string;
-         safe_call (3, args);
+#ifdef USE_FONT_BACKEND
+         if (enable_font_backend)
+           {
+             struct face *face = FACE_FROM_ID (it->f, it->face_id);
+             int c;
+
+             if (STRINGP (it->string))
+               {
+                 EMACS_INT pos_byte = IT_STRING_BYTEPOS (*it);
+                 const unsigned char *s = SDATA (it->string) + pos_byte;
+
+                 if (STRING_MULTIBYTE (it->string))
+                   it->c = STRING_CHAR (s, 0);
+                 else
+                   it->c = *s;
+               }
+             else
+               {
+                 EMACS_INT pos_byte = IT_BYTEPOS (*it);
+
+                 it->c = FETCH_CHAR (pos_byte);
+               }
+             args[3] = font_at (it->c, this_pos, face, it->w, it->string);
+           }
+         else
+#endif /* USE_FONT_BACKEND */
+           args[3] = Qnil;
+         safe_call (4, args);
          unbind_to (count, Qnil);
 
          if (this_pos == pos)
@@ -4576,12 +4626,26 @@ handle_composition_prop (it)
                }
              return HANDLED_RECOMPUTE_PROPS;
            }
+
+         it->stop_charpos = end;
+         push_it (it);
+
          it->method = GET_FROM_COMPOSITION;
          it->cmp_id = id;
          it->cmp_len = COMPOSITION_LENGTH (prop);
 #ifdef USE_FONT_BACKEND
          if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
-           it->c = ' ';
+           {
+             Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
+                                          ->key_and_value,
+                                          cmp->hash_index * 2);
+             Lisp_Object font_object = LGSTRING_FONT (lgstring);
+             struct font *font = XSAVE_VALUE (font_object)->pointer;
+             struct face *face = FACE_FROM_ID (it->f, it->face_id);
+
+             it->face_id = face_for_font (it->f, font, face);
+             it->c = ' ';
+           }
          else
 #endif /* USE_FONT_BACKEND */
          /* For a terminal, draw only the first character of the
@@ -4590,7 +4654,6 @@ handle_composition_prop (it)
          it->len = (STRINGP (it->string)
                     ? string_char_to_byte (it->string, end)
                     : CHAR_TO_BYTE (end)) - pos_byte;
-         it->stop_charpos = end;
          handled = HANDLED_RETURN;
        }
     }
@@ -4650,13 +4713,14 @@ next_overlay_string (it)
       int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
 
       pop_it (it);
-      xassert (it->stop_charpos >= BEGV
-              && it->stop_charpos <= it->end_charpos);
-      it->string = Qnil;
+      xassert (it->sp > 0
+              || it->method == GET_FROM_COMPOSITION
+              || (NILP (it->string)
+                  && it->method == GET_FROM_BUFFER
+                  && it->stop_charpos >= BEGV
+                  && it->stop_charpos <= it->end_charpos));
       it->current.overlay_string_index = -1;
-      SET_TEXT_POS (it->current.string_pos, -1, -1);
       it->n_overlay_strings = 0;
-      it->method = GET_FROM_BUFFER;
 
       /* If we're at the end of the buffer, record that we have
         processed the overlay strings there already, so that
@@ -4912,7 +4976,7 @@ load_overlay_strings (it, charpos)
    least one overlay string was found.  */
 
 static int
-get_overlay_strings (it, charpos)
+get_overlay_strings_1 (it, charpos, compute_stop_p)
      struct it *it;
      int charpos;
 {
@@ -4934,12 +4998,13 @@ get_overlay_strings (it, charpos)
       /* Make sure we know settings in current_buffer, so that we can
         restore meaningful values when we're done with the overlay
         strings.  */
-      compute_stop_pos (it);
+      if (compute_stop_p)
+       compute_stop_pos (it);
       xassert (it->face_id >= 0);
 
       /* Save IT's settings.  They are restored after all overlay
         strings have been processed.  */
-      xassert (it->sp == 0);
+      xassert (!compute_stop_p || it->sp == 0);
       push_it (it);
 
       /* Set up IT to deliver display elements from the first overlay
@@ -4951,14 +5016,23 @@ get_overlay_strings (it, charpos)
       it->end_charpos = SCHARS (it->string);
       it->multibyte_p = STRING_MULTIBYTE (it->string);
       it->method = GET_FROM_STRING;
-    }
-  else
-    {
-      it->string = Qnil;
-      it->current.overlay_string_index = -1;
-      it->method = GET_FROM_BUFFER;
+      return 1;
     }
 
+  it->current.overlay_string_index = -1;
+  return 0;
+}
+
+static int
+get_overlay_strings (it, charpos)
+     struct it *it;
+     int charpos;
+{
+  it->string = Qnil;
+  it->method = GET_FROM_BUFFER;
+
+  (void) get_overlay_strings_1 (it, charpos, 1);
+
   CHECK_IT (it);
 
   /* Value is non-zero if we found at least one overlay string.  */
@@ -4982,19 +5056,38 @@ push_it (it)
 {
   struct iterator_stack_entry *p;
 
-  xassert (it->sp < 2);
+  xassert (it->sp < IT_STACK_SIZE);
   p = it->stack + it->sp;
 
   p->stop_charpos = it->stop_charpos;
   xassert (it->face_id >= 0);
   p->face_id = it->face_id;
   p->string = it->string;
-  p->pos = it->current;
+  p->method = it->method;
+  switch (p->method)
+    {
+    case GET_FROM_IMAGE:
+      p->u.image.object = it->object;
+      p->u.image.image_id = it->image_id;
+      p->u.image.slice = it->slice;
+      break;
+    case GET_FROM_COMPOSITION:
+      p->u.comp.object = it->object;
+      p->u.comp.c = it->c;
+      p->u.comp.len = it->len;
+      p->u.comp.cmp_id = it->cmp_id;
+      p->u.comp.cmp_len = it->cmp_len;
+      break;
+    case GET_FROM_STRETCH:
+      p->u.stretch.object = it->object;
+      break;
+    }
+  p->position = it->position;
+  p->current = it->current;
   p->end_charpos = it->end_charpos;
   p->string_nchars = it->string_nchars;
   p->area = it->area;
   p->multibyte_p = it->multibyte_p;
-  p->slice = it->slice;
   p->space_width = it->space_width;
   p->font_height = it->font_height;
   p->voffset = it->voffset;
@@ -5021,13 +5114,40 @@ pop_it (it)
   p = it->stack + it->sp;
   it->stop_charpos = p->stop_charpos;
   it->face_id = p->face_id;
+  it->current = p->current;
+  it->position = p->position;
   it->string = p->string;
-  it->current = p->pos;
+  if (NILP (it->string))
+    SET_TEXT_POS (it->current.string_pos, -1, -1);
+  it->method = p->method;
+  switch (it->method)
+    {
+    case GET_FROM_IMAGE:
+      it->image_id = p->u.image.image_id;
+      it->object = p->u.image.object;
+      it->slice = p->u.image.slice;
+      break;
+    case GET_FROM_COMPOSITION:
+      it->object = p->u.comp.object;
+      it->c = p->u.comp.c;
+      it->len = p->u.comp.len;
+      it->cmp_id = p->u.comp.cmp_id;
+      it->cmp_len = p->u.comp.cmp_len;
+      break;
+    case GET_FROM_STRETCH:
+      it->object = p->u.comp.object;
+      break;
+    case GET_FROM_BUFFER:
+      it->object = it->w->buffer;
+      break;
+    case GET_FROM_STRING:
+      it->object = it->string;
+      break;
+    }
   it->end_charpos = p->end_charpos;
   it->string_nchars = p->string_nchars;
   it->area = p->area;
   it->multibyte_p = p->multibyte_p;
-  it->slice = p->slice;
   it->space_width = p->space_width;
   it->font_height = p->font_height;
   it->voffset = p->voffset;
@@ -5159,6 +5279,7 @@ back_to_previous_visible_line_start (it)
   while (IT_CHARPOS (*it) > BEGV)
     {
       back_to_previous_line_start (it);
+
       if (IT_CHARPOS (*it) <= BEGV)
        break;
 
@@ -5178,37 +5299,47 @@ back_to_previous_visible_line_start (it)
          continue;
       }
 
-      /* If newline has a display property that replaces the newline with something
-        else (image or text), find start of overlay or interval and continue search
-        from that point.  */
-      if (IT_CHARPOS (*it) > BEGV)
-       {
-         struct it it2 = *it;
-         int pos;
-         int beg, end;
-         Lisp_Object val, overlay;
-
-         pos = --IT_CHARPOS (it2);
-         --IT_BYTEPOS (it2);
-         it2.sp = 0;
-         if (handle_display_prop (&it2) == HANDLED_RETURN
-             && !NILP (val = get_char_property_and_overlay
-                       (make_number (pos), Qdisplay, Qnil, &overlay))
-             && (OVERLAYP (overlay)
-                 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
-                 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
-           {
-             if (beg < BEGV)
-               beg = BEGV;
-             IT_CHARPOS (*it) = beg;
-             IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
-             continue;
-           }
-       }
+      if (IT_CHARPOS (*it) <= BEGV)
+       break;
 
-      break;
+      {
+       struct it it2;
+       int pos;
+       int beg, end;
+       Lisp_Object val, overlay;
+
+       /* If newline is part of a composition, continue from start of composition */
+       if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
+           && beg < IT_CHARPOS (*it))
+         goto replaced;
+
+       /* If newline is replaced by a display property, find start of overlay
+          or interval and continue search from that point.  */
+       it2 = *it;
+       pos = --IT_CHARPOS (it2);
+       --IT_BYTEPOS (it2);
+       it2.sp = 0;
+       if (handle_display_prop (&it2) == HANDLED_RETURN
+           && !NILP (val = get_char_property_and_overlay
+                     (make_number (pos), Qdisplay, Qnil, &overlay))
+           && (OVERLAYP (overlay)
+               ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
+               : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
+         goto replaced;
+
+       /* Newline is not replaced by anything -- so we are done.  */
+       break;
+
+      replaced:
+       if (beg < BEGV)
+         beg = BEGV;
+       IT_CHARPOS (*it) = beg;
+       IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
+      }
     }
 
+  it->continuation_lines_width = 0;
+
   xassert (IT_CHARPOS (*it) >= BEGV);
   xassert (IT_CHARPOS (*it) == BEGV
           || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
@@ -5331,7 +5462,6 @@ reseat_1 (it, pos, set_stop_p)
   xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
 
   it->current.pos = it->position = pos;
-  XSETBUFFER (it->object, current_buffer);
   it->end_charpos = ZV;
   it->dpvec = NULL;
   it->current.dpvec_index = -1;
@@ -5340,15 +5470,11 @@ reseat_1 (it, pos, set_stop_p)
   IT_STRING_BYTEPOS (*it) = -1;
   it->string = Qnil;
   it->method = GET_FROM_BUFFER;
-  /* RMS: I added this to fix a bug in move_it_vertically_backward
-     where it->area continued to relate to the starting point
-     for the backward motion.  Bug report from
-     Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
-     However, I am not sure whether reseat still does the right thing
-     in general after this change.  */
+  it->object = it->w->buffer;
   it->area = TEXT_AREA;
   it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
   it->sp = 0;
+  it->string_from_display_prop_p = 0;
   it->face_before_selective_p = 0;
 
   if (set_stop_p)
@@ -5825,18 +5951,18 @@ set_iterator_to_next (it, reseat_p)
 
     case GET_FROM_COMPOSITION:
       xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
-      if (STRINGP (it->string))
+      xassert (it->sp > 0);
+      pop_it (it);
+      if (it->method == GET_FROM_STRING)
        {
          IT_STRING_BYTEPOS (*it) += it->len;
          IT_STRING_CHARPOS (*it) += it->cmp_len;
-         it->method = GET_FROM_STRING;
          goto consider_string_end;
        }
-      else
+      else if (it->method == GET_FROM_BUFFER)
        {
          IT_BYTEPOS (*it) += it->len;
          IT_CHARPOS (*it) += it->cmp_len;
-         it->method = GET_FROM_BUFFER;
        }
       break;
 
@@ -5866,7 +5992,10 @@ set_iterator_to_next (it, reseat_p)
          else if (STRINGP (it->string))
            it->method = GET_FROM_STRING;
          else
-           it->method = GET_FROM_BUFFER;
+           {
+             it->method = GET_FROM_BUFFER;
+             it->object = it->w->buffer;
+           }
 
          it->dpvec = NULL;
          it->current.dpvec_index = -1;
@@ -5914,9 +6043,8 @@ set_iterator_to_next (it, reseat_p)
              && it->sp > 0)
            {
              pop_it (it);
-             if (STRINGP (it->string))
+             if (it->method == GET_FROM_STRING)
                goto consider_string_end;
-             it->method = GET_FROM_BUFFER;
            }
        }
       break;
@@ -5928,13 +6056,8 @@ set_iterator_to_next (it, reseat_p)
          if the `display' property takes up the whole string.  */
       xassert (it->sp > 0);
       pop_it (it);
-      it->image_id = 0;
-      if (STRINGP (it->string))
-       {
-         it->method = GET_FROM_STRING;
-         goto consider_string_end;
-       }
-      it->method = GET_FROM_BUFFER;
+      if (it->method == GET_FROM_STRING)
+       goto consider_string_end;
       break;
 
     default:
@@ -6079,9 +6202,7 @@ next_element_from_string (it)
        }
     }
 
-  /* Record what we have and where it came from.  Note that we store a
-     buffer position in IT->position although it could arguably be a
-     string position.  */
+  /* Record what we have and where it came from.  */
   it->what = IT_CHARACTER;
   it->object = it->string;
   it->position = position;
@@ -6157,6 +6278,7 @@ next_element_from_ellipsis (it)
         setting face_before_selective_p.  */
       it->saved_face_id = it->face_id;
       it->method = GET_FROM_BUFFER;
+      it->object = it->w->buffer;
       reseat_at_next_visible_line_start (it, 1);
       it->face_before_selective_p = 1;
     }
@@ -6345,6 +6467,8 @@ next_element_from_composition (it)
                  : it->current.pos);
   if (STRINGP (it->string))
     it->object = it->string;
+  else
+    it->object = it->w->buffer;
   return 1;
 }
 
@@ -6803,6 +6927,10 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
          if (reached)
            break;
        }
+      else if (BUFFERP (it->object)
+              && it->method == GET_FROM_BUFFER
+              && IT_CHARPOS (*it) >= to_charpos)
+       skip = MOVE_POS_MATCH_OR_ZV;
       else
        skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
 
@@ -9066,6 +9194,9 @@ prepare_menu_bars ()
     {
       Lisp_Object tail, frame;
       int count = SPECPDL_INDEX ();
+      /* 1 means that update_menu_bar has run its hooks
+        so any further calls to update_menu_bar shouldn't do so again.  */
+      int menu_bar_hooks_run = 0;
 
       record_unwind_save_match_data ();
 
@@ -9097,7 +9228,7 @@ prepare_menu_bars ()
            }
 
          GCPRO1 (tail);
-         update_menu_bar (f, 0);
+         menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
 #ifdef HAVE_WINDOW_SYSTEM
          update_tool_bar (f, 0);
 #ifdef MAC_OS
@@ -9112,7 +9243,7 @@ prepare_menu_bars ()
   else
     {
       struct frame *sf = SELECTED_FRAME ();
-      update_menu_bar (sf, 1);
+      update_menu_bar (sf, 1, 0);
 #ifdef HAVE_WINDOW_SYSTEM
       update_tool_bar (sf, 1);
 #ifdef MAC_OS
@@ -9133,12 +9264,18 @@ prepare_menu_bars ()
    before we start to fill in any display lines, because it can call
    eval.
 
-   If SAVE_MATCH_DATA is non-zero, we must save and restore it here.  */
+   If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
 
-static void
-update_menu_bar (f, save_match_data)
+   If HOOKS_RUN is 1, that means a previous call to update_menu_bar
+   already ran the menu bar hooks for this redisplay, so there
+   is no need to run them again.  The return value is the
+   updated value of this flag, to pass to the next call.  */
+
+static int
+update_menu_bar (f, save_match_data, hooks_run)
      struct frame *f;
      int save_match_data;
+     int hooks_run;
 {
   Lisp_Object window;
   register struct window *w;
@@ -9203,15 +9340,21 @@ update_menu_bar (f, save_match_data)
              specbind (Qoverriding_local_map, Qnil);
            }
 
-         /* Run the Lucid hook.  */
-         safe_run_hooks (Qactivate_menubar_hook);
+         if (!hooks_run)
+           {
+             /* Run the Lucid hook.  */
+             safe_run_hooks (Qactivate_menubar_hook);
+
+             /* If it has changed current-menubar from previous value,
+                really recompute the menu-bar from the value.  */
+             if (! NILP (Vlucid_menu_bar_dirty_flag))
+               call0 (Qrecompute_lucid_menubar);
 
-         /* If it has changed current-menubar from previous value,
-            really recompute the menu-bar from the value.  */
-         if (! NILP (Vlucid_menu_bar_dirty_flag))
-           call0 (Qrecompute_lucid_menubar);
+             safe_run_hooks (Qmenu_bar_update_hook);
+
+             hooks_run = 1;
+           }
 
-         safe_run_hooks (Qmenu_bar_update_hook);
          FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
 
          /* Redisplay the menu bar in case we changed it.  */
@@ -9240,6 +9383,8 @@ update_menu_bar (f, save_match_data)
          set_buffer_internal_1 (prev);
        }
     }
+
+  return hooks_run;
 }
 
 
@@ -9404,7 +9549,8 @@ update_tool_bar (f, save_match_data)
                                          &new_n_tool_bar);
 
          /* Redisplay the tool-bar if we changed it.  */
-         if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
+         if (new_n_tool_bar != f->n_tool_bar_items
+             || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
             {
               /* Redisplay that happens asynchronously due to an expose event
                  may access f->tool_bar_items.  Make sure we update both
@@ -9649,6 +9795,12 @@ display_tool_bar_line (it, height)
              /* Glyph doesn't fit on line.  Backtrack.  */
              row->used[TEXT_AREA] = n_glyphs_before;
              *it = it_before;
+             /* If this is the only glyph on this line, it will never fit on the
+                toolbar, so skip it.   But ensure there is at least one glyph,
+                so we don't accidentally disable the tool-bar.  */
+             if (n_glyphs_before == 0
+                 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
+               break;
              goto out;
            }
 
@@ -9707,6 +9859,11 @@ display_tool_bar_line (it, height)
 }
 
 
+/* Max tool-bar 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
    returned in *N_ROWS if non-NULL.  */
@@ -9718,7 +9875,10 @@ tool_bar_lines_needed (f, n_rows)
 {
   struct window *w = XWINDOW (f->tool_bar_window);
   struct it it;
-  struct glyph_row *temp_row = w->desired_matrix->rows;
+  /* tool_bar_lines_needed is called from redisplay_tool_bar after building
+     the desired matrix, so use (unused) mode-line row as temporary row to
+     avoid destroying the first tool-bar row.  */
+  struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
 
   /* Initialize an iterator for iteration over
      F->desired_tool_bar_string in the tool-bar window of frame F.  */
@@ -9824,13 +9984,13 @@ redisplay_tool_bar (f)
          int old_height = WINDOW_TOTAL_LINES (w);
 
          XSETFRAME (frame, f);
-         clear_glyph_matrix (w->desired_matrix);
          Fmodify_frame_parameters (frame,
                                    Fcons (Fcons (Qtool_bar_lines,
                                                  make_number (nlines)),
                                           Qnil));
          if (WINDOW_TOTAL_LINES (w) != old_height)
            {
+             clear_glyph_matrix (w->desired_matrix);
              fonts_changed_p = 1;
              return 1;
            }
@@ -9882,17 +10042,20 @@ redisplay_tool_bar (f)
 
   if (auto_resize_tool_bars_p)
     {
-      int nlines;
+      int nlines, nrows;
+      int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
 
       /* If we couldn't display everything, change the tool-bar's
-        height.  */
-      if (IT_STRING_CHARPOS (it) < it.end_charpos)
+        height if there is room for more.  */
+      if (IT_STRING_CHARPOS (it) < it.end_charpos
+         && it.current_y < max_tool_bar_height)
        change_height_p = 1;
 
+      row = it.glyph_row - 1;
+
       /* If there are blank lines at the end, except for a partially
         visible blank line at the end that is smaller than
         FRAME_LINE_HEIGHT, change the tool-bar's height.  */
-      row = it.glyph_row - 1;
       if (!row->displays_text_p
          && row->height >= FRAME_LINE_HEIGHT (f))
        change_height_p = 1;
@@ -9900,13 +10063,14 @@ redisplay_tool_bar (f)
       /* If row displays tool-bar items, but is partially visible,
         change the tool-bar's height.  */
       if (row->displays_text_p
-         && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
+         && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
+         && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
        change_height_p = 1;
 
       /* Resize windows as needed by changing the `tool-bar-lines'
         frame parameter.  */
       if (change_height_p
-         && (nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
+         && (nlines = tool_bar_lines_needed (f, &nrows),
              nlines != WINDOW_TOTAL_LINES (w)))
        {
          extern Lisp_Object Qtool_bar_lines;
@@ -9914,13 +10078,16 @@ redisplay_tool_bar (f)
          int old_height = WINDOW_TOTAL_LINES (w);
 
          XSETFRAME (frame, f);
-         clear_glyph_matrix (w->desired_matrix);
          Fmodify_frame_parameters (frame,
                                    Fcons (Fcons (Qtool_bar_lines,
                                                  make_number (nlines)),
                                           Qnil));
          if (WINDOW_TOTAL_LINES (w) != old_height)
-           fonts_changed_p = 1;
+           {
+             clear_glyph_matrix (w->desired_matrix);
+             f->n_tool_bar_rows = nrows;
+             fonts_changed_p = 1;
+           }
        }
     }
 
@@ -11787,9 +11954,12 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
        }
       else
        {
-         string_before_pos = last_pos;
-         string_start = glyph;
-         string_start_x = x;
+         if (string_start == NULL)
+           {
+             string_before_pos = last_pos;
+             string_start = glyph;
+             string_start_x = x;
+           }
          /* Skip all glyphs from string.  */
          do
            {
@@ -11847,25 +12017,25 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
         glyph on point by scanning from string_start again.  */
       Lisp_Object limit;
       Lisp_Object string;
+      struct glyph *stop = glyph;
       int pos;
 
       limit = make_number (pt_old + 1);
-      end = glyph;
       glyph = string_start;
       x = string_start_x;
       string = glyph->object;
       pos = string_buffer_position (w, string, string_before_pos);
       /* If STRING is from overlay, LAST_POS == 0.  We skip such glyphs
         because we always put cursor after overlay strings.  */
-      while (pos == 0 && glyph < end)
+      while (pos == 0 && glyph < stop)
        {
          string = glyph->object;
-         SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
-         if (glyph < end)
+         SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
+         if (glyph < stop)
            pos = string_buffer_position (w, glyph->object, string_before_pos);
        }
 
-      while (glyph < end)
+      while (glyph < stop)
        {
          pos = XINT (Fnext_single_char_property_change
                      (make_number (pos), Qdisplay, Qnil, limit));
@@ -11873,13 +12043,13 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
            break;
          /* Skip glyphs from the same string.  */
          string = glyph->object;
-         SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+         SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
          /* Skip glyphs from an overlay.  */
-         while (glyph < end
+         while (glyph < stop
                 && ! string_buffer_position (w, glyph->object, pos))
            {
              string = glyph->object;
-             SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+             SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
            }
        }
 
@@ -16548,6 +16718,7 @@ display_mode_line (w, face_id, format)
      kboard-local variables in the mode_line_format will get the right
      values.  */
   push_frame_kboard (it.f);
+  record_unwind_save_match_data ();
   display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
   pop_frame_kboard ();
 
@@ -18800,14 +18971,16 @@ fill_composite_glyph_string (s, faces, overlaps)
        = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
                s->cmp->hash_index * 2);
 
-      for (i = 0; i < s->cmp->glyph_len; i++)
+      for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++)
        {
          Lisp_Object g = LGSTRING_GLYPH (gstring, i);
-         unsigned code = XUINT (LGLYPH_CODE (g));
+         unsigned code;
 
+         if (NILP (LGLYPH_FROM (g)))
+           break;
+         code = XUINT (LGLYPH_CODE (g));
          STORE_XCHAR2B (s->char2b + i, code >> 8, code & 0xFF);
        }
-      s->nchars = s->cmp->glyph_len;
       s->width = s->cmp->pixel_width;
     }
   else
@@ -20443,7 +20616,7 @@ x_produce_glyphs (it)
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
          if (face->overline_p)
-           it->ascent += 2;
+           it->ascent += overline_margin;
 
          if (it->constrain_row_ascent_descent_p)
            {
@@ -20643,7 +20816,7 @@ x_produce_glyphs (it)
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
          if (face->overline_p)
-           it->ascent += 2;
+           it->ascent += overline_margin;
 
          take_vertical_position_into_account (it);
 
@@ -20674,6 +20847,10 @@ x_produce_glyphs (it)
          it->char_to_display = unibyte_char_to_multibyte (it->c);
        }
 
+#ifdef USE_FONT_BACKEND
+      if (cmp->method != COMPOSITION_WITH_GLYPH_STRING)
+       {
+#endif /* USE_FONT_BACKEND */
       /* Get face and font to use.  Encode IT->char_to_display.  */
       pos = STRINGP (it->string) ? IT_STRING_CHARPOS (*it) : IT_CHARPOS (*it);
       it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
@@ -20698,6 +20875,9 @@ x_produce_glyphs (it)
          if (font_info->vertical_centering)
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
        }
+#ifdef USE_FONT_BACKEND
+       }
+#endif
 
       /* There are no padding glyphs, so there is only one glyph to
         produce for the composition.  Important is that pixel_width,
@@ -20991,7 +21171,7 @@ x_produce_glyphs (it)
       /* If face has an overline, add the height of the overline
         (1 pixel) and a 1 pixel margin to the character height.  */
       if (face->overline_p)
-       it->ascent += 2;
+       it->ascent += overline_margin;
 
       take_vertical_position_into_account (it);
 
@@ -21367,10 +21547,33 @@ get_window_cursor_type (w, glyph, width, active_cursor)
   /* Use normal cursor if not blinked off.  */
   if (!w->cursor_off_p)
     {
-      if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
-       if (cursor_type == FILLED_BOX_CURSOR)
-         cursor_type = HOLLOW_BOX_CURSOR;
+#ifdef HAVE_WINDOW_SYSTEM
+      if (glyph != NULL && glyph->type == IMAGE_GLYPH)
+       {
+         if (cursor_type == FILLED_BOX_CURSOR)
+           {
+             /* Using a block cursor on large images can be very annoying.
+                So use a hollow cursor for "large" images.  */
+             struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
+             if (img != NULL && IMAGEP (img->spec))
+               {
+                 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
+                    where N = size of default frame font size.
+                    This should cover most of the "tiny" icons people may use.  */
+                 if (img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
+                     || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
+                   cursor_type = HOLLOW_BOX_CURSOR;
+               }
+           }
+         else if (cursor_type != NO_CURSOR)
+           {
+             /* Display current only supports BOX and HOLLOW cursors for images.
+                So for now, unconditionally use a HOLLOW cursor when cursor is
+                not a solid box cursor.  */
+             cursor_type = HOLLOW_BOX_CURSOR;
+           }
       }
+#endif
       return cursor_type;
     }
 
@@ -24268,6 +24471,12 @@ whose contents depend on various data.  */);
               doc: /* Inhibit try_cursor_movement display optimization.  */);
   inhibit_try_cursor_movement = 0;
 #endif /* GLYPH_DEBUG */
+
+  DEFVAR_INT ("overline-margin", &overline_margin,
+              doc: /* *Space between overline and text, in pixels.
+The default value is 2: the height of the overline (1 pixel) plus 1 pixel
+margin to the caracter height.  */);
+  overline_margin = 2;
 }