]> granicus.if.org Git - nethack/commitdiff
B08014 win32tty: hanging when ctrl+alt pressed
authornethack.allison <nethack.allison>
Fri, 23 Aug 2002 18:40:08 +0000 (18:40 +0000)
committernethack.allison <nethack.allison>
Fri, 23 Aug 2002 18:40:08 +0000 (18:40 +0000)
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.

sys/winnt/nttty.c

index d2a806d8cf52fa54133aaafd2b7258d4675467e3..5750dfa3cbc6d97000ac5859f7d47f6f88a3116c 100644 (file)
@@ -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;