* w32term.c: Remove consolidated defines and code.
[bpt/emacs.git] / src / w32term.c
index c06a45e..a934826 100644 (file)
@@ -59,30 +59,17 @@ Boston, MA 02111-1307, USA.  */
 
 #define abs(x) ((x) < 0 ? -(x) : (x))
 
-#define BETWEEN(X, LOWER, UPPER)  ((X) >= (LOWER) && (X) < (UPPER))
-
 \f
 /* Fringe bitmaps.  */
 
 static HBITMAP fringe_bmp[MAX_FRINGE_BITMAPS];
 
-extern Lisp_Object Qhelp_echo;
-
 /* Non-nil means Emacs uses toolkit scroll bars.  */
 
 Lisp_Object Vx_toolkit_scroll_bars;
 
-/* If a string, w32_read_socket generates an event to display that string.
-   (The display is done in read_char.)  */
-
-static Lisp_Object help_echo;
-static Lisp_Object help_echo_window;
-static Lisp_Object help_echo_object;
-static int help_echo_pos;
-
 /* Temporary variables for w32_read_socket.  */
 
-static Lisp_Object previous_help_echo;
 static int last_mousemove_x = 0;
 static int last_mousemove_y = 0;
 
@@ -91,23 +78,9 @@ static int last_mousemove_y = 0;
 
 static int any_help_event_p;
 
-/* Non-zero means autoselect window with the mouse cursor.  */
-
-int mouse_autoselect_window;
-
 /* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
 static Lisp_Object last_window;
 
-/* Non-zero means draw block and hollow cursor as wide as the glyph
-   under it.  For example, if a block cursor is over a tab, it will be
-   drawn as wide as that tab on the display.  */
-
-int x_stretch_cursor_p;
-
-/* Non-zero means make use of UNDERLINE_POSITION font properties.  */
-
-int x_use_underline_position_properties;
-
 extern unsigned int msh_mousewheel;
 
 extern void free_frame_menubar ();
@@ -143,12 +116,6 @@ extern struct frame *updating_frame;
 /* This is a frame waiting to be autoraised, within w32_read_socket.  */
 struct frame *pending_autoraise_frame;
 
-/* Nominal cursor position -- where to draw output.
-   HPOS and VPOS are window relative glyph matrix coordinates.
-   X and Y are window relative pixel coordinates.  */
-
-struct cursor_pos output_cursor;
-
 /* The handle of the frame that currently owns the system caret.  */
 HWND w32_system_caret_hwnd;
 int w32_system_caret_height;
@@ -202,7 +169,6 @@ int last_scroll_bar_drag_pos;
 
 /* Where the mouse was last time we reported a mouse event.  */
 
-FRAME_PTR last_mouse_frame;
 static RECT last_mouse_glyph;
 static Lisp_Object last_mouse_press_frame;
 
@@ -261,25 +227,9 @@ extern int errno;
 extern EMACS_INT extra_keyboard_modifiers;
 
 static void x_update_window_end P_ ((struct window *, int, int));
-static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
 void w32_delete_display P_ ((struct w32_display_info *));
-static int fast_find_position P_ ((struct window *, int, int *, int *,
-                                  int *, int *, Lisp_Object));
-static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
-                                    int *, int *, int *, int *, int));
-static void set_output_cursor P_ ((struct cursor_pos *));
-static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
-                                          int *, int *, int *, int));
-static void note_mode_line_or_margin_highlight P_ ((struct window *, int,
-                                                   int, int));
-static void note_mouse_highlight P_ ((struct frame *, int, int));
-static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
 static void w32_handle_tool_bar_click P_ ((struct frame *,
                                           struct input_event *));
-static void show_mouse_face P_ ((struct w32_display_info *,
-                                enum draw_glyphs_face));
-static int cursor_in_mouse_face_p P_ ((struct window *));
-static int clear_mouse_face P_ ((struct w32_display_info *));
 void w32_define_cursor P_ ((Window, Cursor));
 
 void x_lower_frame P_ ((struct frame *));
@@ -292,18 +242,11 @@ void x_wm_set_icon_pixmap P_ ((struct frame *, int));
 void w32_initialize P_ ((void));
 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
 int x_compute_min_glyph_bounds P_ ((struct frame *));
-static void x_draw_phys_cursor_glyph P_ ((struct window *,
-                                         struct glyph_row *,
-                                         enum draw_glyphs_face));
 static void x_update_end P_ ((struct frame *));
 static void w32_frame_up_to_date P_ ((struct frame *));
 static void w32_set_terminal_modes P_ ((void));
 static void w32_reset_terminal_modes P_ ((void));
-static void w32_cursor_to P_ ((int, int, int, int));
-static void x_write_glyphs P_ ((struct glyph *, int));
-static void x_clear_end_of_line P_ ((int));
 static void x_clear_frame P_ ((void));
-static void x_clear_cursor P_ ((struct window *));
 static void frame_highlight P_ ((struct frame *));
 static void frame_unhighlight P_ ((struct frame *));
 static void x_new_focus_frame P_ ((struct w32_display_info *,
@@ -313,24 +256,8 @@ static void x_frame_rehighlight P_ ((struct w32_display_info *));
 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
                                   enum text_cursor_kinds));
-static void expose_frame P_ ((struct frame *, int, int, int, int));
-static int expose_window_tree P_ ((struct window *, RECT *));
-static void expose_overlaps P_ ((struct window *, struct glyph_row *,
-                                struct glyph_row *));
-static int expose_window P_ ((struct window *, RECT *));
-static void expose_area P_ ((struct window *, struct glyph_row *,
-                            RECT *, enum glyph_row_area));
-static int expose_line P_ ((struct window *, struct glyph_row *,
-                           RECT *));
-void x_update_cursor P_ ((struct frame *, int));
-static void x_update_cursor_in_window_tree P_ ((struct window *, int));
-static void x_update_window_cursor P_ ((struct window *, int));
-static void x_erase_phys_cursor P_ ((struct window *));
-void x_display_cursor P_ ((struct window *w, int, int, int, int, int));
-void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
 static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
                                  HDC, int));
-static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
 
 static Lisp_Object Qvendor_specific_keysyms;
 
@@ -557,36 +484,25 @@ x_update_window_begin (w)
   UNBLOCK_INPUT;
 }
 
-
-/* Draw a vertical window border to the right of window W if W doesn't
-   have vertical scroll bars.  */
+/* Draw a vertical window border from (x,y0) to (x,y1)  */
 
 static void
-x_draw_vertical_border (w)
+w32_draw_vertical_window_border (w, x, y0, y1)
      struct window *w;
+     int x, y0, y1;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
+  RECT r;
+  HDC hdc;
+  
+  r.left = x;
+  r.right = x + 1;
+  r.top = y0;
+  r.bottom = y1;
 
-  /* Redraw borders between horizontally adjacent windows.  Don't
-     do it for frames with vertical scroll bars because either the
-     right scroll bar of a window, or the left scroll bar of its
-     neighbor will suffice as a border.  */
-  if (!WINDOW_RIGHTMOST_P (w)
-      && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
-    {
-      RECT r;
-      HDC hdc;
-
-      window_box_edges (w, -1, (int *) &r.left, (int *) &r.top,
-                       (int *) &r.right, (int *) &r.bottom);
-      r.left = r.right + FRAME_X_RIGHT_FRINGE_WIDTH (f);
-      r.right = r.left + 1;
-      r.bottom -= 1;
-
-      hdc = get_frame_dc (f);
-      w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
-      release_frame_dc (f, hdc);
-    }
+  hdc = get_frame_dc (f);
+  w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
+  release_frame_dc (f, hdc);
 }
 
 
@@ -608,17 +524,16 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
      struct window *w;
      int cursor_on_p, mouse_face_overwritten_p;
 {
-  struct w32_display_info *dpyinfo
-    = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
+  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
 
   if (!w->pseudo_window_p)
     {
       BLOCK_INPUT;
 
       if (cursor_on_p)
-       x_display_and_set_cursor (w, 1, output_cursor.hpos,
-                                 output_cursor.vpos,
-                                 output_cursor.x, output_cursor.y);
+       display_and_set_cursor (w, 1, output_cursor.hpos,
+                               output_cursor.vpos,
+                               output_cursor.x, output_cursor.y);
 
       x_draw_vertical_border (w);
       UNBLOCK_INPUT;
@@ -671,6 +586,7 @@ w32_frame_up_to_date (f)
   if (FRAME_W32_P (f))
     {
       struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+
       if (dpyinfo->mouse_face_deferred_gc
          || f == dpyinfo->mouse_face_mouse_frame)
        {
@@ -725,6 +641,7 @@ x_after_update_window_line (desired_row)
          height > 0))
     {
       int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
+
       /* Internal border is drawn below the tool bar.  */
       if (WINDOWP (f->tool_bar_window)
          && w == XWINDOW (f->tool_bar_window))
@@ -817,64 +734,6 @@ w32_reset_terminal_modes (void)
 
 
 \f
-/***********************************************************************
-                           Output Cursor
- ***********************************************************************/
-
-/* Set the global variable output_cursor to CURSOR.  All cursor
-   positions are relative to updated_window.  */
-
-static void
-set_output_cursor (cursor)
-    struct cursor_pos *cursor;
-{
-  output_cursor.hpos = cursor->hpos;
-  output_cursor.vpos = cursor->vpos;
-  output_cursor.x = cursor->x;
-  output_cursor.y = cursor->y;
-}
-
-
-/* Set a nominal cursor position.
-
-   HPOS and VPOS are column/row positions in a window glyph matrix.  X
-   and Y are window text area relative pixel positions.
-
-   If this is done during an update, updated_window will contain the
-   window that is being updated and the position is the future output
-   cursor position for that window.  If updated_window is null, use
-   selected_window and display the cursor at the given position.  */
-
-static void
-w32_cursor_to (vpos, hpos, y, x)
-     int vpos, hpos, y, x;
-{
-  struct window *w;
-
-  /* If updated_window is not set, work on selected_window.  */
-  if (updated_window)
-    w = updated_window;
-  else
-    w = XWINDOW (selected_window);
-
-  /* Set the output cursor.  */
-  output_cursor.hpos = hpos;
-  output_cursor.vpos = vpos;
-  output_cursor.x = x;
-  output_cursor.y = y;
-
-  /* If not called as part of an update, really display the cursor.
-     This will also set the cursor position of W.  */
-  if (updated_window == NULL)
-    {
-      BLOCK_INPUT;
-      x_display_cursor (w, 1, hpos, vpos, x, y);
-      UNBLOCK_INPUT;
-    }
-}
-
-
-\f
 /***********************************************************************
                           Display Iterator
  ***********************************************************************/
@@ -1231,33 +1090,6 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
 }
 
 
-/* Estimate the pixel height of the mode or top line on frame F.
-   FACE_ID specifies what line's height to estimate.  */
-
-int
-x_estimate_mode_line_height (f, face_id)
-     struct frame *f;
-     enum face_id face_id;
-{
-  int height = FONT_HEIGHT (FRAME_FONT (f));
-
-  /* This function is called so early when Emacs starts that the face
-     cache and mode line face are not yet initialized.  */
-  if (FRAME_FACE_CACHE (f))
-      {
-       struct face *face = FACE_FROM_ID (f, face_id);
-       if (face)
-          {
-            if (face->font)
-              height = FONT_HEIGHT (face->font);
-           if (face->box_line_width > 0)
-             height += 2 * face->box_line_width;
-          }
-      }
-
-  return height;
-}
-
 \f
 /***********************************************************************
                            Glyph display
@@ -1312,8 +1144,6 @@ static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
                                    int, int, int, int, RECT *));
 static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
                                 int, int, int, RECT *));
-static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
-                                       enum glyph_row_area));
 
 #if GLYPH_DEBUG
 static void x_check_font P_ ((struct frame *, XFontStruct *));
@@ -1484,91 +1314,6 @@ x_set_glyph_string_gc (s)
 }
 
 
-/* Return in *R the clipping rectangle for glyph string S.  */
-
-static void
-w32_get_glyph_string_clip_rect (s, r)
-     struct glyph_string *s;
-     RECT *r;
-{
-  int r_height, r_width;
-
-  if (s->row->full_width_p)
-    {
-      /* Draw full-width.  X coordinates are relative to S->w->left.  */
-      int canon_x = CANON_X_UNIT (s->f);
-
-      r->left = WINDOW_LEFT_MARGIN (s->w) * canon_x;
-      r_width = XFASTINT (s->w->width) * canon_x;
-
-      if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
-       {
-         int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
-         if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
-           r->left -= width;
-       }
-
-      r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f);
-
-      /* Unless displaying a mode or menu bar line, which are always
-        fully visible, clip to the visible part of the row.  */
-      if (s->w->pseudo_window_p)
-       r_height = s->row->visible_height;
-      else
-       r_height = s->height;
-    }
-  else
-    {
-      /* This is a text line that may be partially visible.  */
-      r->left = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
-      r_width = window_box_width (s->w, s->area);
-      r_height = s->row->visible_height;
-    }
-
-  /* If S draws overlapping rows, it's sufficient to use the top and
-     bottom of the window for clipping because this glyph string
-     intentionally draws over other lines.  */
-  if (s->for_overlaps_p)
-    {
-      r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
-      r_height = window_text_bottom_y (s->w) - r->top;
-    }
-  else
-    {
-      /* Don't use S->y for clipping because it doesn't take partially
-        visible lines into account.  For example, it can be negative for
-        partially visible lines at the top of a window.  */
-      if (!s->row->full_width_p
-         && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
-       r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
-      else
-       r->top = max (0, s->row->y);
-
-      /* If drawing a tool-bar window, draw it over the internal border
-        at the top of the window.  */
-      if (s->w == XWINDOW (s->f->tool_bar_window))
-       r->top -= s->f->output_data.w32->internal_border_width;
-    }
-
-  r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
-
-  /* If drawing the cursor, don't let glyph draw outside its
-     advertised boundaries. Cleartype does this under some circumstances.  */
-  if (s->hl == DRAW_CURSOR)
-    {
-      if (s->x > r->left)
-       {
-         r_width -= s->x - r->left;
-         r->left = s->x;
-       }
-      r_width = min (r_width, s->first_glyph->pixel_width);
-    }
-
-  r->bottom = r->top + r_height;
-  r->right = r->left + r_width;
-}
-
-
 /* Set clipping for output of glyph string S.  S may be part of a mode
    line or menu if we don't have X toolkit support.  */
 
@@ -1577,7 +1322,7 @@ x_set_glyph_string_clipping (s)
      struct glyph_string *s;
 {
   RECT r;
-  w32_get_glyph_string_clip_rect (s, &r);
+  get_glyph_string_clip_rect (s, &r);
   w32_set_clip_rectangle (s->hdc, &r);
 }
 
@@ -2115,7 +1860,7 @@ x_draw_glyph_string_box (s)
                 && (s->next == NULL
                     || s->next->hl != s->hl)));
 
-  w32_get_glyph_string_clip_rect (s, &clip_rect);
+  get_glyph_string_clip_rect (s, &clip_rect);
 
   if (s->face->box == FACE_SIMPLE_BOX)
     w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
@@ -2261,7 +2006,7 @@ x_draw_image_relief (s)
   y1 = y + s->img->height + thick - 1;
 
   x_setup_relief_colors (s);
-  w32_get_glyph_string_clip_rect (s, &r);
+  get_glyph_string_clip_rect (s, &r);
   w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
 }
 
@@ -2534,7 +2279,7 @@ x_draw_stretch_glyph_string (s)
          else
            gc = s->face->gc;
 
-         w32_get_glyph_string_clip_rect (s, &r);
+         get_glyph_string_clip_rect (s, &r);
          w32_set_clip_rectangle (hdc, &r);
 
 #if 0 /* TODO: stipple */
@@ -2698,147 +2443,20 @@ x_draw_glyph_string (s)
 }
 
 
-/* Fix the display of area AREA of overlapping row ROW in window W.  */
-
-static void
-x_fix_overlapping_area (w, row, area)
-     struct window *w;
-     struct glyph_row *row;
-     enum glyph_row_area area;
-{
-  int i, x;
-
-  BLOCK_INPUT;
-
-  if (area == LEFT_MARGIN_AREA)
-    x = 0;
-  else if (area == TEXT_AREA)
-    x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
-  else
-    x = (window_box_width (w, LEFT_MARGIN_AREA)
-        + window_box_width (w, TEXT_AREA));
-
-  for (i = 0; i < row->used[area];)
-    {
-      if (row->glyphs[area][i].overlaps_vertically_p)
-       {
-         int start = i, start_x = x;
-
-         do
-           {
-             x += row->glyphs[area][i].pixel_width;
-             ++i;
-           }
-         while (i < row->used[area]
-                && row->glyphs[area][i].overlaps_vertically_p);
-
-         x_draw_glyphs (w, start_x, row, area, start, i,
-                        DRAW_NORMAL_TEXT, 1);
-       }
-      else
-       {
-         x += row->glyphs[area][i].pixel_width;
-         ++i;
-       }
-    }
-
-  UNBLOCK_INPUT;
-}
-
-
-/* Output LEN glyphs starting at START at the nominal cursor position.
-   Advance the nominal cursor over the text.  The global variable
-   updated_window contains the window being updated, updated_row is
-   the glyph row being updated, and updated_area is the area of that
-   row being updated.  */
+/* Shift display to make room for inserted glyphs.   */
 
-static void
-x_write_glyphs (start, len)
-     struct glyph *start;
-     int len;
-{
-  int x, hpos;
-
-  xassert (updated_window && updated_row);
-  BLOCK_INPUT;
-
-  /* Write glyphs.  */
-
-  hpos = start - updated_row->glyphs[updated_area];
-  x = x_draw_glyphs (updated_window, output_cursor.x,
-                    updated_row, updated_area,
-                    hpos, hpos + len,
-                    DRAW_NORMAL_TEXT, 0);
-
-  /* Invalidate old phys cursor if the glyph at its hpos is redrawn.  */
-  if (updated_area == TEXT_AREA
-      && updated_window->phys_cursor_on_p
-      && updated_window->phys_cursor.vpos == output_cursor.vpos
-      && updated_window->phys_cursor.hpos >= hpos
-      && updated_window->phys_cursor.hpos < hpos + len)
-    updated_window->phys_cursor_on_p = 0;
-
-  UNBLOCK_INPUT;
-
-  /* Advance the output cursor.  */
-  output_cursor.hpos += len;
-  output_cursor.x = x;
-}
-
-
-/* Insert LEN glyphs from START at the nominal cursor position.   */
-
-static void
-x_insert_glyphs (start, len)
-     struct glyph *start;
-     register int len;
+void
+w32_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
+     struct frame *f;
+     int x, y, width, height, shift_by;
 {
-  struct frame *f;
-  struct window *w;
-  int line_height, shift_by_width, shifted_region_width;
-  struct glyph_row *row;
-  struct glyph *glyph;
-  int frame_x, frame_y, hpos;
   HDC hdc;
 
-  xassert (updated_window && updated_row);
-  BLOCK_INPUT;
-  w = updated_window;
-  f = XFRAME (WINDOW_FRAME (w));
   hdc = get_frame_dc (f);
+  BitBlt (hdc, x + shift_by, y, width, height,
+          hdc, x, y, SRCCOPY);
 
-  /* Get the height of the line we are in.  */
-  row = updated_row;
-  line_height = row->height;
-
-  /* Get the width of the glyphs to insert.  */
-  shift_by_width = 0;
-  for (glyph = start; glyph < start + len; ++glyph)
-    shift_by_width += glyph->pixel_width;
-
-  /* Get the width of the region to shift right.  */
-  shifted_region_width = (window_box_width (w, updated_area)
-                         - output_cursor.x
-                         - shift_by_width);
-
-  /* Shift right.  */
-  frame_x = window_box_left (w, updated_area) + output_cursor.x;
-  frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
-  BitBlt (hdc, frame_x + shift_by_width, frame_y,
-          shifted_region_width, line_height,
-          hdc, frame_x, frame_y, SRCCOPY);
-
-  /* Write the glyphs.  */
-  hpos = start - row->glyphs[updated_area];
-  x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
-                DRAW_NORMAL_TEXT, 0);
-
-  /* Advance the output cursor.  */
-  output_cursor.hpos += len;
-  output_cursor.x += shift_by_width;
   release_frame_dc (f, hdc);
-
-  UNBLOCK_INPUT;
 }
 
 
@@ -2863,86 +2481,6 @@ x_delete_glyphs (n)
 }
 
 
-/* Erase the current text line from the nominal cursor position
-   (inclusive) to pixel column TO_X (exclusive).  The idea is that
-   everything from TO_X onward is already erased.
-
-   TO_X is a pixel position relative to updated_area of
-   updated_window.  TO_X == -1 means clear to the end of this area.  */
-
-static void
-x_clear_end_of_line (to_x)
-     int to_x;
-{
-  struct frame *f;
-  struct window *w = updated_window;
-  int max_x, min_y, max_y;
-  int from_x, from_y, to_y;
-
-  xassert (updated_window && updated_row);
-  f = XFRAME (w->frame);
-
-  if (updated_row->full_width_p)
-    {
-      max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
-      if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
-         && !w->pseudo_window_p)
-       max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
-    }
-  else
-    max_x = window_box_width (w, updated_area);
-  max_y = window_text_bottom_y (w);
-
-  /* TO_X == 0 means don't do anything.  TO_X < 0 means clear to end
-     of window.  For TO_X > 0, truncate to end of drawing area.  */
-  if (to_x == 0)
-    return;
-  else if (to_x < 0)
-    to_x = max_x;
-  else
-    to_x = min (to_x, max_x);
-
-  to_y = min (max_y, output_cursor.y + updated_row->height);
-
-  /* Notice if the cursor will be cleared by this operation.  */
-  if (!updated_row->full_width_p)
-    notice_overwritten_cursor (w, updated_area,
-                              output_cursor.x, -1,
-                              updated_row->y,
-                              MATRIX_ROW_BOTTOM_Y (updated_row));
-
-  from_x = output_cursor.x;
-
-  /* Translate to frame coordinates.  */
-  if (updated_row->full_width_p)
-    {
-      from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
-      to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
-    }
-  else
-    {
-      from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
-      to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
-    }
-
-  min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
-  from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
-  to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
-
-  /* Prevent inadvertently clearing to end of the X window.  */
-  if (to_x > from_x && to_y > from_y)
-    {
-      HDC hdc;
-      BLOCK_INPUT;
-      hdc = get_frame_dc (f);
-
-      w32_clear_area (f, hdc, from_x, from_y, to_x - from_x, to_y - from_y);
-      release_frame_dc (f, hdc);
-      UNBLOCK_INPUT;
-    }
-}
-
-
 /* Clear entire frame.  If updating_frame is non-null, clear that
    frame.  Otherwise clear the selected frame.  */
 
@@ -3131,430 +2669,60 @@ x_scroll_run (w, run)
                           Exposure Events
  ***********************************************************************/
 
-/* Redisplay an exposed area of frame F.  X and Y are the upper-left
-   corner of the exposed rectangle.  W and H are width and height of
-   the exposed area.  All are pixel values.  W or H zero means redraw
-   the entire frame.  */
-
 static void
-expose_frame (f, x, y, w, h)
+frame_highlight (f)
      struct frame *f;
-     int x, y, w, h;
 {
-  RECT r;
-  int mouse_face_overwritten_p = 0;
+  x_update_cursor (f, 1);
+}
 
-  TRACE ((stderr, "expose_frame "));
+static void
+frame_unhighlight (f)
+     struct frame *f;
+{
+  x_update_cursor (f, 1);
+}
 
-  /* No need to redraw if frame will be redrawn soon.  */
-  if (FRAME_GARBAGED_P (f))
-    {
-      TRACE ((stderr, " garbaged\n"));
-      return;
-    }
+/* The focus has changed.  Update the frames as necessary to reflect
+   the new situation.  Note that we can't change the selected frame
+   here, because the Lisp code we are interrupting might become confused.
+   Each event gets marked with the frame in which it occurred, so the
+   Lisp code can tell when the switch took place by examining the events.  */
 
-  /* If basic faces haven't been realized yet, there is no point in
-     trying to redraw anything.  This can happen when we get an expose
-     event while Emacs is starting, e.g. by moving another window.  */
-  if (FRAME_FACE_CACHE (f) == NULL
-      || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
-    {
-      TRACE ((stderr, " no faces\n"));
-      return;
-    }
+static void
+x_new_focus_frame (dpyinfo, frame)
+     struct w32_display_info *dpyinfo;
+     struct frame *frame;
+{
+  struct frame *old_focus = dpyinfo->w32_focus_frame;
 
-  if (w == 0 || h == 0)
-    {
-      r.left = r.top = 0;
-      r.right = CANON_X_UNIT (f) * f->width;
-      r.bottom = CANON_Y_UNIT (f) * f->height;
-    }
-  else
+  if (frame != dpyinfo->w32_focus_frame)
     {
-      r.left = x;
-      r.top = y;
-      r.right = x + w;
-      r.bottom = y + h;
-    }
+      /* Set this before calling other routines, so that they see
+        the correct value of w32_focus_frame.  */
+      dpyinfo->w32_focus_frame = frame;
 
-  TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));
-  mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
-
-  if (WINDOWP (f->tool_bar_window))
-    mouse_face_overwritten_p
-      |= expose_window (XWINDOW (f->tool_bar_window), &r);
-
-  /* Some window managers support a focus-follows-mouse style with
-     delayed raising of frames.  Imagine a partially obscured frame,
-     and moving the mouse into partially obscured mouse-face on that
-     frame.  The visible part of the mouse-face will be highlighted,
-     then the WM raises the obscured frame.  With at least one WM, KDE
-     2.1, Emacs is not getting any event for the raising of the frame
-     (even tried with SubstructureRedirectMask), only Expose events.
-     These expose events will draw text normally, i.e. not
-     highlighted.  Which means we must redo the highlight here.
-     Subsume it under ``we love X''.  --gerd 2001-08-15  */
-  /* Included in Windows version because Windows most likely does not
-     do the right thing if any third party tool offers
-     focus-follows-mouse with delayed raise.  --jason 2001-10-12  */
-  if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
-    {
-      struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-      if (f == dpyinfo->mouse_face_mouse_frame)
-       {
-         int x = dpyinfo->mouse_face_mouse_x;
-         int y = dpyinfo->mouse_face_mouse_y;
-         clear_mouse_face (dpyinfo);
-         note_mouse_highlight (f, x, y);
-       }
-    }
-}
+      if (old_focus && old_focus->auto_lower)
+       x_lower_frame (old_focus);
 
 
-/* Redraw (parts) of all windows in the window tree rooted at W that
-   intersect R.  R contains frame pixel coordinates.  */
 
-static int
-expose_window_tree (w, r)
-     struct window *w;
-     RECT *r;
-{
-  struct frame *f = XFRAME (w->frame);
-  int mouse_face_overwritten_p = 0;
 
-  while (w && !FRAME_GARBAGED_P (f))
-    {
-      if (!NILP (w->hchild))
-       mouse_face_overwritten_p
-         |= expose_window_tree (XWINDOW (w->hchild), r);
-      else if (!NILP (w->vchild))
-       mouse_face_overwritten_p
-         |= expose_window_tree (XWINDOW (w->vchild), r);
-      else
-       mouse_face_overwritten_p |= expose_window (w, r);
 
-      w = NILP (w->next) ? NULL : XWINDOW (w->next);
-    }
 
-  return mouse_face_overwritten_p;
-}
 
 
-/* Redraw the part of glyph row area AREA of glyph row ROW on window W
-   which intersects rectangle R.  R is in window-relative coordinates.  */
 
-static void
-expose_area (w, row, r, area)
-     struct window *w;
-     struct glyph_row *row;
-     RECT *r;
-     enum glyph_row_area area;
-{
-  struct glyph *first = row->glyphs[area];
-  struct glyph *end = row->glyphs[area] + row->used[area];
-  struct glyph *last;
-  int first_x, start_x, x;
-
-  if (area == TEXT_AREA && row->fill_line_p)
-    /* If row extends face to end of line write the whole line.  */
-    x_draw_glyphs (w, 0, row, area,
-                  0, row->used[area],
-                  DRAW_NORMAL_TEXT, 0);
-  else
-    {
-      /* Set START_X to the window-relative start position for drawing glyphs of
-        AREA.  The first glyph of the text area can be partially visible.
-        The first glyphs of other areas cannot.  */
-      if (area == LEFT_MARGIN_AREA)
-       start_x = 0;
-      else if (area == TEXT_AREA)
-       start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
+      if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
+       pending_autoraise_frame = dpyinfo->w32_focus_frame;
       else
-       start_x = (window_box_width (w, LEFT_MARGIN_AREA)
-                  + window_box_width (w, TEXT_AREA));
-      x = start_x;
-
-      /* Find the first glyph that must be redrawn.  */
-      while (first < end
-             && x + first->pixel_width < r->left)
-        {
-          x += first->pixel_width;
-          ++first;
-        }
-
-      /* Find the last one.  */
-      last = first;
-      first_x = x;
-      while (last < end
-             && x < r->right)
-        {
-          x += last->pixel_width;
-          ++last;
-        }
-
-      /* Repaint.  */
-      if (last > first)
-        x_draw_glyphs (w, first_x - start_x, row, area,
-                       first - row->glyphs[area],
-                       last - row->glyphs[area],
-                       DRAW_NORMAL_TEXT, 0);
+       pending_autoraise_frame = 0;
     }
+
+  x_frame_rehighlight (dpyinfo);
 }
 
-
-/* Redraw the parts of the glyph row ROW on window W intersecting
-   rectangle R.  R is in window-relative coordinates.  Value is
-   non-zero if mouse face was overwritten.  */
-
-static int
-expose_line (w, row, r)
-     struct window *w;
-     struct glyph_row *row;
-     RECT *r;
-{
-  xassert (row->enabled_p);
-
-  if (row->mode_line_p || w->pseudo_window_p)
-    x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
-                  DRAW_NORMAL_TEXT, 0);
-  else
-    {
-      if (row->used[LEFT_MARGIN_AREA])
-       expose_area (w, row, r, LEFT_MARGIN_AREA);
-      if (row->used[TEXT_AREA])
-       expose_area (w, row, r, TEXT_AREA);
-      if (row->used[RIGHT_MARGIN_AREA])
-       expose_area (w, row, r, RIGHT_MARGIN_AREA);
-      draw_row_fringe_bitmaps (w, row);
-    }
-
-  return row->mouse_face_p;
-}
-
-
-/* Return non-zero if W's cursor intersects rectangle R.  */
-
-static int
-x_phys_cursor_in_rect_p (w, r)
-     struct window *w;
-     RECT *r;
-{
-  RECT cr, result;
-  struct glyph *cursor_glyph;
-
-  cursor_glyph = get_phys_cursor_glyph (w);
-  if (cursor_glyph)
-    {
-      cr.left = w->phys_cursor.x;
-      cr.top = w->phys_cursor.y;
-      cr.right = cr.left + cursor_glyph->pixel_width;
-      cr.bottom = cr.top + w->phys_cursor_height;
-      return IntersectRect (&result, &cr, r);
-    }
-  else
-    return 0;
-}
-
-
-/* Redraw those parts of glyphs rows during expose event handling that
-   overlap other rows.  Redrawing of an exposed line writes over parts
-   of lines overlapping that exposed line; this function fixes that.
-
-   W is the window being exposed.  FIRST_OVERLAPPING_ROW is the first
-   row in W's current matrix that is exposed and overlaps other rows.
-   LAST_OVERLAPPING_ROW is the last such row.  */
-
-static void
-expose_overlaps (w, first_overlapping_row, last_overlapping_row)
-     struct window *w;
-     struct glyph_row *first_overlapping_row;
-     struct glyph_row *last_overlapping_row;
-{
-  struct glyph_row *row;
-
-  for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
-    if (row->overlapping_p)
-      {
-       xassert (row->enabled_p && !row->mode_line_p);
-
-       if (row->used[LEFT_MARGIN_AREA])
-         x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
-
-       if (row->used[TEXT_AREA])
-         x_fix_overlapping_area (w, row, TEXT_AREA);
-
-       if (row->used[RIGHT_MARGIN_AREA])
-         x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
-      }
-}
-
-
-/* Redraw the part of window W intersection rectagle FR.  Pixel
-   coordinates in FR are frame relative.  Call this function with
-   input blocked.  Value is non-zero if the exposure overwrites
-   mouse-face.  */
-
-static int
-expose_window (w, fr)
-     struct window *w;
-     RECT *fr;
-{
-  struct frame *f = XFRAME (w->frame);
-  RECT wr, r;
-  int mouse_face_overwritten_p = 0;
-
-  /* If window is not yet fully initialized, do nothing.  This can
-     happen when toolkit scroll bars are used and a window is split.
-     Reconfiguring the scroll bar will generate an expose for a newly
-     created window.  */
-  if (w->current_matrix == NULL)
-    return 0;
-
-  /* When we're currently updating the window, display and current
-     matrix usually don't agree.  Arrange for a thorough display
-     later.  */
-  if (w == updated_window)
-    {
-      SET_FRAME_GARBAGED (f);
-      return 0;
-    }
-
-  /* Frame-relative pixel rectangle of W.  */
-  wr.left = XFASTINT (w->left) * CANON_X_UNIT (f);
-  wr.top = XFASTINT (w->top) * CANON_Y_UNIT (f);
-  wr.right = wr.left + XFASTINT (w->width) * CANON_X_UNIT (f);
-  wr.bottom = wr.top + XFASTINT (w->height) * CANON_Y_UNIT (f);
-
-  if (IntersectRect(&r, fr, &wr))
-    {
-      int yb = window_text_bottom_y (w);
-      struct glyph_row *row;
-      int cursor_cleared_p;
-      struct glyph_row *first_overlapping_row, *last_overlapping_row;
-
-      TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
-             r.left, r.top, r.right, r.bottom));
-
-      /* Convert to window coordinates.  */
-      r.left = FRAME_TO_WINDOW_PIXEL_X (w, r.left);
-      r.right = FRAME_TO_WINDOW_PIXEL_X (w, r.right);
-      r.top = FRAME_TO_WINDOW_PIXEL_Y (w, r.top);
-      r.bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r.bottom);
-
-      /* Turn off the cursor.  */
-      if (!w->pseudo_window_p
-         && x_phys_cursor_in_rect_p (w, &r))
-       {
-         x_clear_cursor (w);
-         cursor_cleared_p = 1;
-       }
-      else
-       cursor_cleared_p = 0;
-
-      /* Update lines intersecting rectangle R.  */
-      first_overlapping_row = last_overlapping_row = NULL;
-      for (row = w->current_matrix->rows;
-          row->enabled_p;
-          ++row)
-       {
-         int y0 = row->y;
-         int y1 = MATRIX_ROW_BOTTOM_Y (row);
-
-         if ((y0 >= r.top && y0 < r.bottom)
-             || (y1 > r.top && y1 < r.bottom)
-             || (r.top >= y0 && r.top < y1)
-             || (r.bottom > y0 && r.bottom < y1))
-           {
-             if (row->overlapping_p)
-               {
-                 if (first_overlapping_row == NULL)
-                   first_overlapping_row = row;
-                 last_overlapping_row = row;
-               }
-
-             if (expose_line (w, row, &r))
-               mouse_face_overwritten_p = 1;
-           }
-
-         if (y1 >= yb)
-           break;
-       }
-
-      /* Display the mode line if there is one.  */
-      if (WINDOW_WANTS_MODELINE_P (w)
-         && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
-             row->enabled_p)
-         && row->y < r.bottom)
-       {
-         if (expose_line (w, row, &r))
-           mouse_face_overwritten_p = 1;
-       }
-
-      if (!w->pseudo_window_p)
-       {
-         /* Fix the display of overlapping rows.  */
-         if (first_overlapping_row)
-           expose_overlaps (w, first_overlapping_row, last_overlapping_row);
-
-         /* Draw border between windows.  */
-         x_draw_vertical_border (w);
-
-         /* Turn the cursor on again.  */
-         if (cursor_cleared_p)
-           x_update_window_cursor (w, 1);
-       }
-    }
-
-  return mouse_face_overwritten_p;
-}
-
-\f
-static void
-frame_highlight (f)
-     struct frame *f;
-{
-  x_update_cursor (f, 1);
-}
-
-static void
-frame_unhighlight (f)
-     struct frame *f;
-{
-  x_update_cursor (f, 1);
-}
-
-/* The focus has changed.  Update the frames as necessary to reflect
-   the new situation.  Note that we can't change the selected frame
-   here, because the Lisp code we are interrupting might become confused.
-   Each event gets marked with the frame in which it occurred, so the
-   Lisp code can tell when the switch took place by examining the events.  */
-
-static void
-x_new_focus_frame (dpyinfo, frame)
-     struct w32_display_info *dpyinfo;
-     struct frame *frame;
-{
-  struct frame *old_focus = dpyinfo->w32_focus_frame;
-
-  if (frame != dpyinfo->w32_focus_frame)
-    {
-      /* Set this before calling other routines, so that they see
-        the correct value of w32_focus_frame.  */
-      dpyinfo->w32_focus_frame = frame;
-
-      if (old_focus && old_focus->auto_lower)
-       x_lower_frame (old_focus);
-
-      if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
-       pending_autoraise_frame = dpyinfo->w32_focus_frame;
-      else
-       pending_autoraise_frame = 0;
-    }
-
-  x_frame_rehighlight (dpyinfo);
-}
-
-/* Handle an event saying the mouse has moved out of an Emacs frame.  */
+/* Handle an event saying the mouse has moved out of an Emacs frame.  */
 
 void
 x_mouse_leave (dpyinfo)
@@ -3868,1332 +3036,102 @@ construct_drag_n_drop (result, msg, f)
   HDROP hdrop;
   POINT p;
   WORD num_files;
-  char *name;
-  int i, len;
-
-  result->kind = DRAG_N_DROP_EVENT;
-  result->code = 0;
-  result->timestamp = msg->msg.time;
-  result->modifiers = msg->dwModifiers;
-
-  hdrop = (HDROP) msg->msg.wParam;
-  DragQueryPoint (hdrop, &p);
-
-#if 0
-  p.x = LOWORD (msg->msg.lParam);
-  p.y = HIWORD (msg->msg.lParam);
-  ScreenToClient (msg->msg.hwnd, &p);
-#endif
-
-  XSETINT (result->x, p.x);
-  XSETINT (result->y, p.y);
-
-  num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
-  files = Qnil;
-
-  for (i = 0; i < num_files; i++)
-    {
-      len = DragQueryFile (hdrop, i, NULL, 0);
-      if (len <= 0)
-       continue;
-      name = alloca (len + 1);
-      DragQueryFile (hdrop, i, name, len + 1);
-      files = Fcons (DECODE_FILE (build_string (name)), files);
-    }
-
-  DragFinish (hdrop);
-
-  XSETFRAME (frame, f);
-  result->frame_or_window = Fcons (frame, files);
-  result->arg = Qnil;
-  return Qnil;
-}
-
-\f
-/* Function to report a mouse movement to the mainstream Emacs code.
-   The input handler calls this.
-
-   We have received a mouse movement event, which is given in *event.
-   If the mouse is over a different glyph than it was last time, tell
-   the mainstream emacs code by setting mouse_moved.  If not, ask for
-   another motion event, so we can check again the next time it moves.  */
-
-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
-note_mouse_movement (frame, msg)
-     FRAME_PTR frame;
-     MSG *msg;
-{
-  int mouse_x = LOWORD (msg->lParam);
-  int mouse_y = HIWORD (msg->lParam);
-
-  last_mouse_movement_time = msg->time;
-  memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
-  XSETFRAME (last_mouse_motion_frame, frame);
-
-  if (msg->hwnd != FRAME_W32_WINDOW (frame))
-    {
-      frame->mouse_moved = 1;
-      last_mouse_scroll_bar = Qnil;
-      note_mouse_highlight (frame, -1, -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)
-    {
-      frame->mouse_moved = 1;
-      last_mouse_scroll_bar = Qnil;
-      note_mouse_highlight (frame, mouse_x, mouse_y);
-      /* Remember the mouse position here, as w32_mouse_position only
-        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);
-    }
-}
-
-\f
-/************************************************************************
-                             Mouse Face
- ************************************************************************/
-
-/* Find the glyph under window-relative coordinates X/Y in window W.
-   Consider only glyphs from buffer text, i.e. no glyphs from overlay
-   strings.  Return in *HPOS and *VPOS the row and column number of
-   the glyph found.  Return in *AREA the glyph area containing X.
-   Value is a pointer to the glyph found or null if X/Y is not on
-   text, or we can't tell because W's current matrix is not up to
-   date.  */
-
-static struct glyph *
-x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
-     struct window *w;
-     int x, y;
-     int *hpos, *vpos, *area;
-     int buffer_only_p;
-{
-  struct glyph *glyph, *end;
-  struct glyph_row *row = NULL;
-  int x0, i, left_area_width;
-
-  /* Find row containing Y.  Give up if some row is not enabled.  */
-  for (i = 0; i < w->current_matrix->nrows; ++i)
-    {
-      row = MATRIX_ROW (w->current_matrix, i);
-      if (!row->enabled_p)
-       return NULL;
-      if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
-       break;
-    }
-
-  *vpos = i;
-  *hpos = 0;
-
-  /* Give up if Y is not in the window.  */
-  if (i == w->current_matrix->nrows)
-    return NULL;
-
-  /* Get the glyph area containing X.  */
-  if (w->pseudo_window_p)
-    {
-      *area = TEXT_AREA;
-      x0 = 0;
-    }
-  else
-    {
-      left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
-      if (x < left_area_width)
-       {
-         *area = LEFT_MARGIN_AREA;
-         x0 = 0;
-       }
-      else if (x < left_area_width + window_box_width (w, TEXT_AREA))
-       {
-         *area = TEXT_AREA;
-         x0 = row->x + left_area_width;
-       }
-      else
-       {
-         *area = RIGHT_MARGIN_AREA;
-         x0 = left_area_width + window_box_width (w, TEXT_AREA);
-       }
-    }
-
-  /* Find glyph containing X.  */
-  glyph = row->glyphs[*area];
-  end = glyph + row->used[*area];
-  while (glyph < end)
-    {
-      if (x < x0 + glyph->pixel_width)
-       {
-         if (w->pseudo_window_p)
-           break;
-         else if (!buffer_only_p || BUFFERP (glyph->object))
-           break;
-       }
-
-      x0 += glyph->pixel_width;
-      ++glyph;
-    }
-
-  if (glyph == end)
-    return NULL;
-
-  *hpos = glyph - row->glyphs[*area];
-  return glyph;
-}
-
-
-/* Convert frame-relative x/y to coordinates relative to window W.
-   Takes pseudo-windows into account.  */
-
-static void
-frame_to_window_pixel_xy (w, x, y)
-     struct window *w;
-     int *x, *y;
-{
-  if (w->pseudo_window_p)
-    {
-      /* A pseudo-window is always full-width, and starts at the
-        left edge of the frame, plus a frame border.  */
-      struct frame *f = XFRAME (w->frame);
-      *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
-      *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
-    }
-  else
-    {
-      *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
-      *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
-    }
-}
-
-
-/* Take proper action when mouse has moved to the mode or header line
-   or marginal area of window W, x-position X and y-position Y.  Area
-   is 1, 3, 6 or 7 for the mode line, header line, left and right
-   marginal area respectively.  X is relative to the start of the text
-   display area of W, so the width of bitmap areas and scroll bars
-   must be subtracted to get a position relative to the start of the
-   mode line.  */
-
-static void
-note_mode_line_or_margin_highlight (w, x, y, portion)
-     struct window *w;
-     int x, y, portion;
-{
-  struct frame *f = XFRAME (w->frame);
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-  Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
-  int charpos;
-  Lisp_Object string, help, map, pos;
-
-  if (portion == 1 || portion == 3)
-    string = mode_line_string (w, x, y, portion == 1, &charpos);
-  else
-    string = marginal_area_string (w, x, y, portion, &charpos);
-
-  if (STRINGP (string))
-    {
-      pos = make_number (charpos);
-
-      /* If we're on a string with `help-echo' text property, arrange
-        for the help to be displayed.  This is done by setting the
-        global variable help_echo to the help string.  */
-      help = Fget_text_property (pos, Qhelp_echo, string);
-      if (!NILP (help))
-       {
-         help_echo = help;
-         XSETWINDOW (help_echo_window, w);
-         help_echo_object = string;
-         help_echo_pos = charpos;
-       }
-
-     /* Change the mouse pointer according to what is under X/Y.  */
-      map = Fget_text_property (pos, Qlocal_map, string);
-      if (!KEYMAPP (map))
-       map = Fget_text_property (pos, Qkeymap, string);
-      if (KEYMAPP (map))
-       cursor = f->output_data.w32->nontext_cursor;
-    }
-
-  w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
-}
-
-
-/* Take proper action when the mouse has moved to position X, Y on
-   frame F as regards highlighting characters that have mouse-face
-   properties.  Also de-highlighting chars where the mouse was before.
-   X and Y can be negative or out of range.  */
-
-static void
-note_mouse_highlight (f, x, y)
-     struct frame *f;
-     int x, y;
-{
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-  int portion;
-  Lisp_Object window;
-  struct window *w;
-  Cursor cursor = 0;
-  struct buffer *b;
-
-  /* When a menu is active, don't highlight because this looks odd. */
-  if (popup_activated ())
-    return;
-
-  if (NILP (Vmouse_highlight)
-      || !f->glyphs_initialized_p)
-    return;
-
-  dpyinfo->mouse_face_mouse_x = x;
-  dpyinfo->mouse_face_mouse_y = y;
-  dpyinfo->mouse_face_mouse_frame = f;
-
-  if (dpyinfo->mouse_face_defer)
-    return;
-
-  if (gc_in_progress)
-    {
-      dpyinfo->mouse_face_deferred_gc = 1;
-      return;
-    }
-
-  /* Which window is that in?  */
-  window = window_from_coordinates (f, x, y, &portion, 1);
-
-  /* If we were displaying active text in another window, clear that.  */
-  if (! EQ (window, dpyinfo->mouse_face_window))
-    clear_mouse_face (dpyinfo);
-
-  /* Not on a window -> return.  */
-  if (!WINDOWP (window))
-    return;
-
-  /* Reset help_echo. It will get recomputed below.  */
-  help_echo = Qnil;
-
-  /* Convert to window-relative pixel coordinates.  */
-  w = XWINDOW (window);
-  frame_to_window_pixel_xy (w, &x, &y);
-
-  /* Handle tool-bar window differently since it doesn't display a
-     buffer.  */
-  if (EQ (window, f->tool_bar_window))
-    {
-      note_tool_bar_highlight (f, x, y);
-      return;
-    }
-
-  /* Mouse is on the mode or header line?  */
-  if (portion == 1 || portion == 3 || portion == 6 || portion == 7)
-    {
-      note_mode_line_or_margin_highlight (w, x, y, portion);
-      return;
-    }
-
-  if (portion == 2)
-    cursor = f->output_data.w32->horizontal_drag_cursor;
-  else
-    cursor = f->output_data.w32->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 (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);
-
-      /* Clear mouse face if X/Y not over text.  */
-      if (glyph == NULL
-         || area != TEXT_AREA
-         || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
-       {
-         clear_mouse_face (dpyinfo);
-         cursor = f->output_data.w32->nontext_cursor;
-         goto set_cursor;
-       }
-
-      pos = glyph->charpos;
-      object = glyph->object;
-      if (!STRINGP (object) && !BUFFERP (object))
-       goto set_cursor;
-
-      /* If we get an out-of-range value, return now; avoid an error.  */
-      if (BUFFERP (object) && pos > BUF_Z (b))
-       goto set_cursor;
-
-      /* 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;
-
-      /* 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 = 0;
-
-      /* 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 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;
-
-         dpyinfo->mouse_face_overlay = overlay;
-
-         /* Clear the display of the old active region, if any.  */
-         if (clear_mouse_face (dpyinfo))
-           cursor = 0;
-
-         /* 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, Qnil);
-
-             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, Qnil);
-             dpyinfo->mouse_face_window = window;
-
-             dpyinfo->mouse_face_face_id
-               = face_at_buffer_position (w, pos, 0, 0,
-                                          &ignore, pos + 1,
-                                          !dpyinfo->mouse_face_hidden);
-
-             /* Display it as active.  */
-             show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
-             cursor = 0;
-           }
-         /* 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, Qnil);
-             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, Qnil);
-             dpyinfo->mouse_face_window = window;
-
-             if (BUFFERP (object))
-               dpyinfo->mouse_face_face_id
-                 = face_at_buffer_position (w, pos, 0, 0,
-                                            &ignore, pos + 1,
-                                            !dpyinfo->mouse_face_hidden);
-
-             /* Display it as active.  */
-             show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
-             cursor = 0;
-           }
-         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 (SCHARS (object) - 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);
-             cursor = 0;
-           }
-         else if (STRINGP (object) && NILP (mouse_face))
-           {
-             /* A string which doesn't have mouse-face, but
-                the text ``under'' it might have.  */
-             struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
-             int start = MATRIX_ROW_START_CHARPOS (r);
-
-             pos = string_buffer_position (w, object, start);
-             if (pos > 0)
-               mouse_face = get_char_property_and_overlay (make_number (pos),
-                                                           Qmouse_face,
-                                                           w->buffer,
-                                                           &overlay);
-             if (!NILP (mouse_face) && !NILP (overlay))
-               {
-                 Lisp_Object before = Foverlay_start (overlay);
-                 Lisp_Object after = Foverlay_end (overlay);
-                 int ignore;
-
-                 /* Note that we might not be able to find position
-                    BEFORE in the glyph matrix if the overlay is
-                    entirely covered by a `display' property.  In
-                    this case, we overshoot.  So let's stop in
-                    the glyph matrix before glyphs for OBJECT.  */
-                 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,
-                                     object);
-
-                 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,
-                                          Qnil);
-                 dpyinfo->mouse_face_window = window;
-                 dpyinfo->mouse_face_face_id
-                   = face_at_buffer_position (w, pos, 0, 0,
-                                              &ignore, pos + 1,
-                                              !dpyinfo->mouse_face_hidden);
-
-                 /* Display it as active.  */
-                 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
-                 cursor = 0;
-               }
-           }
-       }
-
-    check_help_echo:
-
-      /* Look for a `help-echo' property.  */
-      {
-       Lisp_Object help, overlay;
-
-       /* 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 < SCHARS (object))
-             {
-               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_char_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;
-    }
-
- set_cursor:
-  if (cursor)
-    w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
-}
-
-static void
-redo_mouse_highlight ()
-{
-  if (!NILP (last_mouse_motion_frame)
-      && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
-    note_mouse_highlight (XFRAME (last_mouse_motion_frame),
-                         LOWORD (last_mouse_motion_event.lParam),
-                         HIWORD (last_mouse_motion_event.lParam));
-}
-
-void
-w32_define_cursor (window, cursor)
-     Window window;
-     Cursor cursor;
-{
-  PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
-}
-
-\f
-/***********************************************************************
-                              Tool-bars
- ***********************************************************************/
-
-static int x_tool_bar_item P_ ((struct frame *, int, int,
-                              struct glyph **, int *, int *, int *));
-
-/* Tool-bar item index of the item on which a mouse button was pressed
-   or -1.  */
-
-static int last_tool_bar_item;
-
-
-/* Get information about the tool-bar item at position X/Y on frame F.
-   Return in *GLYPH a pointer to the glyph of the tool-bar item in
-   the current matrix of the tool-bar window of F, or NULL if not
-   on a tool-bar item.  Return in *PROP_IDX the index of the tool-bar
-   item in F->tool_bar_items.  Value is
-
-   -1  if X/Y is not on a tool-bar item
-   0   if X/Y is on the same item that was highlighted before.
-   1   otherwise.  */
-
-static int
-x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
-     struct frame *f;
-     int x, y;
-     struct glyph **glyph;
-     int *hpos, *vpos, *prop_idx;
-{
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-  struct window *w = XWINDOW (f->tool_bar_window);
-  int area;
-
-  /* Find the glyph under X/Y.  */
-  *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
-  if (*glyph == NULL)
-    return -1;
-
-  /* Get the start of this tool-bar item's properties in
-     f->tool_bar_items.  */
-  if (!tool_bar_item_info (f, *glyph, prop_idx))
-    return -1;
-
-  /* Is mouse on the highlighted item?  */
-  if (EQ (f->tool_bar_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))
-    return 0;
-
-  return 1;
-}
-
-
-/* Handle mouse button event on the tool-bar of frame F, at
-   frame-relative coordinates X/Y.  EVENT_TYPE is either ButtionPress
-   or ButtonRelase.  */
-
-static void
-w32_handle_tool_bar_click (f, button_event)
-     struct frame *f;
-     struct input_event *button_event;
-{
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-  struct window *w = XWINDOW (f->tool_bar_window);
-  int hpos, vpos, prop_idx;
-  struct glyph *glyph;
-  Lisp_Object enabled_p;
-  int x = XFASTINT (button_event->x);
-  int y = XFASTINT (button_event->y);
-
-  /* If not on the highlighted tool-bar item, return.  */
-  frame_to_window_pixel_xy (w, &x, &y);
-  if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
-    return;
-
-  /* If item is disabled, do nothing.  */
-  enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
-  if (NILP (enabled_p))
-    return;
-
-  if (button_event->modifiers & down_modifier)
-    {
-      /* Show item in pressed state.  */
-      show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
-      dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
-      last_tool_bar_item = prop_idx;
-    }
-  else
-    {
-      Lisp_Object key, frame;
-      struct input_event event;
-
-      /* Show item in released state.  */
-      show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
-      dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
-
-      key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
-
-      XSETFRAME (frame, f);
-      event.kind = TOOL_BAR_EVENT;
-      event.frame_or_window = frame;
-      event.arg = frame;
-      kbd_buffer_store_event (&event);
-
-      event.kind = TOOL_BAR_EVENT;
-      event.frame_or_window = frame;
-      event.arg = key;
-      /* The keyboard buffer doesn't like the up modifier being set.  */
-      event.modifiers = button_event->modifiers & ~up_modifier;
-      kbd_buffer_store_event (&event);
-      last_tool_bar_item = -1;
-    }
-}
-
-
-/* Possibly highlight a tool-bar item on frame F when mouse moves to
-   tool-bar window-relative coordinates X/Y.  Called from
-   note_mouse_highlight.  */
-
-static void
-note_tool_bar_highlight (f, x, y)
-     struct frame *f;
-     int x, y;
-{
-  Lisp_Object window = f->tool_bar_window;
-  struct window *w = XWINDOW (window);
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-  int hpos, vpos;
-  struct glyph *glyph;
-  struct glyph_row *row;
-  int i;
-  Lisp_Object enabled_p;
-  int prop_idx;
-  enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
-  int mouse_down_p, rc;
-
-  /* Function note_mouse_highlight is called with negative x(y
-     values when mouse moves outside of the frame.  */
-  if (x <= 0 || y <= 0)
-    {
-      clear_mouse_face (dpyinfo);
-      return;
-    }
-
-  rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
-  if (rc < 0)
-    {
-      /* Not on tool-bar item.  */
-      clear_mouse_face (dpyinfo);
-      return;
-    }
-  else if (rc == 0)
-    /* On same tool-bar item as before.  */
-    goto set_help_echo;
-
-  clear_mouse_face (dpyinfo);
-
-  /* Mouse is down, but on different tool-bar item?  */
-  mouse_down_p = (dpyinfo->grabbed
-                 && f == last_mouse_frame
-                 && FRAME_LIVE_P (f));
-  if (mouse_down_p
-      && last_tool_bar_item != prop_idx)
-    return;
-
-  dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
-  draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
-
-  /* If tool-bar item is not enabled, don't highlight it.  */
-  enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
-  if (!NILP (enabled_p))
-    {
-      /* Compute the x-position of the glyph.  In front and past the
-        image is a space.  We include this is the highlighted area.  */
-      row = MATRIX_ROW (w->current_matrix, vpos);
-      for (i = x = 0; i < hpos; ++i)
-       x += row->glyphs[TEXT_AREA][i].pixel_width;
-
-      /* Record this as the current active region.  */
-      dpyinfo->mouse_face_beg_col = hpos;
-      dpyinfo->mouse_face_beg_row = vpos;
-      dpyinfo->mouse_face_beg_x = x;
-      dpyinfo->mouse_face_beg_y = row->y;
-      dpyinfo->mouse_face_past_end = 0;
-
-      dpyinfo->mouse_face_end_col = hpos + 1;
-      dpyinfo->mouse_face_end_row = vpos;
-      dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
-      dpyinfo->mouse_face_end_y = row->y;
-      dpyinfo->mouse_face_window = window;
-      dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
-
-      /* Display it as active.  */
-      show_mouse_face (dpyinfo, draw);
-      dpyinfo->mouse_face_image_state = draw;
-    }
-
- set_help_echo:
-
-  /* Set help_echo to a help string.to display for this tool-bar item.
-     w32_read_socket does the rest.  */
-  help_echo_object = help_echo_window = Qnil;
-  help_echo_pos = -1;
-  help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
-  if (NILP (help_echo))
-    help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
-}
-
-
-\f
-/* Find the glyph matrix position of buffer position CHARPOS in window
-   *W.  HPOS, *VPOS, *X, and *Y are set to the positions found.  W's
-   current glyphs must be up to date.  If CHARPOS is above window
-   start return (0, 0, 0, 0).  If CHARPOS is after end of W, return end
-   of last line in W.  In the row containing CHARPOS, stop before glyphs
-   having STOP as object.  */
-
-#if 0 /* This is a version of fast_find_position that's more correct
-        in the presence of hscrolling, for example.  I didn't install
-        it right away because the problem fixed is minor, it failed
-        in 20.x as well, and I think it's too risky to install
-        so near the release of 21.1.  2001-09-25 gerd.  */
-
-static int
-fast_find_position (w, charpos, hpos, vpos, x, y, stop)
-     struct window *w;
-     int charpos;
-     int *hpos, *vpos, *x, *y;
-     Lisp_Object stop;
-{
-  struct glyph_row *row, *first;
-  struct glyph *glyph, *end;
-  int i, past_end = 0;
-
-  first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
-  row = row_containing_pos (w, charpos, first, NULL, 0);
-  if (row == NULL)
-    {
-      if (charpos < MATRIX_ROW_START_CHARPOS (first))
-       {
-         *x = *y = *hpos = *vpos = 0;
-         return 0;
-       }
-      else
-       {
-         row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
-         past_end = 1;
-       }
-    }
-
-  *x = row->x;
-  *y = row->y;
-  *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
-
-  glyph = row->glyphs[TEXT_AREA];
-  end = glyph + row->used[TEXT_AREA];
-
-  /* Skip over glyphs not having an object at the start of the row.
-     These are special glyphs like truncation marks on terminal
-     frames.  */
-  if (row->displays_text_p)
-    while (glyph < end
-          && INTEGERP (glyph->object)
-          && !EQ (stop, glyph->object)
-          && glyph->charpos < 0)
-      {
-       *x += glyph->pixel_width;
-       ++glyph;
-      }
-
-  while (glyph < end
-        && !INTEGERP (glyph->object)
-        && !EQ (stop, glyph->object)
-        && (!BUFFERP (glyph->object)
-            || glyph->charpos < charpos))
-    {
-      *x += glyph->pixel_width;
-      ++glyph;
-    }
-
-  *hpos = glyph - row->glyphs[TEXT_AREA];
-  return past_end;
-}
-
-#else /* not 0 */
-
-static int
-fast_find_position (w, pos, hpos, vpos, x, y, stop)
-     struct window *w;
-     int pos;
-     int *hpos, *vpos, *x, *y;
-     Lisp_Object stop;
-{
-  int i;
-  int lastcol;
-  int maybe_next_line_p = 0;
-  int line_start_position;
-  int yb = window_text_bottom_y (w);
-  struct glyph_row *row, *best_row;
-  int row_vpos, best_row_vpos;
-  int current_x;
-
-  row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
-  row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
-
-  while (row->y < yb)
-    {
-      if (row->used[TEXT_AREA])
-       line_start_position = row->glyphs[TEXT_AREA]->charpos;
-      else
-       line_start_position = 0;
-
-      if (line_start_position > pos)
-       break;
-      /* If the position sought is the end of the buffer,
-        don't include the blank lines at the bottom of the window.  */
-      else if (line_start_position == pos
-               && pos == BUF_ZV (XBUFFER (w->buffer)))
-       {
-         maybe_next_line_p = 1;
-         break;
-       }
-      else if (line_start_position > 0)
-        {
-          best_row = row;
-          best_row_vpos = row_vpos;
-        }
-
-      if (row->y + row->height >= yb)
-        break;
-
-      ++row;
-      ++row_vpos;
-    }
-
-  /* Find the right column within BEST_ROW.  */
-  lastcol = 0;
-  current_x = best_row->x;
-  for (i = 0; i < best_row->used[TEXT_AREA]; i++)
-    {
-      struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
-      int charpos = glyph->charpos;
-
-      if (BUFFERP (glyph->object))
-       {
-         if (charpos == pos)
-           {
-             *hpos = i;
-             *vpos = best_row_vpos;
-             *x = current_x;
-             *y = best_row->y;
-             return 1;
-           }
-         else if (charpos > pos)
-           break;
-       }
-      else if (EQ (glyph->object, stop))
-       break;
-
-      if (charpos > 0)
-       lastcol = i;
-      current_x += glyph->pixel_width;
-    }
-
-  /* If we're looking for the end of the buffer,
-     and we didn't find it in the line we scanned,
-     use the start of the following line.  */
-  if (maybe_next_line_p)
-    {
-      ++best_row;
-      ++best_row_vpos;
-      lastcol = 0;
-      current_x = best_row->x;
-    }
-
-  *vpos = best_row_vpos;
-  *hpos = lastcol + 1;
-  *x = current_x;
-  *y = best_row->y;
-  return 0;
-}
-
-#endif /* not 0 */
-
-
-/* Find the position of the glyph for position POS in OBJECT in
-   window W's current matrix, and return in *X/*Y the pixel
-   coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
-
-   RIGHT_P non-zero means return the position of the right edge of the
-   glyph, RIGHT_P zero means return the left edge position.
-
-   If no glyph for POS exists in the matrix, return the position of
-   the glyph with the next smaller position that is in the matrix, if
-   RIGHT_P is zero.  If RIGHT_P is non-zero, and no glyph for POS
-   exists in the matrix, return the position of the glyph with the
-   next larger position in OBJECT.
-
-   Value is non-zero if a glyph was found.  */
-
-static int
-fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
-     struct window *w;
-     int pos;
-     Lisp_Object object;
-     int *hpos, *vpos, *x, *y;
-     int right_p;
-{
-  int yb = window_text_bottom_y (w);
-  struct glyph_row *r;
-  struct glyph *best_glyph = NULL;
-  struct glyph_row *best_row = NULL;
-  int best_x = 0;
-
-  for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
-       r->enabled_p && r->y < yb;
-       ++r)
-    {
-      struct glyph *g = r->glyphs[TEXT_AREA];
-      struct glyph *e = g + r->used[TEXT_AREA];
-      int gx;
-
-      for (gx = r->x; g < e; gx += g->pixel_width, ++g)
-       if (EQ (g->object, object))
-         {
-           if (g->charpos == pos)
-             {
-               best_glyph = g;
-               best_x = gx;
-               best_row = r;
-               goto found;
-             }
-           else if (best_glyph == NULL
-                    || ((abs (g->charpos - pos)
-                        < abs (best_glyph->charpos - pos))
-                        && (right_p
-                            ? g->charpos < pos
-                            : g->charpos > pos)))
-             {
-               best_glyph = g;
-               best_x = gx;
-               best_row = r;
-             }
-         }
-    }
-
- found:
-
-  if (best_glyph)
-    {
-      *x = best_x;
-      *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
-
-      if (right_p)
-       {
-         *x += best_glyph->pixel_width;
-         ++*hpos;
-       }
-
-      *y = best_row->y;
-      *vpos = best_row - w->current_matrix->rows;
-    }
-
-  return best_glyph != NULL;
-}
-
-
-/* Display the active region described by mouse_face_*
-   in its mouse-face if HL > 0, in its normal face if HL = 0.  */
-
-static void
-show_mouse_face (dpyinfo, draw)
-     struct w32_display_info *dpyinfo;
-     enum draw_glyphs_face draw;
-{
-  struct window *w = XWINDOW (dpyinfo->mouse_face_window);
-  struct frame *f = XFRAME (WINDOW_FRAME (w));
-
-  if (/* If window is in the process of being destroyed, don't bother
-        to do anything.  */
-      w->current_matrix != NULL
-      /* Don't update mouse highlight if hidden */
-      && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
-      /* Recognize when we are called to operate on rows that don't exist
-        anymore.  This can happen when a window is split.  */
-      && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
-    {
-      int phys_cursor_on_p = w->phys_cursor_on_p;
-      struct glyph_row *row, *first, *last;
-
-      first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
-      last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
+  char *name;
+  int i, len;
 
-      for (row = first; row <= last && row->enabled_p; ++row)
-       {
-         int start_hpos, end_hpos, start_x;
+  result->kind = DRAG_N_DROP_EVENT;
+  result->code = 0;
+  result->timestamp = msg->msg.time;
+  result->modifiers = msg->dwModifiers;
 
-         /* For all but the first row, the highlight starts at column 0.  */
-         if (row == first)
-           {
-             start_hpos = dpyinfo->mouse_face_beg_col;
-             start_x = dpyinfo->mouse_face_beg_x;
-           }
-         else
-           {
-             start_hpos = 0;
-             start_x = 0;
-           }
+  hdrop = (HDROP) msg->msg.wParam;
+  DragQueryPoint (hdrop, &p);
 
-         if (row == last)
-           end_hpos = dpyinfo->mouse_face_end_col;
-         else
-           end_hpos = row->used[TEXT_AREA];
+#if 0
+  p.x = LOWORD (msg->msg.lParam);
+  p.y = HIWORD (msg->msg.lParam);
+  ScreenToClient (msg->msg.hwnd, &p);
+#endif
 
-         if (end_hpos > start_hpos)
-           {
-             x_draw_glyphs (w, start_x, row, TEXT_AREA,
-                            start_hpos, end_hpos, draw, 0);
+  XSETINT (result->x, p.x);
+  XSETINT (result->y, p.y);
 
-             row->mouse_face_p
-               = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
-           }
-       }
+  num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
+  files = Qnil;
 
-      /* When we've written over the cursor, arrange for it to
-        be displayed again.  */
-      if (phys_cursor_on_p && !w->phys_cursor_on_p)
-       x_display_cursor (w, 1,
-                         w->phys_cursor.hpos, w->phys_cursor.vpos,
-                         w->phys_cursor.x, w->phys_cursor.y);
+  for (i = 0; i < num_files; i++)
+    {
+      len = DragQueryFile (hdrop, i, NULL, 0);
+      if (len <= 0)
+       continue;
+      name = alloca (len + 1);
+      DragQueryFile (hdrop, i, name, len + 1);
+      files = Fcons (DECODE_FILE (build_string (name)), files);
     }
 
-  /* Change the mouse cursor.  */
-  if (draw == DRAW_NORMAL_TEXT)
-    w32_define_cursor (FRAME_W32_WINDOW (f),
-                      f->output_data.w32->text_cursor);
-  else if (draw == DRAW_MOUSE_FACE)
-    w32_define_cursor (FRAME_W32_WINDOW (f),
-                      f->output_data.w32->hand_cursor);
-  else
-    w32_define_cursor (FRAME_W32_WINDOW (f),
-                      f->output_data.w32->nontext_cursor);
+  DragFinish (hdrop);
 
+  XSETFRAME (frame, f);
+  result->frame_or_window = Fcons (frame, files);
+  result->arg = Qnil;
+  return Qnil;
 }
 
-/* Clear out the mouse-highlighted active region.
-   Redraw it un-highlighted first.  */
-
-static int
-clear_mouse_face (dpyinfo)
-     struct w32_display_info *dpyinfo;
-{
-  int cleared = 0;
-
-  if (! NILP (dpyinfo->mouse_face_window))
-    {
-      show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
-      cleared = 1;
-    }
+\f
+/* Function to report a mouse movement to the mainstream Emacs code.
+   The input handler calls this.
 
-  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;
-}
+   We have received a mouse movement event, which is given in *event.
+   If the mouse is over a different glyph than it was last time, tell
+   the mainstream emacs code by setting mouse_moved.  If not, ask for
+   another motion event, so we can check again the next time it moves.  */
 
+static MSG last_mouse_motion_event;
+static Lisp_Object last_mouse_motion_frame;
 
-/* Clear any mouse-face on window W.  This function is part of the
-   redisplay interface, and is called from try_window_id and similar
-   functions to ensure the mouse-highlight is off.  */
+static void remember_mouse_glyph P_ ((struct frame *, int, int));
 
 static void
-x_clear_mouse_face (w)
-     struct window *w;
+note_mouse_movement (frame, msg)
+     FRAME_PTR frame;
+     MSG *msg;
 {
-  struct w32_display_info *dpyinfo
-    = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
-  Lisp_Object window;
-
-  BLOCK_INPUT;
-  XSETWINDOW (window, w);
-  if (EQ (window, dpyinfo->mouse_face_window))
-    clear_mouse_face (dpyinfo);
-  UNBLOCK_INPUT;
-}
-
+  int mouse_x = LOWORD (msg->lParam);
+  int mouse_y = HIWORD (msg->lParam);
 
-/* Just discard the mouse face information for frame F, if any.
-   This is used when the size of F is changed.  */
+  last_mouse_movement_time = msg->time;
+  memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
+  XSETFRAME (last_mouse_motion_frame, frame);
 
-void
-cancel_mouse_face (f)
-     FRAME_PTR f;
-{
-  Lisp_Object window;
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+  if (msg->hwnd != FRAME_W32_WINDOW (frame))
+    {
+      frame->mouse_moved = 1;
+      last_mouse_scroll_bar = Qnil;
+      note_mouse_highlight (frame, -1, -1);
+    }
 
-  window = dpyinfo->mouse_face_window;
-  if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
+  /* 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)
     {
-      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;
+      frame->mouse_moved = 1;
+      last_mouse_scroll_bar = Qnil;
+      note_mouse_highlight (frame, mouse_x, mouse_y);
+      /* Remember the mouse position here, as w32_mouse_position only
+        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);
     }
 }
+
 \f
+/************************************************************************
+                             Mouse Face
+ ************************************************************************/
+
 static struct scroll_bar *x_window_to_scroll_bar ();
 static void x_scroll_bar_report_motion ();
 static void x_check_fullscreen P_ ((struct frame *));
@@ -5201,6 +3139,24 @@ static void x_check_fullscreen_move P_ ((struct frame *));
 static int glyph_rect P_ ((struct frame *f, int, int, RECT *));
 
 
+static void
+redo_mouse_highlight ()
+{
+  if (!NILP (last_mouse_motion_frame)
+      && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
+    note_mouse_highlight (XFRAME (last_mouse_motion_frame),
+                         LOWORD (last_mouse_motion_event.lParam),
+                         HIWORD (last_mouse_motion_event.lParam));
+}
+
+void
+w32_define_cursor (window, cursor)
+     Window window;
+     Cursor 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
@@ -5213,9 +3169,8 @@ glyph_rect (f, x, y, rect)
      RECT *rect;
 {
   Lisp_Object window;
-  int part;
 
-  window = window_from_coordinates (f, x, y, &part, 0);
+  window = window_from_coordinates (f, x, y, 0, 0);
   if (!NILP (window))
     {
       struct window *w = XWINDOW (window);
@@ -5417,6 +3372,35 @@ w32_mouse_position (fp, insist, bar_window, part, x, y, time)
 }
 
 \f
+/***********************************************************************
+                              Tool-bars
+ ***********************************************************************/
+
+/* Handle mouse button event on the tool-bar of frame F, at
+   frame-relative coordinates X/Y.  EVENT_TYPE is either ButtionPress
+   or ButtonRelase.  */
+
+static void
+w32_handle_tool_bar_click (f, button_event)
+     struct frame *f;
+     struct input_event *button_event;
+{
+  int x = XFASTINT (button_event->x);
+  int y = XFASTINT (button_event->y);
+
+  if (button_event->modifiers & down_modifier)
+    handle_tool_bar_click (f, x, y, 1, 0);
+  else
+    handle_tool_bar_click (f, x, y, 0,
+                          button_event->modifiers & ~up_modifier);
+}
+
+
+\f
+/***********************************************************************
+                              Scroll bars
+ ***********************************************************************/
+
 /* Scroll bar support.  */
 
 /* Given a window ID, find the struct scroll_bar which manages it.
@@ -6339,7 +4323,7 @@ w32_read_socket (sd, bufp, numchars, expected)
            last_mousemove_y = y;
          }
 
-          previous_help_echo = help_echo;
+          previous_help_echo_string = help_echo_string;
 
          if (dpyinfo->grabbed && last_mouse_frame
              && FRAME_LIVE_P (last_mouse_frame))
@@ -6359,13 +4343,10 @@ w32_read_socket (sd, bufp, numchars, expected)
              if (mouse_autoselect_window)
                {
                  Lisp_Object window;
-                 int area;
                  int x = LOWORD (msg.msg.lParam);
                  int y = HIWORD (msg.msg.lParam);
 
-                 window = window_from_coordinates (f,
-                                                   x, y,
-                                                   &area, 0);
+                 window = window_from_coordinates (f, x, y, 0, 0);
 
                  /* Window will be selected only when it is not
                     selected now and last mouse movement event was
@@ -6393,15 +4374,15 @@ w32_read_socket (sd, bufp, numchars, expected)
               clear_mouse_face (dpyinfo);
             }
 
-          /* If the contents of the global variable help_echo
+          /* If the contents of the global variable help_echo_string
              has changed, generate a HELP_EVENT.  */
-          if (help_echo != previous_help_echo ||
-             (!NILP (help_echo) && !STRINGP (help_echo) && f->mouse_moved))
+          if (help_echo_string != previous_help_echo_string ||
+             (!NILP (help_echo_string) && !STRINGP (help_echo_string) && f->mouse_moved))
             {
               Lisp_Object frame;
               int n;
 
-             if (help_echo == Qnil)
+             if (help_echo_string == Qnil)
                {
                  help_echo_object = help_echo_window = Qnil;
                  help_echo_pos = -1;
@@ -6413,7 +4394,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                 frame = Qnil;
 
               any_help_event_p = 1;
-              n = gen_help_event (bufp, numchars, help_echo, frame,
+              n = gen_help_event (bufp, numchars, help_echo_string, frame,
                                  help_echo_window, help_echo_object,
                                  help_echo_pos);
               bufp += n, count += n, numchars -= n;
@@ -6453,13 +4434,10 @@ w32_read_socket (sd, bufp, numchars, expected)
                     && XFASTINT (XWINDOW (f->tool_bar_window)->height))
                   {
                     Lisp_Object window;
-                    int p, x, y;
-
-                   x = XFASTINT (emacs_event.x);
-                   y = XFASTINT (emacs_event.y);
+                   int x = XFASTINT (emacs_event.x);
+                   int y = XFASTINT (emacs_event.y);
 
-                    /* Set x and y.  */
-                    window = window_from_coordinates (f, x, y, &p, 1);
+                    window = window_from_coordinates (f, x, y, 0, 1);
 
                     if (EQ (window, f->tool_bar_window))
                       {
@@ -6736,7 +4714,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                  int n;
 
                  XSETFRAME (frame, f);
-                 help_echo = Qnil;
+                 help_echo_string = Qnil;
                  n = gen_help_event (bufp, numchars,
                                      Qnil, frame, Qnil, Qnil, 0);
                  bufp += n, count += n, numchars -= n;
@@ -6795,7 +4773,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                   int n;
 
                   XSETFRAME (frame, f);
-                  help_echo = Qnil;
+                  help_echo_string = Qnil;
                   n = gen_help_event (bufp, numchars,
                                       Qnil, frame, Qnil, Qnil, 0);
                   bufp += n, count += n, numchars -=n;
@@ -7107,7 +5085,7 @@ x_draw_bar_cursor (w, row, width, kind)
     {
       struct glyph_row *row;
       row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
-      x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
+      draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
     }
   else
     {
@@ -7154,270 +5132,48 @@ x_draw_bar_cursor (w, row, width, kind)
 }
 
 
-/* Clear the cursor of window W to background color, and mark the
-   cursor as not shown.  This is used when the text where the cursor
-   is is about to be rewritten.  */
+/* RIF: Define cursor CURSOR on frame F.  */
 
 static void
-x_clear_cursor (w)
-     struct window *w;
+w32_define_frame_cursor (f, cursor)
+     struct frame *f;
+     Cursor cursor;
 {
-  if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
-    x_update_window_cursor (w, 0);
+  w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
 }
 
 
-/* Draw the cursor glyph of window W in glyph row ROW.  See the
-   comment of x_draw_glyphs for the meaning of HL.  */
+/* RIF: Clear area on frame F.  */
 
 static void
-x_draw_phys_cursor_glyph (w, row, hl)
-     struct window *w;
-     struct glyph_row *row;
-     enum draw_glyphs_face hl;
+w32_clear_frame_area (f, x, y, width, height)
+     struct frame *f;
+     int x, y, width, height;
 {
-  /* If cursor hpos is out of bounds, don't draw garbage.  This can
-     happen in mini-buffer windows when switching between echo area
-     glyphs and mini-buffer.  */
-  if (w->phys_cursor.hpos < row->used[TEXT_AREA])
-    {
-      int on_p = w->phys_cursor_on_p;
-      int x1;
-      x1 = x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
-                         w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
-                         hl, 0);
-      w->phys_cursor_on_p = on_p;
-
-      if (hl == DRAW_CURSOR)
-       w->phys_cursor_width = x1 - w->phys_cursor.x;
-
-      /* When we erase the cursor, and ROW is overlapped by other
-        rows, make sure that these overlapping parts of other rows
-        are redrawn.  */
-      if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
-       {
-         if (row > w->current_matrix->rows
-             && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
-           x_fix_overlapping_area (w, row - 1, TEXT_AREA);
+  HDC hdc;
 
-         if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
-             && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
-           x_fix_overlapping_area (w, row + 1, TEXT_AREA);
-       }
-    }
+  hdc = get_frame_dc (f);
+  w32_clear_area (f, hdc, x, y, width, height);
+  release_frame_dc (f, hdc);
 }
 
-
-/* Erase the image of a cursor of window W from the screen.  */
+/* RIF: Draw or clear cursor on window W.  */
 
 static void
-x_erase_phys_cursor (w)
-     struct window *w;
-{
-  struct frame *f = XFRAME (w->frame);
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-  int hpos = w->phys_cursor.hpos;
-  int vpos = w->phys_cursor.vpos;
-  int mouse_face_here_p = 0;
-  struct glyph_matrix *active_glyphs = w->current_matrix;
-  struct glyph_row *cursor_row;
-  struct glyph *cursor_glyph;
-  enum draw_glyphs_face hl;
-
-  /* No cursor displayed or row invalidated => nothing to do on the
-     screen.  */
-  if (w->phys_cursor_type == NO_CURSOR)
-    goto mark_cursor_off;
-
-  /* VPOS >= active_glyphs->nrows means that window has been resized.
-     Don't bother to erase the cursor.  */
-  if (vpos >= active_glyphs->nrows)
-    goto mark_cursor_off;
-
-  /* If row containing cursor is marked invalid, there is nothing we
-     can do.  */
-  cursor_row = MATRIX_ROW (active_glyphs, vpos);
-  if (!cursor_row->enabled_p)
-    goto mark_cursor_off;
-
-  /* If row is completely invisible, don't attempt to delete a cursor which
-     isn't there.  This may happen if cursor is at top of window, and
-     we switch to a buffer with a header line in that window.  */
-  if (cursor_row->visible_height <= 0)
-    goto mark_cursor_off;
-
-  /* This can happen when the new row is shorter than the old one.
-     In this case, either x_draw_glyphs or clear_end_of_line
-     should have cleared the cursor.  Note that we wouldn't be
-     able to erase the cursor in this case because we don't have a
-     cursor glyph at hand.  */
-  if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
-    goto mark_cursor_off;
-
-  /* If the cursor is in the mouse face area, redisplay that when
-     we clear the cursor.  */
-  if (! NILP (dpyinfo->mouse_face_window)
-      && w == XWINDOW (dpyinfo->mouse_face_window)
-      && (vpos > dpyinfo->mouse_face_beg_row
-         || (vpos == dpyinfo->mouse_face_beg_row
-             && hpos >= dpyinfo->mouse_face_beg_col))
-      && (vpos < dpyinfo->mouse_face_end_row
-         || (vpos == dpyinfo->mouse_face_end_row
-             && hpos < dpyinfo->mouse_face_end_col))
-      /* Don't redraw the cursor's spot in mouse face if it is at the
-        end of a line (on a newline).  The cursor appears there, but
-        mouse highlighting does not.  */
-      && cursor_row->used[TEXT_AREA] > hpos)
-    mouse_face_here_p = 1;
-
-  /* Maybe clear the display under the cursor.  */
-  if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
-    {
-      int x;
-      int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
-      HDC hdc;
-
-      cursor_glyph = get_phys_cursor_glyph (w);
-      if (cursor_glyph == NULL)
-       goto mark_cursor_off;
-
-      x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
-
-      hdc = get_frame_dc (f);
-      w32_clear_area (f, hdc, x,
-                      WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
-                                                       cursor_row->y)),
-                      cursor_glyph->pixel_width,
-                      cursor_row->visible_height);
-      release_frame_dc (f, hdc);
-    }
-
-  /* Erase the cursor by redrawing the character underneath it.  */
-  if (mouse_face_here_p)
-    hl = DRAW_MOUSE_FACE;
-  else
-    hl = DRAW_NORMAL_TEXT;
-  x_draw_phys_cursor_glyph (w, cursor_row, hl);
-
- mark_cursor_off:
-  w->phys_cursor_on_p = 0;
-  w->phys_cursor_type = NO_CURSOR;
-}
-
-
-/* Non-zero if physical cursor of window W is within mouse face.  */
-
-static int
-cursor_in_mouse_face_p (w)
-     struct window *w;
-{
-  struct w32_display_info *dpyinfo
-    = FRAME_W32_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.  */
-
-void
-x_display_and_set_cursor (w, on, hpos, vpos, x, y)
+w32_draw_window_cursor (w, glyph_row, on, x, y, new_cursor_type, new_cursor_width)
      struct window *w;
-     int on, hpos, vpos, x, y;
+     struct glyph_row *glyph_row;
+     int on, x, y;
+     int new_cursor_type, new_cursor_width;
 {
-  struct frame *f = XFRAME (w->frame);
-  int new_cursor_type;
-  int new_cursor_width;
-  int active_cursor;
-  struct glyph_matrix *current_glyphs;
-  struct glyph_row *glyph_row;
-  struct glyph *glyph;
-
-  /* This is pointless on invisible frames, and dangerous on garbaged
-     windows and frames; in the latter case, the frame or window may
-     be in the midst of changing its size, and x and y may be off the
-     window.  */
-  if (! FRAME_VISIBLE_P (f)
-      || FRAME_GARBAGED_P (f)
-      || vpos >= w->current_matrix->nrows
-      || hpos >= w->current_matrix->matrix_w)
-    return;
-
-  /* If cursor is off and we want it off, return quickly.  */
-  if (!on && !w->phys_cursor_on_p)
-    return;
-
-  current_glyphs = w->current_matrix;
-  glyph_row = MATRIX_ROW (current_glyphs, vpos);
-  glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
-
-  /* If cursor row is not enabled, we don't really know where to
-     display the cursor.  */
-  if (!glyph_row->enabled_p)
-    {
-      w->phys_cursor_on_p = 0;
-      return;
-    }
-
-  xassert (interrupt_input_blocked);
-
-  /* Set new_cursor_type to the cursor we want to be displayed.  */
-  new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
-
-  /* If cursor is currently being shown and we don't want it to be or
-     it is in the wrong place, or the cursor type is not what we want,
-     erase it.  */
-  if (w->phys_cursor_on_p
-      && (!on
-         || w->phys_cursor.x != x
-         || w->phys_cursor.y != y
-         || new_cursor_type != w->phys_cursor_type
-         || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
-             && new_cursor_width != w->phys_cursor_width)))
-    x_erase_phys_cursor (w);
-
-  /* Don't check phys_cursor_on_p here because that flag is only set
-     to zero in some cases where we know that the cursor has been
-     completely erased, to avoid the extra work of erasing the cursor
-     twice.  In other words, phys_cursor_on_p can be 1 and the cursor
-     still not be visible, or it has only been partly erased.  */
   if (on)
     {
-      w->phys_cursor_ascent = glyph_row->ascent;
-      w->phys_cursor_height = glyph_row->height;
-
-      /* Set phys_cursor_.* before x_draw_.* is called because some
-        of them may need the information.  */
-      w->phys_cursor.x = x;
-      w->phys_cursor.y = glyph_row->y;
-      w->phys_cursor.hpos = hpos;
-      w->phys_cursor.vpos = vpos;
-
       /* If the user wants to use the system caret, make sure our own
         cursor remains invisible.  */
       if (w32_use_visible_system_caret)
        {
          if (w->phys_cursor_type != NO_CURSOR)
-           x_erase_phys_cursor (w);
+           erase_phys_cursor (w);
 
          new_cursor_type = w->phys_cursor_type = NO_CURSOR;
          w->phys_cursor_width = -1;
@@ -7461,7 +5217,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
          break;
 
        case FILLED_BOX_CURSOR:
-         x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+         draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
          break;
 
        case BAR_CURSOR:
@@ -7483,79 +5239,6 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
 }
 
 
-/* Display the cursor on window W, or clear it.  X and Y are window
-   relative pixel coordinates.  HPOS and VPOS are glyph matrix
-   positions.  If W is not the selected window, display a hollow
-   cursor.  ON non-zero means display the cursor at X, Y which
-   correspond to HPOS, VPOS, otherwise it is cleared.  */
-
-void
-x_display_cursor (w, on, hpos, vpos, x, y)
-     struct window *w;
-     int on, hpos, vpos, x, y;
-{
-  BLOCK_INPUT;
-  x_display_and_set_cursor (w, on, hpos, vpos, x, y);
-  UNBLOCK_INPUT;
-}
-
-
-/* Display the cursor on window W, or clear it, according to ON_P.
-   Don't change the cursor's position.  */
-
-void
-x_update_cursor (f, on_p)
-     struct frame *f;
-     int on_p;
-{
-  x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
-}
-
-
-/* Call x_update_window_cursor with parameter ON_P on all leaf windows
-   in the window tree rooted at W.  */
-
-static void
-x_update_cursor_in_window_tree (w, on_p)
-     struct window *w;
-     int on_p;
-{
-  while (w)
-    {
-      if (!NILP (w->hchild))
-       x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
-      else if (!NILP (w->vchild))
-       x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
-      else
-       x_update_window_cursor (w, on_p);
-
-      w = NILP (w->next) ? 0 : XWINDOW (w->next);
-    }
-}
-
-
-/* Switch the display of W's cursor on or off, according to the value
-   of ON.  */
-
-static void
-x_update_window_cursor (w, on)
-     struct window *w;
-     int on;
-{
-  /* Don't update cursor in windows whose frame is in the process
-     of being deleted.  */
-  if (w->current_matrix)
-    {
-      BLOCK_INPUT;
-      x_display_and_set_cursor (w, on, w->phys_cursor.hpos,
-                                w->phys_cursor.vpos, w->phys_cursor.x,
-                                w->phys_cursor.y);
-      UNBLOCK_INPUT;
-    }
-}
-
-
-
 \f
 /* Icons.  */
 
@@ -8805,16 +6488,22 @@ static struct redisplay_interface w32_redisplay_interface =
   x_after_update_window_line,
   x_update_window_begin,
   x_update_window_end,
-  w32_cursor_to,
+  x_cursor_to,
   x_flush,
-  x_clear_mouse_face,
+  0,  /* flush_display_optional */
+  x_clear_window_mouse_face,
   w32_get_glyph_overhangs,
   x_fix_overlapping_area,
   w32_draw_fringe_bitmap,
   w32_per_char_metric,
   w32_encode_char,
   NULL, /* w32_compute_glyph_string_overhangs */
-  x_draw_glyph_string
+  x_draw_glyph_string,
+  w32_define_frame_cursor,
+  w32_clear_frame_area,
+  w32_draw_window_cursor,
+  w32_draw_vertical_window_border,
+  w32_shift_glyphs_for_insert
 };
 
 void
@@ -8840,7 +6529,6 @@ w32_initialize ()
   condemn_scroll_bars_hook = w32_condemn_scroll_bars;
   redeem_scroll_bar_hook = w32_redeem_scroll_bar;
   judge_scroll_bars_hook = w32_judge_scroll_bars;
-  estimate_mode_line_height_hook = x_estimate_mode_line_height;
 
   scroll_region_ok = 1;         /* we'll scroll partial frames */
   char_ins_del_ok = 1;
@@ -8975,20 +6663,6 @@ NT uses Unicode internally anyway, so this flag will probably have no
 affect on NT machines.  */);
   w32_enable_unicode_output = 1;
 
-  help_echo = Qnil;
-  staticpro (&help_echo);
-  help_echo_object = Qnil;
-  staticpro (&help_echo_object);
-  help_echo_window = Qnil;
-  staticpro (&help_echo_window);
-  previous_help_echo = Qnil;
-  staticpro (&previous_help_echo);
-  help_echo_pos = -1;
-
-  DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
-    doc: /* *Non-nil means autoselect window with mouse pointer.  */);
-  mouse_autoselect_window = 0;
-
   DEFVAR_BOOL ("w32-use-visible-system-caret",
               &w32_use_visible_system_caret,
               doc: /* Flag to make the system caret visible.
@@ -9008,20 +6682,6 @@ the cursor have no effect.  */);
                             &w32_use_visible_system_caret, 0))
     w32_use_visible_system_caret = 0;
 
-  DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
-              doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
-For example, if a block cursor is over a tab, it will be drawn as
-wide as that tab on the display.  */);
-  x_stretch_cursor_p = 0;
-
-  DEFVAR_BOOL ("x-use-underline-position-properties",
-              &x_use_underline_position_properties,
-              doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
-nil means ignore them.  If you encounter fonts with bogus
-UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
-to 4.1, set this to nil.  */);
-  x_use_underline_position_properties = 1;
-
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
               doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
   Vx_toolkit_scroll_bars = Qt;