Piotr Caban : msvcrt: Add _getwch implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jun 15 08:49:08 CDT 2015


Module: wine
Branch: master
Commit: 9a10a7163831f6968a1d7a20599f83a2159c3d60
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9a10a7163831f6968a1d7a20599f83a2159c3d60

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Sun Jun 14 14:31:14 2015 +0200

msvcrt: Add _getwch implementation.

---

 dlls/msvcr100/msvcr100.spec |   4 +-
 dlls/msvcr110/msvcr110.spec |   4 +-
 dlls/msvcr120/msvcr120.spec |   4 +-
 dlls/msvcr70/msvcr70.spec   |   2 +-
 dlls/msvcr71/msvcr71.spec   |   2 +-
 dlls/msvcr80/msvcr80.spec   |   4 +-
 dlls/msvcr90/msvcr90.spec   |   4 +-
 dlls/msvcrt/console.c       | 127 ++++++++++++++++++++++++++++++++++++--------
 dlls/msvcrt/msvcrt.spec     |   2 +-
 9 files changed, 118 insertions(+), 35 deletions(-)

diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index 3e4badc..2a3ab47 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -907,8 +907,8 @@
 @ stub _getsystime(ptr)
 @ cdecl _getw(ptr) MSVCRT__getw
 @ cdecl _getwc_nolock(ptr) MSVCRT__fgetwc_nolock
-@ stub _getwch
-@ stub _getwch_nolock
+@ cdecl _getwch()
+@ cdecl _getwch_nolock()
 @ stub _getwche
 @ stub _getwche_nolock
 @ cdecl _getws(ptr) MSVCRT__getws
diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec
index 25efacd..d0a4c05 100644
--- a/dlls/msvcr110/msvcr110.spec
+++ b/dlls/msvcr110/msvcr110.spec
@@ -1254,8 +1254,8 @@
 @ stub _getsystime(ptr)
 @ cdecl _getw(ptr) MSVCRT__getw
 @ cdecl _getwc_nolock(ptr) MSVCRT__fgetwc_nolock
-@ stub _getwch
-@ stub _getwch_nolock
+@ cdecl _getwch()
+@ cdecl _getwch_nolock()
 @ stub _getwche
 @ stub _getwche_nolock
 @ cdecl _getws(ptr) MSVCRT__getws
diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec
index 148b378..a86edff 100644
--- a/dlls/msvcr120/msvcr120.spec
+++ b/dlls/msvcr120/msvcr120.spec
@@ -1252,8 +1252,8 @@
 @ stub _getsystime(ptr)
 @ cdecl _getw(ptr) MSVCRT__getw
 @ cdecl _getwc_nolock(ptr) MSVCRT__fgetwc_nolock
-@ stub _getwch
-@ stub _getwch_nolock
+@ cdecl _getwch()
+@ cdecl _getwch_nolock()
 @ stub _getwche
 @ stub _getwche_nolock
 @ cdecl _getws(ptr) MSVCRT__getws
diff --git a/dlls/msvcr70/msvcr70.spec b/dlls/msvcr70/msvcr70.spec
index 51415a9..0905603 100644
--- a/dlls/msvcr70/msvcr70.spec
+++ b/dlls/msvcr70/msvcr70.spec
@@ -343,7 +343,7 @@
 @ cdecl _getpid() _getpid
 @ stub _getsystime(ptr)
 @ cdecl _getw(ptr) MSVCRT__getw
-@ stub _getwch
+@ cdecl _getwch()
 @ stub _getwche
 @ cdecl _getws(ptr) MSVCRT__getws
 @ cdecl -arch=i386 _global_unwind2(ptr)
diff --git a/dlls/msvcr71/msvcr71.spec b/dlls/msvcr71/msvcr71.spec
index a28725b..35e515e 100644
--- a/dlls/msvcr71/msvcr71.spec
+++ b/dlls/msvcr71/msvcr71.spec
@@ -338,7 +338,7 @@
 @ cdecl _getpid() _getpid
 @ stub _getsystime(ptr)
 @ cdecl _getw(ptr) MSVCRT__getw
-@ stub _getwch
+@ cdecl _getwch()
 @ stub _getwche
 @ cdecl _getws(ptr) MSVCRT__getws
 @ cdecl -arch=i386 _global_unwind2(ptr)
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 3c1bb87..7b37e71 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -581,8 +581,8 @@
 @ stub _getsystime(ptr)
 @ cdecl _getw(ptr) MSVCRT__getw
 @ cdecl _getwc_nolock(ptr) MSVCRT__fgetwc_nolock
-@ stub _getwch
-@ stub _getwch_nolock
+@ cdecl _getwch()
+@ cdecl _getwch_nolock()
 @ stub _getwche
 @ stub _getwche_nolock
 @ cdecl _getws(ptr) MSVCRT__getws
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 547f668..f7a9818 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -558,8 +558,8 @@
 @ stub _getsystime(ptr)
 @ cdecl _getw(ptr) MSVCRT__getw
 @ cdecl _getwc_nolock(ptr) MSVCRT__fgetwc_nolock
-@ stub _getwch
-@ stub _getwch_nolock
+@ cdecl _getwch()
+@ cdecl _getwch_nolock()
 @ stub _getwche
 @ stub _getwche_nolock
 @ cdecl _getws(ptr) MSVCRT__getws
diff --git a/dlls/msvcrt/console.c b/dlls/msvcrt/console.c
index e8eea7f..9c3cccf 100644
--- a/dlls/msvcrt/console.c
+++ b/dlls/msvcrt/console.c
@@ -38,6 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
 static HANDLE MSVCRT_console_in = INVALID_HANDLE_VALUE;
 static HANDLE MSVCRT_console_out= INVALID_HANDLE_VALUE;
 static int __MSVCRT_console_buffer = MSVCRT_EOF;
+static MSVCRT_wchar_t __MSVCRT_console_buffer_w = MSVCRT_WEOF;
 
 /* INTERNAL: Initialise console handles */
 void msvcrt_init_console(void)
@@ -106,7 +107,7 @@ int CDECL _cputws(const MSVCRT_wchar_t* str)
 #define CTRL_CHAR       2
 #define SHIFT_CHAR      3
 
-static const struct {unsigned vk; unsigned ch[4][2];} enh_map[] = {
+static const struct {unsigned short vk; unsigned char 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}}},
@@ -119,6 +120,36 @@ static const struct {unsigned vk; unsigned ch[4][2];} enh_map[] = {
     {0x53, {{0xE0, 0x53}, {0x00, 0xA3}, {0xE0, 0x93}, {0xE0, 0x53}}},
 };
 
+static BOOL handle_enhanced_keys(INPUT_RECORD *ir, unsigned char *ch1, unsigned char *ch2)
+{
+    int i;
+
+    for (i = 0; i < sizeof(enh_map) / sizeof(enh_map[0]); i++)
+    {
+        if (ir->Event.KeyEvent.wVirtualScanCode == enh_map[i].vk)
+        {
+            unsigned idx;
+
+            if (ir->Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
+                idx = ALT_CHAR;
+            else if (ir->Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) )
+                idx = CTRL_CHAR;
+            else if (ir->Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
+                idx = SHIFT_CHAR;
+            else
+                idx = NORMAL_CHAR;
+
+            *ch1 = enh_map[i].ch[idx][0];
+            *ch2 = enh_map[i].ch[idx][1];
+            return TRUE;
+        }
+    }
+
+    WARN("Unmapped char keyState=%x vk=%x\n",
+            ir->Event.KeyEvent.dwControlKeyState, ir->Event.KeyEvent.wVirtualScanCode);
+    return FALSE;
+}
+
 /*********************************************************************
  *		_getch_nolock (MSVCR80.@)
  */
@@ -144,39 +175,24 @@ int CDECL _getch_nolock(void)
     do {
       if (ReadConsoleInputA(MSVCRT_console_in, &ir, 1, &count))
       {
-          unsigned int i;
         /* Only interested in ASCII chars */
         if (ir.EventType == KEY_EVENT &&
             ir.Event.KeyEvent.bKeyDown)
         {
+            unsigned char ch1, ch2;
+
             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]))
+
+            if (handle_enhanced_keys(&ir, &ch1, &ch2))
             {
-                unsigned idx;
-
-                if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
-                    idx = ALT_CHAR;
-                else if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) )
-                    idx = CTRL_CHAR;
-                else if (ir.Event.KeyEvent.dwControlKeyState & 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];
+                retval = ch1;
+                __MSVCRT_console_buffer = ch2;
                 break;
             }
-            WARN("Unmapped char keyState=%x vk=%x\n",
-                 ir.Event.KeyEvent.dwControlKeyState, ir.Event.KeyEvent.wVirtualScanCode);
         }
       }
       else
@@ -202,6 +218,73 @@ int CDECL _getch(void)
 }
 
 /*********************************************************************
+ *		_getwch_nolock (MSVCR80.@)
+ */
+MSVCRT_wchar_t CDECL _getwch_nolock(void)
+{
+    MSVCRT_wchar_t retval = MSVCRT_WEOF;
+
+    if (__MSVCRT_console_buffer_w != MSVCRT_WEOF)
+    {
+        retval = __MSVCRT_console_buffer_w;
+        __MSVCRT_console_buffer_w = MSVCRT_WEOF;
+    }
+    else
+    {
+        INPUT_RECORD ir;
+        DWORD count;
+        DWORD mode = 0;
+
+        GetConsoleMode(MSVCRT_console_in, &mode);
+        if(mode)
+            SetConsoleMode(MSVCRT_console_in, 0);
+
+        do {
+            if (ReadConsoleInputW(MSVCRT_console_in, &ir, 1, &count))
+            {
+                /* Only interested in ASCII chars */
+                if (ir.EventType == KEY_EVENT &&
+                        ir.Event.KeyEvent.bKeyDown)
+                {
+                    unsigned char ch1, ch2;
+
+                    if (ir.Event.KeyEvent.uChar.UnicodeChar)
+                    {
+                        retval = ir.Event.KeyEvent.uChar.UnicodeChar;
+                        break;
+                    }
+
+                    if (handle_enhanced_keys(&ir, &ch1, &ch2))
+                    {
+                        retval = ch1;
+                        __MSVCRT_console_buffer_w = ch2;
+                        break;
+                    }
+                }
+            }
+            else
+                break;
+        } while(1);
+        if (mode)
+            SetConsoleMode(MSVCRT_console_in, mode);
+    }
+    return retval;
+}
+
+/*********************************************************************
+ *              _getwch (MSVCRT.@)
+ */
+MSVCRT_wchar_t CDECL _getwch(void)
+{
+    MSVCRT_wchar_t ret;
+
+    LOCK_CONSOLE;
+    ret = _getwch_nolock();
+    UNLOCK_CONSOLE;
+    return ret;
+}
+
+/*********************************************************************
  *		_putch_nolock (MSVCR80.@)
  */
 int CDECL _putch_nolock(int c)
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 46cbf08..4ac232c 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -533,7 +533,7 @@
 @ cdecl _getpid() _getpid
 @ stub _getsystime(ptr)
 @ cdecl _getw(ptr) MSVCRT__getw
-# stub _getwch()
+@ cdecl _getwch()
 # stub _getwche()
 @ cdecl _getws(ptr) MSVCRT__getws
 @ cdecl -arch=i386 _global_unwind2(ptr)




More information about the wine-cvs mailing list