• Advertisement
Sign in to follow this  

Getting raw keyboard input in console programming using Linux

This topic is 1555 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I thought I would develop tetris game in C on linux. Everything works fine, except I can't find a way to get input without interrupting whats going in my game. My game has main loop which I don't want to stop. So regular console input methods don't work. I also tried to open /dev/input/eventX and read keyboard state from there, but it doesn't seem to read anything, but if I do "cat /dev/input/eventX" it does show that it contains events. 

I also tried using glut and glutKeyboardFunc, but that doesn't seem to work either. As it probably needs a focused X window to operate.

 

Does anyone have any ideas what could I try next? 

Share this post


Link to post
Share on other sites
Advertisement
You need to create a separate thread to handle the keyboard input, and feed that to your main loop when the data is ready. You can use fork() or posix threads.

This way your main loop never stops, but only processes data when it is available.

You can feed the data from the child thread in a few ways.... pipe is OK, google how to do it. You can also set up shared memory, I think posix threads have apis to support.

I would really start with fork() as it clarifies the concept, posix threads are good but more complex.

Good luck! And have fun, sounds like a great Linux programming 101 topic!

Share this post


Link to post
Share on other sites


You need to create a separate thread to handle the keyboard input, and feed that to your main loop when the data is ready [...]

 

That is good advice if you want to process entire lines of text, like you would when implementing a chess engine that communicates with a GUI using text. However, this won't do you any good for tetris, which is what the OP is writing.

Share this post


Link to post
Share on other sites

Are you just trying to read from the device raw? You need to read events:

 

Quick hack cut+paste from another project:

        int fd = ::open( "/dev/input/event0", O_RDONLY | O_CLOEXEC );
        if( -1 == fd )
            return false;
        char name[ 32 ];
        if( -1 == ioctl( fd, EVIOCGNAME( sizeof( name )), name ))
            return false;
        
        // Grab input
        if( -1 == ioctl( fd, EVIOCGRAB, (void*)1 ))
        {
            printf( "Failed to grab input %s: (%i) %m", name, errno );
            return false;
        }

	struct input_event ev;
	memset( &ev, 0, sizeof( ev ));
	if( -1 == read( m_input, &ev, sizeof( ev )) )
	{
		printf( "read() failed: (%i) %m", errno );
		return;
	}
	
	if( ev.type != EV_KEY ) return;
	if( ev.value != 0 ) return;

	if( ev.code == KEY_F11 )
		next_channel();
	else if( ev.code == KEY_F12 )
		display().show_osd( !display().osd_visible );

You will want to enable non blocking, then handle the EAGAIN when the read fails.

 

-Z

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement