Form.c revision 749
749N/A/* $XConsortium: Form.c,v 1.52 94/04/17 20:12:06 kaleb Exp $ */
749N/A
749N/A/***********************************************************
749N/A
749N/ACopyright (c) 1987, 1988, 1994 X Consortium
749N/A
749N/APermission is hereby granted, free of charge, to any person obtaining a copy
749N/Aof this software and associated documentation files (the "Software"), to deal
749N/Ain the Software without restriction, including without limitation the rights
749N/Ato use, copy, modify, merge, publish, distribute, sublicense, and/or sell
749N/Acopies of the Software, and to permit persons to whom the Software is
749N/Afurnished to do so, subject to the following conditions:
749N/A
749N/AThe above copyright notice and this permission notice shall be included in
749N/Aall copies or substantial portions of the Software.
749N/A
749N/ATHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
749N/AIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
749N/AFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
749N/AX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
749N/AAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
749N/ACONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
749N/A
749N/AExcept as contained in this notice, the name of the X Consortium shall not be
749N/Aused in advertising or otherwise to promote the sale, use or other dealings
749N/Ain this Software without prior written authorization from the X Consortium.
749N/A
749N/A
749N/ACopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
749N/A
749N/A All Rights Reserved
749N/A
749N/APermission to use, copy, modify, and distribute this software and its
749N/Adocumentation for any purpose and without fee is hereby granted,
749N/Aprovided that the above copyright notice appear in all copies and that
749N/Aboth that copyright notice and this permission notice appear in
749N/Asupporting documentation, and that the name of Digital not be
749N/Aused in advertising or publicity pertaining to distribution of the
749N/Asoftware without specific, written prior permission.
749N/A
749N/ADIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
749N/AALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
749N/ADIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
749N/AANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
749N/AWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
749N/AARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
749N/ASOFTWARE.
749N/A
749N/A******************************************************************/
749N/A
749N/A#include <X11/IntrinsicP.h>
749N/A#include <X11/StringDefs.h>
749N/A#include <X11/Xmu/Converters.h>
749N/A#include <X11/Xmu/CharSet.h>
749N/A#include <X11/Xaw/XawInit.h>
749N/A#include <X11/Xaw/FormP.h>
749N/A
749N/A/* Private Definitions */
749N/A
749N/Astatic int default_value = -99999;
749N/A
749N/A#define Offset(field) XtOffsetOf(FormRec, form.field)
749N/Astatic XtResource resources[] = {
749N/A {XtNdefaultDistance, XtCThickness, XtRInt, sizeof(int),
749N/A Offset(default_spacing), XtRImmediate, (XtPointer)4}
749N/A};
749N/A#undef Offset
749N/A
749N/Astatic XtEdgeType defEdge = XtRubber;
749N/A
749N/A#define Offset(field) XtOffsetOf(FormConstraintsRec, form.field)
749N/Astatic XtResource formConstraintResources[] = {
749N/A {XtNtop, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
749N/A Offset(top), XtREdgeType, (XtPointer)&defEdge},
749N/A {XtNbottom, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
749N/A Offset(bottom), XtREdgeType, (XtPointer)&defEdge},
749N/A {XtNleft, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
749N/A Offset(left), XtREdgeType, (XtPointer)&defEdge},
749N/A {XtNright, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
749N/A Offset(right), XtREdgeType, (XtPointer)&defEdge},
749N/A {XtNhorizDistance, XtCThickness, XtRInt, sizeof(int),
749N/A Offset(dx), XtRInt, (XtPointer) &default_value},
749N/A {XtNfromHoriz, XtCWidget, XtRWidget, sizeof(Widget),
749N/A Offset(horiz_base), XtRWidget, (XtPointer)NULL},
749N/A {XtNvertDistance, XtCThickness, XtRInt, sizeof(int),
749N/A Offset(dy), XtRInt, (XtPointer) &default_value},
749N/A {XtNfromVert, XtCWidget, XtRWidget, sizeof(Widget),
749N/A Offset(vert_base), XtRWidget, (XtPointer)NULL},
749N/A {XtNresizable, XtCBoolean, XtRBoolean, sizeof(Boolean),
749N/A Offset(allow_resize), XtRImmediate, (XtPointer) FALSE},
749N/A};
749N/A#undef Offset
749N/A
749N/Astatic void ClassInitialize(), ClassPartInitialize(), Initialize(), Resize();
749N/Astatic void ConstraintInitialize();
749N/Astatic Boolean SetValues(), ConstraintSetValues();
749N/Astatic XtGeometryResult GeometryManager(), PreferredGeometry();
749N/Astatic void ChangeManaged();
749N/Astatic Boolean Layout();
749N/A
749N/Astatic void LayoutChild(), ResizeChildren();
749N/A
749N/AFormClassRec formClassRec = {
749N/A { /* core_class fields */
749N/A /* superclass */ (WidgetClass) &constraintClassRec,
749N/A /* class_name */ "Form",
749N/A /* widget_size */ sizeof(FormRec),
749N/A /* class_initialize */ ClassInitialize,
749N/A /* class_part_init */ ClassPartInitialize,
749N/A /* class_inited */ FALSE,
749N/A /* initialize */ Initialize,
749N/A /* initialize_hook */ NULL,
749N/A /* realize */ XtInheritRealize,
749N/A /* actions */ NULL,
749N/A /* num_actions */ 0,
749N/A /* resources */ resources,
749N/A /* num_resources */ XtNumber(resources),
749N/A /* xrm_class */ NULLQUARK,
749N/A /* compress_motion */ TRUE,
749N/A /* compress_exposure */ TRUE,
749N/A /* compress_enterleave*/ TRUE,
749N/A /* visible_interest */ FALSE,
749N/A /* destroy */ NULL,
749N/A /* resize */ Resize,
749N/A /* expose */ XtInheritExpose,
749N/A /* set_values */ SetValues,
749N/A /* set_values_hook */ NULL,
749N/A /* set_values_almost */ XtInheritSetValuesAlmost,
749N/A /* get_values_hook */ NULL,
749N/A /* accept_focus */ NULL,
749N/A /* version */ XtVersion,
749N/A /* callback_private */ NULL,
749N/A /* tm_table */ NULL,
749N/A /* query_geometry */ PreferredGeometry,
749N/A /* display_accelerator*/ XtInheritDisplayAccelerator,
749N/A /* extension */ NULL
749N/A },
749N/A { /* composite_class fields */
749N/A /* geometry_manager */ GeometryManager,
749N/A /* change_managed */ ChangeManaged,
749N/A /* insert_child */ XtInheritInsertChild,
749N/A /* delete_child */ XtInheritDeleteChild,
749N/A /* extension */ NULL
749N/A },
749N/A { /* constraint_class fields */
749N/A /* subresourses */ formConstraintResources,
749N/A /* subresource_count */ XtNumber(formConstraintResources),
749N/A /* constraint_size */ sizeof(FormConstraintsRec),
749N/A /* initialize */ ConstraintInitialize,
749N/A /* destroy */ NULL,
749N/A /* set_values */ ConstraintSetValues,
749N/A /* extension */ NULL
749N/A },
749N/A { /* form_class fields */
749N/A /* layout */ Layout
749N/A }
749N/A};
749N/A
749N/AWidgetClass formWidgetClass = (WidgetClass)&formClassRec;
749N/A
749N/A/****************************************************************
749N/A *
749N/A * Private Procedures
749N/A *
749N/A ****************************************************************/
749N/A
749N/A
749N/Astatic XrmQuark XtQChainLeft, XtQChainRight, XtQChainTop,
749N/A XtQChainBottom, XtQRubber;
749N/A
749N/A/* ARGSUSED */
749N/Astatic void _CvtStringToEdgeType(args, num_args, fromVal, toVal)
749N/A XrmValuePtr args; /* unused */
749N/A Cardinal *num_args; /* unused */
749N/A XrmValuePtr fromVal;
749N/A XrmValuePtr toVal;
749N/A{
749N/A static XtEdgeType edgeType;
749N/A XrmQuark q;
749N/A char lowerName[40];
749N/A
749N/A if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
749N/A XmuCopyISOLatin1Lowered (lowerName, (char*)fromVal->addr);
749N/A q = XrmStringToQuark(lowerName);
749N/A if (q == XtQChainLeft) edgeType = XtChainLeft;
749N/A else if (q == XtQChainRight) edgeType = XtChainRight;
749N/A else if (q == XtQChainTop) edgeType = XtChainTop;
749N/A else if (q == XtQChainBottom) edgeType = XtChainBottom;
749N/A else if (q == XtQRubber) edgeType = XtRubber;
749N/A else {
749N/A toVal->size = 0;
749N/A toVal->addr = NULL;
749N/A return;
749N/A }
749N/A toVal->size = sizeof edgeType;
749N/A toVal->addr = (XPointer) &edgeType;
749N/A return;
749N/A }
749N/A toVal->addr = NULL;
749N/A toVal->size = 0;
749N/A}
749N/A
749N/Astatic void ClassInitialize()
749N/A{
749N/A static XtConvertArgRec parentCvtArgs[] = {
749N/A {XtBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.parent),
749N/A sizeof(Widget)}
749N/A };
749N/A XawInitializeWidgetSet();
749N/A XtQChainLeft = XrmPermStringToQuark("chainleft");
749N/A XtQChainRight = XrmPermStringToQuark("chainright");
749N/A XtQChainTop = XrmPermStringToQuark("chaintop");
749N/A XtQChainBottom = XrmPermStringToQuark("chainbottom");
749N/A XtQRubber = XrmPermStringToQuark("rubber");
749N/A
749N/A XtAddConverter( XtRString, XtREdgeType, _CvtStringToEdgeType,
749N/A (XtConvertArgList)NULL, 0 );
749N/A XtSetTypeConverter (XtRString, XtRWidget, XmuNewCvtStringToWidget,
749N/A parentCvtArgs, XtNumber(parentCvtArgs), XtCacheNone,
749N/A (XtDestructor)NULL);
749N/A}
749N/A
749N/Astatic void ClassPartInitialize(class)
749N/A WidgetClass class;
749N/A{
749N/A FormWidgetClass c = (FormWidgetClass)class;
749N/A FormWidgetClass super = (FormWidgetClass)
749N/A c->core_class.superclass;
749N/A
749N/A if (c->form_class.layout == XtInheritLayout)
749N/A c->form_class.layout = super->form_class.layout;
749N/A}
749N/A
749N/A/* ARGSUSED */
749N/Astatic void Initialize(request, new, args, num_args)
749N/A Widget request, new;
749N/A ArgList args;
749N/A Cardinal *num_args;
749N/A{
749N/A FormWidget fw = (FormWidget)new;
749N/A
749N/A fw->form.old_width = fw->core.width;
749N/A fw->form.old_height = fw->core.height;
749N/A fw->form.no_refigure = False;
749N/A fw->form.needs_relayout = False;
749N/A fw->form.resize_in_layout = True;
749N/A fw->form.resize_is_no_op = False;
749N/A}
749N/A
749N/A/* Function Name: ChangeFormGeometry
749N/A * Description: Ask the parent to change the form widget's geometry.
749N/A * Arguments: w - the Form widget.
749N/A * query_only - TRUE if this is only a query.
749N/A * width, height - the new width and height.
749N/A * ret_width, ret_height - the actual size the form is allowed
749N/A * to resize to.
749N/A * Returns: TRUE of children may always be resized.
749N/A */
749N/A
749N/Astatic Boolean
749N/AChangeFormGeometry(w, query_only, width, height, ret_width, ret_height)
749N/AWidget w;
749N/ABoolean query_only;
749N/ADimension width, height;
749N/ADimension *ret_width, *ret_height;
749N/A{
749N/A FormWidget fw = (FormWidget) w;
749N/A Boolean always_resize_children;
749N/A XtGeometryResult result;
749N/A XtWidgetGeometry request, return_request;
749N/A
749N/A /*
749N/A * If we are already at the desired size then there is no need
749N/A * to ask our parent of we can change size.
749N/A */
749N/A
749N/A if ( (width == fw->core.width) && (height == fw->core.height) )
749N/A return(TRUE);
749N/A
749N/A request.width = width;
749N/A request.height = height;
749N/A request.request_mode = CWWidth | CWHeight;
749N/A if (query_only)
749N/A request.request_mode |= XtCWQueryOnly;
749N/A
749N/A /*
749N/A * Do no invoke the resize rules if our size changes here.
749N/A */
749N/A
749N/A fw->form.resize_is_no_op = TRUE;
749N/A
749N/A result = XtMakeGeometryRequest(w, &request, &return_request);
749N/A if (result == XtGeometryAlmost) {
749N/A request = return_request;
749N/A (void) XtMakeGeometryRequest(w, &request, &return_request);
749N/A always_resize_children = FALSE;
749N/A }
749N/A else
749N/A always_resize_children = (result == XtGeometryYes);
749N/A
749N/A fw->form.resize_is_no_op = FALSE;
749N/A
749N/A if (ret_width != NULL)
749N/A *ret_width = request.width;
749N/A if (ret_height != NULL)
749N/A *ret_height = request.height;
749N/A
749N/A return(always_resize_children);
749N/A}
749N/A
749N/A/* Function Name: Layout
749N/A * Description: Moves all the children around.
749N/A * Arguments: fw - the Form widget.
749N/A * width, height - ** UNUSED **.
749N/A * force_relayout - will force the children to be
749N/A * moved, even if some go past the edge
749N/A * of the form.
749N/A * Returns: True if the children are allowed to move from their
749N/A * current locations to the new ones.
749N/A */
749N/A
749N/A/* ARGSUSED */
749N/Astatic Boolean Layout(fw, width, height, force_relayout)
749N/A FormWidget fw;
749N/A Dimension width, height;
749N/A Boolean force_relayout;
749N/A{
749N/A long num_children = fw->composite.num_children;
749N/A WidgetList children = fw->composite.children;
749N/A Widget *childP;
749N/A Dimension maxx, maxy;
749N/A Boolean ret_val;
749N/A
749N/A for (childP = children; childP - children < num_children; childP++) {
749N/A FormConstraints form = (FormConstraints)(*childP)->core.constraints;
749N/A form->form.layout_state = LayoutPending;
749N/A }
749N/A
749N/A maxx = maxy = 1;
749N/A for (childP = children; childP - children < num_children; childP++) {
749N/A if (XtIsManaged(*childP)) {
749N/A FormConstraints form;
749N/A Position x, y;
749N/A
749N/A form = (FormConstraints)(*childP)->core.constraints;
749N/A
749N/A LayoutChild(*childP);
749N/A
749N/A x = form->form.new_x + (*childP)->core.width +
749N/A ((*childP)->core.border_width << 1);
749N/A if (x > (int)maxx)
749N/A maxx = x;
749N/A
749N/A y = form->form.new_y + (*childP)->core.height +
749N/A ((*childP)->core.border_width << 1);
749N/A if (y > (int)maxy)
749N/A maxy = y;
749N/A }
749N/A }
749N/A
749N/A fw->form.preferred_width = (maxx += fw->form.default_spacing);
749N/A fw->form.preferred_height = (maxy += fw->form.default_spacing);
749N/A
749N/A if (fw->form.resize_in_layout) {
749N/A Boolean always_resize_children;
749N/A
749N/A always_resize_children =
749N/A ChangeFormGeometry( (Widget) fw, FALSE, maxx, maxy,
749N/A (Dimension *)NULL, (Dimension *)NULL);
749N/A
749N/A fw->form.old_width = fw->core.width;
749N/A fw->form.old_height = fw->core.height;
749N/A
749N/A ret_val = (always_resize_children || ( (fw->core.width >= maxx) &&
749N/A (fw->core.height >= maxy)));
749N/A
749N/A if (force_relayout)
749N/A ret_val = TRUE;
749N/A
749N/A if (ret_val)
749N/A ResizeChildren((Widget) fw);
749N/A }
749N/A else
749N/A ret_val = False;
749N/A
749N/A fw->form.needs_relayout = False;
749N/A return ret_val;
749N/A}
749N/A
749N/A/* Function Name: ResizeChildren
749N/A * Description: Resizes all children to new_x and new_y.
749N/A * Arguments: w - the form widget.
749N/A * Returns: none.
749N/A */
749N/A
749N/Astatic void ResizeChildren(w)
749N/AWidget w;
749N/A{
749N/A FormWidget fw = (FormWidget) w;
749N/A long num_children = fw->composite.num_children;
749N/A WidgetList children = fw->composite.children;
749N/A Widget *childP;
749N/A
749N/A for (childP = children; childP - children < num_children; childP++) {
749N/A FormConstraints form;
749N/A
749N/A if (!XtIsManaged(*childP))
749N/A continue;
749N/A
749N/A form = (FormConstraints)(*childP)->core.constraints;
749N/A if (fw->form.no_refigure) {
749N/A/*
749N/A * I am changing the widget wrapper w/o modifing the window. This is
749N/A * risky, but I can get away with it since I am the parent of this
749N/A * widget, and he must ask me for any geometry changes.
749N/A *
749N/A * The window will be updated when no_refigure is set back to False.
749N/A */
749N/A (*childP)->core.x = form->form.new_x;
749N/A (*childP)->core.y = form->form.new_y;
749N/A }
749N/A else
749N/A XtMoveWidget(*childP, form->form.new_x, form->form.new_y);
749N/A }
749N/A}
749N/A
749N/A
749N/Astatic void LayoutChild(w)
749N/A Widget w;
749N/A{
749N/A FormConstraints form = (FormConstraints)w->core.constraints;
749N/A Widget ref;
749N/A
749N/A switch (form->form.layout_state) {
749N/A
749N/A case LayoutPending:
749N/A form->form.layout_state = LayoutInProgress;
749N/A break;
749N/A
749N/A case LayoutDone:
749N/A return;
749N/A
749N/A case LayoutInProgress:
749N/A {
749N/A String subs[2];
749N/A Cardinal num_subs = 2;
749N/A subs[0] = w->core.name;
749N/A subs[1] = w->core.parent->core.name;
749N/A XtAppWarningMsg(XtWidgetToApplicationContext(w),
749N/A "constraintLoop","xawFormLayout","XawToolkitError",
749N/A "constraint loop detected while laying out child '%s' in FormWidget '%s'",
749N/A subs, &num_subs);
749N/A return;
749N/A }
749N/A }
749N/A
749N/A form->form.new_x = form->form.dx;
749N/A form->form.new_y = form->form.dy;
749N/A if ((ref = form->form.horiz_base) != (Widget)NULL) {
749N/A FormConstraints ref_form = (FormConstraints) ref->core.constraints;
749N/A
749N/A LayoutChild(ref);
749N/A form->form.new_x += (ref_form->form.new_x +
749N/A ref->core.width + (ref->core.border_width << 1));
749N/A }
749N/A if ((ref = form->form.vert_base) != (Widget)NULL) {
749N/A FormConstraints ref_form = (FormConstraints) ref->core.constraints;
749N/A
749N/A LayoutChild(ref);
749N/A form->form.new_y += (ref_form->form.new_y +
749N/A ref->core.height + (ref->core.border_width << 1));
749N/A }
749N/A
749N/A form->form.layout_state = LayoutDone;
749N/A}
749N/A
749N/A
749N/Astatic Position TransformCoord(loc, old, new, type)
749N/A Position loc;
749N/A Dimension old, new;
749N/A XtEdgeType type;
749N/A{
749N/A if (type == XtRubber) {
749N/A if ( ((int) old) > 0)
749N/A loc = (int)(loc * new) / (int)old;
749N/A }
749N/A else if (type == XtChainBottom || type == XtChainRight)
749N/A loc += (Position)new - (Position)old;
749N/A
749N/A /* I don't see any problem with returning values less than zero. */
749N/A
749N/A return (loc);
749N/A}
749N/A
749N/Astatic void Resize(w)
749N/A Widget w;
749N/A{
749N/A FormWidget fw = (FormWidget)w;
749N/A WidgetList children = fw->composite.children;
749N/A long num_children = fw->composite.num_children;
749N/A Widget *childP;
749N/A Position x, y;
749N/A Dimension width, height;
749N/A
749N/A if (!fw->form.resize_is_no_op)
749N/A for (childP = children; childP - children < num_children; childP++) {
749N/A FormConstraints form= (FormConstraints)(*childP)->core.constraints;
749N/A if (!XtIsManaged(*childP)) continue;
749N/A x = TransformCoord( (*childP)->core.x, fw->form.old_width,
749N/A fw->core.width, form->form.left );
749N/A y = TransformCoord( (*childP)->core.y, fw->form.old_height,
749N/A fw->core.height, form->form.top );
749N/A
749N/A form->form.virtual_width =
749N/A TransformCoord((Position)((*childP)->core.x
749N/A + form->form.virtual_width
749N/A + 2 * (*childP)->core.border_width),
749N/A fw->form.old_width, fw->core.width,
749N/A form->form.right )
749N/A - (x + 2 * (*childP)->core.border_width);
749N/A
749N/A form->form.virtual_height =
749N/A TransformCoord((Position)((*childP)->core.y
749N/A + form->form.virtual_height
749N/A + 2 * (*childP)->core.border_width),
749N/A fw->form.old_height, fw->core.height,
749N/A form->form.bottom )
749N/A - ( y + 2 * (*childP)->core.border_width);
749N/A
749N/A width = (Dimension)
749N/A (form->form.virtual_width < 1) ? 1 : form->form.virtual_width;
749N/A height = (Dimension)
749N/A (form->form.virtual_height < 1) ? 1 : form->form.virtual_height;
749N/A
749N/A XtConfigureWidget(*childP,x,y, (Dimension)width, (Dimension)height,
749N/A (*childP)->core.border_width );
749N/A }
749N/A
749N/A fw->form.old_width = fw->core.width;
749N/A fw->form.old_height = fw->core.height;
749N/A}
749N/A
749N/A/*
749N/A * I don't want to even think about what ``Almost'' would mean - Chris.
749N/A */
749N/A
749N/A/* ARGSUSED */
749N/Astatic XtGeometryResult GeometryManager(w, request, reply)
749N/A Widget w;
749N/A XtWidgetGeometry *request;
749N/A XtWidgetGeometry *reply; /* RETURN */
749N/A{
749N/A Dimension old_width, old_height;
749N/A FormWidget fw = (FormWidget) XtParent(w);
749N/A FormConstraints form = (FormConstraints) w->core.constraints;
749N/A XtWidgetGeometry allowed;
749N/A XtGeometryResult ret_val;
749N/A
749N/A if ((request->request_mode & ~(XtCWQueryOnly | CWWidth | CWHeight)) ||
749N/A !form->form.allow_resize) {
749N/A
749N/A /* If GeometryManager is invoked during a SetValues call on a child
749N/A * then it is necessary to compute a new layout if ConstraintSetValues
749N/A * allowed any constraint changes. */
749N/A
749N/A if (fw->form.needs_relayout)
749N/A (*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
749N/A (fw, 0, 0, True);
749N/A return(XtGeometryNo);
749N/A }
749N/A
749N/A if (request->request_mode & CWWidth)
749N/A allowed.width = request->width;
749N/A else
749N/A allowed.width = w->core.width;
749N/A
749N/A if (request->request_mode & CWHeight)
749N/A allowed.height = request->height;
749N/A else
749N/A allowed.height = w->core.height;
749N/A
749N/A if (allowed.width == w->core.width && allowed.height == w->core.height) {
749N/A
749N/A /* If GeometryManager is invoked during a SetValues call on a child
749N/A * then it is necessary to compute a new layout if ConstraintSetValues
749N/A * allowed any constraint changes. */
749N/A
749N/A if (fw->form.needs_relayout)
749N/A (*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
749N/A (fw, 0, 0, True);
749N/A return(XtGeometryNo);
749N/A }
749N/A
749N/A /*
749N/A * Remember the old size, and then set the size to the requested size.
749N/A */
749N/A
749N/A old_width = w->core.width;
749N/A old_height = w->core.height;
749N/A w->core.width = allowed.width;
749N/A w->core.height = allowed.height;
749N/A
749N/A if (request->request_mode & XtCWQueryOnly) {
749N/A Boolean always_resize_children;
749N/A Dimension ret_width, ret_height;
749N/A
749N/A fw->form.resize_in_layout = FALSE;
749N/A
749N/A (*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
749N/A ( fw, w->core.width, w->core.height,
749N/A FALSE );
749N/A
749N/A /*
749N/A * Reset the size of this child back to what it used to be.
749N/A */
749N/A
749N/A w->core.width = old_width;
749N/A w->core.height = old_height;
749N/A
749N/A fw->form.resize_in_layout = TRUE;
749N/A
749N/A always_resize_children = ChangeFormGeometry(w, TRUE,
749N/A fw->form.preferred_width,
749N/A fw->form.preferred_height,
749N/A &ret_width, &ret_height);
749N/A
749N/A if (always_resize_children ||
749N/A ((ret_width >= fw->form.preferred_width) &&
749N/A (ret_height >= fw->form.preferred_height)))
749N/A {
749N/A ret_val = XtGeometryYes;
749N/A }
749N/A else
749N/A ret_val = XtGeometryNo;
749N/A }
749N/A else {
749N/A if ((*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
749N/A ( fw, w->core.width, w->core.height,
749N/A FALSE))
749N/A {
749N/A form->form.virtual_width = w->core.width; /* reset virtual */
749N/A form->form.virtual_height = w->core.height; /* width and height. */
749N/A if (fw->form.no_refigure) {
749N/A/*
749N/A * I am changing the widget wrapper w/o modifing the window. This is
749N/A * risky, but I can get away with it since I am the parent of this
749N/A * widget, and he must ask me for any geometry changes.
749N/A *
749N/A * The window will be updated when no_refigure is set back to False.
749N/A */
749N/A form->form.deferred_resize = True;
749N/A ret_val = XtGeometryDone;
749N/A }
749N/A else
749N/A ret_val = XtGeometryYes;
749N/A }
749N/A else {
749N/A w->core.width = old_width;
749N/A w->core.height = old_height;
749N/A ret_val = XtGeometryNo;
749N/A }
749N/A }
749N/A
749N/A return(ret_val);
749N/A}
749N/A
749N/A
749N/A/* ARGSUSED */
749N/Astatic Boolean SetValues(current, request, new, args, num_args)
749N/A Widget current, request, new;
749N/A ArgList args;
749N/A Cardinal *num_args;
749N/A{
749N/A return( FALSE );
749N/A}
749N/A
749N/A
749N/A/* ARGSUSED */
749N/Astatic void ConstraintInitialize(request, new, args, num_args)
749N/A Widget request, new;
749N/A ArgList args;
749N/A Cardinal *num_args;
749N/A{
749N/A FormConstraints form = (FormConstraints)new->core.constraints;
749N/A FormWidget fw = (FormWidget)new->core.parent;
749N/A
749N/A form->form.virtual_width = (int) new->core.width;
749N/A form->form.virtual_height = (int) new->core.height;
749N/A
749N/A if (form->form.dx == default_value)
749N/A form->form.dx = fw->form.default_spacing;
749N/A
749N/A if (form->form.dy == default_value)
749N/A form->form.dy = fw->form.default_spacing;
749N/A
749N/A form->form.deferred_resize = False;
749N/A}
749N/A
749N/A/*ARGSUSED*/
749N/Astatic Boolean ConstraintSetValues(current, request, new, args, num_args)
749N/A Widget current, request, new;
749N/A ArgList args;
749N/A Cardinal *num_args;
749N/A{
749N/A FormConstraints cfc = (FormConstraints) current->core.constraints;
749N/A FormConstraints nfc = (FormConstraints) new->core.constraints;
749N/A
749N/A if (cfc->form.top != nfc->form.top ||
749N/A cfc->form.bottom != nfc->form.bottom ||
749N/A cfc->form.left != nfc->form.left ||
749N/A cfc->form.right != nfc->form.right ||
749N/A cfc->form.dx != nfc->form.dx ||
749N/A cfc->form.dy != nfc->form.dy ||
749N/A cfc->form.horiz_base != nfc->form.horiz_base ||
749N/A cfc->form.vert_base != nfc->form.vert_base) {
749N/A
749N/A FormWidget fp = (FormWidget) XtParent(new);
749N/A
749N/A /* If there are no subclass ConstraintSetValues procedures remaining
749N/A * to be invoked, and if there is no geometry request about to be
749N/A * made, then invoke the new layout now; else defer it. */
749N/A
749N/A if (XtClass(XtParent(new)) == formWidgetClass &&
749N/A current->core.x == new->core.x &&
749N/A current->core.y == new->core.y &&
749N/A current->core.width == new->core.width &&
749N/A current->core.height == new->core.height &&
749N/A current->core.border_width == new->core.border_width)
749N/A Layout(fp, 0, 0, True);
749N/A else fp->form.needs_relayout = True;
749N/A }
749N/A return( FALSE );
749N/A}
749N/A
749N/Astatic void ChangeManaged(w)
749N/A Widget w;
749N/A{
749N/A FormWidget fw = (FormWidget)w;
749N/A FormConstraints form;
749N/A WidgetList children, childP;
749N/A long num_children = fw->composite.num_children;
749N/A Widget child;
749N/A
749N/A /*
749N/A * Reset virtual width and height for all children.
749N/A */
749N/A
749N/A for (children = childP = fw->composite.children ;
749N/A childP - children < num_children; childP++) {
749N/A child = *childP;
749N/A if (XtIsManaged(child)) {
749N/A form = (FormConstraints)child->core.constraints;
749N/A
749N/A/*
749N/A * If the size is one (1) then we must not change the virtual sizes, as
749N/A * they contain useful information. If someone actually wants a widget of
749N/A * width or height one (1) in a form widget he will lose, can't win them all.
749N/A *
749N/A * Chris D. Peterson 2/9/89.
749N/A */
749N/A
749N/A if ( child->core.width != 1)
749N/A form->form.virtual_width = (int) child->core.width;
749N/A if ( child->core.height != 1)
749N/A form->form.virtual_height = (int) child->core.height;
749N/A }
749N/A }
749N/A (*((FormWidgetClass)w->core.widget_class)->form_class.layout)
749N/A ((FormWidget) w, w->core.width,
749N/A w->core.height, TRUE);
749N/A}
749N/A
749N/A
749N/Astatic XtGeometryResult PreferredGeometry( widget, request, reply )
749N/A Widget widget;
749N/A XtWidgetGeometry *request, *reply;
749N/A{
749N/A FormWidget w = (FormWidget)widget;
749N/A
749N/A reply->width = w->form.preferred_width;
749N/A reply->height = w->form.preferred_height;
749N/A reply->request_mode = CWWidth | CWHeight;
749N/A if ( request->request_mode & (CWWidth | CWHeight) ==
749N/A (CWWidth | CWHeight)
749N/A && request->width == reply->width
749N/A && request->height == reply->height)
749N/A return XtGeometryYes;
749N/A else if (reply->width == w->core.width && reply->height == w->core.height)
749N/A return XtGeometryNo;
749N/A else
749N/A return XtGeometryAlmost;
749N/A}
749N/A
749N/A
749N/A/**********************************************************************
749N/A *
749N/A * Public routines
749N/A *
749N/A **********************************************************************/
749N/A
749N/A/*
749N/A * Set or reset figuring (ignored if not realized)
749N/A */
749N/A
749N/Avoid
749N/A#if NeedFunctionPrototypes
749N/AXawFormDoLayout(Widget w,
749N/A#if NeedWidePrototypes
749N/A int doit)
749N/A#else
749N/A Boolean doit)
749N/A#endif
749N/A#else
749N/AXawFormDoLayout(w, doit)
749N/AWidget w;
749N/ABoolean doit;
749N/A#endif
749N/A{
749N/A Widget *childP;
749N/A FormWidget fw = (FormWidget)w;
749N/A long num_children = fw->composite.num_children;
749N/A WidgetList children = fw->composite.children;
749N/A
749N/A if ( ((fw->form.no_refigure = !doit) == TRUE) || !XtIsRealized(w) )
749N/A return;
749N/A
749N/A for (childP = children; childP - children < num_children; childP++) {
749N/A Widget w = *childP;
749N/A if (XtIsManaged(w)) {
749N/A FormConstraints form = (FormConstraints)w->core.constraints;
749N/A
749N/A /*
749N/A * Xt Configure widget is too smart, and optimizes out
749N/A * my changes.
749N/A */
749N/A
749N/A XMoveResizeWindow(XtDisplay(w), XtWindow(w),
749N/A w->core.x, w->core.y,
749N/A w->core.width, w->core.height);
749N/A
749N/A if (form->form.deferred_resize &&
749N/A XtClass(w)->core_class.resize != (XtWidgetProc) NULL) {
749N/A (*(XtClass(w)->core_class.resize))(w);
749N/A form->form.deferred_resize = False;
749N/A }
749N/A }
749N/A }
749N/A}