use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / w32fns.c
index ad5d3c0..a848b23 100644 (file)
@@ -96,7 +96,6 @@ static HWND hourglass_hwnd = NULL;
 #define IDC_HAND MAKEINTRESOURCE(32649)
 #endif
 
-Lisp_Object Qsuppress_icon;
 Lisp_Object Qundefined_color;
 Lisp_Object Qcancel_timer;
 Lisp_Object Qfont_param;
@@ -723,8 +722,7 @@ w32_default_color_map (void)
 
   cmap = Qnil;
 
-  for (i = 0; i < sizeof (w32_color_map) / sizeof (w32_color_map[0]);
-       pc++, i++)
+  for (i = 0; i < ARRAYELTS (w32_color_map); pc++, i++)
     cmap = Fcons (Fcons (build_string (pc->name),
                         make_number (pc->colorref)),
                  cmap);
@@ -2099,6 +2097,7 @@ reset_modifiers (void)
 
 #define CURRENT_STATE(key) ((GetAsyncKeyState (key) & 0x8000) >> 8)
 
+    memset (keystate, 0, sizeof (keystate));
     GetKeyboardState (keystate);
     keystate[VK_SHIFT] = CURRENT_STATE (VK_SHIFT);
     keystate[VK_CONTROL] = CURRENT_STATE (VK_CONTROL);
@@ -3444,6 +3443,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
          tme.cbSize = sizeof (tme);
          tme.dwFlags = TME_LEAVE;
          tme.hwndTrack = hwnd;
+         tme.dwHoverTime = HOVER_DEFAULT;
 
          track_mouse_event_fn (&tme);
          track_mouse_window = hwnd;
@@ -3803,7 +3803,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
        wp.length = sizeof (WINDOWPLACEMENT);
        GetWindowPlacement (hwnd, &wp);
 
-       if (wp.showCmd != SW_SHOWMINIMIZED && (lppos->flags & SWP_NOSIZE) == 0)
+       if (wp.showCmd != SW_SHOWMAXIMIZED && wp.showCmd != SW_SHOWMINIMIZED
+           && (lppos->flags & SWP_NOSIZE) == 0)
          {
            RECT rect;
            int wdiff;
@@ -4242,6 +4243,17 @@ unwind_create_frame (Lisp_Object frame)
     {
 #ifdef GLYPH_DEBUG
       struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+
+      /* If the frame's image cache refcount is still the same as our
+        private shadow variable, it means we are unwinding a frame
+        for which we didn't yet call init_frame_faces, where the
+        refcount is incremented.  Therefore, we increment it here, so
+        that free_frame_faces, called in x_free_frame_resources
+        below, will not mistakenly decrement the counter that was not
+        incremented yet to account for this new frame.  */
+      if (FRAME_IMAGE_CACHE (f) != NULL
+         && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
+       FRAME_IMAGE_CACHE (f)->refcount++;
 #endif
 
       x_free_frame_resources (f);
@@ -4252,7 +4264,8 @@ unwind_create_frame (Lisp_Object frame)
       eassert (dpyinfo->reference_count == dpyinfo_refcount);
       eassert ((dpyinfo->terminal->image_cache == NULL
                && image_cache_refcount == 0)
-              || dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
+              || (dpyinfo->terminal->image_cache != NULL
+                  && dpyinfo->terminal->image_cache->refcount == image_cache_refcount));
 #endif
       return Qt;
     }
@@ -4331,7 +4344,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
   int minibuffer_only = 0;
   long window_prompting = 0;
   int width, height;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   Lisp_Object display;
   struct w32_display_info *dpyinfo = NULL;
@@ -4654,7 +4667,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
      and similar functions.  */
   Vwindow_list = Qnil;
 
-  return unbind_to (count, frame);
+  dynwind_end ();
+  return frame;
 }
 
 /* FRAME is used only to get a handle on the X display.  We don't pass the
@@ -5633,7 +5647,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
   Lisp_Object name;
   long window_prompting = 0;
   int width, height;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   struct gcpro gcpro1, gcpro2, gcpro3;
   struct kboard *kb;
   int face_change_count_before = face_change_count;
@@ -5853,7 +5867,8 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
   face_change_count = face_change_count_before;
 
   /* Discard the unwind_protect.  */
-  return unbind_to (count, frame);
+  dynwind_end ();
+  return frame;
 }
 
 
@@ -5980,7 +5995,7 @@ Text larger than the specified size is clipped.  */)
   int i, width, height, seen_reversed_p;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
 
   specbind (Qinhibit_redisplay, Qt);
 
@@ -6033,12 +6048,13 @@ Text larger than the specified size is clipped.  */)
          /* Put tooltip in topmost group and in position.  */
          SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOPMOST,
                        root_x, root_y, 0, 0,
-                       SWP_NOSIZE | SWP_NOACTIVATE);
+                       SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
 
          /* Ensure tooltip is on top of other topmost windows (eg menus).  */
          SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOP,
                        0, 0, 0, 0,
-                       SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+                       SWP_NOMOVE | SWP_NOSIZE
+                       | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
 
          unblock_input ();
          goto start_timer;
@@ -6236,12 +6252,13 @@ Text larger than the specified size is clipped.  */)
     SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOPMOST,
                  root_x, root_y,
                  rect.right - rect.left + FRAME_COLUMN_WIDTH (f),
-                 rect.bottom - rect.top, SWP_NOACTIVATE);
+                 rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER);
 
     /* Ensure tooltip is on top of other topmost windows (eg menus).  */
     SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOP,
                  0, 0, 0, 0,
-                 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+                 SWP_NOMOVE | SWP_NOSIZE
+                 | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
 
     /* Let redisplay know that we have made the frame visible already.  */
     SET_FRAME_VISIBLE (f, 1);
@@ -6265,7 +6282,8 @@ Text larger than the specified size is clipped.  */)
                     intern ("x-hide-tip"));
 
   UNGCPRO;
-  return unbind_to (count, Qnil);
+  dynwind_end ();
+  return Qnil;
 }
 
 
@@ -6287,7 +6305,7 @@ Value is t if tooltip was open, nil otherwise.  */)
   GCPRO2 (frame, timer);
   tip_frame = tip_timer = deleted = Qnil;
 
-  count = SPECPDL_INDEX ();
+  dynwind_begin ();
   specbind (Qinhibit_redisplay, Qt);
   specbind (Qinhibit_quit, Qt);
 
@@ -6301,7 +6319,8 @@ Value is t if tooltip was open, nil otherwise.  */)
     }
 
   UNGCPRO;
-  return unbind_to (count, deleted);
+  dynwind_end ();
+  return deleted;
 }
 \f
 /***********************************************************************
@@ -6538,13 +6557,13 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
            if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0)
              report_file_error ("filename too long", default_filename);
          }
-       len = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
-                                  SSDATA (prompt), -1, NULL, 0);
+       len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+                                   SSDATA (prompt), -1, NULL, 0);
        if (len > 32768)
          len = 32768;
        prompt_w = alloca (len * sizeof (wchar_t));
-       MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
-                            SSDATA (prompt), -1, prompt_w, len);
+       pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+                             SSDATA (prompt), -1, prompt_w, len);
       }
     else
       {
@@ -6556,18 +6575,18 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
            if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0)
              report_file_error ("filename too long", default_filename);
          }
-       len = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
-                                  SSDATA (prompt), -1, NULL, 0);
+       len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+                                   SSDATA (prompt), -1, NULL, 0);
        if (len > 32768)
          len = 32768;
        prompt_w = alloca (len * sizeof (wchar_t));
-       MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
-                            SSDATA (prompt), -1, prompt_w, len);
-       len = WideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL);
+       pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+                             SSDATA (prompt), -1, prompt_w, len);
+       len = pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL);
        if (len > 32768)
          len = 32768;
        prompt_a = alloca (len);
-       WideCharToMultiByte (CP_ACP, 0, prompt_w, -1, prompt_a, len, NULL, NULL);
+       pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, prompt_a, len, NULL, NULL);
       }
 #endif /* NTGUI_UNICODE */
 
@@ -6641,7 +6660,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
 #endif /* !NTGUI_UNICODE */
 
     {
-      int count = SPECPDL_INDEX ();
+      dynwind_begin ();
       /* Prevent redisplay.  */
       specbind (Qinhibit_redisplay, Qt);
       block_input ();
@@ -6660,7 +6679,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
        }
 #endif /* !NTGUI_UNICODE */
       unblock_input ();
-      unbind_to (count, Qnil);
+      dynwind_end ();
     }
 
     if (file_opened)
@@ -6712,7 +6731,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
   if (NILP (filename))
     Fsignal (Qquit, Qnil);
 
-  RETURN_UNGCPRO (filename);
+  return filename;
 }
 
 \f
@@ -6850,50 +6869,73 @@ handler application, but typically it is one of the following common
 operations:
 
  \"open\"    - open DOCUMENT, which could be a file, a directory, or an
-               executable program.  If it is an application, that
-               application is launched in the current buffer's default
+               executable program (application).  If it is an application,
+               that application is launched in the current buffer's default
                directory.  Otherwise, the application associated with
                DOCUMENT is launched in the buffer's default directory.
- \"print\"   - print DOCUMENT, which must be a file
- \"explore\" - start the Windows Explorer on DOCUMENT
+ \"opennew\" - like \"open\", but instruct the application to open
+               DOCUMENT in a new window.
+ \"openas\"  - open the \"Open With\" dialog for DOCUMENT.
+ \"print\"   - print DOCUMENT, which must be a file.
+ \"printto\" - print DOCUMENT, which must be a file, to a specified printer.
+               The printer should be provided in PARAMETERS, see below.
+ \"explore\" - start the Windows Explorer on DOCUMENT.
  \"edit\"    - launch an editor and open DOCUMENT for editing; which
                editor is launched depends on the association for the
-               specified DOCUMENT
- \"find\"    - initiate search starting from DOCUMENT which must specify
-               a directory
+               specified DOCUMENT.
+ \"find\"    - initiate search starting from DOCUMENT, which must specify
+               a directory.
+ \"delete\"  - move DOCUMENT, a file or a directory, to Recycle Bin.
+ \"copy\"    - copy DOCUMENT, which must be a file or a directory, into
+               the clipboard.
+ \"cut\"     - move DOCUMENT, a file or a directory, into the clipboard.
+ \"paste\"   - paste the file whose name is in the clipboard into DOCUMENT,
+               which must be a directory.
+ \"pastelink\"
+           - create a shortcut in DOCUMENT (which must be a directory)
+               the file or directory whose name is in the clipboard.
  \"runas\"   - run DOCUMENT, which must be an excutable file, with
                elevated privileges (a.k.a. \"as Administrator\").
+ \"properties\"
+           - open the property sheet dialog for DOCUMENT.
  nil       - invoke the default OPERATION, or \"open\" if default is
-               not defined or unavailable
+               not defined or unavailable.
 
 DOCUMENT is typically the name of a document file or a URL, but can
-also be a program executable to run, or a directory to open in the
-Windows Explorer.  If it is a file, it must be a local one; this
-function does not support remote file names.
+also be an executable program to run, or a directory to open in the
+Windows Explorer.  If it is a file or a directory, it must be a local
+one; this function does not support remote file names.
 
-If DOCUMENT is a program executable, the optional third arg PARAMETERS
-can be a string containing command line parameters that will be passed
-to the program; otherwise, PARAMETERS should be nil or unspecified.
+If DOCUMENT is an executable program, the optional third arg PARAMETERS
+can be a string containing command line parameters, separated by blanks,
+that will be passed to the program.  Some values of OPERATION also require
+parameters (e.g., \"printto\" requires the printer address).  Otherwise,
+PARAMETERS should be nil or unspecified.  Note that double quote characters
+in PARAMETERS must each be enclosed in 2 additional quotes, as in \"\"\".
 
 Optional fourth argument SHOW-FLAG can be used to control how the
 application will be displayed when it is invoked.  If SHOW-FLAG is nil
-or unspecified, the application is displayed normally, otherwise it is
-an integer representing a ShowWindow flag:
+or unspecified, the application is displayed as if SHOW-FLAG of 10 was
+specified, otherwise it is an integer between 0 and 11 representing
+a ShowWindow flag:
 
   0 - start hidden
-  1 - start normally
-  3 - start maximized
-  6 - start minimized  */)
+  1 - start as normal-size window
+  3 - start in a maximized window
+  6 - start in a minimized window
+ 10 - start as the application itself specifies; this is the default.  */)
   (Lisp_Object operation, Lisp_Object document, Lisp_Object parameters, Lisp_Object show_flag)
 {
   char *errstr;
   Lisp_Object current_dir = BVAR (current_buffer, directory);;
   wchar_t *doc_w = NULL, *params_w = NULL, *ops_w = NULL;
+#ifdef CYGWIN
   intptr_t result;
-#ifndef CYGWIN
+#else
   int use_unicode = w32_unicode_filenames;
   char *doc_a = NULL, *params_a = NULL, *ops_a = NULL;
   Lisp_Object absdoc, handler;
+  BOOL success;
   struct gcpro gcpro1;
 #endif
 
@@ -6921,7 +6963,48 @@ an integer representing a ShowWindow flag:
                                     GUI_SDATA (current_dir),
                                     (INTEGERP (show_flag)
                                      ? XINT (show_flag) : SW_SHOWDEFAULT));
+
+  if (result > 32)
+    return Qt;
+
+  switch (result)
+    {
+    case SE_ERR_ACCESSDENIED:
+      errstr = w32_strerror (ERROR_ACCESS_DENIED);
+      break;
+    case SE_ERR_ASSOCINCOMPLETE:
+    case SE_ERR_NOASSOC:
+      errstr = w32_strerror (ERROR_NO_ASSOCIATION);
+      break;
+    case SE_ERR_DDEBUSY:
+    case SE_ERR_DDEFAIL:
+      errstr = w32_strerror (ERROR_DDE_FAIL);
+      break;
+    case SE_ERR_DDETIMEOUT:
+      errstr = w32_strerror (ERROR_TIMEOUT);
+      break;
+    case SE_ERR_DLLNOTFOUND:
+      errstr = w32_strerror (ERROR_DLL_NOT_FOUND);
+      break;
+    case SE_ERR_FNF:
+      errstr = w32_strerror (ERROR_FILE_NOT_FOUND);
+      break;
+    case SE_ERR_OOM:
+      errstr = w32_strerror (ERROR_NOT_ENOUGH_MEMORY);
+      break;
+    case SE_ERR_PNF:
+      errstr = w32_strerror (ERROR_PATH_NOT_FOUND);
+      break;
+    case SE_ERR_SHARE:
+      errstr = w32_strerror (ERROR_SHARING_VIOLATION);
+      break;
+    default:
+      errstr = w32_strerror (0);
+      break;
+    }
+
 #else  /* !CYGWIN */
+
   current_dir = ENCODE_FILE (current_dir);
   /* We have a situation here.  If DOCUMENT is a relative file name,
      but its name includes leading directories, i.e. it lives not in
@@ -6951,6 +7034,7 @@ an integer representing a ShowWindow flag:
   if (use_unicode)
     {
       wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH];
+      SHELLEXECUTEINFOW shexinfo_w;
 
       /* Encode filename, current directory and parameters, and
         convert operation to UTF-16.  */
@@ -6962,13 +7046,13 @@ an integer representing a ShowWindow flag:
          int len;
 
          parameters = ENCODE_SYSTEM (parameters);
-         len = MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
-                                    SSDATA (parameters), -1, NULL, 0);
+         len = pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
+                                     SSDATA (parameters), -1, NULL, 0);
          if (len > 32768)
            len = 32768;
          params_w = alloca (len * sizeof (wchar_t));
-         MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
-                              SSDATA (parameters), -1, params_w, len);
+         pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
+                               SSDATA (parameters), -1, params_w, len);
        }
       if (STRINGP (operation))
        {
@@ -6984,14 +7068,28 @@ an integer representing a ShowWindow flag:
            *d++ = *s++;
          *d = 0;
        }
-      result = (intptr_t) ShellExecuteW (NULL, ops_w, doc_w, params_w,
-                                        current_dir_w,
-                                        (INTEGERP (show_flag)
-                                         ? XINT (show_flag) : SW_SHOWDEFAULT));
+
+      /* Using ShellExecuteEx and setting the SEE_MASK_INVOKEIDLIST
+        flag succeeds with more OPERATIONs (a.k.a. "verbs"), as it is
+        able to invoke verbs from shortcut menu extensions, not just
+        static verbs listed in the Registry.  */
+      memset (&shexinfo_w, 0, sizeof (shexinfo_w));
+      shexinfo_w.cbSize = sizeof (shexinfo_w);
+      shexinfo_w.fMask =
+       SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
+      shexinfo_w.hwnd = NULL;
+      shexinfo_w.lpVerb = ops_w;
+      shexinfo_w.lpFile = doc_w;
+      shexinfo_w.lpParameters = params_w;
+      shexinfo_w.lpDirectory = current_dir_w;
+      shexinfo_w.nShow =
+       (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT);
+      success = ShellExecuteExW (&shexinfo_w);
     }
   else
     {
       char document_a[MAX_PATH], current_dir_a[MAX_PATH];
+      SHELLEXECUTEINFOA shexinfo_a;
 
       filename_to_ansi (SSDATA (current_dir), current_dir_a);
       filename_to_ansi (SSDATA (document), document_a);
@@ -7006,51 +7104,27 @@ an integer representing a ShowWindow flag:
          /* Assume OPERATION is pure ASCII.  */
          ops_a = SSDATA (operation);
        }
-      result = (intptr_t) ShellExecuteA (NULL, ops_a, doc_a, params_a,
-                                        current_dir_a,
-                                        (INTEGERP (show_flag)
-                                         ? XINT (show_flag) : SW_SHOWDEFAULT));
+      memset (&shexinfo_a, 0, sizeof (shexinfo_a));
+      shexinfo_a.cbSize = sizeof (shexinfo_a);
+      shexinfo_a.fMask =
+       SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
+      shexinfo_a.hwnd = NULL;
+      shexinfo_a.lpVerb = ops_a;
+      shexinfo_a.lpFile = doc_a;
+      shexinfo_a.lpParameters = params_a;
+      shexinfo_a.lpDirectory = current_dir_a;
+      shexinfo_a.nShow =
+       (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT);
+      success = ShellExecuteExA (&shexinfo_a);
     }
-#endif /* !CYGWIN */
 
-  if (result > 32)
+  if (success)
     return Qt;
 
-  switch (result)
-    {
-    case SE_ERR_ACCESSDENIED:
-      errstr = w32_strerror (ERROR_ACCESS_DENIED);
-      break;
-    case SE_ERR_ASSOCINCOMPLETE:
-    case SE_ERR_NOASSOC:
-      errstr = w32_strerror (ERROR_NO_ASSOCIATION);
-      break;
-    case SE_ERR_DDEBUSY:
-    case SE_ERR_DDEFAIL:
-      errstr = w32_strerror (ERROR_DDE_FAIL);
-      break;
-    case SE_ERR_DDETIMEOUT:
-      errstr = w32_strerror (ERROR_TIMEOUT);
-      break;
-    case SE_ERR_DLLNOTFOUND:
-      errstr = w32_strerror (ERROR_DLL_NOT_FOUND);
-      break;
-    case SE_ERR_FNF:
-      errstr = w32_strerror (ERROR_FILE_NOT_FOUND);
-      break;
-    case SE_ERR_OOM:
-      errstr = w32_strerror (ERROR_NOT_ENOUGH_MEMORY);
-      break;
-    case SE_ERR_PNF:
-      errstr = w32_strerror (ERROR_PATH_NOT_FOUND);
-      break;
-    case SE_ERR_SHARE:
-      errstr = w32_strerror (ERROR_SHARING_VIOLATION);
-      break;
-    default:
-      errstr = w32_strerror (0);
-      break;
-    }
+  errstr = w32_strerror (0);
+
+#endif /* !CYGWIN */
+
   /* The error string might be encoded in the locale's encoding.  */
   if (!NILP (Vlocale_coding_system))
     {
@@ -7470,8 +7544,8 @@ If the underlying system call fails, value is nil.  */)
       (char *, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER)
       = GetProcAddress (hKernel, "GetDiskFreeSpaceExA");
     bool have_pfn_GetDiskFreeSpaceEx =
-      (w32_unicode_filenames && pfn_GetDiskFreeSpaceExW
-       || !w32_unicode_filenames && pfn_GetDiskFreeSpaceExA);
+      ((w32_unicode_filenames && pfn_GetDiskFreeSpaceExW)
+       || (!w32_unicode_filenames && pfn_GetDiskFreeSpaceExA));
 
     /* On Windows, we may need to specify the root directory of the
        volume holding FILENAME.  */
@@ -8015,12 +8089,13 @@ frame_parm_handler w32_frame_parm_handlers[] =
 void
 syms_of_w32fns (void)
 {
+#include "w32fns.x"
+
   globals_of_w32fns ();
   track_mouse_window = NULL;
 
   w32_visible_system_caret_hwnd = NULL;
 
-  DEFSYM (Qsuppress_icon, "suppress-icon");
   DEFSYM (Qundefined_color, "undefined-color");
   DEFSYM (Qcancel_timer, "cancel-timer");
   DEFSYM (Qhyper, "hyper");
@@ -8035,8 +8110,6 @@ syms_of_w32fns (void)
   DEFSYM (Qworkarea, "workarea");
   DEFSYM (Qmm_size, "mm-size");
   DEFSYM (Qframes, "frames");
-  /* This is the end of symbol initialization.  */
-
 
   Fput (Qundefined_color, Qerror_conditions,
        listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
@@ -8298,61 +8371,8 @@ 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;
 
-#if 0 /* TODO: Port to W32 */
-  defsubr (&Sx_change_window_property);
-  defsubr (&Sx_delete_window_property);
-  defsubr (&Sx_window_property);
-#endif
-  defsubr (&Sxw_display_color_p);
-  defsubr (&Sx_display_grayscale_p);
-  defsubr (&Sxw_color_defined_p);
-  defsubr (&Sxw_color_values);
-  defsubr (&Sx_server_max_request_size);
-  defsubr (&Sx_server_vendor);
-  defsubr (&Sx_server_version);
-  defsubr (&Sx_display_pixel_width);
-  defsubr (&Sx_display_pixel_height);
-  defsubr (&Sx_display_mm_width);
-  defsubr (&Sx_display_mm_height);
-  defsubr (&Sx_display_screens);
-  defsubr (&Sx_display_planes);
-  defsubr (&Sx_display_color_cells);
-  defsubr (&Sx_display_visual_class);
-  defsubr (&Sx_display_backing_store);
-  defsubr (&Sx_display_save_under);
-  defsubr (&Sx_create_frame);
-  defsubr (&Sx_open_connection);
-  defsubr (&Sx_close_connection);
-  defsubr (&Sx_display_list);
-  defsubr (&Sx_synchronize);
-
-  /* W32 specific functions */
-
-  defsubr (&Sw32_define_rgb_color);
-  defsubr (&Sw32_default_color_map);
-  defsubr (&Sw32_display_monitor_attributes_list);
-  defsubr (&Sw32_send_sys_command);
-  defsubr (&Sw32_shell_execute);
-  defsubr (&Sw32_register_hot_key);
-  defsubr (&Sw32_unregister_hot_key);
-  defsubr (&Sw32_registered_hot_keys);
-  defsubr (&Sw32_reconstruct_hot_key);
-  defsubr (&Sw32_toggle_lock_key);
-  defsubr (&Sw32_window_exists_p);
-  defsubr (&Sw32_frame_rect);
-  defsubr (&Sw32_battery_status);
-
-#ifdef WINDOWSNT
-  defsubr (&Sfile_system_info);
-  defsubr (&Sdefault_printer_name);
-#endif
-
-  defsubr (&Sset_message_beep);
-
   hourglass_hwnd = NULL;
 
-  defsubr (&Sx_show_tip);
-  defsubr (&Sx_hide_tip);
   tip_timer = Qnil;
   staticpro (&tip_timer);
   tip_frame = Qnil;
@@ -8360,11 +8380,6 @@ only be necessary if the default setting causes problems.  */);
 
   last_show_tip_args = Qnil;
   staticpro (&last_show_tip_args);
-
-  defsubr (&Sx_file_dialog);
-#ifdef WINDOWSNT
-  defsubr (&Ssystem_move_file_to_trash);
-#endif
 }
 
 \f