ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhdisp.c
Revision: 3.14
Committed: Fri Dec 12 11:13:15 1997 UTC (26 years, 4 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 3.13: +15 -0 lines
Log Message:
implemented kill, clobber and restart commands

File Contents

# Content
1 /* Copyright (c) 1997 Silicon Graphics, Inc. */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ SGI";
5 #endif
6
7 /*
8 * Holodeck display process.
9 */
10
11 #include "rholo.h"
12 #include "rhdisp.h"
13 #include "rhdriver.h"
14 #include "selcall.h"
15 #include <ctype.h>
16
17 #ifndef VIEWHISTLEN
18 #define VIEWHISTLEN 2 /* number of remembered views */
19 #endif
20
21 HOLO *hdlist[HDMAX+1]; /* global holodeck list */
22
23 char cmdlist[DC_NCMDS][8] = DC_INIT;
24
25 int imm_mode = 0; /* bundles are being delivered immediately */
26
27 char *progname; /* global argv[0] */
28
29 FILE *sstdin, *sstdout; /* server's standard input and output */
30
31 #define RDY_SRV 01
32 #define RDY_DEV 02
33 #define RDY_SIN 04
34
35
36 main(argc, argv)
37 int argc;
38 char *argv[];
39 {
40 extern int eputs();
41 int rdy, inp, res = 0, pause = 0;
42
43 progname = argv[0];
44 if (argc < 3)
45 error(USER, "bad command line arguments");
46 /* open our device */
47 dev_open(argv[1]);
48 /* open server process i/o */
49 sstdout = fdopen(atoi(argv[2]), "w");
50 if (argc < 4 || (inp = atoi(argv[3])) < 0)
51 sstdin = NULL;
52 else
53 sstdin = fdopen(inp, "r");
54 /* set command error vector */
55 erract[COMMAND].pf = eputs;
56 /* enter main loop */
57 do {
58 rdy = disp_wait();
59 if (rdy & RDY_DEV) { /* user input from driver */
60 inp = dev_input();
61 if (inp & DFL(DC_SETVIEW))
62 new_view(&odev.v);
63 if (inp & DFL(DC_GETVIEW))
64 printview();
65 if (inp & DFL(DC_LASTVIEW))
66 new_view(NULL);
67 if (inp & DFL(DC_PAUSE))
68 pause = 1;
69 if (inp & DFL(DC_RESUME)) {
70 serv_request(DR_NOOP, 0, NULL);
71 pause = 0;
72 }
73 if (inp & DFL(DC_REDRAW))
74 imm_mode = beam_sync() > 0;
75 if (inp & DFL(DC_KILL))
76 serv_request(DR_KILL, 0, NULL);
77 if (inp & DFL(DC_CLOBBER))
78 serv_request(DR_CLOBBER, 0, NULL);
79 if (inp & DFL(DC_RESTART))
80 serv_request(DR_RESTART, 0, NULL);
81 if (inp & DFL(DC_QUIT))
82 serv_request(DR_SHUTDOWN, 0, NULL);
83 }
84 if (rdy & RDY_SIN) /* user input from sstdin */
85 switch (usr_input()) {
86 case DC_PAUSE:
87 pause = 1;
88 break;
89 case DC_RESUME:
90 serv_request(DR_NOOP, 0, NULL);
91 pause = 0;
92 break;
93 }
94 if (rdy & RDY_SRV) { /* process server result */
95 res = serv_result();
96 if (pause && res != DS_SHUTDOWN) {
97 serv_request(DR_ATTEN, 0, NULL);
98 while ((res = serv_result()) != DS_ACKNOW &&
99 res != DS_SHUTDOWN)
100 ;
101 }
102 }
103 } while (res != DS_SHUTDOWN);
104 /* all done */
105 quit(0);
106 }
107
108
109 int
110 disp_wait() /* wait for more input */
111 {
112 fd_set readset, errset;
113 int flgs;
114 int n;
115 register int i;
116 /* see if we can avoid select call */
117 if (imm_mode || stdin->_cnt > 0)
118 return(RDY_SRV);
119 if (sstdin != NULL && sstdin->_cnt > 0)
120 return(RDY_SIN);
121 if (dev_flush())
122 return(RDY_DEV);
123 /* make the call */
124 FD_ZERO(&readset); FD_ZERO(&errset);
125 FD_SET(0, &readset);
126 FD_SET(0, &errset);
127 FD_SET(odev.ifd, &readset);
128 FD_SET(odev.ifd, &errset);
129 n = odev.ifd+1;
130 if (sstdin != NULL) {
131 FD_SET(fileno(sstdin), &readset);
132 if (fileno(sstdin) >= n)
133 n = fileno(sstdin) + 1;
134 }
135 n = select(n, &readset, NULL, &errset, NULL);
136 if (n < 0) {
137 if (errno == EINTR)
138 return(0);
139 error(SYSTEM, "select call failure in disp_wait");
140 }
141 flgs = 0; /* flag what's ready */
142 if (FD_ISSET(0, &readset) || FD_ISSET(0, &errset))
143 flgs |= RDY_SRV;
144 if (FD_ISSET(odev.ifd, &readset) || FD_ISSET(odev.ifd, &errset))
145 flgs |= RDY_DEV;
146 if (sstdin != NULL && FD_ISSET(fileno(sstdin), &readset))
147 flgs |= RDY_SIN;
148 return(flgs);
149 }
150
151
152 add_holo(hdg) /* register a new holodeck section */
153 HDGRID *hdg;
154 {
155 VIEW nv;
156 register int hd;
157
158 for (hd = 0; hd < HDMAX && hdlist[hd] != NULL; hd++)
159 ;
160 if (hd >= HDMAX)
161 error(INTERNAL, "too many holodeck sections in add_holo");
162 hdlist[hd] = (HOLO *)malloc(sizeof(HOLO));
163 if (hdlist[hd] == NULL)
164 error(SYSTEM, "out of memory in add_holo");
165 bcopy((char *)hdg, (char *)hdlist[hd], sizeof(HDGRID));
166 hdcompgrid(hdlist[hd]);
167 if (hd)
168 return;
169 /* set initial viewpoint */
170 copystruct(&nv, &odev.v);
171 VSUM(nv.vp, hdlist[0]->orig, hdlist[0]->xv[0], 0.5);
172 VSUM(nv.vp, nv.vp, hdlist[0]->xv[1], 0.5);
173 VSUM(nv.vp, nv.vp, hdlist[0]->xv[2], 0.5);
174 fcross(nv.vdir, hdlist[0]->xv[1], hdlist[0]->xv[2]);
175 VCOPY(nv.vup, hdlist[0]->xv[2]);
176 new_view(&nv);
177 }
178
179
180 disp_bundle(p) /* display a ray bundle */
181 register PACKHEAD *p;
182 {
183 GCOORD gc[2];
184 FVECT ro, rd, wp;
185 double d;
186 register int i;
187 /* get beam coordinates */
188 if (p->hd < 0 | p->hd >= HDMAX || hdlist[p->hd] == NULL)
189 error(INTERNAL, "bad holodeck number in disp_bundle");
190 if (!hdbcoord(gc, hdlist[p->hd], p->bi))
191 error(INTERNAL, "bad beam index in disp_bundle");
192 /* display each ray */
193 for (i = p->nr; i--; ) {
194 hdray(ro, rd, hdlist[p->hd], gc, packra(p)[i].r);
195 d = hddepth(hdlist[p->hd], packra(p)[i].d);
196 VSUM(wp, ro, rd, d); /* might be behind viewpoint */
197 dev_value(packra(p)[i].v, wp, rd);
198 }
199 }
200
201
202 new_view(v) /* change view parameters */
203 register VIEW *v;
204 {
205 static VIEW viewhist[VIEWHISTLEN];
206 static unsigned nhist;
207 char *err;
208 /* restore previous view? */
209 if (v == NULL) {
210 if (nhist < 2) {
211 error(COMMAND, "no previous view");
212 return;
213 }
214 nhist--; /* get one before last setting */
215 v = viewhist + ((nhist-1)%VIEWHISTLEN);
216 } else if ((err = setview(v)) != NULL) {
217 error(COMMAND, err);
218 return;
219 }
220 again:
221 if (v->type == VT_PAR) {
222 error(COMMAND, "cannot handle parallel views");
223 return;
224 }
225 if (!dev_view(v)) /* update display driver */
226 goto again;
227 dev_flush(); /* update screen */
228 if (!beam_view(v)) /* update beam list */
229 goto again;
230 /* record new view */
231 if (v < viewhist || v >= viewhist+VIEWHISTLEN) {
232 copystruct(viewhist + (nhist%VIEWHISTLEN), v);
233 nhist++;
234 }
235 }
236
237
238 int
239 usr_input() /* get user input and process it */
240 {
241 VIEW vparams;
242 char cmd[128];
243 register char *args;
244 register int i;
245
246 if (fgets(cmd, sizeof(cmd), sstdin) == NULL)
247 return(DC_QUIT);
248 for (args = cmd; *args && !isspace(*args); args++)
249 ;
250 while (isspace(*args))
251 *args++ = '\0';
252 if (!*cmd)
253 return(DC_RESUME);
254 if (*args && args[i=strlen(args)-1] == '\n')
255 args[i] = '\0';
256 for (i = 0; i < DC_NCMDS; i++)
257 if (!strcmp(cmd, cmdlist[i]))
258 break;
259 if (i >= DC_NCMDS) {
260 sprintf(errmsg, "unknown command: %s", cmd);
261 error(COMMAND, errmsg);
262 return(-1);
263 }
264 switch (i) {
265 case DC_SETVIEW: /* set the view */
266 copystruct(&vparams, &odev.v);
267 if (!sscanview(&vparams, args))
268 error(COMMAND, "missing view options");
269 else
270 new_view(&vparams);
271 break;
272 case DC_GETVIEW: /* print the current view */
273 printview();
274 break;
275 case DC_LASTVIEW: /* restore previous view */
276 new_view(NULL);
277 break;
278 case DC_PAUSE: /* pause the current calculation */
279 case DC_RESUME: /* resume the calculation */
280 /* handled in main() */
281 break;
282 case DC_REDRAW: /* redraw from server */
283 imm_mode = beam_sync() > 0;
284 break;
285 case DC_KILL: /* kill rtrace process(es) */
286 serv_request(DR_KILL, 0, NULL);
287 break;
288 case DC_CLOBBER: /* clobber holodeck */
289 serv_request(DR_CLOBBER, 0, NULL);
290 break;
291 case DC_RESTART: /* restart rtrace */
292 serv_request(DR_RESTART, 0, NULL);
293 break;
294 case DC_QUIT: /* quit request */
295 serv_request(DR_SHUTDOWN, 0, NULL);
296 break;
297 default:
298 error(CONSISTENCY, "bad command id in usr_input");
299 }
300 return(i);
301 }
302
303
304 printview() /* print our current view to server stdout */
305 {
306 fputs(VIEWSTR, sstdout);
307 fprintview(&odev.v, sstdout);
308 fputc('\n', sstdout);
309 fflush(sstdout);
310 }
311
312
313 int
314 serv_result() /* get next server result and process it */
315 {
316 static char *buf = NULL;
317 static int bufsiz = 0;
318 MSGHEAD msg;
319 int n;
320 /* read message header */
321 if (fread((char *)&msg, sizeof(MSGHEAD), 1, stdin) != 1)
322 goto readerr;
323 if (msg.nbytes > 0) { /* get the message body */
324 if (msg.nbytes > bufsiz) {
325 if (buf == NULL)
326 buf = (char *)malloc(bufsiz=msg.nbytes);
327 else
328 buf = (char *)realloc(buf, bufsiz=msg.nbytes);
329 if (buf == NULL)
330 error(SYSTEM, "out of memory in serv_result");
331 }
332 if (fread(buf, 1, msg.nbytes, stdin) != msg.nbytes)
333 goto readerr;
334 }
335 switch (msg.type) { /* process results */
336 case DS_BUNDLE:
337 if (msg.nbytes < sizeof(PACKHEAD) ||
338 msg.nbytes != packsiz(((PACKHEAD *)buf)->nr))
339 error(INTERNAL, "bad display packet from server");
340 disp_bundle((PACKHEAD *)buf);
341 break;
342 case DS_ADDHOLO:
343 if (msg.nbytes != sizeof(HDGRID))
344 error(INTERNAL, "bad holodeck record from server");
345 add_holo((HDGRID *)buf);
346 break;
347 case DS_STARTIMM:
348 case DS_ENDIMM:
349 imm_mode = msg.type==DS_STARTIMM;
350 if (msg.type == DS_ENDIMM)
351 dev_flush(); /* update display NOW */
352 /* fall through */
353 case DS_ACKNOW:
354 case DS_SHUTDOWN:
355 if (msg.nbytes) {
356 sprintf(errmsg,
357 "unexpected body with server message %d",
358 msg.type);
359 error(INTERNAL, errmsg);
360 }
361 break;
362 default:
363 error(INTERNAL, "unrecognized result from server process");
364 }
365 return(msg.type); /* return message type */
366 readerr:
367 if (feof(stdin))
368 error(SYSTEM, "server process died");
369 error(SYSTEM, "error reading from server process");
370 }
371
372
373 serv_request(type, nbytes, p) /* send a request to the server process */
374 int type, nbytes;
375 char *p;
376 {
377 MSGHEAD msg;
378 int m;
379 /* get server's attention for big request */
380 if (nbytes >= BIGREQSIZ-sizeof(MSGHEAD)) {
381 serv_request(DR_ATTEN, 0, NULL);
382 while ((m = serv_result()) != DS_ACKNOW)
383 if (m == DS_SHUTDOWN) /* the bugger quit on us */
384 quit(0);
385 }
386 msg.type = type; /* write and flush the message */
387 msg.nbytes = nbytes;
388 fwrite((char *)&msg, sizeof(MSGHEAD), 1, stdout);
389 if (nbytes > 0)
390 fwrite(p, 1, nbytes, stdout);
391 if (fflush(stdout) < 0)
392 error(SYSTEM, "write error in serv_request");
393 }
394
395
396 eputs(s) /* put error message to stderr */
397 register char *s;
398 {
399 static int midline = 0;
400
401 if (!*s)
402 return;
403 if (!midline++) { /* prepend line with program name */
404 fputs(progname, stderr);
405 fputs(": ", stderr);
406 }
407 fputs(s, stderr);
408 if (s[strlen(s)-1] == '\n') {
409 fflush(stderr);
410 midline = 0;
411 }
412 }
413
414
415 quit(code) /* clean up and exit */
416 int code;
417 {
418 if (odev.v.type)
419 dev_close();
420 exit(code);
421 }