ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x11.c
Revision: 2.6
Committed: Wed Jun 24 09:12:50 1992 UTC (31 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +9 -3 lines
Log Message:
added code to get GAMMA from environment

File Contents

# Content
1 /* Copyright (c) 1992 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * x11.c - driver for X-windows version 11
9 *
10 * Jan 1990
11 */
12
13 #include <stdio.h>
14
15 #include <sys/ioctl.h>
16
17 #include <X11/Xlib.h>
18 #include <X11/cursorfont.h>
19 #include <X11/Xutil.h>
20
21 #include "color.h"
22 #include "driver.h"
23 #include "x11twind.h"
24 #include "x11icon.h"
25
26 #define GAMMA 2.2 /* default exponent correction */
27
28 #define MINWIDTH (32*COMCW) /* minimum graphics window width */
29 #define MINHEIGHT MINWIDTH /* minimum graphics window height */
30
31 #define BORWIDTH 5 /* border width */
32 #define COMHEIGHT (COMLH*COMCH) /* command line height (pixels) */
33
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 14 /* approx. character height (pixels) */
38
39 #define ourscreen DefaultScreen(ourdisplay)
40 #define ourroot RootWindow(ourdisplay,ourscreen)
41
42 #define levptr(etype) ((etype *)&currentevent)
43
44 static XEvent currentevent; /* current event */
45
46 static int ncolors = 0; /* color table size */
47 static unsigned long *pixval = NULL; /* allocated pixels */
48 static unsigned long ourblack=0, ourwhite=1;
49
50 static Display *ourdisplay = NULL; /* our display */
51
52 static XVisualInfo ourvinfo; /* our visual information */
53
54 static Window gwind = 0; /* our graphics window */
55
56 static Cursor pickcursor = 0; /* cursor used for picking */
57
58 static int gwidth, gheight; /* graphics window size */
59
60 static TEXTWIND *comline = NULL; /* our command line */
61
62 static char c_queue[64]; /* input queue */
63 static int c_first = 0; /* first character in queue */
64 static int c_last = 0; /* last character in queue */
65
66 static GC ourgc = 0; /* our graphics context for drawing */
67
68 static Colormap ourmap = 0; /* our color map */
69
70 extern char *malloc(), *getcombuf();
71
72 static int x11_close(), x11_clear(), x11_paintr(), x11_errout(),
73 x11_getcur(), x11_comout(), x11_comin(), x11_flush();
74
75 static struct driver x11_driver = {
76 x11_close, x11_clear, x11_paintr, x11_getcur,
77 x11_comout, x11_comin, x11_flush, 1.0
78 };
79
80
81 struct driver *
82 x11_init(name, id) /* initialize driver */
83 char *name, *id;
84 {
85 extern char *getenv();
86 char *gv;
87 int nplanes;
88 XSetWindowAttributes ourwinattr;
89 XWMHints ourxwmhints;
90 XSizeHints oursizhints;
91
92 ourdisplay = XOpenDisplay(NULL);
93 if (ourdisplay == NULL) {
94 stderr_v("cannot open X-windows; DISPLAY variable set?\n");
95 return(NULL);
96 }
97 /* find a usable visual */
98 nplanes = DisplayPlanes(ourdisplay, ourscreen);
99 if (XMatchVisualInfo(ourdisplay,ourscreen,
100 24,TrueColor,&ourvinfo) ||
101 XMatchVisualInfo(ourdisplay,ourscreen,
102 24,DirectColor,&ourvinfo)) {
103 ourblack = 0;
104 ourwhite = ourvinfo.red_mask |
105 ourvinfo.green_mask |
106 ourvinfo.blue_mask ;
107 } else {
108 if (nplanes < 4) {
109 stderr_v("not enough colors\n");
110 return(NULL);
111 }
112 if (!XMatchVisualInfo(ourdisplay,ourscreen,
113 nplanes,PseudoColor,&ourvinfo) &&
114 !XMatchVisualInfo(ourdisplay,ourscreen,
115 nplanes,GrayScale,&ourvinfo)) {
116 stderr_v("unsupported visual type\n");
117 return(NULL);
118 }
119 ourblack = BlackPixel(ourdisplay,ourscreen);
120 ourwhite = WhitePixel(ourdisplay,ourscreen);
121 }
122 /* set gamma */
123 if ((gv = getenv("GAMMA")) != NULL)
124 make_gmap(atof(gv));
125 else
126 make_gmap(GAMMA);
127 /* open window */
128 ourwinattr.background_pixel = ourblack;
129 ourwinattr.border_pixel = ourblack;
130 /* this is stupid */
131 ourwinattr.colormap = XCreateColormap(ourdisplay, ourroot,
132 ourvinfo.visual, AllocNone);
133 gwind = XCreateWindow(ourdisplay, ourroot, 0, 0,
134 DisplayWidth(ourdisplay,ourscreen)-2*BORWIDTH,
135 DisplayHeight(ourdisplay,ourscreen)-2*BORWIDTH,
136 BORWIDTH, ourvinfo.depth, InputOutput, ourvinfo.visual,
137 CWBackPixel|CWBorderPixel|CWColormap, &ourwinattr);
138 if (gwind == 0) {
139 stderr_v("cannot create window\n");
140 return(NULL);
141 }
142 XStoreName(ourdisplay, gwind, id);
143 /* create a cursor */
144 pickcursor = XCreateFontCursor(ourdisplay, XC_diamond_cross);
145 ourgc = XCreateGC(ourdisplay, gwind, 0, NULL);
146 ourxwmhints.flags = InputHint|IconPixmapHint;
147 ourxwmhints.input = True;
148 ourxwmhints.icon_pixmap = XCreateBitmapFromData(ourdisplay,
149 gwind, x11icon_bits, x11icon_width, x11icon_height);
150 XSetWMHints(ourdisplay, gwind, &ourxwmhints);
151 oursizhints.min_width = MINWIDTH;
152 oursizhints.min_height = MINHEIGHT+COMHEIGHT;
153 oursizhints.flags = PMinSize;
154 XSetNormalHints(ourdisplay, gwind, &oursizhints);
155 XSelectInput(ourdisplay, gwind, ExposureMask);
156 XMapWindow(ourdisplay, gwind);
157 XWindowEvent(ourdisplay, gwind, ExposureMask, levptr(XEvent));
158 gwidth = levptr(XExposeEvent)->width;
159 gheight = levptr(XExposeEvent)->height - COMHEIGHT;
160 x11_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth;
161 x11_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight;
162 x11_driver.inpready = 0;
163 cmdvec = x11_comout; /* set error vectors */
164 if (wrnvec != NULL)
165 wrnvec = x11_errout;
166 return(&x11_driver);
167 }
168
169
170 static
171 x11_close() /* close our display */
172 {
173 cmdvec = NULL; /* reset error vectors */
174 if (wrnvec != NULL)
175 wrnvec = stderr_v;
176 if (ourdisplay == NULL)
177 return;
178 if (comline != NULL) {
179 xt_close(comline);
180 comline = NULL;
181 }
182 freepixels();
183 XFreeGC(ourdisplay, ourgc);
184 XDestroyWindow(ourdisplay, gwind);
185 gwind = 0;
186 ourgc = 0;
187 XFreeCursor(ourdisplay, pickcursor);
188 XCloseDisplay(ourdisplay);
189 ourdisplay = NULL;
190 }
191
192
193 static
194 x11_clear(xres, yres) /* clear our display */
195 int xres, yres;
196 {
197 /* check limits */
198 if (xres < MINWIDTH)
199 xres = MINWIDTH;
200 if (yres < MINHEIGHT)
201 yres = MINHEIGHT;
202 /* resize window */
203 if (xres != gwidth || yres != gheight) {
204 XSelectInput(ourdisplay, gwind, 0);
205 XResizeWindow(ourdisplay, gwind, xres, yres+COMHEIGHT);
206 gwidth = xres;
207 gheight = yres;
208 XFlush(ourdisplay);
209 sleep(2); /* wait for window manager */
210 XSync(ourdisplay, 1); /* discard input */
211 }
212 XClearWindow(ourdisplay, gwind);
213 /* reinitialize color table */
214 if (ourvinfo.class == PseudoColor || ourvinfo.class == GrayScale)
215 if (getpixels() == 0)
216 stderr_v("cannot allocate colors\n");
217 else
218 new_ctab(ncolors);
219 /* get new command line */
220 if (comline != NULL)
221 xt_close(comline);
222 comline = xt_open(ourdisplay, gwind, 0, gheight,
223 gwidth, COMHEIGHT, 0, ourblack, ourwhite, COMFN);
224 if (comline == NULL) {
225 stderr_v("Cannot open command line window\n");
226 quit(1);
227 }
228 XSelectInput(ourdisplay, comline->w, ExposureMask);
229 /* remove earmuffs */
230 XSelectInput(ourdisplay, gwind,
231 StructureNotifyMask|ExposureMask|KeyPressMask|ButtonPressMask);
232 }
233
234
235 static
236 x11_paintr(col, xmin, ymin, xmax, ymax) /* fill a rectangle */
237 COLOR col;
238 int xmin, ymin, xmax, ymax;
239 {
240 extern int xnewcolr(); /* pixel assignment routine */
241 extern unsigned long true_pixel();
242 unsigned long pixel;
243
244 if (ncolors > 0)
245 pixel = pixval[get_pixel(col, xnewcolr)];
246 else if (ourvinfo.class == TrueColor || ourvinfo.class == DirectColor)
247 pixel = true_pixel(col);
248 else
249 return;
250 XSetForeground(ourdisplay, ourgc, pixel);
251 XFillRectangle(ourdisplay, gwind,
252 ourgc, xmin, gheight-ymax, xmax-xmin, ymax-ymin);
253 }
254
255
256 static
257 x11_flush() /* flush output */
258 {
259 XNoOp(ourdisplay);
260 while (XPending(ourdisplay) > 0)
261 getevent();
262 }
263
264
265 static
266 x11_comin(inp, prompt) /* read in a command line */
267 char *inp, *prompt;
268 {
269 extern int x11_getc();
270
271 if (prompt != NULL)
272 if (fromcombuf(inp, &x11_driver))
273 return;
274 else
275 xt_puts(prompt, comline);
276 xt_cursor(comline, TBLKCURS);
277 editline(inp, x11_getc, x11_comout);
278 xt_cursor(comline, TNOCURS);
279 }
280
281
282 static
283 x11_comout(out) /* output a string to command line */
284 char *out;
285 {
286 if (comline == NULL)
287 return;
288 xt_puts(out, comline);
289 if (out[strlen(out)-1] == '\n')
290 XFlush(ourdisplay);
291 }
292
293
294 static
295 x11_errout(msg) /* output an error message */
296 char *msg;
297 {
298 stderr_v(msg); /* send to stderr also! */
299 x11_comout(msg);
300 }
301
302
303 static int
304 x11_getcur(xp, yp) /* get cursor position */
305 int *xp, *yp;
306 {
307 while (XGrabPointer(ourdisplay, gwind, True, ButtonPressMask,
308 GrabModeAsync, GrabModeAsync, None, pickcursor,
309 CurrentTime) != GrabSuccess)
310 sleep(2);
311
312 do
313 getevent();
314 while (c_last <= c_first && levptr(XEvent)->type != ButtonPress);
315 *xp = levptr(XButtonPressedEvent)->x;
316 *yp = gheight-1 - levptr(XButtonPressedEvent)->y;
317 XUngrabPointer(ourdisplay, CurrentTime);
318 XFlush(ourdisplay); /* insure release */
319 if (c_last > c_first) /* key pressed */
320 return(x11_getc());
321 /* button pressed */
322 if (levptr(XButtonPressedEvent)->button & Button1)
323 return(MB1);
324 if (levptr(XButtonPressedEvent)->button & Button2)
325 return(MB2);
326 if (levptr(XButtonPressedEvent)->button & Button3)
327 return(MB3);
328 if (levptr(XButtonPressedEvent)->button & (Button4|Button5))
329 return(MB1);
330 return(ABORT);
331 }
332
333
334 static
335 xnewcolr(ndx, r, g, b) /* enter a color into hardware table */
336 int ndx;
337 int r, g, b;
338 {
339 XColor xcolor;
340
341 xcolor.pixel = pixval[ndx];
342 xcolor.red = r << 8;
343 xcolor.green = g << 8;
344 xcolor.blue = b << 8;
345 xcolor.flags = DoRed|DoGreen|DoBlue;
346
347 XStoreColor(ourdisplay, ourmap, &xcolor);
348 }
349
350
351 static int
352 getpixels() /* get the color map */
353 {
354 XColor thiscolor;
355 register int i, j;
356
357 if (ncolors > 0)
358 return(ncolors);
359 if (ourvinfo.visual == DefaultVisual(ourdisplay,ourscreen)) {
360 ourmap = DefaultColormap(ourdisplay,ourscreen);
361 goto loop;
362 }
363 newmap:
364 ourmap = XCreateColormap(ourdisplay,gwind,ourvinfo.visual,AllocNone);
365 loop:
366 for (ncolors = ourvinfo.colormap_size;
367 ncolors > ourvinfo.colormap_size/3;
368 ncolors = ncolors*.937) {
369 pixval = (unsigned long *)malloc(ncolors*sizeof(unsigned long));
370 if (pixval == NULL)
371 return(ncolors = 0);
372 if (XAllocColorCells(ourdisplay,ourmap,0,NULL,0,
373 pixval,ncolors) != 0)
374 break;
375 free((char *)pixval);
376 pixval = NULL;
377 }
378 if (pixval == NULL) {
379 if (ourmap == DefaultColormap(ourdisplay,ourscreen))
380 goto newmap; /* try it with our map */
381 else
382 return(ncolors = 0); /* failed */
383 }
384 if (ourmap != DefaultColormap(ourdisplay,ourscreen))
385 for (i = 0; i < ncolors; i++) { /* reset black and white */
386 if (pixval[i] != ourblack && pixval[i] != ourwhite)
387 continue;
388 thiscolor.pixel = pixval[i];
389 thiscolor.flags = DoRed|DoGreen|DoBlue;
390 XQueryColor(ourdisplay,
391 DefaultColormap(ourdisplay,ourscreen),
392 &thiscolor);
393 XStoreColor(ourdisplay, ourmap, &thiscolor);
394 for (j = i; j+1 < ncolors; j++)
395 pixval[j] = pixval[j+1];
396 ncolors--;
397 i--;
398 }
399 XSetWindowColormap(ourdisplay, gwind, ourmap);
400 return(ncolors);
401 }
402
403
404 static
405 freepixels() /* free our pixels */
406 {
407 if (ncolors == 0)
408 return;
409 XFreeColors(ourdisplay,ourmap,pixval,ncolors,0L);
410 ncolors = 0;
411 if (ourmap != DefaultColormap(ourdisplay,ourscreen))
412 XFreeColormap(ourdisplay, ourmap);
413 ourmap = 0;
414 }
415
416
417 static unsigned long
418 true_pixel(col) /* return true pixel value for color */
419 COLOR col;
420 {
421 unsigned long rval;
422 BYTE rgb[3];
423
424 map_color(rgb, col);
425 rval = ourvinfo.red_mask*rgb[RED]/255 & ourvinfo.red_mask;
426 rval |= ourvinfo.green_mask*rgb[GRN]/255 & ourvinfo.green_mask;
427 rval |= ourvinfo.blue_mask*rgb[BLU]/255 & ourvinfo.blue_mask;
428 return(rval);
429 }
430
431
432 static int
433 x11_getc() /* get a command character */
434 {
435 while (c_last <= c_first) {
436 c_first = c_last = 0; /* reset */
437 getevent(); /* wait for key */
438 }
439 x11_driver.inpready--;
440 return(c_queue[c_first++]);
441 }
442
443
444 static
445 getevent() /* get next event */
446 {
447 XNextEvent(ourdisplay, levptr(XEvent));
448 switch (levptr(XEvent)->type) {
449 case ConfigureNotify:
450 resizewindow(levptr(XConfigureEvent));
451 break;
452 case UnmapNotify:
453 freepixels();
454 break;
455 case MapNotify:
456 if (ourvinfo.class == PseudoColor ||
457 ourvinfo.class == GrayScale)
458 if (getpixels() == 0)
459 stderr_v("Cannot allocate colors\n");
460 else
461 new_ctab(ncolors);
462 break;
463 case Expose:
464 fixwindow(levptr(XExposeEvent));
465 break;
466 case KeyPress:
467 getkey(levptr(XKeyPressedEvent));
468 break;
469 case ButtonPress:
470 break;
471 }
472 }
473
474
475 static
476 getkey(ekey) /* get input key */
477 register XKeyPressedEvent *ekey;
478 {
479 register int n;
480
481 n = XLookupString(ekey, c_queue+c_last, sizeof(c_queue)-c_last,
482 NULL, NULL);
483 c_last += n;
484 x11_driver.inpready += n;
485 }
486
487
488 static
489 fixwindow(eexp) /* repair damage to window */
490 register XExposeEvent *eexp;
491 {
492 if (eexp->window == gwind) {
493 sprintf(getcombuf(&x11_driver), "repaint %d %d %d %d\n",
494 eexp->x, gheight - eexp->y - eexp->height,
495 eexp->x + eexp->width, gheight - eexp->y);
496 } else if (eexp->window == comline->w) {
497 if (eexp->count == 0)
498 xt_redraw(comline);
499 }
500 }
501
502
503 static
504 resizewindow(ersz) /* resize window */
505 register XConfigureEvent *ersz;
506 {
507 if (ersz->width == gwidth && ersz->height-COMHEIGHT == gheight)
508 return;
509
510 gwidth = ersz->width;
511 gheight = ersz->height-COMHEIGHT;
512 x11_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth;
513 x11_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight;
514
515 strcpy(getcombuf(&x11_driver), "new\n");
516 }