ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x10.c
Revision: 1.7
Committed: Sat May 27 09:18:45 1989 UTC (35 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.6: +5 -2 lines
Log Message:
Changed input checking procedure

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