Index: dll/win32/msvcrt/msvcrt.spec =================================================================== --- dll/win32/msvcrt/msvcrt.spec (revision 62562) +++ dll/win32/msvcrt/msvcrt.spec (working copy) @@ -494,8 +494,8 @@ @ cdecl _getpid() kernel32.GetCurrentProcessId @ cdecl _getsystime(ptr) @ cdecl _getw(ptr) -# stub _getwch -# stub _getwche +@ cdecl _getwch() +@ cdecl _getwche() @ cdecl _getws(ptr) @ cdecl -i386 _global_unwind2(ptr) @ cdecl _gmtime32(ptr) Index: lib/sdk/crt/conio/getch.c =================================================================== --- lib/sdk/crt/conio/getch.c (revision 62562) +++ lib/sdk/crt/conio/getch.c (working copy) @@ -20,6 +20,7 @@ HANDLE ConsoleHandle; BOOL RestoreMode; DWORD ConsoleMode; + INPUT_RECORD InputRecord; if (char_avail) { c = ungot_char; @@ -31,7 +32,8 @@ * ENABLE_ECHO_INPUT and ENABLE_LINE_INPUT if they're currently * switched on. */ - ConsoleHandle = (HANDLE) _get_osfhandle(stdin->_file); + c = EOF; + ConsoleHandle = GetStdHandle(STD_INPUT_HANDLE); RestoreMode = GetConsoleMode(ConsoleHandle, &ConsoleMode) && (0 != (ConsoleMode & (ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT))); @@ -39,11 +41,80 @@ SetConsoleMode(ConsoleHandle, ConsoleMode & (~ (ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT))); } - ReadConsoleA((HANDLE)_get_osfhandle(stdin->_file), - &c, - 1, - &NumberOfCharsRead, - NULL); + for ( ;; ) + { + if( !ReadConsoleInput(ConsoleHandle, + &InputRecord, + 1, + &NumberOfCharsRead) || !NumberOfCharsRead) + { + break; + } + if (InputRecord.EventType == KEY_EVENT && + InputRecord.Event.KeyEvent.bKeyDown) + { + if((c = InputRecord.Event.KeyEvent.uChar.AsciiChar) != 0) + break; + + if (InputRecord.Event.KeyEvent.wVirtualScanCode == 0x1d || /* Ctrl */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x2a || /* Left Shift */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x36 || /* Right Shift */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x38 || /* Alt */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x3a || /* Caps Lock */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x45 || /* Num Lock */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x46) /* Scroll Lock */ + continue; + + if (InputRecord.Event.KeyEvent.wVirtualKeyCode >= 0x70 && /* F1-F10 */ + InputRecord.Event.KeyEvent.wVirtualKeyCode <= 0x79) + { + c = 0; + if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x19 + 20; + else if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x19 + 10; + else if(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x19; + else + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode; + char_avail = 1; + } + else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == 0x7a || /* F11-F12 */ + InputRecord.Event.KeyEvent.wVirtualKeyCode == 0x7b) + { + c = 0xe0; + if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x2E + 6; + else if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x2E + 4; + else if(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x2E + 2; + else + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x2E; + char_avail = 1; + } + else + { + if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + { + c = 0; + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x50; + } + else if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) + { + c = 0xe0; + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x50; + } + else + { + c = 0xe0; + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode; + } + char_avail = 1; + } + break; + } + } if (RestoreMode) { SetConsoleMode(ConsoleHandle, ConsoleMode); } Index: lib/sdk/crt/conio/getwch.c =================================================================== --- lib/sdk/crt/conio/getwch.c (revision 0) +++ lib/sdk/crt/conio/getwch.c (working copy) @@ -0,0 +1,123 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/conio/getch.c + * PURPOSE: Writes a character to stdout + * PROGRAMER: Ariadne + * Lee Schroeder + * UPDATE HISTORY: + * 28/12/98: Created + */ + +#include + +wint_t _getwch(void) +{ + DWORD NumberOfCharsRead = 0; + wchar_t c; + HANDLE ConsoleHandle; + BOOL RestoreMode; + DWORD ConsoleMode; + INPUT_RECORD InputRecord; + + if (char_avail) { + c = ungot_char; + char_avail = 0; + } else { + /* + * _getch() is documented to NOT echo characters. Testing shows it + * doesn't wait for a CR either. So we need to switch off + * ENABLE_ECHO_INPUT and ENABLE_LINE_INPUT if they're currently + * switched on. + */ + c = EOF; + ConsoleHandle = GetStdHandle(STD_INPUT_HANDLE); + RestoreMode = GetConsoleMode(ConsoleHandle, &ConsoleMode) && + (0 != (ConsoleMode & + (ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT))); + if (RestoreMode) { + SetConsoleMode(ConsoleHandle, + ConsoleMode & (~ (ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT))); + } + for ( ;; ) + { + if( !ReadConsoleInput(ConsoleHandle, + &InputRecord, + 1, + &NumberOfCharsRead) || !NumberOfCharsRead) + { + break; + } + if (InputRecord.EventType == KEY_EVENT && + InputRecord.Event.KeyEvent.bKeyDown) + { + if((c = InputRecord.Event.KeyEvent.uChar.UnicodeChar) != 0) + break; + + if (InputRecord.Event.KeyEvent.wVirtualScanCode == 0x1d || /* Ctrl */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x2a || /* Left Shift */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x36 || /* Right Shift */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x38 || /* Alt */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x3a || /* Caps Lock */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x45 || /* Num Lock */ + InputRecord.Event.KeyEvent.wVirtualScanCode == 0x46) /* Scroll Lock */ + continue; + + if (InputRecord.Event.KeyEvent.wVirtualKeyCode >= 0x70 && /* F1-F10 */ + InputRecord.Event.KeyEvent.wVirtualKeyCode <= 0x79) + { + c = 0; + if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x19 + 20; + else if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x19 + 10; + else if(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x19; + else + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode; + char_avail = 1; + } + else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == 0x7a || /* F11-F12 */ + InputRecord.Event.KeyEvent.wVirtualKeyCode == 0x7b) + { + c = 0xe0; + if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x2E + 6; + else if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x2E + 4; + else if(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x2E + 2; + else + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x2E; + char_avail = 1; + } + else + { + if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + { + c = 0; + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x50; + } + else if(InputRecord.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) + { + c = 0xe0; + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode + 0x50; + } + else + { + c = 0xe0; + ungot_char = InputRecord.Event.KeyEvent.wVirtualScanCode; + } + char_avail = 1; + } + break; + } + } + if (RestoreMode) { + SetConsoleMode(ConsoleHandle, ConsoleMode); + } + } + if (c == 10) + c = 13; + return c; +} \ No newline at end of file Index: lib/sdk/crt/conio/getwche.c =================================================================== --- lib/sdk/crt/conio/getwche.c (revision 0) +++ lib/sdk/crt/conio/getwche.c (working copy) @@ -0,0 +1,30 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/conio/getwche.c + * PURPOSE: Reads a character from stdin + * PROGRAMER: DJ Delorie + Ariadne + Lee Schroeder + * UPDATE HISTORY: + * 28/12/98: Created + */ + +#include + +wint_t _getwche(void) +{ + if (char_avail) + /* + * We don't know, wether the ungot char was already echoed + * we assume yes (for example in cscanf, probably the only + * place where ungetch is ever called. + * There is no way to check for this really, because + * ungetch could have been called with a character that + * hasn't been got by a conio function. + * We don't echo again. + */ + return(_getwch()); + return (_putwch(_getwch())); + } \ No newline at end of file Index: lib/sdk/crt/crt.cmake =================================================================== --- lib/sdk/crt/crt.cmake (revision 62562) +++ lib/sdk/crt/crt.cmake (working copy) @@ -3,7 +3,9 @@ conio/cgets.c conio/cputs.c conio/getch.c + conio/getwch.c conio/getche.c + conio/getwche.c conio/kbhit.c conio/putch.c conio/ungetch.c