X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fwin32con%2Fwin_driver.c;h=72a9cf53525f8a94d692384347f3b56a552df929;hp=5acc60351005ad9cd3b6df619fa308c39bd8dd0c;hb=18f51bcf99101e5bf4c737239c44064227f34db8;hpb=a8845f1feadb0b4d906e9040e465b93fd3f72660 diff --git a/ncurses/win32con/win_driver.c b/ncurses/win32con/win_driver.c index 5acc6035..72a9cf53 100644 --- a/ncurses/win32con/win_driver.c +++ b/ncurses/win32con/win_driver.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2013,2014 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 * @@ -39,19 +40,24 @@ */ #include + +#ifdef _WIN32 #include +#else +#include +#include +#endif + #include #define PSAPI_VERSION 2 #include -#define CUR my_term.type. +#define CUR TerminalType(my_term). -MODULE_ID("$Id: win_driver.c,v 1.51 2014/09/27 22:17:36 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) @@ -59,7 +65,8 @@ MODULE_ID("$Id: win_driver.c,v 1.51 2014/09/27 22:17:36 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 @@ -89,14 +96,27 @@ static const LONG keylist[] = 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 save +/* A process can only have a single console, so it's safe to maintain all the information about it in a single - static scructure. + static structure. */ static struct { BOOL initialized; @@ -110,6 +130,7 @@ static struct { HANDLE hdl; HANDLE lastOut; int numButtons; + DWORD ansi_map[MAPSIZE]; DWORD map[MAPSIZE]; DWORD rmap[MAPSIZE]; WORD pairs[NUMPAIRS]; @@ -239,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; @@ -288,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; @@ -459,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); @@ -474,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); @@ -483,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' @@ -498,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] = ' '; @@ -628,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) { @@ -644,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; } @@ -762,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)); @@ -777,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); @@ -804,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) && @@ -840,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 @@ -986,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); } @@ -1090,6 +1112,29 @@ MapKey(WORD vKey) 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) { @@ -1190,7 +1235,7 @@ wcon_init(TERMINAL_CONTROL_BLOCK * TCB) AssertTCB(); if (TCB) { - if (CON.hdl == INVALID_HANDLE_VALUE) { + if (!InitConsole()) { returnVoid; } @@ -1222,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); + } } } @@ -1263,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; @@ -1382,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; + } } } @@ -1480,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); @@ -1517,7 +1572,7 @@ console_twait( if (inp_rec.Event.KeyEvent.bKeyDown) { if (0 == ch) { int nKey = MapKey(vk); - if ((nKey < 0) || FALSE == sp->_keypad_on) { + if (nKey < 0) { CONSUME(); continue; } @@ -1578,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; } @@ -1638,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); } @@ -1661,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); } @@ -1706,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); } @@ -1730,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); @@ -1893,7 +1957,12 @@ _nc_mingw_isatty(int fd) { int result = 0; - if (_isatty(fd)) { +#ifdef __MING32__ +#define SysISATTY(fd) _isatty(fd) +#else +#define SysISATTY(fd) isatty(fd) +#endif + if (SysISATTY(fd)) { result = 1; } else { #if WINVER >= 0x0600 @@ -1905,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. */ @@ -2007,7 +2076,8 @@ int _nc_mingw_testmouse( SCREEN *sp, HANDLE fd, - int delay) + int delay + EVENTLIST_2nd(_nc_eventlist * evl)) { int rc = 0; @@ -2032,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; @@ -2047,23 +2117,36 @@ _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; *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) { - if (sp->_keypad_on) { - *buf = MapKey(vk); - if (0 > (*buf)) - continue; - else - break; - } else + int key = MapKey(vk); + if (key < 0) continue; - } else { /* *buf != 0 */ - break; + 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)) { @@ -2074,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; @@ -2094,14 +2177,23 @@ __attribute__((constructor)) } for (i = 0; i < (N_INI + FKEYS); i++) { - if (i < N_INI) + if (i < N_INI) { CON.rmap[i] = CON.map[i] = (DWORD) keylist[i]; - else + 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]), @@ -2158,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