--- ray/src/hd/rhdisp.c 1997/11/21 16:10:17 3.4 +++ ray/src/hd/rhdisp.c 1997/12/11 16:45:58 3.13 @@ -12,51 +12,80 @@ static char SCCSid[] = "$SunId$ SGI"; #include "rhdisp.h" #include "rhdriver.h" #include "selcall.h" +#include +#ifndef VIEWHISTLEN +#define VIEWHISTLEN 2 /* 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 RDY_SRV 01 -#define RDY_DEV 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[]; { + 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 & RDY_DEV) { /* get user input */ + if (rdy & RDY_DEV) { /* user input from driver */ inp = dev_input(); - if (inp & DEV_NEWVIEW) + if (inp & DFL(DC_SETVIEW)) new_view(&odev.v); - if (inp & DEV_SHUTDOWN) - serv_request(DR_SHUTDOWN, 0, NULL); - if (inp & DEV_REDRAW) { - beam_sync(); - imm_mode = 1; /* preempt updates */ - } - if (inp & DEV_WAIT) + if (inp & DFL(DC_GETVIEW)) + printview(); + if (inp & DFL(DC_LASTVIEW)) + new_view(NULL); + if (inp & DFL(DC_PAUSE)) pause = 1; - if (inp & DEV_RESUME) { + if (inp & DFL(DC_RESUME)) { serv_request(DR_NOOP, 0, NULL); pause = 0; } + if (inp & DFL(DC_REDRAW)) + imm_mode = beam_sync() > 0; + if (inp & DFL(DC_QUIT)) + serv_request(DR_SHUTDOWN, 0, NULL); } - if (rdy & RDY_SRV) { /* get server result */ + 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); + pause = 0; + break; + } + if (rdy & RDY_SRV) { /* process server result */ res = serv_result(); if (pause && res != DS_SHUTDOWN) { serv_request(DR_ATTEN, 0, NULL); @@ -81,6 +110,8 @@ disp_wait() /* wait for more input */ /* see if we can avoid select call */ if (imm_mode || stdin->_cnt > 0) return(RDY_SRV); + if (sstdin != NULL && sstdin->_cnt > 0) + return(RDY_SIN); if (dev_flush()) return(RDY_DEV); /* make the call */ @@ -89,7 +120,12 @@ disp_wait() /* wait for more input */ 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) @@ -101,6 +137,8 @@ disp_wait() /* wait for more input */ flgs |= RDY_SRV; if (FD_ISSET(odev.ifd, &readset) || FD_ISSET(odev.ifd, &errset)) flgs |= RDY_DEV; + if (sstdin != NULL && FD_ISSET(fileno(sstdin), &readset)) + flgs |= RDY_SIN; return(flgs); } @@ -150,24 +188,113 @@ 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 < 2) { + error(COMMAND, "no previous view"); + return; + } + nhist--; /* get one before last setting */ + 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_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 */ { @@ -205,6 +332,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: