|
|
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.