⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getch.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifdef lintstatic char *sccsid = "3/1/91	(ULTRIX)	@(#)getch.c	4.2";#endif lint# include	"curses.ext"# include	<signal.h># include	<errno.h># include	<sys/time.h># include	<sys/types.h>static int sig_caught;/* *	This routine reads in a character from the window. * *	wgetch MUST return an int, not a char, because it can return *	things like ERR, meta characters, and function keys > 256. *//* *	30-May-89 Andy Roach *      -------------------- *      Fixed select timeval structure. Cursor keys now return KEY_* * */intwgetch(win)register WINDOW	*win;{	register int inp;	register int i, j;	char c;	int arg;	bool	weset = FALSE;	FILE *inf;	if (SP->fl_echoit && !win->_scroll && (win->_flags&_FULLWIN)	    && win->_curx == win->_maxx && win->_cury == win->_maxy)		return ERR;# ifdef DEBUG	if(outf) fprintf(outf, "WGETCH: SP->fl_echoit = %c, SP->fl_rawmode = %c\n", SP->fl_echoit ? 'T' : 'F', SP->fl_rawmode ? 'T' : 'F');	if (outf) fprintf(outf, "_use_keypad %d, kp_state %d\n", win->_use_keypad, SP->kp_state);# endif	if (SP->fl_echoit && !SP->fl_rawmode) {		cbreak();		weset++;	}#ifdef KEYPAD	/* Make sure keypad on is in proper state */	if (win->_use_keypad != SP->kp_state) {		_kpmode(win->_use_keypad);		fflush(stdout);	}#endif	/* Make sure we are in proper nodelay state */	if (win->_nodelay != SP->fl_nodelay)		_fixdelay(SP->fl_nodelay, win->_nodelay);	/* Check for pushed typeahead.  We make the assumption that	 * if a function key is being typed, there is no pushed	 * typeahead from the previous key waiting.	 */	if (SP->input_queue[0] >= 0) {		inp = SP->input_queue[0];		for (i=0; i<16; i++) {			SP->input_queue[i] = SP->input_queue[i+1];			if (SP->input_queue[i] < 0)				break;		}		goto gotit;	}	inf = SP->input_file;	if (inf == stdout)	/* so output can be teed somewhere */		inf = stdin;#ifdef FIONREAD	if (win->_nodelay) {		ioctl(fileno(inf), FIONREAD, &arg);#ifdef DEBUG		if (outf) fprintf(outf, "FIONREAD returns %d\n", arg);#endif		if (arg < 1)			return -1;	}#endif	for (i = -1; i<0; ) {		extern int errno;		sig_caught = 0;		i = read(fileno(inf), &c, 1);		/*		 * I hope the system won't retern infinite EINTRS - maybe		 * there should be a hop count here.		 */		if (i < 0 && errno != EINTR && !sig_caught) {			inp = ERR;			goto gotit;		}	}	if (i > 0) {		inp = c;		if (!win->_use_meta)			inp &= A_CHARTEXT;		else			inp &= 0377;	} else {		inp = ERR;		goto gotit;	}# ifdef DEBUG	if(outf) fprintf(outf,"WGETCH got '%s'\n",unctrl(inp));# endif#ifdef KEYPAD	/* Check for arrow and function keys */	if (win->_use_keypad) {		SP->input_queue[0] = inp;		SP->input_queue[1] = -1;		for (i=0; SP->kp[i].keynum >= 0; i++) {			if (SP->kp[i].sends[0] == inp) {				for (j=0; ; j++) {					if (SP->kp[i].sends[j] <= 0)						break;	/* found */					if (SP->input_queue[j] == -1) {						SP->input_queue[j] = _fpk(inf);						SP->input_queue[j+1] = -1;					}					if (SP->kp[i].sends[j] != SP->input_queue[j])						goto contouter; /* not this one */				}				/* It matched the function key. */				inp = SP->kp[i].keynum;				SP->input_queue[0] = -1;				goto gotit;			}		contouter:;		}		/* Didn't match any function keys. */		inp = SP->input_queue[0];		for (i=0; i<16; i++) {			SP->input_queue[i] = SP->input_queue[i+1];			if (SP->input_queue[i] < 0)				break;		}		goto gotit;	}#endif	if (SP->fl_echoit) {		waddch(win, (chtype) inp);		wrefresh(win);	}gotit:	if (weset)		nocbreak();#ifdef DEBUG	if(outf) fprintf(outf, "getch returns %o, pushed %o %o %o\n",		inp, SP->input_queue[0], SP->input_queue[1], SP->input_queue[2]);#endif	return inp;}_catch_alarm(){	sig_caught = 1;}/* * Fast peek key.  Like getchar but if the right flags are set, times out * quickly if there is nothing waiting, returning -1. * f is an output stdio descriptor, we read from the fileno.  win is the * window this is supposed to have something to do with. */#ifndef FIONREAD/* * Traditional implementation.  The best resolution we have is 1 second, * so we set a 1 second alarm and try to read.  If we fail for 1 second, * we assume there is no key waiting.  Problem here is that 1 second is * too long, people can type faster than this. */static_fpk(f)FILE *f;{	char c;	int rc;	int (*oldsig)();	int oldalarm;	oldsig = signal(SIGALRM, _catch_alarm);	oldalarm = alarm(1);	sig_caught = 0;	rc = read(fileno(f), &c, 1);	if (sig_caught) {		sig_caught = 0;		alarm(oldalarm);		return -2;	}	signal(SIGALRM, oldsig);	alarm(oldalarm);	return rc == 1 ? c : -1;}#else FIONREAD/* * If we have the select system call, we can do much better. * We wait for long enough for a terminal to send another character * (at 15cps repeat rate, this is 67 ms, I'm using 100ms to allow * a bit of a fudge factor) and time out more quickly.  Even if we * don't have the real 4.2BSD select, we can emulate it with napms * and FIONREAD.  napms might be done with only 1 second resolution, * but this is no worse than what we have above. *  * The AT&T code had the last param to the select as 100, this * should was fixed to have a timeval structure. */static_fpk(f)FILE *f;{	int rc;	fd_set infd;	fd_set *outfd, *exfd;	char c;	struct timeval timeout;	timeout.tv_sec = 0L;        timeout.tv_usec = 100*1000L;	FD_ZERO(&infd);	FD_SET(fileno(f), &infd);	outfd = exfd = (fd_set *) NULL;	rc = select(_curses_dtablesize(), &infd, outfd, exfd, &timeout);	if (rc < 0)		return -2;	rc = read(fileno(f), &c, 1);	return rc == 1 ? c : -1;}_curses_dtablesize(){        static int dt_size;        if (dt_size == 0) {                dt_size = getdtablesize();        }        return (dt_size);}#endif FIONREAD

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -