123c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten/* 223c38816f7c210afae5072fd44658c98fec7e119Glenn KastenC non-blocking keyboard input 323c38816f7c210afae5072fd44658c98fec7e119Glenn Kastenhttp://stackoverflow.com/questions/448944/c-non-blocking-keyboard-input 423c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten*/ 523c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 623c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten#include <stdlib.h> 723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten#include <string.h> 823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten#include <sys/select.h> 923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten#include <termios.h> 101168fe388b96340ada641b7e0da1ca18b270af3aGlenn Kasten#include <unistd.h> 11d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten#include "getch.h" 1223c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 1323c38816f7c210afae5072fd44658c98fec7e119Glenn Kastenstruct termios orig_termios; 1423c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 1523c38816f7c210afae5072fd44658c98fec7e119Glenn Kastenvoid reset_terminal_mode() 1623c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten{ 1723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten tcsetattr(0, TCSANOW, &orig_termios); 1823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten} 1923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 2023c38816f7c210afae5072fd44658c98fec7e119Glenn Kastenvoid set_conio_terminal_mode() 2123c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten{ 2223c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten struct termios new_termios; 2323c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 2423c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten /* take two copies - one for now, one for later */ 2523c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten tcgetattr(0, &orig_termios); 2623c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten memcpy(&new_termios, &orig_termios, sizeof(new_termios)); 2723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 2823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten /* register cleanup handler, and set the new terminal mode */ 2923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten atexit(reset_terminal_mode); 3023c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten cfmakeraw(&new_termios); 310a66743fb5e46c8d94f13d6170ef405f387f05f6Glenn Kasten new_termios.c_oflag |= OPOST; 3223c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten tcsetattr(0, TCSANOW, &new_termios); 3323c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten} 3423c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 3523c38816f7c210afae5072fd44658c98fec7e119Glenn Kastenint kbhit() 3623c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten{ 3723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten struct timeval tv = { 0L, 0L }; 3823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten fd_set fds; 3923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten FD_ZERO(&fds); // not in original posting to stackoverflow 4023c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten FD_SET(0, &fds); 4123c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten return select(1, &fds, NULL, NULL, &tv); 4223c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten} 4323c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 4423c38816f7c210afae5072fd44658c98fec7e119Glenn Kastenint getch() 4523c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten{ 4623c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten int r; 4723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten unsigned char c; 4823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten if ((r = read(0, &c, sizeof(c))) < 0) { 4923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten return r; 5023c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten } else { 5123c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten return c; 5223c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten } 5323c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten} 5423c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 5523c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten#if 0 5623c38816f7c210afae5072fd44658c98fec7e119Glenn Kastenint main(int argc, char *argv[]) 5723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten{ 5823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten set_conio_terminal_mode(); 5923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 6023c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten while (!kbhit()) { 6123c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten /* do some work */ 6223c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten } 6323c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten (void)getch(); /* consume the character */ 6423c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten} 6523c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten#endif 66