lua-users home
lua-l archive

Re: Check for a keypress

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Am 30.11.2013 13:03 schröbte John Hind:
On 2013年11月29日, Jose Torre-Bueno wrote:
Is there a way from inside Lua to check whether any key has been
pressed? io.read() will get a line from the console but if there
is no input it pends waiting for input. I would like to be able
to write a test that gets input if any is ready but would continue
if there is none. It is not obvious to me if this can be done at
all.
Not a solution, but some background. Here is a a Lua C function to do it extracted from one of my libraries, complete with comment:
/* R1: Boolean, true if there is outstanding data in the keyboard buffer.
** This is a helper to allow a demonstration terminal program implemented on the command line.
** Need a solution for Linux, although _kbhit is POSIX there seem to be theological reasons for not
** having it in Linux and it is not in baseline C.
What made you think that `_kbhit` (or `kbhit`) was in POSIX? IIRC, it's an old DOS function (and it's not listed here[1]).
*/
static int luakbhit(lua_State* L) {
#if defined(LUA_WIN)
	lua_pushboolean(L, _kbhit());
#else
	lua_pushboolean(L, FALSE);
#endif
	return 1;
}
Search online for "_kbhit" for more background on the theology!
I did, but found nothing on theology. Could you share a link?
@OP: In case you are on a POSIX machine you could use luaposix[2]:
 local p = require( "posix" )
 local function table_copy( t )
 local copy = {}
 for k,v in pairs( t ) do
 if type( v ) == "table" then
 copy[ k ] = table_copy( v )
 else
 copy[ k ] = v
 end
 end
 return copy
 end
 assert( p.isatty( p.STDIN_FILENO ), "stdin not a terminal" )
 local saved_tcattr = assert( p.tcgetattr( p.STDIN_FILENO ) )
 local raw_tcattr = table_copy( saved_tcattr )
raw_tcattr.lflag = bit32.band( raw_tcattr.lflag, bit32.bnot( p.ICANON ) )
 local guard = setmetatable( {}, { __gc = function()
 p.tcsetattr( p.STDIN_FILENO, p.TCSANOW, saved_tcattr )
 end } )
 local function kbhit()
 assert( p.tcsetattr( p.STDIN_FILENO, p.TCSANOW, raw_tcattr ) )
 local r = assert( p.rpoll( p.STDIN_FILENO, 0 ) )
 assert( p.tcsetattr( p.STDIN_FILENO, p.TCSANOW, saved_tcattr ) )
 return r > 0
 end
 ---[[
 -- Test code
 repeat until kbhit()
 print( "key pressed!" )
 --]]
HTH,
Philipp
 [1]: http://pubs.opengroup.org/onlinepubs/9699919799/
 [2]: https://github.com/luaposix/luaposix

AltStyle によって変換されたページ (->オリジナル) /