00001 /* 00002 Raw terminal I/O 00003 AUP2, Sec. 4.05.9, 4.05.10 00004 00005 Copyright 2003 by Marc J. Rochkind. All rights reserved. 00006 May be copied only for purposes and under conditions described 00007 on the Web page www.basepath.com/aup/copyright.htm. 00008 00009 The Example Files are provided "as is," without any warranty; 00010 without even the implied warranty of merchantability or fitness 00011 for a particular purpose. The author and his publisher are not 00012 responsible for any damages, direct or incidental, resulting 00013 from the use or non-use of these Example Files. 00014 00015 The Example Files may contain defects, and some contain deliberate 00016 coding mistakes that were included for educational reasons. 00017 You are responsible for determining if and how the Example Files 00018 are to be used. 00019 00020 */ 00021 #include "defs.h" 00022 #include "tc_setraw.h" 00023 #include <termios.h> 00024 00025 /*[tc_keystroke]*/ 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 /*[tc_setraw]*/ 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 /* treat undefined as error with errno = 0 */ 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 /*[tc_restore]*/ 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 /*[]*/