ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/sundev.c
Revision: 1.3
Committed: Mon Apr 17 10:08:14 1989 UTC (36 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +25 -26 lines
Log Message:
fixed bug in sun_getcur and added some error checking

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1988 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * sundev.c - standalone driver for Sunwindows.
9     *
10     * 10/3/88
11     */
12    
13     #include <stdio.h>
14     #include <fcntl.h>
15     #include <suntool/sunview.h>
16     #include <suntool/canvas.h>
17     #include <suntool/tty.h>
18    
19     #include "color.h"
20    
21     #include "driver.h"
22    
23     short icon_image[] = {
24     #include "suntools.icon"
25     };
26     DEFINE_ICON_FROM_IMAGE(sun_icon, icon_image);
27    
28     #ifndef TTYPROG
29     #define TTYPROG "sun.com" /* tty program */
30     #endif
31    
32     #define GAMMA 2.0 /* exponent for color correction */
33    
34     #define COMLH 3 /* number of command lines */
35    
36     #define hashcolr(c) ((67*(c)[RED]+59*(c)[GRN]+71*(c)[BLU])%NCOLORS)
37    
38     int colres = 128; /* color resolution */
39     COLR colrmap[256]; /* our color mapping */
40    
41     #define NCOLORS 251 /* color table size (prime) */
42     #define FIRSTCOLOR 2 /* first usable entry */
43    
44     COLR colrtbl[NCOLORS]; /* our color table */
45    
46     int sun_clear(), sun_paintr(), sun_getcur(),
47     sun_comout(), sun_comin();
48    
49     int (*dev_func[NREQUESTS])() = { /* request handlers */
50     sun_clear, sun_paintr, sun_getcur,
51     sun_comout, sun_comin
52     };
53    
54     FILE *ttyin;
55    
56     Frame frame = 0;
57     Tty tty = 0;
58     Canvas canvas = 0;
59    
60     int xres = 0, yres = 0;
61    
62     char *progname;
63    
64    
65     main(argc, argv)
66     int argc;
67     char *argv[];
68     {
69     extern Notify_value my_notice_destroy();
70     char *ttyargv[4], arg1[10], arg2[10];
71     int pd[2];
72     int com;
73    
74     progname = argv[0];
75    
76     frame = window_create(0, FRAME,
77     FRAME_LABEL, argc > 1 ? argv[1] : argv[0],
78     FRAME_ICON, &sun_icon,
79     WIN_X, 0, WIN_Y, 0,
80     0);
81     if (frame == 0)
82     quit("cannot create frame");
83     if (pipe(pd) == -1)
84     quit("cannot create pipe");
85     sprintf(arg1, "%d", getppid());
86     sprintf(arg2, "%d", pd[1]);
87     ttyargv[0] = TTYPROG;
88     ttyargv[1] = arg1;
89     ttyargv[2] = arg2;
90     ttyargv[3] = NULL;
91     #ifdef BSD
92     fcntl(pd[0], F_SETFD, 1);
93     #endif
94     tty = window_create(frame, TTY,
95     TTY_ARGV, ttyargv,
96     WIN_ROWS, COMLH,
97     0);
98     if (tty == 0)
99     quit("cannot create tty subwindow");
100     close(pd[1]);
101     if ((ttyin = fdopen(pd[0], "r")) == NULL)
102     quit("cannot open tty");
103     canvas = window_create(frame, CANVAS,
104     CANVAS_RETAINED, FALSE,
105     WIN_INPUT_DESIGNEE, window_get(tty,WIN_DEVICE_NUMBER),
106     WIN_CONSUME_PICK_EVENTS, WIN_NO_EVENTS,
107     MS_LEFT, MS_MIDDLE, MS_RIGHT, 0,
108     0);
109     if (canvas == 0)
110     quit("cannot create canvas");
111     if (getmap() < 0)
112     quit("not a color screen");
113     window_set(canvas, CANVAS_RETAINED, TRUE, 0);
114     notify_interpose_destroy_func(frame, my_notice_destroy);
115    
116     while ((com = getc(stdin)) != EOF) { /* loop on requests */
117     if (com >= NREQUESTS || dev_func[com] == NULL)
118     quit("invalid request");
119     (*dev_func[com])();
120     }
121     quit(NULL);
122     }
123    
124    
125     quit(msg) /* exit */
126     char *msg;
127     {
128     if (msg != NULL) {
129     fprintf(stderr, "%s: %s\n", progname, msg);
130 greg 1.2 kill(getppid(), SIGPIPE);
131 greg 1.1 exit(1);
132     }
133     exit(0);
134     }
135    
136    
137     Notify_value
138     my_notice_destroy(fr, st) /* we're on our way out */
139     Frame fr;
140     Destroy_status st;
141     {
142     if (st != DESTROY_CHECKING) {
143 greg 1.3 kill((int)window_get(tty, TTY_PID), SIGPIPE);
144     kill(getppid(), SIGPIPE);
145 greg 1.1 }
146     return(notify_next_destroy_func(fr, st));
147     }
148    
149    
150     sun_clear() /* clear our canvas */
151     {
152     register Pixwin *pw;
153     int nwidth, nheight;
154    
155     fread(&nwidth, sizeof(nwidth), 1, stdin);
156     fread(&nheight, sizeof(nheight), 1, stdin);
157     pw = canvas_pixwin(canvas);
158     if (nwidth != xres || nheight != yres) {
159     window_set(frame, WIN_SHOW, FALSE, 0);
160     window_set(canvas, CANVAS_AUTO_SHRINK, TRUE,
161     CANVAS_AUTO_EXPAND, TRUE, 0);
162     window_set(canvas, WIN_WIDTH, nwidth, WIN_HEIGHT, nheight, 0);
163     window_set(canvas, CANVAS_AUTO_SHRINK, FALSE,
164     CANVAS_AUTO_EXPAND, FALSE, 0);
165     window_fit(frame);
166     window_set(frame, WIN_SHOW, TRUE, 0);
167     notify_do_dispatch();
168     xres = nwidth;
169     yres = nheight;
170     }
171     pw_writebackground(pw, 0, 0, xres, xres, PIX_SRC);
172     newmap();
173     }
174    
175    
176     sun_paintr() /* fill a rectangle */
177     {
178     COLOR col;
179     int pval;
180     int xmin, ymin, xmax, ymax;
181     register Pixwin *pw;
182    
183     fread(col, sizeof(COLOR), 1, stdin);
184     fread(&xmin, sizeof(xmin), 1, stdin);
185     fread(&ymin, sizeof(ymin), 1, stdin);
186     fread(&xmax, sizeof(xmax), 1, stdin);
187     fread(&ymax, sizeof(ymax), 1, stdin);
188     pval = pixel(col);
189     pw = canvas_pixwin(canvas);
190     pw_rop(pw, xmin, yres-ymax, xmax-xmin, ymax-ymin,
191     PIX_SRC|PIX_COLOR(pval), NULL, 0, 0);
192     }
193    
194    
195     sun_comout() /* output a string to command line */
196     {
197     char out[256];
198    
199     mygets(out, stdin);
200     ttyputs(out);
201     }
202    
203    
204     sun_comin() /* input a string from the command line */
205     {
206     char buf[256];
207     /* echo characters */
208     do {
209     mygets(buf, ttyin);
210     ttyputs(buf);
211     } while (buf[0]);
212     /* get result */
213     mygets(buf, ttyin);
214     /* send reply */
215     putc(COM_COMIN, stdout);
216     myputs(buf, stdout);
217     fflush(stdout);
218     }
219    
220    
221     sun_getcur() /* get cursor position */
222     {
223 greg 1.3 Event ev;
224 greg 1.1 int xpos, ypos;
225     int c;
226    
227     notify_no_dispatch(); /* allow read to block */
228     window_set(canvas, WIN_CONSUME_KBD_EVENT, WIN_ASCII_EVENTS, 0);
229 greg 1.3 again:
230     if (window_read_event(canvas, &ev) == -1) {
231     notify_perror();
232     quit("window event read error");
233     }
234     c = event_id(&ev);
235     switch (c) {
236     case MS_LEFT:
237     c = MB1;
238 greg 1.1 break;
239 greg 1.3 case MS_MIDDLE:
240     c = MB2;
241     break;
242     case MS_RIGHT:
243     c = MB3;
244     break;
245     default:
246     if (c < ASCII_FIRST || c > ASCII_LAST)
247     goto again;
248     break;
249 greg 1.1 }
250 greg 1.3 xpos = event_x(&ev);
251     ypos = yres-1 - event_y(&ev);
252    
253 greg 1.1 window_set(canvas, WIN_IGNORE_KBD_EVENT, WIN_ASCII_EVENTS, 0);
254     notify_do_dispatch();
255     putc(COM_GETCUR, stdout);
256     putc(c, stdout);
257     fwrite(&xpos, sizeof(xpos), 1, stdout);
258     fwrite(&ypos, sizeof(ypos), 1, stdout);
259     fflush(stdout);
260     }
261    
262    
263     mygets(s, fp) /* get string from file (with nul) */
264     register char *s;
265     register FILE *fp;
266     {
267     register int c;
268    
269     while ((c = getc(fp)) != EOF)
270     if ((*s++ = c) == '\0')
271     return;
272     *s = '\0';
273     }
274    
275    
276     myputs(s, fp) /* put string to file (with nul) */
277     register char *s;
278     register FILE *fp;
279     {
280     do
281     putc(*s, fp);
282     while (*s++);
283     }
284    
285    
286     ttyputs(s) /* put string out to tty subwindow */
287     register char *s;
288     {
289     char buf[256];
290     register char *cp;
291    
292     for (cp = buf; *s; s++) {
293     if (*s == '\n')
294     *cp++ = '\r';
295     *cp++ = *s;
296     }
297     ttysw_output(tty, buf, cp-buf);
298     }
299    
300    
301     int
302     pixel(col) /* return pixel value for color */
303     COLOR col;
304     {
305     COLR clr;
306     register int ndx;
307    
308     mapcolor(clr, col);
309     while ((ndx = insertcolr(clr)) < 0) {
310     reduce_colres();
311     mapcolor(clr, col);
312     }
313     return(ndx+FIRSTCOLOR);
314     }
315    
316    
317     int
318     insertcolr(clr) /* insert a new color */
319     register COLR clr;
320     {
321     int hval;
322     register int ndx, i;
323    
324     hval = ndx = hashcolr(clr);
325    
326     for (i = 1; i < NCOLORS; i++) {
327     if (colrtbl[ndx][EXP] == 0) {
328     colrtbl[ndx][RED] = clr[RED];
329     colrtbl[ndx][GRN] = clr[GRN];
330     colrtbl[ndx][BLU] = clr[BLU];
331     colrtbl[ndx][EXP] = COLXS;
332     newcolr(ndx, clr);
333     return(ndx);
334     }
335     if ( colrtbl[ndx][RED] == clr[RED] &&
336     colrtbl[ndx][GRN] == clr[GRN] &&
337     colrtbl[ndx][BLU] == clr[BLU] )
338     return(ndx);
339     ndx = (hval + i*i) % NCOLORS;
340     }
341     return(-1);
342     }
343    
344    
345     newcolr(ndx, clr) /* enter a color into hardware table */
346     int ndx;
347     COLR clr;
348     {
349     register Pixwin *pw;
350    
351     pw = canvas_pixwin(canvas);
352     pw_putcolormap(pw, ndx+FIRSTCOLOR, 1,
353     &clr[RED], &clr[GRN], &clr[BLU]);
354     pw = (Pixwin *)window_get(tty, WIN_PIXWIN);
355     pw_putcolormap(pw, ndx+FIRSTCOLOR, 1,
356     &clr[RED], &clr[GRN], &clr[BLU]);
357     }
358    
359    
360     reduce_colres() /* reduce the color resolution */
361     {
362     COLR oldtbl[NCOLORS];
363     unsigned char pixmap[256];
364     Pixwin *pw;
365     register int i, j;
366     register unsigned char *p;
367    
368     ttyputs("remapping colors...\n");
369     bcopy(colrtbl, oldtbl, sizeof(oldtbl));
370     colres >>= 1;
371     newmap();
372     for (i = 0; i < 256; i++)
373     pixmap[i] = i;
374     for (i = 0; i < NCOLORS; i++)
375     if (oldtbl[i][EXP] != 0) {
376     for (j = 0; j < 3; j++)
377     oldtbl[i][j] = ((oldtbl[i][j]*colres/256) *
378     256 + 128)/colres;
379     pixmap[i+FIRSTCOLOR] = insertcolr(oldtbl[i])+FIRSTCOLOR;
380     }
381     pw = canvas_pixwin(canvas);
382     /* I probably should get my own memory */
383     p = (unsigned char *)mpr_d(pw->pw_prretained)->md_image;
384     for (j = 0; j < yres; j++) {
385     for (i = 0; i < xres; i++) {
386     *p = pixmap[*p];
387     p++;
388     }
389     if (xres&1) /* 16-bit boundaries */
390     p++;
391     }
392     pw_rop(pw, 0, 0, xres, yres, PIX_SRC, pw->pw_prretained, 0, 0);
393     }
394    
395    
396     mapcolor(clr, col) /* map to our color space */
397     COLR clr;
398     COLOR col;
399     {
400     register int i, p;
401     /* compute color table value */
402     for (i = 0; i < 3; i++) {
403     p = colval(col,i) * 255.0 + 0.5;
404     if (p < 0) p = 0;
405     else if (p > 255) p = 255;
406     clr[i] = colrmap[p][i];
407     }
408     clr[EXP] = COLXS;
409     }
410    
411    
412     getmap() /* allocate color map segments */
413     {
414     char cmsname[20];
415     unsigned char red[256], green[256], blue[256];
416     register Pixwin *pw;
417     register int i;
418    
419     for (i = 0; i < 256; i++)
420     red[i] = green[i] = blue[i] = 128;
421     red[0] = green[0] = blue[0] = 255;
422     red[1] = green[1] = blue[1] = 0;
423     red[255] = green[255] = blue[255] = 0;
424     red[254] = green[254] = blue[254] = 255;
425     red[253] = green[253] = blue[253] = 0;
426     /* name shared segment */
427     sprintf(cmsname, "rv%d", getpid());
428     /* set canvas */
429     pw = canvas_pixwin(canvas);
430     if (pw->pw_pixrect->pr_depth < 8)
431     return(-1);
432     pw_setcmsname(pw, cmsname);
433     pw_putcolormap(pw, 0, 256, red, green, blue);
434     /* set tty subwindow */
435     pw = (Pixwin *)window_get(tty, WIN_PIXWIN);
436     pw_setcmsname(pw, cmsname);
437     pw_putcolormap(pw, 0, 256, red, green, blue);
438     /* set frame */
439     pw = (Pixwin *)window_get(frame, WIN_PIXWIN);
440     pw_setcmsname(pw, cmsname);
441     pw_putcolormap(pw, 0, 256, red, green, blue);
442    
443     return(0);
444     }
445    
446    
447     newmap() /* initialize our color table */
448     {
449     double pow();
450     int val;
451     register int i;
452    
453     for (i = 0; i < 256; i++) {
454     val = pow(i/256.0, 1.0/GAMMA) * colres;
455     val = (val*256 + 128) / colres;
456     colrmap[i][RED] = colrmap[i][GRN] = colrmap[i][BLU] = val;
457     colrmap[i][EXP] = COLXS;
458     }
459     for (i = 0; i < NCOLORS; i++)
460     colrtbl[i][EXP] = 0;
461     }