|
|
1.1 ! root 1: /* ! 2: conwrap.c -- To give DOS's getch() function to Linux for use in Synchronet ! 3: Casey Martin 2000 ! 4: */ ! 5: ! 6: /* $Id: conwrap.c,v 1.2 2000/11/02 13:21:24 rswindell Exp $ */ ! 7: ! 8: /* @format.tab-size 4, @format.use-tabs true */ ! 9: ! 10: #ifdef __unix__ ! 11: ! 12: #include <stdlib.h> ! 13: #include <unistd.h> ! 14: #include <termios.h> ! 15: #include <sys/kd.h> ! 16: #include <sys/time.h> ! 17: #include <sys/types.h> ! 18: #include <signal.h> ! 19: ! 20: #include "conwrap.h" // Verify prototypes ! 21: ! 22: struct termios current; // our current term settings ! 23: struct termios original; // old termios settings ! 24: struct timeval timeout = {0, 0}; // passed in select() call ! 25: fd_set inp; // ditto ! 26: int beensetup = 0; // has _termios_setup() been called? ! 27: ! 28: /* ! 29: I'm using a variable function here simply for the sake of speed. The ! 30: termios functions must be called before a kbhit() can be successful, so ! 31: on the first call, we just set up the terminal, point to variable function ! 32: to kbhit_norm(), and then call the new function. Otherwise, testing would ! 33: be required on every call to determine if termios has already been setup. ! 34: ! 35: Maybe I'm being way too anal, though. ! 36: */ ! 37: ! 38: /* Resets the termios to its previous state */ ! 39: void _termios_reset(void) ! 40: { ! 41: tcsetattr(0, TCSANOW, &original); ! 42: } ! 43: ! 44: /************************************************ ! 45: This pair of functions handles Ctrl-Z presses ! 46: ************************************************/ ! 47: ! 48: void _sighandler_stop(int sig) ! 49: { ! 50: // clean up the terminal ! 51: _termios_reset(); ! 52: ! 53: // ... and stop ! 54: kill(getpid(), SIGSTOP); ! 55: } ! 56: ! 57: void _sighandler_cont(int sig) ! 58: { ! 59: // restore terminal ! 60: tcsetattr(0, TCSANOW, ¤t); ! 61: } ! 62: ! 63: ! 64: /* Prepares termios for non-blocking action */ ! 65: void _termios_setup(void) ! 66: { ! 67: beensetup = 1; ! 68: ! 69: tcgetattr(0, &original); ! 70: ! 71: memcpy(¤t, &original, sizeof(struct termios)); ! 72: current.c_cc[VMIN] = 1; // read() will return with one char ! 73: current.c_cc[VTIME] = 0; // read() blocks forever ! 74: current.c_lflag &= ~ICANON; // character mode ! 75: current.c_lflag &= ~ECHO; // turn off echoing ! 76: tcsetattr(0, TCSANOW, ¤t); ! 77: ! 78: // Let's install an exit function, also. This way, we can reset ! 79: // the termios silently ! 80: atexit(_termios_reset); ! 81: ! 82: // install the Ctrl-Z handler ! 83: signal(SIGSTOP, _sighandler_stop); ! 84: signal(SIGCONT, _sighandler_cont); ! 85: } ! 86: ! 87: ! 88: int kbhit(void) ! 89: { ! 90: // set up select() args ! 91: FD_ZERO(&inp); ! 92: FD_SET(0, &inp); ! 93: ! 94: return select(1, &inp, NULL, NULL, &timeout); ! 95: } ! 96: ! 97: int getch(void) ! 98: { ! 99: char c; ! 100: ! 101: if (!beensetup) ! 102: // I hate to test for this every time, but this shouldn't be ! 103: // called that often anyway... ! 104: _termios_setup(); ! 105: ! 106: // get a char out of stdin ! 107: read(0, &c, 1); ! 108: ! 109: return c; ! 110: } ! 111: ! 112: #endif // __unix__
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.