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.
This commit is contained in:
nethack.allison
2002-08-23 18:40:08 +00:00
parent ba5640ce9a
commit 4a6ed922d7
+65 -65
View File
@@ -319,26 +319,9 @@ static const struct pad {
{'i', 'I', C('i')}, /* Ins */ {'i', 'I', C('i')}, /* Ins */
{'.', ':', ':'} /* Del */ {'.', ':', ':'} /* 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 FDECL(process_keystroke, (INPUT_RECORD *ir, boolean *valid));
int process_keystroke(ir, valid) int process_keystroke(ir, valid)
@@ -346,19 +329,33 @@ INPUT_RECORD *ir;
boolean *valid; boolean *valid;
{ {
int metaflags = 0; int metaflags = 0;
int keycode, vk;
unsigned char ch; unsigned char ch;
unsigned short int scan; unsigned short int scan;
unsigned long shiftstate; unsigned long shiftstate;
int altseq; int altseq = 0;
const struct pad *kpad; 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; shiftstate = 0L;
ch = ir->Event.KeyEvent.uChar.AsciiChar; ch = ir->Event.KeyEvent.uChar.AsciiChar;
scan = ir->Event.KeyEvent.wVirtualScanCode; scan = ir->Event.KeyEvent.wVirtualScanCode;
vk = ir->Event.KeyEvent.wVirtualKeyCode;
keycode = MapVirtualKey(vk, 2);
shiftstate = ir->Event.KeyEvent.dwControlKeyState; shiftstate = ir->Event.KeyEvent.dwControlKeyState;
altseq=(shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED) && (ch || inmap(scan)));
if (ch || (iskeypad(scan)) || altseq) if (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) {
*valid = 1; if (ch || inmap(keycode,vk)) altseq = 1;
else altseq = -1; /* invalid altseq */
}
if (ch || (iskeypad(scan)) || (altseq > 0))
*valid = TRUE;
/* if (!valid) return 0; */ /* if (!valid) return 0; */
/* /*
* shiftstate can be checked to see if various special * shiftstate can be checked to see if various special
@@ -386,11 +383,9 @@ boolean *valid;
ch = kpad[scan - KEYPADLO].normal; ch = kpad[scan - KEYPADLO].normal;
} }
} }
else if (altseq) { /* ALT sequence */ else if (altseq > 0) { /* ALT sequence */
altseq = 0; if (vk == 0xBF) ch = M('?');
if (!ch && inmap(scan)) ch = scanmap[scan - SCANLO]; else ch = M(tolower(keycode));
if (index(extendedlist, tolower(ch)) != 0) ch = M(tolower(ch));
else if (scan == (SCANLO + SIZE(scanmap)) - 1) ch = M('?');
} }
return (ch == '\r') ? '\n' : ch; return (ch == '\r') ? '\n' : ch;
} }
@@ -416,10 +411,7 @@ ntposkey(x, y, mod)
int *x, *y, *mod; int *x, *y, *mod;
{ {
DWORD count; DWORD count;
unsigned short int scan; int keystroke = 0;
unsigned char ch;
unsigned long shiftstate;
int altseq;
int done = 0; int done = 0;
boolean valid = 0; boolean valid = 0;
while (!done) while (!done)
@@ -427,36 +419,39 @@ int *x, *y, *mod;
count = 0; count = 0;
ReadConsoleInput(hConIn,&ir,1,&count); ReadConsoleInput(hConIn,&ir,1,&count);
if (count > 0) { if (count > 0) {
ch = ir.Event.KeyEvent.uChar.AsciiChar; if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
scan = ir.Event.KeyEvent.wVirtualScanCode; keystroke = process_keystroke(&ir, &valid);
shiftstate = ir.Event.KeyEvent.dwControlKeyState; if (valid) return keystroke;
altseq=(shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED) && (ch || inmap(scan))); } else if (ir.EventType == MOUSE_EVENT) {
if (((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) && if ((ir.Event.MouseEvent.dwEventFlags == 0) &&
(ch || (iskeypad(scan)) || altseq)) { (ir.Event.MouseEvent.dwButtonState & MOUSEMASK)) {
*mod = 0; *x = ir.Event.MouseEvent.dwMousePosition.X + 1;
return process_keystroke(&ir, &valid); *y = ir.Event.MouseEvent.dwMousePosition.Y - 1;
} 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.Event.MouseEvent.dwButtonState & LEFTBUTTON)
*mod = CLICK_1; *mod = CLICK_1;
else if (ir.Event.MouseEvent.dwButtonState & RIGHTBUTTON) else if (ir.Event.MouseEvent.dwButtonState & RIGHTBUTTON)
*mod = CLICK_2; *mod = CLICK_2;
#if 0 /* middle button */ #if 0 /* middle button */
else if (ir.Event.MouseEvent.dwButtonState & MIDBUTTON) else if (ir.Event.MouseEvent.dwButtonState & MIDBUTTON)
*mod = CLICK_3; *mod = CLICK_3;
#endif #endif
return 0; 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 */ /* NOTREACHED */
return '\032'; *mod = 0;
return 0;
} }
int int
@@ -468,7 +463,7 @@ nttty_kbhit()
unsigned short int scan; unsigned short int scan;
unsigned char ch; unsigned char ch;
unsigned long shiftstate; unsigned long shiftstate;
int altseq; int altseq = 0, keycode, vk;
done = 0; done = 0;
retval = 0; retval = 0;
while (!done) while (!done)
@@ -476,17 +471,22 @@ nttty_kbhit()
count = 0; count = 0;
PeekConsoleInput(hConIn,&ir,1,&count); PeekConsoleInput(hConIn,&ir,1,&count);
if (count > 0) { if (count > 0) {
ch = ir.Event.KeyEvent.uChar.AsciiChar; if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
scan = ir.Event.KeyEvent.wVirtualScanCode; ch = ir.Event.KeyEvent.uChar.AsciiChar;
shiftstate = ir.Event.KeyEvent.dwControlKeyState; scan = ir.Event.KeyEvent.wVirtualScanCode;
altseq=(shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED) && (ch || inmap(scan))); shiftstate = ir.Event.KeyEvent.dwControlKeyState;
if (((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) && vk = ir.Event.KeyEvent.wVirtualKeyCode;
(ch || (iskeypad(scan)) || altseq)) { keycode = MapVirtualKey(vk, 2);
done = 1; /* Stop looking */ if (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) {
retval = 1; /* Found what we sought */ 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))) { (ir.Event.MouseEvent.dwButtonState & MOUSEMASK))) {
done = 1; done = 1;
retval = 1; retval = 1;