]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(try_window_id) <all changes below window end>: Don't
[gnu-emacs] / src / xterm.c
index a967774f57a138141ad7ada08e50a0460ba1eb36..c7b8535c4808443c3ea891552fd8cb802328e56a 100644 (file)
@@ -399,6 +399,8 @@ enum draw_glyphs_face
   DRAW_IMAGE_SUNKEN
 };
 
+static int cursor_in_mouse_face_p P_ ((struct window *));
+static int clear_mouse_face P_ ((struct x_display_info *));
 static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *));
 static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
 static const XColor *x_color_cells P_ ((Display *, int *));
@@ -4383,14 +4385,23 @@ x_draw_stretch_glyph_string (s)
       /* Clear rest using the GC of the original non-cursor face.  */
       if (width < s->background_width)
        {
-         GC gc = s->face->gc;
          int x = s->x + width, y = s->y;
          int w = s->background_width - width, h = s->height;
          XRectangle r;
+         GC gc;
 
+         if (s->row->mouse_face_p
+             && cursor_in_mouse_face_p (s->w))
+           {
+             x_set_mouse_face_gc (s);
+             gc = s->gc;
+           }
+         else
+           gc = s->face->gc;
+  
          x_get_glyph_string_clip_rect (s, &r);
          XSetClipRectangles (s->display, gc, 0, 0, &r, 1, Unsorted);
-
+         
          if (s->face->stipple)
            {
              /* Fill background with a stipple pattern.  */
@@ -5093,7 +5104,7 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
        }
 
       x += FRAME_INTERNAL_BORDER_WIDTH (f);
-      last_x -= FRAME_INTERNAL_BORDER_WIDTH (f);
+      last_x += FRAME_INTERNAL_BORDER_WIDTH (f);
     }
   else
     {
@@ -6793,6 +6804,8 @@ note_mouse_highlight (f, x, y)
   int portion;
   Lisp_Object window;
   struct window *w;
+  Cursor cursor = None;
+  struct buffer *b;
 
   /* When a menu is active, don't highlight because this looks odd.  */
 #ifdef USE_X_TOOLKIT
@@ -6840,31 +6853,35 @@ note_mouse_highlight (f, x, y)
       return;
     }
 
+  /* Mouse is on the mode or header line?  */
   if (portion == 1 || portion == 3)
     {
-      /* Mouse is on the mode or top line.  */
       note_mode_line_highlight (w, x, portion == 1);
       return;
     }
-  else if (portion == 2)
-    XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                  f->output_data.x->horizontal_drag_cursor);
+  
+  if (portion == 2)
+    cursor = f->output_data.x->horizontal_drag_cursor;
   else
-    XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                  f->output_data.x->text_cursor);
+    cursor = f->output_data.x->text_cursor;
 
   /* Are we in a window whose display is up to date?
      And verify the buffer's text has not changed.  */
+  b = XBUFFER (w->buffer);
   if (/* Within text portion of the window.  */
       portion == 0
       && EQ (w->window_end_valid, w->buffer)
-      && XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))
-      && (XFASTINT (w->last_overlay_modified)
-         == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
+      && XFASTINT (w->last_modified) == BUF_MODIFF (b)
+      && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
     {
       int hpos, vpos, pos, i, area;
       struct glyph *glyph;
       Lisp_Object object;
+      Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
+      Lisp_Object *overlay_vec = NULL;
+      int len, noverlays;
+      struct buffer *obuf;
+      int obegv, ozv, same_region;
 
       /* Find the glyph under X/Y.  */
       glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
@@ -6874,270 +6891,285 @@ note_mouse_highlight (f, x, y)
          || area != TEXT_AREA
          || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
        {
-         clear_mouse_face (dpyinfo);
-         return;
+         if (clear_mouse_face (dpyinfo))
+           cursor = None;
+         goto set_cursor;
        }
 
       pos = glyph->charpos;
       object = glyph->object;
       if (!STRINGP (object) && !BUFFERP (object))
-       return;
+       goto set_cursor;
 
-      {
-       Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
-       Lisp_Object *overlay_vec = NULL;
-       int len, noverlays;
-       struct buffer *obuf;
-       int obegv, ozv;
-
-       /* If we get an out-of-range value, return now; avoid an error.  */
-       if (BUFFERP (object) && pos > BUF_Z (XBUFFER (w->buffer)))
-         return;
-
-       /* Make the window's buffer temporarily current for
-          overlays_at and compute_char_face.  */
-       obuf = current_buffer;
-       current_buffer = XBUFFER (w->buffer);
-       obegv = BEGV;
-       ozv = ZV;
-       BEGV = BEG;
-       ZV = Z;
-
-       /* Is this char mouse-active or does it have help-echo?  */
-       position = make_number (pos);
-
-       if (BUFFERP (object))
-         {
-           /* Put all the overlays we want in a vector in overlay_vec.
-              Store the length in len.  If there are more than 10, make
-              enough space for all, and try again.  */
-           len = 10;
-           overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
-           noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
-           if (noverlays > len)
-             {
-               len = noverlays;
-               overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
-               noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
-             }
+      /* If we get an out-of-range value, return now; avoid an error.  */
+      if (BUFFERP (object) && pos > BUF_Z (b))
+       goto set_cursor;
 
-           /* Sort overlays into increasing priority order.  */
-           noverlays = sort_overlays (overlay_vec, noverlays, w);
-         }
-       else
-         noverlays = 0;
-
-       /* Check mouse-face highlighting.  */
-       if (! (EQ (window, dpyinfo->mouse_face_window)
-              && vpos >= dpyinfo->mouse_face_beg_row
-              && vpos <= dpyinfo->mouse_face_end_row
-              && (vpos > dpyinfo->mouse_face_beg_row
-                  || hpos >= dpyinfo->mouse_face_beg_col)
-              && (vpos < dpyinfo->mouse_face_end_row
-                  || hpos < dpyinfo->mouse_face_end_col
-                  || dpyinfo->mouse_face_past_end))
-           /* If there exists an overlay with mouse-face overlapping
-              the one we are currently highlighting, we have to
-              check if we enter the overlapping overlay, and then
-              highlight only that.  */
-           || (OVERLAYP (dpyinfo->mouse_face_overlay)
-               && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
-         
-         {
-           /* Clear the display of the old active region, if any.  */
-           clear_mouse_face (dpyinfo);
+      /* Make the window's buffer temporarily current for
+        overlays_at and compute_char_face.  */
+      obuf = current_buffer;
+      current_buffer = b;
+      obegv = BEGV;
+      ozv = ZV;
+      BEGV = BEG;
+      ZV = Z;
 
-           /* Find the highest priority overlay that has a mouse-face
-              property.  */
-           overlay = Qnil;
-           for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
-             {
-               mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
-               if (!NILP (mouse_face))
-                 overlay = overlay_vec[i];
-             }
-           dpyinfo->mouse_face_overlay = overlay;
+      /* Is this char mouse-active or does it have help-echo?  */
+      position = make_number (pos);
+
+      if (BUFFERP (object))
+       {
+         /* Put all the overlays we want in a vector in overlay_vec.
+            Store the length in len.  If there are more than 10, make
+            enough space for all, and try again.  */
+         len = 10;
+         overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
+         noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
+         if (noverlays > len)
+           {
+             len = noverlays;
+             overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
+             noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
+           }
+
+         /* Sort overlays into increasing priority order.  */
+         noverlays = sort_overlays (overlay_vec, noverlays, w);
+       }
+      else
+       noverlays = 0;
+
+      same_region = (EQ (window, dpyinfo->mouse_face_window)
+                    && vpos >= dpyinfo->mouse_face_beg_row
+                    && vpos <= dpyinfo->mouse_face_end_row
+                    && (vpos > dpyinfo->mouse_face_beg_row
+                        || hpos >= dpyinfo->mouse_face_beg_col)
+                    && (vpos < dpyinfo->mouse_face_end_row
+                        || hpos < dpyinfo->mouse_face_end_col
+                        || dpyinfo->mouse_face_past_end));
+
+      if (same_region)
+       cursor = None;
+
+      /* Check mouse-face highlighting.  */
+      if (! same_region
+         /* If there exists an overlay with mouse-face overlapping
+            the one we are currently highlighting, we have to
+            check if we enter the overlapping overlay, and then
+            highlight only that.  */
+         || (OVERLAYP (dpyinfo->mouse_face_overlay)
+             && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
+       {
+         /* Find the highest priority overlay that has a mouse-face
+            property.  */
+         overlay = Qnil;
+         for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
+           {
+             mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
+             if (!NILP (mouse_face))
+               overlay = overlay_vec[i];
+           }
+         
+         /* If we're actually highlighting the same overlay as
+            before, there's no need to do that again.  */
+         if (!NILP (overlay)
+             && EQ (overlay, dpyinfo->mouse_face_overlay))
+           goto check_help_echo;
            
-           /* If no overlay applies, get a text property.  */
-           if (NILP (overlay))
-             mouse_face = Fget_text_property (position, Qmouse_face, object);
+         dpyinfo->mouse_face_overlay = overlay;
 
-           /* Handle the overlay case.  */
-           if (!NILP (overlay))
-             {
-               /* Find the range of text around this char that
-                  should be active.  */
-               Lisp_Object before, after;
-               int ignore;
-
-               before = Foverlay_start (overlay);
-               after = Foverlay_end (overlay);
-               /* Record this as the current active region.  */
-               fast_find_position (w, XFASTINT (before),
-                                   &dpyinfo->mouse_face_beg_col,
-                                   &dpyinfo->mouse_face_beg_row,
-                                   &dpyinfo->mouse_face_beg_x,
-                                   &dpyinfo->mouse_face_beg_y);
-               dpyinfo->mouse_face_past_end
-                 = !fast_find_position (w, XFASTINT (after),
-                                        &dpyinfo->mouse_face_end_col,
-                                        &dpyinfo->mouse_face_end_row,
-                                        &dpyinfo->mouse_face_end_x,
-                                        &dpyinfo->mouse_face_end_y);
-               dpyinfo->mouse_face_window = window;
+         /* Clear the display of the old active region, if any.  */
+         if (clear_mouse_face (dpyinfo))
+           cursor = None;
+
+         /* If no overlay applies, get a text property.  */
+         if (NILP (overlay))
+           mouse_face = Fget_text_property (position, Qmouse_face, object);
+
+         /* Handle the overlay case.  */
+         if (!NILP (overlay))
+           {
+             /* Find the range of text around this char that
+                should be active.  */
+             Lisp_Object before, after;
+             int ignore;
+
+             before = Foverlay_start (overlay);
+             after = Foverlay_end (overlay);
+             /* Record this as the current active region.  */
+             fast_find_position (w, XFASTINT (before),
+                                 &dpyinfo->mouse_face_beg_col,
+                                 &dpyinfo->mouse_face_beg_row,
+                                 &dpyinfo->mouse_face_beg_x,
+                                 &dpyinfo->mouse_face_beg_y);
+             dpyinfo->mouse_face_past_end
+               = !fast_find_position (w, XFASTINT (after),
+                                      &dpyinfo->mouse_face_end_col,
+                                      &dpyinfo->mouse_face_end_row,
+                                      &dpyinfo->mouse_face_end_x,
+                                      &dpyinfo->mouse_face_end_y);
+             dpyinfo->mouse_face_window = window;
+             dpyinfo->mouse_face_face_id
+               = face_at_buffer_position (w, pos, 0, 0,
+                                          &ignore, pos + 1, 1);
+
+             /* Display it as active.  */
+             show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+             cursor = None;
+           }
+         /* Handle the text property case.  */
+         else if (!NILP (mouse_face) && BUFFERP (object))
+           {
+             /* Find the range of text around this char that
+                should be active.  */
+             Lisp_Object before, after, beginning, end;
+             int ignore;
+
+             beginning = Fmarker_position (w->start);
+             end = make_number (BUF_Z (XBUFFER (object))
+                                - XFASTINT (w->window_end_pos));
+             before
+               = Fprevious_single_property_change (make_number (pos + 1),
+                                                   Qmouse_face,
+                                                   object, beginning);
+             after
+               = Fnext_single_property_change (position, Qmouse_face,
+                                               object, end);
+               
+             /* Record this as the current active region.  */
+             fast_find_position (w, XFASTINT (before),
+                                 &dpyinfo->mouse_face_beg_col,
+                                 &dpyinfo->mouse_face_beg_row,
+                                 &dpyinfo->mouse_face_beg_x,
+                                 &dpyinfo->mouse_face_beg_y);
+             dpyinfo->mouse_face_past_end
+               = !fast_find_position (w, XFASTINT (after),
+                                      &dpyinfo->mouse_face_end_col,
+                                      &dpyinfo->mouse_face_end_row,
+                                      &dpyinfo->mouse_face_end_x,
+                                      &dpyinfo->mouse_face_end_y);
+             dpyinfo->mouse_face_window = window;
+
+             if (BUFFERP (object))
                dpyinfo->mouse_face_face_id
                  = face_at_buffer_position (w, pos, 0, 0,
                                             &ignore, pos + 1, 1);
 
-               /* Display it as active.  */
-               show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
-             }
-           /* Handle the text property case.  */
-           else if (!NILP (mouse_face) && BUFFERP (object))
-             {
-               /* Find the range of text around this char that
-                  should be active.  */
-               Lisp_Object before, after, beginning, end;
-               int ignore;
-
-               beginning = Fmarker_position (w->start);
-               end = make_number (BUF_Z (XBUFFER (object))
-                                  - XFASTINT (w->window_end_pos));
-               before
-                 = Fprevious_single_property_change (make_number (pos + 1),
-                                                     Qmouse_face,
-                                                     object, beginning);
-               after
-                 = Fnext_single_property_change (position, Qmouse_face,
-                                                 object, end);
+             /* Display it as active.  */
+             show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+             cursor = None;
+           }
+         else if (!NILP (mouse_face) && STRINGP (object))
+           {
+             Lisp_Object b, e;
+             int ignore;
                
-               /* Record this as the current active region.  */
-               fast_find_position (w, XFASTINT (before),
+             b = Fprevious_single_property_change (make_number (pos + 1),
+                                                   Qmouse_face,
+                                                   object, Qnil);
+             e = Fnext_single_property_change (position, Qmouse_face,
+                                               object, Qnil);
+             if (NILP (b))
+               b = make_number (0);
+             if (NILP (e))
+               e = make_number (XSTRING (object)->size - 1);
+             fast_find_string_pos (w, XINT (b), object,
                                    &dpyinfo->mouse_face_beg_col,
                                    &dpyinfo->mouse_face_beg_row,
                                    &dpyinfo->mouse_face_beg_x,
-                                   &dpyinfo->mouse_face_beg_y);
-               dpyinfo->mouse_face_past_end
-                 = !fast_find_position (w, XFASTINT (after),
-                                        &dpyinfo->mouse_face_end_col,
-                                        &dpyinfo->mouse_face_end_row,
-                                        &dpyinfo->mouse_face_end_x,
-                                        &dpyinfo->mouse_face_end_y);
-               dpyinfo->mouse_face_window = window;
-
-               if (BUFFERP (object))
-                 dpyinfo->mouse_face_face_id
-                   = face_at_buffer_position (w, pos, 0, 0,
-                                              &ignore, pos + 1, 1);
-
-               /* Display it as active.  */
-               show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
-             }
-           else if (!NILP (mouse_face) && STRINGP (object))
-             {
-               Lisp_Object b, e;
-               int ignore;
-               
-               b = Fprevious_single_property_change (make_number (pos + 1),
-                                                     Qmouse_face,
-                                                     object, Qnil);
-               e = Fnext_single_property_change (position, Qmouse_face,
-                                                 object, Qnil);
-               if (NILP (b))
-                 b = make_number (0);
-               if (NILP (e))
-                 e = make_number (XSTRING (object)->size - 1);
-               fast_find_string_pos (w, XINT (b), object,
-                                     &dpyinfo->mouse_face_beg_col,
-                                     &dpyinfo->mouse_face_beg_row,
-                                     &dpyinfo->mouse_face_beg_x,
-                                     &dpyinfo->mouse_face_beg_y, 0);
-               fast_find_string_pos (w, XINT (e), object,
-                                     &dpyinfo->mouse_face_end_col,
-                                     &dpyinfo->mouse_face_end_row,
-                                     &dpyinfo->mouse_face_end_x,
-                                     &dpyinfo->mouse_face_end_y, 1);
-               dpyinfo->mouse_face_past_end = 0;
-               dpyinfo->mouse_face_window = window;
-               dpyinfo->mouse_face_face_id
-                 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
-                                            glyph->face_id, 1);
-               show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
-             }
-         }
+                                   &dpyinfo->mouse_face_beg_y, 0);
+             fast_find_string_pos (w, XINT (e), object,
+                                   &dpyinfo->mouse_face_end_col,
+                                   &dpyinfo->mouse_face_end_row,
+                                   &dpyinfo->mouse_face_end_x,
+                                   &dpyinfo->mouse_face_end_y, 1);
+             dpyinfo->mouse_face_past_end = 0;
+             dpyinfo->mouse_face_window = window;
+             dpyinfo->mouse_face_face_id
+               = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
+                                          glyph->face_id, 1);
+             show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+             cursor = None;
+           }
+       }
 
-       /* Look for a `help-echo' property.  */
-       {
-         Lisp_Object help, overlay;
+    check_help_echo:
 
-         /* Check overlays first.  */
-         help = overlay = Qnil;
-         for (i = noverlays - 1; i >= 0 && NILP (help); --i)
-           {
-             overlay = overlay_vec[i];
-             help = Foverlay_get (overlay, Qhelp_echo);
-           }
+      /* Look for a `help-echo' property.  */
+      {
+       Lisp_Object help, overlay;
 
-         if (!NILP (help))
-           {
-             help_echo = help;
-             help_echo_window = window;
-             help_echo_object = overlay;
-             help_echo_pos = pos;
-           }
-         else
-           {
-             Lisp_Object object = glyph->object;
-             int charpos = glyph->charpos;
+       /* Check overlays first.  */
+       help = overlay = Qnil;
+       for (i = noverlays - 1; i >= 0 && NILP (help); --i)
+         {
+           overlay = overlay_vec[i];
+           help = Foverlay_get (overlay, Qhelp_echo);
+         }
+
+       if (!NILP (help))
+         {
+           help_echo = help;
+           help_echo_window = window;
+           help_echo_object = overlay;
+           help_echo_pos = pos;
+         }
+       else
+         {
+           Lisp_Object object = glyph->object;
+           int charpos = glyph->charpos;
              
-             /* Try text properties.  */
-             if (STRINGP (object)
-                 && charpos >= 0
-                 && charpos < XSTRING (object)->size)
-               {
-                 help = Fget_text_property (make_number (charpos),
-                                            Qhelp_echo, object);
-                 if (NILP (help))
-                   {
-                     /* If the string itself doesn't specify a help-echo,
-                        see if the buffer text ``under'' it does.  */
-                     struct glyph_row *r
-                       = MATRIX_ROW (w->current_matrix, vpos);
-                     int start = MATRIX_ROW_START_CHARPOS (r);
-                     int pos = string_buffer_position (w, object, start);
-                     if (pos > 0)
-                       {
-                         help = Fget_text_property (make_number (pos),
-                                                    Qhelp_echo, w->buffer);
-                         if (!NILP (help))
-                           {
-                             charpos = pos;
-                             object = w->buffer;
-                           }
-                       }
-                   }
-               }
-             else if (BUFFERP (object)
-                      && charpos >= BEGV
-                      && charpos < ZV)
-               help = Fget_text_property (make_number (charpos), Qhelp_echo,
-                                          object);
+           /* Try text properties.  */
+           if (STRINGP (object)
+               && charpos >= 0
+               && charpos < XSTRING (object)->size)
+             {
+               help = Fget_text_property (make_number (charpos),
+                                          Qhelp_echo, object);
+               if (NILP (help))
+                 {
+                   /* If the string itself doesn't specify a help-echo,
+                      see if the buffer text ``under'' it does.  */
+                   struct glyph_row *r
+                     = MATRIX_ROW (w->current_matrix, vpos);
+                   int start = MATRIX_ROW_START_CHARPOS (r);
+                   int pos = string_buffer_position (w, object, start);
+                   if (pos > 0)
+                     {
+                       help = Fget_text_property (make_number (pos),
+                                                  Qhelp_echo, w->buffer);
+                       if (!NILP (help))
+                         {
+                           charpos = pos;
+                           object = w->buffer;
+                         }
+                     }
+                 }
+             }
+           else if (BUFFERP (object)
+                    && charpos >= BEGV
+                    && charpos < ZV)
+             help = Fget_text_property (make_number (charpos), Qhelp_echo,
+                                        object);
            
-             if (!NILP (help))
-               {
-                 help_echo = help;
-                 help_echo_window = window;
-                 help_echo_object = object;
-                 help_echo_pos = charpos;
-               }
-           }
-       }
-         
-       BEGV = obegv;
-       ZV = ozv;
-       current_buffer = obuf;
+           if (!NILP (help))
+             {
+               help_echo = help;
+               help_echo_window = window;
+               help_echo_object = object;
+               help_echo_pos = charpos;
+             }
+         }
       }
+         
+      BEGV = obegv;
+      ZV = ozv;
+      current_buffer = obuf;
     }
+
+ set_cursor:
+  
+  if (cursor != None)
+    XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
 }
 
 static void
@@ -7646,24 +7678,26 @@ show_mouse_face (dpyinfo, draw)
 }
 
 /* Clear out the mouse-highlighted active region.
-   Redraw it un-highlighted first.  */
+   Redraw it un-highlighted first.  Value is non-zero if mouse
+   face was actually drawn unhighlighted.  */
 
-void
+static int
 clear_mouse_face (dpyinfo)
      struct x_display_info *dpyinfo;
 {
-#if 0 /* This prevents redrawing tool bar items when changing from one
-        to another while a tooltip is open, so don't do it.  */
-  if (!NILP (tip_frame))
-    return;
-#endif
+  int cleared = 0;
   
-  if (! NILP (dpyinfo->mouse_face_window))
-    show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
+  if (!NILP (dpyinfo->mouse_face_window))
+    {
+      show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
+      cleared = 1;
+    }
 
   dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
   dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
   dpyinfo->mouse_face_window = Qnil;
+  dpyinfo->mouse_face_overlay = Qnil;
+  return cleared;
 }
 
 
@@ -10025,6 +10059,9 @@ XTread_socket (sd, bufp, numchars, expected)
                }
              else
                {
+#ifndef USE_TOOLKIT_SCROLL_BARS
+                 struct scroll_bar *bar;
+#endif
 #if defined USE_X_TOOLKIT && defined USE_LUCID
                  /* Submenus of the Lucid menu bar aren't widgets
                     themselves, so there's no way to dispatch events
@@ -10041,8 +10078,7 @@ XTread_socket (sd, bufp, numchars, expected)
                  /* Dispatch event to the widget.  */
                  goto OTHER;
 #else /* not USE_TOOLKIT_SCROLL_BARS */
-                 struct scroll_bar *bar
-                   = x_window_to_scroll_bar (event.xexpose.window);
+                 bar = x_window_to_scroll_bar (event.xexpose.window);
 
                  if (bar)
                    x_scroll_bar_expose (bar, &event);
@@ -11185,6 +11221,35 @@ x_erase_phys_cursor (w)
 }
 
 
+/* Non-zero if physical cursor of window W is within mouse face.  */
+
+static int
+cursor_in_mouse_face_p (w)
+     struct window *w;
+{
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
+  int in_mouse_face = 0;
+  
+  if (WINDOWP (dpyinfo->mouse_face_window)
+      && XWINDOW (dpyinfo->mouse_face_window) == w)
+    {
+      int hpos = w->phys_cursor.hpos;
+      int vpos = w->phys_cursor.vpos;
+
+      if (vpos >= dpyinfo->mouse_face_beg_row
+         && vpos <= dpyinfo->mouse_face_end_row
+         && (vpos > dpyinfo->mouse_face_beg_row
+             || hpos >= dpyinfo->mouse_face_beg_col)
+         && (vpos < dpyinfo->mouse_face_end_row
+             || hpos < dpyinfo->mouse_face_end_col
+             || dpyinfo->mouse_face_past_end))
+       in_mouse_face = 1;
+    }
+
+  return in_mouse_face;
+}
+
+
 /* Display or clear cursor of window W.  If ON is zero, clear the
    cursor.  If it is non-zero, display the cursor.  If ON is nonzero,
    where to put the cursor is specified by HPOS, VPOS, X and Y.  */
@@ -11967,7 +12032,7 @@ xim_open_dpy (dpyinfo, resource_name)
 #ifdef HAVE_X11R6
       destroy.callback = xim_destroy_callback;
       destroy.client_data = (XPointer)dpyinfo;
-      /* This isn't prptotyped in OSF 5.0.  */
+      /* This isn't prototyped in OSF 5.0.  */
       XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
 #endif
     }