Paned.c revision 5b16253f
17a84e134Smrg/***********************************************************
27a84e134Smrg
37a84e134SmrgCopyright 1987, 1988, 1994, 1998  The Open Group
47a84e134Smrg
57a84e134SmrgPermission to use, copy, modify, distribute, and sell this software and its
67a84e134Smrgdocumentation for any purpose is hereby granted without fee, provided that
77a84e134Smrgthe above copyright notice appear in all copies and that both that
87a84e134Smrgcopyright notice and this permission notice appear in supporting
97a84e134Smrgdocumentation.
107a84e134Smrg
117a84e134SmrgThe above copyright notice and this permission notice shall be included in
127a84e134Smrgall copies or substantial portions of the Software.
137a84e134Smrg
147a84e134SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
157a84e134SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
167a84e134SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
177a84e134SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
187a84e134SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
197a84e134SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
207a84e134Smrg
217a84e134SmrgExcept as contained in this notice, the name of The Open Group shall not be
227a84e134Smrgused in advertising or otherwise to promote the sale, use or other dealings
237a84e134Smrgin this Software without prior written authorization from The Open Group.
247a84e134Smrg
257a84e134Smrg
267a84e134SmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
277a84e134Smrg
287a84e134Smrg                        All Rights Reserved
297a84e134Smrg
30421c997bSmrgPermission to use, copy, modify, and distribute this software and its
31421c997bSmrgdocumentation for any purpose and without fee is hereby granted,
327a84e134Smrgprovided that the above copyright notice appear in all copies and that
33421c997bSmrgboth that copyright notice and this permission notice appear in
347a84e134Smrgsupporting documentation, and that the name of Digital not be
357a84e134Smrgused in advertising or publicity pertaining to distribution of the
36421c997bSmrgsoftware without specific, written prior permission.
377a84e134Smrg
387a84e134SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
397a84e134SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
407a84e134SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
417a84e134SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
427a84e134SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
437a84e134SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
447a84e134SmrgSOFTWARE.
457a84e134Smrg
467a84e134Smrg******************************************************************/
477a84e134Smrg
487a84e134Smrg/*
497a84e134Smrg * Updated and significantly modified from the Athena VPaned Widget.
507a84e134Smrg *
517a84e134Smrg * Date:    March 1, 1989
527a84e134Smrg *
537a84e134Smrg * By:      Chris D. Peterson
547a84e134Smrg *          MIT X Consortium
557a84e134Smrg *          kit@expo.lcs.mit.edu
567a84e134Smrg */
577a84e134Smrg
587a84e134Smrg#ifdef HAVE_CONFIG_H
597a84e134Smrg#include <config.h>
607a84e134Smrg#endif
617a84e134Smrg#include <X11/IntrinsicP.h>
627a84e134Smrg#include <X11/cursorfont.h>
637a84e134Smrg#include <X11/StringDefs.h>
647a84e134Smrg#include <X11/Xmu/CharSet.h>
657a84e134Smrg#include <X11/Xmu/Converters.h>
667a84e134Smrg#include <X11/Xmu/Misc.h>
677a84e134Smrg#include <X11/Xaw/Grip.h>
687a84e134Smrg#include <X11/Xaw/PanedP.h>
69421c997bSmrg#include <X11/Xaw/XawImP.h>
707a84e134Smrg#include <X11/Xaw/XawInit.h>
717a84e134Smrg#include "Private.h"
727a84e134Smrg
737a84e134Smrgtypedef enum {
747a84e134Smrg  UpLeftPane = 'U',
757a84e134Smrg  LowRightPane = 'L',
767a84e134Smrg  ThisBorderOnly = 'T',
777a84e134Smrg  AnyPane = 'A'
787a84e134Smrg} Direction;
797a84e134Smrg
807a84e134Smrg#define NO_INDEX -100
817a84e134Smrg#define IS_GRIP  NULL
827a84e134Smrg
837a84e134Smrg#define PaneInfo(w)	((Pane)(w)->core.constraints)
847a84e134Smrg#define HasGrip(w)	(PaneInfo(w)->grip != NULL)
857a84e134Smrg#define IsPane(w)	((w)->core.widget_class != gripWidgetClass)
867a84e134Smrg#define PaneIndex(w)	(PaneInfo(w)->position)
877a84e134Smrg#define IsVert(w)	((w)->paned.orientation == XtorientVertical)
887a84e134Smrg
897a84e134Smrg#define ForAllPanes(pw, childP) \
907a84e134Smrgfor ((childP) = (pw)->composite.children;				\
917a84e134Smrg     (childP) < (pw)->composite.children + (pw)->paned.num_panes;	\
927a84e134Smrg     (childP)++)
937a84e134Smrg
947a84e134Smrg#define ForAllChildren(pw, childP) \
957a84e134Smrgfor ((childP) = (pw)->composite.children;				 \
967a84e134Smrg     (childP) < (pw)->composite.children + (pw)->composite.num_children; \
977a84e134Smrg     (childP)++)
987a84e134Smrg
997a84e134Smrg#define PaneSize(paned, vertical)			\
1007a84e134Smrg     ((vertical) ? XtHeight(paned) : XtWidth(paned))
1017a84e134Smrg
1027a84e134Smrg#define GetRequestInfo(geo, vertical)			\
1037a84e134Smrg     ((vertical) ? (geo)->height : (geo)->width)
1047a84e134Smrg
1057a84e134Smrg#define SatisfiesRule1(pane, shrink)			\
1067a84e134Smrg     (((shrink) && ((pane)->size != (pane)->min))	\
1077a84e134Smrg      || (!(shrink) && ((pane)->size != (pane)->max)))
1087a84e134Smrg
1097a84e134Smrg#define SatisfiesRule2(pane)					\
1107a84e134Smrg     (!(pane)->skip_adjust || (pane)->paned_adjusted_me)
1117a84e134Smrg
1127a84e134Smrg#define SatisfiesRule3(pane, shrink)					\
1137a84e134Smrg     ((pane)->paned_adjusted_me						\
1147a84e134Smrg      && (((shrink) && ((int)(pane)->wp_size <= (pane)->size))		\
1157a84e134Smrg	  || (!(shrink) && ((int)(pane)->wp_size >= (pane)->size))))
1167a84e134Smrg
1177a84e134Smrg
1187a84e134Smrg/*
1197a84e134Smrg * Class Methods
1207a84e134Smrg */
1217a84e134Smrgstatic void XawPanedClassInitialize(void);
1227a84e134Smrgstatic void XawPanedChangeManaged(Widget);
1237a84e134Smrgstatic void XawPanedDeleteChild(Widget);
1247a84e134Smrgstatic void XawPanedDestroy(Widget);
1257a84e134Smrgstatic XtGeometryResult XawPanedGeometryManager(Widget, XtWidgetGeometry*,
1267a84e134Smrg						XtWidgetGeometry*);
1277a84e134Smrgstatic void XawPanedInitialize(Widget, Widget, ArgList, Cardinal*);
1287a84e134Smrgstatic void XawPanedInsertChild(Widget);
1297a84e134Smrgstatic Boolean XawPanedPaneSetValues(Widget, Widget, Widget,
1307a84e134Smrg				     ArgList, Cardinal*);
1317a84e134Smrgstatic void XawPanedRealize(Widget, Mask*, XSetWindowAttributes*);
1327a84e134Smrgstatic void XawPanedRedisplay(Widget, XEvent*, Region);
1337a84e134Smrgstatic void XawPanedResize(Widget);
1347a84e134Smrgstatic Boolean XawPanedSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
1357a84e134Smrg
1367a84e134Smrg/*
1377a84e134Smrg * Prototypes
1387a84e134Smrg */
1397a84e134Smrgstatic void _DrawInternalBorders(PanedWidget, GC);
1407a84e134Smrgstatic void _DrawRect(PanedWidget, GC, int, int, unsigned int, unsigned int);
1417a84e134Smrgstatic void _DrawTrackLines(PanedWidget, Bool);
1427a84e134Smrgstatic void AdjustPanedSize(PanedWidget, unsigned int, XtGeometryResult*,
1437a84e134Smrg			    Dimension*, Dimension*);
1447a84e134Smrgstatic void ChangeAllGripCursors(PanedWidget);
1457a84e134Smrgstatic Pane ChoosePaneToResize(PanedWidget, int, Direction, Bool);
1467a84e134Smrgstatic void ClearPaneStack(PanedWidget);
1477a84e134Smrgstatic void CommitGripAdjustment(PanedWidget);
1487a84e134Smrgstatic void CreateGrip(Widget);
1497a84e134Smrgstatic int GetEventLocation(PanedWidget, XEvent*);
1507a84e134Smrgstatic void GetGCs(Widget);
1517a84e134Smrgstatic void GetPaneStack(PanedWidget, Bool, Pane*, int*);
1527a84e134Smrgstatic void HandleGrip(Widget, XtPointer, XtPointer);
1537a84e134Smrgstatic void LoopAndRefigureChildren(PanedWidget, int, Direction, int*);
1547a84e134Smrgstatic void ManageAndUnmanageGrips(PanedWidget);
1557a84e134Smrgstatic void MoveGripAdjustment(PanedWidget, Widget, Direction, int);
1567a84e134Smrgstatic Bool PopPaneStack(PanedWidget);
1577a84e134Smrgstatic void PushPaneStack(PanedWidget, Pane);
1587a84e134Smrgstatic void RefigureLocations(PanedWidget, int, Direction);
1597a84e134Smrgstatic void RefigureLocationsAndCommit(Widget);
1607a84e134Smrgstatic void ReleaseGCs(Widget);
1617a84e134Smrgstatic void ResortChildren(PanedWidget);
1627a84e134Smrgstatic void SetChildrenPrefSizes(PanedWidget, unsigned int);
1637a84e134Smrgstatic void StartGripAdjustment(PanedWidget, Widget, Direction);
1647a84e134Smrg
1657a84e134Smrg/*
1667a84e134Smrg * Initialization
1677a84e134Smrg */
1687a84e134Smrgstatic char defGripTranslations[] =
1697a84e134Smrg"<Btn1Down>:"		"GripAction(Start,UpLeftPane)\n"
1707a84e134Smrg"<Btn2Down>:"		"GripAction(Start,ThisBorderOnly)\n"
1717a84e134Smrg"<Btn3Down>:"		"GripAction(Start,LowRightPane)\n"
1727a84e134Smrg"<Btn1Motion>:"		"GripAction(Move,UpLeft)\n"
1737a84e134Smrg"<Btn2Motion>:"		"GripAction(Move,ThisBorder)\n"
1747a84e134Smrg"<Btn3Motion>:"		"GripAction(Move,LowRight)\n"
1757a84e134Smrg"Any<BtnUp>:"		"GripAction(Commit)\n"
1767a84e134Smrg;
1777a84e134Smrg
1787a84e134Smrg#define offset(field) XtOffsetOf(PanedRec, paned.field)
1797a84e134Smrgstatic XtResource resources[] = {
1807a84e134Smrg  {
1817a84e134Smrg    XtNinternalBorderColor,
1827a84e134Smrg    XtCBorderColor,
1837a84e134Smrg    XtRPixel,
1847a84e134Smrg    sizeof(Pixel),
1857a84e134Smrg    offset(internal_bp),
1867a84e134Smrg    XtRString,
1877a84e134Smrg    (XtPointer)XtDefaultForeground
1887a84e134Smrg  },
1897a84e134Smrg  {
1907a84e134Smrg    XtNinternalBorderWidth,
1917a84e134Smrg    XtCBorderWidth,
1927a84e134Smrg    XtRDimension,
1937a84e134Smrg    sizeof(Dimension),
1947a84e134Smrg    offset(internal_bw),
1957a84e134Smrg    XtRImmediate,
1967a84e134Smrg    (XtPointer)1
1977a84e134Smrg  },
1987a84e134Smrg  {
1997a84e134Smrg    XtNgripIndent,
2007a84e134Smrg    XtCGripIndent,
2017a84e134Smrg    XtRPosition,
2027a84e134Smrg    sizeof(Position),
2037a84e134Smrg    offset(grip_indent),
2047a84e134Smrg    XtRImmediate,
2057a84e134Smrg    (XtPointer)10
2067a84e134Smrg  },
2077a84e134Smrg  {
2087a84e134Smrg    XtNrefigureMode,
2097a84e134Smrg    XtCBoolean,
2107a84e134Smrg    XtRBoolean,
2117a84e134Smrg    sizeof(Boolean),
2127a84e134Smrg    offset(refiguremode),
2137a84e134Smrg    XtRImmediate,
2147a84e134Smrg    (XtPointer)True
2157a84e134Smrg  },
2167a84e134Smrg  {
2177a84e134Smrg    XtNgripTranslations,
2187a84e134Smrg    XtCTranslations,
2197a84e134Smrg    XtRTranslationTable,
2207a84e134Smrg    sizeof(XtTranslations),
2217a84e134Smrg    offset(grip_translations),
2227a84e134Smrg    XtRString,
2237a84e134Smrg    (XtPointer)defGripTranslations
2247a84e134Smrg  },
2257a84e134Smrg  {
2267a84e134Smrg    XtNorientation,
2277a84e134Smrg    XtCOrientation,
2287a84e134Smrg    XtROrientation,
2297a84e134Smrg    sizeof(XtOrientation),
2307a84e134Smrg    offset(orientation),
2317a84e134Smrg    XtRImmediate,
2327a84e134Smrg    (XtPointer)XtorientVertical
2337a84e134Smrg  },
2347a84e134Smrg  {
2357a84e134Smrg    XtNcursor,
2367a84e134Smrg    XtCCursor,
2377a84e134Smrg    XtRCursor,
2387a84e134Smrg    sizeof(Cursor),
2397a84e134Smrg    offset(cursor),
2407a84e134Smrg    XtRImmediate,
241775e7de9Smrg    NULL
2427a84e134Smrg  },
2437a84e134Smrg  {
2447a84e134Smrg    XtNgripCursor,
2457a84e134Smrg    XtCCursor,
2467a84e134Smrg    XtRCursor,
2477a84e134Smrg    sizeof(Cursor),
2487a84e134Smrg    offset(grip_cursor),
2497a84e134Smrg    XtRImmediate,
250775e7de9Smrg    NULL
2517a84e134Smrg  },
2527a84e134Smrg  {
2537a84e134Smrg    XtNverticalGripCursor,
2547a84e134Smrg    XtCCursor,
2557a84e134Smrg    XtRCursor,
2567a84e134Smrg    sizeof(Cursor),
2577a84e134Smrg    offset(v_grip_cursor),
2587a84e134Smrg    XtRString,
2595ec34c4cSmrg    (XtPointer)"sb_v_double_arrow"
2607a84e134Smrg  },
2617a84e134Smrg  {
2627a84e134Smrg    XtNhorizontalGripCursor,
2637a84e134Smrg    XtCCursor,
2647a84e134Smrg    XtRCursor,
2657a84e134Smrg    sizeof(Cursor),
2667a84e134Smrg    offset(h_grip_cursor),
2677a84e134Smrg    XtRString,
2685ec34c4cSmrg    (XtPointer)"sb_h_double_arrow"
2697a84e134Smrg  },
2707a84e134Smrg  {
2717a84e134Smrg    XtNbetweenCursor,
2727a84e134Smrg    XtCCursor,
2737a84e134Smrg    XtRCursor,
2747a84e134Smrg    sizeof(Cursor),
2757a84e134Smrg    offset(adjust_this_cursor),
2767a84e134Smrg    XtRString,
277775e7de9Smrg    NULL
2787a84e134Smrg  },
2797a84e134Smrg  {
2807a84e134Smrg    XtNverticalBetweenCursor,
2817a84e134Smrg    XtCCursor,
2827a84e134Smrg    XtRCursor,
2837a84e134Smrg    sizeof(Cursor),
2847a84e134Smrg    offset(v_adjust_this_cursor),
2857a84e134Smrg    XtRString,
2865ec34c4cSmrg    (XtPointer)"sb_left_arrow"
2877a84e134Smrg  },
2887a84e134Smrg  {
2897a84e134Smrg    XtNhorizontalBetweenCursor,
2907a84e134Smrg    XtCCursor,
2917a84e134Smrg    XtRCursor,
2927a84e134Smrg    sizeof(Cursor),
2937a84e134Smrg    offset(h_adjust_this_cursor),
2947a84e134Smrg    XtRString,
2955ec34c4cSmrg    (XtPointer)"sb_up_arrow"
2967a84e134Smrg  },
2977a84e134Smrg  {
2987a84e134Smrg    XtNupperCursor,
2997a84e134Smrg    XtCCursor,
3007a84e134Smrg    XtRCursor,
3017a84e134Smrg    sizeof(Cursor),
3027a84e134Smrg    offset(adjust_upper_cursor),
3037a84e134Smrg    XtRString,
3045ec34c4cSmrg    (XtPointer)"sb_up_arrow"
3057a84e134Smrg  },
3067a84e134Smrg  {
3077a84e134Smrg    XtNlowerCursor,
3087a84e134Smrg    XtCCursor,
3097a84e134Smrg    XtRCursor,
3107a84e134Smrg    sizeof(Cursor),
3117a84e134Smrg    offset(adjust_lower_cursor),
3127a84e134Smrg    XtRString,
3135ec34c4cSmrg    (XtPointer)"sb_down_arrow"
3147a84e134Smrg  },
3157a84e134Smrg  {
3167a84e134Smrg    XtNleftCursor,
3177a84e134Smrg    XtCCursor,
3187a84e134Smrg    XtRCursor,
3197a84e134Smrg    sizeof(Cursor),
3207a84e134Smrg    offset(adjust_left_cursor),
3217a84e134Smrg    XtRString,
3225ec34c4cSmrg    (XtPointer)"sb_left_arrow"
3237a84e134Smrg  },
3247a84e134Smrg  {
3257a84e134Smrg    XtNrightCursor,
3267a84e134Smrg    XtCCursor,
3277a84e134Smrg    XtRCursor,
3287a84e134Smrg    sizeof(Cursor),
3297a84e134Smrg    offset(adjust_right_cursor),
3307a84e134Smrg    XtRString,
3315ec34c4cSmrg    (XtPointer)"sb_right_arrow"
3327a84e134Smrg  },
3337a84e134Smrg};
3347a84e134Smrg#undef offset
3357a84e134Smrg
3367a84e134Smrg#define offset(field) XtOffsetOf(PanedConstraintsRec, paned.field)
3377a84e134Smrgstatic XtResource subresources[] = {
3387a84e134Smrg  {
3397a84e134Smrg    XtNallowResize,
3407a84e134Smrg    XtCBoolean,
3417a84e134Smrg    XtRBoolean,
3427a84e134Smrg    sizeof(Boolean),
3437a84e134Smrg    offset(allow_resize),
3447a84e134Smrg    XtRImmediate,
3457a84e134Smrg    (XtPointer)False
3467a84e134Smrg  },
3477a84e134Smrg  {
3487a84e134Smrg    XtNposition,
3497a84e134Smrg    XtCPosition,
3507a84e134Smrg    XtRInt,
3517a84e134Smrg    sizeof(int),
3527a84e134Smrg    offset(position),
3537a84e134Smrg    XtRImmediate,
3547a84e134Smrg    (XtPointer)0
3557a84e134Smrg  },
3567a84e134Smrg  {
3577a84e134Smrg    XtNmin,
3587a84e134Smrg    XtCMin,
3597a84e134Smrg    XtRDimension,
3607a84e134Smrg    sizeof(Dimension),
3617a84e134Smrg    offset(min),
3627a84e134Smrg    XtRImmediate,
3637a84e134Smrg    (XtPointer)PANED_GRIP_SIZE
3647a84e134Smrg  },
3657a84e134Smrg  {
3667a84e134Smrg    XtNmax,
3677a84e134Smrg    XtCMax,
3687a84e134Smrg    XtRDimension,
3697a84e134Smrg    sizeof(Dimension),
3707a84e134Smrg    offset(max),
3717a84e134Smrg    XtRImmediate,
3727a84e134Smrg    (XtPointer)~0
3737a84e134Smrg  },
3747a84e134Smrg  {
3757a84e134Smrg    XtNpreferredPaneSize,
3767a84e134Smrg    XtCPreferredPaneSize,
3777a84e134Smrg    XtRDimension,
3787a84e134Smrg    sizeof(Dimension),
3797a84e134Smrg    offset(preferred_size),
3807a84e134Smrg    XtRImmediate,
3817a84e134Smrg    (XtPointer)PANED_ASK_CHILD
3827a84e134Smrg  },
3837a84e134Smrg  {
3847a84e134Smrg    XtNresizeToPreferred,
3857a84e134Smrg    XtCBoolean,
3867a84e134Smrg    XtRBoolean,
3877a84e134Smrg    sizeof(Boolean),
3887a84e134Smrg    offset(resize_to_pref),
3897a84e134Smrg    XtRImmediate,
3907a84e134Smrg    (XtPointer)False
3917a84e134Smrg  },
3927a84e134Smrg  {
3937a84e134Smrg    XtNskipAdjust,
3947a84e134Smrg    XtCBoolean,
3957a84e134Smrg    XtRBoolean,
3967a84e134Smrg    sizeof(Boolean),
3977a84e134Smrg    offset(skip_adjust),
3987a84e134Smrg    XtRImmediate,
3997a84e134Smrg    (XtPointer)False
4007a84e134Smrg  },
4017a84e134Smrg  {
4027a84e134Smrg    XtNshowGrip,
4037a84e134Smrg    XtCShowGrip,
4047a84e134Smrg    XtRBoolean,
4057a84e134Smrg    sizeof(Boolean),
4067a84e134Smrg    offset(show_grip),
4077a84e134Smrg    XtRImmediate,
4087a84e134Smrg    (XtPointer)True
4097a84e134Smrg  },
4107a84e134Smrg};
4117a84e134Smrg#undef offset
4127a84e134Smrg
4137a84e134Smrg#define SuperClass ((ConstraintWidgetClass)&constraintClassRec)
4147a84e134Smrg
4157a84e134SmrgPanedClassRec panedClassRec = {
4167a84e134Smrg   /* core */
4177a84e134Smrg   {
4187a84e134Smrg    (WidgetClass)SuperClass,		/* superclass */
4197a84e134Smrg    "Paned",				/* class name */
4207a84e134Smrg    sizeof(PanedRec),			/* size */
4217a84e134Smrg    XawPanedClassInitialize,		/* class_initialize */
4227a84e134Smrg    NULL,				/* class_part init */
4237a84e134Smrg    False,				/* class_inited */
4247a84e134Smrg    XawPanedInitialize,			/* initialize */
4257a84e134Smrg    NULL,				/* initialize_hook */
4267a84e134Smrg    XawPanedRealize,			/* realize */
4277a84e134Smrg    NULL,				/* actions */
4287a84e134Smrg    0,					/* num_actions */
4297a84e134Smrg    resources,				/* resources */
4307a84e134Smrg    XtNumber(resources),		/* num_resources */
4317a84e134Smrg    NULLQUARK,				/* xrm_class */
4327a84e134Smrg    True,				/* compress_motion */
4337a84e134Smrg    True,				/* compress_exposure */
4347a84e134Smrg    True,				/* compress_enterleave */
4357a84e134Smrg    False,				/* visible_interest */
4367a84e134Smrg    XawPanedDestroy,			/* destroy */
4377a84e134Smrg    XawPanedResize,			/* resize */
4387a84e134Smrg    XawPanedRedisplay,			/* expose */
4397a84e134Smrg    XawPanedSetValues,			/* set_values */
4407a84e134Smrg    NULL,				/* set_values_hook */
4417a84e134Smrg    XtInheritSetValuesAlmost,		/* set_values_almost */
4427a84e134Smrg    NULL,				/* get_values_hook */
4437a84e134Smrg    NULL,				/* accept_focus */
4447a84e134Smrg    XtVersion,				/* version */
4457a84e134Smrg    NULL,				/* callback_private */
4467a84e134Smrg    NULL,				/* tm_table */
4477a84e134Smrg    XtInheritQueryGeometry,		/* query_geometry */
4487a84e134Smrg    XtInheritDisplayAccelerator,	/* display_accelerator */
4497a84e134Smrg    NULL,				/* extension */
4507a84e134Smrg  },
4517a84e134Smrg  /* composite */
4527a84e134Smrg  {
4537a84e134Smrg    XawPanedGeometryManager,		/* geometry_manager */
4547a84e134Smrg    XawPanedChangeManaged,		/* change_managed */
4557a84e134Smrg    XawPanedInsertChild,		/* insert_child */
4567a84e134Smrg    XawPanedDeleteChild,		/* delete_child */
4577a84e134Smrg    NULL,				/* extension */
4587a84e134Smrg  },
4597a84e134Smrg  /* constraint */
4607a84e134Smrg  {
4617a84e134Smrg    subresources,			/* subresources */
4627a84e134Smrg    XtNumber(subresources),		/* subresource_count */
4637a84e134Smrg    sizeof(PanedConstraintsRec),	/* constraint_size */
4647a84e134Smrg    NULL,				/* initialize */
4657a84e134Smrg    NULL,				/* destroy */
4667a84e134Smrg    XawPanedPaneSetValues,		/* set_values */
4677a84e134Smrg    NULL,				/* extension */
4687a84e134Smrg  },
4697a84e134Smrg};
4707a84e134Smrg
4717a84e134SmrgWidgetClass panedWidgetClass = (WidgetClass)&panedClassRec;
4727a84e134SmrgWidgetClass vPanedWidgetClass = (WidgetClass)&panedClassRec;
4737a84e134Smrg
4747a84e134Smrg/*
4757a84e134Smrg * Implementation
4767a84e134Smrg */
4777a84e134Smrg/* Function:
4787a84e134Smrg *	AdjustPanedSize
4797a84e134Smrg *
4807a84e134Smrg * Parameters:
4817a84e134Smrg *	pw	     - paned widget to adjust
4827a84e134Smrg *	off_size     - new off_size to use
4837a84e134Smrg *	result_ret   - result of query (return)
4847a84e134Smrg *	on_size_ret  - new on_size  (return)
4857a84e134Smrg *	off_size_ret - new off_size (return)
4867a84e134Smrg *
4877a84e134Smrg * Description:
4887a84e134Smrg *	Adjusts the size of the pane.
4897a84e134Smrg *
4907a84e134Smrg * Returns:
4917a84e134Smrg *	amount of change in size
4927a84e134Smrg */
4937a84e134Smrgstatic void
4947a84e134SmrgAdjustPanedSize(PanedWidget pw, unsigned int off_size,
4957a84e134Smrg		XtGeometryResult *result_ret,
4967a84e134Smrg		Dimension *on_size_ret, Dimension *off_size_ret)
4977a84e134Smrg{
4987a84e134Smrg    Dimension old_size = PaneSize((Widget)pw, IsVert(pw));
4997a84e134Smrg    Dimension newsize = 0;
5007a84e134Smrg    Widget *childP;
5017a84e134Smrg    XtWidgetGeometry request, reply;
5027a84e134Smrg
5037a84e134Smrg    request.request_mode = CWWidth | CWHeight;
5047a84e134Smrg
5057a84e134Smrg    ForAllPanes(pw, childP) {
5067a84e134Smrg	int size = Max(PaneInfo(*childP)->size, (int)PaneInfo(*childP)->min);
5077a84e134Smrg
5087a84e134Smrg	AssignMin(size, (int)PaneInfo(*childP)->max);
5095ec34c4cSmrg	newsize = (newsize + (size + pw->paned.internal_bw));
5107a84e134Smrg    }
5115ec34c4cSmrg    newsize = (Dimension)(newsize - pw->paned.internal_bw);
5127a84e134Smrg
5137a84e134Smrg    if (newsize < 1)
5147a84e134Smrg	newsize = 1;
5157a84e134Smrg
5167a84e134Smrg    if (IsVert(pw)) {
5175ec34c4cSmrg	request.width = (Dimension)off_size;
5187a84e134Smrg	request.height = newsize;
5197a84e134Smrg    }
5207a84e134Smrg    else {
5217a84e134Smrg	request.width = newsize;
5225ec34c4cSmrg	request.height = (Dimension)off_size;
5237a84e134Smrg    }
5247a84e134Smrg
5257a84e134Smrg    if (result_ret != NULL) {
5267a84e134Smrg	request.request_mode |= XtCWQueryOnly;
5277a84e134Smrg
5287a84e134Smrg	*result_ret = XtMakeGeometryRequest((Widget)pw, &request, &reply);
5297a84e134Smrg	_XawImCallVendorShellExtResize((Widget)pw);
5307a84e134Smrg
5317a84e134Smrg	if (newsize == old_size || *result_ret == XtGeometryNo) {
5327a84e134Smrg	    *on_size_ret = old_size;
5335ec34c4cSmrg	    *off_size_ret = (Dimension)off_size;
5347a84e134Smrg	    return;
5357a84e134Smrg	}
5367a84e134Smrg	if (*result_ret != XtGeometryAlmost) {
5377a84e134Smrg	    *on_size_ret = GetRequestInfo(&request, IsVert(pw));
538421c997bSmrg	    *off_size_ret = GetRequestInfo(&request, !IsVert(pw));
5397a84e134Smrg	    return;
5407a84e134Smrg	}
5417a84e134Smrg	*on_size_ret = GetRequestInfo(&reply, IsVert(pw));
5427a84e134Smrg	*off_size_ret = GetRequestInfo(&reply, !IsVert(pw));
5437a84e134Smrg	return;
5447a84e134Smrg    }
5457a84e134Smrg
5467a84e134Smrg    if (newsize == old_size)
5477a84e134Smrg	return;
5487a84e134Smrg
5497a84e134Smrg    if (XtMakeGeometryRequest((Widget)pw, &request, &reply) == XtGeometryAlmost)
5507a84e134Smrg	XtMakeGeometryRequest((Widget)pw, &reply, &request);
5517a84e134Smrg}
5527a84e134Smrg
5537a84e134Smrg/*
5547a84e134Smrg * Function:
5557a84e134Smrg *	ChoosePaneToResize.
5567a84e134Smrg *
5577a84e134Smrg * Parameters:
5587a84e134Smrg *	pw	  - paned widget
5597a84e134Smrg *	paneindex - index of the current pane
5607a84e134Smrg *	dir	  - direction to search first
5617a84e134Smrg *	shrink	  - True if we need to shrink a pane, False otherwise
5627a84e134Smrg *
5637a84e134Smrg * Description:
5647a84e134Smrg *	  This function chooses a pane to resize.
565421c997bSmrg *	  They are chosen using the following rules:
5667a84e134Smrg *
5677a84e134Smrg *		   1) size < max && size > min
5687a84e134Smrg *	2) skip adjust == False
5695b16253fSmrg *	3) widget not its preferred height
5707a84e134Smrg *	   && this change will bring it closer
5717a84e134Smrg *	   && The user has not resized this pane.
572421c997bSmrg *
5737a84e134Smrg *		   If no widgets are found that fits all the rules then
5747a84e134Smrg *		      rule #3 is broken.
5757a84e134Smrg *		   If there are still no widgets found than
5767a84e134Smrg *		      rule #2 is broken.
5777a84e134Smrg *		   Rule #1 is never broken.
5787a84e134Smrg *		   If no widgets are found then NULL is returned.
579421c997bSmrg *
5807a84e134Smrg * Returns:
5817a84e134Smrg *	pane to resize or NULL
5827a84e134Smrg */
5837a84e134Smrgstatic Pane
5847a84e134SmrgChoosePaneToResize(PanedWidget pw, int paneindex, Direction dir, Bool shrink)
5857a84e134Smrg{
5867a84e134Smrg    Widget *childP;
5877a84e134Smrg    int rules = 3;
5887a84e134Smrg    Direction _dir = dir;
5897a84e134Smrg    int _index = paneindex;
5907a84e134Smrg
5917a84e134Smrg    if (paneindex == NO_INDEX || dir == AnyPane) {		/* Use defaults */
5927a84e134Smrg	_dir = LowRightPane;			/* Go up - really */
5937a84e134Smrg	_index = pw->paned.num_panes - 1;	/* Start the last pane, and work
5947a84e134Smrg						   backwards */
5957a84e134Smrg    }
5967a84e134Smrg    childP = pw->composite.children + _index;
5977a84e134Smrg
5987a84e134Smrg    /*CONSTCOND*/
5997a84e134Smrg    while(True) {
6007a84e134Smrg	Pane pane = PaneInfo(*childP);
601421c997bSmrg
6027a84e134Smrg	if ((rules < 3 || SatisfiesRule3(pane, shrink))
6037a84e134Smrg	    && (rules < 2 || SatisfiesRule2(pane))
6047a84e134Smrg	    && SatisfiesRule1(pane, shrink)
6057a84e134Smrg	    && (paneindex != PaneIndex(*childP) || dir == AnyPane))
6067a84e134Smrg	    return (pane);
6077a84e134Smrg
6087a84e134Smrg	/*
6097a84e134Smrg	 * This is counter-intuitive, but if we are resizing the pane
6107a84e134Smrg	 * above the grip we want to choose a pane below the grip to lose,
6117a84e134Smrg	 * and visa-versa
6127a84e134Smrg	 */
6137a84e134Smrg	if (_dir == LowRightPane)
6147a84e134Smrg	    --childP;
6157a84e134Smrg	else
6167a84e134Smrg	    ++childP;
6177a84e134Smrg
6187a84e134Smrg	/*
6197a84e134Smrg	 * If we have come to and edge then reduce the rule set, and try again
6207a84e134Smrg	 * If we are reduced the rules to none, then return NULL
6217a84e134Smrg	 */
6227a84e134Smrg	if ((childP - pw->composite.children) < 0 ||
6237a84e134Smrg	    (childP - pw->composite.children) >= pw->paned.num_panes) {
6247a84e134Smrg	    if (--rules < 1)	/* less strict rules */
6257a84e134Smrg		return (NULL);
6267a84e134Smrg	    childP = pw->composite.children + _index;
6277a84e134Smrg	}
6287a84e134Smrg    }
6297a84e134Smrg}
6307a84e134Smrg
6317a84e134Smrg/*
6327a84e134Smrg * Function:
6337a84e134Smrg *	LoopAndRefigureChildren
6347a84e134Smrg *
6357a84e134Smrg * Parameters:
6367a84e134Smrg *	pw	  - paned widget
637421c997bSmrg *	paneindex - number of the pane border we are moving
6387a84e134Smrg *	dir	  - pane to move (either UpLeftPane or LowRightPane)
6397a84e134Smrg *	sizeused  - current amount of space used (used and returned)
6407a84e134Smrg *
6417a84e134Smrg * Description:
6427a84e134Smrg *	  If we are resizing either the UpleftPane or LowRight Pane loop
6437a84e134Smrg *	through all the children to see if any will allow us to resize them.
6447a84e134Smrg */
6457a84e134Smrgstatic void
6467a84e134SmrgLoopAndRefigureChildren(PanedWidget pw, int paneindex, Direction dir,
6477a84e134Smrg			int *sizeused)
6487a84e134Smrg{
6497a84e134Smrg    int pane_size = (int)PaneSize((Widget)pw, IsVert(pw));
6507a84e134Smrg    Boolean shrink = (*sizeused > pane_size);
6517a84e134Smrg
6527a84e134Smrg    if (dir == LowRightPane)
6537a84e134Smrg	paneindex++;
6547a84e134Smrg
6557a84e134Smrg    /* While all panes do not fit properly */
6567a84e134Smrg    while (*sizeused != pane_size) {
6577a84e134Smrg	/*
6587a84e134Smrg	 * Choose a pane to resize
6597a84e134Smrg	 * First look on the Pane Stack, and then go hunting for another one
6607a84e134Smrg	 * If we fail to find a pane to resize then give up
6617a84e134Smrg	 */
6627a84e134Smrg	Pane pane;
6637a84e134Smrg	int start_size;
6647a84e134Smrg	Dimension old;
6657a84e134Smrg	Boolean rule3_ok = False, from_stack = True;
6667a84e134Smrg
6677a84e134Smrg	GetPaneStack(pw, shrink, &pane, &start_size);
6687a84e134Smrg	if (pane == NULL) {
6697a84e134Smrg	    pane = ChoosePaneToResize(pw, paneindex, dir, shrink);
670421c997bSmrg	    if (pane == NULL)
6717a84e134Smrg		return; /* no one to resize, give up */
6727a84e134Smrg
6737a84e134Smrg	    rule3_ok = SatisfiesRule3(pane, shrink);
6747a84e134Smrg	    from_stack = False;
6757a84e134Smrg	    PushPaneStack(pw, pane);
6767a84e134Smrg	}
6777a84e134Smrg
6787a84e134Smrg	/*
6797a84e134Smrg	 * Try to resize this pane so that all panes will fit, take min and max
6807a84e134Smrg	 * into account
6817a84e134Smrg	 */
6825ec34c4cSmrg	old = (Dimension) pane->size;
6837a84e134Smrg	pane->size += pane_size - *sizeused;
6847a84e134Smrg
6857a84e134Smrg	if (from_stack) {
6867a84e134Smrg	    if (shrink) {
6877a84e134Smrg		AssignMax(pane->size, start_size);
6887a84e134Smrg	    }	/* don't remove these braces */
6897a84e134Smrg	    else
6907a84e134Smrg		AssignMin(pane->size, start_size);
6917a84e134Smrg
6927a84e134Smrg	  if (pane->size == start_size)
6937a84e134Smrg	    (void)PopPaneStack(pw);
6947a84e134Smrg	}
6957a84e134Smrg	else if (rule3_ok) {
6967a84e134Smrg	    if (shrink) {
6977a84e134Smrg		AssignMax(pane->size, (int)pane->wp_size);
6987a84e134Smrg	    }	/* don't remove these braces */
6997a84e134Smrg	    else
7007a84e134Smrg		AssignMin(pane->size, (int)pane->wp_size);
7017a84e134Smrg	}
7027a84e134Smrg
7037a84e134Smrg	pane->paned_adjusted_me = pane->size != pane->wp_size;
7047a84e134Smrg	AssignMax(pane->size, (int)pane->min);
7057a84e134Smrg	AssignMin(pane->size, (int)pane->max);
7067a84e134Smrg	*sizeused += (pane->size - old);
7077a84e134Smrg    }
7087a84e134Smrg}
7097a84e134Smrg
7107a84e134Smrg/*
7117a84e134Smrg * Function:
7127a84e134Smrg *	RefigureLocations
7137a84e134Smrg *
7147a84e134Smrg * Parameters:
7157a84e134Smrg *	pw	  - paned widget
7167a84e134Smrg *	paneindex - child to start refiguring at
7177a84e134Smrg *	dir	  - direction to move from child
7187a84e134Smrg *
7197a84e134Smrg * Description:
7207a84e134Smrg *	  Refigures all locations of children.
7217a84e134Smrg *      There are special arguments to paneindex and dir, they are:
7227a84e134Smrg *      paneindex - NO_INDEX.
7237a84e134Smrg *      dir   - AnyPane.
7247a84e134Smrg *
7257a84e134Smrg *      If either of these is true then all panes may be resized and
7265b16253fSmrg *      the choosing of panes proceeds in reverse order starting with the
7277a84e134Smrg *      last child.
7287a84e134Smrg */
729421c997bSmrgstatic void
7307a84e134SmrgRefigureLocations(PanedWidget pw, int paneindex, Direction dir)
7317a84e134Smrg{
7327a84e134Smrg    Widget *childP;
7337a84e134Smrg    int pane_size = (int)PaneSize((Widget)pw, IsVert(pw));
7347a84e134Smrg    int sizeused = 0;
7357a84e134Smrg    Position loc = 0;
7367a84e134Smrg
7377a84e134Smrg    if (pw->paned.num_panes == 0 || !pw->paned.refiguremode)
7387a84e134Smrg	return;
7397a84e134Smrg
7407a84e134Smrg    /*
7417a84e134Smrg     * Get an initial estimate of the size we will use
7427a84e134Smrg     */
7437a84e134Smrg    ForAllPanes(pw, childP) {
7447a84e134Smrg	Pane pane = PaneInfo(*childP);
7457a84e134Smrg
7467a84e134Smrg	AssignMax(pane->size, (int) pane->min);
7477a84e134Smrg	AssignMin(pane->size, (int) pane->max);
7487a84e134Smrg	sizeused += (int)pane->size + (int)pw->paned.internal_bw;
7497a84e134Smrg    }
7507a84e134Smrg    sizeused -= (int)pw->paned.internal_bw;
7517a84e134Smrg
7527a84e134Smrg    if (dir != ThisBorderOnly && sizeused != pane_size)
7537a84e134Smrg	LoopAndRefigureChildren(pw, paneindex, dir, &sizeused);
7547a84e134Smrg
7557a84e134Smrg    /*
7567a84e134Smrg     * If we still are not the right size, then tell the pane that
7577a84e134Smrg     * wanted to resize that it can't
7587a84e134Smrg     */
7597a84e134Smrg    if (paneindex != NO_INDEX && dir != AnyPane) {
7607a84e134Smrg	Pane pane = PaneInfo(*(pw->composite.children + paneindex));
7615ec34c4cSmrg	Dimension old = (Dimension)pane->size;
7627a84e134Smrg
7637a84e134Smrg	pane->size += pane_size - sizeused;
7647a84e134Smrg	AssignMax(pane->size, (int) pane->min);
7657a84e134Smrg	AssignMin(pane->size, (int) pane->max);
7667a84e134Smrg	sizeused += pane->size - old;
7677a84e134Smrg    }
768421c997bSmrg
7697a84e134Smrg    /*
7707a84e134Smrg     * It is possible that the panes will not fit inside the vpaned widget, but
7717a84e134Smrg     * we have tried out best
7727a84e134Smrg     *
7737a84e134Smrg     * Assign each pane a location
7747a84e134Smrg     */
7757a84e134Smrg    ForAllPanes(pw, childP) {
7767a84e134Smrg	PaneInfo(*childP)->delta = loc;
7775ec34c4cSmrg	loc = (Position)(loc + (PaneInfo(*childP)->size + pw->paned.internal_bw));
7787a84e134Smrg    }
7797a84e134Smrg}
7807a84e134Smrg
7817a84e134Smrg/*
7827a84e134Smrg * Function:
7837a84e134Smrg *	CommitNewLocations
7847a84e134Smrg *
7857a84e134Smrg * Parameters:
7867a84e134Smrg *	pw - paned widget
7877a84e134Smrg *
7887a84e134Smrg * Description:
7897a84e134Smrg *	Commits all of the previously figured locations.
7907a84e134Smrg */
791421c997bSmrgstatic void
7927a84e134SmrgCommitNewLocations(PanedWidget pw)
7937a84e134Smrg{
7947a84e134Smrg    Widget *childP;
7957a84e134Smrg    XWindowChanges changes;
7967a84e134Smrg
7977a84e134Smrg    changes.stack_mode = Above;
7987a84e134Smrg
7997a84e134Smrg    ForAllPanes(pw, childP) {
8007a84e134Smrg	Pane pane = PaneInfo(*childP);
8017a84e134Smrg	Widget grip = pane->grip;	/* may be NULL */
8027a84e134Smrg
8037a84e134Smrg	if (IsVert(pw)) {
8047a84e134Smrg	    XtMoveWidget(*childP, (Position) 0, pane->delta);
8055ec34c4cSmrg	    XtResizeWidget(*childP, XtWidth(pw), (Dimension)pane->size, 0);
8067a84e134Smrg
8077a84e134Smrg	    if (HasGrip(*childP)) {	/* Move and Display the Grip */
8087a84e134Smrg		changes.x = XtWidth(pw) - pw->paned.grip_indent -
8097a84e134Smrg			    XtWidth(grip) - (XtBorderWidth(grip) << 1);
8107a84e134Smrg		changes.y = XtY(*childP) + XtHeight(*childP) -
8117a84e134Smrg			    (XtHeight(grip) >> 1) - XtBorderWidth(grip) +
8127a84e134Smrg			    (pw->paned.internal_bw >> 1);
8137a84e134Smrg	    }
8147a84e134Smrg	}
8157a84e134Smrg	else {
8167a84e134Smrg	    XtMoveWidget(*childP, pane->delta, 0);
8175ec34c4cSmrg	    XtResizeWidget(*childP, (Dimension)pane->size, (Dimension)XtHeight(pw), 0);
8187a84e134Smrg
8197a84e134Smrg	    if (HasGrip(*childP)) {		/* Move and Display the Grip */
8207a84e134Smrg		changes.x = XtX(*childP) + XtWidth(*childP) -
8217a84e134Smrg			    (XtWidth(grip) >> 1) - XtBorderWidth(grip) +
8227a84e134Smrg			    (pw->paned.internal_bw >> 1);
8237a84e134Smrg		changes.y = XtHeight(pw) - pw->paned.grip_indent -
8247a84e134Smrg			    XtHeight(grip) - (XtBorderWidth(grip) << 1);
8257a84e134Smrg	    }
8267a84e134Smrg	}
8277a84e134Smrg
8287a84e134Smrg	/*
829421c997bSmrg	 * This should match XtMoveWidget, except that we're also insuring the
8307a84e134Smrg	 * grip is Raised in the same request
8317a84e134Smrg	 */
8327a84e134Smrg
8337a84e134Smrg	if (HasGrip(*childP)) {
8345ec34c4cSmrg	    XtX(grip) = (Position)changes.x;
8355ec34c4cSmrg	    XtY(grip) = (Position)changes.y;
8367a84e134Smrg
8377a84e134Smrg	    if (XtIsRealized(pane->grip))
8387a84e134Smrg		XConfigureWindow(XtDisplay(pane->grip), XtWindow(pane->grip),
8397a84e134Smrg				 CWX | CWY | CWStackMode, &changes);
8407a84e134Smrg	}
8417a84e134Smrg    }
8427a84e134Smrg    ClearPaneStack(pw);
8437a84e134Smrg}
8447a84e134Smrg
8457a84e134Smrg/*
8467a84e134Smrg * Function:
8477a84e134Smrg *	RefigureLocationsAndCommit
8487a84e134Smrg *
8497a84e134Smrg * Parameters:
8507a84e134Smrg *	pw - paned widget
8517a84e134Smrg *
8527a84e134Smrg * Description:
853421c997bSmrg *	Refigures all locations in a paned widget and commits them immediately.
8547a84e134Smrg *
8557a84e134Smrg *      This function does nothing if any of the following are true.
8567a84e134Smrg *      o refiguremode is false.
8577a84e134Smrg *      o The widget is unrealized.
8587a84e134Smrg *      o There are no panes is the paned widget.
8597a84e134Smrg */
860421c997bSmrgstatic void
8617a84e134SmrgRefigureLocationsAndCommit(Widget w)
8627a84e134Smrg{
8637a84e134Smrg    PanedWidget pw = (PanedWidget)w;
8647a84e134Smrg
8657a84e134Smrg    if (pw->paned.refiguremode && XtIsRealized(w) && pw->paned.num_panes > 0) {
8667a84e134Smrg	RefigureLocations(pw, NO_INDEX, AnyPane);
8677a84e134Smrg	CommitNewLocations(pw);
8687a84e134Smrg    }
8697a84e134Smrg}
8707a84e134Smrg
8717a84e134Smrg/*
8727a84e134Smrg * Function:
8737a84e134Smrg *	_DrawRect
8747a84e134Smrg *
8757a84e134Smrg * Parameters:
8767a84e134Smrg *	pw	 - paned widget
8777a84e134Smrg *	gc	 - gc to used for the draw
8787a84e134Smrg *	on_olc	 - location of upper left corner of rect
8797a84e134Smrg *	off_loc	 - ""
8807a84e134Smrg *	on_size	 - size of rectangle
8817a84e134Smrg *	off_size - ""
8827a84e134Smrg *
8837a84e134Smrg * Description:
8847a84e134Smrg *	Draws a rectangle in the proper orientation.
8857a84e134Smrg */
8867a84e134Smrgstatic void
8877a84e134Smrg_DrawRect(PanedWidget pw, GC gc, int on_loc, int off_loc,
8887a84e134Smrg	  unsigned int on_size, unsigned int off_size)
8897a84e134Smrg{
890421c997bSmrg    if (IsVert(pw))
8917a84e134Smrg	XFillRectangle(XtDisplay((Widget)pw), XtWindow((Widget)pw), gc,
8927a84e134Smrg		       off_loc, on_loc, off_size, on_size);
8937a84e134Smrg    else
8947a84e134Smrg	XFillRectangle(XtDisplay((Widget)pw), XtWindow((Widget)pw), gc,
8957a84e134Smrg		       on_loc, off_loc, on_size, off_size);
8967a84e134Smrg}
8977a84e134Smrg
8987a84e134Smrg/*
8997a84e134Smrg * Function:
9007a84e134Smrg *	_DrawInternalBorders
9017a84e134Smrg *
9027a84e134Smrg * Parameters:
9037a84e134Smrg *	pw - paned widget
9047a84e134Smrg *	gc - GC to use to draw the borders
9057a84e134Smrg *
9067a84e134Smrg * Description:
9077a84e134Smrg *	Draws the internal borders into the paned widget.
9087a84e134Smrg */
9097a84e134Smrgstatic void
9107a84e134Smrg_DrawInternalBorders(PanedWidget pw, GC gc)
9117a84e134Smrg{
9127a84e134Smrg    Widget *childP;
9137a84e134Smrg    int on_loc, off_loc;
9147a84e134Smrg    unsigned int on_size, off_size;
9157a84e134Smrg
9167a84e134Smrg    /*
9177a84e134Smrg     * This is an optimization.  Do not paint the internal borders if
9187a84e134Smrg     * they are the same color as the background
9197a84e134Smrg     */
9207a84e134Smrg    if (pw->core.background_pixel == pw->paned.internal_bp)
9217a84e134Smrg	return;
9227a84e134Smrg
923421c997bSmrg    off_loc = 0;
9247a84e134Smrg    off_size = (unsigned int) PaneSize((Widget)pw, !IsVert(pw));
9257a84e134Smrg    on_size = (unsigned int)pw->paned.internal_bw;
9267a84e134Smrg
9277a84e134Smrg    ForAllPanes(pw, childP) {
9287a84e134Smrg	on_loc = IsVert(pw) ? XtY(*childP) : XtX(*childP);
9297a84e134Smrg	on_loc -= (int)on_size;
9307a84e134Smrg
9317a84e134Smrg	_DrawRect(pw, gc, on_loc, off_loc, on_size, off_size);
9327a84e134Smrg    }
9337a84e134Smrg}
9347a84e134Smrg
9357a84e134Smrg#define DrawInternalBorders(pw)				\
9367a84e134Smrg	_DrawInternalBorders((pw), (pw)->paned.normgc)
9377a84e134Smrg#define EraseInternalBorders(pw)			\
9387a84e134Smrg	_DrawInternalBorders((pw), (pw)->paned.invgc)
939421c997bSmrg/*
9407a84e134Smrg * Function Name:
9417a84e134Smrg *	_DrawTrackLines
9427a84e134Smrg *
9437a84e134Smrg * Parameters:
9447a84e134Smrg *	pw - Paned widget
9457a84e134Smrg *	erase - if True then just erase track lines, else draw them in
9467a84e134Smrg *
9477a84e134Smrg * Description:
9487a84e134Smrg *	Draws the lines that animate the pane borders when the grips are moved.
9497a84e134Smrg */
9507a84e134Smrgstatic void
9517a84e134Smrg_DrawTrackLines(PanedWidget pw, Bool erase)
9527a84e134Smrg{
9537a84e134Smrg    Widget *childP;
9547a84e134Smrg    Pane pane;
9557a84e134Smrg    int on_loc, off_loc;
9567a84e134Smrg    unsigned int on_size, off_size;
9577a84e134Smrg
9587a84e134Smrg    off_loc = 0;
9597a84e134Smrg    off_size = PaneSize((Widget)pw, !IsVert(pw));
9607a84e134Smrg
9617a84e134Smrg    ForAllPanes(pw, childP) {
9627a84e134Smrg	pane = PaneInfo(*childP);
9637a84e134Smrg	if (erase || pane->olddelta != pane->delta) {
964421c997bSmrg	    on_size = pw->paned.internal_bw;
9657a84e134Smrg	    if (!erase) {
9667a84e134Smrg		on_loc = PaneInfo(*childP)->olddelta - (int) on_size;
9677a84e134Smrg		_DrawRect(pw, pw->paned.flipgc,
9687a84e134Smrg			  on_loc, off_loc, on_size, off_size);
9697a84e134Smrg	    }
9707a84e134Smrg
9717a84e134Smrg	    on_loc = PaneInfo(*childP)->delta - (int)on_size;
9727a84e134Smrg
9737a84e134Smrg	    _DrawRect(pw, pw->paned.flipgc,
9747a84e134Smrg		      on_loc, off_loc, on_size, off_size);
9757a84e134Smrg
9767a84e134Smrg	    pane->olddelta = pane->delta;
9777a84e134Smrg	}
9787a84e134Smrg    }
9797a84e134Smrg}
9807a84e134Smrg
9817a84e134Smrg#define DrawTrackLines(pw)	_DrawTrackLines((pw), False);
9827a84e134Smrg#define EraseTrackLines(pw)	_DrawTrackLines((pw), True);
983421c997bSmrg/*
9847a84e134Smrg * Function:
9857a84e134Smrg *	GetEventLocation
9867a84e134Smrg *
9877a84e134Smrg * Parameters:
9887a84e134Smrg *	pw    - the paned widget
9897a84e134Smrg *	event - pointer to an event
9907a84e134Smrg *
9917a84e134Smrg * Description:
9927a84e134Smrg *	Converts and event to an x and y location.
9937a84e134Smrg *
9947a84e134Smrg * Returns:
9957a84e134Smrg *	if this is a vertical pane then (y) else (x)
9967a84e134Smrg */
9977a84e134Smrgstatic int
9987a84e134SmrgGetEventLocation(PanedWidget pw, XEvent *event)
9997a84e134Smrg{
10007a84e134Smrg    int x, y;
10017a84e134Smrg
10027a84e134Smrg    switch (event->xany.type) {
10037a84e134Smrg	case ButtonPress:
1004421c997bSmrg	case ButtonRelease:
10057a84e134Smrg	    x = event->xbutton.x_root;
10067a84e134Smrg	    y = event->xbutton.y_root;
10077a84e134Smrg	    break;
10087a84e134Smrg	case KeyPress:
1009421c997bSmrg	case KeyRelease:
10107a84e134Smrg	    x = event->xkey.x_root;
10117a84e134Smrg	    y = event->xkey.y_root;
10127a84e134Smrg	    break;
1013421c997bSmrg	case MotionNotify:
10147a84e134Smrg	    x = event->xmotion.x_root;
10157a84e134Smrg	    y = event->xmotion.y_root;
10167a84e134Smrg	    break;
1017421c997bSmrg	default:
10187a84e134Smrg	    x = pw->paned.start_loc;
10197a84e134Smrg	    y = pw->paned.start_loc;
10207a84e134Smrg    }
10217a84e134Smrg
1022421c997bSmrg    if (IsVert(pw))
10237a84e134Smrg	return (y);
10247a84e134Smrg
10257a84e134Smrg  return (x);
10267a84e134Smrg}
10277a84e134Smrg
10287a84e134Smrg/*
10297a84e134Smrg * Function:
10307a84e134Smrg *	StartGripAdjustment
10317a84e134Smrg *
10327a84e134Smrg * Parameters:
10337a84e134Smrg *	pw   - paned widget
10347a84e134Smrg *	grip - grip widget selected
10357a84e134Smrg *	dir  - direction that we are to be moving
10367a84e134Smrg *
10377a84e134Smrg * Description:
10387a84e134Smrg *	Starts the grip adjustment procedure.
10397a84e134Smrg */
10407a84e134Smrgstatic void
10417a84e134SmrgStartGripAdjustment(PanedWidget pw, Widget grip, Direction dir)
10427a84e134Smrg{
10437a84e134Smrg    Widget *childP;
10447a84e134Smrg    Cursor cursor;
10457a84e134Smrg
10467a84e134Smrg    pw->paned.whichadd = pw->paned.whichsub = NULL;
10477a84e134Smrg
10487a84e134Smrg    if (dir == ThisBorderOnly || dir == UpLeftPane)
10497a84e134Smrg	pw->paned.whichadd = pw->composite.children[PaneIndex(grip)];
10507a84e134Smrg    if (dir == ThisBorderOnly || dir == LowRightPane)
10517a84e134Smrg	pw->paned.whichsub = pw->composite.children[PaneIndex(grip) + 1];
10527a84e134Smrg
10537a84e134Smrg    /*
10547a84e134Smrg     * Change the cursor
10557a84e134Smrg     */
10567a84e134Smrg    if (XtIsRealized(grip)) {
10577a84e134Smrg	if (IsVert(pw)) {
1058421c997bSmrg	    if (dir == UpLeftPane)
10597a84e134Smrg		cursor = pw->paned.adjust_upper_cursor;
1060421c997bSmrg	    else if (dir == LowRightPane)
1061421c997bSmrg		cursor = pw->paned.adjust_lower_cursor;
10627a84e134Smrg	    else {
10637a84e134Smrg		if (pw->paned.adjust_this_cursor == None)
10647a84e134Smrg		    cursor = pw->paned.v_adjust_this_cursor;
10657a84e134Smrg		else
10667a84e134Smrg		    cursor = pw->paned.adjust_this_cursor;
10677a84e134Smrg	    }
10687a84e134Smrg	}
10697a84e134Smrg	else {
1070421c997bSmrg	    if (dir == UpLeftPane)
10717a84e134Smrg		cursor = pw->paned.adjust_left_cursor;
1072421c997bSmrg	    else if (dir == LowRightPane)
1073421c997bSmrg		cursor = pw->paned.adjust_right_cursor;
10747a84e134Smrg	    else {
10757a84e134Smrg		if (pw->paned.adjust_this_cursor == None)
10767a84e134Smrg		    cursor = pw->paned.h_adjust_this_cursor;
10777a84e134Smrg		else
10787a84e134Smrg		    cursor = pw->paned.adjust_this_cursor;
10797a84e134Smrg	    }
10807a84e134Smrg	}
1081421c997bSmrg
10827a84e134Smrg	XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor);
10837a84e134Smrg    }
10847a84e134Smrg
10857a84e134Smrg    EraseInternalBorders(pw);
1086421c997bSmrg    ForAllPanes(pw, childP)
10877a84e134Smrg	PaneInfo(*childP)->olddelta = -99;
10887a84e134Smrg
10897a84e134Smrg    EraseTrackLines(pw);
10907a84e134Smrg}
10917a84e134Smrg
10927a84e134Smrg/*
10937a84e134Smrg * Function:
10947a84e134Smrg *	MoveGripAdjustment
10957a84e134Smrg *
10967a84e134Smrg * Parameters:
10977a84e134Smrg *	pw   - paned widget
10987a84e134Smrg *	grip - grip that we are moving
10997a84e134Smrg *	dir  - direction the pane we are interested is w.r.t the grip
11007a84e134Smrg *	loc  - location of pointer in proper direction
11017a84e134Smrg *
11027a84e134Smrg * Description:
11037a84e134Smrg *	This routine moves all panes around when a grip is moved.
11047a84e134Smrg */
11057a84e134Smrgstatic void
11067a84e134SmrgMoveGripAdjustment(PanedWidget pw, Widget grip, Direction dir, int loc)
11077a84e134Smrg{
11087a84e134Smrg    int diff, add_size = 0, sub_size = 0;
11097a84e134Smrg
11107a84e134Smrg    diff = loc - pw->paned.start_loc;
11117a84e134Smrg
1112421c997bSmrg    if (pw->paned.whichadd)
11137a84e134Smrg    add_size = PaneSize(pw->paned.whichadd, IsVert(pw)) + diff;
11147a84e134Smrg
1115421c997bSmrg    if (pw->paned.whichsub)
11167a84e134Smrg    sub_size = PaneSize(pw->paned.whichsub, IsVert(pw)) - diff;
11177a84e134Smrg
11187a84e134Smrg    /*
11197a84e134Smrg     * If moving this border only then do not allow either of the borders
11207a84e134Smrg     * to go beyond the min or max size allowed
11217a84e134Smrg     */
11227a84e134Smrg    if (dir == ThisBorderOnly) {
11237a84e134Smrg	int old_add_size = add_size, old_sub_size;
11247a84e134Smrg
11257a84e134Smrg	AssignMax(add_size, (int)PaneInfo(pw->paned.whichadd)->min);
11267a84e134Smrg	AssignMin(add_size, (int)PaneInfo(pw->paned.whichadd)->max);
1127421c997bSmrg	if (add_size != old_add_size)
11287a84e134Smrg	    sub_size += old_add_size - add_size;
11297a84e134Smrg
11307a84e134Smrg	old_sub_size = sub_size;
11317a84e134Smrg	AssignMax(sub_size, (int)PaneInfo(pw->paned.whichsub)->min);
11327a84e134Smrg	AssignMin(sub_size, (int)PaneInfo(pw->paned.whichsub)->max);
11337a84e134Smrg	if (sub_size != old_sub_size)
11347a84e134Smrg	    return;	/* Abort to current sizes */
11357a84e134Smrg    }
11367a84e134Smrg
11377a84e134Smrg    if (add_size != 0)
11387a84e134Smrg	PaneInfo(pw->paned.whichadd)->size = add_size;
11397a84e134Smrg    if (sub_size != 0)
11407a84e134Smrg	PaneInfo(pw->paned.whichsub)->size = sub_size;
11417a84e134Smrg    RefigureLocations(pw, PaneIndex(grip), dir);
11427a84e134Smrg    DrawTrackLines(pw);
11437a84e134Smrg}
11447a84e134Smrg
11457a84e134Smrg/*
11467a84e134Smrg * Function:
11477a84e134Smrg *	CommitGripAdjustment
11487a84e134Smrg *
11497a84e134Smrg * Parameters:
11507a84e134Smrg *	pw - paned widget
11517a84e134Smrg *
11527a84e134Smrg * Description:
11537a84e134Smrg *	Commits the grip adjustment.
11547a84e134Smrg */
11557a84e134Smrgstatic void
11567a84e134SmrgCommitGripAdjustment(PanedWidget pw)
11577a84e134Smrg{
11587a84e134Smrg    EraseTrackLines(pw);
11597a84e134Smrg    CommitNewLocations(pw);
11607a84e134Smrg    DrawInternalBorders(pw);
1161421c997bSmrg
11627a84e134Smrg    /*
11637a84e134Smrg     * Since the user selected this size then use it as the preferred size
11647a84e134Smrg     */
11657a84e134Smrg    if (pw->paned.whichadd) {
11667a84e134Smrg	Pane pane = PaneInfo(pw->paned.whichadd);
11677a84e134Smrg
11685ec34c4cSmrg	pane->wp_size = (Dimension)pane->size;
11697a84e134Smrg    }
11707a84e134Smrg    if (pw->paned.whichsub) {
11717a84e134Smrg	Pane pane = PaneInfo(pw->paned.whichsub);
11727a84e134Smrg
11735ec34c4cSmrg	pane->wp_size = (Dimension)pane->size;
11747a84e134Smrg    }
11757a84e134Smrg}
11767a84e134Smrg
11777a84e134Smrg/*
11787a84e134Smrg * Function:
11797a84e134Smrg *	HandleGrip
11807a84e134Smrg *
11817a84e134Smrg * Parameters:
11827a84e134Smrg *	grip	  - grip widget that has been moved
11837a84e134Smrg *	temp	  - (not used)
11847a84e134Smrg *	call_data - data passed to us from the grip widget
11857a84e134Smrg *
11867a84e134Smrg * Description:
11877a84e134Smrg *	Handles the grip manipulations.
11887a84e134Smrg */
11897a84e134Smrg/*ARGSUSED*/
11907a84e134Smrgstatic void
11915ec34c4cSmrgHandleGrip(Widget grip, XtPointer temp _X_UNUSED, XtPointer callData)
11927a84e134Smrg{
11937a84e134Smrg    XawGripCallData call_data = (XawGripCallData)callData;
11947a84e134Smrg    PanedWidget pw = (PanedWidget) XtParent(grip);
11957a84e134Smrg    int loc;
11967a84e134Smrg    char action_type[2], direction[2];
11977a84e134Smrg    Cursor cursor;
11987a84e134Smrg    Arg arglist[1];
11997a84e134Smrg
12007a84e134Smrg    if (call_data->num_params)
12017a84e134Smrg	XmuNCopyISOLatin1Uppered(action_type, call_data->params[0],
12027a84e134Smrg				 sizeof(action_type));
12037a84e134Smrg
12047a84e134Smrg    if (call_data->num_params == 0
12057a84e134Smrg	|| (action_type[0] == 'C' && call_data->num_params != 1)
12067a84e134Smrg	|| (action_type[0] != 'C' && call_data->num_params != 2))
12077a84e134Smrg	XtAppError(XtWidgetToApplicationContext(grip),
12087a84e134Smrg		   "Paned GripAction has been passed incorrect parameters.");
12097a84e134Smrg
12107a84e134Smrg    loc = GetEventLocation(pw, (XEvent *)call_data->event);
12117a84e134Smrg
12127a84e134Smrg    if (action_type[0] != 'C')
12137a84e134Smrg	XmuNCopyISOLatin1Uppered(direction, call_data->params[1],
12147a84e134Smrg				 sizeof(direction));
12157a84e134Smrg
12167a84e134Smrg    switch (action_type[0]) {
12177a84e134Smrg	case 'S':		/* Start adjustment */
12187a84e134Smrg	    pw->paned.resize_children_to_pref = False;
12197a84e134Smrg	    StartGripAdjustment(pw, grip, (Direction)direction[0]);
1220421c997bSmrg	    pw->paned.start_loc = loc;
12217a84e134Smrg	    break;
1222421c997bSmrg	case 'M':
12237a84e134Smrg	    MoveGripAdjustment(pw, grip, (Direction)direction[0], loc);
12247a84e134Smrg	    break;
12257a84e134Smrg	case 'C':
12267a84e134Smrg	    XtSetArg(arglist[0], XtNcursor, &cursor);
12277a84e134Smrg	    XtGetValues(grip, arglist, 1);
12287a84e134Smrg	    XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor);
12297a84e134Smrg	    CommitGripAdjustment(pw);
12307a84e134Smrg	    break;
12317a84e134Smrg	default:
12327a84e134Smrg	    XtAppError(XtWidgetToApplicationContext(grip),
12337a84e134Smrg		       "Paned GripAction(); 1st parameter invalid");
12347a84e134Smrg	    break;
12357a84e134Smrg     }
12367a84e134Smrg}
12377a84e134Smrg
12387a84e134Smrg/*
12397a84e134Smrg * Function:
12407a84e134Smrg *	ResortChildren
12417a84e134Smrg *
12427a84e134Smrg * Arguments:
12437a84e134Smrg *	pw - paned widget
12447a84e134Smrg *
12457a84e134Smrg * Description:
12467a84e134Smrg *	Resorts the children so that all managed children are first.
12477a84e134Smrg */
12487a84e134Smrgstatic void
12497a84e134SmrgResortChildren(PanedWidget pw)
12507a84e134Smrg{
12517a84e134Smrg    Widget *unmanagedP, *childP;
12527a84e134Smrg
12537a84e134Smrg    unmanagedP = NULL;
12547a84e134Smrg    ForAllChildren(pw, childP) {
12557a84e134Smrg	if (!IsPane(*childP) || !XtIsManaged(*childP)) {
12567a84e134Smrg	    /*
12577a84e134Smrg	     * We only keep track of the first unmanaged pane
12587a84e134Smrg	     */
1259421c997bSmrg	    if (unmanagedP == NULL)
12607a84e134Smrg		unmanagedP = childP;
12617a84e134Smrg	}
12627a84e134Smrg	else {			/* must be a managed pane */
12637a84e134Smrg	    /*
1264421c997bSmrg	     * If an earlier widget was not a managed pane, then swap
12657a84e134Smrg	     */
12667a84e134Smrg	    if (unmanagedP != NULL) {
12677a84e134Smrg		Widget child = *unmanagedP;
12687a84e134Smrg
12697a84e134Smrg		*unmanagedP = *childP;
12707a84e134Smrg		*childP = child;
12717a84e134Smrg		childP = unmanagedP;  /* easiest to just back-track */
12727a84e134Smrg		unmanagedP = NULL;    /* in case there is another managed */
12737a84e134Smrg	   }
12747a84e134Smrg       }
12757a84e134Smrg   }
12767a84e134Smrg}
12777a84e134Smrg
12787a84e134Smrg/*
12797a84e134Smrg * Function:
12807a84e134Smrg *	ManageAndUnmanageGrips
12817a84e134Smrg *
12827a84e134Smrg * Parameters:
12837a84e134Smrg *	pw - paned widget
12847a84e134Smrg *
12857a84e134Smrg * Description:
12867a84e134Smrg *	  This function manages and unmanages the grips so that
12877a84e134Smrg *		   the managed state of each grip matches that of its pane.
12887a84e134Smrg */
1289421c997bSmrgstatic void
12907a84e134SmrgManageAndUnmanageGrips(PanedWidget pw)
12917a84e134Smrg{
12927a84e134Smrg    WidgetList managed_grips, unmanaged_grips;
12937a84e134Smrg    Widget *managedP, *unmanagedP, *childP;
12947a84e134Smrg    Cardinal alloc_size;
12957a84e134Smrg
12965ec34c4cSmrg    alloc_size = (Cardinal)(sizeof(Widget) * (pw->composite.num_children >> 1));
12977a84e134Smrg    managedP = managed_grips = (WidgetList)XtMalloc(alloc_size);
12987a84e134Smrg    unmanagedP = unmanaged_grips = (WidgetList)XtMalloc(alloc_size);
12997a84e134Smrg
13007a84e134Smrg    ForAllChildren(pw, childP)
13017a84e134Smrg	if (IsPane(*childP) && HasGrip(*childP)) {
13027a84e134Smrg	    if (XtIsManaged(*childP))
13037a84e134Smrg		*managedP++ = PaneInfo(*childP)->grip;
13047a84e134Smrg	    else
13057a84e134Smrg		*unmanagedP++ = PaneInfo(*childP)->grip;
13067a84e134Smrg	}
1307421c997bSmrg
13087a84e134Smrg    if (managedP != managed_grips) {
13097a84e134Smrg	*unmanagedP++ = *--managedP;   /* Last grip is never managed */
13105ec34c4cSmrg	XtManageChildren(managed_grips, (Cardinal)(managedP - managed_grips));
13117a84e134Smrg    }
13127a84e134Smrg
13137a84e134Smrg    if (unmanagedP != unmanaged_grips)
13145ec34c4cSmrg	XtUnmanageChildren(unmanaged_grips, (Cardinal)(unmanagedP - unmanaged_grips));
13157a84e134Smrg
13167a84e134Smrg    XtFree((char *)managed_grips);
13177a84e134Smrg    XtFree((char *)unmanaged_grips);
13187a84e134Smrg}
13197a84e134Smrg
13207a84e134Smrg/*
13217a84e134Smrg * Function:
13227a84e134Smrg *	CreateGrip
13237a84e134Smrg *
13247a84e134Smrg * Parameters:
13257a84e134Smrg *	child - child that wants a grip to be created for it
13267a84e134Smrg *
13277a84e134Smrg * Description:
13287a84e134Smrg *	Creates a grip widget.
13297a84e134Smrg */
13307a84e134Smrgstatic void
13317a84e134SmrgCreateGrip(Widget child)
13327a84e134Smrg{
13337a84e134Smrg    PanedWidget pw = (PanedWidget)XtParent(child);
13347a84e134Smrg    Arg arglist[2];
13357a84e134Smrg    Cardinal num_args = 0;
13367a84e134Smrg    Cursor cursor;
1337421c997bSmrg
13387a84e134Smrg    XtSetArg(arglist[num_args], XtNtranslations, pw->paned.grip_translations);
13397a84e134Smrg    num_args++;
13407a84e134Smrg    if ((cursor = pw->paned.grip_cursor) == None) {
13417a84e134Smrg	if (IsVert(pw))
13427a84e134Smrg	    cursor = pw->paned.v_grip_cursor;
13437a84e134Smrg	else
13447a84e134Smrg	    cursor = pw->paned.h_grip_cursor;
13457a84e134Smrg    }
13467a84e134Smrg
13477a84e134Smrg    XtSetArg(arglist[num_args], XtNcursor, cursor);
13487a84e134Smrg    num_args++;
13497a84e134Smrg    PaneInfo(child)->grip = XtCreateWidget("grip", gripWidgetClass, (Widget)pw,
13507a84e134Smrg					   arglist, num_args);
1351421c997bSmrg
1352421c997bSmrg    XtAddCallback(PaneInfo(child)->grip, XtNcallback,
13537a84e134Smrg		  HandleGrip, (XtPointer)child);
13547a84e134Smrg}
13557a84e134Smrg
13567a84e134Smrg/*
13577a84e134Smrg * Function:
13587a84e134Smrg *	GetGCs
13597a84e134Smrg *
13607a84e134Smrg * Parameters:
13617a84e134Smrg *	w - paned widget
13627a84e134Smrg */
13637a84e134Smrgstatic void
13647a84e134SmrgGetGCs(Widget w)
13657a84e134Smrg{
13667a84e134Smrg    PanedWidget pw = (PanedWidget)w;
13677a84e134Smrg    XtGCMask valuemask;
13687a84e134Smrg    XGCValues values;
13697a84e134Smrg
13707a84e134Smrg    /*
13717a84e134Smrg     * Draw pane borders in internal border color
13727a84e134Smrg     */
1373421c997bSmrg    values.foreground = pw->paned.internal_bp;
13747a84e134Smrg    valuemask = GCForeground;
13757a84e134Smrg    pw->paned.normgc = XtGetGC(w, valuemask, &values);
13767a84e134Smrg
13777a84e134Smrg    /*
13787a84e134Smrg     * Erase pane borders with background color
13797a84e134Smrg     */
1380421c997bSmrg    values.foreground = pw->core.background_pixel;
13817a84e134Smrg    valuemask = GCForeground;
13827a84e134Smrg    pw->paned.invgc = XtGetGC(w, valuemask, &values);
13837a84e134Smrg
13847a84e134Smrg    /*
13857a84e134Smrg     * Draw Track lines (animate pane borders) in
13867a84e134Smrg     * internal border color ^ bg color
13877a84e134Smrg     */
13887a84e134Smrg    values.function = GXinvert;
13897a84e134Smrg    values.plane_mask = pw->paned.internal_bp ^ pw->core.background_pixel;
1390421c997bSmrg    values.subwindow_mode = IncludeInferiors;
13917a84e134Smrg    valuemask = GCPlaneMask | GCFunction | GCSubwindowMode;
13927a84e134Smrg    pw->paned.flipgc = XtGetGC(w, valuemask, &values);
13937a84e134Smrg}
13947a84e134Smrg
13957a84e134Smrg/*
13967a84e134Smrg * Function:
13977a84e134Smrg *	SetChildrenPrefSizes
13987a84e134Smrg *
13997a84e134Smrg * Parameters:
14007a84e134Smrg *	pw - paned widget
14017a84e134Smrg *
14027a84e134Smrg * Description:
14037a84e134Smrg *	Sets the preferred sizes of the children.
14047a84e134Smrg */
14057a84e134Smrgstatic void
14067a84e134SmrgSetChildrenPrefSizes(PanedWidget pw, unsigned int off_size)
14077a84e134Smrg{
14087a84e134Smrg    Widget *childP;
14097a84e134Smrg    Boolean vert = IsVert(pw);
14107a84e134Smrg    XtWidgetGeometry request, reply;
14117a84e134Smrg
14127a84e134Smrg    ForAllPanes(pw, childP)
14137a84e134Smrg	if (pw->paned.resize_children_to_pref || PaneInfo(*childP)->size == 0 ||
14147a84e134Smrg	    PaneInfo(*childP)->resize_to_pref) {
14157a84e134Smrg	    if (PaneInfo(*childP)->preferred_size != PANED_ASK_CHILD)
14167a84e134Smrg		PaneInfo(*childP)->wp_size = PaneInfo(*childP)->preferred_size;
14177a84e134Smrg	    else {
14187a84e134Smrg		if(vert) {
14197a84e134Smrg		    request.request_mode = CWWidth;
14205ec34c4cSmrg		    request.width = (Dimension) off_size;
14217a84e134Smrg		}
14227a84e134Smrg		else {
14237a84e134Smrg		    request.request_mode = CWHeight;
14245ec34c4cSmrg		    request.height = (Dimension) off_size;
14257a84e134Smrg		}
14267a84e134Smrg
14277a84e134Smrg		if ((XtQueryGeometry(*childP, &request, &reply)
14287a84e134Smrg		     == XtGeometryAlmost)
14297a84e134Smrg		    && (reply.request_mode = (vert ? CWHeight : CWWidth)))
14307a84e134Smrg		    PaneInfo(*childP)->wp_size = GetRequestInfo(&reply, vert);
14317a84e134Smrg		else
14327a84e134Smrg		    PaneInfo(*childP)->wp_size = PaneSize(*childP, vert);
14337a84e134Smrg	    }
14347a84e134Smrg
14357a84e134Smrg	    PaneInfo(*childP)->size = PaneInfo(*childP)->wp_size;
14367a84e134Smrg	}
14377a84e134Smrg}
14387a84e134Smrg
14397a84e134Smrg/*
14407a84e134Smrg * Function:
14417a84e134Smrg *	ChangeAllGripCursors
14427a84e134Smrg *
14437a84e134Smrg * Parameters:
14447a84e134Smrg *	pw - paned widget
14457a84e134Smrg *
14467a84e134Smrg *	Description:
14477a84e134Smrg *	Changes all the grip cursors.
14487a84e134Smrg */
14497a84e134Smrgstatic void
14507a84e134SmrgChangeAllGripCursors(PanedWidget pw)
14517a84e134Smrg{
14527a84e134Smrg    Widget *childP;
14537a84e134Smrg
14547a84e134Smrg    ForAllPanes(pw, childP) {
14557a84e134Smrg	Arg arglist[1];
14567a84e134Smrg	Cursor cursor;
1457421c997bSmrg
14587a84e134Smrg	if ((cursor = pw->paned.grip_cursor) == None) {
14597a84e134Smrg	    if (IsVert(pw))
14607a84e134Smrg		cursor = pw->paned.v_grip_cursor;
14617a84e134Smrg	    else
14627a84e134Smrg		cursor = pw->paned.h_grip_cursor;
14637a84e134Smrg	}
14647a84e134Smrg
14657a84e134Smrg	if (HasGrip(*childP)) {
14667a84e134Smrg	    XtSetArg(arglist[0], XtNcursor, cursor);
14677a84e134Smrg	    XtSetValues(PaneInfo(*childP)->grip, arglist, 1);
14687a84e134Smrg	}
14697a84e134Smrg    }
14707a84e134Smrg}
1471421c997bSmrg
14727a84e134Smrg/*
14737a84e134Smrg * Function:
14747a84e134Smrg *	PushPaneStack
14757a84e134Smrg *
14767a84e134Smrg * Parameters:
14777a84e134Smrg *	pw   - paned widget
14787a84e134Smrg *	pane - pane that we are pushing
14797a84e134Smrg *
14807a84e134Smrg * Description:
14817a84e134Smrg *	Pushes a value onto the pane stack.
14827a84e134Smrg */
14837a84e134Smrgstatic void
14847a84e134SmrgPushPaneStack(PanedWidget pw, Pane pane)
14857a84e134Smrg{
14867a84e134Smrg    PaneStack *stack = (PaneStack *)XtMalloc(sizeof(PaneStack));
14877a84e134Smrg
14887a84e134Smrg    stack->next = pw->paned.stack;
14897a84e134Smrg    stack->pane = pane;
14907a84e134Smrg    stack->start_size = pane->size;
14917a84e134Smrg
14927a84e134Smrg    pw->paned.stack = stack;
14937a84e134Smrg}
14947a84e134Smrg
14957a84e134Smrg/*
14967a84e134Smrg * Function:
14977a84e134Smrg *	GetPaneStack
14987a84e134Smrg *
14997a84e134Smrg * Parameters:
15007a84e134Smrg *	pw - paned widget
15017a84e134Smrg *	shrink	   - True if we want to shrink this pane, False otherwise
15027a84e134Smrg *	pane	   - pane that we are popping (return)
15037a84e134Smrg *	start_size - size that this pane started at (return)
15047a84e134Smrg *
15057a84e134Smrg * Description:
15067a84e134Smrg *	Gets the top value from the pane stack.
15077a84e134Smrg */
15087a84e134Smrgstatic void
15097a84e134SmrgGetPaneStack(PanedWidget pw, Bool shrink, Pane *pane, int *start_size)
15107a84e134Smrg{
15117a84e134Smrg    if (pw->paned.stack == NULL) {
1512421c997bSmrg	*pane = NULL;
15137a84e134Smrg	return;
15147a84e134Smrg    }
15157a84e134Smrg
15167a84e134Smrg    *pane = pw->paned.stack->pane;
15177a84e134Smrg    *start_size = pw->paned.stack->start_size;
15187a84e134Smrg
15197a84e134Smrg    if (shrink != ((*pane)->size > *start_size))
15207a84e134Smrg	*pane = NULL;
15217a84e134Smrg}
15227a84e134Smrg
15237a84e134Smrg/*
15247a84e134Smrg * Function:
15257a84e134Smrg *	PopPaneStack
15267a84e134Smrg *
15277a84e134Smrg * Parameters:
15287a84e134Smrg *	pw - paned widget
15297a84e134Smrg *
15307a84e134Smrg * Description:
15317a84e134Smrg *	Pops the top item off the pane stack.
15327a84e134Smrg *
15337a84e134Smrg * Returns: True if this is not the last element on the stack
15347a84e134Smrg */
15357a84e134Smrgstatic Bool
15367a84e134SmrgPopPaneStack(PanedWidget pw)
15377a84e134Smrg{
15387a84e134Smrg    PaneStack *stack = pw->paned.stack;
15397a84e134Smrg
15407a84e134Smrg    if (stack == NULL)
15417a84e134Smrg	return (False);
15427a84e134Smrg
15437a84e134Smrg    pw->paned.stack = stack->next;
15447a84e134Smrg    XtFree((char *)stack);
15457a84e134Smrg
15467a84e134Smrg    if (pw->paned.stack == NULL)
15477a84e134Smrg	return (False);
15487a84e134Smrg
15497a84e134Smrg    return (True);
15507a84e134Smrg}
15517a84e134Smrg
15527a84e134Smrg/*
15537a84e134Smrg * Function:
15547a84e134Smrg *	ClearPaneStack
15557a84e134Smrg *
15567a84e134Smrg * Parameters:
15577a84e134Smrg *	pw - paned widget
15587a84e134Smrg *
15597a84e134Smrg * Description:
15607a84e134Smrg *	Removes all entries from the pane stack.
15617a84e134Smrg */
15627a84e134Smrgstatic void
15637a84e134SmrgClearPaneStack(PanedWidget pw)
15647a84e134Smrg{
15657a84e134Smrg    while(PopPaneStack(pw))
15667a84e134Smrg	;
15677a84e134Smrg}
15687a84e134Smrg
1569421c997bSmrgstatic void
15707a84e134SmrgXawPanedClassInitialize(void)
15717a84e134Smrg{
15727a84e134Smrg    XawInitializeWidgetSet();
15737a84e134Smrg    XtAddConverter(XtRString, XtROrientation, XmuCvtStringToOrientation,
15747a84e134Smrg		   NULL, 0);
15757a84e134Smrg    XtSetTypeConverter(XtROrientation, XtRString, XmuCvtOrientationToString,
15767a84e134Smrg		       NULL, 0, XtCacheNone, NULL);
15777a84e134Smrg}
15787a84e134Smrg
15797a84e134Smrg/* The Geometry Manager only allows changes after Realize if
1580421c997bSmrg * allow_resize is True in the constraints record.
1581421c997bSmrg *
15827a84e134Smrg * For vertically paned widgets:
15837a84e134Smrg *
15847a84e134Smrg * It only allows height changes, but offers the requested height
15857a84e134Smrg * as a compromise if both width and height changes were requested.
15867a84e134Smrg *
15877a84e134Smrg * For horizontal widgets the converse is true.
15887a84e134Smrg * As all good Geometry Managers should, we will return No if the
15897a84e134Smrg * request will have no effect; i.e. when the requestor is already
15907a84e134Smrg * of the desired geometry.
15917a84e134Smrg */
15927a84e134Smrgstatic XtGeometryResult
15937a84e134SmrgXawPanedGeometryManager(Widget w, XtWidgetGeometry *request,
15947a84e134Smrg			XtWidgetGeometry *reply)
15957a84e134Smrg{
15967a84e134Smrg    PanedWidget pw = (PanedWidget)XtParent(w);
15977a84e134Smrg    XtGeometryMask mask = request->request_mode;
15987a84e134Smrg    Dimension old_size, old_wpsize, old_paned_size;
15997a84e134Smrg    Pane pane = PaneInfo(w);
16007a84e134Smrg    Boolean vert = IsVert(pw);
16017a84e134Smrg    Dimension on_size, off_size;
16027a84e134Smrg    XtGeometryResult result;
16037a84e134Smrg    Boolean almost = False;
16047a84e134Smrg
16057a84e134Smrg    /*
16067a84e134Smrg     * If any of the following is true, disallow the geometry change
16077a84e134Smrg     *
16087a84e134Smrg     * o The paned widget is realized and allow_resize is false for the pane
16097a84e134Smrg     * o The child did not ask to change the on_size
16107a84e134Smrg     * o The request is not a width or height request
16117a84e134Smrg     * o The requested size is the same as the current size
16127a84e134Smrg     */
16137a84e134Smrg
16147a84e134Smrg    if ((XtIsRealized((Widget)pw) && !pane->allow_resize)
16157a84e134Smrg	|| !(mask & (vert ? CWHeight : CWWidth))
16165ec34c4cSmrg	|| (mask & (XtGeometryMask)(~(CWWidth | CWHeight)))
16177a84e134Smrg	|| GetRequestInfo(request, vert) ==  PaneSize(w, vert))
16187a84e134Smrg	return (XtGeometryNo);
16197a84e134Smrg
16207a84e134Smrg    old_paned_size = PaneSize((Widget)pw, vert);
16217a84e134Smrg    old_wpsize = pane->wp_size;
16225ec34c4cSmrg    old_size = (Dimension)pane->size;
16237a84e134Smrg
16245ec34c4cSmrg    pane->wp_size = (Dimension)(pane->size = GetRequestInfo(request, vert));
16257a84e134Smrg
16267a84e134Smrg    AdjustPanedSize(pw, PaneSize((Widget)pw, !vert), &result, &on_size,
16277a84e134Smrg		    &off_size);
16287a84e134Smrg
16297a84e134Smrg    /*
16307a84e134Smrg     * Fool the Refigure Locations proc to thinking that we are
16317a84e134Smrg     * a different on_size
16327a84e134Smrg     */
16337a84e134Smrg
16347a84e134Smrg    if (result != XtGeometryNo) {
1635421c997bSmrg	if (vert)
16367a84e134Smrg	    XtHeight(pw) = on_size;
1637421c997bSmrg	else
16387a84e134Smrg	    XtWidth(pw) = on_size;
16397a84e134Smrg    }
16407a84e134Smrg
16417a84e134Smrg    RefigureLocations(pw, PaneIndex(w), AnyPane);
16427a84e134Smrg
16437a84e134Smrg    /*
16447a84e134Smrg     * Set up reply struct and reset core on_size
16457a84e134Smrg     */
16467a84e134Smrg    if (vert) {
16477a84e134Smrg	XtHeight(pw) = old_paned_size;
16485ec34c4cSmrg	reply->height = (Dimension) pane->size;
16497a84e134Smrg	reply->width = off_size;
16507a84e134Smrg    }
16517a84e134Smrg    else {
16527a84e134Smrg	XtWidth(pw) = old_paned_size;
16537a84e134Smrg	reply->height = off_size;
16545ec34c4cSmrg	reply->width = (Dimension) pane->size;
1655421c997bSmrg    }
16567a84e134Smrg
16577a84e134Smrg    /*
16587a84e134Smrg     * IF either of the following is true
16597a84e134Smrg     *
16607a84e134Smrg     * o There was a "off_size" request and the new "off_size" is different
16617a84e134Smrg     *   from that requested
16627a84e134Smrg     * o There was no "off_size" request and the new "off_size" is different
1663421c997bSmrg     *
16647a84e134Smrg     * o The "on_size" we will allow is different from that requested
1665421c997bSmrg     *
16667a84e134Smrg     * THEN: set almost
16677a84e134Smrg     */
16687a84e134Smrg    if (!((vert ? CWWidth : CWHeight) & mask)) {
1669421c997bSmrg	if (vert)
16707a84e134Smrg	    request->width = XtWidth(w);
16717a84e134Smrg	else
16727a84e134Smrg	    request->height = XtHeight(w);
16737a84e134Smrg    }
16747a84e134Smrg
16757a84e134Smrg    almost = GetRequestInfo(request, !vert) != GetRequestInfo(reply, !vert);
16765ec34c4cSmrg    almost = (Boolean)(almost | (GetRequestInfo(request, vert) != GetRequestInfo(reply, vert)));
16777a84e134Smrg
16787a84e134Smrg    if ((mask & XtCWQueryOnly) || almost) {
16797a84e134Smrg	pane->wp_size = old_wpsize;
16807a84e134Smrg	pane->size = old_size;
16817a84e134Smrg	RefigureLocations(pw, PaneIndex(w), AnyPane);
16827a84e134Smrg	reply->request_mode = CWWidth | CWHeight;
16837a84e134Smrg	if (almost)
16847a84e134Smrg	    return (XtGeometryAlmost);
16857a84e134Smrg    }
16867a84e134Smrg    else {
16877a84e134Smrg	AdjustPanedSize(pw, PaneSize((Widget) pw, !vert), NULL, NULL, NULL);
16887a84e134Smrg	CommitNewLocations(pw);		/* layout already refigured */
16897a84e134Smrg    }
16907a84e134Smrg
16917a84e134Smrg    return (XtGeometryDone);
16927a84e134Smrg}
16937a84e134Smrg
16947a84e134Smrg/*ARGSUSED*/
16957a84e134Smrgstatic void
16965ec34c4cSmrgXawPanedInitialize(Widget request _X_UNUSED, Widget cnew,
16975ec34c4cSmrg		   ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
16987a84e134Smrg{
16997a84e134Smrg    PanedWidget pw = (PanedWidget)cnew;
17007a84e134Smrg
17017a84e134Smrg    GetGCs((Widget)pw);
17027a84e134Smrg
17037a84e134Smrg    pw->paned.recursively_called = False;
17047a84e134Smrg    pw->paned.stack = NULL;
17057a84e134Smrg    pw->paned.resize_children_to_pref = True;
17067a84e134Smrg    pw->paned.num_panes = 0;
17077a84e134Smrg}
17087a84e134Smrg
1709421c997bSmrgstatic void
17107a84e134SmrgXawPanedRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
17117a84e134Smrg{
17127a84e134Smrg    PanedWidget pw = (PanedWidget)w;
17137a84e134Smrg    Widget *childP;
17147a84e134Smrg
17157a84e134Smrg    if ((attributes->cursor = pw->paned.cursor) != None)
17167a84e134Smrg	*valueMask |= CWCursor;
17177a84e134Smrg
17187a84e134Smrg    (*SuperClass->core_class.realize)(w, valueMask, attributes);
17197a84e134Smrg
17207a84e134Smrg    /*
17217a84e134Smrg     * Before we commit the new locations we need to realize all the panes and
17227a84e134Smrg     * their grips
17237a84e134Smrg     */
17247a84e134Smrg    ForAllPanes(pw, childP) {
17257a84e134Smrg	XtRealizeWidget(*childP);
17267a84e134Smrg	if (HasGrip(*childP))
17277a84e134Smrg	    XtRealizeWidget(PaneInfo(*childP)->grip);
17287a84e134Smrg    }
17297a84e134Smrg
17307a84e134Smrg    RefigureLocationsAndCommit(w);
17317a84e134Smrg    pw->paned.resize_children_to_pref = False;
17327a84e134Smrg}
17337a84e134Smrg
1734421c997bSmrgstatic void
17357a84e134SmrgXawPanedDestroy(Widget w)
17367a84e134Smrg{
17377a84e134Smrg    ReleaseGCs(w);
17387a84e134Smrg}
17397a84e134Smrg
17407a84e134Smrgstatic void
17417a84e134SmrgReleaseGCs(Widget w)
17427a84e134Smrg{
17437a84e134Smrg    PanedWidget pw = (PanedWidget)w;
17447a84e134Smrg
17457a84e134Smrg    XtReleaseGC(w, pw->paned.normgc);
17467a84e134Smrg    XtReleaseGC(w, pw->paned.invgc);
17477a84e134Smrg    XtReleaseGC(w, pw->paned.flipgc);
1748421c997bSmrg}
17497a84e134Smrg
17507a84e134Smrgstatic void
17517a84e134SmrgXawPanedInsertChild(Widget w)
17527a84e134Smrg{
17537a84e134Smrg    Pane pane = PaneInfo(w);
17547a84e134Smrg
17557a84e134Smrg    /* insert the child widget in the composite children list with the
17567a84e134Smrg       superclass insert_child routine
17577a84e134Smrg     */
17587a84e134Smrg    (*SuperClass->composite_class.insert_child)(w);
17597a84e134Smrg
17607a84e134Smrg    if (!IsPane(w))
17617a84e134Smrg	return;
17627a84e134Smrg
17637a84e134Smrg    if (pane->show_grip == True) {
17647a84e134Smrg	CreateGrip(w);
1765421c997bSmrg	if (pane->min == PANED_GRIP_SIZE)
17667a84e134Smrg	    pane->min = PaneSize(pane->grip, IsVert((PanedWidget)XtParent(w)));
17677a84e134Smrg    }
17687a84e134Smrg    else {
17697a84e134Smrg	if (pane->min == PANED_GRIP_SIZE)
17707a84e134Smrg	    pane->min = 1;
17717a84e134Smrg	pane->grip = NULL;
17727a84e134Smrg    }
17737a84e134Smrg
17747a84e134Smrg    pane->size = 0;
17757a84e134Smrg    pane->paned_adjusted_me = False;
17767a84e134Smrg}
17777a84e134Smrg
17787a84e134Smrgstatic void
17797a84e134SmrgXawPanedDeleteChild(Widget w)
17807a84e134Smrg{
17817a84e134Smrg    /* remove the subwidget info and destroy the grip */
17827a84e134Smrg    if (IsPane(w) && HasGrip(w))
17837a84e134Smrg	XtDestroyWidget(PaneInfo(w)->grip);
1784421c997bSmrg
17857a84e134Smrg    /* delete the child widget in the composite children list with the
17867a84e134Smrg       superclass delete_child routine
17877a84e134Smrg     */
17887a84e134Smrg    (*SuperClass->composite_class.delete_child)(w);
17897a84e134Smrg}
17907a84e134Smrg
17917a84e134Smrgstatic void
17927a84e134SmrgXawPanedChangeManaged(Widget w)
17937a84e134Smrg{
17947a84e134Smrg    PanedWidget pw = (PanedWidget)w;
17957a84e134Smrg    Boolean vert = IsVert(pw);
17967a84e134Smrg    Dimension size;
17977a84e134Smrg    Widget *childP;
17987a84e134Smrg
17997a84e134Smrg    if (pw->paned.recursively_called++)
18007a84e134Smrg	return;
18017a84e134Smrg
18027a84e134Smrg    /*
18037a84e134Smrg     * If the size is zero then set it to the size of the widest or tallest pane
18047a84e134Smrg     */
18057a84e134Smrg
18067a84e134Smrg    if ((size = PaneSize((Widget)pw, !vert)) == 0) {
18077a84e134Smrg	size = 1;
18087a84e134Smrg	ForAllChildren(pw, childP)
18097a84e134Smrg	if (XtIsManaged(*childP) && (PaneSize(*childP, !vert) > size))
18107a84e134Smrg	    size = PaneSize(*childP, !vert);
18117a84e134Smrg    }
18127a84e134Smrg
18137a84e134Smrg    ManageAndUnmanageGrips(pw);
18147a84e134Smrg    pw->paned.recursively_called = False;
1815421c997bSmrg    ResortChildren(pw);
18167a84e134Smrg
18177a84e134Smrg    pw->paned.num_panes = 0;
18187a84e134Smrg    ForAllChildren(pw, childP)
18197a84e134Smrg	if (IsPane(*childP)) {
18207a84e134Smrg	    if (XtIsManaged(*childP)) {
18217a84e134Smrg		Pane pane = PaneInfo(*childP);
18227a84e134Smrg
18237a84e134Smrg		if (HasGrip(*childP))
18247a84e134Smrg		    PaneInfo(pane->grip)->position = pw->paned.num_panes;
18255b16253fSmrg		pane->position = pw->paned.num_panes; /* TEMPORARY -CDP 3/89 */
18267a84e134Smrg		pw->paned.num_panes++;
18277a84e134Smrg	    }
18287a84e134Smrg	    else
1829421c997bSmrg		break;		 /* This list is already sorted */
18307a84e134Smrg	}
18317a84e134Smrg
18327a84e134Smrg    SetChildrenPrefSizes((PanedWidget) w, size);
18337a84e134Smrg
18347a84e134Smrg    /*
18357a84e134Smrg     * ForAllPanes can now be used
18367a84e134Smrg     */
18377a84e134Smrg    if (PaneSize((Widget) pw, vert) == 0)
18387a84e134Smrg	AdjustPanedSize(pw, size, NULL, NULL, NULL);
18397a84e134Smrg
18407a84e134Smrg    if (XtIsRealized((Widget)pw))
18417a84e134Smrg	RefigureLocationsAndCommit((Widget)pw);
18427a84e134Smrg}
18437a84e134Smrg
18447a84e134Smrgstatic void
18457a84e134SmrgXawPanedResize(Widget w)
18467a84e134Smrg{
18477a84e134Smrg    SetChildrenPrefSizes((PanedWidget)w,
18487a84e134Smrg			 PaneSize(w, !IsVert((PanedWidget)w)));
18497a84e134Smrg    RefigureLocationsAndCommit(w);
18507a84e134Smrg}
18517a84e134Smrg
18527a84e134Smrg/*ARGSUSED*/
18537a84e134Smrgstatic void
18545ec34c4cSmrgXawPanedRedisplay(Widget w, XEvent *event _X_UNUSED, Region region _X_UNUSED)
18557a84e134Smrg{
18567a84e134Smrg    DrawInternalBorders((PanedWidget)w);
18577a84e134Smrg}
18587a84e134Smrg
18597a84e134Smrg/*ARGSUSED*/
1860421c997bSmrgstatic Boolean
18615ec34c4cSmrgXawPanedSetValues(Widget old, Widget request _X_UNUSED, Widget cnew,
18625ec34c4cSmrg		  ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
18637a84e134Smrg{
18647a84e134Smrg    PanedWidget old_pw = (PanedWidget)old;
18657a84e134Smrg    PanedWidget new_pw = (PanedWidget)cnew;
18667a84e134Smrg    Boolean redisplay = False;
18677a84e134Smrg
18687a84e134Smrg    if ((old_pw->paned.cursor != new_pw->paned.cursor) && XtIsRealized(cnew))
18697a84e134Smrg	XDefineCursor(XtDisplay(cnew), XtWindow(cnew), new_pw->paned.cursor);
18707a84e134Smrg
18717a84e134Smrg    if (old_pw->paned.internal_bp != new_pw->paned.internal_bp ||
18727a84e134Smrg	old_pw->core.background_pixel != new_pw->core.background_pixel) {
18737a84e134Smrg	ReleaseGCs(old);
18747a84e134Smrg	GetGCs(cnew);
18757a84e134Smrg	redisplay = True;
18767a84e134Smrg    }
18777a84e134Smrg
18787a84e134Smrg    if (old_pw->paned.grip_cursor != new_pw->paned.grip_cursor ||
18797a84e134Smrg	old_pw->paned.v_grip_cursor != new_pw->paned.v_grip_cursor ||
18807a84e134Smrg	old_pw->paned.h_grip_cursor != new_pw->paned.h_grip_cursor)
18817a84e134Smrg	ChangeAllGripCursors(new_pw);
1882421c997bSmrg
18837a84e134Smrg    if (IsVert(old_pw) != IsVert(new_pw)) {
18847a84e134Smrg	/*
18857a84e134Smrg	 * We are fooling the paned widget into thinking that is needs to
18867a84e134Smrg	 * fully refigure everything, which is what we want
18877a84e134Smrg	 */
18887a84e134Smrg	if (IsVert(new_pw))
18897a84e134Smrg	    XtWidth(new_pw) = 0;
18907a84e134Smrg	else
18917a84e134Smrg	    XtHeight(new_pw) = 0;
18927a84e134Smrg
18937a84e134Smrg	new_pw->paned.resize_children_to_pref = True;
18947a84e134Smrg	XawPanedChangeManaged(cnew); /* Seems weird, but does the right thing */
18957a84e134Smrg	new_pw->paned.resize_children_to_pref = False;
18967a84e134Smrg	if (new_pw->paned.grip_cursor == None)
18977a84e134Smrg	    ChangeAllGripCursors(new_pw);
18987a84e134Smrg	return (True);
18997a84e134Smrg    }
19007a84e134Smrg
19017a84e134Smrg    if (old_pw->paned.internal_bw != new_pw->paned.internal_bw) {
19027a84e134Smrg	AdjustPanedSize(new_pw, PaneSize(cnew, !IsVert(old_pw)),
19037a84e134Smrg		        NULL, NULL, NULL);
19047a84e134Smrg	RefigureLocationsAndCommit(cnew);
19057a84e134Smrg	return (True);		/* We have done a full configuration, return */
19067a84e134Smrg    }
1907421c997bSmrg
19087a84e134Smrg    if (old_pw->paned.grip_indent != new_pw->paned.grip_indent &&
19097a84e134Smrg	XtIsRealized(cnew)) {
19107a84e134Smrg	CommitNewLocations(new_pw);
19117a84e134Smrg	redisplay = True;
19127a84e134Smrg    }
19137a84e134Smrg
19147a84e134Smrg    return (redisplay);
19157a84e134Smrg}
19167a84e134Smrg
19177a84e134Smrg/*ARGSUSED*/
1918421c997bSmrgstatic Boolean
19195ec34c4cSmrgXawPanedPaneSetValues(Widget old, Widget request _X_UNUSED, Widget cnew,
19205ec34c4cSmrg		      ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
19217a84e134Smrg{
19227a84e134Smrg    Pane old_pane = PaneInfo(old);
19237a84e134Smrg    Pane new_pane = PaneInfo(cnew);
19247a84e134Smrg    Boolean redisplay = False;
19257a84e134Smrg
19267a84e134Smrg    /* Check for new min and max */
19277a84e134Smrg    if (old_pane->min != new_pane->min || old_pane->max != new_pane->max)
19287a84e134Smrg	XawPanedSetMinMax(cnew, (int)new_pane->min, (int)new_pane->max);
19297a84e134Smrg
19307a84e134Smrg    /* Check for change in XtNshowGrip */
19317a84e134Smrg    if (old_pane->show_grip != new_pane->show_grip) {
19327a84e134Smrg	if (new_pane->show_grip == True) {
19337a84e134Smrg	    CreateGrip(cnew);
19347a84e134Smrg	    if (XtIsRealized(XtParent(cnew))) {
19357a84e134Smrg		if (XtIsManaged(cnew))	/* if paned is unrealized this will
19367a84e134Smrg					   happen automatically at realize time
19377a84e134Smrg					 */
19387a84e134Smrg		    XtManageChild(PaneInfo(cnew)->grip);	/* manage the grip */
19397a84e134Smrg		XtRealizeWidget(PaneInfo(cnew)->grip); /* realize the grip */
19407a84e134Smrg		CommitNewLocations((PanedWidget)XtParent(cnew));
19417a84e134Smrg	    }
19427a84e134Smrg	}
19437a84e134Smrg	else if (HasGrip(old)) {
19447a84e134Smrg	    XtDestroyWidget(old_pane->grip);
19457a84e134Smrg	    new_pane->grip = NULL;
19467a84e134Smrg	    redisplay = True;
19477a84e134Smrg	}
19487a84e134Smrg    }
19497a84e134Smrg
19507a84e134Smrg    return (redisplay);
19517a84e134Smrg}
19527a84e134Smrg
19537a84e134Smrg/*
19547a84e134Smrg * Public routines
19557a84e134Smrg */
19567a84e134Smrg/*
19577a84e134Smrg * Function:
19587a84e134Smrg *	XawPanedSetMinMax
19597a84e134Smrg *
19607a84e134Smrg * Parameters:
19617a84e134Smrg *	widget - widget that is a child of the Paned widget
19627a84e134Smrg *	min    - new min and max size for the pane
19637a84e134Smrg *	max    - ""
19647a84e134Smrg *
19657a84e134Smrg * Description:
19667a84e134Smrg *	Sets the min and max size for a pane.
19677a84e134Smrg */
1968421c997bSmrgvoid
19697a84e134SmrgXawPanedSetMinMax(Widget widget, int min, int max)
19707a84e134Smrg{
19717a84e134Smrg    Pane pane = PaneInfo(widget);
19727a84e134Smrg
19735ec34c4cSmrg    pane->min = (Dimension) min;
19745ec34c4cSmrg    pane->max = (Dimension) max;
19757a84e134Smrg    RefigureLocationsAndCommit(widget->core.parent);
19767a84e134Smrg}
19777a84e134Smrg
19787a84e134Smrg/*
19797a84e134Smrg * Function:
19807a84e134Smrg *	XawPanedGetMinMax
19817a84e134Smrg *
19827a84e134Smrg * Parameters:
19837a84e134Smrg *	widget - widget that is a child of the Paned widget
19847a84e134Smrg *	min    - current min and max size for the pane (return)
19857a84e134Smrg *	max    - ""
19867a84e134Smrg *
19877a84e134Smrg * Description:
19887a84e134Smrg *	Gets the min and max size for a pane.
19897a84e134Smrg */
1990421c997bSmrgvoid
19917a84e134SmrgXawPanedGetMinMax(Widget widget, int *min, int *max)
19927a84e134Smrg{
19937a84e134Smrg    Pane pane = PaneInfo(widget);
19947a84e134Smrg
19957a84e134Smrg    *min = pane->min;
19967a84e134Smrg    *max = pane->max;
19977a84e134Smrg}
19987a84e134Smrg
19997a84e134Smrg/*
20007a84e134Smrg * Function:
20017a84e134Smrg *	XawPanedSetRefigureMode
20027a84e134Smrg *
20037a84e134Smrg * Parameters:
20047a84e134Smrg *	w    - paned widget
20057a84e134Smrg *	mode - if False then inhibit refigure
20067a84e134Smrg *
20077a84e134Smrg * Description:
20087a84e134Smrg *	Allows a flag to be set the will inhibit
20097a84e134Smrg *		   the paned widgets relayout routine.
20107a84e134Smrg */
2011421c997bSmrgvoid
20127a84e134SmrgXawPanedSetRefigureMode(Widget w,
20137a84e134Smrg#if NeedWidePrototypes
20147a84e134Smrg	int mode
20157a84e134Smrg#else
20167a84e134Smrg	Boolean mode
20177a84e134Smrg#endif
20187a84e134Smrg)
20197a84e134Smrg{
20207a84e134Smrg    ((PanedWidget)w)->paned.refiguremode = mode;
20217a84e134Smrg    RefigureLocationsAndCommit(w);
20227a84e134Smrg}
20237a84e134Smrg
20247a84e134Smrg/*
20257a84e134Smrg * Function:
20267a84e134Smrg *	XawPanedGetNumSub
20277a84e134Smrg *
20287a84e134Smrg * Parameters:
20297a84e134Smrg *	w - paned widget
20307a84e134Smrg *
20317a84e134Smrg * Description:
20327a84e134Smrg *	Returns the number of panes in the paned widget.
20337a84e134Smrg * Returns:
20347a84e134Smrg *	the number of panes in the paned widget
20357a84e134Smrg */
2036421c997bSmrgint
20377a84e134SmrgXawPanedGetNumSub(Widget w)
20387a84e134Smrg{
20397a84e134Smrg    return (((PanedWidget)w)->paned.num_panes);
20407a84e134Smrg}
20417a84e134Smrg
20427a84e134Smrg/*
20437a84e134Smrg * Function:
20447a84e134Smrg *	XawPanedAllowResize
20457a84e134Smrg *
20467a84e134Smrg * Parameters:
20477a84e134Smrg *	widget - child of the paned widget
20487a84e134Smrg *
20497a84e134Smrg * Description:
20507a84e134Smrg *	  Allows a flag to be set that determines if the paned
20517a84e134Smrg *	widget will allow geometry requests from this child.
20527a84e134Smrg */
2053421c997bSmrgvoid
20547a84e134SmrgXawPanedAllowResize(Widget widget,
20557a84e134Smrg#if NeedWidePrototypes
20567a84e134Smrg	int allow_resize
20577a84e134Smrg#else
20587a84e134Smrg	Boolean allow_resize
20597a84e134Smrg#endif
20607a84e134Smrg)
20617a84e134Smrg{
20627a84e134Smrg    PaneInfo(widget)->allow_resize = allow_resize;
20637a84e134Smrg}
2064