|
|
1.1 root 1: /* D.L.Buck and Associates, Inc. - 84/08/27
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: * emulate
18: *
19: * SYNOPSIS
20: * emulate()
21: *
22: * DESCRIPTION
23: * emulate is the 3277 emulation routine. User input, including PF and
24: * PA key handling and cursor movement, and special commands are handled
25: * here. emulate is called by em3277.
26: */
27:
28: #include "local.h"
29: #include <signal.h>
30: #include <bsc/bscio.h>
31: #include <em.h>
32:
33: #define ERROR -1
34: #define CMDPRE 033 /* indicates a command code follows */
35: #define RDMOD '6' /* read modified command */
36: #define RDBUF '2' /* read buffer command */
37:
38: #ifndef lint
39: static char sccsid[] = "@(#)emulate.c 1.34 REL";
40: #endif
41:
42: extern long dev_navail();
43:
44: /* statistics variables */
45: static int first = 1;
46: extern int rb_ctr; /* received blocks counter */
47: extern int ascii; /* 1=ascii code, 0=ebcdic code */
48: int rsp_ctr; /* response counter */
49: int trax_ctr; /* transaction counter */
50: long atm; /* used to compute response and transaction time */
51: long btm; /* used to compute response time */
52: long ctm; /* used to compute transaction time */
53: long lrsp_tm; /* last request's response time */
54: long rsp_tm; /* used to accumulate total response time */
55: long trax_tm; /* used to accumulate total transaction time */
56: long ltrax_tm; /* last request's transaction time */
57: long times();
58: extern struct tbuffer {
59: long utime;
60: long stime;
61: long cutime;
62: long cstime;
63: } rspbuf;
64:
65: extern char aaid_tbl[]; /* ascii aid encoding table - found in emreadmod */
66: extern char eaid_tbl[]; /* ebcdic aid encoding table - found in emreadmod */
67:
68: extern char *SO; /* standout sequence for this terminal */
69: extern char *SE; /* standend sequence for this terminal */
70:
71: /* myscr[10240+5] makes sure there's room for characters leftover from the last
72: buffer processing (emprocbuf) at the beginning of this buffer. E.g.
73: an SBA came across in the last buffer and the 2-byte address supposed
74: to be attached to it didn't */
75: char myscr[10240+5];
76: extern int devfd;
77: extern int errno;
78: extern struct bscio gp;
79: int pr_ok = 1; /* 1=ok to print; 0=ignore print commands */
80:
81: char aid_val;
82: int lastkey; /* contains last PF or PA key entered */
83: emulate()
84: {
85: int emgetchar();
86: int grabbed;
87: register int len; /* number of chars read in thru devfd */
88: int f;
89: int count;
90: register int endfld;
91: register int stat;
92: int i; /* index */
93: int ocursaddr;
94: int termreset(); /* reset input inhibited terminal status */
95: register char chr;
96: register char *myptr;
97: register int mylen;
98: register int mysize;
99:
100: char rdchk[2]; /* 1st 2 chars of each received buffer
101: go here to check for read modified
102: and read buffer commands from the
103: remote host. */
104: signal(SIGINT,termreset);
105: updstat(MYJOB);
106: aid_val = ascii?0x2d:0x60;
107: lastkey = 0;
108: #ifdef DEBUG
109: f = open("procbuf",0);
110: #endif
111: fiximage(0); /* Initialize screen variables */
112:
113: while (1) { /* Until Quit Command entered ... */
114: myptr = &myscr[5];
115: mysize = sizeof myscr - 5;
116: mylen = 0;
117: /* read from the comm device */
118: READ:
119: #ifdef DEBUG
120: read(f, &count, sizeof count);
121: len = read(f, &myscr[5], count);
122: if (len < 0)
123: exit(0);
124: if (len > 0) {
125: ++rb_ctr;
126: mylen = len;
127: btm = times(&rspbuf);
128: if (atm) {
129: ++rsp_ctr;
130: lrsp_tm = btm - atm;
131: rsp_tm += lrsp_tm;
132: }
133: }
134: #else
135: while ((len = read(devfd,myptr,mysize)) > 0 &&
136: mysize > 0) {
137: rdchk[0] = myptr[0]; /* Save 1st 2 bytes */
138: rdchk[1] = myptr[1];
139: myptr += len;
140: mysize -= len;
141: mylen += len;
142:
143: /* check for read modified or read buffer command from host --
144: if there, call emreadmod() or emreadbuf() immediately, then
145: go back to the top of the read routine. */
146: /*** rdchk[0] = myscr[5]; rdchk[1] = myscr[6]; ***/
147: if (!ascii)
148: ebcasc(rdchk,2);
149: if (mylen &&
150: (rdchk[0]==CMDPRE &&
151: (rdchk[1]==RDMOD || rdchk[1]==RDBUF))) {
152: updstat(status | SYS_AVAIL);
153: /* Did we recv. anything before RDMOD or RDBUF? */
154: /* by checking if they are at the beginning of buf */
155: /* then&dai 5/51/85 */
156: if ( (myptr-2) != &myscr[5]) {
157: mylen -= 2;
158: emprocbuf(&myscr[5],mylen);
159: }
160: if (rdchk[1] == RDMOD)
161: emreadmod(lastkey);
162: else
163: emreadbuf();
164: goto lupe;
165: }
166: ++rb_ctr;
167: }
168: #endif
169: if (len < 0 && (errno == EINTR || errno == EAGAIN) &&
170: mylen != 0) goto READ;
171:
172: if (len < 0) { /* Check out nature of error */
173: get_errors();
174: /* Any serious errors? */
175: if (gp.b_flags == BSCNDSR ||
176: gp.b_flags == BSCTXTO ||
177: gp.b_flags == BSCNBID)
178: return(-1);
179: }
180:
181: if (mylen) {
182: ctm = times(&rspbuf);
183: emprocbuf(&myscr[5],mylen);
184: if (atm) {
185: ltrax_tm = ctm - atm;
186: trax_tm += ltrax_tm;
187: ++trax_ctr;
188: atm = 0L;
189: }
190: if (do_screen && !(status & LOCK_OUT)) {
191: if (LINES <= 24) {
192: touchwin(sub_vterm);
193: wrefresh(sub_vterm);
194: }
195: wmove(vterm_scr,ROW,COL);
196: wrefresh(vterm_scr);
197: }
198: }
199: if (first) {
200: first = 0;
201: grabbed = CLEAR;
202: }
203: else grabbed = emgetchar();
204: if (grabbed == NOCHAR)
205: continue;
206: if ((status & LOCK_OUT) && grabbed != ESC &&
207: grabbed != ERASE_INP && grabbed != RESET)
208: continue;
209: switch(grabbed) {
210: case OTHER:
211: break;
212: case NOCHAR:
213: break;
214: case ERROR:
215: return(-1);
216: case CARRET:
217: cursaddr += (SCREENWIDTH - COL);
218: if (cursaddr >= (MAXSCREENSIZE - 1))
219: cursaddr = 0;
220: if (scrn_image[cursaddr] == (char)ATTRCODE)
221: ++cursaddr;
222: curfield = scrn_xref[cursaddr];
223: if (prot_attr(fldattr[curfield])) goto tabtime;
224: break;
225: case BACKSP:
226: case LEFT:
227: if (--cursaddr < 0)
228: cursaddr = MAXSCREENSIZE - 1;
229: break;
230: case DOWN:
231: cursaddr += SCREENWIDTH;
232: if (cursaddr >= MAXSCREENSIZE)
233: cursaddr -= MAXSCREENSIZE;
234: break;
235: case UPAR:
236: if ((cursaddr -= SCREENWIDTH) < 0)
237: cursaddr += MAXSCREENSIZE;
238: break;
239: case RIGHT:
240: if (++cursaddr >= MAXSCREENSIZE)
241: cursaddr = 0;
242: break;
243: case DELCHR:
244: /* Delete one character at cursaddr, moving
245: * characters within the same field and on
246: * the same line to the left one position,
247: * filling in the rightmost vacated position
248: * with a NULL character.
249: * 1. Check field for protected, or cursaddr
250: * being on attribute character.
251: */
252: if (i = fldcheck())
253: goto STAT_CHK;
254: /* 2. Calculate location of last field position. */
255: endfld=fldstart[curfield] + (fldmax[curfield]-1);
256: if (endfld > MAXSCREENSIZE)
257: endfld -= MAXSCREENSIZE;
258: /* 3. If field continues on next line, stop at */
259: /* end of this line. */
260: if ((endfld/SCREENWIDTH) != ROW)
261: endfld = cursaddr + (SCREENWIDTH - COL)-1;
262: ocursaddr = cursaddr;
263: /* 4. If field highlighted, change screen mode */
264: if (do_screen)
265: if (hl_attr(fldattr[curfield]))
266: wstandout(vterm_scr);
267: else
268: wstandend(vterm_scr);
269: /* 5. Begin moving characters left to endfield */
270: do {
271: if (cursaddr == endfld) break;
272: if (cursaddr+1 > MAXSCREENSIZE)
273: chr = scrn_image[0];
274: else chr = scrn_image[cursaddr+1];
275: scrn_image[cursaddr] = chr;
276: if (do_screen) {
277: if (chr == '\0')
278: chr = ' ';
279: else if (chr == 0x1c)
280: chr = '*'; /* DUP */
281: else if (chr == 0x1e)
282: chr = ';'; /* FM */
283: if (!invis_attr(fldattr[curfield]))
284: mvwaddch(vterm_scr,ROW,COL,chr);
285: }
286: if (++cursaddr > MAXSCREENSIZE)
287: cursaddr = 0;
288: } while (cursaddr != endfld);
289: /* 6. Null at end of field; mark as modified. */
290: if (do_screen) {
291: mvwaddch(vterm_scr,ROW,COL,' ');
292: wstandend(vterm_scr);
293: }
294: scrn_image[cursaddr] = '\0';
295: cursaddr = ocursaddr;
296: fldattr[curfield] = fldattr[curfield] | ATTRMDT;
297: break;
298:
299: case DUP:
300: if (i = emputchar(grabbed))
301: goto STAT_CHK;
302: /* If ok, fall through to TAB */
303: case TAB:
304: tabtime:
305: if (!unprotected) { /* no unprotected fields */
306: cursaddr = 0;
307: break;
308: }
309: tabloop:
310: if (++curfield >= totfields)
311: curfield = 0;
312: if (prot_attr(fldattr[curfield]))
313: goto tabloop;
314: cursaddr = fldstart[curfield];
315:
316: break;
317: case BACKTAB:
318: backtabtime:
319: if (!unprotected) {
320: cursaddr = 0;
321: break;
322: }
323: if (!prot_attr(fldattr[curfield]) &&
324: cursaddr != fldstart[curfield]) {
325: cursaddr = fldstart[curfield];
326: break;
327: }
328: btabloop:
329: if (--curfield < 0)
330: curfield = totfields-1;
331: if (prot_attr(fldattr[curfield]))
332: goto btabloop;
333:
334: cursaddr = fldstart[curfield];
335: break;
336: case ERASE_EOF: /* erase to eofield */
337: if (i = fldcheck())
338: goto STAT_CHK;
339: ocursaddr = cursaddr;
340: cursaddr = fldstart[curfield]+fldmax[curfield]-1;
341: if (cursaddr>=MAXSCREENSIZE)
342: cursaddr-=MAXSCREENSIZE;
343: do {
344: scrn_image[cursaddr] = '\0';
345: if (do_screen &&
346: (cursaddr != (MAXSCREENSIZE-1)))
347: mvwaddch(vterm_scr,ROW,COL,' ');
348: if (cursaddr == ocursaddr) break;
349: --cursaddr;
350: if (cursaddr < 0)
351: cursaddr+=MAXSCREENSIZE;
352: }
353: while(1);
354: break;
355: case ERASE_INP: /* erase all unprotected input */
356: updstat(status & LOCK_OUT);
357: aid_val = ascii?0x2d:0x60;
358: lastkey = 0;
359: for (cursaddr=0;cursaddr<=MAXSCREENSIZE-1; ++cursaddr) {
360: curfield = scrn_xref[cursaddr];
361: if (prot_attr(fldattr[curfield]) ||
362: scrn_image[cursaddr] == ATTRCODE)
363: continue;
364: scrn_image[cursaddr] = '\0';
365: if (do_screen)
366: mvwaddch(vterm_scr,ROW,COL,' ');
367: }
368: curfield = totfields;
369: goto tabtime;
370: break;
371: case INS:
372: if (LINES <= 24)
373: status |= INSERT_MODE;
374: else
375: updstat(status | INSERT_MODE);
376: break;
377: case CLEAR:
378: for (cursaddr=0; cursaddr<MAXSCREENSIZE; ++cursaddr)
379: scrn_image[cursaddr] = '\0';
380: cursaddr = 0;
381: fiximage(0);
382: if (do_screen) {
383: wmove(vterm_scr,0,0);
384: /* if # of lines on screen <= 24, do werase; otherwise,
385: do clear to end of line for 24 lines to avoid losing
386: messages */
387: if (LINES <= 24) {
388: werase(vterm_scr);
389: clearok(curscr,TRUE);
390: }
391: else {
392: for (i=0; i<24; ++i) {
393: wmove(vterm_scr,i,0);
394: wclrtoeol(vterm_scr);
395: }
396: }
397: wrefresh(vterm_scr);
398: }
399: case ENTER:
400: case PF1:
401: case PF2:
402: case PF3:
403: case PF4:
404: case PF5:
405: case PF6:
406: case PF7:
407: case PF8:
408: case PF9:
409: case PF10:
410: case PF11:
411: case PF12:
412: case PA1:
413: case PA2:
414: case PA3:
415: btm = 0L; /* init trax/rsp time counters */
416: ctm = 0L;
417: atm = times(&rspbuf);
418: updstat((status | INPUT_INH) & ~SYS_AVAIL);
419: /* figure out what AID value is and set it */
420: aid_val = (ascii?aaid_tbl:eaid_tbl)[grabbed - ENTER];
421: lastkey = grabbed;
422: #ifndef DEBUG
423: emreadmod(grabbed);
424: #endif
425: break;
426: case ESC:
427: /* process keyboard commands: keyboard status reset,
428: print instructions, test request, end of session */
429: updstat(status & ~MYJOB);
430: if (key_cmds()) return;
431: if (LINES > 24)
432: updstat(status | MYJOB);
433: else
434: status |= MYJOB;
435: break;
436: case RESET:
437: updstat(status & ~LOCK_OUT & ~ INSERT_MODE);
438: aid_val = ascii?0x2d:0x60;
439: lastkey = 0;
440: if (do_screen && (LINES <= 24)) {
441: touchwin(sub_vterm);
442: wrefresh(sub_vterm);
443: }
444: break;
445: case STATS:
446: if (!do_screen)
447: break;
448: emstats(0);
449: mvwaddstr(cmd_scr,0,67,"Press Return");
450: wrefresh(cmd_scr);
451: while ((grabbed=emgetchar()) == NOCHAR) ;
452: wclear(cmd_scr);
453: wrefresh(cmd_scr);
454: if (LINES <= 24) {
455: touchwin(sub_vterm);
456: wrefresh(sub_vterm);
457: }
458: break;
459: case PRINT: /* print currently-displayed screen */
460: if (pr_ok) emprint(0); /* print, inserting newlines
461: every 80 characters if none
462: found before then */
463: break;
464: case HELP: /* display keyboard map */
465: if (!do_screen)
466: break;
467: em_help();
468: break;
469: default:
470: usual: if (i = emputchar(grabbed)) { /* error encountered */
471: STAT_CHK:
472: switch (i) {
473: case NORMAL:
474: break;
475: case NUMERIC: updstat(status | NUM_ONLY);
476: break;
477: case ATTR_CHAR:
478: case PROTECTED: updstat(status | GO_ELSE);
479: break;
480: case FLD_FULL: updstat(status | MORE_THAN);
481: break;
482: default:
483: break;
484: }
485: goto lupe;
486: } else {
487: if (++cursaddr >= MAXSCREENSIZE)
488: cursaddr = 0;
489: curfield = scrn_xref[cursaddr];
490: if (scrn_image[cursaddr] == (char)ATTRCODE &&
491: !(status & INSERT_MODE)) {
492: if (skip_attr(fldattr[curfield]))
493: goto tabtime;
494: if (++cursaddr >= MAXSCREENSIZE)
495: cursaddr = 0;
496: }
497: }
498: };
499: /* decide what field you're on by checking cursaddr with scrn_xref */
500: lupe:
501: curfield = scrn_xref[cursaddr];
502: if (do_screen) {
503: if (LINES > 24 || (status & LOCK_OUT))
504: updstat (status);
505: wmove(vterm_scr,ROW,COL);
506: wrefresh(vterm_scr);
507: }
508: }
509: }
510:
511: /* process keyboard commands: reset keyboard status, test request, print
512: instruction, end of session */
513: extern char ptype;
514: extern char pr_dest[];
515: #ifdef v7
516: extern struct tchars termtchar, origtchar;
517: extern struct sgttyb termio, origtio;
518: #endif
519: #ifndef v7
520: extern struct termio origtio, termio;
521: #endif
522: extern char *termtype;
523: char cmd[100];
524:
525: key_cmds()
526: {
527: char *emgetstr(); /* get a command string */
528: register int i; /* index */
529:
530: while (1) {
531: /* get and set terminal modes */
532: wstandout(cmd_scr);
533: wmove(cmd_scr,0,0);
534: werase(cmd_scr);
535: mvwaddstr(cmd_scr,0,0,"Command: ");
536: touchwin(cmd_scr);
537: wrefresh(cmd_scr);
538:
539: emgetstr(cmd);
540:
541: switch(cmd[0]) {
542: case 'h': /* help -- display keyboard map again */
543: em_help();
544: break;
545: case '!': /* execute one shell command */
546: #ifdef v7
547: ioctl(0,TIOCSETC,&origtchar);
548: ioctl(0, TIOCSETP, &origtio);
549: #else
550: ioctl(0,TCSETA,&origtio);
551: #endif
552: /* write standout sequence to terminal */
553: puts(SO);
554: system(&cmd[1]);
555: write (1,"\nPress Return to Continue:",26);
556: read(0, cmd, sizeof cmd);
557: puts(SE);
558: #ifdef v7
559: ioctl(0,TIOCSETC,&termtchar);
560: ioctl(0, TIOCSETP, &termio);
561: #else
562: ioctl(0,TCSETA,&termio);
563: #endif
564: clearok(curscr,TRUE);
565: touchwin(vterm_scr);
566: wrefresh(vterm_scr);
567: break;
568:
569: case 'p': /* invoke print modes */
570: switch(cmd[1]) {
571: case 'd': /* ignore print commands */
572: pr_ok = 0;
573: break;
574: case 'p': /* save print destination name */
575: case 'f':
576: ptype = (cmd[1]=='p')?'p':'f';
577: strcpy(pr_dest,&cmd[2]);
578: break;
579: case '\0':
580: case 'r': /* copy screen to printer */
581: if (pr_ok)
582: emprint(0); /* insert nl every 80 chars */
583: break;
584: default:
585: mvwaddstr(cmd_scr,0,30,
586: "Valid print commands: p,pd,pf,pp,pr");
587: break;
588: };
589: mvwaddstr(cmd_scr,0,67,"Press Return");
590: wrefresh(cmd_scr);
591: while ((cmd[0] = emgetchar()) == NOCHAR) ;
592: break;
593: case 'r': /* reset status (clear input inhibit) */
594: updstat(status & ~LOCK_OUT & ~INSERT_MODE);
595: aid_val = ascii?0x2d:0x60;
596: lastkey = 0;
597: break;
598: case 'e': /* send msg: dev. not available then quit */
599: emstats(1);
600: dev_navail();
601: return(1);
602: case 'q': /* get session statistics and quit */
603: emstats(1);
604: return(1);
605:
606: case 's': /* statistics */
607: emstats(0);
608:
609: mvwaddstr(cmd_scr,0,67,"Press Return");
610: wrefresh(cmd_scr);
611: while ((cmd[0] = emgetchar()) == NOCHAR) ;
612: break;
613:
614: case 't':
615: btm = 0L;
616: ctm = 0L;
617: atm = times(&rspbuf);
618: updstat(status | INPUT_INH);
619: emreadmod(TESTREQ); /* test request key */
620: aid_val = ascii?0x30:0xf0; /* reset aid value */
621: lastkey = TESTREQ; /*** changed from 0 ttl ***/
622: btm = times(&rspbuf);
623: lrsp_tm = btm - atm;
624: rsp_tm += lrsp_tm;
625: ++rsp_ctr;
626:
627: mvwaddstr(cmd_scr,0,67,"Press Return");
628: wrefresh(cmd_scr);
629: while ((cmd[0] = emgetchar()) == NOCHAR) ;
630: break;
631:
632: case '\0': /* no more cmds if getstr got a null -- return */
633: wstandout(cmd_scr);
634: wmove(cmd_scr,0,0);
635: wclrtoeol(cmd_scr);
636: wrefresh(cmd_scr);
637: if (LINES <= 24) {
638: touchwin(sub_vterm);
639: wrefresh(sub_vterm);
640: } else {
641: updstat(status);
642: }
643: return(0);
644: default:
645: mvwaddstr(cmd_scr,0,40,"Unrecognized command");
646: mvwaddstr(cmd_scr,0,67,"Press Return");
647: wrefresh(cmd_scr);
648: while ((cmd[0] = emgetchar()) == NOCHAR) ;
649: };
650: }
651: }
652: /* termreset() - reset terminal status */
653: termreset()
654: {
655: char tbuf[10]; /* catch extra char thrown out by break here */
656:
657: signal(SIGINT,termreset); /* re-arm signal */
658: read(0,tbuf,1);
659:
660: updstat((status | SYS_AVAIL) & ~LOCK_OUT & ~INSERT_MODE);
661: if (LINES <= 24) {
662: touchwin(vterm_scr);
663: wrefresh(vterm_scr);
664: }
665: }
666:
667: /* fldcheck -- checks whether current field is protected, or current cursaddr
668: is an attribute character. Returns 1 if either case is true. */
669: fldcheck()
670: {
671: if (scrn_image[cursaddr] == (char)ATTRCODE)
672: return ATTR_CHAR;
673: if (prot_attr(fldattr[curfield]))
674: return PROTECTED;
675: return 0;
676: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.