]> code.delx.au - gnu-emacs/blobdiff - src/w32term.c
In x_set_window_size restore do_pending_window_change calls
[gnu-emacs] / src / w32term.c
index fb8648ca4f903ba6dbe9949fe4f3e4f0511b2840..51743f8f94dad77257e9db79cd2f498c07d55bc6 100644 (file)
@@ -1,13 +1,13 @@
 /* Implementation of GUI terminal on the Microsoft Windows API.
 
-Copyright (C) 1989, 1993-2014 Free Software Foundation, Inc.
+Copyright (C) 1989, 1993-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,38 +23,29 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "lisp.h"
 #include "blockinput.h"
 #include "w32term.h"
-
-#include "systty.h"
-#include "systime.h"
+#include "w32common.h" /* for OS version info */
 
 #include <ctype.h>
 #include <errno.h>
 #include <sys/stat.h>
+#ifdef CYGWIN
+#include <fcntl.h>     /* for O_RDWR */
+#endif
 #include <imm.h>
 
-#include "charset.h"
-#include "character.h"
 #include "coding.h"
-#include "ccl.h"
 #include "frame.h"
-#include "dispextern.h"
 #include "fontset.h"
 #include "termhooks.h"
 #include "termopts.h"
 #include "termchar.h"
-#include "disptab.h"
 #include "buffer.h"
 #include "window.h"
 #include "keyboard.h"
-#include "intervals.h"
-#include "process.h"
-#include "atimer.h"
-#include "keymap.h"
-#include "menu.h"
+#include "menu.h"      /* for w32_menu_show */
 
 #ifdef WINDOWSNT
 #include "w32.h"       /* for filename_from_utf16, filename_from_ansi */
-#include "w32heap.h"
 #endif
 
 #ifndef WINDOWSNT
@@ -65,6 +56,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "font.h"
 #include "w32font.h"
+
+#if 0  /* TODO: stipple */
+#include "bitmaps/gray.xbm"
+#endif
 \f
 /* Fringe bitmaps.  */
 
@@ -220,10 +215,6 @@ static void w32fullscreen_hook (struct frame *);
 static void x_check_font (struct frame *, struct font *);
 #endif
 
-static Lisp_Object Qvendor_specific_keysyms;
-static Lisp_Object Qadded, Qremoved, Qmodified;
-static Lisp_Object Qrenamed_from, Qrenamed_to;
-
 \f
 /***********************************************************************
                              Debugging
@@ -405,7 +396,13 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
   oldhb = SelectObject (hdc, hb);
   oldhp = SelectObject (hdc, hp);
 
-  Rectangle (hdc, x, y, x + width, y + height);
+  /* We enlarge WIDTH and HEIGHT by 1 to be bug-compatible to the
+     brain-dead design of XDrawRectangle, which draws a rectangle that
+     is 1 pixel wider and higher than its arguments WIDTH and HEIGHT.
+     This allows us to keep the code that calls this function similar
+     to the corresponding code in xterm.c.  For the details, see
+     http://lists.gnu.org/archives/html/emacs-devel/2014-10/msg00546.html.  */
+  Rectangle (hdc, x, y, x + width + 1, y + height + 1);
 
   SelectObject (hdc, oldhb);
   SelectObject (hdc, oldhp);
@@ -563,7 +560,7 @@ x_update_window_begin (struct window *w)
   if (f == hlinfo->mouse_face_mouse_frame)
     {
       /* Don't do highlighting for mouse motion during the update.  */
-      hlinfo->mouse_face_defer = 1;
+      hlinfo->mouse_face_defer = true;
 
       /* If F needs to be redrawn, simply forget about any prior mouse
         highlighting.  */
@@ -686,11 +683,11 @@ x_update_window_end (struct window *w, bool cursor_on_p,
       block_input ();
 
       if (cursor_on_p)
-       display_and_set_cursor (w, 1,
+       display_and_set_cursor (w, true,
                                w->output_cursor.hpos, w->output_cursor.vpos,
                                w->output_cursor.x, w->output_cursor.y);
 
-      if (draw_window_fringes (w, 1))
+      if (draw_window_fringes (w, true))
        {
          if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
            x_draw_right_divider (w);
@@ -732,7 +729,7 @@ x_update_end (struct frame *f)
     return;
 
   /* Mouse highlight may be displayed again.  */
-  MOUSE_HL_INFO (f)->mouse_face_defer = 0;
+  MOUSE_HL_INFO (f)->mouse_face_defer = false;
 }
 
 
@@ -762,7 +759,7 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
   eassert (w);
 
   if (!desired_row->mode_line_p && !w->pseudo_window_p)
-    desired_row->redraw_fringe_bitmaps_p = 1;
+    desired_row->redraw_fringe_bitmaps_p = true;
 
   /* When a window has disappeared, make sure that no rest of
      full-width rows stays visible in the internal border.  Could
@@ -907,7 +904,7 @@ w32_destroy_fringe_bitmap (int which)
 static void x_set_glyph_string_clipping (struct glyph_string *);
 static void x_set_glyph_string_gc (struct glyph_string *);
 static void x_draw_glyph_string_background (struct glyph_string *,
-                                            int);
+                                            bool);
 static void x_draw_glyph_string_foreground (struct glyph_string *);
 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
 static void x_draw_glyph_string_box (struct glyph_string *);
@@ -929,7 +926,7 @@ static void w32_draw_relief_rect (struct frame *, int, int, int, int,
                                   int, int, int, int, int, int,
                                   RECT *);
 static void w32_draw_box_rect (struct glyph_string *, int, int, int, int,
-                               int, int, int, RECT *);
+                               int, bool, bool, RECT *);
 
 
 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
@@ -1068,7 +1065,7 @@ x_set_glyph_string_gc (struct glyph_string *s)
   else if (s->hl == DRAW_CURSOR)
     {
       x_set_cursor_gc (s);
-      s->stippled_p = 0;
+      s->stippled_p = false;
     }
   else if (s->hl == DRAW_MOUSE_FACE)
     {
@@ -1194,7 +1191,7 @@ x_clear_glyph_string_rect (struct glyph_string *s,
    contains the first component of a composition.  */
 
 static void
-x_draw_glyph_string_background (struct glyph_string *s, int force_p)
+x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
 {
   /* Nothing to do if background has already been drawn or if it
      shouldn't be drawn in the first place.  */
@@ -1212,11 +1209,16 @@ x_draw_glyph_string_background (struct glyph_string *s, int force_p)
                          s->background_width,
                          s->height - 2 * box_line_width);
          XSetFillStyle (s->display, s->gc, FillSolid);
-         s->background_filled_p = 1;
+         s->background_filled_p = true;
        }
       else
 #endif
-        if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
+           if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
+              /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
+                 font dimensions, since the actual glyphs might be
+                 much smaller.  So in that case we always clear the
+                 rectangle with background color.  */
+              || FONT_TOO_HIGH (s->font)
               || s->font_not_found_p
               || s->extends_to_end_of_line_p
               || force_p)
@@ -1224,7 +1226,7 @@ x_draw_glyph_string_background (struct glyph_string *s, int force_p)
          x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
                                     s->background_width,
                                     s->height - 2 * box_line_width);
-         s->background_filled_p = 1;
+         s->background_filled_p = true;
        }
     }
 }
@@ -1277,11 +1279,11 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
       y = s->ybase - boff;
       if (s->for_overlaps
          || (s->background_filled_p && s->hl != DRAW_CURSOR))
-       font->driver->draw (s, 0, s->nchars, x, y, 0);
+       font->driver->draw (s, 0, s->nchars, x, y, false);
       else
-       font->driver->draw (s, 0, s->nchars, x, y, 1);
+       font->driver->draw (s, 0, s->nchars, x, y, true);
       if (s->face->overstrike)
-       font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
+       font->driver->draw (s, 0, s->nchars, x + 1, y, false);
 
       SelectObject (s->hdc, old_font);
     }
@@ -1335,9 +1337,9 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
            int xx = x + s->cmp->offsets[j * 2];
            int yy = y - s->cmp->offsets[j * 2 + 1];
 
-           font->driver->draw (s, j, j + 1, xx, yy, 0);
+           font->driver->draw (s, j, j + 1, xx, yy, false);
            if (s->face->overstrike)
-             font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
+             font->driver->draw (s, j, j + 1, xx + 1, yy, false);
          }
       SelectObject (s->hdc, old_font);
     }
@@ -1362,20 +1364,20 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
 
              if (j < i)
                {
-                 font->driver->draw (s, j, i, x, y, 0);
+                 font->driver->draw (s, j, i, x, y, false);
                  x += width;
                }
              xoff = LGLYPH_XOFF (glyph);
              yoff = LGLYPH_YOFF (glyph);
              wadjust = LGLYPH_WADJUST (glyph);
-             font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
+             font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
              x += wadjust;
              j = i + 1;
              width = 0;
            }
        }
       if (j < i)
-       font->driver->draw (s, j, i, x, y, 0);
+       font->driver->draw (s, j, i, x, y, false);
 
       SelectObject (s->hdc, old_font);
     }
@@ -1390,7 +1392,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
   struct glyph *glyph = s->first_glyph;
   XChar2b char2b[8];
   int x, i, j;
-  int with_background;
+  bool with_background;
 
   /* If first glyph of S has a left box line, start drawing the text
      of S to the right of that box line.  */
@@ -1405,8 +1407,8 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
   s->char2b = char2b;
-  with_background = (s->for_overlaps
-                      || (s->background_filled_p && s->hl != DRAW_CURSOR));
+  with_background = ((s->for_overlaps
+                     || (s->background_filled_p && s->hl != DRAW_CURSOR))) == 0;
   for (i = 0; i < s->nchars; i++, glyph++)
     {
       char buf[7], *str = NULL;
@@ -1414,7 +1416,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
 
       if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
        {
-         if (len > 1
+         if (len > 0
              && CHAR_TABLE_P (Vglyphless_char_display)
              && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
                  >= 1))
@@ -1589,7 +1591,9 @@ w32_setup_relief_color (struct frame *f, struct relief *relief, double factor,
   unsigned long mask = GCForeground;
   COLORREF pixel;
   COLORREF background = di->relief_background;
+#if 0
   struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+#endif
 
   /* TODO: Free colors (if using palette)? */
 
@@ -1716,7 +1720,7 @@ w32_draw_relief_rect (struct frame *f,
 static void
 w32_draw_box_rect (struct glyph_string *s,
                   int left_x, int top_y, int right_x, int bottom_y, int width,
-                   int left_p, int right_p, RECT *clip_rect)
+                   bool left_p, bool right_p, RECT *clip_rect)
 {
   w32_set_clip_rectangle (s->hdc, clip_rect);
 
@@ -1751,8 +1755,8 @@ w32_draw_box_rect (struct glyph_string *s,
 static void
 x_draw_glyph_string_box (struct glyph_string *s)
 {
-  int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
-  int left_p, right_p;
+  int width, left_x, right_x, top_y, bottom_y, last_x;
+  bool left_p, right_p, raised_p;
   struct glyph *last_glyph;
   RECT clip_rect;
 
@@ -2161,7 +2165,7 @@ x_draw_image_glyph_string (struct glyph_string *s)
 #endif
        x_draw_glyph_string_bg_rect (s, x, y, width, height);
 
-      s->background_filled_p = 1;
+      s->background_filled_p = true;
     }
 
   /* Draw the foreground.  */
@@ -2297,7 +2301,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
        x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
     }
 
-  s->background_filled_p = 1;
+  s->background_filled_p = true;
 }
 
 
@@ -2325,7 +2329,7 @@ x_draw_glyph_string (struct glyph_string *s)
            if (next->first_glyph->type == STRETCH_GLYPH)
              x_draw_stretch_glyph_string (next);
            else
-             x_draw_glyph_string_background (next, 1);
+             x_draw_glyph_string_background (next, true);
             next->num_clips = 0;
           }
     }
@@ -2342,7 +2346,7 @@ x_draw_glyph_string (struct glyph_string *s)
 
     {
       x_set_glyph_string_clipping (s);
-      x_draw_glyph_string_background (s, 1);
+      x_draw_glyph_string_background (s, true);
       x_draw_glyph_string_box (s);
       x_set_glyph_string_clipping (s);
       relief_drawn_p = 1;
@@ -2370,26 +2374,26 @@ x_draw_glyph_string (struct glyph_string *s)
 
     case CHAR_GLYPH:
       if (s->for_overlaps)
-       s->background_filled_p = 1;
+       s->background_filled_p = true;
       else
-        x_draw_glyph_string_background (s, 0);
+        x_draw_glyph_string_background (s, false);
       x_draw_glyph_string_foreground (s);
       break;
 
     case COMPOSITE_GLYPH:
       if (s->for_overlaps || (s->cmp_from > 0
                              && ! s->first_glyph->u.cmp.automatic))
-       s->background_filled_p = 1;
+       s->background_filled_p = true;
       else
-       x_draw_glyph_string_background (s, 1);
+       x_draw_glyph_string_background (s, true);
       x_draw_composite_glyph_string_foreground (s);
       break;
 
     case GLYPHLESS_GLYPH:
       if (s->for_overlaps)
-       s->background_filled_p = 1;
+       s->background_filled_p = true;
       else
-       x_draw_glyph_string_background (s, 0);
+       x_draw_glyph_string_background (s, false);
       x_draw_glyphless_glyph_string_foreground (s);
       break;
 
@@ -3227,7 +3231,7 @@ queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
   if (notification_buffer_in_use)
     {
       DWORD info_size = notifications_size;
-      Lisp_Object cs = intern ("utf-16le");
+      Lisp_Object cs = Qutf_16le;
       Lisp_Object obj = w32_get_watch_object (notifications_desc);
 
       /* notifications_size could be zero when the buffer of
@@ -3251,12 +3255,11 @@ queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
              Lisp_Object action = lispy_file_action (fni->Action);
 
              event->kind = FILE_NOTIFY_EVENT;
-             event->code
-               = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc));
              event->timestamp = msg->msg.time;
              event->modifiers = 0;
              event->frame_or_window = callback;
-             event->arg = Fcons (action, fname);
+             event->arg = list3 (make_pointer_integer (notifications_desc),
+                                 action, fname);
              kbd_buffer_store_event (event);
              (*evcount)++;
 
@@ -3307,7 +3310,7 @@ note_mouse_movement (struct frame *frame, MSG *msg)
 
   if (msg->hwnd != FRAME_W32_WINDOW (frame))
     {
-      frame->mouse_moved = 1;
+      frame->mouse_moved = true;
       dpyinfo->last_mouse_scroll_bar = NULL;
       note_mouse_highlight (frame, -1, -1);
       dpyinfo->last_mouse_glyph_frame = NULL;
@@ -3320,7 +3323,7 @@ note_mouse_movement (struct frame *frame, MSG *msg)
       || mouse_x < r->left || mouse_x >= r->right
       || mouse_y < r->top  || mouse_y >= r->bottom)
     {
-      frame->mouse_moved = 1;
+      frame->mouse_moved = true;
       dpyinfo->last_mouse_scroll_bar = NULL;
       note_mouse_highlight (frame, mouse_x, mouse_y);
       /* Remember the mouse position here, as w32_mouse_position only
@@ -3349,8 +3352,6 @@ static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object
                                                   enum scroll_bar_part *,
                                                   Lisp_Object *, Lisp_Object *,
                                                   Time *);
-static void x_check_fullscreen (struct frame *);
-
 static void
 w32_define_cursor (Window window, Cursor cursor)
 {
@@ -3404,7 +3405,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 
       /* Clear the mouse-moved flag for every frame on this display.  */
       FOR_EACH_FRAME (tail, frame)
-       XFRAME (frame)->mouse_moved = 0;
+       XFRAME (frame)->mouse_moved = false;
 
       dpyinfo->last_mouse_scroll_bar = NULL;
 
@@ -3615,8 +3616,8 @@ w32_set_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
   si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
   si.nMin = 0;
   si.nMax = whole;
-  /* Allow nPage to be one larger than nPos so we don't allow to scroll
-     an already fully visible buffer.  */
+  /* Allow nPage to be one larger than nPos so we don't allow the scrolling
+     of an already fully visible buffer.  */
   si.nPage = min (portion, si.nMax) + 1;
   si.nPos = min (position, si.nMax);
   SetScrollInfo (w, SB_CTL, &si, TRUE);
@@ -3827,7 +3828,7 @@ w32_set_vertical_scroll_bar (struct window *w,
        }
       unblock_input ();
 
-      bar = x_scroll_bar_create (w, left, top, width, height, 0);
+      bar = x_scroll_bar_create (w, left, top, width, height, false);
     }
   else
     {
@@ -3927,7 +3928,7 @@ w32_set_horizontal_scroll_bar (struct window *w,
        }
       unblock_input ();
 
-      bar = x_scroll_bar_create (w, left, top, width, height, 1);
+      bar = x_scroll_bar_create (w, left, top, width, height, true);
     }
   else
     {
@@ -4346,8 +4347,6 @@ w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
        if (dragging)
          {
            SCROLLINFO si;
-           int start = bar->start;
-           int end = bar->end;
 
            si.cbSize = sizeof (si);
            si.fMask = SIF_POS;
@@ -4410,7 +4409,7 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
   XSETINT (*x, pos);
   XSETINT (*y, top_range);
 
-  f->mouse_moved = 0;
+  f->mouse_moved = false;
   dpyinfo->last_mouse_scroll_bar = NULL;
 
   *time = dpyinfo->last_mouse_movement_time;
@@ -4461,7 +4460,7 @@ x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_windo
   XSETINT (*y, pos);
   XSETINT (*x, left_range);
 
-  f->mouse_moved = 0;
+  f->mouse_moved = false;
   dpyinfo->last_mouse_scroll_bar = NULL;
 
   *time = dpyinfo->last_mouse_movement_time;
@@ -4505,18 +4504,6 @@ x_scroll_bar_clear (struct frame *f)
       }
 }
 
-static void
-set_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
-{
-  register Lisp_Object old_alist_elt;
-
-  old_alist_elt = Fassq (prop, f->param_alist);
-  if (EQ (old_alist_elt, Qnil))
-    fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist));
-  else
-    Fsetcdr (old_alist_elt, val);
-}
-
 /* The main W32 event-reading loop - w32_read_socket.  */
 
 /* Record the last 100 characters stored
@@ -4601,7 +4588,7 @@ w32_read_socket (struct terminal *terminal,
 
                  /* Definitely not obscured, so mark as visible.  */
                  SET_FRAME_VISIBLE (f, 1);
-                 SET_FRAME_ICONIFIED (f, 0);
+                 SET_FRAME_ICONIFIED (f, false);
                  SET_FRAME_GARBAGED (f);
                  if (!f->output_data.w32->asked_for_visible)
                    DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
@@ -4663,7 +4650,7 @@ w32_read_socket (struct terminal *terminal,
                  && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
                {
                  clear_mouse_face (hlinfo);
-                 hlinfo->mouse_face_hidden = 1;
+                 hlinfo->mouse_face_hidden = true;
                }
 
              if (temp_index == sizeof temp_buffer / sizeof (short))
@@ -4688,7 +4675,7 @@ w32_read_socket (struct terminal *terminal,
                  && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
                {
                  clear_mouse_face (hlinfo);
-                 hlinfo->mouse_face_hidden = 1;
+                 hlinfo->mouse_face_hidden = true;
                }
 
              if (temp_index == sizeof temp_buffer / sizeof (short))
@@ -4766,7 +4753,7 @@ w32_read_socket (struct terminal *terminal,
                  && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
                {
                  clear_mouse_face (hlinfo);
-                 hlinfo->mouse_face_hidden = 1;
+                 hlinfo->mouse_face_hidden = true;
                }
 
              if (temp_index == sizeof temp_buffer / sizeof (short))
@@ -4799,7 +4786,7 @@ w32_read_socket (struct terminal *terminal,
 
          if (hlinfo->mouse_face_hidden)
            {
-             hlinfo->mouse_face_hidden = 0;
+             hlinfo->mouse_face_hidden = false;
              clear_mouse_face (hlinfo);
            }
 
@@ -4918,7 +4905,7 @@ w32_read_socket (struct terminal *terminal,
                    the ButtonPress.  */
                 if (f != 0)
                  {
-                   f->mouse_moved = 0;
+                   f->mouse_moved = false;
                    if (!tool_bar_p)
                      f->last_tool_bar_item = -1;
                  }
@@ -4945,7 +4932,7 @@ w32_read_socket (struct terminal *terminal,
                   event; any subsequent mouse-movement Emacs events
                   should reflect only motion after the
                   ButtonPress.  */
-               f->mouse_moved = 0;
+               f->mouse_moved = false;
                f->last_tool_bar_item = -1;
              }
            dpyinfo->last_mouse_frame = f;
@@ -4994,8 +4981,12 @@ w32_read_socket (struct terminal *terminal,
                 sets the WAIT flag.  */
              if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam)
                  && (f->want_fullscreen & FULLSCREEN_WAIT))
-               w32fullscreen_hook (f);
-             x_check_fullscreen (f);
+               {
+                 /* Must set visibility right here since otherwise
+                    w32fullscreen_hook returns immediately.  */
+                 SET_FRAME_VISIBLE (f, 1);
+                 w32fullscreen_hook (f);
+               }
            }
          check_visibility = 1;
          break;
@@ -5046,7 +5037,7 @@ w32_read_socket (struct terminal *terminal,
                {
                case SIZE_MINIMIZED:
                  SET_FRAME_VISIBLE (f, 0);
-                 SET_FRAME_ICONIFIED (f, 1);
+                 SET_FRAME_ICONIFIED (f, true);
 
                  inev.kind = ICONIFY_EVENT;
                  XSETFRAME (inev.frame_or_window, f);
@@ -5055,9 +5046,10 @@ w32_read_socket (struct terminal *terminal,
                case SIZE_MAXIMIZED:
                  {
                    bool iconified = FRAME_ICONIFIED_P (f);
+                   Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
 
                    SET_FRAME_VISIBLE (f, 1);
-                   SET_FRAME_ICONIFIED (f, 0);
+                   SET_FRAME_ICONIFIED (f, false);
 
                    /* wait_reading_process_output will notice this
                       and update the frame's display structures.  */
@@ -5085,12 +5077,22 @@ w32_read_socket (struct terminal *terminal,
                         to update the frame titles
                         in case this is the second frame.  */
                      record_asynch_buffer_change ();
-                 }
 
-                 if (EQ (get_frame_param (f, Qfullscreen), Qnil))
-                   set_frame_param (f, Qfullscreen, Qmaximized);
-                 else if (! EQ (get_frame_param (f, Qfullscreen), Qmaximized))
-                   set_frame_param (f, Qmaximized, Qmaximized);
+                 /* Windows can send us a SIZE_MAXIMIZED message even
+                    when fullscreen is fullboth.  The following is a
+                    simple hack to check that based on the fact that
+                    only a maximized fullscreen frame should have both
+                    top/left outside the screen.  */
+                 if (EQ (fullscreen, Qfullwidth) || EQ (fullscreen, Qfullheight)
+                     || NILP (fullscreen))
+                     {
+                       int x, y;
+
+                       x_real_positions (f, &x, &y);
+                       if (x < 0 && y < 0)
+                         store_frame_param (f, Qfullscreen, Qmaximized);
+                     }
+                 }
 
                  break;
 
@@ -5104,7 +5106,7 @@ w32_read_socket (struct terminal *terminal,
                       conditional again in revision 116727.  martin */
                    if (iconified)
                      SET_FRAME_VISIBLE (f, 1);
-                   SET_FRAME_ICONIFIED (f, 0);
+                   SET_FRAME_ICONIFIED (f, false);
 
                    /* wait_reading_process_output will notice this
                       and update the frame's display structures.  */
@@ -5131,9 +5133,7 @@ w32_read_socket (struct terminal *terminal,
                  }
 
                  if (EQ (get_frame_param (f, Qfullscreen), Qmaximized))
-                   set_frame_param (f, Qfullscreen, Qnil);
-                 else if (! EQ (get_frame_param (f, Qmaximized), Qnil))
-                   set_frame_param (f, Qmaximized, Qnil);
+                   store_frame_param (f, Qfullscreen, Qnil);
 
                  break;
                }
@@ -5142,7 +5142,7 @@ w32_read_socket (struct terminal *terminal,
          if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED)
            {
              RECT rect;
-             int rows, columns, width, height, text_width, text_height;
+             int /* rows, columns, */ width, height, text_width, text_height;
 
              if (GetClientRect (msg.msg.hwnd, &rect)
                  /* GetClientRect evidently returns (0, 0, 0, 0) if
@@ -5274,11 +5274,18 @@ w32_read_socket (struct terminal *terminal,
 
          if (f)
            {
+             Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
+
              dpyinfo->n_cbits = msg.msg.wParam;
              /* The new display could have a different resolution, in
-                which case we must reconsider what fullscreen
-                means.  */
-             x_check_fullscreen (f);
+                which case we must reconsider what fullscreen means.
+                The following code is untested yet.  */
+             if (!NILP (fullscreen))
+               {
+                 x_set_fullscreen (f, fullscreen, fullscreen);
+                 w32fullscreen_hook (f);
+               }
+
              DebPrint (("display change: %d %d\n",
                         (short) LOWORD (msg.msg.lParam),
                         (short) HIWORD (msg.msg.lParam)));
@@ -5641,7 +5648,7 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
          w->phys_cursor_type = cursor_type;
        }
 
-      w->phys_cursor_on_p = 1;
+      w->phys_cursor_on_p = true;
 
       /* If this is the active cursor, we need to track it with the
         system caret, so third party software like screen magnifiers
@@ -5679,7 +5686,7 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
              ? (w->phys_cursor.hpos < 0)
              : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
        {
-         glyph_row->cursor_in_fringe_p = 1;
+         glyph_row->cursor_in_fringe_p = true;
          draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
          return;
        }
@@ -5808,7 +5815,7 @@ Lisp_Object
 x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 {
   struct font *font = XFONT_OBJECT (font_object);
-  int unit;
+  int unit, font_ascent, font_descent;
 
   if (fontset < 0)
     fontset = fontset_from_font (font_object);
@@ -5821,7 +5828,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
   FRAME_FONT (f) = font;
   FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
   FRAME_COLUMN_WIDTH (f) = unit = font->average_width;
-  FRAME_LINE_HEIGHT (f) = font->height;
+  get_font_ascent_descent (font, &font_ascent, &font_descent);
+  FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
 
   /* Compute number of scrollbar columns.  */
   unit = FRAME_COLUMN_WIDTH (f);
@@ -5843,7 +5851,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
         problems because the tip frame has no widget.  */
       if (NILP (tip_frame) || XFRAME (tip_frame) != f)
        adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
-                          FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0, Qfont);
+                          FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
+                          false, Qfont);
     }
 
   /* X version sets font of input methods here also.  */
@@ -5905,16 +5914,49 @@ x_calc_absolute_position (struct frame *f)
       top_bottom_borders_height = 32;
     }
 
+  /* With multiple monitors, we can legitimately get negative
+     coordinates (for monitors above or to the left of the primary
+     monitor).  Find the display origin to ensure negative positions
+     are computed correctly (Bug#21173).  */
+  int display_left = 0;
+  int display_top = 0;
+  if (flags & (XNegative | YNegative))
+    {
+      Lisp_Object list;
+
+      list = Fw32_display_monitor_attributes_list (Qnil);
+      while (CONSP (list))
+        {
+          Lisp_Object attributes = CAR(list);
+          Lisp_Object geometry;
+          Lisp_Object monitor_left, monitor_top;
+
+          list = CDR(list);
+
+          geometry = Fassoc (Qgeometry, attributes);
+          if (!NILP (geometry))
+            {
+              monitor_left = Fnth (make_number (1), geometry);
+              monitor_top  = Fnth (make_number (2), geometry);
+
+              display_left = min (display_left, XINT (monitor_left));
+              display_top  = min (display_top,  XINT (monitor_top));
+            }
+        }
+    }
+
   /* Treat negative positions as relative to the rightmost bottommost
      position that fits on the screen.  */
   if (flags & XNegative)
     f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f))
+                   + display_left
                   - FRAME_PIXEL_WIDTH (f)
                   + f->left_pos
                   - (left_right_borders_width - 1));
 
   if (flags & YNegative)
     f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
+                  + display_top
                  - FRAME_PIXEL_HEIGHT (f)
                  + f->top_pos
                  - (top_bottom_borders_height - 1));
@@ -5950,7 +5992,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff,
   x_calc_absolute_position (f);
 
   block_input ();
-  x_wm_set_size_hint (f, (long) 0, 0);
+  x_wm_set_size_hint (f, (long) 0, false);
 
   modified_left = f->left_pos;
   modified_top = f->top_pos;
@@ -5963,75 +6005,6 @@ x_set_offset (struct frame *f, register int xoff, register int yoff,
   unblock_input ();
 }
 
-/* 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).
- */
-
-static void
-x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int *left_pos)
-{
-  int newwidth = FRAME_COLS (f);
-  int newheight = FRAME_LINES (f);
-  Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
-
-  *top_pos = f->top_pos;
-  *left_pos = f->left_pos;
-
-  if (f->want_fullscreen & FULLSCREEN_HEIGHT)
-    {
-      int ph;
-
-      ph = x_display_pixel_height (dpyinfo);
-      newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
-      ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
-      newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
-      *top_pos = 0;
-    }
-
-  if (f->want_fullscreen & FULLSCREEN_WIDTH)
-    {
-      int pw;
-
-      pw = x_display_pixel_width (dpyinfo);
-      newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
-      pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
-      newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
-      *left_pos = 0;
-    }
-
-  *width = newwidth;
-  *height = newheight;
-}
-
-/* Check if we need to resize the frame due to a fullscreen request.
-   If so needed, resize the frame.  */
-static void
-x_check_fullscreen (struct frame *f)
-{
-  if (f->want_fullscreen & FULLSCREEN_BOTH)
-    {
-      int width, height, ign;
-
-      x_real_positions (f, &f->left_pos, &f->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 (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
-        {
-          change_frame_size (f, width, height, 0, 1, 0, 0);
-          SET_FRAME_GARBAGED (f);
-          cancel_mouse_face (f);
-
-          /* Wait for the change of frame size to occur.  */
-          f->want_fullscreen |= FULLSCREEN_WAIT;
-        }
-    }
-}
-
 static void
 w32fullscreen_hook (struct frame *f)
 {
@@ -6072,12 +6045,19 @@ w32fullscreen_hook (struct frame *f)
        }
       else if (f->want_fullscreen == FULLSCREEN_BOTH)
         {
+         int menu_bar_height = GetSystemMetrics (SM_CYMENU);
+
          w32_fullscreen_rect (hwnd, f->want_fullscreen,
                               FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
           SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
           SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
                         rect.right - rect.left, rect.bottom - rect.top,
                         SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+         change_frame_size
+           (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, rect.right - rect.left),
+            FRAME_PIXEL_TO_TEXT_HEIGHT (f, (rect.bottom - rect.top
+                                            - menu_bar_height)),
+            0, 1, 0, 1);
         }
       else
         {
@@ -6086,10 +6066,39 @@ w32fullscreen_hook (struct frame *f)
                               FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
           SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
                         rect.right - rect.left, rect.bottom - rect.top, 0);
+
+         if (f->want_fullscreen == FULLSCREEN_WIDTH)
+           {
+             int border_width = GetSystemMetrics (SM_CXFRAME);
+
+             change_frame_size
+               (f, (FRAME_PIXEL_TO_TEXT_WIDTH
+                    (f, rect.right - rect.left - 2 * border_width)),
+                0, 0, 1, 0, 1);
+           }
+         else
+           {
+             int border_height = GetSystemMetrics (SM_CYFRAME);
+             /* Won't work for wrapped menu bar.  */
+             int menu_bar_height = GetSystemMetrics (SM_CYMENU);
+             int title_height = GetSystemMetrics (SM_CYCAPTION);
+
+             change_frame_size
+               (f, 0, (FRAME_PIXEL_TO_TEXT_HEIGHT
+                       (f, rect.bottom - rect.top - 2 * border_height
+                        - title_height - menu_bar_height)),
+                0, 1, 0, 1);
+           }
         }
 
       f->want_fullscreen = FULLSCREEN_NONE;
       unblock_input ();
+
+      if (f->want_fullscreen == FULLSCREEN_BOTH
+         || f->want_fullscreen == FULLSCREEN_WIDTH
+         || f->want_fullscreen == FULLSCREEN_HEIGHT)
+       do_pending_window_change (0);
+
     }
   else
     f->want_fullscreen |= FULLSCREEN_WAIT;
@@ -6105,10 +6114,24 @@ x_set_window_size (struct frame *f, bool change_gravity,
                   int width, int height, bool pixelwise)
 {
   int pixelwidth, pixelheight;
+  Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
   RECT rect;
+  MENUBARINFO info;
+  int menu_bar_height;
 
   block_input ();
 
+  /* Get the height of the menu bar here.  It's used below to detect
+     whether the menu bar is wrapped.  It's also used to specify the
+     third argument for AdjustWindowRect.  FRAME_EXTERNAL_MENU_BAR which
+     has been used before for that reason is unreliable because it only
+     specifies whether we _want_ a menu bar for this frame and not
+     whether this frame _has_ a menu bar.  See bug#22105.  */
+  info.cbSize = sizeof (info);
+  info.rcBar.top = info.rcBar.bottom = 0;
+  GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info);
+  menu_bar_height = info.rcBar.bottom - info.rcBar.top;
+
   if (pixelwise)
     {
       pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
@@ -6123,20 +6146,14 @@ x_set_window_size (struct frame *f, bool change_gravity,
   if (w32_add_wrapped_menu_bar_lines)
     {
       /* When the menu bar wraps sending a SetWindowPos shrinks the
-        height of the frame when the wrapped menu bar lines are not
+        height of the frame then the wrapped menu bar lines are not
         accounted for (Bug#15174 and Bug#18720).  Here we add these
         extra lines to the frame height.  */
-      MENUBARINFO info;
       int default_menu_bar_height;
-      int menu_bar_height;
 
       /* Why is (apparently) SM_CYMENUSIZE needed here instead of
         SM_CYMENU ??  */
       default_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
-      info.cbSize = sizeof (info);
-      info.rcBar.top = info.rcBar.bottom = 0;
-      GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info);
-      menu_bar_height = info.rcBar.bottom - info.rcBar.top;
 
       if ((default_menu_bar_height > 0)
          && (menu_bar_height > default_menu_bar_height)
@@ -6145,57 +6162,60 @@ x_set_window_size (struct frame *f, bool change_gravity,
     }
 
   f->win_gravity = NorthWestGravity;
-  x_wm_set_size_hint (f, (long) 0, 0);
-
-  f->want_fullscreen = FULLSCREEN_NONE;
-  w32fullscreen_hook (f);
+  x_wm_set_size_hint (f, (long) 0, false);
 
   rect.left = rect.top = 0;
   rect.right = pixelwidth;
   rect.bottom = pixelheight;
 
-  AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
-                   FRAME_EXTERNAL_MENU_BAR (f));
+  AdjustWindowRect (&rect, f->output_data.w32->dwStyle, menu_bar_height > 0);
 
-  my_set_window_pos (FRAME_W32_WINDOW (f),
-                    NULL,
-                    0, 0,
-                    rect.right - rect.left,
-                    rect.bottom - rect.top,
-                    SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
-
-  /* If w32_enable_frame_resize_hack is non-nil, immediately apply the
-     new pixel sizes to the frame and its subwindows.
-
-     Jason Rumney earlier refused to call change_frame_size right here
-     with the following argument:
-
-     The following mirrors what is done in xterm.c. It appears to be for
-     informing lisp of the new size immediately, while the actual resize
-     will happen asynchronously. But on Windows, the menu bar
-     automatically wraps when the frame is too narrow to contain it, and
-     that causes any calculations made here to come out wrong.  The end
-     is some nasty buggy behavior, including the potential loss of the
-     minibuffer.
-
-     Disabling this code is either not sufficient to fix the problems
-     completely, or it causes fresh problems, but at least it removes
-     the most problematic symptom of the minibuffer becoming unusable.
-
-     However, as the discussion about how to handle frame size
-     parameters on Windows (Bug#1348, Bug#16028) shows, that cure seems
-     worse than the disease.  In particular, menu bar wrapping looks
-     like a non-issue - maybe so because Windows eventually gets back to
-     us with the correct client rectangle anyway.  But we have to avoid
-     calling change_frame_size with a delta of less than one canoncial
-     character size when frame_resize_pixelwise is nil, as explained in
-     the comment above.  */
-
-  if (w32_enable_frame_resize_hack)
+  if (!(f->after_make_frame)
+      && !(f->want_fullscreen & FULLSCREEN_WAIT)
+      && FRAME_VISIBLE_P (f))
+    {
+      RECT window_rect;
 
+      GetWindowRect (FRAME_W32_WINDOW (f), &window_rect);
+
+      if (EQ (fullscreen, Qmaximized)
+         || EQ (fullscreen, Qfullboth)
+         || EQ (fullscreen, Qfullwidth))
+       {
+         rect.left = window_rect.left;
+         rect.right = window_rect.right;
+         pixelwidth = 0;
+       }
+      if (EQ (fullscreen, Qmaximized)
+         || EQ (fullscreen, Qfullboth)
+         || EQ (fullscreen, Qfullheight))
+       {
+         rect.top = window_rect.top;
+         rect.bottom = window_rect.bottom;
+         pixelheight = 0;
+       }
+    }
+
+  if (pixelwidth > 0 || pixelheight > 0)
     {
-      change_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth),
-                        FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight),
+      frame_size_history_add
+       (f, Qx_set_window_size_1, width, height,
+        list2 (Fcons (make_number (pixelwidth),
+                      make_number (pixelheight)),
+               Fcons (make_number (rect.right - rect.left),
+                      make_number (rect.bottom - rect.top))));
+
+      my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
+                        0, 0,
+                        rect.right - rect.left,
+                        rect.bottom - rect.top,
+                        SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
+
+      change_frame_size (f,
+                        ((pixelwidth == 0)
+                            ? 0 : FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth)),
+                        ((pixelheight == 0)
+                         ? 0 : FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)),
                         0, 1, 0, 1);
       SET_FRAME_GARBAGED (f);
 
@@ -6212,7 +6232,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
 
   unblock_input ();
 
-  do_pending_window_change (0);
+  do_pending_window_change (false);
 }
 \f
 /* Mouse warping.  */
@@ -6220,6 +6240,8 @@ x_set_window_size (struct frame *f, bool change_gravity,
 void
 frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
 {
+  UINT trail_num = 0;
+  BOOL ret = false;
   RECT rect;
   POINT pt;
 
@@ -6230,7 +6252,15 @@ frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
   pt.y = rect.top + pix_y;
   ClientToScreen (FRAME_W32_WINDOW (f), &pt);
 
+  /* When "mouse trails" are in effect, moving the mouse cursor
+     sometimes leaves behind an annoying "ghost" of the pointer.
+     Avoid that by momentarily switching off mouse trails.  */
+  if (os_subtype == OS_NT
+      && w32_major_version + w32_minor_version >= 6)
+    ret = SystemParametersInfo (SPI_GETMOUSETRAILS, 0, &trail_num, 0);
   SetCursorPos (pt.x, pt.y);
+  if (ret)
+    SystemParametersInfo (SPI_SETMOUSETRAILS, trail_num, NULL, 0);
 
   unblock_input ();
 }
@@ -6457,7 +6487,7 @@ x_make_frame_invisible (struct frame *f)
      FRAME_SAMPLE_VISIBILITY set this.  So do it by hand,
      and synchronize with the server to make sure we agree.  */
   SET_FRAME_VISIBLE (f, 0);
-  SET_FRAME_ICONIFIED (f, 0);
+  SET_FRAME_ICONIFIED (f, false);
 
   unblock_input ();
 }
@@ -6482,7 +6512,7 @@ x_iconify_frame (struct frame *f)
   SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
 
   SET_FRAME_VISIBLE (f, 0);
-  SET_FRAME_ICONIFIED (f, 1);
+  SET_FRAME_ICONIFIED (f, true);
 
   unblock_input ();
 }
@@ -6599,7 +6629,10 @@ w32_hide_hourglass (struct frame *f)
   struct w32_output *w32 = FRAME_X_OUTPUT (f);
 
   w32->hourglass_p = 0;
-  SetCursor (w32->current_cursor);
+  if (f->pointer_invisible)
+    SetCursor (NULL);
+  else
+    SetCursor (w32->current_cursor);
 }
 
 /* FIXME: old code did that, but I don't know why.  Anyway,
@@ -6611,6 +6644,21 @@ w32_arrow_cursor (void)
   SetCursor (w32_load_cursor (IDC_ARROW));
 }
 
+static void
+w32_toggle_invisible_pointer (struct frame *f, bool invisible)
+{
+  block_input ();
+
+  if (f->pointer_invisible != invisible)
+    {
+      f->pointer_invisible = invisible;
+      w32_define_cursor (FRAME_W32_WINDOW (f),
+                        f->output_data.w32->current_cursor);
+    }
+
+  unblock_input ();
+}
+
 /***********************************************************************
                            Initialization
  ***********************************************************************/
@@ -6750,6 +6798,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
   terminal->ins_del_lines_hook = x_ins_del_lines;
   terminal->delete_glyphs_hook = x_delete_glyphs;
   terminal->ring_bell_hook = w32_ring_bell;
+  terminal->toggle_invisible_pointer_hook = w32_toggle_invisible_pointer;
   terminal->update_begin_hook = x_update_begin;
   terminal->update_end_hook = x_update_end;
   terminal->read_socket_hook = w32_read_socket;
@@ -6895,6 +6944,15 @@ x_delete_display (struct w32_display_info *dpyinfo)
 \f
 /* Set up use of W32.  */
 
+void
+w32_init_main_thread (void)
+{
+  dwMainThreadId = GetCurrentThreadId ();
+  DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
+                  GetCurrentProcess (), &hMainThread, 0, TRUE,
+                  DUPLICATE_SAME_ACCESS);
+}
+
 DWORD WINAPI w32_msg_worker (void * arg);
 
 static void
@@ -6955,10 +7013,6 @@ w32_initialize (void)
      terminates */
   init_crit ();
 
-  dwMainThreadId = GetCurrentThreadId ();
-  DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
-                  GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
-
   /* Wait for thread to start */
   {
     MSG msg;
@@ -7106,7 +7160,7 @@ Windows 8.  It is set to nil on Windows 9X.  */);
   w32_unicode_filenames = 0;
 
 
-  /* FIXME: The following two variables will be (hopefully) removed
+  /* FIXME: The following variable will be (hopefully) removed
      before Emacs 25.1 gets released.  */
 
   DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines",
@@ -7120,16 +7174,6 @@ wrapped menu bar lines when sending frame resize requests to the Windows
 API.  */);
   w32_add_wrapped_menu_bar_lines = 1;
 
-  DEFVAR_BOOL ("w32-enable-frame-resize-hack",
-              w32_enable_frame_resize_hack,
-     doc: /* Non-nil means enable hack for frame resizing on Windows.
-A value of nil means to resize frames by sending a corresponding request
-to the Windows API and changing the pixel sizes of the frame and its
-windows after the latter calls back.  If this is non-nil, Emacs changes
-the pixel sizes of the frame and its windows at the time it sends the
-resize request to the API.  */);
-  w32_enable_frame_resize_hack = 1;
-
   /* Tell Emacs about this window system.  */
   Fprovide (Qw32, Qnil);
 }