win.getch returns -1
Opened this issue · 10 comments
Is there something special I'm supposed to do?
Yup, do you want to read one char right?
I got same error. It would be my fault about CRT initialization.
I'll try fix it. Thanks!
@tjgillies
C works. But, Crystal doesn't. I think they are logically same codes, weird.
It will take more time, sorry.
c
#include <ncursesw/curses.h>
int main()
{
WINDOW* scr = initscr();
raw();
wgetch(scr);
endwin();
return 0;
}
gcc test.c -lncursesw
./a.out
- ubuntu-16.04 with
libncursesw5-dev
crystal
@[Link("ncursesw")]
lib LibTest
type WindowPtr = Void*
fun initscr : WindowPtr
fun raw
fun wgetch(win : WindowPtr) : Int32
fun endwin
end
scr = LibTest.initscr
LibTest.raw
LibTest.wgetch(scr)
LibTest.endwin
crystal test.cr
I was playing around in another library and I think it has to do with setting timeout. Since there is no timeout set it doesn't wait for input and returns -1 immediately.
Nice! But it still exit immediately.
@[Link("ncursesw")]
lib LibTest
type WindowPtr = Void*
fun initscr : WindowPtr
fun raw
fun nodelay(win : WindowPtr, v : Bool) : Int32
fun notimeout(win : WindowPtr, v : Bool) : Int32
fun wgetch(win : WindowPtr) : Int32
fun endwin
end
scr = LibTest.initscr
LibTest.raw
LibTest.nodelay(scr, false)
LibTest.notimeout(scr, true)
LibTest.wgetch(scr)
LibTest.endwin
I don't know why C works. If we lack some method calls, C should fail too.
You need cbreak
.
This works for me:
win = Crt::Window.new(24, 80)
Crt.cbreak
Crt.notimeout(true)
win.clear
win.print(5, 10, "hello world")
win.refresh
key = win.getch
Crt.done
puts key
I've just added fun notimeout(win : WindowPtr, b : Bool) : Int32
in libncursesw.cr
and
def self.notimeout(b : Bool)
LibNcursesw.notimeout(stdscr, b)
end
in crc.cr
.
The timeout and wtimeout routines set blocking or non-blocking read for a given window. If delay is negative, blocking read is used (i.e., waits indefinitely for input). If delay is zero, then non-blocking read is used (i.e., read returns ERR if no input is waiting). If delay is positive, then read blocks for delay milliseconds, and returns ERR if there is still no input. Hence, these routines provide the same functionality as nodelay, plus the additional capability of being able to block for only delay milliseconds (where delay is positive).
Sounds like .notimeout
should be fixing the issue, not cbreak.
Yes I know it seems weird, but I need both Crt.notimeout(true)
and Crt.cbreak
to make it work, otherwise "it still exits immediately". 😕
Edit: using Crt.cooked
also "works" (it's waiting for inputs until we press the enter
key).
Btw that method is actually broken, there's a typo: LibNcursesw.nobreak
-> LibNcursesw.nocbreak
Yeah, you're right. It doesn't make much sense to me, but it's worth updating the README and example.
Hi @maxdec !
Thank you for many information.
I tried you code, but unfortunately it still exits immediately in my environment.
It would be a difference of OS where I'm using ubuntu-16.04
.
So, I'll check crystal
sources about src/lib_c/*/c/termios.cr
.
Anyway, I fixed typo about nocbreak
and added notimeout
method.
Thanks.