/****************************************************************************
 * 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
