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.5 by gregl, Mon Nov 10 18:07:15 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 > static FILE     *dpout;
23 >
24 >
25 > disp_open(dname)                /* open the named display driver */
26   char    *dname;
27   {
28 <        error(INTERNAL, "display process unimplemented");
28 >        char    dpath[128], *com[3];
29 >        int     i;
30 >
31 > #ifdef DEVPATH
32 >        sprintf(dpath, "%s/%s%s", DEVPATH, dname, HDSUF);
33 > #else
34 >        sprintf(dpath, "dev/%s%s", dname, HDSUF);
35 > #endif
36 >        com[0] = dpath; com[1] = froot; com[2] = NULL;
37 >        pipesiz = open_process(dpd, com);
38 >        if (pipesiz <= 0)
39 >                error(USER, "cannot start display process");
40 >        if ((dpout = fdopen(dup(dpd[1]), "w")) == NULL)
41 >                error(SYSTEM, "cannot associate FILE with display pipe");
42 >        inp_flags = 0;
43 >                                /* write out hologram grids */
44 >        for (i = 0; hdlist[i] != NULL; i++)
45 >                disp_result(DS_ADDHOLO, sizeof(HDGRID), (char *)hdlist[i]);
46 >        disp_flush();
47   }
48  
49  
50 + disp_packet(p)                  /* display a packet */
51 + register PACKHEAD       *p;
52 + {
53 +        disp_result(DS_BUNDLE, packsiz(p->nr), (char *)p);
54 + }
55 +
56 +
57   disp_check(block)               /* check display process */
58   int     block;
59   {
60 <        return(1);
60 >        MSGHEAD msg;
61 >        int     n;
62 >        char    *buf = NULL;
63 >
64 >        if (pipesiz <= 0)
65 >                return(-1);
66 >                                        /* flush display output */
67 >        disp_flush();
68 >                                        /* check read blocking */
69 >        if (block != (inp_flags == 0)) {
70 >                inp_flags = block ? 0 : FNONBLK;
71 >                if (fcntl(dpd[0], F_SETFL, inp_flags) < 0)
72 >                        goto fcntlerr;
73 >        }
74 >                                        /* read message header */
75 >        n = read(dpd[0], (char *)&msg, sizeof(MSGHEAD));
76 >        if (n != sizeof(MSGHEAD)) {
77 >                if (n >= 0)
78 >                        error(USER, "display process died");
79 >                if (errno != EAGAIN & errno != EINTR)
80 >                        goto readerr;
81 >                return(2);              /* acceptable failure */
82 >        }
83 >        if (msg.nbytes) {               /* get the message body */
84 >                buf = (char *)malloc(msg.nbytes);
85 >                if (buf == NULL)
86 >                        error(SYSTEM, "out of memory in disp_check");
87 >                if (fcntl(dpd[0], F_SETFL, inp_flags=0) < 0)
88 >                        goto fcntlerr;
89 >                if (readbuf(dpd[0], buf, msg.nbytes) != msg.nbytes)
90 >                        goto readerr;
91 >        }
92 >        switch (msg.type) {             /* take appropriate action */
93 >        case DR_BUNDLE:
94 >                if (msg.nbytes != sizeof(PACKHEAD))
95 >                        error(INTERNAL, "bad DR_BUNDLE from display process");
96 >                bundle_set(BS_ADD, (PACKHEAD *)buf, 1);
97 >                break;
98 >        case DR_NEWSET:
99 >                if (msg.nbytes % sizeof(PACKHEAD))
100 >                        error(INTERNAL, "bad DR_NEWSET from display process");
101 >                disp_result(DS_STARTIMM, 0, NULL);
102 >                bundle_set(BS_NEW, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
103 >                disp_result(DS_ENDIMM, 0, NULL);
104 >                disp_flush();
105 >                break;
106 >        case DR_ADDSET:
107 >                if (msg.nbytes % sizeof(PACKHEAD))
108 >                        error(INTERNAL, "bad DR_ADDSET from display process");
109 >                disp_result(DS_STARTIMM, 0, NULL);
110 >                bundle_set(BS_ADD, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
111 >                disp_result(DS_ENDIMM, 0, NULL);
112 >                disp_flush();
113 >                break;
114 >        case DR_DELSET:
115 >                if (msg.nbytes % sizeof(PACKHEAD))
116 >                        error(INTERNAL, "bad DR_DELSET from display process");
117 >                bundle_set(BS_DEL, (PACKHEAD *)buf, msg.nbytes/sizeof(PACKHEAD));
118 >                break;
119 >        case DR_ATTEN:
120 >                if (msg.nbytes)
121 >                        error(INTERNAL, "bad DR_ATTEN from display process");
122 >                                        /* send acknowledgement */
123 >                disp_result(DS_ACKNOW, 0, NULL);
124 >                return(disp_check(1));  /* block on following request */
125 >        case DR_SHUTDOWN:
126 >                if (msg.nbytes)
127 >                        error(INTERNAL, "bad DR_SHUTDOWN from display process");
128 >                return(0);              /* zero return signals shutdown */
129 >        default:
130 >                error(INTERNAL, "unrecognized request from display process");
131 >        }
132 >        if (msg.nbytes)                 /* clean up */
133 >                free(buf);
134 >        return(1);                      /* normal return value */
135 > fcntlerr:
136 >        error(SYSTEM, "cannot change display blocking mode");
137 > readerr:
138 >        error(SYSTEM, "error reading from display process");
139   }
140  
141  
142 < disp_packet(p)                  /* display a packet */
143 < register PACKET *p;
142 > int
143 > disp_close()                    /* close our display process */
144   {
145 +        int     rval;
146 +
147 +        if (pipesiz <= 0)
148 +                return(-1);
149 +        disp_result(DS_SHUTDOWN, 0, NULL);
150 +        fclose(dpout);
151 +        dpout = NULL;
152 +        pipesiz = 0;
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 +        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