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