|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.