diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/terminal.nim | 31 | ||||
-rw-r--r-- | lib/windows/winlean.nim | 24 |
2 files changed, 43 insertions, 12 deletions
diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 60f064e7c..60fce04c9 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -493,17 +493,26 @@ template styledEcho*(args: varargs[expr]): expr = ## Echoes styles arguments to stdout using ``styledWriteLine``. callStyledEcho(args) -when defined(nimdoc): - proc getch*(): char = - ## Read a single character from the terminal, blocking until it is entered. - ## The character is not printed to the terminal. This is not available for - ## Windows. - discard -elif not defined(windows): - proc getch*(): char = - ## Read a single character from the terminal, blocking until it is entered. - ## The character is not printed to the terminal. This is not available for - ## Windows. +proc getch*(): char = + ## Read a single character from the terminal, blocking until it is entered. + ## The character is not printed to the terminal. + when defined(windows): + let fd = getStdHandle(STD_INPUT_HANDLE) + # Block until character is entered + discard waitForSingleObject(fd, INFINITE) + var record = INPUT_RECORD() + var recordPtr: ptr INPUT_RECORD = addr(record) + var numRead: cint + while true: + discard readConsoleInput(fd, recordPtr, 1, addr(numRead)) + if numRead == 0 or record.eventType != 1: + continue + let keyEvent = cast[ptr KEY_EVENT_RECORD](recordPtr) + # skip key release events + if keyEvent.bKeyDown == 0: + continue + return char(keyEvent.UnicodeChar) + else: let fd = getFileHandle(stdin) var oldMode: Termios discard fd.tcgetattr(addr oldMode) diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 04edeb2cb..9d44621b9 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -1016,4 +1016,26 @@ proc wsaCloseEvent*(hEvent: Handle): bool {.stdcall, importc: "WSACloseEvent", dynlib: "ws2_32.dll".} proc wsaResetEvent*(hEvent: Handle): bool - {.stdcall, importc: "WSAResetEvent", dynlib: "ws2_32.dll".} \ No newline at end of file + {.stdcall, importc: "WSAResetEvent", dynlib: "ws2_32.dll".} + +type + INPUT_RECORD* {.final, pure.} = object + eventType*: int16 + padding: array[18, byte] + KEY_EVENT_RECORD* {.final, pure.} = object + eventType*: int16 + bKeyDown*: WINBOOL + wRepeatCount*: int16 + wVirtualKeyCode*: int16 + wVirtualScanCode*: int16 + UnicodeChar*: int16 + dwControlKeyState*: DWORD + +when defined(useWinAnsi): + proc readConsoleInput*(hConsoleInput: Handle, lpBuffer: pointer, nLength: cint, + lpNumberOfEventsRead: ptr cint): cint + {.header: "<windows.h>", importc: "ReadConsoleInputA".} +else: + proc readConsoleInput*(hConsoleInput: Handle, lpBuffer: pointer, nLength: cint, + lpNumberOfEventsRead: ptr cint): cint + {.header: "<windows.h>", importc: "ReadConsoleInputW".} \ No newline at end of file |