ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo4.c
(Generate patch)

Comparing ray/src/hd/rholo4.c (file contents):
Revision 3.1 by gregl, Fri Oct 31 10:23:29 1997 UTC vs.
Revision 3.4 by gregl, Thu Nov 6 16:12:41 1997 UTC

# Line 10 | Line 10 | static char SCCSid[] = "$SunId$ SGI";
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 < open_display(dname)             /* open a display process */
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 <        error(INTERNAL, "display process unimplemented");
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 <        return(1);
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 < disp_packet(p)                  /* display a packet */
135 < register PACKET *p;
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   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines