00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "defs.h"
00022 #include "tc_setraw.h"
00023 #include <termios.h>
00024
00025
00026 static struct termios tbufsave;
00027 static bool have_attr = false;
00028
00029 int tc_keystroke(void)
00030 {
00031 static unsigned char buf[10];
00032 static ssize_t total = 0, next = 0;
00033 static bool first = true;
00034 struct termios tbuf;
00035
00036 if (first) {
00037 first = false;
00038 ec_neg1( tcgetattr(STDIN_FILENO, &tbuf) )
00039 have_attr = true;
00040 tbufsave = tbuf;
00041 tbuf.c_lflag &= ~ICANON;
00042 tbuf.c_cc[VMIN] = sizeof(buf);
00043 tbuf.c_cc[VTIME] = 2;
00044 ec_neg1( tcsetattr(STDIN_FILENO, TCSAFLUSH, &tbuf) )
00045 }
00046 if (next >= total)
00047 switch (total = read(0, buf, sizeof(buf))) {
00048 case -1:
00049 syserr("read");
00050 case 0:
00051 fprintf(stderr, "Mysterious EOF\n");
00052 exit(EXIT_FAILURE);
00053 default:
00054 next = 0;
00055 }
00056 return buf[next++];
00057
00058 EC_CLEANUP_BGN
00059 return -1;
00060 EC_CLEANUP_END
00061 }
00062
00063 bool tc_setraw(void)
00064 {
00065 struct termios tbuf;
00066 long disable;
00067 int i;
00068
00069 #ifdef _POSIX_VDISABLE
00070 disable = _POSIX_VDISABLE;
00071 #else
00072
00073 ec_neg1( (errno = 0, disable = fpathconf(STDIN_FILENO, _PC_VDISABLE)) )
00074 #endif
00075 ec_neg1( tcgetattr(STDIN_FILENO, &tbuf) )
00076 have_attr = true;
00077 tbufsave = tbuf;
00078 tbuf.c_cflag &= ~(CSIZE | PARENB);
00079 tbuf.c_cflag |= CS8;
00080 tbuf.c_iflag &= ~(INLCR | ICRNL | ISTRIP | INPCK | IXON | BRKINT);
00081 tbuf.c_oflag &= ~OPOST;
00082 tbuf.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO);
00083 for (i = 0; i < NCCS; i++)
00084 tbuf.c_cc[i] = (cc_t)disable;
00085 tbuf.c_cc[VMIN] = 5;
00086 tbuf.c_cc[VTIME] = 2;
00087 ec_neg1( tcsetattr(STDIN_FILENO, TCSAFLUSH, &tbuf) )
00088 return true;
00089
00090 EC_CLEANUP_BGN
00091 return false;
00092 EC_CLEANUP_END
00093 }
00094
00095 bool tc_restore(void)
00096 {
00097 if (have_attr)
00098 ec_neg1( tcsetattr(STDIN_FILENO, TCSAFLUSH, &tbufsave) )
00099 return true;
00100
00101 EC_CLEANUP_BGN
00102 return false;
00103 EC_CLEANUP_END
00104 }
00105