how to detect a keyboard event in C without prompting the user in linux? That is the program running should terminate by pressing any key. can anyone please help with this?
相关问题
- Multiple sockets for clients to connect to
- Is shmid returned by shmget() unique across proces
- What is the best way to do a search in a large fil
- glDrawElements only draws half a quad
- how to get running process information in java?
Here’s code from
/usr/src/bin/stty/key.c
:At a minimum, you have to get out of
ICANON
mode before yourselect(2)
syscall or yourFIONREAD ioctl
will work.I have an ancient, 20-year-old perl4 program that clears CBREAK and ECHO mode this way. It is doing curses stuff without resorting to the curses library:
And it elsewhere says that for POSIX,
RE-translation back into the original C is left as an exercise for the reader, because I can't remember where the 20-years-ago-me snagged it from originally. :(
Once you're out of ICANON mode on the tty, now your
select(2)
syscall works properly again. Whenselect
's read mask returns that that descriptor is ready, then you do aFIONREAD ioctl
to discover exactly how many bytes are waiting for you on that file descriptor. Having got that, you can do aread(2)
syscall for just that many bytes, preferably on anO_NONBLOCK
descriptor, although by now that should no longer be necessary.Hm, here’s a foreboding note in
/usr/src/usr.bin/vi/cl/README.signal
:If you do a recursive
grep
for\b(TIOC[SG]ET[NP]|TC[SG]ET[SA]|tc[sg]etattr)\b
on the non-kernel portions of/usr/src/
, you should find stuff you can use. For example:I would look at
/usr/src/usr.bin/less/screen.c
, down in theraw_mode()
function. Riddled withifdef
s though it is in a quest for portability, that looks like the cleanest code for what you want to do. There’s also stuff lurking down in GNU.OH MY, look in
/usr/src/gnu/usr.bin/perl/h2pl/cbreak.pl
! That must be my old code that I posted above. Interesting that it’s trickled out to every src system in the world. Scary, too, since it is twenty years out of date. Gosh, it's weird to see echoes of a younger self. Really hard to remember such particulars from 20 years ago.I also see in
/usr/src/lib/libcurses/term.h
this line:in a bunch of
ifdef
s that are trying to infertermio
ortermios
availability.This should be enough to get you started.
You have to modify terminal settings using termios. See Stevens & Rago 2nd Ed 'Advanced Programming in the UNIX Environment' it explains why tcsetattr() can return successfuly without having set all terminal characteristcs, and why you see what looks to be redundant calls to tcsetattr().
This is ANSI C in UNIX:
The nanosleep call is there to prevent the code from gobbling up system resources. You could call nice() and not use nanosleep(). All this does is sit and wait for a keystroke, then exit.
no way with ANSI C. Look at ncurses lib.
If you want to do that in a graphical application, you should use some libraries to do this.
Such a simple task can be easily done with whatever library (even low level ones like Xlib).
Just choose one and look for a tutorial that shows how to handle keyboard events.