Annotation of coherent/g/usr/bin/me/termio.c, revision 1.1.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.