How to get keystrokes w/o ncurses
I've written a few C programs for interactive or conversational use in a terminal, or even outside of Xwindows in a command line session. Currently, i'm using ncurses in raw mode with echo turned off, so i can get immediate response with no buffering and no translation by the ncurses routines.
But i'd really like to get the keystrokes without linking ncurses in, for various reasons. There doesn't seem to be a system call to do this. Am i missing something that's so easy i can't see it? :newbie: |
You must setup the terminal in raw mode, then you reset it to the previous state when you're done. There's an example here:
http://yendor.com/programming/unix/a...vr4/ttymodes.c |
Thanks. I will study this sample code.:study:
I think it's exactly what i was looking for, but i may come back with more questions. . . . :study: . . . I spoke too soon. This code is helpful, but i still don't see how i get a keystroke. I'm looking for the equivalent of a ncurses (or ms c) getch() function, or a bios int 10 call. So i repeat: is this so simple that i can't see it? What am i missing? :scratch: |
You have to setup the terminal in raw mode and then getchar() may do. Also, use setbuf(stdin, NULL) to turn off standard buffering.
Summary: Setting the terminal in raw mode turns off the buffering done by the line terminal driver. Then you need to turn off the buffering done by the standard library itself. |
Yes, now getchar() works, after setting the terminal into raw mode. For that matter, fread to stdin also works. And i seem to get unbuffered input even w/o the setbuf call. But i will keep that in mind as well.
Now, is there a flag in the termio structure that will tell me whether there is indeed any keystrokes waiting in the queue? |
I'm not aware of a way with the termios API. You may try with select() or asynchronous I/O... select() will work easily. See "man select_tut" and termios(3). The FreeBSD manpage is good too:
http://www.freebsd.org/cgi/man.cgi?q...SE&format=html |
Thanks. The link you provided may have what i'm looking for. More studying :study:
. . . OK, i'm back. Turns out to be quite easy. I just changed one line in the tty_raw() routine: Code:
buf.c_cc[VMIN] = 1; /* Case B: 1 byte at a time, no timer */ Code:
buf.c_cc[VMIN] = 0; /* Case D: No minimum, no timer */ Thank you for your help. I'm off & running with this now.:) |
All times are GMT -5. The time now is 11:15 AM. |