ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo4.c
Revision: 3.3
Committed: Tue Nov 4 09:58:24 1997 UTC (26 years, 5 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 3.2: +13 -10 lines
Log Message:
minor bug fixes

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 communication
9 */
10
11 #include "rholo.h"
12 #include "rhdisp.h"
13 #include <sys/uio.h>
14
15 #ifndef HDSUF
16 #define HDSUF ".hdisp"
17 #endif
18
19 static int inp_flags;
20 static int dpd[3];
21 static int pipesiz;
22
23
24 disp_open(dname) /* open the named display driver */
25 char *dname;
26 {
27 char dpath[128], *com[2];
28 int i;
29
30 #ifdef DEVPATH
31 sprintf(dpath, "%s/%s%s", DEVPATH, dname, HDSUF);
32 #else
33 sprintf(dpath, "dev/%s%s", dname, HDSUF);
34 #endif
35 com[0] = dpath; com[1] = NULL;
36 pipesiz = open_process(dpd, com);
37 if (pipesiz <= 0)
38 error(USER, "cannot start display process");
39 inp_flags = 0;
40 /* write out hologram grids */
41 for (i = 0; hdlist[i] != NULL; i++)
42 disp_result(DS_ADDHOLO, sizeof(HDGRID), (char *)hdlist[i]);
43 }
44
45
46 disp_packet(p) /* display a packet */
47 register PACKET *p;
48 {
49 disp_result(DS_BUNDLE, sizeof(PACKHEAD) + p->nr*sizeof(RAYVAL),
50 (char *)p);
51 }
52
53
54 disp_check(block) /* check display process */
55 int block;
56 {
57 MSGHEAD msg;
58 int n;
59 char *buf = NULL;
60
61 if (pipesiz <= 0)
62 return(-1);
63 /* check read blocking */
64 if (block != (inp_flags == 0)) {
65 inp_flags = block ? 0 : FNONBLK;
66 if (fcntl(dpd[0], F_SETFL, inp_flags) < 0)
67 goto fcntlerr;
68 }
69 /* read message header */
70 n = read(dpd[0], (char *)&msg, sizeof(MSGHEAD));
71 if (n != sizeof(MSGHEAD)) {
72 if (n >= 0)
73 error(USER, "display process died");
74 if (errno != EAGAIN & errno != EINTR)
75 goto readerr;
76 return(2); /* acceptable failure */
77 }
78 if (msg.nbytes) { /* get the message body */
79 buf = (char *)malloc(msg.nbytes);
80 if (buf == NULL)
81 error(SYSTEM, "out of memory in disp_check");
82 if (fcntl(dpd[0], F_SETFL, inp_flags=0) < 0)
83 goto fcntlerr;
84 if (readbuf(dpd[0], buf, msg.nbytes) != msg.nbytes)
85 goto readerr;
86 }
87 switch (msg.type) { /* take appropriate action */
88 case DR_BUNDLE:
89 if (msg.nbytes != sizeof(PACKHEAD))
90 error(INTERNAL, "bad DR_BUNDLE from display process");
91 bundle_set(BS_ADD, (PACKHEAD *)buf, 1);
92 break;
93 case DR_NEWSET:
94 if (msg.nbytes % sizeof(PACKHEAD))
95 error(INTERNAL, "bad DR_NEWSET from display process");
96 disp_result(DS_STARTIMM, 0, NULL);
97 bundle_set(BS_NEW, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
98 disp_result(DS_ENDIMM, 0, NULL);
99 break;
100 case DR_ADDSET:
101 if (msg.nbytes % sizeof(PACKHEAD))
102 error(INTERNAL, "bad DR_ADDSET from display process");
103 disp_result(DS_STARTIMM, 0, NULL);
104 bundle_set(BS_ADD, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
105 disp_result(DS_ENDIMM, 0, NULL);
106 break;
107 case DR_DELSET:
108 if (msg.nbytes % sizeof(PACKHEAD))
109 error(INTERNAL, "bad DR_DELSET from display process");
110 bundle_set(BS_DEL, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
111 break;
112 case DR_ATTEN:
113 if (msg.nbytes)
114 error(INTERNAL, "bad DR_ATTEN from display process");
115 /* send acknowledgement */
116 disp_result(DS_ACKNOW, 0, NULL);
117 return(disp_check(1)); /* block on following request */
118 case DR_SHUTDOWN:
119 if (msg.nbytes)
120 error(INTERNAL, "bad DR_SHUTDOWN from display process");
121 return(0); /* zero return signals shutdown */
122 default:
123 error(INTERNAL, "unrecognized request from display process");
124 }
125 if (msg.nbytes) /* clean up */
126 free(buf);
127 return(1); /* normal return value */
128 fcntlerr:
129 error(SYSTEM, "cannot change display blocking mode");
130 readerr:
131 error(SYSTEM, "error reading from display process");
132 }
133
134
135 int
136 disp_close() /* close our display process */
137 {
138 int rval;
139
140 if (pipesiz <= 0)
141 return(-1);
142 disp_result(DS_SHUTDOWN, 0, NULL);
143 pipesiz = 0;
144 return(close_process(dpd));
145 }
146
147
148 disp_result(type, nbytes, p) /* send result message to display process */
149 int type, nbytes;
150 char *p;
151 {
152 struct iovec iov[2];
153 MSGHEAD msg;
154 int n;
155
156 if (pipesiz <= 0)
157 return;
158 msg.type = type;
159 msg.nbytes = nbytes;
160 if (nbytes == 0 || sizeof(MSGHEAD)+nbytes > pipesiz) {
161 do
162 n = write(dpd[1], (char *)&msg, sizeof(MSGHEAD));
163 while (n < 0 && errno == EINTR);
164 if (n != sizeof(MSGHEAD))
165 goto writerr;
166 if (nbytes > 0) {
167 n = writebuf(dpd[1], p, nbytes);
168 if (n != nbytes)
169 goto writerr;
170 }
171 return;
172 }
173 iov[0].iov_base = (char *)&msg;
174 iov[0].iov_len = sizeof(MSGHEAD);
175 iov[1].iov_base = p;
176 iov[1].iov_len = nbytes;
177 do
178 n = writev(dpd[1], iov, 2);
179 while (n < 0 && errno == EINTR);
180 if (n == sizeof(MSGHEAD)+nbytes)
181 return;
182 writerr:
183 error(SYSTEM, "write error in disp_result");
184 }