--- ray/src/hd/rhdisp.c 1997/11/19 18:01:03 3.1 +++ ray/src/hd/rhdisp.c 1997/12/18 18:14:15 3.16 @@ -12,42 +12,101 @@ static char SCCSid[] = "$SunId$ SGI"; #include "rhdisp.h" #include "rhdriver.h" #include "selcall.h" +#include +#ifndef VIEWHISTLEN +#define VIEWHISTLEN 4 /* number of remembered views */ +#endif + HOLO *hdlist[HDMAX+1]; /* global holodeck list */ +char cmdlist[DC_NCMDS][8] = DC_INIT; + int imm_mode = 0; /* bundles are being delivered immediately */ -VIEW dvw; /* our current display view */ - char *progname; /* global argv[0] */ -#define SERV_READY 01 -#define DEV_READY 02 +FILE *sstdin, *sstdout; /* server's standard input and output */ +#define RDY_SRV 01 +#define RDY_DEV 02 +#define RDY_SIN 04 + main(argc, argv) int argc; char *argv[]; { - int rdy, inp, res = 0; + extern int eputs(); + int rdy, inp, res = 0, pause = 0; progname = argv[0]; - if (argc != 2) + if (argc < 3) error(USER, "bad command line arguments"); /* open our device */ dev_open(argv[1]); + /* open server process i/o */ + sstdout = fdopen(atoi(argv[2]), "w"); + if (argc < 4 || (inp = atoi(argv[3])) < 0) + sstdin = NULL; + else + sstdin = fdopen(inp, "r"); + /* set command error vector */ + erract[COMMAND].pf = eputs; /* enter main loop */ do { rdy = disp_wait(); - if (rdy & DEV_READY) { - inp = dev_input(); /* take residual action here */ - if (inp & DEV_SHUTDOWN) - serv_request(DR_SHUTDOWN, 0, NULL); - else if (inp & DEV_NEWVIEW) + if (rdy & RDY_DEV) { /* user input from driver */ + inp = dev_input(); + if (inp & DFL(DC_SETVIEW)) new_view(&odev.v); + if (inp & DFL(DC_GETVIEW)) + printview(); + if (inp & DFL(DC_LASTVIEW)) + new_view(NULL); + if (inp & DFL(DC_RESUME)) { + serv_request(DR_NOOP, 0, NULL); + pause = 0; + } + if (inp & DFL(DC_PAUSE)) + pause = 1; + if (inp & DFL(DC_REDRAW)) + imm_mode = beam_sync() > 0; + if (inp & DFL(DC_KILL)) { + serv_request(DR_KILL, 0, NULL); + pause = 0; + } + if (inp & DFL(DC_CLOBBER)) + serv_request(DR_CLOBBER, 0, NULL); + if (inp & DFL(DC_RESTART)) { + serv_request(DR_RESTART, 0, NULL); + pause = 0; + } + if (inp & DFL(DC_QUIT)) + serv_request(DR_SHUTDOWN, 0, NULL); } - if (rdy & SERV_READY) - res = serv_result(); /* processes result, also */ + if (rdy & RDY_SIN) /* user input from sstdin */ + switch (usr_input()) { + case DC_PAUSE: + pause = 1; + break; + case DC_RESUME: + serv_request(DR_NOOP, 0, NULL); + /* fall through */ + case DC_KILL: + case DC_RESTART: + pause = 0; + break; + } + if (rdy & RDY_SRV) { /* process server result */ + res = serv_result(); + if (pause && res != DS_SHUTDOWN) { + serv_request(DR_ATTEN, 0, NULL); + while ((res = serv_result()) != DS_ACKNOW && + res != DS_SHUTDOWN) + ; + } + } } while (res != DS_SHUTDOWN); /* all done */ quit(0); @@ -63,16 +122,23 @@ disp_wait() /* wait for more input */ register int i; /* see if we can avoid select call */ if (imm_mode || stdin->_cnt > 0) - return(SERV_READY); + return(RDY_SRV); + if (sstdin != NULL && sstdin->_cnt > 0) + return(RDY_SIN); if (dev_flush()) - return(DEV_READY); + return(RDY_DEV); /* make the call */ FD_ZERO(&readset); FD_ZERO(&errset); FD_SET(0, &readset); FD_SET(0, &errset); FD_SET(odev.ifd, &readset); FD_SET(odev.ifd, &errset); - n = odev.ifd + 1; + n = odev.ifd+1; + if (sstdin != NULL) { + FD_SET(fileno(sstdin), &readset); + if (fileno(sstdin) >= n) + n = fileno(sstdin) + 1; + } n = select(n, &readset, NULL, &errset, NULL); if (n < 0) { if (errno == EINTR) @@ -81,9 +147,11 @@ disp_wait() /* wait for more input */ } flgs = 0; /* flag what's ready */ if (FD_ISSET(0, &readset) || FD_ISSET(0, &errset)) - flgs |= SERV_READY; + flgs |= RDY_SRV; if (FD_ISSET(odev.ifd, &readset) || FD_ISSET(odev.ifd, &errset)) - flgs |= DEV_READY; + flgs |= RDY_DEV; + if (sstdin != NULL && FD_ISSET(fileno(sstdin), &readset)) + flgs |= RDY_SIN; return(flgs); } @@ -133,24 +201,122 @@ register PACKHEAD *p; hdray(ro, rd, hdlist[p->hd], gc, packra(p)[i].r); d = hddepth(hdlist[p->hd], packra(p)[i].d); VSUM(wp, ro, rd, d); /* might be behind viewpoint */ - dev_value(packra(p)[i].v, wp); + dev_value(packra(p)[i].v, wp, rd); } } new_view(v) /* change view parameters */ -VIEW *v; +register VIEW *v; { + static VIEW viewhist[VIEWHISTLEN]; + static unsigned nhist; char *err; + /* restore previous view? */ + if (v == NULL) { + if (nhist > 1) /* get one before last setting */ + nhist--; + else /* else go to end of list */ + while (nhist < VIEWHISTLEN && viewhist[nhist].type) + nhist++; + v = viewhist + ((nhist-1)%VIEWHISTLEN); + } else if ((err = setview(v)) != NULL) { + error(COMMAND, err); + return; + } +again: + if (v->type == VT_PAR) { + error(COMMAND, "cannot handle parallel views"); + return; + } + if (!dev_view(v)) /* update display driver */ + goto again; + dev_flush(); /* update screen */ + if (!beam_view(v)) /* update beam list */ + goto again; + /* record new view */ + if (v < viewhist || v >= viewhist+VIEWHISTLEN) { + copystruct(viewhist + (nhist%VIEWHISTLEN), v); + nhist++; + } +} - if ((err = setview(v)) != NULL) - error(INTERNAL, err); - dev_view(v); /* update display driver */ - beam_view(&dvw, v); /* update beam list */ - copystruct(&dvw, v); /* record new view */ + +int +usr_input() /* get user input and process it */ +{ + VIEW vparams; + char cmd[128]; + register char *args; + register int i; + + if (fgets(cmd, sizeof(cmd), sstdin) == NULL) + return(DC_QUIT); + for (args = cmd; *args && !isspace(*args); args++) + ; + while (isspace(*args)) + *args++ = '\0'; + if (!*cmd) + return(DC_RESUME); + if (*args && args[i=strlen(args)-1] == '\n') + args[i] = '\0'; + for (i = 0; i < DC_NCMDS; i++) + if (!strcmp(cmd, cmdlist[i])) + break; + if (i >= DC_NCMDS) { + sprintf(errmsg, "unknown command: %s", cmd); + error(COMMAND, errmsg); + return(-1); + } + switch (i) { + case DC_SETVIEW: /* set the view */ + copystruct(&vparams, &odev.v); + if (!sscanview(&vparams, args)) + error(COMMAND, "missing view options"); + else + new_view(&vparams); + break; + case DC_GETVIEW: /* print the current view */ + printview(); + break; + case DC_LASTVIEW: /* restore previous view */ + new_view(NULL); + break; + case DC_PAUSE: /* pause the current calculation */ + case DC_RESUME: /* resume the calculation */ + /* handled in main() */ + break; + case DC_REDRAW: /* redraw from server */ + imm_mode = beam_sync() > 0; + break; + case DC_KILL: /* kill rtrace process(es) */ + serv_request(DR_KILL, 0, NULL); + break; + case DC_CLOBBER: /* clobber holodeck */ + serv_request(DR_CLOBBER, 0, NULL); + break; + case DC_RESTART: /* restart rtrace */ + serv_request(DR_RESTART, 0, NULL); + break; + case DC_QUIT: /* quit request */ + serv_request(DR_SHUTDOWN, 0, NULL); + break; + default: + error(CONSISTENCY, "bad command id in usr_input"); + } + return(i); } +printview() /* print our current view to server stdout */ +{ + fputs(VIEWSTR, sstdout); + fprintview(&odev.v, sstdout); + fputc('\n', sstdout); + fflush(sstdout); +} + + int serv_result() /* get next server result and process it */ { @@ -188,6 +354,8 @@ serv_result() /* get next server result and process case DS_STARTIMM: case DS_ENDIMM: imm_mode = msg.type==DS_STARTIMM; + if (msg.type == DS_ENDIMM) + dev_flush(); /* update display NOW */ /* fall through */ case DS_ACKNOW: case DS_SHUTDOWN: @@ -229,6 +397,25 @@ char *p; fwrite(p, 1, nbytes, stdout); if (fflush(stdout) < 0) error(SYSTEM, "write error in serv_request"); +} + + +eputs(s) /* put error message to stderr */ +register char *s; +{ + static int midline = 0; + + if (!*s) + return; + if (!midline++) { /* prepend line with program name */ + fputs(progname, stderr); + fputs(": ", stderr); + } + fputs(s, stderr); + if (s[strlen(s)-1] == '\n') { + fflush(stderr); + midline = 0; + } }