ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x10.c
Revision: 1.13
Committed: Tue Oct 3 13:02:57 1989 UTC (35 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.12: +15 -35 lines
Log Message:
Improved color table allocation, second cut.

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.2 /* 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 checkinp() while (XPending() > 0) getevent()
43
44 #define levptr(etype) ((etype *)&thisevent)
45
46 static char *clientname; /* calling client's name */
47
48 static XEvent thisevent; /* current event */
49
50 static int ncolors = 0; /* color table size */
51 static int *pixval; /* allocated pixel values */
52
53 static Display *ourdisplay = NULL; /* our display */
54
55 static Window gwind = 0; /* our graphics window */
56
57 static Cursor pickcursor = 0; /* cursor used for picking */
58
59 static int gwidth = 0; /* graphics window width */
60 static int gheight = 0; /* graphics window height */
61
62 static TEXTWIND *comline = NULL; /* our command line */
63
64 static char c_queue[64]; /* input queue */
65 static int c_first = 0; /* first character in queue */
66 static int c_last = 0; /* last character in queue */
67
68 extern char *malloc();
69
70 int xnewcolr();
71
72 int x_close(), x_clear(), x_paintr(), x_errout(),
73 x_getcur(), x_comout(), x_comin();
74
75 static struct driver x_driver = {
76 x_close, x_clear, x_paintr, x_getcur,
77 x_comout, x_comin,
78 MAXRES, MAXRES
79 };
80
81
82 struct driver *
83 x_init(name) /* initialize driver */
84 char *name;
85 {
86 ourdisplay = XOpenDisplay(NULL);
87 if (ourdisplay == NULL) {
88 stderr_v("cannot open X-windows; DISPLAY variable set?\n");
89 return(NULL);
90 }
91 if (DisplayPlanes() < 4) {
92 stderr_v("not enough colors\n");
93 return(NULL);
94 }
95 make_cmap(GAMMA); /* make color map */
96 if (getpixels() < 0) /* get pixels */
97 stderr_v("cannot allocate colors\n");
98
99 pickcursor = XCreateCursor(bcross_width, bcross_height,
100 bcross_bits, bcross_mask_bits,
101 bcross_x_hot, bcross_y_hot,
102 BlackPixel, WhitePixel, GXcopy);
103 clientname = name;
104 x_driver.inpready = 0;
105 cmdvec = x_comout; /* set error vectors */
106 if (wrnvec != NULL)
107 wrnvec = x_errout;
108 return(&x_driver);
109 }
110
111
112 static
113 x_close() /* close our display */
114 {
115 cmdvec = NULL; /* reset error vectors */
116 if (wrnvec != NULL)
117 wrnvec = stderr_v;
118 if (ourdisplay == NULL)
119 return;
120 if (comline != NULL) {
121 xt_close(comline);
122 comline = NULL;
123 }
124 if (gwind != 0) {
125 XDestroyWindow(gwind);
126 gwind = 0;
127 gwidth = gheight = 0;
128 }
129 XFreeCursor(pickcursor);
130 freepixels();
131 XCloseDisplay(ourdisplay);
132 ourdisplay = NULL;
133 }
134
135
136 static
137 x_clear(xres, yres) /* clear our display */
138 int xres, yres;
139 {
140 if (xres != gwidth || yres != gheight) { /* new window */
141 if (comline != NULL)
142 xt_close(comline);
143 if (gwind != 0)
144 XDestroyWindow(gwind);
145 gwind = XCreateWindow(RootWindow, 0, BARHEIGHT,
146 xres, yres+COMHEIGHT, BORWIDTH,
147 BlackPixmap, BlackPixmap);
148 if (gwind == 0)
149 goto fail;
150 comline = xt_open(gwind, 0, yres, xres, COMHEIGHT, 0, COMFN);
151 if (comline == NULL)
152 goto fail;
153 XMapWindow(gwind);
154 XSelectInput(gwind,
155 KeyPressed|ButtonPressed|ExposeWindow|ExposeRegion|UnmapWindow);
156 XStoreName(gwind, clientname);
157 gwidth = xres;
158 gheight = yres;
159 } else /* just clear */
160 XClear(gwind);
161 if (new_ctab(ncolors, xnewcolr) == 0) {
162 stderr_v("Color allocation error\n");
163 quit(1);
164 }
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
181 if (ncolors > 0) {
182 XPixSet(gwind, xmin, gheight-ymax, xmax-xmin, ymax-ymin,
183 pixval[get_pixel(col)]);
184 }
185 if (nrays - lastflush >= WFLUSH) {
186 if (ncolors <= 0) /* output necessary for death */
187 XPixSet(gwind,0,0,1,1,BlackPixel);
188 checkinp();
189 lastflush = nrays;
190 }
191 }
192
193
194 static
195 x_comin(inp) /* read in a command line */
196 char *inp;
197 {
198 int x_getc(), x_comout();
199
200 xt_cursor(comline, TBLKCURS);
201 editline(inp, x_getc, x_comout);
202 xt_cursor(comline, TNOCURS);
203 }
204
205
206 static
207 x_comout(out) /* output a string to command line */
208 char *out;
209 {
210 if (comline != NULL)
211 xt_puts(out, comline);
212 XFlush();
213 }
214
215
216 static
217 x_errout(msg) /* output an error message */
218 char *msg;
219 {
220 x_comout(msg);
221 stderr_v(msg); /* send to stderr also! */
222 }
223
224
225 static int
226 x_getcur(xp, yp) /* get cursor position */
227 int *xp, *yp;
228 {
229 while (XGrabMouse(gwind, pickcursor, ButtonPressed) == 0)
230 sleep(1);
231 XFocusKeyboard(gwind);
232 do
233 getevent();
234 while (c_last <= c_first && levptr(XEvent)->type != ButtonPressed);
235 *xp = levptr(XKeyOrButtonEvent)->x;
236 *yp = gheight-1 - levptr(XKeyOrButtonEvent)->y;
237 XFocusKeyboard(RootWindow);
238 XUngrabMouse();
239 XFlush(); /* insure release */
240 if (c_last > c_first) /* key pressed */
241 return(x_getc());
242 /* button pressed */
243 switch (levptr(XKeyOrButtonEvent)->detail & 0377) {
244 case LeftButton:
245 return(MB1);
246 case MiddleButton:
247 return(MB2);
248 case RightButton:
249 return(MB3);
250 }
251 return(ABORT);
252 }
253
254
255 static
256 xnewcolr(ndx, r, g, b) /* enter a color into hardware table */
257 int ndx;
258 int r, g, b;
259 {
260 Color xcolor;
261
262 xcolor.pixel = pixval[ndx];
263 xcolor.red = r << 8;
264 xcolor.green = g << 8;
265 xcolor.blue = b << 8;
266
267 XStoreColor(&xcolor);
268 }
269
270
271 static
272 getpixels() /* get the color map */
273 {
274 int planes;
275
276 for (ncolors=(1<<DisplayPlanes())-3; ncolors>12; ncolors=ncolors*.937){
277 pixval = (int *)malloc(ncolors*sizeof(int));
278 if (pixval == NULL)
279 break;
280 if (XGetColorCells(0,ncolors,0,&planes,pixval) != 0)
281 return(0);
282 free((char *)pixval);
283 }
284 ncolors = 0;
285 return(-1);
286 }
287
288
289 static
290 freepixels() /* free our pixels */
291 {
292 if (ncolors == 0)
293 return;
294 XFreeColors(pixval, ncolors, 0);
295 free((char *)pixval);
296 ncolors = 0;
297 }
298
299
300 static int
301 x_getc() /* get a command character */
302 {
303 while (c_last <= c_first) {
304 c_first = c_last = 0; /* reset */
305 getevent(); /* wait for key */
306 }
307 x_driver.inpready--;
308 return(c_queue[c_first++]);
309 }
310
311
312 static
313 getevent() /* get next event */
314 {
315 XNextEvent(levptr(XEvent));
316 switch (levptr(XEvent)->type) {
317 case KeyPressed:
318 getkey(levptr(XKeyPressedEvent));
319 break;
320 case ExposeWindow:
321 if (levptr(XExposeEvent)->subwindow == 0) {
322 if (ncolors == 0 && getpixels() < 0) {
323 stderr_v("cannot allocate colors\n");
324 break;
325 }
326 new_ctab(ncolors, xnewcolr);
327 }
328 /* fall through */
329 case ExposeRegion:
330 fixwindow(levptr(XExposeEvent));
331 break;
332 case UnmapWindow:
333 if (levptr(XUnmapEvent)->subwindow == 0)
334 freepixels();
335 break;
336 case ButtonPressed: /* handled in x_getcur() */
337 break;
338 }
339 }
340
341
342 static
343 getkey(ekey) /* get input key */
344 register XKeyPressedEvent *ekey;
345 {
346 int n;
347 register char *str;
348
349 str = XLookupMapping(ekey, &n);
350 while (n-- > 0 && c_last < sizeof(c_queue))
351 c_queue[c_last++] = *str++;
352 x_driver.inpready = c_last - c_first;
353 }
354
355
356 static
357 fixwindow(eexp) /* repair damage to window */
358 register XExposeEvent *eexp;
359 {
360 if (eexp->subwindow == 0)
361 repaint(eexp->x, gheight - eexp->y - eexp->height,
362 eexp->x + eexp->width, gheight - eexp->y);
363 else if (eexp->subwindow == comline->w)
364 xt_redraw(comline);
365 }