Annotation of coherent/d/usr/bin/elvis/curses.c, revision 1.1.1.1

1.1       root        1: /* curses.c */
                      2: 
                      3: /* Author:
                      4:  *     Steve Kirkendall
                      5:  *     16820 SW Tallac Way
                      6:  *     Beaverton, OR 97006
                      7:  *     [email protected], or ...uunet!tektronix!psueea!jove!kirkenda
                      8:  */
                      9: 
                     10: 
                     11: /* This file contains the functions & variables needed for a tiny subset of
                     12:  * curses.  The principle advantage of this version of curses is its
                     13:  * extreme speed.  Disadvantages are potentially larger code, few supported
                     14:  * functions, limited compatibility with full curses, and only stdscr.
                     15:  */
                     16: 
                     17: #include "config.h"
                     18: #include "vi.h"
                     19: 
                     20: #if ANY_UNIX
                     21: # if UNIXV
                     22: #  include     <termio.h>
                     23: #  undef       TIOCWINSZ       /* we can't handle it correctly yet */
                     24: # else
                     25: #  include     <sgtty.h>
                     26: # endif
                     27: #endif
                     28: 
                     29: #if TOS
                     30: # include      <osbind.h>
                     31: #endif
                     32: 
                     33: #if OSK
                     34: # include      <sgstat.h>
                     35: #endif
                     36: 
                     37: #include <signal.h>
                     38: 
                     39: extern char    *getenv();
                     40: static void     starttcap();
                     41: 
                     42: /* variables, publicly available & used in the macros */
                     43: short  ospeed;         /* speed of the tty, eg B2400 */
                     44: #if OSK
                     45: char   PC_;    /* Pad char */
                     46: char   *BC;    /* backspace character string */
                     47: #else
                     48: char   PC;             /* Pad char */
                     49: #endif
                     50: WINDOW *stdscr;        /* pointer into kbuf[] */
                     51: WINDOW kbuf[KBSIZ];    /* a very large output buffer */
                     52: int    LINES;          /* :li#: number of rows */
                     53: int    COLS;           /* :co#: number of columns */
                     54: int    AM;             /* :am:  boolean: auto margins? */
                     55: int    PT;             /* :pt:  boolean: physical tabs? */
                     56: char   *VB;            /* :vb=: visible bell */
                     57: char   *UP;            /* :up=: move cursor up */
                     58: char   *SO;            /* :so=: standout start */
                     59: char   *SE;            /* :se=: standout end */
                     60: char   *US = "";       /* :us=: underline start */
                     61: char   *UE = "";       /* :ue=: underline end */
                     62: char   *MD = "";       /* :md=: bold start */
                     63: char   *ME = "";       /* :me=: bold end */
                     64: char   *AS;            /* :as=: alternate (italic) start */
                     65: char   *AE;            /* :ae=: alternate (italic) end */
                     66: char   *CM;            /* :cm=: cursor movement */
                     67: char   *CE;            /* :ce=: clear to end of line */
                     68: char   *CD;            /* :cd=: clear to end of screen */
                     69: char   *AL;            /* :al=: add a line */
                     70: char   *DL;            /* :dl=: delete a line */
                     71: #if OSK
                     72: char   *SR_;           /* :sr=: scroll reverse */
                     73: #else
                     74: char   *SR;            /* :sr=: scroll reverse */
                     75: #endif
                     76: char   *KS;            /* :ks=: init string for cursor */
                     77: char   *KE;            /* :ke=: restore string for cursor */
                     78: char   *KU;            /* :ku=: key sequence sent by up arrow */
                     79: char   *KD;            /* :kd=: key sequence sent by down arrow */
                     80: char   *KL;            /* :kl=: key sequence sent by left arrow */
                     81: char   *KR;            /* :kr=: key sequence sent by right arrow */
                     82: char   *HM;            /* :HM=: key sequence sent by the <Home> key */
                     83: char   *EN;            /* :EN=: key sequence sent by the <End> key */
                     84: char   *PU;            /* :PU=: key sequence sent by the <PgUp> key */
                     85: char   *PD;            /* :PD=: key sequence sent by the <PgDn> key */
                     86: char   *IM;            /* :im=: insert mode start */
                     87: char   *IC = "";       /* :ic=: insert the following character */
                     88: char   *EI;            /* :ei=: insert mode end */
                     89: char   *DC;            /* :dc=: delete a character */
                     90: char   *TI;            /* :ti=: terminal init */       /* GB */
                     91: char   *TE;            /* :te=: terminal exit */       /* GB */
                     92: #ifndef NO_CURSORSHAPE
                     93: char   *CQ = (char *)0;/* :cQ=: normal cursor */
                     94: char   *CX = (char *)1;/* :cX=: cursor used for EX command/entry */
                     95: char   *CV = (char *)2;/* :cV=: cursor used for VI command mode */
                     96: char   *CI = (char *)3;/* :cI=: cursor used for VI input mode */
                     97: char   *CR = (char *)4;/* :cR=: cursor used for VI replace mode */
                     98: #endif
                     99: char   *aend = "";     /* end an attribute -- either UE or ME */
                    100: char   ERASEKEY;       /* backspace key taken from ioctl structure */
                    101: 
                    102: #if ANY_UNIX
                    103: # if UNIXV
                    104: static struct termio   oldtermio;      /* original tty mode */
                    105: static struct termio   newtermio;      /* cbreak/noecho tty mode */
                    106: # else
                    107: static struct sgttyb   oldsgttyb;      /* original tty mode */
                    108: static struct sgttyb   newsgttyb;      /* cbreak/nl/noecho tty mode */
                    109: static int             oldint;         /* ^C or DEL, the "intr" character */
                    110: #  ifdef TIOCSLTC
                    111: static int             oldswitch;      /* ^Z, the "suspend" character */
                    112: static int             oldquote;       /* ^V, the "quote next char" char */
                    113: #  endif
                    114: # endif
                    115: #endif
                    116: 
                    117: #if OSK
                    118: static struct sgbuf    oldsgttyb;      /* orginal tty mode */
                    119: static struct sgbuf    newsgttyb;      /* noecho tty mode */
                    120: #endif
                    121: 
                    122: static char    *capbuf;        /* capability string buffer */
                    123: 
                    124: 
                    125: void initscr()
                    126: {
                    127:        /* make sure TERM variable is set */
                    128: #if MSDOS
                    129:        char *val;
                    130:        if (! (val = getenv("TERM"))
                    131:        || !strcmp(val, "pcbios"))
                    132: #else
                    133:        if (!getenv("TERM"))
                    134: #endif
                    135:        {
                    136: #if ANY_UNIX
                    137:                write(2, "Environment variable TERM must be set\n", (unsigned)38);
                    138:                exit(1);
                    139: #endif
                    140: #if OSK
                    141:                writeln(2, "Environment variable TERM must be set\n", (unsigned)38);
                    142:                exit(1);
                    143: #endif
                    144: #if MSDOS || TOS
                    145:                getsize(0);
                    146: #endif
                    147:        }
                    148:        else
                    149:        {
                    150: #if MSDOS
                    151:                *o_pcbios=0;
                    152: #endif
                    153:                /* start termcap stuff */
                    154:                starttcap();
                    155:        }
                    156: 
                    157:        /* create stdscr and curscr */
                    158:        stdscr = kbuf;
                    159: 
                    160:        /* change the terminal mode to cbreak/noecho */
                    161: #if ANY_UNIX
                    162: # if UNIXV
                    163:        ioctl(2, TCGETA, &oldtermio);
                    164: # else
                    165:        ioctl(2, TIOCGETP, &oldsgttyb);
                    166: # endif
                    167: #endif
                    168: 
                    169: #if OSK
                    170:        _gs_opt(0, &oldsgttyb);
                    171: #endif
                    172:        resume_curses(TRUE);
                    173: }
                    174: 
                    175: 
                    176: void endwin()
                    177: {
                    178:        /* change the terminal mode back the way it was */
                    179:        suspend_curses();
                    180: }
                    181: 
                    182: 
                    183: static int curses_active = FALSE;
                    184: 
                    185: void suspend_curses()
                    186: {
                    187: #if ANY_UNIX && !UNIXV
                    188:        struct tchars   tbuf;
                    189: # ifdef TIOCSLTC
                    190:        struct ltchars  ltbuf;
                    191: # endif
                    192: #endif
                    193: #ifndef NO_CURSORSHAPE
                    194:        if (has_CQ)
                    195:        {
                    196:                do_CQ();
                    197:        }
                    198: #endif
                    199:        if (has_TE)                                     /* GB */
                    200:        {
                    201:                do_TE();
                    202:        }
                    203:        if (has_KE)
                    204:        {
                    205:                do_KE();
                    206:        }
                    207:        refresh();
                    208: 
                    209:        /* change the terminal mode back the way it was */
                    210: #if ANY_UNIX
                    211: # if UNIXV
                    212:        ioctl(2, TCSETAW, &oldtermio);
                    213: # else
                    214:        ioctl(2, TIOCSETP, &oldsgttyb);
                    215: 
                    216:        ioctl(2, TIOCGETC, &tbuf);
                    217:        tbuf.t_intrc = oldint;
                    218:        ioctl(2, TIOCSETC, &tbuf);
                    219: 
                    220: #  ifdef TIOCSLTC
                    221:        ioctl(2, TIOCGLTC, &ltbuf);
                    222:        ltbuf.t_suspc = oldswitch;
                    223:        ltbuf.t_lnextc = oldquote;
                    224:        ioctl(2, TIOCSLTC, &ltbuf);
                    225: #  endif
                    226: # endif
                    227: #endif
                    228: #if OSK
                    229:        _ss_opt(0, &oldsgttyb);
                    230: #endif
                    231:        curses_active = FALSE;
                    232: }
                    233: 
                    234: void resume_curses(quietly)
                    235:        int     quietly;
                    236: {
                    237:        if (!curses_active)
                    238:        {
                    239:                /* change the terminal mode to cbreak/noecho */
                    240: #if ANY_UNIX
                    241: # if UNIXV
                    242:                ospeed = (oldtermio.c_cflag & CBAUD);
                    243:                ERASEKEY = oldtermio.c_cc[VERASE];
                    244:                newtermio = oldtermio;
                    245:                newtermio.c_iflag &= (IXON|IXOFF|IXANY|ISTRIP|IGNBRK);
                    246:                newtermio.c_oflag &= ~OPOST;
                    247:                newtermio.c_lflag &= ISIG;
                    248:                newtermio.c_cc[VINTR] = ctrl('C'); /* always use ^C for interrupts */
                    249:                newtermio.c_cc[VMIN] = 1;
                    250:                newtermio.c_cc[VTIME] = 0;
                    251: #  ifdef VSWTCH
                    252:                newtermio.c_cc[VSWTCH] = 0;
                    253: #  endif
                    254:                ioctl(2, TCSETAW, &newtermio);
                    255: # else /* BSD or V7 or Coherent or Minix */
                    256:                struct tchars   tbuf;
                    257: #  ifdef TIOCSLTC
                    258:                struct ltchars  ltbuf;
                    259: #  endif
                    260: 
                    261:                ospeed = oldsgttyb.sg_ospeed;
                    262:                ERASEKEY = oldsgttyb.sg_erase;
                    263:                newsgttyb = oldsgttyb;
                    264:                newsgttyb.sg_flags |= CBREAK;
                    265:                newsgttyb.sg_flags &= ~(CRMOD|ECHO|XTABS);
                    266:                ioctl(2, TIOCSETP, &newsgttyb);
                    267: 
                    268:                ioctl(2, TIOCGETC, &tbuf);
                    269:                oldint = tbuf.t_intrc;
                    270:                tbuf.t_intrc = ctrl('C');       /* always use ^C for interrupts */
                    271:                ioctl(2, TIOCSETC, &tbuf);
                    272: 
                    273: #  ifdef TIOCSLTC
                    274:                ioctl(2, TIOCGLTC, &ltbuf);
                    275:                oldswitch = ltbuf.t_suspc;
                    276:                ltbuf.t_suspc = 0;              /* disable ^Z for elvis */
                    277:                oldquote = ltbuf.t_lnextc;
                    278:                ltbuf.t_lnextc = 0;             /* disable ^V for elvis */
                    279:                ioctl(2, TIOCSLTC, &ltbuf);
                    280: #  endif
                    281: 
                    282: # endif
                    283: #endif
                    284: #if OSK
                    285:                newsgttyb = oldsgttyb;
                    286:                newsgttyb.sg_echo = 0;
                    287:                newsgttyb.sg_eofch = 0;
                    288:                newsgttyb.sg_kbach = 0;
                    289:                newsgttyb.sg_kbich = ctrl('C');
                    290:                _ss_opt(0, &newsgttyb);
                    291:                ospeed = oldsgttyb.sg_baud;
                    292:                ERASEKEY = oldsgttyb.sg_bspch;
                    293: #endif
                    294: 
                    295:                if (has_TI)                                     /* GB */
                    296:                {
                    297:                        do_TI();
                    298:                }
                    299:                if (has_KS)
                    300:                {
                    301:                        do_KS();
                    302:                }
                    303: 
                    304:                curses_active = TRUE;
                    305:        }
                    306: 
                    307:        /* If we're supposed to quit quietly, then we're done */
                    308:        if (quietly)
                    309:        {
                    310:                return;
                    311:        }
                    312: 
                    313:        signal(SIGINT, SIG_IGN);
                    314: 
                    315:        move(LINES - 1, 0);
                    316:        do_SO();
                    317:        qaddstr("[Press <RETURN> to continue]");
                    318:        do_SE();
                    319:        refresh();
                    320:        ttyread(kbuf, 20); /* in RAW mode, so <20 is very likely */
                    321:        if (kbuf[0] == ':')
                    322:        {
                    323:                mode = MODE_COLON;
                    324:                addch('\n');
                    325:                refresh();
                    326:        }
                    327:        else
                    328:        {
                    329:                mode = MODE_VI;
                    330:                redraw(MARK_UNSET, FALSE);
                    331:        }       
                    332:        exwrote = FALSE;
                    333: 
                    334: #if TURBOC
                    335:        signal(SIGINT, (void(*)()) trapint);
                    336: #else
                    337:        signal(SIGINT, trapint);
                    338: #endif
                    339: }
                    340: 
                    341: static void lacking(s)
                    342:        char    *s;
                    343: {
                    344:        write(2, "This termcap entry lacks the :", (unsigned)30);
                    345:        write(2, s, (unsigned)2);
                    346:        write(2, "=: capability\n", (unsigned)14);
                    347: #if OSK
                    348:        write(2, "\l", 1);
                    349: #endif
                    350:        exit(1);
                    351: }
                    352: 
                    353: static void starttcap()
                    354: {
                    355:        char    *str;
                    356:        static char     cbmem[800];
                    357: #define MUSTHAVE(T,s)  if (!(T = tgetstr(s, &capbuf))) lacking(s)
                    358: #define MAYHAVE(T,s)   if (str = tgetstr(s, &capbuf)) T = str
                    359: #define PAIR(T,U,sT,sU)        T=tgetstr(sT,&capbuf);U=tgetstr(sU,&capbuf);if (!T||!U)T=U=""
                    360: 
                    361:        /* allocate memory for capbuf */
                    362:        capbuf = cbmem;
                    363: 
                    364:        /* get the termcap entry */
                    365:        switch (tgetent(kbuf, getenv("TERM")))
                    366:        {
                    367:          case -1:
                    368:                write(2, "Can't read /etc/termcap\n", (unsigned)24);
                    369: #if OSK
                    370:                write(2, "\l", 1);
                    371: #endif
                    372:                exit(2);
                    373: 
                    374:          case 0:
                    375:                write(2, "Unrecognized TERM type\n", (unsigned)23);
                    376: #if OSK
                    377:                write(2, "\l", 1);
                    378: #endif
                    379:                exit(3);
                    380:        }
                    381: 
                    382:        /* get strings */
                    383:        MUSTHAVE(UP, "up");
                    384:        MAYHAVE(VB, "vb");
                    385:        MUSTHAVE(CM, "cm");
                    386:        PAIR(SO, SE, "so", "se");
                    387:        PAIR(TI, TE, "ti", "te");
                    388:        if (tgetnum("ug") <= 0)
                    389:        {
                    390:                PAIR(US, UE, "us", "ue");
                    391:                PAIR(MD, ME, "md", "me");
                    392: 
                    393:                /* get italics, or have it default to underline */
                    394:                PAIR(AS, AE, "as", "ae");
                    395:                if (!*AS)
                    396:                {
                    397:                        AS = US;
                    398:                        AE = UE;
                    399:                }
                    400:        }
                    401:        MAYHAVE(AL, "al");
                    402:        MAYHAVE(DL, "dl");
                    403:        MUSTHAVE(CE, "ce");
                    404:        MAYHAVE(CD, "cd");
                    405: #if OSK
                    406:        MAYHAVE(SR_, "sr");
                    407: #else  
                    408:        MAYHAVE(SR, "sr");
                    409: #endif
                    410:        PAIR(IM, EI, "im", "ei");
                    411:        MAYHAVE(IC, "ic");
                    412:        MAYHAVE(DC, "dc");
                    413: 
                    414:        /* other termcap stuff */
                    415:        AM = tgetflag("am");
                    416:        PT = tgetflag("pt");
                    417:        getsize(0);
                    418: 
                    419:        /* Key sequences */
                    420:        PAIR(KS, KE, "ks", "ke");
                    421:        MAYHAVE(KU, "ku");              /* up */
                    422:        MAYHAVE(KD, "kd");              /* down */
                    423:        MAYHAVE(KL, "kl");              /* left */
                    424:        MAYHAVE(KR, "kr");              /* right */
                    425:        MAYHAVE(PU, "kP");              /* PgUp */
                    426:        MAYHAVE(PD, "kN");              /* PgDn */
                    427:        MAYHAVE(HM, "kh");              /* Home */
                    428:        MAYHAVE(EN, "kH");              /* End */
                    429: #ifndef CRUNCH
                    430:        if (!PU) MAYHAVE(PU, "K2");     /* "3x3 pad" names for PgUp, etc. */
                    431:        if (!PD) MAYHAVE(PD, "K5");
                    432:        if (!HM) MAYHAVE(HM, "K1");
                    433:        if (!EN) MAYHAVE(EN, "K4");
                    434: 
                    435:        MAYHAVE(PU, "PU");              /* old XENIX names for PgUp, etc. */
                    436:        MAYHAVE(PD, "PD");              /* (overrides others, if used.) */
                    437:        MAYHAVE(HM, "HM");
                    438:        MAYHAVE(EN, "EN");
                    439: #endif
                    440: 
                    441: #ifndef NO_CURSORSHAPE
                    442:        /* cursor shapes */
                    443:        CQ = tgetstr("cQ", &capbuf);
                    444:        if (has_CQ)
                    445:        {
                    446:                CX = tgetstr("cX", &capbuf);
                    447:                if (!CX) CX = CQ;
                    448:                CV = tgetstr("cV", &capbuf);
                    449:                if (!CV) CV = CQ;
                    450:                CI = tgetstr("cI", &capbuf);
                    451:                if (!CI) CI = CQ;
                    452:                CR = tgetstr("cR", &capbuf);
                    453:                if (!CR) CR = CQ;
                    454:        }
                    455: # ifndef CRUNCH
                    456:        else
                    457:        {
                    458:                PAIR(CQ, CV, "ve", "vs");
                    459:                CX = CI = CR = CQ;
                    460:        }
                    461: # endif /* !CRUNCH */
                    462: #endif /* !NO_CURSORSHAPE */
                    463: 
                    464: #undef MUSTHAVE
                    465: #undef MAYHAVE
                    466: #undef PAIR
                    467: }
                    468: 
                    469: 
                    470: /* This function gets the window size.  It uses the TIOCGWINSZ ioctl call if
                    471:  * your system has it, or tgetnum("li") and tgetnum("co") if it doesn't.
                    472:  * This function is called once during initialization, and thereafter it is
                    473:  * called whenever the SIGWINCH signal is sent to this process.
                    474:  */
                    475: int getsize(signo)
                    476:        int     signo;
                    477: {
                    478:        int     lines;
                    479:        int     cols;
                    480: #ifdef TIOCGWINSZ
                    481:        struct winsize size;
                    482: #endif
                    483: 
                    484: #ifdef SIGWINCH
                    485:        /* reset the signal vector */
                    486:        signal(SIGWINCH, getsize);
                    487: #endif
                    488: 
                    489:        /* get the window size, one way or another. */
                    490:        lines = cols = 0;
                    491: #ifdef TIOCGWINSZ
                    492:        if (ioctl(2, TIOCGWINSZ, &size) >= 0)
                    493:        {
                    494:                lines = size.ws_row;
                    495:                cols = size.ws_col;
                    496:        }
                    497: #endif
                    498:        if ((lines == 0 || cols == 0) && signo == 0)
                    499:        {
                    500:                LINES = CHECKBIOS(v_rows(), tgetnum("li"));
                    501:                COLS = CHECKBIOS(v_cols(), tgetnum("co"));
                    502:        }
                    503:        if (lines >= 2 && cols >= 30)
                    504:        {
                    505:                LINES = lines;
                    506:                COLS = cols;
                    507:        }
                    508: 
                    509:        /* Make sure we got values that we can live with */
                    510:        if (LINES < 2 || COLS < 30)
                    511:        {
                    512:                write(2, "Screen too small\n", (unsigned)17);
                    513: #if OSK
                    514:                write(2, "\l", 1);
                    515: #endif
                    516:                endwin();
                    517:                exit(2);
                    518:        }
                    519: 
                    520:        /* !!! copy the new values into Elvis' options */
                    521:        {
                    522:                extern char     o_columns[], o_lines[];
                    523: 
                    524:                *o_columns = COLS;
                    525:                *o_lines = LINES;
                    526:        }
                    527: 
                    528:        return 0;
                    529: }
                    530: 
                    531: 
                    532: /* This is a function version of addch() -- it is used by tputs() */
                    533: int faddch(ch)
                    534:        int     ch;
                    535: {
                    536:        addch(ch);
                    537: 
                    538:        return 0;
                    539: }
                    540: 
                    541: /* These functions are equivelent to the macros of the same names... */
                    542: 
                    543: void qaddstr(str)
                    544:        char    *str;
                    545: {
                    546:        REG char *s_, *d_;
                    547: 
                    548: #if MSDOS
                    549:        if (o_pcbios[0])
                    550:        {
                    551:                while (*str)
                    552:                        qaddch(*str++);
                    553:                return;
                    554:        }
                    555: #endif
                    556:        for (s_=(str), d_=stdscr; *d_++ = *s_++; )
                    557:        {
                    558:        }
                    559:        stdscr = d_ - 1;
                    560: }
                    561: 
                    562: void attrset(a)
                    563:        int     a;
                    564: {
                    565:        do_aend();
                    566:        if (a == A_BOLD)
                    567:        {
                    568:                do_MD();
                    569:                aend = ME;
                    570:        }
                    571:        else if (a == A_UNDERLINE)
                    572:        {
                    573:                do_US();
                    574:                aend = UE;
                    575:        }
                    576:        else if (a == A_ALTCHARSET)
                    577:        {
                    578:                do_AS();
                    579:                aend = AE;
                    580:        }
                    581:        else
                    582:        {
                    583:                aend = "";
                    584:        }
                    585: }
                    586: 
                    587: 
                    588: void insch(ch)
                    589:        int     ch;
                    590: {
                    591:        if (has_IM)
                    592:                do_IM();
                    593:        do_IC();
                    594:        qaddch(ch);
                    595:        if (has_EI)
                    596:                do_EI();
                    597: }
                    598: 
                    599: #if MSDOS
                    600: 
                    601: static int alarmtime;
                    602: 
                    603: /* raw read - #defined to read (0, ...) on non-MSDOS.
                    604:  * With MSDOS, am maximum of 1 byte is read.
                    605:  * If more bytes should be read, just change the loop.
                    606:  * The following code uses the IBM-PC-System-Timer, so probably wont't work
                    607:  * on non-compatibles.
                    608:  */
                    609: /*ARGSUSED*/
                    610: ttyread(buf, len)
                    611:        char *buf;
                    612:        int len;
                    613: {
                    614:        volatile char far *biostimer;
                    615:        char oldtime;
                    616:        int nticks = 0;
                    617:        int pos = 0;
                    618: 
                    619:        biostimer = (char far *)0x0040006cl;
                    620:        oldtime = *biostimer;
                    621: 
                    622:        while (!pos && (!alarmtime || nticks<alarmtime))
                    623:        {       if (kbhit())
                    624:                        if ((buf[pos++] = getch()) == 0) /* function key */
                    625:                                buf[pos-1] = '#';
                    626:                if (oldtime != *biostimer)
                    627:                {       nticks++;
                    628:                        oldtime = *biostimer;
                    629:                }
                    630:        }
                    631:        return pos;
                    632: }
                    633: 
                    634: alarm(time)
                    635:        int time;
                    636: {
                    637:        alarmtime = 2 * time;           /* ticks are 1/18 sec. */
                    638: }
                    639: #endif
                    640: 
                    641: #if TOS
                    642: 
                    643: static int alarmtime;
                    644: static long timer;
                    645: 
                    646: static gettime()
                    647: {
                    648:        timer = *(long *)(0x4ba);
                    649: }
                    650: 
                    651: /*ARGSUSED*/
                    652: ttyread(buf, len)
                    653:        char *buf;
                    654:        int len;
                    655: {
                    656:        int     pos=0;
                    657:        long    l;
                    658:        long    endtime;
                    659: 
                    660:        Supexec(gettime);
                    661:        endtime = timer+alarmtime;
                    662: 
                    663:        while (!pos && (!alarmtime || timer<endtime))
                    664:        {
                    665:                if (Bconstat(2))
                    666:                {
                    667:                        l = Bconin(2);
                    668:                        if ((buf[pos++]=l) == '\0')
                    669:                        {
                    670:                                buf[pos-1]='#';
                    671:                                buf[pos++]=l>>16;
                    672:                        }
                    673:                }
                    674:                Supexec(gettime);
                    675:        }
                    676:        return pos;
                    677: }
                    678: 
                    679: alarm(time)
                    680:        int time;
                    681: {
                    682:        alarmtime = 50 * time;          /* ticks are 1/200 sec. */
                    683: }
                    684: 
                    685: ttywrite(buf, len)
                    686:        char *buf;
                    687:        int len;
                    688: {
                    689:        while (len--)
                    690:                Bconout(2, *buf++);
                    691: }
                    692: #endif
                    693: 
                    694: #if OSK
                    695: ttyread(buf, len)
                    696:        char *buf;
                    697:        int len;
                    698: {
                    699:        REG int i;
                    700:        if ((i = _gs_rdy(0)) > 0)
                    701:                return read(0, buf, i < len ? i : len);
                    702:        else
                    703:                return read(0, buf, 1);
                    704: }
                    705: 
                    706: alarm(time)
                    707:        int time;
                    708: {
                    709: #define TIME(secs) ((secs << 8) | 0x80000000)
                    710:        static int alrmid;
                    711: 
                    712:        if (time)       
                    713:                alrmid = alm_set(SIGQUIT, TIME(time));
                    714:        else    
                    715:                alm_delete(alrmid);
                    716: }
                    717: #endif /* OSK */

unix.superglobalmegacorp.com

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