ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x10.c
Revision: 2.3
Committed: Fri Jun 4 14:48:35 1993 UTC (31 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +1 -1 lines
Log Message:
added math.h for atof() usage

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 greg 2.3 #include <math.h>
15 greg 1.1 #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 greg 1.12 #define GAMMA 2.2 /* exponent for color correction */
28 greg 1.1
29     #define BORWIDTH 5 /* border width */
30     #define COMHEIGHT (COMLH*COMCH) /* command line height (pixels) */
31 greg 1.18 #define MINWIDTH (32*COMCW) /* minimum graphics window width */
32 greg 1.26 #define MINHEIGHT MINWIDTH /* minimum graphics window height */
33 greg 1.1
34     #define COMFN "8x13" /* command line font name */
35     #define COMLH 3 /* number of command lines */
36     #define COMCW 8 /* approx. character width (pixels) */
37     #define COMCH 13 /* approx. character height (pixels) */
38    
39     #define levptr(etype) ((etype *)&thisevent)
40    
41     static XEvent thisevent; /* current event */
42    
43     static int ncolors = 0; /* color table size */
44 greg 1.12 static int *pixval; /* allocated pixel values */
45 greg 1.1
46     static Display *ourdisplay = NULL; /* our display */
47    
48     static Window gwind = 0; /* our graphics window */
49    
50     static Cursor pickcursor = 0; /* cursor used for picking */
51    
52 greg 1.24 static int gwidth, gheight; /* graphics window size */
53 greg 1.1
54     static TEXTWIND *comline = NULL; /* our command line */
55    
56     static char c_queue[64]; /* input queue */
57     static int c_first = 0; /* first character in queue */
58     static int c_last = 0; /* last character in queue */
59    
60 greg 1.18 extern char *malloc(), *getcombuf();
61 greg 1.1
62 greg 1.21 extern char *progname;
63    
64 greg 1.28 static int x_close(), x_clear(), x_paintr(), x_errout(),
65 greg 1.25 x_getcur(), x_comout(), x_comin(), x_flush();
66 greg 1.1
67     static struct driver x_driver = {
68     x_close, x_clear, x_paintr, x_getcur,
69 greg 1.25 x_comout, x_comin, x_flush, 1.0
70 greg 1.1 };
71    
72    
73     struct driver *
74 greg 1.16 x_init(name, id) /* initialize driver */
75     char *name, *id;
76 greg 1.1 {
77 greg 2.2 extern char *getenv();
78     char *gv;
79 greg 1.19 char defgeom[32];
80     OpaqueFrame mainframe;
81    
82 greg 1.1 ourdisplay = XOpenDisplay(NULL);
83     if (ourdisplay == NULL) {
84 greg 1.2 stderr_v("cannot open X-windows; DISPLAY variable set?\n");
85 greg 1.1 return(NULL);
86     }
87     if (DisplayPlanes() < 4) {
88     stderr_v("not enough colors\n");
89     return(NULL);
90     }
91 greg 2.2 /* make color map */
92     if ((gv = getenv("GAMMA")) != NULL)
93     make_gmap(atof(gv));
94     else
95     make_gmap(GAMMA);
96 greg 1.1
97     pickcursor = XCreateCursor(bcross_width, bcross_height,
98     bcross_bits, bcross_mask_bits,
99     bcross_x_hot, bcross_y_hot,
100     BlackPixel, WhitePixel, GXcopy);
101 greg 1.19 mainframe.bdrwidth = BORWIDTH;
102     mainframe.border = BlackPixmap;
103     mainframe.background = BlackPixmap;
104     sprintf(defgeom, "=%dx%d+0+22", DisplayWidth()-(2*BORWIDTH),
105     DisplayHeight()-(2*BORWIDTH+22));
106 greg 1.21 gwind = XCreate("X10 display driver", progname, NULL, defgeom,
107 greg 1.19 &mainframe, MINWIDTH, MINHEIGHT+COMHEIGHT);
108     if (gwind == 0) {
109     stderr_v("can't create window\n");
110     return(NULL);
111     }
112     XStoreName(gwind, id);
113     XSelectInput(gwind, KeyPressed|ButtonPressed|
114     ExposeWindow|ExposeRegion|UnmapWindow);
115 greg 1.24 gwidth = mainframe.width;
116     gheight = mainframe.height-COMHEIGHT;
117     x_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth;
118     x_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight;
119 greg 1.1 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     }
143     XFreeCursor(pickcursor);
144 greg 1.12 freepixels();
145 greg 1.1 XCloseDisplay(ourdisplay);
146     ourdisplay = NULL;
147     }
148    
149    
150     static
151     x_clear(xres, yres) /* clear our display */
152     int xres, yres;
153     {
154     if (xres != gwidth || yres != gheight) { /* new window */
155 greg 1.19 XChangeWindow(gwind, xres, yres+COMHEIGHT);
156 greg 1.1 gwidth = xres;
157     gheight = yres;
158     } else /* just clear */
159     XClear(gwind);
160 greg 1.17 /* reinitialize color table */
161 greg 1.22 if (getpixels() == 0)
162 greg 1.17 stderr_v("cannot allocate colors\n");
163     else
164     new_ctab(ncolors);
165 greg 1.29 /* open new command line */
166     if (comline != NULL)
167     xt_close(comline);
168     comline = xt_open(gwind, 0, yres, xres, COMHEIGHT, 0, COMFN);
169     if (comline == NULL) {
170     stderr_v("Cannot open command line window\n");
171     quit(1);
172     }
173 greg 1.24 XMapWindow(gwind); /* make sure it's mapped */
174 greg 1.17 XSync(1); /* discard input */
175 greg 1.1 return;
176     }
177    
178    
179     static
180     x_paintr(col, xmin, ymin, xmax, ymax) /* fill a rectangle */
181     COLOR col;
182     int xmin, ymin, xmax, ymax;
183     {
184 greg 1.14 extern int xnewcolr(); /* pixel assignment routine */
185 greg 1.1
186     if (ncolors > 0) {
187     XPixSet(gwind, xmin, gheight-ymax, xmax-xmin, ymax-ymin,
188 greg 1.14 pixval[get_pixel(col, xnewcolr)]);
189 greg 1.1 }
190 greg 1.25 }
191    
192    
193     static
194     x_flush() /* flush output */
195     {
196     if (ncolors <= 0) /* output necessary for death */
197     XPixSet(gwind,0,0,1,1,BlackPixel);
198     while (XPending() > 0)
199     getevent();
200    
201 greg 1.1 }
202    
203    
204     static
205 greg 1.23 x_comin(inp, prompt) /* read in a command line */
206     char *inp, *prompt;
207 greg 1.1 {
208 greg 1.28 extern int x_getc();
209 greg 1.1
210 greg 1.23 if (prompt != NULL)
211     if (fromcombuf(inp, &x_driver))
212     return;
213     else
214     xt_puts(prompt, comline);
215 greg 1.1 xt_cursor(comline, TBLKCURS);
216 greg 1.11 editline(inp, x_getc, x_comout);
217 greg 1.1 xt_cursor(comline, TNOCURS);
218     }
219    
220    
221     static
222     x_comout(out) /* output a string to command line */
223     char *out;
224     {
225 greg 1.27 if (comline == NULL)
226     return;
227     xt_puts(out, comline);
228     if (out[strlen(out)-1] == '\n')
229     XFlush();
230 greg 1.1 }
231    
232    
233     static
234     x_errout(msg) /* output an error message */
235     char *msg;
236     {
237 greg 1.27 stderr_v(msg); /* send to stderr also! */
238 greg 1.1 x_comout(msg);
239     }
240    
241    
242     static int
243     x_getcur(xp, yp) /* get cursor position */
244     int *xp, *yp;
245     {
246     while (XGrabMouse(gwind, pickcursor, ButtonPressed) == 0)
247     sleep(1);
248     XFocusKeyboard(gwind);
249     do
250     getevent();
251     while (c_last <= c_first && levptr(XEvent)->type != ButtonPressed);
252     *xp = levptr(XKeyOrButtonEvent)->x;
253     *yp = gheight-1 - levptr(XKeyOrButtonEvent)->y;
254     XFocusKeyboard(RootWindow);
255     XUngrabMouse();
256 greg 1.8 XFlush(); /* insure release */
257 greg 1.1 if (c_last > c_first) /* key pressed */
258     return(x_getc());
259     /* button pressed */
260     switch (levptr(XKeyOrButtonEvent)->detail & 0377) {
261     case LeftButton:
262     return(MB1);
263     case MiddleButton:
264     return(MB2);
265     case RightButton:
266     return(MB3);
267     }
268     return(ABORT);
269     }
270    
271    
272     static
273 greg 1.13 xnewcolr(ndx, r, g, b) /* enter a color into hardware table */
274 greg 1.1 int ndx;
275 greg 1.13 int r, g, b;
276 greg 1.1 {
277     Color xcolor;
278    
279     xcolor.pixel = pixval[ndx];
280 greg 1.13 xcolor.red = r << 8;
281     xcolor.green = g << 8;
282     xcolor.blue = b << 8;
283 greg 1.1
284     XStoreColor(&xcolor);
285     }
286    
287    
288 greg 1.17 static int
289 greg 1.12 getpixels() /* get the color map */
290 greg 1.1 {
291     int planes;
292    
293 greg 1.22 if (ncolors > 0)
294     return(ncolors);
295 greg 1.1 for (ncolors=(1<<DisplayPlanes())-3; ncolors>12; ncolors=ncolors*.937){
296     pixval = (int *)malloc(ncolors*sizeof(int));
297 greg 1.12 if (pixval == NULL)
298     break;
299 greg 1.1 if (XGetColorCells(0,ncolors,0,&planes,pixval) != 0)
300 greg 1.17 return(ncolors);
301 greg 1.1 free((char *)pixval);
302     }
303 greg 1.17 return(ncolors = 0);
304 greg 1.1 }
305    
306    
307     static
308 greg 1.12 freepixels() /* free our pixels */
309 greg 1.1 {
310     if (ncolors == 0)
311     return;
312     XFreeColors(pixval, ncolors, 0);
313     free((char *)pixval);
314     ncolors = 0;
315     }
316    
317    
318     static int
319     x_getc() /* get a command character */
320     {
321     while (c_last <= c_first) {
322     c_first = c_last = 0; /* reset */
323     getevent(); /* wait for key */
324     }
325     x_driver.inpready--;
326     return(c_queue[c_first++]);
327     }
328    
329    
330     static
331     getevent() /* get next event */
332     {
333     XNextEvent(levptr(XEvent));
334     switch (levptr(XEvent)->type) {
335     case KeyPressed:
336     getkey(levptr(XKeyPressedEvent));
337     break;
338     case ExposeWindow:
339 greg 1.18 windowchange(levptr(XExposeEvent));
340     break;
341 greg 1.1 case ExposeRegion:
342     fixwindow(levptr(XExposeEvent));
343     break;
344     case UnmapWindow:
345     if (levptr(XUnmapEvent)->subwindow == 0)
346 greg 1.12 freepixels();
347 greg 1.1 break;
348     case ButtonPressed: /* handled in x_getcur() */
349     break;
350     }
351     }
352    
353    
354     static
355 greg 1.18 windowchange(eexp) /* process window change event */
356     register XExposeEvent *eexp;
357     {
358     if (eexp->subwindow != 0) {
359     fixwindow(eexp);
360     return;
361     }
362     /* check for change in size */
363 greg 1.19 if (eexp->width != gwidth || eexp->height-COMHEIGHT != gheight) {
364 greg 1.24 gwidth = eexp->width;
365     gheight = eexp->height-COMHEIGHT;
366     x_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth;
367     x_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight;
368 greg 1.18 strcpy(getcombuf(&x_driver), "new\n");
369     return;
370     }
371     /* remap colors */
372 greg 1.22 if (getpixels() == 0) {
373 greg 1.18 stderr_v("cannot allocate colors\n");
374     return;
375     }
376     new_ctab(ncolors);
377     /* redraw */
378     fixwindow(eexp);
379     }
380    
381    
382     static
383 greg 1.1 getkey(ekey) /* get input key */
384     register XKeyPressedEvent *ekey;
385     {
386     int n;
387     register char *str;
388    
389     str = XLookupMapping(ekey, &n);
390 greg 1.20 while (n-- > 0 && c_last < sizeof(c_queue)) {
391 greg 1.1 c_queue[c_last++] = *str++;
392 greg 1.20 x_driver.inpready++;
393     }
394 greg 1.1 }
395    
396    
397     static
398     fixwindow(eexp) /* repair damage to window */
399     register XExposeEvent *eexp;
400     {
401     if (eexp->subwindow == 0)
402 greg 1.18 sprintf(getcombuf(&x_driver), "repaint %d %d %d %d\n",
403     eexp->x, gheight - eexp->y - eexp->height,
404 greg 1.1 eexp->x + eexp->width, gheight - eexp->y);
405     else if (eexp->subwindow == comline->w)
406     xt_redraw(comline);
407     }