Annotation of coherent/g/usr/lib/ncurses/lib_getch.c, revision 1.1.1.1

1.1       root        1: /*********************************************************************
                      2: *                         COPYRIGHT NOTICE                           *
                      3: **********************************************************************
                      4: *        This software is copyright (C) 1982 by Pavel Curtis         *
                      5: *                                                                    *
                      6: *        Permission is granted to reproduce and distribute           *
                      7: *        this file by any means so long as no fee is charged         *
                      8: *        above a nominal handling fee and so long as this            *
                      9: *        notice is always included in the copies.                    *
                     10: *                                                                    *
                     11: *        Other rights are reserved except as explicitly granted      *
                     12: *        by written permission of the author.                        *
                     13: *                Pavel Curtis                                        *
                     14: *                Computer Science Dept.                              *
                     15: *                405 Upson Hall                                      *
                     16: *                Cornell University                                  *
                     17: *                Ithaca, NY 14853                                    *
                     18: *                                                                    *
                     19: *                Ph- (607) 256-4934                                  *
                     20: *                                                                    *
                     21: *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
                     22: *                decvax!cornell!pavel       (UUCPnet)                *
                     23: *********************************************************************/
                     24: 
                     25: /*
                     26: **     lib_getch.c
                     27: **
                     28: **     The routine getch().
                     29: **
                     30: ** $Log:       lib_getch.c,v $
                     31:  * Revision 1.9  93/04/12  14:13:39  bin
                     32:  * Udo: third color update
                     33:  * 
                     34:  * Revision 2.3  92/11/21  14:47:37  munk
                     35:  * Improved alarm signal handling
                     36:  *
                     37:  * Revision 1.3  92/06/10  14:17:06  bin
                     38:  * changed ref to sys/fcntl.h
                     39:  * 
                     40:  * Revision 1.2  92/04/13  14:37:30  bin
                     41:  * update by vlad
                     42:  * 
                     43:  * Revision 2.2  91/02/09  13:37:40  munk   
                     44:  * Conditional code added for systems that don't support ioctl with
                     45:  * the command FIONREAD (use fcntl O_NDELAY).
                     46:  * Bug fixed in kgetch(), do not put EOF in buffer.
                     47:  * Save the old alarm-timer and restart it, after use by kgetch().
                     48:  *
                     49:  * Revision 2.1  82/10/25  14:47:29  pavel
                     50:  * Added Copyright Notice
                     51:  * 
                     52:  * Revision 2.0  82/10/25  13:45:19  pavel
                     53:  * Beta-one Test Release
                     54:  * 
                     55: **
                     56: */
                     57: 
                     58: #ifdef RCSHDR
                     59: static char RCSid[] =
                     60:        "$Header: /src386/usr/lib/ncurses/RCS/lib_getch.c,v 1.9 93/04/12 14:13:39 bin Exp Locker: bin $";
                     61: #endif
                     62: 
                     63: #include <signal.h>
                     64: #ifdef COHERENT
                     65: #include <fcntl.h>
                     66: #else
                     67: #include <fcntl.h>
                     68: #endif
                     69: #include "curses.h"
                     70: #include "curses.priv.h"
                     71: 
                     72: #define nextc()       (SP->_backcnt > 0  ?  SP->_backbuf[--SP->_backcnt] \
                     73:                                          :  getc(SP->_ifp))
                     74:                                       
                     75: #define putback(ch)   SP->_backbuf[SP->_backcnt++] = ch
                     76: 
                     77: 
                     78: wgetch(win)
                     79: register WINDOW        *win;
                     80: {
                     81:        bool            setHere = FALSE; /* cbreak mode was set here         */
                     82:        register int    ch;              /* 'int' because of keypad codes  */
                     83: 
                     84: #ifdef TRACE
                     85:        if (_tracing)
                     86:            _tracef("wgetch(%o) called flags = 0%o", win, win->_flags);
                     87: #endif
                     88: 
                     89:        if (! win->_scroll  &&  (win->_flags & _FULLWIN)
                     90:                                                &&  win->_curx == win->_maxx
                     91:                                                &&  win->_cury == win->_maxy)
                     92:            return(ERR);
                     93: 
                     94: #ifdef FIONREAD
                     95:        if (win->_nodelay)
                     96:        {
                     97:            long count;
                     98: 
                     99:            ioctl(fileno(SP->_ifp), FIONREAD, &count);
                    100: 
                    101:            if (! count)
                    102:                return(-1);
                    103:        }
                    104: #else
                    105:        if (win->_nodelay)
                    106:        {
                    107:                int flags;
                    108: 
                    109:                flags = fcntl(fileno(SP->_ifp), F_GETFL, 0);
                    110:                fcntl(fileno(SP->_ifp), F_SETFL, flags | O_NDELAY);
                    111:                ch = fgetc(SP->_ifp);
                    112:                fcntl(fileno(SP->_ifp), F_SETFL, flags);
                    113:                if (ch == -1)
                    114:                        return(-1);
                    115:                ungetc(ch, SP->_ifp);
                    116:        }
                    117: #endif
                    118: 
                    119:        if (SP->_echo  &&  ! (SP->_raw  ||  SP->_cbreak))
                    120:        {
                    121:                cbreak();
                    122:                setHere = TRUE;
                    123:        }
                    124: 
                    125:         if (win->_use_keypad)
                    126:             ch = kgetch();
                    127:         else {
                    128:            while ((ch = nextc()) == EOF)       /* ignore interrupted */
                    129:                ;                               /* system call        */
                    130:        }
                    131: 
                    132:        if (SP->_echo  &&  ch < 0400 && ch >= 0)/* ch < 0400 => not a keypad key */
                    133:        {
                    134:            mvwaddch(curscr, win->_begy + win->_cury,
                    135:                              win->_begx + win->_curx, ch | win->_attrs);
                    136:            waddch(win, ch | win->_attrs);
                    137:        }
                    138: 
                    139:        if (setHere) {
                    140:            nocbreak();
                    141:         }
                    142: 
                    143:        return(ch);
                    144: }
                    145: 
                    146: 
                    147: /*
                    148: **      kgetch()
                    149: **
                    150: **      Get an input character, but take care of keypad sequences, returning
                    151: **      an appropriate code when one matches the input.  After each character
                    152: **      is received, set a one-second alarm call.  If no more of the sequence
                    153: **      is received by the time the alarm goes off, pass through the sequence
                    154: **      gotten so far.
                    155: **
                    156: */
                    157: 
                    158: static  bool    alarmed;
                    159: 
                    160: static
                    161: int
                    162: kgetch()
                    163: {
                    164:         struct try     *ptr;
                    165:        register int    ch;
                    166:        char            buffer[10]; /* Assume no sequences longer than 10 */
                    167:        register char   *bufp = buffer;
                    168:        int             (*oldsig)();
                    169:        int             oldalarm;
                    170:        int             sigalrm();
                    171: 
                    172:        ptr = SP->_keytry;
                    173:        
                    174:        oldalarm = alarm(0);
                    175:        oldsig = signal(SIGALRM, sigalrm);
                    176:        signal(SIGALRM, oldsig);
                    177:        alarm(oldalarm);
                    178:        alarmed = FALSE;
                    179:        
                    180:        do
                    181:        {
                    182:     readagain:
                    183:            ch = nextc();
                    184:            if (ch != EOF)              /* do not put EOF in buffer */
                    185:                *(bufp++) = ch;
                    186:            else if (alarmed)           /* handle interrupted system */
                    187:                break;                  /* call properly             */
                    188:            else
                    189:                goto readagain;
                    190:            
                    191:            while (ptr != NULL  &&  ptr->ch != ch)
                    192:                ptr = ptr->sibling;
                    193:            
                    194:            if (ptr != NULL)
                    195:            {
                    196:                if (ptr->value != 0)
                    197:                {
                    198:                    signal(SIGALRM, oldsig);
                    199:                    alarm(oldalarm);
                    200:                    return(ptr->value);
                    201:                }
                    202:                else
                    203:                {
                    204:                    ptr = ptr->child;
                    205:                    signal(SIGALRM, sigalrm);
                    206:                    alarm(1);
                    207:                }
                    208:            }
                    209:            
                    210:        } while (ptr != NULL);
                    211:        
                    212:        signal(SIGALRM, oldsig);
                    213:        alarm(oldalarm);
                    214:        
                    215:        while (--bufp > buffer)
                    216:            putback(*bufp);
                    217:            
                    218:        return(*bufp);
                    219: }
                    220: 
                    221: 
                    222: static
                    223: sigalrm()
                    224: {
                    225:         alarmed = TRUE;
                    226:        signal(SIGALRM, sigalrm);
                    227: }

unix.superglobalmegacorp.com

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