Source:NetHack 1.3d/unixtty.c

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('\n'); 151. 	exit(1); 152. }  153.   154.  /*  155.   * Read a line closed with '\n' into the array char bufp[BUFSZ]. 156.  * (The '\n' 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 == '\n') { 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('\n'); 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) != '\n') { 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?\n"); 329. 	clearlocks; 330. 	exit(0); 331. }