Annotation of coherent/d/usr/bin/elvis/curses.c, revision 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.