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