ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x11.c
Revision: 1.3
Committed: Tue Jan 30 11:37:54 1990 UTC (34 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +4 -2 lines
Log Message:
fixed bug where drivers would send commands inappropriately

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, prompt) /* read in a command line */
240 char *inp, *prompt;
241 {
242 int x11_getc(), x11_comout();
243
244 if (prompt != NULL)
245 xt_puts(prompt, comline);
246 xt_cursor(comline, TBLKCURS);
247 editline(inp, x11_getc, x11_comout);
248 xt_cursor(comline, TNOCURS);
249 }
250
251
252 static
253 x11_comout(out) /* output a string to command line */
254 char *out;
255 {
256 if (comline != NULL)
257 xt_puts(out, comline);
258 XFlush(ourdisplay);
259 }
260
261
262 static
263 x11_errout(msg) /* output an error message */
264 char *msg;
265 {
266 x11_comout(msg);
267 stderr_v(msg); /* send to stderr also! */
268 }
269
270
271 static int
272 x11_getcur(xp, yp) /* get cursor position */
273 int *xp, *yp;
274 {
275 while (XGrabPointer(ourdisplay, gwind, True, ButtonPressMask,
276 GrabModeAsync, GrabModeAsync, None, pickcursor,
277 CurrentTime) != GrabSuccess)
278 sleep(2);
279
280 do
281 getevent();
282 while (c_last <= c_first && levptr(XEvent)->type != ButtonPress);
283 *xp = levptr(XButtonPressedEvent)->x;
284 *yp = gheight-1 - levptr(XButtonPressedEvent)->y;
285 XUngrabPointer(ourdisplay, CurrentTime);
286 XFlush(ourdisplay); /* insure release */
287 if (c_last > c_first) /* key pressed */
288 return(x11_getc());
289 /* button pressed */
290 if (levptr(XButtonPressedEvent)->button & Button1)
291 return(MB1);
292 if (levptr(XButtonPressedEvent)->button & Button2)
293 return(MB2);
294 if (levptr(XButtonPressedEvent)->button & Button3)
295 return(MB3);
296 if (levptr(XButtonPressedEvent)->button & (Button4|Button5))
297 return(MB1);
298 return(ABORT);
299 }
300
301
302 static
303 xnewcolr(ndx, r, g, b) /* enter a color into hardware table */
304 int ndx;
305 int r, g, b;
306 {
307 XColor xcolor;
308
309 xcolor.pixel = pixval[ndx];
310 xcolor.red = r << 8;
311 xcolor.green = g << 8;
312 xcolor.blue = b << 8;
313 xcolor.flags = DoRed|DoGreen|DoBlue;
314
315 XStoreColor(ourdisplay, ourmap, &xcolor);
316 }
317
318
319 static int
320 getpixels() /* get the color map */
321 {
322 Visual *ourvis = DefaultVisual(ourdisplay,DefaultScreen(ourdisplay));
323
324 freepixels();
325 for (ncolors=(ourvis->map_entries)-3; ncolors>12; ncolors=ncolors*.937){
326 pixval = (int *)malloc(ncolors*sizeof(int));
327 if (pixval == NULL)
328 break;
329 if (XAllocColorCells(ourdisplay,ourmap,0,NULL,0,
330 pixval,ncolors) != 0)
331 return(ncolors);
332 free((char *)pixval);
333 }
334 return(ncolors = 0);
335 }
336
337
338 static
339 freepixels() /* free our pixels */
340 {
341 if (ncolors == 0)
342 return;
343 XFreeColors(ourdisplay,ourmap,pixval,ncolors,0L);
344 ncolors = 0;
345 }
346
347
348 static int
349 x11_getc() /* get a command character */
350 {
351 while (c_last <= c_first) {
352 c_first = c_last = 0; /* reset */
353 getevent(); /* wait for key */
354 }
355 x11_driver.inpready--;
356 return(c_queue[c_first++]);
357 }
358
359
360 static
361 getevent() /* get next event */
362 {
363 XNextEvent(ourdisplay, levptr(XEvent));
364 switch (levptr(XEvent)->type) {
365 case KeyPress:
366 getkey(levptr(XKeyPressedEvent));
367 break;
368 case ButtonPress:
369 break;
370 }
371 }
372
373
374 static
375 getkey(ekey) /* get input key */
376 register XKeyPressedEvent *ekey;
377 {
378 c_last += XLookupString(ekey, c_queue+c_last, sizeof(c_queue)-c_last,
379 NULL, NULL);
380 x11_driver.inpready = c_last-c_first;
381 }
382
383
384 #ifdef notdef
385 static
386 fixwindow(eexp) /* repair damage to window */
387 register XExposeEvent *eexp;
388 {
389 if (eexp->subwindow == 0)
390 repaint(eexp->x, gheight - eexp->y - eexp->height,
391 eexp->x + eexp->width, gheight - eexp->y);
392 else if (eexp->subwindow == comline->w)
393 xt_redraw(comline);
394 }
395 #endif