crt.cr icon indicating copy to clipboard operation
crt.cr copied to clipboard

win.getch returns -1

Open hackervera opened this issue 8 years ago • 10 comments

Is there something special I'm supposed to do?

hackervera avatar Jan 04 '17 02:01 hackervera

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!

maiha avatar Jan 04 '17 11:01 maiha

@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

maiha avatar Jan 04 '17 14:01 maiha

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.

hackervera avatar Jan 04 '17 16:01 hackervera

https://github.com/jreinert/ncurses-crystal/blob/master/src/ncurses/window.cr#L108

hackervera avatar Jan 04 '17 16:01 hackervera

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.

maiha avatar Jan 04 '17 17:01 maiha

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.

maxdec avatar May 02 '17 20:05 maxdec

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.

MatthewBennington avatar May 02 '17 22:05 MatthewBennington

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

maxdec avatar May 03 '17 06:05 maxdec

Yeah, you're right. It doesn't make much sense to me, but it's worth updating the README and example.

MatthewBennington avatar May 03 '17 13:05 MatthewBennington

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.

maiha avatar May 04 '17 07:05 maiha