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 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

# Content
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 kill(getppid(), SIGPIPE);
131 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 kill((int)window_get(tty, TTY_PID), SIGPIPE);
144 kill(getppid(), SIGPIPE);
145 }
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 Event ev;
224 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 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 break;
239 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 }
250 xpos = event_x(&ev);
251 ypos = yres-1 - event_y(&ev);
252
253 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 }