Upgraded to mh-e version 6.1.1.
[bpt/emacs.git] / src / w32term.c
index 19e5126..bde0388 100644 (file)
@@ -86,7 +86,7 @@ enum fringe_bitmap_type
 #define zv_width 8
 #define zv_height 72
 #define zv_period 3
-static unsigned char zv_bits[] = {
+static unsigned short zv_bits[] = {
   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
@@ -170,6 +170,10 @@ static Lisp_Object previous_help_echo;
 
 static int any_help_event_p;
 
+/* Non-zero means autoselect window with the mouse cursor.  */
+
+int mouse_autoselect_window;
+
 /* Non-zero means draw block and hollow cursor as wide as the glyph
    under it.  For example, if a block cursor is over a tab, it will be
    drawn as wide as that tab on the display.  */
@@ -222,10 +226,10 @@ struct cursor_pos output_cursor;
 
 /* The handle of the frame that currently owns the system caret.  */
 HWND w32_system_caret_hwnd;
-int w32_system_caret_width;
 int w32_system_caret_height;
 int w32_system_caret_x;
 int w32_system_caret_y;
+int w32_use_visible_system_caret;
 
 /* Flag to enable Unicode output in case users wish to use programs
    like Twinbridge on '95 rather than installed system level support
@@ -329,7 +333,7 @@ extern int errno;
 
 /* A mask of extra modifier bits to put into every keyboard char.  */
 
-extern int extra_keyboard_modifiers;
+extern EMACS_INT extra_keyboard_modifiers;
 
 /* Enumeration for overriding/changing the face to use for drawing
    glyphs in x_draw_glyphs.  */
@@ -388,14 +392,17 @@ static void x_clear_frame P_ ((void));
 static void x_clear_cursor P_ ((struct window *));
 static void frame_highlight P_ ((struct frame *));
 static void frame_unhighlight P_ ((struct frame *));
-static void w32_new_focus_frame P_ ((struct w32_display_info *,
-                                     struct frame *));
+static void x_new_focus_frame P_ ((struct w32_display_info *,
+                                  struct frame *));
 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));
@@ -407,13 +414,17 @@ static void x_update_window_cursor P_ ((struct window *, int));
 static void x_erase_phys_cursor P_ ((struct window *));
 void x_display_cursor P_ ((struct window *w, int, int, int, int, int));
 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
-static void w32_draw_fringe_bitmap P_ ((struct window *, HDC hdc, struct glyph_row *, 
+static void w32_draw_fringe_bitmap P_ ((struct window *, HDC hdc,
+                                       struct glyph_row *, 
                                        enum fringe_bitmap_type, int left_p));
 static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
                                  HDC, int));
 static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
-static void x_draw_row_fringe_bitmaps P_ ((struct window *, struct glyph_row *));
-static void notice_overwritten_cursor P_ ((struct window *, int, int));
+static void x_draw_row_fringe_bitmaps P_ ((struct window *,
+                                          struct glyph_row *));
+static void notice_overwritten_cursor P_ ((struct window *,
+                                          enum glyph_row_area,
+                                          int, int, int, int));
 
 static Lisp_Object Qvendor_specific_keysyms;
 
@@ -589,6 +600,10 @@ x_update_window_begin (w)
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
 
+  /* Hide the system caret during an update.  */
+  if (w32_use_visible_system_caret)
+    SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
+
   updated_window = w;
   set_output_cursor (&w->cursor);
 
@@ -710,6 +725,12 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
       dpyinfo->mouse_face_window = Qnil;
     }
 
+  /* Unhide the caret.  This won't actually show the cursor, unless it
+     was visible before the corresponding call to HideCaret in
+     x_update_window_begin.  */
+  if (w32_use_visible_system_caret)
+    SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
+
   updated_window = NULL;
 }
 
@@ -1206,9 +1227,24 @@ w32_native_per_char_metric (font, char2b, font_type, pcm)
 
       if (retval)
        {
+#if 0
+         /* Disabled until we can find a way to get the right results
+            on all versions of Windows.  */
+
+         /* Don't trust the ABC widths.  For synthesized fonts they are
+            wrong, and so is the result of GetCharWidth()!  */
+         int real_width;
+         GetCharWidth (hdc, *char2b, *char2b, &real_width);
+#endif
          pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
+#if 0
+         /* As far as I can tell, this is the best way to determine what
+            ExtTextOut will do with the broken font.  */
+         if (pcm->width != real_width)
+           pcm->width = (pcm->width + real_width) / 2;
+#endif
          pcm->lbearing = char_widths.abcA;
-         pcm->rbearing = pcm->width - char_widths.abcC;
+         pcm->rbearing = char_widths.abcA + char_widths.abcB;
          pcm->ascent = FONT_BASE (font);
          pcm->descent = FONT_DESCENT (font);
        }
@@ -1811,7 +1847,7 @@ x_append_stretch_glyph (it, object, width, height, ascent)
    4. `:height HEIGHT' specifies that the height of the stretch produced
    should be HEIGHT, measured in canonical character units.
 
-   5. `:relative-height FACTOR' specifies that the height of the the
+   5. `:relative-height FACTOR' specifies that the height of the
    stretch should be FACTOR times the height of the characters having
    the glyph property.
 
@@ -2702,7 +2738,8 @@ struct glyph_string
 
 /* Encapsulate the different ways of displaying text under W32.  */
 
-void W32_TEXTOUT (s, x, y,chars,nchars)
+static void
+w32_text_out (s, x, y,chars,nchars)
      struct glyph_string * s;
      int x, y;
      wchar_t * chars;
@@ -2716,8 +2753,8 @@ void W32_TEXTOUT (s, x, y,chars,nchars)
   else if (s->first_glyph->w32_font_type == UNICODE_FONT)
     ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
   else
-    ExtTextOut (s->hdc, x, y, 0, NULL, (char *) chars,
-                nchars * charset_dim, NULL);
+    ExtTextOutA (s->hdc, x, y, 0, NULL, (char *) chars,
+                nchars * charset_dim, NULL);
 }
 
 #if GLYPH_DEBUG
@@ -3450,7 +3487,7 @@ x_draw_glyph_string_foreground (s)
           char1b[i] = BYTE2 (s->char2b[i]);
 
       /* Draw text with TextOut and friends. */
-      W32_TEXTOUT (s, x, s->ybase - boff, s->char2b, s->nchars);
+      w32_text_out (s, x, s->ybase - boff, s->char2b, s->nchars);
     }
   if (s->font && s->font->hfont)
     SelectObject (s->hdc, old_font);
@@ -3497,7 +3534,7 @@ x_draw_composite_glyph_string_foreground (s)
   else
     {
       for (i = 0; i < s->nchars; i++, ++s->gidx)
-          W32_TEXTOUT (s, x + s->cmp->offsets[s->gidx * 2],
+          w32_text_out (s, x + s->cmp->offsets[s->gidx * 2],
                        s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
                        s->char2b + i, 1);
     }
@@ -3646,6 +3683,7 @@ x_setup_relief_colors (s)
   if (s->face->use_box_color_for_shadows_p)
     color = s->face->box_color;
   else if (s->first_glyph->type == IMAGE_GLYPH
+          && s->img->pixmap
           && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
     color = IMAGE_BACKGROUND  (s->img, s->f, 0);
   else
@@ -3693,14 +3731,14 @@ w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
   for (i = 0; i < width; ++i)
     w32_fill_area (f, hdc, gc.foreground,
                   left_x + i * left_p, top_y + i,
-                  (right_x + 1 - i * right_p) - (left_x + i * left_p) + 1, 1);
+                  right_x - left_x - i * (left_p + right_p ) + 1, 1);
 
   /* Left.  */
   if (left_p)
     for (i = 0; i < width; ++i)
       w32_fill_area (f, hdc, gc.foreground,
                     left_x + i, top_y + i, 1,
-                    (bottom_y - i) - (top_y + i) + 2);
+                    bottom_y - top_y - 2 * i + 1);
 
   if (raised_p)
     gc.foreground = f->output_data.w32->black_relief.gc->foreground;
@@ -3711,14 +3749,14 @@ w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
   for (i = 0; i < width; ++i)
     w32_fill_area (f, hdc, gc.foreground, 
                   left_x + i * left_p, bottom_y - i,
-                  (right_x - i * right_p) - (left_x + i * left_p) + 2, 1);
+                  right_x - left_x - i * (left_p + right_p) + 1, 1);
 
   /* Right.  */
   if (right_p)
     for (i = 0; i < width; ++i)
       w32_fill_area (f, hdc, gc.foreground,
                     right_x - i, top_y + i + 1, 1,
-                    (bottom_y - i) - (top_y + i));
+                    bottom_y - top_y - 2 * i - 1);
 
   w32_set_clip_rectangle (hdc, NULL);
   
@@ -3911,8 +3949,12 @@ x_draw_image_foreground (s)
             the image.  I believe it's looking better if we do
             nothing here for mouse-face.  */
          if (s->hl == DRAW_CURSOR)
-            w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width - 1,
-                                s->img->height - 1);
+           {
+             int r = s->img->relief;
+             if (r < 0) r = -r;
+             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);
        }
     }
@@ -3952,7 +3994,7 @@ x_draw_image_relief (s)
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
     {
-      thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : 3;
+      thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
       raised_p = s->hl == DRAW_IMAGE_RAISED;
     }
   else
@@ -4052,8 +4094,12 @@ w32_draw_image_foreground_1 (s, pixmap)
             the image.  I believe it's looking better if we do
             nothing here for mouse-face.  */
          if (s->hl == DRAW_CURSOR)
-            w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
-                                s->img->height - 1);
+           {
+             int r = s->img->relief;
+             if (r < 0) r = -r;
+             w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
+                                 s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+           }
        }
     }
   else
@@ -5035,7 +5081,12 @@ x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
   for (s = head; s; s = s->next)
     x_draw_glyph_string (s);
 
-  if (area == TEXT_AREA && !row->full_width_p)
+  if (area == TEXT_AREA
+      && !row->full_width_p
+      /* When drawing overlapping rows, only the glyph strings'
+        foreground is drawn, which doesn't erase a cursor
+        completely. */
+      && !overlaps_p)
     {
       int x0 = head ? head->x : x;
       int x1 = tail ? tail->x + tail->background_width : x;
@@ -5050,7 +5101,8 @@ x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
          x1 -= left_area_width;
        }
 
-      notice_overwritten_cursor (w, x0, x1);
+      notice_overwritten_cursor (w, area, x0, x1,
+                                row->y, MATRIX_ROW_BOTTOM_Y (row));
     }
 
   /* Value is the x-position up to which drawn, relative to AREA of W.
@@ -5270,10 +5322,13 @@ x_clear_end_of_line (to_x)
   
   /* Notice if the cursor will be cleared by this operation.  */
   if (!updated_row->full_width_p)
-    notice_overwritten_cursor (w, output_cursor.x, -1);
+    notice_overwritten_cursor (w, updated_area,
+                              output_cursor.x, -1,
+                              updated_row->y,
+                              MATRIX_ROW_BOTTOM_Y (updated_row));
 
   from_x = output_cursor.x;
-     
+
   /* Translate to frame coordinates.  */
   if (updated_row->full_width_p)
     {
@@ -5418,7 +5473,8 @@ x_scroll_run (w, run)
 {
   struct frame *f = XFRAME (w->frame);
   int x, y, width, height, from_y, to_y, bottom_y;
-  HDC hdc = get_frame_dc (f);
+  HWND hwnd = FRAME_W32_WINDOW (f);
+  HRGN expect_dirty;
 
   /* Get frame-relative bounding box of the text display area of W,
      without mode lines.  Include in this box the left and right
@@ -5439,6 +5495,7 @@ x_scroll_run (w, run)
        height = bottom_y - from_y;
       else
        height = run->height;
+      expect_dirty = CreateRectRgn (x, y + height, x + width, bottom_y);
     }
   else
     {
@@ -5448,6 +5505,7 @@ x_scroll_run (w, run)
        height = bottom_y - to_y;
       else
        height = run->height;
+      expect_dirty = CreateRectRgn (x, y, x + width, to_y);
     }
 
   BLOCK_INPUT;
@@ -5456,10 +5514,32 @@ x_scroll_run (w, run)
   updated_window = w;
   x_clear_cursor (w);
 
-  BitBlt (hdc, x, to_y, width, height, hdc, x, from_y, SRCCOPY);
-  
+  {
+    RECT from;
+    RECT to;
+    HRGN dirty = CreateRectRgn (0, 0, 0, 0);
+    HRGN combined = CreateRectRgn (0, 0, 0, 0);
+
+    from.left = to.left = x;
+    from.right = to.right = x + width;
+    from.top = from_y;
+    from.bottom = from_y + height;
+    to.top = y;
+    to.bottom = bottom_y;
+
+    ScrollWindowEx (hwnd, 0, to_y - from_y, &from, &to, dirty,
+                   NULL, SW_INVALIDATE);
+
+    /* Combine this with what we expect to be dirty. This covers the
+       case where not all of the region we expect is actually dirty.  */
+    CombineRgn (combined, dirty, expect_dirty, RGN_OR);
+
+    /* If the dirty region is not what we expected, redraw the entire frame.  */
+    if (!EqualRgn (combined, expect_dirty))
+      SET_FRAME_GARBAGED (f);
+  }
+
   UNBLOCK_INPUT;
-  release_frame_dc (f, hdc);
 }
 
 
@@ -5693,6 +5773,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
@@ -5734,6 +5847,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));
@@ -5754,7 +5868,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)
@@ -5767,6 +5882,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;
            }
@@ -5787,6 +5909,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);
 
@@ -5875,29 +6001,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
@@ -6023,9 +6149,13 @@ glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
   return success_p;
 }
 
+/* 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 
-parse_button (message, pbutton, pup)
+parse_button (message, xbutton, pbutton, pup)
      int message;
+     int xbutton;
      int * pbutton;
      int * pup;
 {
@@ -6070,6 +6200,14 @@ parse_button (message, pbutton, pup)
        button = 1;
       up = 1;
       break;
+    case WM_XBUTTONDOWN:
+      button = xbutton + 2;
+      up = 0;
+      break;
+    case WM_XBUTTONUP:
+      button = xbutton + 2;
+      up = 1;
+      break;
     default:
       return (FALSE);
     }
@@ -6095,11 +6233,12 @@ construct_mouse_click (result, msg, f)
   int button;
   int up;
 
-  parse_button (msg->msg.message, &button, &up);
+  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
@@ -6121,7 +6260,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;
@@ -6149,7 +6288,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;
@@ -6176,7 +6315,7 @@ construct_drag_n_drop (result, msg, f)
        continue;
       name = alloca (len + 1);
       DragQueryFile (hdrop, i, name, len + 1);
-      files = Fcons (build_string (name), files);
+      files = Fcons (DECODE_FILE (build_string (name)), files);
     }
 
   DragFinish (hdrop);
@@ -6213,6 +6352,28 @@ note_mouse_movement (frame, msg)
   memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
   XSETFRAME (last_mouse_motion_frame, frame);
 
+#if 0 /* Calling Lisp asynchronously is not safe.  */
+  if (mouse_autoselect_window)
+    {
+      int area;
+      Lisp_Object window;
+      static Lisp_Object last_window;
+
+      window = window_from_coordinates (frame, mouse_x, mouse_y, &area, 0);
+
+      /* Window will be selected only when it is not selected now and
+        last mouse movement event was not in it.  Minibuffer window
+        will be selected iff it is active.  */
+      if (!EQ (window, last_window)
+         && !EQ (window, selected_window)
+         && (!MINI_WINDOW_P (XWINDOW (window))
+             || (EQ (window, minibuf_window) && minibuf_level > 0)))
+       Fselect_window (window);
+
+      last_window=window;
+    }
+#endif
+
   if (msg->hwnd != FRAME_W32_WINDOW (frame))
     {
       frame->mouse_moved = 1;
@@ -6237,11 +6398,6 @@ note_mouse_movement (frame, msg)
     }
 }
 
-/* This is used for debugging, to turn off note_mouse_highlight.  */
-
-int disable_mouse_highlight;
-
-
 \f
 /************************************************************************
                              Mouse Face
@@ -6400,9 +6556,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
@@ -6458,7 +6614,7 @@ note_mouse_highlight (f, x, y)
   if (popup_activated ())
     return;
 
-  if (disable_mouse_highlight
+  if (NILP (Vmouse_highlight)
       || !f->glyphs_initialized_p)
     return;
 
@@ -6721,7 +6877,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,
@@ -6819,7 +6975,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);
@@ -6967,7 +7123,7 @@ w32_handle_tool_bar_click (f, button_event)
   if (NILP (enabled_p))
     return;
   
-  if (button_event->kind == mouse_click)
+  if (button_event->modifiers & down_modifier)
     {
       /* Show item in pressed state.  */
       show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
@@ -6994,7 +7150,8 @@ w32_handle_tool_bar_click (f, button_event)
       event.kind = TOOL_BAR_EVENT;
       event.frame_or_window = frame;
       event.arg = key;
-      event.modifiers = button_event->modifiers;
+      /* The keyboard buffer doesn't like the up modifier being set.  */
+      event.modifiers = button_event->modifiers & ~up_modifier;
       kbd_buffer_store_event (&event);
       last_tool_bar_item = -1;
     }
@@ -7271,7 +7428,7 @@ fast_find_position (w, pos, hpos, vpos, x, y, stop)
 #endif /* not 0 */
 
 
-/* Find the position of the the glyph for position POS in OBJECT in
+/* Find the position of the glyph for position POS in OBJECT in
    window W's current matrix, and return in *X/*Y the pixel
    coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
 
@@ -7367,6 +7524,8 @@ show_mouse_face (dpyinfo, draw)
   if (/* If window is in the process of being destroyed, don't bother
         to do anything.  */
       w->current_matrix != NULL
+      /* Don't update mouse highlight if hidden */
+      && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
       /* Recognize when we are called to operate on rows that don't exist
         anymore.  This can happen when a window is split.  */
       && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
@@ -7403,7 +7562,8 @@ show_mouse_face (dpyinfo, draw)
              x_draw_glyphs (w, start_x, row, TEXT_AREA, 
                             start_hpos, end_hpos, draw, 0);
 
-             row->mouse_face_p = draw == DRAW_MOUSE_FACE || DRAW_IMAGE_RAISED;
+             row->mouse_face_p
+               = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
            }
        }
 
@@ -7493,6 +7653,8 @@ cancel_mouse_face (f)
 \f
 static struct scroll_bar *x_window_to_scroll_bar ();
 static void x_scroll_bar_report_motion ();
+static void x_check_fullscreen P_ ((struct frame *));
+static void x_check_fullscreen_move P_ ((struct frame *));
 static int glyph_rect P_ ((struct frame *f, int, int, RECT *));
 
 
@@ -7508,7 +7670,7 @@ glyph_rect (f, x, y, rect)
      RECT *rect;
 {
   Lisp_Object window;
-  int part, found = 0;
+  int part;
 
   window = window_from_coordinates (f, x, y, &part, 0);
   if (!NILP (window))
@@ -7518,27 +7680,44 @@ glyph_rect (f, x, y, rect)
       struct glyph_row *end = r + w->current_matrix->nrows - 1;
 
       frame_to_window_pixel_xy (w, &x, &y);
-      
-      for (; !found && r < end && r->enabled_p; ++r)
-       if (r->y + r->height >= y)
+
+      for (; r < end && r->enabled_p; ++r)
+       if (r->y <= y && r->y + r->height > y)
          {
+           /* Found the row at y.  */
            struct glyph *g = r->glyphs[TEXT_AREA];
            struct glyph *end = g + r->used[TEXT_AREA];
            int gx;
-             
-           for (gx = r->x; !found && g < end; gx += g->pixel_width, ++g)
-             if (gx + g->pixel_width >= x)
+
+           rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
+           rect->bottom = rect->top + r->height;
+
+           if (x < r->x)
+             {
+               /* x is to the left of the first glyph in the row.  */
+               rect->left = XINT (w->left);
+               rect->right = WINDOW_TO_FRAME_PIXEL_X (w, r->x);
+               return 1;
+             }
+
+           for (gx = r->x; g < end; gx += g->pixel_width, ++g)
+             if (gx <= x && gx + g->pixel_width > x)
                {
+                 /* x is on a glyph.  */
                  rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
-                 rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
                  rect->right = rect->left + g->pixel_width;
-                 rect->bottom = rect->top + r->height;
-                 found = 1;
+                 return 1;
                }
+
+           /* x is to the right of the last glyph in the row.  */
+           rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
+           rect->right = XINT (w->left) + XINT (w->width);
+           return 1;
          }
     }
 
-  return found;
+  /* The y is not on any row.  */
+  return 0;
 }
 
 /* Record the position of the mouse in last_mouse_glyph.  */
@@ -7810,7 +7989,7 @@ my_create_scrollbar (f, bar)
                             (LPARAM) bar);
 }
 
-//#define ATTACH_THREADS
+/*#define ATTACH_THREADS*/
 
 BOOL
 my_show_window (FRAME_PTR f, HWND hwnd, int how)
@@ -8064,7 +8243,7 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
             SetScrollRange (hwnd, SB_CTL, 0,
                             VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
           my_show_window (f, hwnd, SW_NORMAL);
-          //  InvalidateRect (w, NULL, FALSE);
+          /* InvalidateRect (w, NULL, FALSE);  */
 
           /* Remember new settings.  */
           XSETINT (bar->left, sb_left);
@@ -8188,7 +8367,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.  */
@@ -8202,7 +8381,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;
@@ -8302,7 +8481,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;
       }
 
@@ -8416,12 +8595,6 @@ x_scroll_bar_clear (f)
 \f
 /* The main W32 event-reading loop - w32_read_socket.  */
 
-/* Time stamp of enter window event.  This is only used by w32_read_socket,
-   but we have to put it out here, since static variables within functions
-   sometimes don't work.  */
-
-static Time enter_timestamp;
-
 /* Record the last 100 characters stored
    to help debug the loss-of-chars-during-GC problem.  */
 
@@ -8494,7 +8667,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)
                {
@@ -8503,13 +8676,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++;
@@ -8547,7 +8720,7 @@ 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;
@@ -8564,10 +8737,16 @@ w32_read_socket (sd, bufp, numchars, expected)
          
          if (f && !f->iconified)
            {
+             if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+               {
+                 dpyinfo->mouse_face_hidden = 1;
+                 clear_mouse_face (dpyinfo);
+               }
+
              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);
@@ -8585,10 +8764,16 @@ w32_read_socket (sd, bufp, numchars, expected)
          
          if (f && !f->iconified)
            {
+             if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+               {
+                 dpyinfo->mouse_face_hidden = 1;
+                 clear_mouse_face (dpyinfo);
+               }
+
              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);
@@ -8611,6 +8796,12 @@ w32_read_socket (sd, bufp, numchars, expected)
          else
            f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
          
+         if (dpyinfo->mouse_face_hidden)
+           {
+             dpyinfo->mouse_face_hidden = 0;
+             clear_mouse_face (dpyinfo);
+           }
+
          if (f)
            note_mouse_movement (f, &msg.msg);
          else
@@ -8646,6 +8837,8 @@ w32_read_socket (sd, bufp, numchars, expected)
        case WM_MBUTTONUP:
        case WM_RBUTTONDOWN:
        case WM_RBUTTONUP:
+       case WM_XBUTTONDOWN:
+       case WM_XBUTTONUP:
          {
             /* If we decide we want to generate an event to be seen
                by the rest of Emacs, we put it here.  */
@@ -8654,7 +8847,7 @@ 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))
@@ -8671,13 +8864,14 @@ w32_read_socket (sd, bufp, numchars, expected)
                     && XFASTINT (XWINDOW (f->tool_bar_window)->height))
                   {
                     Lisp_Object window;
-                    int p;
+                    int p, x, y;
+
+                   x = XFASTINT (emacs_event.x);
+                   y = XFASTINT (emacs_event.y);
 
                     /* Set x and y.  */
-                    window = window_from_coordinates (f,
-                                                      emacs_event.x,
-                                                      emacs_event.y,
-                                                      &p, 1);
+                    window = window_from_coordinates (f, x, y, &p, 1);
+
                     if (EQ (window, f->tool_bar_window))
                       {
                         w32_handle_tool_bar_click (f, &emacs_event);
@@ -8697,8 +8891,9 @@ w32_read_socket (sd, bufp, numchars, expected)
                     }
              }
            
-           parse_button (msg.msg.message, &button, &up);
-           
+           parse_button (msg.msg.message, HIWORD (msg.msg.wParam),
+                         &button, &up);
+
            if (up)
              {
                dpyinfo->grabbed &= ~ (1 << button);
@@ -8771,8 +8966,22 @@ w32_read_socket (sd, bufp, numchars, expected)
          }
          
        case WM_WINDOWPOSCHANGED:
+         f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
+         if (f)
+           {
+             x_check_fullscreen_move(f);
+             if (f->output_data.w32->want_fullscreen & FULLSCREEN_WAIT)
+               f->output_data.w32->want_fullscreen &=
+                 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
+           }
+         check_visibility = 1;
+         break;
+
        case WM_ACTIVATE:
        case WM_ACTIVATEAPP:
+         f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
+         if (f)
+           x_check_fullscreen (f);
          check_visibility = 1;
          break;
 
@@ -8830,7 +9039,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                  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++;
@@ -8860,7 +9069,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++;
@@ -9008,7 +9217,7 @@ w32_read_socket (sd, bufp, numchars, expected)
              if (numchars == 0)
                abort ();
              
-             bufp->kind = delete_window_event;
+             bufp->kind = DELETE_WINDOW_EVENT;
              XSETFRAME (bufp->frame_or_window, f);
              bufp->arg = Qnil;
              bufp++;
@@ -9025,7 +9234,7 @@ w32_read_socket (sd, bufp, numchars, expected)
              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++;
@@ -9147,7 +9356,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
@@ -9159,7 +9368,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 ();
@@ -9187,15 +9396,17 @@ w32_read_socket (sd, bufp, numchars, expected)
    of the line after START_X has been written.  */
 
 static void
-notice_overwritten_cursor (w, start_x, end_x)
+notice_overwritten_cursor (w, area, x0, x1, y0, y1)
      struct window *w;
-     int start_x, end_x;
+     enum glyph_row_area area;
+     int x0, x1, y0, y1;
 {
-  if (updated_area == TEXT_AREA
+  if (area == TEXT_AREA
       && w->phys_cursor_on_p
-      && output_cursor.vpos == w->phys_cursor.vpos
-      && start_x <= w->phys_cursor.x
-      && (end_x < 0 || end_x > w->phys_cursor.x))
+      && y0 <= w->phys_cursor.y
+      && y1 >= w->phys_cursor.y + w->phys_cursor_height
+      && x0 <= w->phys_cursor.x
+      && (x1 < 0 || x1 > w->phys_cursor.x))
     w->phys_cursor_on_p = 0;
 }
 
@@ -9259,7 +9470,7 @@ x_draw_hollow_cursor (w, row)
   rect.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
   rect.top = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
               + row->ascent - w->phys_cursor_ascent);
-  rect.bottom = rect.top + row->height - 1;
+  rect.bottom = rect.top + row->height;
 
   /* Get the glyph the cursor is on.  If we can't tell because
      the current matrix is invalid or such, give up.  */
@@ -9271,7 +9482,7 @@ x_draw_hollow_cursor (w, row)
      glyph, and `x-stretch-block-cursor' is nil, don't draw a
      rectangle as wide as the glyph, but use a canonical character
      width instead.  */
-  wd = cursor_glyph->pixel_width - 1;
+  wd = cursor_glyph->pixel_width;
   if (cursor_glyph->type == STRETCH_GLYPH
       && !x_stretch_cursor_p)
     wd = min (CANON_X_UNIT (f), wd);
@@ -9293,10 +9504,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;
@@ -9325,7 +9537,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
@@ -9338,10 +9551,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);
     }
 }
@@ -9429,6 +9652,12 @@ x_erase_phys_cursor (w)
   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
@@ -9436,7 +9665,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)
@@ -9564,58 +9793,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 if (w->cursor_off_p)
-        new_cursor_type = NO_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);
-       }
-    }
+  /* Set new_cursor_type to the cursor we want to be displayed.  */
+  new_cursor_type = get_window_cursor_type (w, &new_cursor_width);
 
   /* 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,
@@ -9624,12 +9803,17 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
       && (!on
          || w->phys_cursor.x != x
          || w->phys_cursor.y != y
-         || new_cursor_type != w->phys_cursor_type))
+         || new_cursor_type != w->phys_cursor_type
+         || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
+             && new_cursor_width != w->phys_cursor_width)))
     x_erase_phys_cursor (w);
 
-  /* 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;
@@ -9640,7 +9824,23 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
       w->phys_cursor.y = glyph_row->y;
       w->phys_cursor.hpos = hpos;
       w->phys_cursor.vpos = vpos;
-      w->phys_cursor_type = new_cursor_type;
+
+      /* If the user wants to use the system caret, make sure our own
+        cursor remains invisible.  */
+      if (w32_use_visible_system_caret)
+       {
+         if (w->phys_cursor_type != NO_CURSOR)
+           x_erase_phys_cursor (w);
+
+         new_cursor_type = w->phys_cursor_type = NO_CURSOR;
+         w->phys_cursor_width = -1;
+       }
+      else
+       {
+         w->phys_cursor_type = new_cursor_type;
+         w->phys_cursor_width = new_cursor_width;
+       }
+
       w->phys_cursor_on_p = 1;
 
       /* If this is the active cursor, we need to track it with the
@@ -9648,33 +9848,24 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
         and speech synthesizers can follow the cursor.  */
       if (active_cursor)
        {
-         struct glyph * cursor_glyph = get_phys_cursor_glyph (w);
-         if (cursor_glyph)
-           {
-             HWND hwnd = FRAME_W32_WINDOW (f);
-             int caret_width = cursor_glyph->pixel_width;
-             w32_system_caret_x
-               = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
-             w32_system_caret_y
-               = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
-                  + glyph_row->ascent - w->phys_cursor_ascent);
-
-             /* If the size of the active cursor changed, destroy the old
-                system caret.  */
-             if (w32_system_caret_hwnd
-                 && (w32_system_caret_height != w->phys_cursor_height
-                     || w32_system_caret_width != caret_width))
-               PostMessage (hwnd, WM_EMACS_DESTROY_CARET, NULL, NULL);
-
-             if (!w32_system_caret_hwnd)
-               {
-                 w32_system_caret_height = w->phys_cursor_height;
-                 w32_system_caret_width = caret_width;
-               }
+         HWND hwnd = FRAME_W32_WINDOW (f);
 
-             /* Move the system caret.  */
-             PostMessage (hwnd, WM_EMACS_TRACK_CARET, NULL, NULL);
-           }
+         w32_system_caret_x
+           = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+         w32_system_caret_y
+           = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
+              + glyph_row->ascent - w->phys_cursor_ascent);
+
+         /* If the size of the active cursor changed, destroy the old
+            system caret.  */
+         if (w32_system_caret_hwnd
+             && (w32_system_caret_height != w->phys_cursor_height))
+           PostMessage (hwnd, WM_EMACS_DESTROY_CARET, 0, 0);
+
+         w32_system_caret_height = w->phys_cursor_height;
+
+         /* Move the system caret.  */
+         PostMessage (hwnd, WM_EMACS_TRACK_CARET, 0, 0);
        }
 
       switch (new_cursor_type)
@@ -9688,7 +9879,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:
@@ -9790,7 +9985,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))
     {
@@ -9920,7 +10115,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.  */
@@ -10129,6 +10324,115 @@ x_set_offset (f, xoff, yoff, change_gravity)
   UNBLOCK_INPUT;
 }
 
+
+/* Check if we need to resize the frame due to a fullscreen request.
+   If so needed, resize the frame. */
+static void
+x_check_fullscreen (f)
+     struct frame *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
+         x_check_fullscreen_move. */
+      if (f->width != width || f->height != height)
+        {
+          change_frame_size (f, height, width, 0, 1, 0);
+          SET_FRAME_GARBAGED (f);
+          cancel_mouse_face (f);
+
+          /* Wait for the change of frame size to occur */
+          f->output_data.w32->want_fullscreen |= FULLSCREEN_WAIT;
+        }
+    }
+}
+
+/* If frame parameters are set after the frame is mapped, we need to move
+   the window.  This is done in xfns.c.
+   Some window managers moves the window to the right position, some
+   moves the outer window manager window to the specified position.
+   Here we check that we are in the right spot.  If not, make a second
+   move, assuming we are dealing with the second kind of window manager. */
+static void
+x_check_fullscreen_move (f)
+     struct frame *f;
+{
+  if (f->output_data.w32->want_fullscreen & FULLSCREEN_MOVE_WAIT)
+  {
+    int expect_top = f->output_data.w32->top_pos;
+    int expect_left = f->output_data.w32->left_pos;
+
+    if (f->output_data.w32->want_fullscreen & FULLSCREEN_HEIGHT)
+      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);
+
+    /* Just do this once */
+    f->output_data.w32->want_fullscreen &= ~FULLSCREEN_MOVE_WAIT;
+  }
+}
+
+
+/* Calculate fullscreen size.  Return in *TOP_POS and *LEFT_POS the
+   wanted positions of the WM window (not emacs window).
+   Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
+   window (FRAME_X_WINDOW).
+ */
+void
+x_fullscreen_adjust (f, width, height, top_pos, left_pos)
+     struct frame *f;
+     int *width;
+     int *height;
+     int *top_pos;
+     int *left_pos;
+{
+  int newwidth = f->width, newheight = f->height;
+
+  *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)
+        - f->output_data.w32->y_pixels_diff;
+      newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
+      *top_pos = 0;
+    }
+
+  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)
+        - f->output_data.w32->x_pixels_diff;
+      newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
+      *left_pos = 0;
+    }
+
+  *width = newwidth;
+  *height = newheight;
+}
+
+
 /* Call this to change the size of frame F's x-window.
    If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
    for this size change and subsequent size changes.
@@ -10401,7 +10705,7 @@ x_make_frame_visible (f)
 
       f->output_data.w32->asked_for_visible = 1;
 
-//      my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
+/*      my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);  */
       my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
     }
 
@@ -10453,8 +10757,8 @@ 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;
   
@@ -10482,8 +10786,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;
@@ -10537,8 +10841,8 @@ x_free_frame_resources (f)
     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)
     {
@@ -10737,11 +11041,11 @@ w32_initialize_display_info (display_name)
   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.  */
@@ -10760,6 +11064,7 @@ w32_initialize_display_info (display_name)
   dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
   dpyinfo->mouse_face_window = Qnil;
   dpyinfo->mouse_face_overlay = Qnil;
+  dpyinfo->mouse_face_hidden = 0;
   /* TODO: dpyinfo->gray */
 
 }
@@ -10969,7 +11274,6 @@ w32_initialize ()
 
   w32_system_caret_hwnd = NULL;
   w32_system_caret_height = 0;
-  w32_system_caret_width = 0;
   w32_system_caret_x = 0;
   w32_system_caret_y = 0;
 
@@ -11103,21 +11407,42 @@ affect on NT machines.  */);
   staticpro (&previous_help_echo);
   help_echo_pos = -1;
 
+  DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
+    doc: /* *Non-nil means autoselect window with mouse pointer.  */);
+  mouse_autoselect_window = 0;
+
+  DEFVAR_BOOL ("w32-use-visible-system-caret",
+              &w32_use_visible_system_caret,
+              doc: /* Flag to make the system caret visible.
+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 
+software is running as it starts up.
+
+When this variable is set, other variables affecting the appearance of
+the cursor have no effect.  */);
+
+  /* Initialize w32_use_visible_system_caret based on whether a screen
+     reader is in use.  */
+  if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
+                            &w32_use_visible_system_caret, 0))
+    w32_use_visible_system_caret = 0;
+
   DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
               doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
 For example, if a block cursor is over a tab, it will be drawn as
 wide as that tab on the display.  */);
   x_stretch_cursor_p = 0;
 
-#if 0 /* TODO: Setting underline position from font properties.  */
   DEFVAR_BOOL ("x-use-underline-position-properties",
               &x_use_underline_position_properties,
               doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
-Nil means ignore them.  If you encounter fonts with bogus
+nil means ignore them.  If you encounter fonts with bogus
 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
 to 4.1, set this to nil.  */);
   x_use_underline_position_properties = 1;
-#endif
 
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
               doc: /* If not nil, Emacs uses toolkit scroll bars.  */);