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