Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Unsubscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin AT sourceware DOT cygnus DOT com Message-Id: <199908182201.RAA31653@mercury.xraylith.wisc.edu> To: "'Cygwin Mailing List'" Subject: Re: Porting getch() and kbdhit() ??? In-Reply-To: Your message of "Wed, 18 Aug 1999 16:39:24 EDT." Date: Wed, 18 Aug 1999 17:01:29 -0500 From: Mumit Khan "Lincoln, W. Terry" writes: > I have a M$-C book on my shelf and it says that the function kbhit() should > return a 0 if no characters have been struck otherwise the character-code of > the struck key (without removing the key from the KB queue). > > getch() removes a single key from the KB queue (waiting for one if > necessary) and returns it character-code without echoing it to the terminal > screen. > > getche() is the same but echoes the character it gets to the screen. Unfortunately, I know nothing about DOS, and DJ already pointed the fact that my kbhit is not what DOS has. However, it should still be reasonably straight forward to implement using select with 0 timeout (not NULL, but 0 for the values) to check if there's input pending for standard input descriptor. Here's an untested attempt that should work on all POSIX systems. Note the global cbreak/raw mode wrapper, which is necessary for this type of input handling to work. This needs work, especially in the area of cleanups/tty reset if things go bad, and catching signals and so on. Left as an exercise ;-) I'm sure this code is full of holes, but I don't care enough about to actually spend time on it ... Regards, Mumit --- cut from here to end /* kbhit.c -- sample kbhit/getch implementation. */ #include #include #include #ifndef STDIN_FILENO # define STDIN_FILENO 0 #endif /* Use of raw mode requires that you understand how to manage signals and all that. */ #ifdef USE_RAW_MODE # define RAW_MODE(x) tty_raw((x)) #else # define RAW_MODE(x) tty_cbreak((x)) #endif static struct termios save_termios; static int tty_cbreak (int fd) { struct termios ios; if (tcgetattr (fd, &save_termios) < 0) return -1; ios = save_termios; ios.c_lflag &= ~(ICANON | ECHO); ios.c_cc[VMIN] = 1; ios.c_cc[VTIME] = 0; return tcsetattr (fd, TCSAFLUSH, &ios); } static int tty_raw (int fd) { struct termios ios; if (tcgetattr (fd, &save_termios) < 0) return -1; ios = save_termios; ios.c_lflag &= ~(ICANON | ECHO | IEXTEN | ISIG); ios.c_lflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); ios.c_lflag &= ~(CSIZE | PARENB); ios.c_lflag |= CS8; ios.c_lflag &= ~(OPOST); ios.c_cc[VMIN] = 1; ios.c_cc[VTIME] = 0; return tcsetattr (fd, TCSAFLUSH, &ios); } static int tty_reset (int fd) { return tcsetattr (fd, TCSAFLUSH, &save_termios); } int kbdhit (void) { fd_set rfds; struct timeval tv; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO (&rfds); FD_SET (STDIN_FILENO, &rfds); /* Return immediately. */ tv.tv_sec = 0; tv.tv_usec = 0; /* Must be in raw or cbreak mode for this to work correctly. */ return select (STDIN_FILENO + 1, &rfds, NULL, NULL, &tv) && FD_ISSET (STDIN_FILENO, &rfds); } int getch (void) { int c; /* Must be in raw or cbreak mode for this to work correctly. */ if (read (STDIN_FILENO, &c, 1) != 1) c = EOF; return c & 0xff; } int main () { int i; char c; puts ("Press Q to quit ... "); fflush (stdout); RAW_MODE (STDIN_FILENO); while (1) { fputs ("going to sleep for 2 seconds ... ", stdout); fflush (stdout); sleep (2); fputs ("awake. Checking for key\n", stdout); fflush (stdout); if (kbdhit ()) { int c; fputs ("yes ... ", stdout); fflush (stdout); c = getch (); fprintf (stdout, "%c\n", c); fflush (stdout); if (c == 'q' || c == 'Q' || c == EOF) break; } fputs ("Nope. back to sleep\n", stdout); } tty_reset (STDIN_FILENO); puts ("\nDone."); return 0; } -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com