diff --git a/ncurses/win32con/gettimeofday.c b/ncurses/win32con/gettimeofday.c
new file mode 100644
index 0000000..867041f
--- /dev/null
+++ b/ncurses/win32con/gettimeofday.c
@@ -0,0 +1,54 @@
+/****************************************************************************
+ * Copyright (c) 2008-2010,2014 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+#ifdef WINVER
+#  undef WINVER
+#endif
+#define WINVER 0x0501
+
+#include <curses.priv.h>
+
+#include <windows.h>
+
+MODULE_ID("$Id: gettimeofday.c,v 1.3 2014/04/26 19:41:34 juergen Exp $")
+
+#define JAN1970 116444736000000000LL	/* the value for 01/01/1970 00:00 */
+
+int
+gettimeofday(struct timeval *tv, void *tz GCC_UNUSED)
+{
+    union {
+	FILETIME ft;
+	long long since1601;	/* time since 1 Jan 1601 in 100ns units */
+    } data;
+
+    GetSystemTimeAsFileTime(&data.ft);
+    tv->tv_usec = (long) ((data.since1601 / 10LL) % 1000000LL);
+    tv->tv_sec = (long) ((data.since1601 - JAN1970) / 10000000LL);
+    return (0);
+}
diff --git a/ncurses/win32con/wcwidth.c b/ncurses/win32con/wcwidth.c
new file mode 100644
index 0000000..cdef64a
--- /dev/null
+++ b/ncurses/win32con/wcwidth.c
@@ -0,0 +1,50 @@
+/****************************************************************************
+ * Copyright (c) 2010 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+#include <curses.priv.h>
+
+MODULE_ID("$Id: wcwidth.c,v 1.2 2010/08/07 20:52:43 tom Exp $")
+
+#if USE_WIDEC_SUPPORT
+#define mk_wcwidth(ucs)          _nc_wcwidth(ucs)
+#define mk_wcswidth(pwcs, n)     _nc_wcswidth(pwcs, n)
+#define mk_wcwidth_cjk(ucs)      _nc_wcwidth_cjk(ucs)
+#define mk_wcswidth_cjk(pwcs, n) _nc_wcswidth_cjk(pwcs, n)
+
+extern int mk_wcwidth(wchar_t);
+extern int mk_wcswidth(const wchar_t *, size_t);
+extern int mk_wcwidth_cjk(wchar_t);
+extern int mk_wcswidth_cjk(const wchar_t *, size_t);
+
+#include <wcwidth.h>
+#else
+void _nc_empty_wcwidth(void);
+void
+_nc_empty_wcwidth(void)
+{
+}
+#endif
diff --git a/ncurses/win32con/win_driver.c b/ncurses/win32con/win_driver.c
new file mode 100644
index 0000000..78ccfed
--- /dev/null
+++ b/ncurses/win32con/win_driver.c
@@ -0,0 +1,2264 @@
+/****************************************************************************
+ * Copyright (c) 1998-2014,2015 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/****************************************************************************
+ *  Author: Juergen Pfeifer                                                 *
+ *     and: Thomas E. Dickey                                                *
+ ****************************************************************************/
+
+/*
+ * TODO - GetMousePos(POINT * result) from ntconio.c
+ * TODO - implement nodelay
+ * TODO - improve screen-repainting performance, using implied wraparound to reduce write's
+ * TODO - make it optional whether screen is restored or not when non-buffered
+ */
+
+#include <curses.priv.h>
+
+#ifdef __MINGW32__
+#include <tchar.h>
+#else
+#include <windows.h>
+#include <wchar.h>
+#endif
+
+#include <io.h>
+
+#define PSAPI_VERSION 2
+#include <psapi.h>
+
+#define CUR my_term.type.
+
+MODULE_ID("$Id: win_driver.c,v 1.55 2015/02/28 21:30:23 tom Exp $")
+
+#ifndef __GNUC__
+#  error We need GCC to compile for MinGW
+#endif
+
+#define WINMAGIC NCDRV_MAGIC(NCDRV_WINCONSOLE)
+
+#define EXP_OPTIMIZE 0
+
+#define array_length(a) (sizeof(a)/sizeof(a[0]))
+
+static bool InitConsole(void);
+static bool okConsoleHandle(TERMINAL_CONTROL_BLOCK *);
+
+#define AssertTCB() assert(TCB != 0 && (TCB->magic == WINMAGIC))
+#define SetSP()     assert(TCB->csp != 0); sp = TCB->csp; (void) sp
+
+#define GenMap(vKey,key) MAKELONG(key, vKey)
+
+#define AdjustY() (CON.buffered ? 0 : (int) CON.SBI.srWindow.Top)
+
+#if USE_WIDEC_SUPPORT
+#define write_screen WriteConsoleOutputW
+#define read_screen  ReadConsoleOutputW
+#else
+#define write_screen WriteConsoleOutput
+#define read_screen  ReadConsoleOutput
+#endif
+
+static const LONG keylist[] =
+{
+    GenMap(VK_PRIOR, KEY_PPAGE),
+    GenMap(VK_NEXT, KEY_NPAGE),
+    GenMap(VK_END, KEY_END),
+    GenMap(VK_HOME, KEY_HOME),
+    GenMap(VK_LEFT, KEY_LEFT),
+    GenMap(VK_UP, KEY_UP),
+    GenMap(VK_RIGHT, KEY_RIGHT),
+    GenMap(VK_DOWN, KEY_DOWN),
+    GenMap(VK_DELETE, KEY_DC),
+    GenMap(VK_INSERT, KEY_IC)
+};
+static const LONG ansi_keys[] =
+{
+    GenMap(VK_PRIOR, 'I'),
+    GenMap(VK_NEXT, 'Q'),
+    GenMap(VK_END, 'O'),
+    GenMap(VK_HOME, 'H'),
+    GenMap(VK_LEFT, 'K'),
+    GenMap(VK_UP, 'H'),
+    GenMap(VK_RIGHT, 'M'),
+    GenMap(VK_DOWN, 'P'),
+    GenMap(VK_DELETE, 'S'),
+    GenMap(VK_INSERT, 'R')
+};
+#define N_INI ((int)array_length(keylist))
+#define FKEYS 24
+#define MAPSIZE (FKEYS + N_INI)
+#define NUMPAIRS 64
+
+/*   A process can only have a single console, so it's safe
+     to maintain all the information about it in a single
+     static structure.
+ */
+static struct {
+    BOOL initialized;
+    BOOL buffered;
+    BOOL window_only;
+    BOOL progMode;
+    BOOL isMinTTY;
+    BOOL isTermInfoConsole;
+    HANDLE out;
+    HANDLE inp;
+    HANDLE hdl;
+    HANDLE lastOut;
+    int numButtons;
+    DWORD ansi_map[MAPSIZE];
+    DWORD map[MAPSIZE];
+    DWORD rmap[MAPSIZE];
+    WORD pairs[NUMPAIRS];
+    COORD origin;
+    CHAR_INFO *save_screen;
+    COORD save_size;
+    SMALL_RECT save_region;
+    CONSOLE_SCREEN_BUFFER_INFO SBI;
+    CONSOLE_SCREEN_BUFFER_INFO save_SBI;
+    CONSOLE_CURSOR_INFO save_CI;
+} CON;
+
+static BOOL console_initialized = FALSE;
+
+static WORD
+MapColor(bool fore, int color)
+{
+    static const int _cmap[] =
+    {0, 4, 2, 6, 1, 5, 3, 7};
+    int a;
+    if (color < 0 || color > 7)
+	a = fore ? 7 : 0;
+    else
+	a = _cmap[color];
+    if (!fore)
+	a = a << 4;
+    return (WORD) a;
+}
+
+#define RevAttr(attr) \
+	       (WORD) (((attr) & 0xff00) | \
+		      ((((attr) & 0x07) << 4) | \
+		       (((attr) & 0x70) >> 4)))
+
+static WORD
+MapAttr(WORD res, attr_t ch)
+{
+    if (ch & A_COLOR) {
+	int p;
+
+	p = PairNumber(ch);
+	if (p > 0 && p < NUMPAIRS) {
+	    WORD a;
+	    a = CON.pairs[p];
+	    res = (WORD) ((res & 0xff00) | a);
+	}
+    }
+
+    if (ch & A_REVERSE) {
+	res = RevAttr(res);
+    }
+
+    if (ch & A_STANDOUT) {
+	res = RevAttr(res) | BACKGROUND_INTENSITY;
+    }
+
+    if (ch & A_BOLD)
+	res |= FOREGROUND_INTENSITY;
+
+    if (ch & A_DIM)
+	res |= BACKGROUND_INTENSITY;
+
+    return res;
+}
+
+#if 0				/* def TRACE */
+static void
+dump_screen(const char *fn, int ln)
+{
+    int max_cells = (CON.SBI.dwSize.Y * (1 + CON.SBI.dwSize.X)) + 1;
+    char output[max_cells];
+    CHAR_INFO save_screen[max_cells];
+    COORD save_size;
+    SMALL_RECT save_region;
+    COORD bufferCoord;
+
+    T(("dump_screen %s@%d", fn, ln));
+
+    save_region.Top = CON.SBI.srWindow.Top;
+    save_region.Left = CON.SBI.srWindow.Left;
+    save_region.Bottom = CON.SBI.srWindow.Bottom;
+    save_region.Right = CON.SBI.srWindow.Right;
+
+    save_size.X = (SHORT) (save_region.Right - save_region.Left + 1);
+    save_size.Y = (SHORT) (save_region.Bottom - save_region.Top + 1);
+
+    bufferCoord.X = bufferCoord.Y = 0;
+
+    if (read_screen(CON.hdl,
+		    save_screen,
+		    save_size,
+		    bufferCoord,
+		    &save_region)) {
+	int i, j;
+	int ij = 0;
+	int k = 0;
+
+	for (i = save_region.Top; i <= save_region.Bottom; ++i) {
+	    for (j = save_region.Left; j <= save_region.Right; ++j) {
+		output[k++] = save_screen[ij++].Char.AsciiChar;
+	    }
+	    output[k++] = '\n';
+	}
+	output[k] = 0;
+
+	T(("DUMP: %d,%d - %d,%d",
+	   save_region.Top,
+	   save_region.Left,
+	   save_region.Bottom,
+	   save_region.Right));
+	T(("%s", output));
+    }
+}
+
+#else
+#define dump_screen(fn,ln)	/* nothing */
+#endif
+
+#if USE_WIDEC_SUPPORT
+/*
+ * TODO: support surrogate pairs
+ * TODO: support combining characters
+ * TODO: support acsc
+ * TODO: _nc_wacs should be part of sp.
+ */
+static BOOL
+con_write16(TERMINAL_CONTROL_BLOCK * TCB, int y, int x, cchar_t *str, int limit)
+{
+    int actual = 0;
+    CHAR_INFO ci[limit];
+    COORD loc, siz;
+    SMALL_RECT rec;
+    int i;
+    cchar_t ch;
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    for (i = actual = 0; i < limit; i++) {
+	ch = str[i];
+	if (isWidecExt(ch))
+	    continue;
+	ci[actual].Char.UnicodeChar = CharOf(ch);
+	ci[actual].Attributes = MapAttr(CON.SBI.wAttributes,
+					AttrOf(ch));
+	if (AttrOf(ch) & A_ALTCHARSET) {
+	    if (_nc_wacs) {
+		int which = CharOf(ch);
+		if (which > 0
+		    && which < ACS_LEN
+		    && CharOf(_nc_wacs[which]) != 0) {
+		    ci[actual].Char.UnicodeChar = CharOf(_nc_wacs[which]);
+		} else {
+		    ci[actual].Char.UnicodeChar = ' ';
+		}
+	    }
+	}
+	++actual;
+    }
+
+    loc.X = (SHORT) 0;
+    loc.Y = (SHORT) 0;
+    siz.X = (SHORT) actual;
+    siz.Y = 1;
+
+    rec.Left = (SHORT) x;
+    rec.Top = (SHORT) (y + AdjustY());
+    rec.Right = (SHORT) (x + limit - 1);
+    rec.Bottom = rec.Top;
+
+    return write_screen(CON.hdl, ci, siz, loc, &rec);
+}
+#define con_write(tcb, y, x, str, n) con_write16(tcb, y, x, str, n)
+#else
+static BOOL
+con_write8(TERMINAL_CONTROL_BLOCK * TCB, int y, int x, chtype *str, int n)
+{
+    CHAR_INFO ci[n];
+    COORD loc, siz;
+    SMALL_RECT rec;
+    int i;
+    chtype ch;
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    for (i = 0; i < n; i++) {
+	ch = str[i];
+	ci[i].Char.AsciiChar = ChCharOf(ch);
+	ci[i].Attributes = MapAttr(CON.SBI.wAttributes,
+				   ChAttrOf(ch));
+	if (ChAttrOf(ch) & A_ALTCHARSET) {
+	    if (sp->_acs_map)
+		ci[i].Char.AsciiChar =
+		ChCharOf(NCURSES_SP_NAME(_nc_acs_char) (sp, ChCharOf(ch)));
+	}
+    }
+
+    loc.X = (short) 0;
+    loc.Y = (short) 0;
+    siz.X = (short) n;
+    siz.Y = 1;
+
+    rec.Left = (short) x;
+    rec.Top = (short) y;
+    rec.Right = (short) (x + n - 1);
+    rec.Bottom = rec.Top;
+
+    return write_screen(CON.hdl, ci, siz, loc, &rec);
+}
+#define con_write(tcb, y, x, str, n) con_write8(tcb, y, x, str, n)
+#endif
+
+#if EXP_OPTIMIZE
+/*
+ * Comparing new/current screens, determine the last column-index for a change
+ * beginning on the given row,col position.  Unlike a serial terminal, there is
+ * no cost for "moving" the "cursor" on the line as we update it.
+ */
+static int
+find_end_of_change(SCREEN *sp, int row, int col)
+{
+    int result = col;
+    struct ldat *curdat = CurScreen(sp)->_line + row;
+    struct ldat *newdat = NewScreen(sp)->_line + row;
+
+    while (col <= newdat->lastchar) {
+#if USE_WIDEC_SUPPORT
+	if (isWidecExt(curdat->text[col]) || isWidecExt(newdat->text[col])) {
+	    result = col;
+	} else if (memcmp(&curdat->text[col],
+			  &newdat->text[col],
+			  sizeof(curdat->text[0]))) {
+	    result = col;
+	} else {
+	    break;
+	}
+#else
+	if (curdat->text[col] != newdat->text[col]) {
+	    result = col;
+	} else {
+	    break;
+	}
+#endif
+	++col;
+    }
+    return result;
+}
+
+/*
+ * Given a row,col position at the end of a change-chunk, look for the
+ * beginning of the next change-chunk.
+ */
+static int
+find_next_change(SCREEN *sp, int row, int col)
+{
+    struct ldat *curdat = CurScreen(sp)->_line + row;
+    struct ldat *newdat = NewScreen(sp)->_line + row;
+    int result = newdat->lastchar + 1;
+
+    while (++col <= newdat->lastchar) {
+#if USE_WIDEC_SUPPORT
+	if (isWidecExt(curdat->text[col]) != isWidecExt(newdat->text[col])) {
+	    result = col;
+	    break;
+	} else if (memcmp(&curdat->text[col],
+			  &newdat->text[col],
+			  sizeof(curdat->text[0]))) {
+	    result = col;
+	    break;
+	}
+#else
+	if (curdat->text[col] != newdat->text[col]) {
+	    result = col;
+	    break;
+	}
+#endif
+    }
+    return result;
+}
+
+#define EndChange(first) \
+	find_end_of_change(sp, y, first)
+#define NextChange(last) \
+	find_next_change(sp, y, last)
+
+#endif /* EXP_OPTIMIZE */
+
+#define MARK_NOCHANGE(win,row) \
+		win->_line[row].firstchar = _NOCHANGE; \
+		win->_line[row].lastchar  = _NOCHANGE
+
+static void
+selectActiveHandle(void)
+{
+    if (CON.lastOut != CON.hdl) {
+	CON.lastOut = CON.hdl;
+	SetConsoleActiveScreenBuffer(CON.lastOut);
+    }
+}
+
+static bool
+restore_original_screen(void)
+{
+    COORD bufferCoord;
+    bool result = FALSE;
+    SMALL_RECT save_region = CON.save_region;
+
+    T(("... restoring %s", CON.window_only ? "window" : "entire buffer"));
+
+    bufferCoord.X = (SHORT) (CON.window_only ? CON.SBI.srWindow.Left : 0);
+    bufferCoord.Y = (SHORT) (CON.window_only ? CON.SBI.srWindow.Top : 0);
+
+    if (write_screen(CON.hdl,
+		     CON.save_screen,
+		     CON.save_size,
+		     bufferCoord,
+		     &save_region)) {
+	result = TRUE;
+	mvcur(-1, -1, LINES - 2, 0);
+	T(("... restore original screen contents ok %dx%d (%d,%d - %d,%d)",
+	   CON.save_size.Y,
+	   CON.save_size.X,
+	   save_region.Top,
+	   save_region.Left,
+	   save_region.Bottom,
+	   save_region.Right));
+    } else {
+	T(("... restore original screen contents err"));
+    }
+    return result;
+}
+
+static const char *
+wcon_name(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    (void) TCB;
+    return "win32console";
+}
+
+static int
+wcon_doupdate(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    int result = ERR;
+    int y, nonempty, n, x0, x1, Width, Height;
+    SCREEN *sp;
+
+    T((T_CALLED("win32con::wcon_doupdate(%p)"), TCB));
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+
+	Width = screen_columns(sp);
+	Height = screen_lines(sp);
+	nonempty = min(Height, NewScreen(sp)->_maxy + 1);
+
+	T(("... %dx%d clear cur:%d new:%d",
+	   Height, Width,
+	   CurScreen(sp)->_clear,
+	   NewScreen(sp)->_clear));
+
+	if (SP_PARM->_endwin) {
+
+	    T(("coming back from shell mode"));
+	    NCURSES_SP_NAME(reset_prog_mode) (NCURSES_SP_ARG);
+
+	    NCURSES_SP_NAME(_nc_mvcur_resume) (NCURSES_SP_ARG);
+	    NCURSES_SP_NAME(_nc_screen_resume) (NCURSES_SP_ARG);
+	    SP_PARM->_mouse_resume(SP_PARM);
+
+	    SP_PARM->_endwin = FALSE;
+	}
+
+	if ((CurScreen(sp)->_clear || NewScreen(sp)->_clear)) {
+	    int x;
+#if USE_WIDEC_SUPPORT
+	    cchar_t empty[Width];
+	    wchar_t blank[2] =
+	    {
+		L' ', L'\0'
+	    };
+
+	    for (x = 0; x < Width; x++)
+		setcchar(&empty[x], blank, 0, 0, 0);
+#else
+	    chtype empty[Width];
+
+	    for (x = 0; x < Width; x++)
+		empty[x] = ' ';
+#endif
+
+	    for (y = 0; y < nonempty; y++) {
+		con_write(TCB, y, 0, empty, Width);
+		memcpy(empty,
+		       CurScreen(sp)->_line[y].text,
+		       (size_t) Width * sizeof(empty[0]));
+	    }
+	    CurScreen(sp)->_clear = FALSE;
+	    NewScreen(sp)->_clear = FALSE;
+	    touchwin(NewScreen(sp));
+	    T(("... cleared %dx%d lines @%d of screen", nonempty, Width,
+	       AdjustY()));
+	}
+
+	for (y = 0; y < nonempty; y++) {
+	    x0 = NewScreen(sp)->_line[y].firstchar;
+	    if (x0 != _NOCHANGE) {
+#if EXP_OPTIMIZE
+		int x2;
+		int limit = NewScreen(sp)->_line[y].lastchar;
+		while ((x1 = EndChange(x0)) <= limit) {
+		    while ((x2 = NextChange(x1)) <= limit && x2 <= (x1 + 2)) {
+			x1 = x2;
+		    }
+		    n = x1 - x0 + 1;
+		    memcpy(&CurScreen(sp)->_line[y].text[x0],
+			   &NewScreen(sp)->_line[y].text[x0],
+			   n * sizeof(CurScreen(sp)->_line[y].text[x0]));
+		    con_write(TCB,
+			      y,
+			      x0,
+			      &CurScreen(sp)->_line[y].text[x0], n);
+		    x0 = NextChange(x1);
+		}
+
+		/* mark line changed successfully */
+		if (y <= NewScreen(sp)->_maxy) {
+		    MARK_NOCHANGE(NewScreen(sp), y);
+		}
+		if (y <= CurScreen(sp)->_maxy) {
+		    MARK_NOCHANGE(CurScreen(sp), y);
+		}
+#else
+		x1 = NewScreen(sp)->_line[y].lastchar;
+		n = x1 - x0 + 1;
+		if (n > 0) {
+		    memcpy(&CurScreen(sp)->_line[y].text[x0],
+			   &NewScreen(sp)->_line[y].text[x0],
+			   (size_t) n * sizeof(CurScreen(sp)->_line[y].text[x0]));
+		    con_write(TCB,
+			      y,
+			      x0,
+			      &CurScreen(sp)->_line[y].text[x0], n);
+
+		    /* mark line changed successfully */
+		    if (y <= NewScreen(sp)->_maxy) {
+			MARK_NOCHANGE(NewScreen(sp), y);
+		    }
+		    if (y <= CurScreen(sp)->_maxy) {
+			MARK_NOCHANGE(CurScreen(sp), y);
+		    }
+		}
+#endif
+	    }
+	}
+
+	/* put everything back in sync */
+	for (y = nonempty; y <= NewScreen(sp)->_maxy; y++) {
+	    MARK_NOCHANGE(NewScreen(sp), y);
+	}
+	for (y = nonempty; y <= CurScreen(sp)->_maxy; y++) {
+	    MARK_NOCHANGE(CurScreen(sp), y);
+	}
+
+	if (!NewScreen(sp)->_leaveok) {
+	    CurScreen(sp)->_curx = NewScreen(sp)->_curx;
+	    CurScreen(sp)->_cury = NewScreen(sp)->_cury;
+
+	    TCB->drv->td_hwcur(TCB,
+			       0, 0,
+			       CurScreen(sp)->_cury, CurScreen(sp)->_curx);
+	}
+	selectActiveHandle();
+	result = OK;
+    }
+    returnCode(result);
+}
+
+static bool
+wcon_CanHandle(TERMINAL_CONTROL_BLOCK * TCB,
+	       const char *tname,
+	       int *errret GCC_UNUSED)
+{
+    bool code = FALSE;
+
+    T((T_CALLED("win32con::wcon_CanHandle(%p)"), TCB));
+
+    assert((TCB != 0) && (tname != 0));
+
+    TCB->magic = WINMAGIC;
+
+    if (tname == 0 || *tname == 0)
+	code = TRUE;
+    else if (tname != 0 && *tname == '#') {
+	/*
+	 * Use "#" (a character which cannot begin a terminal's name) to
+	 * select specific driver from the table.
+	 *
+	 * In principle, we could have more than one non-terminfo driver,
+	 * e.g., "win32gui".
+	 */
+	size_t n = strlen(tname + 1);
+	if (n != 0
+	    && ((strncmp(tname + 1, "win32console", n) == 0)
+		|| (strncmp(tname + 1, "win32con", n) == 0))) {
+	    code = TRUE;
+	}
+    } else if (tname != 0 && stricmp(tname, "unknown") == 0) {
+	code = TRUE;
+    }
+
+    /*
+     * This is intentional, to avoid unnecessary breakage of applications
+     * using <term.h> symbols.
+     */
+    if (code && (TCB->term.type.Booleans == 0)) {
+	_nc_init_termtype(&(TCB->term.type));
+    }
+
+    if (!code) {
+	if (_nc_mingw_isconsole(0))
+	    CON.isTermInfoConsole = TRUE;
+    }
+    returnBool(code);
+}
+
+static int
+wcon_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB,
+		 int beepFlag)
+{
+    SCREEN *sp;
+    int res = ERR;
+
+    int high = (CON.SBI.srWindow.Bottom - CON.SBI.srWindow.Top + 1);
+    int wide = (CON.SBI.srWindow.Right - CON.SBI.srWindow.Left + 1);
+    int max_cells = (high * wide);
+    int i;
+
+    CHAR_INFO this_screen[max_cells];
+    CHAR_INFO that_screen[max_cells];
+    COORD this_size;
+    SMALL_RECT this_region;
+    COORD bufferCoord;
+
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+	this_region.Top = CON.SBI.srWindow.Top;
+	this_region.Left = CON.SBI.srWindow.Left;
+	this_region.Bottom = CON.SBI.srWindow.Bottom;
+	this_region.Right = CON.SBI.srWindow.Right;
+
+	this_size.X = (SHORT) wide;
+	this_size.Y = (SHORT) high;
+
+	bufferCoord.X = this_region.Left;
+	bufferCoord.Y = this_region.Top;
+
+	if (!beepFlag &&
+	    read_screen(CON.hdl,
+			this_screen,
+			this_size,
+			bufferCoord,
+			&this_region)) {
+
+	    memcpy(that_screen, this_screen, sizeof(that_screen));
+
+	    for (i = 0; i < max_cells; i++) {
+		that_screen[i].Attributes = RevAttr(that_screen[i].Attributes);
+	    }
+
+	    write_screen(CON.hdl, that_screen, this_size, bufferCoord, &this_region);
+	    Sleep(200);
+	    write_screen(CON.hdl, this_screen, this_size, bufferCoord, &this_region);
+
+	} else {
+	    MessageBeep(MB_ICONWARNING);	/* MB_OK might be better */
+	}
+	res = OK;
+    }
+    return res;
+}
+
+static int
+wcon_print(TERMINAL_CONTROL_BLOCK * TCB,
+	   char *data GCC_UNUSED,
+	   int len GCC_UNUSED)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    return ERR;
+}
+
+static int
+wcon_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB,
+		   int fg GCC_UNUSED,
+		   int bg GCC_UNUSED)
+{
+    SCREEN *sp;
+    int code = ERR;
+
+    AssertTCB();
+    SetSP();
+
+    return (code);
+}
+
+static bool
+get_SBI(void)
+{
+    bool rc = FALSE;
+    if (GetConsoleScreenBufferInfo(CON.hdl, &(CON.SBI))) {
+	T(("GetConsoleScreenBufferInfo"));
+	T(("... buffer(X:%d Y:%d)",
+	   CON.SBI.dwSize.X,
+	   CON.SBI.dwSize.Y));
+	T(("... window(X:%d Y:%d)",
+	   CON.SBI.dwMaximumWindowSize.X,
+	   CON.SBI.dwMaximumWindowSize.Y));
+	T(("... cursor(X:%d Y:%d)",
+	   CON.SBI.dwCursorPosition.X,
+	   CON.SBI.dwCursorPosition.Y));
+	T(("... display(Top:%d Bottom:%d Left:%d Right:%d)",
+	   CON.SBI.srWindow.Top,
+	   CON.SBI.srWindow.Bottom,
+	   CON.SBI.srWindow.Left,
+	   CON.SBI.srWindow.Right));
+	if (CON.buffered) {
+	    CON.origin.X = 0;
+	    CON.origin.Y = 0;
+	} else {
+	    CON.origin.X = CON.SBI.srWindow.Left;
+	    CON.origin.Y = CON.SBI.srWindow.Top;
+	}
+	rc = TRUE;
+    } else {
+	T(("GetConsoleScreenBufferInfo ERR"));
+    }
+    return rc;
+}
+
+static void
+wcon_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
+	      int fore,
+	      int color,
+	      int (*outc) (SCREEN *, int) GCC_UNUSED)
+{
+    if (okConsoleHandle(TCB)) {
+	WORD a = MapColor(fore, color);
+	a |= (WORD) ((CON.SBI.wAttributes) & (fore ? 0xfff8 : 0xff8f));
+	SetConsoleTextAttribute(CON.hdl, a);
+	get_SBI();
+    }
+}
+
+static bool
+wcon_rescol(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    bool res = FALSE;
+
+    if (okConsoleHandle(TCB)) {
+	WORD a = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN;
+	SetConsoleTextAttribute(CON.hdl, a);
+	get_SBI();
+	res = TRUE;
+    }
+    return res;
+}
+
+static bool
+wcon_rescolors(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    int result = FALSE;
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    return result;
+}
+
+static int
+wcon_size(TERMINAL_CONTROL_BLOCK * TCB, int *Lines, int *Cols)
+{
+    int result = ERR;
+
+    T((T_CALLED("win32con::wcon_size(%p)"), TCB));
+
+    if (okConsoleHandle(TCB) &&
+	Lines != NULL &&
+	Cols != NULL) {
+	if (CON.buffered) {
+	    *Lines = (int) (CON.SBI.dwSize.Y);
+	    *Cols = (int) (CON.SBI.dwSize.X);
+	} else {
+	    *Lines = (int) (CON.SBI.srWindow.Bottom + 1 -
+			    CON.SBI.srWindow.Top);
+	    *Cols = (int) (CON.SBI.srWindow.Right + 1 -
+			   CON.SBI.srWindow.Left);
+	}
+	result = OK;
+    }
+    returnCode(result);
+}
+
+static int
+wcon_setsize(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED,
+	     int l GCC_UNUSED,
+	     int c GCC_UNUSED)
+{
+    AssertTCB();
+    return ERR;
+}
+
+static int
+wcon_sgmode(TERMINAL_CONTROL_BLOCK * TCB, int setFlag, TTY * buf)
+{
+    DWORD dwFlag = 0;
+    tcflag_t iflag;
+    tcflag_t lflag;
+    int result = ERR;
+
+    if (buf != NULL && okConsoleHandle(TCB)) {
+
+	if (setFlag) {
+	    iflag = buf->c_iflag;
+	    lflag = buf->c_lflag;
+
+	    GetConsoleMode(CON.inp, &dwFlag);
+
+	    if (lflag & ICANON)
+		dwFlag |= ENABLE_LINE_INPUT;
+	    else
+		dwFlag &= (DWORD) (~ENABLE_LINE_INPUT);
+
+	    if (lflag & ECHO)
+		dwFlag |= ENABLE_ECHO_INPUT;
+	    else
+		dwFlag &= (DWORD) (~ENABLE_ECHO_INPUT);
+
+	    if (iflag & BRKINT)
+		dwFlag |= ENABLE_PROCESSED_INPUT;
+	    else
+		dwFlag &= (DWORD) (~ENABLE_PROCESSED_INPUT);
+
+	    dwFlag |= ENABLE_MOUSE_INPUT;
+
+	    buf->c_iflag = iflag;
+	    buf->c_lflag = lflag;
+	    SetConsoleMode(CON.inp, dwFlag);
+	    TCB->term.Nttyb = *buf;
+	} else {
+	    iflag = TCB->term.Nttyb.c_iflag;
+	    lflag = TCB->term.Nttyb.c_lflag;
+	    GetConsoleMode(CON.inp, &dwFlag);
+
+	    if (dwFlag & ENABLE_LINE_INPUT)
+		lflag |= ICANON;
+	    else
+		lflag &= (tcflag_t) (~ICANON);
+
+	    if (dwFlag & ENABLE_ECHO_INPUT)
+		lflag |= ECHO;
+	    else
+		lflag &= (tcflag_t) (~ECHO);
+
+	    if (dwFlag & ENABLE_PROCESSED_INPUT)
+		iflag |= BRKINT;
+	    else
+		iflag &= (tcflag_t) (~BRKINT);
+
+	    TCB->term.Nttyb.c_iflag = iflag;
+	    TCB->term.Nttyb.c_lflag = lflag;
+
+	    *buf = TCB->term.Nttyb;
+	}
+	result = OK;
+    }
+    return result;
+}
+
+#define MIN_WIDE 80
+#define MIN_HIGH 24
+
+/*
+ * In "normal" mode, reset the buffer- and window-sizes back to their original values.
+ */
+static void
+set_scrollback(bool normal, CONSOLE_SCREEN_BUFFER_INFO * info)
+{
+    SMALL_RECT rect;
+    COORD coord;
+    bool changed = FALSE;
+
+    T((T_CALLED("win32con::set_scrollback(%s)"),
+       (normal
+	? "normal"
+	: "application")));
+
+    T(("... SBI.srWindow %d,%d .. %d,%d",
+       info->srWindow.Top,
+       info->srWindow.Left,
+       info->srWindow.Bottom,
+       info->srWindow.Right));
+    T(("... SBI.dwSize %dx%d",
+       info->dwSize.Y,
+       info->dwSize.X));
+
+    if (normal) {
+	rect = info->srWindow;
+	coord = info->dwSize;
+	if (memcmp(info, &CON.SBI, sizeof(*info)) != 0) {
+	    changed = TRUE;
+	    CON.SBI = *info;
+	}
+    } else {
+	int high = info->srWindow.Bottom - info->srWindow.Top + 1;
+	int wide = info->srWindow.Right - info->srWindow.Left + 1;
+
+	if (high < MIN_HIGH) {
+	    T(("... height %d < %d", high, MIN_HIGH));
+	    high = MIN_HIGH;
+	    changed = TRUE;
+	}
+	if (wide < MIN_WIDE) {
+	    T(("... width %d < %d", wide, MIN_WIDE));
+	    wide = MIN_WIDE;
+	    changed = TRUE;
+	}
+
+	rect.Left =
+	    rect.Top = 0;
+	rect.Right = (SHORT) (wide - 1);
+	rect.Bottom = (SHORT) (high - 1);
+
+	coord.X = (SHORT) wide;
+	coord.Y = (SHORT) high;
+
+	if (info->dwSize.Y != high ||
+	    info->dwSize.X != wide ||
+	    info->srWindow.Top != 0 ||
+	    info->srWindow.Left != 0) {
+	    changed = TRUE;
+	}
+
+    }
+
+    if (changed) {
+	T(("... coord %d,%d", coord.Y, coord.X));
+	T(("... rect %d,%d - %d,%d",
+	   rect.Top, rect.Left,
+	   rect.Bottom, rect.Right));
+	SetConsoleScreenBufferSize(CON.hdl, coord);	/* dwSize */
+	SetConsoleWindowInfo(CON.hdl, TRUE, &rect);	/* srWindow */
+	get_SBI();
+    }
+    returnVoid;
+}
+
+static int
+wcon_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag)
+{
+    SCREEN *sp;
+    TERMINAL *_term = (TERMINAL *) TCB;
+    int code = ERR;
+
+    if (okConsoleHandle(TCB)) {
+	sp = TCB->csp;
+
+	T((T_CALLED("win32con::wcon_mode(%p, prog=%d, def=%d)"),
+	   TCB, progFlag, defFlag));
+
+	CON.progMode = progFlag;
+	CON.lastOut = progFlag ? CON.hdl : CON.out;
+	SetConsoleActiveScreenBuffer(CON.lastOut);
+
+	if (progFlag) /* prog mode */  {
+	    if (defFlag) {
+		if ((wcon_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) {
+		    _term->Nttyb.c_oflag &= (tcflag_t) (~OFLAGS_TABS);
+		    code = OK;
+		}
+	    } else {
+		/* reset_prog_mode */
+		if (wcon_sgmode(TCB, TRUE, &(_term->Nttyb)) == OK) {
+		    if (sp) {
+			if (sp->_keypad_on)
+			    _nc_keypad(sp, TRUE);
+		    }
+		    if (!CON.buffered) {
+			set_scrollback(FALSE, &CON.SBI);
+		    }
+		    code = OK;
+		}
+	    }
+	    T(("... buffered:%d, clear:%d", CON.buffered, CurScreen(sp)->_clear));
+	} else {		/* shell mode */
+	    if (defFlag) {
+		/* def_shell_mode */
+		if (wcon_sgmode(TCB, FALSE, &(_term->Ottyb)) == OK) {
+		    code = OK;
+		}
+	    } else {
+		/* reset_shell_mode */
+		if (sp) {
+		    _nc_keypad(sp, FALSE);
+		    NCURSES_SP_NAME(_nc_flush) (sp);
+		}
+		code = wcon_sgmode(TCB, TRUE, &(_term->Ottyb));
+		if (!CON.buffered) {
+		    set_scrollback(TRUE, &CON.save_SBI);
+		    if (!restore_original_screen())
+			code = ERR;
+		}
+		SetConsoleCursorInfo(CON.hdl, &CON.save_CI);
+	    }
+	}
+
+    }
+    returnCode(code);
+}
+
+static void
+wcon_screen_init(SCREEN *sp GCC_UNUSED)
+{
+}
+
+static void
+wcon_wrap(SCREEN *sp GCC_UNUSED)
+{
+}
+
+static int
+rkeycompare(const void *el1, const void *el2)
+{
+    WORD key1 = (LOWORD((*((const LONG *) el1)))) & 0x7fff;
+    WORD key2 = (LOWORD((*((const LONG *) el2)))) & 0x7fff;
+
+    return ((key1 < key2) ? -1 : ((key1 == key2) ? 0 : 1));
+}
+
+static int
+keycompare(const void *el1, const void *el2)
+{
+    WORD key1 = HIWORD((*((const LONG *) el1)));
+    WORD key2 = HIWORD((*((const LONG *) el2)));
+
+    return ((key1 < key2) ? -1 : ((key1 == key2) ? 0 : 1));
+}
+
+static int
+MapKey(WORD vKey)
+{
+    WORD nKey = 0;
+    void *res;
+    LONG key = GenMap(vKey, 0);
+    int code = -1;
+
+    res = bsearch(&key,
+		  CON.map,
+		  (size_t) (N_INI + FKEYS),
+		  sizeof(keylist[0]),
+		  keycompare);
+    if (res) {
+	key = *((LONG *) res);
+	nKey = LOWORD(key);
+	code = (int) (nKey & 0x7fff);
+	if (nKey & 0x8000)
+	    code = -code;
+    }
+    return code;
+}
+
+static int
+AnsiKey(WORD vKey)
+{
+    WORD nKey = 0;
+    void *res;
+    LONG key = GenMap(vKey, 0);
+    int code = -1;
+
+    res = bsearch(&key,
+		  CON.ansi_map,
+		  (size_t) (N_INI + FKEYS),
+		  sizeof(keylist[0]),
+		  keycompare);
+    if (res) {
+	key = *((LONG *) res);
+	nKey = LOWORD(key);
+	code = (int) (nKey & 0x7fff);
+	if (nKey & 0x8000)
+	    code = -code;
+    }
+    return code;
+}
+
+static void
+wcon_release(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    T((T_CALLED("win32con::wcon_release(%p)"), TCB));
+
+    AssertTCB();
+    if (TCB->prop)
+	free(TCB->prop);
+
+    returnVoid;
+}
+
+static bool
+read_screen_data(void)
+{
+    bool result = FALSE;
+    COORD bufferCoord;
+    size_t want;
+
+    CON.save_size.X = (SHORT) (CON.save_region.Right
+			       - CON.save_region.Left + 1);
+    CON.save_size.Y = (SHORT) (CON.save_region.Bottom
+			       - CON.save_region.Top + 1);
+
+    want = (size_t) (CON.save_size.X * CON.save_size.Y);
+
+    if ((CON.save_screen = malloc(want * sizeof(CHAR_INFO))) != 0) {
+	bufferCoord.X = (SHORT) (CON.window_only ? CON.SBI.srWindow.Left : 0);
+	bufferCoord.Y = (SHORT) (CON.window_only ? CON.SBI.srWindow.Top : 0);
+
+	T(("... reading console %s %dx%d into %d,%d - %d,%d at %d,%d",
+	   CON.window_only ? "window" : "buffer",
+	   CON.save_size.Y, CON.save_size.X,
+	   CON.save_region.Top,
+	   CON.save_region.Left,
+	   CON.save_region.Bottom,
+	   CON.save_region.Right,
+	   bufferCoord.Y,
+	   bufferCoord.X));
+
+	if (read_screen(CON.hdl,
+			CON.save_screen,
+			CON.save_size,
+			bufferCoord,
+			&CON.save_region)) {
+	    result = TRUE;
+	} else {
+	    T((" error %#lx", (unsigned long) GetLastError()));
+	    FreeAndNull(CON.save_screen);
+	}
+    }
+
+    return result;
+}
+
+/*
+ * Attempt to save the screen contents.  PDCurses does this if
+ * PDC_RESTORE_SCREEN is set, giving the same visual appearance on
+ * restoration as if the library had allocated a console buffer.  MSDN
+ * says that the data which can be read is limited to 64Kb (and may be
+ * less).
+ */
+static bool
+save_original_screen(void)
+{
+    bool result = FALSE;
+
+    CON.save_region.Top = 0;
+    CON.save_region.Left = 0;
+    CON.save_region.Bottom = (SHORT) (CON.SBI.dwSize.Y - 1);
+    CON.save_region.Right = (SHORT) (CON.SBI.dwSize.X - 1);
+
+    if (read_screen_data()) {
+	result = TRUE;
+    } else {
+
+	CON.save_region.Top = CON.SBI.srWindow.Top;
+	CON.save_region.Left = CON.SBI.srWindow.Left;
+	CON.save_region.Bottom = CON.SBI.srWindow.Bottom;
+	CON.save_region.Right = CON.SBI.srWindow.Right;
+
+	CON.window_only = TRUE;
+
+	if (read_screen_data()) {
+	    result = TRUE;
+	}
+    }
+
+    T(("... save original screen contents %s", result ? "ok" : "err"));
+    return result;
+}
+
+static void
+wcon_init(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    T((T_CALLED("win32con::wcon_init(%p)"), TCB));
+
+    AssertTCB();
+
+    if (TCB) {
+	if (!InitConsole()) {
+	    returnVoid;
+	}
+
+	TCB->info.initcolor = TRUE;
+	TCB->info.canchange = FALSE;
+	TCB->info.hascolor = TRUE;
+	TCB->info.caninit = TRUE;
+
+	TCB->info.maxpairs = NUMPAIRS;
+	TCB->info.maxcolors = 8;
+	TCB->info.numlabels = 0;
+	TCB->info.labelwidth = 0;
+	TCB->info.labelheight = 0;
+	TCB->info.nocolorvideo = 1;
+	TCB->info.tabsize = 8;
+
+	TCB->info.numbuttons = CON.numButtons;
+	TCB->info.defaultPalette = _nc_cga_palette;
+
+    }
+    returnVoid;
+}
+
+static void
+wcon_initpair(TERMINAL_CONTROL_BLOCK * TCB,
+	      int pair,
+	      int f,
+	      int b)
+{
+    SCREEN *sp;
+
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+
+	if ((pair > 0) && (pair < NUMPAIRS) && (f >= 0) && (f < 8)
+	    && (b >= 0) && (b < 8)) {
+	    CON.pairs[pair] = MapColor(true, f) | MapColor(false, b);
+	}
+    }
+}
+
+static void
+wcon_initcolor(TERMINAL_CONTROL_BLOCK * TCB,
+	       int color GCC_UNUSED,
+	       int r GCC_UNUSED,
+	       int g GCC_UNUSED,
+	       int b GCC_UNUSED)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+}
+
+static void
+wcon_do_color(TERMINAL_CONTROL_BLOCK * TCB,
+	      int old_pair GCC_UNUSED,
+	      int pair GCC_UNUSED,
+	      int reverse GCC_UNUSED,
+	      int (*outc) (SCREEN *, int) GCC_UNUSED
+)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+}
+
+static void
+wcon_initmouse(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    SCREEN *sp;
+
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+
+	sp->_mouse_type = M_TERM_DRIVER;
+    }
+}
+
+static int
+wcon_testmouse(TERMINAL_CONTROL_BLOCK * TCB, int delay)
+{
+    int rc = 0;
+    SCREEN *sp;
+
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+
+	if (sp->_drv_mouse_head < sp->_drv_mouse_tail) {
+	    rc = TW_MOUSE;
+	} else {
+	    rc = TCBOf(sp)->drv->td_twait(TCBOf(sp),
+					  TWAIT_MASK,
+					  delay,
+					  (int *) 0
+					  EVENTLIST_2nd(evl));
+	}
+    }
+
+    return rc;
+}
+
+static int
+wcon_mvcur(TERMINAL_CONTROL_BLOCK * TCB,
+	   int yold GCC_UNUSED, int xold GCC_UNUSED,
+	   int y, int x)
+{
+    int ret = ERR;
+    if (okConsoleHandle(TCB)) {
+	COORD loc;
+	loc.X = (short) x;
+	loc.Y = (short) (y + AdjustY());
+	SetConsoleCursorPosition(CON.hdl, loc);
+	ret = OK;
+    }
+    return ret;
+}
+
+static void
+wcon_hwlabel(TERMINAL_CONTROL_BLOCK * TCB,
+	     int labnum GCC_UNUSED,
+	     char *text GCC_UNUSED)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+}
+
+static void
+wcon_hwlabelOnOff(TERMINAL_CONTROL_BLOCK * TCB,
+		  int OnFlag GCC_UNUSED)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+}
+
+static chtype
+wcon_conattr(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED)
+{
+    chtype res = A_NORMAL;
+    res |= (A_BOLD | A_DIM | A_REVERSE | A_STANDOUT | A_COLOR);
+    return res;
+}
+
+static void
+wcon_setfilter(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+}
+
+static void
+wcon_initacs(TERMINAL_CONTROL_BLOCK * TCB,
+	     chtype *real_map GCC_UNUSED,
+	     chtype *fake_map GCC_UNUSED)
+{
+#define DATA(a,b) { a, b }
+    static struct {
+	int acs_code;
+	int use_code;
+    } table[] = {
+	DATA('a', 0xb1),	/* ACS_CKBOARD  */
+	    DATA('f', 0xf8),	/* ACS_DEGREE   */
+	    DATA('g', 0xf1),	/* ACS_PLMINUS  */
+	    DATA('j', 0xd9),	/* ACS_LRCORNER */
+	    DATA('l', 0xda),	/* ACS_ULCORNER */
+	    DATA('k', 0xbf),	/* ACS_URCORNER */
+	    DATA('m', 0xc0),	/* ACS_LLCORNER */
+	    DATA('n', 0xc5),	/* ACS_PLUS     */
+	    DATA('q', 0xc4),	/* ACS_HLINE    */
+	    DATA('t', 0xc3),	/* ACS_LTEE     */
+	    DATA('u', 0xb4),	/* ACS_RTEE     */
+	    DATA('v', 0xc1),	/* ACS_BTEE     */
+	    DATA('w', 0xc2),	/* ACS_TTEE     */
+	    DATA('x', 0xb3),	/* ACS_VLINE    */
+	    DATA('y', 0xf3),	/* ACS_LEQUAL   */
+	    DATA('z', 0xf2),	/* ACS_GEQUAL   */
+	    DATA('0', 0xdb),	/* ACS_BLOCK    */
+	    DATA('{', 0xe3),	/* ACS_PI       */
+	    DATA('}', 0x9c),	/* ACS_STERLING */
+	    DATA(',', 0xae),	/* ACS_LARROW   */
+	    DATA('+', 0xaf),	/* ACS_RARROW   */
+	    DATA('~', 0xf9),	/* ACS_BULLET   */
+    };
+#undef DATA
+    unsigned n;
+
+    SCREEN *sp;
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+
+	for (n = 0; n < SIZEOF(table); ++n) {
+	    real_map[table[n].acs_code] = (chtype) table[n].use_code | A_ALTCHARSET;
+	    if (sp != 0)
+		sp->_screen_acs_map[table[n].acs_code] = TRUE;
+	}
+    }
+}
+
+static ULONGLONG
+tdiff(FILETIME fstart, FILETIME fend)
+{
+    ULARGE_INTEGER ustart;
+    ULARGE_INTEGER uend;
+    ULONGLONG diff;
+
+    ustart.LowPart = fstart.dwLowDateTime;
+    ustart.HighPart = fstart.dwHighDateTime;
+    uend.LowPart = fend.dwLowDateTime;
+    uend.HighPart = fend.dwHighDateTime;
+
+    diff = (uend.QuadPart - ustart.QuadPart) / 10000;
+    return diff;
+}
+
+static int
+Adjust(int milliseconds, int diff)
+{
+    if (milliseconds != INFINITY) {
+	milliseconds -= diff;
+	if (milliseconds < 0)
+	    milliseconds = 0;
+    }
+    return milliseconds;
+}
+
+#define BUTTON_MASK (FROM_LEFT_1ST_BUTTON_PRESSED | \
+		     FROM_LEFT_2ND_BUTTON_PRESSED | \
+		     FROM_LEFT_3RD_BUTTON_PRESSED | \
+		     FROM_LEFT_4TH_BUTTON_PRESSED | \
+		     RIGHTMOST_BUTTON_PRESSED)
+
+static int
+decode_mouse(SCREEN *sp, int mask)
+{
+    int result = 0;
+
+    (void) sp;
+    assert(sp && console_initialized);
+
+    if (mask & FROM_LEFT_1ST_BUTTON_PRESSED)
+	result |= BUTTON1_PRESSED;
+    if (mask & FROM_LEFT_2ND_BUTTON_PRESSED)
+	result |= BUTTON2_PRESSED;
+    if (mask & FROM_LEFT_3RD_BUTTON_PRESSED)
+	result |= BUTTON3_PRESSED;
+    if (mask & FROM_LEFT_4TH_BUTTON_PRESSED)
+	result |= BUTTON4_PRESSED;
+
+    if (mask & RIGHTMOST_BUTTON_PRESSED) {
+	switch (CON.numButtons) {
+	case 1:
+	    result |= BUTTON1_PRESSED;
+	    break;
+	case 2:
+	    result |= BUTTON2_PRESSED;
+	    break;
+	case 3:
+	    result |= BUTTON3_PRESSED;
+	    break;
+	case 4:
+	    result |= BUTTON4_PRESSED;
+	    break;
+	}
+    }
+
+    return result;
+}
+
+static int
+console_twait(
+		 SCREEN *sp,
+		 HANDLE fd,
+		 int mode,
+		 int milliseconds,
+		 int *timeleft
+		 EVENTLIST_2nd(_nc_eventlist * evl))
+{
+    INPUT_RECORD inp_rec;
+    BOOL b;
+    DWORD nRead = 0, rc = (DWORD) (-1);
+    int code = 0;
+    FILETIME fstart;
+    FILETIME fend;
+    int diff;
+    bool isImmed = (milliseconds == 0);
+
+#define CONSUME() ReadConsoleInput(fd,&inp_rec,1,&nRead)
+
+    assert(sp);
+
+    TR(TRACE_IEVENT, ("start twait: %d milliseconds, mode: %d",
+		      milliseconds, mode));
+
+    if (milliseconds < 0)
+	milliseconds = INFINITY;
+
+    memset(&inp_rec, 0, sizeof(inp_rec));
+
+    while (true) {
+	GetSystemTimeAsFileTime(&fstart);
+	rc = WaitForSingleObject(fd, (DWORD) milliseconds);
+	GetSystemTimeAsFileTime(&fend);
+	diff = (int) tdiff(fstart, fend);
+	milliseconds = Adjust(milliseconds, diff);
+
+	if (!isImmed && milliseconds <= 0)
+	    break;
+
+	if (rc == WAIT_OBJECT_0) {
+	    if (mode) {
+		b = GetNumberOfConsoleInputEvents(fd, &nRead);
+		if (b && nRead > 0) {
+		    b = PeekConsoleInput(fd, &inp_rec, 1, &nRead);
+		    if (b && nRead > 0) {
+			switch (inp_rec.EventType) {
+			case KEY_EVENT:
+			    if (mode & TW_INPUT) {
+				WORD vk = inp_rec.Event.KeyEvent.wVirtualKeyCode;
+				char ch = inp_rec.Event.KeyEvent.uChar.AsciiChar;
+
+				if (inp_rec.Event.KeyEvent.bKeyDown) {
+				    if (0 == ch) {
+					int nKey = MapKey(vk);
+					if (nKey < 0) {
+					    CONSUME();
+					    continue;
+					}
+				    }
+				    code = TW_INPUT;
+				    goto end;
+				} else {
+				    CONSUME();
+				}
+			    }
+			    continue;
+			case MOUSE_EVENT:
+			    if (decode_mouse(sp,
+					     (inp_rec.Event.MouseEvent.dwButtonState
+					      & BUTTON_MASK)) == 0) {
+				CONSUME();
+			    } else if (mode & TW_MOUSE) {
+				code = TW_MOUSE;
+				goto end;
+			    }
+			    continue;
+			    /* e.g., FOCUS_EVENT */
+			default:
+			    CONSUME();
+			    selectActiveHandle();
+			    continue;
+			}
+		    }
+		}
+	    }
+	    continue;
+	} else {
+	    if (rc != WAIT_TIMEOUT) {
+		code = -1;
+		break;
+	    } else {
+		code = 0;
+		break;
+	    }
+	}
+    }
+  end:
+
+    TR(TRACE_IEVENT, ("end twait: returned %d (%d), remaining time %d msec",
+		      code, errno, milliseconds));
+
+    if (timeleft)
+	*timeleft = milliseconds;
+
+    return code;
+}
+
+static int
+wcon_twait(TERMINAL_CONTROL_BLOCK * TCB,
+	   int mode,
+	   int milliseconds,
+	   int *timeleft
+	   EVENTLIST_2nd(_nc_eventlist * evl))
+{
+    SCREEN *sp;
+    int code = 0;
+
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+
+	code = console_twait(sp,
+			     CON.inp,
+			     mode,
+			     milliseconds,
+			     timeleft EVENTLIST_2nd(_nc_eventlist * evl));
+    }
+    return code;
+}
+
+static bool
+handle_mouse(SCREEN *sp, MOUSE_EVENT_RECORD mer)
+{
+    MEVENT work;
+    bool result = FALSE;
+
+    assert(sp);
+
+    sp->_drv_mouse_old_buttons = sp->_drv_mouse_new_buttons;
+    sp->_drv_mouse_new_buttons = mer.dwButtonState & BUTTON_MASK;
+
+    /*
+     * We're only interested if the button is pressed or released.
+     * FIXME: implement continuous event-tracking.
+     */
+    if (sp->_drv_mouse_new_buttons != sp->_drv_mouse_old_buttons) {
+
+	memset(&work, 0, sizeof(work));
+
+	if (sp->_drv_mouse_new_buttons) {
+
+	    work.bstate |= (mmask_t) decode_mouse(sp, sp->_drv_mouse_new_buttons);
+
+	} else {
+
+	    /* cf: BUTTON_PRESSED, BUTTON_RELEASED */
+	    work.bstate |= (mmask_t) (decode_mouse(sp,
+						   sp->_drv_mouse_old_buttons)
+				      >> 1);
+
+	    result = TRUE;
+	}
+
+	work.x = mer.dwMousePosition.X;
+	work.y = mer.dwMousePosition.Y - AdjustY();
+
+	sp->_drv_mouse_fifo[sp->_drv_mouse_tail] = work;
+	sp->_drv_mouse_tail += 1;
+    }
+
+    return result;
+}
+
+static int
+wcon_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf)
+{
+    SCREEN *sp;
+    int n = -1;
+
+    T((T_CALLED("win32con::wcon_read(%p)"), TCB));
+
+    assert(buf);
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+
+	n = _nc_mingw_console_read(sp, CON.inp, buf);
+    }
+    returnCode(n);
+}
+
+static int
+wcon_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms)
+{
+    T((T_CALLED("win32con::wcon_nap(%p, %d)"), TCB, ms));
+    Sleep((DWORD) ms);
+    returnCode(OK);
+}
+
+static int
+wcon_cursorSet(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int mode)
+{
+    int res = -1;
+
+    T((T_CALLED("win32con:wcon_cursorSet(%d)"), mode));
+    if (okConsoleHandle(TCB)) {
+	CONSOLE_CURSOR_INFO this_CI = CON.save_CI;
+	switch (mode) {
+	case 0:
+	    this_CI.bVisible = FALSE;
+	    break;
+	case 1:
+	    break;
+	case 2:
+	    this_CI.dwSize = 100;
+	    break;
+	}
+	SetConsoleCursorInfo(CON.hdl, &this_CI);
+    }
+    returnCode(res);
+}
+
+static bool
+wcon_kyExist(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int keycode)
+{
+    WORD nKey;
+    void *res;
+    bool found = FALSE;
+    LONG key = GenMap(0, (WORD) keycode);
+
+    T((T_CALLED("win32con::wcon_kyExist(%d)"), keycode));
+    res = bsearch(&key,
+		  CON.rmap,
+		  (size_t) (N_INI + FKEYS),
+		  sizeof(keylist[0]),
+		  rkeycompare);
+    if (res) {
+	key = *((LONG *) res);
+	nKey = LOWORD(key);
+	if (!(nKey & 0x8000))
+	    found = TRUE;
+    }
+    returnCode(found);
+}
+
+static int
+wcon_kpad(TERMINAL_CONTROL_BLOCK * TCB, int flag GCC_UNUSED)
+{
+    SCREEN *sp;
+    int code = ERR;
+
+    T((T_CALLED("win32con::wcon_kpad(%p, %d)"), TCB, flag));
+
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+
+	if (sp) {
+	    code = OK;
+	}
+    }
+    returnCode(code);
+}
+
+static int
+wcon_keyok(TERMINAL_CONTROL_BLOCK * TCB,
+	   int keycode,
+	   int flag)
+{
+    int code = ERR;
+    SCREEN *sp;
+    WORD nKey;
+    WORD vKey;
+    void *res;
+    LONG key = GenMap(0, (WORD) keycode);
+
+    T((T_CALLED("win32con::wcon_keyok(%p, %d, %d)"), TCB, keycode, flag));
+
+    if (okConsoleHandle(TCB)) {
+	SetSP();
+
+	if (sp) {
+	    res = bsearch(&key,
+			  CON.rmap,
+			  (size_t) (N_INI + FKEYS),
+			  sizeof(keylist[0]),
+			  rkeycompare);
+	    if (res) {
+		key = *((LONG *) res);
+		vKey = HIWORD(key);
+		nKey = (LOWORD(key)) & 0x7fff;
+		if (!flag)
+		    nKey |= 0x8000;
+		*(LONG *) res = GenMap(vKey, nKey);
+	    }
+	}
+    }
+    returnCode(code);
+}
+
+NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_WIN_DRIVER = {
+    FALSE,
+	wcon_name,		/* Name */
+	wcon_CanHandle,		/* CanHandle */
+	wcon_init,		/* init */
+	wcon_release,		/* release */
+	wcon_size,		/* size */
+	wcon_sgmode,		/* sgmode */
+	wcon_conattr,		/* conattr */
+	wcon_mvcur,		/* hwcur */
+	wcon_mode,		/* mode */
+	wcon_rescol,		/* rescol */
+	wcon_rescolors,		/* rescolors */
+	wcon_setcolor,		/* color */
+	wcon_dobeepflash,	/* DoBeepFlash */
+	wcon_initpair,		/* initpair */
+	wcon_initcolor,		/* initcolor */
+	wcon_do_color,		/* docolor */
+	wcon_initmouse,		/* initmouse */
+	wcon_testmouse,		/* testmouse */
+	wcon_setfilter,		/* setfilter */
+	wcon_hwlabel,		/* hwlabel */
+	wcon_hwlabelOnOff,	/* hwlabelOnOff */
+	wcon_doupdate,		/* update */
+	wcon_defaultcolors,	/* defaultcolors */
+	wcon_print,		/* print */
+	wcon_size,		/* getsize */
+	wcon_setsize,		/* setsize */
+	wcon_initacs,		/* initacs */
+	wcon_screen_init,	/* scinit */
+	wcon_wrap,		/* scexit */
+	wcon_twait,		/* twait */
+	wcon_read,		/* read */
+	wcon_nap,		/* nap */
+	wcon_kpad,		/* kpad */
+	wcon_keyok,		/* kyOk */
+	wcon_kyExist,		/* kyExist */
+	wcon_cursorSet		/* cursorSet */
+};
+
+/* --------------------------------------------------------- */
+
+static HANDLE
+get_handle(int fd)
+{
+    intptr_t value = _get_osfhandle(fd);
+    return (HANDLE) value;
+}
+
+#if WINVER >= 0x0600
+/*   This function tests, whether or not the ncurses application
+     is running as a descendant of MSYS2/cygwin mintty terminal
+     application. mintty doesn't use Windows Console for it's screen
+     I/O, so the native Windows _isatty doesn't recognize it as
+     character device. But we can discover we are at the end of an
+     Pipe and can query to server side of the pipe, looking whether
+     or not this is mintty.
+ */
+static int
+_ismintty(int fd, LPHANDLE pMinTTY)
+{
+    HANDLE handle = get_handle(fd);
+    DWORD dw;
+    int code = 0;
+
+    T((T_CALLED("win32con::_ismintty(%d, %p)"), fd, pMinTTY));
+
+    if (handle != INVALID_HANDLE_VALUE) {
+	dw = GetFileType(handle);
+	if (dw == FILE_TYPE_PIPE) {
+	    if (GetNamedPipeInfo(handle, 0, 0, 0, 0)) {
+		ULONG pPid;
+		/* Requires NT6 */
+		if (GetNamedPipeServerProcessId(handle, &pPid)) {
+		    TCHAR buf[MAX_PATH];
+		    DWORD len = 0;
+		    /* These security attributes may allow us to
+		       create a remote thread in mintty to manipulate
+		       the terminal state remotely */
+		    HANDLE pHandle = OpenProcess(
+						    PROCESS_CREATE_THREAD
+						    | PROCESS_QUERY_INFORMATION
+						    | PROCESS_VM_OPERATION
+						    | PROCESS_VM_WRITE
+						    | PROCESS_VM_READ,
+						    FALSE,
+						    pPid);
+		    if (pMinTTY)
+			*pMinTTY = INVALID_HANDLE_VALUE;
+		    if (pHandle != INVALID_HANDLE_VALUE) {
+			if ((len = GetProcessImageFileName(
+							      pHandle,
+							      buf,
+							      (DWORD)
+							      array_length(buf)))) {
+			    TCHAR *pos = _tcsrchr(buf, _T('\\'));
+			    if (pos) {
+				pos++;
+				if (_tcsnicmp(pos, _TEXT("mintty.exe"), 10)
+				    == 0) {
+				    if (pMinTTY)
+					*pMinTTY = pHandle;
+				    code = 1;
+				}
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    returnCode(code);
+}
+#endif
+
+/*   Borrowed from ansicon project.
+     Check whether or not an I/O handle is associated with
+     a Windows console.
+*/
+static BOOL
+IsConsoleHandle(HANDLE hdl)
+{
+    DWORD dwFlag = 0;
+    BOOL result;
+
+    if (!GetConsoleMode(hdl, &dwFlag)) {
+	result = (int) WriteConsoleA(hdl, NULL, 0, &dwFlag, NULL);
+    } else {
+	result = (int) (dwFlag & ENABLE_PROCESSED_OUTPUT);
+    }
+    return result;
+}
+
+/*   Our replacement for the systems _isatty to include also
+     a test for mintty. This is called from the NC_ISATTY macro
+     defined in curses.priv.h
+ */
+int
+_nc_mingw_isatty(int fd)
+{
+    int result = 0;
+
+#ifdef __MING32__
+#define SysISATTY(fd) _isatty(fd)
+#else
+#define SysISATTY(fd) isatty(fd)
+#endif
+    if (SysISATTY(fd)) {
+	result = 1;
+    } else {
+#if WINVER >= 0x0600
+	result = _ismintty(fd, NULL);
+#endif
+    }
+    return result;
+}
+
+/*   This is used when running in terminfo mode to discover,
+     whether or not the "terminal" is actually a Windows
+     Console. It's the responsibilty of the console to deal
+     with the terminal escape sequences that are sent by
+     terminfo.
+ */
+int
+_nc_mingw_isconsole(int fd)
+{
+    HANDLE hdl = get_handle(fd);
+    int code = 0;
+
+    T((T_CALLED("win32con::_nc_mingw_isconsole(%d)"), fd));
+
+    code = (int) IsConsoleHandle(hdl);
+
+    returnCode(code);
+}
+
+#define TC_PROLOGUE(fd) \
+    SCREEN *sp;                                               \
+    TERMINAL *term = 0;                                       \
+    int code = ERR;                                           \
+    if (_nc_screen_chain == 0)                                \
+        return 0;                                             \
+    for (each_screen(sp)) {                                   \
+        if (sp->_term && (sp->_term->Filedes == fd)) {        \
+            term = sp->_term;                                 \
+            break;                                            \
+        }                                                     \
+    }                                                         \
+    assert(term != 0)
+
+int
+_nc_mingw_tcsetattr(
+		       int fd,
+		       int optional_action GCC_UNUSED,
+		       const struct termios *arg)
+{
+    TC_PROLOGUE(fd);
+
+    if (_nc_mingw_isconsole(fd)) {
+	DWORD dwFlag = 0;
+	HANDLE ofd = get_handle(fd);
+	if (ofd != INVALID_HANDLE_VALUE) {
+	    if (arg) {
+		if (arg->c_lflag & ICANON)
+		    dwFlag |= ENABLE_LINE_INPUT;
+		else
+		    dwFlag = dwFlag & (DWORD) (~ENABLE_LINE_INPUT);
+
+		if (arg->c_lflag & ECHO)
+		    dwFlag = dwFlag | ENABLE_ECHO_INPUT;
+		else
+		    dwFlag = dwFlag & (DWORD) (~ENABLE_ECHO_INPUT);
+
+		if (arg->c_iflag & BRKINT)
+		    dwFlag |= ENABLE_PROCESSED_INPUT;
+		else
+		    dwFlag = dwFlag & (DWORD) (~ENABLE_PROCESSED_INPUT);
+	    }
+	    dwFlag |= ENABLE_MOUSE_INPUT;
+	    SetConsoleMode(ofd, dwFlag);
+	    code = OK;
+	}
+    }
+    if (arg)
+	term->Nttyb = *arg;
+
+    return code;
+}
+
+int
+_nc_mingw_tcgetattr(int fd, struct termios *arg)
+{
+    TC_PROLOGUE(fd);
+
+    if (_nc_mingw_isconsole(fd)) {
+	if (arg)
+	    *arg = term->Nttyb;
+    }
+    return code;
+}
+
+int
+_nc_mingw_tcflush(int fd, int queue)
+{
+    TC_PROLOGUE(fd);
+    (void) term;
+
+    if (_nc_mingw_isconsole(fd)) {
+	if (queue == TCIFLUSH) {
+	    BOOL b = FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
+	    if (!b)
+		return (int) GetLastError();
+	}
+    }
+    return code;
+}
+
+int
+_nc_mingw_testmouse(
+		       SCREEN *sp,
+		       HANDLE fd,
+		       int delay)
+{
+    int rc = 0;
+
+    assert(sp);
+
+    if (sp->_drv_mouse_head < sp->_drv_mouse_tail) {
+	rc = TW_MOUSE;
+    } else {
+	rc = console_twait(sp,
+			   fd,
+			   TWAIT_MASK,
+			   delay,
+			   (int *) 0
+			   EVENTLIST_2nd(evl));
+    }
+    return rc;
+}
+
+int
+_nc_mingw_console_read(
+			  SCREEN *sp,
+			  HANDLE fd,
+			  int *buf)
+{
+    int rc = -1;
+    INPUT_RECORD inp_rec;
+    BOOL b;
+    DWORD nRead;
+    WORD vk;
+
+    assert(sp);
+    assert(buf);
+
+    memset(&inp_rec, 0, sizeof(inp_rec));
+
+    T((T_CALLED("_nc_mingw_console_read(%p)"), sp));
+
+    while ((b = ReadConsoleInput(fd, &inp_rec, 1, &nRead))) {
+	if (b && nRead > 0) {
+	    if (rc < 0)
+		rc = 0;
+	    rc += nRead;
+	    if (inp_rec.EventType == KEY_EVENT) {
+		if (!inp_rec.Event.KeyEvent.bKeyDown)
+		    continue;
+		*buf = (int) inp_rec.Event.KeyEvent.uChar.AsciiChar;
+		vk = inp_rec.Event.KeyEvent.wVirtualKeyCode;
+		/*
+		 * There are 24 virtual function-keys, and typically
+		 * 12 function-keys on a keyboard.  Use the shift-modifier
+		 * to provide the remaining 12 keys.
+		 */
+		if (vk >= VK_F1 && vk <= VK_F12) {
+		    if (inp_rec.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) {
+			vk = (WORD) (vk + 12);
+		    }
+		}
+		if (*buf == 0) {
+		    int key = MapKey(vk);
+		    if (key < 0)
+			continue;
+		    if (sp->_keypad_on) {
+			*buf = key;
+		    } else {
+			ungetch('\0');
+			*buf = AnsiKey(vk);
+		    }
+		}
+		break;
+	    } else if (inp_rec.EventType == MOUSE_EVENT) {
+		if (handle_mouse(sp,
+				 inp_rec.Event.MouseEvent)) {
+		    *buf = KEY_MOUSE;
+		    break;
+		}
+	    }
+	    continue;
+	}
+    }
+    returnCode(rc);
+}
+
+static bool
+InitConsole(void)
+{
+    /* initalize once, or not at all */
+    if (!console_initialized) {
+	int i;
+	DWORD num_buttons;
+	WORD a;
+	BOOL buffered = TRUE;
+	BOOL b;
+
+	START_TRACE();
+	if (_nc_mingw_isatty(0)) {
+	    CON.isMinTTY = TRUE;
+	}
+
+	for (i = 0; i < (N_INI + FKEYS); i++) {
+	    if (i < N_INI) {
+		CON.rmap[i] = CON.map[i] =
+		    (DWORD) keylist[i];
+		CON.ansi_map[i] = (DWORD) ansi_keys[i];
+	    } else {
+		CON.rmap[i] = CON.map[i] =
+		    (DWORD) GenMap((VK_F1 + (i - N_INI)),
+				   (KEY_F(1) + (i - N_INI)));
+		CON.ansi_map[i] =
+		    (DWORD) GenMap((VK_F1 + (i - N_INI)),
+				   (';' + (i - N_INI)));
+	    }
+	}
+	qsort(CON.ansi_map,
+	      (size_t) (MAPSIZE),
+	      sizeof(keylist[0]),
+	      keycompare);
+	qsort(CON.map,
+	      (size_t) (MAPSIZE),
+	      sizeof(keylist[0]),
+	      keycompare);
+	qsort(CON.rmap,
+	      (size_t) (MAPSIZE),
+	      sizeof(keylist[0]),
+	      rkeycompare);
+
+	if (GetNumberOfConsoleMouseButtons(&num_buttons)) {
+	    CON.numButtons = (int) num_buttons;
+	} else {
+	    CON.numButtons = 1;
+	}
+
+	a = MapColor(true, COLOR_WHITE) | MapColor(false, COLOR_BLACK);
+	for (i = 0; i < NUMPAIRS; i++)
+	    CON.pairs[i] = a;
+
+	CON.inp = GetStdHandle(STD_INPUT_HANDLE);
+	CON.out = GetStdHandle(STD_OUTPUT_HANDLE);
+
+	b = AllocConsole();
+
+	if (!b)
+	    b = AttachConsole(ATTACH_PARENT_PROCESS);
+
+	if (getenv("NCGDB") || getenv("NCURSES_CONSOLE2")) {
+	    T(("... will not buffer console"));
+	    buffered = FALSE;
+	    CON.hdl = CON.out;
+	} else {
+	    T(("... creating console buffer"));
+	    CON.hdl = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
+						0,
+						NULL,
+						CONSOLE_TEXTMODE_BUFFER,
+						NULL);
+	}
+
+	if (CON.hdl != INVALID_HANDLE_VALUE) {
+	    CON.buffered = buffered;
+	    get_SBI();
+	    CON.save_SBI = CON.SBI;
+	    if (!buffered) {
+		save_original_screen();
+		set_scrollback(FALSE, &CON.SBI);
+	    }
+	    GetConsoleCursorInfo(CON.hdl, &CON.save_CI);
+	    T(("... initial cursor is %svisible, %d%%",
+	       (CON.save_CI.bVisible ? "" : "not-"),
+	       (int) CON.save_CI.dwSize));
+	}
+
+	console_initialized = TRUE;
+    }
+    return (CON.hdl != INVALID_HANDLE_VALUE);
+}
+
+static bool
+okConsoleHandle(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    return ((TCB != 0) &&
+	    (TCB->magic == WINMAGIC) &&
+	    InitConsole());
+}
+
+/*
+ * While a constructor would ensure that this module is initialized, that will
+ * interfere with applications that may combine this with GUI interfaces.
+ */
+#if 0
+static
+__attribute__((constructor))
+     void _enter_console(void)
+{
+    (void) InitConsole();
+}
+#endif
