From dd7a24d8ccae7cf943fcb66133c51591fb2e719d Mon Sep 17 00:00:00 2001 From: miere43 Date: Thu, 23 Jun 2016 23:22:38 +0300 Subject: Implemented terminal.getch() for Windows --- lib/pure/terminal.nim | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'lib/pure') 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) -- cgit 1.4.1-2-gfad0 From 57bd50a9166fa4171071f88bc29f37f6d8959c11 Mon Sep 17 00:00:00 2001 From: miere43 Date: Sun, 26 Jun 2016 16:01:37 +0300 Subject: Removed INPUT_KEY_RECORD --- lib/pure/terminal.nim | 17 ++++++----------- lib/windows/winlean.nim | 18 ++++++++---------- 2 files changed, 14 insertions(+), 21 deletions(-) (limited to 'lib/pure') diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 60fce04c9..62cee0ee8 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -498,20 +498,15 @@ proc getch*(): char = ## 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 keyEvent = KEY_EVENT_RECORD() var numRead: cint while true: - discard readConsoleInput(fd, recordPtr, 1, addr(numRead)) - if numRead == 0 or record.eventType != 1: + # Block until character is entered + assert(waitForSingleObject(fd, INFINITE) == WAIT_OBJECT_0) + assert(readConsoleInput(fd, addr(keyEvent), 1, addr(numRead)) != 0) + if numRead == 0 or keyEvent.eventType != 1 or keyEvent.bKeyDown == 0: continue - let keyEvent = cast[ptr KEY_EVENT_RECORD](recordPtr) - # skip key release events - if keyEvent.bKeyDown == 0: - continue - return char(keyEvent.UnicodeChar) + return char(keyEvent.uChar) else: let fd = getFileHandle(stdin) var oldMode: Termios diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 9d44621b9..b24a62b33 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -1019,23 +1019,21 @@ proc wsaResetEvent*(hEvent: Handle): bool {.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 + eventType*: uint16 + # padding: array[2, byte] bKeyDown*: WINBOOL - wRepeatCount*: int16 - wVirtualKeyCode*: int16 - wVirtualScanCode*: int16 - UnicodeChar*: int16 + wRepeatCount*: uint16 + wVirtualKeyCode*: uint16 + wVirtualScanCode*: uint16 + uChar*: uint16 dwControlKeyState*: DWORD when defined(useWinAnsi): proc readConsoleInput*(hConsoleInput: Handle, lpBuffer: pointer, nLength: cint, lpNumberOfEventsRead: ptr cint): cint - {.header: "", importc: "ReadConsoleInputA".} + {.dynlib: "kernel32", importc: "ReadConsoleInputA".} else: proc readConsoleInput*(hConsoleInput: Handle, lpBuffer: pointer, nLength: cint, lpNumberOfEventsRead: ptr cint): cint - {.header: "", importc: "ReadConsoleInputW".} \ No newline at end of file + {.dynlib: "kernel32", importc: "ReadConsoleInputW".} \ No newline at end of file -- cgit 1.4.1-2-gfad0 From 7fc9585f7b77965f171dba5a866f06c2cc7b459a Mon Sep 17 00:00:00 2001 From: miere43 Date: Sun, 26 Jun 2016 17:46:43 +0300 Subject: getch() asserts to doAsserts --- lib/pure/terminal.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/pure') diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 62cee0ee8..c135f6a00 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -502,8 +502,8 @@ proc getch*(): char = var numRead: cint while true: # Block until character is entered - assert(waitForSingleObject(fd, INFINITE) == WAIT_OBJECT_0) - assert(readConsoleInput(fd, addr(keyEvent), 1, addr(numRead)) != 0) + doAssert(waitForSingleObject(fd, INFINITE) == WAIT_OBJECT_0) + doAssert(readConsoleInput(fd, addr(keyEvent), 1, addr(numRead)) != 0) if numRead == 0 or keyEvent.eventType != 1 or keyEvent.bKeyDown == 0: continue return char(keyEvent.uChar) -- cgit 1.4.1-2-gfad0