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:
+65
-65
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user