diff options
Diffstat (limited to 'libXaw/src/Form.c')
-rw-r--r-- | libXaw/src/Form.c | 2212 |
1 files changed, 1106 insertions, 1106 deletions
diff --git a/libXaw/src/Form.c b/libXaw/src/Form.c index 9f5ac8271..58723e845 100644 --- a/libXaw/src/Form.c +++ b/libXaw/src/Form.c @@ -1,1106 +1,1106 @@ -/***********************************************************
-
-Copyright 1987, 1988, 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/IntrinsicP.h>
-#include <X11/StringDefs.h>
-#include <X11/Xmu/CharSet.h>
-#include <X11/Xmu/Converters.h>
-#include <X11/Xaw/FormP.h>
-#include <X11/Xaw/XawInit.h>
-#include "Private.h"
-
-/*
- * Class Methods
- */
-static void XawFormChangeManaged(Widget);
-static void XawFormClassInitialize(void);
-static void XawFormClassPartInitialize(WidgetClass);
-static void XawFormConstraintInitialize(Widget, Widget, ArgList, Cardinal*);
-static Boolean XawFormConstraintSetValues(Widget, Widget, Widget,
- ArgList, Cardinal*);
-static XtGeometryResult XawFormGeometryManager(Widget, XtWidgetGeometry*,
- XtWidgetGeometry*);
-static void XawFormInitialize(Widget, Widget, ArgList, Cardinal*);
-#ifndef OLDXAW
-static void XawFormRealize(Widget, Mask*, XSetWindowAttributes*);
-static void XawFormRedisplay(Widget, XEvent*, Region);
-#endif
-static XtGeometryResult XawFormQueryGeometry(Widget, XtWidgetGeometry*,
- XtWidgetGeometry*);
-static void XawFormResize(Widget);
-static Boolean XawFormSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
-static Boolean Layout(FormWidget, unsigned int, unsigned int, Bool);
-
-/*
- * Prototypes
- */
-static void _CvtStringToEdgeType(XrmValuePtr, Cardinal*,
- XrmValuePtr, XrmValuePtr);
-static Bool ChangeFormGeometry(Widget, Bool, unsigned int, unsigned int,
- Dimension*, Dimension*);
-Boolean CvtEdgeTypeToString(Display*, XrmValuePtr, Cardinal*,
- XrmValuePtr, XrmValuePtr, XtPointer*);
-static void LayoutChild(Widget);
-static int TransformCoord(int, unsigned int, unsigned int, XtEdgeType);
-static void ResizeChildren(Widget);
-
-/*
- * Initialization
- */
-#ifndef OLDXAW
-static XtActionsRec actions[] = {
- {"set-values", XawSetValuesAction},
- {"get-values", XawGetValuesAction},
- {"declare", XawDeclareAction},
- {"call-proc", XawCallProcAction},
-};
-#endif
-
-static XrmQuark QchainLeft, QchainRight, QchainTop, QchainBottom, Qrubber;
-
-#define default_value -99999
-#define Offset(field) XtOffsetOf(FormRec, form.field)
-static XtResource resources[] = {
- {
- XtNdefaultDistance,
- XtCThickness,
- XtRInt,
- sizeof(int),
- Offset(default_spacing),
- XtRImmediate,
- (XtPointer)4
- },
-#ifndef OLDXAW
- {
- XawNdisplayList,
- XawCDisplayList,
- XawRDisplayList,
- sizeof(XawDisplayList*),
- Offset(display_list),
- XtRImmediate,
- NULL
- },
-#endif
-};
-#undef Offset
-
-#define defEdge XtRubber
-
-#define Offset(field) XtOffsetOf(FormConstraintsRec, form.field)
-static XtResource formConstraintResources[] = {
- {
- XtNtop,
- XtCEdge,
- XtREdgeType,
- sizeof(XtEdgeType),
- Offset(top),
- XtRImmediate,
- (XtPointer)defEdge
- },
- {
- XtNbottom,
- XtCEdge,
- XtREdgeType,
- sizeof(XtEdgeType),
- Offset(bottom),
- XtRImmediate,
- (XtPointer)defEdge
- },
- {
- XtNleft,
- XtCEdge,
- XtREdgeType,
- sizeof(XtEdgeType),
- Offset(left),
- XtRImmediate,
- (XtPointer)defEdge
- },
- {
- XtNright,
- XtCEdge,
- XtREdgeType,
- sizeof(XtEdgeType),
- Offset(right),
- XtRImmediate,
- (XtPointer)defEdge
- },
- {
- XtNhorizDistance,
- XtCThickness,
- XtRInt,
- sizeof(int),
- Offset(dx),
- XtRImmediate,
- (XtPointer)default_value
- },
- {
- XtNfromHoriz,
- XtCWidget,
- XtRWidget,
- sizeof(Widget),
- Offset(horiz_base),
- XtRWidget,
- NULL
- },
- {
- XtNvertDistance,
- XtCThickness,
- XtRInt,
- sizeof(int),
- Offset(dy),
- XtRImmediate,
- (XtPointer)default_value
- },
- {
- XtNfromVert,
- XtCWidget,
- XtRWidget,
- sizeof(Widget),
- Offset(vert_base),
- XtRWidget,
- NULL
- },
- {
- XtNresizable,
- XtCBoolean,
- XtRBoolean,
- sizeof(Boolean),
- Offset(allow_resize),
- XtRImmediate,
- (XtPointer)False
- },
-};
-#undef Offset
-
-FormClassRec formClassRec = {
- /* core */
- {
- (WidgetClass)&constraintClassRec, /* superclass */
- "Form", /* class_name */
- sizeof(FormRec), /* widget_size */
- XawFormClassInitialize, /* class_initialize */
- XawFormClassPartInitialize, /* class_part_init */
- False, /* class_inited */
- XawFormInitialize, /* initialize */
- NULL, /* initialize_hook */
-#ifndef OLDXAW
- XawFormRealize, /* realize */
- actions, /* actions */
- XtNumber(actions), /* num_actions */
-#else
- XtInheritRealize, /* realize */
- NULL, /* actions */
- 0, /* num_actions */
-#endif
- resources, /* resources */
- XtNumber(resources), /* num_resources */
- NULLQUARK, /* xrm_class */
- True, /* compress_motion */
- True, /* compress_exposure */
- True, /* compress_enterleave */
- False, /* visible_interest */
- NULL, /* destroy */
- XawFormResize, /* resize */
-#ifndef OLDXAW
- XawFormRedisplay, /* expose */
-#else
- XtInheritExpose, /* expose */
-#endif
- XawFormSetValues, /* set_values */
- NULL, /* set_values_hook */
- XtInheritSetValuesAlmost, /* set_values_almost */
- NULL, /* get_values_hook */
- NULL, /* accept_focus */
- XtVersion, /* version */
- NULL, /* callback_private */
- NULL, /* tm_table */
- XawFormQueryGeometry, /* query_geometry */
- XtInheritDisplayAccelerator, /* display_accelerator */
- NULL, /* extension */
- },
- /* composite */
- {
- XawFormGeometryManager, /* geometry_manager */
- XawFormChangeManaged, /* change_managed */
- XtInheritInsertChild, /* insert_child */
- XtInheritDeleteChild, /* delete_child */
- NULL, /* extension */
- },
- /* constraint */
- {
- formConstraintResources, /* subresourses */
- XtNumber(formConstraintResources), /* subresource_count */
- sizeof(FormConstraintsRec), /* constraint_size */
- XawFormConstraintInitialize, /* initialize */
- NULL, /* destroy */
- XawFormConstraintSetValues, /* set_values */
- NULL, /* extension */
- },
- /* form */
- {
- Layout, /* layout */
- },
-};
-
-WidgetClass formWidgetClass = (WidgetClass)&formClassRec;
-
-/*
- * Implementation
- */
-#ifndef OLDXAW
-static void
-XawFormRealize(Widget w, Mask *mask, XSetWindowAttributes *attr)
-{
- XawPixmap *pixmap;
-
- (*formWidgetClass->core_class.superclass->core_class.realize)(w, mask, attr);
-
- if (w->core.background_pixmap > XtUnspecifiedPixmap) {
- pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w),
- w->core.colormap, w->core.depth);
- if (pixmap && pixmap->mask)
- XawReshapeWidget(w, pixmap);
- }
-}
-
-static void
-XawFormRedisplay(Widget w, XEvent *event, Region region)
-{
- FormWidget xaw = (FormWidget)w;
-
- if (xaw->form.display_list)
- XawRunDisplayList(w, xaw->form.display_list, event, region);
-}
-#endif
-
-/*ARGSUSED*/
-static void
-_CvtStringToEdgeType(XrmValuePtr args, Cardinal *num_args,
- XrmValuePtr fromVal, XrmValuePtr toVal)
-{
- static XtEdgeType edgeType;
- XrmQuark q;
- char name[12];
-
- XmuNCopyISOLatin1Lowered(name, (char*)fromVal->addr, sizeof(name));
- q = XrmStringToQuark(name);
-
- if (q == QchainLeft)
- edgeType = XtChainLeft;
- else if (q == QchainRight)
- edgeType = XtChainRight;
- else if (q == QchainTop)
- edgeType = XtChainTop;
- else if (q == QchainBottom)
- edgeType = XtChainBottom;
- else if (q == Qrubber)
- edgeType = XtRubber;
- else {
- XtStringConversionWarning(fromVal->addr, XtREdgeType);
- toVal->size = 0;
- toVal->addr = NULL;
- return;
- }
-
- toVal->size = sizeof(XtEdgeType);
- toVal->addr = (XPointer)&edgeType;
-}
-
-/*ARGSUSED*/
-Boolean
-CvtEdgeTypeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args,
- XrmValuePtr fromVal, XrmValuePtr toVal, XtPointer *data)
-{
- static String buffer;
- Cardinal size;
-
- switch (*(XtEdgeType *)fromVal->addr) {
- case XtChainLeft:
- buffer = XtEchainLeft;
- break;
- case XtChainRight:
- buffer = XtEchainRight;
- break;
- case XtChainTop:
- buffer = XtEchainTop;
- break;
- case XtChainBottom:
- buffer = XtEchainBottom;
- break;
- case XtRubber:
- buffer = XtErubber;
- break;
- default:
- XawTypeToStringWarning(dpy, XtREdgeType);
- toVal->addr = NULL;
- toVal->size = 0;
- return (False);
- }
-
- size = strlen(buffer) + 1;
- if (toVal->addr != NULL) {
- if (toVal->size < size) {
- toVal->size = size;
- return (False);
- }
- strcpy((char *)toVal->addr, buffer);
- }
- else
- toVal->addr = (XPointer)buffer;
- toVal->size = sizeof(String);
-
- return (True);
-}
-
-static void
-XawFormClassInitialize(void)
-{
- static XtConvertArgRec parentCvtArgs[] = {
- {XtBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.parent),
- sizeof(Widget)}
- };
-
- char name[12];
-
- XawInitializeWidgetSet();
- XmuNCopyISOLatin1Lowered(name, XtEchainLeft, sizeof(name));
- QchainLeft = XrmStringToQuark(name);
- XmuNCopyISOLatin1Lowered(name, XtEchainRight, sizeof(name));
- QchainRight = XrmStringToQuark(name);
- XmuNCopyISOLatin1Lowered(name, XtEchainTop, sizeof(name));
- QchainTop = XrmStringToQuark(name);
- XmuNCopyISOLatin1Lowered(name, XtEchainBottom, sizeof(name));
- QchainBottom = XrmStringToQuark(name);
- XmuNCopyISOLatin1Lowered(name, XtErubber, sizeof(name));
- Qrubber = XrmStringToQuark(name);
-
- XtAddConverter(XtRString, XtREdgeType, _CvtStringToEdgeType, NULL, 0);
- XtSetTypeConverter(XtREdgeType, XtRString, CvtEdgeTypeToString,
- NULL, 0, XtCacheNone, NULL);
- XtSetTypeConverter(XtRString, XtRWidget, XmuNewCvtStringToWidget,
- parentCvtArgs, XtNumber(parentCvtArgs), XtCacheNone,
- NULL);
- XtSetTypeConverter(XtRWidget, XtRString, XmuCvtWidgetToString,
- NULL, 0, XtCacheNone, NULL);
-}
-
-static void
-XawFormClassPartInitialize(WidgetClass cclass)
-{
- FormWidgetClass c = (FormWidgetClass)cclass;
- FormWidgetClass super = (FormWidgetClass)c->core_class.superclass;
-
- if (c->form_class.layout == XtInheritLayout)
- c->form_class.layout = super->form_class.layout;
-}
-
-/*ARGSUSED*/
-static void
-XawFormInitialize(Widget request, Widget cnew,
- ArgList args, Cardinal *num_args)
-{
- FormWidget fw = (FormWidget)cnew;
-
- fw->form.old_width = fw->form.old_height = 0;
- fw->form.no_refigure = False;
- fw->form.needs_relayout = False;
- fw->form.resize_in_layout = True;
- fw->form.resize_is_no_op = False;
-}
-
-/*
- * Function:
- * ChangeFormGeometry
- *
- * Parameters:
- * w - Form widget
- * query_only - is only a query?
- * width - new width and height
- * height - ""
- * ret_width - actual size the form is allowed to resize to (return)
- * ret_height - ""
- *
- * Description:
- * Ask the parent to change the form widget's geometry.
- *
- * Returns:
- * True of children may always be resized
- */
-static Bool
-ChangeFormGeometry(Widget w, Bool query_only,
- unsigned int width, unsigned int height,
- Dimension *ret_width, Dimension *ret_height)
-{
- FormWidget fw = (FormWidget)w;
- Boolean always_resize_children;
- XtGeometryResult result;
- XtWidgetGeometry request, return_request;
-
- /*
- * If we are already at the desired size then there is no need
- * to ask our parent of we can change size
- */
- if (width == XtWidth(fw) && height == XtHeight(fw))
- return (True);
-
- request.width = width;
- request.height = height;
- request.request_mode = CWWidth | CWHeight;
- if (query_only)
- request.request_mode |= XtCWQueryOnly;
-
- /*
- * Do no invoke the resize rules if our size changes here
- */
- fw->form.resize_is_no_op = True;
-
- result = XtMakeGeometryRequest(w, &request, &return_request);
- if (result == XtGeometryAlmost) {
- request = return_request;
- (void)XtMakeGeometryRequest(w, &request, &return_request);
- always_resize_children = False;
- }
- else
- always_resize_children = result == XtGeometryYes;
-
- fw->form.resize_is_no_op = False;
-
- if (ret_width != NULL)
- *ret_width = request.width;
- if (ret_height != NULL)
- *ret_height = request.height;
-
- return (always_resize_children);
-}
-
-/*
- * Function:
- * Layout
- *
- * Parameters:
- * fw - Form widget
- * width - unused
- * height - ""
- * force_relayout - will force the children to be moved, even if some
- * go past the edge of the form
- *
- * Description:
- * Moves all the children around.
- *
- * Returns:
- * True if the children are allowed to move from their
- * current locations to the new ones.
- */
-/*ARGSUSED*/
-static Boolean
-Layout(FormWidget fw, unsigned int width, unsigned int height,
- Bool force_relayout)
-{
- int num_children = fw->composite.num_children;
- WidgetList children = fw->composite.children;
- Widget *childP;
- Dimension maxx, maxy;
- Boolean ret_val;
-
- for (childP = children; childP - children < num_children; childP++) {
- FormConstraints form = (FormConstraints)(*childP)->core.constraints;
- form->form.layout_state = LayoutPending;
- }
-
- maxx = maxy = 1;
- for (childP = children; childP - children < num_children; childP++) {
- if (XtIsManaged(*childP)) {
- FormConstraints form;
- Position x, y;
-
- form = (FormConstraints)(*childP)->core.constraints;
-
- LayoutChild(*childP);
-
- x = form->form.new_x + XtWidth(*childP)
- + (XtBorderWidth(*childP) << 1);
- if (x > (int)maxx)
- maxx = x;
-
- y = form->form.new_y + XtHeight(*childP)
- + (XtBorderWidth(*childP) << 1);
- if (y > (int)maxy)
- maxy = y;
- }
- }
-
- fw->form.preferred_width = (maxx += fw->form.default_spacing);
- fw->form.preferred_height = (maxy += fw->form.default_spacing);
-
- if (fw->form.resize_in_layout) {
- Boolean always_resize_children;
-
- always_resize_children =
- ChangeFormGeometry((Widget)fw, False, maxx, maxy, NULL, NULL);
-
-#ifdef OLDXAW
- fw->form.old_width = fw->core.width;
- fw->form.old_height = fw->core.height;
-#endif
-
- if (force_relayout)
- ret_val = True;
- else
- ret_val = always_resize_children ||
- (XtWidth(fw) >= maxx && XtHeight(fw) >= maxy);
-
- if (ret_val)
- ResizeChildren((Widget)fw);
- }
- else
- ret_val = False;
-
- fw->form.needs_relayout = False;
-
- return (ret_val);
-}
-
-/*
- * Function:
- * ResizeChildren
- *
- * Parameters:
- * w - form widget
- *
- * Description:
- * Resizes all children to new_x and new_y.
- */
-static void
-ResizeChildren(Widget w)
-{
- FormWidget fw = (FormWidget)w;
- int num_children = fw->composite.num_children;
- WidgetList children = fw->composite.children;
- Widget *childP;
-
- for (childP = children; childP - children < num_children; childP++) {
- FormConstraints form;
- Position x, y;
-
- if (!XtIsManaged(*childP))
- continue;
-
- form = (FormConstraints)(*childP)->core.constraints;
-
- if (fw->form.old_width && fw->form.old_height) {
- x = TransformCoord(form->form.new_x, fw->form.old_width,
- XtWidth(fw), form->form.left);
- y = TransformCoord(form->form.new_y, fw->form.old_height,
- XtHeight(fw), form->form.top);
- }
- else {
- x = form->form.new_x;
- y = form->form.new_y;
- }
-
- if (fw->form.no_refigure) {
- /*
- * I am changing the widget wrapper w/o modifing the window. This is
- * risky, but I can get away with it since I am the parent of this
- * widget, and he must ask me for any geometry changes
- *
- * The window will be updated when no_refigure is set back to False
- */
- XtX(*childP) = x;
- XtY(*childP) = y;
- }
- else
- XtMoveWidget(*childP, x, y);
- }
-}
-
-static void
-LayoutChild(Widget w)
-{
- FormConstraints form = (FormConstraints)w->core.constraints;
- Widget ref;
-
- switch (form->form.layout_state) {
- case LayoutPending:
- form->form.layout_state = LayoutInProgress;
- break;
- case LayoutDone:
- return;
- case LayoutInProgress: {
- String subs[2];
- Cardinal num_subs = 2;
- subs[0] = w->core.name;
- subs[1] = w->core.parent->core.name;
-
- XtAppWarningMsg(XtWidgetToApplicationContext(w),
- "constraintLoop", "xawFormLayout", "XawToolkitError",
- "constraint loop detected while laying out "
- "child '%s' in FormWidget '%s'",
- subs, &num_subs);
- } return;
- }
-
- form->form.new_x = form->form.dx;
- form->form.new_y = form->form.dy;
- if ((ref = form->form.horiz_base) != NULL) {
- FormConstraints ref_form = (FormConstraints)ref->core.constraints;
-
- LayoutChild(ref);
- form->form.new_x += ref_form->form.new_x + XtWidth(ref) +
- (XtBorderWidth(ref) << 1);
- }
- if ((ref = form->form.vert_base) != NULL) {
- FormConstraints ref_form = (FormConstraints)ref->core.constraints;
-
- LayoutChild(ref);
- form->form.new_y += ref_form->form.new_y + XtHeight(ref) +
- (XtBorderWidth(ref) << 1);
- }
-
- form->form.layout_state = LayoutDone;
-}
-
-static int
-TransformCoord(int loc, unsigned int old, unsigned int cnew, XtEdgeType type)
-{
- if (type == XtRubber) {
- if ((int)old > 0)
- loc = (int)(loc * ((double)cnew / (double)old));
- }
- else if (type == XtChainBottom || type == XtChainRight)
- loc += (int)cnew - (int)old;
-
- return (loc);
-}
-
-static void
-XawFormResize(Widget w)
-{
- FormWidget fw = (FormWidget)w;
- WidgetList children = fw->composite.children;
- int num_children = fw->composite.num_children;
- Widget *childP;
- int x, y;
- int width, height;
- Boolean unmap = XtIsRealized(w) && w->core.mapped_when_managed &&
- XtIsManaged(w);
-
- if (unmap)
- XtUnmapWidget(w);
-
- if (!fw->form.resize_is_no_op)
- for (childP = children; childP - children < num_children; childP++) {
- FormConstraints form = (FormConstraints)(*childP)->core.constraints;
-
- if (!XtIsManaged(*childP))
- continue;
-
-#ifndef OLDXAW
- x = TransformCoord(form->form.virtual_x, fw->form.old_width,
- XtWidth(fw), form->form.left);
- y = TransformCoord(form->form.virtual_y, fw->form.old_height,
- XtHeight(fw), form->form.top);
- width = TransformCoord(form->form.virtual_x +
- form->form.virtual_width +
- (XtBorderWidth(*childP) << 1),
- fw->form.old_width, XtWidth(fw),
- form->form.right) -
- (x + (XtBorderWidth(*childP) << 1));
- height = TransformCoord(form->form.virtual_y +
- form->form.virtual_height +
- (XtBorderWidth(*childP) << 1),
- fw->form.old_height, XtHeight(fw),
- form->form.bottom) -
- (y + (XtBorderWidth(*childP) << 1));
-#else
- x = TransformCoord(XtX(*childP), fw->form.old_width,
- XtWidth(fw), form->form.left);
- y = TransformCoord(XtY(*childP), fw->form.old_height,
- XtHeight(fw), form->form.top);
- width = TransformCoord(XtX(*childP) + form->form.virtual_width +
- (XtBorderWidth(*childP) << 1),
- fw->form.old_width, XtWidth(fw),
- form->form.right) -
- (x + (XtBorderWidth(*childP) << 1));
- height = TransformCoord(XtY(*childP) + form->form.virtual_height +
- (XtBorderWidth(*childP) << 1),
- fw->form.old_height, XtHeight(fw),
- form->form.bottom) -
- (y + (XtBorderWidth(*childP) << 1));
- form->form.virtual_width = width;
- form->form.virtual_height = height;
-#endif
-
- width = width < 1 ? 1 : width;
- height = height < 1 ? 1 : height;
-
- XtConfigureWidget(*childP, x, y, width, height,
- XtBorderWidth(*childP));
- }
-
- if (unmap)
- XtMapWidget(w);
-
-#ifdef OLDXAW
- fw->form.old_width = XtWidth(fw);
- fw->form.old_height = XtHeight(fw);
-#endif
-}
-
-/*ARGSUSED*/
-static XtGeometryResult
-XawFormGeometryManager(Widget w, XtWidgetGeometry *request,
- XtWidgetGeometry *reply)
-{
- Dimension old_width, old_height;
- FormWidget fw = (FormWidget)XtParent(w);
- FormConstraints form = (FormConstraints)w->core.constraints;
- XtWidgetGeometry allowed;
- XtGeometryResult ret_val;
-
- if ((request->request_mode & (unsigned)~(XtCWQueryOnly | CWWidth | CWHeight))
- || !form->form.allow_resize) {
- /* If GeometryManager is invoked during a SetValues call on a child
- * then it is necessary to compute a new layout if ConstraintSetValues
- * allowed any constraint changes
- */
- if (fw->form.needs_relayout)
- (*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
- (fw, 0, 0, True);
- return (XtGeometryNo);
- }
-
- if (request->request_mode & CWWidth)
- allowed.width = request->width;
- else
- allowed.width = XtWidth(w);
-
- if (request->request_mode & CWHeight)
- allowed.height = request->height;
- else
- allowed.height = XtHeight(w);
-
- if (allowed.width == XtWidth(w) && allowed.height == XtHeight(w)) {
- /* If GeometryManager is invoked during a SetValues call on a child
- * then it is necessary to compute a new layout if ConstraintSetValues
- * allowed any constraint changes
- */
- if (fw->form.needs_relayout)
- (*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
- (fw, 0, 0, True);
- return (XtGeometryNo);
- }
-
- /*
- * Remember the old size, and then set the size to the requested size
- */
- old_width = XtWidth(w);
- old_height = XtHeight(w);
- XtWidth(w) = allowed.width;
- XtHeight(w) = allowed.height;
-
- if (request->request_mode & XtCWQueryOnly) {
- Boolean always_resize_children;
- Dimension ret_width, ret_height;
-
- fw->form.resize_in_layout = False;
-
- (*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
- (fw, XtWidth(w), XtHeight(w), False);
-
- /*
- * Reset the size of this child back to what it used to be
- */
- XtWidth(w) = old_width;
- XtHeight(w) = old_height;
-
- fw->form.resize_in_layout = True;
-
- always_resize_children = ChangeFormGeometry(w, True,
- fw->form.preferred_width,
- fw->form.preferred_height,
- &ret_width, &ret_height);
-
- if (always_resize_children
- || (ret_width >= fw->form.preferred_width
- && ret_height >= fw->form.preferred_height))
- ret_val = XtGeometryYes;
- else
- ret_val = XtGeometryNo;
- }
- else {
- if ((*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
- (fw, XtWidth(w), XtHeight(w), False)) {
- Widget *childP;
- int num_children = fw->composite.num_children;
- WidgetList children = fw->composite.children;
-
- if (fw->form.no_refigure) {
- /*
- * I am changing the widget wrapper w/o modifing the window.
- * This is risky, but I can get away with it since I am the
- * parent of this widget, and he must ask me for any geometry
- * changes
- *
- * The window will be updated when no_refigure is set back
- * to False
- */
- form->form.deferred_resize = True;
- ret_val = XtGeometryDone;
- }
- else
- ret_val = XtGeometryYes;
-
- /*
- * Resets everything.
- */
- fw->form.old_width = XtWidth(fw);
- fw->form.old_height = XtHeight(fw);
- for (childP = children; childP - children < num_children; childP++) {
- Widget nw = *childP;
-
- if (XtIsManaged(nw)) {
- FormConstraints nform = (FormConstraints)nw->core.constraints;
-
-#ifndef OLDXAW
- nform->form.virtual_x = XtX(nw);
- nform->form.virtual_y = XtY(nw);
-#endif
- nform->form.virtual_width = XtWidth(nw);
- nform->form.virtual_height = XtHeight(nw);
- }
- }
- }
- else {
- XtWidth(w) = old_width;
- XtHeight(w) = old_height;
- ret_val = XtGeometryNo;
- }
- }
-
- return (ret_val);
-}
-
-/*ARGSUSED*/
-static Boolean
-XawFormSetValues(Widget current, Widget request, Widget cnew,
- ArgList args, Cardinal *num_args)
-{
-#ifndef OLDXAW
- FormWidget f_old = (FormWidget)current;
- FormWidget f_new = (FormWidget)cnew;
-
- if (f_old->core.background_pixmap != f_new->core.background_pixmap) {
- XawPixmap *opix, *npix;
-
- opix = XawPixmapFromXPixmap(f_old->core.background_pixmap, XtScreen(f_old),
- f_old->core.colormap, f_old->core.depth);
- npix = XawPixmapFromXPixmap(f_new->core.background_pixmap, XtScreen(f_new),
- f_new->core.colormap, f_new->core.depth);
- if ((npix && npix->mask) || (opix && opix->mask))
- XawReshapeWidget(cnew, npix);
- }
-#endif /* OLDXAW */
-
- return (False);
-}
-
-/* ARGSUSED */
-static void
-XawFormConstraintInitialize(Widget request, Widget cnew,
- ArgList args, Cardinal *num_args)
-{
- FormConstraints form = (FormConstraints)cnew->core.constraints;
- FormWidget fw = (FormWidget)cnew->core.parent;
-
-#ifndef OLDXAW
- form->form.virtual_x = XtX(cnew);
- form->form.virtual_y = XtY(cnew);
-#endif
- form->form.virtual_width = XtWidth(cnew);
- form->form.virtual_height = XtHeight(cnew);
-
- if (form->form.dx == default_value)
- form->form.dx = fw->form.default_spacing;
-
- if (form->form.dy == default_value)
- form->form.dy = fw->form.default_spacing;
-
- form->form.deferred_resize = False;
-}
-
-/*ARGSUSED*/
-static Boolean
-XawFormConstraintSetValues(Widget current, Widget request, Widget cnew,
- ArgList args, Cardinal *num_args)
-{
- FormConstraints cfc = (FormConstraints)current->core.constraints;
- FormConstraints nfc = (FormConstraints)cnew->core.constraints;
-
- if (cfc->form.top != nfc->form.top || cfc->form.bottom != nfc->form.bottom
- || cfc->form.left != nfc->form.left || cfc->form.right != nfc->form.right
- || cfc->form.dx != nfc->form.dx || cfc->form.dy != nfc->form.dy
- || cfc->form.horiz_base != nfc->form.horiz_base
- || cfc->form.vert_base != nfc->form.vert_base) {
- FormWidget fp = (FormWidget)XtParent(cnew);
-
- /* If there are no subclass ConstraintSetValues procedures remaining
- * to be invoked, and if there is no geometry request about to be
- * made, then invoke the new layout now; else defer it
- */
- if (XtClass(XtParent(cnew)) == formWidgetClass
- && XtX(current) == XtX(cnew)
- && XtY(current) == XtY(cnew)
- && XtWidth(current) == XtWidth(cnew)
- && XtHeight(current) == XtHeight(cnew)
- && XtBorderWidth(current) == XtBorderWidth(cnew))
- Layout(fp, 0, 0, True);
- else
- fp->form.needs_relayout = True;
- }
-
- return (False);
-}
-
-static void
-XawFormChangeManaged(Widget w)
-{
- FormWidget fw = (FormWidget)w;
- FormConstraints form;
- WidgetList children, childP;
- int num_children = fw->composite.num_children;
- Widget child;
-
- (*((FormWidgetClass)w->core.widget_class)->form_class.layout)
- (fw, XtWidth(w), XtHeight(w), True);
-
- fw->form.old_width = XtWidth(w);
- fw->form.old_height = XtHeight(w);
- for (children = childP = fw->composite.children;
- childP - children < num_children;
- childP++) {
- child = *childP;
- if (!XtIsManaged(child))
- continue;
- form = (FormConstraints)child->core.constraints;
-#ifndef OLDXAW
- form->form.virtual_x = XtX(child);
- form->form.virtual_y = XtY(child);
-#endif
- form->form.virtual_width = XtWidth(child);
- form->form.virtual_height = XtHeight(child);
- }
-}
-
-static XtGeometryResult
-XawFormQueryGeometry(Widget widget, XtWidgetGeometry *request,
- XtWidgetGeometry *reply)
-{
- FormWidget w = (FormWidget)widget;
-
- reply->width = w->form.preferred_width;
- reply->height = w->form.preferred_height;
- reply->request_mode = CWWidth | CWHeight;
-
- if ((request->request_mode & (CWWidth | CWHeight)) == (CWWidth | CWHeight)
- && request->width == reply->width
- && request->height == reply->height)
- return (XtGeometryYes);
- else if (reply->width == XtWidth(w) && reply->height == XtHeight(w))
- return (XtGeometryNo);
-
- return (XtGeometryAlmost);
-}
-
-/*
- * Public routines
- */
-/*
- * Set or reset figuring (ignored if not realized)
- */
-void
-XawFormDoLayout(Widget w,
-#if NeedWidePrototypes
- Bool force
-#else
- Boolean force
-#endif
-)
-{
- Widget *childP;
- FormWidget fw = (FormWidget)w;
- int num_children = fw->composite.num_children;
- WidgetList children = fw->composite.children;
-
- if ((fw->form.no_refigure = !force) == True || !XtIsRealized(w))
- return;
-
- for (childP = children; childP - children < num_children; childP++) {
- Widget nw = *childP;
-
- if (XtIsManaged(nw)) {
- FormConstraints form = (FormConstraints)nw->core.constraints;
-
- /*
- * Xt Configure widget is too smart, and optimizes out
- * my changes
- */
- XMoveResizeWindow(XtDisplay(nw), XtWindow(nw),
- XtX(nw), XtY(nw), XtWidth(nw), XtHeight(nw));
-
- if (form)
- if (form->form.deferred_resize &&
- XtClass(nw)->core_class.resize != NULL) {
- (*(XtClass(nw)->core_class.resize))(nw);
- form->form.deferred_resize = False;
- }
- }
- }
-}
+/*********************************************************** + +Copyright 1987, 1988, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include <X11/Xmu/CharSet.h> +#include <X11/Xmu/Converters.h> +#include <X11/Xaw/FormP.h> +#include <X11/Xaw/XawInit.h> +#include "Private.h" + +/* + * Class Methods + */ +static void XawFormChangeManaged(Widget); +static void XawFormClassInitialize(void); +static void XawFormClassPartInitialize(WidgetClass); +static void XawFormConstraintInitialize(Widget, Widget, ArgList, Cardinal*); +static Boolean XawFormConstraintSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static XtGeometryResult XawFormGeometryManager(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawFormInitialize(Widget, Widget, ArgList, Cardinal*); +#ifndef OLDXAW +static void XawFormRealize(Widget, Mask*, XSetWindowAttributes*); +static void XawFormRedisplay(Widget, XEvent*, Region); +#endif +static XtGeometryResult XawFormQueryGeometry(Widget, XtWidgetGeometry*, + XtWidgetGeometry*); +static void XawFormResize(Widget); +static Boolean XawFormSetValues(Widget, Widget, Widget, ArgList, Cardinal*); +static Boolean Layout(FormWidget, unsigned int, unsigned int, Bool); + +/* + * Prototypes + */ +static void _CvtStringToEdgeType(XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr); +static Bool ChangeFormGeometry(Widget, Bool, unsigned int, unsigned int, + Dimension*, Dimension*); +Boolean CvtEdgeTypeToString(Display*, XrmValuePtr, Cardinal*, + XrmValuePtr, XrmValuePtr, XtPointer*); +static void LayoutChild(Widget); +static int TransformCoord(int, unsigned int, unsigned int, XtEdgeType); +static void ResizeChildren(Widget); + +/* + * Initialization + */ +#ifndef OLDXAW +static XtActionsRec actions[] = { + {"set-values", XawSetValuesAction}, + {"get-values", XawGetValuesAction}, + {"declare", XawDeclareAction}, + {"call-proc", XawCallProcAction}, +}; +#endif + +static XrmQuark QchainLeft, QchainRight, QchainTop, QchainBottom, Qrubber; + +#define default_value -99999 +#define Offset(field) XtOffsetOf(FormRec, form.field) +static XtResource resources[] = { + { + XtNdefaultDistance, + XtCThickness, + XtRInt, + sizeof(int), + Offset(default_spacing), + XtRImmediate, + (XtPointer)4 + }, +#ifndef OLDXAW + { + XawNdisplayList, + XawCDisplayList, + XawRDisplayList, + sizeof(XawDisplayList*), + Offset(display_list), + XtRImmediate, + NULL + }, +#endif +}; +#undef Offset + +#define defEdge XtRubber + +#define Offset(field) XtOffsetOf(FormConstraintsRec, form.field) +static XtResource formConstraintResources[] = { + { + XtNtop, + XtCEdge, + XtREdgeType, + sizeof(XtEdgeType), + Offset(top), + XtRImmediate, + (XtPointer)defEdge + }, + { + XtNbottom, + XtCEdge, + XtREdgeType, + sizeof(XtEdgeType), + Offset(bottom), + XtRImmediate, + (XtPointer)defEdge + }, + { + XtNleft, + XtCEdge, + XtREdgeType, + sizeof(XtEdgeType), + Offset(left), + XtRImmediate, + (XtPointer)defEdge + }, + { + XtNright, + XtCEdge, + XtREdgeType, + sizeof(XtEdgeType), + Offset(right), + XtRImmediate, + (XtPointer)defEdge + }, + { + XtNhorizDistance, + XtCThickness, + XtRInt, + sizeof(int), + Offset(dx), + XtRImmediate, + (XtPointer)default_value + }, + { + XtNfromHoriz, + XtCWidget, + XtRWidget, + sizeof(Widget), + Offset(horiz_base), + XtRWidget, + NULL + }, + { + XtNvertDistance, + XtCThickness, + XtRInt, + sizeof(int), + Offset(dy), + XtRImmediate, + (XtPointer)default_value + }, + { + XtNfromVert, + XtCWidget, + XtRWidget, + sizeof(Widget), + Offset(vert_base), + XtRWidget, + NULL + }, + { + XtNresizable, + XtCBoolean, + XtRBoolean, + sizeof(Boolean), + Offset(allow_resize), + XtRImmediate, + (XtPointer)False + }, +}; +#undef Offset + +FormClassRec formClassRec = { + /* core */ + { + (WidgetClass)&constraintClassRec, /* superclass */ + "Form", /* class_name */ + sizeof(FormRec), /* widget_size */ + XawFormClassInitialize, /* class_initialize */ + XawFormClassPartInitialize, /* class_part_init */ + False, /* class_inited */ + XawFormInitialize, /* initialize */ + NULL, /* initialize_hook */ +#ifndef OLDXAW + XawFormRealize, /* realize */ + actions, /* actions */ + XtNumber(actions), /* num_actions */ +#else + XtInheritRealize, /* realize */ + NULL, /* actions */ + 0, /* num_actions */ +#endif + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + True, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + NULL, /* destroy */ + XawFormResize, /* resize */ +#ifndef OLDXAW + XawFormRedisplay, /* expose */ +#else + XtInheritExpose, /* expose */ +#endif + XawFormSetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* tm_table */ + XawFormQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL, /* extension */ + }, + /* composite */ + { + XawFormGeometryManager, /* geometry_manager */ + XawFormChangeManaged, /* change_managed */ + XtInheritInsertChild, /* insert_child */ + XtInheritDeleteChild, /* delete_child */ + NULL, /* extension */ + }, + /* constraint */ + { + formConstraintResources, /* subresourses */ + XtNumber(formConstraintResources), /* subresource_count */ + sizeof(FormConstraintsRec), /* constraint_size */ + XawFormConstraintInitialize, /* initialize */ + NULL, /* destroy */ + XawFormConstraintSetValues, /* set_values */ + NULL, /* extension */ + }, + /* form */ + { + Layout, /* layout */ + }, +}; + +WidgetClass formWidgetClass = (WidgetClass)&formClassRec; + +/* + * Implementation + */ +#ifndef OLDXAW +static void +XawFormRealize(Widget w, Mask *mask, XSetWindowAttributes *attr) +{ + XawPixmap *pixmap; + + (*formWidgetClass->core_class.superclass->core_class.realize)(w, mask, attr); + + if (w->core.background_pixmap > XtUnspecifiedPixmap) { + pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w), + w->core.colormap, w->core.depth); + if (pixmap && pixmap->mask) + XawReshapeWidget(w, pixmap); + } +} + +static void +XawFormRedisplay(Widget w, XEvent *event, Region region) +{ + FormWidget xaw = (FormWidget)w; + + if (xaw->form.display_list) + XawRunDisplayList(w, xaw->form.display_list, event, region); +} +#endif + +/*ARGSUSED*/ +static void +_CvtStringToEdgeType(XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal) +{ + static XtEdgeType edgeType; + XrmQuark q; + char name[12]; + + XmuNCopyISOLatin1Lowered(name, (char*)fromVal->addr, sizeof(name)); + q = XrmStringToQuark(name); + + if (q == QchainLeft) + edgeType = XtChainLeft; + else if (q == QchainRight) + edgeType = XtChainRight; + else if (q == QchainTop) + edgeType = XtChainTop; + else if (q == QchainBottom) + edgeType = XtChainBottom; + else if (q == Qrubber) + edgeType = XtRubber; + else { + XtStringConversionWarning(fromVal->addr, XtREdgeType); + toVal->size = 0; + toVal->addr = NULL; + return; + } + + toVal->size = sizeof(XtEdgeType); + toVal->addr = (XPointer)&edgeType; +} + +/*ARGSUSED*/ +Boolean +CvtEdgeTypeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args, + XrmValuePtr fromVal, XrmValuePtr toVal, XtPointer *data) +{ + static String buffer; + Cardinal size; + + switch (*(XtEdgeType *)fromVal->addr) { + case XtChainLeft: + buffer = XtEchainLeft; + break; + case XtChainRight: + buffer = XtEchainRight; + break; + case XtChainTop: + buffer = XtEchainTop; + break; + case XtChainBottom: + buffer = XtEchainBottom; + break; + case XtRubber: + buffer = XtErubber; + break; + default: + XawTypeToStringWarning(dpy, XtREdgeType); + toVal->addr = NULL; + toVal->size = 0; + return (False); + } + + size = strlen(buffer) + 1; + if (toVal->addr != NULL) { + if (toVal->size < size) { + toVal->size = size; + return (False); + } + strcpy((char *)toVal->addr, buffer); + } + else + toVal->addr = (XPointer)buffer; + toVal->size = sizeof(String); + + return (True); +} + +static void +XawFormClassInitialize(void) +{ + static XtConvertArgRec parentCvtArgs[] = { + {XtBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.parent), + sizeof(Widget)} + }; + + char name[12]; + + XawInitializeWidgetSet(); + XmuNCopyISOLatin1Lowered(name, XtEchainLeft, sizeof(name)); + QchainLeft = XrmStringToQuark(name); + XmuNCopyISOLatin1Lowered(name, XtEchainRight, sizeof(name)); + QchainRight = XrmStringToQuark(name); + XmuNCopyISOLatin1Lowered(name, XtEchainTop, sizeof(name)); + QchainTop = XrmStringToQuark(name); + XmuNCopyISOLatin1Lowered(name, XtEchainBottom, sizeof(name)); + QchainBottom = XrmStringToQuark(name); + XmuNCopyISOLatin1Lowered(name, XtErubber, sizeof(name)); + Qrubber = XrmStringToQuark(name); + + XtAddConverter(XtRString, XtREdgeType, _CvtStringToEdgeType, NULL, 0); + XtSetTypeConverter(XtREdgeType, XtRString, CvtEdgeTypeToString, + NULL, 0, XtCacheNone, NULL); + XtSetTypeConverter(XtRString, XtRWidget, XmuNewCvtStringToWidget, + parentCvtArgs, XtNumber(parentCvtArgs), XtCacheNone, + NULL); + XtSetTypeConverter(XtRWidget, XtRString, XmuCvtWidgetToString, + NULL, 0, XtCacheNone, NULL); +} + +static void +XawFormClassPartInitialize(WidgetClass cclass) +{ + FormWidgetClass c = (FormWidgetClass)cclass; + FormWidgetClass super = (FormWidgetClass)c->core_class.superclass; + + if (c->form_class.layout == XtInheritLayout) + c->form_class.layout = super->form_class.layout; +} + +/*ARGSUSED*/ +static void +XawFormInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + FormWidget fw = (FormWidget)cnew; + + fw->form.old_width = fw->form.old_height = 0; + fw->form.no_refigure = False; + fw->form.needs_relayout = False; + fw->form.resize_in_layout = True; + fw->form.resize_is_no_op = False; +} + +/* + * Function: + * ChangeFormGeometry + * + * Parameters: + * w - Form widget + * query_only - is only a query? + * width - new width and height + * height - "" + * ret_width - actual size the form is allowed to resize to (return) + * ret_height - "" + * + * Description: + * Ask the parent to change the form widget's geometry. + * + * Returns: + * True of children may always be resized + */ +static Bool +ChangeFormGeometry(Widget w, Bool query_only, + unsigned int width, unsigned int height, + Dimension *ret_width, Dimension *ret_height) +{ + FormWidget fw = (FormWidget)w; + Boolean always_resize_children; + XtGeometryResult result; + XtWidgetGeometry request, return_request; + + /* + * If we are already at the desired size then there is no need + * to ask our parent of we can change size + */ + if (width == XtWidth(fw) && height == XtHeight(fw)) + return (True); + + request.width = width; + request.height = height; + request.request_mode = CWWidth | CWHeight; + if (query_only) + request.request_mode |= XtCWQueryOnly; + + /* + * Do no invoke the resize rules if our size changes here + */ + fw->form.resize_is_no_op = True; + + result = XtMakeGeometryRequest(w, &request, &return_request); + if (result == XtGeometryAlmost) { + request = return_request; + (void)XtMakeGeometryRequest(w, &request, &return_request); + always_resize_children = False; + } + else + always_resize_children = result == XtGeometryYes; + + fw->form.resize_is_no_op = False; + + if (ret_width != NULL) + *ret_width = request.width; + if (ret_height != NULL) + *ret_height = request.height; + + return (always_resize_children); +} + +/* + * Function: + * Layout + * + * Parameters: + * fw - Form widget + * width - unused + * height - "" + * force_relayout - will force the children to be moved, even if some + * go past the edge of the form + * + * Description: + * Moves all the children around. + * + * Returns: + * True if the children are allowed to move from their + * current locations to the new ones. + */ +/*ARGSUSED*/ +static Boolean +Layout(FormWidget fw, unsigned int width, unsigned int height, + Bool force_relayout) +{ + int num_children = fw->composite.num_children; + WidgetList children = fw->composite.children; + Widget *childP; + Dimension maxx, maxy; + Boolean ret_val; + + for (childP = children; childP - children < num_children; childP++) { + FormConstraints form = (FormConstraints)(*childP)->core.constraints; + form->form.layout_state = LayoutPending; + } + + maxx = maxy = 1; + for (childP = children; childP - children < num_children; childP++) { + if (XtIsManaged(*childP)) { + FormConstraints form; + Position x, y; + + form = (FormConstraints)(*childP)->core.constraints; + + LayoutChild(*childP); + + x = form->form.new_x + XtWidth(*childP) + + (XtBorderWidth(*childP) << 1); + if (x > (int)maxx) + maxx = x; + + y = form->form.new_y + XtHeight(*childP) + + (XtBorderWidth(*childP) << 1); + if (y > (int)maxy) + maxy = y; + } + } + + fw->form.preferred_width = (maxx += fw->form.default_spacing); + fw->form.preferred_height = (maxy += fw->form.default_spacing); + + if (fw->form.resize_in_layout) { + Boolean always_resize_children; + + always_resize_children = + ChangeFormGeometry((Widget)fw, False, maxx, maxy, NULL, NULL); + +#ifdef OLDXAW + fw->form.old_width = fw->core.width; + fw->form.old_height = fw->core.height; +#endif + + if (force_relayout) + ret_val = True; + else + ret_val = always_resize_children || + (XtWidth(fw) >= maxx && XtHeight(fw) >= maxy); + + if (ret_val) + ResizeChildren((Widget)fw); + } + else + ret_val = False; + + fw->form.needs_relayout = False; + + return (ret_val); +} + +/* + * Function: + * ResizeChildren + * + * Parameters: + * w - form widget + * + * Description: + * Resizes all children to new_x and new_y. + */ +static void +ResizeChildren(Widget w) +{ + FormWidget fw = (FormWidget)w; + int num_children = fw->composite.num_children; + WidgetList children = fw->composite.children; + Widget *childP; + + for (childP = children; childP - children < num_children; childP++) { + FormConstraints form; + Position x, y; + + if (!XtIsManaged(*childP)) + continue; + + form = (FormConstraints)(*childP)->core.constraints; + + if (fw->form.old_width && fw->form.old_height) { + x = TransformCoord(form->form.new_x, fw->form.old_width, + XtWidth(fw), form->form.left); + y = TransformCoord(form->form.new_y, fw->form.old_height, + XtHeight(fw), form->form.top); + } + else { + x = form->form.new_x; + y = form->form.new_y; + } + + if (fw->form.no_refigure) { + /* + * I am changing the widget wrapper w/o modifing the window. This is + * risky, but I can get away with it since I am the parent of this + * widget, and he must ask me for any geometry changes + * + * The window will be updated when no_refigure is set back to False + */ + XtX(*childP) = x; + XtY(*childP) = y; + } + else + XtMoveWidget(*childP, x, y); + } +} + +static void +LayoutChild(Widget w) +{ + FormConstraints form = (FormConstraints)w->core.constraints; + Widget ref; + + switch (form->form.layout_state) { + case LayoutPending: + form->form.layout_state = LayoutInProgress; + break; + case LayoutDone: + return; + case LayoutInProgress: { + String subs[2]; + Cardinal num_subs = 2; + subs[0] = w->core.name; + subs[1] = w->core.parent->core.name; + + XtAppWarningMsg(XtWidgetToApplicationContext(w), + "constraintLoop", "xawFormLayout", "XawToolkitError", + "constraint loop detected while laying out " + "child '%s' in FormWidget '%s'", + subs, &num_subs); + } return; + } + + form->form.new_x = form->form.dx; + form->form.new_y = form->form.dy; + if ((ref = form->form.horiz_base) != NULL) { + FormConstraints ref_form = (FormConstraints)ref->core.constraints; + + LayoutChild(ref); + form->form.new_x += ref_form->form.new_x + XtWidth(ref) + + (XtBorderWidth(ref) << 1); + } + if ((ref = form->form.vert_base) != NULL) { + FormConstraints ref_form = (FormConstraints)ref->core.constraints; + + LayoutChild(ref); + form->form.new_y += ref_form->form.new_y + XtHeight(ref) + + (XtBorderWidth(ref) << 1); + } + + form->form.layout_state = LayoutDone; +} + +static int +TransformCoord(int loc, unsigned int old, unsigned int cnew, XtEdgeType type) +{ + if (type == XtRubber) { + if ((int)old > 0) + loc = (int)(loc * ((double)cnew / (double)old)); + } + else if (type == XtChainBottom || type == XtChainRight) + loc += (int)cnew - (int)old; + + return (loc); +} + +static void +XawFormResize(Widget w) +{ + FormWidget fw = (FormWidget)w; + WidgetList children = fw->composite.children; + int num_children = fw->composite.num_children; + Widget *childP; + int x, y; + int width, height; + Boolean unmap = XtIsRealized(w) && w->core.mapped_when_managed && + XtIsManaged(w); + + if (unmap) + XtUnmapWidget(w); + + if (!fw->form.resize_is_no_op) + for (childP = children; childP - children < num_children; childP++) { + FormConstraints form = (FormConstraints)(*childP)->core.constraints; + + if (!XtIsManaged(*childP)) + continue; + +#ifndef OLDXAW + x = TransformCoord(form->form.virtual_x, fw->form.old_width, + XtWidth(fw), form->form.left); + y = TransformCoord(form->form.virtual_y, fw->form.old_height, + XtHeight(fw), form->form.top); + width = TransformCoord(form->form.virtual_x + + form->form.virtual_width + + (XtBorderWidth(*childP) << 1), + fw->form.old_width, XtWidth(fw), + form->form.right) - + (x + (XtBorderWidth(*childP) << 1)); + height = TransformCoord(form->form.virtual_y + + form->form.virtual_height + + (XtBorderWidth(*childP) << 1), + fw->form.old_height, XtHeight(fw), + form->form.bottom) - + (y + (XtBorderWidth(*childP) << 1)); +#else + x = TransformCoord(XtX(*childP), fw->form.old_width, + XtWidth(fw), form->form.left); + y = TransformCoord(XtY(*childP), fw->form.old_height, + XtHeight(fw), form->form.top); + width = TransformCoord(XtX(*childP) + form->form.virtual_width + + (XtBorderWidth(*childP) << 1), + fw->form.old_width, XtWidth(fw), + form->form.right) - + (x + (XtBorderWidth(*childP) << 1)); + height = TransformCoord(XtY(*childP) + form->form.virtual_height + + (XtBorderWidth(*childP) << 1), + fw->form.old_height, XtHeight(fw), + form->form.bottom) - + (y + (XtBorderWidth(*childP) << 1)); + form->form.virtual_width = width; + form->form.virtual_height = height; +#endif + + width = width < 1 ? 1 : width; + height = height < 1 ? 1 : height; + + XtConfigureWidget(*childP, x, y, width, height, + XtBorderWidth(*childP)); + } + + if (unmap) + XtMapWidget(w); + +#ifdef OLDXAW + fw->form.old_width = XtWidth(fw); + fw->form.old_height = XtHeight(fw); +#endif +} + +/*ARGSUSED*/ +static XtGeometryResult +XawFormGeometryManager(Widget w, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + Dimension old_width, old_height; + FormWidget fw = (FormWidget)XtParent(w); + FormConstraints form = (FormConstraints)w->core.constraints; + XtWidgetGeometry allowed; + XtGeometryResult ret_val; + + if ((request->request_mode & (unsigned)~(XtCWQueryOnly | CWWidth | CWHeight)) + || !form->form.allow_resize) { + /* If GeometryManager is invoked during a SetValues call on a child + * then it is necessary to compute a new layout if ConstraintSetValues + * allowed any constraint changes + */ + if (fw->form.needs_relayout) + (*((FormWidgetClass)fw->core.widget_class)->form_class.layout) + (fw, 0, 0, True); + return (XtGeometryNo); + } + + if (request->request_mode & CWWidth) + allowed.width = request->width; + else + allowed.width = XtWidth(w); + + if (request->request_mode & CWHeight) + allowed.height = request->height; + else + allowed.height = XtHeight(w); + + if (allowed.width == XtWidth(w) && allowed.height == XtHeight(w)) { + /* If GeometryManager is invoked during a SetValues call on a child + * then it is necessary to compute a new layout if ConstraintSetValues + * allowed any constraint changes + */ + if (fw->form.needs_relayout) + (*((FormWidgetClass)fw->core.widget_class)->form_class.layout) + (fw, 0, 0, True); + return (XtGeometryNo); + } + + /* + * Remember the old size, and then set the size to the requested size + */ + old_width = XtWidth(w); + old_height = XtHeight(w); + XtWidth(w) = allowed.width; + XtHeight(w) = allowed.height; + + if (request->request_mode & XtCWQueryOnly) { + Boolean always_resize_children; + Dimension ret_width, ret_height; + + fw->form.resize_in_layout = False; + + (*((FormWidgetClass)fw->core.widget_class)->form_class.layout) + (fw, XtWidth(w), XtHeight(w), False); + + /* + * Reset the size of this child back to what it used to be + */ + XtWidth(w) = old_width; + XtHeight(w) = old_height; + + fw->form.resize_in_layout = True; + + always_resize_children = ChangeFormGeometry(w, True, + fw->form.preferred_width, + fw->form.preferred_height, + &ret_width, &ret_height); + + if (always_resize_children + || (ret_width >= fw->form.preferred_width + && ret_height >= fw->form.preferred_height)) + ret_val = XtGeometryYes; + else + ret_val = XtGeometryNo; + } + else { + if ((*((FormWidgetClass)fw->core.widget_class)->form_class.layout) + (fw, XtWidth(w), XtHeight(w), False)) { + Widget *childP; + int num_children = fw->composite.num_children; + WidgetList children = fw->composite.children; + + if (fw->form.no_refigure) { + /* + * I am changing the widget wrapper w/o modifing the window. + * This is risky, but I can get away with it since I am the + * parent of this widget, and he must ask me for any geometry + * changes + * + * The window will be updated when no_refigure is set back + * to False + */ + form->form.deferred_resize = True; + ret_val = XtGeometryDone; + } + else + ret_val = XtGeometryYes; + + /* + * Resets everything. + */ + fw->form.old_width = XtWidth(fw); + fw->form.old_height = XtHeight(fw); + for (childP = children; childP - children < num_children; childP++) { + Widget nw = *childP; + + if (XtIsManaged(nw)) { + FormConstraints nform = (FormConstraints)nw->core.constraints; + +#ifndef OLDXAW + nform->form.virtual_x = XtX(nw); + nform->form.virtual_y = XtY(nw); +#endif + nform->form.virtual_width = XtWidth(nw); + nform->form.virtual_height = XtHeight(nw); + } + } + } + else { + XtWidth(w) = old_width; + XtHeight(w) = old_height; + ret_val = XtGeometryNo; + } + } + + return (ret_val); +} + +/*ARGSUSED*/ +static Boolean +XawFormSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ +#ifndef OLDXAW + FormWidget f_old = (FormWidget)current; + FormWidget f_new = (FormWidget)cnew; + + if (f_old->core.background_pixmap != f_new->core.background_pixmap) { + XawPixmap *opix, *npix; + + opix = XawPixmapFromXPixmap(f_old->core.background_pixmap, XtScreen(f_old), + f_old->core.colormap, f_old->core.depth); + npix = XawPixmapFromXPixmap(f_new->core.background_pixmap, XtScreen(f_new), + f_new->core.colormap, f_new->core.depth); + if ((npix && npix->mask) || (opix && opix->mask)) + XawReshapeWidget(cnew, npix); + } +#endif /* OLDXAW */ + + return (False); +} + +/* ARGSUSED */ +static void +XawFormConstraintInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + FormConstraints form = (FormConstraints)cnew->core.constraints; + FormWidget fw = (FormWidget)cnew->core.parent; + +#ifndef OLDXAW + form->form.virtual_x = XtX(cnew); + form->form.virtual_y = XtY(cnew); +#endif + form->form.virtual_width = XtWidth(cnew); + form->form.virtual_height = XtHeight(cnew); + + if (form->form.dx == default_value) + form->form.dx = fw->form.default_spacing; + + if (form->form.dy == default_value) + form->form.dy = fw->form.default_spacing; + + form->form.deferred_resize = False; +} + +/*ARGSUSED*/ +static Boolean +XawFormConstraintSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + FormConstraints cfc = (FormConstraints)current->core.constraints; + FormConstraints nfc = (FormConstraints)cnew->core.constraints; + + if (cfc->form.top != nfc->form.top || cfc->form.bottom != nfc->form.bottom + || cfc->form.left != nfc->form.left || cfc->form.right != nfc->form.right + || cfc->form.dx != nfc->form.dx || cfc->form.dy != nfc->form.dy + || cfc->form.horiz_base != nfc->form.horiz_base + || cfc->form.vert_base != nfc->form.vert_base) { + FormWidget fp = (FormWidget)XtParent(cnew); + + /* If there are no subclass ConstraintSetValues procedures remaining + * to be invoked, and if there is no geometry request about to be + * made, then invoke the new layout now; else defer it + */ + if (XtClass(XtParent(cnew)) == formWidgetClass + && XtX(current) == XtX(cnew) + && XtY(current) == XtY(cnew) + && XtWidth(current) == XtWidth(cnew) + && XtHeight(current) == XtHeight(cnew) + && XtBorderWidth(current) == XtBorderWidth(cnew)) + Layout(fp, 0, 0, True); + else + fp->form.needs_relayout = True; + } + + return (False); +} + +static void +XawFormChangeManaged(Widget w) +{ + FormWidget fw = (FormWidget)w; + FormConstraints form; + WidgetList children, childP; + int num_children = fw->composite.num_children; + Widget child; + + (*((FormWidgetClass)w->core.widget_class)->form_class.layout) + (fw, XtWidth(w), XtHeight(w), True); + + fw->form.old_width = XtWidth(w); + fw->form.old_height = XtHeight(w); + for (children = childP = fw->composite.children; + childP - children < num_children; + childP++) { + child = *childP; + if (!XtIsManaged(child)) + continue; + form = (FormConstraints)child->core.constraints; +#ifndef OLDXAW + form->form.virtual_x = XtX(child); + form->form.virtual_y = XtY(child); +#endif + form->form.virtual_width = XtWidth(child); + form->form.virtual_height = XtHeight(child); + } +} + +static XtGeometryResult +XawFormQueryGeometry(Widget widget, XtWidgetGeometry *request, + XtWidgetGeometry *reply) +{ + FormWidget w = (FormWidget)widget; + + reply->width = w->form.preferred_width; + reply->height = w->form.preferred_height; + reply->request_mode = CWWidth | CWHeight; + + if ((request->request_mode & (CWWidth | CWHeight)) == (CWWidth | CWHeight) + && request->width == reply->width + && request->height == reply->height) + return (XtGeometryYes); + else if (reply->width == XtWidth(w) && reply->height == XtHeight(w)) + return (XtGeometryNo); + + return (XtGeometryAlmost); +} + +/* + * Public routines + */ +/* + * Set or reset figuring (ignored if not realized) + */ +void +XawFormDoLayout(Widget w, +#if NeedWidePrototypes + Bool force +#else + Boolean force +#endif +) +{ + Widget *childP; + FormWidget fw = (FormWidget)w; + int num_children = fw->composite.num_children; + WidgetList children = fw->composite.children; + + if ((fw->form.no_refigure = !force) == True || !XtIsRealized(w)) + return; + + for (childP = children; childP - children < num_children; childP++) { + Widget nw = *childP; + + if (XtIsManaged(nw)) { + FormConstraints form = (FormConstraints)nw->core.constraints; + + /* + * Xt Configure widget is too smart, and optimizes out + * my changes + */ + XMoveResizeWindow(XtDisplay(nw), XtWindow(nw), + XtX(nw), XtY(nw), XtWidth(nw), XtHeight(nw)); + + if (form) + if (form->form.deferred_resize && + XtClass(nw)->core_class.resize != NULL) { + (*(XtClass(nw)->core_class.resize))(nw); + form->form.deferred_resize = False; + } + } + } +} |