ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x10.c
Revision: 1.19
Committed: Mon Jan 8 14:45:05 1990 UTC (35 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.18: +27 -24 lines
Log Message:
added window resizing

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