File:  [MW Coherent from dump] / coherent / g / usr / lib / ncurses / lib_getch.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:35 2019 UTC (7 years ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

/*
**	lib_getch.c
**
**	The routine getch().
**
** $Log: lib_getch.c,v $
** Revision 1.1.1.1  2019/05/29 04:56:35  root
** coherent
**
 * Revision 1.9  93/04/12  14:13:39  bin
 * Udo: third color update
 * 
 * Revision 2.3  92/11/21  14:47:37  munk
 * Improved alarm signal handling
 *
 * Revision 1.3  92/06/10  14:17:06  bin
 * changed ref to sys/fcntl.h
 * 
 * Revision 1.2  92/04/13  14:37:30  bin
 * update by vlad
 * 
 * Revision 2.2  91/02/09  13:37:40  munk   
 * Conditional code added for systems that don't support ioctl with
 * the command FIONREAD (use fcntl O_NDELAY).
 * Bug fixed in kgetch(), do not put EOF in buffer.
 * Save the old alarm-timer and restart it, after use by kgetch().
 *
 * Revision 2.1  82/10/25  14:47:29  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:45:19  pavel
 * Beta-one Test Release
 * 
**
*/

#ifdef RCSHDR
static char RCSid[] =
	"$Header: /var/lib/cvsd/repos/coherent/coherent/g/usr/lib/ncurses/lib_getch.c,v 1.1.1.1 2019/05/29 04:56:35 root Exp $";
#endif

#include <signal.h>
#ifdef COHERENT
#include <fcntl.h>
#else
#include <fcntl.h>
#endif
#include "curses.h"
#include "curses.priv.h"

#define nextc()       (SP->_backcnt > 0  ?  SP->_backbuf[--SP->_backcnt] \
                                         :  getc(SP->_ifp))
				       
#define putback(ch)   SP->_backbuf[SP->_backcnt++] = ch


wgetch(win)
register WINDOW	*win;
{
	bool		setHere = FALSE; /* cbreak mode was set here         */
	register int	ch;		 /* 'int' because of keypad codes  */

#ifdef TRACE
	if (_tracing)
	    _tracef("wgetch(%o) called flags = 0%o", win, win->_flags);
#endif

	if (! win->_scroll  &&  (win->_flags & _FULLWIN)
						&&  win->_curx == win->_maxx
						&&  win->_cury == win->_maxy)
	    return(ERR);

#ifdef FIONREAD
	if (win->_nodelay)
	{
	    long count;

	    ioctl(fileno(SP->_ifp), FIONREAD, &count);

	    if (! count)
		return(-1);
	}
#else
	if (win->_nodelay)
	{
		int flags;

		flags = fcntl(fileno(SP->_ifp), F_GETFL, 0);
		fcntl(fileno(SP->_ifp), F_SETFL, flags | O_NDELAY);
		ch = fgetc(SP->_ifp);
		fcntl(fileno(SP->_ifp), F_SETFL, flags);
		if (ch == -1)
			return(-1);
		ungetc(ch, SP->_ifp);
	}
#endif

	if (SP->_echo  &&  ! (SP->_raw  ||  SP->_cbreak))
	{
		cbreak();
		setHere = TRUE;
	}

        if (win->_use_keypad)
            ch = kgetch();
        else {
	    while ((ch = nextc()) == EOF)	/* ignore interrupted */
	    	;				/* system call        */
	}

	if (SP->_echo  &&  ch < 0400 && ch >= 0)/* ch < 0400 => not a keypad key */
	{
	    mvwaddch(curscr, win->_begy + win->_cury,
                             win->_begx + win->_curx, ch | win->_attrs);
	    waddch(win, ch | win->_attrs);
	}

	if (setHere) {
	    nocbreak();
	 }

	return(ch);
}


/*
**      kgetch()
**
**      Get an input character, but take care of keypad sequences, returning
**      an appropriate code when one matches the input.  After each character
**      is received, set a one-second alarm call.  If no more of the sequence
**      is received by the time the alarm goes off, pass through the sequence
**      gotten so far.
**
*/

static  bool    alarmed;

static
int
kgetch()
{
        struct try	*ptr;
	register int	ch;
	char		buffer[10]; /* Assume no sequences longer than 10 */
	register char	*bufp = buffer;
	int		(*oldsig)();
	int		oldalarm;
	int		sigalrm();

	ptr = SP->_keytry;
	
	oldalarm = alarm(0);
	oldsig = signal(SIGALRM, sigalrm);
	signal(SIGALRM, oldsig);
	alarm(oldalarm);
	alarmed = FALSE;
	
	do
	{
    readagain:
	    ch = nextc();
	    if (ch != EOF)		/* do not put EOF in buffer */
	        *(bufp++) = ch;
	    else if (alarmed)		/* handle interrupted system */
	        break;			/* call properly             */
	    else
	    	goto readagain;
	    
	    while (ptr != NULL  &&  ptr->ch != ch)
	        ptr = ptr->sibling;
	    
	    if (ptr != NULL)
	    {
	        if (ptr->value != 0)
		{
		    signal(SIGALRM, oldsig);
		    alarm(oldalarm);
		    return(ptr->value);
		}
		else
		{
		    ptr = ptr->child;
		    signal(SIGALRM, sigalrm);
		    alarm(1);
	        }
	    }
	    
	} while (ptr != NULL);
	
	signal(SIGALRM, oldsig);
	alarm(oldalarm);
	
	while (--bufp > buffer)
	    putback(*bufp);
	    
	return(*bufp);
}


static
sigalrm()
{
        alarmed = TRUE;
	signal(SIGALRM, sigalrm);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.