[Gambas-user] What is the Gambas equivalent of Inkey ?

Tobias Boege taboege at ...626...
Sun Dec 7 20:52:30 CET 2014


On Sat, 06 Dec 2014, Lewis Balentine wrote:
> For a console application I want to issue a prompt:
> "Press any key to continue ..."
> or
> "Press 'X' to exit or 'C' to continue:"
> and then wait for the user to press a key.
> 
> I can find no equivalent for the Basic "inkey" function. I have tried 
> using wait/read but it seems one must press the "enter" key.
> Private Function InKey(Prompt As String) As Byte
>    Dim n As Byte
>    If Prompt <> "" Then Print Prompt
>    n = 0
>    While n = 0
>      Wait 0.01
>      ' n = Read As Byte
>      n = Read 1
>    Wend
>    Return n
> End
> 
> Suggestions ?
> 

Yes, terminals operate line-buffered by default, that is a newline must be
typed by the user before the whole line even leaves the terminal driver. In
this mode, Gambas can't do anything to help you.

Good news is that you can change the mode of the terminal. There are several
ways to do that:

 - use gb.ncurses (this will make your whole Gambas program into an
   interactive "terminal-GUI" program; that *may* be too intervening for
   you),
 - use the C library's tcsetattr() function -- just the thought of it is
   so painful to me that I didn't try it until today,
 - beg Benoit to implement it in Gambas (I don't know about portability
   issues with that),
 - use stty.

The last option is the only one that worked for me (although I didn't try
options 2 and 3). stty is a little utility that comes with the coreutils
package (on my Arch Linux it says so at least) that knows how to talk to
terminals portably.

You would want to do

  Dim sState As String

  Exec ["stty", "-g"] To sState ' Save the current state of the terminal
  Exec ["stty", "cbreak"] Wait  ' The input mode you want is called "cbreak"
  ' Do your thing here ...
  Exec ["stty", Trim$(sState)] Wait ' Restore the terminal

In general you want to restore the state as soon as possible. I attach you
a script which you can use as a basis.

Regards,
Tobi

-- 
"There's an old saying: Don't change anything... ever!" -- Mr. Monk
-------------- next part --------------
#!/usr/bin/gbs3

Public Sub Main()
  Dim sState, sChar As String

  Exec ["stty", "-g"] To sState
  Exec ["stty", "cbreak"] Wait

  Do
    sChar = Read 1
    If sChar = "q" Then Break
    Print "You typed";; sChar
  Loop

  Exec ["stty", Trim$(sState)] Wait
End


More information about the User mailing list