ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x10.c
Revision: 1.11
Committed: Fri Sep 29 13:23:59 1989 UTC (35 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.10: +1 -13 lines
Log Message:
Added word erase and allowed ^H or ^?, ^U or ^X in editline.

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