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.6 by gregl, Thu Nov 20 11:40:11 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 FILE     *dpout;
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[3];
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] = froot; com[2] = NULL;
36 >        i = open_process(dpd, com);
37 >        if (i <= 0)
38 >                error(USER, "cannot start display process");
39 >        if ((dpout = fdopen(dup(dpd[1]), "w")) == NULL)
40 >                error(SYSTEM, "cannot associate FILE with display pipe");
41 >        inp_flags = 0;
42 >                                /* write out hologram grids */
43 >        for (i = 0; hdlist[i] != NULL; i++)
44 >                disp_result(DS_ADDHOLO, sizeof(HDGRID), (char *)hdlist[i]);
45 >        disp_flush();
46   }
47  
48  
49 + disp_packet(p)                  /* display a packet */
50 + register PACKHEAD       *p;
51 + {
52 +        disp_result(DS_BUNDLE, packsiz(p->nr), (char *)p);
53 + }
54 +
55 +
56   disp_check(block)               /* check display process */
57   int     block;
58   {
59 <        return(1);
59 >        MSGHEAD msg;
60 >        int     n;
61 >        char    *buf = NULL;
62 >
63 >        if (dpout == NULL)
64 >                return(-1);
65 >                                        /* flush display output */
66 >        disp_flush();
67 >                                        /* check read blocking */
68 >        if (block != (inp_flags == 0)) {
69 >                inp_flags = block ? 0 : FNONBLK;
70 >                if (fcntl(dpd[0], F_SETFL, inp_flags) < 0)
71 >                        goto fcntlerr;
72 >        }
73 >                                        /* read message header */
74 >        n = read(dpd[0], (char *)&msg, sizeof(MSGHEAD));
75 >        if (n != sizeof(MSGHEAD)) {
76 >                if (n >= 0)
77 >                        error(USER, "display process died");
78 >                if (errno != EAGAIN & errno != EINTR)
79 >                        goto readerr;
80 >                return(2);              /* acceptable failure */
81 >        }
82 >        if (msg.nbytes) {               /* get the message body */
83 >                buf = (char *)malloc(msg.nbytes);
84 >                if (buf == NULL)
85 >                        error(SYSTEM, "out of memory in disp_check");
86 >                if (fcntl(dpd[0], F_SETFL, inp_flags=0) < 0)
87 >                        goto fcntlerr;
88 >                if (readbuf(dpd[0], buf, msg.nbytes) != msg.nbytes)
89 >                        goto readerr;
90 >        }
91 >        switch (msg.type) {             /* take appropriate action */
92 >        case DR_BUNDLE:
93 >                if (msg.nbytes != sizeof(PACKHEAD))
94 >                        error(INTERNAL, "bad DR_BUNDLE from display process");
95 >                bundle_set(BS_ADD, (PACKHEAD *)buf, 1);
96 >                break;
97 >        case DR_NEWSET:
98 >                if (msg.nbytes % sizeof(PACKHEAD))
99 >                        error(INTERNAL, "bad DR_NEWSET from display process");
100 >                disp_result(DS_STARTIMM, 0, NULL);
101 >                bundle_set(BS_NEW, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
102 >                disp_result(DS_ENDIMM, 0, NULL);
103 >                disp_flush();
104 >                break;
105 >        case DR_ADDSET:
106 >                if (msg.nbytes % sizeof(PACKHEAD))
107 >                        error(INTERNAL, "bad DR_ADDSET from display process");
108 >                disp_result(DS_STARTIMM, 0, NULL);
109 >                bundle_set(BS_ADD, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
110 >                disp_result(DS_ENDIMM, 0, NULL);
111 >                disp_flush();
112 >                break;
113 >        case DR_DELSET:
114 >                if (msg.nbytes % sizeof(PACKHEAD))
115 >                        error(INTERNAL, "bad DR_DELSET from display process");
116 >                bundle_set(BS_DEL, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
117 >                break;
118 >        case DR_ATTEN:
119 >                if (msg.nbytes)
120 >                        error(INTERNAL, "bad DR_ATTEN from display process");
121 >                                        /* send acknowledgement */
122 >                disp_result(DS_ACKNOW, 0, NULL);
123 >                return(disp_check(1));  /* block on following request */
124 >        case DR_SHUTDOWN:
125 >                if (msg.nbytes)
126 >                        error(INTERNAL, "bad DR_SHUTDOWN from display process");
127 >                return(0);              /* zero return signals shutdown */
128 >        default:
129 >                error(INTERNAL, "unrecognized request from display process");
130 >        }
131 >        if (msg.nbytes)                 /* clean up */
132 >                free(buf);
133 >        return(1);                      /* normal return value */
134 > fcntlerr:
135 >        error(SYSTEM, "cannot change display blocking mode");
136 > readerr:
137 >        error(SYSTEM, "error reading from display process");
138   }
139  
140  
141 < disp_packet(p)                  /* display a packet */
142 < register PACKET *p;
141 > int
142 > disp_close()                    /* close our display process */
143   {
144 +        int     rval;
145 +
146 +        if (dpout == NULL)
147 +                return(-1);
148 +        disp_result(DS_SHUTDOWN, 0, NULL);
149 +        fclose(dpout);
150 +        dpout = NULL;
151 +        return(close_process(dpd));
152 + }
153 +
154 +
155 + disp_result(type, nbytes, p)    /* queue result message to display process */
156 + int     type, nbytes;
157 + char    *p;
158 + {
159 +        MSGHEAD msg;
160 +
161 +        if (dpout == NULL)
162 +                return;
163 +        msg.type = type;
164 +        msg.nbytes = nbytes;
165 +        fwrite((char *)&msg, sizeof(MSGHEAD), 1, dpout);
166 +        if (nbytes > 0)
167 +                fwrite(p, 1, nbytes, dpout);
168 + }
169 +
170 +
171 + disp_flush()                    /* flush output to display */
172 + {
173 +        if (fflush(dpout) < 0)
174 +                error(SYSTEM, "error writing to the display process");
175   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines