]> code.delx.au - gnu-emacs/commitdiff
Merge from trunk.
authorEli Zaretskii <eliz@gnu.org>
Sat, 7 Dec 2013 17:21:57 +0000 (19:21 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sat, 7 Dec 2013 17:21:57 +0000 (19:21 +0200)
1  2 
etc/NEWS
nt/inc/ms-w32.h
src/emacs.c
src/fileio.c
src/gnutls.c
src/image.c
src/w32fns.c
src/w32proc.c
src/w32term.c

diff --combined etc/NEWS
index 5f6cf12fb24053313a41da1e111837e76898f0a1,89fc9583759926d24ed8e0c8204bd59e34a1562d..f354f5ce2f79c7862925a29944625d293caa838b
+++ b/etc/NEWS
@@@ -62,9 -62,20 +62,20 @@@ To use the old backend by default, do o
  \f
  * Startup Changes in Emacs 24.4
  
+ +++
+ ** When initializing `load-path', an empty element in the EMACSLOADPATH
+ environment variable (either leading, e.g., ":/foo"; trailing, e.g.,
+ "/foo:"; or embedded, e.g., "/foo::/bar") is replaced with the default
+ load-path (the one that would have been used if EMACSLOADPATH was unset).
+ This makes it easier to _extend_ the load-path via EMACSLOADPATH
+ (previously, EMACSLOADPATH had to specify the complete load-path,
+ including the defaults).  (In older versions of Emacs, an empty element
+ was replaced by ".", so use an explicit "." now if that is what you want.)
  +++
  ** The -L option, which normally prepends its argument to load-path,
- will instead append, if the argument begins with `:'.
+ will instead append, if the argument begins with `:' (or `;' on MS Windows;
+ i.e., `path-separator').
  
  \f
  * Changes in Emacs 24.4
@@@ -160,10 -171,13 +171,13 @@@ monitor, use the new functions above.  
  `x-display-pixel-width', `x-display-pixel-height', `display-mm-width',
  `display-mm-height', `x-display-mm-width', and `x-display-mm-height'.
  
- ** New macro `alternatives-define' can be used to define generic commands.
+ ** New macro `define-alternatives' can be used to define generic commands.
  Generic commands are interactive functions whose implementation can be
  selected among several alternatives, as a matter of user preference.
  
+ ** New hooks `focus-in-hook', `focus-out-hook'.
+ These are normal hooks run when an Emacs frame gains or loses input focus.
  ** The blink cursor stops blinking after 10 blinks (default) on X and NS.
  You can change the default by customizing the variable blink-cursor-blinks.
  Also timers for blinking are stopped when no blinking is done, so Emacs does
@@@ -189,6 -203,10 +203,10 @@@ Czech typography rules.  To globally en
  \f
  * Editing Changes in Emacs 24.4
  
+ ** `electric-indent-mode' is enabled by default.
+ ** Uniquify is enabled by default.
  ** Command `rectangle-mark-mode' bound to C-x SPC makes a rectangular region.
  Most commands are still unaware of it, but kill/yank do work on the rectangle.
  
@@@ -229,6 -247,8 +247,8 @@@ You can pick the name of the function a
  \f
  * Changes in Specialized Modes and Packages in Emacs 24.4
  
+ ** The backtrace debugger can display local vars with `v'.
  ** prolog-use-smie has been removed, along with the non-SMIE indentation code.
  
  ** SMIE indentation can be customized via `smie-config'.
@@@ -625,6 -645,22 +645,22 @@@ whether it is safe to use Bash's --noed
  +++
  ** There is a new macro `skip-unless' for skipping ERT tests.  See the manual.
  
+ ** Imenu
+ *** New option `imenu-generic-skip-comments-and-strings'.
+ ** Ruby mode
+ *** New option `ruby-encoding-magic-comment-style'.
+ *** New option `ruby-custom-encoding-magic-comment-template'.
+ *** New mode menu.
+ *** Improved syntax highlighting and indentation.
+ *** Add more Ruby file types to `auto-mode-alist'.
  \f
  * New Modes and Packages in Emacs 24.4
  
@@@ -717,6 -753,8 +753,8 @@@ for something (not just adding element
  \f
  * Lisp Changes in Emacs 24.4
  
+ ** New function get-pos-property.
  ** New hook `pre-redisplay-function'.
  
  +++
@@@ -736,8 -774,8 +774,8 @@@ frame
  *** `bool-vector-set-difference'
  *** `bool-vector-not'
  *** `bool-vector-subsetp'
- *** `bool-vector-count-matches'
- *** `bool-vector-count-matches-at'
+ *** `bool-vector-count-consecutive'
+ *** `bool-vector-count-population'
  
  ** Comparison functions =, <, >, <=, >= now take many arguments.
  
  ** New library helpers.el for misc helper functions
  *** `hash-table-keys'
  *** `hash-table-values'
+ *** `string-blank-p`
+ *** `string-empty-p`
+ *** `string-join`
+ *** `string-reverse`
+ *** `string-trim-left'
+ *** `string-trim-right'
+ *** `string-trim'
  
  ** Obsoleted functions:
  *** `log10'
@@@ -772,10 -817,15 +817,15 @@@ The few hooks that used with-wrapper-ho
  *** `completion-in-region-function' obsoletes `completion-in-region-functions'.
  *** `filter-buffer-substring-function' obsoletes `filter-buffer-substring-functions'.
  
+ ** `byte-compile-interactive-only-functions' is now obsolete.
+ It has been replaced by the symbol property 'interactive-only.
  ** `split-string' now takes an optional argument TRIM.
  The value, if non-nil, is a regexp that specifies what to trim from
  the start and end of each substring.
  
+ ** New function `string-suffix-p'.
  ** `get-upcase-table' is obsoleted by the new `case-table-get-table'.
  
  ** Support for filesystem notifications.
@@@ -930,14 -980,6 +980,14 @@@ files are in share/emacs/VERSION/etc.  
  directories and will find the files in there automatically; there's no
  need to set any variables due to this change.)
  
 ++++
 +** Emacs on Windows 2000 and later can now access files and directories
 +whose names cannot be encoded in the current system codepage.
 +
 +The new variable `w32-unicode-filenames' controls this feature: if it
 +is t, Emacs uses Unicode APIs to pass file names to system calls,
 +which lifts the limitation of file names to the current locale.
 +
  +++
  ** The "generate a backtrace on fatal error" feature now works on MS Windows.
  The backtrace is written to the 'emacs_backtrace.txt' file in the
@@@ -1806,6 -1848,13 +1856,13 @@@ reused
  *** New option `switch-to-buffer-preserve-window-point' to restore a
  window's point when switching buffers.
  
+ *** New display action function `display-buffer-no-window' to not
+ display the buffer in a window.
+ *** New display action alist entry `allow-no-window' to indicate the
+ caller of `display-buffer' is ready to handle the case of not
+ displaying the buffer in a window.
  *** New display action alist entries `window-height' and `window-width'
  specify the size of new windows created by `display-buffer'.
  
diff --combined nt/inc/ms-w32.h
index 3691b303b8086228f3eb0c55673756dd6e5f98f8,cd6ec1725d610f1e985fe6bcc15ef71815af9495..bcccebc13a0ebfff90d88b423f7dcb69b2faba33
@@@ -152,16 -152,10 +152,13 @@@ extern char *getenv ()
  #define MAXPATHLEN      _MAX_PATH
  #endif
  
 +/* This is used to hold UTF-8 encoded file names.  */
 +#define MAX_UTF8_PATH   (MAXPATHLEN * 4)
 +
  #ifdef HAVE_NTGUI
  # ifndef HAVE_WINDOW_SYSTEM
  #  define HAVE_WINDOW_SYSTEM 1
  # endif
- # ifndef HAVE_MENUS
- #  define HAVE_MENUS 1
- # endif
  #endif
  
  /* Get some redefinitions in place.  */
  extern struct tm * sys_localtime (const time_t *);
  /* MinGW64 uses a 2-argument _setjmp, and setjmp is a macro defined to
     supply the 2nd arg correctly, so don't use _setjmp directly in that
-    case. */
+    case.  */
  #undef HAVE__SETJMP
  #endif
  
  #define strerror sys_strerror
  #undef unlink
  #define unlink  sys_unlink
 +#undef opendir
 +#define opendir sys_opendir
 +#undef closedir
 +#define closedir sys_closedir
 +#undef readdir
 +#define readdir sys_readdir
 +#undef seekdir
 +#define seekdir sys_seekdir
  /* This prototype is needed because some files include config.h
     _after_ the standard headers, so sys_unlink gets no prototype from
     stdio.h or io.h.  */
diff --combined src/emacs.c
index 22be1d82949b2c51d5752f0fd4691824f0eb486b,159b0d5040d516b7b348c3185f2c4b02d56d14f7..af69e2c4efead6691d8dd29aec8ce1f4fff889b6
@@@ -36,7 -36,6 +36,7 @@@ along with GNU Emacs.  If not, see <htt
  #ifdef WINDOWSNT
  #include <fcntl.h>
  #include <sys/socket.h>
 +#include <mbstring.h>
  #include "w32.h"
  #include "w32heap.h"
  #endif
@@@ -394,20 -393,7 +394,20 @@@ init_cmdargs (int argc, char **argv, in
    initial_argv = argv;
    initial_argc = argc;
  
 +#ifdef WINDOWSNT
 +  /* Must use argv[0] converted to UTF-8, as it begets many standard
 +     file and directory names.  */
 +  {
 +    char argv0[MAX_UTF8_PATH];
 +
 +    if (filename_from_ansi (argv[0], argv0) == 0)
 +      raw_name = build_unibyte_string (argv0);
 +    else
 +      raw_name = build_unibyte_string (argv[0]);
 +  }
 +#else
    raw_name = build_unibyte_string (argv[0]);
 +#endif
  
    /* Add /: to the front of the name
       if it would otherwise be treated as magic.  */
@@@ -809,14 -795,6 +809,14 @@@ main (int argc, char **argv
  
    if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args))
      {
 +#ifdef WINDOWSNT
 +      /* argv[] array is kept in its original ANSI codepage encoding,
 +       we need to convert to UTF-8, for chdir to work.  */
 +      char newdir[MAX_UTF8_PATH];
 +
 +      filename_from_ansi (ch_to_dir, newdir);
 +      ch_to_dir = newdir;
 +#endif
        original_pwd = get_current_dir_name ();
        if (chdir (ch_to_dir) != 0)
          {
@@@ -1539,6 -1517,10 +1539,10 @@@ Using an Emacs configured with --with-x
    init_keyboard ();   /* This too must precede init_sys_modes.  */
    if (!noninteractive)
      init_display ();  /* Determine terminal type.  Calls init_sys_modes.  */
+ #if HAVE_W32NOTIFY
+   else
+     init_crit ();     /* w32notify.c needs this in batch mode.  */
+ #endif        /* HAVE_W32NOTIFY */
    init_xdisp ();
  #ifdef HAVE_WINDOW_SYSTEM
    init_fringe ();
        char *file;
        /* Handle -l loadup, args passed by Makefile.  */
        if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
 -      Vtop_level = list2 (intern_c_string ("load"), build_string (file));
 +      {
 +#ifdef WINDOWSNT
 +        char file_utf8[MAX_UTF8_PATH];
 +
 +        if (filename_from_ansi (file, file_utf8) == 0)
 +          file = file_utf8;
 +#endif
 +        Vtop_level = list2 (intern_c_string ("load"),
 +                            build_unibyte_string (file));
 +      }
        /* Unless next switch is -nl, load "loadup.el" first thing.  */
        if (! no_loadup)
        Vtop_level = list2 (intern_c_string ("load"),
@@@ -2198,21 -2171,18 +2202,24 @@@ synchronize_system_messages_locale (voi
  \f
  
  Lisp_Object
- decode_env_path (const char *evarname, const char *defalt)
+ decode_env_path (const char *evarname, const char *defalt, bool empty)
  {
    const char *path, *p;
    Lisp_Object lpath, element, tem;
+   /* Default is to use "." for empty path elements.
+      But if argument EMPTY is true, use nil instead.  */
+   Lisp_Object empty_element = empty ? Qnil : build_string (".");
  #ifdef WINDOWSNT
    bool defaulted = 0;
 -  const char *emacs_dir = egetenv ("emacs_dir");
    static const char *emacs_dir_env = "%emacs_dir%/";
    const size_t emacs_dir_len = strlen (emacs_dir_env);
 +  const char *edir = egetenv ("emacs_dir");
 +  char emacs_dir[MAX_UTF8_PATH];
 +
 +  /* egetenv looks in process-environment, which holds the variables
 +     in their original system-locale encoding.  We need emacs_dir to
 +     be in UTF-8.  */
 +  filename_from_ansi (edir, emacs_dir);
  #endif
  
    /* It's okay to use getenv here, because this function is only used
    /* Ensure values from the environment use the proper directory separator.  */
    if (path)
      {
 -      char *path_copy = alloca (strlen (path) + 1);
 +      char *path_copy;
 +
 +#ifdef WINDOWSNT
 +      char *path_utf8, *q, *d;
 +      int cnv_result;
 +
 +      /* Convert each element of PATH to UTF-8.  */
 +      p = path_copy = alloca (strlen (path) + 1);
        strcpy (path_copy, path);
 -      dostounix_filename (path_copy, 0);
 +      d = path_utf8 = alloca (4 * strlen (path) + 1);
 +      *d = '\0';
 +      do {
 +      q = _mbschr (p, SEPCHAR);
 +      if (q)
 +        *q = '\0';
 +      cnv_result = filename_from_ansi (p, d);
 +      if (q)
 +        {
 +          *q++ = SEPCHAR;
 +          p = q;
 +          /* If conversion of this PATH elements fails, make sure
 +             destination pointer will stay put, thus effectively
 +             ignoring the offending element.  */
 +          if (cnv_result == 0)
 +            {
 +              d += strlen (d);
 +              *d++ = SEPCHAR;
 +            }
 +        }
 +      else if (cnv_result != 0 && d > path_utf8)
 +        d[-1] = '\0'; /* remove last semi-colon and null-terminate PATH */
 +      } while (q);
 +      path_copy = path_utf8;
 +#else  /* MSDOS */
 +      path_copy = alloca (strlen (path) + 1);
 +      strcpy (path_copy, path);
 +#endif
 +      dostounix_filename (path_copy);
        path = path_copy;
      }
  #endif
        if (!p)
        p = path + strlen (path);
        element = (p - path ? make_unibyte_string (path, p - path)
-                : build_string ("."));
+                : empty_element);
+       if (! NILP (element))
+         {
  #ifdef WINDOWSNT
-       /* Relative file names in the default path are interpreted as
-        being relative to $emacs_dir.  */
-       if (emacs_dir && defaulted
-         && strncmp (path, emacs_dir_env, emacs_dir_len) == 0)
-       element = Fexpand_file_name (Fsubstring (element,
-                                                make_number (emacs_dir_len),
-                                                Qnil),
-                                    build_unibyte_string (emacs_dir));
- #endif
-       /* Add /: to the front of the name
-        if it would otherwise be treated as magic.  */
-       tem = Ffind_file_name_handler (element, Qt);
-       /* However, if the handler says "I'm safe",
-        don't bother adding /:.  */
-       if (SYMBOLP (tem))
-       {
-         Lisp_Object prop;
-         prop = Fget (tem, intern ("safe-magic"));
-         if (! NILP (prop))
-           tem = Qnil;
-       }
+           /* Relative file names in the default path are interpreted as
+              being relative to $emacs_dir.  */
+           if (emacs_dir && defaulted
+               && strncmp (path, emacs_dir_env, emacs_dir_len) == 0)
+             element = Fexpand_file_name (Fsubstring
+                                          (element,
+                                           make_number (emacs_dir_len),
+                                           Qnil),
+                                          build_unibyte_string (emacs_dir));
+ #endif
+           /* Add /: to the front of the name
+              if it would otherwise be treated as magic.  */
+           tem = Ffind_file_name_handler (element, Qt);
+           /* However, if the handler says "I'm safe",
+              don't bother adding /:.  */
+           if (SYMBOLP (tem))
+             {
+               Lisp_Object prop;
+               prop = Fget (tem, intern ("safe-magic"));
+               if (! NILP (prop))
+                 tem = Qnil;
+             }
  
-       if (! NILP (tem))
-       element = concat2 (build_string ("/:"), element);
+           if (! NILP (tem))
+             element = concat2 (build_string ("/:"), element);
+         } /* !NILP (element) */
  
        lpath = Fcons (element, lpath);
        if (*p)
diff --combined src/fileio.c
index 7b4bd7f196da86ea81cd2bd35040d310e895b867,a0603b490d9f523c6d52ae71474bb21002eacac3..2ef3f1fe0f9399a890e545942b8485cecffcae04
@@@ -460,8 -460,7 +460,8 @@@ Given a Unix syntax file name, returns 
            strcat (res, "/");
          beg = res;
          p = beg + strlen (beg);
 -        dostounix_filename (beg, 0);
 +        dostounix_filename (beg);
 +        /* FIXME: Figure out the multibyte vs unibyte stuff here.  */
          tem_fn = make_specified_string (beg, -1, p - beg,
                                          STRING_MULTIBYTE (filename));
        }
    else if (STRING_MULTIBYTE (filename))
      {
        tem_fn = make_specified_string (beg, -1, p - beg, 1);
 -      dostounix_filename (SSDATA (tem_fn), 1);
 +      dostounix_filename (SSDATA (tem_fn));
  #ifdef WINDOWSNT
        if (!NILP (Vw32_downcase_file_names))
        tem_fn = Fdowncase (tem_fn);
      }
    else
      {
 -      dostounix_filename (beg, 0);
 +      dostounix_filename (beg);
        tem_fn = make_specified_string (beg, -1, p - beg, 0);
      }
    return tem_fn;
@@@ -584,7 -583,7 +584,7 @@@ file_name_as_directory (char *dst, cons
      dst[srclen++] = DIRECTORY_SEP;
    dst[srclen] = 0;
  #ifdef DOS_NT
 -  dostounix_filename (dst, multibyte);
 +  dostounix_filename (dst);
  #endif
    return srclen;
  }
@@@ -653,7 -652,7 +653,7 @@@ directory_file_name (char *dst, char *s
    memcpy (dst, src, srclen);
    dst[srclen] = 0;
  #ifdef DOS_NT
 -  dostounix_filename (dst, multibyte);
 +  dostounix_filename (dst);
  #endif
    return srclen;
  }
@@@ -1102,8 -1101,7 +1102,8 @@@ filesystem tree, not (expand-file-name 
  #ifdef DOS_NT
          /* Make sure directories are all separated with /, but
             avoid allocation of a new string when not required. */
 -        dostounix_filename (nm, multibyte);
 +        /* FIXME: Figure out multibyte and downcase here.  */
 +        dostounix_filename (nm);
  #ifdef WINDOWSNT
          if (IS_DIRECTORY_SEP (nm[1]))
            {
          nm++;
          /* `egetenv' may return a unibyte string, which will bite us since
             we expect the directory to be multibyte.  */
 -        tem = build_string (newdir);
 +#ifdef WINDOWSNT
 +        if (newdir[0])
 +          {
 +            char newdir_utf8[MAX_UTF8_PATH];
 +
 +            filename_from_ansi (newdir, newdir_utf8);
 +            tem = build_string (newdir_utf8);
 +          }
 +        else
 +#else
 +          tem = build_string (newdir);
 +#endif
          if (multibyte && !STRING_MULTIBYTE (tem))
            {
              hdir = DECODE_FILE (tem);
             indirectly by prepending newdir to nm if necessary, and using
             cwd (or the wd of newdir's drive) as the new newdir.  */
          char *adir;
 +#ifdef WINDOWSNT
 +        const int adir_size = MAX_UTF8_PATH;
 +#else
 +        const int adir_size = MAXPATHLEN + 1;
 +#endif
  
          if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
            {
              strcat (tmp, nm);
              nm = tmp;
            }
 -        adir = alloca (MAXPATHLEN + 1);
 +        adir = alloca (adir_size);
          if (drive)
            {
              if (!getdefdir (c_toupper (drive) - 'A' + 1, adir))
                strcpy (adir, "/");
            }
          else
 -          getcwd (adir, MAXPATHLEN + 1);
 +          getcwd (adir, adir_size);
          if (multibyte)
            {
              Lisp_Object tem = build_string (adir);
        target[1] = ':';
        }
      result = make_specified_string (target, -1, o - target, multibyte);
 -    dostounix_filename (SSDATA (result), multibyte);
 +    /* FIXME: Figure out the multibyte and downcase here.  */
 +    dostounix_filename (SSDATA (result));
  #ifdef WINDOWSNT
      if (!NILP (Vw32_downcase_file_names))
        result = Fdowncase (result);
@@@ -1782,8 -1763,7 +1782,8 @@@ those `/' is discarded.  */
    nm = xlispstrdupa (filename);
  
  #ifdef DOS_NT
 -  dostounix_filename (nm, multibyte);
 +  /* FIXME: Figure out multibyte and downcase.  */
 +  dostounix_filename (nm);
    substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0);
  #endif
    endp = nm + SBYTES (filename);
@@@ -2681,9 -2661,9 +2681,9 @@@ emacs_readlinkat (int fd, char const *f
    if (!buf)
      return Qnil;
  
 -  val = build_string (buf);
 +  val = build_unibyte_string (buf);
    if (buf[0] == '/' && strchr (buf, ':'))
 -    val = concat2 (build_string ("/:"), val);
 +    val = concat2 (build_unibyte_string ("/:"), val);
    if (buf != readlink_buf)
      xfree (buf);
    val = DECODE_FILE (val);
@@@ -3878,6 -3858,9 +3878,9 @@@ by calling `format-decode', which see
          beg_offset += same_at_start - BEGV_BYTE;
          end_offset -= ZV_BYTE - same_at_end;
  
+         invalidate_buffer_caches (current_buffer,
+                                   BYTE_TO_CHAR (same_at_start),
+                                   BYTE_TO_CHAR (same_at_end));
          del_range_byte (same_at_start, same_at_end, 0);
          /* Insert from the file at the proper position.  */
          temp = BYTE_TO_CHAR (same_at_start);
        {
          /* Truncate the buffer to the size of the file.  */
          if (same_at_start != same_at_end)
-           del_range_byte (same_at_start, same_at_end, 0);
+           {
+             invalidate_buffer_caches (current_buffer,
+                                       BYTE_TO_CHAR (same_at_start),
+                                       BYTE_TO_CHAR (same_at_end));
+             del_range_byte (same_at_start, same_at_end, 0);
+           }
          inserted = 0;
  
          unbind_to (this_count, Qnil);
  
        if (same_at_end != same_at_start)
        {
+         invalidate_buffer_caches (current_buffer,
+                                   BYTE_TO_CHAR (same_at_start),
+                                   BYTE_TO_CHAR (same_at_end));
          del_range_byte (same_at_start, same_at_end, 0);
          temp = GPT;
          eassert (same_at_start == GPT_BYTE);
  init_fileio (void)
  {
    valid_timestamp_file_system = 0;
+   /* fsync can be a significant performance hit.  Often it doesn't
+      suffice to make the file-save operation survive a crash.  For
+      batch scripts, which are typically part of larger shell commands
+      that don't fsync other files, its effect on performance can be
+      significant so its utility is particularly questionable.
+      Hence, for now by default fsync is used only when interactive.
+      For more on why fsync often fails to work on today's hardware, see:
+      Zheng M et al. Understanding the robustness of SSDs under power fault.
+      11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84
+      http://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf
+      For more on why fsync does not suffice even if it works properly, see:
+      Roche X. Necessary step(s) to synchronize filename operations on disk.
+      Austin Group Defect 672, 2013-03-19
+      http://austingroupbugs.net/view.php?id=672  */
+   write_region_inhibit_fsync = noninteractive;
  }
  
  void
@@@ -5849,11 -5858,7 +5878,11 @@@ syms_of_fileio (void
  
    DEFVAR_LISP ("file-name-coding-system", Vfile_name_coding_system,
               doc: /* Coding system for encoding file names.
 -If it is nil, `default-file-name-coding-system' (which see) is used.  */);
 +If it is nil, `default-file-name-coding-system' (which see) is used.
 +
 +On MS-Windows, the value of this variable is largely ignored if
 +\`w32-unicode-filenames' (which see) is non-nil.  Emacs on Windows
 +behaves as if file names were encoded in `utf-8'.  */);
    Vfile_name_coding_system = Qnil;
  
    DEFVAR_LISP ("default-file-name-coding-system",
@@@ -5864,11 -5869,7 +5893,11 @@@ This variable is used only when `file-n
  This variable is set/changed by the command `set-language-environment'.
  User should not set this variable manually,
  instead use `file-name-coding-system' to get a constant encoding
 -of file names regardless of the current language environment.  */);
 +of file names regardless of the current language environment.
 +
 +On MS-Windows, the value of this variable is largely ignored if
 +\`w32-unicode-filenames' (which see) is non-nil.  Emacs on Windows
 +behaves as if file names were encoded in `utf-8'.  */);
    Vdefault_file_name_coding_system = Qnil;
  
    DEFSYM (Qformat_decode, "format-decode");
@@@ -6013,28 -6014,12 +6042,12 @@@ in the buffer; this is the default beha
  file is usually more useful if it contains the deleted text.  */);
    Vauto_save_include_big_deletions = Qnil;
  
-   /* fsync can be a significant performance hit.  Often it doesn't
-      suffice to make the file-save operation survive a crash.  For
-      batch scripts, which are typically part of larger shell commands
-      that don't fsync other files, its effect on performance can be
-      significant so its utility is particularly questionable.
-      Hence, for now by default fsync is used only when interactive.
-      For more on why fsync often fails to work on today's hardware, see:
-      Zheng M et al. Understanding the robustness of SSDs under power fault.
-      11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84
-      http://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf
-      For more on why fsync does not suffice even if it works properly, see:
-      Roche X. Necessary step(s) to synchronize filename operations on disk.
-      Austin Group Defect 672, 2013-03-19
-      http://austingroupbugs.net/view.php?id=672  */
    DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync,
               doc: /* Non-nil means don't call fsync in `write-region'.
  This variable affects calls to `write-region' as well as save commands.
  Setting this to nil may avoid data loss if the system loses power or
  the operating system crashes.  */);
-   write_region_inhibit_fsync = noninteractive;
+   write_region_inhibit_fsync = 0; /* See also `init_fileio' above.  */
  
    DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash,
                 doc: /* Specifies whether to use the system's trash can.
diff --combined src/gnutls.c
index 19617cea4b29ccd553a5407a59b6c982ab17a9d6,5a296166cdd482e72d8697d75ae0fb93582a9801..9ea3f59100d9c50f428edfa3457f9c66cc6e89f1
@@@ -21,7 -21,6 +21,7 @@@ along with GNU Emacs.  If not, see <htt
  
  #include "lisp.h"
  #include "process.h"
 +#include "coding.h"
  
  #ifdef HAVE_GNUTLS
  #include <gnutls/gnutls.h>
@@@ -56,8 -55,10 +56,10 @@@ static Lisp_Object QCgnutls_bootprop_ve
  static Lisp_Object QCgnutls_bootprop_callbacks_verify;
  
  static void gnutls_log_function (int, const char *);
- static void gnutls_audit_log_function (gnutls_session_t, const char *);
  static void gnutls_log_function2 (int, const char*, const char*);
+ #ifdef HAVE_GNUTLS3
+ static void gnutls_audit_log_function (gnutls_session_t, const char *);
+ #endif
  
  \f
  #ifdef WINDOWSNT
@@@ -262,6 -263,7 +264,7 @@@ init_gnutls_functions (void
  #endif /* !WINDOWSNT */
  
  \f
+ #ifdef HAVE_GNUTLS3
  /* Function to log a simple audit message.  */
  static void
  gnutls_audit_log_function (gnutls_session_t session, const char* string)
        message ("gnutls.c: [audit] %s", string);
      }
  }
+ #endif
  
  /* Function to log a simple message.  */
  static void
@@@ -896,13 -899,6 +900,13 @@@ one trustfile (usually a CA bundle).  *
            {
              GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
                           SSDATA (trustfile));
 +            trustfile = ENCODE_FILE (trustfile);
 +#ifdef WINDOWSNT
 +            /* Since GnuTLS doesn't support UTF-8 or UTF-16 encoded
 +               file names on Windows, we need to re-encode the file
 +               name using the current ANSI codepage.  */
 +            trustfile = ansi_encode_filename (trustfile);
 +#endif
              ret = fn_gnutls_certificate_set_x509_trust_file
                (x509_cred,
                 SSDATA (trustfile),
            {
              GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
                           SSDATA (crlfile));
 +            crlfile = ENCODE_FILE (crlfile);
 +#ifdef WINDOWSNT
 +            crlfile = ansi_encode_filename (crlfile);
 +#endif
              ret = fn_gnutls_certificate_set_x509_crl_file
                (x509_cred, SSDATA (crlfile), file_format);
  
                           SSDATA (keyfile));
              GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
                           SSDATA (certfile));
 +            keyfile = ENCODE_FILE (keyfile);
 +            certfile = ENCODE_FILE (certfile);
 +#ifdef WINDOWSNT
 +            keyfile = ansi_encode_filename (keyfile);
 +            certfile = ansi_encode_filename (certfile);
 +#endif
              ret = fn_gnutls_certificate_set_x509_key_file
                (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format);
  
diff --combined src/image.c
index 89e4f863d535cab485315ea9812d29c2ff4172a6,91038dd480a23ad278557768be88e4182e6e26c9..38a92277299aa8254ffb6ae3424913fc694c34c5
@@@ -3590,12 -3590,6 +3590,12 @@@ xpm_load (struct frame *f, struct imag
        }
  
  #ifdef HAVE_NTGUI
 +#ifdef WINDOWSNT
 +      /* FILE is encoded in UTF-8, but image libraries on Windows
 +       support neither UTF-8 nor UTF-16 encoded file names.  So we
 +       need to re-encode it in ANSI.  */
 +      file = ansi_encode_filename (file);
 +#endif
        /* XpmReadFileToPixmap is not available in the Windows port of
         libxpm.  But XpmReadFileToImage almost does what we want.  */
        rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
@@@ -6974,9 -6968,6 +6974,9 @@@ tiff_load (struct frame *f, struct imag
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
          return 0;
        }
 +#ifdef WINDOWSNT
 +      file = ansi_encode_filename (file);
 +#endif
  
        /* Try to open the image file.  */
        tiff = fn_TIFFOpen (SSDATA (file), "r");
@@@ -7362,9 -7353,6 +7362,9 @@@ gif_load (struct frame *f, struct imag
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
          return 0;
        }
 +#ifdef WINDOWSNT
 +      file = ansi_encode_filename (file);
 +#endif
  
        /* Open the GIF file.  */
  #if GIFLIB_MAJOR < 5
@@@ -8105,7 -8093,7 +8105,7 @@@ imagemagick_compute_animated_image (Mag
            {
              /* Sanity check.  This shouldn't happen, but apparently
                 also does in some pictures.  */
-             if (x + source_left > dest_width)
+             if (x + source_left > dest_width - 1)
                break;
              /* Normally we only copy over non-transparent pixels,
                 but if the disposal method is "Background", then we
@@@ -8491,9 -8479,6 +8491,9 @@@ imagemagick_load (struct frame *f, stru
          image_error ("Cannot find image file `%s'", file_name, Qnil);
          return 0;
        }
 +#ifdef WINDOWSNT
 +      file = ansi_encode_filename (file);
 +#endif
        success_p = imagemagick_load_image (f, img, 0, 0, SSDATA (file));
      }
    /* Else its not a file, its a lisp object.  Load the image from a
@@@ -9517,7 -9502,7 +9517,7 @@@ A cross is always drawn on black & whit
  
    DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
      doc: /* List of directories to search for window system bitmap files.  */);
-   Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS);
+   Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS, 0);
  
    DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
      doc: /* Maximum time after which images are removed from the cache.
diff --combined src/w32fns.c
index a4f9e320fc4b496d0439d2b4e0a4cb816f1c9a96,79011f9afc21b30788c865b10fb7841fd78735fa..b3e6d29b9732d8c7b9c7e2d1393a3a35bf2da897
@@@ -51,7 -51,6 +51,7 @@@ along with GNU Emacs.  If not, see <htt
  
  #ifdef WINDOWSNT
  #include "w32heap.h"
 +#include <mbstring.h>
  #endif /* WINDOWSNT */
  
  #if CYGWIN
@@@ -1384,6 -1383,17 +1384,17 @@@ x_set_mouse_color (struct frame *f, Lis
      horizontal_drag_cursor
        = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow);
  
+   if (!NILP (Vx_window_vertical_drag_shape))
+     {
+       CHECK_NUMBER (Vx_window_vertical_drag_shape);
+       vertical_drag_cursor
+       = XCreateFontCursor (FRAME_X_DISPLAY (f),
+                            XINT (Vx_window_vertical_drag_shape));
+     }
+   else
+     vertical_drag_cursor
+       = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_v_double_arrow);
    /* Check and report errors with the above calls.  */
    x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
    x_uncatch_errors (FRAME_W32_DISPLAY (f), count);
@@@ -1624,6 -1634,7 +1635,7 @@@ x_set_menu_bar_lines (struct frame *f, 
      nlines = 0;
  
    FRAME_MENU_BAR_LINES (f) = 0;
+   FRAME_MENU_BAR_HEIGHT (f) = 0;
    if (nlines)
      FRAME_EXTERNAL_MENU_BAR (f) = 1;
    else
        /* Adjust the frame size so that the client (text) dimensions
         remain the same.  This depends on FRAME_EXTERNAL_MENU_BAR being
         set correctly.  */
-       x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+       x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
        do_pending_window_change (0);
      }
    adjust_frame_glyphs (f);
  
  
  /* Set the number of lines used for the tool bar of frame F to VALUE.
-    VALUE not an integer, or < 0 means set the lines to zero.  OLDVAL
-    is the old number of tool bar lines.  This function changes the
-    height of all windows on frame F to match the new tool bar height.
-    The frame's height doesn't change.  */
+    VALUE not an integer, or < 0 means set the lines to zero.  OLDVAL is
+    the old number of tool bar lines (and is unused).  This function may
+    change the height of all windows on frame F to match the new tool bar
+    height.  By design, the frame's height doesn't change (but maybe it
+    should if we don't get enough space otherwise).  */
  
  void
  x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
  {
    int delta, nlines, root_height;
-   Lisp_Object root_window;
+   int unit = FRAME_LINE_HEIGHT (f);
  
    /* Treat tool bars like menu bars.  */
    if (FRAME_MINIBUF_ONLY_P (f))
    /* Make sure we redisplay all windows in this frame.  */
    windows_or_buffers_changed = 23;
  
-   delta = nlines - FRAME_TOOL_BAR_LINES (f);
+   /* DELTA is in pixels now.  */
+   delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit;
  
-   /* Don't resize the tool-bar to more than we have room for.  */
-   root_window = FRAME_ROOT_WINDOW (f);
-   root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
-   if (root_height - delta < 1)
+   /* Don't resize the tool-bar to more than we have room for.  FIXME:
+      This must use window_sizable eventually !!!!!!!!!!!!  */
+   if (delta > 0)
      {
-       delta = root_height - 1;
-       nlines = FRAME_TOOL_BAR_LINES (f) + delta;
+       root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)));
+       if (root_height - delta < unit)
+       {
+         delta = root_height - unit;
+         nlines = (root_height / unit) + min (1, (root_height % unit));
+       }
      }
  
    FRAME_TOOL_BAR_LINES (f) = nlines;
-   resize_frame_windows (f, FRAME_LINES (f), 0);
+   FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
+   ++windows_or_buffers_changed;
+   resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
    adjust_frame_glyphs (f);
  
    /* We also have to make sure that the internal border at the top of
       below the tool bar if one is displayed, but is below the menu bar
       if there isn't a tool bar.  The tool bar draws into the area
       below the menu bar.  */
-   if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
+   if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
      {
        clear_frame (f);
        clear_current_matrices (f);
      {
        int height = FRAME_INTERNAL_BORDER_WIDTH (f);
        int width = FRAME_PIXEL_WIDTH (f);
-       int y = nlines * FRAME_LINE_HEIGHT (f);
+       int y = nlines * unit;
  
        block_input ();
        {
@@@ -1949,7 -1967,7 +1968,7 @@@ w32_createwindow (struct frame *f
        SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
        SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
        SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
-       SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width);
+       SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
        SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
  
        /* Enable drag-n-drop.  */
@@@ -3225,6 -3243,7 +3244,7 @@@ w32_wnd_proc (HWND hwnd, UINT msg, WPAR
                               - WINDOW_RIGHT_MARGIN_WIDTH (w)
                               - WINDOW_RIGHT_FRINGE_WIDTH (w));
          form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
+                               - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
                                - w32_system_caret_mode_height);
  
          /* Punt if the window was deleted behind our back.  */
  
      case WM_WINDOWPOSCHANGING:
        /* Don't restrict the sizing of tip frames.  */
-       if (hwnd == tip_window)
+       if (frame_resize_pixelwise || hwnd == tip_window)
        return 0;
  
        /* Don't restrict the sizing of fullscreened frames, allowing them to be
@@@ -4453,6 -4472,10 +4473,10 @@@ This function is an internal primitive-
    /* Default internalBorderWidth to 0 on Windows to match other programs.  */
    x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
                       "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
+   x_default_parameter (f, parameters, Qright_divider_width, make_number (0),
+                      NULL, NULL, RES_TYPE_NUMBER);
+   x_default_parameter (f, parameters, Qbottom_divider_width, make_number (0),
+                      NULL, NULL, RES_TYPE_NUMBER);
    x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
                       "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
  
       happen.  */
    init_frame_faces (f);
  
+   /* PXW: This is a duplicate from below.  We have to do it here since
+      otherwise x_set_tool_bar_lines will work with the character sizes
+      installed by init_frame_faces while the frame's pixel size is still
+      calculated from a character size of 1 and we subsequently hit the
+      eassert (height >= 0) assertion in window_box_height.  The
+      non-pixelwise code apparently worked around this because it had one
+      frame line vs one toolbar line which left us with a zero root
+      window height which was obviously wrong as well ...  */
+   width = FRAME_TEXT_WIDTH (f);
+   height = FRAME_TEXT_HEIGHT (f);
+   FRAME_TEXT_HEIGHT (f) = 0;
+   SET_FRAME_WIDTH (f, 0);
+   change_frame_size (f, width, height, 1, 0, 0, 1);
    /* The X resources controlling the menu-bar and tool-bar are
       processed specially at startup, and reflected in the mode
       variables; ignore them here.  */
    f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND);
    f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
    f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
+   f->output_data.w32->vertical_drag_cursor = w32_load_cursor (IDC_SIZENS);
  
    f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
  
    /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
       Change will not be effected unless different from the current
       FRAME_LINES (f).  */
-   width = FRAME_COLS (f);
-   height = FRAME_LINES (f);
-   FRAME_LINES (f) = 0;
-   SET_FRAME_COLS (f, 0);
-   change_frame_size (f, height, width, 1, 0, 0);
+   width = FRAME_TEXT_WIDTH (f);
+   height = FRAME_TEXT_HEIGHT (f);
+   FRAME_TEXT_HEIGHT (f) = 0;
+   SET_FRAME_WIDTH (f, 0);
+   change_frame_size (f, width, height, 1, 0, 0, 1);
  
    /* Tell the server what size and position, etc, we want, and how
       badly we want them.  This should be done after we have the menu
@@@ -5690,6 -5727,10 +5728,10 @@@ x_create_tip_frame (struct w32_display_
    x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
                       "internalBorderWidth", "internalBorderWidth",
                       RES_TYPE_NUMBER);
+   x_default_parameter (f, parms, Qright_divider_width, make_number (0),
+                      NULL, NULL, RES_TYPE_NUMBER);
+   x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
+                      NULL, NULL, RES_TYPE_NUMBER);
  
    /* 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, parms, Qcursor_type, Qbox,
                       "cursorType", "CursorType", RES_TYPE_SYMBOL);
  
-   /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
-      Change will not be effected unless different from the current
-      FRAME_LINES (f).  */
+   /* Dimensions, especially FRAME_LINES (f), must be done via
+      change_frame_size.  Change will not be effected unless different
+      from the current FRAME_LINES (f).  */
    width = FRAME_COLS (f);
    height = FRAME_LINES (f);
    FRAME_LINES (f) = 0;
    SET_FRAME_COLS (f, 0);
-   change_frame_size (f, height, width, 1, 0, 0);
+   change_frame_size (f, width, height, 1, 0, 0, 0);
  
    /* Add `tooltip' frame parameter's default value. */
    if (NILP (Fframe_parameter (frame, Qtooltip)))
@@@ -5999,6 -6040,10 +6041,10 @@@ Text larger than the specified size is 
      parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
    if (NILP (Fassq (Qinternal_border_width, parms)))
      parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
+   if (NILP (Fassq (Qright_divider_width, parms)))
+     parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
+   if (NILP (Fassq (Qbottom_divider_width, parms)))
+     parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
    if (NILP (Fassq (Qborder_width, parms)))
      parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
    if (NILP (Fassq (Qborder_color, parms)))
    w = XWINDOW (FRAME_ROOT_WINDOW (f));
    w->left_col = 0;
    w->top_line = 0;
+   w->pixel_left = 0;
+   w->pixel_top = 0;
  
    if (CONSP (Vx_max_tooltip_size)
        && INTEGERP (XCAR (Vx_max_tooltip_size))
        w->total_lines = 40;
      }
  
+   w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
+   w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
    FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w);
    adjust_frame_glyphs (f);
    w->pseudo_window_p = 1;
       width of the frame.  */
    if (seen_reversed_p)
      {
-       /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
+       /* PXW: Why do we do the pixel-to-cols conversion only if
+        seen_reversed_p holds?  Don't we have to set other fields of
+        the window/frame structure?
+        w->total_cols and FRAME_TOTAL_COLS want the width in columns,
         not in pixels.  */
+       w->pixel_width = width;
        width /= WINDOW_FRAME_COLUMN_WIDTH (w);
        w->total_cols = width;
        FRAME_TOTAL_COLS (f) = width;
+       SET_FRAME_WIDTH (f, width);
        adjust_frame_glyphs (f);
        w->pseudo_window_p = 1;
        clear_glyph_matrix (w->desired_matrix);
        }
      }
  
-   /* Round up the height to an integral multiple of FRAME_LINE_HEIGHT.  */
-   if (height % FRAME_LINE_HEIGHT (f) != 0)
-     height += FRAME_LINE_HEIGHT (f) - height % FRAME_LINE_HEIGHT (f);
    /* Add the frame's internal border to the width and height the w32
       window should have.  */
    height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
    width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
  
    /* Move the tooltip window where the mouse pointer is.  Resize and
-      show it.  */
+      show it.
+      PXW: This should use the frame's pixel coordinates.  */
    compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
  
    {
@@@ -6250,31 -6305,18 +6306,31 @@@ file_dialog_callback (HWND hwnd, UINT m
  {
    if (msg == WM_NOTIFY)
      {
 +      OFNOTIFYW * notify_w = (OFNOTIFYW *)lParam;
 +      OFNOTIFYA * notify_a = (OFNOTIFYA *)lParam;
 +      int dropdown_changed;
 +      int dir_index;
  #ifdef NTGUI_UNICODE
 -      OFNOTIFYW * notify = (OFNOTIFYW *)lParam;
 +      const int use_unicode = 1;
  #else /* !NTGUI_UNICODE */
 -      OFNOTIFYA * notify = (OFNOTIFYA *)lParam;
 +      int use_unicode = w32_unicode_filenames;
  #endif /* NTGUI_UNICODE */
 +
        /* Detect when the Filter dropdown is changed.  */
 -      if (notify->hdr.code == CDN_TYPECHANGE
 -        || notify->hdr.code == CDN_INITDONE)
 +      if (use_unicode)
 +      dropdown_changed =
 +        notify_w->hdr.code == CDN_TYPECHANGE
 +        || notify_w->hdr.code == CDN_INITDONE;
 +      else
 +      dropdown_changed =
 +        notify_a->hdr.code == CDN_TYPECHANGE
 +        || notify_a->hdr.code == CDN_INITDONE;
 +      if (dropdown_changed)
        {
          HWND dialog = GetParent (hwnd);
          HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD);
          HWND list = GetDlgItem (dialog, FILE_NAME_LIST);
 +        int hdr_code;
  
          /* At least on Windows 7, the above attempt to get the window handle
             to the File Name Text Field fails.  The following code does the
            }
  
          /* Directories is in index 2.  */
 -        if (notify->lpOFN->nFilterIndex == 2)
 +        if (use_unicode)
 +          {
 +            dir_index = notify_w->lpOFN->nFilterIndex;
 +            hdr_code = notify_w->hdr.code;
 +          }
 +        else
            {
 -            CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
 -                                             GUISTR ("Current Directory"));
 +            dir_index = notify_a->lpOFN->nFilterIndex;
 +            hdr_code = notify_a->hdr.code;
 +          }
 +        if (dir_index == 2)
 +          {
 +            if (use_unicode)
 +              SendMessageW (dialog, CDM_SETCONTROLTEXT, FILE_NAME_TEXT_FIELD,
 +                            (LPARAM)L"Current Directory");
 +            else
 +              SendMessageA (dialog, CDM_SETCONTROLTEXT, FILE_NAME_TEXT_FIELD,
 +                            (LPARAM)"Current Directory");
              EnableWindow (edit_control, FALSE);
              /* Note that at least on Windows 7, the above call to EnableWindow
                 disables the window that would ordinarily have focus.  If we
                 no man's land and the user will be unable to tab through the
                 dialog box (pressing tab will only result in a beep).
                 Avoid that problem by setting focus to the list here.  */
 -            if (notify->hdr.code == CDN_INITDONE)
 +            if (hdr_code == CDN_INITDONE)
                SetFocus (list);
            }
          else
            {
              /* Don't override default filename on init done.  */
 -            if (notify->hdr.code == CDN_TYPECHANGE)
 -              CommDlg_OpenSave_SetControlText (dialog,
 -                                               FILE_NAME_TEXT_FIELD,
 -                                                 GUISTR (""));
 +            if (hdr_code == CDN_TYPECHANGE)
 +              {
 +                if (use_unicode)
 +                  SendMessageW (dialog, CDM_SETCONTROLTEXT,
 +                                FILE_NAME_TEXT_FIELD, (LPARAM)L"");
 +                else
 +                  SendMessageA (dialog, CDM_SETCONTROLTEXT,
 +                                FILE_NAME_TEXT_FIELD, (LPARAM)"");
 +              }
              EnableWindow (edit_control, TRUE);
            }
        }
@@@ -6351,8 -6374,8 +6407,8 @@@ Otherwise, if ONLY-DIR-P is non-nil, th
    (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
  {
    /* Filter index: 1: All Files, 2: Directories only  */
 -  static const guichar_t filter[] =
 -    GUISTR ("All Files (*.*)\0*.*\0Directories\0*|*\0");
 +  static const wchar_t filter_w[] = L"All Files (*.*)\0*.*\0Directories\0*|*\0";
 +  static const char filter_a[] = "All Files (*.*)\0*.*\0Directories\0*|*\0";
  
    Lisp_Object filename = default_filename;
    struct frame *f = SELECTED_FRAME ();
       enough struct for the new dialog to trick GetOpenFileName into
       giving us the new dialogs on newer versions of Windows.  */
    struct {
 -#ifdef NTGUI_UNICODE
      OPENFILENAMEW details;
 -#else /* !NTGUI_UNICODE */
 -    OPENFILENAMEA details;
 -#endif /* NTGUI_UNICODE */
 -
  #if _WIN32_WINNT < 0x500 /* < win2k */
        PVOID pvReserved;
        DWORD dwReserved;
        DWORD FlagsEx;
  #endif /* < win2k */
 -  } new_file_details;
 +  } new_file_details_w;
  
  #ifdef NTGUI_UNICODE
 -  wchar_t filename_buf[32*1024 + 1]; // NT kernel maximum
 -  OPENFILENAMEW * file_details = &new_file_details.details;
 +  wchar_t filename_buf_w[32*1024 + 1]; // NT kernel maximum
 +  OPENFILENAMEW * file_details_w = &new_file_details_w.details;
 +  const int use_unicode = 1;
  #else /* not NTGUI_UNICODE */
 -  char filename_buf[MAX_PATH + 1];
 -  OPENFILENAMEA * file_details = &new_file_details.details;
 +  struct {
 +    OPENFILENAMEA details;
 +#if _WIN32_WINNT < 0x500 /* < win2k */
 +      PVOID pvReserved;
 +      DWORD dwReserved;
 +      DWORD FlagsEx;
 +#endif /* < win2k */
 +  } new_file_details_a;
 +  wchar_t filename_buf_w[MAX_PATH + 1], dir_w[MAX_PATH];
 +  char filename_buf_a[MAX_PATH + 1], dir_a[MAX_PATH];
 +  OPENFILENAMEW * file_details_w = &new_file_details_w.details;
 +  OPENFILENAMEA * file_details_a = &new_file_details_a.details;
 +  int use_unicode = w32_unicode_filenames;
 +  wchar_t *prompt_w;
 +  char *prompt_a;
 +  int len;
 +  char fname_ret[MAX_UTF8_PATH];
  #endif /* NTGUI_UNICODE */
  
    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
      to_unicode (prompt, &prompt);
      to_unicode (dir, &dir);
      to_unicode (filename, &filename);
 +    if (SBYTES (filename) + 1 > sizeof (filename_buf_w))
 +      report_file_error ("filename too long", default_filename);
 +
 +    memcpy (filename_buf_w, SDATA (filename), SBYTES (filename) + 1);
  #else /* !NTGUI_UNICODE */
      prompt = ENCODE_FILE (prompt);
      dir = ENCODE_FILE (dir);
      unixtodos_filename (SDATA (dir));
      filename = Fcopy_sequence (filename);
      unixtodos_filename (SDATA (filename));
 +    if (SBYTES (filename) >= MAX_UTF8_PATH)
 +      report_file_error ("filename too long", default_filename);
 +    if (w32_unicode_filenames)
 +      {
 +      filename_to_utf16 (SSDATA (dir), dir_w);
 +      if (filename_to_utf16 (SSDATA (filename), filename_buf_w) != 0)
 +        {
 +          /* filename_to_utf16 sets errno to ENOENT when the file
 +             name is too long or cannot be converted to UTF-16.  */
 +          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);
 +      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);
 +      }
 +    else
 +      {
 +      filename_to_ansi (SSDATA (dir), dir_a);
 +      if (filename_to_ansi (SSDATA (filename), filename_buf_a) != '\0')
 +        {
 +          /* filename_to_ansi sets errno to ENOENT when the file
 +             name is too long or cannot be converted to UTF-16.  */
 +          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);
 +      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);
 +      if (len > 32768)
 +        len = 32768;
 +      prompt_a = alloca (len);
 +      WideCharToMultiByte (CP_ACP, 0, prompt_w, -1, prompt_a, len, NULL, NULL);
 +      }
  #endif /* NTGUI_UNICODE */
  
      /* Fill in the structure for the call to GetOpenFileName below.
         builds, we tell the OS we're using an old version of the
         structure if the OS isn't new enough to support the newer
         version.  */
 -    memset (&new_file_details, 0, sizeof (new_file_details));
 -
 -    if (w32_major_version > 4 && w32_major_version < 95)
 -      file_details->lStructSize = sizeof (new_file_details);
 +    if (use_unicode)
 +      {
 +      memset (&new_file_details_w, 0, sizeof (new_file_details_w));
 +      if (w32_major_version > 4 && w32_major_version < 95)
 +        file_details_w->lStructSize = sizeof (new_file_details_w);
 +      else
 +        file_details_w->lStructSize = sizeof (*file_details_w);
 +      /* Set up the inout parameter for the selected file name.  */
 +      file_details_w->lpstrFile = filename_buf_w;
 +      file_details_w->nMaxFile =
 +        sizeof (filename_buf_w) / sizeof (*filename_buf_w);
 +      file_details_w->hwndOwner = FRAME_W32_WINDOW (f);
 +      /* Undocumented Bug in Common File Dialog:
 +         If a filter is not specified, shell links are not resolved.  */
 +      file_details_w->lpstrFilter = filter_w;
 +#ifdef NTGUI_UNICODE
 +      file_details_w->lpstrInitialDir = (wchar_t*) SDATA (dir);
 +      file_details->lpstrTitle = (guichar_t*) SDATA (prompt);
 +#else
 +      file_details_w->lpstrInitialDir = dir_w;
 +      file_details_w->lpstrTitle = prompt_w;
 +#endif
 +      file_details_w->nFilterIndex = NILP (only_dir_p) ? 1 : 2;
 +      file_details_w->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
 +                               | OFN_EXPLORER | OFN_ENABLEHOOK);
 +      if (!NILP (mustmatch))
 +        {
 +          /* Require that the path to the parent directory exists.  */
 +          file_details_w->Flags |= OFN_PATHMUSTEXIST;
 +          /* If we are looking for a file, require that it exists.  */
 +          if (NILP (only_dir_p))
 +            file_details_w->Flags |= OFN_FILEMUSTEXIST;
 +        }
 +      }
      else
 -      file_details->lStructSize = sizeof (*file_details);
 -
 -    /* Set up the inout parameter for the selected file name.  */
 -    if (SBYTES (filename) + 1 > sizeof (filename_buf))
 -      report_file_error ("filename too long", default_filename);
 -
 -    memcpy (filename_buf, SDATA (filename), SBYTES (filename) + 1);
 -    file_details->lpstrFile = filename_buf;
 -    file_details->nMaxFile = sizeof (filename_buf) / sizeof (*filename_buf);
 -
 -    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 = filter;
 -    file_details->lpstrInitialDir = (guichar_t*) SDATA (dir);
 -    file_details->lpstrTitle = (guichar_t*) SDATA (prompt);
 -    file_details->nFilterIndex = NILP (only_dir_p) ? 1 : 2;
 -    file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
 -                           | OFN_EXPLORER | OFN_ENABLEHOOK);
 -
 -    if (!NILP (mustmatch))
        {
 -        /* 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;
 +      memset (&new_file_details_a, 0, sizeof (new_file_details_a));
 +      if (w32_major_version > 4 && w32_major_version < 95)
 +        file_details_a->lStructSize = sizeof (new_file_details_a);
 +      else
 +        file_details_a->lStructSize = sizeof (*file_details_a);
 +      file_details_a->lpstrFile = filename_buf_a;
 +      file_details_a->nMaxFile =
 +        sizeof (filename_buf_a) / sizeof (*filename_buf_a);
 +      file_details_a->hwndOwner = FRAME_W32_WINDOW (f);
 +      file_details_a->lpstrFilter = filter_a;
 +      file_details_a->lpstrInitialDir = dir_a;
 +      file_details_a->lpstrTitle = prompt_a;
 +      file_details_a->nFilterIndex = NILP (only_dir_p) ? 1 : 2;
 +      file_details_a->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
 +                               | OFN_EXPLORER | OFN_ENABLEHOOK);
 +      if (!NILP (mustmatch))
 +        {
 +          /* Require that the path to the parent directory exists.  */
 +          file_details_a->Flags |= OFN_PATHMUSTEXIST;
 +          /* If we are looking for a file, require that it exists.  */
 +          if (NILP (only_dir_p))
 +            file_details_a->Flags |= OFN_FILEMUSTEXIST;
 +        }
        }
  
      {
        /* Prevent redisplay.  */
        specbind (Qinhibit_redisplay, Qt);
        block_input ();
 -      file_details->lpfnHook = file_dialog_callback;
 +      if (use_unicode)
 +      {
 +        file_details_w->lpfnHook = file_dialog_callback;
 +
 +        file_opened = GetOpenFileNameW (file_details_w);
 +      }
 +      else
 +      {
 +        file_details_a->lpfnHook = file_dialog_callback;
  
 -      file_opened = GUI_FN (GetOpenFileName) (file_details);
 +        file_opened = GetOpenFileNameA (file_details_a);
 +      }
        unblock_input ();
        unbind_to (count, Qnil);
      }
        {
          /* Get an Emacs string from the value Windows gave us.  */
  #ifdef NTGUI_UNICODE
 -        filename = from_unicode_buffer (filename_buf);
 +        filename = from_unicode_buffer (filename_buf_w);
  #else /* !NTGUI_UNICODE */
 -        dostounix_filename (filename_buf, 0);
 -        filename = DECODE_FILE (build_string (filename_buf));
 +      if (use_unicode)
 +        filename_from_utf16 (filename_buf_w, fname_ret);
 +      else
 +        filename_from_ansi (filename_buf_a, fname_ret);
 +      dostounix_filename (fname_ret);
 +        filename = DECODE_FILE (build_unibyte_string (fname_ret));
  #endif /* NTGUI_UNICODE */
  
  #ifdef CYGWIN
  
          /* Strip the dummy filename off the end of the string if we
             added it to select a directory.  */
 -        if (file_details->nFilterIndex == 2)
 -          {
 -            filename = Ffile_name_directory (filename);
 -          }
 +        if (use_unicode && file_details_w->nFilterIndex == 2
 +          || !use_unicode && file_details_a->nFilterIndex == 2)
 +        filename = Ffile_name_directory (filename);
        }
      /* User canceled the dialog without making a selection.  */
      else if (!CommDlgExtendedError ())
@@@ -6656,80 -6582,38 +6712,80 @@@ DEFUN ("system-move-file-to-trash", Fsy
        operation = intern ("delete-directory");
        filename = Fdirectory_file_name (filename);
      }
 +
 +  /* Must have fully qualified file names for moving files to Recycle
 +     Bin. */
    filename = Fexpand_file_name (filename, Qnil);
  
    handler = Ffind_file_name_handler (filename, operation);
    if (!NILP (handler))
      return call2 (handler, operation, filename);
 +  else
 +    {
 +      const char * path;
 +      int result;
  
 -  encoded_file = ENCODE_FILE (filename);
 +      encoded_file = ENCODE_FILE (filename);
  
 -  {
 -    const char * path;
 -    SHFILEOPSTRUCT file_op;
 -    char tmp_path[MAX_PATH + 1];
 +      path = map_w32_filename (SDATA (encoded_file), NULL);
  
 -    path = map_w32_filename (SDATA (encoded_file), NULL);
 +      /* The Unicode version of SHFileOperation is not supported on
 +       Windows 9X. */
 +      if (w32_unicode_filenames && os_subtype != OS_9X)
 +      {
 +        SHFILEOPSTRUCTW file_op_w;
 +        /* We need one more element beyond MAX_PATH because this is
 +           a list of file names, with the last element double-null
 +           terminated. */
 +        wchar_t tmp_path_w[MAX_PATH + 1];
 +
 +        memset (tmp_path_w, 0, sizeof (tmp_path_w));
 +        filename_to_utf16 (path, tmp_path_w);
 +
 +        /* On Windows, write permission is required to delete/move files.  */
 +        _wchmod (tmp_path_w, 0666);
 +
 +        memset (&file_op_w, 0, sizeof (file_op_w));
 +        file_op_w.hwnd = HWND_DESKTOP;
 +        file_op_w.wFunc = FO_DELETE;
 +        file_op_w.pFrom = tmp_path_w;
 +        file_op_w.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO
 +          | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS;
 +        file_op_w.fAnyOperationsAborted = FALSE;
 +
 +        result = SHFileOperationW (&file_op_w);
 +      }
 +      else
 +      {
 +        SHFILEOPSTRUCTA file_op_a;
 +        char tmp_path_a[MAX_PATH + 1];
  
 -    /* On Windows, write permission is required to delete/move files.  */
 -    _chmod (path, 0666);
 +        memset (tmp_path_a, 0, sizeof (tmp_path_a));
 +        filename_to_ansi (path, tmp_path_a);
  
 -    memset (tmp_path, 0, sizeof (tmp_path));
 -    strcpy (tmp_path, path);
 +        /* If a file cannot be represented in ANSI codepage, don't
 +           let them inadvertently delete other files because some
 +           characters are interpreted as a wildcards.  */
 +        if (_mbspbrk (tmp_path_a, "?*"))
 +          result = ERROR_FILE_NOT_FOUND;
 +        else
 +          {
 +            _chmod (tmp_path_a, 0666);
  
 -    memset (&file_op, 0, sizeof (file_op));
 -    file_op.hwnd = HWND_DESKTOP;
 -    file_op.wFunc = FO_DELETE;
 -    file_op.pFrom = tmp_path;
 -    file_op.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO
 -      | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS;
 -    file_op.fAnyOperationsAborted = FALSE;
 +            memset (&file_op_a, 0, sizeof (file_op_a));
 +            file_op_a.hwnd = HWND_DESKTOP;
 +            file_op_a.wFunc = FO_DELETE;
 +            file_op_a.pFrom = tmp_path_a;
 +            file_op_a.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO
 +              | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS;
 +            file_op_a.fAnyOperationsAborted = FALSE;
  
 -    if (SHFileOperation (&file_op) != 0)
 -      report_file_error ("Removing old name", list1 (filename));
 -  }
 +            result = SHFileOperationA (&file_op_a);
 +          }
 +      }
 +      if (result != 0)
 +      report_file_error ("Removing old name", list1 (filename));
 +    }
    return Qnil;
  }
  
@@@ -6804,159 -6688,38 +6860,159 @@@ an integer representing a ShowWindow fl
    6 - start minimized  */)
    (Lisp_Object operation, Lisp_Object document, Lisp_Object parameters, Lisp_Object show_flag)
  {
 -  Lisp_Object current_dir;
    char *errstr;
 +  Lisp_Object current_dir = BVAR (current_buffer, directory);;
 +  wchar_t *doc_w = NULL, *params_w = NULL, *ops_w = NULL;
 +  int result;
 +#ifndef CYGWIN
 +  int use_unicode = w32_unicode_filenames;
 +  char *doc_a = NULL, *params_a = NULL, *ops_a = NULL;
 +#endif
  
    CHECK_STRING (document);
  
 -  /* Encode filename, current directory and parameters.  */
 -  current_dir = BVAR (current_buffer, directory);
 -
  #ifdef CYGWIN
    current_dir = Fcygwin_convert_file_name_to_windows (current_dir, Qt);
    if (STRINGP (document))
      document = Fcygwin_convert_file_name_to_windows (document, Qt);
 -#endif /* CYGWIN */
  
 +  /* Encode filename, current directory and parameters.  */
    current_dir = GUI_ENCODE_FILE (current_dir);
    if (STRINGP (document))
 -    document = GUI_ENCODE_FILE (document);
 +    {
 +      document = GUI_ENCODE_FILE (document);
 +      doc_w = GUI_SDATA (document);
 +    }
    if (STRINGP (parameters))
 -    parameters = GUI_ENCODE_SYSTEM (parameters);
 -
 -  if ((int) GUI_FN (ShellExecute) (NULL,
 -                                   (STRINGP (operation) ?
 -                                    GUI_SDATA (operation) : NULL),
 -                                   GUI_SDATA (document),
 -                                   (STRINGP (parameters) ?
 -                                    GUI_SDATA (parameters) : NULL),
 -                                   GUI_SDATA (current_dir),
 -                                   (INTEGERP (show_flag) ?
 -                                    XINT (show_flag) : SW_SHOWDEFAULT))
 -      > 32)
 +    {
 +      parameters = GUI_ENCODE_SYSTEM (parameters);
 +      params_w = GUI_SDATA (parameters);
 +    }
 +  if (STRINGP (operation))
 +    {
 +      operation = GUI_ENCODE_SYSTEM (operation);
 +      ops_w = GUI_SDATA (operation);
 +    }
 +  result = (int) ShellExecuteW (NULL, ops_w, doc_w, params_w,
 +                              GUI_SDATA (current_dir),
 +                              (INTEGERP (show_flag)
 +                               ? XINT (show_flag) : SW_SHOWDEFAULT));
 +#else  /* !CYGWIN */
 +  if (use_unicode)
 +    {
 +      wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH];
 +
 +      /* Encode filename, current directory and parameters, and
 +       convert operation to UTF-16.  */
 +      current_dir = ENCODE_FILE (current_dir);
 +      filename_to_utf16 (SSDATA (current_dir), current_dir_w);
 +      if (STRINGP (document))
 +      {
 +        document = ENCODE_FILE (document);
 +        filename_to_utf16 (SSDATA (document), document_w);
 +        doc_w = document_w;
 +      }
 +      if (STRINGP (parameters))
 +      {
 +        int len;
 +
 +        parameters = ENCODE_SYSTEM (parameters);
 +        len = MultiByteToWideChar (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);
 +      }
 +      if (STRINGP (operation))
 +      {
 +        /* Assume OPERATION is pure ASCII.  */
 +        const char *s = SSDATA (operation);
 +        wchar_t *d;
 +        int len = SBYTES (operation) + 1;
 +
 +        if (len > 32768)
 +          len = 32768;
 +        d = ops_w = alloca (len * sizeof (wchar_t));
 +        while (d < ops_w + len - 1)
 +          *d++ = *s++;
 +        *d = 0;
 +      }
 +      result = (int) ShellExecuteW (NULL, ops_w, doc_w, params_w,
 +                                  current_dir_w,
 +                                  (INTEGERP (show_flag)
 +                                   ? XINT (show_flag) : SW_SHOWDEFAULT));
 +    }
 +  else
 +    {
 +      char document_a[MAX_PATH], current_dir_a[MAX_PATH];
 +
 +      current_dir = ENCODE_FILE (current_dir);
 +      filename_to_ansi (SSDATA (current_dir), current_dir_a);
 +      if (STRINGP (document))
 +      {
 +        ENCODE_FILE (document);
 +        filename_to_ansi (SSDATA (document), document_a);
 +        doc_a = document_a;
 +      }
 +      if (STRINGP (parameters))
 +      {
 +        int len;
 +
 +        parameters = ENCODE_SYSTEM (parameters);
 +        params_a = SSDATA (parameters);
 +      }
 +      if (STRINGP (operation))
 +      {
 +        /* Assume OPERATION is pure ASCII.  */
 +        ops_a = SSDATA (operation);
 +      }
 +      result = (int) ShellExecuteA (NULL, ops_a, doc_a, params_a,
 +                                  current_dir_a,
 +                                  (INTEGERP (show_flag)
 +                                   ? XINT (show_flag) : SW_SHOWDEFAULT));
 +    }
 +#endif /* !CYGWIN */
 +
 +  if (result > 32)
      return Qt;
 -  errstr = w32_strerror (0);
 +
 +  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;
 +    }
    /* The error string might be encoded in the locale's encoding.  */
    if (!NILP (Vlocale_coding_system))
      {
@@@ -7212,6 -6975,29 +7268,29 @@@ This is a direct interface to the Windo
    return Qt;
  }
  
+ DEFUN ("w32-frame-rect", Fw32_frame_rect, Sw32_frame_rect, 0, 2, 0,
+        doc: /* Return boundary rectangle of FRAME in screen coordinates.
+ FRAME must be a live frame and defaults to the selected one.
+ The boundary rectangle is a list of four elements, specifying the left,
+ top, right and bottom screen coordinates of FRAME including menu and
+ title bar and decorations.  Optional argument CLIENT non-nil means to
+ return the boundaries of the client rectangle which excludes menu and
+ title bar and decorations.  */)
+   (Lisp_Object frame, Lisp_Object client)
+ {
+   struct frame *f = decode_live_frame (frame);
+   RECT rect;
+   if (!NILP (client))
+     GetClientRect (FRAME_W32_WINDOW (f), &rect);
+   else
+     GetWindowRect (FRAME_W32_WINDOW (f), &rect);
+   return list4 (make_number (rect.left), make_number (rect.top),
+               make_number (rect.right), make_number (rect.bottom));
+ }
  DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0,
         doc: /* Get power status information from Windows system.
  
@@@ -7346,23 -7132,14 +7425,23 @@@ If the underlying system call fails, va
       added rather late on.  */
    {
      HMODULE hKernel = GetModuleHandle ("kernel32");
 -    BOOL (*pfn_GetDiskFreeSpaceEx)
 +    BOOL (*pfn_GetDiskFreeSpaceExW)
 +      (wchar_t *, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER)
 +      = (void *) GetProcAddress (hKernel, "GetDiskFreeSpaceExW");
 +    BOOL (*pfn_GetDiskFreeSpaceExA)
        (char *, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER)
 -      = (void *) GetProcAddress (hKernel, "GetDiskFreeSpaceEx");
 +      = (void *) GetProcAddress (hKernel, "GetDiskFreeSpaceExA");
 +    bool have_pfn_GetDiskFreeSpaceEx =
 +      (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.  */
 -    char rootname[MAX_PATH];
 +    char rootname[MAX_UTF8_PATH];
 +    wchar_t rootname_w[MAX_PATH];
 +    char rootname_a[MAX_PATH];
      char *name = SDATA (encoded);
 +    BOOL result;
  
      /* find the root name of the volume if given */
      if (isalpha (name[0]) && name[1] == ':')
        *str = 0;
        }
  
 -    if (pfn_GetDiskFreeSpaceEx)
 +    if (w32_unicode_filenames)
 +      filename_to_utf16 (rootname, rootname_w);
 +    else
 +      filename_to_ansi (rootname, rootname_a);
 +
 +    if (have_pfn_GetDiskFreeSpaceEx)
        {
        /* Unsigned large integers cannot be cast to double, so
           use signed ones instead.  */
        LARGE_INTEGER freebytes;
        LARGE_INTEGER totalbytes;
  
 -      if (pfn_GetDiskFreeSpaceEx (rootname,
 -                                  (ULARGE_INTEGER *)&availbytes,
 -                                  (ULARGE_INTEGER *)&totalbytes,
 -                                  (ULARGE_INTEGER *)&freebytes))
 +      if (w32_unicode_filenames)
 +        result = pfn_GetDiskFreeSpaceExW (rootname_w,
 +                                          (ULARGE_INTEGER *)&availbytes,
 +                                          (ULARGE_INTEGER *)&totalbytes,
 +                                          (ULARGE_INTEGER *)&freebytes);
 +      else
 +        result = pfn_GetDiskFreeSpaceExA (rootname_a,
 +                                          (ULARGE_INTEGER *)&availbytes,
 +                                          (ULARGE_INTEGER *)&totalbytes,
 +                                          (ULARGE_INTEGER *)&freebytes);
 +      if (result)
          value = list3 (make_float ((double) totalbytes.QuadPart),
                         make_float ((double) freebytes.QuadPart),
                         make_float ((double) availbytes.QuadPart));
        DWORD free_clusters;
        DWORD total_clusters;
  
 -      if (GetDiskFreeSpace (rootname,
 -                            &sectors_per_cluster,
 -                            &bytes_per_sector,
 -                            &free_clusters,
 -                            &total_clusters))
 +      if (w32_unicode_filenames)
 +        result = GetDiskFreeSpaceW (rootname_w,
 +                                    &sectors_per_cluster,
 +                                    &bytes_per_sector,
 +                                    &free_clusters,
 +                                    &total_clusters);
 +      else
 +        result = GetDiskFreeSpaceA (rootname_a,
 +                                    &sectors_per_cluster,
 +                                    &bytes_per_sector,
 +                                    &free_clusters,
 +                                    &total_clusters);
 +      if (result)
          value = list3 (make_float ((double) total_clusters
                                     * sectors_per_cluster * bytes_per_sector),
                         make_float ((double) free_clusters
@@@ -7457,11 -7214,8 +7536,11 @@@ DEFUN ("default-printer-name", Fdefault
    static char pname_buf[256];
    int err;
    HANDLE hPrn;
 -  PRINTER_INFO_2 *ppi2 = NULL;
 +  PRINTER_INFO_2W *ppi2w = NULL;
 +  PRINTER_INFO_2A *ppi2a = NULL;
    DWORD dwNeeded = 0, dwReturned = 0;
 +  char server_name[MAX_UTF8_PATH], share_name[MAX_UTF8_PATH];
 +  char port_name[MAX_UTF8_PATH];
  
    /* Retrieve the default string from Win.ini (the registry).
     * String will be in form "printername,drivername,portname".
    /* We want to know more than the printer name */
    if (!OpenPrinter (pname_buf, &hPrn, NULL))
      return Qnil;
 -  GetPrinter (hPrn, 2, NULL, 0, &dwNeeded);
 +  /* GetPrinterW is not supported by unicows.dll.  */
 +  if (w32_unicode_filenames && os_subtype != OS_9X)
 +    GetPrinterW (hPrn, 2, NULL, 0, &dwNeeded);
 +  else
 +    GetPrinterA (hPrn, 2, NULL, 0, &dwNeeded);
    if (dwNeeded == 0)
      {
        ClosePrinter (hPrn);
        return Qnil;
      }
 -  /* Allocate memory for the PRINTER_INFO_2 struct */
 -  ppi2 = xmalloc (dwNeeded);
 -  if (!ppi2)
 +  /* Call GetPrinter again with big enough memory block.  */
 +  if (w32_unicode_filenames && os_subtype != OS_9X)
      {
 +      /* Allocate memory for the PRINTER_INFO_2 struct.  */
 +      ppi2w = xmalloc (dwNeeded);
 +      err = GetPrinterW (hPrn, 2, (LPBYTE)ppi2w, dwNeeded, &dwReturned);
        ClosePrinter (hPrn);
 -      return Qnil;
 +      if (!err)
 +      {
 +        xfree (ppi2w);
 +        return Qnil;
 +      }
 +
 +      if ((ppi2w->Attributes & PRINTER_ATTRIBUTE_SHARED)
 +        && ppi2w->pServerName)
 +      {
 +        filename_from_utf16 (ppi2w->pServerName, server_name);
 +        filename_from_utf16 (ppi2w->pShareName, share_name);
 +      }
 +      else
 +      {
 +        server_name[0] = '\0';
 +        filename_from_utf16 (ppi2w->pPortName, port_name);
 +      }
      }
 -  /* Call GetPrinter again with big enough memory block.  */
 -  err = GetPrinter (hPrn, 2, (LPBYTE)ppi2, dwNeeded, &dwReturned);
 -  ClosePrinter (hPrn);
 -  if (!err)
 +  else
      {
 -      xfree (ppi2);
 -      return Qnil;
 -    }
 +      ppi2a = xmalloc (dwNeeded);
 +      err = GetPrinterA (hPrn, 2, (LPBYTE)ppi2a, dwNeeded, &dwReturned);
 +      ClosePrinter (hPrn);
 +      if (!err)
 +      {
 +        xfree (ppi2a);
 +        return Qnil;
 +      }
  
 -  if (ppi2)
 -    {
 -      if (ppi2->Attributes & PRINTER_ATTRIBUTE_SHARED && ppi2->pServerName)
 -        {
 -        /* a remote printer */
 -        if (*ppi2->pServerName == '\\')
 -          snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
 -                     ppi2->pShareName);
 -        else
 -          snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
 -                     ppi2->pShareName);
 -        pname_buf[sizeof (pname_buf) - 1] = '\0';
 +      if ((ppi2a->Attributes & PRINTER_ATTRIBUTE_SHARED)
 +        && ppi2a->pServerName)
 +      {
 +        filename_from_ansi (ppi2a->pServerName, server_name);
 +        filename_from_ansi (ppi2a->pShareName, share_name);
        }
        else
 -        {
 -        /* a local printer */
 -        strncpy (pname_buf, ppi2->pPortName, sizeof (pname_buf));
 -        pname_buf[sizeof (pname_buf) - 1] = '\0';
 -        /* `pPortName' can include several ports, delimited by ','.
 -         * we only use the first one. */
 -        strtok (pname_buf, ",");
 +      {
 +        server_name[0] = '\0';
 +        filename_from_ansi (ppi2a->pPortName, port_name);
        }
 -      xfree (ppi2);
      }
  
 -  return build_string (pname_buf);
 +  if (server_name[0])
 +    {
 +      /* a remote printer */
 +      if (server_name[0] == '\\')
 +      snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", server_name,
 +                share_name);
 +      else
 +      snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", server_name,
 +                share_name);
 +      pname_buf[sizeof (pname_buf) - 1] = '\0';
 +    }
 +  else
 +    {
 +      /* a local printer */
 +      strncpy (pname_buf, port_name, sizeof (pname_buf));
 +      pname_buf[sizeof (pname_buf) - 1] = '\0';
 +      /* `pPortName' can include several ports, delimited by ','.
 +       * we only use the first one. */
 +      strtok (pname_buf, ",");
 +    }
 +
 +  return DECODE_FILE (build_unibyte_string (pname_buf));
  }
  \f
  
@@@ -7868,6 -7589,8 +7947,8 @@@ frame_parm_handler w32_frame_parm_handl
    x_set_icon_name,
    x_set_icon_type,
    x_set_internal_border_width,
+   x_set_right_divider_width,
+   x_set_bottom_divider_width,
    x_set_menu_bar_lines,
    x_set_mouse_color,
    x_explicitly_set_name,
@@@ -8119,6 -7842,13 +8200,13 @@@ or when you set the mouse color.  */)
  This variable takes effect when you create a new frame
  or when you set the mouse color.  */);
    Vx_window_horizontal_drag_shape = Qnil;
+   DEFVAR_LISP ("x-window-vertical-drag-cursor",
+              Vx_window_vertical_drag_shape,
+              doc: /* Pointer shape to use for indicating a window can be dragged vertically.
+ This variable takes effect when you create a new frame
+ or when you set the mouse color.  */);
+   Vx_window_vertical_drag_shape = Qnil;
  #endif
  
    DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
@@@ -8211,6 -7941,7 +8299,7 @@@ only be necessary if the default settin
    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
  #endif
  }
  
\f
  
- /*
-       globals_of_w32fns is used to initialize those global variables that
-       must always be initialized on startup even when the global variable
-       initialized is non zero (see the function main in emacs.c).
-       globals_of_w32fns is called from syms_of_w32fns when the global
-       variable initialized is 0 and directly from main when initialized
-       is non zero.
-  */
- void
- globals_of_w32fns (void)
- {
-   HMODULE user32_lib = GetModuleHandle ("user32.dll");
-   /*
-     TrackMouseEvent not available in all versions of Windows, so must load
-     it dynamically.  Do it once, here, instead of every time it is used.
-   */
-   track_mouse_event_fn = (TrackMouseEvent_Proc)
-     GetProcAddress (user32_lib, "TrackMouseEvent");
-   monitor_from_point_fn = (MonitorFromPoint_Proc)
-     GetProcAddress (user32_lib, "MonitorFromPoint");
-   get_monitor_info_fn = (GetMonitorInfo_Proc)
-     GetProcAddress (user32_lib, "GetMonitorInfoA");
-   monitor_from_window_fn = (MonitorFromWindow_Proc)
-     GetProcAddress (user32_lib, "MonitorFromWindow");
-   enum_display_monitors_fn = (EnumDisplayMonitors_Proc)
-     GetProcAddress (user32_lib, "EnumDisplayMonitors");
-   {
-     HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
-     get_composition_string_fn = (ImmGetCompositionString_Proc)
-       GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
-     get_ime_context_fn = (ImmGetContext_Proc)
-       GetProcAddress (imm32_lib, "ImmGetContext");
-     release_ime_context_fn = (ImmReleaseContext_Proc)
-       GetProcAddress (imm32_lib, "ImmReleaseContext");
-     set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
-       GetProcAddress (imm32_lib, "ImmSetCompositionWindow");
-   }
-   DEFVAR_INT ("w32-ansi-code-page",
-             w32_ansi_code_page,
-             doc: /* The ANSI code page used by the system.  */);
-   w32_ansi_code_page = GetACP ();
+ /* Crashing and reporting backtrace.  */
  
-   if (os_subtype == OS_NT)
-     w32_unicode_gui = 1;
-   else
-     w32_unicode_gui = 0;
-   /* MessageBox does not work without this when linked to comctl32.dll 6.0.  */
-   InitCommonControls ();
+ #ifndef CYGWIN
+ static LONG CALLBACK my_exception_handler (EXCEPTION_POINTERS *);
+ static LPTOP_LEVEL_EXCEPTION_FILTER prev_exception_handler;
+ #endif
+ static DWORD except_code;
+ static PVOID except_addr;
  
-   syms_of_w32uniscribe ();
+ #ifndef CYGWIN
+ /* This handler records the exception code and the address where it
+    was triggered so that this info could be included in the backtrace.
+    Without that, the backtrace in some cases has no information
+    whatsoever about the offending code, and looks as if the top-level
+    exception handler in the MinGW startup code di the one that
+    crashed.  */
+ static LONG CALLBACK
+ my_exception_handler (EXCEPTION_POINTERS * exception_data)
+ {
+   except_code = exception_data->ExceptionRecord->ExceptionCode;
+   except_addr = exception_data->ExceptionRecord->ExceptionAddress;
+   if (prev_exception_handler)
+     return prev_exception_handler (exception_data);
+   return EXCEPTION_EXECUTE_HANDLER;
  }
+ #endif
  
  typedef USHORT (WINAPI * CaptureStackBackTrace_proc) (ULONG, ULONG, PVOID *,
                                                      PULONG);
@@@ -8349,21 -8054,32 +8412,32 @@@ emacs_abort (void
  
        if (i)
          {
+           int errfile_fd = -1;
+           int j;
+           char buf[sizeof ("\r\nException  at this address:\r\n\r\n")
+                    + 2 * INT_BUFSIZE_BOUND (void *)];
  #ifdef CYGWIN
            int stderr_fd = 2;
  #else
            HANDLE errout = GetStdHandle (STD_ERROR_HANDLE);
            int stderr_fd = -1;
- #endif
-           int errfile_fd = -1;
-           int j;
  
- #ifndef CYGWIN
            if (errout && errout != INVALID_HANDLE_VALUE)
              stderr_fd = _open_osfhandle ((intptr_t)errout, O_APPEND | O_BINARY);
  #endif
+           /* We use %p, not 0x%p, as %p produces a leading "0x" on XP,
+              but not on Windows 7.  addr2line doesn't mind a missing
+              "0x", but will be confused by an extra one.  */
+           if (except_addr)
+             sprintf (buf, "\r\nException 0x%lx at this address:\r\n%p\r\n",
+                      except_code, except_addr);
            if (stderr_fd >= 0)
-             write (stderr_fd, "\r\nBacktrace:\r\n", 14);
+             {
+               if (except_addr)
+                 write (stderr_fd, buf, strlen (buf));
+               write (stderr_fd, "\r\nBacktrace:\r\n", 14);
+             }
  #ifdef CYGWIN
  #define _open open
  #endif
            if (errfile_fd >= 0)
              {
                lseek (errfile_fd, 0L, SEEK_END);
+               if (except_addr)
+                 write (errfile_fd, buf, strlen (buf));
                write (errfile_fd, "\r\nBacktrace:\r\n", 14);
              }
  
            for (j = 0; j < i; j++)
              {
-               char buf[INT_BUFSIZE_BOUND (void *)];
                /* stack[] gives the return addresses, whereas we want
                   the address of the call, so decrease each address
                   by approximate size of 1 CALL instruction.  */
-               sprintf (buf, "0x%p\r\n", (char *)stack[j] - sizeof(void *));
+               sprintf (buf, "%p\r\n", (char *)stack[j] - sizeof(void *));
                if (stderr_fd >= 0)
                  write (stderr_fd, buf, strlen (buf));
                if (errfile_fd >= 0)
      }
  }
  
\f
+ /* Initialization.  */
+ /*
+       globals_of_w32fns is used to initialize those global variables that
+       must always be initialized on startup even when the global variable
+       initialized is non zero (see the function main in emacs.c).
+       globals_of_w32fns is called from syms_of_w32fns when the global
+       variable initialized is 0 and directly from main when initialized
+       is non zero.
+  */
+ void
+ globals_of_w32fns (void)
+ {
+   HMODULE user32_lib = GetModuleHandle ("user32.dll");
+   /*
+     TrackMouseEvent not available in all versions of Windows, so must load
+     it dynamically.  Do it once, here, instead of every time it is used.
+   */
+   track_mouse_event_fn = (TrackMouseEvent_Proc)
+     GetProcAddress (user32_lib, "TrackMouseEvent");
+   monitor_from_point_fn = (MonitorFromPoint_Proc)
+     GetProcAddress (user32_lib, "MonitorFromPoint");
+   get_monitor_info_fn = (GetMonitorInfo_Proc)
+     GetProcAddress (user32_lib, "GetMonitorInfoA");
+   monitor_from_window_fn = (MonitorFromWindow_Proc)
+     GetProcAddress (user32_lib, "MonitorFromWindow");
+   enum_display_monitors_fn = (EnumDisplayMonitors_Proc)
+     GetProcAddress (user32_lib, "EnumDisplayMonitors");
+   {
+     HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
+     get_composition_string_fn = (ImmGetCompositionString_Proc)
+       GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
+     get_ime_context_fn = (ImmGetContext_Proc)
+       GetProcAddress (imm32_lib, "ImmGetContext");
+     release_ime_context_fn = (ImmReleaseContext_Proc)
+       GetProcAddress (imm32_lib, "ImmReleaseContext");
+     set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
+       GetProcAddress (imm32_lib, "ImmSetCompositionWindow");
+   }
+   except_code = 0;
+   except_addr = 0;
+ #ifndef CYGWIN
+   prev_exception_handler = SetUnhandledExceptionFilter (my_exception_handler);
+ #endif
+   DEFVAR_INT ("w32-ansi-code-page",
+             w32_ansi_code_page,
+             doc: /* The ANSI code page used by the system.  */);
+   w32_ansi_code_page = GetACP ();
+   if (os_subtype == OS_NT)
+     w32_unicode_gui = 1;
+   else
+     w32_unicode_gui = 0;
+   /* MessageBox does not work without this when linked to comctl32.dll 6.0.  */
+   InitCommonControls ();
+   syms_of_w32uniscribe ();
+ }
  #ifdef NTGUI_UNICODE
  
  Lisp_Object
diff --combined src/w32proc.c
index d2751d506805ed2d951a2f01ae58edfe73933764,3e0081cd802ea3b0d706d7ec3db14b14d34db077..7d4fb9825fa55cae91eba3859f41823cda76ef27
@@@ -30,7 -30,6 +30,7 @@@ along with GNU Emacs.  If not, see <htt
  #include <fcntl.h>
  #include <signal.h>
  #include <sys/file.h>
 +#include <mbstring.h>
  
  /* must include CRT headers *before* config.h */
  #include <config.h>
@@@ -862,6 -861,8 +862,6 @@@ new_child (void
    cp->pid = -1;
    cp->procinfo.hProcess = NULL;
    cp->status = STATUS_READ_ERROR;
 -  cp->input_file = NULL;
 -  cp->pending_deletion = 0;
  
    /* use manual reset event so that select() will function properly */
    cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL);
@@@ -910,6 -911,21 +910,6 @@@ delete_child (child_process *cp
    if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL)
      return;
  
 -  /* Delete the child's temporary input file, if any, that is pending
 -     deletion.  */
 -  if (cp->input_file)
 -    {
 -      if (cp->pending_deletion)
 -      {
 -        if (unlink (cp->input_file))
 -          DebPrint (("delete_child.unlink (%s) failed, errno: %d\n",
 -                     cp->input_file, errno));
 -        cp->pending_deletion = 0;
 -      }
 -      xfree (cp->input_file);
 -      cp->input_file = NULL;
 -    }
 -
    /* reap thread if necessary */
    if (cp->thrd)
      {
@@@ -1057,10 -1073,9 +1057,10 @@@ reader_thread (void *arg
    return 0;
  }
  
 -/* To avoid Emacs changing directory, we just record here the directory
 -   the new process should start in.  This is set just before calling
 -   sys_spawnve, and is not generally valid at any other time.  */
 +/* To avoid Emacs changing directory, we just record here the
 +   directory the new process should start in.  This is set just before
 +   calling sys_spawnve, and is not generally valid at any other time.
 +   Note that this directory's name is UTF-8 encoded.  */
  static char * process_dir;
  
  static BOOL
@@@ -1073,8 -1088,7 +1073,8 @@@ create_child (char *exe, char *cmdline
    SECURITY_DESCRIPTOR sec_desc;
  #endif
    DWORD flags;
 -  char dir[ MAXPATHLEN ];
 +  char dir[ MAX_PATH ];
 +  char *p;
  
    if (cp == NULL) emacs_abort ();
  
    sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */;
    sec_attrs.bInheritHandle = FALSE;
  
 -  strcpy (dir, process_dir);
 -  unixtodos_filename (dir);
 +  filename_to_ansi (process_dir, dir);
 +  /* Can't use unixtodos_filename here, since that needs its file name
 +     argument encoded in UTF-8.  OTOH, process_dir, which _is_ in
 +     UTF-8, points, to the directory computed by our caller, and we
 +     don't want to modify that, either.  */
 +  for (p = dir; *p; p = CharNextA (p))
 +    if (*p == '/')
 +      *p = '\\';
  
    flags = (!NILP (Vw32_start_process_share_console)
           ? CREATE_NEW_PROCESS_GROUP
           : CREATE_NEW_CONSOLE);
    if (NILP (Vw32_start_process_inherit_error_mode))
      flags |= CREATE_DEFAULT_ERROR_MODE;
 -  if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
 -                    flags, env, dir, &start, &cp->procinfo))
 +  if (!CreateProcessA (exe, cmdline, &sec_attrs, NULL, TRUE,
 +                     flags, env, dir, &start, &cp->procinfo))
      goto EH_Fail;
  
    cp->pid = (int) cp->procinfo.dwProcessId;
@@@ -1174,6 -1182,45 +1174,6 @@@ register_child (pid_t pid, int fd
    fd_info[fd].cp = cp;
  }
  
 -/* Record INFILE as an input file for process PID.  */
 -void
 -record_infile (pid_t pid, char *infile)
 -{
 -  child_process *cp;
 -
 -  /* INFILE should never be NULL, since xstrdup would have signaled
 -     memory full condition in that case, see callproc.c where this
 -     function is called.  */
 -  eassert (infile);
 -
 -  cp = find_child_pid ((DWORD)pid);
 -  if (cp == NULL)
 -    {
 -      DebPrint (("record_infile is unable to find pid %lu\n", pid));
 -      return;
 -    }
 -
 -  cp->input_file = infile;
 -}
 -
 -/* Mark the input file INFILE of the corresponding subprocess as
 -   temporary, to be deleted when the subprocess exits.  */
 -void
 -record_pending_deletion (char *infile)
 -{
 -  child_process *cp;
 -
 -  eassert (infile);
 -
 -  for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
 -    if (CHILD_ACTIVE (cp)
 -      && cp->input_file && xstrcasecmp (cp->input_file, infile) == 0)
 -      {
 -      cp->pending_deletion = 1;
 -      break;
 -      }
 -}
 -
  /* Called from waitpid when a process exits.  */
  static void
  reap_subprocess (child_process *cp)
@@@ -1380,8 -1427,6 +1380,8 @@@ waitpid (pid_t pid, int *status, int op
  # define IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER
  #endif
  
 +/* Implementation note: This function works with file names encoded in
 +   the current ANSI codepage.  */
  static void
  w32_executable_type (char * filename,
                     int * is_dos_app,
@@@ -1572,7 -1617,6 +1572,7 @@@ sys_spawnve (int mode, char *cmdname, c
    char *sepchars = " \t*?";
    /* This is for native w32 apps; modified below for Cygwin apps.  */
    char escape_char = '\\';
 +  char cmdname_a[MAX_PATH];
  
    /* We don't care about the other modes */
    if (mode != _P_NOWAIT)
        return -1;
      }
  
 -  /* Handle executable names without an executable suffix.  */
 -  program = build_string (cmdname);
 -  if (NILP (Ffile_executable_p (program)))
 +  /* Handle executable names without an executable suffix.  The caller
 +     already searched exec-path and verified the file is executable,
 +     but start-process doesn't do that for file names that are already
 +     absolute.  So we double-check this here, just in case.  */
 +  if (faccessat (AT_FDCWD, cmdname, X_OK, AT_EACCESS) != 0)
      {
        struct gcpro gcpro1;
  
 +      program = build_string (cmdname);
        full = Qnil;
        GCPRO1 (program);
        openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK));
          errno = EINVAL;
          return -1;
        }
 -      program = full;
 +      program = ENCODE_FILE (full);
 +      cmdname = SDATA (program);
      }
  
    /* make sure argv[0] and cmdname are both in DOS format */
 -  cmdname = SDATA (program);
    unixtodos_filename (cmdname);
 +  /* argv[0] was encoded by caller using ENCODE_FILE, so it is in
 +     UTF-8.  All the other arguments are encoded by ENCODE_SYSTEM or
 +     some such, and are in some ANSI codepage.  We need to have
 +     argv[0] encoded in ANSI codepage.  */
 +  filename_to_ansi (cmdname, cmdname_a);
 +  /* We explicitly require that the command's file name be encodable
 +     in the current ANSI codepage, because we will be invoking it via
 +     the ANSI APIs.  */
 +  if (_mbspbrk (cmdname_a, "?"))
 +    {
 +      errno = ENOENT;
 +      return -1;
 +    }
 +  /* From here on, CMDNAME is an ANSI-encoded string.  */
 +  cmdname = cmdname_a;
    argv[0] = cmdname;
  
    /* Determine whether program is a 16-bit DOS executable, or a 32-bit Windows
       while leaving the real app name as argv[0].  */
    if (is_dos_app)
      {
 -      cmdname = alloca (MAXPATHLEN);
 +      char *p;
 +
 +      cmdname = alloca (MAX_PATH);
        if (egetenv ("CMDPROXY"))
        strcpy (cmdname, egetenv ("CMDPROXY"));
        else
          strcpy (cmdname, SDATA (Vinvocation_directory));
          strcat (cmdname, "cmdproxy.exe");
        }
 -      unixtodos_filename (cmdname);
 +
 +      /* Can't use unixtodos_filename here, since that needs its file
 +       name argument encoded in UTF-8.  */
 +      for (p = cmdname; *p; p = CharNextA (p))
 +      if (*p == '/')
 +        *p = '\\';
      }
  
    /* we have to do some conjuring here to put argv and envp into the
@@@ -1941,12 -1960,17 +1941,17 @@@ sys_select (int nfds, SELECT_TYPE *rfds
    FD_ZERO (rfds);
    nr = 0;
  
-   /* Always wait on interrupt_handle, to detect C-g (quit).  */
-   wait_hnd[0] = interrupt_handle;
-   fdindex[0] = -1;
+   /* If interrupt_handle is available and valid, always wait on it, to
+      detect C-g (quit).  */
+   nh = 0;
+   if (interrupt_handle && interrupt_handle != INVALID_HANDLE_VALUE)
+     {
+       wait_hnd[0] = interrupt_handle;
+       fdindex[0] = -1;
+       nh++;
+     }
  
    /* Build a list of pipe handles to wait on.  */
-   nh = 1;
    for (i = 0; i < nfds; i++)
      if (FD_ISSET (i, &orfds))
        {
                FD_SET (i, rfds);
                return 1;
              }
+           else if (noninteractive)
+             {
+               if (handle_file_notifications (NULL))
+                 return 1;
+             }
          }
        else
          {
@@@ -2067,6 -2096,11 +2077,11 @@@ count_children
      {
        if (timeout)
        Sleep (timeout_ms);
+       if (noninteractive)
+       {
+         if (handle_file_notifications (NULL))
+           return 1;
+       }
        return 0;
      }
  
      }
    else if (active == WAIT_TIMEOUT)
      {
+       if (noninteractive)
+       {
+         if (handle_file_notifications (NULL))
+           return 1;
+       }
        return 0;
      }
    else if (active >= WAIT_OBJECT_0
          break;
      } while (active < nh + nc);
  
+   if (noninteractive)
+     {
+       if (handle_file_notifications (NULL))
+       nr++;
+     }
    /* If no input has arrived and timeout hasn't expired, wait again.  */
    if (nr == 0)
      {
@@@ -2628,11 -2673,10 +2654,11 @@@ All path elements in FILENAME are conve
    filename = Fexpand_file_name (filename, Qnil);
  
    /* luckily, this returns the short version of each element in the path.  */
 -  if (GetShortPathName (SDATA (ENCODE_FILE (filename)), shortname, MAX_PATH) == 0)
 +  if (w32_get_short_filename (SDATA (ENCODE_FILE (filename)),
 +                            shortname, MAX_PATH) == 0)
      return Qnil;
  
 -  dostounix_filename (shortname, 0);
 +  dostounix_filename (shortname);
  
    /* No need to DECODE_FILE, because 8.3 names are pure ASCII.   */
    return build_string (shortname);
@@@ -2646,7 -2690,7 +2672,7 @@@ If FILENAME does not exist, return nil
  All path elements in FILENAME are converted to their long names.  */)
    (Lisp_Object filename)
  {
 -  char longname[ MAX_PATH ];
 +  char longname[ MAX_UTF8_PATH ];
    int drive_only = 0;
  
    CHECK_STRING (filename);
    /* first expand it.  */
    filename = Fexpand_file_name (filename, Qnil);
  
 -  if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)), longname, MAX_PATH))
 +  if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)), longname,
 +                            MAX_UTF8_PATH))
      return Qnil;
  
 -  dostounix_filename (longname, 0);
 +  dostounix_filename (longname);
  
    /* If we were passed only a drive, make sure that a slash is not appended
       for consistency with directories.  Allow for drive mapping via SUBST
    if (drive_only && longname[1] == ':' && longname[2] == '/' && !longname[3])
      longname[2] = '\0';
  
 -  return DECODE_FILE (build_string (longname));
 +  return DECODE_FILE (build_unibyte_string (longname));
  }
  
  DEFUN ("w32-set-process-priority", Fw32_set_process_priority,
diff --combined src/w32term.c
index b29087ef57ba771683aeb90abac8887777043d1d,42a11e1eff63bbd36b01b7ac7f278de0eca218b9..9c74304a83a967a74f5b180a198d7c931e0e28c2
@@@ -52,7 -52,6 +52,7 @@@ along with GNU Emacs.  If not, see <htt
  #include "keymap.h"
  
  #ifdef WINDOWSNT
 +#include "w32.h"      /* for filename_from_utf16, filename_from_ansi */
  #include "w32heap.h"
  #endif
  
@@@ -181,7 -180,7 +181,7 @@@ void x_lower_frame (struct frame *)
  void x_scroll_bar_clear (struct frame *);
  void x_wm_set_size_hint (struct frame *, long, bool);
  void x_raise_frame (struct frame *);
- void x_set_window_size (struct frame *, int, int, int);
+ void x_set_window_size (struct frame *, int, int, int, bool);
  void x_wm_set_window_state (struct frame *, int);
  void x_wm_set_icon_pixmap (struct frame *, int);
  static void w32_initialize (void);
@@@ -622,6 -621,32 +622,32 @@@ w32_draw_vertical_window_border (struc
  }
  
  
+ /* Draw a window divider from (x0, y0) to (x1, y1)  */
+ static void
+ w32_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
+ {
+   struct frame *f = XFRAME (WINDOW_FRAME (w));
+   RECT r;
+   HDC hdc;
+   struct face *face;
+   r.left = x0;
+   r.right = x1;
+   r.top = y0;
+   r.bottom = y1;
+   hdc = get_frame_dc (f);
+   face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
+   if (face)
+     w32_fill_rect (f, hdc, face->foreground, &r);
+   else
+     w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
+   release_frame_dc (f, hdc);
+ }
  /* End update of window W.
  
     Draw vertical borders between horizontally adjacent windows, and
@@@ -649,7 -674,12 +675,12 @@@ x_update_window_end (struct window *w, 
                                w->output_cursor.x, w->output_cursor.y);
  
        if (draw_window_fringes (w, 1))
-       x_draw_vertical_border (w);
+       {
+         if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+           x_draw_right_divider (w);
+         else
+           x_draw_vertical_border (w);
+       }
  
        unblock_input ();
      }
@@@ -778,8 -808,7 +809,7 @@@ w32_draw_fringe_bitmap (struct window *
          if (sb_width > 0)
            {
              int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
-             int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
-                                   * FRAME_COLUMN_WIDTH (f));
+             int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
  
              if (bx < 0)
                {
@@@ -2676,8 -2705,7 +2706,7 @@@ x_scroll_run (struct window *w, struct 
        if (sb_width > 0)
        {
          int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
-         int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
-                               * FRAME_COLUMN_WIDTH (f));
+         int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
  
          if (bar_area_x + bar_area_width == x)
            {
@@@ -3100,14 -3128,7 +3129,14 @@@ construct_drag_n_drop (struct input_eve
    HDROP hdrop;
    POINT p;
    WORD num_files;
 -  guichar_t *name;
 +  wchar_t name_w[MAX_PATH];
 +#ifdef NTGUI_UNICODE
 +  const int use_unicode = 1;
 +#else
 +  int use_unicode = w32_unicode_filenames;
 +  char name_a[MAX_PATH];
 +  char file[MAX_UTF8_PATH];
 +#endif
    int i, len;
  
    result->kind = DRAG_N_DROP_EVENT;
  
    for (i = 0; i < num_files; i++)
      {
 -      len = GUI_FN (DragQueryFile) (hdrop, i, NULL, 0);
 -      if (len <= 0)
 -      continue;
 -
 -      name = alloca ((len + 1) * sizeof (*name));
 -      GUI_FN (DragQueryFile) (hdrop, i, name, len + 1);
 +      if (use_unicode)
 +      {
 +        eassert (DragQueryFileW (hdrop, i, NULL, 0) < MAX_PATH);
 +        /* If DragQueryFile returns zero, it failed to fetch a file
 +           name.  */
 +        if (DragQueryFileW (hdrop, i, name_w, MAX_PATH) == 0)
 +          continue;
  #ifdef NTGUI_UNICODE
 -      files = Fcons (from_unicode_buffer (name), files);
 +        files = Fcons (from_unicode_buffer (name_w), files);
  #else
 -      files = Fcons (DECODE_FILE (build_string (name)), files);
 +        filename_from_utf16 (name_w, file);
 +        files = Fcons (DECODE_FILE (build_unibyte_string (file)), files);
  #endif /* NTGUI_UNICODE */
 +      }
 +#ifndef NTGUI_UNICODE
 +      else
 +      {
 +        eassert (DragQueryFileA (hdrop, i, NULL, 0) < MAX_PATH);
 +        if (DragQueryFileA (hdrop, i, name_a, MAX_PATH) == 0)
 +          continue;
 +        filename_from_ansi (name_a, file);
 +        files = Fcons (DECODE_FILE (build_unibyte_string (file)), files);
 +      }
 +#endif
      }
  
    DragFinish (hdrop);
@@@ -3761,7 -3769,7 +3790,7 @@@ w32_set_vertical_scroll_bar (struct win
    /* Get window dimensions.  */
    window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
    top  = window_y;
-   width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
+   width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
    height = window_height;
  
    /* Compute the left edge of the scroll bar area.  */
@@@ -4216,7 -4224,6 +4245,6 @@@ w32_read_socket (struct terminal *termi
    struct frame *f;
    struct w32_display_info *dpyinfo = &one_w32_display_info;
    Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
-   static char buf[1];
  
    block_input ();
  
                  break;
  
                case SIZE_MAXIMIZED:
+                 {
+                   bool iconified = FRAME_ICONIFIED_P (f);
+                   SET_FRAME_VISIBLE (f, 1);
+                   SET_FRAME_ICONIFIED (f, 0);
+                   /* wait_reading_process_output will notice this
+                      and update the frame's display structures.  */
+                   SET_FRAME_GARBAGED (f);
+                   if (iconified)
+                     {
+                       int x, y;
+                       /* Reset top and left positions of the Window
+                          here since Windows sends a WM_MOVE message
+                          BEFORE telling us the Window is minimized
+                          when the Window is iconified, with 3000,3000
+                          as the co-ords. */
+                       x_real_positions (f, &x, &y);
+                       f->left_pos = x;
+                       f->top_pos = y;
+                       inev.kind = DEICONIFY_EVENT;
+                       XSETFRAME (inev.frame_or_window, f);
+                     }
+                   else if (! NILP (Vframe_list)
+                            && ! NILP (XCDR (Vframe_list)))
+                     /* Force a redisplay sooner or later
+                        to update the frame titles
+                        in case this is the second frame.  */
+                     record_asynch_buffer_change ();
+                 }
+                 if (get_frame_param (f, Qfullscreen) == Qnil)
+                   set_frame_param (f, Qfullscreen, Qmaximized);
+                 else if (get_frame_param (f, Qfullscreen) != Qmaximized)
+                   set_frame_param (f, Qmaximized, Qmaximized);
+                 break;
                case SIZE_RESTORED:
                  {
                    bool iconified = FRAME_ICONIFIED_P (f);
                         in case this is the second frame.  */
                      record_asynch_buffer_change ();
                  }
+                 if (get_frame_param (f, Qfullscreen) == Qmaximized)
+                   set_frame_param (f, Qfullscreen, Qnil);
+                 else if (get_frame_param (f, Qmaximized) != Qnil)
+                   set_frame_param (f, Qmaximized, Qnil);
                  break;
                }
            }
          if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED)
            {
              RECT rect;
-             int rows;
-             int columns;
-             int width;
-             int height;
+             int rows, columns, width, height, text_width, text_height;
  
              GetClientRect (msg.msg.hwnd, &rect);
  
              height = rect.bottom - rect.top;
              width = rect.right - rect.left;
+             text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
+             text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
              rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
              columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
  
                 not changed, the font size may have changed, so we need
                 to check the pixel dimensions as well.  */
  
-             if (columns != FRAME_COLS (f)
-                 || rows != FRAME_LINES (f)
-                 || width != FRAME_PIXEL_WIDTH (f)
-                 || height != FRAME_PIXEL_HEIGHT (f))
+             if (width != FRAME_PIXEL_WIDTH (f)
+                 || height != FRAME_PIXEL_HEIGHT (f)
+                 || text_width != FRAME_TEXT_WIDTH (f)
+                 || text_height != FRAME_TEXT_HEIGHT (f))
                {
-                 change_frame_size (f, rows, columns, 0, 1, 0);
+                 change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
                  SET_FRAME_GARBAGED (f);
                  cancel_mouse_face (f);
-                 FRAME_PIXEL_WIDTH (f) = width;
-                 FRAME_PIXEL_HEIGHT (f) = height;
+                 /* Do we want to set these here ????  */
+ /**             FRAME_PIXEL_WIDTH (f) = width; **/
+ /**             FRAME_TEXT_WIDTH (f) = text_width; **/
+ /**             FRAME_PIXEL_HEIGHT (f) = height; **/
                  f->win_gravity = NorthWestGravity;
                }
            }
@@@ -5425,7 -5479,8 +5500,8 @@@ x_new_font (struct frame *f, Lisp_Objec
         doing it because it's done in Fx_show_tip, and it leads to
         problems because the tip frame has no widget.  */
        if (NILP (tip_frame) || XFRAME (tip_frame) != f)
-       x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+       x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+                          FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1);
      }
  
    /* X version sets font of input methods here also.  */
@@@ -5563,7 -5618,7 +5639,7 @@@ x_check_fullscreen (struct frame *f
           when setting WM manager hints.  */
        if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
          {
-           change_frame_size (f, height, width, 0, 1, 0);
+           change_frame_size (f, width, height, 0, 1, 0, 0);
            SET_FRAME_GARBAGED (f);
            cancel_mouse_face (f);
  
@@@ -5627,20 -5682,28 +5703,28 @@@ w32fullscreen_hook (struct frame *f
     Otherwise we leave the window gravity unchanged.  */
  
  void
- x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
+ x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
  {
    int pixelwidth, pixelheight;
  
    block_input ();
  
-   check_frame_size (f, &rows, &cols);
+   check_frame_size (f, &width, &height, pixelwise);
    f->scroll_bar_actual_width
      = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
  
    compute_fringe_widths (f, 0);
  
-   pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
-   pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+   if (pixelwise)
+     {
+       pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
+       pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
+     }
+   else
+     {
+       pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
+       pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
+     }
  
    f->win_gravity = NorthWestGravity;
    x_wm_set_size_hint (f, (long) 0, 0);
  
       We pass 1 for DELAY since we can't run Lisp code inside of
       a BLOCK_INPUT.  */
-   change_frame_size (f, rows, cols, 0, 1, 0);
+   change_frame_size (f, width, height, 0, 1, 0, 0);
    FRAME_PIXEL_WIDTH (f) = pixelwidth;
    FRAME_PIXEL_HEIGHT (f) = pixelheight;
  
@@@ -6072,7 -6135,7 +6156,7 @@@ x_wm_set_size_hint (struct frame *f, lo
    SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
    SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
    SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
-   SetWindowLong (window, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width);
+   SetWindowLong (window, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
  
    leave_crit ();
  }
@@@ -6212,6 -6275,7 +6296,7 @@@ static struct redisplay_interface w32_r
    w32_clear_frame_area,
    w32_draw_window_cursor,
    w32_draw_vertical_window_border,
+   w32_draw_window_divider,
    w32_shift_glyphs_for_insert
  };
  
@@@ -6580,18 -6644,6 +6665,18 @@@ X toolkit.  Possible values are: gtk, m
  With MS Windows or Nextstep, the value is t.  */);
    Vx_toolkit_scroll_bars = Qt;
  
 +  DEFVAR_BOOL ("w32-unicode-filenames",
 +             w32_unicode_filenames,
 +     doc: /* Non-nil means use Unicode APIs when passing file names to the OS.
 +A value of nil means file names passed to the OS APIs and returned
 +from those APIs are encoded/decoded using the ANSI codepage
 +specified by `file-name-coding-system'.
 +
 +This variable is set to non-nil by default when Emacs runs on Windows
 +systems of the NT family, including W2K, XP, Vista, Windows 7 and
 +Windows 8.  It is set to nil on Windows 9X.  */);
 +  w32_unicode_filenames = 0;
 +
    /* Tell Emacs about this window system.  */
    Fprovide (Qw32, Qnil);
  }