ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo4.c
Revision: 3.2
Committed: Mon Nov 3 18:33:14 1997 UTC (26 years, 5 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 3.1: +154 -5 lines
Log Message:
added more routines for display support

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