(save-match-data): Add comment about using evaporate arg
[bpt/emacs.git] / src / w32fns.c
index fc40f5f..6a2f98c 100644 (file)
@@ -1,5 +1,5 @@
 /* Graphical user interface functions for the Microsoft W32 API.
-   Copyright (C) 1989, 92, 93, 94, 95, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright (C) 1989, 1992, 93, 94, 95, 96, 97, 98, 99, 2000, 01, 04
      Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -64,6 +64,7 @@ extern double atof ();
 extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));
 extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));
 extern void w32_free_menu_strings P_ ((HWND));
+extern XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, int));
 
 extern int quit_char;
 
@@ -88,7 +89,7 @@ Lisp_Object Vw32_pass_alt_to_system;
 Lisp_Object Vw32_alt_is_meta;
 
 /* If non-zero, the windows virtual key code for an alternative quit key. */
-Lisp_Object Vw32_quit_key;
+int w32_quit_key;
 
 /* Non nil if left window key events are passed on to Windows (this only
    affects whether "tapping" the key opens the Start menu).  */
@@ -132,11 +133,11 @@ Lisp_Object Vw32_enable_palette;
 
 /* Control how close left/right button down events must be to
    be converted to a middle button down event. */
-Lisp_Object Vw32_mouse_button_tolerance;
+int w32_mouse_button_tolerance;
 
 /* Minimum interval between mouse movement (and scroll bar drag)
    events that are passed on to the event loop. */
-Lisp_Object Vw32_mouse_move_interval;
+int w32_mouse_move_interval;
 
 /* Flag to indicate if XBUTTON events should be passed on to Windows.  */
 int w32_pass_extra_mouse_buttons_to_system;
@@ -235,7 +236,7 @@ Lisp_Object Qw32_charset_unicode;
 #endif
 
 /* The ANSI codepage.  */
-Lisp_Object Vw32_ansi_code_page;
+int w32_ansi_code_page;
 
 /* Prefix for system colors.  */
 #define SYSTEM_COLOR_PREFIX "System"
@@ -260,6 +261,7 @@ typedef BOOL (WINAPI * TrackMouseEvent_Proc)
 
 TrackMouseEvent_Proc track_mouse_event_fn = NULL;
 ClipboardSequence_Proc clipboard_sequence_fn = NULL;
+extern AppendMenuW_Proc unicode_append_menu;
 
 /* W95 mousewheel handler */
 unsigned int msh_mousewheel = 0;
@@ -283,7 +285,7 @@ int image_cache_refcount, dpyinfo_refcount;
 
 
 /* From w32term.c. */
-extern Lisp_Object Vw32_num_mouse_buttons;
+extern int w32_num_mouse_buttons;
 extern Lisp_Object Vw32_recognize_altgr;
 
 extern HWND w32_system_caret_hwnd;
@@ -465,7 +467,7 @@ if the entry is new.  */)
   CHECK_NUMBER (blue);
   CHECK_STRING (name);
 
-  XSET (rgb, Lisp_Int, RGB(XUINT (red), XUINT (green), XUINT (blue)));
+  XSETINT (rgb, RGB(XUINT (red), XUINT (green), XUINT (blue)));
 
   BLOCK_INPUT;
 
@@ -828,7 +830,7 @@ w32_to_x_color (rgb)
     return Qnil;
 }
 
-COLORREF
+static Lisp_Object
 w32_color_map_lookup (colorname)
      char *colorname;
 {
@@ -847,7 +849,7 @@ w32_color_map_lookup (colorname)
 
       if (lstrcmpi (SDATA (tem), colorname) == 0)
        {
-         ret = XUINT (Fcdr (elt));
+         ret = Fcdr (elt);
          break;
        }
 
@@ -910,7 +912,7 @@ add_system_logical_colors_to_map (system_colors)
 }
 
 
-COLORREF
+static Lisp_Object
 x_to_w32_color (colorname)
      char * colorname;
 {
@@ -970,7 +972,8 @@ x_to_w32_color (colorname)
              if (i == 2)
                {
                  UNBLOCK_INPUT;
-                 return (colorval);
+                 XSETINT (ret, colorval);
+                 return ret;
                }
              color = end;
            }
@@ -1023,7 +1026,8 @@ x_to_w32_color (colorname)
              if (*end != '\0')
                break;
              UNBLOCK_INPUT;
-             return (colorval);
+             XSETINT (ret, colorval);
+             return ret;
            }
          if (*end != '/')
            break;
@@ -1064,7 +1068,8 @@ x_to_w32_color (colorname)
              if (*end != '\0')
                break;
              UNBLOCK_INPUT;
-             return (colorval);
+             XSETINT (ret, colorval);
+             return ret;
            }
          if (*end != '/')
            break;
@@ -2418,6 +2423,10 @@ Lisp_Object w32_grabbed_keys;
 #define HOTKEY_VK_CODE(k)     (XFASTINT (k) & 255)
 #define HOTKEY_MODIFIERS(k)   (XFASTINT (k) >> 8)
 
+#define RAW_HOTKEY_ID(k)        ((k) & 0xbfff)
+#define RAW_HOTKEY_VK_CODE(k)   ((k) & 255)
+#define RAW_HOTKEY_MODIFIERS(k) ((k) >> 8)
+
 /* Register hot-keys for reserved key combinations when Emacs has
    keyboard focus, since this is the only way Emacs can receive key
    combinations like Alt-Tab which are used by the system.  */
@@ -2499,20 +2508,20 @@ w32_msg_pump (deferred_msg * msg_buf)
              focus_window = GetFocus ();
              if (focus_window != NULL)
                RegisterHotKey (focus_window,
-                               HOTKEY_ID (msg.wParam),
-                               HOTKEY_MODIFIERS (msg.wParam),
-                               HOTKEY_VK_CODE (msg.wParam));
+                               RAW_HOTKEY_ID (msg.wParam),
+                               RAW_HOTKEY_MODIFIERS (msg.wParam),
+                               RAW_HOTKEY_VK_CODE (msg.wParam));
              /* Reply is not expected.  */
              break;
            case WM_EMACS_UNREGISTER_HOT_KEY:
              focus_window = GetFocus ();
              if (focus_window != NULL)
-               UnregisterHotKey (focus_window, HOTKEY_ID (msg.wParam));
+               UnregisterHotKey (focus_window, RAW_HOTKEY_ID (msg.wParam));
              /* Mark item as erased.  NB: this code must be
                  thread-safe.  The next line is okay because the cons
                  cell is never made into garbage and is not relocated by
                  GC.  */
-             XSETCAR ((Lisp_Object) msg.lParam, Qnil);
+             XSETCAR ((Lisp_Object) ((EMACS_INT) msg.lParam), Qnil);
              if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
                abort ();
              break;
@@ -2520,7 +2529,7 @@ w32_msg_pump (deferred_msg * msg_buf)
              {
                int vk_code = (int) msg.wParam;
                int cur_state = (GetKeyState (vk_code) & 1);
-               Lisp_Object new_state = (Lisp_Object) msg.lParam;
+               Lisp_Object new_state = (Lisp_Object) ((EMACS_INT) msg.lParam);
 
                /* NB: This code must be thread-safe.  It is safe to
                    call NILP because symbols are not relocated by GC,
@@ -2710,7 +2719,7 @@ post_character_message (hwnd, msg, wParam, lParam, modifiers)
       c = make_ctrl_char (c) & 0377;
     if (c == quit_char
        || (wmsg.dwModifiers == 0 &&
-           XFASTINT (Vw32_quit_key) && wParam == XFASTINT (Vw32_quit_key)))
+           w32_quit_key && wParam == w32_quit_key))
       {
        Vquit_flag = Qt;
 
@@ -3120,7 +3129,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
         are used together, but only if user has two button mouse. */
     case WM_LBUTTONDOWN:
     case WM_RBUTTONDOWN:
-      if (XINT (Vw32_num_mouse_buttons) > 2)
+      if (w32_num_mouse_buttons > 2)
        goto handle_plain_button;
 
       {
@@ -3170,7 +3179,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
            /* Hold onto message for now. */
            mouse_button_timer =
              SetTimer (hwnd, MOUSE_BUTTON_ID,
-                       XINT (Vw32_mouse_button_tolerance), NULL);
+                       w32_mouse_button_tolerance, NULL);
            saved_mouse_button_msg.msg.hwnd = hwnd;
            saved_mouse_button_msg.msg.message = msg;
            saved_mouse_button_msg.msg.wParam = wParam;
@@ -3183,7 +3192,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
 
     case WM_LBUTTONUP:
     case WM_RBUTTONUP:
-      if (XINT (Vw32_num_mouse_buttons) > 2)
+      if (w32_num_mouse_buttons > 2)
        goto handle_plain_button;
 
       {
@@ -3279,7 +3288,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
          track_mouse_window = hwnd;
        }
     case WM_VSCROLL:
-      if (XINT (Vw32_mouse_move_interval) <= 0
+      if (w32_mouse_move_interval <= 0
          || (msg == WM_MOUSEMOVE && button_state == 0))
        {
          wmsg.dwModifiers = w32_get_modifiers ();
@@ -3295,7 +3304,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
       if (saved_mouse_move_msg.msg.hwnd == 0)
        mouse_move_timer =
          SetTimer (hwnd, MOUSE_MOVE_ID,
-                   XINT (Vw32_mouse_move_interval), NULL);
+                   w32_mouse_move_interval, NULL);
 
       /* Hold onto message for now. */
       saved_mouse_move_msg.msg.hwnd = hwnd;
@@ -3450,7 +3459,13 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
               pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE);
               if (title)
                 {
-                  GetTextExtentPoint32 (hdc, title, strlen (title), &size);
+                 if (unicode_append_menu)
+                   GetTextExtentPoint32W (hdc, (WCHAR *) title,
+                                          wcslen ((WCHAR *) title),
+                                          &size);
+                 else
+                   GetTextExtentPoint32 (hdc, title, strlen (title), &size);
+
                   pMis->itemWidth = size.cx;
                   if (pMis->itemHeight < size.cy)
                     pMis->itemHeight = size.cy;
@@ -3488,13 +3503,22 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
                   menu_font = CreateFontIndirect (&menu_logfont);
                   old_font = SelectObject (hdc, menu_font);
 
-                  /* Always draw title as if not selected.  */
-                  ExtTextOut (hdc,
-                              pDis->rcItem.left
-                              + GetSystemMetrics (SM_CXMENUCHECK),
-                              pDis->rcItem.top,
-                              ETO_OPAQUE, &pDis->rcItem,
-                              title, strlen (title), NULL);
+                 /* Always draw title as if not selected.  */
+                 if (unicode_append_menu)
+                   ExtTextOutW (hdc,
+                                pDis->rcItem.left
+                                + GetSystemMetrics (SM_CXMENUCHECK),
+                                pDis->rcItem.top,
+                                ETO_OPAQUE, &pDis->rcItem,
+                                (WCHAR *) title,
+                                wcslen ((WCHAR *) title), NULL);
+                 else
+                   ExtTextOut (hdc,
+                               pDis->rcItem.left
+                               + GetSystemMetrics (SM_CXMENUCHECK),
+                               pDis->rcItem.top,
+                               ETO_OPAQUE, &pDis->rcItem,
+                               title, strlen (title), NULL);
 
                   SelectObject (hdc, old_font);
                   DeleteObject (menu_font);
@@ -4038,15 +4062,15 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
        1, 1, 0,
        doc: /* Make a new window, which is called a \"frame\" in Emacs terms.
 Returns an Emacs frame object.
-ALIST is an alist of frame parameters.
+PARAMETERS is an alist of frame parameters.
 If the parameters specify that the frame should not have a minibuffer,
 and do not specify a specific minibuffer window to use,
 then `default-minibuffer-frame' must be a frame whose minibuffer can
 be shared by the new frame.
 
 This function is an internal primitive--use `make-frame' instead.  */)
-  (parms)
-     Lisp_Object parms;
+  (parameters)
+     Lisp_Object parameters;
 {
   struct frame *f;
   Lisp_Object frame, tem;
@@ -4067,7 +4091,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
      until we know if this frame has a specified name.  */
   Vx_resource_name = Vinvocation_name;
 
-  display = w32_get_arg (parms, Qdisplay, 0, 0, RES_TYPE_STRING);
+  display = w32_get_arg (parameters, Qdisplay, 0, 0, RES_TYPE_STRING);
   if (EQ (display, Qunbound))
     display = Qnil;
   dpyinfo = check_x_display_info (display);
@@ -4077,7 +4101,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
   kb = &the_only_kboard;
 #endif
 
-  name = w32_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
+  name = w32_get_arg (parameters, Qname, "name", "Name", RES_TYPE_STRING);
   if (!STRINGP (name)
       && ! EQ (name, Qunbound)
       && ! NILP (name))
@@ -4087,7 +4111,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
     Vx_resource_name = name;
 
   /* See if parent window is specified.  */
-  parent = w32_get_arg (parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
+  parent = w32_get_arg (parameters, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
   if (EQ (parent, Qunbound))
     parent = Qnil;
   if (! NILP (parent))
@@ -4097,8 +4121,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
   /* No need to protect DISPLAY because that's not used after passing
      it to make_frame_without_minibuffer.  */
   frame = Qnil;
-  GCPRO4 (parms, parent, name, frame);
-  tem = w32_get_arg (parms, Qminibuffer, "minibuffer", "Minibuffer",
+  GCPRO4 (parameters, parent, name, frame);
+  tem = w32_get_arg (parameters, Qminibuffer, "minibuffer", "Minibuffer",
                      RES_TYPE_SYMBOL);
   if (EQ (tem, Qnone) || NILP (tem))
     f = make_frame_without_minibuffer (Qnil, kb, display);
@@ -4128,7 +4152,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
   record_unwind_protect (unwind_create_frame, frame);
 
   f->icon_name
-    = w32_get_arg (parms, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
+    = w32_get_arg (parameters, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
   if (! STRINGP (f->icon_name))
     f->icon_name = Qnil;
 
@@ -4170,7 +4194,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
   {
     Lisp_Object font;
 
-    font = w32_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
+    font = w32_get_arg (parameters, Qfont, "font", "Font", RES_TYPE_STRING);
 
     BLOCK_INPUT;
     /* First, try whatever font the caller has specified.  */
@@ -4194,49 +4218,49 @@ This function is an internal primitive--use `make-frame' instead.  */)
     if (! STRINGP (font))
       font = build_string ("Fixedsys");
 
-    x_default_parameter (f, parms, Qfont, font,
+    x_default_parameter (f, parameters, Qfont, font,
                         "font", "Font", RES_TYPE_STRING);
   }
 
-  x_default_parameter (f, parms, Qborder_width, make_number (2),
+  x_default_parameter (f, parameters, Qborder_width, make_number (2),
                       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
   /* This defaults to 2 in order to match xterm.  We recognize either
      internalBorderWidth or internalBorder (which is what xterm calls
      it).  */
-  if (NILP (Fassq (Qinternal_border_width, parms)))
+  if (NILP (Fassq (Qinternal_border_width, parameters)))
     {
       Lisp_Object value;
 
-      value = w32_get_arg (parms, Qinternal_border_width,
-                        "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
+      value = w32_get_arg (parameters, Qinternal_border_width,
+                           "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
       if (! EQ (value, Qunbound))
-       parms = Fcons (Fcons (Qinternal_border_width, value),
-                      parms);
+       parameters = Fcons (Fcons (Qinternal_border_width, value),
+                            parameters);
     }
   /* Default internalBorderWidth to 0 on Windows to match other programs.  */
-  x_default_parameter (f, parms, Qinternal_border_width, make_number (0),
+  x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
                       "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
-  x_default_parameter (f, parms, Qvertical_scroll_bars, Qright,
+  x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
                       "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
 
   /* Also do the stuff which must be set before the window exists.  */
-  x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
+  x_default_parameter (f, parameters, Qforeground_color, build_string ("black"),
                       "foreground", "Foreground", RES_TYPE_STRING);
-  x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
+  x_default_parameter (f, parameters, Qbackground_color, build_string ("white"),
                       "background", "Background", RES_TYPE_STRING);
-  x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
+  x_default_parameter (f, parameters, Qmouse_color, build_string ("black"),
                       "pointerColor", "Foreground", RES_TYPE_STRING);
-  x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
+  x_default_parameter (f, parameters, Qcursor_color, build_string ("black"),
                       "cursorColor", "Foreground", RES_TYPE_STRING);
-  x_default_parameter (f, parms, Qborder_color, build_string ("black"),
+  x_default_parameter (f, parameters, Qborder_color, build_string ("black"),
                       "borderColor", "BorderColor", RES_TYPE_STRING);
-  x_default_parameter (f, parms, Qscreen_gamma, Qnil,
+  x_default_parameter (f, parameters, Qscreen_gamma, Qnil,
                       "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
-  x_default_parameter (f, parms, Qline_spacing, Qnil,
+  x_default_parameter (f, parameters, Qline_spacing, Qnil,
                       "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
-  x_default_parameter (f, parms, Qleft_fringe, Qnil,
+  x_default_parameter (f, parameters, Qleft_fringe, Qnil,
                       "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
-  x_default_parameter (f, parms, Qright_fringe, Qnil,
+  x_default_parameter (f, parameters, Qright_fringe, Qnil,
                       "rightFringe", "RightFringe", RES_TYPE_NUMBER);
 
 
@@ -4248,16 +4272,16 @@ This function is an internal primitive--use `make-frame' instead.  */)
      happen.  */
   init_frame_faces (f);
 
-  x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
+  x_default_parameter (f, parameters, Qmenu_bar_lines, make_number (1),
                       "menuBar", "MenuBar", RES_TYPE_NUMBER);
-  x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
+  x_default_parameter (f, parameters, Qtool_bar_lines, make_number (1),
                        "toolBar", "ToolBar", RES_TYPE_NUMBER);
 
-  x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
+  x_default_parameter (f, parameters, Qbuffer_predicate, Qnil,
                       "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
-  x_default_parameter (f, parms, Qtitle, Qnil,
+  x_default_parameter (f, parameters, Qtitle, Qnil,
                       "title", "Title", RES_TYPE_STRING);
-  x_default_parameter (f, parms, Qfullscreen, Qnil,
+  x_default_parameter (f, parameters, Qfullscreen, Qnil,
                        "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
 
   f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
@@ -4270,13 +4294,13 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
   f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
 
-  window_prompting = x_figure_window_size (f, parms, 1);
+  window_prompting = x_figure_window_size (f, parameters, 1);
 
-  tem = w32_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
+  tem = w32_get_arg (parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
   f->no_split = minibuffer_only || EQ (tem, Qt);
 
   w32_window (f, window_prompting, minibuffer_only);
-  x_icon (f, parms);
+  x_icon (f, parameters);
 
   x_make_gc (f);
 
@@ -4286,16 +4310,16 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
   /* We need to do this after creating the window, so that the
      icon-creation functions can say whose icon they're describing.  */
-  x_default_parameter (f, parms, Qicon_type, Qnil,
+  x_default_parameter (f, parameters, Qicon_type, Qnil,
                       "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
 
-  x_default_parameter (f, parms, Qauto_raise, Qnil,
+  x_default_parameter (f, parameters, Qauto_raise, Qnil,
                       "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
-  x_default_parameter (f, parms, Qauto_lower, Qnil,
+  x_default_parameter (f, parameters, Qauto_lower, Qnil,
                       "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
-  x_default_parameter (f, parms, Qcursor_type, Qbox,
+  x_default_parameter (f, parameters, Qcursor_type, Qbox,
                       "cursorType", "CursorType", RES_TYPE_SYMBOL);
-  x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
+  x_default_parameter (f, parameters, Qscroll_bar_width, Qnil,
                       "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
 
   /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
@@ -4333,7 +4357,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
     {
       Lisp_Object visibility;
 
-      visibility = w32_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
+      visibility = w32_get_arg (parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
       if (EQ (visibility, Qunbound))
        visibility = Qt;
 
@@ -4521,7 +4545,7 @@ w32_load_system_font (f,fontname,size)
         /* Fill out details in lf according to the font that was
            actually loaded.  */
         lf.lfHeight = font->tm.tmInternalLeading - font->tm.tmHeight;
-        lf.lfWidth = font->tm.tmAveCharWidth;
+        lf.lfWidth = font->tm.tmMaxCharWidth;
         lf.lfWeight = font->tm.tmWeight;
         lf.lfItalic = font->tm.tmItalic;
         lf.lfCharSet = font->tm.tmCharSet;
@@ -4569,6 +4593,24 @@ w32_load_system_font (f,fontname,size)
     fontp->name = (char *) xmalloc (strlen (fontname) + 1);
     bcopy (fontname, fontp->name, strlen (fontname) + 1);
 
+    if (lf.lfPitchAndFamily == FIXED_PITCH)
+      {
+       /* Fixed width font.  */
+       fontp->average_width = fontp->space_width = FONT_WIDTH (font);
+      }
+    else
+      {
+       wchar_t space = 32;
+       XCharStruct* pcm;
+       pcm = w32_per_char_metric (font, &space, ANSI_FONT);
+       if (pcm)
+         fontp->space_width = pcm->width;
+       else
+         fontp->space_width = FONT_WIDTH (font);
+
+       fontp->average_width = font->tm.tmAveCharWidth;
+      }
+
     charset = xlfd_charset_of_font (fontname);
 
   /* Cache the W32 codepage for a font.  This makes w32_encode_char
@@ -4635,6 +4677,7 @@ int size;
 {
   Lisp_Object bdf_fonts;
   struct font_info *retval = NULL;
+  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
 
   bdf_fonts = w32_list_bdf_fonts (build_string (fontname), 1);
 
@@ -4642,11 +4685,22 @@ int size;
     {
       char *bdf_name, *bdf_file;
       Lisp_Object bdf_pair;
+      int i;
 
       bdf_name = SDATA (XCAR (bdf_fonts));
       bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist);
       bdf_file = SDATA (XCDR (bdf_pair));
 
+      // If the font is already loaded, do not load it again.
+      for (i = 0; i < dpyinfo->n_fonts; i++)
+       {
+         if ((dpyinfo->font_table[i].name
+              && !strcmp (dpyinfo->font_table[i].name, bdf_name))
+             || (dpyinfo->font_table[i].full_name
+                 && !strcmp (dpyinfo->font_table[i].full_name, bdf_name)))
+           return dpyinfo->font_table + i;
+       }
+
       retval = w32_load_bdf_font (f, bdf_name, size, bdf_file);
 
       bdf_fonts = XCDR (bdf_fonts);
@@ -4772,46 +4826,46 @@ x_to_w32_charset (lpcs)
   w32_charset = Fcar (Fcdr (this_entry));
 
   /* Translate Lisp symbol to number.  */
-  if (w32_charset == Qw32_charset_ansi)
+  if (EQ (w32_charset, Qw32_charset_ansi))
     return ANSI_CHARSET;
-  if (w32_charset == Qw32_charset_symbol)
+  if (EQ (w32_charset, Qw32_charset_symbol))
     return SYMBOL_CHARSET;
-  if (w32_charset == Qw32_charset_shiftjis)
+  if (EQ (w32_charset, Qw32_charset_shiftjis))
     return SHIFTJIS_CHARSET;
-  if (w32_charset == Qw32_charset_hangeul)
+  if (EQ (w32_charset, Qw32_charset_hangeul))
     return HANGEUL_CHARSET;
-  if (w32_charset == Qw32_charset_chinesebig5)
+  if (EQ (w32_charset, Qw32_charset_chinesebig5))
     return CHINESEBIG5_CHARSET;
-  if (w32_charset == Qw32_charset_gb2312)
+  if (EQ (w32_charset, Qw32_charset_gb2312))
     return GB2312_CHARSET;
-  if (w32_charset == Qw32_charset_oem)
+  if (EQ (w32_charset, Qw32_charset_oem))
     return OEM_CHARSET;
 #ifdef JOHAB_CHARSET
-  if (w32_charset == Qw32_charset_johab)
+  if (EQ (w32_charset, Qw32_charset_johab))
     return JOHAB_CHARSET;
-  if (w32_charset == Qw32_charset_easteurope)
+  if (EQ (w32_charset, Qw32_charset_easteurope))
     return EASTEUROPE_CHARSET;
-  if (w32_charset == Qw32_charset_turkish)
+  if (EQ (w32_charset, Qw32_charset_turkish))
     return TURKISH_CHARSET;
-  if (w32_charset == Qw32_charset_baltic)
+  if (EQ (w32_charset, Qw32_charset_baltic))
     return BALTIC_CHARSET;
-  if (w32_charset == Qw32_charset_russian)
+  if (EQ (w32_charset, Qw32_charset_russian))
     return RUSSIAN_CHARSET;
-  if (w32_charset == Qw32_charset_arabic)
+  if (EQ (w32_charset, Qw32_charset_arabic))
     return ARABIC_CHARSET;
-  if (w32_charset == Qw32_charset_greek)
+  if (EQ (w32_charset, Qw32_charset_greek))
     return GREEK_CHARSET;
-  if (w32_charset == Qw32_charset_hebrew)
+  if (EQ (w32_charset, Qw32_charset_hebrew))
     return HEBREW_CHARSET;
-  if (w32_charset == Qw32_charset_vietnamese)
+  if (EQ (w32_charset, Qw32_charset_vietnamese))
     return VIETNAMESE_CHARSET;
-  if (w32_charset == Qw32_charset_thai)
+  if (EQ (w32_charset, Qw32_charset_thai))
     return THAI_CHARSET;
-  if (w32_charset == Qw32_charset_mac)
+  if (EQ (w32_charset, Qw32_charset_mac))
     return MAC_CHARSET;
 #endif /* JOHAB_CHARSET */
 #ifdef UNICODE_CHARSET
-  if (w32_charset == Qw32_charset_unicode)
+  if (EQ (w32_charset, Qw32_charset_unicode))
     return UNICODE_CHARSET;
 #endif
 
@@ -4937,8 +4991,8 @@ w32_to_x_charset (fncharset)
 
         /* Look for Same charset and a valid codepage (or non-int
            which means ignore).  */
-        if (w32_charset == charset_type
-            && (!INTEGERP (codepage) || codepage == CP_DEFAULT
+        if (EQ (w32_charset, charset_type)
+            && (!INTEGERP (codepage) || XINT (codepage) == CP_DEFAULT
                 || IsValidCodePage (XINT (codepage))))
           {
             /* If we don't have a match already, then this is the
@@ -5095,8 +5149,8 @@ w32_to_all_x_charsets (fncharset)
 
         /* Look for Same charset and a valid codepage (or non-int
            which means ignore).  */
-        if (w32_charset == charset_type
-            && (!INTEGERP (codepage) || codepage == CP_DEFAULT
+        if (EQ (w32_charset, charset_type)
+            && (!INTEGERP (codepage) || XINT (codepage) == CP_DEFAULT
                 || IsValidCodePage (XINT (codepage))))
           {
            retval = Fcons (x_charset, retval);
@@ -5335,7 +5389,7 @@ x_to_w32_font (lpxstr, lplogfont)
           setup_coding_system
             (Fcheck_coding_system (Vlocale_coding_system), &coding);
          coding.src_multibyte = 1;
-         coding.dst_multibyte = 1;
+         coding.dst_multibyte = 0;
          /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
             encode_coding_iso2022 trying to dereference a null pointer.  */
          coding.composing = COMPOSITION_DISABLED;
@@ -5572,11 +5626,11 @@ w32_font_match (fontname, pattern)
     char * fontname;
     char * pattern;
 {
-  char *regex = alloca (strlen (pattern) * 2 + 3);
-  char *font_name_copy = alloca (strlen (fontname) + 1);
   char *ptr;
+  char *font_name_copy;
+  char *regex = alloca (strlen (pattern) * 2 + 3);
 
-  /* Copy fontname so we can modify it during comparison.  */
+  font_name_copy = alloca (strlen (fontname) + 1);
   strcpy (font_name_copy, fontname);
 
   ptr = regex;
@@ -5615,8 +5669,8 @@ w32_font_match (fontname, pattern)
       return FALSE;
   }
 
-  return (fast_c_string_match_ignore_case (build_string (regex),
-                                           font_name_copy) >= 0);
+  return (fast_string_match_ignore_case (build_string (regex),
+                                         build_string(font_name_copy)) >= 0);
 }
 
 /* Callback functions, and a structure holding info they need, for
@@ -6145,6 +6199,9 @@ w32_find_ccl_program (fontp)
     }
 }
 
+/* directory-files from dired.c.  */
+Lisp_Object Fdirectory_files P_((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
+
 \f
 /* Find BDF files in a specified directory.  (use GCPRO when calling,
    as this calls lisp to get a directory listing).  */
@@ -6158,7 +6215,7 @@ w32_find_bdf_fonts_in_dir (Lisp_Object directory)
     return Qnil;
 
   filelist = Fdirectory_files (directory, Qt,
-                              build_string (".*\\.[bB][dD][fF]"), Qt);
+                              build_string (".*\\.[bB][dD][fF]"), Qt);
 
   for ( ; CONSP(filelist); filelist = XCDR (filelist))
     {
@@ -6171,10 +6228,10 @@ w32_find_bdf_fonts_in_dir (Lisp_Object directory)
 
 DEFUN ("w32-find-bdf-fonts", Fw32_find_bdf_fonts, Sw32_find_bdf_fonts,
        1, 1, 0,
-       doc: /* Return a list of BDF fonts in DIR.
-The list is suitable for appending to w32-bdf-filename-alist.  Fonts
-which do not contain an xlfd description will not be included in the
-list. DIR may be a list of directories.  */)
+       doc: /* Return a list of BDF fonts in DIRECTORY.
+The list is suitable for appending to `w32-bdf-filename-alist'.
+Fonts which do not contain an xlfd description will not be included
+in the list.  DIRECTORY may be a list of directories.  */)
      (directory)
      Lisp_Object directory;
 {
@@ -6255,7 +6312,7 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
 
 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p,
        Sx_display_grayscale_p, 0, 1, 0,
-       doc: /* Return t if the X display supports shades of gray.
+       doc: /* Return t if DISPLAY supports shades of gray.
 Note that color displays do support shades of gray.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
@@ -6328,9 +6385,9 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
   hdc = GetDC (dpyinfo->root_window);
   if (dpyinfo->has_palette)
-    cap = GetDeviceCaps (hdc,SIZEPALETTE);
+    cap = GetDeviceCaps (hdc, SIZEPALETTE);
   else
-    cap = GetDeviceCaps (hdc,NUMCOLORS);
+    cap = GetDeviceCaps (hdc, NUMCOLORS);
 
   /* We force 24+ bit depths to 24-bit, both to prevent an overflow
      and because probably is more meaningful on Windows anyway */
@@ -6358,7 +6415,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 }
 
 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
-       doc: /* Returns the vendor ID string of the W32 system (Microsoft).
+       doc: /* Returns the "vendor ID" string of the W32 system (Microsoft).
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6371,7 +6428,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
        doc: /* Returns the version numbers of the server of DISPLAY.
 The value is a list of three integers: the major and minor
-version numbers, and the vendor-specific release
+version numbers of the X Protocol in use, and the distributor-specific release
 number.  See also the function `x-server-vendor'.
 
 The optional argument DISPLAY specifies which display to ask about.
@@ -7384,7 +7441,7 @@ used to change the tooltip's appearance.
 Automatically hide the tooltip after TIMEOUT seconds.  TIMEOUT nil
 means use the default timeout of 5 seconds.
 
-If the list of frame parameters PARAMS contains a `left' parameter,
+If the list of frame parameters PARMS contains a `left' parameter,
 the tooltip is displayed at that x-position.  Otherwise it is
 displayed at the mouse position, with offset DX added (default is 5 if
 DX isn't specified).  Likewise for the y-position; if a `top' frame
@@ -7676,7 +7733,8 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
     {
       OFNOTIFY * notify = (OFNOTIFY *)lParam;
       /* Detect when the Filter dropdown is changed.  */
-      if (notify->hdr.code == CDN_TYPECHANGE)
+      if (notify->hdr.code == CDN_TYPECHANGE
+         || notify->hdr.code == CDN_INITDONE)
        {
          HWND dialog = GetParent (hwnd);
          HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD);
@@ -7690,8 +7748,10 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
            }
          else
            {
-             CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
-                                              "");
+             /* Don't override default filename on init done.  */
+             if (notify->hdr.code == CDN_TYPECHANGE)
+               CommDlg_OpenSave_SetControlText (dialog,
+                                                FILE_NAME_TEXT_FIELD, "");
              EnableWindow (edit_control, TRUE);
            }
        }
@@ -7699,36 +7759,51 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
   return 0;
 }
 
-DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
+/* Since we compile with _WIN32_WINNT set to 0x0400 (for NT4 compatibility)
+   we end up with the old file dialogs. Define a big enough struct for the
+   new dialog to trick GetOpenFileName into giving us the new dialogs on
+   Windows 2000 and XP.  */
+typedef struct
+{
+  OPENFILENAME real_details;
+  void * pReserved;
+  DWORD dwReserved;
+  DWORD FlagsEx;
+} NEWOPENFILENAME;
+
+    
+DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
        doc: /* Read file name, prompting with PROMPT in directory DIR.
 Use a file selection dialog.
 Select DEFAULT-FILENAME in the dialog's file selection box, if
-specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
-  (prompt, dir, default_filename, mustmatch)
-     Lisp_Object prompt, dir, default_filename, mustmatch;
+specified.  Ensure that file exists if MUSTMATCH is non-nil.
+If ONLY-DIR-P is non-nil, the user can only select directories.  */)
+  (prompt, dir, default_filename, mustmatch, only_dir_p)
+     Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
 {
   struct frame *f = SELECTED_FRAME ();
   Lisp_Object file = Qnil;
   int count = SPECPDL_INDEX ();
-  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
   char filename[MAX_PATH + 1];
   char init_dir[MAX_PATH + 1];
+  int default_filter_index = 1; /* 1: All Files, 2: Directories only  */
 
-  GCPRO5 (prompt, dir, default_filename, mustmatch, file);
+  GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
   CHECK_STRING (prompt);
   CHECK_STRING (dir);
 
   /* Create the dialog with PROMPT as title, using DIR as initial
      directory and using "*" as pattern.  */
   dir = Fexpand_file_name (dir, Qnil);
-  strncpy (init_dir, SDATA (dir), MAX_PATH);
+  strncpy (init_dir, SDATA (ENCODE_FILE (dir)), MAX_PATH);
   init_dir[MAX_PATH] = '\0';
   unixtodos_filename (init_dir);
 
   if (STRINGP (default_filename))
     {
       char *file_name_only;
-      char *full_path_name = SDATA (default_filename);
+      char *full_path_name = SDATA (ENCODE_FILE (default_filename));
 
       unixtodos_filename (full_path_name);
 
@@ -7736,9 +7811,7 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
       if (!file_name_only)
         file_name_only = full_path_name;
       else
-        {
-          file_name_only++;
-        }
+       file_name_only++;
 
       strncpy (filename, file_name_only, MAX_PATH);
       filename[MAX_PATH] = '\0';
@@ -7747,35 +7820,60 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
     filename[0] = '\0';
 
   {
-    OPENFILENAME file_details;
-
+    NEWOPENFILENAME new_file_details;
+    BOOL file_opened = FALSE;
+    OPENFILENAME * file_details = &new_file_details.real_details;
+  
     /* Prevent redisplay.  */
     specbind (Qinhibit_redisplay, Qt);
     BLOCK_INPUT;
 
-    bzero (&file_details, sizeof (file_details));
-    file_details.lStructSize = sizeof (file_details);
-    file_details.hwndOwner = FRAME_W32_WINDOW (f);
+    bzero (&new_file_details, sizeof (new_file_details));
+    /* Apparently NT4 crashes if you give it an unexpected size.
+       I'm not sure about Windows 9x, so play it safe.  */
+    if (w32_major_version > 4 && w32_major_version < 95)
+      file_details->lStructSize = sizeof (new_file_details);
+    else
+      file_details->lStructSize = sizeof (file_details);
+
+    file_details->hwndOwner = FRAME_W32_WINDOW (f);
     /* Undocumented Bug in Common File Dialog:
        If a filter is not specified, shell links are not resolved.  */
-    file_details.lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0";
-    file_details.lpstrFile = filename;
-    file_details.nMaxFile = sizeof (filename);
-    file_details.lpstrInitialDir = init_dir;
-    file_details.lpstrTitle = SDATA (prompt);
-    file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
+    file_details->lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0";
+    file_details->lpstrFile = filename;
+    file_details->nMaxFile = sizeof (filename);
+    file_details->lpstrInitialDir = init_dir;
+    file_details->lpstrTitle = SDATA (prompt);
+
+    if (! NILP (only_dir_p))
+      default_filter_index = 2;
+
+    file_details->nFilterIndex = default_filter_index;
+
+    file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
                          | OFN_EXPLORER | OFN_ENABLEHOOK);
     if (!NILP (mustmatch))
-      file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
+      {
+       /* Require that the path to the parent directory exists.  */
+       file_details->Flags |= OFN_PATHMUSTEXIST;
+       /* If we are looking for a file, require that it exists.  */
+       if (NILP (only_dir_p))
+         file_details->Flags |= OFN_FILEMUSTEXIST;
+      }
+
+    file_details->lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
+
+    file_opened = GetOpenFileName (file_details);
 
-    file_details.lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
+    UNBLOCK_INPUT;
 
-    if (GetOpenFileName (&file_details))
+    if (file_opened)
       {
        dostounix_filename (filename);
-       if (file_details.nFilterIndex == 2)
+
+       if (file_details->nFilterIndex == 2)
          {
-           /* "Folder Only" selected - strip dummy file name.  */
+           /* "Directories" selected - strip dummy file name.  */
            char * last = strrchr (filename, '/');
            *last = '\0';
          }
@@ -7791,7 +7889,6 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
                               dir, mustmatch, dir, Qfile_name_history,
                               default_filename, Qnil);
 
-    UNBLOCK_INPUT;
     file = unbind_to (count, file);
   }
 
@@ -7865,7 +7962,7 @@ Returns an X font string corresponding to the selection.  */)
 DEFUN ("w32-send-sys-command", Fw32_send_sys_command,
        Sw32_send_sys_command, 1, 2, 0,
        doc: /* Send frame a Windows WM_SYSCOMMAND message of type COMMAND.
-Some useful values for command are #xf030 to maximise frame (#xf020
+Some useful values for COMMAND are #xf030 to maximize frame (#xf020
 to minimize), #xf120 to restore frame to original size, and #xf100
 to activate the menubar for keyboard access.  #xf140 activates the
 screen saver if defined.
@@ -7945,7 +8042,7 @@ lookup_vk_code (char *key)
 
 /* Convert a one-element vector style key sequence to a hot key
    definition.  */
-static int
+static Lisp_Object
 w32_parse_hot_key (key)
      Lisp_Object key;
 {
@@ -7977,7 +8074,7 @@ w32_parse_hot_key (key)
   if (SYMBOLP (c))
     {
       c = parse_modifiers (c);
-      lisp_modifiers = Fcar (Fcdr (c));
+      lisp_modifiers = XINT (Fcar (Fcdr (c)));
       c = Fcar (c);
       if (!SYMBOLP (c))
        abort ();
@@ -8046,8 +8143,13 @@ The return value is the hotkey-id if registered, otherwise nil.  */)
 
       /* Notify input thread about new hot-key definition, so that it
         takes effect without needing to switch focus.  */
+#ifdef USE_LISP_UNION_TYPE
+      PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
+                        (WPARAM) key.i, 0);
+#else
       PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
                         (WPARAM) key, 0);
+#endif
     }
 
   return key;
@@ -8055,7 +8157,7 @@ The return value is the hotkey-id if registered, otherwise nil.  */)
 
 DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key,
        Sw32_unregister_hot_key, 1, 1, 0,
-       doc: /* Unregister HOTKEY as a hot-key combination.  */)
+       doc: /* Unregister KEY as a hot-key combination.  */)
   (key)
      Lisp_Object key;
 {
@@ -8070,8 +8172,14 @@ DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key,
     {
       /* Notify input thread about hot-key definition being removed, so
         that it takes effect without needing focus switch.  */
+#ifdef USE_LISP_UNION_TYPE
+      if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
+                            (WPARAM) XINT (XCAR (item)), (LPARAM) item.i))
+#else
       if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
                             (WPARAM) XINT (XCAR (item)), (LPARAM) item))
+
+#endif
        {
          MSG msg;
          GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
@@ -8091,7 +8199,8 @@ DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys,
 
 DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key,
        Sw32_reconstruct_hot_key, 1, 1, 0,
-       doc: /* Convert hot-key ID to a lisp key combination.  */)
+       doc: /* Convert hot-key ID to a lisp key combination.
+usage: (w32-reconstruct-hot-key ID)  */)
   (hotkeyid)
      Lisp_Object hotkeyid;
 {
@@ -8144,8 +8253,13 @@ is set to off if the low bit of NEW-STATE is zero, otherwise on.  */)
   if (!dwWindowsThreadId)
     return make_number (w32_console_toggle_lock_key (vk_code, new_state));
 
+#ifdef USE_LISP_UNION_TYPE
+  if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
+                        (WPARAM) vk_code, (LPARAM) new_state.i))
+#else
   if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
                         (WPARAM) vk_code, (LPARAM) new_state))
+#endif
     {
       MSG msg;
       GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
@@ -8325,7 +8439,7 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
                            Initialization
  ***********************************************************************/
 
-/* Keep this list in the same order as frame_parms in frame.c. 
+/* Keep this list in the same order as frame_parms in frame.c.
    Use 0 for unsupported frame parameters.  */
 
 frame_parm_handler w32_frame_parm_handlers[] =
@@ -8410,7 +8524,7 @@ syms_of_w32fns ()
   w32_grabbed_keys = Qnil;
 
   DEFVAR_LISP ("w32-color-map", &Vw32_color_map,
-              doc: /* An array of color name mappings for windows.  */);
+              doc: /* An array of color name mappings for Windows.  */);
   Vw32_color_map = Qnil;
 
   DEFVAR_LISP ("w32-pass-alt-to-system", &Vw32_pass_alt_to_system,
@@ -8424,9 +8538,9 @@ open the System menu.  When nil, Emacs silently swallows alt key events.  */);
 When nil, Emacs will translate the alt key to the Alt modifier, and not Meta.  */);
   Vw32_alt_is_meta = Qt;
 
-  DEFVAR_INT ("w32-quit-key", &Vw32_quit_key,
-             doc: /* If non-zero, the virtual key code for an alternative quit key.  */);
-  XSETINT (Vw32_quit_key, 0);
+  DEFVAR_INT ("w32-quit-key", &w32_quit_key,
+              doc: /* If non-zero, the virtual key code for an alternative quit key.  */);
+  w32_quit_key = 0;
 
   DEFVAR_LISP ("w32-pass-lwindow-to-system",
               &Vw32_pass_lwindow_to_system,
@@ -8440,9 +8554,9 @@ When non-nil, the Start menu is opened by tapping the key.  */);
 When non-nil, the Start menu is opened by tapping the key.  */);
   Vw32_pass_rwindow_to_system = Qt;
 
-  DEFVAR_INT ("w32-phantom-key-code",
+  DEFVAR_LISP ("w32-phantom-key-code",
               &Vw32_phantom_key_code,
-             doc: /* Virtual key code used to generate \"phantom\" key presses.
+              doc: /* Virtual key code used to generate \"phantom\" key presses.
 Value is a number between 0 and 255.
 
 Phantom key presses are generated in order to stop the system from
@@ -8450,7 +8564,7 @@ acting on \"Windows\" key events when `w32-pass-lwindow-to-system' or
 `w32-pass-rwindow-to-system' is nil.  */);
   /* Although 255 is technically not a valid key code, it works and
      means that this hack won't interfere with any real key code.  */
-  Vw32_phantom_key_code = 255;
+  XSETINT (Vw32_phantom_key_code, 255);
 
   DEFVAR_LISP ("w32-enable-num-lock",
               &Vw32_enable_num_lock,
@@ -8505,21 +8619,21 @@ Any other value will cause the key to be ignored.  */);
   Vw32_enable_palette = Qt;
 
   DEFVAR_INT ("w32-mouse-button-tolerance",
-             &Vw32_mouse_button_tolerance,
+             &w32_mouse_button_tolerance,
              doc: /* Analogue of double click interval for faking middle mouse events.
 The value is the minimum time in milliseconds that must elapse between
 left/right button down events before they are considered distinct events.
 If both mouse buttons are depressed within this interval, a middle mouse
 button down event is generated instead.  */);
-  XSETINT (Vw32_mouse_button_tolerance, GetDoubleClickTime () / 2);
+  w32_mouse_button_tolerance = GetDoubleClickTime () / 2;
 
   DEFVAR_INT ("w32-mouse-move-interval",
-             &Vw32_mouse_move_interval,
+             &w32_mouse_move_interval,
              doc: /* Minimum interval between mouse move events.
 The value is the minimum time in milliseconds that must elapse between
 successive mouse move (or scroll bar drag) events before they are
 reported as lisp events.  */);
-  XSETINT (Vw32_mouse_move_interval, 0);
+  w32_mouse_move_interval = 0;
 
   DEFVAR_BOOL ("w32-pass-extra-mouse-buttons-to-system",
               &w32_pass_extra_mouse_buttons_to_system,
@@ -8615,7 +8729,7 @@ fontsets are automatically created.  */);
   DEFVAR_BOOL ("w32-strict-painting",
                &w32_strict_painting,
               doc: /* Non-nil means use strict rules for repainting frames.
-Set this to nil to get the old behaviour for repainting; this should
+Set this to nil to get the old behavior for repainting; this should
 only be necessary if the default setting causes problems.  */);
   w32_strict_painting = 1;
 
@@ -8800,31 +8914,32 @@ void globals_of_w32fns ()
     GetProcAddress (user32_lib, "GetClipboardSequenceNumber");
 
   DEFVAR_INT ("w32-ansi-code-page",
-             &Vw32_ansi_code_page,
+             &w32_ansi_code_page,
              doc: /* The ANSI code page used by the system.  */);
-  XSETINT (Vw32_ansi_code_page, GetACP ());
+  w32_ansi_code_page = GetACP ();
 }
 
 #undef abort
 
+void w32_abort (void) NO_RETURN;
+
 void
 w32_abort()
 {
   int button;
   button = MessageBox (NULL,
                       "A fatal error has occurred!\n\n"
-                      "Select Abort to exit, Retry to debug, Ignore to continue",
+                      "Would you like to attach a debugger?\n\n"
+                      "Select YES to debug, NO to abort Emacs",
                       "Emacs Abort Dialog",
                       MB_ICONEXCLAMATION | MB_TASKMODAL
-                      | MB_SETFOREGROUND | MB_ABORTRETRYIGNORE);
+                      | MB_SETFOREGROUND | MB_YESNO);
   switch (button)
     {
-    case IDRETRY:
+    case IDYES:
       DebugBreak ();
-      break;
-    case IDIGNORE:
-      break;
-    case IDABORT:
+      exit (2);        /* tell the compiler we will never return */
+    case IDNO:
     default:
       abort ();
       break;