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

# Content
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 #define flush() XFlush()
45
46 #define checkinp() while (QLength() > 0) getevent()
47
48 #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 stderr_v("cannot open X-windows; DISPLAY variable set?\n");
107 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 cmdvec = x_comout; /* set error vectors */
123 if (wrnvec != NULL)
124 wrnvec = x_errout;
125 return(&x_driver);
126 }
127
128
129 static
130 x_close() /* close our display */
131 {
132 cmdvec = NULL; /* reset error vectors */
133 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 flush();
207 lastflush = nrays;
208 }
209 checkinp();
210 }
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 flush();
232 }
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 }