Jump to content

  • Log In with Google      Sign In   
  • Create Account

Getting raw keyboard input in console programming using Linux


Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.


  • You cannot reply to this topic
5 replies to this topic

#1   Members   -  Reputation: 1163

Like
0Likes
Like

Posted 16 October 2013 - 02:27 AM

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? 


“There are thousands and thousands of people out there leading lives of quiet, screaming desperation, where they work long, hard hours at jobs they hate to enable them to buy things they don't need to impress people they don't like.”― Nigel Marsh

#2   Crossbones+   -  Reputation: 2571

Like
0Likes
Like

Posted 16 October 2013 - 03:38 AM

Reading from /dev/input/eventX should work, perhaps if you share your code we can help pinpoint the problem?

 

Otherwise, have you checked out one of the console UI libraries such as ncurses?


"Windows 10 doesn't only include spyware, it is designed as spyware" -- Gaius Publius, The Big Picture RT Interview

"[...] we will access, disclose and preserve personal data, including your content (such as the content of your emails, other private communications or files in private folders), when we have a good faith belief that doing so is necessary" -- Windows 10 Privacy Statement


#3   Crossbones+   -  Reputation: 19345

Like
0Likes
Like

Posted 16 October 2013 - 07:40 AM

There are other options, like SDL. What are you using for graphics? Or does your program run in a terminal?



#4   Members   -  Reputation: 101

Like
0Likes
Like

Posted 16 October 2013 - 08:50 AM

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!

#5   Crossbones+   -  Reputation: 19345

Like
0Likes
Like

Posted 16 October 2013 - 08:58 AM


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.



#6   Members   -  Reputation: 237

Like
0Likes
Like

Posted 18 October 2013 - 06:29 AM

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






Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.




PARTNERS