Source:NetHack 1.4f/unixtty.c

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