X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fwin32con%2Fwin_driver.c;h=72a9cf53525f8a94d692384347f3b56a552df929;hp=7478aceaa146904d19cb99c6be11530b5a910e6b;hb=312665d3aaaf5d8e3ba34d80fdd650abf758272a;hpb=4ad721f3e68db15c3dfa9b042f533c89d7476366 diff --git a/ncurses/win32con/win_driver.c b/ncurses/win32con/win_driver.c index 7478acea..72a9cf53 100644 --- a/ncurses/win32con/win_driver.c +++ b/ncurses/win32con/win_driver.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2014,2015 Free Software Foundation, Inc. * + * Copyright 2018,2020 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 * @@ -40,7 +41,7 @@ #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #else #include @@ -52,13 +53,11 @@ #define PSAPI_VERSION 2 #include -#define CUR my_term.type. +#define CUR TerminalType(my_term). -MODULE_ID("$Id: win_driver.c,v 1.54 2015/01/10 23:13:24 tom Exp $") +MODULE_ID("$Id: win_driver.c,v 1.66 2020/03/01 00:18:49 tom Exp $") -#ifndef __GNUC__ -# error We need GCC to compile for MinGW -#endif +#define TypeAlloca(type,count) (type*) _alloca(sizeof(type) * (size_t) (count)) #define WINMAGIC NCDRV_MAGIC(NCDRV_WINCONSOLE) @@ -66,7 +65,8 @@ MODULE_ID("$Id: win_driver.c,v 1.54 2015/01/10 23:13:24 tom Exp $") #define array_length(a) (sizeof(a)/sizeof(a[0])) -#define okConsoleHandle(TCB) (TCB != 0 && CON.hdl != INVALID_HANDLE_VALUE) +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 @@ -260,7 +260,7 @@ static BOOL con_write16(TERMINAL_CONTROL_BLOCK * TCB, int y, int x, cchar_t *str, int limit) { int actual = 0; - CHAR_INFO ci[limit]; + CHAR_INFO *ci = TypeAlloca(CHAR_INFO, limit); COORD loc, siz; SMALL_RECT rec; int i; @@ -309,7 +309,7 @@ con_write16(TERMINAL_CONTROL_BLOCK * TCB, int y, int x, cchar_t *str, int limit) static BOOL con_write8(TERMINAL_CONTROL_BLOCK * TCB, int y, int x, chtype *str, int n) { - CHAR_INFO ci[n]; + CHAR_INFO *ci = TypeAlloca(CHAR_INFO, n); COORD loc, siz; SMALL_RECT rec; int i; @@ -480,11 +480,9 @@ wcon_doupdate(TERMINAL_CONTROL_BLOCK * TCB) int y, nonempty, n, x0, x1, Width, Height; SCREEN *sp; - AssertTCB(); - SetSP(); - T((T_CALLED("win32con::wcon_doupdate(%p)"), TCB)); if (okConsoleHandle(TCB)) { + SetSP(); Width = screen_columns(sp); Height = screen_lines(sp); @@ -495,7 +493,7 @@ wcon_doupdate(TERMINAL_CONTROL_BLOCK * TCB) CurScreen(sp)->_clear, NewScreen(sp)->_clear)); - if (SP_PARM->_endwin) { + if (SP_PARM->_endwin == ewSuspend) { T(("coming back from shell mode")); NCURSES_SP_NAME(reset_prog_mode) (NCURSES_SP_ARG); @@ -504,13 +502,13 @@ wcon_doupdate(TERMINAL_CONTROL_BLOCK * TCB) NCURSES_SP_NAME(_nc_screen_resume) (NCURSES_SP_ARG); SP_PARM->_mouse_resume(SP_PARM); - SP_PARM->_endwin = FALSE; + SP_PARM->_endwin = ewRunning; } if ((CurScreen(sp)->_clear || NewScreen(sp)->_clear)) { int x; #if USE_WIDEC_SUPPORT - cchar_t empty[Width]; + cchar_t *empty = TypeAlloca(cchar_t, Width); wchar_t blank[2] = { L' ', L'\0' @@ -519,7 +517,7 @@ wcon_doupdate(TERMINAL_CONTROL_BLOCK * TCB) for (x = 0; x < Width; x++) setcchar(&empty[x], blank, 0, 0, 0); #else - chtype empty[Width]; + chtype *empty = TypeAlloca(chtype, Width); for (x = 0; x < Width; x++) empty[x] = ' '; @@ -649,8 +647,11 @@ wcon_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, * This is intentional, to avoid unnecessary breakage of applications * using symbols. */ - if (code && (TCB->term.type.Booleans == 0)) { - _nc_init_termtype(&(TCB->term.type)); + 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) { @@ -665,53 +666,55 @@ wcon_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB, int beepFlag) { SCREEN *sp; - int res = OK; + 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]; + 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; - AssertTCB(); - - 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; + 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)) { - bufferCoord.X = this_region.Left; - bufferCoord.Y = this_region.Top; + memcpy(that_screen, + this_screen, + sizeof(CHAR_INFO) * (size_t) max_cells); - if (!beepFlag && - read_screen(CON.hdl, - this_screen, - this_size, - bufferCoord, - &this_region)) { + for (i = 0; i < max_cells; i++) { + that_screen[i].Attributes = RevAttr(that_screen[i].Attributes); + } - memcpy(that_screen, this_screen, sizeof(that_screen)); + write_screen(CON.hdl, that_screen, this_size, bufferCoord, &this_region); + Sleep(200); + write_screen(CON.hdl, this_screen, this_size, bufferCoord, &this_region); - for (i = 0; i < max_cells; i++) { - that_screen[i].Attributes = RevAttr(that_screen[i].Attributes); + } else { + MessageBeep(MB_ICONWARNING); /* MB_OK might be better */ } - - 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; } @@ -783,8 +786,6 @@ wcon_setcolor(TERMINAL_CONTROL_BLOCK * TCB, int color, int (*outc) (SCREEN *, int) GCC_UNUSED) { - AssertTCB(); - if (okConsoleHandle(TCB)) { WORD a = MapColor(fore, color); a |= (WORD) ((CON.SBI.wAttributes) & (fore ? 0xfff8 : 0xff8f)); @@ -798,7 +799,6 @@ wcon_rescol(TERMINAL_CONTROL_BLOCK * TCB) { bool res = FALSE; - AssertTCB(); if (okConsoleHandle(TCB)) { WORD a = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN; SetConsoleTextAttribute(CON.hdl, a); @@ -825,8 +825,6 @@ wcon_size(TERMINAL_CONTROL_BLOCK * TCB, int *Lines, int *Cols) { int result = ERR; - AssertTCB(); - T((T_CALLED("win32con::wcon_size(%p)"), TCB)); if (okConsoleHandle(TCB) && @@ -861,65 +859,65 @@ wcon_sgmode(TERMINAL_CONTROL_BLOCK * TCB, int setFlag, TTY * buf) DWORD dwFlag = 0; tcflag_t iflag; tcflag_t lflag; + int result = ERR; - AssertTCB(); - - if (TCB == 0 || buf == NULL) - return ERR; + if (buf != NULL && okConsoleHandle(TCB)) { - if (setFlag) { - iflag = buf->c_iflag; - lflag = buf->c_lflag; + if (setFlag) { + iflag = buf->c_iflag; + lflag = buf->c_lflag; - GetConsoleMode(CON.inp, &dwFlag); + GetConsoleMode(CON.inp, &dwFlag); - if (lflag & ICANON) - dwFlag |= ENABLE_LINE_INPUT; - else - dwFlag &= (DWORD) (~ENABLE_LINE_INPUT); + 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 (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); + if (iflag & BRKINT) + dwFlag |= ENABLE_PROCESSED_INPUT; + else + dwFlag &= (DWORD) (~ENABLE_PROCESSED_INPUT); - dwFlag |= ENABLE_MOUSE_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); + 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_LINE_INPUT) + lflag |= ICANON; + else + lflag &= (tcflag_t) (~ICANON); - if (dwFlag & ENABLE_ECHO_INPUT) - lflag |= ECHO; - else - lflag &= (tcflag_t) (~ECHO); + if (dwFlag & ENABLE_ECHO_INPUT) + lflag |= ECHO; + else + lflag &= (tcflag_t) (~ECHO); - if (dwFlag & ENABLE_PROCESSED_INPUT) - iflag |= BRKINT; - else - iflag &= (tcflag_t) (~BRKINT); + if (dwFlag & ENABLE_PROCESSED_INPUT) + iflag |= BRKINT; + else + iflag &= (tcflag_t) (~BRKINT); - TCB->term.Nttyb.c_iflag = iflag; - TCB->term.Nttyb.c_lflag = lflag; + TCB->term.Nttyb.c_iflag = iflag; + TCB->term.Nttyb.c_lflag = lflag; - *buf = TCB->term.Nttyb; + *buf = TCB->term.Nttyb; + } + result = OK; } - return OK; + return result; } #define MIN_WIDE 80 @@ -1007,56 +1005,59 @@ wcon_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag) TERMINAL *_term = (TERMINAL *) TCB; int code = ERR; - AssertTCB(); - 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; + 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; + } } - } else { - /* reset_prog_mode */ - if (wcon_sgmode(TCB, TRUE, &(_term->Nttyb)) == 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) { - if (sp->_keypad_on) - _nc_keypad(sp, TRUE); + _nc_keypad(sp, FALSE); + NCURSES_SP_NAME(_nc_flush) (sp); } + code = wcon_sgmode(TCB, TRUE, &(_term->Ottyb)); if (!CON.buffered) { - set_scrollback(FALSE, &CON.SBI); + set_scrollback(TRUE, &CON.save_SBI); + if (!restore_original_screen()) + code = ERR; } - code = OK; + SetConsoleCursorInfo(CON.hdl, &CON.save_CI); } } - 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); } @@ -1234,7 +1235,7 @@ wcon_init(TERMINAL_CONTROL_BLOCK * TCB) AssertTCB(); if (TCB) { - if (CON.hdl == INVALID_HANDLE_VALUE) { + if (!InitConsole()) { returnVoid; } @@ -1266,12 +1267,13 @@ wcon_initpair(TERMINAL_CONTROL_BLOCK * TCB, { SCREEN *sp; - AssertTCB(); - SetSP(); + 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); + if ((pair > 0) && (pair < NUMPAIRS) && (f >= 0) && (f < 8) + && (b >= 0) && (b < 8)) { + CON.pairs[pair] = MapColor(true, f) | MapColor(false, b); + } } } @@ -1307,29 +1309,33 @@ wcon_initmouse(TERMINAL_CONTROL_BLOCK * TCB) { SCREEN *sp; - AssertTCB(); - SetSP(); + if (okConsoleHandle(TCB)) { + SetSP(); - sp->_mouse_type = M_TERM_DRIVER; + sp->_mouse_type = M_TERM_DRIVER; + } } static int -wcon_testmouse(TERMINAL_CONTROL_BLOCK * TCB, int delay) +wcon_testmouse(TERMINAL_CONTROL_BLOCK * TCB, + int delay + EVENTLIST_2nd(_nc_eventlist * evl)) { int rc = 0; SCREEN *sp; - AssertTCB(); - SetSP(); + 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)); + 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; @@ -1426,13 +1432,14 @@ wcon_initacs(TERMINAL_CONTROL_BLOCK * TCB, unsigned n; SCREEN *sp; - AssertTCB(); - SetSP(); + 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; + 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; + } } } @@ -1524,6 +1531,10 @@ console_twait( int diff; bool isImmed = (milliseconds == 0); +#ifdef NCURSES_WGETCH_EVENTS + (void) evl; /* TODO: implement wgetch-events */ +#endif + #define CONSUME() ReadConsoleInput(fd,&inp_rec,1,&nRead) assert(sp); @@ -1622,16 +1633,17 @@ wcon_twait(TERMINAL_CONTROL_BLOCK * TCB, EVENTLIST_2nd(_nc_eventlist * evl)) { SCREEN *sp; - int code; + int code = 0; - AssertTCB(); - SetSP(); + if (okConsoleHandle(TCB)) { + SetSP(); - code = console_twait(sp, - CON.inp, - mode, - milliseconds, - timeleft EVENTLIST_2nd(_nc_eventlist * evl)); + code = console_twait(sp, + CON.inp, + mode, + milliseconds, + timeleft EVENTLIST_2nd(evl)); + } return code; } @@ -1682,14 +1694,16 @@ static int wcon_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf) { SCREEN *sp; - int n; + int n = -1; + + T((T_CALLED("win32con::wcon_read(%p)"), TCB)); - AssertTCB(); assert(buf); - SetSP(); + if (okConsoleHandle(TCB)) { + SetSP(); - T((T_CALLED("win32con::wcon_read(%p)"), TCB)); - n = _nc_mingw_console_read(sp, CON.inp, buf); + n = _nc_mingw_console_read(sp, CON.inp, buf); + } returnCode(n); } @@ -1705,19 +1719,22 @@ static int wcon_cursorSet(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int mode) { int res = -1; - CONSOLE_CURSOR_INFO this_CI = CON.save_CI; + T((T_CALLED("win32con:wcon_cursorSet(%d)"), mode)); - switch (mode) { - case 0: - this_CI.bVisible = FALSE; - break; - case 1: - break; - case 2: - this_CI.dwSize = 100; - break; + 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); } - SetConsoleCursorInfo(CON.hdl, &this_CI); returnCode(res); } @@ -1750,12 +1767,14 @@ wcon_kpad(TERMINAL_CONTROL_BLOCK * TCB, int flag GCC_UNUSED) SCREEN *sp; int code = ERR; - AssertTCB(); - SetSP(); - T((T_CALLED("win32con::wcon_kpad(%p, %d)"), TCB, flag)); - if (sp) { - code = OK; + + if (okConsoleHandle(TCB)) { + SetSP(); + + if (sp) { + code = OK; + } } returnCode(code); } @@ -1774,22 +1793,23 @@ wcon_keyok(TERMINAL_CONTROL_BLOCK * TCB, T((T_CALLED("win32con::wcon_keyok(%p, %d, %d)"), TCB, keycode, flag)); - AssertTCB(); - 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); + 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); @@ -1954,7 +1974,7 @@ _nc_mingw_isatty(int fd) /* 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 + Console. It's the responsibility of the console to deal with the terminal escape sequences that are sent by terminfo. */ @@ -2056,7 +2076,8 @@ int _nc_mingw_testmouse( SCREEN *sp, HANDLE fd, - int delay) + int delay + EVENTLIST_2nd(_nc_eventlist * evl)) { int rc = 0; @@ -2081,7 +2102,7 @@ _nc_mingw_console_read( HANDLE fd, int *buf) { - int n = 1; + int rc = -1; INPUT_RECORD inp_rec; BOOL b; DWORD nRead; @@ -2096,6 +2117,9 @@ _nc_mingw_console_read( while ((b = ReadConsoleInput(fd, &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; @@ -2133,13 +2157,13 @@ _nc_mingw_console_read( continue; } } - returnCode(n); + returnCode(rc); } -static -__attribute__((constructor)) - void _enter_console(void) +static bool +InitConsole(void) { + /* initialize once, or not at all */ if (!console_initialized) { int i; DWORD num_buttons; @@ -2226,4 +2250,26 @@ __attribute__((constructor)) 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