1/***********************************************************
2
3Copyright 1987, 1988, 1994, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25
26Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28                        All Rights Reserved
29
30Permission to use, copy, modify, and distribute this software and its
31documentation for any purpose and without fee is hereby granted,
32provided that the above copyright notice appear in all copies and that
33both that copyright notice and this permission notice appear in
34supporting documentation, and that the name of Digital not be
35used in advertising or publicity pertaining to distribution of the
36software without specific, written prior permission.
37
38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44SOFTWARE.
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 */
61static void XawBoxChangeManaged(Widget);
62static void XawBoxClassInitialize(void);
63#ifndef OLDXAW
64static void XawBoxExpose(Widget, XEvent*, Region);
65#endif
66static XtGeometryResult XawBoxGeometryManager(Widget, XtWidgetGeometry*,
67					      XtWidgetGeometry*);
68static void XawBoxInitialize(Widget, Widget, ArgList, Cardinal*);
69static XtGeometryResult XawBoxQueryGeometry(Widget, XtWidgetGeometry*,
70					    XtWidgetGeometry*);
71static void XawBoxRealize(Widget, Mask*, XSetWindowAttributes*);
72static void XawBoxResize(Widget);
73static Boolean XawBoxSetValues(Widget, Widget, Widget,
74			       ArgList, Cardinal*);
75
76/*
77 * Prototypes
78 */
79static void DoLayout(BoxWidget, unsigned int, unsigned int,
80		     Dimension*, Dimension*, Bool);
81static Bool TryNewLayout(BoxWidget);
82
83/*
84 * Initialization
85 */
86#ifndef OLDXAW
87static XtActionsRec actions[] = {
88  {"set-values", XawSetValuesAction},
89  {"get-values", XawGetValuesAction},
90  {"declare",    XawDeclareAction},
91  {"call-proc",  XawCallProcAction},
92};
93#endif
94
95static 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
136BoxClassRec 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
195WidgetClass 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 */
201static void
202DoLayout(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    unsigned int num_mapped_children = 0;
212
213    /* Box width and height */
214    h_space = bbw->box.h_space;
215
216    w = 0;
217    for (i = 0; i < bbw->composite.num_children; i++) {
218	if (XtIsManaged(bbw->composite.children[i])
219	    && bbw->composite.children[i]->core.width > w)
220	    w = bbw->composite.children[i]->core.width;
221    }
222    w = (Dimension)(w + h_space);
223    if (w > width)
224	width = w;
225    h = bbw->box.v_space;
226
227    /* Line width and height */
228    lh = 0;
229    lw = h_space;
230
231    for (i = 0; i < bbw->composite.num_children; i++) {
232	Widget widget = bbw->composite.children[i]; /* Current widget */
233	if (widget->core.managed) {
234	    if (widget->core.mapped_when_managed)
235		num_mapped_children++;
236	    /* Compute widget width */
237	    bw = (Dimension)(XtWidth(widget) + (XtBorderWidth(widget)<<1) + h_space);
238	    if ((Dimension)(lw + bw) > width) {
239		if (lw > h_space) {
240		    /* At least one widget on this line, and
241		     * can't fit any more.  Start new line if vbox
242		     */
243		    AssignMax(w, lw);
244		    if (vbox) {
245			h = (Dimension)(h + (lh + bbw->box.v_space));
246			lh = 0;
247			lw = h_space;
248		    }
249		}
250		else if (!position) {
251		    /* too narrow for this widget; we'll assume we can grow */
252		    DoLayout(bbw, (unsigned)(lw + bw), height, reply_width,
253			     reply_height, position);
254		    return;
255		}
256	    }
257	    if (position && (lw != XtX(widget) || h != XtY(widget))) {
258		/* It would be nice to use window gravity, but there isn't
259		 * sufficient fine-grain control to nicely handle all
260		 * situations (e.g. when only the height changes --
261		 * a common case).  Explicit unmapping is a cheap hack
262		 * to speed things up & avoid the visual jitter as
263		 * things slide around.
264		 *
265		 * %%% perhaps there should be a client resource to
266		 * control this.  If so, we'll have to optimize to
267		 * perform the moves from the correct end so we don't
268		 * force extra exposures as children occlude each other.
269		 */
270		if (XtIsRealized(widget) && widget->core.mapped_when_managed)
271		XUnmapWindow( XtDisplay(widget), XtWindow(widget));
272		XtMoveWidget(widget, (Position)lw, (Position)h);
273	    }
274	    lw = (Dimension)(lw + bw);
275	    bh = (Dimension)(XtHeight(widget) + (XtBorderWidth(widget) << 1));
276	    AssignMax(lh, bh);
277	}
278    }
279
280    if (!vbox && width && lw > width && lh < height) {
281	/* reduce width if too wide and height not filled */
282	Dimension sw = lw, sh = lh;
283	Dimension width_needed = (Dimension)width;
284	XtOrientation orientation = bbw->box.orientation;
285
286	bbw->box.orientation = XtorientVertical;
287	while (sh < height && sw > width) {
288	    width_needed = sw;
289	    DoLayout(bbw, (unsigned)(sw-1), height, &sw, &sh, False);
290	}
291	if (sh < height)
292	  width_needed = sw;
293	if (width_needed != lw) {
294	    DoLayout(bbw, width_needed, height,
295		     reply_width, reply_height, position);
296	    bbw->box.orientation = orientation;
297	    return;
298	}
299	bbw->box.orientation = orientation;
300    }
301    if (vbox && (width < w || width < lw)) {
302	AssignMax(w, lw);
303	DoLayout(bbw, w, height, reply_width, reply_height, position);
304	return;
305    }
306     if (position && XtIsRealized((Widget)bbw)) {
307	if (bbw->composite.num_children == num_mapped_children)
308	    XMapSubwindows(XtDisplay((Widget)bbw), XtWindow((Widget)bbw));
309	else {
310	    int ii = (int)bbw->composite.num_children;
311	    Widget *childP = bbw->composite.children;
312
313	    for (; ii > 0; childP++, ii--)
314		if (XtIsRealized(*childP) && XtIsManaged(*childP)
315		    && (*childP)->core.mapped_when_managed)
316		    XtMapWidget(*childP);
317	}
318    }
319
320    /* Finish off last line */
321    if (lw > h_space) {
322	AssignMax(w, lw);
323        h = (Dimension)(h + (lh + bbw->box.v_space));
324    }
325
326    *reply_width = Max(w, 1);
327    *reply_height = Max(h, 1);
328}
329
330/*
331 * Calculate preferred size, given constraining box, caching it in the widget
332 */
333static XtGeometryResult
334XawBoxQueryGeometry(Widget widget, XtWidgetGeometry *constraint,
335		    XtWidgetGeometry *preferred)
336{
337    BoxWidget w = (BoxWidget)widget;
338    Dimension width;
339    Dimension preferred_width = w->box.preferred_width;
340    Dimension preferred_height = w->box.preferred_height;
341
342    constraint->request_mode &= CWWidth | CWHeight;
343
344    if (constraint->request_mode == 0)
345	/* parent isn't going to change w or h, so nothing to re-compute */
346    return (XtGeometryYes);
347
348    if (constraint->request_mode == w->box.last_query_mode
349	&& (!(constraint->request_mode & CWWidth)
350	  || constraint->width == w->box.last_query_width)
351	&& (!(constraint->request_mode & CWHeight)
352	  || constraint->height == w->box.last_query_height)) {
353	/* same query; current preferences are still valid */
354	preferred->request_mode = CWWidth | CWHeight;
355	preferred->width = preferred_width;
356	preferred->height = preferred_height;
357	if (constraint->request_mode == (CWWidth | CWHeight)
358	    && constraint->width == preferred_width
359	    && constraint->height == preferred_height)
360	    return (XtGeometryYes);
361	else
362	    return (XtGeometryAlmost);
363    }
364
365    /* else gotta do it the long way...
366       I have a preference for tall and narrow, so if my width is
367       constrained, I'll accept it; otherwise, I'll compute the minimum
368       width that will fit me within the height constraint */
369
370    w->box.last_query_mode = constraint->request_mode;
371    w->box.last_query_width = constraint->width;
372    w->box.last_query_height= constraint->height;
373
374    if (constraint->request_mode & CWWidth)
375	width = constraint->width;
376    else { /* if (constraint->request_mode & CWHeight) */
377	   /* let's see if I can become any narrower */
378	width = 0;
379	constraint->width = 65535;
380    }
381
382    /* height is currently ignored by DoLayout.
383       height = (constraint->request_mode & CWHeight) ? constraint->height
384		       : *preferred_height;
385     */
386    DoLayout(w, width, 0, &preferred_width, &preferred_height, False);
387
388    if (constraint->request_mode & CWHeight
389	&& preferred_height > constraint->height) {
390	/* find minimum width for this height */
391	if (preferred_width <= constraint->width) {
392	    width = preferred_width;
393	    do { /* find some width big enough to stay within this height */
394		if (width > (constraint->width >> 1)) /* avoid short int overflow */
395		    width = constraint->width;
396		else
397		    width = (Dimension)(width << 1);
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 */
428static void
429XawBoxResize(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 returned
439 * by XawBoxQueryGeometry
440 *
441 * TryNewLayout just says if it's possible, and doesn't actually move the kids
442 */
443static Bool
444TryNewLayout(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 = {
501                        .request_mode = CWHeight,
502                        .height = proposed_height
503                    };
504                    XtWidgetGeometry reply;
505
506		    (void)XawBoxQueryGeometry((Widget)bbw, &constraints, &reply);
507		    proposed_width = preferred_width;
508		}
509		/*FALLTHROUGH*/
510	    default:
511		break;
512	}
513	iterations++;
514    } while (iterations < 10);
515
516    return (False);
517}
518
519/*
520 * Geometry Manager
521 *
522 * 'reply' is unused; we say only yeay or nay, never almost.
523 */
524/*ARGSUSED*/
525static XtGeometryResult
526XawBoxGeometryManager(Widget w, XtWidgetGeometry *request,
527		      XtWidgetGeometry *reply _X_UNUSED)
528{
529    /* Position request always denied */
530    if (((request->request_mode & CWX) && request->x != XtX(w))
531	|| ((request->request_mode & CWY) && request->y != XtY(w)))
532        return (XtGeometryNo);
533
534    /* Size changes must see if the new size can be accommodated */
535    if (request->request_mode & (CWWidth | CWHeight | CWBorderWidth)) {
536	Dimension width, height, borderWidth;
537	BoxWidget bbw;
538
539	/* Make all three fields in the request valid */
540	if ((request->request_mode & CWWidth) == 0)
541	    request->width = XtWidth(w);
542	if ((request->request_mode & CWHeight) == 0)
543	    request->height = XtHeight(w);
544        if ((request->request_mode & CWBorderWidth) == 0)
545	    request->border_width = XtBorderWidth(w);
546
547	/* Save current size and set to new size */
548	width = XtWidth(w);
549	height = XtHeight(w);
550	borderWidth = XtBorderWidth(w);
551	XtWidth(w) = request->width;
552	XtHeight(w) = request->height;
553	XtBorderWidth(w) = request->border_width;
554
555      /* Decide if new layout works:
556	 (1) new widget is smaller,
557	 (2) new widget fits in existing Box,
558	 (3) Box can be expanded to allow new widget to fit
559      */
560
561	bbw = (BoxWidget) w->core.parent;
562
563	if (TryNewLayout(bbw)) {
564	    /* Fits in existing or new space, relayout */
565	    (*XtClass((Widget)bbw)->core_class.resize)((Widget)bbw);
566	    return (XtGeometryYes);
567	}
568	else {
569	    /* Cannot satisfy request, change back to original geometry */
570	    XtWidth(w) = width;
571	    XtHeight(w) = height;
572	    XtBorderWidth(w) = borderWidth;
573	    return (XtGeometryNo);
574	}
575    }
576
577    /* Any stacking changes don't make a difference, so allow if that's all */
578    return (XtGeometryYes);
579}
580
581static void
582XawBoxChangeManaged(Widget w)
583{
584    /* Reconfigure the box */
585    (void)TryNewLayout((BoxWidget)w);
586    XawBoxResize(w);
587}
588
589static void
590XawBoxClassInitialize(void)
591{
592    XawInitializeWidgetSet();
593    XtAddConverter(XtRString, XtROrientation, XmuCvtStringToOrientation,
594		   NULL, 0);
595    XtSetTypeConverter(XtROrientation, XtRString, XmuCvtOrientationToString,
596		       NULL, 0, XtCacheNone, NULL);
597}
598
599/*ARGSUSED*/
600static void
601XawBoxInitialize(Widget request _X_UNUSED, Widget cnew,
602		 ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
603{
604    BoxWidget newbbw = (BoxWidget)cnew;
605
606    newbbw->box.last_query_mode = CWWidth | CWHeight;
607    newbbw->box.last_query_width = newbbw->box.last_query_height = 0;
608    newbbw->box.preferred_width = Max(newbbw->box.h_space, 1);
609    newbbw->box.preferred_height = Max(newbbw->box.v_space, 1);
610
611    if (XtWidth(newbbw) == 0)
612	XtWidth(newbbw) = newbbw->box.preferred_width;
613
614    if (XtHeight(newbbw) == 0)
615	XtHeight(newbbw) = newbbw->box.preferred_height;
616}
617
618static void
619XawBoxRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
620{
621#ifndef OLDXAW
622    XawPixmap *pixmap;
623#endif
624
625    XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent,
626		   *valueMask, attributes);
627
628#ifndef OLDXAW
629    if (w->core.background_pixmap > XtUnspecifiedPixmap) {
630	pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w),
631				      w->core.colormap, (int)w->core.depth);
632	if (pixmap && pixmap->mask)
633	    XawReshapeWidget(w, pixmap);
634    }
635#endif
636}
637
638/*ARGSUSED*/
639static Boolean
640XawBoxSetValues(Widget current _X_UNUSED, Widget request _X_UNUSED, Widget cnew _X_UNUSED,
641		ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
642{
643     /* need to relayout if h_space or v_space change */
644#ifndef OLDXAW
645    BoxWidget b_old = (BoxWidget)current;
646    BoxWidget b_new = (BoxWidget)cnew;
647
648    if (b_old->core.background_pixmap != b_new->core.background_pixmap) {
649	XawPixmap *opix, *npix;
650
651	opix = XawPixmapFromXPixmap(b_old->core.background_pixmap,
652				    XtScreen(b_old), b_old->core.colormap,
653				    (int)b_old->core.depth);
654	npix = XawPixmapFromXPixmap(b_new->core.background_pixmap,
655				    XtScreen(b_new), b_new->core.colormap,
656				    (int)b_new->core.depth);
657	if ((npix && npix->mask) || (opix && opix->mask))
658	    XawReshapeWidget(cnew, npix);
659    }
660#endif /* OLDXAW */
661
662  return (False);
663}
664
665#ifndef OLDXAW
666static void
667XawBoxExpose(Widget w, XEvent *event, Region region)
668{
669    BoxWidget xaw = (BoxWidget)w;
670
671    if (xaw->box.display_list)
672	XawRunDisplayList(w, xaw->box.display_list, event, region);
673}
674#endif /* OLDXAW */
675