简体   繁体   中英

Linux keyboard raw reading, what's better, reading from /dev/input/event0 or reading from stdin?

I'm working on a small C videogames library for the Raspberry Pi. I'm coding the input system from scratch and after reading and seeing some examples about raw input reading, I got some doubts.

For mouse reading, I just use /dev/input/event1, I open() it as O_NONBLOCK, I read() input_event(s) and I also put the mouse reading in a separate pthread. Easy.

For keyboard reading, I saw some examples that reconfigure stdin to O_NONBLOCK (using fcntl()), then save and reconfigure keyboard termios attibutes (ICANON, ECHO), and some example also save and reconfigure keyboard mode with ioctl(). What's the point of doing all that stuff instead of just reading /dev/input/event0 input_event(s) (same way as mouse)?

Note that I undestand what those functions do, I just don't undestand why should be better to do all that stuff instead of just reading input_event(s).

Reading stdin is not limited to reading locally connected keyboards (but has other limitation making it mostly unsuitable for games). Then reading stdin you could be reading keystrokes from a user logged in remotely, using a locally connected serial terminal or a terminal emulator (possibly operated from a remote X server).

For terminal based games it might make sense to use stdin. But then it would probably be better to use GPM instead of reading /dev/input/event1 for the mouse. And possibly even better to use ncurses for everything.

Otherwise you might want to look at SDL , if not for using it directly, at least for learning about different ways to read input. For example, SDL has full support for network transparency using X. Which means a game can execute on one computer but be played on another.

Expanding on Fabel answer - standard input and event1 are entirely different things. Starting from that the event1 does not have to be mouse but can be an other device depending on udev, kernel version, phase of moon etc. - on my (non Raspberry Pi) system it's input device Sleep Button - which has a keyboard interface. In short you cannot and should not assume it's keyboard - or the only keyboard for that matter (for example also YubiKey emulates the keyboard for it's function but it's rather useless as gaming device, and while 2 keyboards are rarely connected to same Raspberry Pi I don't think it's good idea to assume such setup never happens).

Furthermore typically input devices can be read only by privileged user (on older/current systems) or by user holding a 'seat' (on rootless X systems) - assuming you're not using bleeding edge system it means your game can only by used by root user which is usually considered a bad idea .

Finally it only allows for user to play using a evdev subsystem, which probably should be considered Linux/X11 implementation detail. If you try to connect via network (X11, vnc or whaterver), try to use on-screen keyboard or any accessible input program - you might run into problems.

On the other hand what you can do is either use standard input directly, use some more portable libraries like readline (which should be sufficient for rougulike ) or use graphics server (probably indirectly via library like QT or SDL as X11 is not the nicest protocol to program against).

Reading from /dev/input/eventN works only on GNU/Linux.

Configuring and using stdin works on any system implementing POSIX.1-2008 , specifically chapter 11: General Terminal Interface . So if you want portable code, like say to work on Linux and OS X without rewriting the input system, you'd do it this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM