Annotation of coherent/g/usr/bin/me/termio.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * The functions in this file negotiate with the operating system
        !             3:  * for characters, and write characters in  a barely buffered fashion
        !             4:  * on the display.
        !             5:  * All operating systems.
        !             6:  */
        !             7: #include       <stdio.h>
        !             8: #include       "ed.h"
        !             9: 
        !            10: #if    IBM
        !            11: #define        lo(r)   ((r)&0xFF)      /* low-order byte of word register */
        !            12: #define        hi(r)   ((r)>>8)        /* high-order byte of word register */
        !            13: #endif
        !            14: 
        !            15: #if    VMS
        !            16: #include       <stsdef.h>
        !            17: #include       <ssdef.h>
        !            18: #include       <descrip.h>
        !            19: #include       <iodef.h>
        !            20: #include       <ttdef.h>
        !            21: 
        !            22: #define        NIBUF   128                     /* Input  buffer size           */
        !            23: #define        NOBUF   1024                    /* MM says bug buffers win!     */
        !            24: #define        EFN     0                       /* Event flag                   */
        !            25: 
        !            26: uchar  obuf[NOBUF];                    /* Output buffer                */
        !            27: int    nobuf;                          /* # of bytes in above          */
        !            28: uchar  ibuf[NIBUF];                    /* Input buffer                 */
        !            29: int    nibuf;                          /* # of bytes in above          */
        !            30: int    ibufi;                          /* Read index                   */
        !            31: int    oldmode[2];                     /* Old TTY mode bits            */
        !            32: int    newmode[2];                     /* New TTY mode bits            */
        !            33: short  iochan;                         /* TTY I/O channel              */
        !            34: #endif
        !            35: 
        !            36: #if    CPM
        !            37: #include       <bdos.h>
        !            38: #endif
        !            39: 
        !            40: #if    MSDOS
        !            41: #include       <dos.h>
        !            42: #endif
        !            43: 
        !            44: #if    GEM
        !            45: #include       <osbind.h>
        !            46: #endif
        !            47: 
        !            48: #if V7
        !            49: #include       <sgtty.h>               /* for stty/gtty functions */
        !            50: struct sgttyb  ostate;                 /* saved tty state */
        !            51: struct sgttyb  nstate;                 /* values for editor mode */
        !            52: #endif
        !            53: 
        !            54: /*
        !            55:  * This function is called once
        !            56:  * to set up the terminal device streams.
        !            57:  * On VMS, it translates SYS$INPUT until it
        !            58:  * finds the terminal, then assigns a channel to it
        !            59:  * and sets it raw. On CPM it is a no-op.
        !            60:  */
        !            61: ttopen()
        !            62: {
        !            63: #if    VMS
        !            64:        struct  dsc$descriptor  idsc;
        !            65:        struct  dsc$descriptor  odsc;
        !            66:        uchar   oname[40];
        !            67:        int     iosb[2];
        !            68:        int     status;
        !            69: 
        !            70:        odsc.dsc$a_pointer = "SYS$INPUT";
        !            71:        odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
        !            72:        odsc.dsc$b_dtype   = DSC$K_DTYPE_T;
        !            73:        odsc.dsc$b_class   = DSC$K_CLASS_S;
        !            74:        idsc.dsc$b_dtype   = DSC$K_DTYPE_T;
        !            75:        idsc.dsc$b_class   = DSC$K_CLASS_S;
        !            76:        do {
        !            77:                idsc.dsc$a_pointer = odsc.dsc$a_pointer;
        !            78:                idsc.dsc$w_length  = odsc.dsc$w_length;
        !            79:                odsc.dsc$a_pointer = &oname[0];
        !            80:                odsc.dsc$w_length  = sizeof(oname);
        !            81:                status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
        !            82:                if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
        !            83:                        exit(status);
        !            84:                if (oname[0] == 0x1B) {
        !            85:                        odsc.dsc$a_pointer += 4;
        !            86:                        odsc.dsc$w_length  -= 4;
        !            87:                }
        !            88:        } while (status == SS$_NORMAL);
        !            89:        status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
        !            90:        if (status != SS$_NORMAL)
        !            91:                exit(status);
        !            92:        status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
        !            93:                          oldmode, sizeof(oldmode), 0, 0, 0, 0);
        !            94:        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
        !            95:                exit(status);
        !            96:        newmode[0] = oldmode[0];
        !            97:        newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO;
        !            98:        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
        !            99:                          newmode, sizeof(newmode), 0, 0, 0, 0);
        !           100:        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
        !           101:                exit(status);
        !           102: #endif
        !           103: #if    CPM
        !           104: #endif
        !           105: #if    MSDOS
        !           106: #if    !IBM
        !           107: /*
        !           108:  * Redefine cursor keys (as described in DOS Technical Reference Manual
        !           109:  * p. 2-11, DOS BASIC Manual p. G-6) to mean what the user might expect.
        !           110:  */
        !           111:        static char *control[] = {
        !           112:                "\033[0;72;16p",        /* up    = <ctrl-p>  */
        !           113:                "\033[0;77;6p",         /* right = <ctrl-f>  */
        !           114:                "\033[0;75;2p",         /* left  = <ctrl-b>  */
        !           115:                "\033[0;80;14p",        /* down  = <ctrl-n>  */
        !           116:                "\033[0;81;22p",        /* pg dn = <ctrl-v>  */
        !           117:                "\033[0;73;27;86p",     /* pg up = <esc>V    */
        !           118:                "\033[0;71;27;60p",     /* home  = <esc><    */
        !           119:                "\033[0;79;27;62p",     /* end   = <esc>>    */
        !           120:                "\033[0;83;127p",       /* del   = del       */
        !           121:                "\033[0;3;27;46p"       /* <ctrl-@> = <esc>. */
        !           122:        };
        !           123:        register uchar *cp;
        !           124:        register int i;
        !           125: 
        !           126:        for (i = 0; i < sizeof(control)/sizeof(uchar *); i++) {
        !           127:                for (cp = control[i]; *cp; )
        !           128:                        ttputc(*cp++);
        !           129:        }
        !           130: 
        !           131: #endif
        !           132: #endif
        !           133: #if    V7
        !           134:        gtty(1, &ostate);                       /* save old state */
        !           135:        nstate = ostate;                        /* get base of new state */
        !           136:        nstate.sg_flags |= RAW;
        !           137:        nstate.sg_flags &= ~(ECHO|CRMOD);       /* no echo for now... */
        !           138:        stty(1, &nstate);                       /* set mode */
        !           139: #endif
        !           140: }
        !           141: 
        !           142: /*
        !           143:  * This function gets called just
        !           144:  * before we go back home to the command interpreter.
        !           145:  * On VMS it puts the terminal back in a reasonable state.
        !           146:  * Another no-operation on CPM.
        !           147:  */
        !           148: ttclose()
        !           149: {
        !           150: #if    VMS
        !           151:        int     status;
        !           152:        int     iosb[1];
        !           153: 
        !           154:        ttflush();
        !           155:        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
        !           156:                 oldmode, sizeof(oldmode), 0, 0, 0, 0);
        !           157:        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
        !           158:                exit(status);
        !           159:        status = SYS$DASSGN(iochan);
        !           160:        if (status != SS$_NORMAL)
        !           161:                exit(status);
        !           162: #endif
        !           163: #if    CPM
        !           164: #endif
        !           165: #if    MSDOS
        !           166: #if    !IBM
        !           167: /* Redefine cursor keys to default values. */
        !           168:        static char *control[] = {
        !           169:                "\033[0;72;0;72p",
        !           170:                "\033[0;77;0;77p",
        !           171:                "\033[0;75;0;75p",
        !           172:                "\033[0;80;0;80p",
        !           173:                "\033[0;81;0;81p",
        !           174:                "\033[0;73;0;73p",
        !           175:                "\033[0;71;0;71p",
        !           176:                "\033[0;79;0;79p",
        !           177:                "\033[0;83;0;83p",
        !           178:                "\033[0;3;0;3p"
        !           179:        };
        !           180:        register uchar *cp;
        !           181:        register int i;
        !           182: 
        !           183:        for (i = 0; i < sizeof(control)/sizeof(uchar *); i++) {
        !           184:                for (cp = control[i]; *cp; )
        !           185:                        ttputc(*cp++);
        !           186:        }
        !           187: #endif
        !           188: #endif
        !           189: #if    V7
        !           190:        stty(1, &ostate);
        !           191: #endif
        !           192: }
        !           193: 
        !           194: #ifndef IBM
        !           195: /*
        !           196:  * Write a character to the display.
        !           197:  * On VMS, terminal output is buffered, and
        !           198:  * we just put the characters in the big array,
        !           199:  * after cheching for overflow. On CPM terminal I/O
        !           200:  * unbuffered, so we just write the byte out.
        !           201:  * Ditto on MS-DOS (use the very very raw console
        !           202:  * output routine).
        !           203:  */
        !           204: ttputc(c)
        !           205: {
        !           206: #if    VMS
        !           207:        if (nobuf >= NOBUF)
        !           208:                ttflush();
        !           209:        obuf[nobuf++] = c;
        !           210: #endif
        !           211: #if    CPM
        !           212:        bios(BCONOUT, c, 0);
        !           213: #endif
        !           214: #if    GEM
        !           215: #if    NATIVE
        !           216:        Bconout(2, c);
        !           217: #else
        !           218:        Crawio(c);
        !           219: #endif
        !           220: #endif
        !           221: #if    MSDOS
        !           222:        dosb(CONDIO, c, 0);
        !           223: #endif
        !           224: #if    V7
        !           225:        fputc(c, stdout);
        !           226: #endif
        !           227: }
        !           228: #endif
        !           229: /*
        !           230:  * Flush terminal buffer. Does real work
        !           231:  * where the terminal output is buffered up. A
        !           232:  * no-operation on systems where byte at a time
        !           233:  * terminal I/O is done.
        !           234:  */
        !           235: ttflush()
        !           236: {
        !           237: #if    VMS
        !           238:        int     status;
        !           239:        int     iosb[2];
        !           240: 
        !           241:        status = SS$_NORMAL;
        !           242:        if (nobuf != 0) {
        !           243:                status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
        !           244:                         iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
        !           245:                if (status == SS$_NORMAL)
        !           246:                        status = iosb[0] & 0xFFFF;
        !           247:                nobuf = 0;
        !           248:        }
        !           249:        return (status);
        !           250: #endif
        !           251: #if    CPM
        !           252: #endif
        !           253: #if    MSDOS
        !           254: #endif
        !           255: #if    V7
        !           256:        fflush(stdout);
        !           257: #endif
        !           258: }
        !           259: 
        !           260: /*
        !           261:  * Read a character from the terminal,
        !           262:  * performing no editing and doing no echo at all.
        !           263:  * More complex in VMS that almost anyplace else, which
        !           264:  * figures. Very simple on CPM, because the system can
        !           265:  * do exactly what you want.
        !           266:  */
        !           267: ttgetc()
        !           268: {
        !           269: #if    VMS
        !           270:        int     status;
        !           271:        int     iosb[2];
        !           272:        int     term[2];
        !           273: 
        !           274:        while (ibufi >= nibuf) {
        !           275:                ibufi = 0;
        !           276:                term[0] = 0;
        !           277:                term[1] = 0;
        !           278:                status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
        !           279:                         iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
        !           280:                if (status != SS$_NORMAL)
        !           281:                        exit(status);
        !           282:                status = iosb[0] & 0xFFFF;
        !           283:                if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
        !           284:                        exit(status);
        !           285:                nibuf = (iosb[0]>>16) + (iosb[1]>>16);
        !           286:                if (nibuf == 0) {
        !           287:                        status = sys$qiow(EFN, iochan, IO$_READLBLK,
        !           288:                                 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
        !           289:                        if (status != SS$_NORMAL
        !           290:                        || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
        !           291:                                exit(status);
        !           292:                        nibuf = (iosb[0]>>16) + (iosb[1]>>16);
        !           293:                }
        !           294:        }
        !           295:        return (ibuf[ibufi++] & 0xFF);          /* Allow multinational  */
        !           296: #endif
        !           297: #if    CPM
        !           298:        return (biosb(BCONIN, 0, 0));
        !           299: #endif
        !           300: #if    GEM
        !           301:        register long c;
        !           302: 
        !           303: #if    NATIVE
        !           304:        c = Bconin(2);
        !           305: #else
        !           306:        c = Crawcin();
        !           307: #endif
        !           308:        /*
        !           309:         * Convert arrow keys to ctrl-p,n,f,b, and function keys to
        !           310:         * various things.  (No longer return 0 for function keys.)
        !           311:         */
        !           312:        switch ((int)(c >> 16)) {
        !           313:        case 0x48:                      /* Up arrow to ^P       */
        !           314:                return (OBND|0x10);
        !           315:        case 0x50:                      /* Down arrow to ^N     */
        !           316:                return (OBND|0x0E);
        !           317:        case 0x4D:                      /* Right arrow to ^F    */
        !           318:                return (OBND|0x06);
        !           319:        case 0x4B:                      /* Left arrow to ^B     */
        !           320:                return (OBND|0x02);
        !           321: #if    EXKEYS
        !           322:        case 0x3B:                      /* F1                   */
        !           323:                return (FN1);
        !           324:        case 0x3C:                      /* F2                   */
        !           325:                return (FN2);
        !           326:        case 0x3D:                      /* F3                   */
        !           327:                return (FN3);
        !           328:        case 0x3E:                      /* F4                   */
        !           329:                return (FN4);
        !           330:        case 0x3F:                      /* F5                   */
        !           331:                return (FN5);
        !           332:        case 0x40:                      /* F6                   */
        !           333:                return (FN6);
        !           334:        case 0x41:                      /* F7                   */
        !           335:                return (FN7);
        !           336:        case 0x42:                      /* F8                   */
        !           337:                return (FN8);
        !           338:        case 0x43:                      /* F9                   */
        !           339:                return (FN9);
        !           340:        case 0x44:                      /* F10                  */
        !           341:                return (FN10);
        !           342:        case 0x47:                      /* Clr/Home             */
        !           343:                return (FN1D);          /*  Delete this window  */
        !           344:        case 0x52:                      /* Insert               */
        !           345:                return (FN1C);          /*  perform macro       */
        !           346:        case 0x61:                      /* Undo                 */
        !           347:                return (FN1B);          /*  Remove help window  */
        !           348:        case 0x62:                      /* Help                 */
        !           349:                return (FN1A);          /*  Prompt for help     */
        !           350: #else
        !           351:        case 0x3B:                      /* F1                   */
        !           352:        case 0x3C:                      /* F2                   */
        !           353:        case 0x3D:                      /* F3                   */
        !           354:        case 0x3E:                      /* F4                   */
        !           355:        case 0x3F:                      /* F5                   */
        !           356:        case 0x40:                      /* F6                   */
        !           357:        case 0x41:                      /* F7                   */
        !           358:        case 0x42:                      /* F8                   */
        !           359:        case 0x43:                      /* F9                   */
        !           360:        case 0x44:                      /* F10                  */
        !           361:                return (0x07|OBND);             /*  Ctrl-G              */
        !           362:        case 0x47:                      /* Clr/Home             */
        !           363:                return (OBND|META|'1'); /*  Delete this window  */
        !           364:        case 0x52:                      /* Insert               */
        !           365:                return (OBND|PFX1|'E'); /*  perform macro       */
        !           366:        case 0x61:                      /* Undo                 */
        !           367:                return (OBND|META|'2'); /*  Remove help window  */
        !           368:        case 0x62:                      /* Help                 */
        !           369:                return (OBND|META|'?'); /*  Prompt for help     */
        !           370: #endif
        !           371:        default:                        /* Return the keyboard character */
        !           372:                return ((int)c);
        !           373:        }
        !           374: #endif
        !           375: #if    MSDOS
        !           376: #if    IBM
        !           377:        unsigned i;
        !           378: 
        !           379:        for (;;) {      /* try again on bad stuff */
        !           380:        /* Read a character through IBM PC ROM BIOS keyboard interrupt. */
        !           381:        i = ibmrbkey(0);                        /* read character fn */
        !           382:        if (lo(i))
        !           383:                return (lo(i));                 /* got a char */
        !           384: 
        !           385:        switch (hi(i)) {        /* else translate scan code */
        !           386:        case 03:                        /* <ctl-@> = <esc>. */
        !           387:                return OBND| '.' | META;
        !           388:        case 71:                        /* home = <esc>< */
        !           389:                return OBND| '<' | META;
        !           390:        case 72:                        /* up   = <ctl>p */
        !           391:                return OBND| 'P' | CTRL;
        !           392:        case 73:                        /* pg up = <esc>v */
        !           393:                return OBND| 'V' | META;
        !           394:        case 75:                        /* left  = <ctl>b */
        !           395:                return OBND| 'B' | CTRL;
        !           396:        case 77:                        /* right = <ctl>f */
        !           397:                return OBND| 'F' | CTRL;
        !           398:        case 79:                        /* end   = <esc>> */
        !           399:                return OBND| '>' | META;
        !           400:        case 80:                        /* down  = <ctl>n */
        !           401:                return OBND| 'N' | CTRL;
        !           402:        case 81:                        /* pg dn = <ctl>v */
        !           403:                return OBND| 'V' | CTRL;
        !           404:        case 83:                        /* del = del */
        !           405:                return OBND| 127;
        !           406: #if    EXKEYS
        !           407:        case 0x3B:                      /* F1                   */
        !           408:                return (FN1);
        !           409:        case 0x3C:                      /* F2                   */
        !           410:                return (FN2);
        !           411:        case 0x3D:                      /* F3                   */
        !           412:                return (FN3);
        !           413:        case 0x3E:                      /* F4                   */
        !           414:                return (FN4);
        !           415:        case 0x3F:                      /* F5                   */
        !           416:                return (FN5);
        !           417:        case 0x40:                      /* F6                   */
        !           418:                return (FN6);
        !           419:        case 0x41:                      /* F7                   */
        !           420:                return (FN7);
        !           421:        case 0x42:                      /* F8                   */
        !           422:                return (FN8);
        !           423:        case 0x43:                      /* F9                   */
        !           424:                return (FN9);
        !           425:        case 0x44:                      /* F10                  */
        !           426:                return (FN10);
        !           427:        case 0x52:                      /* Insert               */
        !           428:                return (FN1C);          /*  perform macro       */
        !           429:        case 0x61:                      /* Undo                 */
        !           430:                return (FN1B);          /*  Remove help window  */
        !           431:        case 0x62:                      /* Help                 */
        !           432:                return (FN1A);          /*  Prompt for help     */
        !           433: #endif
        !           434:        }
        !           435:     }
        !           436: #else
        !           437:        return (dosb(CONRAW, 0, 0));
        !           438: #endif
        !           439: #endif
        !           440: #if    V7
        !           441:        return (fgetc(stdin));
        !           442: #endif
        !           443: }

unix.superglobalmegacorp.com

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