[PATCH] [MSVCRT]: properly handle the extended keys in getch()

Eric Pouech eric.pouech at orange.fr
Fri May 23 13:04:36 CDT 2008


Fix for #10907

A+
---

 dlls/msvcrt/console.c |   52 +++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 48 insertions(+), 4 deletions(-)


diff --git a/dlls/msvcrt/console.c b/dlls/msvcrt/console.c
index 1e65832..c0549d2 100644
--- a/dlls/msvcrt/console.c
+++ b/dlls/msvcrt/console.c
@@ -77,6 +77,24 @@ int CDECL _cputs(const char* str)
   return retval;
 }
 
+#define NORMAL_CHAR     0
+#define ALT_CHAR        1
+#define CTRL_CHAR       2
+#define SHIFT_CHAR      3
+
+static struct {unsigned vk; unsigned ch[4][2];} enh_map[] = {
+    {0x47, {{0xE0, 0x47}, {0x00, 0x97}, {0xE0, 0x77}, {0xE0, 0x47}}},
+    {0x48, {{0xE0, 0x48}, {0x00, 0x98}, {0xE0, 0x8D}, {0xE0, 0x48}}},
+    {0x49, {{0xE0, 0x49}, {0x00, 0x99}, {0xE0, 0x86}, {0xE0, 0x49}}},
+    {0x4B, {{0xE0, 0x4B}, {0x00, 0x9B}, {0xE0, 0x73}, {0xE0, 0x4B}}},
+    {0x4D, {{0xE0, 0x4D}, {0x00, 0x9D}, {0xE0, 0x74}, {0xE0, 0x4D}}},
+    {0x4F, {{0xE0, 0x4F}, {0x00, 0x9F}, {0xE0, 0x75}, {0xE0, 0x4F}}},
+    {0x50, {{0xE0, 0x50}, {0x00, 0xA0}, {0xE0, 0x91}, {0xE0, 0x50}}},
+    {0x51, {{0xE0, 0x51}, {0x00, 0xA1}, {0xE0, 0x76}, {0xE0, 0x51}}},
+    {0x52, {{0xE0, 0x52}, {0x00, 0xA2}, {0xE0, 0x92}, {0xE0, 0x52}}},
+    {0x53, {{0xE0, 0x53}, {0x00, 0xA3}, {0xE0, 0x93}, {0xE0, 0x53}}},
+};
+
 /*********************************************************************
  *		_getch (MSVCRT.@)
  */
@@ -103,13 +121,39 @@ int CDECL _getch(void)
     do {
       if (ReadConsoleInputA(MSVCRT_console_in, &ir, 1, &count))
       {
+          int i;
         /* Only interested in ASCII chars */
         if (ir.EventType == KEY_EVENT &&
-            ir.Event.KeyEvent.bKeyDown &&
-            ir.Event.KeyEvent.uChar.AsciiChar)
+            ir.Event.KeyEvent.bKeyDown)
         {
-          retval = ir.Event.KeyEvent.uChar.AsciiChar;
-          break;
+            if (ir.Event.KeyEvent.uChar.AsciiChar)
+            {
+                retval = ir.Event.KeyEvent.uChar.AsciiChar;
+                break;
+            }
+            for (i = 0; i < sizeof(enh_map) / sizeof(enh_map[0]); i++)
+            {
+                if (ir.Event.KeyEvent.wVirtualScanCode == enh_map[i].vk) break;
+            }
+            if (i < sizeof(enh_map) / sizeof(enh_map[0]))
+            {
+                unsigned idx;
+
+                if (ir.Event.KeyEvent.wVirtualScanCode & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
+                    idx = ALT_CHAR;
+                else if (ir.Event.KeyEvent.wVirtualScanCode & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) )
+                    idx = CTRL_CHAR;
+                else if (ir.Event.KeyEvent.wVirtualScanCode & SHIFT_PRESSED)
+                    idx = SHIFT_CHAR;
+                else
+                    idx = NORMAL_CHAR;
+
+                retval = enh_map[i].ch[idx][0];
+                __MSVCRT_console_buffer = enh_map[i].ch[idx][1];
+                break;
+            }
+            WARN("Unmapped char keyState=%x vk=%x\n",
+                 ir.Event.KeyEvent.dwControlKeyState, ir.Event.KeyEvent.wVirtualScanCode);
         }
       }
       else





More information about the wine-patches mailing list