]> code.delx.au - gnu-emacs/blobdiff - src/w32term.c
Merge from emacs--devo--0
[gnu-emacs] / src / w32term.c
index f0d5dc507acc8b11a0d1322212ffca23f8f5fd47..0a7007cc8f45b4334867ed64b3bcc30d7330356b 100644 (file)
@@ -1,6 +1,6 @@
 /* Implementation of GUI terminal on the Microsoft W32 API.
    Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-                 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+                 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -173,32 +173,6 @@ HANDLE hWindowsThread = NULL;
 DWORD dwMainThreadId = 0;
 HANDLE hMainThread = NULL;
 
-#ifndef SIF_ALL
-/* These definitions are new with Windows 95. */
-#define SIF_RANGE           0x0001
-#define SIF_PAGE            0x0002
-#define SIF_POS             0x0004
-#define SIF_DISABLENOSCROLL 0x0008
-#define SIF_TRACKPOS        0x0010
-#define SIF_ALL             (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
-
-typedef struct tagSCROLLINFO
-{
-    UINT    cbSize;
-    UINT    fMask;
-    int     nMin;
-    int     nMax;
-    UINT    nPage;
-    int     nPos;
-    int     nTrackPos;
-}   SCROLLINFO, FAR *LPSCROLLINFO;
-typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;
-#endif /* SIF_ALL */
-
-/* Dynamic linking to new proportional scroll bar functions. */
-int (PASCAL *pfnSetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw);
-BOOL (PASCAL *pfnGetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi);
-
 int vertical_scroll_bar_min_handle;
 int vertical_scroll_bar_top_border;
 int vertical_scroll_bar_bottom_border;
@@ -210,6 +184,7 @@ int last_scroll_bar_drag_pos;
 /* Where the mouse was last time we reported a mouse event.  */
 
 static RECT last_mouse_glyph;
+static FRAME_PTR last_mouse_glyph_frame;
 static Lisp_Object last_mouse_press_frame;
 
 int w32_num_mouse_buttons;
@@ -1718,7 +1693,7 @@ x_draw_glyph_string_foreground (s)
   else
     x = s->x;
 
-  if (s->for_overlaps_p || (s->background_filled_p && s->hl != DRAW_CURSOR))
+  if (s->for_overlaps || (s->background_filled_p && s->hl != DRAW_CURSOR))
     SetBkMode (s->hdc, TRANSPARENT);
   else
     SetBkMode (s->hdc, OPAQUE);
@@ -2539,20 +2514,29 @@ x_draw_stretch_glyph_string (s)
     {
       /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
         as wide as the stretch glyph.  */
-      int width = min (FRAME_COLUMN_WIDTH (s->f), s->background_width);
+      int width, background_width = s->background_width;
+      int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+      if (x < left_x)
+       {
+         background_width -= left_x - x;
+         x = left_x;
+       }
+      width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
 
       /* Draw cursor.  */
-      x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
+      x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
 
       /* Clear rest using the GC of the original non-cursor face.  */
-      if (width < s->background_width)
+      if (width < background_width)
        {
          XGCValues *gc = s->face->gc;
-         int x = s->x + width, y = s->y;
-         int w = s->background_width - width, h = s->height;
+         int y = s->y;
+         int w = background_width - width, h = s->height;
          RECT r;
           HDC hdc = s->hdc;
 
+         x += width;
          if (s->row->mouse_face_p
              && cursor_in_mouse_face_p (s->w))
            {
@@ -2581,8 +2565,18 @@ x_draw_stretch_glyph_string (s)
         }
     }
   else if (!s->background_filled_p)
-    x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
-                                s->height);
+    {
+      int background_width = s->background_width;
+      int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+      if (x < left_x)
+       {
+         background_width -= left_x - x;
+         x = left_x;
+       }
+      if (background_width > 0)
+       x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+    }
 
   s->background_filled_p = 1;
 }
@@ -2599,7 +2593,7 @@ x_draw_glyph_string (s)
   /* If S draws into the background of its successor, draw the
      background of the successor first so that S can draw into it.
      This makes S->next use XDrawString instead of XDrawImageString.  */
-  if (s->next && s->right_overhang && !s->for_overlaps_p)
+  if (s->next && s->right_overhang && !s->for_overlaps)
     {
       xassert (s->next->img == NULL);
       x_set_glyph_string_gc (s->next);
@@ -2612,7 +2606,7 @@ x_draw_glyph_string (s)
 
   /* Draw relief (if any) in advance for char/composition so that the
      glyph string can be drawn over it.  */
-  if (!s->for_overlaps_p
+  if (!s->for_overlaps
       && s->face->box != FACE_NO_BOX
       && (s->first_glyph->type == CHAR_GLYPH
          || s->first_glyph->type == COMPOSITE_GLYPH))
@@ -2638,7 +2632,7 @@ x_draw_glyph_string (s)
       break;
 
     case CHAR_GLYPH:
-      if (s->for_overlaps_p)
+      if (s->for_overlaps)
        s->background_filled_p = 1;
       else
         x_draw_glyph_string_background (s, 0);
@@ -2646,7 +2640,7 @@ x_draw_glyph_string (s)
       break;
 
     case COMPOSITE_GLYPH:
-      if (s->for_overlaps_p || s->gidx > 0)
+      if (s->for_overlaps || s->gidx > 0)
        s->background_filled_p = 1;
       else
        x_draw_glyph_string_background (s, 1);
@@ -2657,7 +2651,7 @@ x_draw_glyph_string (s)
       abort ();
     }
 
-  if (!s->for_overlaps_p)
+  if (!s->for_overlaps)
     {
       /* Draw underline.  */
       if (s->face->underline_p
@@ -3281,8 +3275,10 @@ construct_mouse_wheel (result, msg, f)
   result->modifiers = (msg->dwModifiers
                        | ((delta < 0 ) ? down_modifier : up_modifier));
 
-  p.x = LOWORD (msg->msg.lParam);
-  p.y = HIWORD (msg->msg.lParam);
+  /* With multiple monitors, we can legitimately get negative
+     coordinates, so cast to short to interpret them correctly.  */
+  p.x = (short) LOWORD (msg->msg.lParam);
+  p.y = (short) HIWORD (msg->msg.lParam);
   ScreenToClient (msg->msg.hwnd, &p);
   XSETINT (result->x, p.x);
   XSETINT (result->y, p.y);
@@ -3338,8 +3334,8 @@ construct_drag_n_drop (result, msg, f)
   DragFinish (hdrop);
 
   XSETFRAME (frame, f);
-  result->frame_or_window = Fcons (frame, files);
-  result->arg = Qnil;
+  result->frame_or_window = frame;
+  result->arg = files;
   return Qnil;
 }
 
@@ -3355,9 +3351,7 @@ construct_drag_n_drop (result, msg, f)
 static MSG last_mouse_motion_event;
 static Lisp_Object last_mouse_motion_frame;
 
-static void remember_mouse_glyph P_ ((struct frame *, int, int));
-
-static void
+static int
 note_mouse_movement (frame, msg)
      FRAME_PTR frame;
      MSG *msg;
@@ -3374,13 +3368,16 @@ note_mouse_movement (frame, msg)
       frame->mouse_moved = 1;
       last_mouse_scroll_bar = Qnil;
       note_mouse_highlight (frame, -1, -1);
+      last_mouse_glyph_frame = 0;
+      return 1;
     }
 
   /* Has the mouse moved off the glyph it was on at the last sighting?  */
-  else if (mouse_x < last_mouse_glyph.left
-          || mouse_x > last_mouse_glyph.right
-          || mouse_y < last_mouse_glyph.top
-          || mouse_y > last_mouse_glyph.bottom)
+  if (frame != last_mouse_glyph_frame
+      || mouse_x < last_mouse_glyph.left
+      || mouse_x >= last_mouse_glyph.right
+      || mouse_y < last_mouse_glyph.top
+      || mouse_y >= last_mouse_glyph.bottom)
     {
       frame->mouse_moved = 1;
       last_mouse_scroll_bar = Qnil;
@@ -3389,8 +3386,12 @@ note_mouse_movement (frame, msg)
         gets called when mouse tracking is enabled but we also need
         to keep track of the mouse for help_echo and highlighting at
         other times.  */
-      remember_mouse_glyph (frame, mouse_x, mouse_y);
+      remember_mouse_glyph (frame, mouse_x, mouse_y, &last_mouse_glyph);
+      last_mouse_glyph_frame = frame;
+      return 1;
     }
+
+  return 0;
 }
 
 \f
@@ -3401,8 +3402,6 @@ note_mouse_movement (frame, msg)
 static struct scroll_bar *x_window_to_scroll_bar ();
 static void x_scroll_bar_report_motion ();
 static void x_check_fullscreen P_ ((struct frame *));
-static int glyph_rect P_ ((struct frame *f, int, int, RECT *));
-
 
 static void
 redo_mouse_highlight ()
@@ -3421,108 +3420,6 @@ w32_define_cursor (window, cursor)
 {
   PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
 }
-
-/* Try to determine frame pixel position and size of the glyph under
-   frame pixel coordinates X/Y on frame F .  Return the position and
-   size in *RECT.  Value is non-zero if we could compute these
-   values.  */
-
-static int
-glyph_rect (f, x, y, rect)
-     struct frame *f;
-     int x, y;
-     RECT *rect;
-{
-  Lisp_Object window;
-
-  window = window_from_coordinates (f, x, y, 0, &x, &y, 0);
-
-  if (!NILP (window))
-    {
-      struct window *w = XWINDOW (window);
-      struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
-      struct glyph_row *end = r + w->current_matrix->nrows - 1;
-
-      for (; r < end && r->enabled_p; ++r)
-       if (r->y <= y && r->y + r->height > y)
-         {
-           /* Found the row at y.  */
-           struct glyph *g = r->glyphs[TEXT_AREA];
-           struct glyph *end = g + r->used[TEXT_AREA];
-           int gx;
-
-           rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
-           rect->bottom = rect->top + r->height;
-
-           if (x < r->x)
-             {
-               /* x is to the left of the first glyph in the row.  */
-               /* Shouldn't this be a pixel value?
-                  WINDOW_LEFT_EDGE_X (w) seems to be the right value.
-                  ++KFS */
-               rect->left = WINDOW_LEFT_EDGE_COL (w);
-               rect->right = WINDOW_TO_FRAME_PIXEL_X (w, r->x);
-               return 1;
-             }
-
-           for (gx = r->x; g < end; gx += g->pixel_width, ++g)
-             if (gx <= x && gx + g->pixel_width > x)
-               {
-                 /* x is on a glyph.  */
-                 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
-                 rect->right = rect->left + g->pixel_width;
-                 return 1;
-               }
-
-           /* x is to the right of the last glyph in the row.  */
-           rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
-           /* Shouldn't this be a pixel value?
-              WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
-              ++KFS */
-           rect->right = WINDOW_RIGHT_EDGE_COL (w);
-           return 1;
-         }
-    }
-
-  /* The y is not on any row.  */
-  return 0;
-}
-
-/* Record the position of the mouse in last_mouse_glyph.  */
-static void
-remember_mouse_glyph (f1, gx, gy)
-     struct frame * f1;
-     int gx, gy;
-{
-  if (!glyph_rect (f1, gx, gy, &last_mouse_glyph))
-    {
-      int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
-      int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
-
-      /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
-        round down even for negative values.  */
-      if (gx < 0)
-       gx -= width - 1;
-      if (gy < 0)
-       gy -= height - 1;
-#if 0
-      /* This was the original code from XTmouse_position, but it seems
-        to give the position of the glyph diagonally next to the one
-        the mouse is over.  */
-      gx = (gx + width - 1) / width * width;
-      gy = (gy + height - 1) / height * height;
-#else
-      gx = gx / width * width;
-      gy = gy / height * height;
-#endif
-
-      last_mouse_glyph.left = gx;
-      last_mouse_glyph.top = gy;
-      last_mouse_glyph.right  = gx + width;
-      last_mouse_glyph.bottom = gy + height;
-    }
-}
-
 /* Return the current position of the mouse.
    *fp should be a frame which indicates which display to ask about.
 
@@ -3614,19 +3511,9 @@ w32_mouse_position (fp, insist, bar_window, part, x, y, time)
               on it, i.e. into the same rectangles that matrices on
               the frame are divided into.  */
 
-#if OLD_REDISPLAY_CODE
-           int ignore1, ignore2;
-
-           ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
-
-           pixel_to_glyph_coords (f1, pt.x, pt.y, &ignore1, &ignore2,
-                                  &last_mouse_glyph,
-                                  FRAME_W32_DISPLAY_INFO (f1)->grabbed
-                                  || insist);
-#else
            ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
-           remember_mouse_glyph (f1, pt.x, pt.y);
-#endif
+           remember_mouse_glyph (f1, pt.x, pt.y, &last_mouse_glyph);
+           last_mouse_glyph_frame = f1;
 
            *bar_window = Qnil;
            *part = 0;
@@ -3725,6 +3612,7 @@ w32_set_scroll_bar_thumb (bar, portion, position, whole)
   double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
   int sb_page, sb_pos;
   BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
+  SCROLLINFO si;
 
   if (whole)
     {
@@ -3749,24 +3637,17 @@ w32_set_scroll_bar_thumb (bar, portion, position, whole)
 
   BLOCK_INPUT;
 
-  if (pfnSetScrollInfo)
-    {
-      SCROLLINFO si;
-
-      si.cbSize = sizeof (si);
-      /* Only update page size if currently dragging, to reduce
-         flicker effects.  */
-      if (draggingp)
-        si.fMask = SIF_PAGE;
-      else
-        si.fMask = SIF_PAGE | SIF_POS;
-      si.nPage = sb_page;
-      si.nPos = sb_pos;
-
-      pfnSetScrollInfo (w, SB_CTL, &si, !draggingp);
-    }
+  si.cbSize = sizeof (si);
+  /* Only update page size if currently dragging, to reduce
+     flicker effects.  */
+  if (draggingp)
+    si.fMask = SIF_PAGE;
   else
-    SetScrollPos (w, SB_CTL, sb_pos, !draggingp);
+    si.fMask = SIF_PAGE | SIF_POS;
+  si.nPage = sb_page;
+  si.nPos = sb_pos;
+
+  SetScrollInfo (w, SB_CTL, &si, !draggingp);
 
   UNBLOCK_INPUT;
 }
@@ -3855,6 +3736,7 @@ x_scroll_bar_create (w, top, left, width, height)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   HWND hwnd;
+  SCROLLINFO si;
   struct scroll_bar *bar
     = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
 
@@ -3873,26 +3755,15 @@ x_scroll_bar_create (w, top, left, width, height)
 
   hwnd = my_create_scrollbar (f, bar);
 
-  if (pfnSetScrollInfo)
-    {
-      SCROLLINFO si;
-
-      si.cbSize = sizeof (si);
-      si.fMask = SIF_ALL;
-      si.nMin = 0;
-      si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
-       + VERTICAL_SCROLL_BAR_MIN_HANDLE;
-      si.nPage = si.nMax;
-      si.nPos = 0;
+  si.cbSize = sizeof (si);
+  si.fMask = SIF_ALL;
+  si.nMin = 0;
+  si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
+    + VERTICAL_SCROLL_BAR_MIN_HANDLE;
+  si.nPage = si.nMax;
+  si.nPos = 0;
 
-      pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
-    }
-  else
-    {
-      SetScrollRange (hwnd, SB_CTL, 0,
-                      VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
-      SetScrollPos (hwnd, SB_CTL, 0, FALSE);
-    }
+  SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
 
   SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
 
@@ -4001,6 +3872,8 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
       else
         {
           HDC hdc;
+         SCROLLINFO si;
+
           BLOCK_INPUT;
          if (width && height)
            {
@@ -4020,21 +3893,15 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
           MoveWindow (hwnd, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
                      top, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
                      max (height, 1), TRUE);
-          if (pfnSetScrollInfo)
-            {
-              SCROLLINFO si;
 
-              si.cbSize = sizeof (si);
-              si.fMask = SIF_RANGE;
-              si.nMin = 0;
-              si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
-                + VERTICAL_SCROLL_BAR_MIN_HANDLE;
+         si.cbSize = sizeof (si);
+         si.fMask = SIF_RANGE;
+         si.nMin = 0;
+         si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
+           + VERTICAL_SCROLL_BAR_MIN_HANDLE;
+
+         SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
 
-              pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
-            }
-          else
-            SetScrollRange (hwnd, SB_CTL, 0,
-                            VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
           my_show_window (f, hwnd, SW_NORMAL);
           /* InvalidateRect (w, NULL, FALSE);  */
 
@@ -4186,19 +4053,13 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
     int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
     int y;
     int dragging = !NILP (bar->dragging);
+    SCROLLINFO si;
 
-    if (pfnGetScrollInfo)
-      {
-       SCROLLINFO si;
-
-       si.cbSize = sizeof (si);
-       si.fMask = SIF_POS;
+    si.cbSize = sizeof (si);
+    si.fMask = SIF_POS;
 
-       pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
-       y = si.nPos;
-      }
-    else
-      y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
+    GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
+    y = si.nPos;
 
     bar->dragging = Qnil;
 
@@ -4235,21 +4096,18 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
        emacs_event->part = scroll_bar_handle;
 
        /* "Silently" update current position.  */
-       if (pfnSetScrollInfo)
-         {
-           SCROLLINFO si;
+       {
+         SCROLLINFO si;
 
-           si.cbSize = sizeof (si);
-           si.fMask = SIF_POS;
-           si.nPos = y;
-           /* Remember apparent position (we actually lag behind the real
-              position, so don't set that directly.  */
-           last_scroll_bar_drag_pos = y;
+         si.cbSize = sizeof (si);
+         si.fMask = SIF_POS;
+         si.nPos = y;
+         /* Remember apparent position (we actually lag behind the real
+            position, so don't set that directly.  */
+         last_scroll_bar_drag_pos = y;
 
-           pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
-         }
-       else
-         SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
+         SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
+       }
        break;
       case SB_ENDSCROLL:
        /* If this is the end of a drag sequence, then reset the scroll
@@ -4257,20 +4115,15 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
           nothing.  */
        if (dragging)
          {
-           if (pfnSetScrollInfo)
-             {
-               SCROLLINFO si;
-               int start = XINT (bar->start);
-               int end = XINT (bar->end);
-
-               si.cbSize = sizeof (si);
-               si.fMask = SIF_PAGE | SIF_POS;
-                si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
-               si.nPos = last_scroll_bar_drag_pos;
-               pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
-             }
-           else
-             SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
+           SCROLLINFO si;
+           int start = XINT (bar->start);
+           int end = XINT (bar->end);
+
+           si.cbSize = sizeof (si);
+           si.fMask = SIF_PAGE | SIF_POS;
+           si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
+           si.nPos = last_scroll_bar_drag_pos;
+           SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
          }
        /* fall through */
       default:
@@ -4301,25 +4154,19 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   int pos;
   int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
+  SCROLLINFO si;
 
   BLOCK_INPUT;
 
   *fp = f;
   *bar_window = bar->window;
 
-  if (pfnGetScrollInfo)
-    {
-      SCROLLINFO si;
-
-      si.cbSize = sizeof (si);
-      si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
+  si.cbSize = sizeof (si);
+  si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
 
-      pfnGetScrollInfo (w, SB_CTL, &si);
-      pos = si.nPos;
-      top_range = si.nMax - si.nPage + 1;
-    }
-  else
-    pos = GetScrollPos (w, SB_CTL);
+  GetScrollInfo (w, SB_CTL, &si);
+  pos = si.nPos;
+  top_range = si.nMax - si.nPage + 1;
 
   switch (LOWORD (last_mouse_scroll_bar_pos))
   {
@@ -4519,7 +4366,8 @@ w32_read_socket (sd, expected, hold_quit)
 
          if (f && !f->iconified)
            {
-             if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+             if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+                 && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
                {
                  clear_mouse_face (dpyinfo);
                  dpyinfo->mouse_face_hidden = 1;
@@ -4542,7 +4390,8 @@ w32_read_socket (sd, expected, hold_quit)
 
          if (f && !f->iconified)
            {
-             if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+             if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+                 && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
                {
                  clear_mouse_face (dpyinfo);
                  dpyinfo->mouse_face_hidden = 1;
@@ -4571,6 +4420,7 @@ w32_read_socket (sd, expected, hold_quit)
          }
 
           previous_help_echo_string = help_echo_string;
+         help_echo_string = Qnil;
 
          if (dpyinfo->grabbed && last_mouse_frame
              && FRAME_LIVE_P (last_mouse_frame))
@@ -4609,7 +4459,8 @@ w32_read_socket (sd, expected, hold_quit)
 
                  last_window=window;
                }
-             note_mouse_movement (f, &msg.msg);
+             if (!note_mouse_movement (f, &msg.msg))
+               help_echo_string = previous_help_echo_string;
            }
          else
             {
@@ -5184,7 +5035,7 @@ x_draw_hollow_cursor (w, row)
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   HDC hdc;
   RECT rect;
-  int h;
+  int left, top, h;
   struct glyph *cursor_glyph;
   HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
 
@@ -5195,8 +5046,9 @@ x_draw_hollow_cursor (w, row)
     return;
 
   /* Compute frame-relative coordinates for phys cursor.  */
-  rect.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
-  rect.top = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+  get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
+  rect.left = left;
+  rect.top = top;
   rect.bottom = rect.top + h;
   rect.right = rect.left + w->phys_cursor_width;
 
@@ -5487,6 +5339,8 @@ x_error_catcher (display, error)
 x_catch_errors (dpy)
 x_catch_errors_unwind (old_val)
 x_check_errors (dpy, format)
+x_fully_uncatch_errors ()
+x_catching_errors ()
 x_had_errors_p (dpy)
 x_clear_errors (dpy)
 x_uncatch_errors (dpy, count)