ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x10.c
Revision: 1.9
Committed: Fri Jun 2 17:21:26 1989 UTC (35 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.8: +3 -1 lines
Log Message:
Changed WFLUSH value and added output to flush so rview would
die with X-windows when the server was killed and rview iconified

File Contents

# Content
1 /* Copyright (c) 1987 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * x10.c - driver for X-windows version 10.4
9 *
10 * 5/7/87
11 */
12
13 #include <stdio.h>
14
15 #include <sys/ioctl.h>
16
17 #include <X/Xlib.h>
18 #include <X/cursors/bcross.cursor>
19 #include <X/cursors/bcross_mask.cursor>
20
21 #include "color.h"
22
23 #include "driver.h"
24
25 #include "xtwind.h"
26
27 #define GAMMA 2.0 /* exponent for color correction */
28
29 #define BORWIDTH 5 /* border width */
30 #define BARHEIGHT 25 /* menu bar size */
31 #define COMHEIGHT (COMLH*COMCH) /* command line height (pixels) */
32
33 #define COMFN "8x13" /* command line font name */
34 #define COMLH 3 /* number of command lines */
35 #define COMCW 8 /* approx. character width (pixels) */
36 #define COMCH 13 /* approx. character height (pixels) */
37
38 #ifndef WFLUSH
39 #define WFLUSH 50 /* flush after this many rays */
40 #endif
41
42 #define hashcolr(c) ((67*(c)[RED]+59*(c)[GRN]+71*(c)[BLU])%ncolors)
43
44 #define checkinp() while (XPending() > 0) getevent()
45
46 #define levptr(etype) ((etype *)&thisevent)
47
48 static char *clientname; /* calling client's name */
49
50 static XEvent thisevent; /* current event */
51
52 static int colres = 128; /* color resolution */
53 static COLR colrmap[256]; /* our color mapping */
54
55 static int ncolors = 0; /* color table size */
56 static COLR *colrtbl; /* our color table */
57 static int *pixval; /* associated pixel values */
58
59 static Display *ourdisplay = NULL; /* our display */
60
61 static Window gwind = 0; /* our graphics window */
62
63 static Cursor pickcursor = 0; /* cursor used for picking */
64
65 static int gwidth = 0; /* graphics window width */
66 static int gheight = 0; /* graphics window height */
67
68 static TEXTWIND *comline = NULL; /* our command line */
69
70 static int c_erase, c_kill; /* erase and kill characters */
71
72 static char c_queue[64]; /* input queue */
73 static int c_first = 0; /* first character in queue */
74 static int c_last = 0; /* last character in queue */
75
76 extern char *malloc();
77
78 int x_close(), x_clear(), x_paintr(), x_errout(),
79 x_getcur(), x_comout(), x_comin();
80
81 static struct driver x_driver = {
82 x_close, x_clear, x_paintr, x_getcur,
83 x_comout, x_comin,
84 MAXRES, MAXRES
85 };
86
87
88 struct driver *
89 x_init(name) /* initialize driver */
90 char *name;
91 {
92 struct sgttyb ttymode;
93
94 if (isatty(0)) {
95 ioctl(0, TIOCGETP, &ttymode);
96 c_erase = ttymode.sg_erase;
97 c_kill = ttymode.sg_kill;
98 } else {
99 c_erase = 'H'-'@';
100 c_kill = 'U'-'@';
101 }
102 ourdisplay = XOpenDisplay(NULL);
103 if (ourdisplay == NULL) {
104 stderr_v("cannot open X-windows; DISPLAY variable set?\n");
105 return(NULL);
106 }
107 if (DisplayPlanes() < 4) {
108 stderr_v("not enough colors\n");
109 return(NULL);
110 }
111 if (getmap() < 0) /* not fatal */
112 stderr_v("cannot allocate colors\n");
113
114 pickcursor = XCreateCursor(bcross_width, bcross_height,
115 bcross_bits, bcross_mask_bits,
116 bcross_x_hot, bcross_y_hot,
117 BlackPixel, WhitePixel, GXcopy);
118 clientname = name;
119 x_driver.inpready = 0;
120 cmdvec = x_comout; /* set error vectors */
121 if (wrnvec != NULL)
122 wrnvec = x_errout;
123 return(&x_driver);
124 }
125
126
127 static
128 x_close() /* close our display */
129 {
130 cmdvec = NULL; /* reset error vectors */
131 if (wrnvec != NULL)
132 wrnvec = stderr_v;
133 if (ourdisplay == NULL)
134 return;
135 if (comline != NULL) {
136 xt_close(comline);
137 comline = NULL;
138 }
139 if (gwind != 0) {
140 XDestroyWindow(gwind);
141 gwind = 0;
142 gwidth = gheight = 0;
143 }
144 XFreeCursor(pickcursor);
145 freemap();
146 XCloseDisplay(ourdisplay);
147 ourdisplay = NULL;
148 }
149
150
151 static
152 x_clear(xres, yres) /* clear our display */
153 int xres, yres;
154 {
155 if (xres != gwidth || yres != gheight) { /* new window */
156 if (comline != NULL)
157 xt_close(comline);
158 if (gwind != 0)
159 XDestroyWindow(gwind);
160 gwind = XCreateWindow(RootWindow, 0, BARHEIGHT,
161 xres, yres+COMHEIGHT, BORWIDTH,
162 BlackPixmap, BlackPixmap);
163 if (gwind == 0)
164 goto fail;
165 comline = xt_open(gwind, 0, yres, xres, COMHEIGHT, 0, COMFN);
166 if (comline == NULL)
167 goto fail;
168 XMapWindow(gwind);
169 XSelectInput(gwind,
170 KeyPressed|ButtonPressed|ExposeWindow|ExposeRegion|UnmapWindow);
171 XStoreName(gwind, clientname);
172 gwidth = xres;
173 gheight = yres;
174 } else /* just clear */
175 XClear(gwind);
176 newmap();
177 checkinp();
178 return;
179 fail:
180 stderr_v("Failure opening window in x_clear\n");
181 quit(1);
182 }
183
184
185 static
186 x_paintr(col, xmin, ymin, xmax, ymax) /* fill a rectangle */
187 COLOR col;
188 int xmin, ymin, xmax, ymax;
189 {
190 extern long nrays; /* global ray count */
191 static long lastflush = 0; /* ray count at last flush */
192 int ndx;
193
194 if (ncolors > 0) {
195 if ((ndx = colindex(col)) < 0) {
196 colres >>= 1;
197 redraw();
198 return;
199 }
200 XPixSet(gwind, xmin, gheight-ymax, xmax-xmin, ymax-ymin,
201 pixval[ndx]);
202 }
203 if (nrays - lastflush >= WFLUSH) {
204 if (ncolors <= 0) /* output necessary for death */
205 XPixSet(gwind,0,0,1,1,BlackPixel);
206 checkinp();
207 lastflush = nrays;
208 }
209 }
210
211
212 static
213 x_comin(inp) /* read in a command line */
214 char *inp;
215 {
216 int x_getc(), x_comout();
217
218 xt_cursor(comline, TBLKCURS);
219 editline(inp, x_getc, x_comout, c_erase, c_kill);
220 xt_cursor(comline, TNOCURS);
221 }
222
223
224 static
225 x_comout(out) /* output a string to command line */
226 char *out;
227 {
228 if (comline != NULL)
229 xt_puts(out, comline);
230 XFlush();
231 }
232
233
234 static
235 x_errout(msg) /* output an error message */
236 char *msg;
237 {
238 x_comout(msg);
239 stderr_v(msg); /* send to stderr also! */
240 }
241
242
243 static int
244 x_getcur(xp, yp) /* get cursor position */
245 int *xp, *yp;
246 {
247 while (XGrabMouse(gwind, pickcursor, ButtonPressed) == 0)
248 sleep(1);
249 XFocusKeyboard(gwind);
250 do
251 getevent();
252 while (c_last <= c_first && levptr(XEvent)->type != ButtonPressed);
253 *xp = levptr(XKeyOrButtonEvent)->x;
254 *yp = gheight-1 - levptr(XKeyOrButtonEvent)->y;
255 XFocusKeyboard(RootWindow);
256 XUngrabMouse();
257 XFlush(); /* insure release */
258 if (c_last > c_first) /* key pressed */
259 return(x_getc());
260 /* button pressed */
261 switch (levptr(XKeyOrButtonEvent)->detail & 0377) {
262 case LeftButton:
263 return(MB1);
264 case MiddleButton:
265 return(MB2);
266 case RightButton:
267 return(MB3);
268 }
269 return(ABORT);
270 }
271
272
273 static int
274 colindex(col) /* return index for color */
275 COLOR col;
276 {
277 static COLR clr;
278 int hval;
279 register int ndx, i;
280
281 mapcolor(clr, col);
282
283 hval = ndx = hashcolr(clr);
284
285 for (i = 1; i < ncolors; i++) {
286 if (colrtbl[ndx][EXP] == 0) {
287 colrtbl[ndx][RED] = clr[RED];
288 colrtbl[ndx][GRN] = clr[GRN];
289 colrtbl[ndx][BLU] = clr[BLU];
290 colrtbl[ndx][EXP] = COLXS;
291 newcolr(ndx, clr);
292 return(ndx);
293 }
294 if ( colrtbl[ndx][RED] == clr[RED] &&
295 colrtbl[ndx][GRN] == clr[GRN] &&
296 colrtbl[ndx][BLU] == clr[BLU] )
297 return(ndx);
298 ndx = (hval + i*i) % ncolors;
299 }
300 return(-1);
301 }
302
303
304 static
305 newcolr(ndx, clr) /* enter a color into hardware table */
306 int ndx;
307 COLR clr;
308 {
309 Color xcolor;
310
311 xcolor.pixel = pixval[ndx];
312 xcolor.red = clr[RED] << 8;
313 xcolor.green = clr[GRN] << 8;
314 xcolor.blue = clr[BLU] << 8;
315
316 XStoreColor(&xcolor);
317 }
318
319
320 static
321 mapcolor(clr, col) /* map to our color space */
322 COLR clr;
323 COLOR col;
324 {
325 register int i, p;
326 /* compute color table value */
327 for (i = 0; i < 3; i++) {
328 p = colval(col,i) * 255.0 + 0.5;
329 if (p < 0) p = 0;
330 else if (p > 255) p = 255;
331 clr[i] = colrmap[p][i];
332 }
333 clr[EXP] = COLXS;
334 }
335
336
337 static
338 getmap() /* get the color map */
339 {
340 int planes;
341
342 for (ncolors=(1<<DisplayPlanes())-3; ncolors>12; ncolors=ncolors*.937){
343 colrtbl = (COLR *)malloc(ncolors*sizeof(COLR));
344 pixval = (int *)malloc(ncolors*sizeof(int));
345 if (colrtbl == NULL || pixval == NULL)
346 return(-1);
347 if (XGetColorCells(0,ncolors,0,&planes,pixval) != 0)
348 return(0);
349 free((char *)colrtbl);
350 free((char *)pixval);
351 }
352 ncolors = 0;
353 return(-1);
354 }
355
356
357 static
358 freemap() /* free our color map */
359 {
360 if (ncolors == 0)
361 return;
362 XFreeColors(pixval, ncolors, 0);
363 free((char *)colrtbl);
364 free((char *)pixval);
365 ncolors = 0;
366 }
367
368
369 static
370 newmap() /* initialize the color map */
371 {
372 double pow();
373 int val;
374 register int i;
375
376 for (i = 0; i < 256; i++) {
377 val = pow(i/256.0, 1.0/GAMMA) * colres;
378 val = (val*256 + 128) / colres;
379 colrmap[i][RED] = colrmap[i][GRN] = colrmap[i][BLU] = val;
380 colrmap[i][EXP] = COLXS;
381 }
382 for (i = 0; i < ncolors; i++)
383 colrtbl[i][EXP] = 0;
384 }
385
386
387 static int
388 x_getc() /* get a command character */
389 {
390 while (c_last <= c_first) {
391 c_first = c_last = 0; /* reset */
392 getevent(); /* wait for key */
393 }
394 x_driver.inpready--;
395 return(c_queue[c_first++]);
396 }
397
398
399 static
400 getevent() /* get next event */
401 {
402 XNextEvent(levptr(XEvent));
403 switch (levptr(XEvent)->type) {
404 case KeyPressed:
405 getkey(levptr(XKeyPressedEvent));
406 break;
407 case ExposeWindow:
408 if (ncolors == 0 && levptr(XExposeEvent)->subwindow == 0)
409 if (getmap() < 0)
410 stderr_v("cannot grab colors\n");
411 else
412 newmap();
413 /* fall through */
414 case ExposeRegion:
415 fixwindow(levptr(XExposeEvent));
416 break;
417 case UnmapWindow:
418 if (levptr(XUnmapEvent)->subwindow == 0)
419 freemap();
420 break;
421 case ButtonPressed: /* handled in x_getcur() */
422 break;
423 }
424 }
425
426
427 static
428 getkey(ekey) /* get input key */
429 register XKeyPressedEvent *ekey;
430 {
431 int n;
432 register char *str;
433
434 str = XLookupMapping(ekey, &n);
435 while (n-- > 0 && c_last < sizeof(c_queue))
436 c_queue[c_last++] = *str++;
437 x_driver.inpready = c_last - c_first;
438 }
439
440
441 static
442 fixwindow(eexp) /* repair damage to window */
443 register XExposeEvent *eexp;
444 {
445 if (eexp->subwindow == 0)
446 repaint(eexp->x, gheight - eexp->y - eexp->height,
447 eexp->x + eexp->width, gheight - eexp->y);
448 else if (eexp->subwindow == comline->w)
449 xt_redraw(comline);
450 }