ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/devcomm.c
Revision: 2.9
Committed: Thu Jul 3 15:00:19 2003 UTC (20 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.8: +3 -1 lines
Log Message:
Added -N option to rad for parallel rendering (preliminary w/o using -PP)

File Contents

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