|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ ! 2: /* hack.tty.c - version 1.0.3 */ ! 3: /* With thanks to the people who sent code for SYSV - hpscdi!jon, ! 4: arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others. */ ! 5: ! 6: #include "hack.h" ! 7: #include <stdio.h> ! 8: ! 9: /* ! 10: * The distinctions here are not BSD - rest but rather USG - rest, as ! 11: * BSD still has the old sgttyb structure, but SYSV has termio. Thus: ! 12: */ ! 13: #ifdef BSD ! 14: #define V7 ! 15: #else ! 16: #define USG ! 17: #endif BSD ! 18: ! 19: /* ! 20: * Some systems may have getchar() return EOF for various reasons, and ! 21: * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs. ! 22: */ ! 23: #ifndef BSD ! 24: #define NR_OF_EOFS 20 ! 25: #endif BSD ! 26: ! 27: ! 28: #ifdef USG ! 29: ! 30: #include <termio.h> ! 31: #define termstruct termio ! 32: #define kill_sym c_cc[VKILL] ! 33: #define erase_sym c_cc[VERASE] ! 34: #define EXTABS TAB3 ! 35: #define tabflgs c_oflag ! 36: #define echoflgs c_lflag ! 37: #define cbrkflgs c_lflag ! 38: #define CBRKMASK ICANON ! 39: #define CBRKON ! /* reverse condition */ ! 40: #define OSPEED(x) ((x).c_cflag & CBAUD) ! 41: #define GTTY(x) (ioctl(0, TCGETA, x)) ! 42: #define STTY(x) (ioctl(0, TCSETA, x)) /* TCSETAF? TCSETAW? */ ! 43: ! 44: #else /* V7 */ ! 45: ! 46: #include <sgtty.h> ! 47: #define termstruct sgttyb ! 48: #define kill_sym sg_kill ! 49: #define erase_sym sg_erase ! 50: #define EXTABS XTABS ! 51: #define tabflgs sg_flags ! 52: #define echoflgs sg_flags ! 53: #define cbrkflgs sg_flags ! 54: #define CBRKMASK CBREAK ! 55: #define CBRKON /* empty */ ! 56: #define OSPEED(x) (x).sg_ospeed ! 57: #define GTTY(x) (gtty(0, x)) ! 58: #define STTY(x) (stty(0, x)) ! 59: ! 60: #endif USG ! 61: ! 62: extern short ospeed; ! 63: static char erase_char, kill_char; ! 64: static boolean settty_needed = FALSE; ! 65: struct termstruct inittyb, curttyb; ! 66: ! 67: /* ! 68: * Get initial state of terminal, set ospeed (for termcap routines) ! 69: * and switch off tab expansion if necessary. ! 70: * Called by startup() in termcap.c and after returning from ! or ^Z ! 71: */ ! 72: gettty(){ ! 73: if(GTTY(&inittyb) < 0) ! 74: perror("Hack (gettty)"); ! 75: curttyb = inittyb; ! 76: ospeed = OSPEED(inittyb); ! 77: erase_char = inittyb.erase_sym; ! 78: kill_char = inittyb.kill_sym; ! 79: getioctls(); ! 80: ! 81: /* do not expand tabs - they might be needed inside a cm sequence */ ! 82: if(curttyb.tabflgs & EXTABS) { ! 83: curttyb.tabflgs &= ~EXTABS; ! 84: setctty(); ! 85: } ! 86: settty_needed = TRUE; ! 87: } ! 88: ! 89: /* reset terminal to original state */ ! 90: settty(s) char *s; { ! 91: clear_screen(); ! 92: end_screen(); ! 93: if(s) printf(s); ! 94: (void) fflush(stdout); ! 95: if(STTY(&inittyb) < 0) ! 96: perror("Hack (settty)"); ! 97: flags.echo = (inittyb.echoflgs & ECHO) ? ON : OFF; ! 98: flags.cbreak = (CBRKON(inittyb.cbrkflgs & CBRKMASK)) ? ON : OFF; ! 99: setioctls(); ! 100: } ! 101: ! 102: setctty(){ ! 103: if(STTY(&curttyb) < 0) ! 104: perror("Hack (setctty)"); ! 105: } ! 106: ! 107: ! 108: setftty(){ ! 109: register int ef = 0; /* desired value of flags & ECHO */ ! 110: register int cf = CBRKON(CBRKMASK); /* desired value of flags & CBREAK */ ! 111: register int change = 0; ! 112: flags.cbreak = ON; ! 113: flags.echo = OFF; ! 114: /* Should use (ECHO|CRMOD) here instead of ECHO */ ! 115: if((curttyb.echoflgs & ECHO) != ef){ ! 116: curttyb.echoflgs &= ~ECHO; ! 117: /* curttyb.echoflgs |= ef; */ ! 118: change++; ! 119: } ! 120: if((curttyb.cbrkflgs & CBRKMASK) != cf){ ! 121: curttyb.cbrkflgs &= ~CBRKMASK; ! 122: curttyb.cbrkflgs |= cf; ! 123: #ifdef USG ! 124: /* be satisfied with one character; no timeout */ ! 125: curttyb.c_cc[VMIN] = 1; /* was VEOF */ ! 126: curttyb.c_cc[VTIME] = 0; /* was VEOL */ ! 127: #endif USG ! 128: change++; ! 129: } ! 130: if(change){ ! 131: setctty(); ! 132: } ! 133: start_screen(); ! 134: } ! 135: ! 136: ! 137: /* fatal error */ ! 138: /*VARARGS1*/ ! 139: error(s,x,y) char *s; { ! 140: if(settty_needed) ! 141: settty((char *) 0); ! 142: printf(s,x,y); ! 143: putchar('\n'); ! 144: exit(1); ! 145: } ! 146: ! 147: /* ! 148: * Read a line closed with '\n' into the array char bufp[BUFSZ]. ! 149: * (The '\n' is not stored. The string is closed with a '\0'.) ! 150: * Reading can be interrupted by an escape ('\033') - now the ! 151: * resulting string is "\033". ! 152: */ ! 153: getlin(bufp) ! 154: register char *bufp; ! 155: { ! 156: register char *obufp = bufp; ! 157: register int c; ! 158: ! 159: flags.toplin = 2; /* nonempty, no --More-- required */ ! 160: for(;;) { ! 161: (void) fflush(stdout); ! 162: if((c = getchar()) == EOF) { ! 163: *bufp = 0; ! 164: return; ! 165: } ! 166: if(c == '\033') { ! 167: *obufp = c; ! 168: obufp[1] = 0; ! 169: return; ! 170: } ! 171: if(c == erase_char || c == '\b') { ! 172: if(bufp != obufp) { ! 173: bufp--; ! 174: putstr("\b \b"); /* putsym converts \b */ ! 175: } else bell(); ! 176: } else if(c == '\n') { ! 177: *bufp = 0; ! 178: return; ! 179: } else if(' ' <= c && c < '\177') { ! 180: /* avoid isprint() - some people don't have it ! 181: ' ' is not always a printing char */ ! 182: *bufp = c; ! 183: bufp[1] = 0; ! 184: putstr(bufp); ! 185: if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO) ! 186: bufp++; ! 187: } else if(c == kill_char || c == '\177') { /* Robert Viduya */ ! 188: /* this test last - @ might be the kill_char */ ! 189: while(bufp != obufp) { ! 190: bufp--; ! 191: putstr("\b \b"); ! 192: } ! 193: } else ! 194: bell(); ! 195: } ! 196: } ! 197: ! 198: getret() { ! 199: cgetret(""); ! 200: } ! 201: ! 202: cgetret(s) ! 203: register char *s; ! 204: { ! 205: putsym('\n'); ! 206: if(flags.standout) ! 207: standoutbeg(); ! 208: putstr("Hit "); ! 209: putstr(flags.cbreak ? "space" : "return"); ! 210: putstr(" to continue: "); ! 211: if(flags.standout) ! 212: standoutend(); ! 213: xwaitforspace(s); ! 214: } ! 215: ! 216: char morc; /* tell the outside world what char he used */ ! 217: ! 218: xwaitforspace(s) ! 219: register char *s; /* chars allowed besides space or return */ ! 220: { ! 221: register int c; ! 222: ! 223: morc = 0; ! 224: ! 225: while((c = readchar()) != '\n') { ! 226: if(flags.cbreak) { ! 227: if(c == ' ') break; ! 228: if(s && index(s,c)) { ! 229: morc = c; ! 230: break; ! 231: } ! 232: bell(); ! 233: } ! 234: } ! 235: } ! 236: ! 237: char * ! 238: parse() ! 239: { ! 240: static char inline[COLNO]; ! 241: register foo; ! 242: ! 243: flags.move = 1; ! 244: if(!Invisible) curs_on_u(); else home(); ! 245: while((foo = readchar()) >= '0' && foo <= '9') ! 246: multi = 10*multi+foo-'0'; ! 247: if(multi) { ! 248: multi--; ! 249: save_cm = inline; ! 250: } ! 251: inline[0] = foo; ! 252: inline[1] = 0; ! 253: if(foo == 'f' || foo == 'F'){ ! 254: inline[1] = getchar(); ! 255: #ifdef QUEST ! 256: if(inline[1] == foo) inline[2] = getchar(); else ! 257: #endif QUEST ! 258: inline[2] = 0; ! 259: } ! 260: if(foo == 'm' || foo == 'M'){ ! 261: inline[1] = getchar(); ! 262: inline[2] = 0; ! 263: } ! 264: clrlin(); ! 265: return(inline); ! 266: } ! 267: ! 268: char ! 269: readchar() { ! 270: register int sym; ! 271: ! 272: (void) fflush(stdout); ! 273: if((sym = getchar()) == EOF) ! 274: #ifdef NR_OF_EOFS ! 275: { /* ! 276: * Some SYSV systems seem to return EOFs for various reasons ! 277: * (?like when one hits break or for interrupted systemcalls?), ! 278: * and we must see several before we quit. ! 279: */ ! 280: register int cnt = NR_OF_EOFS; ! 281: while (cnt--) { ! 282: clearerr(stdin); /* omit if clearerr is undefined */ ! 283: if((sym = getchar()) != EOF) goto noteof; ! 284: } ! 285: end_of_input(); ! 286: noteof: ; ! 287: } ! 288: #else ! 289: end_of_input(); ! 290: #endif NR_OF_EOFS ! 291: if(flags.toplin == 1) ! 292: flags.toplin = 2; ! 293: return((char) sym); ! 294: } ! 295: ! 296: end_of_input() ! 297: { ! 298: settty("End of input?\n"); ! 299: clearlocks(); ! 300: exit(0); ! 301: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.