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, 8 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

# User Rev Content
1 greg 1.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 greg 1.12 #define GAMMA 2.2 /* exponent for color correction */
28 greg 1.1
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 greg 1.10 #define WFLUSH 30 /* flush after this many rays */
40 greg 1.1 #endif
41    
42 greg 1.8 #define checkinp() while (XPending() > 0) getevent()
43 greg 1.1
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 greg 1.12 static int *pixval; /* allocated pixel values */
52 greg 1.1
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 greg 1.13 int xnewcolr();
71    
72 greg 1.1 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 greg 1.2 stderr_v("cannot open X-windows; DISPLAY variable set?\n");
89 greg 1.1 return(NULL);
90     }
91     if (DisplayPlanes() < 4) {
92     stderr_v("not enough colors\n");
93     return(NULL);
94     }
95 greg 1.12 make_cmap(GAMMA); /* make color map */
96     if (getpixels() < 0) /* get pixels */
97 greg 1.1 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 greg 1.5 cmdvec = x_comout; /* set error vectors */
106 greg 1.1 if (wrnvec != NULL)
107     wrnvec = x_errout;
108     return(&x_driver);
109     }
110    
111    
112     static
113     x_close() /* close our display */
114     {
115 greg 1.5 cmdvec = NULL; /* reset error vectors */
116 greg 1.1 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 greg 1.12 freepixels();
131 greg 1.1 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 greg 1.13 if (new_ctab(ncolors, xnewcolr) == 0) {
162 greg 1.12 stderr_v("Color allocation error\n");
163     quit(1);
164     }
165 greg 1.8 checkinp();
166 greg 1.1 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 greg 1.12 pixval[get_pixel(col)]);
184 greg 1.1 }
185     if (nrays - lastflush >= WFLUSH) {
186 greg 1.9 if (ncolors <= 0) /* output necessary for death */
187     XPixSet(gwind,0,0,1,1,BlackPixel);
188 greg 1.8 checkinp();
189 greg 1.1 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 greg 1.11 editline(inp, x_getc, x_comout);
202 greg 1.1 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 greg 1.8 XFlush();
213 greg 1.1 }
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 greg 1.8 XFlush(); /* insure release */
240 greg 1.1 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 greg 1.13 xnewcolr(ndx, r, g, b) /* enter a color into hardware table */
257 greg 1.1 int ndx;
258 greg 1.13 int r, g, b;
259 greg 1.1 {
260     Color xcolor;
261    
262     xcolor.pixel = pixval[ndx];
263 greg 1.13 xcolor.red = r << 8;
264     xcolor.green = g << 8;
265     xcolor.blue = b << 8;
266 greg 1.1
267     XStoreColor(&xcolor);
268     }
269    
270    
271     static
272 greg 1.12 getpixels() /* get the color map */
273 greg 1.1 {
274     int planes;
275    
276     for (ncolors=(1<<DisplayPlanes())-3; ncolors>12; ncolors=ncolors*.937){
277     pixval = (int *)malloc(ncolors*sizeof(int));
278 greg 1.12 if (pixval == NULL)
279     break;
280 greg 1.1 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 greg 1.12 freepixels() /* free our pixels */
291 greg 1.1 {
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 greg 1.13 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 greg 1.1 /* fall through */
329     case ExposeRegion:
330     fixwindow(levptr(XExposeEvent));
331     break;
332     case UnmapWindow:
333     if (levptr(XUnmapEvent)->subwindow == 0)
334 greg 1.12 freepixels();
335 greg 1.1 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     }