ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/devcomm.c
Revision: 2.15
Committed: Thu Aug 21 07:05:58 2008 UTC (15 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R0
Changes since 2.14: +3 -1 lines
Log Message:
Added -n option to rvu for multiple rendering processes

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: devcomm.c,v 2.14 2008/05/01 15:50:28 greg Exp $";
3 #endif
4 /*
5 * devcomm.c - communication routines for separate drivers.
6 *
7 * External symbols declared in driver.h
8 */
9
10 #include "copyright.h"
11
12 #include <sys/types.h>
13 #include <sys/wait.h> /* XXX platform specific */
14
15 #include "platform.h"
16 #include "standard.h"
17 #include "driver.h"
18
19 #ifndef DEVPATH
20 #define DEVPATH getenv("PATH") /* device search path */
21 #endif
22
23 FILE *devin, *devout;
24 int devchild;
25
26 static struct driver * final_connect(void);
27 static void mygets(char *s, FILE *fp);
28 static void myputs(char *s, FILE *fp);
29 static void reply_error(char *routine);
30 static void getstate(void);
31
32 static dr_closef_t comm_close;
33 static dr_clearf_t comm_clear;
34 static dr_paintrf_t comm_paintr;
35 static dr_getcurf_t comm_getcur;
36 static dr_comoutf_t comm_comout;
37 static dr_cominf_t comm_comin;
38 static dr_flushf_t comm_flush;
39
40 struct driver comm_driver = {
41 comm_close, comm_clear, comm_paintr, comm_getcur,
42 comm_comout, comm_comin, comm_flush
43 };
44
45
46 static struct driver *
47 final_connect(void) /* verify and initialize connection */
48 {
49 putw(COM_SENDM, devout);
50 fflush(devout);
51 if (getw(devin) != COM_RECVM)
52 return(NULL);
53 /* get driver parameters */
54 getstate();
55 /* set error vectors */
56 erract[COMMAND].pf = comm_comout;
57 /* doesn't work with raypcalls.c
58 if (erract[WARNING].pf != NULL)
59 erract[WARNING].pf = comm_comout;
60 */
61 return(&comm_driver);
62 }
63
64
65 extern struct driver *
66 slave_init( /* run rview in slave mode */
67 char *dname,
68 char *id
69 )
70 {
71 devchild = -1; /* we're the slave here */
72 devout = stdout; /* use standard input */
73 devin = stdin; /* and standard output */
74 return(final_connect()); /* verify initialization */
75 }
76
77
78 extern struct driver *
79 comm_init( /* set up and execute driver */
80 char *dname,
81 char *id
82 )
83 {
84 char *dvcname;
85 int p1[2], p2[2];
86 char pin[16], pout[16];
87 /* find driver program */
88 if ((dvcname = getpath(dname, DEVPATH, X_OK)) == NULL) {
89 eputs(dname);
90 eputs(": not found\n");
91 return(NULL);
92 }
93 #ifdef RHAS_FORK_EXEC
94 /* open communication pipes */
95 if (pipe(p1) == -1 || pipe(p2) == -1)
96 goto syserr;
97 if ((devchild = fork()) == 0) { /* fork driver process */
98 close(p1[1]);
99 close(p2[0]);
100 sprintf(pin, "%d", p1[0]);
101 sprintf(pout, "%d", p2[1]);
102 execl(dvcname, dname, pin, pout, id, NULL);
103 perror(dvcname);
104 _exit(127);
105 }
106 if (devchild == -1)
107 goto syserr;
108 close(p1[0]);
109 close(p2[1]);
110 /*
111 * Close write stream on exec to avoid multiprocessing deadlock.
112 * No use in read stream without it, so set flag there as well.
113 */
114 fcntl(p1[1], F_SETFD, FD_CLOEXEC);
115 fcntl(p2[0], F_SETFD, FD_CLOEXEC);
116 if ((devout = fdopen(p1[1], "w")) == NULL)
117 goto syserr;
118 if ((devin = fdopen(p2[0], "r")) == NULL)
119 goto syserr;
120 return(final_connect()); /* verify initialization */
121 syserr:
122 perror(dname);
123 return(NULL);
124
125 #else /* ! RHAS_FORK_EXEC */
126
127 eputs(dname);
128 eputs(": no fork/exec\n");
129 return(NULL);
130
131 #endif /* ! RHAS_FORK_EXEC */
132 }
133
134
135 static void
136 comm_close(void) /* done with driver */
137 {
138 int pid;
139
140 erract[COMMAND].pf = NULL; /* reset error vectors */
141 if (erract[WARNING].pf != NULL)
142 erract[WARNING].pf = wputs;
143 fclose(devout);
144 fclose(devin);
145 if (devchild < 0)
146 return;
147 while ((pid = wait(0)) != -1 && pid != devchild)
148 ;
149 }
150
151
152 static void
153 comm_clear( /* clear screen */
154 int xres,
155 int yres
156 )
157 {
158 putc(COM_CLEAR, devout);
159 putw(xres, devout);
160 putw(yres, devout);
161 fflush(devout);
162 }
163
164
165 static void
166 comm_paintr( /* paint a rectangle */
167 COLOR col,
168 int xmin,
169 int ymin,
170 int xmax,
171 int ymax
172 )
173 {
174 putc(COM_PAINTR, devout);
175 fwrite((char *)col, sizeof(COLOR), 1, devout);
176 putw(xmin, devout);
177 putw(ymin, devout);
178 putw(xmax, devout);
179 putw(ymax, devout);
180 }
181
182
183 static void
184 comm_flush(void) /* flush output to driver */
185 {
186 putc(COM_FLUSH, devout);
187 fflush(devout);
188 if (getc(devin) != COM_FLUSH)
189 reply_error("flush");
190 getstate();
191 }
192
193
194 static int
195 comm_getcur( /* get and return cursor position */
196 int *xp,
197 int *yp
198 )
199 {
200 int c;
201
202 putc(COM_GETCUR, devout);
203 fflush(devout);
204 if (getc(devin) != COM_GETCUR)
205 reply_error("getcur");
206 c = getc(devin);
207 *xp = getw(devin);
208 *yp = getw(devin);
209 return(c);
210 }
211
212
213 static void
214 comm_comout( /* print string to command line */
215 char *str
216 )
217 {
218 putc(COM_COMOUT, devout);
219 myputs(str, devout);
220 if (str[strlen(str)-1] == '\n')
221 fflush(devout);
222 }
223
224
225 static void
226 comm_comin( /* read string from command line */
227 char *buf,
228 char *prompt
229 )
230 {
231 putc(COM_COMIN, devout);
232 if (prompt == NULL)
233 putc(0, devout);
234 else {
235 putc(1, devout);
236 myputs(prompt, devout);
237 }
238 fflush(devout);
239 if (getc(devin) != COM_COMIN)
240 reply_error("comin");
241 mygets(buf, devin);
242 getstate();
243 }
244
245
246 static void
247 mygets( /* get string from file (with nul) */
248 register char *s,
249 register FILE *fp
250 )
251 {
252 register int c;
253
254 while ((c = getc(fp)) != EOF)
255 if ((*s++ = c) == '\0')
256 return;
257 *s = '\0';
258 }
259
260
261 static void
262 myputs( /* put string to file (with nul) */
263 register char *s,
264 register FILE *fp
265 )
266 {
267 do
268 putc(*s, fp);
269 while (*s++);
270 }
271
272
273 static void
274 reply_error( /* what should we do here? */
275 char *routine
276 )
277 {
278 eputs(routine);
279 eputs(": driver reply error\n");
280 quit(1);
281 }
282
283
284 static void
285 getstate(void) /* get driver state variables */
286 {
287 fread((char *)&comm_driver.pixaspect,
288 sizeof(comm_driver.pixaspect), 1, devin);
289 comm_driver.xsiz = getw(devin);
290 comm_driver.ysiz = getw(devin);
291 comm_driver.inpready = getw(devin);
292 }