Source:NetHack 2.2a/unixtty.c

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