Annotation of cci/usr/src/usr.bin/bsc/cmd/3270/emterm.c, revision 1.1.1.1

1.1       root        1: /*     D.L.Buck and Associates, Inc. - May, 1984
                      2:  *
                      3:  *     COPYRIGHT NOTICE:
                      4:  *             Copyright c 1984 - An unpublished work by 
                      5:  *             D.L.Buck and Associates, Inc.
                      6:  *
                      7:  *     PROPRIETARY RIGHTS NOTICE:
                      8:  *             All rights reserved. This document and program contains
                      9:  *             proprietary information of D.L.Buck and Associates,Inc.
                     10:  *             of San Jose, California, U.S.A., embodying confidential
                     11:  *             information,  ideas, and expressions,  no part of which
                     12:  *             may be reproduced, or transmitted in any form or by any
                     13:  *             means,  electronic,  mechanical,  or otherwise, without
                     14:  *             the written permission of D.L.Buck and Associates, Inc.
                     15:  *
                     16:  *     NAME
                     17:  *             emsetup 
                     18:  *     SYNOPSIS
                     19:  *             emsetup(term)
                     20:  *             char *term;
                     21:  *     DESCRIPTION
                     22:  *             NOTE: If terminal is to be managed, 'do_screen' must be
                     23:  *             set to a non-zero value. Otherwise, the package only
                     24:  *             manages the data structures fldstart, fldmax, fldattr,
                     25:  *             totfields, curfield, bufaddr, and cursaddr.
                     26:  *             emsetup() sets the terminal characteristics for emulation via
                     27:  *             ioctl, does keyboard mapping of special function keys via 
                     28:  *             termcap, initializes the window curses uses to manipulate
                     29:  *             the cursor and the screen image, and the data structures
                     30:  *             used to attend to the screen image.
                     31:  *
                     32:  *     ALGORITHM
                     33:  *             I. Initialize data structures
                     34:  *                     A. screen-image cross-indices and arrays
                     35:  *                     B. termcap key string structures and arrays
                     36:  *                      The function key structure tcts defines function key
                     37:  *                      name, where to find corresponding character string,
                     38:  *                      default character string value, and value to return
                     39:  *                      if that key has been pressed. 
                     40:  *                     C. terminal information structures
                     41:  *                      These are used to save the original terminal
                     42:  *                      characteristics and set the emulation characteristics.
                     43:  *     
                     44:  *             II. Set up function key table
                     45:  *                     A. assign values defined in tcts structure to the
                     46:  *                        function key table.
                     47:  *
                     48:  *             III. Get terminal information
                     49:  *                     A. terminal type
                     50:  *                     B. termcap entry
                     51:  *                      This is captured by tgetent(), which gets the 
                     52:  *                      terminal's termcap entry and saves it in a convenient
                     53:  *                      buffer.
                     54:  *                     C. get the number of lines, columns, and characters
                     55:  *                     added by the standout mode from the entry. 
                     56:  *                      This information is captured by tgetnum(), which
                     57:  *                      returns the numeric value for specified character-
                     58:  *                      istics.
                     59:  *                     D. put termcap's function key string values for each
                     60:  *                     function into the function table.
                     61:  *                      for each function key:
                     62:  *                             get its string value from termcap
                     63:  *                             (tgetstr() does this nicely)
                     64:  *             
                     65:  *                             if no value was assigned in termcap:
                     66:  *                                     assign function key's string to
                     67:  *                                     the default value contained in the
                     68:  *                                     table
                     69:  *                                     set its length to 1
                     70:  *                             else
                     71:  *                                     set the string value's length to
                     72:  *                                     the termcap string's length
                     73:  *
                     74:  *             III. Set terminal characteristics
                     75:  *                     A. do ioctls to get current characteristics
                     76:  *                     B. save terminal's characteristics and baud rate
                     77:  *                     C. set signal to call the cleanup routine if
                     78:  *                     interrupt encountered
                     79:  *                      cleanup() sets the original terminal characteristics
                     80:  *                      and exits
                     81:  *                     D. use ioctl to set the terminal characteristics for
                     82:  *                     3277 emulation.
                     83:  *
                     84:  *             IV. Initialize the curses window
                     85:  */
                     86: static char s_emterm[] = "@(#)CCIemterm.c      1.24 REL";
                     87: 
                     88: #include <em.h>
                     89: #include "local.h"
                     90: #include <signal.h>
                     91: #include <ctype.h>
                     92: #include <setjmp.h>
                     93: #ifndef v7
                     94: #ifndef DEBUG
                     95: #include <fcntl.h>
                     96: #endif
                     97: #endif
                     98: 
                     99: jmp_buf env;
                    100: int do_screen;                 /* Set if caller wants display managed */
                    101: extern int initflag;                   /* set if initscr called */
                    102: extern FILE *aud;
                    103: extern char audname[];
                    104: extern char new_audnm[];
                    105: extern char auditlock[];
                    106: extern WINDOW *curscr;
                    107: 
                    108: int fldstart[MAXFIELDS];       /* Index of starting position of each
                    109:                                   field's first data character.
                    110:                                   Attribute characters are immediately
                    111:                                   before each field. */
                    112: char fldattr[MAXFIELDS];       /* Attribute of each field */
                    113: int fldmax[MAXFIELDS];         /* Maximum width of each field */
                    114: int totfields;                 /* Total number of fields on screen */
                    115: int curfield;                  /* Current field number */
                    116: int bufaddr;                   /* Current buffer address, 0 to
                    117:                                           MAXSCREENSIZE-1 */
                    118: int cursaddr;                  /* Current cursor address, 0 to
                    119:                                   MAXSCREENSIZE-1 */
                    120: /* scrn_image is a replica of the current ASCII screen image, except that 
                    121:    attribute characters are replaced with ATTRCODE (see em.h) */
                    122: char scrn_image[MAXSCREENSIZE];
                    123: 
                    124: /* scrn_xref is a cross-reference into scrn_image. It contains the current
                    125:    field number corresponding to each screen location. 
                    126:    For example, a screen containing two fields, one beginning at screen
                    127:    position 10 and the other beginning at screen position 30, can be
                    128:    visualized as follows (top row of numbers represent screen positions):
                    129:     0        1         2         3         4         5 
                    130:     012345678901234567890123456789012345678901234567890...
                    131:     111111111122222222222222222222333333333333333333333...
                    132: 
                    133:    */
                    134: int scrn_xref[MAXSCREENSIZE];
                    135: 
                    136: /* status indicates 3277 terminal status */
                    137: int status;
                    138: 
                    139: WINDOW *stat_scr;
                    140: 
                    141: int sigalrm();         /* for dealing with v7 alarm signals */
                    142: 
                    143: int    COLS;   /* number of columns */
                    144: int    LINES;  /* # lines on screen */
                    145: int    SG;     /* # chars added by SO */
                    146: char   *SO;    /* standout character sequence */
                    147: char   *SE;    /* standend character sequence */
                    148: char   * S0;   /* ESC string */
                    149: char   * S1;   /* ENTER string */
                    150: char   * S2;   /* CLEAR string */
                    151: char   * S3;   /* BACKTAB string */
                    152: char   * S4;   /* ERASE_EOF string */
                    153: char   * S5;   /* ERASE_INP string */
                    154: char   * S6;   /* INS string */
                    155: char   * S7;   /* DELCHAR string */
                    156: char   * S8;   /* DUP string */
                    157: char   * S9;   /* FM string */
                    158: char   * bs;   /* bs key */
                    159: char   * cr;   /* cr key */
                    160: char   * kd;   /* down arrow key */
                    161: char   * kl;   /* left arrow key */
                    162: char   * kr;   /* right arrow key */
                    163: char   * ta;   /* tab key string */
                    164: char   * ku;   /* up arrow key */
                    165: char   * P1;   /* pf1 string */
                    166: char    * P2;  /* pf2 string */
                    167: char    * P3;   /* pf3 string */
                    168: char    * P4;  /* pf4 string */
                    169: char   * P5;   /* pf5 string */
                    170: char   * P6;   /* pf6 string */
                    171: char   * P7;   /* pf7 string */
                    172: char   * P8;   /* pf8 string */
                    173: char   * P9;   /* pf9 string */
                    174: char   * Pa;   /* pf10 string */
                    175: char   * Pb;   /* pf11 string */
                    176: char   * Pc;   /* pf12 string */
                    177: char   * A1;   /* pa1 string */
                    178: char   * A2;   /* pa2 string */
                    179: char   * A3;   /* pa3 string */
                    180: char   * SZ;   /* reset string */
                    181: char   * SH;   /* help string */
                    182: char   * ST;   /* statistics string */
                    183: char   * SP;   /* print string */
                    184: 
                    185: struct tcts    {
                    186:        char em_name[4];        /* name of item in termcap entry */
                    187:        char **em_s;            /* addr of addr of corresponding char string */
                    188:        char em_def;            /* default single char. if none in termcap */
                    189:        int em_keycode;         /* value to be returned to caller if this
                    190:                                   char. sequence arrives at the terminal */
                    191: };
                    192: struct tcts em_ktbl[] = {
                    193:         {"bs", &bs, 010, BACKSP},      /* bs key */
                    194:        {"cr", &cr, 015, CARRET},       /* CR key */
                    195:         {"kd", &kd, 012, DOWN},                /* down arrow key */
                    196:         {"kl", &kl, 010, LEFT},                /* left arrow key */
                    197:         {"kr", &kr, 014, RIGHT},       /* right arrow key */
                    198:         {"ku", &ku, 013, UPAR},                /* up arrow key */
                    199:         {"ta", &ta, 011, TAB},         /* tab key */
                    200:         {"S0", &S0, 033, ESC},         /* escape key */
                    201:         {"S1", &S1, 016, ENTER},       /* enter key */
                    202:         {"S2", &S2, 017, CLEAR},       /* clear key */
                    203:         {"S3", &S3, 025, BACKTAB},     /* backtab string*/
                    204:         {"S4", &S4, 031, ERASE_EOF},   /* erase eof string */
                    205:         {"S5", &S5, 020, ERASE_INP},   /* erase input string*/
                    206:         {"S6", &S6, 036, INS},         /* insert string */
                    207:         {"S7", &S7, 0177, DELCHR},     /* delete character string */
                    208:         {"S8", &S8, 034, DUP},         /* duplicate op. string */
                    209:         {"S9", &S9, 035, FM},          /* field mark key */
                    210:        {"P1", &P1, 021, PF1},          /* program function key 1 */
                    211:        {"P2", &P2, 027, PF2},          /* program function key 2 */
                    212:        {"P3", &P3, 005, PF3},          /* program function key 3 */
                    213:        {"P4", &P4, 022, PF4},          /* program function key 4 */
                    214:        {"P5", &P5, 024, PF5},          /* program function key 5 */
                    215:        {"P6", &P6, 001, PF6},          /* program function key 6 */
                    216:        {"P7", &P7, 023, PF7},          /* program function key 7 */
                    217:        {"P8", &P8, 004, PF8},          /* program function key 8 */
                    218:        {"P9", &P9, 006, PF9},          /* program function key 9 */
                    219:        {"Pa", &Pa, 007, PF10},         /* program function key 10 */
                    220:        {"Pb", &Pb, 026, PF11},         /* program function key 11 */
                    221:        {"Pc", &Pc, 002, PF12},         /* program function key 12 */
                    222:        {"A1", &A1, 032, PA1},          /* program attention key 1 */
                    223:        {"A2", &A2, 030, PA2},          /* program attention key 2 */
                    224:        {"A3", &A3, 003, PA3},          /* program attention key 3 */
                    225:        {"SZ", &SZ, 0, RESET},          /* reset key */
                    226:        {"SH", &SH, 0, HELP},           /* help key */
                    227:        {"ST", &ST, 0, STATS},          /* statistics key */
                    228:        {"SP", &SP, 0, PRINT},          /* print key */
                    229:         {"", (char **)0, 000, 0}       /* end of list */
                    230:        };
                    231: 
                    232: #ifdef v7
                    233: struct tchars origtchar, termtchar;
                    234: struct sgttyb origtio, termio;
                    235: struct ltchars olchars, lchars;
                    236: #else
                    237: struct termio origtio, termio;
                    238: #endif
                    239: 
                    240: char emarea[256], *emaptr = emarea;
                    241: 
                    242: /*
                    243:  *     The following character array, `kytrt', is used by the `getchar'
                    244:  *     routine to translate incoming keystrokes into 3270 keystrokes.
                    245:  *     It is built by examining the TERMCAP entry for this terminal
                    246:  *     for all special keystroke sequences.
                    247:  *     The resulting table has one element per ASCII character; the
                    248:  *     first incoming ASCII character is matched against this table,
                    249:  *     with the following results:
                    250:  *             kytrt[c] == 0   Not a special keystroke
                    251:  *             kytrt[c] == n, n <> 0   Special keystroke of max n chars
                    252:  */
                    253: char kytrt[128];       /* function key trt table */
                    254: 
                    255: #define max(a,b)       ((a) > (b)?(a):(b))
                    256: 
                    257: emsetup(term)          /* set up terminal attributes via em_ktbl */
                    258: char *term;
                    259: {
                    260:        register struct tcts *tps;      /* pointer into em_ktbl */
                    261:        register char *sp;              /* key string pointer */
                    262:        char tbuf[2048];                /* buffer for tgetent */
                    263:        char tname[20];
                    264:        int ans;                        /* answer to help ? goes here */
                    265:        int cleanwin();                 /* cleanup before exiting */
                    266: 
                    267:        /* tgetstr() gets the capability string for a particular function key
                    268:           from the termcap database entry for this terminal. It decodes the
                    269:           abbreviations used by termcap, returns the key string which
                    270:           performs the function desired, and places it in a buffer
                    271:           (emarea is used here).
                    272:           for example, tgets for the clear screen function key on a
                    273:           Zentec 8001 terminal would get:
                    274:                cl=\EH\EJ
                    275:           from /etc/termcap, and return the key sequence escape-H escape-J,
                    276:           which clears the screen. */
                    277:        char *tgetstr();
                    278:        int cleanup();
                    279: 
                    280:        if (term == (char *) 0) term = "dumb";
                    281:        if (term[0] == '\0') term = "dumb";
                    282: 
                    283:        if (tgetent(tbuf, term) != 1)   {
                    284:                fprintf(stderr,"em3277: terminal type <%s> unknown\n",
                    285:                        term);
                    286:                return(1);
                    287:        }
                    288: 
                    289:        /* tgetnum is the numeric version of tgetstr -- it get the numeric
                    290:         * value of the capability named from the /etc/termcap entry for this
                    291:         * terminal. */
                    292:        LINES = tgetnum("li");
                    293:        COLS = tgetnum("co");
                    294:        SG = tgetnum("sg");
                    295:        if (SG == -1)
                    296:                SG = 0;
                    297: 
                    298:        for (tps = em_ktbl; tps->em_name[0]; ++tps)     {
                    299:                sp = *tps->em_s = tgetstr(tps->em_name,&emaptr);
                    300:                if (sp == (char *)0)    {       /* doesn't appear - default */
                    301:                        *tps->em_s = &tps->em_def;
                    302:                        kytrt[tps->em_def] = 1; /* def. string is one char */
                    303:                } else
                    304:                        kytrt[*sp] = max(strlen(sp), kytrt[*sp]);
                    305:        }
                    306: 
                    307: /* get standout, standend sequences */
                    308:        SO = tgetstr("so", &emaptr);
                    309:        SE = tgetstr("se", &emaptr);
                    310: 
                    311: #ifdef v7
                    312:        ioctl (0, TIOCGETC, &origtchar);
                    313:        ioctl (0, TIOCGETP, &origtio);
                    314:        ioctl (0, TIOCGLTC, &olchars);
                    315: #else
                    316:        ioctl(0,TCGETA, &origtio);
                    317: #endif
                    318: 
                    319:        signal(SIGHUP,cleanwin);
                    320:        signal(SIGTERM,cleanwin);
                    321:        cursaddr = 0;
                    322:        if (do_screen)  {       /* screen to be managed */
                    323:                My_term = TRUE; /* force curses to use stdout */
                    324:                Def_term = term;
                    325:                gettmode();
                    326:                initscr();      /* set up virtual terminal screen */
                    327:                initflag = 1;   /* initscr has been called */
                    328:                crmode();       /* set cbreak mode */
                    329:                noecho();       /* turn off echo */
                    330:                nonl();         /* turn off cr-lf mapping */
                    331:                clearok(curscr,TRUE);   /* clear screen next refresh */
                    332:        /* Set up our 24x80 terminal screen */
                    333:                vterm_scr = newwin(24,80,0,0);
                    334:                wmove(vterm_scr,0,0);
                    335:                werase(vterm_scr);
                    336:                wrefresh(vterm_scr);
                    337:                clearok(curscr,FALSE);
                    338: 
                    339:        /* initialize help screen */
                    340:                help_scr = newwin(24,80,0,0);
                    341:                wmove(help_scr,0,0);
                    342:                werase(help_scr);
                    343: 
                    344:        /* fill with keyboard map */
                    345:                tgetent(tbuf, term);
                    346:                helpinit(term);
                    347: 
                    348:        /* set up hidden subwindow behind status and command area */
                    349:                sub_vterm = subwin(vterm_scr,2,80,22,0);
                    350: 
                    351:        /* set up command window */
                    352:                cmd_scr = newwin(1,80,LINES-1,0);
                    353:                wmove(cmd_scr,0,0);
                    354:                werase(cmd_scr);
                    355: 
                    356:        /* set up status window */
                    357:                stat_scr = newwin(1,80,LINES-2,0);
                    358:                wmove(stat_scr,0,0);
                    359:                werase(stat_scr);
                    360: 
                    361:        /* disable interrupts */
                    362: #ifdef v7
                    363:                ioctl (0, TIOCGETC, &termtchar);
                    364:                termtchar.t_intrc = -1;         /* disable DEL as INTR */
                    365:                ioctl (0, TIOCSETC, &termtchar);
                    366:                ioctl (0, TIOCGETP, &termio);
                    367:                ioctl (0, TIOCGLTC, &lchars);
                    368:                lchars.t_suspc = -1;
                    369:                ioctl (0, TIOCSLTC, &lchars);
                    370: #else
                    371:                ioctl(0, TCGETA, &termio);
                    372:                termio.c_cc[VINTR] = -1;        /* disable DEL as INTR */
                    373:                termio.c_iflag |= BRKINT;       /* break key is reset */
                    374:                termio.c_iflag &= ~IXON;        /* disable xon, xoff */
                    375:                ioctl(0,TCSETA, &termio);
                    376: #endif
                    377:                signal(SIGALRM,sigalrm);
                    378:        /* ask if user wants a keyboard map */
                    379:                wstandout(vterm_scr);
                    380:                mvwaddstr(vterm_scr,0,0,"Would you like help? (Y/N):");
                    381:                wmove(vterm_scr,0,30);
                    382:                wstandend(vterm_scr);
                    383:                wrefresh(vterm_scr);
                    384:                while((ans=emgetchar()) == NOCHAR)      continue;
                    385:                if (ans == 'y' || ans == 'Y')   {
                    386:                        werase(vterm_scr);
                    387:                        em_help();
                    388:                }
                    389: 
                    390:                clearok(curscr,TRUE);
                    391:        }
                    392: 
                    393:        return(0);
                    394: }
                    395: 
                    396: /* emgetchar() - get a character keyed in at the terminal and process it
                    397:  *              Called from emulate().
                    398:  *
                    399:  * ALGORITHM
                    400:  *     I. Read the character into a temporary character buffer, cbuf
                    401:  *     II. If nothing was read in, return NOCHAR
                    402:  *     III. If read returned -1, return ERROR
                    403:  *     IV. If character read in has a value in the key length array, it's
                    404:  *         a special function key character. Process it:
                    405:  *             A. for the length specified, read characters into cbuf
                    406:  *             B. search through the function key table for a string value
                    407:  *                match.
                    408:  *             C. if a match is found, return the function key code specified
                    409:  *                in the function key table.
                    410:  *             D. If no match is found, return OTHER.
                    411:  *     V. If the character is not a special function key, process it:
                    412:  *             A. if it's printable, return it
                    413:  *             B. otherwise, return OTHER
                    414:  *     VI. return
                    415:  */
                    416: #define ERROR -1
                    417: extern int errno;
                    418: 
                    419: int emgetchar()
                    420: {
                    421:        register int nread;     
                    422:        register char cc;
                    423:        register struct tcts *em_kyptr;         /* ptr into em_ktbl */
                    424:        register char *s;
                    425:        extern char kytrt[];
                    426:        char cbuf[10];
                    427:        int nmax,nhave;
                    428: 
                    429:        if(setjmp(env) == 0) {
                    430:                alarm(1);
                    431:                nread = read(0,cbuf,1);
                    432:                alarm(0);
                    433:        }
                    434:        else
                    435:                return NOCHAR;
                    436: 
                    437:        if (nread < 0 && errno == EINTR)  return NOCHAR;
                    438:        if (nread < 0) return ERROR;
                    439:        if (nread == 0)
                    440:                return NOCHAR;
                    441:        cc = cbuf[0];
                    442:        nhave = nread;
                    443:        if (nmax = kytrt[cc]) { /* Special keystroke sequence indicated */
                    444:                while (nread > 0) {
                    445:                        /* Search em_ktbl for sequence of this length   */
                    446:                        cbuf[nhave] = '\0';     /* Null-terminate       */
                    447:                        for (em_kyptr = em_ktbl; em_kyptr->em_s; em_kyptr++)
                    448:                                if (strcmp(*(em_kyptr->em_s),cbuf)==0)  {
                    449:                                        return em_kyptr->em_keycode;
                    450:                                }
                    451:                        if (nhave >= nmax)
                    452:                                return OTHER;
                    453:                        nread = read(0, &cbuf[nhave], nmax-nhave);
                    454:                        nhave += nread;
                    455:                        cbuf[nhave] = '\0';
                    456:                }
                    457:                if (nread < 0)
                    458:                        return ERROR;
                    459:                if (nread == 0)
                    460:                        return NOCHAR;
                    461:        }
                    462: 
                    463:        if (isprint(cc) || cc == ' ')
                    464:                return cc;
                    465:        else    return OTHER;
                    466: }
                    467: 
                    468: /* cleanwin() - clean up before exiting em3277.
                    469:  *
                    470:  *     ALGORITHM
                    471:  *             I. Finish off curses routines and  close the window
                    472:  *             II. Reset the terminal characteristics to their original
                    473:  *                 values
                    474:  *             III. Remove temp audit files, lock files, ...
                    475:  */
                    476: 
                    477: cleanwin()
                    478: {
                    479:        if (initflag)  {
                    480: 
                    481:                endwin();
                    482:        /* reset original terminal characteristics */
                    483: #ifdef v7
                    484:                ioctl (0, TIOCSETC, &origtchar);
                    485:                ioctl (0, TIOCSETP, &origtio);
                    486:                ioctl (0, TIOCSLTC, &olchars);
                    487: #else
                    488:                ioctl(0,TCSETA, &origtio);
                    489: #endif
                    490:        }
                    491: /* remove temp audit files, lock files, etc.. */
                    492:        if (aud)        {
                    493:                fclose(aud);
                    494:                if (link(audname,new_audnm) >= 0)
                    495:                        unlink(audname);
                    496:                unlink(auditlock);
                    497:        }
                    498: }
                    499: 
                    500: /* cleanup -- clean up before exiting em3277 */
                    501: cleanup()
                    502: {
                    503:        cleanwin();
                    504:        write(1,"\n",1);        /* make screen pretty before leaving */
                    505:        exit(0);
                    506: }
                    507: 
                    508: /* update the keyboard status */
                    509: updstat(val)
                    510: register int val;
                    511: {
                    512:        status = val;
                    513:        werase(stat_scr);
                    514: 
                    515:        wstandout(stat_scr);
                    516:        if (status & LOCK_OUT)
                    517:                mvwaddstr(stat_scr,0,0,"Input Inhibited");
                    518:        if (status & SYS_AVAIL)
                    519:                mvwaddstr(stat_scr,0,20,"System Available");
                    520:        if (status & INSERT_MODE)
                    521:                mvwaddstr(stat_scr,0,40,"Insert Mode");
                    522:        touchwin(stat_scr);
                    523:        wstandend(stat_scr);
                    524:        wrefresh(stat_scr);
                    525: }
                    526: 
                    527: /* sigalrm -- reset alarm signal (for no-delay reading under v7) */
                    528: sigalrm()
                    529: {
                    530:        signal(SIGALRM,sigalrm);
                    531:        longjmp(env,1);
                    532: }

unix.superglobalmegacorp.com

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