Implemented terminal.getch() for Windows

This commit is contained in:
miere43
2016-06-23 23:22:38 +03:00
parent 5f4e98bbc7
commit dd7a24d8cc
2 changed files with 43 additions and 12 deletions

View File

@@ -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)

View File

@@ -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".}
{.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".}