/****************************************************************************
 * Copyright 2020,2021 Thomas E. Dickey                                     *
 * Copyright 1998-2009,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.                                                           *
 ****************************************************************************/

/****************************************************************************
 *  Author: Juergen Pfeifer                                                 *
 *     and: Thomas E. Dickey                                                *
 ****************************************************************************/

/*
 * TODO - GetMousePos(POINT * result) from ntconio.c
 */

#include <curses.priv.h>

MODULE_ID("$Id: lib_win32con.c,v 1.7 2021/09/04 10:54:35 tom Exp $")

#ifdef _NC_WINDOWS

#ifdef _NC_MINGW
#include <wchar.h>
#else
#include <tchar.h>
#endif

#include <io.h>

#if USE_WIDEC_SUPPORT
#define write_screen WriteConsoleOutputW
#define read_screen  ReadConsoleOutputW
#else
#define write_screen WriteConsoleOutput
#define read_screen  ReadConsoleOutput
#endif

static BOOL IsConsoleHandle(HANDLE hdl);
static bool save_original_screen(void);
static bool restore_original_screen(void) GCC_UNUSED;
static bool read_screen_data(void);
static int  Adjust(int milliseconds, int diff);
static int  decode_mouse(SCREEN *sp, int mask);
static bool handle_mouse(SCREEN *sp, MOUSE_EVENT_RECORD mer);
static int  rkeycompare(const void *el1, const void *el2);
static int  keycompare(const void *el1, const void *el2);
static int  MapKey(WORD vKey);
static int  AnsiKey(WORD vKey);

static ULONGLONG tdiff(FILETIME fstart, FILETIME fend);

#define GenMap(vKey,key) MAKELONG(key, vKey)
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 array_length(a) (sizeof(a)/sizeof(a[0]))
#define N_INI ((int)array_length(keylist))
#define FKEYS 24
#define MAPSIZE (FKEYS + N_INI)

/*   A process can only have a single console, so it is safe
     to maintain all the information about it in a single
     static structure.
 */
NCURSES_EXPORT_VAR(ConsoleInfo) _nc_CONSOLE;
static bool console_initialized = FALSE;

#define EnsureInit() (void)(console_initialized ? TRUE : _nc_console_checkinit(TRUE, TRUE))

#define REQUIRED_MAX_V (DWORD)10
#define REQUIRED_MIN_V (DWORD)0
#define REQUIRED_BUILD (DWORD)17763
/*
  This function returns 0 if the Windows version has no support for
  the modern Console interface, otherwise it returns 1
 */
NCURSES_EXPORT(int)
_nc_console_vt_supported(void)
{
    OSVERSIONINFO osvi;
    int res = 0;

    T((T_CALLED("lib_win32con::_nc_console_vt_supported")));
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    GetVersionEx(&osvi);
    T(("GetVersionEx returnedMajor=%ld, Minor=%ld, Build=%ld",
       osvi.dwMajorVersion,
       osvi.dwMinorVersion,
       osvi.dwBuildNumber));
    if (osvi.dwMajorVersion >= REQUIRED_MAX_V) {
      if (osvi.dwMajorVersion == REQUIRED_MAX_V) {
          if (((osvi.dwMinorVersion == REQUIRED_MIN_V) &&
               (osvi.dwBuildNumber >= REQUIRED_BUILD)) ||
              ((osvi.dwMinorVersion > REQUIRED_MIN_V)))
              res = 1;
      } else
          res = 1;
    }
    returnCode(res);
}

NCURSES_EXPORT(void)
_nc_console_size(int* Lines, int* Cols)
{
  EnsureInit();
  if (Lines != NULL && Cols != NULL) {
      if (WINCONSOLE.buffered) {
          *Lines = (int) (WINCONSOLE.SBI.dwSize.Y);
          *Cols = (int) (WINCONSOLE.SBI.dwSize.X);
      } else {
          *Lines = (int) (WINCONSOLE.SBI.srWindow.Bottom + 1 -
                          WINCONSOLE.SBI.srWindow.Top);
          *Cols = (int) (WINCONSOLE.SBI.srWindow.Right + 1 -
                         WINCONSOLE.SBI.srWindow.Left);
      }
  }
}

/* Convert a file descriptor into a HANDLE
   That's not necessarily a console HANDLE
*/
NCURSES_EXPORT(HANDLE)
_nc_console_handle(int fd)
{
    intptr_t value = _get_osfhandle(fd);
    return (HANDLE) value;
}

/* Validate that a HANDLE is actually a
   console HANDLE
*/
static BOOL
IsConsoleHandle(HANDLE hdl)
{
    DWORD dwFlag = 0;
    BOOL result = FALSE;

    T((T_CALLED("lib_win32con::IsConsoleHandle(HANDLE=%p"), hdl));

    EnsureInit();

    if (!GetConsoleMode(hdl, &dwFlag)) {
        T(("GetConsoleMode failed"));
    } else {
        result = TRUE;
    }

    returnBool(result);
}

/*   This is used when running in terminfo mode to discover,
     whether or not the "terminal" is actually a Windows
     Console. It is the responsibility of the console to deal
     with the terminal escape sequences that are sent by
     terminfo.
 */
NCURSES_EXPORT(int)
_nc_console_test(int fd)
{
    int code = 0;
    HANDLE hdl = INVALID_HANDLE_VALUE;
    T((T_CALLED("lib_win32con::_nc_console_test(%d)"), fd));
    hdl = _nc_console_handle(fd);
    code = (int) IsConsoleHandle(hdl);
    returnCode(code);
}

#define OutHandle() ((WINCONSOLE.isTermInfoConsole || WINCONSOLE.progMode) ? WINCONSOLE.hdl : WINCONSOLE.out)

NCURSES_EXPORT(void)
_nc_console_selectActiveHandle(void)
{
    if (WINCONSOLE.lastOut != WINCONSOLE.hdl) {
        WINCONSOLE.lastOut = WINCONSOLE.hdl;
        SetConsoleActiveScreenBuffer(WINCONSOLE.lastOut);
    }
}

NCURSES_EXPORT(HANDLE)
_nc_console_fd2handle(int fd)
{
    HANDLE hdl = _nc_console_handle(fd);
    if (hdl==WINCONSOLE.inp) {
        T(("lib_win32con:validateHandle %d -> WINCONSOLE.inp", fd));
    } else if (hdl==WINCONSOLE.hdl) {
        T(("lib_win32con:validateHandle %d -> WINCONSOLE.hdl", fd));
    } else if (hdl==WINCONSOLE.out) {
        T(("lib_win32con:validateHandle %d -> WINCONSOLE.out", fd));
    } else {
        T(("lib_win32con:validateHandle %d maps to unknown HANDLE", fd));
        hdl = INVALID_HANDLE_VALUE;
    }
#if 1
    assert(hdl != INVALID_HANDLE_VALUE);
#endif
    if (hdl != INVALID_HANDLE_VALUE) {
        if (hdl != WINCONSOLE.inp && (!WINCONSOLE.isTermInfoConsole && WINCONSOLE.progMode)) {
            if (hdl==WINCONSOLE.out && hdl!=WINCONSOLE.hdl) {
                T(("lib_win32con:validateHandle forcing WINCONSOLE.out -> WINCONSOLE.hdl"));
                hdl = WINCONSOLE.hdl;
            }
        }
    }
    return hdl;
}

NCURSES_EXPORT(int)
_nc_console_setmode(HANDLE hdl, const TTY *arg)
{
    DWORD dwFlag = 0;
    int code = ERR;
    HANDLE alt;

    if (arg) {
#ifdef TRACE
        TTY TRCTTY;
#define TRCTTYOUT(flag) TRCTTY.dwFlagOut = flag
#define TRCTTYIN(flag)  TRCTTY.dwFlagIn = flag
#else
#define TRCTTYOUT(flag)
#define TRCTTYIN(flag)
#endif
        T(("lib_win32con:_nc_console_setmode %s", _nc_trace_ttymode(arg)));
        if (hdl==WINCONSOLE.inp) {
            dwFlag = arg->dwFlagIn | ENABLE_MOUSE_INPUT | VT_FLAG_IN;
            if (WINCONSOLE.isTermInfoConsole)
                dwFlag |= (VT_FLAG_IN);
            else
                dwFlag &= (DWORD) ~(VT_FLAG_IN);
            TRCTTYIN(dwFlag);
            SetConsoleMode(hdl, dwFlag);

            alt = OutHandle();
            dwFlag = arg->dwFlagOut;
            if (WINCONSOLE.isTermInfoConsole)
                dwFlag |= (VT_FLAG_OUT);
            else
                dwFlag |= (VT_FLAG_OUT);
            TRCTTYOUT(dwFlag);
            SetConsoleMode(alt, dwFlag);
        } else {
            dwFlag = arg->dwFlagOut;
            if (WINCONSOLE.isTermInfoConsole)
                dwFlag |= (VT_FLAG_OUT);
            else
                dwFlag |= (VT_FLAG_OUT);
            TRCTTYOUT(dwFlag);
            SetConsoleMode(hdl, dwFlag);

            alt = WINCONSOLE.inp;
            dwFlag = arg->dwFlagIn | ENABLE_MOUSE_INPUT;
            if (WINCONSOLE.isTermInfoConsole)
                dwFlag |= (VT_FLAG_IN);
            else
                dwFlag &= (DWORD) ~(VT_FLAG_IN);
            TRCTTYIN(dwFlag);
            SetConsoleMode(alt, dwFlag);
            T(("effective mode set %s", _nc_trace_ttymode(&TRCTTY)));
        }
        code = OK;
    }
    return(code);
}

NCURSES_EXPORT(int)
_nc_console_getmode(HANDLE hdl, TTY *arg)
{
    int code = ERR;

    if (arg) {
        DWORD dwFlag = 0;
        HANDLE alt;

        if (hdl==WINCONSOLE.inp) {
            if(GetConsoleMode(hdl, &dwFlag)) {
                arg->dwFlagIn = dwFlag;
                alt = OutHandle();
                if (GetConsoleMode(alt, &dwFlag)) {
                    arg->dwFlagOut = dwFlag;
                    code = OK;
                }
            }
        } else {
            if (GetConsoleMode(hdl, &dwFlag)) {
                arg->dwFlagOut = dwFlag;
                alt = WINCONSOLE.inp;
                if (GetConsoleMode(alt, &dwFlag)) {
                    arg->dwFlagIn = dwFlag;
                    code = OK;
                }
            }
        }
    }
    T(("lib_win32con:_nc_console_getmode %s", _nc_trace_ttymode(arg)));
    return(code);
}

NCURSES_EXPORT(int)
_nc_console_flush(HANDLE hdl)
{
    int code = OK;

    T((T_CALLED("lib_win32con::_nc_console_flush(hdl=%p"), hdl));

    if (hdl != INVALID_HANDLE_VALUE) {
        if (hdl == WINCONSOLE.hdl ||
            hdl == WINCONSOLE.inp ||
            hdl == WINCONSOLE.out) {
            if (!FlushConsoleInputBuffer(WINCONSOLE.inp))
                code = ERR;
        } else {
            code = ERR;
            T(("_nc_console_flush not requesting a handle owned by console."));
        }
    }
    returnCode(code);
}

NCURSES_EXPORT(WORD)
_nc_console_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;
}


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

    WINCONSOLE.save_region.Top = 0;
    WINCONSOLE.save_region.Left = 0;
    WINCONSOLE.save_region.Bottom = (SHORT) (WINCONSOLE.SBI.dwSize.Y - 1);
    WINCONSOLE.save_region.Right = (SHORT) (WINCONSOLE.SBI.dwSize.X - 1);

    if (read_screen_data()) {
        result = TRUE;
    } else {

        WINCONSOLE.save_region.Top = WINCONSOLE.SBI.srWindow.Top;
        WINCONSOLE.save_region.Left = WINCONSOLE.SBI.srWindow.Left;
        WINCONSOLE.save_region.Bottom = WINCONSOLE.SBI.srWindow.Bottom;
        WINCONSOLE.save_region.Right = WINCONSOLE.SBI.srWindow.Right;

        WINCONSOLE.window_only = TRUE;

        if (read_screen_data()) {
            result = TRUE;
        }
    }

    T(("... save original screen contents %s", result ? "ok" : "err"));
    return result;
}

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 bool
read_screen_data(void)
{
    bool result = FALSE;
    COORD bufferCoord;
    size_t want;

    WINCONSOLE.save_size.X = (SHORT) (WINCONSOLE.save_region.Right
                                      - WINCONSOLE.save_region.Left + 1);
    WINCONSOLE.save_size.Y = (SHORT) (WINCONSOLE.save_region.Bottom
                                      - WINCONSOLE.save_region.Top + 1);

    want = (size_t) (WINCONSOLE.save_size.X * WINCONSOLE.save_size.Y);

    if ((WINCONSOLE.save_screen = malloc(want * sizeof(CHAR_INFO))) != 0) {
        bufferCoord.X = (SHORT) (WINCONSOLE.window_only ?
                                 WINCONSOLE.SBI.srWindow.Left : 0);
        bufferCoord.Y = (SHORT) (WINCONSOLE.window_only ?
                                 WINCONSOLE.SBI.srWindow.Top : 0);

        T(("... reading console %s %dx%d into %d,%d - %d,%d at %d,%d",
           WINCONSOLE.window_only ? "window" : "buffer",
           WINCONSOLE.save_size.Y, WINCONSOLE.save_size.X,
           WINCONSOLE.save_region.Top,
           WINCONSOLE.save_region.Left,
           WINCONSOLE.save_region.Bottom,
           WINCONSOLE.save_region.Right,
           bufferCoord.Y,
           bufferCoord.X));

        if (read_screen(WINCONSOLE.hdl,
                        WINCONSOLE.save_screen,
                        WINCONSOLE.save_size,
                        bufferCoord,
                        &WINCONSOLE.save_region)) {
            result = TRUE;
        } else {
            T((" error %#lx", (unsigned long) GetLastError()));
            FreeAndNull(WINCONSOLE.save_screen);
        }
    }

    return result;
}

NCURSES_EXPORT(bool)
_nc_console_get_SBI(void)
{
    bool rc = FALSE;
    if (GetConsoleScreenBufferInfo(WINCONSOLE.hdl, &(WINCONSOLE.SBI))) {
        T(("GetConsoleScreenBufferInfo"));
        T(("... buffer(X:%d Y:%d)",
           WINCONSOLE.SBI.dwSize.X,
           WINCONSOLE.SBI.dwSize.Y));
        T(("... window(X:%d Y:%d)",
           WINCONSOLE.SBI.dwMaximumWindowSize.X,
           WINCONSOLE.SBI.dwMaximumWindowSize.Y));
        T(("... cursor(X:%d Y:%d)",
           WINCONSOLE.SBI.dwCursorPosition.X,
           WINCONSOLE.SBI.dwCursorPosition.Y));
        T(("... display(Top:%d Bottom:%d Left:%d Right:%d)",
           WINCONSOLE.SBI.srWindow.Top,
           WINCONSOLE.SBI.srWindow.Bottom,
           WINCONSOLE.SBI.srWindow.Left,
           WINCONSOLE.SBI.srWindow.Right));
        if (WINCONSOLE.buffered) {
            WINCONSOLE.origin.X = 0;
            WINCONSOLE.origin.Y = 0;
        } else {
            WINCONSOLE.origin.X = WINCONSOLE.SBI.srWindow.Left;
            WINCONSOLE.origin.Y = WINCONSOLE.SBI.srWindow.Top;
        }
        rc = TRUE;
    } else {
        T(("GetConsoleScreenBufferInfo ERR"));
    }
    return rc;
}

#define MIN_WIDE 80
#define MIN_HIGH 24

/*
 * In "normal" mode, reset the buffer- and window-sizes back to their original values.
 */
NCURSES_EXPORT(void)
_nc_console_set_scrollback(bool normal, CONSOLE_SCREEN_BUFFER_INFO * info)
{
    SMALL_RECT rect;
    COORD coord;
    bool changed = FALSE;

    T((T_CALLED("lib_win32con::_nc_console_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, &WINCONSOLE.SBI, sizeof(*info)) != 0) {
            changed = TRUE;
            WINCONSOLE.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(WINCONSOLE.hdl, coord);      /* dwSize */
        SetConsoleWindowInfo(WINCONSOLE.hdl, TRUE, &rect);      /* srWindow */
        _nc_console_get_SBI();
    }
    returnVoid;
}

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 (WINCONSOLE.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;
}

#define AdjustY() (WINCONSOLE.buffered ? 0 : (int) WINCONSOLE.SBI.srWindow.Top)

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
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)
{
    int code = -1;

    if (!WINCONSOLE.isTermInfoConsole) {
        WORD nKey = 0;
        void *res;
        LONG key = GenMap(vKey, 0);

        res = bsearch(&key,
                      WINCONSOLE.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)
{
    int code = -1;

    if (!WINCONSOLE.isTermInfoConsole) {
        WORD nKey = 0;
        void *res;
        LONG key = GenMap(vKey, 0);

        res = bsearch(&key,
                      WINCONSOLE.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;
}

NCURSES_EXPORT(int)
_nc_console_keyok(int keycode, int flag)
{
    int code = ERR;
    WORD nKey;
    WORD vKey;
    void *res;
    LONG key = GenMap(0, (WORD) keycode);

    T((T_CALLED("lib_win32con::_nc_console_keyok(%d, %d)"), keycode, flag));

    res = bsearch(&key,
                  WINCONSOLE.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(bool)
_nc_console_keyExist(int keycode)
{
    WORD nKey;
    void *res;
    bool found = FALSE;
    LONG key = GenMap(0, (WORD) keycode);

    T((T_CALLED("lib_win32con::_nc_console_keyExist(%d)"), keycode));
    res = bsearch(&key,
                  WINCONSOLE.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);
}

NCURSES_EXPORT(int)
_nc_console_twait(
    SCREEN *sp,
    HANDLE hdl,
    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 isNoDelay = (milliseconds == 0);

#ifdef NCURSES_WGETCH_EVENTS
    (void) evl;                 /* TODO: implement wgetch-events */
#endif

#define IGNORE_CTRL_KEYS (SHIFT_PRESSED|LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED| \
                          LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)
#define CONSUME() ReadConsoleInput(hdl, &inp_rec, 1, &nRead)

    assert(sp);

    TR(TRACE_IEVENT, ("start twait: hdl=%p, %d milliseconds, mode: %d",
                      hdl, milliseconds, mode));

    if (milliseconds < 0)
        milliseconds = INFINITY;

    memset(&inp_rec, 0, sizeof(inp_rec));

    while (true) {
        if (!isNoDelay) {
            GetSystemTimeAsFileTime(&fstart);
            rc = WaitForSingleObject(hdl, (DWORD) milliseconds);
            GetSystemTimeAsFileTime(&fend);
            diff = (int) tdiff(fstart, fend);
            milliseconds = Adjust(milliseconds, diff);
            if (milliseconds< 0)
                break;
        }

        if (isNoDelay || (rc == WAIT_OBJECT_0)) {
            if (mode) {
                nRead = 0;
                b = GetNumberOfConsoleInputEvents(hdl, &nRead);
                if (!b) {
                    T(("twait:err GetNumberOfConsoleInputEvents"));
                }
                if (isNoDelay && b) {
                    T(("twait: Events Available: %ld", nRead));
                    if (nRead==0) {
                        code = 0;
                        goto end;
                    } else {
                        DWORD n = 0;
                        INPUT_RECORD* pInpRec =
                            TypeAlloca(INPUT_RECORD, nRead);
                        if (pInpRec != NULL) {
                            DWORD i;
                            BOOL f;
                            memset(pInpRec, 0, sizeof(INPUT_RECORD)*nRead);
                            f = PeekConsoleInput(hdl, pInpRec, nRead, &n);
                            if (f) {
                                for(i = 0; i < n; i++) {
                                    if (pInpRec[i].EventType==KEY_EVENT) {
                                        if(pInpRec[i].Event.KeyEvent.bKeyDown) {
                                          DWORD ctrlMask =
                                              (pInpRec[i].Event.KeyEvent.dwControlKeyState &
                                               IGNORE_CTRL_KEYS);
                                          if (!ctrlMask) {
                                              code = TW_INPUT;
                                              goto end;
                                          }
                                        }
                                    }
                                }
                            } else {
                                T(("twait:err PeekConsoleInput"));
                            }
                            code = 0;
                            goto end;
                        } else {
                            T(("twait:err could not alloca input records"));
                        }
                    }
                }
                if (b && nRead > 0) {
                    b = PeekConsoleInput(hdl, &inp_rec, 1, &nRead);
                    if (!b) {
                        T(("twait:err PeekConsoleInput"));
                    }
                    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;
                                T(("twait:event KEY_EVENT"));
                                T(("twait vk=%d, ch=%d, keydown=%d",
                                   vk, ch, inp_rec.Event.KeyEvent.bKeyDown));
                                if (inp_rec.Event.KeyEvent.bKeyDown) {
                                    T(("twait:event KeyDown"));
                                    if (!WINCONSOLE.isTermInfoConsole &&
                                        (0 == ch)) {
                                        int nKey = MapKey(vk);
                                        if (nKey < 0) {
                                            CONSUME();
                                            continue;
                                        }
                                    }
                                    code = TW_INPUT;
                                    goto end;
                                } else {
                                    CONSUME();
                                }
                            }
                            continue;
                        case MOUSE_EVENT:
                            T(("twait:event 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:
                            T(("twait:event Tyoe %d", inp_rec.EventType));
                            CONSUME();
                            _nc_console_selectActiveHandle();
                            continue;
                        }
                    }
                }
            }
            continue;
        } else {
            if (rc != WAIT_TIMEOUT) {
                code = -1;
                break;
            } else {
                code = 0;
                break;
            }
        }
    }
end:

    TR(TRACE_IEVENT, ("end twait: returned %d (%lu), remaining time %d msec",
                      code, GetLastError(), milliseconds));

    if (timeleft)
        *timeleft = milliseconds;

    return code;
}

NCURSES_EXPORT(int)
_nc_console_testmouse(
                      SCREEN *sp,
                      HANDLE hdl,
                      int delay
                      EVENTLIST_2nd(_nc_eventlist * evl))
{
    int rc = 0;

    assert(sp);

    if (sp->_drv_mouse_head < sp->_drv_mouse_tail) {
        rc = TW_MOUSE;
    } else {
        rc = _nc_console_twait(sp,
                               hdl,
                               TWAIT_MASK,
                               delay,
                               (int *) 0
                               EVENTLIST_2nd(evl));
    }
    return rc;
}

NCURSES_EXPORT(int)
_nc_console_read(
                 SCREEN *sp,
                 HANDLE hdl,
                 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("lib_win32con::_nc_console_read(%p)"), sp));

    while ((b = ReadConsoleInput(hdl, &inp_rec, 1, &nRead))) {
        if (b && nRead > 0) {
            if (rc < 0)
                rc = 0;
            rc = rc + (int) 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);
}

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

     Return codes:
     - 0 : Not a TTY
     - 1 : A Windows character device detected by _isatty
     - 2 : A future implementation may return 2 for mintty
 */
NCURSES_EXPORT(int)
_nc_console_isatty(int fd)
{
    int result = 0;
    T((T_CALLED("lib_win32con::_nc_console_isatty(%d"), fd));

    if (_isatty(fd))
        result = 1;
#ifdef _NC_CHECK_MINTTY
    else {
        if (_nc_console_checkmintty(fd, NULL)) {
            result = 2;
            fprintf(stderr, "ncurses on Windows must run in a Windows console.\n");
            fprintf(stderr, "On newer versions of Windows, the calling program should create a PTY-like.\n");
            fprintf(stderr, "device using the CreatePseudoConsole Windows API call.\n");
            exit(EXIT_FAILURE);
        }
    }
#endif
    returnCode(result);
}

NCURSES_EXPORT(bool)
_nc_console_checkinit(bool initFlag, bool assumeTermInfo)
{
    bool res = FALSE;

    T((T_CALLED("lib_win32con::_nc_console_checkinit(initFlag=%d, assumeTermInfo=%d)"),
       initFlag, assumeTermInfo));

    if (!initFlag) {
        res = console_initialized;
    } else {
        /* initialize once, or not at all */
        if (!console_initialized) {
            int i;
            DWORD num_buttons;
            WORD a;
            BOOL buffered = FALSE;
            BOOL b;

            START_TRACE();
            WINCONSOLE.isTermInfoConsole = assumeTermInfo;

            WINCONSOLE.map = (LPDWORD)malloc(sizeof(DWORD)*MAPSIZE);
            WINCONSOLE.rmap = (LPDWORD)malloc(sizeof(DWORD)*MAPSIZE);
            WINCONSOLE.ansi_map = (LPDWORD)malloc(sizeof(DWORD)*MAPSIZE);

            for (i = 0; i < (N_INI + FKEYS); i++) {
                if (i < N_INI) {
                    WINCONSOLE.rmap[i] = WINCONSOLE.map[i] =
                        (DWORD) keylist[i];
                    WINCONSOLE.ansi_map[i] = (DWORD) ansi_keys[i];
                } else {
                    WINCONSOLE.rmap[i] = WINCONSOLE.map[i] =
                        (DWORD) GenMap((VK_F1 + (i - N_INI)),
                                       (KEY_F(1) + (i - N_INI)));
                    WINCONSOLE.ansi_map[i] =
                        (DWORD) GenMap((VK_F1 + (i - N_INI)),
                                       (';' + (i - N_INI)));
                }
            }
            qsort(WINCONSOLE.ansi_map,
                  (size_t) (MAPSIZE),
                  sizeof(keylist[0]),
                  keycompare);
            qsort(WINCONSOLE.map,
                  (size_t) (MAPSIZE),
                  sizeof(keylist[0]),
                  keycompare);
            qsort(WINCONSOLE.rmap,
                  (size_t) (MAPSIZE),
                  sizeof(keylist[0]),
                  rkeycompare);

            if (GetNumberOfConsoleMouseButtons(&num_buttons)) {
                WINCONSOLE.numButtons = (int) num_buttons;
            } else {
                WINCONSOLE.numButtons = 1;
            }

            a = _nc_console_MapColor(true, COLOR_WHITE) |
                _nc_console_MapColor(false, COLOR_BLACK);
            for (i = 0; i < CON_NUMPAIRS; i++)
                WINCONSOLE.pairs[i] = a;

            WINCONSOLE.inp = GetStdHandle(STD_INPUT_HANDLE);
            WINCONSOLE.out = GetStdHandle(STD_OUTPUT_HANDLE);
            WINCONSOLE.hdl = WINCONSOLE.out;

            GetConsoleMode(WINCONSOLE.inp, &WINCONSOLE.originalMode.dwFlagIn);
            GetConsoleMode(WINCONSOLE.out, &WINCONSOLE.originalMode.dwFlagOut);

            if (!WINCONSOLE.isTermInfoConsole) {
                b = AllocConsole();

                if (!b)
                    b = AttachConsole(ATTACH_PARENT_PROCESS);

                if (getenv("NCGDB") || getenv("NCURSES_CONSOLE2")) {
                    T(("... will not buffer console"));
                } else {
                    T(("... creating console buffer"));
                    WINCONSOLE.hdl =
                        CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
                                                  0,
                                                  NULL,
                                                  CONSOLE_TEXTMODE_BUFFER,
                                                  NULL);
                    buffered = TRUE;
                }
            }

            /* We set binary I/O even when using the console
               driver to cover the situation, that the
               TERM variable is set to #win32con, but actually
               Windows supports virtual terminal processing.
               So if terminfo functions are used in this setup,
               they actually may work.
            */
            _setmode(fileno(stdin), _O_BINARY);
            _setmode(fileno(stdout), _O_BINARY);

            if (WINCONSOLE.hdl != INVALID_HANDLE_VALUE) {
                WINCONSOLE.buffered = buffered;
                _nc_console_get_SBI();
                WINCONSOLE.save_SBI = WINCONSOLE.SBI;
                if (!buffered) {
                    save_original_screen();
                    _nc_console_set_scrollback(FALSE, &WINCONSOLE.SBI);
                }
                GetConsoleCursorInfo(WINCONSOLE.hdl, &WINCONSOLE.save_CI);
                T(("... initial cursor is %svisible, %d%%",
                   (WINCONSOLE.save_CI.bVisible ? "" : "not-"),
                   (int) WINCONSOLE.save_CI.dwSize));
            }

            WINCONSOLE.initialized = TRUE;
            console_initialized = TRUE;
        }
        res = (WINCONSOLE.hdl != INVALID_HANDLE_VALUE);
    }
    returnBool(res);
}

#endif // _NC_WINDOWS
