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