7aa14a5e8b3bccf99f33f64280b289f23dbed9f9
[framework/uifw/xorg/lib/libxaw.git] / src / Box.c
1 /***********************************************************
2
3 Copyright 1987, 1988, 1994, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24
25
26 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28                         All Rights Reserved
29
30 Permission to use, copy, modify, and distribute this software and its 
31 documentation for any purpose and without fee is hereby granted, 
32 provided that the above copyright notice appear in all copies and that
33 both that copyright notice and this permission notice appear in 
34 supporting documentation, and that the name of Digital not be
35 used in advertising or publicity pertaining to distribution of the
36 software without specific, written prior permission.  
37
38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44 SOFTWARE.
45
46 ******************************************************************/
47
48 #ifdef HAVE_CONFIG_H
49 #include <config.h>
50 #endif
51 #include <X11/IntrinsicP.h>
52 #include <X11/StringDefs.h>
53 #include <X11/Xmu/Misc.h>
54 #include <X11/Xaw/BoxP.h>
55 #include <X11/Xaw/XawInit.h>
56 #include "Private.h"
57
58 /*
59  * Class Methods
60  */
61 static void XawBoxChangeManaged(Widget);
62 static void XawBoxClassInitialize(void);
63 #ifndef OLDXAW
64 static void XawBoxExpose(Widget, XEvent*, Region);
65 #endif
66 static XtGeometryResult XawBoxGeometryManager(Widget, XtWidgetGeometry*,
67                                               XtWidgetGeometry*);
68 static void XawBoxInitialize(Widget, Widget, ArgList, Cardinal*);
69 static XtGeometryResult XawBoxQueryGeometry(Widget, XtWidgetGeometry*,
70                                             XtWidgetGeometry*);
71 static void XawBoxRealize(Widget, Mask*, XSetWindowAttributes*);
72 static void XawBoxResize(Widget);
73 static Boolean XawBoxSetValues(Widget, Widget, Widget,
74                                ArgList, Cardinal*);
75
76 /*
77  * Prototypes
78  */
79 static void DoLayout(BoxWidget, unsigned int, unsigned int,
80                      Dimension*, Dimension*, Bool);
81 static Bool TryNewLayout(BoxWidget);
82
83 /*
84  * Initialization
85  */
86 #ifndef OLDXAW
87 static XtActionsRec actions[] = {
88   {"set-values", XawSetValuesAction},
89   {"get-values", XawGetValuesAction},
90   {"declare",    XawDeclareAction},
91   {"call-proc",  XawCallProcAction},
92 };
93 #endif
94
95 static XtResource resources[] = {
96   {
97     XtNhSpace,
98     XtCHSpace,
99     XtRDimension,
100     sizeof(Dimension),
101     XtOffsetOf(BoxRec, box.h_space),
102     XtRImmediate,
103     (XtPointer)4
104   },
105   {
106     XtNvSpace,
107     XtCVSpace,
108     XtRDimension,
109     sizeof(Dimension),
110     XtOffsetOf(BoxRec, box.v_space),
111     XtRImmediate,
112     (XtPointer)4
113   },
114   {
115     XtNorientation,
116     XtCOrientation,
117     XtROrientation,
118     sizeof(XtOrientation),
119     XtOffsetOf(BoxRec, box.orientation),
120     XtRImmediate,
121     (XtPointer)XtorientVertical
122   },
123 #ifndef OLDXAW
124   {
125     XawNdisplayList,
126     XawCDisplayList,
127     XawRDisplayList,
128     sizeof(XawDisplayList*),
129     XtOffsetOf(BoxRec, box.display_list),
130     XtRImmediate,
131     NULL
132   },
133 #endif
134 };
135
136 BoxClassRec boxClassRec = {
137   /* core */
138   {
139     (WidgetClass)&compositeClassRec,    /* superclass */
140     "Box",                              /* class_name */
141     sizeof(BoxRec),                     /* widget_size */
142     XawBoxClassInitialize,              /* class_initialize */
143     NULL,                               /* class_part_init */
144     False,                              /* class_inited */
145     XawBoxInitialize,                   /* initialize */
146     NULL,                               /* initialize_hook */
147     XawBoxRealize,                      /* realize */
148 #ifndef OLDXAW
149     actions,                            /* actions */
150     XtNumber(actions),                  /* num_actions */
151 #else
152     NULL,                               /* actions */
153     0,                                  /* num_actions */
154 #endif
155     resources,                          /* resources */
156     XtNumber(resources),                /* num_resources */
157     NULLQUARK,                          /* xrm_class */
158     True,                               /* compress_motion */
159     True,                               /* compress_exposure */
160     True,                               /* compress_enterleave */
161     False,                              /* visible_interest */
162     NULL,                               /* destroy */
163     XawBoxResize,                       /* resize */
164 #ifndef OLDXAW
165     XawBoxExpose,                       /* expose */
166 #else
167     NULL,                               /* expose */
168 #endif
169     XawBoxSetValues,                    /* set_values */
170     NULL,                               /* set_values_hook */
171     XtInheritSetValuesAlmost,           /* set_values_almost */
172     NULL,                               /* get_values_hook */
173     NULL,                               /* accept_focus */
174     XtVersion,                          /* version */
175     NULL,                               /* callback_private */
176     NULL,                               /* tm_table */
177     XawBoxQueryGeometry,                /* query_geometry */
178     XtInheritDisplayAccelerator,        /* display_accelerator */
179     NULL,                               /* extension */
180   },
181   /* composite */
182   {
183     XawBoxGeometryManager,              /* geometry_manager */
184     XawBoxChangeManaged,                /* change_managed */
185     XtInheritInsertChild,               /* insert_child */
186     XtInheritDeleteChild,               /* delete_child */
187     NULL,                               /* extension */
188   },
189   /* box */
190   {
191     NULL,                               /* extension */
192   },
193 };
194
195 WidgetClass boxWidgetClass = (WidgetClass)&boxClassRec;
196
197 /*
198  * Do a layout, either actually assigning positions, or just calculating size.
199  * Returns minimum width and height that will preserve the same layout.
200  */
201 static void
202 DoLayout(BoxWidget bbw, unsigned int width, unsigned int height,
203          Dimension *reply_width, Dimension *reply_height, Bool position)
204 {
205     Boolean vbox = (bbw->box.orientation == XtorientVertical);
206     Cardinal  i;
207     Dimension w, h;     /* Width and height needed for box              */
208     Dimension lw, lh;   /* Width and height needed for current line     */
209     Dimension bw, bh;   /* Width and height needed for current widget   */
210     Dimension h_space;  /* Local copy of bbw->box.h_space               */
211     Widget widget;      /* Current widget                               */
212     unsigned int num_mapped_children = 0;
213  
214     /* Box width and height */
215     h_space = bbw->box.h_space;
216
217     w = 0;
218     for (i = 0; i < bbw->composite.num_children; i++) {
219         if (XtIsManaged(bbw->composite.children[i])
220             && bbw->composite.children[i]->core.width > w)
221             w = bbw->composite.children[i]->core.width;
222     }
223     w += h_space;
224     if (w > width)
225         width = w;
226     h = bbw->box.v_space;
227    
228     /* Line width and height */
229     lh = 0;
230     lw = h_space;
231   
232     for (i = 0; i < bbw->composite.num_children; i++) {
233         widget = bbw->composite.children[i];
234         if (widget->core.managed) {
235             if (widget->core.mapped_when_managed)
236                 num_mapped_children++;
237             /* Compute widget width */
238             bw = XtWidth(widget) + (XtBorderWidth(widget)<<1) + h_space;
239             if ((Dimension)(lw + bw) > width) {
240                 if (lw > h_space) {
241                     /* At least one widget on this line, and
242                      * can't fit any more.  Start new line if vbox
243                      */
244                     AssignMax(w, lw);
245                     if (vbox) {
246                         h += lh + bbw->box.v_space;
247                         lh = 0;
248                         lw = h_space;
249                     }
250                 }
251                 else if (!position) {
252                     /* too narrow for this widget; we'll assume we can grow */
253                     DoLayout(bbw, (unsigned)(lw + bw), height, reply_width,
254                              reply_height, position);
255                     return;
256                 }
257             }
258             if (position && (lw != XtX(widget) || h != XtY(widget))) {
259                 /* It would be nice to use window gravity, but there isn't
260                  * sufficient fine-grain control to nicely handle all
261                  * situations (e.g. when only the height changes --
262                  * a common case).  Explicit unmapping is a cheap hack
263                  * to speed things up & avoid the visual jitter as
264                  * things slide around.
265                  *
266                  * %%% perhaps there should be a client resource to
267                  * control this.  If so, we'll have to optimize to
268                  * perform the moves from the correct end so we don't
269                  * force extra exposures as children occlude each other.
270                  */
271                 if (XtIsRealized(widget) && widget->core.mapped_when_managed)
272                 XUnmapWindow( XtDisplay(widget), XtWindow(widget));
273                 XtMoveWidget(widget, (int)lw, (int)h);
274             }
275             lw += bw;
276             bh = XtHeight(widget) + (XtBorderWidth(widget) << 1);
277             AssignMax(lh, bh);
278         }
279     }
280
281     if (!vbox && width && lw > width && lh < height) {
282         /* reduce width if too wide and height not filled */
283         Dimension sw = lw, sh = lh;
284         Dimension width_needed = width;
285         XtOrientation orientation = bbw->box.orientation;
286
287         bbw->box.orientation = XtorientVertical;
288         while (sh < height && sw > width) {
289             width_needed = sw;
290             DoLayout(bbw, (unsigned)(sw-1), height, &sw, &sh, False);
291         }
292         if (sh < height)
293           width_needed = sw;
294         if (width_needed != lw) {
295             DoLayout(bbw, width_needed, height,
296                      reply_width, reply_height, position);
297             bbw->box.orientation = orientation;
298             return;
299         }
300         bbw->box.orientation = orientation;
301     }
302     if (vbox && (width < w || width < lw)) {
303         AssignMax(w, lw);
304         DoLayout(bbw, w, height, reply_width, reply_height, position);
305         return;
306     }
307      if (position && XtIsRealized((Widget)bbw)) {
308         if (bbw->composite.num_children == num_mapped_children)
309             XMapSubwindows(XtDisplay((Widget)bbw), XtWindow((Widget)bbw));
310         else {
311             int ii = bbw->composite.num_children;
312             Widget *childP = bbw->composite.children;
313
314             for (; ii > 0; childP++, ii--)
315                 if (XtIsRealized(*childP) && XtIsManaged(*childP)
316                     && (*childP)->core.mapped_when_managed)
317                     XtMapWidget(*childP);
318         }
319     }
320
321     /* Finish off last line */
322     if (lw > h_space) {
323         AssignMax(w, lw);
324         h += lh + bbw->box.v_space;
325     }
326
327     *reply_width = Max(w, 1);
328     *reply_height = Max(h, 1);
329 }
330
331 /*
332  * Calculate preferred size, given constraining box, caching it in the widget
333  */
334 static XtGeometryResult
335 XawBoxQueryGeometry(Widget widget, XtWidgetGeometry *constraint,
336                     XtWidgetGeometry *preferred)
337 {
338     BoxWidget w = (BoxWidget)widget;
339     Dimension width;
340     Dimension preferred_width = w->box.preferred_width;
341     Dimension preferred_height = w->box.preferred_height;
342
343     constraint->request_mode &= CWWidth | CWHeight;
344
345     if (constraint->request_mode == 0)
346         /* parent isn't going to change w or h, so nothing to re-compute */
347     return (XtGeometryYes);
348
349     if (constraint->request_mode == w->box.last_query_mode
350         && (!(constraint->request_mode & CWWidth)
351           || constraint->width == w->box.last_query_width)
352         && (!(constraint->request_mode & CWHeight)
353           || constraint->height == w->box.last_query_height)) {
354         /* same query; current preferences are still valid */
355         preferred->request_mode = CWWidth | CWHeight;
356         preferred->width = preferred_width;
357         preferred->height = preferred_height;
358         if (constraint->request_mode == (CWWidth | CWHeight)
359             && constraint->width == preferred_width
360             && constraint->height == preferred_height)
361             return (XtGeometryYes);
362         else
363             return (XtGeometryAlmost);
364     }
365         
366     /* else gotta do it the long way...
367        I have a preference for tall and narrow, so if my width is
368        constrained, I'll accept it; otherwise, I'll compute the minimum
369        width that will fit me within the height constraint */
370
371     w->box.last_query_mode = constraint->request_mode;
372     w->box.last_query_width = constraint->width;
373     w->box.last_query_height= constraint->height;
374
375     if (constraint->request_mode & CWWidth)
376         width = constraint->width;
377     else { /* if (constraint->request_mode & CWHeight) */
378            /* let's see if I can become any narrower */
379         width = 0;
380         constraint->width = 65535;
381     }
382
383     /* height is currently ignored by DoLayout.
384        height = (constraint->request_mode & CWHeight) ? constraint->height
385                        : *preferred_height;
386      */
387     DoLayout(w, width, 0, &preferred_width, &preferred_height, False);
388
389     if (constraint->request_mode & CWHeight
390         && preferred_height > constraint->height) {
391         /* find minimum width for this height */
392         if (preferred_width <= constraint->width) {
393             width = preferred_width;
394             do { /* find some width big enough to stay within this height */
395                 width <<= 1;
396                 if (width > constraint->width)
397                     width = constraint->width;
398                 DoLayout(w, width, 0, &preferred_width, &preferred_height, False);
399             } while (preferred_height > constraint->height
400                      && width < constraint->width);
401             if (width != constraint->width) {
402                 do { /* find minimum width */
403                     width = preferred_width;
404                     DoLayout(w, (unsigned)(preferred_width - 1), 0,
405                              &preferred_width, &preferred_height, False);
406                 } while (preferred_height < constraint->height);
407                 /* one last time */
408                 DoLayout(w, width, 0, &preferred_width, &preferred_height, False);
409             }
410         }
411     }
412
413     preferred->request_mode = CWWidth | CWHeight;
414     preferred->width = w->box.preferred_width = preferred_width;
415     preferred->height = w->box.preferred_height = preferred_height;
416
417     if (constraint->request_mode == (CWWidth|CWHeight)
418         && constraint->width == preferred_width
419         && constraint->height == preferred_height)
420         return (XtGeometryYes);
421
422     return (XtGeometryAlmost);
423 }
424
425 /*
426  * Actually layout the box
427  */
428 static void
429 XawBoxResize(Widget w)
430 {
431     Dimension tmp;
432
433     DoLayout((BoxWidget)w, XtWidth(w), XtHeight(w), &tmp, &tmp, True);
434 }
435
436 /*
437  * Try to do a new layout within the current width and height;
438  * if that fails try to resize and do it within the box returne
439  * by XawBoxQueryGeometry
440  *
441  * TryNewLayout just says if it's possible, and doesn't actually move the kids
442  */
443 static Bool
444 TryNewLayout(BoxWidget bbw)
445 {
446     Dimension   preferred_width, preferred_height;
447     Dimension   proposed_width, proposed_height;
448     int         iterations;
449
450     DoLayout(bbw, bbw->core.width, bbw->core.height,
451              &preferred_width, &preferred_height, False);
452
453     /* at this point, preferred_width is guaranteed to not be greater
454        than bbw->core.width unless some child is larger, so there's no
455        point in re-computing another layout */
456
457     if (XtWidth(bbw) == preferred_width && XtHeight(bbw) == preferred_height)
458         return (True);
459
460     /* let's see if our parent will go for a new size */
461     iterations = 0;
462     proposed_width = preferred_width;
463     proposed_height = preferred_height;
464     do {
465         switch (XtMakeResizeRequest((Widget)bbw,proposed_width,proposed_height,
466                                      &proposed_width, &proposed_height)) {
467             case XtGeometryYes:
468                 return (True);
469             case XtGeometryNo:
470                 if (iterations > 0)
471                     /* protect from malicious parents who change their minds */
472                     DoLayout(bbw, bbw->core.width, bbw->core.height,
473                              &preferred_width, &preferred_height, False);
474                 if (preferred_width <= XtWidth(bbw)
475                     && preferred_height <= XtHeight(bbw))
476                     return (True);
477                 else
478                     return (False);
479             case XtGeometryAlmost:
480                 if (proposed_height >= preferred_height &&
481                     proposed_width >= preferred_width) {
482                     /*
483                      * Take it, and assume the parent knows what it is doing.
484                      *
485                      * The parent must accept this since it was returned in
486                      * almost.
487                      */
488                     (void)XtMakeResizeRequest((Widget)bbw,
489                                                proposed_width, proposed_height,
490                                                &proposed_width, &proposed_height);
491                     return (True);
492                 }
493                 else if (proposed_width != preferred_width) {
494                     /* recalc bounding box; height might change */
495                     DoLayout(bbw, proposed_width, 0,
496                              &preferred_width, &preferred_height, False);
497                     proposed_height = preferred_height;
498                 }
499                 else {  /* proposed_height != preferred_height */
500                     XtWidgetGeometry constraints, reply;
501
502                     constraints.request_mode = CWHeight;
503                     constraints.height = proposed_height;
504                     (void)XawBoxQueryGeometry((Widget)bbw, &constraints, &reply);
505                     proposed_width = preferred_width;
506                 }
507                 /*FALLTHROUGH*/
508             default:
509                 break;
510         }
511         iterations++;
512     } while (iterations < 10);
513
514     return (False);
515 }
516
517 /*
518  * Geometry Manager
519  *
520  * 'reply' is unused; we say only yeay or nay, never almost.
521  */
522 /*ARGSUSED*/
523 static XtGeometryResult
524 XawBoxGeometryManager(Widget w, XtWidgetGeometry *request,
525                       XtWidgetGeometry *reply)
526 {
527     Dimension   width, height, borderWidth;
528     BoxWidget bbw;
529
530     /* Position request always denied */
531     if (((request->request_mode & CWX) && request->x != XtX(w))
532         || ((request->request_mode & CWY) && request->y != XtY(w)))
533         return (XtGeometryNo);
534
535     /* Size changes must see if the new size can be accomodated */
536     if (request->request_mode & (CWWidth | CWHeight | CWBorderWidth)) {
537         /* Make all three fields in the request valid */
538         if ((request->request_mode & CWWidth) == 0)
539             request->width = XtWidth(w);
540         if ((request->request_mode & CWHeight) == 0)
541             request->height = XtHeight(w);
542         if ((request->request_mode & CWBorderWidth) == 0)
543             request->border_width = XtBorderWidth(w);
544
545         /* Save current size and set to new size */
546       width = XtWidth(w);
547       height = XtHeight(w);
548       borderWidth = XtBorderWidth(w);
549       XtWidth(w) = request->width;
550       XtHeight(w) = request->height;
551       XtBorderWidth(w) = request->border_width;
552
553       /* Decide if new layout works:
554          (1) new widget is smaller,
555          (2) new widget fits in existing Box,
556          (3) Box can be expanded to allow new widget to fit
557       */
558
559         bbw = (BoxWidget) w->core.parent;
560
561         if (TryNewLayout(bbw)) {
562             /* Fits in existing or new space, relayout */
563             (*XtClass((Widget)bbw)->core_class.resize)((Widget)bbw);
564             return (XtGeometryYes);
565         }
566         else {
567             /* Cannot satisfy request, change back to original geometry */
568             XtWidth(w) = width;
569             XtHeight(w) = height;
570             XtBorderWidth(w) = borderWidth;
571             return (XtGeometryNo);
572         }
573     }
574
575     /* Any stacking changes don't make a difference, so allow if that's all */
576     return (XtGeometryYes);
577 }
578
579 static void
580 XawBoxChangeManaged(Widget w)
581 {
582     /* Reconfigure the box */
583     (void)TryNewLayout((BoxWidget)w);
584     XawBoxResize(w);
585 }
586
587 static void
588 XawBoxClassInitialize(void)
589 {
590     XawInitializeWidgetSet();
591     XtAddConverter(XtRString, XtROrientation, XmuCvtStringToOrientation,
592                    NULL, 0);
593     XtSetTypeConverter(XtROrientation, XtRString, XmuCvtOrientationToString,
594                        NULL, 0, XtCacheNone, NULL);
595 }
596
597 /*ARGSUSED*/
598 static void
599 XawBoxInitialize(Widget request, Widget cnew,
600                  ArgList args, Cardinal *num_args)
601 {
602     BoxWidget newbbw = (BoxWidget)cnew;
603
604     newbbw->box.last_query_mode = CWWidth | CWHeight;
605     newbbw->box.last_query_width = newbbw->box.last_query_height = 0;
606     newbbw->box.preferred_width = Max(newbbw->box.h_space, 1);
607     newbbw->box.preferred_height = Max(newbbw->box.v_space, 1);
608
609     if (XtWidth(newbbw) == 0)
610         XtWidth(newbbw) = newbbw->box.preferred_width;
611
612     if (XtHeight(newbbw) == 0)
613         XtHeight(newbbw) = newbbw->box.preferred_height;
614 }
615
616 static void
617 XawBoxRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
618 {
619 #ifndef OLDXAW
620     XawPixmap *pixmap;
621 #endif
622
623     XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent,
624                    *valueMask, attributes);
625
626 #ifndef OLDXAW
627     if (w->core.background_pixmap > XtUnspecifiedPixmap) {
628         pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w),
629                                       w->core.colormap, w->core.depth);
630         if (pixmap && pixmap->mask)
631             XawReshapeWidget(w, pixmap);
632     }
633 #endif
634 }
635
636 /*ARGSUSED*/
637 static Boolean
638 XawBoxSetValues(Widget current, Widget request, Widget cnew,
639                 ArgList args, Cardinal *num_args)
640 {
641      /* need to relayout if h_space or v_space change */
642 #ifndef OLDXAW
643     BoxWidget b_old = (BoxWidget)current;
644     BoxWidget b_new = (BoxWidget)cnew;
645
646     if (b_old->core.background_pixmap != b_new->core.background_pixmap) {
647         XawPixmap *opix, *npix;
648
649         opix = XawPixmapFromXPixmap(b_old->core.background_pixmap,
650                                     XtScreen(b_old), b_old->core.colormap,
651                                     b_old->core.depth);
652         npix = XawPixmapFromXPixmap(b_new->core.background_pixmap,
653                                     XtScreen(b_new), b_new->core.colormap,
654                                     b_new->core.depth);
655         if ((npix && npix->mask) || (opix && opix->mask))
656             XawReshapeWidget(cnew, npix);
657     }
658 #endif /* OLDXAW */
659
660   return (False);
661 }
662
663 #ifndef OLDXAW
664 static void
665 XawBoxExpose(Widget w, XEvent *event, Region region)
666 {
667     BoxWidget xaw = (BoxWidget)w;
668
669     if (xaw->box.display_list)
670         XawRunDisplayList(w, xaw->box.display_list, event, region);
671 }
672 #endif /* OLDXAW */