(Info-dir-remove-duplicates): Avoid infloop when
[bpt/emacs.git] / src / w32term.c
index eb055da..73740b2 100644 (file)
@@ -155,15 +155,17 @@ 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 variable for w32_read_socket.  */
+/* Temporary variables for w32_read_socket.  */
 
 static Lisp_Object previous_help_echo;
+static int last_mousemove_x = 0;
+static int last_mousemove_y = 0;
 
 /* Non-zero means that a HELP_EVENT has been generated since Emacs
    start.  */
@@ -397,9 +399,12 @@ static void x_new_focus_frame P_ ((struct w32_display_info *,
 static void w32_frame_rehighlight P_ ((struct frame *));
 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));
+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));
@@ -412,7 +417,7 @@ 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_draw_fringe_bitmap P_ ((struct window *, HDC hdc,
-                                       struct glyph_row *, 
+                                       struct glyph_row *,
                                        enum fringe_bitmap_type, int left_p));
 static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
                                  HDC, int));
@@ -435,7 +440,7 @@ static Lisp_Object Qvendor_specific_keysyms;
 /* This is a function useful for recording debugging information about
    the sequence of occurrences in this file.  */
 
-struct record 
+struct record
 {
   char *locus;
   int type;
@@ -524,7 +529,7 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
 }
 
 /* Draw a filled rectangle at the specified position. */
-void 
+void
 w32_fill_rect (f, hdc, pix, lprect)
      FRAME_PTR f;
      HDC hdc;
@@ -538,7 +543,7 @@ w32_fill_rect (f, hdc, pix, lprect)
   DeleteObject (hb);
 }
 
-void 
+void
 w32_clear_window (f)
      FRAME_PTR f;
 {
@@ -561,7 +566,7 @@ w32_clear_window (f)
 /***********************************************************************
                    Starting and ending an update
  ***********************************************************************/
-                                                                       
+
 /* Start an update of frame F.  This function is installed as a hook
    for update_begin, i.e. it is called when update_begin is called.
    This function is called prior to calls to x_update_window_begin for
@@ -622,7 +627,7 @@ x_update_window_begin (w)
         flag set.  So, rows containing mouse-face glyphs are never
         scrolled, and we don't have to switch the mouse highlight off
         here to prevent it from being scrolled.  */
-      
+
       /* Can we tell that this update does not affect the window
         where the mouse highlight is?  If so, no need to turn off.
         Likewise, don't do anything if the frame is garbaged;
@@ -655,7 +660,7 @@ x_draw_vertical_border (w)
      struct window *w;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  
+
   /* 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
@@ -678,7 +683,7 @@ x_draw_vertical_border (w)
     }
 }
 
-   
+
 /* End update of window W (which is equal to updated_window).
 
    Draw vertical borders between horizontally adjacent windows, and
@@ -708,7 +713,7 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
        x_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;
     }
@@ -789,7 +794,7 @@ x_after_update_window_line (desired_row)
   int width, height;
 
   xassert (w);
-  
+
   if (!desired_row->mode_line_p && !w->pseudo_window_p)
     {
       BLOCK_INPUT;
@@ -844,7 +849,6 @@ w32_draw_fringe_bitmap (w, hdc, row, which, left_p)
      int left_p;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  Window window = FRAME_W32_WINDOW (f);
   HDC compat_hdc;
   int x, y, wd, h, dy;
   int b1, b2;
@@ -870,13 +874,13 @@ w32_draw_fringe_bitmap (w, hdc, row, which, left_p)
       h = left_height;
       pixmap = left_bmp;
       break;
-      
+
     case OVERLAY_ARROW_BITMAP:
       wd = ov_width;
       h = ov_height;
       pixmap = ov_bmp;
       break;
-      
+
     case RIGHT_TRUNCATION_BITMAP:
       wd = right_width;
       h = right_height;
@@ -888,7 +892,7 @@ w32_draw_fringe_bitmap (w, hdc, row, which, left_p)
       h = continued_height;
       pixmap = continued_bmp;
       break;
-      
+
     case CONTINUATION_LINE_BITMAP:
       wd = continuation_width;
       h = continuation_height;
@@ -956,7 +960,7 @@ w32_draw_fringe_bitmap (w, hdc, row, which, left_p)
   if (b1 >= 0)
     {
       int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
-      
+
       w32_fill_area (f, hdc, face->background,
                      b1,
                      WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
@@ -1084,7 +1088,7 @@ set_output_cursor (cursor)
 
    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
@@ -1382,7 +1386,7 @@ int w32_font_is_double_byte (XFontStruct *font)
 }
 
 
-static BOOL 
+static BOOL
 w32_use_unicode_for_codepage (codepage)
      int codepage;
 {
@@ -1446,11 +1450,11 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
       /* Fixed encoding scheme.  See fontset.h for the meaning of the
         encoding numbers.  */
       int enc = font_info->encoding[charset];
-      
+
       if ((enc == 1 || enc == 2)
          && CHARSET_DIMENSION (charset) == 2)
        *char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b));
-      
+
       if (enc == 1 || enc == 3
           || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
        *char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80);
@@ -1528,7 +1532,7 @@ x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
   else
     {
       int c1, c2, charset;
-      
+
       /* Split characters into bytes.  If c2 is -1 afterwards, C is
         really a one-byte character so that byte1 is zero.  */
       SPLIT_CHAR (c, charset, c1, c2);
@@ -1536,7 +1540,7 @@ x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
        *char2b = BUILD_WCHAR_T (c1, c2);
       else
        *char2b = BUILD_WCHAR_T (0, c1);
-  
+
       /* Maybe encode the character in *CHAR2B.  */
       if (face->font != NULL)
        {
@@ -1550,7 +1554,7 @@ x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
   /* Make sure X resources of the face are allocated.  */
   xassert (face != NULL);
   PREPARE_FACE_FOR_DISPLAY (f, face);
-  
+
   return face;
 }
 
@@ -1592,7 +1596,7 @@ x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
   else
     {
       int c1, c2, charset;
-      
+
       /* Split characters into bytes.  If c2 is -1 afterwards, C is
         really a one-byte character so that byte1 is zero.  */
       SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
@@ -1621,7 +1625,7 @@ x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
 }
 
 
-/* Store one glyph for IT->char_to_display in IT->glyph_row.  
+/* Store one glyph for IT->char_to_display in IT->glyph_row.
    Called from x_produce_glyphs when IT->glyph_row is non-null.  */
 
 static INLINE void
@@ -1630,10 +1634,10 @@ x_append_glyph (it)
 {
   struct glyph *glyph;
   enum glyph_row_area area = it->area;
-  
+
   xassert (it->glyph_row);
   xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
-  
+
   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
@@ -1656,7 +1660,7 @@ x_append_glyph (it)
     }
 }
 
-/* Store one glyph for the composition IT->cmp_id in IT->glyph_row.  
+/* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
    Called from x_produce_glyphs when IT->glyph_row is non-null.  */
 
 static INLINE void
@@ -1665,9 +1669,9 @@ x_append_composite_glyph (it)
 {
   struct glyph *glyph;
   enum glyph_row_area area = it->area;
-  
+
   xassert (it->glyph_row);
-  
+
   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
@@ -1738,7 +1742,7 @@ x_produce_image_glyph (it)
   it->pixel_width = img->width + 2 * img->hmargin;
 
   it->nglyphs = 1;
-  
+
   if (face->box != FACE_NO_BOX)
     {
       if (face->box_line_width > 0)
@@ -1746,7 +1750,7 @@ x_produce_image_glyph (it)
          it->ascent += face->box_line_width;
          it->descent += face->box_line_width;
        }
-      
+
       if (it->start_of_box_run_p)
        it->pixel_width += abs (face->box_line_width);
       if (it->end_of_box_run_p)
@@ -1754,12 +1758,12 @@ x_produce_image_glyph (it)
     }
 
   take_vertical_position_into_account (it);
-  
+
   if (it->glyph_row)
     {
       struct glyph *glyph;
       enum glyph_row_area area = it->area;
-      
+
       glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
       if (glyph < it->glyph_row->glyphs[area + 1])
        {
@@ -1784,10 +1788,10 @@ x_produce_image_glyph (it)
 
 
 /* Append a stretch glyph to IT->glyph_row.  OBJECT is the source
-   of the glyph, WIDTH and HEIGHT are the width and height of the 
-   stretch.  ASCENT is the percentage/100 of HEIGHT to use for the 
+   of the glyph, WIDTH and HEIGHT are the width and height of the
+   stretch.  ASCENT is the percentage/100 of HEIGHT to use for the
    ascent of the glyph (0 <= ASCENT <= 1).  */
-  
+
 static void
 x_append_stretch_glyph (it, object, width, height, ascent)
      struct it *it;
@@ -1799,7 +1803,7 @@ x_append_stretch_glyph (it, object, width, height, ascent)
   enum glyph_row_area area = it->area;
 
   xassert (ascent >= 0 && ascent <= 1);
-  
+
   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
@@ -1829,7 +1833,7 @@ x_append_stretch_glyph (it, object, width, height, ascent)
    being recognized:
 
    1. `:width WIDTH' specifies that the space should be WIDTH *
-   canonical char width wide.  WIDTH may be an integer or floating 
+   canonical char width wide.  WIDTH may be an integer or floating
    point number.
 
    2. `:relative-width FACTOR' specifies that the width of the stretch
@@ -1839,7 +1843,7 @@ x_append_stretch_glyph (it, object, width, height, ascent)
    3. `:align-to HPOS' specifies that the space should be wide enough
    to reach HPOS, a value in canonical character units.
 
-   Exactly one of the above pairs must be present.  
+   Exactly one of the above pairs must be present.
 
    4. `:height HEIGHT' specifies that the height of the stretch produced
    should be HEIGHT, measured in canonical character units.
@@ -1877,7 +1881,7 @@ x_produce_stretch_glyph (it)
   XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
 
   PREPARE_FACE_FOR_DISPLAY (it->f, face);
-  
+
   /* List should start with `space'.  */
   xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
   plist = XCDR (it->object);
@@ -1895,7 +1899,7 @@ x_produce_stretch_glyph (it)
         property.  */
       struct it it2;
       unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
-      
+
       it2 = *it;
       if (it->multibyte_p)
        {
@@ -1917,7 +1921,7 @@ x_produce_stretch_glyph (it)
   else
     /* Nothing specified -> width defaults to canonical char width.  */
     width = CANON_X_UNIT (it->f);
-  
+
   /* Compute height.  */
   if (prop = Fplist_get (plist, QCheight),
       NUMVAL (prop) > 0)
@@ -1928,7 +1932,7 @@ x_produce_stretch_glyph (it)
   else
     height = FONT_HEIGHT (font);
 
-  /* Compute percentage of height used for ascent.  If 
+  /* Compute percentage of height used for ascent.  If
      `:ascent ASCENT' is present and valid, use that.  Otherwise,
      derive the ascent from the font in use.  */
   if (prop = Fplist_get (plist, QCascent),
@@ -1962,13 +1966,13 @@ x_produce_stretch_glyph (it)
          it->ascent += face->box_line_width;
          it->descent += face->box_line_width;
        }
-      
+
       if (it->start_of_box_run_p)
        it->pixel_width += abs (face->box_line_width);
       if (it->end_of_box_run_p)
        it->pixel_width += abs (face->box_line_width);
     }
-  
+
   take_vertical_position_into_account (it);
 }
 
@@ -2060,7 +2064,7 @@ x_produce_glyphs (it)
              face = FACE_FROM_ID (it->f, it->face_id);
            }
         }
-      
+
       /* Get font to use.  Encode IT->char_to_display.  */
       x_get_char_face_and_encoding (it->f, it->char_to_display,
                                     it->face_id, &char2b,
@@ -2109,7 +2113,7 @@ x_produce_glyphs (it)
               it->phys_descent = FONT_DESCENT (font) - boff;
               it->pixel_width = FONT_WIDTH (font);
             }
-          
+
          /* If this is a space inside a region of text with
             `space-width' property, change its width.  */
          stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
@@ -2122,7 +2126,7 @@ x_produce_glyphs (it)
          if (face->box != FACE_NO_BOX)
            {
              int thick = face->box_line_width;
-             
+
              if (thick > 0)
                {
                  it->ascent += thick;
@@ -2130,7 +2134,7 @@ x_produce_glyphs (it)
                }
              else
                thick = -thick;
-             
+
              if (it->start_of_box_run_p)
                it->pixel_width += thick;
              if (it->end_of_box_run_p)
@@ -2143,7 +2147,7 @@ x_produce_glyphs (it)
            it->ascent += 2;
 
          take_vertical_position_into_account (it);
-  
+
          /* If we have to actually produce glyphs, do it.  */
          if (it->glyph_row)
            {
@@ -2153,7 +2157,7 @@ x_produce_glyphs (it)
                     into a stretch glyph.  */
                  double ascent = (double) FONT_BASE (font)
                                 / FONT_HEIGHT (font);
-                 x_append_stretch_glyph (it, it->object, it->pixel_width, 
+                 x_append_stretch_glyph (it, it->object, it->pixel_width,
                                          it->ascent + it->descent, ascent);
                }
              else
@@ -2173,7 +2177,7 @@ x_produce_glyphs (it)
          it->nglyphs = 0;
          it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
          it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
-      
+
          if (face->box != FACE_NO_BOX
              && face->box_line_width > 0)
            {
@@ -2186,7 +2190,7 @@ x_produce_glyphs (it)
          int tab_width = it->tab_width * CANON_X_UNIT (it->f);
          int x = it->current_x + it->continuation_lines_width;
          int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
-      
+
          /* If the distance from the current position to the next tab
             stop is less than a canonical character width, use the
             tab stop after that.  */
@@ -2197,15 +2201,15 @@ x_produce_glyphs (it)
          it->nglyphs = 1;
          it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
          it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
-         
+
          if (it->glyph_row)
            {
              double ascent = (double) it->ascent / (it->ascent + it->descent);
-             x_append_stretch_glyph (it, it->object, it->pixel_width, 
+             x_append_stretch_glyph (it, it->object, it->pixel_width,
                                      it->ascent + it->descent, ascent);
            }
        }
-      else 
+      else
        {
          /* A multi-byte character.
              If we found a font, this font should give us the right
@@ -2258,20 +2262,20 @@ x_produce_glyphs (it)
                }
              else
                thick = - thick;
-         
+
              if (it->start_of_box_run_p)
                it->pixel_width += thick;
              if (it->end_of_box_run_p)
                it->pixel_width += thick;
            }
-  
+
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
          if (face->overline_p)
            it->ascent += 2;
 
          take_vertical_position_into_account (it);
-  
+
          if (it->glyph_row)
            x_append_glyph (it);
        }
@@ -2373,12 +2377,12 @@ x_produce_glyphs (it)
              ascent = FONT_BASE (font);
              descent = FONT_DESCENT (font);
            }
-         
+
          rightmost = width;
          lowest = - descent + boff;
          highest = ascent + boff;
          leftmost = 0;
-         
+
          if (font_info
              && font_info->default_ascent
              && CHAR_TABLE_P (Vuse_default_ascent)
@@ -2546,20 +2550,20 @@ x_produce_glyphs (it)
            }
          else
            thick = - thick;
-         
+
          if (it->start_of_box_run_p)
            it->pixel_width += thick;
          if (it->end_of_box_run_p)
            it->pixel_width += thick;
        }
-  
+
       /* If face has an overline, add the height of the overline
         (1 pixel) and a 1 pixel margin to the character height.  */
       if (face->overline_p)
        it->ascent += 2;
 
       take_vertical_position_into_account (it);
-  
+
       if (it->glyph_row)
        x_append_composite_glyph (it);
     }
@@ -2606,7 +2610,7 @@ x_estimate_mode_line_height (f, face_id)
              height += 2 * face->box_line_width;
           }
       }
-  
+
   return height;
 }
 
@@ -2798,7 +2802,7 @@ static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int,
 static void w32_init_glyph_string P_ ((struct glyph_string *, HDC hdc,
                                        wchar_t *, struct window *,
                                        struct glyph_row *,
-                                       enum glyph_row_area, int, 
+                                       enum glyph_row_area, int,
                                        enum draw_glyphs_face));
 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
                              enum glyph_row_area, int, int,
@@ -2844,7 +2848,7 @@ static int x_fill_stretch_glyph_string P_ ((struct glyph_string *,
 static void x_check_font P_ ((struct frame *, XFontStruct *));
 #endif
 
-     
+
 /* Append the list of glyph strings with head H and tail T to the list
    with head *HEAD and tail *TAIL.  Set *HEAD and *TAIL to the result.  */
 
@@ -2953,11 +2957,11 @@ x_set_cursor_gc (s)
 
 
 /* Set up S->gc of glyph string S for drawing text in mouse face.  */
-   
+
 static void
 x_set_mouse_face_gc (s)
      struct glyph_string *s;
-{     
+{
   int face_id;
   struct face *face;
 
@@ -2966,7 +2970,7 @@ x_set_mouse_face_gc (s)
   face = FACE_FROM_ID (s->f, face_id);
   if (face == NULL)
     face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
-  
+
   if (s->first_glyph->type == CHAR_GLYPH)
     face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
   else
@@ -2983,20 +2987,20 @@ x_set_mouse_face_gc (s)
         but font FONT.  */
       XGCValues xgcv;
       unsigned long mask;
-      
+
       xgcv.background = s->face->background;
       xgcv.foreground = s->face->foreground;
       IF_DEBUG (x_check_font (s->f, s->font));
       xgcv.font = s->font;
       mask = GCForeground | GCBackground | GCFont;
-      
+
       if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
        XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
                   mask, &xgcv);
       else
        FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
          = XCreateGC (NULL, s->window, mask, &xgcv);
-      
+
       s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
     }
 
@@ -3011,7 +3015,7 @@ x_set_mouse_face_gc (s)
 static INLINE void
 x_set_mode_line_face_gc (s)
      struct glyph_string *s;
-{     
+{
   s->gc = s->face->gc;
 }
 
@@ -3025,7 +3029,7 @@ x_set_glyph_string_gc (s)
      struct glyph_string *s;
 {
   PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
-  
+
   if (s->hl == DRAW_NORMAL_TEXT)
     {
       s->gc = s->face->gc;
@@ -3076,7 +3080,7 @@ w32_get_glyph_string_clip_rect (s, r)
     {
       /* 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;
 
@@ -3086,7 +3090,7 @@ w32_get_glyph_string_clip_rect (s, r)
          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
@@ -3131,6 +3135,18 @@ w32_get_glyph_string_clip_rect (s, r)
 
   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;
 }
@@ -3165,7 +3181,7 @@ x_compute_glyph_string_overhangs (s)
 /* Compute overhangs and x-positions for glyph string S and its
    predecessors, or successors.  X is the starting x-position for S.
    BACKWARD_P non-zero means process predecessors.  */
-   
+
 static void
 x_compute_overhangs_and_x (s, x, backward_p)
      struct glyph_string *s;
@@ -3207,7 +3223,7 @@ w32_get_glyph_overhangs (hdc, glyph, f, left, right)
      int *left, *right;
 {
   *left = *right = 0;
-  
+
   if (glyph->type == CHAR_GLYPH)
     {
       XFontStruct *font;
@@ -3253,7 +3269,7 @@ x_left_overwritten (s)
      struct glyph_string *s;
 {
   int k;
-    
+
   if (s->left_overhang)
     {
       int x = 0, i;
@@ -3315,7 +3331,7 @@ x_right_overwritten (s)
       struct glyph *glyphs = s->row->glyphs[s->area];
       int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
       int end = s->row->used[s->area];
-      
+
       for (i = first; i < end && s->right_overhang > x; ++i)
        x += glyphs[i].pixel_width;
 
@@ -3594,7 +3610,7 @@ w32_alloc_lighter_color (f, color, factor, delta)
       double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
       /* The additive adjustment.  */
       int min_delta = delta * dimness * factor / 2;
-      
+
       if (factor < 1)
         new = PALETTERGB (max (0, min (0xff, min_delta - GetRValue (*color))),
                           max (0, min (0xff, min_delta - GetGValue (*color))),
@@ -3604,7 +3620,7 @@ w32_alloc_lighter_color (f, color, factor, delta)
                           max (0, min (0xff, min_delta + GetGValue (*color))),
                           max (0, min (0xff, min_delta + GetBValue (*color))));
     }
-  
+
   if (new == *color)
     new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
                       max (0, min (0xff, delta + GetGValue (*color))),
@@ -3628,7 +3644,7 @@ w32_alloc_lighter_color (f, color, factor, delta)
    DELTA lighter or darker than the relief's background which is found
    in S->f->output_data.x->relief_background.  If such a color cannot
    be allocated, use DEFAULT_PIXEL, instead.  */
-   
+
 static void
 w32_setup_relief_color (f, relief, factor, delta, default_pixel)
      struct frame *f;
@@ -3654,7 +3670,7 @@ w32_setup_relief_color (f, relief, factor, delta, default_pixel)
       relief->allocated_p = 1;
       xgcv.foreground = relief->pixel = pixel;
     }
-  
+
   if (relief->gc == 0)
     {
 #if 0 /* TODO: stipple */
@@ -3741,10 +3757,10 @@ w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
     gc.foreground = f->output_data.w32->black_relief.gc->foreground;
   else
     gc.foreground = f->output_data.w32->white_relief.gc->foreground;
-  
+
   /* Bottom.  */
   for (i = 0; i < width; ++i)
-    w32_fill_area (f, hdc, gc.foreground, 
+    w32_fill_area (f, hdc, gc.foreground,
                   left_x + i * left_p, bottom_y - i,
                   right_x - left_x - i * (left_p + right_p) + 1, 1);
 
@@ -3756,7 +3772,7 @@ w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
                     bottom_y - top_y - 2 * i - 1);
 
   w32_set_clip_rectangle (hdc, NULL);
-  
+
   release_frame_dc (f, hdc);
 }
 
@@ -3776,7 +3792,7 @@ w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
      RECT *clip_rect;
 {
   w32_set_clip_rectangle (s->hdc, clip_rect);
-  
+
   /* Top.  */
   w32_fill_area (s->f, s->hdc, s->face->box_color,
                  left_x, top_y, right_x - left_x + 1, width);
@@ -3787,11 +3803,11 @@ w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
       w32_fill_area (s->f, s->hdc, s->face->box_color,
                      left_x, top_y, width, bottom_y - top_y + 1);
     }
-  
+
   /* Bottom.  */
   w32_fill_area (s->f, s->hdc, s->face->box_color,
                  left_x, bottom_y - width + 1, right_x - left_x + 1, width);
-  
+
   /* Right.  */
   if (right_p)
     {
@@ -3822,7 +3838,7 @@ x_draw_glyph_string_box (s)
       if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f))
        last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f);
     }
-  
+
   /* The glyph that may have a right box line.  */
   last_glyph = (s->cmp || s->img
                ? s->first_glyph
@@ -3845,7 +3861,7 @@ x_draw_glyph_string_box (s)
             || (s->hl == DRAW_MOUSE_FACE
                 && (s->next == NULL
                     || s->next->hl != s->hl)));
-  
+
   w32_get_glyph_string_clip_rect (s, &clip_rect);
 
   if (s->face->box == FACE_SIMPLE_BOX)
@@ -3886,58 +3902,39 @@ x_draw_image_foreground (s)
 
   if (s->img->pixmap)
     {
-#if 0 /* TODO: image mask */
+      HDC compat_hdc = CreateCompatibleDC (s->hdc);
+      HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
+      HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
+      HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
+      SetBkColor (compat_hdc, RGB (255, 255, 255));
+      SetTextColor (s->hdc, RGB (0, 0, 0));
+      x_set_glyph_string_clipping (s);
+
       if (s->img->mask)
        {
-         /* We can't set both a clip mask and use XSetClipRectangles
-            because the latter also sets a clip mask.  We also can't
-            trust on the shape extension to be available
-            (XShapeCombineRegion).  So, compute the rectangle to draw
-            manually.  */
-         unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
-                               | GCFunction);
-         XGCValues xgcv;
-         XRectangle clip_rect, image_rect, r;
-
-         xgcv.clip_mask = s->img->mask;
-         xgcv.clip_x_origin = x;
-         xgcv.clip_y_origin = y;
-         xgcv.function = GXcopy;
-         XChangeGC (s->display, s->gc, mask, &xgcv);
-         
-         w32_get_glyph_string_clip_rect (s, &clip_rect);
-         image_rect.x = x;
-         image_rect.y = y;
-         image_rect.width = s->img->width;
-         image_rect.height = s->img->height;
-         if (IntersectRect (&r, &clip_rect, &image_rect))
-           XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
-                      r.x - x, r.y - y, r.width, r.height, r.x, r.y);
+         HDC mask_dc = CreateCompatibleDC (s->hdc);
+         HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
+
+         SetTextColor (s->hdc, RGB (255, 255, 255));
+         SetBkColor (s->hdc, RGB (0, 0, 0));
+
+         BitBlt (s->hdc, x, y, s->img->width, s->img->height,
+                 compat_hdc, 0, 0, SRCINVERT);
+         BitBlt (s->hdc, x, y, s->img->width, s->img->height,
+                 mask_dc, 0, 0, SRCAND);
+         BitBlt (s->hdc, x, y, s->img->width, s->img->height,
+                 compat_hdc, 0, 0, SRCINVERT);
+
+         SelectObject (mask_dc, mask_orig_obj);
+         DeleteDC (mask_dc);
        }
       else
-#endif
        {
-          HDC compat_hdc = CreateCompatibleDC (s->hdc);
-          HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
-          HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
-          HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
-          x_set_glyph_string_clipping (s);
-
-          SetTextColor (s->hdc, s->gc->foreground);
-          SetBkColor (s->hdc, s->gc->background);
-#if 0 /* From w32bdf.c (which is from Meadow).  */
+         SetTextColor (s->hdc, s->gc->foreground);
+         SetBkColor (s->hdc, s->gc->background);
+
           BitBlt (s->hdc, x, y, s->img->width, s->img->height,
                   compat_hdc, 0, 0, SRCCOPY);
-          BitBlt (s->hdc, x, y, s->img->width, s->img->height,
-                  compat_hdc, 0, 0, 0xB8074A);
-#else
-          BitBlt (s->hdc, x, y, s->img->width, s->img->height,
-                  compat_hdc, 0, 0, 0xE20746);
-#endif
-          SelectObject (s->hdc, orig_brush);
-          DeleteObject (fg_brush);
-         SelectObject (compat_hdc, orig_obj);
-          DeleteDC (compat_hdc);
 
          /* When the image has a mask, we can expect that at
             least part of a mouse highlight or a block cursor will
@@ -3952,8 +3949,13 @@ x_draw_image_foreground (s)
              w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
                                  s->img->width + r*2 - 1, s->img->height + r*2 - 1);
            }
-          w32_set_clip_rectangle (s->hdc, NULL);
        }
+
+      w32_set_clip_rectangle (s->hdc, NULL);
+      SelectObject (s->hdc, orig_brush);
+      DeleteObject (fg_brush);
+      SelectObject (compat_hdc, orig_obj);
+      DeleteDC (compat_hdc);
     }
   else
     w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width -1,
@@ -3974,7 +3976,7 @@ x_draw_image_relief (s)
   RECT r;
   int x;
   int y = s->ybase - image_ascent (s->img, s->face);
+
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
   if (s->face->box != FACE_NO_BOX
@@ -3982,12 +3984,12 @@ x_draw_image_relief (s)
     x = s->x + abs (s->face->box_line_width);
   else
     x = s->x;
-  
+
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
   x += s->img->hmargin;
   y += s->img->vmargin;
-  
+
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
     {
@@ -3999,12 +4001,12 @@ x_draw_image_relief (s)
       thick = abs (s->img->relief);
       raised_p = s->img->relief > 0;
     }
-  
+
   x0 = x - thick;
   y0 = y - thick;
   x1 = x + s->img->width + thick - 1;
   y1 = y + s->img->height + thick - 1;
-  
+
   x_setup_relief_colors (s);
   w32_get_glyph_string_clip_rect (s, &r);
   w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
@@ -4038,51 +4040,35 @@ w32_draw_image_foreground_1 (s, pixmap)
 
   if (s->img->pixmap)
     {
-#if 0 /* TODO: image mask */
+      HDC compat_hdc = CreateCompatibleDC (hdc);
+      HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
+      HBRUSH orig_brush = SelectObject (hdc, fg_brush);
+      HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
+
       if (s->img->mask)
        {
-         /* We can't set both a clip mask and use XSetClipRectangles
-            because the latter also sets a clip mask.  We also can't
-            trust on the shape extension to be available
-            (XShapeCombineRegion).  So, compute the rectangle to draw
-            manually.  */
-         unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
-                               | GCFunction);
-         XGCValues xgcv;
-
-         xgcv.clip_mask = s->img->mask;
-         xgcv.clip_x_origin = x;
-         xgcv.clip_y_origin = y;
-         xgcv.function = GXcopy;
-         XChangeGC (s->display, s->gc, mask, &xgcv);
-
-         XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
-                    0, 0, s->img->width, s->img->height, x, y);
-         XSetClipMask (s->display, s->gc, None);
+         HDC mask_dc = CreateCompatibleDC (hdc);
+         HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
+
+         SetTextColor (hdc, RGB (0, 0, 0));
+         SetBkColor (hdc, RGB (255, 255, 255));
+         BitBlt (hdc, x, y, s->img->width, s->img->height,
+                 compat_hdc, 0, 0, SRCINVERT);
+         BitBlt (hdc, x, y, s->img->width, s->img->height,
+                 mask_dc, 0, 0, SRCAND);
+         BitBlt (hdc, x, y, s->img->width, s->img->height,
+                 compat_hdc, 0, 0, SRCINVERT);
+
+         SelectObject (mask_dc, mask_orig_obj);
+         DeleteDC (mask_dc);
        }
       else
-#endif
        {
-          HDC compat_hdc = CreateCompatibleDC (hdc);
-          HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
-          HBRUSH orig_brush = SelectObject (hdc, fg_brush);
-          HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
-
-          SetTextColor (hdc, s->gc->foreground);
-          SetBkColor (hdc, s->gc->background);
-#if 0 /* From w32bdf.c (which is from Meadow).  */
+         SetTextColor (hdc, s->gc->foreground);
+         SetBkColor (hdc, s->gc->background);
+
           BitBlt (hdc, x, y, s->img->width, s->img->height,
                   compat_hdc, 0, 0, SRCCOPY);
-          BitBlt (hdc, x, y, s->img->width, s->img->height,
-                  compat_hdc, 0, 0, 0xB8074A);
-#else
-          BitBlt (hdc, x, y, s->img->width, s->img->height,
-                  compat_hdc, 0, 0, 0xE20746);
-#endif
-          SelectObject (hdc, orig_brush);
-          DeleteObject (fg_brush);
-         SelectObject (compat_hdc, orig_obj);
-          DeleteDC (compat_hdc);
 
          /* When the image has a mask, we can expect that at
             least part of a mouse highlight or a block cursor will
@@ -4094,10 +4080,15 @@ w32_draw_image_foreground_1 (s, pixmap)
            {
              int r = s->img->relief;
              if (r < 0) r = -r;
-             w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
+             w32_draw_rectangle (hdc, s->gc, x - r, y - r ,
                                  s->img->width + r*2 - 1, s->img->height + r*2 - 1);
            }
        }
+
+      SelectObject (hdc, orig_brush);
+      DeleteObject (fg_brush);
+      SelectObject (compat_hdc, orig_obj);
+      DeleteDC (compat_hdc);
     }
   else
     w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
@@ -4130,7 +4121,7 @@ x_draw_glyph_string_bg_rect (s, x, y, w, h)
 }
 
 
-/* Draw image glyph string S.  
+/* Draw image glyph string S.
 
             s->y
    s->x      +-------------------------
@@ -4163,9 +4154,7 @@ x_draw_image_glyph_string (s)
   if (height > s->img->height
       || s->img->hmargin
       || s->img->vmargin
-#if 0 /* TODO: image mask */
       || s->img->mask
-#endif
       || s->img->pixmap == 0
       || s->width != s->background_width)
     {
@@ -4173,9 +4162,9 @@ x_draw_image_glyph_string (s)
        x = s->x + box_line_hwidth;
       else
        x = s->x;
-      
+
       y = s->y + box_line_vwidth;
-#if 0 /* TODO: image mask */
+#if 0 /* TODO: figure out if we need to do this on Windows.  */
       if (s->img->mask)
        {
          /* Create a pixmap as large as the glyph string.  Fill it
@@ -4188,7 +4177,7 @@ x_draw_image_glyph_string (s)
          pixmap = XCreatePixmap (s->display, s->window,
                                  s->background_width,
                                  s->height, depth);
-         
+
          /* Don't clip in the following because we're working on the
             pixmap.  */
          XSetClipMask (s->display, s->gc, None);
@@ -4216,7 +4205,7 @@ x_draw_image_glyph_string (s)
       else
 #endif
        x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
-      
+
       s->background_filled_p = 1;
     }
 
@@ -4233,15 +4222,9 @@ x_draw_image_glyph_string (s)
 
         SetTextColor (s->hdc, s->gc->foreground);
         SetBkColor (s->hdc, s->gc->background);
-#if 0 /* From w32bdf.c (which is from Meadow).  */
         BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
                 compat_hdc, 0, 0, SRCCOPY);
-        BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
-                compat_hdc, 0, 0, 0xB8074A);
-#else
-        BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
-                compat_hdc, 0, 0, 0xE20746);
-#endif
+
         SelectObject (s->hdc, orig_brush);
         DeleteObject (fg_brush);
         SelectObject (compat_hdc, orig_obj);
@@ -4297,7 +4280,7 @@ x_draw_stretch_glyph_string (s)
            }
          else
            gc = s->face->gc;
-  
+
          w32_get_glyph_string_clip_rect (s, &r);
          w32_set_clip_rectangle (hdc, &r);
 
@@ -4319,7 +4302,7 @@ x_draw_stretch_glyph_string (s)
   else if (!s->background_filled_p)
     x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
                                 s->height);
-  
+
   s->background_filled_p = 1;
 }
 
@@ -4467,7 +4450,7 @@ static int x_fill_composite_glyph_string P_ ((struct glyph_string *,
 
 
 /* Fill glyph string S with composition components specified by S->cmp.
-   
+
    FACES is an array of faces for all components of this composition.
    S->gidx is the index of the first component for S.
    OVERLAPS_P non-zero means S should draw the foreground only, and
@@ -4515,7 +4498,7 @@ x_fill_composite_glyph_string (s, faces, overlaps_p)
 
   /* Adjust base line for subscript/superscript text.  */
   s->ybase += s->first_glyph->voffset;
-  
+
   xassert (s->face && s->face->gc);
 
   /* This glyph string must always be drawn with 16-bit functions.  */
@@ -4526,7 +4509,7 @@ x_fill_composite_glyph_string (s, faces, overlaps_p)
 
 
 /* Fill glyph string S from a sequence of character glyphs.
-   
+
    FACE_ID is the face id of the string.  START is the index of the
    first glyph to consider, END is the index of the last + 1.
    OVERLAPS_P non-zero means S should draw the foreground only, and
@@ -4576,7 +4559,7 @@ x_fill_glyph_string (s, face_id, start, end, overlaps_p)
 
   s->font = s->face->font;
   s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
-  
+
   /* If the specified font could not be loaded, use the frame's font,
      but record the fact that we couldn't load it in
      S->font_not_found_p so that we can draw rectangles for the
@@ -4589,7 +4572,7 @@ x_fill_glyph_string (s, face_id, start, end, overlaps_p)
 
   /* Adjust base line for subscript/superscript text.  */
   s->ybase += voffset;
-  
+
   xassert (s->face && s->face->gc);
   return glyph - s->row->glyphs[s->area];
 }
@@ -4607,7 +4590,7 @@ x_fill_image_glyph_string (s)
   s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
   s->font = s->face->font;
   s->width = s->first_glyph->pixel_width;
-  
+
   /* Adjust base line for subscript/superscript text.  */
   s->ybase += s->first_glyph->voffset;
 }
@@ -4630,9 +4613,9 @@ x_fill_stretch_glyph_string (s, row, area, start, end)
 {
   struct glyph *glyph, *last;
   int voffset, face_id;
-  
+
   xassert (s->first_glyph->type == STRETCH_GLYPH);
-  
+
   glyph = s->row->glyphs[s->area] + start;
   last = s->row->glyphs[s->area] + end;
   face_id = glyph->face_id;
@@ -4649,7 +4632,7 @@ x_fill_stretch_glyph_string (s, row, area, start, end)
        && glyph->face_id == face_id);
        ++glyph)
     s->width += glyph->pixel_width;
-  
+
   /* Adjust base line for subscript/superscript text.  */
   s->ybase += voffset;
 
@@ -4665,7 +4648,7 @@ x_fill_stretch_glyph_string (s, row, area, start, end)
    and area within the row from which S is constructed.  START is the
    index of the first glyph structure covered by S.  HL is a
    face-override for drawing S.  */
-   
+
 static void
 w32_init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
      struct glyph_string *s;
@@ -4693,7 +4676,7 @@ w32_init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
   /* Display the internal border below the tool-bar window.  */
   if (s->w == XWINDOW (s->f->tool_bar_window))
     s->y -= s->f->output_data.w32->internal_border_width;
-  
+
   s->ybase = s->y + row->ascent;
 }
 
@@ -4711,7 +4694,7 @@ x_set_glyph_string_background_width (s, start, last_x)
   /* If the face of this glyph string has to be drawn to the end of
      the drawing area, set S->extends_to_end_of_line_p.  */
   struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
-  
+
   if (start == s->row->used[s->area]
       && s->area == TEXT_AREA
       && ((s->hl == DRAW_NORMAL_TEXT
@@ -4723,7 +4706,7 @@ x_set_glyph_string_background_width (s, start, last_x)
          || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
              && s->row->fill_line_p)))
     s->extends_to_end_of_line_p = 1;
-  
+
   /* If S extends its face to the end of the line, set its
      background_width to the distance to the right edge of the drawing
      area.  */
@@ -4802,7 +4785,7 @@ x_set_glyph_string_background_width (s, start, last_x)
                                           OVERLAPS_P);                    \
        }                                                                  \
      while (0)
-     
+
 
 /* Add a glyph string for a composite sequence to the list of strings
    between HEAD and TAIL.  START is the index of the first glyph in
@@ -4927,7 +4910,7 @@ x_set_glyph_string_background_width (s, start, last_x)
    and clip to the physical height of ROW.
 
    Value is the x-position reached, relative to AREA of W.  */
-     
+
 static int
 x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
      struct window *w;
@@ -5009,7 +4992,7 @@ x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
       /* Prepend glyph strings for glyphs in front of the first glyph
         string that are overwritten because of the first glyph
         string's left overhang.  The background of all strings
-        prepended must be drawn because the first glyph string 
+        prepended must be drawn because the first glyph string
         draws over it.  */
       i = x_left_overwritten (head);
       if (i >= 0)
@@ -5087,10 +5070,10 @@ x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
     {
       int x0 = head ? head->x : x;
       int x1 = tail ? tail->x + tail->background_width : x;
-      
+
       x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
       x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
-      
+
       if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0)
        {
          int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
@@ -5128,9 +5111,9 @@ x_fix_overlapping_area (w, row, area)
      enum glyph_row_area area;
 {
   int i, x;
-  
+
   BLOCK_INPUT;
-  
+
   if (area == LEFT_MARGIN_AREA)
     x = 0;
   else if (area == TEXT_AREA)
@@ -5162,7 +5145,7 @@ x_fix_overlapping_area (w, row, area)
          ++i;
        }
     }
-  
+
   UNBLOCK_INPUT;
 }
 
@@ -5182,7 +5165,7 @@ x_write_glyphs (start, len)
 
   xassert (updated_window && updated_row);
   BLOCK_INPUT;
-  
+
   /* Write glyphs.  */
 
   hpos = start - updated_row->glyphs[updated_area];
@@ -5192,7 +5175,7 @@ x_write_glyphs (start, len)
                     DRAW_NORMAL_TEXT, 0);
 
   UNBLOCK_INPUT;
-  
+
   /* Advance the output cursor.  */
   output_cursor.hpos += len;
   output_cursor.x = x;
@@ -5291,10 +5274,10 @@ x_clear_end_of_line (to_x)
   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);
@@ -5316,7 +5299,7 @@ x_clear_end_of_line (to_x)
     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,
@@ -5337,11 +5320,11 @@ x_clear_end_of_line (to_x)
       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)
     {
@@ -5408,7 +5391,7 @@ w32_ring_bell (void)
       int i;
       HWND hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ());
 
-      for (i = 0; i < 5; i++) 
+      for (i = 0; i < 5; i++)
        {
          FlashWindow (hwnd, TRUE);
          Sleep (10);
@@ -5506,7 +5489,7 @@ x_scroll_run (w, run)
     }
 
   BLOCK_INPUT;
-  
+
   /* Cursor off.  Will be switched on again in x_update_window_end.  */
   updated_window = w;
   x_clear_cursor (w);
@@ -5544,7 +5527,7 @@ 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
@@ -5695,7 +5678,7 @@ expose_area (w, row, r, area)
           x += first->pixel_width;
           ++first;
         }
-  
+
       /* Find the last one.  */
       last = first;
       first_x = x;
@@ -5727,7 +5710,7 @@ expose_line (w, row, r)
      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);
@@ -5770,6 +5753,39 @@ x_phys_cursor_in_rect_p (w, r)
 }
 
 
+/* 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
@@ -5811,6 +5827,7 @@ expose_window (w, fr)
       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));
@@ -5831,7 +5848,8 @@ expose_window (w, fr)
       else
        cursor_cleared_p = 0;
 
-      /* Find the first row intersecting the rectangle R.  */
+      /* Update lines intersecting rectangle R.  */
+      first_overlapping_row = last_overlapping_row = NULL;
       for (row = w->current_matrix->rows;
           row->enabled_p;
           ++row)
@@ -5844,6 +5862,13 @@ expose_window (w, fr)
              || (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;
            }
@@ -5864,6 +5889,10 @@ expose_window (w, fr)
 
       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);
 
@@ -5952,29 +5981,29 @@ static void
 x_frame_rehighlight (dpyinfo)
      struct w32_display_info *dpyinfo;
 {
-  struct frame *old_highlight = dpyinfo->w32_highlight_frame;
+  struct frame *old_highlight = dpyinfo->x_highlight_frame;
 
   if (dpyinfo->w32_focus_frame)
     {
-      dpyinfo->w32_highlight_frame
+      dpyinfo->x_highlight_frame
        = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
           ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
           : dpyinfo->w32_focus_frame);
-      if (! FRAME_LIVE_P (dpyinfo->w32_highlight_frame))
+      if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
        {
          FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
-         dpyinfo->w32_highlight_frame = dpyinfo->w32_focus_frame;
+         dpyinfo->x_highlight_frame = dpyinfo->w32_focus_frame;
        }
     }
   else
-    dpyinfo->w32_highlight_frame = 0;
+    dpyinfo->x_highlight_frame = 0;
 
-  if (dpyinfo->w32_highlight_frame != old_highlight)
+  if (dpyinfo->x_highlight_frame != old_highlight)
     {
       if (old_highlight)
        frame_unhighlight (old_highlight);
-      if (dpyinfo->w32_highlight_frame)
-       frame_highlight (dpyinfo->w32_highlight_frame);
+      if (dpyinfo->x_highlight_frame)
+       frame_highlight (dpyinfo->x_highlight_frame);
     }
 }
 \f
@@ -6103,7 +6132,7 @@ glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
 /* Parse a button MESSAGE. The button index is returned in PBUTTON, and
    the state in PUP. XBUTTON provides extra information for extended mouse
    button messages. Returns FALSE if unable to parse the message.  */
-BOOL 
+BOOL
 parse_button (message, xbutton, pbutton, pup)
      int message;
      int xbutton;
@@ -6112,7 +6141,7 @@ parse_button (message, xbutton, pbutton, pup)
 {
   int button = 0;
   int up = 0;
-  
+
   switch (message)
     {
     case WM_LBUTTONDOWN:
@@ -6162,10 +6191,10 @@ parse_button (message, xbutton, pbutton, pup)
     default:
       return (FALSE);
     }
-  
+
   if (pup) *pup = up;
   if (pbutton) *pbutton = button;
-  
+
   return (TRUE);
 }
 
@@ -6187,9 +6216,9 @@ construct_mouse_click (result, msg, f)
   parse_button (msg->msg.message, HIWORD (msg->msg.wParam),
                &button, &up);
 
-  /* Make the event type no_event; we'll change that when we decide
+  /* Make the event type NO_EVENT; we'll change that when we decide
      otherwise.  */
-  result->kind = mouse_click;
+  result->kind = MOUSE_CLICK_EVENT;
   result->code = button;
   result->timestamp = msg->msg.time;
   result->modifiers = (msg->dwModifiers
@@ -6211,7 +6240,7 @@ construct_mouse_wheel (result, msg, f)
      struct frame *f;
 {
   POINT p;
-  result->kind = mouse_wheel;
+  result->kind = MOUSE_WHEEL_EVENT;
   result->code = (short) HIWORD (msg->msg.wParam);
   result->timestamp = msg->msg.time;
   result->modifiers = msg->dwModifiers;
@@ -6239,7 +6268,7 @@ construct_drag_n_drop (result, msg, f)
   char *name;
   int i, len;
 
-  result->kind = drag_n_drop;
+  result->kind = DRAG_N_DROP_EVENT;
   result->code = 0;
   result->timestamp = msg->msg.time;
   result->modifiers = msg->dwModifiers;
@@ -6428,7 +6457,7 @@ x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
          else if (!buffer_only_p || BUFFERP (glyph->object))
            break;
        }
-      
+
       x0 += glyph->pixel_width;
       ++glyph;
     }
@@ -6491,13 +6520,13 @@ note_mode_line_highlight (w, x, mode_line_p)
       struct glyph *glyph, *end;
       Lisp_Object help, map;
       int x0;
-      
+
       /* Find the glyph under X.  */
       glyph = row->glyphs[TEXT_AREA];
       end = glyph + row->used[TEXT_AREA];
       x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)
              + FRAME_X_LEFT_FRINGE_WIDTH (f));
-      
+
       while (glyph < end
             && x >= x0 + glyph->pixel_width)
        {
@@ -6507,9 +6536,9 @@ note_mode_line_highlight (w, x, mode_line_p)
 
       if (glyph < end
          && STRINGP (glyph->object)
-         && XSTRING (glyph->object)->intervals
+         && STRING_INTERVALS (glyph->object)
          && glyph->charpos >= 0
-         && glyph->charpos < XSTRING (glyph->object)->size)
+         && glyph->charpos < SCHARS (glyph->object))
        {
          /* If we're on a string with `help-echo' text property,
             arrange for the help to be displayed.  This is done by
@@ -6538,7 +6567,6 @@ note_mode_line_highlight (w, x, mode_line_p)
            }
        }
     }
-
 #if 0 /* TODO: mouse cursor */
   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
 #endif
@@ -6767,7 +6795,8 @@ note_mouse_highlight (f, x, y)
 
              dpyinfo->mouse_face_face_id
                = face_at_buffer_position (w, pos, 0, 0,
-                                          &ignore, pos + 1, 1);
+                                          &ignore, pos + 1,
+                                          !dpyinfo->mouse_face_hidden);
 
              /* Display it as active.  */
              show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
@@ -6809,7 +6838,8 @@ note_mouse_highlight (f, x, y)
              if (BUFFERP (object))
                dpyinfo->mouse_face_face_id
                  = face_at_buffer_position (w, pos, 0, 0,
-                                            &ignore, pos + 1, 1);
+                                            &ignore, pos + 1,
+                                            !dpyinfo->mouse_face_hidden);
 
              /* Display it as active.  */
              show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
@@ -6828,7 +6858,7 @@ note_mouse_highlight (f, x, y)
              if (NILP (b))
                b = make_number (0);
              if (NILP (e))
-               e = make_number (XSTRING (object)->size - 1);
+               e = make_number (SCHARS (object) - 1);
              fast_find_string_pos (w, XINT (b), object,
                                    &dpyinfo->mouse_face_beg_col,
                                    &dpyinfo->mouse_face_beg_row,
@@ -6853,7 +6883,7 @@ note_mouse_highlight (f, x, y)
                 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),
@@ -6877,7 +6907,7 @@ note_mouse_highlight (f, x, y)
                                      &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,
@@ -6888,7 +6918,8 @@ note_mouse_highlight (f, x, y)
                  dpyinfo->mouse_face_window = window;
                  dpyinfo->mouse_face_face_id
                    = face_at_buffer_position (w, pos, 0, 0,
-                                              &ignore, pos + 1, 1);
+                                              &ignore, pos + 1,
+                                              !dpyinfo->mouse_face_hidden);
 
                  /* Display it as active.  */
                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
@@ -6908,7 +6939,7 @@ note_mouse_highlight (f, x, y)
        for (i = noverlays - 1; i >= 0 && NILP (help); --i)
          {
            overlay = overlay_vec[i];
-           help = Foverlay_get (overlay, Qhelp_echo); 
+           help = Foverlay_get (overlay, Qhelp_echo);
          }
 
        if (!NILP (help))
@@ -6926,7 +6957,7 @@ note_mouse_highlight (f, x, y)
            /* Try text properties.  */
            if (STRINGP (object)
                && charpos >= 0
-               && charpos < XSTRING (object)->size)
+               && charpos < SCHARS (object))
              {
                help = Fget_text_property (make_number (charpos),
                                           Qhelp_echo, object);
@@ -6955,7 +6986,7 @@ note_mouse_highlight (f, x, y)
                     && charpos < ZV)
              help = Fget_text_property (make_number (charpos), Qhelp_echo,
                                         object);
-           
+
            if (!NILP (help))
              {
                help_echo = help;
@@ -7042,7 +7073,7 @@ x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
          || *hpos < dpyinfo->mouse_face_end_col
          || dpyinfo->mouse_face_past_end))
     return 0;
-  
+
   return 1;
 }
 
@@ -7063,7 +7094,7 @@ w32_handle_tool_bar_click (f, button_event)
   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)
@@ -7073,7 +7104,7 @@ w32_handle_tool_bar_click (f, button_event)
   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.  */
@@ -7150,7 +7181,7 @@ note_tool_bar_highlight (f, x, y)
     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
@@ -7161,7 +7192,7 @@ note_tool_bar_highlight (f, x, y)
 
   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))
@@ -7171,28 +7202,28 @@ note_tool_bar_highlight (f, x, y)
       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;
@@ -7214,7 +7245,7 @@ note_tool_bar_highlight (f, x, y)
 #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 
+        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
@@ -7247,10 +7278,10 @@ fast_find_position (w, charpos, hpos, vpos, x, y, stop)
   *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.  */
@@ -7452,7 +7483,7 @@ fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
          *x += best_glyph->pixel_width;
          ++*hpos;
        }
-      
+
       *y = best_row->y;
       *vpos = best_row - w->current_matrix->rows;
     }
@@ -7471,7 +7502,7 @@ show_mouse_face (dpyinfo, 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
@@ -7486,7 +7517,7 @@ show_mouse_face (dpyinfo, draw)
 
       first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
       last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
-      
+
       for (row = first; row <= last && row->enabled_p; ++row)
        {
          int start_hpos, end_hpos, start_x;
@@ -7510,7 +7541,7 @@ show_mouse_face (dpyinfo, draw)
 
          if (end_hpos > start_hpos)
            {
-             x_draw_glyphs (w, start_x, row, TEXT_AREA, 
+             x_draw_glyphs (w, start_x, row, TEXT_AREA,
                             start_hpos, end_hpos, draw, 0);
 
              row->mouse_face_p
@@ -7752,7 +7783,7 @@ w32_mouse_position (fp, insist, bar_window, part, x, y, time)
        XFRAME (frame)->mouse_moved = 0;
 
       last_mouse_scroll_bar = Qnil;
-      
+
       GetCursorPos (&pt);
 
       /* Now we have a position on the root; find the innermost window
@@ -7929,14 +7960,14 @@ w32_set_scroll_bar_thumb (bar, portion, position, whole)
 /************************************************************************
                         Scroll bars, general
  ************************************************************************/
-                                                                        
-HWND 
+
+HWND
 my_create_scrollbar (f, bar)
      struct frame * f;
      struct scroll_bar * bar;
 {
   return (HWND) SendMessage (FRAME_W32_WINDOW (f),
-                            WM_EMACS_CREATESCROLLBAR, (WPARAM) f, 
+                            WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
                             (LPARAM) bar);
 }
 
@@ -7976,7 +8007,7 @@ my_set_focus (f, hwnd)
      struct frame * f;
      HWND hwnd;
 {
-  SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS, 
+  SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
               (WPARAM) hwnd, 0);
 }
 
@@ -7992,7 +8023,7 @@ my_destroy_window (f, hwnd)
      struct frame * f;
      HWND hwnd;
 {
-  SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW, 
+  SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
               (WPARAM) hwnd, 0);
 }
 
@@ -8119,7 +8150,7 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
 
   /* Compute the left edge of the scroll bar.  */
   if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
-    sb_left = left + width - sb_width - (width - sb_width) / 2; 
+    sb_left = left + width - sb_width - (width - sb_width) / 2;
   else
     sb_left = left + (width - sb_width) / 2;
 
@@ -8140,7 +8171,7 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
     }
   else
     {
-      /* It may just need to be moved and resized.  */      
+      /* It may just need to be moved and resized.  */
       HWND hwnd;
 
       bar = XSCROLL_BAR (w->vertical_scroll_bar);
@@ -8318,7 +8349,7 @@ w32_judge_scroll_bars (f)
 }
 
 /* Handle a mouse click on the scroll bar BAR.  If *EMACS_EVENT's kind
-   is set to something other than no_event, it is enqueued.
+   is set to something other than NO_EVENT, it is enqueued.
 
    This may be called from a signal handler, so we have to ignore GC
    mark bits.  */
@@ -8332,7 +8363,7 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
   if (! GC_WINDOWP (bar->window))
     abort ();
 
-  emacs_event->kind = w32_scroll_bar_click;
+  emacs_event->kind = W32_SCROLL_BAR_CLICK_EVENT;
   emacs_event->code = 0;
   /* not really meaningful to distinguish up/down */
   emacs_event->modifiers = msg->dwModifiers;
@@ -8362,7 +8393,7 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
 
 
     last_mouse_scroll_bar_pos = msg->msg.wParam;
+
     switch (LOWORD (msg->msg.wParam))
       {
       case SB_LINEDOWN:
@@ -8432,7 +8463,7 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
          }
        /* fall through */
       default:
-       emacs_event->kind = no_event;
+       emacs_event->kind = NO_EVENT;
        return FALSE;
       }
 
@@ -8562,14 +8593,14 @@ static short temp_buffer[100];
    We return the number of characters stored into the buffer,
    thus pretending to be `read'.
 
-   EXPECTED is nonzero if the caller knows input is available.  
+   EXPECTED is nonzero if the caller knows input is available.
 
    Some of these messages are reposted back to the message queue since the
-   system calls the windows proc directly in a context where we cannot return 
+   system calls the windows proc directly in a context where we cannot return
    the data nor can we guarantee the state we are in.  So if we dispatch  them
    we will get into an infinite loop.  To prevent this from ever happening we
    will set a variable to indicate we are in the read_socket call and indicate
-   which message we are processing since the windows proc gets called 
+   which message we are processing since the windows proc gets called
    recursively with different messages by the system.
 */
 
@@ -8610,7 +8641,7 @@ w32_read_socket (sd, bufp, numchars, expected)
        case WM_PAINT:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
 
-         if (f) 
+         if (f)
            {
              if (msg.rect.right == msg.rect.left ||
                  msg.rect.bottom == msg.rect.top)
@@ -8618,7 +8649,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                  /* We may get paint messages even though the client
                     area is clipped - these are not expose events. */
                  DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
-                            XSTRING (f->name)->data));
+                            SDATA (f->name)));
                }
              else if (f->async_visible != 1)
                {
@@ -8627,13 +8658,13 @@ w32_read_socket (sd, bufp, numchars, expected)
                  f->async_iconified = 0;
                  SET_FRAME_GARBAGED (f);
                  DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
-                            XSTRING (f->name)->data));
+                            SDATA (f->name)));
 
                  /* WM_PAINT serves as MapNotify as well, so report
                     visibility changes properly.  */
                  if (f->iconified)
                    {
-                     bufp->kind = deiconify_event;
+                     bufp->kind = DEICONIFY_EVENT;
                      XSETFRAME (bufp->frame_or_window, f);
                      bufp->arg = Qnil;
                      bufp++;
@@ -8670,8 +8701,8 @@ w32_read_socket (sd, bufp, numchars, expected)
            {
              if (numchars == 0)
                abort ();
-         
-             bufp->kind = language_change_event;
+
+             bufp->kind = LANGUAGE_CHANGE_EVENT;
              XSETFRAME (bufp->frame_or_window, f);
              bufp->arg = Qnil;
              bufp->code = msg.msg.wParam;
@@ -8685,7 +8716,7 @@ w32_read_socket (sd, bufp, numchars, expected)
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
-         
+
          if (f && !f->iconified)
            {
              if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
@@ -8697,7 +8728,7 @@ w32_read_socket (sd, bufp, numchars, expected)
              if (temp_index == sizeof temp_buffer / sizeof (short))
                temp_index = 0;
              temp_buffer[temp_index++] = msg.msg.wParam;
-             bufp->kind = non_ascii_keystroke;
+             bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
              bufp->code = msg.msg.wParam;
              bufp->modifiers = msg.dwModifiers;
              XSETFRAME (bufp->frame_or_window, f);
@@ -8712,7 +8743,7 @@ w32_read_socket (sd, bufp, numchars, expected)
        case WM_SYSCHAR:
        case WM_CHAR:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
-         
+
          if (f && !f->iconified)
            {
              if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
@@ -8724,7 +8755,7 @@ w32_read_socket (sd, bufp, numchars, expected)
              if (temp_index == sizeof temp_buffer / sizeof (short))
                temp_index = 0;
              temp_buffer[temp_index++] = msg.msg.wParam;
-             bufp->kind = ascii_keystroke;
+             bufp->kind = ASCII_KEYSTROKE_EVENT;
              bufp->code = msg.msg.wParam;
              bufp->modifiers = msg.dwModifiers;
              XSETFRAME (bufp->frame_or_window, f);
@@ -8737,16 +8768,24 @@ w32_read_socket (sd, bufp, numchars, expected)
          break;
 
        case WM_MOUSEMOVE:
+         /* Ignore non-movement.  */
+         {
+           int x = LOWORD (msg.msg.lParam);
+           int y = HIWORD (msg.msg.lParam);
+           if (x == last_mousemove_x && y == last_mousemove_y)
+             break;
+           last_mousemove_x = x;
+           last_mousemove_y = y;
+         }
+
           previous_help_echo = help_echo;
-          help_echo_object = help_echo_window = Qnil;
-          help_echo_pos = -1;
 
          if (dpyinfo->grabbed && last_mouse_frame
              && FRAME_LIVE_P (last_mouse_frame))
            f = last_mouse_frame;
          else
            f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
-         
+
          if (dpyinfo->mouse_face_hidden)
            {
              dpyinfo->mouse_face_hidden = 0;
@@ -8764,11 +8803,18 @@ w32_read_socket (sd, bufp, numchars, expected)
 
           /* If the contents of the global variable help_echo
              has changed, generate a HELP_EVENT.  */
-          if (help_echo != previous_help_echo)
+          if (help_echo != previous_help_echo ||
+             (!NILP (help_echo) && !STRINGP (help_echo) && f->mouse_moved))
             {
               Lisp_Object frame;
               int n;
 
+             if (help_echo == Qnil)
+               {
+                 help_echo_object = help_echo_window = Qnil;
+                 help_echo_pos = -1;
+               }
+
               if (f)
                 XSETFRAME (frame, f);
               else
@@ -8798,18 +8844,18 @@ w32_read_socket (sd, bufp, numchars, expected)
            int button;
            int up;
 
-            emacs_event.kind = no_event;
-           
+            emacs_event.kind = NO_EVENT;
+
            if (dpyinfo->grabbed && last_mouse_frame
                && FRAME_LIVE_P (last_mouse_frame))
              f = last_mouse_frame;
            else
              f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
-           
+
            if (f)
              {
                 construct_mouse_click (&emacs_event, &msg, f);
-                
+
                 /* Is this in the tool-bar?  */
                 if (WINDOWP (f->tool_bar_window)
                     && XFASTINT (XWINDOW (f->tool_bar_window)->height))
@@ -8841,7 +8887,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                       numchars--;
                     }
              }
-           
+
            parse_button (msg.msg.message, HIWORD (msg.msg.wParam),
                          &button, &up);
 
@@ -8865,7 +8911,7 @@ w32_read_socket (sd, bufp, numchars, expected)
              }
            break;
          }
-         
+
       case WM_MOUSEWHEEL:
           if (dpyinfo->grabbed && last_mouse_frame
               && FRAME_LIVE_P (last_mouse_frame))
@@ -8875,7 +8921,7 @@ w32_read_socket (sd, bufp, numchars, expected)
 
           if (f)
             {
-              if ((!dpyinfo->w32_focus_frame 
+              if ((!dpyinfo->w32_focus_frame
                    || f == dpyinfo->w32_focus_frame)
                   && (numchars >= 1))
                 {
@@ -8903,7 +8949,7 @@ w32_read_socket (sd, bufp, numchars, expected)
          {
            struct scroll_bar *bar =
              x_window_to_scroll_bar ((HWND)msg.msg.lParam);
-             
+
            if (bar && numchars >= 1)
              {
                if (w32_scroll_bar_handle_click (bar, &msg, bufp))
@@ -8915,7 +8961,7 @@ w32_read_socket (sd, bufp, numchars, expected)
              }
            break;
          }
-         
+
        case WM_WINDOWPOSCHANGED:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
          if (f)
@@ -8938,7 +8984,7 @@ w32_read_socket (sd, bufp, numchars, expected)
 
        case WM_MOVE:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
-         
+
          if (f && !f->async_iconified)
            {
              int x, y;
@@ -8980,7 +9026,7 @@ w32_read_socket (sd, bufp, numchars, expected)
 
        case WM_SIZE:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
-         
+
          /* Inform lisp of whether frame has been iconified etc. */
          if (f)
            {
@@ -8989,8 +9035,8 @@ w32_read_socket (sd, bufp, numchars, expected)
                case SIZE_MINIMIZED:
                  f->async_visible = 0;
                  f->async_iconified = 1;
-                 
-                 bufp->kind = iconify_event;
+
+                 bufp->kind = ICONIFY_EVENT;
                  XSETFRAME (bufp->frame_or_window, f);
                  bufp->arg = Qnil;
                  bufp++;
@@ -9002,11 +9048,11 @@ w32_read_socket (sd, bufp, numchars, expected)
                case SIZE_RESTORED:
                  f->async_visible = 1;
                  f->async_iconified = 0;
-                 
+
                  /* wait_reading_process_input will notice this and update
                     the frame's display structures.  */
                  SET_FRAME_GARBAGED (f);
-                 
+
                  if (f->iconified)
                    {
                       int x, y;
@@ -9020,7 +9066,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                       f->output_data.w32->left_pos = x;
                       f->output_data.w32->top_pos = y;
 
-                     bufp->kind = deiconify_event;
+                     bufp->kind = DEICONIFY_EVENT;
                      XSETFRAME (bufp->frame_or_window, f);
                      bufp->arg = Qnil;
                      bufp++;
@@ -9044,21 +9090,21 @@ w32_read_socket (sd, bufp, numchars, expected)
              int columns;
              int width;
              int height;
-             
+
              GetClientRect (msg.msg.hwnd, &rect);
-             
+
              height = rect.bottom - rect.top;
              width = rect.right - rect.left;
-             
+
              rows = PIXEL_TO_CHAR_HEIGHT (f, height);
              columns = PIXEL_TO_CHAR_WIDTH (f, width);
-             
+
              /* TODO: Clip size to the screen dimensions.  */
-             
+
              /* Even if the number of character rows and columns has
                 not changed, the font size may have changed, so we need
                 to check the pixel dimensions as well.  */
-             
+
              if (columns != f->width
                  || rows != f->height
                  || width != f->output_data.w32->pixel_width
@@ -9105,12 +9151,12 @@ w32_read_socket (sd, bufp, numchars, expected)
                }
            }
          break;
-             
+
        case WM_SETFOCUS:
          f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
 
           dpyinfo->w32_focus_event_frame = f;
-          
+
           if (f)
             x_new_focus_frame (dpyinfo, f);
 
@@ -9162,13 +9208,13 @@ w32_read_socket (sd, bufp, numchars, expected)
 
        case WM_CLOSE:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
-         
+
          if (f)
            {
              if (numchars == 0)
                abort ();
-             
-             bufp->kind = delete_window_event;
+
+             bufp->kind = DELETE_WINDOW_EVENT;
              XSETFRAME (bufp->frame_or_window, f);
              bufp->arg = Qnil;
              bufp++;
@@ -9179,13 +9225,13 @@ w32_read_socket (sd, bufp, numchars, expected)
 
        case WM_INITMENU:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
-         
+
          if (f)
            {
              if (numchars == 0)
                abort ();
-         
-             bufp->kind = menu_bar_activate_event;
+
+             bufp->kind = MENU_BAR_ACTIVATE_EVENT;
              XSETFRAME (bufp->frame_or_window, f);
              bufp->arg = Qnil;
              bufp++;
@@ -9210,7 +9256,7 @@ w32_read_socket (sd, bufp, numchars, expected)
        case WM_DISPLAYCHANGE:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
 
-         if (f) 
+         if (f)
            {
              dpyinfo->width = (short) LOWORD (msg.msg.lParam);
              dpyinfo->height = (short) HIWORD (msg.msg.lParam);
@@ -9218,7 +9264,7 @@ w32_read_socket (sd, bufp, numchars, expected)
              DebPrint (("display change: %d %d\n", dpyinfo->width,
                         dpyinfo->height));
            }
-         
+
          check_visibility = 1;
          break;
 
@@ -9226,15 +9272,15 @@ w32_read_socket (sd, bufp, numchars, expected)
          /* Check for messages registered at runtime. */
          if (msg.msg.message == msh_mousewheel)
            {
-             if (dpyinfo->grabbed && last_mouse_frame 
+             if (dpyinfo->grabbed && last_mouse_frame
                  && FRAME_LIVE_P (last_mouse_frame))
                f = last_mouse_frame;
              else
                f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
-          
+
              if (f)
                {
-                 if ((!dpyinfo->w32_focus_frame 
+                 if ((!dpyinfo->w32_focus_frame
                       || f == dpyinfo->w32_focus_frame)
                      && (numchars >= 1))
                    {
@@ -9307,7 +9353,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                  if (!FRAME_OBSCURED_P (f))
                    {
                      DebPrint (("frame %p (%s) obscured\n", f,
-                                XSTRING (f->name)->data));
+                                SDATA (f->name)));
                    }
                }
              else
@@ -9319,7 +9365,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                    {
                      SET_FRAME_GARBAGED (f);
                      DebPrint (("obscured frame %p (%s) found to be visible\n", f,
-                                XSTRING (f->name)->data));
+                                SDATA (f->name)));
 
                      /* Force a redisplay sooner or later.  */
                      record_asynch_buffer_change ();
@@ -9455,10 +9501,11 @@ x_draw_hollow_cursor (w, row)
    --gerd.  */
 
 static void
-x_draw_bar_cursor (w, row, width)
+x_draw_bar_cursor (w, row, width, kind)
      struct window *w;
      struct glyph_row *row;
      int width;
+     enum text_cursor_kinds kind;
 {
   struct frame *f = XFRAME (w->frame);
   struct glyph *cursor_glyph;
@@ -9487,7 +9534,8 @@ x_draw_bar_cursor (w, row, width)
       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
 
       if (width < 0)
-        width = f->output_data.w32->cursor_width;
+        width = FRAME_CURSOR_WIDTH (f);
+      width = min (cursor_glyph->pixel_width, width);
 
       /* If the glyph's background equals the color we normally draw
         the bar cursor in, the bar cursor in its normal color is
@@ -9500,10 +9548,20 @@ x_draw_bar_cursor (w, row, width)
       x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
       hdc = get_frame_dc (f);
       w32_clip_to_row (w, row, hdc, 0);
-      w32_fill_area (f, hdc, cursor_color, x,
-                     WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-                     min (cursor_glyph->pixel_width, width),
-                     row->height);
+
+      if (kind == BAR_CURSOR)
+       {
+         w32_fill_area (f, hdc, cursor_color, x,
+                        WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
+                        width, row->height);
+       }
+      else
+       {
+         w32_fill_area (f, hdc, cursor_color, x,
+                        WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
+                                                 row->height - width),
+                        cursor_glyph->pixel_width, width);
+       }
       release_frame_dc (f, hdc);
     }
 }
@@ -9579,7 +9637,7 @@ x_erase_phys_cursor (w)
      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)
@@ -9590,13 +9648,13 @@ x_erase_phys_cursor (w)
   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
@@ -9604,7 +9662,7 @@ x_erase_phys_cursor (w)
      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)
@@ -9642,7 +9700,7 @@ x_erase_phys_cursor (w)
                       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;
@@ -9665,7 +9723,7 @@ cursor_in_mouse_face_p (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)
     {
@@ -9698,11 +9756,10 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
   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;
-  int cursor_non_selected;
-  int active_cursor = 1;
 
   /* This is pointless on invisible frames, and dangerous on garbaged
      windows and frames; in the latter case, the frame or window may
@@ -9721,8 +9778,8 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
   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 
+
+  /* If cursor row is not enabled, we don't really know where to
      display the cursor.  */
   if (!glyph_row->enabled_p)
     {
@@ -9732,65 +9789,8 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
 
   xassert (interrupt_input_blocked);
 
-  /* Set new_cursor_type to the cursor we want to be displayed.  In a
-     mini-buffer window, we want the cursor only to appear if we are
-     reading input from this window.  For the selected window, we want
-     the cursor type given by the frame parameter.  If explicitly
-     marked off, draw no cursor.  In all other cases, we want a hollow
-     box cursor.  */
-  cursor_non_selected 
-    = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
-                                 w->buffer));
-  new_cursor_width = -1;
-  if (cursor_in_echo_area
-      && FRAME_HAS_MINIBUF_P (f)
-      && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
-    {
-      if (w == XWINDOW (echo_area_window))
-       new_cursor_type = FRAME_DESIRED_CURSOR (f);
-      else
-       {
-         if (cursor_non_selected)
-           new_cursor_type = HOLLOW_BOX_CURSOR;
-         else
-           new_cursor_type = NO_CURSOR;
-         active_cursor = 0;
-       }
-    }
-  else
-    {
-      if (f != FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame
-          || w != XWINDOW (f->selected_window))
-        {
-         active_cursor = 0;
-
-          if (MINI_WINDOW_P (w) 
-              || !cursor_non_selected
-              || NILP (XBUFFER (w->buffer)->cursor_type))
-            new_cursor_type = NO_CURSOR;
-          else
-            new_cursor_type = HOLLOW_BOX_CURSOR;
-        }
-      else
-        {
-         struct buffer *b = XBUFFER (w->buffer);
-
-         if (EQ (b->cursor_type, Qt))
-            new_cursor_type = FRAME_DESIRED_CURSOR (f);
-         else
-           new_cursor_type = x_specified_cursor_type (b->cursor_type, 
-                                                      &new_cursor_width);
-         if (w->cursor_off_p)
-           {
-             if (new_cursor_type == FILLED_BOX_CURSOR)
-               new_cursor_type = HOLLOW_BOX_CURSOR;
-             else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
-               new_cursor_width = 1;
-             else
-               new_cursor_type = NO_CURSOR;
-           }
-       }
-    }
+  /* 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,
@@ -9800,17 +9800,20 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
          || 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 == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
              && new_cursor_width != w->phys_cursor_width)))
     x_erase_phys_cursor (w);
 
-  /* If the cursor is now invisible and we want it to be visible,
-     display it.  */
-  if (on && !w->phys_cursor_on_p)
+  /* 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;
@@ -9872,7 +9875,11 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
          break;
 
        case BAR_CURSOR:
-         x_draw_bar_cursor (w, glyph_row, new_cursor_width);
+         x_draw_bar_cursor (w, glyph_row, new_cursor_width, BAR_CURSOR);
+         break;
+
+       case HBAR_CURSOR:
+         x_draw_bar_cursor (w, glyph_row, new_cursor_width, HBAR_CURSOR);
          break;
 
        case NO_CURSOR:
@@ -9974,7 +9981,7 @@ x_bitmap_icon (f, icon)
   if (NILP (icon))
     hicon = LoadIcon (hinst, EMACS_CLASS);
   else if (STRINGP (icon))
-    hicon = LoadImage (NULL, (LPCTSTR) XSTRING (icon)->data, IMAGE_ICON, 0, 0,
+    hicon = LoadImage (NULL, (LPCTSTR) SDATA (icon), IMAGE_ICON, 0, 0,
                       LR_DEFAULTSIZE | LR_LOADFROMFILE);
   else if (SYMBOLP (icon))
     {
@@ -10104,7 +10111,7 @@ x_new_fontset (f, fontsetname)
        to do.  */
     return fontset_name (fontset);
 
-  result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
+  result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
 
   if (!STRINGP (result))
     /* Can't load ASCII font.  */
@@ -10243,7 +10250,7 @@ x_calc_absolute_position (f)
   {
       RECT rt;
       rt.left = rt.right = rt.top = rt.bottom = 0;
-      
+
       BLOCK_INPUT;
       AdjustWindowRect(&rt, f->output_data.w32->dwStyle,
                       FRAME_EXTERNAL_MENU_BAR (f));
@@ -10323,12 +10330,12 @@ x_check_fullscreen (f)
   if (f->output_data.w32->want_fullscreen & FULLSCREEN_BOTH)
     {
       int width, height, ign;
-                      
+
       x_real_positions (f, &f->output_data.w32->left_pos,
                         &f->output_data.w32->top_pos);
 
       x_fullscreen_adjust (f, &width, &height, &ign, &ign);
-                  
+
       /* We do not need to move the window, it shall be taken care of
          when setting WM manager hints.
          If the frame is visible already, the position is checked by
@@ -10364,7 +10371,7 @@ x_check_fullscreen_move (f)
       expect_top = 0;
     if (f->output_data.w32->want_fullscreen & FULLSCREEN_WIDTH)
       expect_left = 0;
-    
+
     if (expect_top != f->output_data.w32->top_pos
         || expect_left != f->output_data.w32->left_pos)
       x_set_offset (f, expect_left, expect_top, 1);
@@ -10392,11 +10399,11 @@ x_fullscreen_adjust (f, width, height, top_pos, left_pos)
 
   *top_pos = f->output_data.w32->top_pos;
   *left_pos = f->output_data.w32->left_pos;
-  
+
   if (f->output_data.w32->want_fullscreen & FULLSCREEN_HEIGHT)
     {
       int ph;
-      
+
       ph = FRAME_X_DISPLAY_INFO (f)->height;
       newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
       ph = CHAR_TO_PIXEL_HEIGHT (f, newheight)
@@ -10408,7 +10415,7 @@ x_fullscreen_adjust (f, width, height, top_pos, left_pos)
   if (f->output_data.w32->want_fullscreen & FULLSCREEN_WIDTH)
     {
       int pw;
-      
+
       pw = FRAME_X_DISPLAY_INFO (f)->width;
       newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
       pw = CHAR_TO_PIXEL_WIDTH (f, newwidth)
@@ -10434,9 +10441,9 @@ x_set_window_size (f, change_gravity, cols, rows)
      int cols, rows;
 {
   int pixelwidth, pixelheight;
-  
+
   BLOCK_INPUT;
-  
+
   check_frame_size (f, &rows, &cols);
   f->output_data.w32->vertical_scroll_bar_extra
     = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
@@ -10447,33 +10454,33 @@ x_set_window_size (f, change_gravity, cols, rows)
 
   pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
   pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
-  
+
   f->output_data.w32->win_gravity = NorthWestGravity;
   x_wm_set_size_hint (f, (long) 0, 0);
-  
+
   {
     RECT rect;
 
     rect.left = rect.top = 0;
     rect.right = pixelwidth;
     rect.bottom = pixelheight;
-      
+
     AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
                     FRAME_EXTERNAL_MENU_BAR (f));
-      
+
     my_set_window_pos (FRAME_W32_WINDOW (f),
-                      NULL, 
+                      NULL,
                       0, 0,
                       rect.right - rect.left,
                       rect.bottom - rect.top,
                       SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
   }
-  
+
   /* Now, strictly speaking, we can't be sure that this is accurate,
      but the window manager will get around to dealing with the size
      change request eventually, and we'll hear how it went when the
      ConfigureNotify event gets here.
-     
+
      We could just not bother storing any of this information here,
      and let the ConfigureNotify event set everything up, but that
      might be kind of confusing to the Lisp code, since size changes
@@ -10496,7 +10503,7 @@ x_set_window_size (f, change_gravity, cols, rows)
   mark_window_cursors_off (XWINDOW (f->root_window));
 
   /* Clear out any recollection of where the mouse highlighting was,
-     since it might be in a place that's outside the new frame size. 
+     since it might be in a place that's outside the new frame size.
      Actually checking whether it is outside is a pain in the neck,
      so don't try--just let the highlighting be done afresh with new size.  */
   cancel_mouse_face (f);
@@ -10746,13 +10753,13 @@ x_make_frame_invisible (f)
      struct frame *f;
 {
   /* Don't keep the highlight on an invisible frame.  */
-  if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
-    FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
-  
+  if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
+    FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
+
   BLOCK_INPUT;
-  
+
   my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
-  
+
   /* We can't distinguish this from iconification
      just by the event that we get from the server.
      So we can't win using the usual strategy of letting
@@ -10762,7 +10769,7 @@ x_make_frame_invisible (f)
   FRAME_ICONIFIED_P (f) = 0;
   f->async_visible = 0;
   f->async_iconified = 0;
-  
+
   UNBLOCK_INPUT;
 }
 
@@ -10775,8 +10782,8 @@ x_iconify_frame (f)
   Lisp_Object type;
 
   /* Don't keep the highlight on an invisible frame.  */
-  if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
-    FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
+  if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
+    FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
 
   if (f->async_iconified)
     return;
@@ -10806,7 +10813,7 @@ x_free_frame_resources (f)
 
   if (FRAME_W32_WINDOW (f))
     my_destroy_window (f, FRAME_W32_WINDOW (f));
-      
+
   free_frame_menubar (f);
 
   unload_color (f, f->output_data.x->foreground_pixel);
@@ -10822,16 +10829,16 @@ x_free_frame_resources (f)
 
   if (FRAME_FACE_CACHE (f))
     free_frame_faces (f);
-      
+
   xfree (f->output_data.w32);
   f->output_data.w32 = NULL;
-  
+
   if (f == dpyinfo->w32_focus_frame)
     dpyinfo->w32_focus_frame = 0;
   if (f == dpyinfo->w32_focus_event_frame)
     dpyinfo->w32_focus_event_frame = 0;
-  if (f == dpyinfo->w32_highlight_frame)
-    dpyinfo->w32_highlight_frame = 0;
+  if (f == dpyinfo->x_highlight_frame)
+    dpyinfo->x_highlight_frame = 0;
 
   if (f == dpyinfo->mouse_face_mouse_frame)
     {
@@ -10931,7 +10938,7 @@ x_check_font (f, font)
   xassert (font != NULL);
 
   for (i = 0; i < dpyinfo->n_fonts; i++)
-    if (dpyinfo->font_table[i].name 
+    if (dpyinfo->font_table[i].name
        && font == dpyinfo->font_table[i].font)
       break;
 
@@ -10975,20 +10982,20 @@ x_compute_min_glyph_bounds (f)
   XFontStruct *font;
   int old_width = dpyinfo->smallest_char_width;
   int old_height = dpyinfo->smallest_font_height;
-  
+
   dpyinfo->smallest_font_height = 100000;
   dpyinfo->smallest_char_width = 100000;
-  
+
   for (i = 0; i < dpyinfo->n_fonts; ++i)
     if (dpyinfo->font_table[i].name)
       {
        struct font_info *fontp = dpyinfo->font_table + i;
        int w, h;
-       
+
        font = (XFontStruct *) fontp->font;
        xassert (font != (XFontStruct *) ~0);
        x_font_min_bounds (font, &w, &h);
-       
+
        dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
        dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
       }
@@ -11028,13 +11035,13 @@ w32_initialize_display_info (display_name)
   w32_display_name_list = Fcons (Fcons (display_name, Qnil),
                                  w32_display_name_list);
   dpyinfo->name_list_element = XCAR (w32_display_name_list);
-  
+
   dpyinfo->w32_id_name
-    = (char *) xmalloc (XSTRING (Vinvocation_name)->size
-                       + XSTRING (Vsystem_name)->size
+    = (char *) xmalloc (SCHARS (Vinvocation_name)
+                       + SCHARS (Vsystem_name)
                        + 2);
   sprintf (dpyinfo->w32_id_name, "%s@%s",
-          XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
+          SDATA (Vinvocation_name), SDATA (Vsystem_name));
 
   /* Default Console mode values - overridden when running in GUI mode
      with values obtained from system metrics.  */
@@ -11066,15 +11073,15 @@ w32_term_init (display_name, xrm_option, resource_name)
 {
   struct w32_display_info *dpyinfo;
   HDC hdc;
-  
+
   BLOCK_INPUT;
-  
+
   if (!w32_initialized)
     {
       w32_initialize ();
       w32_initialized = 1;
     }
-  
+
   {
     int argc = 0;
     char *argv[3];
@@ -11087,7 +11094,7 @@ w32_term_init (display_name, xrm_option, resource_name)
        argv[argc++] = xrm_option;
       }
   }
-  
+
   w32_initialize_display_info (display_name);
 
   dpyinfo = &one_w32_display_info;
@@ -11095,7 +11102,7 @@ w32_term_init (display_name, xrm_option, resource_name)
   /* Put this display on the chain.  */
   dpyinfo->next = x_display_list;
   x_display_list = dpyinfo;
-  
+
   hdc = GetDC (GetDesktopWindow ());
 
   dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
@@ -11113,7 +11120,7 @@ w32_term_init (display_name, xrm_option, resource_name)
 
   /* initialise palette with white and black */
   {
-    COLORREF color;
+    XColor color;
     w32_defined_color (0, "white", &color, 1);
     w32_defined_color (0, "black", &color, 1);
   }
@@ -11278,7 +11285,7 @@ w32_initialize ()
   init_crit ();
 
   dwMainThreadId = GetCurrentThreadId ();
-  DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), 
+  DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
                   GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
 
   /* Wait for thread to start */
@@ -11288,13 +11295,13 @@ w32_initialize ()
 
     PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
 
-    hWindowsThread = CreateThread (NULL, 0, 
-                              (LPTHREAD_START_ROUTINE) w32_msg_worker, 
+    hWindowsThread = CreateThread (NULL, 0,
+                              (LPTHREAD_START_ROUTINE) w32_msg_worker,
                               0, 0, &dwWindowsThreadId);
 
     GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
   }
-  
+
   /* It is desirable that mainThread should have the same notion of
      focus window and active window as windowsThread.  Unfortunately, the
      following call to AttachThreadInput, which should do precisely what
@@ -11374,7 +11381,7 @@ When nil, CapsLock only affects normal character input keys.  */);
               &Vw32_recognize_altgr,
               doc: /* Recognize right-alt and left-ctrl as AltGr.
 When nil, the right-alt and left-ctrl key combination is
-interpreted normally.  */); 
+interpreted normally.  */);
   Vw32_recognize_altgr = Qt;
 
   DEFVAR_BOOL ("w32-enable-unicode-output",
@@ -11407,7 +11414,7 @@ When this is non-nil, Emacs will indicate the position of point by
 using the system caret instead of drawing its own cursor.  Some screen
 reader software does not track the system cursor properly when it is
 invisible, and gets confused by Emacs drawing its own cursor, so this
-variable is initialized to t when Emacs detects that screen reader 
+variable is initialized to t when Emacs detects that screen reader
 software is running as it starts up.
 
 When this variable is set, other variables affecting the appearance of