14b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten/*
24b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn KastenC non-blocking keyboard input
34b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kastenhttp://stackoverflow.com/questions/448944/c-non-blocking-keyboard-input
44b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten*/
54b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
64b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#include <stdlib.h>
74b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#include <string.h>
84b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#include <sys/select.h>
94b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#include <termios.h>
10e629abc58c2acadc7487ea71c1e063f8f8989199Glenn Kasten#include <unistd.h>
1158432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten#include "getch.h"
124b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
134b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kastenstruct termios orig_termios;
144b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
154b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kastenvoid reset_terminal_mode()
164b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten{
174b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    tcsetattr(0, TCSANOW, &orig_termios);
184b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
194b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
204b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kastenvoid set_conio_terminal_mode()
214b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten{
224b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    struct termios new_termios;
234b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
244b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    /* take two copies - one for now, one for later */
254b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    tcgetattr(0, &orig_termios);
264b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    memcpy(&new_termios, &orig_termios, sizeof(new_termios));
274b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
284b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    /* register cleanup handler, and set the new terminal mode */
294b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    atexit(reset_terminal_mode);
304b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    cfmakeraw(&new_termios);
312a6437ce83811c28df37b4cbad171c74e7613892Glenn Kasten    new_termios.c_oflag |= OPOST;
324b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    tcsetattr(0, TCSANOW, &new_termios);
334b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
344b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
354b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kastenint kbhit()
364b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten{
374b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    struct timeval tv = { 0L, 0L };
384b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    fd_set fds;
394b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    FD_ZERO(&fds); // not in original posting to stackoverflow
404b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    FD_SET(0, &fds);
414b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    return select(1, &fds, NULL, NULL, &tv);
424b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
434b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
444b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kastenint getch()
454b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten{
464b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    int r;
474b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    unsigned char c;
484b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    if ((r = read(0, &c, sizeof(c))) < 0) {
494b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        return r;
504b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    } else {
514b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        return c;
524b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    }
534b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
544b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
554b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#if 0
564b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kastenint main(int argc, char *argv[])
574b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten{
584b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    set_conio_terminal_mode();
594b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
604b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    while (!kbhit()) {
614b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        /* do some work */
624b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    }
634b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    (void)getch(); /* consume the character */
644b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
654b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif
66