LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How to get keystrokes w/o ncurses (https://www.linuxquestions.org/questions/programming-9/how-to-get-keystrokes-w-o-ncurses-386819/)

dogpatch 11-26-2005 07:07 PM

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:

primo 11-26-2005 07:16 PM

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

dogpatch 11-26-2005 07:45 PM

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:

primo 11-27-2005 04:36 PM

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.

dogpatch 11-27-2005 08:05 PM

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?

primo 11-27-2005 09:14 PM

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

dogpatch 11-27-2005 10:03 PM

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 */
          buf.c_cc[VTIME] = 0;*/

becomes
Code:

        buf.c_cc[VMIN] = 0;        /* Case D: No minimum, no timer */
        buf.c_cc[VTIME] = 0;

Now, if there are no keystrokes in the queue, the getchar() returns -1, instead of waiting for a keystroke.

Thank you for your help. I'm off & running with this now.:)


All times are GMT -5. The time now is 11:15 AM.