diff --git a/src/os_win32.c b/src/os_win32.c
new file mode 100644
index 0000000..74b8960
--- /dev/null
+++ b/src/os_win32.c
@@ -0,0 +1,4790 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+/*
+ * os_win32.c
+ *
+ * Used for both the console version and the Win32 GUI.  A lot of code is for
+ * the console version only, so there is a lot of "#ifndef FEAT_GUI_W32".
+ *
+ * Win32 (Windows NT and Windows 95) system-dependent routines.
+ * Portions lifted from the Win32 SDK samples, the MSDOS-dependent code,
+ * NetHack 3.1.3, GNU Emacs 19.30, and Vile 5.5.
+ *
+ * George V. Reilly <george@reilly.org> wrote most of this.
+ * Roger Knobbe <rogerk@wonderware.com> did the initial port of Vim 3.0.
+ */
+
+#include <io.h>
+#include "vim.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#include <sys/types.h>
+#include <errno.h>
+#include <signal.h>
+#include <limits.h>
+#include <process.h>
+
+#undef chdir
+#ifdef __GNUC__
+# ifndef __MINGW32__
+#  include <dirent.h>
+# endif
+#else
+# include <direct.h>
+#endif
+
+#if defined(FEAT_TITLE) && !defined(FEAT_GUI_W32)
+# include <shellapi.h>
+#endif
+
+#ifdef __MINGW32__
+# ifndef FROM_LEFT_1ST_BUTTON_PRESSED
+#  define FROM_LEFT_1ST_BUTTON_PRESSED    0x0001
+# endif
+# ifndef RIGHTMOST_BUTTON_PRESSED
+#  define RIGHTMOST_BUTTON_PRESSED	  0x0002
+# endif
+# ifndef FROM_LEFT_2ND_BUTTON_PRESSED
+#  define FROM_LEFT_2ND_BUTTON_PRESSED    0x0004
+# endif
+# ifndef FROM_LEFT_3RD_BUTTON_PRESSED
+#  define FROM_LEFT_3RD_BUTTON_PRESSED    0x0008
+# endif
+# ifndef FROM_LEFT_4TH_BUTTON_PRESSED
+#  define FROM_LEFT_4TH_BUTTON_PRESSED    0x0010
+# endif
+
+/*
+ * EventFlags
+ */
+# ifndef MOUSE_MOVED
+#  define MOUSE_MOVED   0x0001
+# endif
+# ifndef DOUBLE_CLICK
+#  define DOUBLE_CLICK  0x0002
+# endif
+#endif
+
+/* Record all output and all keyboard & mouse input */
+/* #define MCH_WRITE_DUMP */
+
+#ifdef MCH_WRITE_DUMP
+FILE* fdDump = NULL;
+#endif
+
+/*
+ * When generating prototypes for Win32 on Unix, these lines make the syntax
+ * errors disappear.  They do not need to be correct.
+ */
+#ifdef PROTO
+#define WINAPI
+#define WINBASEAPI
+typedef char * LPCSTR;
+typedef int ACCESS_MASK;
+typedef int BOOL;
+typedef int COLORREF;
+typedef int CONSOLE_CURSOR_INFO;
+typedef int COORD;
+typedef int DWORD;
+typedef int HANDLE;
+typedef int HDC;
+typedef int HFONT;
+typedef int HICON;
+typedef int HINSTANCE;
+typedef int HWND;
+typedef int INPUT_RECORD;
+typedef int KEY_EVENT_RECORD;
+typedef int LOGFONT;
+typedef int LPBOOL;
+typedef int LPCTSTR;
+typedef int LPDWORD;
+typedef int LPSTR;
+typedef int LPTSTR;
+typedef int LPVOID;
+typedef int MOUSE_EVENT_RECORD;
+typedef int PACL;
+typedef int PDWORD;
+typedef int PHANDLE;
+typedef int PRINTDLG;
+typedef int PSECURITY_DESCRIPTOR;
+typedef int PSID;
+typedef int SECURITY_INFORMATION;
+typedef int SHORT;
+typedef int SMALL_RECT;
+typedef int TEXTMETRIC;
+typedef int TOKEN_INFORMATION_CLASS;
+typedef int TRUSTEE;
+typedef int WORD;
+typedef int WCHAR;
+typedef void VOID;
+#endif
+
+#ifndef FEAT_GUI_W32
+/* Undocumented API in kernel32.dll needed to work around dead key bug in
+ * console-mode applications in NT 4.0.  If you switch keyboard layouts
+ * in a console app to a layout that includes dead keys and then hit a
+ * dead key, a call to ToAscii will trash the stack.  My thanks to Ian James
+ * and Michael Dietrich for helping me figure out this workaround.
+ */
+
+/* WINBASEAPI BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR); */
+#ifndef WINBASEAPI
+# define WINBASEAPI __stdcall
+#endif
+#if defined(__BORLANDC__)
+typedef BOOL (__stdcall *PFNGCKLN)(LPSTR);
+#else
+typedef WINBASEAPI BOOL (WINAPI *PFNGCKLN)(LPSTR);
+#endif
+PFNGCKLN    s_pfnGetConsoleKeyboardLayoutName = NULL;
+#endif
+
+#if defined(__BORLANDC__)
+/* Strangely Borland uses a non-standard name. */
+# define wcsicmp(a, b) wcscmpi((a), (b))
+#endif
+
+#ifndef FEAT_GUI_W32
+/* Win32 Console handles for input and output */
+static HANDLE g_hConIn  = INVALID_HANDLE_VALUE;
+static HANDLE g_hConOut = INVALID_HANDLE_VALUE;
+
+/* Win32 Screen buffer,coordinate,console I/O information */
+static SMALL_RECT g_srScrollRegion;
+static COORD	  g_coord;  /* 0-based, but external coords are 1-based */
+
+/* The attribute of the screen when the editor was started */
+static WORD  g_attrDefault = 7;  /* lightgray text on black background */
+static WORD  g_attrCurrent;
+
+static int g_fCBrkPressed = FALSE;  /* set by ctrl-break interrupt */
+static int g_fCtrlCPressed = FALSE; /* set when ctrl-C or ctrl-break detected */
+static int g_fForceExit = FALSE;    /* set when forcefully exiting */
+
+static void termcap_mode_start(void);
+static void termcap_mode_end(void);
+static void clear_chars(COORD coord, DWORD n);
+static void clear_screen(void);
+static void clear_to_end_of_display(void);
+static void clear_to_end_of_line(void);
+static void scroll(unsigned cLines);
+static void set_scroll_region(unsigned left, unsigned top,
+			      unsigned right, unsigned bottom);
+static void insert_lines(unsigned cLines);
+static void delete_lines(unsigned cLines);
+static void gotoxy(unsigned x, unsigned y);
+static void normvideo(void);
+static void textattr(WORD wAttr);
+static void textcolor(WORD wAttr);
+static void textbackground(WORD wAttr);
+static void standout(void);
+static void standend(void);
+static void visual_bell(void);
+static void cursor_visible(BOOL fVisible);
+static BOOL write_chars(LPCSTR pchBuf, DWORD cchToWrite);
+static char_u tgetch(int *pmodifiers, char_u *pch2);
+static void create_conin(void);
+static int s_cursor_visible = TRUE;
+static int did_create_conin = FALSE;
+#else
+static int s_dont_use_vimrun = TRUE;
+static int need_vimrun_warning = FALSE;
+static char *vimrun_path = "vimrun ";
+#endif
+
+#ifndef FEAT_GUI_W32
+static int suppress_winsize = 1;	/* don't fiddle with console */
+#endif
+
+    static void
+get_exe_name(void)
+{
+    char	temp[256];
+
+    if (exe_name == NULL)
+    {
+	/* store the name of the executable, may be used for $VIM */
+	GetModuleFileName(NULL, temp, 255);
+	if (*temp != NUL)
+	    exe_name = FullName_save((char_u *)temp, FALSE);
+    }
+}
+
+#if defined(DYNAMIC_GETTEXT) || defined(PROTO)
+# ifndef GETTEXT_DLL
+#  define GETTEXT_DLL "libintl.dll"
+# endif
+/* Dummy funcitons */
+static char* null_libintl_gettext(const char *);
+static char* null_libintl_textdomain(const char *);
+static char* null_libintl_bindtextdomain(const char *, const char *);
+
+static HINSTANCE hLibintlDLL = 0;
+char* (*dyn_libintl_gettext)(const char *) = null_libintl_gettext;
+char* (*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain;
+char* (*dyn_libintl_bindtextdomain)(const char *, const char *)
+						= null_libintl_bindtextdomain;
+
+    int
+dyn_libintl_init(char *libname)
+{
+    int i;
+    static struct
+    {
+	char	    *name;
+	FARPROC	    *ptr;
+    } libintl_entry[] =
+    {
+	{"gettext", (FARPROC*)&dyn_libintl_gettext},
+	{"textdomain", (FARPROC*)&dyn_libintl_textdomain},
+	{"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain},
+	{NULL, NULL}
+    };
+
+    /* No need to initialize twice. */
+    if (hLibintlDLL)
+	return 1;
+    /* Load gettext library (libintl.dll) */
+    hLibintlDLL = LoadLibrary(libname != NULL ? libname : GETTEXT_DLL);
+    if (!hLibintlDLL)
+    {
+	char_u	    dirname[_MAX_PATH];
+
+	/* Try using the path from gvim.exe to find the .dll there. */
+	get_exe_name();
+	STRCPY(dirname, exe_name);
+	STRCPY(gettail(dirname), GETTEXT_DLL);
+	hLibintlDLL = LoadLibrary((char *)dirname);
+	if (!hLibintlDLL)
+	{
+	    if (p_verbose > 0)
+		EMSG2(_(e_loadlib), GETTEXT_DLL);
+	    return 0;
+	}
+    }
+    for (i = 0; libintl_entry[i].name != NULL
+					 && libintl_entry[i].ptr != NULL; ++i)
+    {
+	if ((*libintl_entry[i].ptr = (FARPROC)GetProcAddress(hLibintlDLL,
+					      libintl_entry[i].name)) == NULL)
+	{
+	    dyn_libintl_end();
+	    if (p_verbose > 0)
+		EMSG2(_(e_loadfunc), libintl_entry[i].name);
+	    return 0;
+	}
+    }
+    return 1;
+}
+
+    void
+dyn_libintl_end()
+{
+    if (hLibintlDLL)
+	FreeLibrary(hLibintlDLL);
+    hLibintlDLL			= NULL;
+    dyn_libintl_gettext		= null_libintl_gettext;
+    dyn_libintl_textdomain	= null_libintl_textdomain;
+    dyn_libintl_bindtextdomain	= null_libintl_bindtextdomain;
+}
+
+    static char *
+null_libintl_gettext(const char* msgid)
+{
+    return (char*)msgid;
+}
+
+    static char *
+null_libintl_bindtextdomain(const char* domainname, const char* dirname)
+{
+    return NULL;
+}
+
+    static char *
+null_libintl_textdomain(const char* domainname)
+{
+    return NULL;
+}
+
+#endif /* DYNAMIC_GETTEXT */
+
+/* This symbol is not defined in older versions of the SDK or Visual C++ */
+
+#ifndef VER_PLATFORM_WIN32_WINDOWS
+# define VER_PLATFORM_WIN32_WINDOWS 1
+#endif
+
+DWORD g_PlatformId;
+
+#ifdef HAVE_ACL
+# include <aclapi.h>
+/*
+ * These are needed to dynamically load the ADVAPI DLL, which is not
+ * implemented under Windows 95 (and causes VIM to crash)
+ */
+typedef DWORD (WINAPI *PSNSECINFO) (LPTSTR, enum SE_OBJECT_TYPE,
+	SECURITY_INFORMATION, PSID, PSID, PACL, PACL);
+typedef DWORD (WINAPI *PGNSECINFO) (LPSTR, enum SE_OBJECT_TYPE,
+	SECURITY_INFORMATION, PSID *, PSID *, PACL *, PACL *,
+	PSECURITY_DESCRIPTOR *);
+
+static HANDLE advapi_lib = NULL;	/* Handle for ADVAPI library */
+static PSNSECINFO pSetNamedSecurityInfo;
+static PGNSECINFO pGetNamedSecurityInfo;
+#endif
+
+/*
+ * Set g_PlatformId to VER_PLATFORM_WIN32_NT (NT) or
+ * VER_PLATFORM_WIN32_WINDOWS (Win95).
+ */
+    void
+PlatformId(void)
+{
+    static int done = FALSE;
+
+    if (!done)
+    {
+	OSVERSIONINFO ovi;
+
+	ovi.dwOSVersionInfoSize = sizeof(ovi);
+	GetVersionEx(&ovi);
+
+	g_PlatformId = ovi.dwPlatformId;
+
+#ifdef HAVE_ACL
+	/*
+	 * Load the ADVAPI runtime if we are on anything
+	 * other than Windows 95
+	 */
+	if (g_PlatformId == VER_PLATFORM_WIN32_NT)
+	{
+	    /*
+	     * do this load.  Problems: Doesn't unload at end of run (this is
+	     * theoretically okay, since Windows should unload it when VIM
+	     * terminates).  Should we be using the 'mch_libcall' routines?
+	     * Seems like a lot of overhead to load/unload ADVAPI32.DLL each
+	     * time we verify security...
+	     */
+	    advapi_lib = LoadLibrary("ADVAPI32.DLL");
+	    if (advapi_lib != NULL)
+	    {
+		pSetNamedSecurityInfo = (PSNSECINFO)GetProcAddress(advapi_lib,
+						      "SetNamedSecurityInfoA");
+		pGetNamedSecurityInfo = (PGNSECINFO)GetProcAddress(advapi_lib,
+						      "GetNamedSecurityInfoA");
+		if (pSetNamedSecurityInfo == NULL
+			|| pGetNamedSecurityInfo == NULL)
+		{
+		    /* If we can't get the function addresses, set advapi_lib
+		     * to NULL so that we don't use them. */
+		    FreeLibrary(advapi_lib);
+		    advapi_lib = NULL;
+		}
+	    }
+	}
+#endif
+	done = TRUE;
+    }
+}
+
+/*
+ * Return TRUE when running on Windows 95 (or 98 or ME).
+ * Only to be used after mch_init().
+ */
+    int
+mch_windows95(void)
+{
+    return g_PlatformId == VER_PLATFORM_WIN32_WINDOWS;
+}
+
+#ifdef FEAT_GUI_W32
+/*
+ * Used to work around the "can't do synchronous spawn"
+ * problem on Win32s, without resorting to Universal Thunk.
+ */
+static int old_num_windows;
+static int num_windows;
+
+    static BOOL CALLBACK
+win32ssynch_cb(HWND hwnd, LPARAM lparam)
+{
+    num_windows++;
+    return TRUE;
+}
+#endif
+
+#ifndef FEAT_GUI_W32
+
+#define SHIFT  (SHIFT_PRESSED)
+#define CTRL   (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)
+#define ALT    (RIGHT_ALT_PRESSED  | LEFT_ALT_PRESSED)
+#define ALT_GR (RIGHT_ALT_PRESSED  | LEFT_CTRL_PRESSED)
+
+
+/* When uChar.AsciiChar is 0, then we need to look at wVirtualKeyCode.
+ * We map function keys to their ANSI terminal equivalents, as produced
+ * by ANSI.SYS, for compatibility with the MS-DOS version of Vim.  Any
+ * ANSI key with a value >= '\300' is nonstandard, but provided anyway
+ * so that the user can have access to all SHIFT-, CTRL-, and ALT-
+ * combinations of function/arrow/etc keys.
+ */
+
+const static struct
+{
+    WORD    wVirtKey;
+    BOOL    fAnsiKey;
+    int	    chAlone;
+    int	    chShift;
+    int	    chCtrl;
+    int	    chAlt;
+} VirtKeyMap[] =
+{
+
+/*    Key	ANSI	alone	shift	ctrl	    alt */
+    { VK_ESCAPE,FALSE,	ESC,	ESC,	ESC,	    ESC,    },
+
+    { VK_F1,	TRUE,	';',	'T',	'^',	    'h', },
+    { VK_F2,	TRUE,	'<',	'U',	'_',	    'i', },
+    { VK_F3,	TRUE,	'=',	'V',	'`',	    'j', },
+    { VK_F4,	TRUE,	'>',	'W',	'a',	    'k', },
+    { VK_F5,	TRUE,	'?',	'X',	'b',	    'l', },
+    { VK_F6,	TRUE,	'@',	'Y',	'c',	    'm', },
+    { VK_F7,	TRUE,	'A',	'Z',	'd',	    'n', },
+    { VK_F8,	TRUE,	'B',	'[',	'e',	    'o', },
+    { VK_F9,	TRUE,	'C',	'\\',	'f',	    'p', },
+    { VK_F10,	TRUE,	'D',	']',	'g',	    'q', },
+    { VK_F11,	TRUE,	'\205',	'\207',	'\211',	    '\213', },
+    { VK_F12,	TRUE,	'\206',	'\210',	'\212',	    '\214', },
+
+    { VK_HOME,	TRUE,	'G',	'\302',	'w',	    '\303', },
+    { VK_UP,	TRUE,	'H',	'\304',	'\305',	    '\306', },
+    { VK_PRIOR,	TRUE,	'I',	'\307',	'\204',	    '\310', }, /*PgUp*/
+    { VK_LEFT,	TRUE,	'K',	'\311',	's',	    '\312', },
+    { VK_RIGHT,	TRUE,	'M',	'\313',	't',	    '\314', },
+    { VK_END,	TRUE,	'O',	'\315',	'u',	    '\316', },
+    { VK_DOWN,	TRUE,	'P',	'\317',	'\320',	    '\321', },
+    { VK_NEXT,	TRUE,	'Q',	'\322',	'v',	    '\323', }, /*PgDn*/
+    { VK_INSERT,TRUE,	'R',	'\324',	'\325',	    '\326', },
+    { VK_DELETE,TRUE,	'S',	'\327',	'\330',	    '\331', },
+
+    { VK_SNAPSHOT,TRUE,	0,	0,	0,	    'r', }, /*PrtScrn*/
+
+#if 0
+    /* Most people don't have F13-F20, but what the hell... */
+    { VK_F13,	TRUE,	'\332',	'\333',	'\334',	    '\335', },
+    { VK_F14,	TRUE,	'\336',	'\337',	'\340',	    '\341', },
+    { VK_F15,	TRUE,	'\342',	'\343',	'\344',	    '\345', },
+    { VK_F16,	TRUE,	'\346',	'\347',	'\350',	    '\351', },
+    { VK_F17,	TRUE,	'\352',	'\353',	'\354',	    '\355', },
+    { VK_F18,	TRUE,	'\356',	'\357',	'\360',	    '\361', },
+    { VK_F19,	TRUE,	'\362',	'\363',	'\364',	    '\365', },
+    { VK_F20,	TRUE,	'\366',	'\367',	'\370',	    '\371', },
+#endif
+    { VK_ADD,	TRUE,   'N',    'N',    'N',	'N',	}, /* keyp '+' */
+    { VK_SUBTRACT, TRUE,'J',	'J',    'J',	'J',	}, /* keyp '-' */
+ /* { VK_DIVIDE,   TRUE,'N',	'N',    'N',	'N',	},    keyp '/' */
+    { VK_MULTIPLY, TRUE,'7',	'7',    '7',	'7',	}, /* keyp '*' */
+
+    { VK_NUMPAD0,TRUE,  '\332',	'\333',	'\334',	    '\335', },
+    { VK_NUMPAD1,TRUE,  '\336',	'\337',	'\340',	    '\341', },
+    { VK_NUMPAD2,TRUE,  '\342',	'\343',	'\344',	    '\345', },
+    { VK_NUMPAD3,TRUE,  '\346',	'\347',	'\350',	    '\351', },
+    { VK_NUMPAD4,TRUE,  '\352',	'\353',	'\354',	    '\355', },
+    { VK_NUMPAD5,TRUE,  '\356',	'\357',	'\360',	    '\361', },
+    { VK_NUMPAD6,TRUE,  '\362',	'\363',	'\364',	    '\365', },
+    { VK_NUMPAD7,TRUE,  '\366',	'\367',	'\370',	    '\371', },
+    { VK_NUMPAD8,TRUE,  '\372',	'\373',	'\374',	    '\375', },
+    /* Sorry, out of number space! <negri>*/
+    { VK_NUMPAD9,TRUE,  '\376',	'\377',	'\377',	    '\367', },
+
+};
+
+
+#ifdef _MSC_VER
+// The ToAscii bug destroys several registers.	Need to turn off optimization
+// or the GetConsoleKeyboardLayoutName hack will fail in non-debug versions
+# pragma optimize("", off)
+#endif
+
+#if defined(__GNUC__) && !defined(__MINGW32__)  && !defined(__CYGWIN__)
+# define AChar AsciiChar
+#else
+# define AChar uChar.AsciiChar
+#endif
+
+/* The return code indicates key code size. */
+    static int
+#ifdef __BORLANDC__
+    __stdcall
+#endif
+win32_kbd_patch_key(
+    KEY_EVENT_RECORD* pker)
+{
+    UINT uMods = pker->dwControlKeyState;
+    static int s_iIsDead = 0;
+    static WORD awAnsiCode[2];
+    static BYTE abKeystate[256];
+
+
+    if (s_iIsDead == 2)
+    {
+	pker->AChar = (CHAR) awAnsiCode[1];
+	s_iIsDead = 0;
+	return 1;
+    }
+
+    if (pker->AChar != 0)
+	return 1;
+
+    memset(abKeystate, 0, sizeof (abKeystate));
+
+    // Should only be non-NULL on NT 4.0
+    if (s_pfnGetConsoleKeyboardLayoutName != NULL)
+    {
+	CHAR szKLID[KL_NAMELENGTH];
+
+	if ((*s_pfnGetConsoleKeyboardLayoutName)(szKLID))
+	    (void)LoadKeyboardLayout(szKLID, KLF_ACTIVATE);
+    }
+
+    /* Clear any pending dead keys */
+    ToAscii(VK_SPACE, MapVirtualKey(VK_SPACE, 0), abKeystate, awAnsiCode, 0);
+
+    if (uMods & SHIFT_PRESSED)
+	abKeystate[VK_SHIFT] = 0x80;
+    if (uMods & CAPSLOCK_ON)
+	abKeystate[VK_CAPITAL] = 1;
+
+    if ((uMods & ALT_GR) == ALT_GR)
+    {
+	abKeystate[VK_CONTROL] = abKeystate[VK_LCONTROL] =
+	    abKeystate[VK_MENU] = abKeystate[VK_RMENU] = 0x80;
+    }
+
+    s_iIsDead = ToAscii(pker->wVirtualKeyCode, pker->wVirtualScanCode,
+			abKeystate, awAnsiCode, 0);
+
+    if (s_iIsDead > 0)
+	pker->AChar = (CHAR) awAnsiCode[0];
+
+    return s_iIsDead;
+}
+
+#ifdef _MSC_VER
+/* MUST switch optimization on again here, otherwise a call to
+ * decode_key_event() may crash (e.g. when hitting caps-lock) */
+# pragma optimize("", on)
+
+# if (_MSC_VER < 1100)
+/* MUST turn off global optimisation for this next function, or
+ * pressing ctrl-minus in insert mode crashes Vim when built with
+ * VC4.1. -- negri. */
+#  pragma optimize("g", off)
+# endif
+#endif
+
+static BOOL g_fJustGotFocus = FALSE;
+
+/*
+ * Decode a KEY_EVENT into one or two keystrokes
+ */
+    static BOOL
+decode_key_event(
+    KEY_EVENT_RECORD	*pker,
+    char_u		*pch,
+    char_u		*pch2,
+    int			*pmodifiers,
+    BOOL		fDoPost)
+{
+    int i;
+    const int nModifs = pker->dwControlKeyState & (SHIFT | ALT | CTRL);
+
+    *pch = *pch2 = NUL;
+    g_fJustGotFocus = FALSE;
+
+    /* ignore key up events */
+    if (!pker->bKeyDown)
+	return FALSE;
+
+    /* ignore some keystrokes */
+    switch (pker->wVirtualKeyCode)
+    {
+    /* modifiers */
+    case VK_SHIFT:
+    case VK_CONTROL:
+    case VK_MENU:   /* Alt key */
+	return FALSE;
+
+    default:
+	break;
+    }
+
+    /* special cases */
+    if ((nModifs & CTRL) != 0 && (nModifs & ~CTRL) == 0 && pker->AChar == NUL)
+    {
+	/* Ctrl-6 is Ctrl-^ */
+	if (pker->wVirtualKeyCode == '6')
+	{
+	    *pch = Ctrl_HAT;
+	    return TRUE;
+	}
+	/* Ctrl-2 is Ctrl-@ */
+	else if (pker->wVirtualKeyCode == '2')
+	{
+	    *pch = NUL;
+	    return TRUE;
+	}
+	/* Ctrl-- is Ctrl-_ */
+	else if (pker->wVirtualKeyCode == 0xBD)
+	{
+	    *pch = Ctrl__;
+	    return TRUE;
+	}
+    }
+
+    /* Shift-TAB */
+    if (pker->wVirtualKeyCode == VK_TAB && (nModifs & SHIFT_PRESSED))
+    {
+	*pch = K_NUL;
+	*pch2 = '\017';
+	return TRUE;
+    }
+
+    for (i = sizeof(VirtKeyMap) / sizeof(VirtKeyMap[0]);  --i >= 0;  )
+    {
+	if (VirtKeyMap[i].wVirtKey == pker->wVirtualKeyCode)
+	{
+	    if (nModifs == 0)
+		*pch = VirtKeyMap[i].chAlone;
+	    else if ((nModifs & SHIFT) != 0 && (nModifs & ~SHIFT) == 0)
+		*pch = VirtKeyMap[i].chShift;
+	    else if ((nModifs & CTRL) != 0 && (nModifs & ~CTRL) == 0)
+		*pch = VirtKeyMap[i].chCtrl;
+	    else if ((nModifs & ALT) != 0 && (nModifs & ~ALT) == 0)
+		*pch = VirtKeyMap[i].chAlt;
+
+	    if (*pch != 0)
+	    {
+		if (VirtKeyMap[i].fAnsiKey)
+		{
+		    *pch2 = *pch;
+		    *pch = K_NUL;
+		}
+
+		return TRUE;
+	    }
+	}
+    }
+
+    i = win32_kbd_patch_key(pker);
+
+    if (i < 0)
+	*pch = NUL;
+    else
+    {
+	*pch = (i > 0) ? pker->AChar : NUL;
+
+	if (pmodifiers != NULL)
+	{
+	    /* Pass on the ALT key as a modifier, but only when not combined
+	     * with CTRL (which is ALTGR). */
+	    if ((nModifs & ALT) != 0 && (nModifs & CTRL) == 0)
+		*pmodifiers |= MOD_MASK_ALT;
+
+	    /* Pass on SHIFT only for special keys, because we don't know when
+	     * it's already included with the character. */
+	    if ((nModifs & SHIFT) != 0 && *pch <= 0x20)
+		*pmodifiers |= MOD_MASK_SHIFT;
+
+	    /* Pass on CTRL only for non-special keys, because we don't know
+	     * when it's already included with the character.  And not when
+	     * combined with ALT (which is ALTGR). */
+	    if ((nModifs & CTRL) != 0 && (nModifs & ALT) == 0
+					       && *pch >= 0x20 && *pch < 0x80)
+		*pmodifiers |= MOD_MASK_CTRL;
+	}
+    }
+
+    return (*pch != NUL);
+}
+
+#ifdef _MSC_VER
+# pragma optimize("", on)
+#endif
+
+#endif /* FEAT_GUI_W32 */
+
+
+#ifdef FEAT_MOUSE
+
+/*
+ * For the GUI the mouse handling is in gui_w32.c.
+ */
+# ifdef FEAT_GUI_W32
+    void
+mch_setmouse(
+    int on)
+{
+}
+# else
+static int g_fMouseAvail = FALSE;   /* mouse present */
+static int g_fMouseActive = FALSE;  /* mouse enabled */
+static int g_nMouseClick = -1;	    /* mouse status */
+static int g_xMouse;		    /* mouse x coordinate */
+static int g_yMouse;		    /* mouse y coordinate */
+
+/*
+ * Enable or disable mouse input
+ */
+    void
+mch_setmouse(
+    int on)
+{
+    DWORD cmodein;
+
+    if (!g_fMouseAvail)
+	return;
+
+    g_fMouseActive = on;
+    GetConsoleMode(g_hConIn, &cmodein);
+
+    if (g_fMouseActive)
+	cmodein |= ENABLE_MOUSE_INPUT;
+    else
+	cmodein &= ~ENABLE_MOUSE_INPUT;
+
+    SetConsoleMode(g_hConIn, cmodein);
+}
+
+
+/*
+ * Decode a MOUSE_EVENT.  If it's a valid event, return MOUSE_LEFT,
+ * MOUSE_MIDDLE, or MOUSE_RIGHT for a click; MOUSE_DRAG for a mouse
+ * move with a button held down; and MOUSE_RELEASE after a MOUSE_DRAG
+ * or a MOUSE_LEFT, _MIDDLE, or _RIGHT.  We encode the button type,
+ * the number of clicks, and the Shift/Ctrl/Alt modifiers in g_nMouseClick,
+ * and we return the mouse position in g_xMouse and g_yMouse.
+ *
+ * Every MOUSE_LEFT, _MIDDLE, or _RIGHT will be followed by zero or more
+ * MOUSE_DRAGs and one MOUSE_RELEASE.  MOUSE_RELEASE will be followed only
+ * by MOUSE_LEFT, _MIDDLE, or _RIGHT.
+ *
+ * For multiple clicks, we send, say, MOUSE_LEFT/1 click, MOUSE_RELEASE,
+ * MOUSE_LEFT/2 clicks, MOUSE_RELEASE, MOUSE_LEFT/3 clicks, MOUSE_RELEASE, ....
+ *
+ * Windows will send us MOUSE_MOVED notifications whenever the mouse
+ * moves, even if it stays within the same character cell.  We ignore
+ * all MOUSE_MOVED messages if the position hasn't really changed, and
+ * we ignore all MOUSE_MOVED messages where no button is held down (i.e.,
+ * we're only interested in MOUSE_DRAG).
+ *
+ * All of this is complicated by the code that fakes MOUSE_MIDDLE on
+ * 2-button mouses by pressing the left & right buttons simultaneously.
+ * In practice, it's almost impossible to click both at the same time,
+ * so we need to delay a little.  Also, we tend not to get MOUSE_RELEASE
+ * in such cases, if the user is clicking quickly.
+ */
+    static BOOL
+decode_mouse_event(
+    MOUSE_EVENT_RECORD* pmer)
+{
+    static int s_nOldButton = -1;
+    static int s_nOldMouseClick = -1;
+    static int s_xOldMouse = -1;
+    static int s_yOldMouse = -1;
+    static linenr_T s_old_topline = 0;
+#ifdef FEAT_DIFF
+    static int s_old_topfill = 0;
+#endif
+    static int s_cClicks = 1;
+    static BOOL s_fReleased = TRUE;
+    static DWORD s_dwLastClickTime = 0;
+    static BOOL s_fNextIsMiddle = FALSE;
+
+    static DWORD cButtons = 0;	/* number of buttons supported */
+
+    const DWORD LEFT = FROM_LEFT_1ST_BUTTON_PRESSED;
+    const DWORD MIDDLE = FROM_LEFT_2ND_BUTTON_PRESSED;
+    const DWORD RIGHT = RIGHTMOST_BUTTON_PRESSED;
+    const DWORD LEFT_RIGHT = LEFT | RIGHT;
+
+    int nButton;
+
+    if (cButtons == 0 && !GetNumberOfConsoleMouseButtons(&cButtons))
+	cButtons = 2;
+
+    if (!g_fMouseAvail || !g_fMouseActive)
+    {
+	g_nMouseClick = -1;
+	return FALSE;
+    }
+
+    /* get a spurious MOUSE_EVENT immediately after receiving focus; ignore */
+    if (g_fJustGotFocus)
+    {
+	g_fJustGotFocus = FALSE;
+	return FALSE;
+    }
+
+    /* unprocessed mouse click? */
+    if (g_nMouseClick != -1)
+	return TRUE;
+
+    nButton = -1;
+    g_xMouse = pmer->dwMousePosition.X;
+    g_yMouse = pmer->dwMousePosition.Y;
+
+    if (pmer->dwEventFlags == MOUSE_MOVED)
+    {
+	/* ignore MOUSE_MOVED events if (x, y) hasn't changed.	(We get these
+	 * events even when the mouse moves only within a char cell.) */
+	if (s_xOldMouse == g_xMouse && s_yOldMouse == g_yMouse)
+	    return FALSE;
+    }
+
+    /* If no buttons are pressed... */
+    if ((pmer->dwButtonState & ((1 << cButtons) - 1)) == 0)
+    {
+	/* If the last thing returned was MOUSE_RELEASE, ignore this */
+	if (s_fReleased)
+	    return FALSE;
+
+	nButton = MOUSE_RELEASE;
+	s_fReleased = TRUE;
+    }
+    else    /* one or more buttons pressed */
+    {
+	/* on a 2-button mouse, hold down left and right buttons
+	 * simultaneously to get MIDDLE. */
+
+	if (cButtons == 2 && s_nOldButton != MOUSE_DRAG)
+	{
+	    DWORD dwLR = (pmer->dwButtonState & LEFT_RIGHT);
+
+	    /* if either left or right button only is pressed, see if the
+	     * the next mouse event has both of them pressed */
+	    if (dwLR == LEFT || dwLR == RIGHT)
+	    {
+		for (;;)
+		{
+		    /* wait a short time for next input event */
+		    if (WaitForSingleObject(g_hConIn, p_mouset / 3)
+							     != WAIT_OBJECT_0)
+			break;
+		    else
+		    {
+			DWORD cRecords = 0;
+			INPUT_RECORD ir;
+			MOUSE_EVENT_RECORD* pmer2 = &ir.Event.MouseEvent;
+
+			PeekConsoleInput(g_hConIn, &ir, 1, &cRecords);
+
+			if (cRecords == 0 || ir.EventType != MOUSE_EVENT
+				|| !(pmer2->dwButtonState & LEFT_RIGHT))
+			    break;
+			else
+			{
+			    if (pmer2->dwEventFlags != MOUSE_MOVED)
+			    {
+				ReadConsoleInput(g_hConIn, &ir, 1, &cRecords);
+
+				return decode_mouse_event(pmer2);
+			    }
+			    else if (s_xOldMouse == pmer2->dwMousePosition.X &&
+				     s_yOldMouse == pmer2->dwMousePosition.Y)
+			    {
+				/* throw away spurious mouse move */
+				ReadConsoleInput(g_hConIn, &ir, 1, &cRecords);
+
+				/* are there any more mouse events in queue? */
+				PeekConsoleInput(g_hConIn, &ir, 1, &cRecords);
+
+				if (cRecords==0 || ir.EventType != MOUSE_EVENT)
+				    break;
+			    }
+			    else
+				break;
+			}
+		    }
+		}
+	    }
+	}
+
+	if (s_fNextIsMiddle)
+	{
+	    nButton = (pmer->dwEventFlags == MOUSE_MOVED)
+		? MOUSE_DRAG : MOUSE_MIDDLE;
+	    s_fNextIsMiddle = FALSE;
+	}
+	else if (cButtons == 2	&&
+	    ((pmer->dwButtonState & LEFT_RIGHT) == LEFT_RIGHT))
+	{
+	    nButton = MOUSE_MIDDLE;
+
+	    if (! s_fReleased && pmer->dwEventFlags != MOUSE_MOVED)
+	    {
+		s_fNextIsMiddle = TRUE;
+		nButton = MOUSE_RELEASE;
+	    }
+	}
+	else if ((pmer->dwButtonState & LEFT) == LEFT)
+	    nButton = MOUSE_LEFT;
+	else if ((pmer->dwButtonState & MIDDLE) == MIDDLE)
+	    nButton = MOUSE_MIDDLE;
+	else if ((pmer->dwButtonState & RIGHT) == RIGHT)
+	    nButton = MOUSE_RIGHT;
+
+	if (! s_fReleased && ! s_fNextIsMiddle
+		&& nButton != s_nOldButton && s_nOldButton != MOUSE_DRAG)
+	    return FALSE;
+
+	s_fReleased = s_fNextIsMiddle;
+    }
+
+    if (pmer->dwEventFlags == 0 || pmer->dwEventFlags == DOUBLE_CLICK)
+    {
+	/* button pressed or released, without mouse moving */
+	if (nButton != -1 && nButton != MOUSE_RELEASE)
+	{
+	    DWORD dwCurrentTime = GetTickCount();
+
+	    if (s_xOldMouse != g_xMouse
+		    || s_yOldMouse != g_yMouse
+		    || s_nOldButton != nButton
+		    || s_old_topline != curwin->w_topline
+#ifdef FEAT_DIFF
+		    || s_old_topfill != curwin->w_topfill
+#endif
+		    || (int)(dwCurrentTime - s_dwLastClickTime) > p_mouset)
+	    {
+		s_cClicks = 1;
+	    }
+	    else if (++s_cClicks > 4)
+	    {
+		s_cClicks = 1;
+	    }
+
+	    s_dwLastClickTime = dwCurrentTime;
+	}
+    }
+    else if (pmer->dwEventFlags == MOUSE_MOVED)
+    {
+	if (nButton != -1 && nButton != MOUSE_RELEASE)
+	    nButton = MOUSE_DRAG;
+
+	s_cClicks = 1;
+    }
+
+    if (nButton == -1)
+	return FALSE;
+
+    if (nButton != MOUSE_RELEASE)
+	s_nOldButton = nButton;
+
+    g_nMouseClick = nButton;
+
+    if (pmer->dwControlKeyState & SHIFT_PRESSED)
+	g_nMouseClick |= MOUSE_SHIFT;
+    if (pmer->dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+	g_nMouseClick |= MOUSE_CTRL;
+    if (pmer->dwControlKeyState & (RIGHT_ALT_PRESSED  | LEFT_ALT_PRESSED))
+	g_nMouseClick |= MOUSE_ALT;
+
+    if (nButton != MOUSE_DRAG && nButton != MOUSE_RELEASE)
+	SET_NUM_MOUSE_CLICKS(g_nMouseClick, s_cClicks);
+
+    /* only pass on interesting (i.e., different) mouse events */
+    if (s_xOldMouse == g_xMouse
+	    && s_yOldMouse == g_yMouse
+	    && s_nOldMouseClick == g_nMouseClick)
+    {
+	g_nMouseClick = -1;
+	return FALSE;
+    }
+
+    s_xOldMouse = g_xMouse;
+    s_yOldMouse = g_yMouse;
+    s_old_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+    s_old_topfill = curwin->w_topfill;
+#endif
+    s_nOldMouseClick = g_nMouseClick;
+
+    return TRUE;
+}
+
+# endif /* FEAT_GUI_W32 */
+#endif /* FEAT_MOUSE */
+
+
+#ifdef MCH_CURSOR_SHAPE
+/*
+ * Set the shape of the cursor.
+ * 'thickness' can be from 1 (thin) to 99 (block)
+ */
+    static void
+mch_set_cursor_shape(int thickness)
+{
+    CONSOLE_CURSOR_INFO ConsoleCursorInfo;
+    ConsoleCursorInfo.dwSize = thickness;
+    ConsoleCursorInfo.bVisible = s_cursor_visible;
+
+    SetConsoleCursorInfo(g_hConOut, &ConsoleCursorInfo);
+    if (s_cursor_visible)
+	SetConsoleCursorPosition(g_hConOut, g_coord);
+}
+
+    void
+mch_update_cursor(void)
+{
+    int		idx;
+    int		thickness;
+
+    /*
+     * How the cursor is drawn depends on the current mode.
+     */
+    idx = get_shape_idx(FALSE);
+
+    if (shape_table[idx].shape == SHAPE_BLOCK)
+	thickness = 99;	/* 100 doesn't work on W95 */
+    else
+	thickness = shape_table[idx].percentage;
+    mch_set_cursor_shape(thickness);
+}
+#endif
+
+#ifndef FEAT_GUI_W32	    /* this isn't used for the GUI */
+/*
+ * Handle FOCUS_EVENT.
+ */
+    static void
+handle_focus_event(INPUT_RECORD ir)
+{
+    g_fJustGotFocus = ir.Event.FocusEvent.bSetFocus;
+    ui_focus_change((int)g_fJustGotFocus);
+}
+
+/*
+ * Wait until console input from keyboard or mouse is available,
+ * or the time is up.
+ * Return TRUE if something is available FALSE if not.
+ */
+    static int
+WaitForChar(long msec)
+{
+    DWORD	    dwNow = 0, dwEndTime = 0;
+    INPUT_RECORD    ir;
+    DWORD	    cRecords;
+    char_u	    ch, ch2;
+
+    if (msec > 0)
+	/* Wait until the specified time has elapsed. */
+	dwEndTime = GetTickCount() + msec;
+    else if (msec < 0)
+	/* Wait forever. */
+	dwEndTime = INFINITE;
+
+    /* We need to loop until the end of the time period, because
+     * we might get multiple unusable mouse events in that time.
+     */
+    for (;;)
+    {
+#ifdef FEAT_CLIENTSERVER
+	serverProcessPendingMessages();
+#endif
+	if (0
+#ifdef FEAT_MOUSE
+		|| g_nMouseClick != -1
+#endif
+#ifdef FEAT_CLIENTSERVER
+		|| input_available()
+#endif
+	   )
+	    return TRUE;
+
+	if (msec > 0)
+	{
+	    /* If the specified wait time has passed, return. */
+	    dwNow = GetTickCount();
+	    if (dwNow >= dwEndTime)
+		break;
+	}
+	if (msec != 0)
+	{
+#ifdef FEAT_CLIENTSERVER
+	    /* Wait for either an event on the console input or a message in
+	     * the client-server window. */
+	    if (MsgWaitForMultipleObjects(1, &g_hConIn, FALSE,
+			  dwEndTime - dwNow, QS_SENDMESSAGE) != WAIT_OBJECT_0)
+#else
+	    if (WaitForSingleObject(g_hConIn, dwEndTime - dwNow)
+							     != WAIT_OBJECT_0)
+#endif
+		    continue;
+	}
+
+	cRecords = 0;
+	PeekConsoleInput(g_hConIn, &ir, 1, &cRecords);
+
+#ifdef FEAT_MBYTE_IME
+	if (State & CMDLINE && msg_row == Rows - 1)
+	{
+	    CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+	    if (GetConsoleScreenBufferInfo(g_hConOut, &csbi))
+	    {
+		if (csbi.dwCursorPosition.Y != msg_row)
+		{
+		    /* The screen is now messed up, must redraw the
+		     * command line and later all the windows. */
+		    redraw_all_later(CLEAR);
+		    cmdline_row -= (msg_row - csbi.dwCursorPosition.Y);
+		    redrawcmd();
+		}
+	    }
+	}
+#endif
+
+	if (cRecords > 0)
+	{
+	    if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown)
+	    {
+#ifdef FEAT_MBYTE_IME
+		/* Windows IME sends two '\n's with only one 'ENTER'.  First:
+		 * wVirtualKeyCode == 13. second: wVirtualKeyCode == 0 */
+		if (ir.Event.KeyEvent.uChar.UnicodeChar == 0
+			&& ir.Event.KeyEvent.wVirtualKeyCode == 13)
+		{
+		    ReadConsoleInput(g_hConIn, &ir, 1, &cRecords);
+		    continue;
+		}
+#endif
+		if (decode_key_event(&ir.Event.KeyEvent, &ch, &ch2,
+								 NULL, FALSE))
+		    return TRUE;
+	    }
+
+	    ReadConsoleInput(g_hConIn, &ir, 1, &cRecords);
+
+	    if (ir.EventType == FOCUS_EVENT)
+		handle_focus_event(ir);
+	    else if (ir.EventType == WINDOW_BUFFER_SIZE_EVENT)
+		shell_resized();
+#ifdef FEAT_MOUSE
+	    else if (ir.EventType == MOUSE_EVENT
+		    && decode_mouse_event(&ir.Event.MouseEvent))
+		return TRUE;
+#endif
+	}
+	else if (msec == 0)
+	    break;
+    }
+
+#ifdef FEAT_CLIENTSERVER
+    /* Something might have been received while we were waiting. */
+    if (input_available())
+	return TRUE;
+#endif
+    return FALSE;
+}
+
+#ifndef FEAT_GUI_MSWIN
+/*
+ * return non-zero if a character is available
+ */
+    int
+mch_char_avail()
+{
+    return WaitForChar(0L);
+}
+#endif
+
+/*
+ * Create the console input.  Used when reading stdin doesn't work.
+ */
+    static void
+create_conin(void)
+{
+    g_hConIn =	CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE,
+			FILE_SHARE_READ|FILE_SHARE_WRITE,
+			(LPSECURITY_ATTRIBUTES) NULL,
+			OPEN_EXISTING, (DWORD)NULL, (HANDLE)NULL);
+    did_create_conin = TRUE;
+}
+
+/*
+ * Get a keystroke or a mouse event
+ */
+    static char_u
+tgetch(int *pmodifiers, char_u *pch2)
+{
+    char_u ch;
+
+    for (;;)
+    {
+	INPUT_RECORD ir;
+	DWORD cRecords = 0;
+
+#ifdef FEAT_CLIENTSERVER
+	(void)WaitForChar(-1L);
+	if (input_available())
+	    return 0;
+# ifdef FEAT_MOUSE
+	if (g_nMouseClick != -1)
+	    return 0;
+# endif
+#endif
+	if (ReadConsoleInput(g_hConIn, &ir, 1, &cRecords) == 0)
+	{
+	    if (did_create_conin)
+		read_error_exit();
+	    create_conin();
+	    continue;
+	}
+
+	if (ir.EventType == KEY_EVENT)
+	{
+	    if (decode_key_event(&ir.Event.KeyEvent, &ch, pch2,
+							    pmodifiers, TRUE))
+		return ch;
+	}
+	else if (ir.EventType == FOCUS_EVENT)
+	    handle_focus_event(ir);
+	else if (ir.EventType == WINDOW_BUFFER_SIZE_EVENT)
+	    shell_resized();
+#ifdef FEAT_MOUSE
+	else if (ir.EventType == MOUSE_EVENT)
+	{
+	    if (decode_mouse_event(&ir.Event.MouseEvent))
+		return 0;
+	}
+#endif
+    }
+}
+#endif /* !FEAT_GUI_W32 */
+
+
+/*
+ * mch_inchar(): low-level input funcion.
+ * Get one or more characters from the keyboard or the mouse.
+ * If time == 0, do not wait for characters.
+ * If time == n, wait a short time for characters.
+ * If time == -1, wait forever for characters.
+ * Returns the number of characters read into buf.
+ */
+    int
+mch_inchar(
+    char_u	*buf,
+    int		maxlen,
+    long	time,
+    int		tb_change_cnt)
+{
+#ifndef FEAT_GUI_W32	    /* this isn't used for the GUI */
+
+    int		len;
+    int		c;
+#ifdef FEAT_AUTOCMD
+    static int	once_already = 0;
+#endif
+#define TYPEAHEADLEN 20
+    static char_u   typeahead[TYPEAHEADLEN];	/* previously typed bytes. */
+    static int	    typeaheadlen = 0;
+
+    /* First use any typeahead that was kept because "buf" was too small. */
+    if (typeaheadlen > 0)
+	goto theend;
+
+#ifdef FEAT_SNIFF
+    if (want_sniff_request)
+    {
+	if (sniff_request_waiting)
+	{
+	    /* return K_SNIFF */
+	    typeahead[typeaheadlen++] = CSI;
+	    typeahead[typeaheadlen++] = (char_u)KS_EXTRA;
+	    typeahead[typeaheadlen++] = (char_u)KE_SNIFF;
+	    sniff_request_waiting = 0;
+	    want_sniff_request = 0;
+	    goto theend;
+	}
+	else if (time < 0 || time > 250)
+	{
+	    /* don't wait too long, a request might be pending */
+	    time = 250;
+	}
+    }
+#endif
+
+    if (time >= 0)
+    {
+	if (!WaitForChar(time))     /* no character available */
+	{
+#ifdef FEAT_AUTOCMD
+	    once_already = 0;
+#endif
+	    return 0;
+	}
+    }
+    else    /* time == -1, wait forever */
+    {
+	mch_set_winsize_now();	/* Allow winsize changes from now on */
+
+#ifdef FEAT_AUTOCMD
+	/* If there is no character available within 2 seconds (default),
+	 * write the autoscript file to disk */
+	if (once_already == 2)
+	    updatescript(0);
+	else if (once_already == 1)
+	{
+	    setcursor();
+	    once_already = 2;
+	    return 0;
+	}
+	else
+#endif
+	    if (!WaitForChar(p_ut))
+	{
+#ifdef FEAT_AUTOCMD
+	    if (has_cursorhold() && get_real_state() == NORMAL_BUSY)
+	    {
+		apply_autocmds(EVENT_CURSORHOLD, NULL, NULL, FALSE, curbuf);
+		update_screen(VALID);
+		once_already = 1;
+		return 0;
+	    }
+#endif
+	    updatescript(0);
+	}
+    }
+
+    /*
+     * Try to read as many characters as there are, until the buffer is full.
+     */
+
+    /* we will get at least one key. Get more if they are available. */
+    g_fCBrkPressed = FALSE;
+
+#ifdef MCH_WRITE_DUMP
+    if (fdDump)
+	fputc('[', fdDump);
+#endif
+
+    /* Keep looping until there is something in the typeahead buffer and more
+     * to get and still room in the buffer (up to two bytes for a char and
+     * three bytes for a modifier). */
+    while ((typeaheadlen == 0 || WaitForChar(0L))
+					  && typeaheadlen + 5 <= TYPEAHEADLEN)
+    {
+	if (typebuf_changed(tb_change_cnt))
+	{
+	    /* "buf" may be invalid now if a client put something in the
+	     * typeahead buffer and "buf" is in the typeahead buffer. */
+	    typeaheadlen = 0;
+	    break;
+	}
+#ifdef FEAT_MOUSE
+	if (g_nMouseClick != -1)
+	{
+# ifdef MCH_WRITE_DUMP
+	    if (fdDump)
+		fprintf(fdDump, "{%02x @ %d, %d}",
+			g_nMouseClick, g_xMouse, g_yMouse);
+# endif
+	    typeahead[typeaheadlen++] = ESC + 128;
+	    typeahead[typeaheadlen++] = 'M';
+	    typeahead[typeaheadlen++] = g_nMouseClick;
+	    typeahead[typeaheadlen++] = g_xMouse + '!';
+	    typeahead[typeaheadlen++] = g_yMouse + '!';
+	    g_nMouseClick = -1;
+	}
+	else
+#endif
+	{
+	    char_u	ch2 = NUL;
+	    int		modifiers = 0;
+
+	    c = tgetch(&modifiers, &ch2);
+
+	    if (typebuf_changed(tb_change_cnt))
+	    {
+		/* "buf" may be invalid now if a client put something in the
+		 * typeahead buffer and "buf" is in the typeahead buffer. */
+		typeaheadlen = 0;
+		break;
+	    }
+
+	    if (c == Ctrl_C && ctrl_c_interrupts)
+	    {
+#if defined(FEAT_CLIENTSERVER)
+		trash_input_buf();
+#endif
+		got_int = TRUE;
+	    }
+
+#ifdef FEAT_MOUSE
+	    if (g_nMouseClick == -1)
+#endif
+	    {
+		int	n = 1;
+
+		/* A key may have one or two bytes. */
+		typeahead[typeaheadlen] = c;
+		if (ch2 != NUL)
+		{
+		    typeahead[typeaheadlen + 1] = ch2;
+		    ++n;
+		}
+#ifdef FEAT_MBYTE
+		/* Only convert normal characters, not special keys.  Need to
+		 * convert before applying ALT, otherwise mapping <M-x> breaks
+		 * when 'tenc' is set. */
+		if (input_conv.vc_type != CONV_NONE
+						&& (ch2 == NUL || c != K_NUL))
+		    n = convert_input(typeahead + typeaheadlen, n,
+						 TYPEAHEADLEN - typeaheadlen);
+#endif
+
+		/* Use the ALT key to set the 8th bit of the character
+		 * when it's one byte, the 8th bit isn't set yet and not
+		 * using a double-byte encoding (would become a lead
+		 * byte). */
+		if ((modifiers & MOD_MASK_ALT)
+			&& n == 1
+			&& (typeahead[typeaheadlen] & 0x80) == 0
+#ifdef FEAT_MBYTE
+			&& !enc_dbcs
+#endif
+		   )
+		{
+		    typeahead[typeaheadlen] |= 0x80;
+		    modifiers &= ~MOD_MASK_ALT;
+		}
+
+		if (modifiers != 0)
+		{
+		    /* Prepend modifiers to the character. */
+		    mch_memmove(typeahead + typeaheadlen + 3,
+						 typeahead + typeaheadlen, n);
+		    typeahead[typeaheadlen++] = K_SPECIAL;
+		    typeahead[typeaheadlen++] = (char_u)KS_MODIFIER;
+		    typeahead[typeaheadlen++] =  modifiers;
+		}
+
+		typeaheadlen += n;
+
+#ifdef MCH_WRITE_DUMP
+		if (fdDump)
+		    fputc(c, fdDump);
+#endif
+	    }
+	}
+    }
+
+#ifdef MCH_WRITE_DUMP
+    if (fdDump)
+    {
+	fputs("]\n", fdDump);
+	fflush(fdDump);
+    }
+#endif
+
+#ifdef FEAT_AUTOCMD
+    once_already = 0;
+#endif
+
+theend:
+    /* Move typeahead to "buf", as much as fits. */
+    len = 0;
+    while (len < maxlen && typeaheadlen > 0)
+    {
+	buf[len++] = typeahead[0];
+	mch_memmove(typeahead, typeahead + 1, --typeaheadlen);
+    }
+    return len;
+
+#else /* FEAT_GUI_W32 */
+    return 0;
+#endif /* FEAT_GUI_W32 */
+}
+
+#ifndef __MINGW32__
+# include <shellapi.h>	/* required for FindExecutable() */
+#endif
+
+    static int
+executable_exists(char *name)
+{
+    char location[2 * _MAX_PATH + 2];
+    char widename[2 * _MAX_PATH];
+
+    /* There appears to be a bug in FindExecutableA() on Windows NT.
+     * Use FindExecutableW() instead... */
+    if (g_PlatformId == VER_PLATFORM_WIN32_NT)
+    {
+	MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)name, -1,
+						 (LPWSTR)widename, _MAX_PATH);
+	if (FindExecutableW((LPCWSTR)widename, (LPCWSTR)"",
+					    (LPWSTR)location) > (HINSTANCE)32)
+	    return TRUE;
+    }
+    else
+    {
+	if (FindExecutableA((LPCTSTR)name, (LPCTSTR)"",
+					    (LPTSTR)location) > (HINSTANCE)32)
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+#ifdef FEAT_GUI_W32
+
+/*
+ * GUI version of mch_init().
+ */
+    void
+mch_init()
+{
+#ifndef __MINGW32__
+    extern int _fmode;
+#endif
+
+    /* Let critical errors result in a failure, not in a dialog box.  Required
+     * for the timestamp test to work on removed floppies. */
+    SetErrorMode(SEM_FAILCRITICALERRORS);
+
+    _fmode = O_BINARY;		/* we do our own CR-LF translation */
+
+    /* Specify window size.  Is there a place to get the default from? */
+    Rows = 25;
+    Columns = 80;
+
+    /* Look for 'vimrun' */
+    if (!gui_is_win32s())
+    {
+	char_u vimrun_location[_MAX_PATH + 4];
+
+	/* First try in same directory as gvim.exe */
+	STRCPY(vimrun_location, exe_name);
+	STRCPY(gettail(vimrun_location), "vimrun.exe");
+	if (mch_getperm(vimrun_location) >= 0)
+	{
+	    if (*skiptowhite(vimrun_location) != NUL)
+	    {
+		/* Enclose path with white space in double quotes. */
+		mch_memmove(vimrun_location + 1, vimrun_location,
+						 STRLEN(vimrun_location) + 1);
+		*vimrun_location = '"';
+		STRCPY(gettail(vimrun_location), "vimrun\" ");
+	    }
+	    else
+		STRCPY(gettail(vimrun_location), "vimrun ");
+
+	    vimrun_path = (char *)vim_strsave(vimrun_location);
+	    s_dont_use_vimrun = FALSE;
+	}
+	else if (executable_exists("vimrun.exe"))
+	    s_dont_use_vimrun = FALSE;
+
+	/* Don't give the warning for a missing vimrun.exe right now, but only
+	 * when vimrun was supposed to be used.  Don't bother people that do
+	 * not need vimrun.exe. */
+	if (s_dont_use_vimrun)
+	    need_vimrun_warning = TRUE;
+    }
+
+    /*
+     * If "finstr.exe" doesn't exist, use "grep -n" for 'grepprg'.
+     * Otherwise the default "findstr /n" is used.
+     */
+    if (!executable_exists("findstr.exe"))
+	set_option_value((char_u *)"grepprg", 0, (char_u *)"grep -n", 0);
+
+#ifdef FEAT_CLIPBOARD
+    clip_init(TRUE);
+
+    /*
+     * Vim's own clipboard format recognises whether the text is char, line, or
+     * rectangular block.  Only useful for copying between two Vims.
+     * "VimClipboard" was used for previous versions, using the first
+     * character to specify MCHAR, MLINE or MBLOCK.
+     */
+    clip_star.format = RegisterClipboardFormat("VimClipboard2");
+    clip_star.format_raw = RegisterClipboardFormat("VimRawBytes");
+#endif
+}
+
+
+#else /* FEAT_GUI_W32 */
+
+#define SRWIDTH(sr) ((sr).Right - (sr).Left + 1)
+#define SRHEIGHT(sr) ((sr).Bottom - (sr).Top + 1)
+
+/*
+ * ClearConsoleBuffer()
+ * Description:
+ *  Clears the entire contents of the console screen buffer, using the
+ *  specified attribute.
+ * Returns:
+ *  TRUE on success
+ */
+    static BOOL
+ClearConsoleBuffer(WORD wAttribute)
+{
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+    COORD coord;
+    DWORD NumCells, dummy;
+
+    if (!GetConsoleScreenBufferInfo(g_hConOut, &csbi))
+	return FALSE;
+
+    NumCells = csbi.dwSize.X * csbi.dwSize.Y;
+    coord.X = 0;
+    coord.Y = 0;
+    if (!FillConsoleOutputCharacter(g_hConOut, ' ', NumCells,
+	    coord, &dummy))
+    {
+	return FALSE;
+    }
+    if (!FillConsoleOutputAttribute(g_hConOut, wAttribute, NumCells,
+	    coord, &dummy))
+    {
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*
+ * FitConsoleWindow()
+ * Description:
+ *  Checks if the console window will fit within given buffer dimensions.
+ *  Also, if requested, will shrink the window to fit.
+ * Returns:
+ *  TRUE on success
+ */
+    static BOOL
+FitConsoleWindow(
+    COORD dwBufferSize,
+    BOOL WantAdjust)
+{
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+    COORD dwWindowSize;
+    BOOL NeedAdjust = FALSE;
+
+    if (GetConsoleScreenBufferInfo(g_hConOut, &csbi))
+    {
+	/*
+	 * A buffer resize will fail if the current console window does
+	 * not lie completely within that buffer.  To avoid this, we might
+	 * have to move and possibly shrink the window.
+	 */
+	if (csbi.srWindow.Right >= dwBufferSize.X)
+	{
+	    dwWindowSize.X = SRWIDTH(csbi.srWindow);
+	    if (dwWindowSize.X > dwBufferSize.X)
+		dwWindowSize.X = dwBufferSize.X;
+	    csbi.srWindow.Right = dwBufferSize.X - 1;
+	    csbi.srWindow.Left = dwBufferSize.X - dwWindowSize.X;
+	    NeedAdjust = TRUE;
+	}
+	if (csbi.srWindow.Bottom >= dwBufferSize.Y)
+	{
+	    dwWindowSize.Y = SRHEIGHT(csbi.srWindow);
+	    if (dwWindowSize.Y > dwBufferSize.Y)
+		dwWindowSize.Y = dwBufferSize.Y;
+	    csbi.srWindow.Bottom = dwBufferSize.Y - 1;
+	    csbi.srWindow.Top = dwBufferSize.Y - dwWindowSize.Y;
+	    NeedAdjust = TRUE;
+	}
+	if (NeedAdjust && WantAdjust)
+	{
+	    if (!SetConsoleWindowInfo(g_hConOut, TRUE, &csbi.srWindow))
+		return FALSE;
+	}
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
+typedef struct ConsoleBufferStruct
+{
+    BOOL IsValid;
+    CONSOLE_SCREEN_BUFFER_INFO Info;
+    PCHAR_INFO Buffer;
+    COORD BufferSize;
+} ConsoleBuffer;
+
+/*
+ * SaveConsoleBuffer()
+ * Description:
+ *  Saves important information about the console buffer, including the
+ *  actual buffer contents.  The saved information is suitable for later
+ *  restoration by RestoreConsoleBuffer().
+ * Returns:
+ *  TRUE if all information was saved; FALSE otherwise
+ *  If FALSE, still sets cb->IsValid if buffer characteristics were saved.
+ */
+    static BOOL
+SaveConsoleBuffer(
+    ConsoleBuffer *cb)
+{
+    DWORD NumCells;
+    COORD BufferCoord;
+    SMALL_RECT ReadRegion;
+    WORD Y, Y_incr;
+
+    if (cb == NULL)
+	return FALSE;
+
+    if (!GetConsoleScreenBufferInfo(g_hConOut, &cb->Info))
+    {
+	cb->IsValid = FALSE;
+	return FALSE;
+    }
+    cb->IsValid = TRUE;
+
+    /*
+     * Allocate a buffer large enough to hold the entire console screen
+     * buffer.  If this ConsoleBuffer structure has already been initialized
+     * with a buffer of the correct size, then just use that one.
+     */
+    if (!cb->IsValid || cb->Buffer == NULL ||
+	    cb->BufferSize.X != cb->Info.dwSize.X ||
+	    cb->BufferSize.Y != cb->Info.dwSize.Y)
+    {
+	cb->BufferSize.X = cb->Info.dwSize.X;
+	cb->BufferSize.Y = cb->Info.dwSize.Y;
+	NumCells = cb->BufferSize.X * cb->BufferSize.Y;
+	if (cb->Buffer != NULL)
+	    vim_free(cb->Buffer);
+	cb->Buffer = (PCHAR_INFO)alloc(NumCells * sizeof(CHAR_INFO));
+	if (cb->Buffer == NULL)
+	    return FALSE;
+    }
+
+    /*
+     * We will now copy the console screen buffer into our buffer.
+     * ReadConsoleOutput() seems to be limited as far as how much you
+     * can read at a time.  Empirically, this number seems to be about
+     * 12000 cells (rows * columns).  Start at position (0, 0) and copy
+     * in chunks until it is all copied.  The chunks will all have the
+     * same horizontal characteristics, so initialize them now.  The
+     * height of each chunk will be (12000 / width).
+     */
+    BufferCoord.X = 0;
+    ReadRegion.Left = 0;
+    ReadRegion.Right = cb->Info.dwSize.X - 1;
+    Y_incr = 12000 / cb->Info.dwSize.X;
+    for (Y = 0; Y < cb->BufferSize.Y; Y += Y_incr)
+    {
+	/*
+	 * Read into position (0, Y) in our buffer.
+	 */
+	BufferCoord.Y = Y;
+	/*
+	 * Read the region whose top left corner is (0, Y) and whose bottom
+	 * right corner is (width - 1, Y + Y_incr - 1).  This should define
+	 * a region of size width by Y_incr.  Don't worry if this region is
+	 * too large for the remaining buffer; it will be cropped.
+	 */
+	ReadRegion.Top = Y;
+	ReadRegion.Bottom = Y + Y_incr - 1;
+	if (!ReadConsoleOutput(g_hConOut,	/* output handle */
+		cb->Buffer,			/* our buffer */
+		cb->BufferSize,			/* dimensions of our buffer */
+		BufferCoord,			/* offset in our buffer */
+		&ReadRegion))			/* region to save */
+	{
+	    vim_free(cb->Buffer);
+	    cb->Buffer = NULL;
+	    return FALSE;
+	}
+    }
+
+    return TRUE;
+}
+
+/*
+ * RestoreConsoleBuffer()
+ * Description:
+ *  Restores important information about the console buffer, including the
+ *  actual buffer contents, if desired.  The information to restore is in
+ *  the same format used by SaveConsoleBuffer().
+ * Returns:
+ *  TRUE on success
+ */
+    static BOOL
+RestoreConsoleBuffer(
+    ConsoleBuffer *cb,
+    BOOL RestoreScreen)
+{
+    COORD BufferCoord;
+    SMALL_RECT WriteRegion;
+
+    if (cb == NULL || !cb->IsValid)
+	return FALSE;
+
+    /*
+     * Before restoring the buffer contents, clear the current buffer, and
+     * restore the cursor position and window information.  Doing this now
+     * prevents old buffer contents from "flashing" onto the screen.
+     */
+    if (RestoreScreen)
+	ClearConsoleBuffer(cb->Info.wAttributes);
+
+    FitConsoleWindow(cb->Info.dwSize, TRUE);
+    if (!SetConsoleScreenBufferSize(g_hConOut, cb->Info.dwSize))
+	return FALSE;
+    if (!SetConsoleTextAttribute(g_hConOut, cb->Info.wAttributes))
+	return FALSE;
+
+    if (!RestoreScreen)
+    {
+	/*
+	 * No need to restore the screen buffer contents, so we're done.
+	 */
+	return TRUE;
+    }
+
+    if (!SetConsoleCursorPosition(g_hConOut, cb->Info.dwCursorPosition))
+	return FALSE;
+    if (!SetConsoleWindowInfo(g_hConOut, TRUE, &cb->Info.srWindow))
+	return FALSE;
+
+    /*
+     * Restore the screen buffer contents.
+     */
+    if (cb->Buffer != NULL)
+    {
+	BufferCoord.X = 0;
+	BufferCoord.Y = 0;
+	WriteRegion.Left = 0;
+	WriteRegion.Top = 0;
+	WriteRegion.Right = cb->Info.dwSize.X - 1;
+	WriteRegion.Bottom = cb->Info.dwSize.Y - 1;
+	if (!WriteConsoleOutput(g_hConOut,	/* output handle */
+		cb->Buffer,			/* our buffer */
+		cb->BufferSize,			/* dimensions of our buffer */
+		BufferCoord,			/* offset in our buffer */
+		&WriteRegion))			/* region to restore */
+	{
+	    return FALSE;
+	}
+    }
+
+    return TRUE;
+}
+
+#ifdef FEAT_RESTORE_ORIG_SCREEN
+static ConsoleBuffer g_cbOrig = { 0 };
+#endif
+static ConsoleBuffer g_cbNonTermcap = { 0 };
+static ConsoleBuffer g_cbTermcap = { 0 };
+
+#ifdef FEAT_TITLE
+#ifdef __BORLANDC__
+typedef HWND (__stdcall *GETCONSOLEWINDOWPROC)(VOID);
+#else
+typedef WINBASEAPI HWND (WINAPI *GETCONSOLEWINDOWPROC)(VOID);
+#endif
+char g_szOrigTitle[256] = { 0 };
+HWND g_hWnd = NULL;	/* also used in os_mswin.c */
+static HICON g_hOrigIconSmall = NULL;
+static HICON g_hOrigIcon = NULL;
+static HICON g_hVimIcon = NULL;
+static BOOL g_fCanChangeIcon = FALSE;
+
+/* ICON* are not defined in VC++ 4.0 */
+#ifndef ICON_SMALL
+#define ICON_SMALL 0
+#endif
+#ifndef ICON_BIG
+#define ICON_BIG 1
+#endif
+/*
+ * GetConsoleIcon()
+ * Description:
+ *  Attempts to retrieve the small icon and/or the big icon currently in
+ *  use by a given window.
+ * Returns:
+ *  TRUE on success
+ */
+    static BOOL
+GetConsoleIcon(
+    HWND hWnd,
+    HICON *phIconSmall,
+    HICON *phIcon)
+{
+    if (hWnd == NULL)
+	return FALSE;
+
+    if (phIconSmall != NULL)
+    {
+	*phIconSmall = (HICON) SendMessage(hWnd, WM_GETICON,
+			    (WPARAM) ICON_SMALL, (LPARAM) 0);
+    }
+    if (phIcon != NULL)
+    {
+	*phIcon = (HICON) SendMessage(hWnd, WM_GETICON,
+			    (WPARAM) ICON_BIG, (LPARAM) 0);
+    }
+    return TRUE;
+}
+
+/*
+ * SetConsoleIcon()
+ * Description:
+ *  Attempts to change the small icon and/or the big icon currently in
+ *  use by a given window.
+ * Returns:
+ *  TRUE on success
+ */
+    static BOOL
+SetConsoleIcon(
+    HWND hWnd,
+    HICON hIconSmall,
+    HICON hIcon)
+{
+    HICON hPrevIconSmall;
+    HICON hPrevIcon;
+
+    if (hWnd == NULL)
+	return FALSE;
+
+    if (hIconSmall != NULL)
+    {
+	hPrevIconSmall = (HICON) SendMessage(hWnd, WM_SETICON,
+			    (WPARAM) ICON_SMALL, (LPARAM) hIconSmall);
+    }
+    if (hIcon != NULL)
+    {
+	hPrevIcon = (HICON) SendMessage(hWnd, WM_SETICON,
+			    (WPARAM) ICON_BIG, (LPARAM) hIcon);
+    }
+    return TRUE;
+}
+
+/*
+ * SaveConsoleTitleAndIcon()
+ * Description:
+ *  Saves the current console window title in g_szOrigTitle, for later
+ *  restoration.  Also, attempts to obtain a handle to the console window,
+ *  and use it to save the small and big icons currently in use by the
+ *  console window.  This is not always possible on some versions of Windows;
+ *  nor is it possible when running Vim remotely using Telnet (since the
+ *  console window the user sees is owned by a remote process).
+ */
+    static void
+SaveConsoleTitleAndIcon(void)
+{
+    GETCONSOLEWINDOWPROC GetConsoleWindowProc;
+
+    /* Save the original title. */
+    if (!GetConsoleTitle(g_szOrigTitle, sizeof(g_szOrigTitle)))
+	return;
+
+    /*
+     * Obtain a handle to the console window using GetConsoleWindow() from
+     * KERNEL32.DLL; we need to handle in order to change the window icon.
+     * This function only exists on NT-based Windows, starting with Windows
+     * 2000.  On older operating systems, we can't change the window icon
+     * anyway.
+     */
+    if ((GetConsoleWindowProc = (GETCONSOLEWINDOWPROC)
+	    GetProcAddress(GetModuleHandle("KERNEL32.DLL"),
+		    "GetConsoleWindow")) != NULL)
+    {
+	g_hWnd = (*GetConsoleWindowProc)();
+    }
+    if (g_hWnd == NULL)
+	return;
+
+    /* Save the original console window icon. */
+    GetConsoleIcon(g_hWnd, &g_hOrigIconSmall, &g_hOrigIcon);
+    if (g_hOrigIconSmall == NULL || g_hOrigIcon == NULL)
+	return;
+
+    /* Extract the first icon contained in the Vim executable. */
+    g_hVimIcon = ExtractIcon(NULL, exe_name, 0);
+    if (g_hVimIcon != NULL)
+	g_fCanChangeIcon = TRUE;
+}
+#endif
+
+static int g_fWindInitCalled = FALSE;
+static int g_fTermcapMode = FALSE;
+static CONSOLE_CURSOR_INFO g_cci;
+static DWORD g_cmodein = 0;
+static DWORD g_cmodeout = 0;
+
+/*
+ * non-GUI version of mch_init().
+ */
+    void
+mch_init()
+{
+#ifndef FEAT_RESTORE_ORIG_SCREEN
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+#endif
+#ifndef __MINGW32__
+    extern int _fmode;
+#endif
+
+    /* Let critical errors result in a failure, not in a dialog box.  Required
+     * for the timestamp test to work on removed floppies. */
+    SetErrorMode(SEM_FAILCRITICALERRORS);
+
+    _fmode = O_BINARY;		/* we do our own CR-LF translation */
+    out_flush();
+
+    /* Obtain handles for the standard Console I/O devices */
+    if (read_cmd_fd == 0)
+	g_hConIn =  GetStdHandle(STD_INPUT_HANDLE);
+    else
+	create_conin();
+    g_hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
+
+#ifdef FEAT_RESTORE_ORIG_SCREEN
+    /* Save the initial console buffer for later restoration */
+    SaveConsoleBuffer(&g_cbOrig);
+    g_attrCurrent = g_attrDefault = g_cbOrig.Info.wAttributes;
+#else
+    /* Get current text attributes */
+    GetConsoleScreenBufferInfo(g_hConOut, &csbi);
+    g_attrCurrent = g_attrDefault = csbi.wAttributes;
+#endif
+    if (cterm_normal_fg_color == 0)
+	cterm_normal_fg_color = (g_attrCurrent & 0xf) + 1;
+    if (cterm_normal_bg_color == 0)
+	cterm_normal_bg_color = ((g_attrCurrent >> 4) & 0xf) + 1;
+
+    /* set termcap codes to current text attributes */
+    update_tcap(g_attrCurrent);
+
+    GetConsoleCursorInfo(g_hConOut, &g_cci);
+    GetConsoleMode(g_hConIn,  &g_cmodein);
+    GetConsoleMode(g_hConOut, &g_cmodeout);
+
+#ifdef FEAT_TITLE
+    SaveConsoleTitleAndIcon();
+    /*
+     * Set both the small and big icons of the console window to Vim's icon.
+     * Note that Vim presently only has one size of icon (32x32), but it
+     * automatically gets scaled down to 16x16 when setting the small icon.
+     */
+    if (g_fCanChangeIcon)
+	SetConsoleIcon(g_hWnd, g_hVimIcon, g_hVimIcon);
+#endif
+
+    ui_get_shellsize();
+
+#ifdef MCH_WRITE_DUMP
+    fdDump = fopen("dump", "wt");
+
+    if (fdDump)
+    {
+	time_t t;
+
+	time(&t);
+	fputs(ctime(&t), fdDump);
+	fflush(fdDump);
+    }
+#endif
+
+    g_fWindInitCalled = TRUE;
+
+#ifdef FEAT_MOUSE
+    g_fMouseAvail = GetSystemMetrics(SM_MOUSEPRESENT);
+#endif
+
+#ifdef FEAT_CLIPBOARD
+    clip_init(TRUE);
+
+    /*
+     * Vim's own clipboard format recognises whether the text is char, line, or
+     * rectangular block.  Only useful for copying between two Vims.
+     * "VimClipboard" was used for previous versions, using the first
+     * character to specify MCHAR, MLINE or MBLOCK.
+     */
+    clip_star.format = RegisterClipboardFormat("VimClipboard2");
+    clip_star.format_raw = RegisterClipboardFormat("VimRawBytes");
+#endif
+
+    /* This will be NULL on anything but NT 4.0 */
+    s_pfnGetConsoleKeyboardLayoutName =
+	(PFNGCKLN) GetProcAddress(GetModuleHandle("kernel32.dll"),
+				  "GetConsoleKeyboardLayoutNameA");
+}
+
+/*
+ * non-GUI version of mch_exit().
+ * Shut down and exit with status `r'
+ * Careful: mch_exit() may be called before mch_init()!
+ */
+    void
+mch_exit(int r)
+{
+    stoptermcap();
+
+    if (g_fWindInitCalled)
+	settmode(TMODE_COOK);
+
+    ml_close_all(TRUE);		/* remove all memfiles */
+
+    if (g_fWindInitCalled)
+    {
+#ifdef FEAT_TITLE
+	mch_restore_title(3);
+	/*
+	 * Restore both the small and big icons of the console window to
+	 * what they were at startup.  Don't do this when the window is
+	 * closed, Vim would hang here.
+	 */
+	if (g_fCanChangeIcon && !g_fForceExit)
+	    SetConsoleIcon(g_hWnd, g_hOrigIconSmall, g_hOrigIcon);
+#endif
+
+#ifdef MCH_WRITE_DUMP
+	if (fdDump)
+	{
+	    time_t t;
+
+	    time(&t);
+	    fputs(ctime(&t), fdDump);
+	    fclose(fdDump);
+	}
+	fdDump = NULL;
+#endif
+    }
+
+    SetConsoleCursorInfo(g_hConOut, &g_cci);
+    SetConsoleMode(g_hConIn,  g_cmodein);
+    SetConsoleMode(g_hConOut, g_cmodeout);
+
+#ifdef DYNAMIC_GETTEXT
+    dyn_libintl_end();
+#endif
+
+    exit(r);
+}
+#endif /* !FEAT_GUI_W32 */
+
+
+/*
+ * Do we have an interactive window?
+ */
+    int
+mch_check_win(
+    int argc,
+    char **argv)
+{
+    get_exe_name();
+
+#ifdef FEAT_GUI_W32
+    return OK;	    /* GUI always has a tty */
+#else
+    if (isatty(1))
+	return OK;
+    return FAIL;
+#endif
+}
+
+
+/*
+ * fname_case(): Set the case of the file name, if it already exists.
+ * When "len" is > 0, also expand short to long filenames.
+ */
+    void
+fname_case(
+    char_u	*name,
+    int		len)
+{
+    char		szTrueName[_MAX_PATH + 2];
+    char		*ptrue, *ptruePrev;
+    char		*porig, *porigPrev;
+    int			flen;
+    WIN32_FIND_DATA	fb;
+    HANDLE		hFind;
+    int			c;
+
+    flen = (name != NULL) ? (int)STRLEN(name) : 0;
+    if (flen == 0 || flen > _MAX_PATH)
+	return;
+
+    slash_adjust(name);
+
+    /* Build the new name in szTrueName[] one component at a time. */
+    porig = name;
+    ptrue = szTrueName;
+
+    if (isalpha(porig[0]) && porig[1] == ':')
+    {
+	/* copy leading drive letter */
+	*ptrue++ = *porig++;
+	*ptrue++ = *porig++;
+	*ptrue = NUL;	    /* in case nothing follows */
+    }
+
+    while (*porig != NUL)
+    {
+	/* copy \ characters */
+	while (*porig == psepc)
+	    *ptrue++ = *porig++;
+
+	ptruePrev = ptrue;
+	porigPrev = porig;
+	while (*porig != NUL && *porig != psepc)
+	{
+#ifdef FEAT_MBYTE
+	    int l;
+
+	    if (enc_dbcs)
+	    {
+		l = (*mb_ptr2len_check)(porig);
+		while (--l >= 0)
+		    *ptrue++ = *porig++;
+	    }
+	    else
+#endif
+		*ptrue++ = *porig++;
+	}
+	*ptrue = NUL;
+
+	/* Skip "", "." and "..". */
+	if (ptrue > ptruePrev
+		&& (ptruePrev[0] != '.'
+		    || (ptruePrev[1] != NUL
+			&& (ptruePrev[1] != '.' || ptruePrev[2] != NUL)))
+		&& (hFind = FindFirstFile(szTrueName, &fb))
+						      != INVALID_HANDLE_VALUE)
+	{
+	    c = *porig;
+	    *porig = NUL;
+
+	    /* Only use the match when it's the same name (ignoring case) or
+	     * expansion is allowed and there is a match with the short name
+	     * and there is enough room. */
+	    if (_stricoll(porigPrev, fb.cFileName) == 0
+		    || (len > 0
+			&& (_stricoll(porigPrev, fb.cAlternateFileName) == 0
+			    && (int)(ptruePrev - szTrueName)
+					   + (int)strlen(fb.cFileName) < len)))
+	    {
+		STRCPY(ptruePrev, fb.cFileName);
+
+		/* Look for exact match and prefer it if found.  Must be a
+		 * long name, otherwise there would be only one match. */
+		while (FindNextFile(hFind, &fb))
+		{
+		    if (*fb.cAlternateFileName != NUL
+			    && (strcoll(porigPrev, fb.cFileName) == 0
+				|| (len > 0
+				    && (_stricoll(porigPrev,
+						   fb.cAlternateFileName) == 0
+				    && (int)(ptruePrev - szTrueName)
+					 + (int)strlen(fb.cFileName) < len))))
+		    {
+			STRCPY(ptruePrev, fb.cFileName);
+			break;
+		    }
+		}
+	    }
+	    FindClose(hFind);
+	    *porig = c;
+	    ptrue = ptruePrev + strlen(ptruePrev);
+	}
+    }
+
+    STRCPY(name, szTrueName);
+}
+
+
+/*
+ * Insert user name in s[len].
+ */
+    int
+mch_get_user_name(
+    char_u *s,
+    int len)
+{
+    char szUserName[MAX_COMPUTERNAME_LENGTH + 1];
+    DWORD cch = sizeof szUserName;
+
+    if (GetUserName(szUserName, &cch))
+    {
+	STRNCPY(s, szUserName, len);
+	return OK;
+    }
+    s[0] = NUL;
+    return FAIL;
+}
+
+
+/*
+ * Insert host name in s[len].
+ */
+    void
+mch_get_host_name(
+    char_u	*s,
+    int		len)
+{
+    DWORD cch = len;
+
+    if (!GetComputerName(s, &cch))
+    {
+	STRNCPY(s, "PC (Win32 Vim)", len);
+	s[len - 1] = NUL;	/* make sure it's terminated */
+    }
+}
+
+
+/*
+ * return process ID
+ */
+    long
+mch_get_pid()
+{
+    return (long)GetCurrentProcessId();
+}
+
+
+/*
+ * Get name of current directory into buffer 'buf' of length 'len' bytes.
+ * Return OK for success, FAIL for failure.
+ */
+    int
+mch_dirname(
+    char_u	*buf,
+    int		len)
+{
+    /*
+     * Originally this was:
+     *    return (getcwd(buf, len) != NULL ? OK : FAIL);
+     * But the Win32s known bug list says that getcwd() doesn't work
+     * so use the Win32 system call instead. <Negri>
+     */
+#ifdef FEAT_MBYTE
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	WCHAR	wbuf[_MAX_PATH + 1];
+
+	if (GetCurrentDirectoryW(_MAX_PATH, wbuf) != 0)
+	{
+	    char_u  *p = ucs2_to_enc(wbuf, NULL);
+
+	    if (p != NULL)
+	    {
+		STRNCPY(buf, p, len - 1);
+		buf[len - 1] = NUL;
+		vim_free(p);
+		return OK;
+	    }
+	}
+	/* Retry with non-wide function (for Windows 98). */
+    }
+#endif
+    return (GetCurrentDirectory(len, buf) != 0 ? OK : FAIL);
+}
+
+/*
+ * get file permissions for `name'
+ * -1 : error
+ * else FILE_ATTRIBUTE_* defined in winnt.h
+ */
+    long
+mch_getperm(
+    char_u *name)
+{
+#ifdef FEAT_MBYTE
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	WCHAR	*p = enc_to_ucs2(name, NULL);
+	long	n;
+
+	if (p != NULL)
+	{
+	    n = (long)GetFileAttributesW(p);
+	    vim_free(p);
+	    if (n >= 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+		return n;
+	    /* Retry with non-wide function (for Windows 98). */
+	}
+    }
+#endif
+    return (long)GetFileAttributes((char *)name);
+}
+
+
+/*
+ * set file permission for `name' to `perm'
+ */
+    int
+mch_setperm(
+    char_u *name,
+    long perm)
+{
+    perm |= FILE_ATTRIBUTE_ARCHIVE;	/* file has changed, set archive bit */
+#ifdef FEAT_MBYTE
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	WCHAR	*p = enc_to_ucs2(name, NULL);
+	long	n;
+
+	if (p != NULL)
+	{
+	    n = (long)SetFileAttributesW(p, perm);
+	    vim_free(p);
+	    if (n || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+		return n ? OK : FAIL;
+	    /* Retry with non-wide function (for Windows 98). */
+	}
+    }
+#endif
+    return SetFileAttributes((char *)name, perm) ? OK : FAIL;
+}
+
+/*
+ * Set hidden flag for "name".
+ */
+    void
+mch_hide(char_u *name)
+{
+    int		perm;
+#ifdef FEAT_MBYTE
+    WCHAR	*p = NULL;
+
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+	p = enc_to_ucs2(name, NULL);
+#endif
+
+#ifdef FEAT_MBYTE
+    if (p != NULL)
+    {
+	perm = GetFileAttributesW(p);
+	if (perm < 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+	{
+	    /* Retry with non-wide function (for Windows 98). */
+	    vim_free(p);
+	    p = NULL;
+	}
+    }
+    if (p == NULL)
+#endif
+	perm = GetFileAttributes((char *)name);
+    if (perm >= 0)
+    {
+	perm |= FILE_ATTRIBUTE_HIDDEN;
+#ifdef FEAT_MBYTE
+	if (p != NULL)
+	{
+	    if (SetFileAttributesW(p, perm) == 0
+		    && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+	    {
+		/* Retry with non-wide function (for Windows 98). */
+		vim_free(p);
+		p = NULL;
+	    }
+	}
+	if (p == NULL)
+#endif
+	    SetFileAttributes((char *)name, perm);
+    }
+#ifdef FEAT_MBYTE
+    vim_free(p);
+#endif
+}
+
+/*
+ * return TRUE if "name" is a directory
+ * return FALSE if "name" is not a directory or upon error
+ */
+    int
+mch_isdir(char_u *name)
+{
+    int f = mch_getperm(name);
+
+    if (f == -1)
+	return FALSE;		    /* file does not exist at all */
+
+    return (f & FILE_ATTRIBUTE_DIRECTORY) != 0;
+}
+
+/*
+ * Return TRUE if file or directory "name" is writable (not readonly).
+ * Strange semantics of Win32: a readonly directory is writable, but you can't
+ * delete a file.  Let's say this means it is writable.
+ */
+    int
+mch_writable(char_u *name)
+{
+    int perm = mch_getperm(name);
+
+    return (perm != -1 && (!(perm & FILE_ATTRIBUTE_READONLY)
+				       || (perm & FILE_ATTRIBUTE_DIRECTORY)));
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return 1 if "name" can be executed, 0 if not.
+ * Return -1 if unknown.
+ */
+    int
+mch_can_exe(char_u *name)
+{
+    return executable_exists((char *)name);
+}
+#endif
+
+/*
+ * Check what "name" is:
+ * NODE_NORMAL: file or directory (or doesn't exist)
+ * NODE_WRITABLE: writable device, socket, fifo, etc.
+ * NODE_OTHER: non-writable things
+ */
+    int
+mch_nodetype(char_u *name)
+{
+    HANDLE	hFile;
+    int		type;
+
+    hFile = CreateFile(name,		/* file name */
+		GENERIC_WRITE,		/* access mode */
+		0,			/* share mode */
+		NULL,			/* security descriptor */
+		OPEN_EXISTING,		/* creation disposition */
+		0,			/* file attributes */
+		NULL);			/* handle to template file */
+
+    if (hFile == INVALID_HANDLE_VALUE)
+	return NODE_NORMAL;
+
+    type = GetFileType(hFile);
+    CloseHandle(hFile);
+    if (type == FILE_TYPE_CHAR)
+	return NODE_WRITABLE;
+    if (type == FILE_TYPE_DISK)
+	return NODE_NORMAL;
+    return NODE_OTHER;
+}
+
+#ifdef HAVE_ACL
+struct my_acl
+{
+    PSECURITY_DESCRIPTOR    pSecurityDescriptor;
+    PSID		    pSidOwner;
+    PSID		    pSidGroup;
+    PACL		    pDacl;
+    PACL		    pSacl;
+};
+#endif
+
+/*
+ * Return a pointer to the ACL of file "fname" in allocated memory.
+ * Return NULL if the ACL is not available for whatever reason.
+ */
+    vim_acl_T
+mch_get_acl(fname)
+    char_u	*fname;
+{
+#ifndef HAVE_ACL
+    return (vim_acl_T)NULL;
+#else
+    struct my_acl   *p = NULL;
+
+    /* This only works on Windows NT and 2000. */
+    if (g_PlatformId == VER_PLATFORM_WIN32_NT && advapi_lib != NULL)
+    {
+	p = (struct my_acl *)alloc_clear((unsigned)sizeof(struct my_acl));
+	if (p != NULL)
+	{
+	    if (pGetNamedSecurityInfo(
+			(LPTSTR)fname,		// Abstract filename
+			SE_FILE_OBJECT,		// File Object
+			// Retrieve the entire security descriptor.
+			OWNER_SECURITY_INFORMATION |
+			GROUP_SECURITY_INFORMATION |
+			DACL_SECURITY_INFORMATION |
+			SACL_SECURITY_INFORMATION,
+			&p->pSidOwner,		// Ownership information.
+			&p->pSidGroup,		// Group membership.
+			&p->pDacl,		// Discretionary information.
+			&p->pSacl,		// For auditing purposes.
+			&p->pSecurityDescriptor
+				    ) != ERROR_SUCCESS)
+	    {
+		mch_free_acl((vim_acl_T)p);
+		p = NULL;
+	    }
+	}
+    }
+
+    return (vim_acl_T)p;
+#endif
+}
+
+/*
+ * Set the ACL of file "fname" to "acl" (unless it's NULL).
+ * Errors are ignored.
+ * This must only be called with "acl" equal to what mch_get_acl() returned.
+ */
+    void
+mch_set_acl(fname, acl)
+    char_u	*fname;
+    vim_acl_T	acl;
+{
+#ifdef HAVE_ACL
+    struct my_acl   *p = (struct my_acl *)acl;
+
+    if (p != NULL && advapi_lib != NULL)
+	(void)pSetNamedSecurityInfo(
+		    (LPTSTR)fname,		// Abstract filename
+		    SE_FILE_OBJECT,		// File Object
+		    // Retrieve the entire security descriptor.
+		    OWNER_SECURITY_INFORMATION |
+			GROUP_SECURITY_INFORMATION |
+			DACL_SECURITY_INFORMATION |
+			SACL_SECURITY_INFORMATION,
+		    p->pSidOwner,		// Ownership information.
+		    p->pSidGroup,		// Group membership.
+		    p->pDacl,			// Discretionary information.
+		    p->pSacl			// For auditing purposes.
+		    );
+#endif
+}
+
+    void
+mch_free_acl(acl)
+    vim_acl_T	acl;
+{
+#ifdef HAVE_ACL
+    struct my_acl   *p = (struct my_acl *)acl;
+
+    if (p != NULL)
+    {
+	LocalFree(p->pSecurityDescriptor);	// Free the memory just in case
+	vim_free(p);
+    }
+#endif
+}
+
+#ifndef FEAT_GUI_W32
+
+/*
+ * handler for ctrl-break, ctrl-c interrupts, and fatal events.
+ */
+    static BOOL WINAPI
+handler_routine(
+    DWORD dwCtrlType)
+{
+    switch (dwCtrlType)
+    {
+    case CTRL_C_EVENT:
+	if (ctrl_c_interrupts)
+	    g_fCtrlCPressed = TRUE;
+	return TRUE;
+
+    case CTRL_BREAK_EVENT:
+	g_fCBrkPressed	= TRUE;
+	return TRUE;
+
+    /* fatal events: shut down gracefully */
+    case CTRL_CLOSE_EVENT:
+    case CTRL_LOGOFF_EVENT:
+    case CTRL_SHUTDOWN_EVENT:
+	windgoto((int)Rows - 1, 0);
+	g_fForceExit = TRUE;
+
+	sprintf((char *)IObuff, _("Vim: Caught %s event\n"),
+		(dwCtrlType == CTRL_CLOSE_EVENT
+		     ? _("close")
+		     : dwCtrlType == CTRL_LOGOFF_EVENT
+			 ? _("logoff")
+			 : _("shutdown")));
+#ifdef DEBUG
+	OutputDebugString(IObuff);
+#endif
+
+	preserve_exit();	/* output IObuff, preserve files and exit */
+
+	return TRUE;		/* not reached */
+
+    default:
+	return FALSE;
+    }
+}
+
+
+/*
+ * set the tty in (raw) ? "raw" : "cooked" mode
+ */
+    void
+mch_settmode(
+    int tmode)
+{
+    DWORD cmodein;
+    DWORD cmodeout;
+    BOOL bEnableHandler;
+
+    GetConsoleMode(g_hConIn, &cmodein);
+    GetConsoleMode(g_hConOut, &cmodeout);
+    if (tmode == TMODE_RAW)
+    {
+	cmodein &= ~(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
+		     ENABLE_ECHO_INPUT);
+#ifdef FEAT_MOUSE
+	if (g_fMouseActive)
+	    cmodein |= ENABLE_MOUSE_INPUT;
+#endif
+	cmodeout &= ~(ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
+	bEnableHandler = TRUE;
+    }
+    else /* cooked */
+    {
+	cmodein |= (ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
+		    ENABLE_ECHO_INPUT);
+	cmodeout |= (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
+	bEnableHandler = FALSE;
+    }
+    SetConsoleMode(g_hConIn, cmodein);
+    SetConsoleMode(g_hConOut, cmodeout);
+    SetConsoleCtrlHandler(handler_routine, bEnableHandler);
+
+#ifdef MCH_WRITE_DUMP
+    if (fdDump)
+    {
+	fprintf(fdDump, "mch_settmode(%s, in = %x, out = %x)\n",
+		tmode == TMODE_RAW ? "raw" :
+				    tmode == TMODE_COOK ? "cooked" : "normal",
+		cmodein, cmodeout);
+	fflush(fdDump);
+    }
+#endif
+}
+
+
+/*
+ * Get the size of the current window in `Rows' and `Columns'
+ * Return OK when size could be determined, FAIL otherwise.
+ */
+    int
+mch_get_shellsize()
+{
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+    if (!g_fTermcapMode && g_cbTermcap.IsValid)
+    {
+	/*
+	 * For some reason, we are trying to get the screen dimensions
+	 * even though we are not in termcap mode.  The 'Rows' and 'Columns'
+	 * variables are really intended to mean the size of Vim screen
+	 * while in termcap mode.
+	 */
+	Rows = g_cbTermcap.Info.dwSize.Y;
+	Columns = g_cbTermcap.Info.dwSize.X;
+    }
+    else if (GetConsoleScreenBufferInfo(g_hConOut, &csbi))
+    {
+	Rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+	Columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
+    }
+    else
+    {
+	Rows = 25;
+	Columns = 80;
+    }
+    return OK;
+}
+
+/*
+ * Set a console window to `xSize' * `ySize'
+ */
+    static void
+ResizeConBufAndWindow(
+    HANDLE hConsole,
+    int xSize,
+    int ySize)
+{
+    CONSOLE_SCREEN_BUFFER_INFO csbi;	/* hold current console buffer info */
+    SMALL_RECT	    srWindowRect;	/* hold the new console size */
+    COORD	    coordScreen;
+
+#ifdef MCH_WRITE_DUMP
+    if (fdDump)
+    {
+	fprintf(fdDump, "ResizeConBufAndWindow(%d, %d)\n", xSize, ySize);
+	fflush(fdDump);
+    }
+#endif
+
+    /* get the largest size we can size the console window to */
+    coordScreen = GetLargestConsoleWindowSize(hConsole);
+
+    /* define the new console window size and scroll position */
+    srWindowRect.Left = srWindowRect.Top = (SHORT) 0;
+    srWindowRect.Right =  (SHORT) (min(xSize, coordScreen.X) - 1);
+    srWindowRect.Bottom = (SHORT) (min(ySize, coordScreen.Y) - 1);
+
+    if (GetConsoleScreenBufferInfo(g_hConOut, &csbi))
+    {
+	int sx, sy;
+
+	sx = csbi.srWindow.Right - csbi.srWindow.Left + 1;
+	sy = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+	if (sy < ySize || sx < xSize)
+	{
+	    /*
+	     * Increasing number of lines/columns, do buffer first.
+	     * Use the maximal size in x and y direction.
+	     */
+	    if (sy < ySize)
+		coordScreen.Y = ySize;
+	    else
+		coordScreen.Y = sy;
+	    if (sx < xSize)
+		coordScreen.X = xSize;
+	    else
+		coordScreen.X = sx;
+	    SetConsoleScreenBufferSize(hConsole, coordScreen);
+	}
+    }
+
+    if (!SetConsoleWindowInfo(g_hConOut, TRUE, &srWindowRect))
+    {
+#ifdef MCH_WRITE_DUMP
+	if (fdDump)
+	{
+	    fprintf(fdDump, "SetConsoleWindowInfo failed: %lx\n",
+		    GetLastError());
+	    fflush(fdDump);
+	}
+#endif
+    }
+
+    /* define the new console buffer size */
+    coordScreen.X = xSize;
+    coordScreen.Y = ySize;
+
+    if (!SetConsoleScreenBufferSize(hConsole, coordScreen))
+    {
+#ifdef MCH_WRITE_DUMP
+	if (fdDump)
+	{
+	    fprintf(fdDump, "SetConsoleScreenBufferSize failed: %lx\n",
+		    GetLastError());
+	    fflush(fdDump);
+	}
+#endif
+    }
+}
+
+
+/*
+ * Set the console window to `Rows' * `Columns'
+ */
+    void
+mch_set_shellsize()
+{
+    COORD coordScreen;
+
+    /* Don't change window size while still starting up */
+    if (suppress_winsize != 0)
+    {
+	suppress_winsize = 2;
+	return;
+    }
+
+    if (term_console)
+    {
+	coordScreen = GetLargestConsoleWindowSize(g_hConOut);
+
+	/* Clamp Rows and Columns to reasonable values */
+	if (Rows > coordScreen.Y)
+	    Rows = coordScreen.Y;
+	if (Columns > coordScreen.X)
+	    Columns = coordScreen.X;
+
+	ResizeConBufAndWindow(g_hConOut, Columns, Rows);
+    }
+}
+
+/*
+ * Rows and/or Columns has changed.
+ */
+    void
+mch_new_shellsize()
+{
+    set_scroll_region(0, 0, Columns - 1, Rows - 1);
+}
+
+
+/*
+ * Called when started up, to set the winsize that was delayed.
+ */
+    void
+mch_set_winsize_now()
+{
+    if (suppress_winsize == 2)
+    {
+	suppress_winsize = 0;
+	mch_set_shellsize();
+	shell_resized();
+    }
+    suppress_winsize = 0;
+}
+#endif /* FEAT_GUI_W32 */
+
+
+
+#if defined(FEAT_GUI_W32) || defined(PROTO)
+
+/*
+ * Specialised version of system() for Win32 GUI mode.
+ * This version proceeds as follows:
+ *    1. Create a console window for use by the subprocess
+ *    2. Run the subprocess (it gets the allocated console by default)
+ *    3. Wait for the subprocess to terminate and get its exit code
+ *    4. Prompt the user to press a key to close the console window
+ */
+    static int
+mch_system(char *cmd, int options)
+{
+    STARTUPINFO		si;
+    PROCESS_INFORMATION pi;
+    DWORD		ret = 0;
+    HWND		hwnd = GetFocus();
+
+    si.cb = sizeof(si);
+    si.lpReserved = NULL;
+    si.lpDesktop = NULL;
+    si.lpTitle = NULL;
+    si.dwFlags = STARTF_USESHOWWINDOW;
+    /*
+     * It's nicer to run a filter command in a minimized window, but in
+     * Windows 95 this makes the command MUCH slower.  We can't do it under
+     * Win32s either as it stops the synchronous spawn workaround working.
+     */
+    if ((options & SHELL_DOOUT) && !mch_windows95() && !gui_is_win32s())
+	si.wShowWindow = SW_SHOWMINIMIZED;
+    else
+	si.wShowWindow = SW_SHOWNORMAL;
+    si.cbReserved2 = 0;
+    si.lpReserved2 = NULL;
+
+    /* There is a strange error on Windows 95 when using "c:\\command.com".
+     * When the "c:\\" is left out it works OK...? */
+    if (mch_windows95()
+	    && (STRNICMP(cmd, "c:/command.com", 14) == 0
+		|| STRNICMP(cmd, "c:\\command.com", 14) == 0))
+	cmd += 3;
+
+    /* Now, run the command */
+    CreateProcess(NULL,			/* Executable name */
+		  cmd,			/* Command to execute */
+		  NULL,			/* Process security attributes */
+		  NULL,			/* Thread security attributes */
+		  FALSE,		/* Inherit handles */
+		  CREATE_DEFAULT_ERROR_MODE |	/* Creation flags */
+			CREATE_NEW_CONSOLE,
+		  NULL,			/* Environment */
+		  NULL,			/* Current directory */
+		  &si,			/* Startup information */
+		  &pi);			/* Process information */
+
+
+    /* Wait for the command to terminate before continuing */
+    if (g_PlatformId != VER_PLATFORM_WIN32s)
+    {
+#ifdef FEAT_GUI
+	int	    delay = 1;
+
+	/* Keep updating the window while waiting for the shell to finish. */
+	for (;;)
+	{
+	    MSG	msg;
+
+	    if (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE))
+	    {
+		TranslateMessage(&msg);
+		DispatchMessage(&msg);
+	    }
+	    if (WaitForSingleObject(pi.hProcess, delay) != WAIT_TIMEOUT)
+		break;
+
+	    /* We start waiting for a very short time and then increase it, so
+	     * that we respond quickly when the process is quick, and don't
+	     * consume too much overhead when it's slow. */
+	    if (delay < 50)
+		delay += 10;
+	}
+#else
+	WaitForSingleObject(pi.hProcess, INFINITE);
+#endif
+
+	/* Get the command exit code */
+	GetExitCodeProcess(pi.hProcess, &ret);
+    }
+    else
+    {
+	/*
+	 * This ugly code is the only quick way of performing
+	 * a synchronous spawn under Win32s. Yuk.
+	 */
+	num_windows = 0;
+	EnumWindows(win32ssynch_cb, 0);
+	old_num_windows = num_windows;
+	do
+	{
+	    Sleep(1000);
+	    num_windows = 0;
+	    EnumWindows(win32ssynch_cb, 0);
+	} while (num_windows == old_num_windows);
+	ret = 0;
+    }
+
+    /* Close the handles to the subprocess, so that it goes away */
+    CloseHandle(pi.hThread);
+    CloseHandle(pi.hProcess);
+
+    /* Try to get input focus back.  Doesn't always work though. */
+    PostMessage(hwnd, WM_SETFOCUS, 0, 0);
+
+    return ret;
+}
+#else
+
+# define mch_system(c, o) system(c)
+
+#endif
+
+/*
+ * Either execute a command by calling the shell or start a new shell
+ */
+    int
+mch_call_shell(
+    char_u *cmd,
+    int options)	/* SHELL_*, see vim.h */
+{
+    int		x = 0;
+    int		tmode = cur_tmode;
+#ifdef FEAT_TITLE
+    char szShellTitle[512];
+
+    /* Change the title to reflect that we are in a subshell. */
+    if (GetConsoleTitle(szShellTitle, sizeof(szShellTitle) - 4) > 0)
+    {
+	if (cmd == NULL)
+	    strcat(szShellTitle, " :sh");
+	else
+	{
+	    strcat(szShellTitle, " - !");
+	    if ((strlen(szShellTitle) + strlen(cmd) < sizeof(szShellTitle)))
+		strcat(szShellTitle, cmd);
+	}
+	mch_settitle(szShellTitle, NULL);
+    }
+#endif
+
+    out_flush();
+
+#ifdef MCH_WRITE_DUMP
+    if (fdDump)
+    {
+	fprintf(fdDump, "mch_call_shell(\"%s\", %d)\n", cmd, options);
+	fflush(fdDump);
+    }
+#endif
+
+    /*
+     * Catch all deadly signals while running the external command, because a
+     * CTRL-C, Ctrl-Break or illegal instruction  might otherwise kill us.
+     */
+    signal(SIGINT, SIG_IGN);
+#if defined(__GNUC__) && !defined(__MINGW32__)
+    signal(SIGKILL, SIG_IGN);
+#else
+    signal(SIGBREAK, SIG_IGN);
+#endif
+    signal(SIGILL, SIG_IGN);
+    signal(SIGFPE, SIG_IGN);
+    signal(SIGSEGV, SIG_IGN);
+    signal(SIGTERM, SIG_IGN);
+    signal(SIGABRT, SIG_IGN);
+
+    if (options & SHELL_COOKED)
+	settmode(TMODE_COOK);	/* set to normal mode */
+
+    if (cmd == NULL)
+    {
+	x = mch_system(p_sh, options);
+    }
+    else
+    {
+	/* we use "command" or "cmd" to start the shell; slow but easy */
+	char_u *newcmd;
+
+	newcmd = lalloc((long_u) (
+#ifdef FEAT_GUI_W32
+		STRLEN(vimrun_path) +
+#endif
+		STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10), TRUE);
+	if (newcmd != NULL)
+	{
+	    char_u *cmdbase = (*cmd == '"' ? cmd + 1 : cmd);
+
+	    if ((STRNICMP(cmdbase, "start", 5) == 0) && vim_iswhite(cmdbase[5]))
+	    {
+		STARTUPINFO		si;
+		PROCESS_INFORMATION	pi;
+
+		si.cb = sizeof(si);
+		si.lpReserved = NULL;
+		si.lpDesktop = NULL;
+		si.lpTitle = NULL;
+		si.dwFlags = 0;
+		si.cbReserved2 = 0;
+		si.lpReserved2 = NULL;
+
+		cmdbase = skipwhite(cmdbase + 5);
+		if ((STRNICMP(cmdbase, "/min", 4) == 0)
+			&& vim_iswhite(cmdbase[4]))
+		{
+		    cmdbase = skipwhite(cmdbase + 4);
+		    si.dwFlags = STARTF_USESHOWWINDOW;
+		    si.wShowWindow = SW_SHOWMINNOACTIVE;
+		}
+
+		/* When the command is in double quotes, but 'shellxquote' is
+		 * empty, keep the double quotes around the command.
+		 * Otherwise remove the double quotes, they aren't needed
+		 * here, because we don't use a shell to run the command. */
+		if (*cmd == '"' && *p_sxq == NUL)
+		{
+		    newcmd[0] = '"';
+		    STRCPY(newcmd + 1, cmdbase);
+		}
+		else
+		{
+		    STRCPY(newcmd, cmdbase);
+		    if (*cmd == '"' && *newcmd != NUL)
+			newcmd[STRLEN(newcmd) - 1] = NUL;
+		}
+
+		/*
+		 * Now, start the command as a process, so that it doesn't
+		 * inherit our handles which causes unpleasant dangling swap
+		 * files if we exit before the spawned process
+		 */
+		if (CreateProcess (NULL,	// Executable name
+			newcmd,			// Command to execute
+			NULL,			// Process security attributes
+			NULL,			// Thread security attributes
+			FALSE,			// Inherit handles
+			CREATE_NEW_CONSOLE,	// Creation flags
+			NULL,			// Environment
+			NULL,			// Current directory
+			&si,			// Startup information
+			&pi))			// Process information
+		    x = 0;
+		else
+		{
+		    x = -1;
+#ifdef FEAT_GUI_W32
+		    EMSG(_("E371: Command not found"));
+#endif
+		}
+		/* Close the handles to the subprocess, so that it goes away */
+		CloseHandle(pi.hThread);
+		CloseHandle(pi.hProcess);
+	    }
+	    else
+	    {
+#if defined(FEAT_GUI_W32)
+		if (need_vimrun_warning)
+		{
+		    MessageBox(NULL,
+			    _("VIMRUN.EXE not found in your $PATH.\n"
+				"External commands will not pause after completion.\n"
+				"See  :help win32-vimrun  for more information."),
+			    _("Vim Warning"),
+			    MB_ICONWARNING);
+		    need_vimrun_warning = FALSE;
+		}
+		if (!s_dont_use_vimrun)
+		    /* Use vimrun to execute the command.  It opens a console
+		     * window, which can be closed without killing Vim. */
+		    sprintf((char *)newcmd, "%s%s%s %s %s",
+			    vimrun_path,
+			    (msg_silent != 0 || (options & SHELL_DOOUT))
+								 ? "-s " : "",
+			    p_sh, p_shcf, cmd);
+		else
+#endif
+		    sprintf((char *)newcmd, "%s %s %s", p_sh, p_shcf, cmd);
+		x = mch_system((char *)newcmd, options);
+	    }
+	    vim_free(newcmd);
+	}
+    }
+
+    if (tmode == TMODE_RAW)
+	settmode(TMODE_RAW);	/* set to raw mode */
+
+    /* Print the return value, unless "vimrun" was used. */
+    if (x != 0 && !(options & SHELL_SILENT) && !emsg_silent
+#if defined(FEAT_GUI_W32)
+		&& ((options & SHELL_DOOUT) || s_dont_use_vimrun)
+#endif
+	    )
+    {
+	smsg(_("shell returned %d"), x);
+	msg_putchar('\n');
+    }
+#ifdef FEAT_TITLE
+    resettitle();
+#endif
+
+    signal(SIGINT, SIG_DFL);
+#if defined(__GNUC__) && !defined(__MINGW32__)
+    signal(SIGKILL, SIG_DFL);
+#else
+    signal(SIGBREAK, SIG_DFL);
+#endif
+    signal(SIGILL, SIG_DFL);
+    signal(SIGFPE, SIG_DFL);
+    signal(SIGSEGV, SIG_DFL);
+    signal(SIGTERM, SIG_DFL);
+    signal(SIGABRT, SIG_DFL);
+
+    return x;
+}
+
+
+#ifndef FEAT_GUI_W32
+
+/*
+ * Start termcap mode
+ */
+    static void
+termcap_mode_start(void)
+{
+    DWORD cmodein;
+
+    if (g_fTermcapMode)
+	return;
+
+    SaveConsoleBuffer(&g_cbNonTermcap);
+
+    if (g_cbTermcap.IsValid)
+    {
+	/*
+	 * We've been in termcap mode before.  Restore certain screen
+	 * characteristics, including the buffer size and the window
+	 * size.  Since we will be redrawing the screen, we don't need
+	 * to restore the actual contents of the buffer.
+	 */
+	RestoreConsoleBuffer(&g_cbTermcap, FALSE);
+	SetConsoleWindowInfo(g_hConOut, TRUE, &g_cbTermcap.Info.srWindow);
+	Rows = g_cbTermcap.Info.dwSize.Y;
+	Columns = g_cbTermcap.Info.dwSize.X;
+    }
+    else
+    {
+	/*
+	 * This is our first time entering termcap mode.  Clear the console
+	 * screen buffer, and resize the buffer to match the current window
+	 * size.  We will use this as the size of our editing environment.
+	 */
+	ClearConsoleBuffer(g_attrCurrent);
+	ResizeConBufAndWindow(g_hConOut, Columns, Rows);
+    }
+
+#ifdef FEAT_TITLE
+    resettitle();
+#endif
+
+    GetConsoleMode(g_hConIn, &cmodein);
+#ifdef FEAT_MOUSE
+    if (g_fMouseActive)
+	cmodein |= ENABLE_MOUSE_INPUT;
+    else
+	cmodein &= ~ENABLE_MOUSE_INPUT;
+#endif
+    cmodein |= ENABLE_WINDOW_INPUT;
+    SetConsoleMode(g_hConIn, cmodein);
+
+    redraw_later_clear();
+    g_fTermcapMode = TRUE;
+}
+
+
+/*
+ * End termcap mode
+ */
+    static void
+termcap_mode_end(void)
+{
+    DWORD cmodein;
+    ConsoleBuffer *cb;
+    COORD coord;
+    DWORD dwDummy;
+
+    if (!g_fTermcapMode)
+	return;
+
+    SaveConsoleBuffer(&g_cbTermcap);
+
+    GetConsoleMode(g_hConIn, &cmodein);
+    cmodein &= ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT);
+    SetConsoleMode(g_hConIn, cmodein);
+
+#ifdef FEAT_RESTORE_ORIG_SCREEN
+    cb = exiting ? &g_cbOrig : &g_cbNonTermcap;
+#else
+    cb = &g_cbNonTermcap;
+#endif
+    RestoreConsoleBuffer(cb, p_rs);
+    SetConsoleCursorInfo(g_hConOut, &g_cci);
+
+    if (p_rs || exiting)
+    {
+	/*
+	 * Clear anything that happens to be on the current line.
+	 */
+	coord.X = 0;
+	coord.Y = (SHORT) (p_rs ? cb->Info.dwCursorPosition.Y : (Rows - 1));
+	FillConsoleOutputCharacter(g_hConOut, ' ',
+		cb->Info.dwSize.X, coord, &dwDummy);
+	/*
+	 * The following is just for aesthetics.  If we are exiting without
+	 * restoring the screen, then we want to have a prompt string
+	 * appear at the bottom line.  However, the command interpreter
+	 * seems to always advance the cursor one line before displaying
+	 * the prompt string, which causes the screen to scroll.  To
+	 * counter this, move the cursor up one line before exiting.
+	 */
+	if (exiting && !p_rs)
+	    coord.Y--;
+	/*
+	 * Position the cursor at the leftmost column of the desired row.
+	 */
+	SetConsoleCursorPosition(g_hConOut, coord);
+    }
+
+    g_fTermcapMode = FALSE;
+}
+#endif /* FEAT_GUI_W32 */
+
+
+#ifdef FEAT_GUI_W32
+    void
+mch_write(
+    char_u  *s,
+    int	    len)
+{
+    /* never used */
+}
+
+#else
+
+/*
+ * clear `n' chars, starting from `coord'
+ */
+    static void
+clear_chars(
+    COORD coord,
+    DWORD n)
+{
+    DWORD dwDummy;
+
+    FillConsoleOutputCharacter(g_hConOut, ' ', n, coord, &dwDummy);
+    FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, n, coord, &dwDummy);
+}
+
+
+/*
+ * Clear the screen
+ */
+    static void
+clear_screen(void)
+{
+    g_coord.X = g_coord.Y = 0;
+    clear_chars(g_coord, Rows * Columns);
+}
+
+
+/*
+ * Clear to end of display
+ */
+    static void
+clear_to_end_of_display(void)
+{
+    clear_chars(g_coord, (Rows - g_coord.Y - 1)
+					   * Columns + (Columns - g_coord.X));
+}
+
+
+/*
+ * Clear to end of line
+ */
+    static void
+clear_to_end_of_line(void)
+{
+    clear_chars(g_coord, Columns - g_coord.X);
+}
+
+
+/*
+ * Scroll the scroll region up by `cLines' lines
+ */
+    static void
+scroll(
+    unsigned cLines)
+{
+    COORD oldcoord = g_coord;
+
+    gotoxy(g_srScrollRegion.Left + 1, g_srScrollRegion.Top + 1);
+    delete_lines(cLines);
+
+    g_coord = oldcoord;
+}
+
+
+/*
+ * Set the scroll region
+ */
+    static void
+set_scroll_region(
+    unsigned left,
+    unsigned top,
+    unsigned right,
+    unsigned bottom)
+{
+    if (left >= right
+	    || top >= bottom
+	    || right > (unsigned) Columns - 1
+	    || bottom > (unsigned) Rows - 1)
+	return;
+
+    g_srScrollRegion.Left =   left;
+    g_srScrollRegion.Top =    top;
+    g_srScrollRegion.Right =  right;
+    g_srScrollRegion.Bottom = bottom;
+}
+
+
+/*
+ * Insert `cLines' lines at the current cursor position
+ */
+    static void
+insert_lines(
+    unsigned cLines)
+{
+    SMALL_RECT	    source;
+    COORD	    dest;
+    CHAR_INFO	    fill;
+
+    dest.X = 0;
+    dest.Y = g_coord.Y + cLines;
+
+    source.Left   = 0;
+    source.Top	  = g_coord.Y;
+    source.Right  = g_srScrollRegion.Right;
+    source.Bottom = g_srScrollRegion.Bottom - cLines;
+
+    fill.Char.AsciiChar = ' ';
+    fill.Attributes = g_attrCurrent;
+
+    ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
+
+    /* Here we have to deal with a win32 console flake: If the scroll
+     * region looks like abc and we scroll c to a and fill with d we get
+     * cbd... if we scroll block c one line at a time to a, we get cdd...
+     * vim expects cdd consistently... So we have to deal with that
+     * here... (this also occurs scrolling the same way in the other
+     * direction).  */
+
+    if (source.Bottom < dest.Y)
+    {
+	COORD coord;
+
+	coord.X = 0;
+	coord.Y = source.Bottom;
+	clear_chars(coord, Columns * (dest.Y - source.Bottom));
+    }
+}
+
+
+/*
+ * Delete `cLines' lines at the current cursor position
+ */
+    static void
+delete_lines(
+    unsigned cLines)
+{
+    SMALL_RECT	    source;
+    COORD	    dest;
+    CHAR_INFO	    fill;
+    int		    nb;
+
+    dest.X = 0;
+    dest.Y = g_coord.Y;
+
+    source.Left   = 0;
+    source.Top	  = g_coord.Y + cLines;
+    source.Right  = g_srScrollRegion.Right;
+    source.Bottom = g_srScrollRegion.Bottom;
+
+    fill.Char.AsciiChar = ' ';
+    fill.Attributes = g_attrCurrent;
+
+    ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
+
+    /* Here we have to deal with a win32 console flake: If the scroll
+     * region looks like abc and we scroll c to a and fill with d we get
+     * cbd... if we scroll block c one line at a time to a, we get cdd...
+     * vim expects cdd consistently... So we have to deal with that
+     * here... (this also occurs scrolling the same way in the other
+     * direction).  */
+
+    nb = dest.Y + (source.Bottom - source.Top) + 1;
+
+    if (nb < source.Top)
+    {
+	COORD coord;
+
+	coord.X = 0;
+	coord.Y = nb;
+	clear_chars(coord, Columns * (source.Top - nb));
+    }
+}
+
+
+/*
+ * Set the cursor position
+ */
+    static void
+gotoxy(
+    unsigned x,
+    unsigned y)
+{
+    if (x < 1 || x > (unsigned)Columns || y < 1 || y > (unsigned)Rows)
+	return;
+
+    /* external cursor coords are 1-based; internal are 0-based */
+    g_coord.X = x - 1;
+    g_coord.Y = y - 1;
+    SetConsoleCursorPosition(g_hConOut, g_coord);
+}
+
+
+/*
+ * Set the current text attribute = (foreground | background)
+ * See ../doc/os_win32.txt for the numbers.
+ */
+    static void
+textattr(
+    WORD wAttr)
+{
+    g_attrCurrent = wAttr;
+
+    SetConsoleTextAttribute(g_hConOut, wAttr);
+}
+
+
+    static void
+textcolor(
+    WORD wAttr)
+{
+    g_attrCurrent = (g_attrCurrent & 0xf0) + wAttr;
+
+    SetConsoleTextAttribute(g_hConOut, g_attrCurrent);
+}
+
+
+    static void
+textbackground(
+    WORD wAttr)
+{
+    g_attrCurrent = (g_attrCurrent & 0x0f) + (wAttr << 4);
+
+    SetConsoleTextAttribute(g_hConOut, g_attrCurrent);
+}
+
+
+/*
+ * restore the default text attribute (whatever we started with)
+ */
+    static void
+normvideo()
+{
+    textattr(g_attrDefault);
+}
+
+
+static WORD g_attrPreStandout = 0;
+
+/*
+ * Make the text standout, by brightening it
+ */
+    static void
+standout(void)
+{
+    g_attrPreStandout = g_attrCurrent;
+    textattr((WORD) (g_attrCurrent|FOREGROUND_INTENSITY|BACKGROUND_INTENSITY));
+}
+
+
+/*
+ * Turn off standout mode
+ */
+    static void
+standend()
+{
+    if (g_attrPreStandout)
+    {
+	textattr(g_attrPreStandout);
+	g_attrPreStandout = 0;
+    }
+}
+
+
+/*
+ * Set normal fg/bg color, based on T_ME.  Called whem t_me has been set.
+ */
+    void
+mch_set_normal_colors()
+{
+    char_u	*p;
+    int		n;
+
+    cterm_normal_fg_color = (g_attrDefault & 0xf) + 1;
+    cterm_normal_bg_color = ((g_attrDefault >> 4) & 0xf) + 1;
+    if (T_ME[0] == ESC && T_ME[1] == '|')
+    {
+	p = T_ME + 2;
+	n = getdigits(&p);
+	if (*p == 'm' && n > 0)
+	{
+	    cterm_normal_fg_color = (n & 0xf) + 1;
+	    cterm_normal_bg_color = ((n >> 4) & 0xf) + 1;
+	}
+    }
+}
+
+
+/*
+ * visual bell: flash the screen
+ */
+    static void
+visual_bell()
+{
+    COORD   coordOrigin = {0, 0};
+    WORD    attrFlash = ~g_attrCurrent & 0xff;
+
+    DWORD   dwDummy;
+    LPWORD  oldattrs = (LPWORD)alloc(Rows * Columns * sizeof(WORD));
+
+    if (oldattrs == NULL)
+	return;
+    ReadConsoleOutputAttribute(g_hConOut, oldattrs, Rows * Columns,
+			       coordOrigin, &dwDummy);
+    FillConsoleOutputAttribute(g_hConOut, attrFlash, Rows * Columns,
+			       coordOrigin, &dwDummy);
+
+    Sleep(15);	    /* wait for 15 msec */
+    WriteConsoleOutputAttribute(g_hConOut, oldattrs, Rows * Columns,
+				coordOrigin, &dwDummy);
+    vim_free(oldattrs);
+}
+
+
+/*
+ * Make the cursor visible or invisible
+ */
+    static void
+cursor_visible(
+    BOOL fVisible)
+{
+    s_cursor_visible = fVisible;
+#ifdef MCH_CURSOR_SHAPE
+    mch_update_cursor();
+#endif
+}
+
+
+/*
+ * write `cchToWrite' characters in `pchBuf' to the screen
+ * Returns the number of characters actually written (at least one).
+ */
+    static BOOL
+write_chars(
+    LPCSTR pchBuf,
+    DWORD  cchToWrite)
+{
+    COORD coord = g_coord;
+    DWORD written;
+
+    FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cchToWrite,
+				coord, &written);
+    /* When writing fails or didn't write a single character, pretend one
+     * character was written, otherwise we get stuck. */
+    if (WriteConsoleOutputCharacter(g_hConOut, pchBuf, cchToWrite,
+				coord, &written) == 0
+	    || written == 0)
+	written = 1;
+
+    g_coord.X += (SHORT) written;
+
+    while (g_coord.X > g_srScrollRegion.Right)
+    {
+	g_coord.X -= (SHORT) Columns;
+	if (g_coord.Y < g_srScrollRegion.Bottom)
+	    g_coord.Y++;
+    }
+
+    gotoxy(g_coord.X + 1, g_coord.Y + 1);
+
+    return written;
+}
+
+
+/*
+ * mch_write(): write the output buffer to the screen, translating ESC
+ * sequences into calls to console output routines.
+ */
+    void
+mch_write(
+    char_u  *s,
+    int	    len)
+{
+    s[len] = NUL;
+
+    if (!term_console)
+    {
+	write(1, s, (unsigned)len);
+	return;
+    }
+
+    /* translate ESC | sequences into faked bios calls */
+    while (len--)
+    {
+	/* optimization: use one single write_chars for runs of text,
+	 * rather than once per character  It ain't curses, but it helps. */
+	DWORD  prefix = strcspn(s, "\n\r\b\a\033");
+
+	if (p_wd)
+	{
+	    WaitForChar(p_wd);
+	    if (prefix != 0)
+		prefix = 1;
+	}
+
+	if (prefix != 0)
+	{
+	    DWORD nWritten;
+
+	    nWritten = write_chars(s, prefix);
+#ifdef MCH_WRITE_DUMP
+	    if (fdDump)
+	    {
+		fputc('>', fdDump);
+		fwrite(s, sizeof(char_u), nWritten, fdDump);
+		fputs("<\n", fdDump);
+	    }
+#endif
+	    len -= (nWritten - 1);
+	    s += nWritten;
+	}
+	else if (s[0] == '\n')
+	{
+	    /* \n, newline: go to the beginning of the next line or scroll */
+	    if (g_coord.Y == g_srScrollRegion.Bottom)
+	    {
+		scroll(1);
+		gotoxy(g_srScrollRegion.Left + 1, g_srScrollRegion.Bottom + 1);
+	    }
+	    else
+	    {
+		gotoxy(g_srScrollRegion.Left + 1, g_coord.Y + 2);
+	    }
+#ifdef MCH_WRITE_DUMP
+	    if (fdDump)
+		fputs("\\n\n", fdDump);
+#endif
+	    s++;
+	}
+	else if (s[0] == '\r')
+	{
+	    /* \r, carriage return: go to beginning of line */
+	    gotoxy(g_srScrollRegion.Left+1, g_coord.Y + 1);
+#ifdef MCH_WRITE_DUMP
+	    if (fdDump)
+		fputs("\\r\n", fdDump);
+#endif
+	    s++;
+	}
+	else if (s[0] == '\b')
+	{
+	    /* \b, backspace: move cursor one position left */
+	    if (g_coord.X > g_srScrollRegion.Left)
+		g_coord.X--;
+	    else if (g_coord.Y > g_srScrollRegion.Top)
+	    {
+		g_coord.X = g_srScrollRegion.Right;
+		g_coord.Y--;
+	    }
+	    gotoxy(g_coord.X + 1, g_coord.Y + 1);
+#ifdef MCH_WRITE_DUMP
+	    if (fdDump)
+		fputs("\\b\n", fdDump);
+#endif
+	    s++;
+	}
+	else if (s[0] == '\a')
+	{
+	    /* \a, bell */
+	    MessageBeep(0xFFFFFFFF);
+#ifdef MCH_WRITE_DUMP
+	    if (fdDump)
+		fputs("\\a\n", fdDump);
+#endif
+	    s++;
+	}
+	else if (s[0] == ESC && len >= 3-1 && s[1] == '|')
+	{
+#ifdef MCH_WRITE_DUMP
+	    char_u* old_s = s;
+#endif
+	    char_u* p;
+	    int arg1 = 0, arg2 = 0;
+
+	    switch (s[2])
+	    {
+	    /* one or two numeric arguments, separated by ';' */
+
+	    case '0': case '1': case '2': case '3': case '4':
+	    case '5': case '6': case '7': case '8': case '9':
+		p = s + 2;
+		arg1 = getdigits(&p);	    /* no check for length! */
+		if (p > s + len)
+		    break;
+
+		if (*p == ';')
+		{
+		    ++p;
+		    arg2 = getdigits(&p);   /* no check for length! */
+		    if (p > s + len)
+			break;
+
+		    if (*p == 'H')
+			gotoxy(arg2, arg1);
+		    else if (*p == 'r')
+			set_scroll_region(0, arg1 - 1, Columns - 1, arg2 - 1);
+		}
+		else if (*p == 'A')
+		{
+		    /* move cursor up arg1 lines in same column */
+		    gotoxy(g_coord.X + 1,
+			   max(g_srScrollRegion.Top, g_coord.Y - arg1) + 1);
+		}
+		else if (*p == 'C')
+		{
+		    /* move cursor right arg1 columns in same line */
+		    gotoxy(min(g_srScrollRegion.Right, g_coord.X + arg1) + 1,
+			   g_coord.Y + 1);
+		}
+		else if (*p == 'H')
+		{
+		    gotoxy(1, arg1);
+		}
+		else if (*p == 'L')
+		{
+		    insert_lines(arg1);
+		}
+		else if (*p == 'm')
+		{
+		    if (arg1 == 0)
+			normvideo();
+		    else
+			textattr((WORD) arg1);
+		}
+		else if (*p == 'f')
+		{
+		    textcolor((WORD) arg1);
+		}
+		else if (*p == 'b')
+		{
+		    textbackground((WORD) arg1);
+		}
+		else if (*p == 'M')
+		{
+		    delete_lines(arg1);
+		}
+
+		len -= p - s;
+		s = p + 1;
+		break;
+
+
+	    /* Three-character escape sequences */
+
+	    case 'A':
+		/* move cursor up one line in same column */
+		gotoxy(g_coord.X + 1,
+		       max(g_srScrollRegion.Top, g_coord.Y - 1) + 1);
+		goto got3;
+
+	    case 'B':
+		visual_bell();
+		goto got3;
+
+	    case 'C':
+		/* move cursor right one column in same line */
+		gotoxy(min(g_srScrollRegion.Right, g_coord.X + 1) + 1,
+		       g_coord.Y + 1);
+		goto got3;
+
+	    case 'E':
+		termcap_mode_end();
+		goto got3;
+
+	    case 'F':
+		standout();
+		goto got3;
+
+	    case 'f':
+		standend();
+		goto got3;
+
+	    case 'H':
+		gotoxy(1, 1);
+		goto got3;
+
+	    case 'j':
+		clear_to_end_of_display();
+		goto got3;
+
+	    case 'J':
+		clear_screen();
+		goto got3;
+
+	    case 'K':
+		clear_to_end_of_line();
+		goto got3;
+
+	    case 'L':
+		insert_lines(1);
+		goto got3;
+
+	    case 'M':
+		delete_lines(1);
+		goto got3;
+
+	    case 'S':
+		termcap_mode_start();
+		goto got3;
+
+	    case 'V':
+		cursor_visible(TRUE);
+		goto got3;
+
+	    case 'v':
+		cursor_visible(FALSE);
+		goto got3;
+
+	    got3:
+		s += 3;
+		len -= 2;
+	    }
+
+#ifdef MCH_WRITE_DUMP
+	    if (fdDump)
+	    {
+		fputs("ESC | ", fdDump);
+		fwrite(old_s + 2, sizeof(char_u), s - old_s - 2, fdDump);
+		fputc('\n', fdDump);
+	    }
+#endif
+	}
+	else
+	{
+	    /* Write a single character */
+	    DWORD nWritten;
+
+	    nWritten = write_chars(s, 1);
+#ifdef MCH_WRITE_DUMP
+	    if (fdDump)
+	    {
+		fputc('>', fdDump);
+		fwrite(s, sizeof(char_u), nWritten, fdDump);
+		fputs("<\n", fdDump);
+	    }
+#endif
+
+	    len -= (nWritten - 1);
+	    s += nWritten;
+	}
+    }
+
+#ifdef MCH_WRITE_DUMP
+    if (fdDump)
+	fflush(fdDump);
+#endif
+}
+
+#endif /* FEAT_GUI_W32 */
+
+
+/*
+ * Delay for half a second.
+ */
+    void
+mch_delay(
+    long    msec,
+    int	    ignoreinput)
+{
+#ifdef FEAT_GUI_W32
+    Sleep((int)msec);	    /* never wait for input */
+#else
+    if (ignoreinput)
+	Sleep((int)msec);
+    else
+	WaitForChar(msec);
+#endif
+}
+
+
+/*
+ * this version of remove is not scared by a readonly (backup) file
+ * Return 0 for success, -1 for failure.
+ */
+    int
+mch_remove(char_u *name)
+{
+#ifdef FEAT_MBYTE
+    WCHAR	*wn = NULL;
+    int		n;
+
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	wn = enc_to_ucs2(name, NULL);
+	if (wn != NULL)
+	{
+	    SetFileAttributesW(wn, FILE_ATTRIBUTE_NORMAL);
+	    n = DeleteFileW(wn) ? 0 : -1;
+	    vim_free(wn);
+	    if (n == 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+		return n;
+	    /* Retry with non-wide function (for Windows 98). */
+	}
+    }
+#endif
+    SetFileAttributes(name, FILE_ATTRIBUTE_NORMAL);
+    return DeleteFile(name) ? 0 : -1;
+}
+
+
+/*
+ * check for an "interrupt signal": CTRL-break or CTRL-C
+ */
+    void
+mch_breakcheck()
+{
+#ifndef FEAT_GUI_W32	    /* never used */
+    if (g_fCtrlCPressed || g_fCBrkPressed)
+    {
+	g_fCtrlCPressed = g_fCBrkPressed = FALSE;
+	got_int = TRUE;
+    }
+#endif
+}
+
+
+/*
+ * How much memory is available?
+ * Return sum of available physical and page file memory.
+ */
+    long_u
+mch_avail_mem(
+    int special)
+{
+    MEMORYSTATUS	ms;
+
+    ms.dwLength = sizeof(MEMORYSTATUS);
+    GlobalMemoryStatus(&ms);
+    return (long_u) (ms.dwAvailPhys + ms.dwAvailPageFile);
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Same code as below, but with wide functions and no comments.
+ * Return 0 for success, non-zero for failure.
+ */
+    int
+mch_wrename(WCHAR *wold, WCHAR *wnew)
+{
+    WCHAR	*p;
+    int		i;
+    WCHAR	szTempFile[_MAX_PATH + 1];
+    WCHAR	szNewPath[_MAX_PATH + 1];
+    HANDLE	hf;
+
+    if (!mch_windows95())
+    {
+	p = wold;
+	for (i = 0; wold[i] != NUL; ++i)
+	    if ((wold[i] == '/' || wold[i] == '\\' || wold[i] == ':')
+		    && wold[i + 1] != 0)
+		p = wold + i + 1;
+	if ((int)(wold + i - p) < 8 || p[6] != '~')
+	    return (MoveFileW(wold, wnew) == 0);
+    }
+
+    if (GetFullPathNameW(wnew, _MAX_PATH, szNewPath, &p) == 0 || p == NULL)
+	return -1;
+    *p = NUL;
+
+    if (GetTempFileNameW(szNewPath, L"VIM", 0, szTempFile) == 0)
+	return -2;
+
+    if (!DeleteFileW(szTempFile))
+	return -3;
+
+    if (!MoveFileW(wold, szTempFile))
+	return -4;
+
+    if ((hf = CreateFileW(wold, GENERIC_WRITE, 0, NULL, CREATE_NEW,
+		    FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
+	return -5;
+    if (!CloseHandle(hf))
+	return -6;
+
+    if (!MoveFileW(szTempFile, wnew))
+    {
+	(void)MoveFileW(szTempFile, wold);
+	return -7;
+    }
+
+    DeleteFileW(szTempFile);
+
+    if (!DeleteFileW(wold))
+	return -8;
+
+    return 0;
+}
+#endif
+
+
+/*
+ * mch_rename() works around a bug in rename (aka MoveFile) in
+ * Windows 95: rename("foo.bar", "foo.bar~") will generate a
+ * file whose short file name is "FOO.BAR" (its long file name will
+ * be correct: "foo.bar~").  Because a file can be accessed by
+ * either its SFN or its LFN, "foo.bar" has effectively been
+ * renamed to "foo.bar", which is not at all what was wanted.  This
+ * seems to happen only when renaming files with three-character
+ * extensions by appending a suffix that does not include ".".
+ * Windows NT gets it right, however, with an SFN of "FOO~1.BAR".
+ *
+ * There is another problem, which isn't really a bug but isn't right either:
+ * When renaming "abcdef~1.txt" to "abcdef~1.txt~", the short name can be
+ * "abcdef~1.txt" again.  This has been reported on Windows NT 4.0 with
+ * service pack 6.  Doesn't seem to happen on Windows 98.
+ *
+ * Like rename(), returns 0 upon success, non-zero upon failure.
+ * Should probably set errno appropriately when errors occur.
+ */
+    int
+mch_rename(
+    const char	*pszOldFile,
+    const char	*pszNewFile)
+{
+    char	szTempFile[_MAX_PATH+1];
+    char	szNewPath[_MAX_PATH+1];
+    char	*pszFilePart;
+    HANDLE	hf;
+#ifdef FEAT_MBYTE
+    WCHAR	*wold = NULL;
+    WCHAR	*wnew = NULL;
+    int		retval = -1;
+
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	wold = enc_to_ucs2((char_u *)pszOldFile, NULL);
+	wnew = enc_to_ucs2((char_u *)pszNewFile, NULL);
+	if (wold != NULL && wnew != NULL)
+	    retval = mch_wrename(wold, wnew);
+	vim_free(wold);
+	vim_free(wnew);
+	if (retval == 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+	    return retval;
+	/* Retry with non-wide function (for Windows 98). */
+    }
+#endif
+
+    /*
+     * No need to play tricks if not running Windows 95, unless the file name
+     * contains a "~" as the seventh character.
+     */
+    if (!mch_windows95())
+    {
+	pszFilePart = (char *)gettail((char_u *)pszOldFile);
+	if (STRLEN(pszFilePart) < 8 || pszFilePart[6] != '~')
+	    return rename(pszOldFile, pszNewFile);
+    }
+
+    /* Get base path of new file name.  Undocumented feature: If pszNewFile is
+     * a directory, no error is returned and pszFilePart will be NULL. */
+    if (GetFullPathName(pszNewFile, _MAX_PATH, szNewPath, &pszFilePart) == 0
+	    || pszFilePart == NULL)
+	return -1;
+    *pszFilePart = NUL;
+
+    /* Get (and create) a unique temporary file name in directory of new file */
+    if (GetTempFileName(szNewPath, "VIM", 0, szTempFile) == 0)
+	return -2;
+
+    /* blow the temp file away */
+    if (!DeleteFile(szTempFile))
+	return -3;
+
+    /* rename old file to the temp file */
+    if (!MoveFile(pszOldFile, szTempFile))
+	return -4;
+
+    /* now create an empty file called pszOldFile; this prevents the operating
+     * system using pszOldFile as an alias (SFN) if we're renaming within the
+     * same directory.  For example, we're editing a file called
+     * filename.asc.txt by its SFN, filena~1.txt.  If we rename filena~1.txt
+     * to filena~1.txt~ (i.e., we're making a backup while writing it), the
+     * SFN for filena~1.txt~ will be filena~1.txt, by default, which will
+     * cause all sorts of problems later in buf_write.  So, we create an empty
+     * file called filena~1.txt and the system will have to find some other
+     * SFN for filena~1.txt~, such as filena~2.txt
+     */
+    if ((hf = CreateFile(pszOldFile, GENERIC_WRITE, 0, NULL, CREATE_NEW,
+		    FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
+	return -5;
+    if (!CloseHandle(hf))
+	return -6;
+
+    /* rename the temp file to the new file */
+    if (!MoveFile(szTempFile, pszNewFile))
+    {
+	/* Renaming failed.  Rename the file back to its old name, so that it
+	 * looks like nothing happened. */
+	(void)MoveFile(szTempFile, pszOldFile);
+
+	return -7;
+    }
+
+    /* Seems to be left around on Novell filesystems */
+    DeleteFile(szTempFile);
+
+    /* finally, remove the empty old file */
+    if (!DeleteFile(pszOldFile))
+	return -8;
+
+    return 0;	/* success */
+}
+
+/*
+ * Get the default shell for the current hardware platform
+ */
+    char *
+default_shell()
+{
+    char* psz = NULL;
+
+    PlatformId();
+
+    if (g_PlatformId == VER_PLATFORM_WIN32_NT)		/* Windows NT */
+	psz = "cmd.exe";
+    else if (g_PlatformId == VER_PLATFORM_WIN32_WINDOWS) /* Windows 95 */
+	psz = "command.com";
+
+    return psz;
+}
+
+/*
+ * mch_access() extends access() to do more detailed check on network drives.
+ * Returns 0 if file "n" has access rights according to "p", -1 otherwise.
+ */
+    int
+mch_access(char *n, int p)
+{
+    HANDLE	hFile;
+    DWORD	am;
+    int		retval = -1;	    /* default: fail */
+#ifdef FEAT_MBYTE
+    WCHAR	*wn = NULL;
+
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+	wn = enc_to_ucs2(n, NULL);
+#endif
+
+    if (mch_isdir(n))
+    {
+	char TempName[_MAX_PATH + 16] = "";
+#ifdef FEAT_MBYTE
+	WCHAR TempNameW[_MAX_PATH + 16] = L"";
+#endif
+
+	if (p & R_OK)
+	{
+	    /* Read check is performed by seeing if we can do a find file on
+	     * the directory for any file. */
+#ifdef FEAT_MBYTE
+	    if (wn != NULL)
+	    {
+		int		    i;
+		WIN32_FIND_DATAW    d;
+
+		for (i = 0; i < _MAX_PATH && wn[i] != 0; ++i)
+		    TempNameW[i] = wn[i];
+		if (TempNameW[i - 1] != '\\' && TempNameW[i - 1] != '/')
+		    TempNameW[i++] = '\\';
+		TempNameW[i++] = '*';
+		TempNameW[i++] = 0;
+
+		hFile = FindFirstFileW(TempNameW, &d);
+		if (hFile == INVALID_HANDLE_VALUE)
+		{
+		    if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+			goto getout;
+
+		    /* Retry with non-wide function (for Windows 98). */
+		    vim_free(wn);
+		    wn = NULL;
+		}
+		else
+		    (void)FindClose(hFile);
+	    }
+	    if (wn == NULL)
+#endif
+	    {
+		char		    *pch;
+		WIN32_FIND_DATA	    d;
+
+		STRNCPY(TempName, n, _MAX_PATH);
+		pch = TempName + STRLEN(TempName) - 1;
+		if (*pch != '\\' && *pch != '/')
+		    *++pch = '\\';
+		*++pch = '*';
+		*++pch = NUL;
+
+		hFile = FindFirstFile(TempName, &d);
+		if (hFile == INVALID_HANDLE_VALUE)
+		    goto getout;
+		(void)FindClose(hFile);
+	    }
+	}
+
+	if (p & W_OK)
+	{
+	    /* Trying to create a temporary file in the directory should catch
+	     * directories on read-only network shares.  However, in
+	     * directories whose ACL allows writes but denies deletes will end
+	     * up keeping the temporary file :-(. */
+#ifdef FEAT_MBYTE
+	    if (wn != NULL)
+	    {
+		if (!GetTempFileNameW(wn, L"VIM", 0, TempNameW))
+		{
+		    if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+			goto getout;
+
+		    /* Retry with non-wide function (for Windows 98). */
+		    vim_free(wn);
+		    wn = NULL;
+		}
+		else
+		    DeleteFileW(TempNameW);
+	    }
+	    if (wn == NULL)
+#endif
+	    {
+		if (!GetTempFileName(n, "VIM", 0, TempName))
+		    goto getout;
+		mch_remove((char_u *)TempName);
+	    }
+	}
+    }
+    else
+    {
+	/* Trying to open the file for the required access does ACL, read-only
+	 * network share, and file attribute checks.  */
+	am = ((p & W_OK) ? GENERIC_WRITE : 0)
+		| ((p & R_OK) ? GENERIC_READ : 0);
+#ifdef FEAT_MBYTE
+	if (wn != NULL)
+	{
+	    hFile = CreateFileW(wn, am, 0, NULL, OPEN_EXISTING, 0, NULL);
+	    if (hFile == INVALID_HANDLE_VALUE
+			      && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+	    {
+		/* Retry with non-wide function (for Windows 98). */
+		vim_free(wn);
+		wn = NULL;
+	    }
+	}
+	if (wn == NULL)
+#endif
+	    hFile = CreateFile(n, am, 0, NULL, OPEN_EXISTING, 0, NULL);
+	if (hFile == INVALID_HANDLE_VALUE)
+	    goto getout;
+	CloseHandle(hFile);
+    }
+
+    retval = 0;	    /* success */
+getout:
+#ifdef FEAT_MBYTE
+    vim_free(wn);
+#endif
+    return retval;
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Version of open() that may use ucs2 file name.
+ */
+    int
+mch_open(char *name, int flags, int mode)
+{
+    WCHAR	*wn;
+    int		f;
+
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage
+# ifdef __BORLANDC__
+	    /* Wide functions of Borland C 5.5 do not work on Windows 98. */
+	    && g_PlatformId == VER_PLATFORM_WIN32_NT
+# endif
+       )
+    {
+	wn = enc_to_ucs2(name, NULL);
+	if (wn != NULL)
+	{
+	    f = _wopen(wn, flags, mode);
+	    vim_free(wn);
+	    if (f >= 0)
+		return f;
+	    /* Retry with non-wide function (for Windows 98). Can't use
+	     * GetLastError() here and it's unclear what errno gets set to if
+	     * the _wopen() fails for missing wide functions. */
+	}
+    }
+
+    return open(name, flags, mode);
+}
+
+/*
+ * Version of fopen() that may use ucs2 file name.
+ */
+    FILE *
+mch_fopen(char *name, char *mode)
+{
+    WCHAR	*wn, *wm;
+    FILE	*f = NULL;
+
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage
+# ifdef __BORLANDC__
+	    /* Wide functions of Borland C 5.5 do not work on Windows 98. */
+	    && g_PlatformId == VER_PLATFORM_WIN32_NT
+# endif
+       )
+    {
+	wn = enc_to_ucs2(name, NULL);
+	wm = enc_to_ucs2(mode, NULL);
+	if (wn != NULL && wm != NULL)
+	    f = _wfopen(wn, wm);
+	vim_free(wn);
+	vim_free(wm);
+	if (f != NULL)
+	    return f;
+	/* Retry with non-wide function (for Windows 98). Can't use
+	 * GetLastError() here and it's unclear what errno gets set to if
+	 * the _wfopen() fails for missing wide functions. */
+    }
+
+    return fopen(name, mode);
+}
+#endif
+
+#ifdef FEAT_MBYTE
+/*
+ * SUB STREAM (aka info stream) handling:
+ *
+ * NTFS can have sub streams for each file.  Normal contents of file is
+ * stored in the main stream, and extra contents (author information and
+ * title and so on) can be stored in sub stream.  After Windows 2000, user
+ * can access and store those informations in sub streams via explorer's
+ * property menuitem in right click menu.  Those informations in sub streams
+ * were lost when copying only the main stream.  So we have to copy sub
+ * streams.
+ *
+ * Incomplete explanation:
+ *	http://msdn.microsoft.com/library/en-us/dnw2k/html/ntfs5.asp
+ * More useful info and an example:
+ *	http://www.sysinternals.com/ntw2k/source/misc.shtml#streams
+ */
+
+/*
+ * Copy info stream data "substream".  Read from the file with BackupRead(sh)
+ * and write to stream "substream" of file "to".
+ * Errors are ignored.
+ */
+    static void
+copy_substream(HANDLE sh, void *context, WCHAR *to, WCHAR *substream, long len)
+{
+    HANDLE  hTo;
+    WCHAR   *to_name;
+
+    to_name = malloc((wcslen(to) + wcslen(substream) + 1) * sizeof(WCHAR));
+    wcscpy(to_name, to);
+    wcscat(to_name, substream);
+
+    hTo = CreateFileW(to_name, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
+						 FILE_ATTRIBUTE_NORMAL, NULL);
+    if (hTo != INVALID_HANDLE_VALUE)
+    {
+	long	done;
+	DWORD	todo;
+	DWORD	readcnt, written;
+	char	buf[4096];
+
+	/* Copy block of bytes at a time.  Abort when something goes wrong. */
+	for (done = 0; done < len; done += written)
+	{
+	    /* (size_t) cast for Borland C 5.5 */
+	    todo = (size_t)(len - done) > sizeof(buf) ? sizeof(buf)
+						       : (size_t)(len - done);
+	    if (!BackupRead(sh, (LPBYTE)buf, todo, &readcnt,
+						       FALSE, FALSE, context)
+		    || readcnt != todo
+		    || !WriteFile(hTo, buf, todo, &written, NULL)
+		    || written != todo)
+		break;
+	}
+	CloseHandle(hTo);
+    }
+
+    free(to_name);
+}
+
+/*
+ * Copy info streams from file "from" to file "to".
+ */
+    static void
+copy_infostreams(char_u *from, char_u *to)
+{
+    WCHAR		*fromw;
+    WCHAR		*tow;
+    HANDLE		sh;
+    WIN32_STREAM_ID	sid;
+    int			headersize;
+    WCHAR		streamname[_MAX_PATH];
+    DWORD		readcount;
+    void		*context = NULL;
+    DWORD		lo, hi;
+    int			len;
+
+    /* Convert the file names to wide characters. */
+    fromw = enc_to_ucs2(from, NULL);
+    tow = enc_to_ucs2(to, NULL);
+    if (fromw != NULL && tow != NULL)
+    {
+	/* Open the file for reading. */
+	sh = CreateFileW(fromw, GENERIC_READ, FILE_SHARE_READ, NULL,
+			     OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+	if (sh != INVALID_HANDLE_VALUE)
+	{
+	    /* Use BackupRead() to find the info streams.  Repeat until we
+	     * have done them all.*/
+	    for (;;)
+	    {
+		/* Get the header to find the length of the stream name.  If
+		 * the "readcount" is zero we have done all info streams. */
+		ZeroMemory(&sid, sizeof(WIN32_STREAM_ID));
+		headersize = (char *)&sid.cStreamName - (char *)&sid.dwStreamId;
+		if (!BackupRead(sh, (LPBYTE)&sid, headersize,
+					   &readcount, FALSE, FALSE, &context)
+			|| readcount == 0)
+		    break;
+
+		/* We only deal with streams that have a name.  The normal
+		 * file data appears to be without a name, even though docs
+		 * suggest it is called "::$DATA". */
+		if (sid.dwStreamNameSize > 0)
+		{
+		    /* Read the stream name. */
+		    if (!BackupRead(sh, (LPBYTE)streamname,
+							 sid.dwStreamNameSize,
+					  &readcount, FALSE, FALSE, &context))
+			break;
+
+		    /* Copy an info stream with a name ":anything:$DATA".
+		     * Skip "::$DATA", it has no stream name (examples suggest
+		     * it might be used for the normal file contents).
+		     * Note that BackupRead() counts bytes, but the name is in
+		     * wide characters. */
+		    len = readcount / sizeof(WCHAR);
+		    streamname[len] = 0;
+		    if (len > 7 && wcsicmp(streamname + len - 6,
+							      L":$DATA") == 0)
+		    {
+			streamname[len - 6] = 0;
+			copy_substream(sh, &context, tow, streamname,
+						      (long)sid.Size.LowPart);
+		    }
+		}
+
+		/* Advance to the next stream.  We might try seeking too far,
+		 * but BackupSeek() doesn't skip over stream borders, thus
+		 * that's OK. */
+		(void)BackupSeek(sh, sid.Size.LowPart, sid.Size.HighPart,
+							  &lo, &hi, &context);
+	    }
+
+	    /* Clear the context. */
+	    (void)BackupRead(sh, NULL, 0, &readcount, TRUE, FALSE, &context);
+
+	    CloseHandle(sh);
+	}
+    }
+    vim_free(fromw);
+    vim_free(tow);
+}
+#endif
+
+/*
+ * Copy file attributes from file "from" to file "to".
+ * For Windows NT and later we copy info streams.
+ * Always returns zero, errors are ignored.
+ */
+    int
+mch_copy_file_attribute(char_u *from, char_u *to)
+{
+#ifdef FEAT_MBYTE
+    /* File streams only work on Windows NT and later. */
+    PlatformId();
+    if (g_PlatformId == VER_PLATFORM_WIN32_NT)
+	copy_infostreams(from, to);
+#endif
+    return 0;
+}
+
+#if defined(MYRESETSTKOFLW) || defined(PROTO)
+/*
+ * Recreate a destroyed stack guard page in win32.
+ * Written by Benjamin Peterson.
+ */
+
+/* These magic numbers are from the MS header files */
+#define MIN_STACK_WIN9X 17
+#define MIN_STACK_WINNT 2
+
+/*
+ * This function does the same thing as _resetstkoflw(), which is only
+ * available in DevStudio .net and later.
+ * Returns 0 for failure, 1 for success.
+ */
+    int
+myresetstkoflw(void)
+{
+    BYTE	*pStackPtr;
+    BYTE	*pGuardPage;
+    BYTE	*pStackBase;
+    BYTE	*pLowestPossiblePage;
+    MEMORY_BASIC_INFORMATION mbi;
+    SYSTEM_INFO si;
+    DWORD	nPageSize;
+    DWORD	dummy;
+
+    /* This code will not work on win32s. */
+    PlatformId();
+    if (g_PlatformId == VER_PLATFORM_WIN32s)
+	return 0;
+
+    /* We need to know the system page size. */
+    GetSystemInfo(&si);
+    nPageSize = si.dwPageSize;
+
+    /* ...and the current stack pointer */
+    pStackPtr = (BYTE*)_alloca(1);
+
+    /* ...and the base of the stack. */
+    if (VirtualQuery(pStackPtr, &mbi, sizeof mbi) == 0)
+	return 0;
+    pStackBase = (BYTE*)mbi.AllocationBase;
+
+    /* ...and the page thats min_stack_req pages away from stack base; this is
+     * the lowest page we could use. */
+    pLowestPossiblePage = pStackBase + ((g_PlatformId == VER_PLATFORM_WIN32_NT)
+			     ? MIN_STACK_WINNT : MIN_STACK_WIN9X) * nPageSize;
+
+    /* On Win95, we want the next page down from the end of the stack. */
+    if (g_PlatformId == VER_PLATFORM_WIN32_WINDOWS)
+    {
+	/* Find the page that's only 1 page down from the page that the stack
+	 * ptr is in. */
+	pGuardPage = (BYTE*)((DWORD)nPageSize * (((DWORD)pStackPtr
+						    / (DWORD)nPageSize) - 1));
+	if (pGuardPage < pLowestPossiblePage)
+	    return 0;
+
+	/* Apply the noaccess attribute to the page -- there's no guard
+	 * attribute in win95-type OSes. */
+	if (!VirtualProtect(pGuardPage, nPageSize, PAGE_NOACCESS, &dummy))
+	    return 0;
+    }
+    else
+    {
+	/* On NT, however, we want the first committed page in the stack Start
+	 * at the stack base and move forward through memory until we find a
+	 * committed block. */
+	BYTE *pBlock = pStackBase;
+
+	while (1)
+	{
+	    if (VirtualQuery(pBlock, &mbi, sizeof mbi) == 0)
+		return 0;
+
+	    pBlock += mbi.RegionSize;
+
+	    if (mbi.State & MEM_COMMIT)
+		break;
+	}
+
+	/* mbi now describes the first committed block in the stack. */
+	if (mbi.Protect & PAGE_GUARD)
+	    return 1;
+
+	/* decide where the guard page should start */
+	if ((long_u)(mbi.BaseAddress) < (long_u)pLowestPossiblePage)
+	    pGuardPage = pLowestPossiblePage;
+	else
+	    pGuardPage = (BYTE*)mbi.BaseAddress;
+
+	/* allocate the guard page */
+	if (!VirtualAlloc(pGuardPage, nPageSize, MEM_COMMIT, PAGE_READWRITE))
+	    return 0;
+
+	/* apply the guard attribute to the page */
+	if (!VirtualProtect(pGuardPage, nPageSize, PAGE_READWRITE | PAGE_GUARD,
+								      &dummy))
+	    return 0;
+    }
+
+    return 1;
+}
+
+#endif
