199478f473889925e07c5a99a344abf16c6e58055Glenn Kasten/* 299478f473889925e07c5a99a344abf16c6e58055Glenn KastenC non-blocking keyboard input 399478f473889925e07c5a99a344abf16c6e58055Glenn Kastenhttp://stackoverflow.com/questions/448944/c-non-blocking-keyboard-input 499478f473889925e07c5a99a344abf16c6e58055Glenn Kasten*/ 599478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 699478f473889925e07c5a99a344abf16c6e58055Glenn Kasten#include <stdlib.h> 799478f473889925e07c5a99a344abf16c6e58055Glenn Kasten#include <string.h> 899478f473889925e07c5a99a344abf16c6e58055Glenn Kasten#include <sys/select.h> 999478f473889925e07c5a99a344abf16c6e58055Glenn Kasten#include <termios.h> 1099478f473889925e07c5a99a344abf16c6e58055Glenn Kasten#include <unistd.h> 1199478f473889925e07c5a99a344abf16c6e58055Glenn Kasten#include "getch.h" 1299478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 1399478f473889925e07c5a99a344abf16c6e58055Glenn Kastenstruct termios orig_termios; 1499478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 1599478f473889925e07c5a99a344abf16c6e58055Glenn Kastenvoid reset_terminal_mode() 1699478f473889925e07c5a99a344abf16c6e58055Glenn Kasten{ 1799478f473889925e07c5a99a344abf16c6e58055Glenn Kasten tcsetattr(0, TCSANOW, &orig_termios); 1899478f473889925e07c5a99a344abf16c6e58055Glenn Kasten} 1999478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 2099478f473889925e07c5a99a344abf16c6e58055Glenn Kastenvoid set_conio_terminal_mode() 2199478f473889925e07c5a99a344abf16c6e58055Glenn Kasten{ 2299478f473889925e07c5a99a344abf16c6e58055Glenn Kasten struct termios new_termios; 2399478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 2499478f473889925e07c5a99a344abf16c6e58055Glenn Kasten /* take two copies - one for now, one for later */ 2599478f473889925e07c5a99a344abf16c6e58055Glenn Kasten tcgetattr(0, &orig_termios); 2699478f473889925e07c5a99a344abf16c6e58055Glenn Kasten memcpy(&new_termios, &orig_termios, sizeof(new_termios)); 2799478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 2899478f473889925e07c5a99a344abf16c6e58055Glenn Kasten /* register cleanup handler, and set the new terminal mode */ 2999478f473889925e07c5a99a344abf16c6e58055Glenn Kasten atexit(reset_terminal_mode); 3099478f473889925e07c5a99a344abf16c6e58055Glenn Kasten cfmakeraw(&new_termios); 3199478f473889925e07c5a99a344abf16c6e58055Glenn Kasten new_termios.c_oflag |= OPOST; 3299478f473889925e07c5a99a344abf16c6e58055Glenn Kasten tcsetattr(0, TCSANOW, &new_termios); 3399478f473889925e07c5a99a344abf16c6e58055Glenn Kasten} 3499478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 3599478f473889925e07c5a99a344abf16c6e58055Glenn Kastenint kbhit() 3699478f473889925e07c5a99a344abf16c6e58055Glenn Kasten{ 3799478f473889925e07c5a99a344abf16c6e58055Glenn Kasten struct timeval tv = { 0L, 0L }; 3899478f473889925e07c5a99a344abf16c6e58055Glenn Kasten fd_set fds; 3999478f473889925e07c5a99a344abf16c6e58055Glenn Kasten FD_ZERO(&fds); // not in original posting to stackoverflow 4099478f473889925e07c5a99a344abf16c6e58055Glenn Kasten FD_SET(0, &fds); 4199478f473889925e07c5a99a344abf16c6e58055Glenn Kasten return select(1, &fds, NULL, NULL, &tv); 4299478f473889925e07c5a99a344abf16c6e58055Glenn Kasten} 4399478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 4499478f473889925e07c5a99a344abf16c6e58055Glenn Kastenint getch() 4599478f473889925e07c5a99a344abf16c6e58055Glenn Kasten{ 4699478f473889925e07c5a99a344abf16c6e58055Glenn Kasten int r; 4799478f473889925e07c5a99a344abf16c6e58055Glenn Kasten unsigned char c; 4899478f473889925e07c5a99a344abf16c6e58055Glenn Kasten if ((r = read(0, &c, sizeof(c))) < 0) { 4999478f473889925e07c5a99a344abf16c6e58055Glenn Kasten return r; 5099478f473889925e07c5a99a344abf16c6e58055Glenn Kasten } else { 5199478f473889925e07c5a99a344abf16c6e58055Glenn Kasten return c; 5299478f473889925e07c5a99a344abf16c6e58055Glenn Kasten } 5399478f473889925e07c5a99a344abf16c6e58055Glenn Kasten} 5499478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 5599478f473889925e07c5a99a344abf16c6e58055Glenn Kasten#if 0 5699478f473889925e07c5a99a344abf16c6e58055Glenn Kastenint main(int argc, char *argv[]) 5799478f473889925e07c5a99a344abf16c6e58055Glenn Kasten{ 5899478f473889925e07c5a99a344abf16c6e58055Glenn Kasten set_conio_terminal_mode(); 5999478f473889925e07c5a99a344abf16c6e58055Glenn Kasten 6099478f473889925e07c5a99a344abf16c6e58055Glenn Kasten while (!kbhit()) { 6199478f473889925e07c5a99a344abf16c6e58055Glenn Kasten /* do some work */ 6299478f473889925e07c5a99a344abf16c6e58055Glenn Kasten } 6399478f473889925e07c5a99a344abf16c6e58055Glenn Kasten (void)getch(); /* consume the character */ 6499478f473889925e07c5a99a344abf16c6e58055Glenn Kasten} 6599478f473889925e07c5a99a344abf16c6e58055Glenn Kasten#endif 66