Annotation of coherent/g/usr/lib/ncurses/lib_getch.c, revision 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.