Avoid crash on composition (backport from trunk).
[bpt/emacs.git] / src / xdisp.c
index 1f42e42..ca61947 100644 (file)
@@ -4641,6 +4641,11 @@ handle_composition_prop (it)
       && COMPOSITION_VALID_P (start, end, prop)
       && (STRINGP (it->string) || (PT <= start || PT >= end)))
     {
+      if (start < pos)
+       /* As we can't handle this situation (perhaps, font-lock added
+          a new composition), we just return here hoping that next
+          redisplay will detect this composition much earlier.  */
+       return HANDLED_NORMALLY;
       if (start != pos)
        {
          if (STRINGP (it->string))
@@ -19630,6 +19635,12 @@ fill_composite_glyph_string (s, base_face, overlaps)
     }
   s->cmp_to = i;
 
+  if (s->face == NULL)
+    {
+      s->face = base_face->ascii_face;
+      s->font = s->face->font;
+    }
+
   /* All glyph strings for the same composition has the same width,
      i.e. the width set for the first component of the composition.  */
   s->width = s->first_glyph->pixel_width;
@@ -23479,7 +23490,7 @@ note_mouse_highlight (f, x, y)
      int x, y;
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  enum window_part part;
+  enum window_part part = ON_NOTHING;
   Lisp_Object window;
   struct window *w;
   Cursor cursor = No_Cursor;
@@ -23513,11 +23524,14 @@ note_mouse_highlight (f, x, y)
   /* Which window is that in?  */
   window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
 
-  /* If we were displaying active text in another window, clear that.
-     Also clear if we move out of text area in same window.  */
+  /* If displaying active text in another window, clear that.  */
   if (! EQ (window, dpyinfo->mouse_face_window)
-      || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
-         && !NILP (dpyinfo->mouse_face_window)))
+      /* Also clear if we move out of text area in same window.  */
+      || (!NILP (dpyinfo->mouse_face_window)
+         && !NILP (window)
+         && part != ON_TEXT
+         && part != ON_MODE_LINE
+         && part != ON_HEADER_LINE))
     clear_mouse_face (dpyinfo);
 
   /* Not on a window -> return.  */
@@ -24244,7 +24258,7 @@ expose_window (w, fr)
     {
       int yb = window_text_bottom_y (w);
       struct glyph_row *row;
-      int cursor_cleared_p;
+      int cursor_cleared_p, phys_cursor_on_p;
       struct glyph_row *first_overlapping_row, *last_overlapping_row;
 
       TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
@@ -24264,6 +24278,13 @@ expose_window (w, fr)
       else
        cursor_cleared_p = 0;
 
+      /* If the row containing the cursor extends face to end of line,
+        then expose_area might overwrite the cursor outside the
+        rectangle and thus notice_overwritten_cursor might clear
+        w->phys_cursor_on_p.  We remember the original value and
+        check later if it is changed.  */
+      phys_cursor_on_p = w->phys_cursor_on_p;
+
       /* Update lines intersecting rectangle R.  */
       first_overlapping_row = last_overlapping_row = NULL;
       for (row = w->current_matrix->rows;
@@ -24330,7 +24351,8 @@ expose_window (w, fr)
          x_draw_vertical_border (w);
 
          /* Turn the cursor on again.  */
-         if (cursor_cleared_p)
+         if (cursor_cleared_p
+             || (phys_cursor_on_p && !w->phys_cursor_on_p))
            update_window_cursor (w, 1);
        }
     }