Source:NetHack 2.3e/unixtty.c

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