diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 3e4badc0830..2a3ab477e6b 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 25efacdc7af..d0a4c0529ad 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 148b378a877..a86edffc943 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 51415a92e8e..09056037ade 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 a28725bfd0c..35e515e18a9 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 3c1bb873770..7b37e712a7f 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 547f66818c1..f7a981820f3 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 e8eea7f90c7..9c3cccfed68 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])) - { - 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]; + if (handle_enhanced_keys(&ir, &ch1, &ch2)) + { + retval = ch1; + __MSVCRT_console_buffer = ch2; break; } - WARN("Unmapped char keyState=%x vk=%x\n", - ir.Event.KeyEvent.dwControlKeyState, ir.Event.KeyEvent.wVirtualScanCode); } } else @@ -201,6 +217,73 @@ int CDECL _getch(void) return ret; } +/********************************************************************* + * _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.@) */ diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 46cbf085baf..4ac232cafd7 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)