From: nethack.allison Date: Fri, 23 Aug 2002 18:40:08 +0000 (+0000) Subject: B08014 win32tty: hanging when ctrl+alt pressed X-Git-Tag: MOVE2GIT~2468 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4a6ed922d7d2ba6550028f18250c52ab922d4e54;p=nethack B08014 win32tty: hanging when ctrl+alt pressed CTRL+ALT was being treated as a valid ALT-sequence, so the meta bit was being set on it, letting it slip past this check in wintty.c "if (!i) i = '\033';" This overhauls the ALT processing in nttty.c, some of which was using scancode mappings from the DOS port needlessly. --- diff --git a/sys/winnt/nttty.c b/sys/winnt/nttty.c index d2a806d8c..5750dfa3c 100644 --- a/sys/winnt/nttty.c +++ b/sys/winnt/nttty.c @@ -319,26 +319,9 @@ static const struct pad { {'i', 'I', C('i')}, /* Ins */ {'.', ':', ':'} /* Del */ }; -/* - * Unlike Ctrl-letter, the Alt-letter keystrokes have no specific ASCII - * meaning unless assigned one by a keyboard conversion table - * To interpret Alt-letters, we use a - * scan code table to translate the scan code into a letter, then set the - * "meta" bit for it. -3. - */ -#define SCANLO 0x02 - -static const char scanmap[] = { /* ... */ - '1','2','3','4','5','6','7','8','9','0',0,0,0,0, - 'q','w','e','r','t','y','u','i','o','p','[',']', '\n', - 0, 'a','s','d','f','g','h','j','k','l',';','\'', '`', - 0, '\\', 'z','x','c','v','b','n','m',',','.','?' /* ... */ -}; - -static const char *extendedlist = "acdefijlmnopqrstuvw?2"; - -#define inmap(x) (SCANLO <= (x) && (x) < SCANLO + SIZE(scanmap)) +#define inmap(x,vk) (((x) > 'A' && (x) < 'Z') || (vk) == 0xBF || (x) == '2') + int FDECL(process_keystroke, (INPUT_RECORD *ir, boolean *valid)); int process_keystroke(ir, valid) @@ -346,19 +329,33 @@ INPUT_RECORD *ir; boolean *valid; { int metaflags = 0; + int keycode, vk; unsigned char ch; unsigned short int scan; unsigned long shiftstate; - int altseq; + int altseq = 0; const struct pad *kpad; +#if 0 + /* sanity check, but caller should have checked already */ + if (ir->EventType != KEY_EVENT) { + if (valid) *valid = 0; + return 0; + } +#endif shiftstate = 0L; ch = ir->Event.KeyEvent.uChar.AsciiChar; scan = ir->Event.KeyEvent.wVirtualScanCode; + vk = ir->Event.KeyEvent.wVirtualKeyCode; + keycode = MapVirtualKey(vk, 2); shiftstate = ir->Event.KeyEvent.dwControlKeyState; - altseq=(shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED) && (ch || inmap(scan))); - if (ch || (iskeypad(scan)) || altseq) - *valid = 1; + + if (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) { + if (ch || inmap(keycode,vk)) altseq = 1; + else altseq = -1; /* invalid altseq */ + } + if (ch || (iskeypad(scan)) || (altseq > 0)) + *valid = TRUE; /* if (!valid) return 0; */ /* * shiftstate can be checked to see if various special @@ -386,11 +383,9 @@ boolean *valid; ch = kpad[scan - KEYPADLO].normal; } } - else if (altseq) { /* ALT sequence */ - altseq = 0; - if (!ch && inmap(scan)) ch = scanmap[scan - SCANLO]; - if (index(extendedlist, tolower(ch)) != 0) ch = M(tolower(ch)); - else if (scan == (SCANLO + SIZE(scanmap)) - 1) ch = M('?'); + else if (altseq > 0) { /* ALT sequence */ + if (vk == 0xBF) ch = M('?'); + else ch = M(tolower(keycode)); } return (ch == '\r') ? '\n' : ch; } @@ -416,10 +411,7 @@ ntposkey(x, y, mod) int *x, *y, *mod; { DWORD count; - unsigned short int scan; - unsigned char ch; - unsigned long shiftstate; - int altseq; + int keystroke = 0; int done = 0; boolean valid = 0; while (!done) @@ -427,36 +419,39 @@ int *x, *y, *mod; count = 0; ReadConsoleInput(hConIn,&ir,1,&count); if (count > 0) { - ch = ir.Event.KeyEvent.uChar.AsciiChar; - scan = ir.Event.KeyEvent.wVirtualScanCode; - shiftstate = ir.Event.KeyEvent.dwControlKeyState; - altseq=(shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED) && (ch || inmap(scan))); - if (((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) && - (ch || (iskeypad(scan)) || altseq)) { - *mod = 0; - return process_keystroke(&ir, &valid); - } else if ( - (ir.EventType == MOUSE_EVENT && - (ir.Event.MouseEvent.dwEventFlags == 0) && - (ir.Event.MouseEvent.dwButtonState & MOUSEMASK))) { - *x = ir.Event.MouseEvent.dwMousePosition.X + 1; - *y = ir.Event.MouseEvent.dwMousePosition.Y - 1; - - if (ir.Event.MouseEvent.dwButtonState & LEFTBUTTON) + if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) { + keystroke = process_keystroke(&ir, &valid); + if (valid) return keystroke; + } else if (ir.EventType == MOUSE_EVENT) { + if ((ir.Event.MouseEvent.dwEventFlags == 0) && + (ir.Event.MouseEvent.dwButtonState & MOUSEMASK)) { + *x = ir.Event.MouseEvent.dwMousePosition.X + 1; + *y = ir.Event.MouseEvent.dwMousePosition.Y - 1; + + if (ir.Event.MouseEvent.dwButtonState & LEFTBUTTON) *mod = CLICK_1; - else if (ir.Event.MouseEvent.dwButtonState & RIGHTBUTTON) + else if (ir.Event.MouseEvent.dwButtonState & RIGHTBUTTON) *mod = CLICK_2; #if 0 /* middle button */ - else if (ir.Event.MouseEvent.dwButtonState & MIDBUTTON) + else if (ir.Event.MouseEvent.dwButtonState & MIDBUTTON) *mod = CLICK_3; #endif return 0; - - } - } + } + } +#if 0 + /* We ignore these types of console events */ + else if (ir.EventType == FOCUS_EVENT) { + } + else if (ir.EventType == MENU_EVENT) { + } +#endif + } else + done = 1; } - /* Not Reached */ - return '\032'; + /* NOTREACHED */ + *mod = 0; + return 0; } int @@ -468,7 +463,7 @@ nttty_kbhit() unsigned short int scan; unsigned char ch; unsigned long shiftstate; - int altseq; + int altseq = 0, keycode, vk; done = 0; retval = 0; while (!done) @@ -476,17 +471,22 @@ nttty_kbhit() count = 0; PeekConsoleInput(hConIn,&ir,1,&count); if (count > 0) { - ch = ir.Event.KeyEvent.uChar.AsciiChar; - scan = ir.Event.KeyEvent.wVirtualScanCode; - shiftstate = ir.Event.KeyEvent.dwControlKeyState; - altseq=(shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED) && (ch || inmap(scan))); - if (((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) && - (ch || (iskeypad(scan)) || altseq)) { - done = 1; /* Stop looking */ - retval = 1; /* Found what we sought */ + if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) { + ch = ir.Event.KeyEvent.uChar.AsciiChar; + scan = ir.Event.KeyEvent.wVirtualScanCode; + shiftstate = ir.Event.KeyEvent.dwControlKeyState; + vk = ir.Event.KeyEvent.wVirtualKeyCode; + keycode = MapVirtualKey(vk, 2); + if (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) { + if (ch || inmap(keycode,vk)) altseq = 1; + else altseq = -1; /* invalid altseq */ + } + if (ch || iskeypad(scan) || altseq) { + done = 1; /* Stop looking */ + retval = 1; /* Found what we sought */ + } } - - else if ((ir.EventType == MOUSE_EVENT && + else if ((ir.EventType == MOUSE_EVENT && (ir.Event.MouseEvent.dwButtonState & MOUSEMASK))) { done = 1; retval = 1;