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

# 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 checkinp() while (XPending() > 0) getevent()
45
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 stderr_v("cannot open X-windows; DISPLAY variable set?\n");
93 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 cmdvec = x_comout; /* set error vectors */
109 if (wrnvec != NULL)
110 wrnvec = x_errout;
111 return(&x_driver);
112 }
113
114
115 static
116 x_close() /* close our display */
117 {
118 cmdvec = NULL; /* reset error vectors */
119 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 checkinp();
166 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 if (ncolors <= 0) /* output necessary for death */
193 XPixSet(gwind,0,0,1,1,BlackPixel);
194 checkinp();
195 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 editline(inp, x_getc, x_comout);
208 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 XFlush();
219 }
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 XFlush(); /* insure release */
246 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 }