ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo4.c
Revision: 3.4
Committed: Thu Nov 6 16:12:41 1997 UTC (26 years, 4 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 3.3: +4 -8 lines
Log Message:
changed disp_packet to take PACKHEAD* r.t. PACKET*

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 PACKHEAD *p;
48 {
49 disp_result(DS_BUNDLE, packsiz(p->nr), (char *)p);
50 }
51
52
53 disp_check(block) /* check display process */
54 int block;
55 {
56 MSGHEAD msg;
57 int n;
58 char *buf = NULL;
59
60 if (pipesiz <= 0)
61 return(-1);
62 /* check read blocking */
63 if (block != (inp_flags == 0)) {
64 inp_flags = block ? 0 : FNONBLK;
65 if (fcntl(dpd[0], F_SETFL, inp_flags) < 0)
66 goto fcntlerr;
67 }
68 /* read message header */
69 n = read(dpd[0], (char *)&msg, sizeof(MSGHEAD));
70 if (n != sizeof(MSGHEAD)) {
71 if (n >= 0)
72 error(USER, "display process died");
73 if (errno != EAGAIN & errno != EINTR)
74 goto readerr;
75 return(2); /* acceptable failure */
76 }
77 if (msg.nbytes) { /* get the message body */
78 buf = (char *)malloc(msg.nbytes);
79 if (buf == NULL)
80 error(SYSTEM, "out of memory in disp_check");
81 if (fcntl(dpd[0], F_SETFL, inp_flags=0) < 0)
82 goto fcntlerr;
83 if (readbuf(dpd[0], buf, msg.nbytes) != msg.nbytes)
84 goto readerr;
85 }
86 switch (msg.type) { /* take appropriate action */
87 case DR_BUNDLE:
88 if (msg.nbytes != sizeof(PACKHEAD))
89 error(INTERNAL, "bad DR_BUNDLE from display process");
90 bundle_set(BS_ADD, (PACKHEAD *)buf, 1);
91 break;
92 case DR_NEWSET:
93 if (msg.nbytes % sizeof(PACKHEAD))
94 error(INTERNAL, "bad DR_NEWSET from display process");
95 disp_result(DS_STARTIMM, 0, NULL);
96 bundle_set(BS_NEW, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
97 disp_result(DS_ENDIMM, 0, NULL);
98 break;
99 case DR_ADDSET:
100 if (msg.nbytes % sizeof(PACKHEAD))
101 error(INTERNAL, "bad DR_ADDSET from display process");
102 disp_result(DS_STARTIMM, 0, NULL);
103 bundle_set(BS_ADD, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
104 disp_result(DS_ENDIMM, 0, NULL);
105 break;
106 case DR_DELSET:
107 if (msg.nbytes % sizeof(PACKHEAD))
108 error(INTERNAL, "bad DR_DELSET from display process");
109 bundle_set(BS_DEL, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
110 break;
111 case DR_ATTEN:
112 if (msg.nbytes)
113 error(INTERNAL, "bad DR_ATTEN from display process");
114 /* send acknowledgement */
115 disp_result(DS_ACKNOW, 0, NULL);
116 return(disp_check(1)); /* block on following request */
117 case DR_SHUTDOWN:
118 if (msg.nbytes)
119 error(INTERNAL, "bad DR_SHUTDOWN from display process");
120 return(0); /* zero return signals shutdown */
121 default:
122 error(INTERNAL, "unrecognized request from display process");
123 }
124 if (msg.nbytes) /* clean up */
125 free(buf);
126 return(1); /* normal return value */
127 fcntlerr:
128 error(SYSTEM, "cannot change display blocking mode");
129 readerr:
130 error(SYSTEM, "error reading from display process");
131 }
132
133
134 int
135 disp_close() /* close our display process */
136 {
137 int rval;
138
139 if (pipesiz <= 0)
140 return(-1);
141 disp_result(DS_SHUTDOWN, 0, NULL);
142 pipesiz = 0;
143 return(close_process(dpd));
144 }
145
146
147 disp_result(type, nbytes, p) /* send result message to display process */
148 int type, nbytes;
149 char *p;
150 {
151 struct iovec iov[2];
152 MSGHEAD msg;
153 int n;
154
155 if (pipesiz <= 0)
156 return;
157 msg.type = type;
158 msg.nbytes = nbytes;
159 if (nbytes == 0 || sizeof(MSGHEAD)+nbytes > pipesiz) {
160 do
161 n = write(dpd[1], (char *)&msg, sizeof(MSGHEAD));
162 while (n < 0 && errno == EINTR);
163 if (n != sizeof(MSGHEAD))
164 goto writerr;
165 if (nbytes > 0 && writebuf(dpd[1], p, nbytes) != nbytes)
166 goto writerr;
167 return;
168 }
169 iov[0].iov_base = (char *)&msg;
170 iov[0].iov_len = sizeof(MSGHEAD);
171 iov[1].iov_base = p;
172 iov[1].iov_len = nbytes;
173 do
174 n = writev(dpd[1], iov, 2);
175 while (n < 0 && errno == EINTR);
176 if (n == sizeof(MSGHEAD)+nbytes)
177 return;
178 writerr:
179 error(SYSTEM, "write error in disp_result");
180 }