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

# User Rev Content
1 greg 1.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 greg 1.9 #define WFLUSH 50 /* flush after this many rays */
40 greg 1.1 #endif
41    
42     #define hashcolr(c) ((67*(c)[RED]+59*(c)[GRN]+71*(c)[BLU])%ncolors)
43    
44 greg 1.8 #define checkinp() while (XPending() > 0) getevent()
45 greg 1.1
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 greg 1.2 stderr_v("cannot open X-windows; DISPLAY variable set?\n");
105 greg 1.1 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 greg 1.5 cmdvec = x_comout; /* set error vectors */
121 greg 1.1 if (wrnvec != NULL)
122     wrnvec = x_errout;
123     return(&x_driver);
124     }
125    
126    
127     static
128     x_close() /* close our display */
129     {
130 greg 1.5 cmdvec = NULL; /* reset error vectors */
131 greg 1.1 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 greg 1.8 checkinp();
178 greg 1.1 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 greg 1.9 if (ncolors <= 0) /* output necessary for death */
205     XPixSet(gwind,0,0,1,1,BlackPixel);
206 greg 1.8 checkinp();
207 greg 1.1 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 greg 1.8 XFlush();
231 greg 1.1 }
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 greg 1.8 XFlush(); /* insure release */
258 greg 1.1 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     }