Annotation of coherent/g/usr/bin/vi/curses.c, revision 1.1.1.1

1.1       root        1: /* curses.c */
                      2: 
                      3: /* Author:
                      4:  *     Steve Kirkendall
                      5:  *     14407 SW Teal Blvd. #C
                      6:  *     Beaverton, OR 97005
                      7:  *     [email protected]
                      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: #  ifdef TERMIOS
                     23: #   include    <termios.h>
                     24: #  else
                     25: #   include    <termio.h>
                     26: #  endif
                     27: #  ifdef S5WINSIZE
                     28: #   include    <sys/stream.h>  /* winsize struct defined in one of these? */
                     29: #   include    <sys/ptem.h>
                     30: #  else
                     31: #   undef      TIOCGWINSZ      /* we can't handle it correctly yet */
                     32: #  endif
                     33: # else
                     34: #  include     <sgtty.h>
                     35: # endif
                     36: #endif
                     37: 
                     38: #if TOS
                     39: # include      <osbind.h>
                     40: #endif
                     41: 
                     42: #if OSK
                     43: # include      <sgstat.h>
                     44: #endif
                     45: 
                     46: #if VMS
                     47: extern int VMS_read_raw;  /* Set in initscr() */
                     48: #endif
                     49: 
                     50: 
                     51: extern char    *getenv();
                     52: static void     starttcap();
                     53: 
                     54: /* variables, publicly available & used in the macros */
                     55: char   *termtype;      /* name of terminal entry */
                     56: short  ospeed;         /* speed of the tty, eg B2400 */
                     57: #if OSK
                     58: char   PC_;    /* Pad char */
                     59: char   *BC;    /* backspace character string */
                     60: #else
                     61: char   PC;             /* Pad char */
                     62: #endif
                     63: WINDOW *stdscr;        /* pointer into kbuf[] */
                     64: WINDOW kbuf[KBSIZ];    /* a very large output buffer */
                     65: int    LINES;          /* :li#: number of rows */
                     66: int    COLS;           /* :co#: number of columns */
                     67: int    AM;             /* :am:  boolean: auto margins? */
                     68: int    PT;             /* :pt:  boolean: physical tabs? */
                     69: char   *VB;            /* :vb=: visible bell */
                     70: char   *UP;            /* :up=: move cursor up */
                     71: char   *SO = "";       /* :so=: standout start */
                     72: char   *SE = "";       /* :se=: standout end */
                     73: char   *US = "";       /* :us=: underline start */
                     74: char   *UE = "";       /* :ue=: underline end */
                     75: char   *MD = "";       /* :md=: bold start */
                     76: char   *ME = "";       /* :me=: bold end */
                     77: char   *AS = "";       /* :as=: alternate (italic) start */
                     78: char   *AE = "";       /* :ae=: alternate (italic) end */
                     79: #ifndef NO_VISIBLE
                     80: char   *MV;            /* :mv=: "visible" selection start */
                     81: #endif
                     82: char   *CM;            /* :cm=: cursor movement */
                     83: char   *CE;            /* :ce=: clear to end of line */
                     84: char   *CD;            /* :cd=: clear to end of screen */
                     85: char   *AL;            /* :al=: add a line */
                     86: char   *DL;            /* :dl=: delete a line */
                     87: #if OSK
                     88: char   *SR_;           /* :sr=: scroll reverse */
                     89: #else
                     90: char   *SR;            /* :sr=: scroll reverse */
                     91: #endif
                     92: char   *KU;            /* :ku=: key sequence sent by up arrow */
                     93: char   *KD;            /* :kd=: key sequence sent by down arrow */
                     94: char   *KL;            /* :kl=: key sequence sent by left arrow */
                     95: char   *KR;            /* :kr=: key sequence sent by right arrow */
                     96: char   *HM;            /* :HM=: key sequence sent by the <Home> key */
                     97: char   *EN;            /* :EN=: key sequence sent by the <End> key */
                     98: char   *PU;            /* :PU=: key sequence sent by the <PgUp> key */
                     99: char   *PD;            /* :PD=: key sequence sent by the <PgDn> key */
                    100: char   *KI;            /* :kI=: key sequence sent by the <Insert> key */
                    101: #ifndef NO_FKEY
                    102: char   *FKEY[NFKEYS];  /* :k0=: ... :k9=: sequences sent by function keys */
                    103: #endif
                    104: char   *IM = "";       /* :im=: insert mode start */
                    105: char   *IC = "";       /* :ic=: insert the following character */
                    106: char   *EI = "";       /* :ei=: insert mode end */
                    107: char   *DC;            /* :dc=: delete a character */
                    108: char   *TI = "";       /* :ti=: terminal init */       /* GB */
                    109: char   *TE = "";       /* :te=: terminal exit */       /* GB */
                    110: #ifndef NO_CURSORSHAPE
                    111: #if 1
                    112: char   *CQ = (char *)0;/* :cQ=: normal cursor */
                    113: char   *CX = (char *)1;/* :cX=: cursor used for EX command/entry */
                    114: char   *CV = (char *)2;/* :cV=: cursor used for VI command mode */
                    115: char   *CI = (char *)3;/* :cI=: cursor used for VI input mode */
                    116: char   *CR = (char *)4;/* :cR=: cursor used for VI replace mode */
                    117: #else
                    118: char   *CQ = "";       /* :cQ=: normal cursor */
                    119: char   *CX = "";       /* :cX=: cursor used for EX command/entry */
                    120: char   *CV = "";       /* :cV=: cursor used for VI command mode */
                    121: char   *CI = "";       /* :cI=: cursor used for VI input mode */
                    122: char   *CR = "";       /* :cR=: cursor used for VI replace mode */
                    123: #endif
                    124: #endif
                    125: char   *aend = "";     /* end an attribute -- either UE or ME */
                    126: char   ERASEKEY;       /* backspace key taken from ioctl structure */
                    127: #ifndef NO_COLOR
                    128: char   normalcolor[16];
                    129: char   SOcolor[16];
                    130: char   SEcolor[16];
                    131: char   UScolor[16];
                    132: char   UEcolor[16];
                    133: char   MDcolor[16];
                    134: char   MEcolor[16];
                    135: char   AScolor[16];
                    136: char   AEcolor[16];
                    137: # ifndef NO_POPUP
                    138: char   POPUPcolor[16];
                    139: # endif
                    140: # ifndef NO_VISIBLE
                    141: char   VISIBLEcolor[16];
                    142: # endif
                    143: #endif
                    144: 
                    145: #if ANY_UNIX
                    146: # if UNIXV
                    147: #  ifdef TERMIOS
                    148: static struct termios  oldtermio;      /* original tty mode */
                    149: static struct termios  newtermio;      /* cbreak/noecho tty mode */
                    150: #  else
                    151: static struct termio   oldtermio;      /* original tty mode */
                    152: static struct termio   newtermio;      /* cbreak/noecho tty mode */
                    153: #  endif
                    154: # else
                    155: static struct sgttyb   oldsgttyb;      /* original tty mode */
                    156: static struct sgttyb   newsgttyb;      /* cbreak/nl/noecho tty mode */
                    157: static int             oldint;         /* ^C or DEL, the "intr" character */
                    158: #  ifdef TIOCSLTC
                    159: static int             oldswitch;      /* ^Z, the "suspend" character */
                    160: static int             olddswitch;     /* ^Y, the "delayed suspend" char */
                    161: static int             oldquote;       /* ^V, the "quote next char" char */
                    162: #  endif
                    163: # endif
                    164: #endif
                    165: 
                    166: #if OSK
                    167: static struct sgbuf    oldsgttyb;      /* orginal tty mode */
                    168: static struct sgbuf    newsgttyb;      /* noecho tty mode */
                    169: #endif
                    170: 
                    171: static char    *capbuf;        /* capability string buffer */
                    172: 
                    173: 
                    174: /* Initialize the Curses package. */
                    175: void initscr()
                    176: {
                    177:        /* make sure TERM variable is set */
                    178:        termtype = getenv("TERM");
                    179: 
                    180: #if VMS
                    181:        /* VMS getenv() handles TERM as a environment setting.  Foreign 
                    182:         * terminal support can be implemented by setting the ELVIS_TERM
                    183:         * logical or symbol to match a tinytcap entry.
                    184:         */
                    185:        if (!strcmp(termtype,"unknown"))
                    186:                termtype = getenv("ELVIS_TERM");
                    187: #endif
                    188: #if MSDOS
                    189:        /* For MS-DOS, if TERM is unset we can default to "pcbios", or
                    190:         * maybe "rainbow".
                    191:         */
                    192:        if (!termtype)
                    193:        {
                    194: #ifdef RAINBOW
                    195:                if (*(unsigned char far*)(0xffff000eL) == 6   /* Rainbow 100a */
                    196:                 || *(unsigned char far*)(0xffff000eL) == 148)/* Rainbow 100b */
                    197:                {
                    198:                        termtype = "rainbow";
                    199:                }
                    200:                else
                    201: #endif
                    202:                        termtype = "pcbios";
                    203:        }
                    204:        if (!strcmp(termtype, "pcbios"))
                    205: #else
                    206:        if (!termtype)
                    207: #endif
                    208:        {
                    209: #if ANY_UNIX
                    210:                write(2, "Environment variable TERM must be set\n", (unsigned)38);
                    211:                exit(2);
                    212: #endif
                    213: #if OSK
                    214:                writeln(2, "Environment variable TERM must be set\n", (unsigned)38);
                    215:                exit(2);
                    216: #endif
                    217: #if AMIGA
                    218:                termtype = TERMTYPE;
                    219:                starttcap(termtype);
                    220: #endif
                    221: #if MSDOS
                    222:                starttcap("pcbios");
                    223: #endif
                    224: #if TOS
                    225:                termtype = "vt52";
                    226:                starttcap(termtype);
                    227: #endif
                    228: #if VMS
                    229:                write(2, "UNKNOWN terminal: define ELVIS_TERM\n", (unsigned)36);
                    230:                exit(2);
                    231: #endif
                    232:        }
                    233:        else
                    234:        {
                    235: #if MSDOS
                    236:                *o_pcbios = 0;
                    237: #endif
                    238:                /* start termcap stuff */
                    239:                starttcap(termtype);
                    240:        }
                    241: 
                    242:        /* create stdscr and curscr */
                    243:        stdscr = kbuf;
                    244: 
                    245:        /* change the terminal mode to cbreak/noecho */
                    246: #if ANY_UNIX
                    247: # if UNIXV
                    248: #  ifdef TERMIOS
                    249:        tcgetattr(2, &oldtermio);
                    250: #  else
                    251:        ioctl(2, TCGETA, &oldtermio);
                    252: #  endif
                    253: # else
                    254:        ioctl(2, TIOCGETP, &oldsgttyb);
                    255: # endif
                    256: #endif
                    257: 
                    258: #if OSK
                    259:        _gs_opt(0, &oldsgttyb);
                    260: #endif
                    261: 
                    262: #if VMS
                    263:        VMS_read_raw = 1;   /* cbreak/noecho */
                    264:        vms_open_tty();
                    265: #endif
                    266:        resume_curses(TRUE);
                    267: }
                    268: 
                    269: /* Shut down the Curses package. */
                    270: void endwin()
                    271: {
                    272:        /* change the terminal mode back the way it was */
                    273:        suspend_curses();
                    274: #if AMIGA
                    275:        amiclosewin();
                    276: #endif
                    277: }
                    278: 
                    279: 
                    280: static int curses_active = FALSE;
                    281: 
                    282: /* Send any required termination strings.  Turn off "raw" mode. */
                    283: void suspend_curses()
                    284: {
                    285: #if ANY_UNIX && !UNIXV
                    286:        struct tchars   tbuf;
                    287: # ifdef TIOCSLTC
                    288:        struct ltchars  ltbuf;
                    289: # endif
                    290: #endif
                    291: #ifndef NO_CURSORSHAPE
                    292:        if (has_CQ)
                    293:        {
                    294:                do_CQ();
                    295:        }
                    296: #endif
                    297:        if (has_TE)                                     /* GB */
                    298:        {
                    299:                do_TE();
                    300:        }
                    301: #ifndef NO_COLOR
                    302:        quitcolor();
                    303: #endif
                    304:        refresh();
                    305: 
                    306:        /* change the terminal mode back the way it was */
                    307: #if ANY_UNIX
                    308: # if UNIXV
                    309: #  if TERMIOS
                    310:        tcsetattr(2, TCSADRAIN, &oldtermio);
                    311: #  else
                    312:        ioctl(2, TCSETAW, &oldtermio);
                    313: #  endif
                    314: # else
                    315:        ioctl(2, TIOCSETP, &oldsgttyb);
                    316: 
                    317:        ioctl(2, TIOCGETC, (struct sgttyb *) &tbuf);
                    318:        tbuf.t_intrc = oldint;
                    319:        ioctl(2, TIOCSETC, (struct sgttyb *) &tbuf);
                    320: 
                    321: #  ifdef TIOCSLTC
                    322:        ioctl(2, TIOCGLTC, &ltbuf);
                    323:        ltbuf.t_suspc = oldswitch;
                    324:        ltbuf.t_dsuspc = olddswitch;
                    325:        ltbuf.t_lnextc = oldquote;
                    326:        ioctl(2, TIOCSLTC, &ltbuf);
                    327: #  endif
                    328: # endif
                    329: #endif
                    330: #if OSK
                    331:        _ss_opt(0, &oldsgttyb);
                    332: #endif
                    333: #if AMIGA
                    334:        ttyshutdown();
                    335: #endif
                    336: #if MSDOS
                    337:        raw_set_stdio(FALSE);
                    338: #endif
                    339: 
                    340: #if VMS
                    341:        VMS_read_raw = 0;
                    342: #endif
                    343:        curses_active = FALSE;
                    344: }
                    345: 
                    346: 
                    347: /* put the terminal in RAW mode.  If "quietly" is FALSE, then ask the user
                    348:  * to hit a key, and wait for keystroke before returning.
                    349:  */
                    350: void resume_curses(quietly)
                    351:        int     quietly;
                    352: {
                    353:        if (!curses_active)
                    354:        {
                    355:                /* change the terminal mode to cbreak/noecho */
                    356: #if ANY_UNIX
                    357: # if UNIXV
                    358:                ospeed = (oldtermio.c_cflag & CBAUD);
                    359:                ERASEKEY = oldtermio.c_cc[VERASE];
                    360:                newtermio = oldtermio;
                    361:                newtermio.c_iflag &= (IXON|IXOFF|IXANY|ISTRIP|IGNBRK);
                    362:                newtermio.c_oflag &= ~OPOST;
                    363:                newtermio.c_lflag &= ISIG;
                    364:                newtermio.c_cc[VINTR] = ctrl('C'); /* always use ^C for interrupts */
                    365:                newtermio.c_cc[VMIN] = 1;
                    366:                newtermio.c_cc[VTIME] = 0;
                    367: #  ifdef VSWTCH
                    368:                newtermio.c_cc[VSWTCH] = 0;
                    369: #  endif
                    370: #  ifdef VSUSP
                    371:                newtermio.c_cc[VSUSP] = 0;
                    372: #  endif
                    373: #  ifdef TERMIOS
                    374:                tcsetattr(2, TCSADRAIN, &newtermio);
                    375: #  else
                    376:                ioctl(2, TCSETAW, &newtermio);
                    377: #  endif
                    378: # else /* BSD or V7 or Coherent or Minix */
                    379:                struct tchars   tbuf;
                    380: #  ifdef TIOCSLTC
                    381:                struct ltchars  ltbuf;
                    382: #  endif
                    383: 
                    384:                ospeed = oldsgttyb.sg_ospeed;
                    385:                ERASEKEY = oldsgttyb.sg_erase;
                    386:                newsgttyb = oldsgttyb;
                    387:                newsgttyb.sg_flags |= CBREAK;
                    388:                newsgttyb.sg_flags &= ~(CRMOD|ECHO|XTABS);
                    389:                ioctl(2, TIOCSETP, &newsgttyb);
                    390: 
                    391:                ioctl(2, TIOCGETC, (struct sgttyb *) &tbuf);
                    392:                oldint = tbuf.t_intrc;
                    393:                tbuf.t_intrc = ctrl('C');       /* always use ^C for interrupts */
                    394:                ioctl(2, TIOCSETC, (struct sgttyb *) &tbuf);
                    395: 
                    396: #  ifdef TIOCSLTC
                    397:                ioctl(2, TIOCGLTC, &ltbuf);
                    398:                oldswitch = ltbuf.t_suspc;
                    399:                ltbuf.t_suspc = 0;              /* disable ^Z for elvis */
                    400:                olddswitch = ltbuf.t_dsuspc;
                    401:                ltbuf.t_dsuspc = 0;             /* disable ^Y for elvis */
                    402:                oldquote = ltbuf.t_lnextc;
                    403:                ltbuf.t_lnextc = 0;             /* disable ^V for elvis */
                    404:                ioctl(2, TIOCSLTC, &ltbuf);
                    405: #  endif
                    406: 
                    407: # endif
                    408: #endif
                    409: #if OSK
                    410:                newsgttyb = oldsgttyb;
                    411:                newsgttyb.sg_echo = 0;
                    412:                newsgttyb.sg_eofch = 0;
                    413:                newsgttyb.sg_kbach = 0;
                    414:                newsgttyb.sg_kbich = ctrl('C');
                    415:                _ss_opt(0, &newsgttyb);
                    416:                ospeed = oldsgttyb.sg_baud;
                    417:                ERASEKEY = oldsgttyb.sg_bspch;
                    418: #endif
                    419: #if AMIGA
                    420:                /* turn on window resize and RAW */
                    421:                ttysetup();
                    422: #endif
                    423: #if MSDOS
                    424:                raw_set_stdio(TRUE);
                    425: #endif
                    426: 
                    427: #if VMS
                    428:                VMS_read_raw = 1;
                    429:                { int c;
                    430:                        read(0,&c,0);   /* Flush the tty buffer. */
                    431:                }
                    432:                ERASEKEY = '\177';  /* Accept <DEL> as <^H> for VMS */
                    433: #endif
                    434: 
                    435:                curses_active = TRUE;
                    436:        }
                    437: 
                    438:        /* If we're supposed to quit quietly, then we're done */
                    439:        if (quietly)
                    440:        {
                    441:                if (has_TI)                                     /* GB */
                    442:                {
                    443:                        do_TI();
                    444:                }
                    445: 
                    446:                return;
                    447:        }
                    448: 
                    449:        signal(SIGINT, SIG_IGN);
                    450: 
                    451:        move(LINES - 1, 0);
                    452:        do_SO();
                    453: #if VMS
                    454:        qaddstr("\n[Press <RETURN> to continue]");
                    455: #else
                    456:        qaddstr("[Press <RETURN> to continue]");
                    457: #endif
                    458:        do_SE();
                    459:        refresh();
                    460:        ttyread(kbuf, 20, 0); /* in RAW mode, so <20 is very likely */
                    461:        if (has_TI)
                    462:        {
                    463:                do_TI();
                    464:        }
                    465:        if (kbuf[0] == ':')
                    466:        {
                    467:                mode = MODE_COLON;
                    468:                addch('\n');
                    469:                refresh();
                    470:        }
                    471:        else
                    472:        {
                    473:                mode = MODE_VI;
                    474:                redraw(MARK_UNSET, FALSE);
                    475:        }       
                    476:        exwrote = FALSE;
                    477: 
                    478: #if TURBOC || __GNUC__
                    479:        signal(SIGINT, (void(*)()) trapint);
                    480: #else
                    481:        signal(SIGINT, trapint);
                    482: #endif
                    483: }
                    484: 
                    485: /* This function fetches an optional string from termcap */
                    486: static void mayhave(T, s)
                    487:        char    **T;    /* where to store the returned pointer */
                    488:        char    *s;     /* name of the capability */
                    489: {
                    490:        char    *val;
                    491: 
                    492:        val = tgetstr(s, &capbuf);
                    493:        if (val)
                    494:        {
                    495:                *T = val;
                    496:        }
                    497: }
                    498: 
                    499: 
                    500: /* This function fetches a required string from termcap */
                    501: static void musthave(T, s)
                    502:        char    **T;    /* where to store the returned pointer */
                    503:        char    *s;     /* name of the capability */
                    504: {
                    505:        mayhave(T, s);
                    506:        if (!*T)
                    507:        {
                    508:                write(2, "This termcap entry lacks the :", (unsigned)30);
                    509:                write(2, s, (unsigned)2);
                    510:                write(2, "=: capability\n", (unsigned)14);
                    511: #if OSK
                    512:                write(2, "\l", 1);
                    513: #endif
                    514:                exit(2);
                    515:        }
                    516: }
                    517: 
                    518: 
                    519: /* This function fetches a pair of strings from termcap.  If one of them is
                    520:  * missing, then the other one is ignored.
                    521:  */
                    522: static void pair(T, U, sT, sU)
                    523:        char    **T;    /* where to store the first pointer */
                    524:        char    **U;    /* where to store the second pointer */
                    525:        char    *sT;    /* name of the first capability */
                    526:        char    *sU;    /* name of the second capability */
                    527: {
                    528:        mayhave(T, sT);
                    529:        mayhave(U, sU);
                    530:        if (!**T || !**U)
                    531:        {
                    532:                *T = *U = "";
                    533:        }
                    534: }
                    535: 
                    536: 
                    537: 
                    538: /* Read everything from termcap */
                    539: static void starttcap(term)
                    540:        char    *term;
                    541: {
                    542:        static char     cbmem[800];
                    543: 
                    544:        /* allocate memory for capbuf */
                    545:        capbuf = cbmem;
                    546: 
                    547:        /* get the termcap entry */
                    548:        switch (tgetent(kbuf, term))
                    549:        {
                    550:          case -1:
                    551:                write(2, "Can't read /etc/termcap\n", (unsigned)24);
                    552: #if OSK
                    553:                write(2, "\l", 1);
                    554: #endif
                    555:                exit(2);
                    556: 
                    557:          case 0:
                    558:                write(2, "Unrecognized TERM type\n", (unsigned)23);
                    559: #if OSK
                    560:                write(2, "\l", 1);
                    561: #endif
                    562:                exit(3);
                    563:        }
                    564: 
                    565:        /* get strings */
                    566:        musthave(&UP, "up");
                    567:        mayhave(&VB, "vb");
                    568:        musthave(&CM, "cm");
                    569:        pair(&SO, &SE, "so", "se");
                    570:        mayhave(&TI, "ti");
                    571:        mayhave(&TE, "te");
                    572:        if (tgetnum("ug") <= 0)
                    573:        {
                    574:                pair(&US, &UE, "us", "ue");
                    575:                pair(&MD, &ME, "md", "me");
                    576: 
                    577:                /* get italics, or have it default to underline */
                    578:                pair(&AS, &AE, "as", "ae");
                    579:                if (!*AS)
                    580:                {
                    581:                        AS = US;
                    582:                        AE = UE;
                    583:                }
                    584:        }
                    585: #ifndef NO_VISIBLE
                    586:        MV = SO; /* by default */
                    587:        mayhave(&MV, "mv");
                    588: #endif
                    589:        mayhave(&AL, "al");
                    590:        mayhave(&DL, "dl");
                    591:        musthave(&CE, "ce");
                    592:        mayhave(&CD, "cd");
                    593: #if OSK
                    594:        mayhave(&SR_, "sr");
                    595: #else  
                    596:        mayhave(&SR, "sr");
                    597: #endif
                    598:        pair(&IM, &EI, "im", "ei");
                    599:        mayhave(&IC, "ic");
                    600:        mayhave(&DC, "dc");
                    601: 
                    602:        /* other termcap stuff */
                    603:        AM = (tgetflag("am") && !tgetflag("xn"));
                    604:        PT = tgetflag("pt");
                    605: #if AMIGA
                    606:        amiopenwin(termtype);   /* Must run this before ttysetup(); */
                    607:        ttysetup();     /* Must run this before getsize(0); */
                    608: #endif
                    609:        getsize(0);
                    610: 
                    611:        /* Key sequences */
                    612:        mayhave(&KU, "ku");             /* up */
                    613:        mayhave(&KD, "kd");             /* down */
                    614:        mayhave(&KL, "kl");             /* left */
                    615:        mayhave(&KR, "kr");             /* right */
                    616: #if COHERENT
                    617:        if (KL && KL[0]=='\b' && !KL[1])
                    618:        {
                    619:                /* never use '\b' as a left arrow! */
                    620:                KL = (char *)0;
                    621:        }
                    622: #else
                    623:        if (KR && KR[0]=='\b' && !KR[1])
                    624:        {
                    625:                /* never use '\b' as a right arrow! */
                    626:                KR = (char *)0;
                    627:        }
                    628: #endif
                    629:        mayhave(&PU, "kP");             /* PgUp */
                    630:        mayhave(&PD, "kN");             /* PgDn */
                    631:        mayhave(&HM, "kh");             /* Home */
                    632:        mayhave(&EN, "kH");             /* End */
                    633:        mayhave(&KI, "kI");             /* Insert */
                    634: #ifndef CRUNCH
                    635:        if (!PU) mayhave(&PU, "K2");    /* "3x3 pad" names for PgUp, etc. */
                    636:        if (!PD) mayhave(&PD, "K5");
                    637:        if (!HM) mayhave(&HM, "K1");
                    638:        if (!EN) mayhave(&EN, "K4");
                    639: 
                    640:        mayhave(&PU, "PU");             /* old XENIX names for PgUp, etc. */
                    641:        mayhave(&PD, "PD");             /* (overrides others, if used.) */
                    642:        mayhave(&HM, "HM");
                    643:        mayhave(&EN, "EN");
                    644: #endif
                    645: #ifndef NO_FKEY
                    646:        mayhave(&FKEY[0], "k0");                /* function key codes */
                    647:        mayhave(&FKEY[1], "k1");
                    648:        mayhave(&FKEY[2], "k2");
                    649:        mayhave(&FKEY[3], "k3");
                    650:        mayhave(&FKEY[4], "k4");
                    651:        mayhave(&FKEY[5], "k5");
                    652:        mayhave(&FKEY[6], "k6");
                    653:        mayhave(&FKEY[7], "k7");
                    654:        mayhave(&FKEY[8], "k8");
                    655:        mayhave(&FKEY[9], "k9");
                    656: # ifndef NO_SHIFT_FKEY
                    657:        mayhave(&FKEY[10], "s0");               /* shift function key codes */
                    658:        mayhave(&FKEY[11], "s1");
                    659:        mayhave(&FKEY[12], "s2");
                    660:        mayhave(&FKEY[13], "s3");
                    661:        mayhave(&FKEY[14], "s4");
                    662:        mayhave(&FKEY[15], "s5");
                    663:        mayhave(&FKEY[16], "s6");
                    664:        mayhave(&FKEY[17], "s7");
                    665:        mayhave(&FKEY[18], "s8");
                    666:        mayhave(&FKEY[19], "s9");
                    667: #  ifndef NO_CTRL_FKEY
                    668:        mayhave(&FKEY[20], "c0");               /* control function key codes */
                    669:        mayhave(&FKEY[21], "c1");
                    670:        mayhave(&FKEY[22], "c2");
                    671:        mayhave(&FKEY[23], "c3");
                    672:        mayhave(&FKEY[24], "c4");
                    673:        mayhave(&FKEY[25], "c5");
                    674:        mayhave(&FKEY[26], "c6");
                    675:        mayhave(&FKEY[27], "c7");
                    676:        mayhave(&FKEY[28], "c8");
                    677:        mayhave(&FKEY[29], "c9");
                    678: #   ifndef NO_ALT_FKEY
                    679:        mayhave(&FKEY[30], "a0");               /* alt function key codes */
                    680:        mayhave(&FKEY[31], "a1");
                    681:        mayhave(&FKEY[32], "a2");
                    682:        mayhave(&FKEY[33], "a3");
                    683:        mayhave(&FKEY[34], "a4");
                    684:        mayhave(&FKEY[35], "a5");
                    685:        mayhave(&FKEY[36], "a6");
                    686:        mayhave(&FKEY[37], "a7");
                    687:        mayhave(&FKEY[38], "a8");
                    688:        mayhave(&FKEY[39], "a9");
                    689: #   endif
                    690: #  endif
                    691: # endif
                    692: #endif
                    693: 
                    694: #ifndef NO_CURSORSHAPE
                    695:        /* cursor shapes */
                    696:        CQ = tgetstr("cQ", &capbuf);
                    697:        if (has_CQ)
                    698:        {
                    699:                CX = tgetstr("cX", &capbuf);
                    700:                if (!CX) CX = CQ;
                    701:                CV = tgetstr("cV", &capbuf);
                    702:                if (!CV) CV = CQ;
                    703:                CI = tgetstr("cI", &capbuf);
                    704:                if (!CI) CI = CQ;
                    705:                CR = tgetstr("cR", &capbuf);
                    706:                if (!CR) CR = CQ;
                    707:        }
                    708: # ifndef CRUNCH
                    709:        else
                    710:        {
                    711:                CQ = CV = "";
                    712:                pair(&CQ, &CV, "ve", "vs");
                    713:                CX = CI = CR = CQ;
                    714:        }
                    715: # endif /* !CRUNCH */
                    716: #endif /* !NO_CURSORSHAPE */
                    717: 
                    718: #ifndef NO_COLOR
                    719:        strcpy(SOcolor, SO);
                    720:        strcpy(SEcolor, SE);
                    721:        strcpy(AScolor, AS);
                    722:        strcpy(AEcolor, AE);
                    723:        strcpy(MDcolor, MD);
                    724:        strcpy(MEcolor, ME);
                    725:        strcpy(UScolor, US);
                    726:        strcpy(UEcolor, UE);
                    727: # ifndef NO_POPUP
                    728:        strcpy(POPUPcolor, SO);
                    729: # endif
                    730: # ifndef NO_VISIBLE
                    731:        strcpy(VISIBLEcolor, MV);
                    732: # endif
                    733: #endif
                    734: 
                    735: }
                    736: 
                    737: 
                    738: /* This function gets the window size.  It uses the TIOCGWINSZ ioctl call if
                    739:  * your system has it, or tgetnum("li") and tgetnum("co") if it doesn't.
                    740:  * This function is called once during initialization, and thereafter it is
                    741:  * called whenever the SIGWINCH signal is sent to this process.
                    742:  */
                    743: int getsize(signo)
                    744:        int     signo;
                    745: {
                    746:        int     lines;
                    747:        int     cols;
                    748: #ifdef TIOCGWINSZ
                    749:        struct winsize size;
                    750: #endif
                    751: 
                    752: #ifdef SIGWINCH
                    753:        /* reset the signal vector */
                    754:        signal(SIGWINCH, getsize);
                    755: #endif
                    756: 
                    757:        /* get the window size, one way or another. */
                    758:        lines = cols = 0;
                    759: #ifdef TIOCGWINSZ
                    760:        if (ioctl(2, TIOCGWINSZ, &size) >= 0)
                    761:        {
                    762:                lines = size.ws_row;
                    763:                cols = size.ws_col;
                    764:        }
                    765: #endif
                    766: #if AMIGA
                    767:        /* Amiga gets window size by asking the console.device */
                    768:        if (!strcmp(TERMTYPE, termtype))
                    769:        {
                    770:            auto long len;
                    771:            auto char buf[30];
                    772:            
                    773:            Write(Output(), "\2330 q", 4); /* Ask the console.device */
                    774:            len = Read(Input(), buf, 29);
                    775:            buf[len] = '\000';
                    776:            sscanf(&buf[5], "%d;%d", &lines, &cols);
                    777:        }
                    778: #endif
                    779:        if ((lines == 0 || cols == 0) && signo == 0)
                    780:        {
                    781: #if COHERENT
                    782:                char * temp;
                    783: 
                    784:                temp = getenv("COLUMNS");
                    785:                if (temp)
                    786:                        COLS = atoi(temp);
                    787:                else
                    788:                        COLS = tgetnum("co");
                    789: 
                    790:                temp = getenv("LINES");
                    791:                if (temp)
                    792:                        LINES = atoi(temp);
                    793:                else
                    794:                        LINES = tgetnum("li");
                    795: #else
                    796:                LINES = tgetnum("li");
                    797:                COLS = tgetnum("co");
                    798: #endif
                    799:        }
                    800: #if MSDOS
                    801: # ifdef RAINBOW
                    802:        if (!strcmp(termtype, "rainbow"))
                    803:        {
                    804:                /* Determine whether Rainbow is in 80-column or 132-column mode */
                    805:                cols = *(unsigned char far *)0xee000f57L;
                    806:        }
                    807:        else
                    808: # endif
                    809:        {
                    810:                lines = v_rows();
                    811:                cols = v_cols();
                    812:        }
                    813: #endif
                    814:        if (lines >= 2 && cols >= 30)
                    815:        {
                    816:                LINES = lines;
                    817:                COLS = cols;
                    818:        }
                    819: 
                    820:        /* Make sure we got values that we can live with */
                    821:        if (LINES < 2 || COLS < 30)
                    822:        {
                    823:                write(2, "Screen too small\n", (unsigned)17);
                    824: #if OSK
                    825:                write(2, "\l", 1);
                    826: #endif
                    827:                endwin();
                    828:                exit(2);
                    829:        }
                    830: 
                    831: #if AMIGA
                    832:        if (*o_lines != LINES || *o_columns != COLS)
                    833:        {
                    834:                *o_lines = LINES;
                    835:                *o_columns = COLS;
                    836:        }
                    837: #endif
                    838: 
                    839:        return 0;
                    840: }
                    841: 
                    842: 
                    843: /* This is a function version of addch() -- it is used by tputs() */
                    844: int faddch(ch)
                    845: int    ch;
                    846: {
                    847: #if 0
                    848:        if (stdscr)
                    849:                addch(ch);
                    850:        else
                    851:                msg("OOPS! tried to access null stdscr");
                    852: #else
                    853:        addch(ch);
                    854: #endif
                    855: 
                    856:        return 0;
                    857: }
                    858: 
                    859: /* This function quickly adds a string to the output queue.  It does *NOT*
                    860:  * convert \n into <CR><LF>.
                    861:  */
                    862: void qaddstr(str)
                    863:        char    *str;
                    864: {
                    865:        REG char *s_, *d_;
                    866: 
                    867: #if MSDOS
                    868:        if (o_pcbios[0])
                    869:        {
                    870:                while (*str)
                    871:                        qaddch(*str++);
                    872:                return;
                    873:        }
                    874: #endif
                    875:        for (s_=(str), d_=stdscr; *d_++ = *s_++; )
                    876:        {
                    877:        }
                    878:        stdscr = d_ - 1;
                    879: }
                    880: 
                    881: /* Output the ESC sequence needed to go into any video mode, if supported */
                    882: void attrset(a)
                    883:        int     a;
                    884: {
                    885:        do_aend();
                    886:        if (a == A_BOLD)
                    887:        {
                    888:                do_MD();
                    889:                aend = ME;
                    890:        }
                    891:        else if (a == A_UNDERLINE)
                    892:        {
                    893:                do_US();
                    894:                aend = UE;
                    895:        }
                    896:        else if (a == A_ALTCHARSET)
                    897:        {
                    898:                do_AS();
                    899:                aend = AE;
                    900:        }
                    901:        else
                    902:        {
                    903:                aend = "";
                    904:        }
                    905: }
                    906: 
                    907: 
                    908: /* Insert a single character into the display */
                    909: void insch(ch)
                    910:        int     ch;
                    911: {
                    912:        if (has_IM)
                    913:                do_IM();
                    914:        do_IC();
                    915:        qaddch(ch);
                    916:        if (has_EI)
                    917:                do_EI();
                    918: }
                    919: 
                    920: void wrefresh()
                    921: {
                    922:        if (stdscr != kbuf)
                    923:        {
                    924:                VOIDBIOS(;,ttywrite(kbuf, (unsigned)(stdscr - kbuf)));
                    925:                stdscr = kbuf;
                    926:        }
                    927: }
                    928: 
                    929: void wqrefresh()
                    930: {
                    931:        if (stdscr - kbuf > 2000)
                    932:        {
                    933:                VOIDBIOS(stdscr = kbuf,
                    934:                {
                    935:                        ttywrite(kbuf, (unsigned)(stdscr - kbuf)); 
                    936:                        stdscr = kbuf;
                    937:                });
                    938:        }
                    939: }
                    940: 
                    941: #ifndef NO_COLOR
                    942: /* This function is called during termination.  It resets color modes */
                    943: int ansiquit()
                    944: {
                    945:        /* if ANSI color terminal, then reset the colors */
                    946:        if (!strcmp(UP, "\033[A"))
                    947:        {
                    948:                tputs("\033[37;40m\033[m", 1, faddch);
                    949:                clrtoeol();
                    950:                return 1;
                    951:        }
                    952:        return 0;
                    953: }
                    954: 
                    955: /* This sets the color strings that work for ANSI terminals.  If the TERMCAP
                    956:  * doesn't look like an ANSI terminal, then it returns FALSE.  If the colors
                    957:  * aren't understood, it also returns FALSE.  If all goes well, it returns TRUE
                    958:  */
                    959: int ansicolor(cmode, attrbyte)
                    960:        int     cmode;          /* mode to set, e.g. A_NORMAL */
                    961:        int     attrbyte;       /* IBM PC attribute byte */
                    962: {
                    963:        char    temp[16];       /* hold the new mode string */
                    964: 
                    965:        /* if not ANSI-ish, then fail */
                    966:        if (strcmp(UP, "\033[A") && strcmp(UP, "\033OA"))
                    967:        {
                    968: #if COHERENT
                    969:                return 1;
                    970: #else
                    971:                msg("Don't know how to set colors for this terminal");
                    972:                return 0;
                    973: #endif
                    974:        }
                    975: 
                    976:        /* construct the color string */
                    977:        sprintf(temp, "\033[m\033[3%c;4%c%s%sm",
                    978:                "04261537"[attrbyte & 0x07],
                    979:                "04261537"[(attrbyte >> 4) & 0x07],
                    980:                (attrbyte & 0x08) ? ";1" : "",
                    981:                (attrbyte & 0x80) ? ";5" : "");
                    982: 
                    983:        /* stick it in the right place */
                    984:        switch (cmode)
                    985:        {
                    986:          case A_NORMAL:
                    987:                if (!strcmp(MEcolor, normalcolor))
                    988:                        strcpy(MEcolor, temp);
                    989:                if (!strcmp(UEcolor, normalcolor))
                    990:                        strcpy(UEcolor, temp);
                    991:                if (!strcmp(AEcolor, normalcolor))
                    992:                        strcpy(AEcolor, temp);
                    993:                if (!strcmp(SEcolor, normalcolor))
                    994:                        strcpy(SEcolor, temp);
                    995: 
                    996:                strcpy(normalcolor, temp);
                    997:                tputs(normalcolor, 1, faddch);
                    998:                break;
                    999: 
                   1000:          case A_BOLD:
                   1001:                strcpy(MDcolor, temp);
                   1002:                strcpy(MEcolor, normalcolor);
                   1003:                break;
                   1004: 
                   1005:          case A_UNDERLINE:
                   1006:                strcpy(UScolor, temp);
                   1007:                strcpy(UEcolor, normalcolor);
                   1008:                break;
                   1009: 
                   1010:          case A_ALTCHARSET:
                   1011:                strcpy(AScolor, temp);
                   1012:                strcpy(AEcolor, normalcolor);
                   1013:                break;
                   1014: 
                   1015:          case A_STANDOUT:
                   1016:                strcpy(SOcolor, temp);
                   1017:                strcpy(SEcolor, normalcolor);
                   1018:                break;
                   1019: 
                   1020: #ifndef NO_POPUP
                   1021:          case A_POPUP:
                   1022:                strcpy(POPUPcolor, temp);
                   1023:                break;
                   1024: #endif
                   1025: 
                   1026: #ifndef NO_VISIBLE
                   1027:          case A_VISIBLE:
                   1028:                strcpy(VISIBLEcolor, temp);
                   1029:                break;
                   1030: #endif
                   1031:        }
                   1032: 
                   1033:        return 1;
                   1034: }
                   1035: 
                   1036: 
                   1037: /* This function outputs the ESC sequence needed to switch the screen back
                   1038:  * to "normal" mode.  On color terminals which haven't had their color set
                   1039:  * yet, this is one of the termcap strings; for color terminals that really
                   1040:  * have had colors defined, we just the "normal color" escape sequence.
                   1041:  */
                   1042: int
                   1043: endcolor()
                   1044: {
                   1045:        if (aend == ME)
                   1046:                tputs(MEcolor, 1, faddch);
                   1047:        else if (aend == UE)
                   1048:                tputs(UEcolor, 1, faddch);
                   1049:        else if (aend == AE)
                   1050:                tputs(AEcolor, 1, faddch);
                   1051:        else if (aend == SE)
                   1052:                tputs(SEcolor, 1, faddch);
                   1053:        aend = "";
                   1054:        return 0;
                   1055: }
                   1056: 
                   1057: 
                   1058: #endif /* !NO_COLOR */

unix.superglobalmegacorp.com

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