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

unix.superglobalmegacorp.com

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