ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x11.c
Revision: 1.4
Committed: Thu Feb 22 10:22:01 1990 UTC (34 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +100 -84 lines
Log Message:
added response to resize, iconify, etc.

File Contents

# Content
1 #ifndef lint
2 static char SCCSid[] = "$SunId$ LBL";
3 #endif
4
5 /* Copyright (c) 1989 Regents of the University of California */
6
7 /*
8 * x11.c - driver for X-windows version 11.3
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
25 #define GAMMA 2.2 /* exponent for color correction */
26
27 #define MINWIDTH (4*COMCW) /* minimum graphics window width */
28 #define MINHEIGHT 16 /* minimum graphics window height */
29
30 #define BORWIDTH 5 /* border width */
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 14 /* approx. character height (pixels) */
37
38 #ifndef WFLUSH
39 #define WFLUSH 30 /* flush after this many rays */
40 #endif
41
42 #define ourscreen DefaultScreen(ourdisplay)
43 #define ourroot RootWindow(ourdisplay,ourscreen)
44 #define ourwhite WhitePixel(ourdisplay,ourscreen)
45 #define ourblack BlackPixel(ourdisplay,ourscreen)
46
47 #define checkinp() while (XPending(ourdisplay) > 0) getevent()
48
49 #define levptr(etype) ((etype *)&currentevent)
50
51 static XEvent currentevent; /* current event */
52
53 static int ncolors = 0; /* color table size */
54 static int *pixval = NULL; /* allocated pixels */
55
56 static Display *ourdisplay = NULL; /* our display */
57
58 static Window gwind = 0; /* our graphics window */
59
60 static Cursor pickcursor = 0; /* cursor used for picking */
61
62 static int gwidth, gheight; /* graphics window size */
63
64 static TEXTWIND *comline = NULL; /* our command line */
65
66 static char c_queue[64]; /* input queue */
67 static int c_first = 0; /* first character in queue */
68 static int c_last = 0; /* last character in queue */
69
70 static GC ourgc = 0; /* our graphics context for drawing */
71
72 static Colormap ourmap; /* our color map */
73
74 extern char *malloc();
75
76 int x11_close(), x11_clear(), x11_paintr(), x11_errout(),
77 x11_getcur(), x11_comout(), x11_comin();
78
79 static struct driver x11_driver = {
80 x11_close, x11_clear, x11_paintr, x11_getcur,
81 x11_comout, x11_comin, 1.0
82 };
83
84
85 struct driver *
86 x11_init(name, id) /* initialize driver */
87 char *name, *id;
88 {
89 XWMHints ourxwmhints;
90 Pixmap bmCursorSrc, bmCursorMsk;
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 if (DisplayPlanes(ourdisplay, ourscreen) < 4) {
98 stderr_v("not enough colors\n");
99 return(NULL);
100 }
101 ourmap = DefaultColormap(ourdisplay,ourscreen);
102 make_gmap(GAMMA); /* make color map */
103 /* create a cursor */
104 pickcursor = XCreateFontCursor (ourdisplay, XC_diamond_cross);
105 /* open window */
106 gwind = XCreateSimpleWindow(ourdisplay, ourroot, 0, 0,
107 DisplayWidth(ourdisplay,ourscreen)-2*BORWIDTH,
108 DisplayHeight(ourdisplay,ourscreen)-2*BORWIDTH,
109 BORWIDTH, ourblack, ourwhite);
110 if (gwind == 0) {
111 stderr_v("cannot create window\n");
112 return(NULL);
113 }
114 XStoreName(ourdisplay, gwind, id);
115 ourgc = XCreateGC(ourdisplay, gwind, 0, NULL);
116 ourxwmhints.flags = InputHint;
117 ourxwmhints.input = True;
118 XSetWMHints(ourdisplay, gwind, &ourxwmhints);
119 XSelectInput(ourdisplay, gwind, ExposureMask);
120 XMapWindow(ourdisplay, gwind);
121 XWindowEvent(ourdisplay, gwind, ExposureMask, levptr(XExposeEvent));
122 gwidth = levptr(XExposeEvent)->width;
123 gheight = levptr(XExposeEvent)->height - COMHEIGHT;
124 x11_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth;
125 x11_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight;
126 x11_driver.inpready = 0;
127 cmdvec = x11_comout; /* set error vectors */
128 if (wrnvec != NULL)
129 wrnvec = x11_errout;
130 return(&x11_driver);
131 }
132
133
134 static
135 x11_close() /* close our display */
136 {
137 cmdvec = NULL; /* reset error vectors */
138 if (wrnvec != NULL)
139 wrnvec = stderr_v;
140 if (ourdisplay == NULL)
141 return;
142 if (comline != NULL) {
143 xt_close(comline);
144 comline = NULL;
145 }
146 if (gwind != 0) {
147 XFreeGC(ourdisplay, ourgc);
148 XDestroyWindow(ourdisplay, gwind);
149 gwind = 0;
150 ourgc = 0;
151 }
152 XFreeCursor(ourdisplay, pickcursor);
153 freepixels();
154 XCloseDisplay(ourdisplay);
155 ourdisplay = NULL;
156 }
157
158
159 static
160 x11_clear(xres, yres) /* clear our display */
161 int xres, yres;
162 {
163 if (xres != gwidth || yres != gheight) { /* change window */
164 if (comline != NULL)
165 xt_close(comline);
166 XSelectInput(ourdisplay, gwind, 0);
167 XResizeWindow(ourdisplay, gwind, xres, yres+COMHEIGHT);
168 comline = xt_open(ourdisplay,
169 DefaultGC(ourdisplay,ourscreen),
170 gwind, 0, yres, xres, COMHEIGHT, 0, COMFN);
171 if (comline == NULL) {
172 stderr_v("Cannot open command line window\n");
173 quit(1);
174 }
175 XSelectInput(ourdisplay, comline->w, ExposureMask);
176 gwidth = xres;
177 gheight = yres;
178 XSync(ourdisplay, 1); /* discard input */
179 sleep(2); /* wait for window manager */
180 }
181 XClearWindow(ourdisplay, gwind);
182 /* reinitialize color table */
183 if (getpixels() == 0)
184 stderr_v("cannot allocate colors\n");
185 else
186 new_ctab(ncolors);
187
188 XSelectInput(ourdisplay, gwind,
189 StructureNotifyMask|ExposureMask|KeyPressMask|ButtonPressMask);
190 }
191
192
193 static
194 x11_paintr(col, xmin, ymin, xmax, ymax) /* fill a rectangle */
195 COLOR col;
196 int xmin, ymin, xmax, ymax;
197 {
198 extern long nrays; /* global ray count */
199 extern int xnewcolr(); /* pixel assignment routine */
200 static long lastflush = 0; /* ray count at last flush */
201
202 if (ncolors > 0) {
203 XSetForeground(ourdisplay, ourgc,
204 pixval[get_pixel(col, xnewcolr)]);
205 XFillRectangle(ourdisplay, gwind,
206 ourgc, xmin, gheight-ymax, xmax-xmin, ymax-ymin);
207 }
208 if (nrays - lastflush >= WFLUSH) {
209 if (ncolors <= 0) /* output necessary for death */
210 XFillRectangle(ourdisplay, gwind,
211 ourgc, 0, 0, 1 ,1);
212 checkinp();
213 lastflush = nrays;
214 }
215 }
216
217
218 static
219 x11_comin(inp, prompt) /* read in a command line */
220 char *inp, *prompt;
221 {
222 int x11_getc(), x11_comout();
223
224 if (prompt != NULL)
225 if (fromcombuf(inp, &x11_driver))
226 return;
227 else
228 xt_puts(prompt, comline);
229 xt_cursor(comline, TBLKCURS);
230 editline(inp, x11_getc, x11_comout);
231 xt_cursor(comline, TNOCURS);
232 }
233
234
235 static
236 x11_comout(out) /* output a string to command line */
237 char *out;
238 {
239 if (comline != NULL)
240 xt_puts(out, comline);
241 XFlush(ourdisplay);
242 }
243
244
245 static
246 x11_errout(msg) /* output an error message */
247 char *msg;
248 {
249 x11_comout(msg);
250 stderr_v(msg); /* send to stderr also! */
251 }
252
253
254 static int
255 x11_getcur(xp, yp) /* get cursor position */
256 int *xp, *yp;
257 {
258 while (XGrabPointer(ourdisplay, gwind, True, ButtonPressMask,
259 GrabModeAsync, GrabModeAsync, None, pickcursor,
260 CurrentTime) != GrabSuccess)
261 sleep(2);
262
263 do
264 getevent();
265 while (c_last <= c_first && levptr(XEvent)->type != ButtonPress);
266 *xp = levptr(XButtonPressedEvent)->x;
267 *yp = gheight-1 - levptr(XButtonPressedEvent)->y;
268 XUngrabPointer(ourdisplay, CurrentTime);
269 XFlush(ourdisplay); /* insure release */
270 if (c_last > c_first) /* key pressed */
271 return(x11_getc());
272 /* button pressed */
273 if (levptr(XButtonPressedEvent)->button & Button1)
274 return(MB1);
275 if (levptr(XButtonPressedEvent)->button & Button2)
276 return(MB2);
277 if (levptr(XButtonPressedEvent)->button & Button3)
278 return(MB3);
279 if (levptr(XButtonPressedEvent)->button & (Button4|Button5))
280 return(MB1);
281 return(ABORT);
282 }
283
284
285 static
286 xnewcolr(ndx, r, g, b) /* enter a color into hardware table */
287 int ndx;
288 int r, g, b;
289 {
290 XColor xcolor;
291
292 xcolor.pixel = pixval[ndx];
293 xcolor.red = r << 8;
294 xcolor.green = g << 8;
295 xcolor.blue = b << 8;
296 xcolor.flags = DoRed|DoGreen|DoBlue;
297
298 XStoreColor(ourdisplay, ourmap, &xcolor);
299 }
300
301
302 static int
303 getpixels() /* get the color map */
304 {
305 Visual *ourvis = DefaultVisual(ourdisplay,ourscreen);
306
307 if (ncolors > 0)
308 return(ncolors);
309 for (ncolors=(ourvis->map_entries)-3; ncolors>12; ncolors=ncolors*.937){
310 pixval = (int *)malloc(ncolors*sizeof(int));
311 if (pixval == NULL)
312 break;
313 if (XAllocColorCells(ourdisplay,ourmap,0,NULL,0,
314 pixval,ncolors) != 0)
315 return(ncolors);
316 free((char *)pixval);
317 }
318 return(ncolors = 0);
319 }
320
321
322 static
323 freepixels() /* free our pixels */
324 {
325 if (ncolors == 0)
326 return;
327 XFreeColors(ourdisplay,ourmap,pixval,ncolors,0L);
328 ncolors = 0;
329 }
330
331
332 static int
333 x11_getc() /* get a command character */
334 {
335 while (c_last <= c_first) {
336 c_first = c_last = 0; /* reset */
337 getevent(); /* wait for key */
338 }
339 x11_driver.inpready--;
340 return(c_queue[c_first++]);
341 }
342
343
344 static
345 getevent() /* get next event */
346 {
347 XNextEvent(ourdisplay, levptr(XEvent));
348 switch (levptr(XEvent)->type) {
349 case ConfigureNotify:
350 resizewindow(levptr(XConfigureEvent));
351 break;
352 case UnmapNotify:
353 freepixels();
354 break;
355 case MapNotify:
356 if (getpixels() == 0)
357 stderr_v("Cannot allocate colors\n");
358 else
359 new_ctab(ncolors);
360 break;
361 case Expose:
362 fixwindow(levptr(XExposeEvent));
363 break;
364 case KeyPress:
365 getkey(levptr(XKeyPressedEvent));
366 break;
367 case ButtonPress:
368 break;
369 }
370 }
371
372
373 static
374 getkey(ekey) /* get input key */
375 register XKeyPressedEvent *ekey;
376 {
377 c_last += XLookupString(ekey, c_queue+c_last, sizeof(c_queue)-c_last,
378 NULL, NULL);
379 x11_driver.inpready = c_last-c_first;
380 }
381
382
383 static
384 fixwindow(eexp) /* repair damage to window */
385 register XExposeEvent *eexp;
386 {
387 if (eexp->window == gwind) {
388 sprintf(getcombuf(&x11_driver), "repaint %d %d %d %d\n",
389 eexp->x, gheight - eexp->y - eexp->height,
390 eexp->x + eexp->width, gheight - eexp->y);
391 } else if (eexp->window == comline->w) {
392 if (eexp->count == 0)
393 xt_redraw(comline);
394 }
395 }
396
397
398 static
399 resizewindow(ersz) /* resize window */
400 register XConfigureEvent *ersz;
401 {
402 if (ersz->width == gwidth && ersz->height-COMHEIGHT == gheight)
403 return;
404
405 gwidth = ersz->width;
406 gheight = ersz->height-COMHEIGHT;
407 x11_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth;
408 x11_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight;
409
410 strcpy(getcombuf(&x11_driver), "new\n");
411 }