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.7 by gregl, Thu Nov 20 18:07:00 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 >        case DR_NOOP:
129 >                break;
130 >        default:
131 >                error(INTERNAL, "unrecognized request from display process");
132 >        }
133 >        if (msg.nbytes)                 /* clean up */
134 >                free(buf);
135 >        return(1);                      /* normal return value */
136 > fcntlerr:
137 >        error(SYSTEM, "cannot change display blocking mode");
138 > readerr:
139 >        error(SYSTEM, "error reading from display process");
140   }
141  
142  
143 < disp_packet(p)                  /* display a packet */
144 < register PACKET *p;
143 > int
144 > disp_close()                    /* close our display process */
145   {
146 +        int     rval;
147 +
148 +        if (dpout == NULL)
149 +                return(-1);
150 +        disp_result(DS_SHUTDOWN, 0, NULL);
151 +        fclose(dpout);
152 +        dpout = NULL;
153 +        return(close_process(dpd));
154 + }
155 +
156 +
157 + disp_result(type, nbytes, p)    /* queue result message to display process */
158 + int     type, nbytes;
159 + char    *p;
160 + {
161 +        MSGHEAD msg;
162 +
163 +        if (dpout == NULL)
164 +                return;
165 +        msg.type = type;
166 +        msg.nbytes = nbytes;
167 +        fwrite((char *)&msg, sizeof(MSGHEAD), 1, dpout);
168 +        if (nbytes > 0)
169 +                fwrite(p, 1, nbytes, dpout);
170 + }
171 +
172 +
173 + disp_flush()                    /* flush output to display */
174 + {
175 +        if (fflush(dpout) < 0)
176 +                error(SYSTEM, "error writing to the display process");
177   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines