|
|
Power 6/32 Unix version 1.21
/* D.L.Buck and Associates, Inc. - 84/08/27
*
* COPYRIGHT NOTICE:
* Copyright c 1984 - An unpublished work by
* D.L.Buck and Associates, Inc.
*
* PROPRIETARY RIGHTS NOTICE:
* All rights reserved. This document and program contains
* proprietary information of D.L.Buck and Associates,Inc.
* of San Jose, California, U.S.A., embodying confidential
* information, ideas, and expressions, no part of which
* may be reproduced, or transmitted in any form or by any
* means, electronic, mechanical, or otherwise, without
* the written permission of D.L.Buck and Associates, Inc.
*
* NAME
* emulate
*
* SYNOPSIS
* emulate()
*
* DESCRIPTION
* emulate is the 3277 emulation routine. User input, including PF and
* PA key handling and cursor movement, and special commands are handled
* here. emulate is called by em3277.
*/
#include "local.h"
#include <signal.h>
#include <bsc/bscio.h>
#include <em.h>
#define ERROR -1
#define CMDPRE 033 /* indicates a command code follows */
#define RDMOD '6' /* read modified command */
#define RDBUF '2' /* read buffer command */
#ifndef lint
static char sccsid[] = "@(#)emulate.c 1.34 REL";
#endif
extern long dev_navail();
/* statistics variables */
static int first = 1;
extern int rb_ctr; /* received blocks counter */
extern int ascii; /* 1=ascii code, 0=ebcdic code */
int rsp_ctr; /* response counter */
int trax_ctr; /* transaction counter */
long atm; /* used to compute response and transaction time */
long btm; /* used to compute response time */
long ctm; /* used to compute transaction time */
long lrsp_tm; /* last request's response time */
long rsp_tm; /* used to accumulate total response time */
long trax_tm; /* used to accumulate total transaction time */
long ltrax_tm; /* last request's transaction time */
long times();
extern struct tbuffer {
long utime;
long stime;
long cutime;
long cstime;
} rspbuf;
extern char aaid_tbl[]; /* ascii aid encoding table - found in emreadmod */
extern char eaid_tbl[]; /* ebcdic aid encoding table - found in emreadmod */
extern char *SO; /* standout sequence for this terminal */
extern char *SE; /* standend sequence for this terminal */
/* myscr[10240+5] makes sure there's room for characters leftover from the last
buffer processing (emprocbuf) at the beginning of this buffer. E.g.
an SBA came across in the last buffer and the 2-byte address supposed
to be attached to it didn't */
char myscr[10240+5];
extern int devfd;
extern int errno;
extern struct bscio gp;
int pr_ok = 1; /* 1=ok to print; 0=ignore print commands */
char aid_val;
int lastkey; /* contains last PF or PA key entered */
emulate()
{
int emgetchar();
int grabbed;
register int len; /* number of chars read in thru devfd */
int f;
int count;
register int endfld;
register int stat;
int i; /* index */
int ocursaddr;
int termreset(); /* reset input inhibited terminal status */
register char chr;
register char *myptr;
register int mylen;
register int mysize;
char rdchk[2]; /* 1st 2 chars of each received buffer
go here to check for read modified
and read buffer commands from the
remote host. */
signal(SIGINT,termreset);
updstat(MYJOB);
aid_val = ascii?0x2d:0x60;
lastkey = 0;
#ifdef DEBUG
f = open("procbuf",0);
#endif
fiximage(0); /* Initialize screen variables */
while (1) { /* Until Quit Command entered ... */
myptr = &myscr[5];
mysize = sizeof myscr - 5;
mylen = 0;
/* read from the comm device */
READ:
#ifdef DEBUG
read(f, &count, sizeof count);
len = read(f, &myscr[5], count);
if (len < 0)
exit(0);
if (len > 0) {
++rb_ctr;
mylen = len;
btm = times(&rspbuf);
if (atm) {
++rsp_ctr;
lrsp_tm = btm - atm;
rsp_tm += lrsp_tm;
}
}
#else
while ((len = read(devfd,myptr,mysize)) > 0 &&
mysize > 0) {
rdchk[0] = myptr[0]; /* Save 1st 2 bytes */
rdchk[1] = myptr[1];
myptr += len;
mysize -= len;
mylen += len;
/* check for read modified or read buffer command from host --
if there, call emreadmod() or emreadbuf() immediately, then
go back to the top of the read routine. */
/*** rdchk[0] = myscr[5]; rdchk[1] = myscr[6]; ***/
if (!ascii)
ebcasc(rdchk,2);
if (mylen &&
(rdchk[0]==CMDPRE &&
(rdchk[1]==RDMOD || rdchk[1]==RDBUF))) {
updstat(status | SYS_AVAIL);
/* Did we recv. anything before RDMOD or RDBUF? */
/* by checking if they are at the beginning of buf */
/* then&dai 5/51/85 */
if ( (myptr-2) != &myscr[5]) {
mylen -= 2;
emprocbuf(&myscr[5],mylen);
}
if (rdchk[1] == RDMOD)
emreadmod(lastkey);
else
emreadbuf();
goto lupe;
}
++rb_ctr;
}
#endif
if (len < 0 && (errno == EINTR || errno == EAGAIN) &&
mylen != 0) goto READ;
if (len < 0) { /* Check out nature of error */
get_errors();
/* Any serious errors? */
if (gp.b_flags == BSCNDSR ||
gp.b_flags == BSCTXTO ||
gp.b_flags == BSCNBID)
return(-1);
}
if (mylen) {
ctm = times(&rspbuf);
emprocbuf(&myscr[5],mylen);
if (atm) {
ltrax_tm = ctm - atm;
trax_tm += ltrax_tm;
++trax_ctr;
atm = 0L;
}
if (do_screen && !(status & LOCK_OUT)) {
if (LINES <= 24) {
touchwin(sub_vterm);
wrefresh(sub_vterm);
}
wmove(vterm_scr,ROW,COL);
wrefresh(vterm_scr);
}
}
if (first) {
first = 0;
grabbed = CLEAR;
}
else grabbed = emgetchar();
if (grabbed == NOCHAR)
continue;
if ((status & LOCK_OUT) && grabbed != ESC &&
grabbed != ERASE_INP && grabbed != RESET)
continue;
switch(grabbed) {
case OTHER:
break;
case NOCHAR:
break;
case ERROR:
return(-1);
case CARRET:
cursaddr += (SCREENWIDTH - COL);
if (cursaddr >= (MAXSCREENSIZE - 1))
cursaddr = 0;
if (scrn_image[cursaddr] == (char)ATTRCODE)
++cursaddr;
curfield = scrn_xref[cursaddr];
if (prot_attr(fldattr[curfield])) goto tabtime;
break;
case BACKSP:
case LEFT:
if (--cursaddr < 0)
cursaddr = MAXSCREENSIZE - 1;
break;
case DOWN:
cursaddr += SCREENWIDTH;
if (cursaddr >= MAXSCREENSIZE)
cursaddr -= MAXSCREENSIZE;
break;
case UPAR:
if ((cursaddr -= SCREENWIDTH) < 0)
cursaddr += MAXSCREENSIZE;
break;
case RIGHT:
if (++cursaddr >= MAXSCREENSIZE)
cursaddr = 0;
break;
case DELCHR:
/* Delete one character at cursaddr, moving
* characters within the same field and on
* the same line to the left one position,
* filling in the rightmost vacated position
* with a NULL character.
* 1. Check field for protected, or cursaddr
* being on attribute character.
*/
if (i = fldcheck())
goto STAT_CHK;
/* 2. Calculate location of last field position. */
endfld=fldstart[curfield] + (fldmax[curfield]-1);
if (endfld > MAXSCREENSIZE)
endfld -= MAXSCREENSIZE;
/* 3. If field continues on next line, stop at */
/* end of this line. */
if ((endfld/SCREENWIDTH) != ROW)
endfld = cursaddr + (SCREENWIDTH - COL)-1;
ocursaddr = cursaddr;
/* 4. If field highlighted, change screen mode */
if (do_screen)
if (hl_attr(fldattr[curfield]))
wstandout(vterm_scr);
else
wstandend(vterm_scr);
/* 5. Begin moving characters left to endfield */
do {
if (cursaddr == endfld) break;
if (cursaddr+1 > MAXSCREENSIZE)
chr = scrn_image[0];
else chr = scrn_image[cursaddr+1];
scrn_image[cursaddr] = chr;
if (do_screen) {
if (chr == '\0')
chr = ' ';
else if (chr == 0x1c)
chr = '*'; /* DUP */
else if (chr == 0x1e)
chr = ';'; /* FM */
if (!invis_attr(fldattr[curfield]))
mvwaddch(vterm_scr,ROW,COL,chr);
}
if (++cursaddr > MAXSCREENSIZE)
cursaddr = 0;
} while (cursaddr != endfld);
/* 6. Null at end of field; mark as modified. */
if (do_screen) {
mvwaddch(vterm_scr,ROW,COL,' ');
wstandend(vterm_scr);
}
scrn_image[cursaddr] = '\0';
cursaddr = ocursaddr;
fldattr[curfield] = fldattr[curfield] | ATTRMDT;
break;
case DUP:
if (i = emputchar(grabbed))
goto STAT_CHK;
/* If ok, fall through to TAB */
case TAB:
tabtime:
if (!unprotected) { /* no unprotected fields */
cursaddr = 0;
break;
}
tabloop:
if (++curfield >= totfields)
curfield = 0;
if (prot_attr(fldattr[curfield]))
goto tabloop;
cursaddr = fldstart[curfield];
break;
case BACKTAB:
backtabtime:
if (!unprotected) {
cursaddr = 0;
break;
}
if (!prot_attr(fldattr[curfield]) &&
cursaddr != fldstart[curfield]) {
cursaddr = fldstart[curfield];
break;
}
btabloop:
if (--curfield < 0)
curfield = totfields-1;
if (prot_attr(fldattr[curfield]))
goto btabloop;
cursaddr = fldstart[curfield];
break;
case ERASE_EOF: /* erase to eofield */
if (i = fldcheck())
goto STAT_CHK;
ocursaddr = cursaddr;
cursaddr = fldstart[curfield]+fldmax[curfield]-1;
if (cursaddr>=MAXSCREENSIZE)
cursaddr-=MAXSCREENSIZE;
do {
scrn_image[cursaddr] = '\0';
if (do_screen &&
(cursaddr != (MAXSCREENSIZE-1)))
mvwaddch(vterm_scr,ROW,COL,' ');
if (cursaddr == ocursaddr) break;
--cursaddr;
if (cursaddr < 0)
cursaddr+=MAXSCREENSIZE;
}
while(1);
break;
case ERASE_INP: /* erase all unprotected input */
updstat(status & LOCK_OUT);
aid_val = ascii?0x2d:0x60;
lastkey = 0;
for (cursaddr=0;cursaddr<=MAXSCREENSIZE-1; ++cursaddr) {
curfield = scrn_xref[cursaddr];
if (prot_attr(fldattr[curfield]) ||
scrn_image[cursaddr] == ATTRCODE)
continue;
scrn_image[cursaddr] = '\0';
if (do_screen)
mvwaddch(vterm_scr,ROW,COL,' ');
}
curfield = totfields;
goto tabtime;
break;
case INS:
if (LINES <= 24)
status |= INSERT_MODE;
else
updstat(status | INSERT_MODE);
break;
case CLEAR:
for (cursaddr=0; cursaddr<MAXSCREENSIZE; ++cursaddr)
scrn_image[cursaddr] = '\0';
cursaddr = 0;
fiximage(0);
if (do_screen) {
wmove(vterm_scr,0,0);
/* if # of lines on screen <= 24, do werase; otherwise,
do clear to end of line for 24 lines to avoid losing
messages */
if (LINES <= 24) {
werase(vterm_scr);
clearok(curscr,TRUE);
}
else {
for (i=0; i<24; ++i) {
wmove(vterm_scr,i,0);
wclrtoeol(vterm_scr);
}
}
wrefresh(vterm_scr);
}
case ENTER:
case PF1:
case PF2:
case PF3:
case PF4:
case PF5:
case PF6:
case PF7:
case PF8:
case PF9:
case PF10:
case PF11:
case PF12:
case PA1:
case PA2:
case PA3:
btm = 0L; /* init trax/rsp time counters */
ctm = 0L;
atm = times(&rspbuf);
updstat((status | INPUT_INH) & ~SYS_AVAIL);
/* figure out what AID value is and set it */
aid_val = (ascii?aaid_tbl:eaid_tbl)[grabbed - ENTER];
lastkey = grabbed;
#ifndef DEBUG
emreadmod(grabbed);
#endif
break;
case ESC:
/* process keyboard commands: keyboard status reset,
print instructions, test request, end of session */
updstat(status & ~MYJOB);
if (key_cmds()) return;
if (LINES > 24)
updstat(status | MYJOB);
else
status |= MYJOB;
break;
case RESET:
updstat(status & ~LOCK_OUT & ~ INSERT_MODE);
aid_val = ascii?0x2d:0x60;
lastkey = 0;
if (do_screen && (LINES <= 24)) {
touchwin(sub_vterm);
wrefresh(sub_vterm);
}
break;
case STATS:
if (!do_screen)
break;
emstats(0);
mvwaddstr(cmd_scr,0,67,"Press Return");
wrefresh(cmd_scr);
while ((grabbed=emgetchar()) == NOCHAR) ;
wclear(cmd_scr);
wrefresh(cmd_scr);
if (LINES <= 24) {
touchwin(sub_vterm);
wrefresh(sub_vterm);
}
break;
case PRINT: /* print currently-displayed screen */
if (pr_ok) emprint(0); /* print, inserting newlines
every 80 characters if none
found before then */
break;
case HELP: /* display keyboard map */
if (!do_screen)
break;
em_help();
break;
default:
usual: if (i = emputchar(grabbed)) { /* error encountered */
STAT_CHK:
switch (i) {
case NORMAL:
break;
case NUMERIC: updstat(status | NUM_ONLY);
break;
case ATTR_CHAR:
case PROTECTED: updstat(status | GO_ELSE);
break;
case FLD_FULL: updstat(status | MORE_THAN);
break;
default:
break;
}
goto lupe;
} else {
if (++cursaddr >= MAXSCREENSIZE)
cursaddr = 0;
curfield = scrn_xref[cursaddr];
if (scrn_image[cursaddr] == (char)ATTRCODE &&
!(status & INSERT_MODE)) {
if (skip_attr(fldattr[curfield]))
goto tabtime;
if (++cursaddr >= MAXSCREENSIZE)
cursaddr = 0;
}
}
};
/* decide what field you're on by checking cursaddr with scrn_xref */
lupe:
curfield = scrn_xref[cursaddr];
if (do_screen) {
if (LINES > 24 || (status & LOCK_OUT))
updstat (status);
wmove(vterm_scr,ROW,COL);
wrefresh(vterm_scr);
}
}
}
/* process keyboard commands: reset keyboard status, test request, print
instruction, end of session */
extern char ptype;
extern char pr_dest[];
#ifdef v7
extern struct tchars termtchar, origtchar;
extern struct sgttyb termio, origtio;
#endif
#ifndef v7
extern struct termio origtio, termio;
#endif
extern char *termtype;
char cmd[100];
key_cmds()
{
char *emgetstr(); /* get a command string */
register int i; /* index */
while (1) {
/* get and set terminal modes */
wstandout(cmd_scr);
wmove(cmd_scr,0,0);
werase(cmd_scr);
mvwaddstr(cmd_scr,0,0,"Command: ");
touchwin(cmd_scr);
wrefresh(cmd_scr);
emgetstr(cmd);
switch(cmd[0]) {
case 'h': /* help -- display keyboard map again */
em_help();
break;
case '!': /* execute one shell command */
#ifdef v7
ioctl(0,TIOCSETC,&origtchar);
ioctl(0, TIOCSETP, &origtio);
#else
ioctl(0,TCSETA,&origtio);
#endif
/* write standout sequence to terminal */
puts(SO);
system(&cmd[1]);
write (1,"\nPress Return to Continue:",26);
read(0, cmd, sizeof cmd);
puts(SE);
#ifdef v7
ioctl(0,TIOCSETC,&termtchar);
ioctl(0, TIOCSETP, &termio);
#else
ioctl(0,TCSETA,&termio);
#endif
clearok(curscr,TRUE);
touchwin(vterm_scr);
wrefresh(vterm_scr);
break;
case 'p': /* invoke print modes */
switch(cmd[1]) {
case 'd': /* ignore print commands */
pr_ok = 0;
break;
case 'p': /* save print destination name */
case 'f':
ptype = (cmd[1]=='p')?'p':'f';
strcpy(pr_dest,&cmd[2]);
break;
case '\0':
case 'r': /* copy screen to printer */
if (pr_ok)
emprint(0); /* insert nl every 80 chars */
break;
default:
mvwaddstr(cmd_scr,0,30,
"Valid print commands: p,pd,pf,pp,pr");
break;
};
mvwaddstr(cmd_scr,0,67,"Press Return");
wrefresh(cmd_scr);
while ((cmd[0] = emgetchar()) == NOCHAR) ;
break;
case 'r': /* reset status (clear input inhibit) */
updstat(status & ~LOCK_OUT & ~INSERT_MODE);
aid_val = ascii?0x2d:0x60;
lastkey = 0;
break;
case 'e': /* send msg: dev. not available then quit */
emstats(1);
dev_navail();
return(1);
case 'q': /* get session statistics and quit */
emstats(1);
return(1);
case 's': /* statistics */
emstats(0);
mvwaddstr(cmd_scr,0,67,"Press Return");
wrefresh(cmd_scr);
while ((cmd[0] = emgetchar()) == NOCHAR) ;
break;
case 't':
btm = 0L;
ctm = 0L;
atm = times(&rspbuf);
updstat(status | INPUT_INH);
emreadmod(TESTREQ); /* test request key */
aid_val = ascii?0x30:0xf0; /* reset aid value */
lastkey = TESTREQ; /*** changed from 0 ttl ***/
btm = times(&rspbuf);
lrsp_tm = btm - atm;
rsp_tm += lrsp_tm;
++rsp_ctr;
mvwaddstr(cmd_scr,0,67,"Press Return");
wrefresh(cmd_scr);
while ((cmd[0] = emgetchar()) == NOCHAR) ;
break;
case '\0': /* no more cmds if getstr got a null -- return */
wstandout(cmd_scr);
wmove(cmd_scr,0,0);
wclrtoeol(cmd_scr);
wrefresh(cmd_scr);
if (LINES <= 24) {
touchwin(sub_vterm);
wrefresh(sub_vterm);
} else {
updstat(status);
}
return(0);
default:
mvwaddstr(cmd_scr,0,40,"Unrecognized command");
mvwaddstr(cmd_scr,0,67,"Press Return");
wrefresh(cmd_scr);
while ((cmd[0] = emgetchar()) == NOCHAR) ;
};
}
}
/* termreset() - reset terminal status */
termreset()
{
char tbuf[10]; /* catch extra char thrown out by break here */
signal(SIGINT,termreset); /* re-arm signal */
read(0,tbuf,1);
updstat((status | SYS_AVAIL) & ~LOCK_OUT & ~INSERT_MODE);
if (LINES <= 24) {
touchwin(vterm_scr);
wrefresh(vterm_scr);
}
}
/* fldcheck -- checks whether current field is protected, or current cursaddr
is an attribute character. Returns 1 if either case is true. */
fldcheck()
{
if (scrn_image[cursaddr] == (char)ATTRCODE)
return ATTR_CHAR;
if (prot_attr(fldattr[curfield]))
return PROTECTED;
return 0;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.