ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x11.c
Revision: 1.2
Committed: Fri Jan 12 11:33:05 1990 UTC (34 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +6 -12 lines
Log Message:
*** empty log message ***

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