ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/x11.c
Revision: 2.29
Committed: Sat Feb 22 02:07:29 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.28: +81 -31 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * x11.c - driver for X-windows version 11
6 */
7
8 /* ====================================================================
9 * The Radiance Software License, Version 1.0
10 *
11 * Copyright (c) 1990 - 2002 The Regents of the University of California,
12 * through Lawrence Berkeley National Laboratory. All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in
23 * the documentation and/or other materials provided with the
24 * distribution.
25 *
26 * 3. The end-user documentation included with the redistribution,
27 * if any, must include the following acknowledgment:
28 * "This product includes Radiance software
29 * (http://radsite.lbl.gov/)
30 * developed by the Lawrence Berkeley National Laboratory
31 * (http://www.lbl.gov/)."
32 * Alternately, this acknowledgment may appear in the software itself,
33 * if and wherever such third-party acknowledgments normally appear.
34 *
35 * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
36 * and "The Regents of the University of California" must
37 * not be used to endorse or promote products derived from this
38 * software without prior written permission. For written
39 * permission, please contact [email protected].
40 *
41 * 5. Products derived from this software may not be called "Radiance",
42 * nor may "Radiance" appear in their name, without prior written
43 * permission of Lawrence Berkeley National Laboratory.
44 *
45 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48 * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 * ====================================================================
58 *
59 * This software consists of voluntary contributions made by many
60 * individuals on behalf of Lawrence Berkeley National Laboratory. For more
61 * information on Lawrence Berkeley National Laboratory, please see
62 * <http://www.lbl.gov/>.
63 */
64
65 #include "standard.h"
66 #include <sys/ioctl.h>
67 #ifdef sparc
68 #include <sys/conf.h>
69 #include <sys/file.h>
70 #include <sys/filio.h>
71 #endif
72 #if !defined(FNDELAY) && defined(O_NONBLOCK)
73 #define FNDELAY O_NONBLOCK
74 #endif
75
76 #include <X11/Xlib.h>
77 #include <X11/cursorfont.h>
78 #include <X11/Xutil.h>
79
80 #include "color.h"
81 #include "driver.h"
82 #include "x11twind.h"
83 #include "x11icon.h"
84
85 #define GAMMA 2.2 /* default exponent correction */
86
87 #define MINWIDTH (32*COMCW) /* minimum graphics window width */
88 #define MINHEIGHT (MINWIDTH/2) /* minimum graphics window height */
89
90 #define BORWIDTH 5 /* border width */
91 #define COMHEIGHT (COMLH*COMCH) /* command line height (pixels) */
92
93 #define COMFN "8x13" /* command line font name */
94 #define COMLH 3 /* number of command lines */
95 #define COMCW 8 /* approx. character width (pixels) */
96 #define COMCH 14 /* approx. character height (pixels) */
97
98 #define ourscreen DefaultScreen(ourdisplay)
99 #define ourroot RootWindow(ourdisplay,ourscreen)
100
101 #define levptr(etype) ((etype *)&currentevent)
102
103 static XEvent currentevent; /* current event */
104
105 static int ncolors = 0; /* color table size */
106 static int mapped = 0; /* window is mapped? */
107 static unsigned long *pixval = NULL; /* allocated pixels */
108 static unsigned long ourblack=0, ourwhite=1;
109
110 static Display *ourdisplay = NULL; /* our display */
111
112 static XVisualInfo ourvinfo; /* our visual information */
113
114 static Window gwind = 0; /* our graphics window */
115
116 static Cursor pickcursor = 0; /* cursor used for picking */
117
118 static int gwidth, gheight; /* graphics window size */
119
120 static int comheight; /* desired comline height */
121 static TEXTWIND *comline = NULL; /* our command line */
122
123 static char c_queue[64]; /* input queue */
124 static int c_first = 0; /* first character in queue */
125 static int c_last = 0; /* last character in queue */
126
127 static GC ourgc = 0; /* our graphics context for drawing */
128
129 static Colormap ourmap = 0; /* our color map */
130
131 #define IC_X11 0
132 #define IC_IOCTL 1
133 #define IC_READ 2
134
135 static int inpcheck; /* whence to check input */
136
137 static int x11_getcur();
138
139 static void x11_close(), x11_clear(), x11_paintr(), x11_errout(),
140 x11_comout(), x11_comin(), x11_flush();
141
142 static void std_comin(), std_comout();
143
144 static struct driver x11_driver = {
145 x11_close, x11_clear, x11_paintr, x11_getcur,
146 NULL, NULL, x11_flush, 1.0
147 };
148
149 static int getpixels(), x11_getc();
150 static void xnewcolr(), freepixels(), resizewindow(),
151 getevent(), getkey(), fixwindow();
152 static unsigned long true_pixel();
153
154
155 struct driver *
156 x11_init(name, id) /* initialize driver */
157 char *name, *id;
158 {
159 char *gv;
160 int nplanes;
161 XSetWindowAttributes ourwinattr;
162 XWMHints ourxwmhints;
163 XSizeHints oursizhints;
164 /* open display server */
165 ourdisplay = XOpenDisplay(NULL);
166 if (ourdisplay == NULL) {
167 eputs("cannot open X-windows; DISPLAY variable set?\n");
168 return(NULL);
169 }
170 /* find a usable visual */
171 nplanes = DisplayPlanes(ourdisplay, ourscreen);
172 if (XMatchVisualInfo(ourdisplay,ourscreen,
173 nplanes>12?nplanes:24,TrueColor,&ourvinfo) ||
174 XMatchVisualInfo(ourdisplay,ourscreen,
175 nplanes>12?nplanes:24,DirectColor,&ourvinfo)) {
176 ourblack = 0;
177 ourwhite = ourvinfo.red_mask |
178 ourvinfo.green_mask |
179 ourvinfo.blue_mask ;
180 } else {
181 if (nplanes < 4) {
182 eputs("not enough colors\n");
183 return(NULL);
184 }
185 if (!XMatchVisualInfo(ourdisplay,ourscreen,
186 nplanes,PseudoColor,&ourvinfo) &&
187 !XMatchVisualInfo(ourdisplay,ourscreen,
188 nplanes,GrayScale,&ourvinfo)) {
189 eputs("unsupported visual type\n");
190 return(NULL);
191 }
192 ourblack = BlackPixel(ourdisplay,ourscreen);
193 ourwhite = WhitePixel(ourdisplay,ourscreen);
194 }
195 /* set gamma */
196 if ((gv = XGetDefault(ourdisplay, "radiance", "gamma")) != NULL
197 || (gv = getenv("DISPLAY_GAMMA")) != NULL)
198 make_gmap(atof(gv));
199 else
200 make_gmap(GAMMA);
201 /* X11 command line or no? */
202 if (!strcmp(name, "x11"))
203 comheight = COMHEIGHT;
204 else /* "x11d" */ {
205 comheight = 0;
206 #ifndef FNDELAY
207 eputs("warning: x11d driver not fully functional on this machine\n");
208 #endif
209 }
210 /* open window */
211 ourwinattr.background_pixel = ourblack;
212 ourwinattr.border_pixel = ourblack;
213 /* this is stupid */
214 ourwinattr.colormap = XCreateColormap(ourdisplay, ourroot,
215 ourvinfo.visual, AllocNone);
216 gwind = XCreateWindow(ourdisplay, ourroot, 0, 0,
217 DisplayWidth(ourdisplay,ourscreen)-2*BORWIDTH,
218 DisplayHeight(ourdisplay,ourscreen)-2*BORWIDTH,
219 BORWIDTH, ourvinfo.depth, InputOutput, ourvinfo.visual,
220 CWBackPixel|CWBorderPixel|CWColormap, &ourwinattr);
221 if (gwind == 0) {
222 eputs("cannot create window\n");
223 return(NULL);
224 }
225 XStoreName(ourdisplay, gwind, id);
226 /* create a cursor */
227 pickcursor = XCreateFontCursor(ourdisplay, XC_diamond_cross);
228 ourgc = XCreateGC(ourdisplay, gwind, 0, NULL);
229 ourxwmhints.flags = InputHint|IconPixmapHint;
230 ourxwmhints.input = True;
231 ourxwmhints.icon_pixmap = XCreateBitmapFromData(ourdisplay,
232 gwind, x11icon_bits, x11icon_width, x11icon_height);
233 XSetWMHints(ourdisplay, gwind, &ourxwmhints);
234 oursizhints.min_width = MINWIDTH;
235 oursizhints.min_height = MINHEIGHT+comheight;
236 oursizhints.flags = PMinSize;
237 XSetNormalHints(ourdisplay, gwind, &oursizhints);
238 XSelectInput(ourdisplay, gwind, ExposureMask);
239 XMapWindow(ourdisplay, gwind);
240 XWindowEvent(ourdisplay, gwind, ExposureMask, levptr(XEvent));
241 gwidth = levptr(XExposeEvent)->width;
242 gheight = levptr(XExposeEvent)->height - comheight;
243 x11_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth;
244 x11_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight;
245 x11_driver.inpready = 0;
246 mapped = 1;
247 /* set i/o vectors */
248 if (comheight) {
249 x11_driver.comin = x11_comin;
250 x11_driver.comout = x11_comout;
251 erract[COMMAND].pf = x11_comout;
252 if (erract[WARNING].pf != NULL)
253 erract[WARNING].pf = x11_errout;
254 inpcheck = IC_X11;
255 } else {
256 x11_driver.comin = std_comin;
257 x11_driver.comout = std_comout;
258 erract[COMMAND].pf = std_comout;
259 inpcheck = IC_IOCTL;
260 }
261 return(&x11_driver);
262 }
263
264
265 static void
266 x11_close() /* close our display */
267 {
268 erract[COMMAND].pf = NULL; /* reset error vectors */
269 if (erract[WARNING].pf != NULL)
270 erract[WARNING].pf = wputs;
271 if (ourdisplay == NULL)
272 return;
273 if (comline != NULL) {
274 xt_close(comline);
275 comline = NULL;
276 }
277 freepixels();
278 XFreeGC(ourdisplay, ourgc);
279 XDestroyWindow(ourdisplay, gwind);
280 gwind = 0;
281 ourgc = 0;
282 XFreeCursor(ourdisplay, pickcursor);
283 XCloseDisplay(ourdisplay);
284 ourdisplay = NULL;
285 }
286
287
288 static void
289 x11_clear(xres, yres) /* clear our display */
290 int xres, yres;
291 {
292 /* check limits */
293 if (xres < MINWIDTH)
294 xres = MINWIDTH;
295 if (yres < MINHEIGHT)
296 yres = MINHEIGHT;
297 /* resize window */
298 if (xres != gwidth || yres != gheight) {
299 XSelectInput(ourdisplay, gwind, 0);
300 XResizeWindow(ourdisplay, gwind, xres, yres+comheight);
301 gwidth = xres;
302 gheight = yres;
303 XFlush(ourdisplay);
304 sleep(2); /* wait for window manager */
305 XSync(ourdisplay, 1); /* discard input */
306 }
307 XClearWindow(ourdisplay, gwind);
308 /* reinitialize color table */
309 if (ourvinfo.class == PseudoColor || ourvinfo.class == GrayScale)
310 if (getpixels() == 0)
311 eputs("cannot allocate colors\n");
312 else
313 new_ctab(ncolors);
314 /* get new command line */
315 if (comline != NULL)
316 xt_close(comline);
317 if (comheight) {
318 comline = xt_open(ourdisplay, gwind, 0, gheight, gwidth,
319 comheight, 0, ourblack, ourwhite, COMFN);
320 if (comline == NULL) {
321 eputs("cannot open command line window\n");
322 quit(1);
323 }
324 XSelectInput(ourdisplay, comline->w, ExposureMask);
325 /* remove earmuffs */
326 XSelectInput(ourdisplay, gwind,
327 StructureNotifyMask|ExposureMask|KeyPressMask|ButtonPressMask);
328 } else /* remove earmuffs */
329 XSelectInput(ourdisplay, gwind,
330 StructureNotifyMask|ExposureMask|ButtonPressMask);
331 }
332
333
334 static void
335 x11_paintr(col, xmin, ymin, xmax, ymax) /* fill a rectangle */
336 COLOR col;
337 int xmin, ymin, xmax, ymax;
338 {
339 unsigned long pixel;
340
341 if (!mapped)
342 return;
343 if (ncolors > 0)
344 pixel = pixval[get_pixel(col, xnewcolr)];
345 else
346 pixel = true_pixel(col);
347 XSetForeground(ourdisplay, ourgc, pixel);
348 XFillRectangle(ourdisplay, gwind,
349 ourgc, xmin, gheight-ymax, xmax-xmin, ymax-ymin);
350 }
351
352
353 static void
354 x11_flush() /* flush output */
355 {
356 char buf[256];
357 int n;
358 /* check for input */
359 XNoOp(ourdisplay);
360 n = XPending(ourdisplay); /* from X server */
361 while (n-- > 0)
362 getevent();
363 #ifdef FNDELAY
364 if (inpcheck == IC_IOCTL) { /* from stdin */
365 #ifdef FIONREAD
366 if (ioctl(fileno(stdin), FIONREAD, &n) < 0) {
367 #else
368 if (1) {
369 #endif
370 if (fcntl(fileno(stdin), F_SETFL, FNDELAY) < 0) {
371 eputs("cannot change input mode\n");
372 quit(1);
373 }
374 inpcheck = IC_READ;
375 } else
376 x11_driver.inpready += n;
377 }
378 if (inpcheck == IC_READ) {
379 n = read(fileno(stdin), buf, sizeof(buf)-1);
380 if (n > 0) {
381 buf[n] = '\0';
382 tocombuf(buf, &x11_driver);
383 }
384 }
385 #endif
386 }
387
388
389 static void
390 x11_comin(inp, prompt) /* read in a command line */
391 char *inp, *prompt;
392 {
393 if (prompt != NULL) {
394 x11_flush(); /* make sure we get everything */
395 if (fromcombuf(inp, &x11_driver))
396 return;
397 xt_puts(prompt, comline);
398 }
399 xt_cursor(comline, TBLKCURS);
400 editline(inp, x11_getc, x11_comout);
401 xt_cursor(comline, TNOCURS);
402 }
403
404
405 static void
406 x11_comout(outp) /* output a string to command line */
407 char *outp;
408 {
409 if (comline == NULL || outp == NULL || !outp[0])
410 return;
411 xt_puts(outp, comline);
412 if (outp[strlen(outp)-1] == '\n')
413 XFlush(ourdisplay);
414 }
415
416
417 static void
418 x11_errout(msg) /* output an error message */
419 char *msg;
420 {
421 eputs(msg); /* send to stderr also! */
422 x11_comout(msg);
423 }
424
425
426 static void
427 std_comin(inp, prompt) /* read in command line from stdin */
428 char *inp, *prompt;
429 {
430 if (prompt != NULL) {
431 if (fromcombuf(inp, &x11_driver))
432 return;
433 if (!x11_driver.inpready)
434 std_comout(prompt);
435 }
436 #ifdef FNDELAY
437 if (inpcheck == IC_READ) { /* turn off FNDELAY */
438 if (fcntl(fileno(stdin), F_SETFL, 0) < 0) {
439 eputs("cannot change input mode\n");
440 quit(1);
441 }
442 inpcheck = IC_IOCTL;
443 }
444 #endif
445 if (gets(inp) == NULL) {
446 strcpy(inp, "quit");
447 return;
448 }
449 x11_driver.inpready -= strlen(inp) + 1;
450 if (x11_driver.inpready < 0)
451 x11_driver.inpready = 0;
452 }
453
454
455 static void
456 std_comout(outp) /* write out string to stdout */
457 char *outp;
458 {
459 fputs(outp, stdout);
460 fflush(stdout);
461 }
462
463
464 static int
465 x11_getcur(xp, yp) /* get cursor position */
466 int *xp, *yp;
467 {
468 while (XGrabPointer(ourdisplay, gwind, True, ButtonPressMask,
469 GrabModeAsync, GrabModeAsync, None, pickcursor,
470 CurrentTime) != GrabSuccess)
471 sleep(2);
472
473 do
474 getevent();
475 while (c_last <= c_first && levptr(XEvent)->type != ButtonPress);
476 *xp = levptr(XButtonPressedEvent)->x;
477 *yp = gheight-1 - levptr(XButtonPressedEvent)->y;
478 XUngrabPointer(ourdisplay, CurrentTime);
479 XFlush(ourdisplay); /* insure release */
480 if (c_last > c_first) /* key pressed */
481 return(x11_getc());
482 /* button pressed */
483 if (levptr(XButtonPressedEvent)->button == Button1)
484 return(MB1);
485 if (levptr(XButtonPressedEvent)->button == Button2)
486 return(MB2);
487 if (levptr(XButtonPressedEvent)->button == Button3)
488 return(MB3);
489 return(ABORT);
490 }
491
492
493 static void
494 xnewcolr(ndx, r, g, b) /* enter a color into hardware table */
495 int ndx;
496 int r, g, b;
497 {
498 XColor xcolor;
499
500 xcolor.pixel = pixval[ndx];
501 xcolor.red = r << 8;
502 xcolor.green = g << 8;
503 xcolor.blue = b << 8;
504 xcolor.flags = DoRed|DoGreen|DoBlue;
505
506 XStoreColor(ourdisplay, ourmap, &xcolor);
507 }
508
509
510 static int
511 getpixels() /* get the color map */
512 {
513 XColor thiscolor;
514 register int i, j;
515
516 if (ncolors > 0)
517 return(ncolors);
518 if (ourvinfo.visual == DefaultVisual(ourdisplay,ourscreen)) {
519 ourmap = DefaultColormap(ourdisplay,ourscreen);
520 goto loop;
521 }
522 newmap:
523 ourmap = XCreateColormap(ourdisplay,gwind,ourvinfo.visual,AllocNone);
524 loop:
525 for (ncolors = ourvinfo.colormap_size;
526 ncolors > ourvinfo.colormap_size/3;
527 ncolors = ncolors*.937) {
528 pixval = (unsigned long *)malloc(ncolors*sizeof(unsigned long));
529 if (pixval == NULL)
530 return(ncolors = 0);
531 if (XAllocColorCells(ourdisplay,ourmap,0,NULL,0,pixval,ncolors))
532 break;
533 free((void *)pixval);
534 pixval = NULL;
535 }
536 if (pixval == NULL) {
537 if (ourmap == DefaultColormap(ourdisplay,ourscreen))
538 goto newmap; /* try it with our map */
539 else
540 return(ncolors = 0); /* failed */
541 }
542 if (ourmap != DefaultColormap(ourdisplay,ourscreen))
543 for (i = 0; i < ncolors; i++) { /* reset black and white */
544 if (pixval[i] != ourblack && pixval[i] != ourwhite)
545 continue;
546 thiscolor.pixel = pixval[i];
547 thiscolor.flags = DoRed|DoGreen|DoBlue;
548 XQueryColor(ourdisplay,
549 DefaultColormap(ourdisplay,ourscreen),
550 &thiscolor);
551 XStoreColor(ourdisplay, ourmap, &thiscolor);
552 for (j = i; j+1 < ncolors; j++)
553 pixval[j] = pixval[j+1];
554 ncolors--;
555 i--;
556 }
557 XSetWindowColormap(ourdisplay, gwind, ourmap);
558 return(ncolors);
559 }
560
561
562 static void
563 freepixels() /* free our pixels */
564 {
565 if (ncolors == 0)
566 return;
567 XFreeColors(ourdisplay,ourmap,pixval,ncolors,0L);
568 free((void *)pixval);
569 pixval = NULL;
570 ncolors = 0;
571 if (ourmap != DefaultColormap(ourdisplay,ourscreen))
572 XFreeColormap(ourdisplay, ourmap);
573 ourmap = 0;
574 }
575
576
577 static unsigned long
578 true_pixel(col) /* return true pixel value for color */
579 COLOR col;
580 {
581 unsigned long rval;
582 BYTE rgb[3];
583
584 map_color(rgb, col);
585 rval = ourvinfo.red_mask*rgb[RED]/255 & ourvinfo.red_mask;
586 rval |= ourvinfo.green_mask*rgb[GRN]/255 & ourvinfo.green_mask;
587 rval |= ourvinfo.blue_mask*rgb[BLU]/255 & ourvinfo.blue_mask;
588 return(rval);
589 }
590
591
592 static int
593 x11_getc() /* get a command character */
594 {
595 while (c_last <= c_first) {
596 c_first = c_last = 0; /* reset */
597 getevent(); /* wait for key */
598 }
599 x11_driver.inpready--;
600 return(c_queue[c_first++]);
601 }
602
603
604 static void
605 getevent() /* get next event */
606 {
607 XNextEvent(ourdisplay, levptr(XEvent));
608 switch (levptr(XEvent)->type) {
609 case ConfigureNotify:
610 resizewindow(levptr(XConfigureEvent));
611 break;
612 case UnmapNotify:
613 mapped = 0;
614 freepixels();
615 break;
616 case MapNotify:
617 if (ourvinfo.class == PseudoColor ||
618 ourvinfo.class == GrayScale)
619 if (getpixels() == 0)
620 eputs("cannot allocate colors\n");
621 else
622 new_ctab(ncolors);
623 mapped = 1;
624 break;
625 case Expose:
626 fixwindow(levptr(XExposeEvent));
627 break;
628 case KeyPress:
629 getkey(levptr(XKeyPressedEvent));
630 break;
631 case ButtonPress:
632 break;
633 }
634 }
635
636
637 static void
638 getkey(ekey) /* get input key */
639 register XKeyPressedEvent *ekey;
640 {
641 register int n;
642
643 n = XLookupString(ekey, c_queue+c_last, sizeof(c_queue)-c_last,
644 NULL, NULL);
645 c_last += n;
646 x11_driver.inpready += n;
647 }
648
649
650 static void
651 fixwindow(eexp) /* repair damage to window */
652 register XExposeEvent *eexp;
653 {
654 char buf[80];
655
656 if (eexp->window == gwind) {
657 sprintf(buf, "repaint %d %d %d %d\n",
658 eexp->x, gheight - eexp->y - eexp->height,
659 eexp->x + eexp->width, gheight - eexp->y);
660 tocombuf(buf, &x11_driver);
661 } else if (eexp->window == comline->w) {
662 if (eexp->count == 0)
663 xt_redraw(comline);
664 }
665 }
666
667
668 static void
669 resizewindow(ersz) /* resize window */
670 register XConfigureEvent *ersz;
671 {
672 if (ersz->width == gwidth && ersz->height-comheight == gheight)
673 return;
674
675 gwidth = ersz->width;
676 gheight = ersz->height-comheight;
677 x11_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth;
678 x11_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight;
679
680 tocombuf("new\n", &x11_driver);
681 }