diff --git a/ncurses/win32con/win32_driver.c b/ncurses/win32con/win32_driver.c
new file mode 100644
index 0000000..0a43588
--- /dev/null
+++ b/ncurses/win32con/win32_driver.c
@@ -0,0 +1,1225 @@
+/****************************************************************************
+ * Copyright 2018-2020,2023 Thomas E. Dickey                                *
+ * Copyright 2008-2016,2017 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 - 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 _NC_WINDOWS
+#if (defined(__MINGW32__) || defined(__MINGW64__))
+#include <wchar.h>
+#else
+#include <tchar.h>
+#endif
+#include <io.h>
+
+#define CUR TerminalType(my_term).
+
+MODULE_ID("$Id: win32_driver.c,v 1.4 2023/09/16 16:29:24 tom Exp $")
+
+#define WINMAGIC NCDRV_MAGIC(NCDRV_WINCONSOLE)
+#define EXP_OPTIMIZE 0
+
+static bool console_initialized = FALSE;
+
+#define AssertTCB() assert(TCB != 0 && (TCB->magic == WINMAGIC))
+#define validateConsoleHandle() (AssertTCB() , console_initialized ||\
+                                 (console_initialized=\
+                                  _nc_console_checkinit(TRUE,FALSE)))
+#define SetSP() assert(TCB->csp != 0); sp = TCB->csp; (void) sp
+#define AdjustY() (WINCONSOLE.buffered ?\
+                   0 : (int) WINCONSOLE.SBI.srWindow.Top)
+#define RevAttr(attr) (WORD) (((attr) & 0xff00) |   \
+                              ((((attr) & 0x07) << 4) | \
+                               (((attr) & 0x70) >> 4)))
+
+#if USE_WIDEC_SUPPORT
+#define write_screen WriteConsoleOutputW
+#define read_screen  ReadConsoleOutputW
+#else
+#define write_screen WriteConsoleOutput
+#define read_screen  ReadConsoleOutput
+#endif
+
+static WORD
+MapAttr(WORD res, attr_t ch)
+{
+    if (ch & A_COLOR) {
+	int p;
+
+	p = PairNumber(ch);
+	if (p > 0 && p < CON_NUMPAIRS) {
+	    WORD a;
+	    a = WINCONSOLE.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 = (WINCONSOLE.SBI.dwSize.Y *
+		     (1 + WINCONSOLE.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 = WINCONSOLE.SBI.srWindow.Top;
+    save_region.Left = WINCONSOLE.SBI.srWindow.Left;
+    save_region.Bottom = WINCONSOLE.SBI.srWindow.Bottom;
+    save_region.Right = WINCONSOLE.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(WINCONSOLE.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 = TypeAlloca(CHAR_INFO, 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(WINCONSOLE.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(WINCONSOLE.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 = TypeAlloca(CHAR_INFO, 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(WINCONSOLE.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(WINCONSOLE.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 bool
+restore_original_screen(void)
+{
+    COORD bufferCoord;
+    bool result = FALSE;
+    SMALL_RECT save_region = WINCONSOLE.save_region;
+
+    T(("... restoring %s", WINCONSOLE.window_only ?
+       "window" : "entire buffer"));
+
+    bufferCoord.X = (SHORT) (WINCONSOLE.window_only ?
+			     WINCONSOLE.SBI.srWindow.Left : 0);
+    bufferCoord.Y = (SHORT) (WINCONSOLE.window_only ?
+			     WINCONSOLE.SBI.srWindow.Top : 0);
+
+    if (write_screen(WINCONSOLE.hdl,
+		     WINCONSOLE.save_screen,
+		     WINCONSOLE.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)",
+	   WINCONSOLE.save_size.Y,
+	   WINCONSOLE.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 (validateConsoleHandle()) {
+	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 == ewSuspend) {
+
+	    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 = ewRunning;
+	}
+
+	if ((CurScreen(sp)->_clear || NewScreen(sp)->_clear)) {
+	    int x;
+#if USE_WIDEC_SUPPORT
+	    cchar_t *empty = TypeAlloca(cchar_t, Width);
+	    wchar_t blank[2] =
+	    {
+		L' ', L'\0'
+	    };
+
+	    for (x = 0; x < Width; x++)
+		setcchar(&empty[x], blank, 0, 0, 0);
+#else
+	    chtype *empty = TypeAlloca(chtype, 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);
+	}
+	_nc_console_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) {
+	if (!_nc_console_vt_supported())
+	    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 && (TerminalType(&TCB->term).Booleans == 0)) {
+	_nc_init_termtype(&TerminalType(&TCB->term));
+#if NCURSES_EXT_NUMBERS
+	_nc_export_termtype2(&TCB->term.type, &TerminalType(&TCB->term));
+#endif
+    }
+
+    if (!code) {
+	if (_nc_console_test(0)) {
+	    T(("isTermInfoConsole=TRUE"));
+	    WINCONSOLE.isTermInfoConsole = TRUE;
+	}
+    }
+    returnBool(code);
+}
+
+static int
+wcon_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB,
+		 int beepFlag)
+{
+    SCREEN *sp;
+    int res = ERR;
+
+    int high = (WINCONSOLE.SBI.srWindow.Bottom -
+		WINCONSOLE.SBI.srWindow.Top + 1);
+    int wide = (WINCONSOLE.SBI.srWindow.Right -
+		WINCONSOLE.SBI.srWindow.Left + 1);
+    int max_cells = (high * wide);
+    int i;
+
+    CHAR_INFO *this_screen = TypeAlloca(CHAR_INFO, max_cells);
+    CHAR_INFO *that_screen = TypeAlloca(CHAR_INFO, max_cells);
+    COORD this_size;
+    SMALL_RECT this_region;
+    COORD bufferCoord;
+
+    if (validateConsoleHandle()) {
+	SetSP();
+	this_region.Top = WINCONSOLE.SBI.srWindow.Top;
+	this_region.Left = WINCONSOLE.SBI.srWindow.Left;
+	this_region.Bottom = WINCONSOLE.SBI.srWindow.Bottom;
+	this_region.Right = WINCONSOLE.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(WINCONSOLE.hdl,
+			this_screen,
+			this_size,
+			bufferCoord,
+			&this_region)) {
+
+	    memcpy(that_screen,
+		   this_screen,
+		   sizeof(CHAR_INFO) * (size_t) max_cells);
+
+	    for (i = 0; i < max_cells; i++) {
+		that_screen[i].Attributes =
+		    RevAttr(that_screen[i].Attributes);
+	    }
+
+	    write_screen(WINCONSOLE.hdl, that_screen, this_size,
+			 bufferCoord, &this_region);
+	    Sleep(200);
+	    write_screen(WINCONSOLE.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 void
+wcon_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
+	      int fore,
+	      int color,
+	      int (*outc) (SCREEN *, int) GCC_UNUSED)
+{
+    (void) TCB;
+    if (validateConsoleHandle()) {
+	WORD a = _nc_console_MapColor(fore, color);
+	a |= (WORD) ((WINCONSOLE.SBI.wAttributes) & (fore ? 0xfff8 : 0xff8f));
+	SetConsoleTextAttribute(WINCONSOLE.hdl, a);
+	_nc_console_get_SBI();
+    }
+}
+
+static bool
+wcon_rescol(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    bool res = FALSE;
+
+    (void) TCB;
+    if (validateConsoleHandle()) {
+	WORD a = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN;
+	SetConsoleTextAttribute(WINCONSOLE.hdl, a);
+	_nc_console_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 (validateConsoleHandle() &&
+	(Lines != NULL) && (Cols != NULL)) {
+	_nc_console_size(Lines, Cols);
+	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)
+{
+    int result = ERR;
+
+    T((T_CALLED("win32con::wcon_sgmode(TCB=(%p),setFlag=%d,TTY=(%p)"),
+       TCB, setFlag, buf));
+    if (buf != NULL && validateConsoleHandle()) {
+
+	if (setFlag) {
+	    _nc_console_setmode(WINCONSOLE.hdl, buf);
+	    TCB->term.Nttyb = *buf;
+	} else {
+	    _nc_console_getmode(WINCONSOLE.hdl, &(TCB->term.Nttyb));
+	    *buf = TCB->term.Nttyb;
+	}
+	result = OK;
+    }
+    returnCode(result);
+}
+
+#define MIN_WIDE 80
+#define MIN_HIGH 24
+
+static int
+wcon_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag)
+{
+    SCREEN *sp;
+    TERMINAL *_term = (TERMINAL *) TCB;
+    int code = ERR;
+
+    if (validateConsoleHandle()) {
+	sp = TCB->csp;
+
+	T((T_CALLED("win32con::wcon_mode(%p, progFlag=%d, defFlag=%d)"),
+	   TCB, progFlag, defFlag));
+
+	WINCONSOLE.progMode = progFlag;
+	WINCONSOLE.lastOut = progFlag ? WINCONSOLE.hdl : WINCONSOLE.out;
+	SetConsoleActiveScreenBuffer(WINCONSOLE.lastOut);
+
+	if (progFlag) /* prog mode */  {
+	    if (defFlag) {
+		if ((wcon_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) {
+		    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 (!WINCONSOLE.buffered) {
+			_nc_console_set_scrollback(FALSE, &WINCONSOLE.SBI);
+		    }
+		    code = OK;
+		}
+	    }
+	    T(("... buffered:%d, clear:%d",
+	       WINCONSOLE.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 (!WINCONSOLE.buffered) {
+		    _nc_console_set_scrollback(TRUE, &WINCONSOLE.save_SBI);
+		    if (!restore_original_screen())
+			code = ERR;
+		}
+		SetConsoleCursorInfo(WINCONSOLE.hdl, &WINCONSOLE.save_CI);
+	    }
+	}
+
+    }
+    returnCode(code);
+}
+
+static void
+wcon_screen_init(SCREEN *sp GCC_UNUSED)
+{
+}
+
+static void
+wcon_wrap(SCREEN *sp GCC_UNUSED)
+{
+}
+
+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 void
+wcon_init(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    T((T_CALLED("win32con::wcon_init(%p)"), TCB));
+
+    AssertTCB();
+
+    if (!(console_initialized = _nc_console_checkinit(TRUE, FALSE))) {
+	returnVoid;
+    }
+
+    if (TCB) {
+	TCB->info.initcolor = TRUE;
+	TCB->info.canchange = FALSE;
+	TCB->info.hascolor = TRUE;
+	TCB->info.caninit = TRUE;
+
+	TCB->info.maxpairs = CON_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 = WINCONSOLE.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 (validateConsoleHandle()) {
+	SetSP();
+
+	if ((pair > 0) && (pair < CON_NUMPAIRS) && (f >= 0) && (f < 8)
+	    && (b >= 0) && (b < 8)) {
+	    WINCONSOLE.pairs[pair] =
+		_nc_console_MapColor(true, f) |
+		_nc_console_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;
+
+    T((T_CALLED("win32con::wcon_initmouse(%p)"), TCB));
+
+    if (validateConsoleHandle()) {
+	SetSP();
+
+	sp->_mouse_type = M_TERM_DRIVER;
+    }
+    returnVoid;
+}
+
+static int
+wcon_testmouse(TERMINAL_CONTROL_BLOCK * TCB,
+	       int delay
+	       EVENTLIST_2nd(_nc_eventlist * evl))
+{
+    int rc = 0;
+    SCREEN *sp;
+
+    T((T_CALLED("win32con::wcon_testmouse(%p)"), TCB));
+    if (validateConsoleHandle()) {
+	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));
+	}
+    }
+
+    returnCode(rc);
+}
+
+static int
+wcon_mvcur(TERMINAL_CONTROL_BLOCK * TCB,
+	   int yold GCC_UNUSED, int xold GCC_UNUSED,
+	   int y, int x)
+{
+    int ret = ERR;
+
+    (void) TCB;
+    if (validateConsoleHandle()) {
+	COORD loc;
+	loc.X = (short) x;
+	loc.Y = (short) (y + AdjustY());
+	SetConsoleCursorPosition(WINCONSOLE.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 (validateConsoleHandle()) {
+	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 int
+wcon_twait(TERMINAL_CONTROL_BLOCK * TCB,
+	   int mode,
+	   int milliseconds,
+	   int *timeleft
+	   EVENTLIST_2nd(_nc_eventlist * evl))
+{
+    SCREEN *sp;
+    int code = 0;
+
+    if (validateConsoleHandle()) {
+	SetSP();
+
+	code = _nc_console_twait(sp,
+				 WINCONSOLE.inp,
+				 mode,
+				 milliseconds,
+				 timeleft EVENTLIST_2nd(evl));
+    }
+    return code;
+}
+
+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 (validateConsoleHandle()) {
+	SetSP();
+
+	n = _nc_console_read(sp, WINCONSOLE.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 (validateConsoleHandle()) {
+	CONSOLE_CURSOR_INFO this_CI = WINCONSOLE.save_CI;
+	switch (mode) {
+	case 0:
+	    this_CI.bVisible = FALSE;
+	    break;
+	case 1:
+	    break;
+	case 2:
+	    this_CI.dwSize = 100;
+	    break;
+	}
+	SetConsoleCursorInfo(WINCONSOLE.hdl, &this_CI);
+    }
+    returnCode(res);
+}
+
+static bool
+wcon_kyExist(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int keycode)
+{
+    bool found = FALSE;
+
+    T((T_CALLED("win32con::wcon_kyExist(%d)"), keycode));
+    found = _nc_console_keyExist(keycode);
+    returnBool(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 (validateConsoleHandle()) {
+	SetSP();
+
+	if (sp) {
+	    code = OK;
+	}
+    }
+    returnCode(code);
+}
+
+static int
+wcon_keyok(TERMINAL_CONTROL_BLOCK * TCB,
+	   int keycode,
+	   int flag)
+{
+    int code = ERR;
+    SCREEN *sp;
+
+    T((T_CALLED("win32con::wcon_keyok(%p, %d, %d)"), TCB, keycode, flag));
+
+    if (validateConsoleHandle()) {
+	SetSP();
+	if (sp) {
+	    code = _nc_console_keyok(keycode, flag);
+	}
+    }
+    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     */
+};
+
+#endif /* _NC_WINDOWS */
