Blame lib/Xm/Form.c

Packit b099d7
/* 
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
*/ 
Packit b099d7
/* 
Packit b099d7
 * HISTORY
Packit b099d7
*/ 
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char rcsid[] = "$TOG: Form.c /main/19 1998/03/25 12:24:56 csn $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
Packit b099d7
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
Packit b099d7
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#ifndef X_NOT_STDC_ENV
Packit b099d7
#include <stdlib.h>		/* for abs, float operation... */
Packit b099d7
#endif
Packit b099d7
#include <Xm/DrawP.h>
Packit b099d7
#include <Xm/FormP.h>
Packit b099d7
#include <Xm/DialogS.h>
Packit b099d7
#include <Xm/VaSimpleP.h>
Packit b099d7
#include "XmI.h"
Packit b099d7
#include "MessagesI.h"
Packit b099d7
#include "RepTypeI.h"
Packit b099d7
#include "GeoUtilsI.h"
Packit b099d7
#include "GMUtilsI.h"
Packit b099d7
Packit b099d7
#define FIX_1299
Packit b099d7
Packit b099d7
#define MESSAGE1	_XmMMsgForm_0000
Packit b099d7
#define MESSAGE5	_XmMMsgForm_0002
Packit b099d7
#define MESSAGE7 	_XmMMsgForm_0003
Packit b099d7
	
Packit b099d7
Packit b099d7
/*  Useful macros  */
Packit b099d7
Packit b099d7
#define Value(a) (really ? (a)->value : (a)->tempValue)
Packit b099d7
Packit b099d7
#define AssignValue(a, v)  (really ? (a->value = (int) (v))\
Packit b099d7
			           : (a->tempValue = (int) (v)))
Packit b099d7
Packit b099d7
#define GetFormConstraint(w) \
Packit b099d7
	(&((XmFormConstraintPtr) (w)->core.constraints)->form)
Packit b099d7
Packit b099d7
#define NE(x) (oldc->x != newc->x)
Packit b099d7
Packit b099d7
#define ANY(x) (NE(att[LEFT].x) || NE(att[RIGHT].x) || \
Packit b099d7
		NE(att[TOP].x)  || NE(att[BOTTOM].x))
Packit b099d7
Packit b099d7
#define SIBLINGS(w,s)	(((w != NULL) && (s != NULL)) &&\
Packit b099d7
			 (XtParent(w) == XtParent(s)))
Packit b099d7
Packit b099d7
#ifdef FIX_1299
Packit b099d7
#define ATTACHED_WIDGET(cons, j) \
Packit b099d7
  (cons->att[j].w)
Packit b099d7
  
Packit b099d7
#define IS_ATTACHED_WIDGET(cons, j) \
Packit b099d7
  ((cons->att[j].type == XmATTACH_WIDGET || cons->att[j].type == XmATTACH_OPPOSITE_WIDGET) \
Packit b099d7
  && cons->att[j].w != (Widget) NULL)
Packit b099d7
#endif /* FIX_1299 */
Packit b099d7
Packit b099d7
/* convenient magic numbers */
Packit b099d7
Packit b099d7
#define MAX_LOOP 10000
Packit b099d7
Packit b099d7
#define LEFT	_XmFORM_LEFT
Packit b099d7
#define RIGHT	_XmFORM_RIGHT
Packit b099d7
#define TOP	_XmFORM_TOP
Packit b099d7
#define BOTTOM	_XmFORM_BOTTOM
Packit b099d7
#define FIRST_ATTACHMENT  LEFT
Packit b099d7
#define LAST_ATTACHMENT   BOTTOM	
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static void FromTopOffset( 
Packit b099d7
                        Widget w,
Packit b099d7
                        int offset,
Packit b099d7
                        XtArgVal *value) ;
Packit b099d7
static void FromBottomOffset( 
Packit b099d7
                        Widget w,
Packit b099d7
                        int offset,
Packit b099d7
                        XtArgVal *value) ;
Packit b099d7
static void FromLeftOffset( 
Packit b099d7
                        Widget w,
Packit b099d7
                        int offset,
Packit b099d7
                        XtArgVal *value) ;
Packit b099d7
static void FromRightOffset( 
Packit b099d7
                        Widget w,
Packit b099d7
                        int offset,
Packit b099d7
                        XtArgVal *value) ;
Packit b099d7
static void MarginWidthOut( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        int offset,
Packit b099d7
                        XtArgVal *value) ;
Packit b099d7
static void MarginHeightOut( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        int offset,
Packit b099d7
                        XtArgVal *value) ;
Packit b099d7
static void ClassPartInitialize( 
Packit b099d7
                        WidgetClass wc) ;
Packit b099d7
static Boolean SyncEdges( 
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
                        Widget last_child,
Packit b099d7
                        Dimension *form_width,
Packit b099d7
                        Dimension *form_height,
Packit b099d7
                        Widget instigator,
Packit b099d7
                        XtWidgetGeometry *geometry) ;
Packit b099d7
static Boolean CalcFormSizeWithChange( 
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
                        Dimension *w,
Packit b099d7
                        Dimension *h,
Packit b099d7
                        Widget c,
Packit b099d7
                        XtWidgetGeometry *g) ;
Packit b099d7
static void CalcFormSize( 
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
                        Dimension *w,
Packit b099d7
                        Dimension *h) ;
Packit b099d7
static XtGeometryResult GeometryManager( 
Packit b099d7
                        Widget w,
Packit b099d7
                        XtWidgetGeometry *desired,
Packit b099d7
                        XtWidgetGeometry *allowed) ;
Packit b099d7
static XtGeometryResult QueryGeometry( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XtWidgetGeometry *req,
Packit b099d7
                        XtWidgetGeometry *ret) ;
Packit b099d7
static void Resize( 
Packit b099d7
                        Widget wid) ;
Packit b099d7
static void Redisplay( 
Packit b099d7
                        Widget fw,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        Region region) ;
Packit b099d7
#ifdef FIX_1299
Packit b099d7
static void UpdateAttachments(
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
                        Widget wid,
Packit b099d7
                        Widget instigator,
Packit b099d7
                        XtWidgetGeometry* inst_geometry);
Packit b099d7
static void PlaceChild(
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
                        Widget child,
Packit b099d7
                        Widget instigator,
Packit b099d7
                        XtWidgetGeometry* inst_geometry);
Packit b099d7
#endif /* FIX_1299 */
Packit b099d7
static void PlaceChildren( 
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
                        Widget instigator,
Packit b099d7
                        XtWidgetGeometry *inst_geometry) ;
Packit b099d7
static void ChangeManaged( 
Packit b099d7
                        Widget wid) ;
Packit b099d7
static void GetSize( 
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
		        XtWidgetGeometry *g,
Packit b099d7
                        Widget w,
Packit b099d7
                        XtWidgetGeometry *desired) ;
Packit b099d7
static void ChangeIfNeeded( 
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
                        Widget w,
Packit b099d7
                        XtWidgetGeometry *desired) ;
Packit b099d7
static void DeleteChild( 
Packit b099d7
                        Widget child) ;
Packit b099d7
static Boolean SetValues( 
Packit b099d7
                        Widget cw,
Packit b099d7
                        Widget rw,
Packit b099d7
                        Widget nw,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void SetValuesAlmost( 
Packit b099d7
                        Widget cw,
Packit b099d7
                        Widget nw,
Packit b099d7
                        XtWidgetGeometry *req,
Packit b099d7
                        XtWidgetGeometry *rep) ;
Packit b099d7
static Boolean ConstraintSetValues( 
Packit b099d7
                        register Widget old,
Packit b099d7
                        register Widget ref,
Packit b099d7
                        register Widget new_w,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void Initialize( 
Packit b099d7
                        Widget rw,
Packit b099d7
                        Widget nw,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void ConstraintInitialize( 
Packit b099d7
                        Widget req,
Packit b099d7
                        Widget new_w,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void CheckConstraints( 
Packit b099d7
                        Widget w) ;
Packit b099d7
static void SortChildren( 
Packit b099d7
                        register XmFormWidget fw) ;
Packit b099d7
static void CalcEdgeValues( 
Packit b099d7
                        Widget w,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int really,
Packit b099d7
#else
Packit b099d7
                        Boolean really,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        Widget instigator,
Packit b099d7
                        XtWidgetGeometry *inst_geometry,
Packit b099d7
                        Dimension *form_width,
Packit b099d7
                        Dimension *form_height) ;
Packit b099d7
static float CheckBottomBase( 
Packit b099d7
                        Widget sibling,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int opposite) ;
Packit b099d7
#else
Packit b099d7
                        Boolean opposite) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static float CheckRightBase( 
Packit b099d7
                        Widget sibling,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int opposite) ;
Packit b099d7
#else
Packit b099d7
                        Boolean opposite) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static float CheckLeftBase( 
Packit b099d7
                        Widget sibling,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int opposite) ;
Packit b099d7
#else
Packit b099d7
                        Boolean opposite) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static void CalcEdgeValue( 
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
                        Widget w,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int size,
Packit b099d7
                        int border_width,
Packit b099d7
#else
Packit b099d7
                        Dimension size,
Packit b099d7
                        Dimension border_width,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        int which,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int really,
Packit b099d7
#else
Packit b099d7
                        Boolean really,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        Dimension *fwidth,
Packit b099d7
                        Dimension *fheight) ;
Packit b099d7
static void ComputeAttachment( 
Packit b099d7
			XmFormWidget fw,
Packit b099d7
                        Widget w,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int size,
Packit b099d7
                        int border_width,
Packit b099d7
#else
Packit b099d7
                        Dimension size,
Packit b099d7
                        Dimension border_width,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        int which,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int really,
Packit b099d7
#else
Packit b099d7
                        Boolean really,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        Dimension *fwidth,
Packit b099d7
                        Dimension *fheight) ;
Packit b099d7
static int GetFormOffset( 
Packit b099d7
                        XmFormWidget fw,
Packit b099d7
                        int which,
Packit b099d7
                        XmFormAttachment a) ;
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
Packit b099d7
static XtResource resources[] = 
Packit b099d7
{
Packit b099d7
   {
Packit b099d7
       XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension,
Packit b099d7
       sizeof(Dimension),
Packit b099d7
       XtOffsetOf( struct _XmFormRec, bulletin_board.margin_width),
Packit b099d7
       XmRImmediate, (XtPointer) XmINVALID_DIMENSION
Packit b099d7
   },
Packit b099d7
   {
Packit b099d7
       XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension,
Packit b099d7
       sizeof(Dimension),
Packit b099d7
       XtOffsetOf( struct _XmFormRec, bulletin_board.margin_height),
Packit b099d7
       XmRImmediate, (XtPointer) XmINVALID_DIMENSION
Packit b099d7
   },
Packit b099d7
   {
Packit b099d7
       XmNhorizontalSpacing, XmCSpacing, XmRHorizontalDimension,
Packit b099d7
       sizeof(Dimension),
Packit b099d7
       XtOffsetOf( struct _XmFormRec, form.horizontal_spacing), 
Packit b099d7
       XmRImmediate, (XtPointer) 0
Packit b099d7
   },
Packit b099d7
   {
Packit b099d7
       XmNverticalSpacing, XmCSpacing, XmRVerticalDimension,
Packit b099d7
       sizeof(Dimension),
Packit b099d7
       XtOffsetOf( struct _XmFormRec, form.vertical_spacing), 
Packit b099d7
       XmRImmediate, (XtPointer) 0
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
       XmNfractionBase, XmCMaxValue, XmRInt, sizeof(int),
Packit b099d7
       XtOffsetOf( struct _XmFormRec, form.fraction_base), 
Packit b099d7
       XmRImmediate, (XtPointer) 100
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
       XmNrubberPositioning, XmCRubberPositioning, XmRBoolean, 
Packit b099d7
       sizeof(Boolean),
Packit b099d7
       XtOffsetOf( struct _XmFormRec, form.rubber_positioning), 
Packit b099d7
       XmRImmediate, (XtPointer) False
Packit b099d7
   },
Packit b099d7
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
/*  Definition for resources that need special processing in get values  */
Packit b099d7
Packit b099d7
static XmSyntheticResource syn_resources[] =
Packit b099d7
{
Packit b099d7
   { XmNmarginWidth,
Packit b099d7
     sizeof (Dimension),
Packit b099d7
     XtOffsetOf( struct _XmFormRec, bulletin_board.margin_width), 
Packit b099d7
	 MarginWidthOut,
Packit b099d7
	 XmeToHorizontalPixels },
Packit b099d7
Packit b099d7
   { XmNmarginHeight,
Packit b099d7
     sizeof (Dimension),
Packit b099d7
     XtOffsetOf( struct _XmFormRec, bulletin_board.margin_height), 
Packit b099d7
	 MarginHeightOut,
Packit b099d7
	 XmeToVerticalPixels },
Packit b099d7
Packit b099d7
   { XmNhorizontalSpacing,
Packit b099d7
     sizeof (Dimension),
Packit b099d7
     XtOffsetOf( struct _XmFormRec, form.horizontal_spacing), 
Packit b099d7
     XmeFromHorizontalPixels,
Packit b099d7
	 XmeToHorizontalPixels },
Packit b099d7
Packit b099d7
   { XmNverticalSpacing,
Packit b099d7
     sizeof (Dimension),
Packit b099d7
     XtOffsetOf( struct _XmFormRec, form.vertical_spacing), 
Packit b099d7
     XmeFromVerticalPixels,
Packit b099d7
	 XmeToVerticalPixels },
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
/*  The constraint resource list  */
Packit b099d7
Packit b099d7
static XtResource constraints[] =
Packit b099d7
{
Packit b099d7
   {
Packit b099d7
      XmNtopAttachment, XmCAttachment, XmRAttachment, sizeof(unsigned char),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[TOP].type),
Packit b099d7
      XmRImmediate, (XtPointer) XmATTACH_NONE
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNbottomAttachment, XmCAttachment, XmRAttachment,
Packit b099d7
      sizeof(unsigned char),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[BOTTOM].type),
Packit b099d7
      XmRImmediate, (XtPointer) XmATTACH_NONE
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNleftAttachment, XmCAttachment, XmRAttachment,
Packit b099d7
      sizeof(unsigned char),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[LEFT].type),
Packit b099d7
      XmRImmediate, (XtPointer) XmATTACH_NONE
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNrightAttachment, XmCAttachment, XmRAttachment,
Packit b099d7
      sizeof(unsigned char),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[RIGHT].type),
Packit b099d7
      XmRImmediate, (XtPointer) XmATTACH_NONE
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNtopWidget, XmCWidget, XmRWidget, sizeof(Widget),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[TOP].w),
Packit b099d7
      XmRImmediate, (XtPointer) NULL
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNbottomWidget, XmCWidget, XmRWidget, sizeof(Widget),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[BOTTOM].w),
Packit b099d7
      XmRImmediate, (XtPointer) NULL
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNleftWidget, XmCWidget, XmRWidget, sizeof(Widget),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[LEFT].w),
Packit b099d7
      XmRImmediate, (XtPointer) NULL
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNrightWidget, XmCWidget, XmRWidget, sizeof(Widget),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[RIGHT].w),
Packit b099d7
      XmRImmediate, (XtPointer) NULL
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNtopPosition, XmCPosition, XmRInt, sizeof(int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[TOP].percent),
Packit b099d7
      XmRImmediate, (XtPointer) 0
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNbottomPosition, XmCPosition, XmRInt, sizeof(int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[BOTTOM].percent),
Packit b099d7
      XmRImmediate, (XtPointer) 0
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNleftPosition, XmCPosition, XmRInt, sizeof(int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[LEFT].percent),
Packit b099d7
      XmRImmediate, (XtPointer) 0
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNrightPosition, XmCPosition, XmRInt, sizeof(int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[RIGHT].percent),
Packit b099d7
      XmRImmediate, (XtPointer) 0
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNtopOffset, XmCOffset, XmRVerticalInt, sizeof(int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[TOP].offset),
Packit b099d7
      XmRImmediate, (XtPointer) XmINVALID_DIMENSION
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNbottomOffset, XmCOffset, XmRVerticalInt, sizeof(int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[BOTTOM].offset),
Packit b099d7
      XmRImmediate, (XtPointer) XmINVALID_DIMENSION
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNleftOffset, XmCOffset, XmRHorizontalInt, sizeof(int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[LEFT].offset),
Packit b099d7
      XmRImmediate, (XtPointer) XmINVALID_DIMENSION
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNrightOffset, XmCOffset, XmRHorizontalInt, sizeof(int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[RIGHT].offset),
Packit b099d7
      XmRImmediate, (XtPointer) XmINVALID_DIMENSION
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XmNresizable, XmCBoolean, XmRBoolean, sizeof(Boolean),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.resizable),
Packit b099d7
      XmRImmediate, (XtPointer) True
Packit b099d7
   }
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
/*  Definition for constraint resources that need special  */
Packit b099d7
/*  processing in get values                               */
Packit b099d7
Packit b099d7
static XmSyntheticResource syn_constraint_resources[] =
Packit b099d7
{
Packit b099d7
Packit b099d7
   { XmNtopOffset,
Packit b099d7
     sizeof (int),
Packit b099d7
     XtOffsetOf( struct _XmFormConstraintRec, form.att[TOP].offset),
Packit b099d7
     FromTopOffset,
Packit b099d7
	 XmeToVerticalPixels },
Packit b099d7
Packit b099d7
   {  XmNbottomOffset,
Packit b099d7
      sizeof (int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[BOTTOM].offset),
Packit b099d7
     FromBottomOffset,
Packit b099d7
	 XmeToVerticalPixels },
Packit b099d7
Packit b099d7
   {  XmNleftOffset,
Packit b099d7
      sizeof (int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[LEFT].offset),
Packit b099d7
     FromLeftOffset,
Packit b099d7
	 XmeToHorizontalPixels },
Packit b099d7
Packit b099d7
   {  XmNrightOffset,
Packit b099d7
      sizeof (int),
Packit b099d7
      XtOffsetOf( struct _XmFormConstraintRec, form.att[RIGHT].offset),
Packit b099d7
     FromRightOffset,
Packit b099d7
	 XmeToHorizontalPixels },
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/*  Static initialization of the attached dialog box widget class record.  */
Packit b099d7
Packit b099d7
externaldef(xmformclassrec) XmFormClassRec xmFormClassRec =
Packit b099d7
{
Packit b099d7
   {                    /* core_class fields    */
Packit b099d7
      (WidgetClass) &xmBulletinBoardClassRec,   /* superclass   */
Packit b099d7
      "XmForm",                 /* class_name           */
Packit b099d7
      sizeof(XmFormRec),        /* widget_size          */
Packit b099d7
      (XtProc)NULL,             /* class_initialize */
Packit b099d7
      ClassPartInitialize,      /* class init part proc */
Packit b099d7
      False,                    /* class_inited         */
Packit b099d7
      Initialize,               /* initialize           */
Packit b099d7
      (XtArgsProc)NULL,         /* initialize_notify    */
Packit b099d7
      XtInheritRealize,         /* realize              */
Packit b099d7
      NULL,                     /* actions              */
Packit b099d7
      0,                        /* num_actions          */
Packit b099d7
      resources,                /* resources            */
Packit b099d7
      XtNumber(resources),      /* num_resources        */
Packit b099d7
      NULLQUARK,                /* xrm_class            */
Packit b099d7
      True,                     /* compress_motion  */
Packit b099d7
      XtExposeCompressMaximal,  /* compress_exposure    */
Packit b099d7
      False,                    /* compress_enterleave  */
Packit b099d7
      False,                    /* visible_interest     */
Packit b099d7
      (XtWidgetProc)NULL,       /* destroy              */
Packit b099d7
      Resize,                   /* resize               */
Packit b099d7
      Redisplay,                /* expose               */
Packit b099d7
      SetValues,                /* set_values           */
Packit b099d7
      (XtArgsFunc)NULL,         /* set_values_hook      */
Packit b099d7
      SetValuesAlmost,          /* set_values_almost    */
Packit b099d7
      (XtArgsProc)NULL,         /* get_values_hook      */
Packit b099d7
      (XtAcceptFocusProc)NULL,  /* accept_focus         */
Packit b099d7
      XtVersion,                /* version      */
Packit b099d7
      NULL,                     /* callback_private */
Packit b099d7
      XtInheritTranslations,    /* tm_table             */
Packit b099d7
      QueryGeometry,            /* Query Geometry proc  */
Packit b099d7
      (XtStringProc)NULL,       /* disp accelerator     */
Packit b099d7
      NULL,                     /* extension            */    
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {                    /* composite_class fields */
Packit b099d7
      GeometryManager,      /* geometry_manager       */
Packit b099d7
      ChangeManaged,        /* change_managed         */
Packit b099d7
      XtInheritInsertChild, /* insert_child           */
Packit b099d7
      DeleteChild,          /* delete_child           */
Packit b099d7
      NULL,                 /* extension              */
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {                    /* constraint_class fields */
Packit b099d7
      constraints,                  /* constraint resource     */
Packit b099d7
      XtNumber(constraints),        /* number of constraints   */
Packit b099d7
      sizeof(XmFormConstraintRec),  /* size of constraint      */
Packit b099d7
      ConstraintInitialize,         /* initialization          */
Packit b099d7
      (XtWidgetProc)NULL,           /* destroy proc            */
Packit b099d7
      ConstraintSetValues,          /* set_values proc         */
Packit b099d7
      NULL,                         /* extension               */
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {                        /* manager_class fields   */
Packit b099d7
      XtInheritTranslations,                /* translations           */
Packit b099d7
      syn_resources,                        /* syn_resources          */
Packit b099d7
      XtNumber(syn_resources),              /* num_syn_resources      */
Packit b099d7
      syn_constraint_resources,             /* syn_cont_resources     */
Packit b099d7
      XtNumber(syn_constraint_resources),   /* num_syn_cont_resources */
Packit b099d7
      XmInheritParentProcess,               /* parent_process         */
Packit b099d7
      NULL,                                 /* extension              */
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {                        /* bulletin_board_class fields */
Packit b099d7
      FALSE,                                /* always_install_accelerators */
Packit b099d7
      (XmGeoCreateProc)NULL,                /* geo_matrix_create  */
Packit b099d7
      XmInheritFocusMovedProc,              /* focus_moved_proc   */
Packit b099d7
      NULL,                                 /* extension          */
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {                        /* form_class fields  */
Packit b099d7
      (XtPointer) NULL,                     /* extension          */
Packit b099d7
   }
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
externaldef(xmformwidgetclass) WidgetClass 
Packit b099d7
	xmFormWidgetClass = (WidgetClass) &xmFormClassRec;
Packit b099d7
Packit b099d7
static void
Packit b099d7
FromTopOffset(
Packit b099d7
	Widget w,
Packit b099d7
	int offset,
Packit b099d7
	XtArgVal *value)
Packit b099d7
{
Packit b099d7
    XmFormWidget fw = (XmFormWidget) w->core.parent;
Packit b099d7
    XmFormConstraint fc = GetFormConstraint(w);
Packit b099d7
Packit b099d7
    *value = (XtArgVal) GetFormOffset(fw, TOP, fc->att);
Packit b099d7
    XmeFromVerticalPixels(w, offset, value);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
FromBottomOffset(
Packit b099d7
	Widget w,
Packit b099d7
	int offset,
Packit b099d7
	XtArgVal *value)
Packit b099d7
{
Packit b099d7
    XmFormWidget fw = (XmFormWidget) w->core.parent;
Packit b099d7
    XmFormConstraint fc = GetFormConstraint(w);
Packit b099d7
Packit b099d7
    *value = (XtArgVal) GetFormOffset(fw, BOTTOM, fc->att);
Packit b099d7
    XmeFromVerticalPixels(w, offset, value);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
FromLeftOffset(
Packit b099d7
	Widget w,
Packit b099d7
	int offset,
Packit b099d7
	XtArgVal *value)
Packit b099d7
{
Packit b099d7
    XmFormWidget fw = (XmFormWidget) w->core.parent;
Packit b099d7
    XmFormConstraint fc = GetFormConstraint(w);
Packit b099d7
Packit b099d7
    *value = (XtArgVal) GetFormOffset(fw, LEFT, fc->att);
Packit b099d7
    XmeFromHorizontalPixels(w, offset, value);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
FromRightOffset(
Packit b099d7
	Widget w,
Packit b099d7
	int offset,
Packit b099d7
	XtArgVal *value)
Packit b099d7
{
Packit b099d7
    XmFormWidget fw = (XmFormWidget) w->core.parent;
Packit b099d7
    XmFormConstraint fc = GetFormConstraint(w);
Packit b099d7
Packit b099d7
    *value = (XtArgVal) GetFormOffset(fw, RIGHT, fc->att);
Packit b099d7
    XmeFromHorizontalPixels(w, offset, value);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
static void 
Packit b099d7
MarginWidthOut(
Packit b099d7
        Widget wid,
Packit b099d7
        int offset,
Packit b099d7
        XtArgVal *value )
Packit b099d7
{
Packit b099d7
        XmFormWidget fw = (XmFormWidget) wid ;
Packit b099d7
Packit b099d7
	if (fw->bulletin_board.margin_width == XmINVALID_DIMENSION)
Packit b099d7
		*value = 0;
Packit b099d7
	else
Packit b099d7
		XmeFromHorizontalPixels((Widget) fw, offset, value);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
MarginHeightOut(
Packit b099d7
        Widget wid,
Packit b099d7
        int offset,
Packit b099d7
        XtArgVal *value )
Packit b099d7
{
Packit b099d7
        XmFormWidget fw = (XmFormWidget) wid ;
Packit b099d7
Packit b099d7
	if (fw->bulletin_board.margin_height == XmINVALID_DIMENSION)
Packit b099d7
		*value = 0;
Packit b099d7
	else
Packit b099d7
		XmeFromVerticalPixels((Widget) fw, offset, value);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ClassPartInitialize
Packit b099d7
 *	Set up the fast subclassing.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
ClassPartInitialize(
Packit b099d7
        WidgetClass wc )
Packit b099d7
{
Packit b099d7
   _XmFastSubclassInit (wc, XmFORM_BIT);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  CalcFormSizeWithChange
Packit b099d7
 *	Find size of a bounding box which will include all of the 
Packit b099d7
 *	children, including the child which may change
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static Boolean 
Packit b099d7
SyncEdges(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
        Widget last_child,
Packit b099d7
        Dimension *form_width,
Packit b099d7
        Dimension *form_height,
Packit b099d7
        Widget instigator,
Packit b099d7
        XtWidgetGeometry *geometry )
Packit b099d7
{
Packit b099d7
	register Widget child;
Packit b099d7
	register XmFormConstraint c;
Packit b099d7
	long int loop_count;
Packit b099d7
	Dimension tmp_w = *form_width, tmp_h = *form_height;
Packit b099d7
	Dimension sav_w, sav_h;
Packit b099d7
	Boolean settled = FALSE;
Packit b099d7
	Boolean finished = TRUE;
Packit b099d7
Packit b099d7
	sav_w = tmp_w;
Packit b099d7
	sav_h = tmp_h;
Packit b099d7
Packit b099d7
	loop_count = 0;
Packit b099d7
	while (!settled)
Packit b099d7
	{
Packit b099d7
		/*
Packit b099d7
		 * Contradictory constraints can cause the constraint
Packit b099d7
		 * processing to go into endless oscillation.  This means that
Packit b099d7
		 * proper exit condition for this loop is never satisfied.
Packit b099d7
		 * But, infinite loops are a bad thing, even if is the result
Packit b099d7
		 * of a careless user.  We therefore have added a loop counter
Packit b099d7
		 * to ensure that this loop will terminate.
Packit b099d7
		 *
Packit b099d7
		 * There are problems with this however.  In the worst case
Packit b099d7
		 * this procedure could need to loop fw->composite.num_children!
Packit b099d7
		 * times.  Unfortunately, numbers like 100! don't fit integer
Packit b099d7
		 * space well; neither will current architectures complete that
Packit b099d7
		 * many loops before the sun burns out.
Packit b099d7
		 *
Packit b099d7
		 * Soooo, we will wait for an arbitrarily large number of
Packit b099d7
		 * iterations to go by before we give up.  This allows us to
Packit b099d7
		 * claim that the procedure will always complete, and the number
Packit b099d7
		 * is large enough to accomodate all but the very large and
Packit b099d7
		 * very pathological Form widget configurations.
Packit b099d7
		 *
Packit b099d7
		 * This is gross, but it's either do this or risk truly
Packit b099d7
		 * infinite loops.
Packit b099d7
		 */
Packit b099d7
Packit b099d7
		if (loop_count++ > MAX_LOOP)
Packit b099d7
			break;
Packit b099d7
Packit b099d7
		for (child = fw->form.first_child;
Packit b099d7
			child != NULL;
Packit b099d7
			child = c->next_sibling) 
Packit b099d7
		{
Packit b099d7
			if (!XtIsManaged (child))
Packit b099d7
				break;
Packit b099d7
Packit b099d7
			c = GetFormConstraint(child);
Packit b099d7
Packit b099d7
			CalcEdgeValues(child, FALSE, instigator, geometry, 
Packit b099d7
				&tmp_w, &tmp_h);
Packit b099d7
Packit b099d7
			if (child == last_child)
Packit b099d7
				break;
Packit b099d7
		}
Packit b099d7
Packit b099d7
		if ((sav_w == tmp_w) && (sav_h == tmp_h))
Packit b099d7
			settled = TRUE;
Packit b099d7
		else
Packit b099d7
		{
Packit b099d7
			sav_w = tmp_w;
Packit b099d7
			sav_h = tmp_h;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
Packit b099d7
Packit b099d7
	if (loop_count > MAX_LOOP)
Packit b099d7
	{
Packit b099d7
		XmeWarning( (Widget) fw, MESSAGE7);
Packit b099d7
		finished = FALSE;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	*form_width = sav_w;
Packit b099d7
	*form_height = sav_h;
Packit b099d7
Packit b099d7
	return(finished);
Packit b099d7
}
Packit b099d7
Packit b099d7
static Boolean 
Packit b099d7
CalcFormSizeWithChange(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
        Dimension *w,
Packit b099d7
        Dimension *h,
Packit b099d7
        Widget c,
Packit b099d7
        XtWidgetGeometry *g )
Packit b099d7
{
Packit b099d7
	Dimension junkh = fw->core.height;
Packit b099d7
	Dimension junkw = fw->core.width;
Packit b099d7
	Widget child;
Packit b099d7
	XmFormConstraint fc;
Packit b099d7
	int tmp;
Packit b099d7
Packit b099d7
	if (h == NULL) h = &junkh;
Packit b099d7
	if (w == NULL) w = &junkw;
Packit b099d7
Packit b099d7
	/* Place children, but don't do it for real--just get new size */
Packit b099d7
Packit b099d7
	for(child = fw->form.first_child; 
Packit b099d7
		child != NULL;
Packit b099d7
		child = fc->next_sibling)
Packit b099d7
	{
Packit b099d7
		if (!XtIsManaged (child))
Packit b099d7
			break;
Packit b099d7
Packit b099d7
		fc = GetFormConstraint(child);
Packit b099d7
Packit b099d7
		CalcEdgeValues(child, False, c, g, w, h);
Packit b099d7
		if (!SyncEdges(fw, child, w, h, c, g))
Packit b099d7
			return(False);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	for(child = fw->form.first_child; 
Packit b099d7
		child != NULL;
Packit b099d7
		child = fc->next_sibling)
Packit b099d7
	{
Packit b099d7
		if (!XtIsManaged (child)) 
Packit b099d7
			break;
Packit b099d7
Packit b099d7
		fc = GetFormConstraint(child);
Packit b099d7
Packit b099d7
		tmp = fc->att[RIGHT].tempValue;
Packit b099d7
		if (fc->att[RIGHT].type == XmATTACH_FORM)
Packit b099d7
			tmp += GetFormOffset(fw, RIGHT, fc->att);
Packit b099d7
		if (tmp > 0) 
Packit b099d7
			ASSIGN_MAX(*w, tmp);
Packit b099d7
		
Packit b099d7
		tmp = fc->att[BOTTOM].tempValue ;
Packit b099d7
		if (fc->att[BOTTOM].type == XmATTACH_FORM)
Packit b099d7
			tmp += GetFormOffset(fw, BOTTOM, fc->att);
Packit b099d7
		if (tmp > 0) 
Packit b099d7
			ASSIGN_MAX (*h, tmp);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (!(*w))
Packit b099d7
		*w = 1;
Packit b099d7
	if (!(*h))
Packit b099d7
		*h = 1;
Packit b099d7
Packit b099d7
	if (*w != XtWidth(fw) || *h != XtHeight(fw)) 
Packit b099d7
		return True;
Packit b099d7
	else
Packit b099d7
		return False;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  CalcFormSize
Packit b099d7
 *	Find size of a bounding box which will include all of the children.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
CalcFormSize(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
        Dimension *w,
Packit b099d7
        Dimension *h )
Packit b099d7
{
Packit b099d7
	Widget child;
Packit b099d7
	Dimension junkh = fw->core.height;
Packit b099d7
	Dimension junkw = fw->core.width;
Packit b099d7
	XmFormConstraint fc;
Packit b099d7
	int tmp;
Packit b099d7
Packit b099d7
	if (h == NULL) h = &junkh;
Packit b099d7
	if (w == NULL) w = &junkw;
Packit b099d7
Packit b099d7
	for (child = fw->form.first_child;
Packit b099d7
		child != NULL;
Packit b099d7
		child = fc->next_sibling)
Packit b099d7
	{
Packit b099d7
		if (!XtIsManaged (child))
Packit b099d7
			break;
Packit b099d7
Packit b099d7
		fc = GetFormConstraint(child);
Packit b099d7
Packit b099d7
		CalcEdgeValues(child, False, NULL, NULL, w, h);
Packit b099d7
		if (!SyncEdges(fw, child, w, h, NULL, NULL))
Packit b099d7
			break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	for(child = fw->form.first_child; 
Packit b099d7
		child != NULL;
Packit b099d7
		child = fc->next_sibling)
Packit b099d7
	{
Packit b099d7
		if (!XtIsManaged (child)) 
Packit b099d7
			break;
Packit b099d7
Packit b099d7
		fc = GetFormConstraint(child);
Packit b099d7
Packit b099d7
		tmp = fc->att[RIGHT].tempValue;
Packit b099d7
		if (fc->att[RIGHT].type == XmATTACH_FORM)
Packit b099d7
			tmp += GetFormOffset(fw, RIGHT, fc->att);
Packit b099d7
		if (tmp > 0) 
Packit b099d7
			ASSIGN_MAX(*w, tmp);
Packit b099d7
		
Packit b099d7
		tmp = fc->att[BOTTOM].tempValue ;
Packit b099d7
		if (fc->att[BOTTOM].type == XmATTACH_FORM)
Packit b099d7
			tmp += GetFormOffset(fw, BOTTOM, fc->att);
Packit b099d7
		if (tmp > 0) 
Packit b099d7
			ASSIGN_MAX(*h, tmp);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (!(*w))
Packit b099d7
		*w = 1;
Packit b099d7
	if (!(*h))
Packit b099d7
		*h = 1;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GeometryManager
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static XtGeometryResult 
Packit b099d7
GeometryManager(
Packit b099d7
        Widget w,
Packit b099d7
        XtWidgetGeometry *desired,
Packit b099d7
        XtWidgetGeometry *allowed )
Packit b099d7
{
Packit b099d7
    int size_req ;
Packit b099d7
    XtWidgetGeometry original;
Packit b099d7
    XtGeometryResult reply = XtGeometryNo;
Packit b099d7
    XmFormWidget fw = (XmFormWidget) XtParent(w);
Packit b099d7
    XmFormConstraint c = GetFormConstraint(w);
Packit b099d7
    
Packit b099d7
    /* sooo confusing... */
Packit b099d7
    if (fw->form.processing_constraints) {
Packit b099d7
	fw->form.processing_constraints = FALSE;
Packit b099d7
	PlaceChildren (fw, NULL, NULL);
Packit b099d7
	return(XtGeometryNo);
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    /*
Packit b099d7
     * Fix for 4854 - If the widget is not resizable, do not set the
Packit b099d7
     *                preferred_width or the preferred_height.
Packit b099d7
     */
Packit b099d7
    if ((desired->request_mode & CWWidth) &&
Packit b099d7
 	!(desired->request_mode & XtCWQueryOnly) && c->resizable)
Packit b099d7
  	c->preferred_width = desired->width;
Packit b099d7
    if ((desired->request_mode & CWHeight) &&
Packit b099d7
 	!(desired->request_mode & XtCWQueryOnly) && c->resizable)
Packit b099d7
  	c->preferred_height = desired->height;
Packit b099d7
Packit b099d7
    if (desired->request_mode == (CWX | CWY)) return(XtGeometryNo);
Packit b099d7
Packit b099d7
    original.x = w->core.x;
Packit b099d7
    original.y = w->core.y;
Packit b099d7
    original.width = w->core.width;
Packit b099d7
    original.height = w->core.height;
Packit b099d7
    original.border_width = w->core.border_width;
Packit b099d7
    original.request_mode = (CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
Packit b099d7
Packit b099d7
    size_req = desired->request_mode & 
Packit b099d7
	              (CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
Packit b099d7
    if (size_req && c->resizable) {
Packit b099d7
	XtWidgetGeometry g, r;
Packit b099d7
	XtGeometryResult res ;
Packit b099d7
	
Packit b099d7
	/* get the size the Form wants to be */
Packit b099d7
	GetSize(fw, &g, w, desired);
Packit b099d7
	
Packit b099d7
	/* GetSize takes care of the resizePolicy resource as well
Packit b099d7
	   and returns the desired change in g if any.
Packit b099d7
	   g.request_mode might be 0 at this point, which means the 
Packit b099d7
	   Form doesn't want to change, but we still want to
Packit b099d7
	   see if the child request can be accomodated into
Packit b099d7
	   the current Form size, so we move forward with the
Packit b099d7
	   0 in request mode.  */
Packit b099d7
	
Packit b099d7
	/* if the child requesed query only, propagate */
Packit b099d7
	if (desired->request_mode & XtCWQueryOnly) 
Packit b099d7
	    g.request_mode |= XtCWQueryOnly;
Packit b099d7
	
Packit b099d7
	/* Let's make a request to the parent.
Packit b099d7
	   At this point, we do not want to accept any compromise
Packit b099d7
	   because we're not sure our kid will accept it in turn. 
Packit b099d7
	   So use the Xt API, no _XmMakeGeometryRequest.
Packit b099d7
	   If g.request_mode is 0, nothing will happen, yes
Packit b099d7
	   will be returned */
Packit b099d7
	res = XtMakeGeometryRequest((Widget)fw, &g, &r);
Packit b099d7
	
Packit b099d7
	/* check that a real request has failed or that if request_mode was 0,
Packit b099d7
	   consider that a No */
Packit b099d7
	if (!g.request_mode || (res != XtGeometryYes)) {
Packit b099d7
	    Dimension orig_form_width, orig_form_height  ;
Packit b099d7
	    
Packit b099d7
	    /* let's save the original form size first */
Packit b099d7
	    orig_form_width = fw->core.width ;
Packit b099d7
	    orig_form_height = fw->core.height ;
Packit b099d7
	    
Packit b099d7
	    if (res == XtGeometryAlmost) {
Packit b099d7
		/* let's try the proposal. Stuff the Form with it so that 
Packit b099d7
		   PlaceChildren does the layout base on it */
Packit b099d7
		if (r.request_mode | CWWidth) fw->core.width = r.width ;
Packit b099d7
		if (r.request_mode | CWHeight) fw->core.height = r.height ;
Packit b099d7
	    }
Packit b099d7
	    /* else it's No and we keep the same size */
Packit b099d7
	    
Packit b099d7
	    /* let's see if there is a chance that the child request 
Packit b099d7
	       be honored: the needed form overall size is smaller than
Packit b099d7
	       the current or proposed size (now in the core field) */
Packit b099d7
	    
Packit b099d7
	    if ((g.width <= fw->core.width) &&
Packit b099d7
		(g.height <= fw->core.height)) {
Packit b099d7
		/* ok, now we'are going to try to place the kid 
Packit b099d7
		   using the new Form size for the layout */
Packit b099d7
		PlaceChildren (fw, w, desired);
Packit b099d7
		
Packit b099d7
		/* now, we check if the requestor has gotten
Packit b099d7
		   what it asked for.  The logic is that:
Packit b099d7
		   width = req_width iff req_width 
Packit b099d7
		   height = req_height iff req_height */
Packit b099d7
		if (((desired->request_mode & CWWidth && 
Packit b099d7
		      desired->width == w->core.width) ||
Packit b099d7
		     ! (desired->request_mode & CWWidth)) &&
Packit b099d7
		    ((desired->request_mode & CWHeight && 
Packit b099d7
		      desired->height == w->core.height) ||
Packit b099d7
		     ! (desired->request_mode & CWHeight))) {
Packit b099d7
		    /* ok, the kid request has been honored, although the
Packit b099d7
		       Form couldn't change its own size, let's
Packit b099d7
		       return Yes to the kid and ask the Form's parent
Packit b099d7
		       the needed size if Almost was returned */
Packit b099d7
		    if (res == XtGeometryAlmost) {
Packit b099d7
			/* let's backup the original Form size first */
Packit b099d7
			fw->core.width = orig_form_width  ;
Packit b099d7
			fw->core.height = orig_form_height;
Packit b099d7
			
Packit b099d7
			/* success guaranteed */
Packit b099d7
			XtMakeGeometryRequest((Widget)fw, &r, NULL);
Packit b099d7
			
Packit b099d7
			/* no need to do the layout PlaceCHildren, it 
Packit b099d7
			   has already been done using the correct size */
Packit b099d7
		    }
Packit b099d7
		    
Packit b099d7
		    /* simply return Yes, since PlaceChildren already
Packit b099d7
		       change the kid core fields */
Packit b099d7
		    reply = XtGeometryYes ;
Packit b099d7
Packit b099d7
		} else {
Packit b099d7
		    /* the kid hasn't gotten what it asked for in the
Packit b099d7
		       current Form geometry, we have to backup
Packit b099d7
		       everything and return either No or Almost
Packit b099d7
		       to the kid */
Packit b099d7
		    
Packit b099d7
		    if ((w->core.width != original.width) ||
Packit b099d7
			(w->core.height != original.height)) {
Packit b099d7
			
Packit b099d7
			allowed->request_mode = desired->request_mode;
Packit b099d7
			allowed->sibling = desired->sibling;
Packit b099d7
			allowed->stack_mode = desired->stack_mode;
Packit b099d7
			allowed->x = w->core.x;
Packit b099d7
			allowed->y = w->core.y;
Packit b099d7
			allowed->width = w->core.width;
Packit b099d7
			allowed->height = w->core.height;
Packit b099d7
			allowed->border_width = w->core.border_width;
Packit b099d7
			reply = XtGeometryAlmost;
Packit b099d7
			
Packit b099d7
		    } else reply = XtGeometryNo;
Packit b099d7
		    
Packit b099d7
		    /* backup the kid geometry */
Packit b099d7
		    w->core.x = original.x;
Packit b099d7
		    w->core.y = original.y;
Packit b099d7
		    w->core.width = original.width;
Packit b099d7
		    w->core.height = original.height;
Packit b099d7
		    w->core.border_width = original.border_width;
Packit b099d7
		    
Packit b099d7
		    /* backup the Form and the layout too */
Packit b099d7
		    fw->core.width = orig_form_width  ;
Packit b099d7
		    fw->core.height = orig_form_height;
Packit b099d7
		    
Packit b099d7
		    PlaceChildren (fw, w, &original); 
Packit b099d7
		}
Packit b099d7
	    } else {
Packit b099d7
		/* the size the Form wants for the kid request is bigger than 
Packit b099d7
		   its current or proposed size, return No to the kid */
Packit b099d7
		
Packit b099d7
		/* backup the original Form size first */
Packit b099d7
		fw->core.width = orig_form_width  ;
Packit b099d7
		fw->core.height = orig_form_height;
Packit b099d7
		
Packit b099d7
		/* we haden't changed anything else, just return No */
Packit b099d7
		reply = XtGeometryNo;
Packit b099d7
	    }
Packit b099d7
	} else {
Packit b099d7
	    /* ok, we got a Yes form the Form's parent, let's relayout
Packit b099d7
	       using the new size, except if query only was specified */
Packit b099d7
	    
Packit b099d7
	    if (!(desired->request_mode & XtCWQueryOnly)) {
Packit b099d7
		/* Reposition the widget only if not QueryOnly */
Packit b099d7
		PlaceChildren (fw, w, desired);
Packit b099d7
	    }
Packit b099d7
	    reply = XtGeometryYes;
Packit b099d7
	}
Packit b099d7
    } 
Packit b099d7
Packit b099d7
    /* let's deal with stacking order */
Packit b099d7
Packit b099d7
    if (desired->request_mode & (CWSibling | CWStackMode)) {
Packit b099d7
	/* always honor stand alone stack requests */
Packit b099d7
	if (!size_req) reply = XtGeometryYes;
Packit b099d7
	else 
Packit b099d7
	    /* the request concerned size as well, see if it was denied.
Packit b099d7
	       if so, propose the stack request alone */
Packit b099d7
	    if (reply != XtGeometryYes) {
Packit b099d7
		allowed->request_mode = desired->request_mode;
Packit b099d7
		allowed->sibling = desired->sibling;
Packit b099d7
		allowed->stack_mode = desired->stack_mode;
Packit b099d7
		allowed->x = w->core.x;
Packit b099d7
		allowed->y = w->core.y;
Packit b099d7
		allowed->width = w->core.width;
Packit b099d7
		allowed->height = w->core.height;
Packit b099d7
		allowed->border_width = w->core.border_width;
Packit b099d7
		reply = XtGeometryAlmost;
Packit b099d7
	    }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* deal with the shadow resize without Expose */
Packit b099d7
    if ( fw->bulletin_board.old_shadow_thickness &&
Packit b099d7
	(fw->bulletin_board.old_width != fw->core.width ||
Packit b099d7
	 fw->bulletin_board.old_height != fw->core.height) )
Packit b099d7
	{
Packit b099d7
	    _XmClearShadowType ((Widget) fw, fw->bulletin_board.old_width,
Packit b099d7
				fw->bulletin_board.old_height,
Packit b099d7
				fw->bulletin_board.old_shadow_thickness, 0);
Packit b099d7
	}
Packit b099d7
    
Packit b099d7
    fw->bulletin_board.old_width = fw->core.width;
Packit b099d7
    fw->bulletin_board.old_height = fw->core.height;
Packit b099d7
    fw->bulletin_board.old_shadow_thickness = fw->manager.shadow_thickness;
Packit b099d7
Packit b099d7
Packit b099d7
    return (reply);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  QueryGeometry
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static XtGeometryResult 
Packit b099d7
QueryGeometry(
Packit b099d7
        Widget widget,
Packit b099d7
        XtWidgetGeometry *intended,
Packit b099d7
        XtWidgetGeometry *desired )
Packit b099d7
{
Packit b099d7
    Dimension width = 0, height = 0 ;
Packit b099d7
    XmFormWidget fw = (XmFormWidget) widget ;
Packit b099d7
    
Packit b099d7
    /* first determine what is the desired size, using the resize_policy. */
Packit b099d7
    if (fw->bulletin_board.resize_policy == XmRESIZE_NONE) {
Packit b099d7
	desired->width = XtWidth(widget) ;
Packit b099d7
	desired->height = XtHeight(widget) ;
Packit b099d7
    } else {
Packit b099d7
	SortChildren(fw);
Packit b099d7
	if (GMode( intended) & CWWidth) width = intended->width;
Packit b099d7
	if (GMode( intended) & CWHeight) height = intended->height;
Packit b099d7
Packit b099d7
	if (!XtIsRealized((Widget)fw))
Packit b099d7
	{
Packit b099d7
		int i;
Packit b099d7
		Widget child;
Packit b099d7
		XmFormConstraint c;
Packit b099d7
Packit b099d7
		for (i = 0; i < fw->composite.num_children; i++)
Packit b099d7
		{
Packit b099d7
			child = fw->composite.children[i];
Packit b099d7
			c = GetFormConstraint(child);
Packit b099d7
			c->preferred_width = XtWidth(child);
Packit b099d7
			c->preferred_height = XtHeight(child);
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
Packit b099d7
	CalcFormSize(fw, &width, &height);
Packit b099d7
	if ((fw->bulletin_board.resize_policy == XmRESIZE_GROW) &&
Packit b099d7
	    ((width < XtWidth(widget)) ||
Packit b099d7
	     (height < XtHeight(widget)))) {
Packit b099d7
	    desired->width = XtWidth(widget) ;
Packit b099d7
	    desired->height = XtHeight(widget) ;
Packit b099d7
	} else {
Packit b099d7
	    desired->width = width ;
Packit b099d7
	    desired->height = height ;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* deal with user initial size setting */
Packit b099d7
    if (!XtIsRealized(widget))  {
Packit b099d7
	if (XtWidth(widget) != 0) desired->width = XtWidth(widget) ;
Packit b099d7
	if (XtHeight(widget) != 0) desired->height = XtHeight(widget) ;
Packit b099d7
    }	    
Packit b099d7
Packit b099d7
    return XmeReplyToQueryGeometry(widget, intended, desired) ;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  Resize
Packit b099d7
 *	This routine is called by the parent's geometry manager after it
Packit b099d7
 *	has ok'd the resize request AND resized the form window.  This 
Packit b099d7
 *	routine is responsible for implementing the size given.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
Resize(
Packit b099d7
        Widget wid )
Packit b099d7
{
Packit b099d7
    XmFormWidget fw = (XmFormWidget) wid ;
Packit b099d7
    Boolean      draw_shadow = False;
Packit b099d7
Packit b099d7
    /* clear the shadow if its needed (will check if its now larger) */
Packit b099d7
    _XmClearShadowType ((Widget )fw, fw->bulletin_board.old_width,
Packit b099d7
			fw->bulletin_board.old_height,
Packit b099d7
			fw->bulletin_board.old_shadow_thickness, 0);
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * if it is now smaller, redraw the shadow since there may not be a
Packit b099d7
	 * redisplay
Packit b099d7
	 */
Packit b099d7
    if ((fw->bulletin_board.old_height > fw->core.height) ||
Packit b099d7
	(fw->bulletin_board.old_width > fw->core.width))
Packit b099d7
	draw_shadow = True;
Packit b099d7
Packit b099d7
    
Packit b099d7
    fw->bulletin_board.old_width = fw->core.width;
Packit b099d7
    fw->bulletin_board.old_height = fw->core.height;
Packit b099d7
    fw->bulletin_board.old_shadow_thickness = 
Packit b099d7
	fw->manager.shadow_thickness;
Packit b099d7
Packit b099d7
Packit b099d7
    PlaceChildren (fw, NULL, NULL) ;
Packit b099d7
Packit b099d7
    if ((draw_shadow) && (XtIsRealized((Widget)fw)))
Packit b099d7
	XmeDrawShadows  (XtDisplay (fw), XtWindow (fw),
Packit b099d7
			 fw->manager.top_shadow_GC,
Packit b099d7
			 fw->manager.bottom_shadow_GC,
Packit b099d7
			 0, 0, fw->core.width, fw->core.height,
Packit b099d7
			 fw->manager.shadow_thickness,
Packit b099d7
			 fw->bulletin_board.shadow_type);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static void 
Packit b099d7
Redisplay(
Packit b099d7
        Widget fw,
Packit b099d7
        XEvent *event,
Packit b099d7
        Region region )
Packit b099d7
{
Packit b099d7
    XmeRedisplayGadgets( fw, event, region);
Packit b099d7
Packit b099d7
    XmeDrawShadows (XtDisplay((Widget)fw), 
Packit b099d7
		    XtWindow((Widget)fw), 
Packit b099d7
		    ((XmFormWidget) fw)->manager.top_shadow_GC,
Packit b099d7
		    ((XmFormWidget) fw)->manager.bottom_shadow_GC,
Packit b099d7
		    0, 0,
Packit b099d7
		    XtWidth(fw), XtHeight(fw),
Packit b099d7
		    ((XmFormWidget) fw)->manager.shadow_thickness, 
Packit b099d7
		    ((XmFormWidget) fw)->bulletin_board.shadow_type);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  PlaceChildren
Packit b099d7
 *	Position all children according to their constraints.  
Packit b099d7
 *      Return desired width and height.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
PlaceChildren(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
        Widget instigator,
Packit b099d7
        XtWidgetGeometry *inst_geometry )
Packit b099d7
{
Packit b099d7
    Widget child;
Packit b099d7
    
Packit b099d7
#ifdef FIX_1299
Packit b099d7
    for (child = fw->form.first_child;
Packit b099d7
        child != NULL;
Packit b099d7
        child = (GetFormConstraint(child))->next_sibling) {
Packit b099d7
      /* Place child itself */
Packit b099d7
      PlaceChild(fw, child, instigator, inst_geometry);
Packit b099d7
Packit b099d7
      /* Update all attached widgets 
Packit b099d7
       * according to the placement of a child */
Packit b099d7
      UpdateAttachments(fw, child, instigator, inst_geometry);
Packit b099d7
    }
Packit b099d7
#else
Packit b099d7
    register XmFormConstraint c;
Packit b099d7
    int height, width;
Packit b099d7
    Dimension border_width;
Packit b099d7
    int near_edge;
Packit b099d7
Packit b099d7
    for (child = fw->form.first_child;
Packit b099d7
	 child != NULL;
Packit b099d7
	 child = c->next_sibling) {
Packit b099d7
	if (!XtIsManaged(child))
Packit b099d7
	    break;
Packit b099d7
Packit b099d7
	c = GetFormConstraint(child);
Packit b099d7
	
Packit b099d7
	CalcEdgeValues(child, TRUE, instigator, inst_geometry, 
Packit b099d7
		       NULL, NULL);
Packit b099d7
Packit b099d7
	if ((child == instigator) &&
Packit b099d7
	    (inst_geometry->request_mode & CWBorderWidth))
Packit b099d7
	    border_width = inst_geometry->border_width;
Packit b099d7
	else
Packit b099d7
	    border_width = ((RectObj) child)->rectangle.border_width;
Packit b099d7
Packit b099d7
        if (LayoutIsRtoLM(fw)) {
Packit b099d7
	  /* switch the meanings of left and right attachements */
Packit b099d7
	  width = c->att[LEFT].value - c->att[RIGHT].value - (2 * border_width);
Packit b099d7
	  near_edge = RIGHT;
Packit b099d7
	} else {
Packit b099d7
	  width = c->att[RIGHT].value - c->att[LEFT].value - (2 * border_width);
Packit b099d7
	  near_edge = LEFT;
Packit b099d7
	}
Packit b099d7
	height = c->att[BOTTOM].value - c->att[TOP].value
Packit b099d7
	    - (2 * border_width);
Packit b099d7
Packit b099d7
	if (width <= 0) width = 1;
Packit b099d7
	if (height <= 0) height = 1;
Packit b099d7
Packit b099d7
	if ((c->att[near_edge].value != ((RectObj) child)->rectangle.x) ||
Packit b099d7
	    (c->att[TOP].value != ((RectObj) child)->rectangle.y)  ||
Packit b099d7
	    (width != ((RectObj) child)->rectangle.width)          || 
Packit b099d7
	    (height != ((RectObj) child)->rectangle.height)        ||
Packit b099d7
	    (border_width != ((RectObj) child)->rectangle.border_width)) {
Packit b099d7
	  
Packit b099d7
	  /* Yes policy everywhere, so don't resize the instigator */
Packit b099d7
	  if (child != instigator) {
Packit b099d7
	    XmeConfigureObject(child,
Packit b099d7
			       c->att[near_edge].value, 
Packit b099d7
			       c->att[TOP].value,
Packit b099d7
			       width, height, border_width);
Packit b099d7
	  } else {
Packit b099d7
	    XmeConfigureObject(child,
Packit b099d7
			       c->att[near_edge].value, 
Packit b099d7
			       c->att[TOP].value,
Packit b099d7
			       child->core.width, child->core.height, 
Packit b099d7
			       child->core.border_width);
Packit b099d7
	    child->core.width = width ;
Packit b099d7
	    child->core.height = height ;
Packit b099d7
	    child->core.border_width = border_width ;
Packit b099d7
	  }
Packit b099d7
	}
Packit b099d7
      }
Packit b099d7
#endif /* FIX_1299 */
Packit b099d7
}
Packit b099d7
Packit b099d7
#ifdef FIX_1299
Packit b099d7
static void
Packit b099d7
UpdateAttachments(
Packit b099d7
    XmFormWidget fw,
Packit b099d7
    Widget wid,
Packit b099d7
    Widget instigator,
Packit b099d7
    XtWidgetGeometry* inst_geometry)
Packit b099d7
{
Packit b099d7
  register XmFormConstraint c;
Packit b099d7
  c = GetFormConstraint(wid);
Packit b099d7
  
Packit b099d7
  if (IS_ATTACHED_WIDGET(c, LEFT))
Packit b099d7
      PlaceChild(fw, ATTACHED_WIDGET(c, LEFT), instigator, inst_geometry);
Packit b099d7
  if (IS_ATTACHED_WIDGET(c, RIGHT))
Packit b099d7
      PlaceChild(fw, ATTACHED_WIDGET(c, RIGHT), instigator, inst_geometry);
Packit b099d7
  if (IS_ATTACHED_WIDGET(c, TOP))
Packit b099d7
      PlaceChild(fw, ATTACHED_WIDGET(c, TOP), instigator, inst_geometry);
Packit b099d7
  if (IS_ATTACHED_WIDGET(c, BOTTOM))
Packit b099d7
      PlaceChild(fw, ATTACHED_WIDGET(c, BOTTOM), instigator, inst_geometry);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
PlaceChild(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
        Widget child,
Packit b099d7
        Widget instigator,
Packit b099d7
        XtWidgetGeometry* inst_geometry)
Packit b099d7
{
Packit b099d7
  register XmFormConstraint c;
Packit b099d7
  int height, width;
Packit b099d7
  Dimension border_width;
Packit b099d7
  int near_edge;
Packit b099d7
Packit b099d7
  if (!XtIsManaged(child))
Packit b099d7
	    return;
Packit b099d7
Packit b099d7
	c = GetFormConstraint(child);
Packit b099d7
	
Packit b099d7
	CalcEdgeValues(child, TRUE, instigator, inst_geometry, 
Packit b099d7
		       NULL, NULL);
Packit b099d7
Packit b099d7
	if ((child == instigator) &&
Packit b099d7
	    (inst_geometry->request_mode & CWBorderWidth))
Packit b099d7
	    border_width = inst_geometry->border_width;
Packit b099d7
	else
Packit b099d7
	    border_width = ((RectObj) child)->rectangle.border_width;
Packit b099d7
Packit b099d7
        if (LayoutIsRtoLM(fw)) {
Packit b099d7
	  /* switch the meanings of left and right attachements */
Packit b099d7
	  width = c->att[LEFT].value - c->att[RIGHT].value - (2 * border_width);
Packit b099d7
	  near_edge = RIGHT;
Packit b099d7
	} else {
Packit b099d7
	  width = c->att[RIGHT].value - c->att[LEFT].value - (2 * border_width);
Packit b099d7
	  near_edge = LEFT;
Packit b099d7
	}
Packit b099d7
	height = c->att[BOTTOM].value - c->att[TOP].value
Packit b099d7
	    - (2 * border_width);
Packit b099d7
Packit b099d7
	if (width <= 0) width = 1;
Packit b099d7
	if (height <= 0) height = 1;
Packit b099d7
Packit b099d7
	if ((c->att[near_edge].value != ((RectObj) child)->rectangle.x) ||
Packit b099d7
	    (c->att[TOP].value != ((RectObj) child)->rectangle.y)  ||
Packit b099d7
	    (width != ((RectObj) child)->rectangle.width)          || 
Packit b099d7
	    (height != ((RectObj) child)->rectangle.height)        ||
Packit b099d7
	    (border_width != ((RectObj) child)->rectangle.border_width)) {
Packit b099d7
	  
Packit b099d7
	  /* Yes policy everywhere, so don't resize the instigator */
Packit b099d7
	  if (child != instigator) {
Packit b099d7
	    XmeConfigureObject(child,
Packit b099d7
			       c->att[near_edge].value, 
Packit b099d7
			       c->att[TOP].value,
Packit b099d7
			       width, height, border_width);
Packit b099d7
	  } else {
Packit b099d7
	    XmeConfigureObject(child,
Packit b099d7
			       c->att[near_edge].value, 
Packit b099d7
			       c->att[TOP].value,
Packit b099d7
			       child->core.width, child->core.height, 
Packit b099d7
			       child->core.border_width);
Packit b099d7
	    child->core.width = width ;
Packit b099d7
	    child->core.height = height ;
Packit b099d7
	    child->core.border_width = border_width ;
Packit b099d7
	  }
Packit b099d7
	}
Packit b099d7
}
Packit b099d7
#endif /* FIX_1299 */
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ChangeManaged
Packit b099d7
 *	Something changed in the set of managed children, so place 
Packit b099d7
 *	the children and change the form widget size to reflect new size, 
Packit b099d7
 *	if possible.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
ChangeManaged(
Packit b099d7
        Widget wid )
Packit b099d7
{
Packit b099d7
    XmFormWidget fw = (XmFormWidget) wid ;
Packit b099d7
    XtWidgetGeometry g;
Packit b099d7
    int i, j, k;
Packit b099d7
    register XmFormConstraint c;
Packit b099d7
    register Widget w, child;
Packit b099d7
    
Packit b099d7
    /*
Packit b099d7
     * The following code works around a bug in the intrinsics
Packit b099d7
     * destroy processing.  The child is unmanaged before anything
Packit b099d7
     * else (destroy callbacks) so we have to handle the destroy
Packit b099d7
     * inside of changemanaged instead of in a destroy callback
Packit b099d7
     */
Packit b099d7
    for (k = 0; k < fw->composite.num_children; k++) {
Packit b099d7
	child = fw->composite.children[k];
Packit b099d7
	
Packit b099d7
	if (child->core.being_destroyed) {
Packit b099d7
	    /*  If anyone depends on this child,
Packit b099d7
		make into a dependency on form  */
Packit b099d7
	    
Packit b099d7
	    
Packit b099d7
	    for (i = 0; i < fw->composite.num_children; i++) {
Packit b099d7
		w = fw->composite.children[i];
Packit b099d7
		c = GetFormConstraint(w);
Packit b099d7
		
Packit b099d7
		for (j = FIRST_ATTACHMENT; j < (LAST_ATTACHMENT + 1); j++)  {
Packit b099d7
		    if (((c->att[j].type == XmATTACH_WIDGET) &&
Packit b099d7
			 (c->att[j].w == child))
Packit b099d7
			||
Packit b099d7
			((c->att[j].type == XmATTACH_OPPOSITE_WIDGET) &&
Packit b099d7
			 (c->att[j].w == child))) {
Packit b099d7
			switch (j)
Packit b099d7
			    {
Packit b099d7
			    case LEFT:
Packit b099d7
				c->att[j].type = XmATTACH_FORM;
Packit b099d7
				c->att[j].offset = w->core.x;
Packit b099d7
				break;
Packit b099d7
			    case TOP:
Packit b099d7
				c->att[j].type = XmATTACH_FORM;
Packit b099d7
				c->att[j].offset = w->core.y;
Packit b099d7
				break;
Packit b099d7
			    default:
Packit b099d7
				c->att[j].type = XmATTACH_NONE;
Packit b099d7
				break;
Packit b099d7
			    }
Packit b099d7
			c->att[j].w = NULL;
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    SortChildren (fw);
Packit b099d7
    
Packit b099d7
    /* Don't use XtRealizedWidget(form) as a test to initialize the
Packit b099d7
       preferred geometry, since when you realize the form before its
Packit b099d7
       kid, everything goes to the ground.
Packit b099d7
       Here we initialize a field if it hasn't been done already,
Packit b099d7
       the XmINVALID_DIMENSION has been set in ConstraintInitialize */
Packit b099d7
    
Packit b099d7
    for (i = 0; i < fw->composite.num_children; i++) {
Packit b099d7
	child = fw->composite.children[i];
Packit b099d7
	c = GetFormConstraint(child);
Packit b099d7
	if (c->preferred_width == XmINVALID_DIMENSION)  
Packit b099d7
	    c->preferred_width = XtWidth(child);
Packit b099d7
	if (c->preferred_height == XmINVALID_DIMENSION) 
Packit b099d7
	    c->preferred_height = XtHeight(child);
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (!XtIsRealized((Widget)fw))
Packit b099d7
	{
Packit b099d7
	    /* First time through */
Packit b099d7
	    Dimension w = 0, h = 0;
Packit b099d7
	    
Packit b099d7
	    g.request_mode = 0;
Packit b099d7
	    g.width = (fw->core.width ? fw->core.width : 1);
Packit b099d7
	    g.height = (fw->core.height ? fw->core.height : 1);
Packit b099d7
	    
Packit b099d7
	    if (!XtWidth(fw) && XtHeight(fw))
Packit b099d7
		{
Packit b099d7
		    CalcFormSize(fw, &w, NULL);
Packit b099d7
		    g.width = w;
Packit b099d7
		    g.request_mode |= CWWidth;
Packit b099d7
		}
Packit b099d7
	    else if (XtWidth(fw) && !XtHeight(fw))
Packit b099d7
		{
Packit b099d7
		    CalcFormSize(fw, NULL, &h);
Packit b099d7
		    g.height = h;
Packit b099d7
		    g.request_mode |= CWHeight;
Packit b099d7
		}
Packit b099d7
	    else if (!XtWidth(fw) && !XtHeight(fw))
Packit b099d7
		{
Packit b099d7
		    CalcFormSize(fw, &w, &h);
Packit b099d7
		    g.width = w;
Packit b099d7
		    g.height = h;
Packit b099d7
		    g.request_mode |= (CWWidth | CWHeight);
Packit b099d7
		}
Packit b099d7
Packit b099d7
	    if (g.request_mode != 0) 
Packit b099d7
		_XmMakeGeometryRequest((Widget) fw, &g);
Packit b099d7
	    
Packit b099d7
	    PlaceChildren (fw, NULL, NULL);
Packit b099d7
	}
Packit b099d7
    else
Packit b099d7
	{
Packit b099d7
	    ChangeIfNeeded(fw, NULL, NULL);
Packit b099d7
	    PlaceChildren (fw, NULL, NULL);
Packit b099d7
	}
Packit b099d7
    
Packit b099d7
    fw->bulletin_board.old_width = fw->core.width;
Packit b099d7
    fw->bulletin_board.old_height = fw->core.height;
Packit b099d7
    fw->bulletin_board.old_shadow_thickness =
Packit b099d7
	fw->manager.shadow_thickness;
Packit b099d7
    
Packit b099d7
    XmeNavigChangeManaged((Widget) fw);
Packit b099d7
}                       
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GetSize
Packit b099d7
 *	
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
GetSize(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
	XtWidgetGeometry * g,
Packit b099d7
	Widget w,
Packit b099d7
        XtWidgetGeometry *desired )
Packit b099d7
{
Packit b099d7
    Boolean grow_ok = fw->bulletin_board.resize_policy != XmRESIZE_NONE,
Packit b099d7
            shrink_ok = fw->bulletin_board.resize_policy == XmRESIZE_ANY;
Packit b099d7
    
Packit b099d7
    g->request_mode = 0;
Packit b099d7
    g->width = 0;
Packit b099d7
    g->height = 0;
Packit b099d7
    
Packit b099d7
    /* Compute the desired size of the form */
Packit b099d7
    if (CalcFormSizeWithChange(fw, &g->width, &g->height, w, desired)) {
Packit b099d7
Packit b099d7
	/* there is a change - check resize policy first */
Packit b099d7
	if ((g->width > fw->core.width && !grow_ok) ||
Packit b099d7
	    (g->width < fw->core.width && !shrink_ok) ||
Packit b099d7
	    (g->height > fw->core.height && !grow_ok) ||
Packit b099d7
	    (g->height < fw->core.height && !shrink_ok))
Packit b099d7
	    return ; /* exit with request_mode = 0 */
Packit b099d7
	
Packit b099d7
	if (g->width != fw->core.width) g->request_mode |= CWWidth;
Packit b099d7
	if (g->height != fw->core.height) g->request_mode |= CWHeight; 
Packit b099d7
    }
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ChangeIfNeeded
Packit b099d7
 *	Returns whether to honor widget w's resize request; only returns 
Packit b099d7
 *      False if resize would require form to change size but it cannot.
Packit b099d7
 *	Form changes size as a side effect.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void
Packit b099d7
ChangeIfNeeded(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
        Widget w,
Packit b099d7
        XtWidgetGeometry *desired )
Packit b099d7
{
Packit b099d7
    XtWidgetGeometry g;
Packit b099d7
Packit b099d7
    /* find out the desired size of the form, using the 
Packit b099d7
       children attachment and the resizePolicy */
Packit b099d7
    GetSize(fw, &g, w, desired);
Packit b099d7
    
Packit b099d7
    _XmMakeGeometryRequest((Widget)fw, &g) ;
Packit b099d7
    
Packit b099d7
    if ( fw->bulletin_board.old_shadow_thickness &&
Packit b099d7
	(fw->bulletin_board.old_width != fw->core.width ||
Packit b099d7
	 fw->bulletin_board.old_height != fw->core.height) )
Packit b099d7
	{
Packit b099d7
	    _XmClearShadowType ((Widget) fw, fw->bulletin_board.old_width,
Packit b099d7
				fw->bulletin_board.old_height,
Packit b099d7
				fw->bulletin_board.old_shadow_thickness, 0);
Packit b099d7
	}
Packit b099d7
    
Packit b099d7
    fw->bulletin_board.old_width = fw->core.width;
Packit b099d7
    fw->bulletin_board.old_height = fw->core.height;
Packit b099d7
    fw->bulletin_board.old_shadow_thickness = fw->manager.shadow_thickness;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  DeleteChild
Packit b099d7
 *	Delete a single widget from a parent widget
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
DeleteChild(
Packit b099d7
        Widget child )
Packit b099d7
{
Packit b099d7
    XtWidgetProc delete_child;
Packit b099d7
Packit b099d7
    if (!XtIsRectObj(child)) return;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    delete_child = ((CompositeWidgetClass) xmFormClassRec.core_class.superclass)->
Packit b099d7
			    composite_class.delete_child;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    (*delete_child)(child);
Packit b099d7
Packit b099d7
    SortChildren((XmFormWidget) XtParent(child));
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SetValues
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
SetValues(
Packit b099d7
        Widget cw,
Packit b099d7
        Widget rw,
Packit b099d7
        Widget nw,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal * num_args )	/* unused */
Packit b099d7
{
Packit b099d7
        XmFormWidget old = (XmFormWidget) cw ;
Packit b099d7
        XmFormWidget new_w = (XmFormWidget) nw ;
Packit b099d7
Packit b099d7
	Boolean returnFlag = FALSE;
Packit b099d7
	Dimension w = 0;
Packit b099d7
	Dimension h = 0;
Packit b099d7
Packit b099d7
Packit b099d7
	/*  Check for invalid fraction base  */
Packit b099d7
Packit b099d7
	if (new_w->form.fraction_base == 0)
Packit b099d7
	{
Packit b099d7
		XmeWarning( (Widget) new_w, MESSAGE1);
Packit b099d7
		new_w->form.fraction_base = old->form.fraction_base;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (XtIsRealized((Widget)new_w))
Packit b099d7
	{
Packit b099d7
	    /* SetValues of width and/or height = 0, signals the form to  */
Packit b099d7
	    /* recompute its bounding box and grow if it needs.           */
Packit b099d7
Packit b099d7
		if ((XtWidth(new_w) != XtWidth(old)) ||
Packit b099d7
			(XtHeight(new_w) != XtHeight(old))) 
Packit b099d7
		{
Packit b099d7
			if ((XtWidth(new_w) == 0) || (XtHeight(new_w) == 0))
Packit b099d7
			{
Packit b099d7
				CalcFormSize (new_w, &w, &h);
Packit b099d7
				if (XtWidth(new_w) == 0) XtWidth(new_w) = w;
Packit b099d7
				if (XtHeight(new_w) == 0) XtHeight(new_w) = h;
Packit b099d7
Packit b099d7
			} 
Packit b099d7
			else
Packit b099d7
			{
Packit b099d7
				w = XtWidth(new_w);
Packit b099d7
				h = XtHeight(new_w);
Packit b099d7
			}
Packit b099d7
		}
Packit b099d7
Packit b099d7
Packit b099d7
		/*  If default distance has changed, or the
Packit b099d7
			fraction base has changed, recalculate size.  */
Packit b099d7
Packit b099d7
		if ((new_w->form.horizontal_spacing !=
Packit b099d7
				old->form.horizontal_spacing)   ||
Packit b099d7
			(new_w->bulletin_board.margin_width != 
Packit b099d7
				old->bulletin_board.margin_width)     ||
Packit b099d7
			(new_w->form.vertical_spacing != 
Packit b099d7
				old->form.vertical_spacing)     ||
Packit b099d7
			(new_w->bulletin_board.margin_height != 
Packit b099d7
				old->bulletin_board.margin_height)     ||
Packit b099d7
			(new_w->form.fraction_base != 
Packit b099d7
				old->form.fraction_base))
Packit b099d7
		{
Packit b099d7
			CalcFormSize(new_w, &w, &h);
Packit b099d7
			XtWidth(new_w) = w;
Packit b099d7
			XtHeight(new_w) = h;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
	
Packit b099d7
	return(returnFlag);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
SetValuesAlmost(
Packit b099d7
        Widget cw,		/* unused */
Packit b099d7
        Widget nw,
Packit b099d7
        XtWidgetGeometry *req,
Packit b099d7
        XtWidgetGeometry *rep )
Packit b099d7
{
Packit b099d7
	XmFormWidget new_w = (XmFormWidget) nw ;
Packit b099d7
Packit b099d7
	if (!rep->request_mode)
Packit b099d7
		PlaceChildren(new_w, NULL, NULL);
Packit b099d7
Packit b099d7
	*req = *rep;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ConstraintSetValues
Packit b099d7
 *	If any values change, what we do is place everything again.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
ConstraintSetValues(
Packit b099d7
        register Widget old,
Packit b099d7
        register Widget ref,	/* unused */
Packit b099d7
        register Widget new_w,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal * num_args )	/* unused */
Packit b099d7
{
Packit b099d7
    XmFormWidget fw = (XmFormWidget) XtParent(new_w);
Packit b099d7
    register XmFormConstraint oldc, newc;
Packit b099d7
    register int i;
Packit b099d7
    
Packit b099d7
    if (!XtIsRectObj(new_w))
Packit b099d7
	return(FALSE);
Packit b099d7
    
Packit b099d7
    oldc = GetFormConstraint(old),
Packit b099d7
    newc = GetFormConstraint(new_w);
Packit b099d7
   
Packit b099d7
   /* This fragment has been removed in order to fix bug #1298
Packit b099d7
    if (XtWidth(new_w) != XtWidth(old))
Packit b099d7
	newc->preferred_width = XtWidth(new_w);
Packit b099d7
    if (XtHeight(new_w) != XtHeight(old))
Packit b099d7
	newc->preferred_height = XtHeight(new_w);
Packit b099d7
    */
Packit b099d7
Packit b099d7
    /*  Validate the attachement type.  */
Packit b099d7
    
Packit b099d7
    for (i = FIRST_ATTACHMENT; i < (LAST_ATTACHMENT + 1); i++) {
Packit b099d7
	if (newc->att[i].type != oldc->att[i].type) {
Packit b099d7
	    if(    !XmRepTypeValidValue( XmRID_ATTACHMENT,
Packit b099d7
					newc->att[i].type, new_w)    )
Packit b099d7
		{
Packit b099d7
		    newc->att[i].type = oldc->att[i].type;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
	if ((newc->att[i].type == XmATTACH_WIDGET) ||
Packit b099d7
	    (newc->att[i].type == XmATTACH_OPPOSITE_WIDGET)) {
Packit b099d7
Packit b099d7
	    while ((newc->att[i].w) && !SIBLINGS(newc->att[i].w, new_w)) {
Packit b099d7
		newc->att[i].w = XtParent(newc->att[i].w);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    /* Re do the layout only if we have to */
Packit b099d7
    if ((XtIsRealized((Widget)fw)) && (XtIsManaged(new_w)) &&
Packit b099d7
	(ANY(type) || ANY(w) || ANY(percent) || ANY(offset)))
Packit b099d7
	{
Packit b099d7
	    XtWidgetGeometry g;
Packit b099d7
	    
Packit b099d7
	    g.request_mode = 0;
Packit b099d7
	    
Packit b099d7
	    if (XtWidth(new_w) != XtWidth(old))
Packit b099d7
		{
Packit b099d7
		    g.request_mode |= CWWidth;
Packit b099d7
		    g.width = XtWidth(new_w);
Packit b099d7
		}
Packit b099d7
	    
Packit b099d7
	    if (XtHeight(new_w) != XtHeight(old))
Packit b099d7
		{
Packit b099d7
		    g.request_mode |= CWHeight;
Packit b099d7
		    g.height = XtHeight(new_w);
Packit b099d7
		}
Packit b099d7
	    
Packit b099d7
	    if (XtBorderWidth(new_w) != XtBorderWidth(old))
Packit b099d7
		{
Packit b099d7
		    g.request_mode |= CWBorderWidth;
Packit b099d7
		    g.border_width = XtBorderWidth(new_w);
Packit b099d7
		}
Packit b099d7
	    
Packit b099d7
	    fw->form.processing_constraints = TRUE;
Packit b099d7
	    SortChildren(fw);
Packit b099d7
	    ChangeIfNeeded(fw, new_w, &g);
Packit b099d7
	    PlaceChildren(fw, new_w, &g);
Packit b099d7
	    new_w->core.x ++ ; /* Force a call to the GeometryManager.
Packit b099d7
				  There are cases where a change in
Packit b099d7
				  constraints does not result in a change
Packit b099d7
				  in the geometry of new_w. As a result, 
Packit b099d7
				  processing_constraint stays True and
Packit b099d7
				  everything is screwed up... 
Packit b099d7
				  Note that this change in x is only
Packit b099d7
				  temporary since Xt will reset it to
Packit b099d7
				  its old value before calling the GM */
Packit b099d7
	}
Packit b099d7
    
Packit b099d7
    return (False);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  Initialize
Packit b099d7
 *	The form widget specific initialization.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
Initialize(
Packit b099d7
        Widget rw,		/* unused */
Packit b099d7
        Widget nw,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal * num_args )	/* unused */
Packit b099d7
{
Packit b099d7
        XmFormWidget new_w = (XmFormWidget) nw ;
Packit b099d7
Packit b099d7
	new_w->form.first_child = NULL;
Packit b099d7
Packit b099d7
Packit b099d7
	if (new_w->form.fraction_base == 0)
Packit b099d7
	{
Packit b099d7
		new_w->form.fraction_base = 100;
Packit b099d7
		XmeWarning( (Widget) new_w, MESSAGE1);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	new_w->form.processing_constraints = FALSE;
Packit b099d7
Packit b099d7
	/* Set up for shadow drawing */
Packit b099d7
Packit b099d7
	new_w->bulletin_board.old_width = XtWidth(new_w);
Packit b099d7
	new_w->bulletin_board.old_height = XtHeight(new_w);
Packit b099d7
	new_w->bulletin_board.old_shadow_thickness =
Packit b099d7
		new_w->manager.shadow_thickness;
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ConstraintInitialize
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
ConstraintInitialize(
Packit b099d7
        Widget req,		/* unused */
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal * num_args )	/* unused */
Packit b099d7
{
Packit b099d7
    XmFormConstraint nc;
Packit b099d7
    register int i;
Packit b099d7
    
Packit b099d7
    if (!XtIsRectObj(new_w)) return;
Packit b099d7
    
Packit b099d7
    nc = GetFormConstraint(new_w);
Packit b099d7
    
Packit b099d7
    /*  Validate the attachement type.  */
Packit b099d7
    
Packit b099d7
    for (i = FIRST_ATTACHMENT; i < (LAST_ATTACHMENT + 1); i++){
Packit b099d7
	if(!XmRepTypeValidValue( XmRID_ATTACHMENT, nc->att[i].type, new_w))
Packit b099d7
	    {
Packit b099d7
		nc->att[i].type = XmATTACH_NONE;
Packit b099d7
	    }
Packit b099d7
	if ((nc->att[i].type == XmATTACH_WIDGET) ||
Packit b099d7
	    (nc->att[i].type == XmATTACH_OPPOSITE_WIDGET)) {
Packit b099d7
	    
Packit b099d7
	    while ((nc->att[i].w) && !SIBLINGS(nc->att[i].w, new_w)) {
Packit b099d7
		nc->att[i].w = XtParent(nc->att[i].w);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	nc->att[i].value = nc->att[i].tempValue = 0 ;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    /* set the preferred geometry to some magic value that will help
Packit b099d7
       us find in ChangeManaged that it's the first time this kid is
Packit b099d7
       going thru layout */
Packit b099d7
    /* this code used to set the current geometry as preferred, 
Packit b099d7
       I don't see why it was needed, since the preferred field are 
Packit b099d7
       always used after the changemanaged is called */
Packit b099d7
    nc->preferred_width = XmINVALID_DIMENSION;
Packit b099d7
    nc->preferred_height = XmINVALID_DIMENSION;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  CheckConstraints
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
CheckConstraints(
Packit b099d7
        Widget w )
Packit b099d7
{
Packit b099d7
  XmFormConstraint c = GetFormConstraint(w);
Packit b099d7
  XmFormWidget fw = (XmFormWidget) XtParent(w);
Packit b099d7
  XmFormAttachment left = &c->att[LEFT], right = &c->att[RIGHT],
Packit b099d7
  top = &c->att[TOP], bottom = &c->att[BOTTOM] ;
Packit b099d7
  XmFormAttachment a;
Packit b099d7
  int which;
Packit b099d7
  int wid, ht;
Packit b099d7
  
Packit b099d7
  if (left->type == XmATTACH_NONE && right->type == XmATTACH_NONE) 
Packit b099d7
    {
Packit b099d7
      if (fw->form.rubber_positioning) 
Packit b099d7
	left->type = right->type = XmATTACH_SELF;
Packit b099d7
      else
Packit b099d7
	{
Packit b099d7
	  left->type = XmATTACH_FORM;
Packit b099d7
	  left->offset = w->core.x;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  if (top->type == XmATTACH_NONE && bottom->type == XmATTACH_NONE)
Packit b099d7
    {
Packit b099d7
      if (fw->form.rubber_positioning) 
Packit b099d7
	top->type = bottom->type = XmATTACH_SELF;
Packit b099d7
      else 
Packit b099d7
	{
Packit b099d7
	  top->type = XmATTACH_FORM;
Packit b099d7
	  top->offset = w->core.y;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  for (which = FIRST_ATTACHMENT; which < (LAST_ATTACHMENT + 1); which++) 
Packit b099d7
    {
Packit b099d7
      a = &c->att[which];
Packit b099d7
      
Packit b099d7
      switch (a->type) 
Packit b099d7
	{
Packit b099d7
	case XmATTACH_NONE:
Packit b099d7
	case XmATTACH_FORM:
Packit b099d7
	case XmATTACH_OPPOSITE_FORM:
Packit b099d7
	  a->w = NULL;
Packit b099d7
	  a->percent = 0;
Packit b099d7
	  break;
Packit b099d7
	  
Packit b099d7
	case XmATTACH_SELF:
Packit b099d7
	  a->offset = 0;
Packit b099d7
	  a->w = NULL;
Packit b099d7
	  a->type = XmATTACH_POSITION;
Packit b099d7
	  a->percent = 0;	/* default in case wid or ht are 0, although 
Packit b099d7
				   behavior in that case is poorly defined */
Packit b099d7
  	  
Packit b099d7
	  wid = w->core.x + w->core.width
Packit b099d7
	    + (2 * w->core.border_width);
Packit b099d7
	  ht = w->core.y + w->core.height
Packit b099d7
	    + (2 * w->core.border_width);
Packit b099d7
	  
Packit b099d7
	  if (wid < fw->core.width)
Packit b099d7
	    wid = fw->core.width;
Packit b099d7
	  if (ht  < fw->core.height)
Packit b099d7
	    ht  = fw->core.height;
Packit b099d7
	  
Packit b099d7
	  switch (which)
Packit b099d7
	    {
Packit b099d7
	    case LEFT:
Packit b099d7
		if (wid != 0)
Packit b099d7
		    a->percent = (w->core.x
Packit b099d7
				  * fw->form.fraction_base) / wid;
Packit b099d7
		break;
Packit b099d7
	      
Packit b099d7
	    case TOP:
Packit b099d7
		if (ht != 0)
Packit b099d7
		    a->percent = (w->core.y
Packit b099d7
				  * fw->form.fraction_base) / ht;
Packit b099d7
		break;
Packit b099d7
	      
Packit b099d7
	    case RIGHT:
Packit b099d7
		if (wid != 0)
Packit b099d7
		    a->percent = ((w->core.x + w->core.width +
Packit b099d7
				   2 * w->core.border_width) *
Packit b099d7
				  fw->form.fraction_base) / wid;
Packit b099d7
		break;
Packit b099d7
	      
Packit b099d7
	    case BOTTOM:
Packit b099d7
		if (ht != 0)
Packit b099d7
		    a->percent = ((w->core.y + w->core.height +
Packit b099d7
				   2 * w->core.border_width) *
Packit b099d7
				  fw->form.fraction_base) / ht;
Packit b099d7
		break;
Packit b099d7
	    }
Packit b099d7
	  break;
Packit b099d7
	  
Packit b099d7
	case XmATTACH_POSITION:
Packit b099d7
	  a->w = NULL;
Packit b099d7
	  break;
Packit b099d7
	  
Packit b099d7
	case XmATTACH_WIDGET:
Packit b099d7
	case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
	  a->percent = 0;
Packit b099d7
	  break;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SortChildren
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
SortChildren(
Packit b099d7
        register XmFormWidget fw )
Packit b099d7
{
Packit b099d7
	int i, j;
Packit b099d7
	Widget child = NULL;
Packit b099d7
	register XmFormConstraint c = NULL, c1 = NULL;
Packit b099d7
	int sortedCount = 0;
Packit b099d7
	Widget last_child, att_widget;
Packit b099d7
	Boolean sortable;
Packit b099d7
Packit b099d7
Packit b099d7
	fw->form.first_child = NULL;
Packit b099d7
Packit b099d7
	for (i = 0; i < fw->composite.num_children; i++)
Packit b099d7
	{
Packit b099d7
		child = fw->composite.children[i];
Packit b099d7
		if (!XtIsRectObj(child))
Packit b099d7
			continue;
Packit b099d7
		c = GetFormConstraint(child);
Packit b099d7
Packit b099d7
		if (XtIsManaged(child))
Packit b099d7
		{
Packit b099d7
			c->sorted = False;
Packit b099d7
			c->next_sibling = NULL;
Packit b099d7
		}
Packit b099d7
		else
Packit b099d7
		{	
Packit b099d7
			c->next_sibling = fw->form.first_child;
Packit b099d7
			fw->form.first_child = child;
Packit b099d7
			c->sorted = True;
Packit b099d7
			sortedCount++;
Packit b099d7
		}
Packit b099d7
Packit b099d7
		CheckConstraints(child);
Packit b099d7
	}
Packit b099d7
Packit b099d7
Packit b099d7
	/* THIS IS PROBABLY WRONG AND SHOULD BE FIXED SOMEDAY             */
Packit b099d7
	/* WHY SHOULD UNMANAGED CHILDREN BE ALLOWED AS ATTACHMENT POINTS  */
Packit b099d7
	/* FOR MANAGED CHILDREN???                                        */
Packit b099d7
Packit b099d7
	/* While there are unsorted children, find one with only sorted  */
Packit b099d7
	/* predecessors and put it in the list.  This algorithm works    */
Packit b099d7
	/* particularly well if the order is already correct             */
Packit b099d7
Packit b099d7
	last_child = NULL;
Packit b099d7
Packit b099d7
	for ( ; sortedCount != fw->composite.num_children; sortedCount++) 
Packit b099d7
	{
Packit b099d7
		sortable = False;
Packit b099d7
Packit b099d7
		for (i = 0; !sortable && i < fw->composite.num_children; i++) 
Packit b099d7
		{
Packit b099d7
			child = fw->composite.children[i];
Packit b099d7
			if (!XtIsRectObj(child))
Packit b099d7
				continue;
Packit b099d7
			c = GetFormConstraint(child);
Packit b099d7
Packit b099d7
			if (c->sorted)
Packit b099d7
				continue;
Packit b099d7
Packit b099d7
			sortable = True;
Packit b099d7
Packit b099d7
			for (j = FIRST_ATTACHMENT; j < (LAST_ATTACHMENT + 1); j++) 
Packit b099d7
			{
Packit b099d7
				if ((c->att[j].type == XmATTACH_WIDGET) ||
Packit b099d7
				(c->att[j].type == XmATTACH_OPPOSITE_WIDGET))
Packit b099d7
				{	
Packit b099d7
					att_widget = c->att[j].w;
Packit b099d7
Packit b099d7
					if ((SIBLINGS(att_widget, child)) &&
Packit b099d7
						(XtIsRectObj(att_widget)))
Packit b099d7
					{
Packit b099d7
						c1 = GetFormConstraint (att_widget);
Packit b099d7
						
Packit b099d7
						if (!c1->sorted)
Packit b099d7
							sortable = False;
Packit b099d7
					}
Packit b099d7
				}
Packit b099d7
			}
Packit b099d7
		}
Packit b099d7
Packit b099d7
		if (sortable)
Packit b099d7
		{
Packit b099d7
			/*  We have found a sortable child...add to sorted list.  */
Packit b099d7
Packit b099d7
			if (last_child == NULL) 
Packit b099d7
			{
Packit b099d7
				c->next_sibling = fw->form.first_child;
Packit b099d7
				fw->form.first_child = child;
Packit b099d7
			}
Packit b099d7
			else
Packit b099d7
			{
Packit b099d7
				c1 = GetFormConstraint(last_child);
Packit b099d7
				c->next_sibling = c1->next_sibling;
Packit b099d7
				c1->next_sibling = child;
Packit b099d7
			}
Packit b099d7
Packit b099d7
			last_child = child;
Packit b099d7
			c->sorted = True;
Packit b099d7
		}
Packit b099d7
#ifndef FIX_1299
Packit b099d7
Packit b099d7
		else
Packit b099d7
		{
Packit b099d7
			/*  We failed to find a sortable child, there must be  */
Packit b099d7
			/*  a circular dependency.                             */ 
Packit b099d7
Packit b099d7
			XmeWarning( (Widget) fw, MESSAGE5);
Packit b099d7
			return;
Packit b099d7
		}
Packit b099d7
#endif
Packit b099d7
	}
Packit b099d7
Packit b099d7
#ifdef FIX_1299
Packit b099d7
  /*Add other children that haven't been sorted*/
Packit b099d7
	for (i = 0; i < fw->composite.num_children; i++)
Packit b099d7
	{
Packit b099d7
		child = fw->composite.children[i];
Packit b099d7
Packit b099d7
    c = GetFormConstraint(child);
Packit b099d7
    
Packit b099d7
    if (!XtIsRectObj(child) || c->sorted)
Packit b099d7
			continue;
Packit b099d7
		
Packit b099d7
    if(!c->sorted) {
Packit b099d7
			if (last_child == NULL) 
Packit b099d7
			{
Packit b099d7
				c->next_sibling = fw->form.first_child;
Packit b099d7
				fw->form.first_child = child;
Packit b099d7
			  }
Packit b099d7
			else
Packit b099d7
			{
Packit b099d7
				c1 = GetFormConstraint(last_child);
Packit b099d7
				c->next_sibling = c1->next_sibling;
Packit b099d7
				c1->next_sibling = child;
Packit b099d7
			}
Packit b099d7
Packit b099d7
			last_child = child;
Packit b099d7
			c->sorted = True;
Packit b099d7
		}
Packit b099d7
  }
Packit b099d7
#endif
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  CalcEdgeValues
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
CalcEdgeValues(
Packit b099d7
        Widget w,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int really,
Packit b099d7
#else
Packit b099d7
        Boolean really,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        Widget instigator,
Packit b099d7
        XtWidgetGeometry *inst_geometry,
Packit b099d7
        Dimension *form_width,
Packit b099d7
        Dimension *form_height )
Packit b099d7
{
Packit b099d7
	XmFormConstraint c = GetFormConstraint (w);
Packit b099d7
	XmFormWidget fw = (XmFormWidget) XtParent (w);
Packit b099d7
	XmFormAttachment left = &c->att[LEFT], right = &c->att[RIGHT],
Packit b099d7
		top = &c->att[TOP], bottom = &c->att[BOTTOM] ;
Packit b099d7
	Dimension width, height, border_width;
Packit b099d7
Packit b099d7
	if (w == instigator) 
Packit b099d7
	{ 
Packit b099d7
		if (inst_geometry->request_mode & CWWidth)
Packit b099d7
			width = inst_geometry->width; 
Packit b099d7
		else
Packit b099d7
			width = w->core.width;
Packit b099d7
		if (inst_geometry->request_mode & CWHeight)
Packit b099d7
			height = inst_geometry->height; 
Packit b099d7
		else
Packit b099d7
			height = w->core.height;
Packit b099d7
		if (inst_geometry->request_mode & CWBorderWidth)
Packit b099d7
			border_width = inst_geometry->border_width;
Packit b099d7
		else
Packit b099d7
			border_width = w->core.border_width;
Packit b099d7
	}
Packit b099d7
	else if (!fw->form.processing_constraints)
Packit b099d7
	{
Packit b099d7
		/*
Packit b099d7
		* If we just use the widget's current geometry we will
Packit b099d7
		* effectively be grow only.  That would not be correct.
Packit b099d7
		*
Packit b099d7
		* Instead we will use our idea of the child's preferred
Packit b099d7
		* size.
Packit b099d7
		*/
Packit b099d7
		width = c->preferred_width;
Packit b099d7
		height = c->preferred_height;
Packit b099d7
		border_width = w->core.border_width;
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
		width = w->core.width;
Packit b099d7
		height = w->core.height;
Packit b099d7
		border_width = w->core.border_width;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	width += border_width * 2;
Packit b099d7
	height += border_width * 2;
Packit b099d7
Packit b099d7
Packit b099d7
	if (width <= 0) width = 1;
Packit b099d7
	if (height <= 0) height = 1;
Packit b099d7
Packit b099d7
	if (left->type != XmATTACH_NONE)
Packit b099d7
	{
Packit b099d7
		if (right->type != XmATTACH_NONE)	    /* LEFT and right are attached */
Packit b099d7
		{
Packit b099d7
			CalcEdgeValue(fw, w, width, border_width, 
Packit b099d7
				LEFT, really, form_width, form_height);
Packit b099d7
			CalcEdgeValue(fw, w, width, border_width, 
Packit b099d7
				RIGHT, really, form_width, form_height);
Packit b099d7
		}
Packit b099d7
Packit b099d7
		else 	/*  LEFT attached, compute right  */
Packit b099d7
		{
Packit b099d7
			CalcEdgeValue(fw, w, width, border_width, 
Packit b099d7
				LEFT, really, form_width, form_height);
Packit b099d7
			ComputeAttachment(fw, w, width, border_width, RIGHT, really,
Packit b099d7
			form_width, form_height);
Packit b099d7
		}
Packit b099d7
	} 
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
		if (right->type != XmATTACH_NONE)    /* RIGHT attached, compute left */
Packit b099d7
		{
Packit b099d7
		CalcEdgeValue(fw, w, width, border_width, 
Packit b099d7
			RIGHT, really, form_width, form_height);
Packit b099d7
		ComputeAttachment(fw, w, width, border_width, 
Packit b099d7
			LEFT, really, form_width, form_height);
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (top->type != XmATTACH_NONE) 
Packit b099d7
	{
Packit b099d7
		if (bottom->type != XmATTACH_NONE)   /* TOP and bottom are attached */
Packit b099d7
		{
Packit b099d7
			CalcEdgeValue(fw, w, height, border_width, 
Packit b099d7
				TOP, really, form_width, form_height);
Packit b099d7
			CalcEdgeValue(fw, w, height, border_width, 
Packit b099d7
				BOTTOM, really, form_width, form_height);
Packit b099d7
		}
Packit b099d7
		else	/* TOP attached, compute bottom */
Packit b099d7
		{
Packit b099d7
			CalcEdgeValue(fw, w, height, border_width, 
Packit b099d7
				TOP, really, form_width, form_height);
Packit b099d7
			ComputeAttachment(fw, w, height, border_width, 
Packit b099d7
				BOTTOM, really, form_width, form_height);
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
		if (bottom->type != XmATTACH_NONE)   /* BOTTOM attached, compute top */
Packit b099d7
		{
Packit b099d7
			CalcEdgeValue(fw, w, height, border_width, 
Packit b099d7
				BOTTOM, really, form_width, form_height);
Packit b099d7
			ComputeAttachment(fw, w, height, border_width, 
Packit b099d7
				TOP, really, form_width, form_height);
Packit b099d7
		} 
Packit b099d7
	}
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/*********************************************************************
Packit b099d7
 *
Packit b099d7
 * CheckBottomBase
Packit b099d7
 *
Packit b099d7
 *********************************************************************/
Packit b099d7
static float 
Packit b099d7
CheckBottomBase(
Packit b099d7
        Widget sibling,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int opposite )
Packit b099d7
#else
Packit b099d7
        Boolean opposite )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
	XmFormWidget fw = (XmFormWidget) sibling->core.parent;
Packit b099d7
	XmFormConstraint c = GetFormConstraint(sibling);
Packit b099d7
	Boolean flag = FALSE;
Packit b099d7
	float return_val;
Packit b099d7
Packit b099d7
	if (!opposite)
Packit b099d7
	{
Packit b099d7
		switch (c->att[TOP].type)
Packit b099d7
		{
Packit b099d7
			case XmATTACH_POSITION:
Packit b099d7
				return_val = (float) c->att[TOP].percent /
Packit b099d7
				    (float) fw->form.fraction_base ;
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_NONE:
Packit b099d7
				switch (c->att[BOTTOM].type)
Packit b099d7
				{
Packit b099d7
					case XmATTACH_FORM:
Packit b099d7
						return_val = 1.0;
Packit b099d7
					break;
Packit b099d7
					case XmATTACH_POSITION:
Packit b099d7
						return_val = (float) c->att[BOTTOM].percent /
Packit b099d7
							(float) fw->form.fraction_base ;
Packit b099d7
					break;
Packit b099d7
					case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
						flag = TRUE;
Packit b099d7
					case XmATTACH_WIDGET:
Packit b099d7
						if (SIBLINGS(c->att[BOTTOM].w, sibling))
Packit b099d7
							return_val = 
Packit b099d7
								CheckBottomBase(c->att[BOTTOM].w, flag);
Packit b099d7
						else
Packit b099d7
						{
Packit b099d7
							if (flag)
Packit b099d7
								return_val = 0.0;
Packit b099d7
							else
Packit b099d7
								return_val = 1.0;
Packit b099d7
						}
Packit b099d7
					break;
Packit b099d7
					default:
Packit b099d7
						return_val = 0.0;
Packit b099d7
					break;
Packit b099d7
				}
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_OPPOSITE_FORM:
Packit b099d7
				return_val = 1.0;
Packit b099d7
			break;
Packit b099d7
			default:
Packit b099d7
				return_val = 0.0;
Packit b099d7
			break;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
		switch(c->att[BOTTOM].type)
Packit b099d7
		{
Packit b099d7
			case XmATTACH_NONE:
Packit b099d7
				if (c->att[TOP].type == XmATTACH_POSITION)
Packit b099d7
					return_val = (float) c->att[TOP].percent /
Packit b099d7
						(float) fw->form.fraction_base;
Packit b099d7
				else
Packit b099d7
					return_val = 0.0;
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_POSITION:
Packit b099d7
				return_val = (float) c->att[BOTTOM].percent /
Packit b099d7
				    (float) fw->form.fraction_base;
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
				flag = TRUE;
Packit b099d7
			case XmATTACH_WIDGET:
Packit b099d7
				if (SIBLINGS(c->att[BOTTOM].w, sibling))
Packit b099d7
					return_val = 
Packit b099d7
						CheckBottomBase(c->att[BOTTOM].w, flag);
Packit b099d7
				else
Packit b099d7
				{
Packit b099d7
					if (flag)
Packit b099d7
						return_val = 0.0;
Packit b099d7
					else
Packit b099d7
						return_val = 1.0;
Packit b099d7
				}
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_FORM:
Packit b099d7
				return_val = 1.0;
Packit b099d7
			break;
Packit b099d7
			default:
Packit b099d7
				return_val = 0.0;
Packit b099d7
			break;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
Packit b099d7
	return(return_val);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*********************************************************************
Packit b099d7
 *
Packit b099d7
 * CheckRightBase
Packit b099d7
 *
Packit b099d7
 *********************************************************************/
Packit b099d7
static float 
Packit b099d7
CheckRightBase(
Packit b099d7
        Widget sibling,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int opposite )
Packit b099d7
#else
Packit b099d7
        Boolean opposite )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
	XmFormWidget fw = (XmFormWidget) sibling->core.parent;
Packit b099d7
	XmFormConstraint c = GetFormConstraint(sibling);
Packit b099d7
	Boolean flag = FALSE;
Packit b099d7
	float return_val;
Packit b099d7
Packit b099d7
	if (!opposite)
Packit b099d7
	{
Packit b099d7
		switch (c->att[LEFT].type)
Packit b099d7
		{
Packit b099d7
			case XmATTACH_POSITION:
Packit b099d7
				return_val =  (float) c->att[LEFT].percent /
Packit b099d7
				    (float) fw->form.fraction_base;
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_NONE:
Packit b099d7
				switch (c->att[RIGHT].type)
Packit b099d7
				{
Packit b099d7
					case XmATTACH_FORM:
Packit b099d7
						return_val = 1.0;
Packit b099d7
					break;
Packit b099d7
					case XmATTACH_POSITION:
Packit b099d7
						return_val = (float) c->att[RIGHT].percent /
Packit b099d7
							(float) fw->form.fraction_base ;
Packit b099d7
					break;
Packit b099d7
					case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
						flag = TRUE;
Packit b099d7
					case XmATTACH_WIDGET:
Packit b099d7
						if (SIBLINGS(c->att[RIGHT].w, sibling))
Packit b099d7
							return_val = 
Packit b099d7
								CheckRightBase(c->att[RIGHT].w, flag);
Packit b099d7
						else
Packit b099d7
						{
Packit b099d7
							if (flag)
Packit b099d7
								return_val =  0.0;
Packit b099d7
							else
Packit b099d7
								return_val = 1.0;
Packit b099d7
						}
Packit b099d7
					break;
Packit b099d7
					default:
Packit b099d7
						return_val =  0.0;
Packit b099d7
					break;
Packit b099d7
				}
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_OPPOSITE_FORM:
Packit b099d7
				return_val = 1.0;
Packit b099d7
			break;
Packit b099d7
			default:
Packit b099d7
				return_val = 0.0;
Packit b099d7
			break;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
		switch(c->att[RIGHT].type)
Packit b099d7
		{
Packit b099d7
			case XmATTACH_NONE:
Packit b099d7
				if (c->att[LEFT].type == XmATTACH_POSITION)
Packit b099d7
					return_val = (float) c->att[LEFT].percent /
Packit b099d7
						(float) fw->form.fraction_base ;
Packit b099d7
				else
Packit b099d7
					return_val = 0.0;
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_POSITION:
Packit b099d7
				return_val = (float) c->att[RIGHT].percent /
Packit b099d7
				    (float) fw->form.fraction_base;
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
				flag = TRUE;
Packit b099d7
			case XmATTACH_WIDGET:
Packit b099d7
				if (SIBLINGS(c->att[RIGHT].w, sibling))
Packit b099d7
					return_val = 
Packit b099d7
						CheckRightBase(c->att[RIGHT].w, flag);
Packit b099d7
				else
Packit b099d7
				{
Packit b099d7
					if (flag)
Packit b099d7
						return_val =  0.0;
Packit b099d7
					else
Packit b099d7
						return_val = 1.0;
Packit b099d7
				}
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_FORM:
Packit b099d7
				return_val = 1.0;
Packit b099d7
			break;
Packit b099d7
			default:
Packit b099d7
				return_val = 0.0;
Packit b099d7
			break;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
Packit b099d7
	return(return_val);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*********************************************************************
Packit b099d7
 *
Packit b099d7
 * CheckLeftBase
Packit b099d7
 *
Packit b099d7
 *********************************************************************/
Packit b099d7
static float 
Packit b099d7
CheckLeftBase(
Packit b099d7
        Widget sibling,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int opposite )
Packit b099d7
#else
Packit b099d7
        Boolean opposite )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
	XmFormWidget fw = (XmFormWidget) sibling->core.parent;
Packit b099d7
	XmFormConstraint c = GetFormConstraint(sibling);
Packit b099d7
	Boolean flag = FALSE;
Packit b099d7
	float return_val;
Packit b099d7
Packit b099d7
	if (!opposite)
Packit b099d7
	{
Packit b099d7
		switch (c->att[RIGHT].type)
Packit b099d7
		{
Packit b099d7
			case XmATTACH_POSITION:
Packit b099d7
				return_val =  (float) c->att[RIGHT].percent /
Packit b099d7
				    (float) fw->form.fraction_base;
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_NONE:
Packit b099d7
				switch (c->att[LEFT].type)
Packit b099d7
				{
Packit b099d7
					case XmATTACH_FORM:
Packit b099d7
						return_val = 1.0;
Packit b099d7
					break;
Packit b099d7
					case XmATTACH_POSITION:
Packit b099d7
						return_val = (float) c->att[LEFT].percent /
Packit b099d7
							(float) fw->form.fraction_base ;
Packit b099d7
					break;
Packit b099d7
					case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
						flag = TRUE;
Packit b099d7
					case XmATTACH_WIDGET:
Packit b099d7
						if (SIBLINGS(c->att[LEFT].w, sibling))
Packit b099d7
							return_val = 
Packit b099d7
								CheckLeftBase(c->att[LEFT].w, flag);
Packit b099d7
						else
Packit b099d7
						{
Packit b099d7
							if (flag)
Packit b099d7
								return_val =  0.0;
Packit b099d7
							else
Packit b099d7
								return_val = 1.0;
Packit b099d7
						}
Packit b099d7
					break;
Packit b099d7
					default:
Packit b099d7
						return_val =  0.0;
Packit b099d7
					break;
Packit b099d7
				}
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_OPPOSITE_FORM:
Packit b099d7
				return_val = 1.0;
Packit b099d7
			break;
Packit b099d7
			default:
Packit b099d7
				return_val = 0.0;
Packit b099d7
			break;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
		switch(c->att[LEFT].type)
Packit b099d7
		{
Packit b099d7
			case XmATTACH_NONE:
Packit b099d7
				if (c->att[RIGHT].type == XmATTACH_POSITION)
Packit b099d7
					return_val = (float) c->att[RIGHT].percent /
Packit b099d7
						(float) fw->form.fraction_base ;
Packit b099d7
				else
Packit b099d7
					return_val = 0.0;
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_POSITION:
Packit b099d7
				return_val = (float) c->att[LEFT].percent /
Packit b099d7
				    (float) fw->form.fraction_base;
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
				flag = TRUE;
Packit b099d7
			case XmATTACH_WIDGET:
Packit b099d7
				if (SIBLINGS(c->att[LEFT].w, sibling))
Packit b099d7
					return_val = 
Packit b099d7
						CheckLeftBase(c->att[LEFT].w, flag);
Packit b099d7
				else
Packit b099d7
				{
Packit b099d7
					if (flag)
Packit b099d7
						return_val =  0.0;
Packit b099d7
					else
Packit b099d7
						return_val = 1.0;
Packit b099d7
				}
Packit b099d7
			break;
Packit b099d7
			case XmATTACH_FORM:
Packit b099d7
				return_val = 1.0;
Packit b099d7
			break;
Packit b099d7
			default:
Packit b099d7
				return_val = 0.0;
Packit b099d7
			break;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
Packit b099d7
	return(return_val);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*********************************************************************
Packit b099d7
 *
Packit b099d7
 *  CalcEdgeValue
Packit b099d7
 *     Note that Left attachment apply to the right side in a 
Packit b099d7
 *     Right-to-Left environment. Slightly confusing, but it is more a
Packit b099d7
 *     matter of switching right and left in the computing.
Packit b099d7
 *
Packit b099d7
 *********************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
CalcEdgeValue(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
        Widget w,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int size,
Packit b099d7
        int border_width,	/* unused */
Packit b099d7
#else
Packit b099d7
        Dimension size,
Packit b099d7
        Dimension border_width,	/* unused */
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        int which,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int really,
Packit b099d7
#else
Packit b099d7
        Boolean really,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        Dimension *fwidth,
Packit b099d7
        Dimension *fheight )
Packit b099d7
{
Packit b099d7
  float scale;
Packit b099d7
  XmFormAttachment att = GetFormConstraint(w)->att;
Packit b099d7
  XmFormAttachment a = att + which;
Packit b099d7
  XmFormConstraint c;
Packit b099d7
  XmFormAttachment ref;
Packit b099d7
  float factor;
Packit b099d7
  int temp1, temp2, temp3;
Packit b099d7
  int ctype;
Packit b099d7
  
Packit b099d7
  
Packit b099d7
  ctype = a->type;
Packit b099d7
  
Packit b099d7
  if ((ctype == XmATTACH_WIDGET) && !(SIBLINGS(a->w, w)))
Packit b099d7
    ctype = XmATTACH_FORM;
Packit b099d7
  
Packit b099d7
  if ((ctype == XmATTACH_OPPOSITE_WIDGET) && !(SIBLINGS(a->w, w)))
Packit b099d7
    ctype = XmATTACH_OPPOSITE_FORM;
Packit b099d7
  
Packit b099d7
  if (LayoutIsRtoLM(fw)) 
Packit b099d7
    switch (ctype) 
Packit b099d7
      {
Packit b099d7
      case XmATTACH_FORM:
Packit b099d7
	a->w = NULL;
Packit b099d7
	a->percent = 0;
Packit b099d7
	
Packit b099d7
	switch (which) 
Packit b099d7
	  {
Packit b099d7
	  case RIGHT:
Packit b099d7
	  case TOP:
Packit b099d7
	    AssignValue(a, GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case LEFT:
Packit b099d7
	    if (fwidth != NULL) {
Packit b099d7
	      if ((att + RIGHT)->type == XmATTACH_NONE) {
Packit b099d7
		temp1 = *fwidth - (GetFormOffset(fw, which, att));
Packit b099d7
		temp2 = temp1 - size;
Packit b099d7
		if (temp2 < 0) {
Packit b099d7
		  *fwidth += abs(temp2);
Packit b099d7
		  AssignValue(a, (temp1 + abs(temp2)));
Packit b099d7
		} else
Packit b099d7
		  AssignValue(a, temp1);
Packit b099d7
	      } else {
Packit b099d7
		temp1 = *fwidth - (GetFormOffset(fw, which, att));
Packit b099d7
		temp2 = Value(att + RIGHT);
Packit b099d7
		temp3 = temp1 - temp2 - size;
Packit b099d7
		if (temp3 < 0) {
Packit b099d7
		  *fwidth += abs(temp3);
Packit b099d7
		  AssignValue(a, (*fwidth - size - GetFormOffset(fw, which, att)));
Packit b099d7
		} else
Packit b099d7
		  AssignValue(a, temp1);
Packit b099d7
	      }
Packit b099d7
	    } else
Packit b099d7
	      AssignValue(a, fw->core.width - GetFormOffset(fw,which,att));
Packit b099d7
	    break;
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    if (fheight != NULL) {
Packit b099d7
	      if ((att + TOP)->type == XmATTACH_NONE) {
Packit b099d7
		temp1 = *fheight - GetFormOffset(fw, which, att);
Packit b099d7
		temp2 = temp1 - size;
Packit b099d7
		if (temp2 < 0) {
Packit b099d7
		  *fheight += abs(temp2);
Packit b099d7
		  AssignValue(a, (temp1 + abs(temp2)));
Packit b099d7
		} else
Packit b099d7
		  AssignValue(a, temp1);
Packit b099d7
	      } else {
Packit b099d7
		temp1 = *fheight - GetFormOffset(fw, which, att);
Packit b099d7
		temp2 = Value(att + TOP);
Packit b099d7
		temp3 = temp1 - temp2 - size;
Packit b099d7
		if (temp3 < 0) {
Packit b099d7
		  *fheight += abs(temp3);
Packit b099d7
		  AssignValue(a, (*fheight - size - GetFormOffset(fw, which, att)));
Packit b099d7
		} else
Packit b099d7
		  AssignValue(a, temp1);
Packit b099d7
	      }
Packit b099d7
	    } else
Packit b099d7
	      AssignValue(a, fw->core.height - GetFormOffset(fw,which,att));
Packit b099d7
	    break;
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
	
Packit b099d7
      case XmATTACH_OPPOSITE_FORM:
Packit b099d7
	a->w = NULL;
Packit b099d7
	a->percent = 0;
Packit b099d7
	
Packit b099d7
	switch (which) 
Packit b099d7
	  {
Packit b099d7
	  case RIGHT:
Packit b099d7
	    if (fwidth) {
Packit b099d7
	      temp1 = *fwidth + GetFormOffset(fw, which, att);
Packit b099d7
	      if (temp1 < 0) {
Packit b099d7
		*fwidth += abs(temp1);
Packit b099d7
		temp1 = 0;
Packit b099d7
	      }
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    } else
Packit b099d7
	      AssignValue(a, fw->core.width + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case TOP:
Packit b099d7
	    if (fheight) {
Packit b099d7
	      temp1 = *fheight + GetFormOffset(fw, which, att);
Packit b099d7
	      if (temp1 < 0) {
Packit b099d7
		*fheight += abs(temp1);
Packit b099d7
		temp1 = 0;
Packit b099d7
	      }
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    } else
Packit b099d7
	      AssignValue(a, fw->core.height + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case LEFT:
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    AssignValue(a, -(GetFormOffset(fw, which, att)));
Packit b099d7
	    break;
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
	
Packit b099d7
      case XmATTACH_POSITION:
Packit b099d7
	scale = ((float) a->percent) / fw->form.fraction_base;
Packit b099d7
	a->w = 0;
Packit b099d7
	
Packit b099d7
	switch (which) 
Packit b099d7
	  {
Packit b099d7
	  case RIGHT:
Packit b099d7
	    scale = 1.0 - scale;
Packit b099d7
	    if (fwidth != NULL)
Packit b099d7
	      AssignValue(a, (*fwidth * scale + 0.5) + 
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	    else
Packit b099d7
	      AssignValue(a, (fw->core.width * scale + 0.5) +
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	  case TOP:
Packit b099d7
	    if (fheight != NULL)
Packit b099d7
	      AssignValue(a, (*fheight * scale + 0.5) + 
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	    else
Packit b099d7
	      AssignValue(a, (fw->core.height * scale + 0.5) + 
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	  case LEFT:
Packit b099d7
	    scale = 1.0 - scale;
Packit b099d7
	    if (fwidth != NULL)
Packit b099d7
	      if ((att + RIGHT)->type != XmATTACH_NONE) {
Packit b099d7
		temp1 = (int) (((*fwidth  * scale) + 0.5) - 
Packit b099d7
			       GetFormOffset(fw, which, att));
Packit b099d7
		temp2 = Value(att + RIGHT);
Packit b099d7
		temp3 = temp1 - temp2 - size;
Packit b099d7
		if (temp3 < 0) {
Packit b099d7
		  if (!scale)
Packit b099d7
		    scale = 1.0;
Packit b099d7
Packit b099d7
		  *fwidth += (Dimension) (((1.0 / scale) * abs(temp3)) + 0.5);
Packit b099d7
		}
Packit b099d7
		AssignValue(a, (temp2 + size));
Packit b099d7
	      } else
Packit b099d7
		AssignValue(a, (*fwidth * scale + 0.5) - 
Packit b099d7
			    GetFormOffset(fw, which, att));
Packit b099d7
	    else
Packit b099d7
	      AssignValue(a, (fw->core.width * scale + 0.5) - 
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    if (fheight != NULL)
Packit b099d7
	      if ((att + TOP)->type != XmATTACH_NONE) {
Packit b099d7
		temp1 = (int) (((*fheight  * scale) + 0.5) 
Packit b099d7
			       - GetFormOffset(fw, which, att));
Packit b099d7
		temp2 = Value(att + TOP);
Packit b099d7
		temp3 = temp1 - temp2 - size;
Packit b099d7
		if (temp3 < 0) {
Packit b099d7
		  if (!scale)
Packit b099d7
		    scale = 1.0;
Packit b099d7
		  
Packit b099d7
		  *fheight += (Dimension) (((1.0 / scale) * abs(temp3)) + 0.5);
Packit b099d7
		}
Packit b099d7
		AssignValue(a, (temp2 + size));
Packit b099d7
	      } else
Packit b099d7
		AssignValue(a, (*fheight * scale + 0.5) - 
Packit b099d7
			    GetFormOffset(fw, which, att));
Packit b099d7
	    else
Packit b099d7
	      AssignValue(a, (fw->core.height * scale + 0.5) - 
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
	
Packit b099d7
      case XmATTACH_WIDGET:
Packit b099d7
	a->percent = 0;
Packit b099d7
	c = GetFormConstraint(a->w);
Packit b099d7
	
Packit b099d7
	switch (which)
Packit b099d7
	  {
Packit b099d7
	  case RIGHT:
Packit b099d7
	    ref = &c->att[LEFT];
Packit b099d7
	    AssignValue(a, Value(ref) + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case TOP:
Packit b099d7
	    ref = &c->att[BOTTOM];
Packit b099d7
	    AssignValue(a, Value(ref) + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case LEFT:
Packit b099d7
	    ref = &c->att[RIGHT];
Packit b099d7
	    if (att[RIGHT].type != XmATTACH_NONE) {
Packit b099d7
	      temp1 = Value(ref) - GetFormOffset(fw, which, att);
Packit b099d7
	      temp2 = temp1 - Value(&(att[RIGHT]));
Packit b099d7
	      temp3 = temp2 - size;
Packit b099d7
	      if ((fwidth) && (temp3 < 0)) {
Packit b099d7
		factor = CheckLeftBase(a->w, FALSE);
Packit b099d7
		*fwidth += (Dimension) ((factor * abs(temp3)) + 0.5);
Packit b099d7
		temp1 = Value(&(att[RIGHT])) + size;
Packit b099d7
	      }
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    } else {
Packit b099d7
	      temp1 = Value(ref) - GetFormOffset(fw, which, att);
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    }
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    ref = &c->att[TOP];
Packit b099d7
	    if (att[TOP].type != XmATTACH_NONE) {
Packit b099d7
	      temp1 = Value(ref) - GetFormOffset(fw, which, att);
Packit b099d7
	      temp2 = temp1 - Value((&att[TOP]));
Packit b099d7
	      temp3 = temp2 - size;
Packit b099d7
	      if ((fheight) && (temp3 < 0)) {
Packit b099d7
		factor = CheckBottomBase(a->w, FALSE);
Packit b099d7
		*fheight += (Dimension) ((factor * abs(temp3)) + 0.5);
Packit b099d7
		temp1 = Value((&att[TOP])) + size;
Packit b099d7
	      }
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    } else {
Packit b099d7
	      temp1 = Value(ref) - GetFormOffset(fw, which, att);
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    }
Packit b099d7
	    break;
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
	
Packit b099d7
      case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
	a->percent = 0;
Packit b099d7
	c = GetFormConstraint(a->w);
Packit b099d7
	
Packit b099d7
	switch (which) 
Packit b099d7
	  {
Packit b099d7
	  case RIGHT:
Packit b099d7
	    ref = &c->att[RIGHT];
Packit b099d7
	    AssignValue(a, Value(ref) + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case TOP:
Packit b099d7
	    ref = &c->att[TOP];
Packit b099d7
	    AssignValue(a, Value(ref) + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case LEFT:
Packit b099d7
	    ref = &c->att[LEFT];
Packit b099d7
	    AssignValue(a, Value(ref) - GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    ref = &c->att[BOTTOM];
Packit b099d7
	    AssignValue(a, Value(ref) - GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
      }      
Packit b099d7
  else /* Left to Right environment */
Packit b099d7
    switch (ctype) 
Packit b099d7
      {
Packit b099d7
      case XmATTACH_FORM:
Packit b099d7
	a->w = NULL;
Packit b099d7
	a->percent = 0;
Packit b099d7
	
Packit b099d7
	switch (which) 
Packit b099d7
	  {
Packit b099d7
	  case LEFT:
Packit b099d7
	  case TOP:
Packit b099d7
	    AssignValue(a, GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case RIGHT:
Packit b099d7
	    if (fwidth != NULL) {
Packit b099d7
	      if ((att + LEFT)->type == XmATTACH_NONE) {
Packit b099d7
		temp1 = *fwidth - (GetFormOffset(fw, which, att));
Packit b099d7
		temp2 = temp1 - size;
Packit b099d7
		if (temp2 < 0) {
Packit b099d7
		  *fwidth += abs(temp2);
Packit b099d7
		  AssignValue(a, (temp1 + abs(temp2)));
Packit b099d7
		} else
Packit b099d7
		  AssignValue(a, temp1);
Packit b099d7
	      } else {
Packit b099d7
		temp1 = *fwidth - (GetFormOffset(fw, which, att));
Packit b099d7
		temp2 = Value(att + LEFT);
Packit b099d7
		temp3 = temp1 - temp2 - size;
Packit b099d7
		if (temp3 < 0) {
Packit b099d7
		  *fwidth += abs(temp3);
Packit b099d7
		  AssignValue(a, (*fwidth - size - GetFormOffset(fw, which, att)));
Packit b099d7
		} else
Packit b099d7
		  AssignValue(a, temp1);
Packit b099d7
	      }
Packit b099d7
	    } else
Packit b099d7
	      AssignValue(a, fw->core.width - GetFormOffset(fw,which,att));
Packit b099d7
	    break;
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    if (fheight != NULL) {
Packit b099d7
	      if ((att + TOP)->type == XmATTACH_NONE) {
Packit b099d7
		temp1 = *fheight - GetFormOffset(fw, which, att);
Packit b099d7
		temp2 = temp1 - size;
Packit b099d7
		if (temp2 < 0) {
Packit b099d7
		  *fheight += abs(temp2);
Packit b099d7
		  AssignValue(a, (temp1 + abs(temp2)));
Packit b099d7
		} else
Packit b099d7
		  AssignValue(a, temp1);
Packit b099d7
	      } else {
Packit b099d7
		temp1 = *fheight - GetFormOffset(fw, which, att);
Packit b099d7
		temp2 = Value(att + TOP);
Packit b099d7
		temp3 = temp1 - temp2 - size;
Packit b099d7
		if (temp3 < 0) {
Packit b099d7
		  *fheight += abs(temp3);
Packit b099d7
		  AssignValue(a, (*fheight - size - GetFormOffset(fw, which, att)));
Packit b099d7
		} else
Packit b099d7
		  AssignValue(a, temp1);
Packit b099d7
	      }
Packit b099d7
	    } else
Packit b099d7
	      AssignValue(a, fw->core.height - GetFormOffset(fw,which,att));
Packit b099d7
	    break;
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
	
Packit b099d7
      case XmATTACH_OPPOSITE_FORM:
Packit b099d7
	a->w = NULL;
Packit b099d7
	a->percent = 0;
Packit b099d7
	
Packit b099d7
	switch (which) 
Packit b099d7
	  {
Packit b099d7
	  case LEFT:
Packit b099d7
	    if (fwidth) {
Packit b099d7
	      temp1 = *fwidth + GetFormOffset(fw, which, att);
Packit b099d7
	      if (temp1 < 0) {
Packit b099d7
		*fwidth += abs(temp1);
Packit b099d7
		temp1 = 0;
Packit b099d7
	      }
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    } else
Packit b099d7
	      AssignValue(a, fw->core.width + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case TOP:
Packit b099d7
	    if (fheight) {
Packit b099d7
	      temp1 = *fheight + GetFormOffset(fw, which, att);
Packit b099d7
	      if (temp1 < 0) {
Packit b099d7
		*fheight += abs(temp1);
Packit b099d7
		temp1 = 0;
Packit b099d7
	      }
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    } else
Packit b099d7
	      AssignValue(a, fw->core.height + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case RIGHT:
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    AssignValue(a, -(GetFormOffset(fw, which, att)));
Packit b099d7
	    break;
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
	
Packit b099d7
      case XmATTACH_POSITION:
Packit b099d7
	scale = ((float) a->percent) / fw->form.fraction_base;
Packit b099d7
	a->w = 0;
Packit b099d7
	
Packit b099d7
	switch (which) 
Packit b099d7
	  {
Packit b099d7
	  case LEFT:
Packit b099d7
	    if (fwidth != NULL)
Packit b099d7
	      AssignValue(a, (*fwidth * scale + 0.5) + GetFormOffset(fw, which, att));
Packit b099d7
	    else
Packit b099d7
	      AssignValue(a, (fw->core.width * scale + 0.5) +
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	  case TOP:
Packit b099d7
	    if (fheight != NULL)
Packit b099d7
	      AssignValue(a, (*fheight * scale + 0.5) + 
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	    else
Packit b099d7
	      AssignValue(a, (fw->core.height * scale + 0.5) + 
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	  case RIGHT:
Packit b099d7
	    if (fwidth != NULL)
Packit b099d7
	      if ((att + LEFT)->type != XmATTACH_NONE) {
Packit b099d7
		temp1 = (int) (((*fwidth  * scale) + 0.5) - 
Packit b099d7
			       GetFormOffset(fw, which, att));
Packit b099d7
		temp2 = Value(att + LEFT);
Packit b099d7
		temp3 = temp1 - temp2 - size;
Packit b099d7
		if (temp3 < 0) {
Packit b099d7
		  if (!scale)
Packit b099d7
		    scale = 1.0;
Packit b099d7
Packit b099d7
		  *fwidth += (Dimension) (((1.0 / scale) * abs(temp3)) + 0.5);
Packit b099d7
		}
Packit b099d7
		AssignValue(a, (temp2 + size));
Packit b099d7
	      } else
Packit b099d7
		AssignValue(a, (*fwidth * scale + 0.5) - 
Packit b099d7
			    GetFormOffset(fw, which, att));
Packit b099d7
	    else
Packit b099d7
	      AssignValue(a, (fw->core.width * scale + 0.5) - 
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    if (fheight != NULL)
Packit b099d7
	      if ((att + TOP)->type != XmATTACH_NONE) {
Packit b099d7
		temp1 = (int) (((*fheight  * scale) + 0.5) 
Packit b099d7
			       - GetFormOffset(fw, which, att));
Packit b099d7
		temp2 = Value(att + TOP);
Packit b099d7
		temp3 = temp1 - temp2 - size;
Packit b099d7
		if (temp3 < 0) {
Packit b099d7
		  if (!scale)
Packit b099d7
		    scale = 1.0;
Packit b099d7
		  
Packit b099d7
		  *fheight += (Dimension) (((1.0 / scale) * abs(temp3)) + 0.5);
Packit b099d7
		}
Packit b099d7
		AssignValue(a, (temp2 + size));
Packit b099d7
	      } else
Packit b099d7
		AssignValue(a, (*fheight * scale + 0.5) - 
Packit b099d7
			    GetFormOffset(fw, which, att));
Packit b099d7
	    else
Packit b099d7
	      AssignValue(a, (fw->core.height * scale + 0.5) - 
Packit b099d7
			  GetFormOffset(fw, which, att));
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
	
Packit b099d7
      case XmATTACH_WIDGET:
Packit b099d7
	a->percent = 0;
Packit b099d7
	c = GetFormConstraint(a->w);
Packit b099d7
	
Packit b099d7
	switch (which)
Packit b099d7
	  {
Packit b099d7
	  case LEFT:
Packit b099d7
	    ref = &c->att[RIGHT];
Packit b099d7
	    AssignValue(a, Value(ref) + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case TOP:
Packit b099d7
	    ref = &c->att[BOTTOM];
Packit b099d7
	    AssignValue(a, Value(ref) + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case RIGHT:
Packit b099d7
	    ref = &c->att[LEFT];
Packit b099d7
	    if (att[LEFT].type != XmATTACH_NONE) {
Packit b099d7
	      temp1 = Value(ref) - GetFormOffset(fw, which, att);
Packit b099d7
	      temp2 = temp1 - Value(&(att[LEFT]));
Packit b099d7
	      temp3 = temp2 - size;
Packit b099d7
	      if ((fwidth) && (temp3 < 0)) {
Packit b099d7
		factor = CheckRightBase(a->w, FALSE);
Packit b099d7
		*fwidth += (Dimension) ((factor * abs(temp3)) + 0.5);
Packit b099d7
		temp1 = Value(&(att[LEFT])) + size;
Packit b099d7
	      }
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    } else {
Packit b099d7
	      temp1 = Value(ref) - GetFormOffset(fw, which, att);
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    }
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    ref = &c->att[TOP];
Packit b099d7
	    if (att[TOP].type != XmATTACH_NONE) {
Packit b099d7
	      temp1 = Value(ref) - GetFormOffset(fw, which, att);
Packit b099d7
	      temp2 = temp1 - Value((&att[TOP]));
Packit b099d7
	      temp3 = temp2 - size;
Packit b099d7
	      if ((fheight) && (temp3 < 0)) {
Packit b099d7
		factor = CheckBottomBase(a->w, FALSE);
Packit b099d7
		*fheight += (Dimension) ((factor * abs(temp3)) + 0.5);
Packit b099d7
		temp1 = Value((&att[TOP])) + size;
Packit b099d7
	      }
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    } else {
Packit b099d7
	      temp1 = Value(ref) - GetFormOffset(fw, which, att);
Packit b099d7
	      AssignValue(a, temp1);
Packit b099d7
	    }
Packit b099d7
	    break;
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
	
Packit b099d7
      case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
	a->percent = 0;
Packit b099d7
	c = GetFormConstraint(a->w);
Packit b099d7
	
Packit b099d7
	switch (which) 
Packit b099d7
	  {
Packit b099d7
	  case LEFT:
Packit b099d7
	    ref = &c->att[LEFT];
Packit b099d7
	    AssignValue(a, Value(ref) + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case TOP:
Packit b099d7
	    ref = &c->att[TOP];
Packit b099d7
	    AssignValue(a, Value(ref) + GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case RIGHT:
Packit b099d7
	    ref = &c->att[RIGHT];
Packit b099d7
	    AssignValue(a, Value(ref) - GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	  case BOTTOM:
Packit b099d7
	    ref = &c->att[BOTTOM];
Packit b099d7
	    AssignValue(a, Value(ref) - GetFormOffset(fw, which, att));
Packit b099d7
	    break;
Packit b099d7
	  }
Packit b099d7
	return;
Packit b099d7
      }      
Packit b099d7
  
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ComputeAttachment
Packit b099d7
 *     Note that Left attachment apply to the right side in a 
Packit b099d7
 *     Right-to-Left environment. Slightly confusing, but it is more a
Packit b099d7
 *     matter of switching right and left in the computing.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
ComputeAttachment(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
        Widget w,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int size,
Packit b099d7
        int border_width,	/* unused */
Packit b099d7
#else
Packit b099d7
        Dimension size,
Packit b099d7
        Dimension border_width,	/* unused */
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        int which,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int really,
Packit b099d7
#else
Packit b099d7
        Boolean really,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        Dimension *fwidth,
Packit b099d7
        Dimension *fheight )
Packit b099d7
{
Packit b099d7
   XmFormConstraint c = GetFormConstraint(w);
Packit b099d7
   XmFormAttachment a = &c->att[which];
Packit b099d7
   int temp;
Packit b099d7
Packit b099d7
   if (LayoutIsRtoLM(fw))
Packit b099d7
     switch (which) 
Packit b099d7
       {
Packit b099d7
       case RIGHT:
Packit b099d7
	 temp =  Value(&c->att[LEFT]) - size;
Packit b099d7
	 if ((fwidth != NULL) && (temp < 0))
Packit b099d7
	   {
Packit b099d7
	     *fwidth += abs(temp);
Packit b099d7
	     temp = 0;
Packit b099d7
	   }
Packit b099d7
         AssignValue(a,temp);
Packit b099d7
	 break;
Packit b099d7
	 
Packit b099d7
       case LEFT:
Packit b099d7
	 temp = Value(&c->att[RIGHT]) + size;
Packit b099d7
	 if ((fwidth != NULL) && (temp > 0) && (temp > *fwidth))
Packit b099d7
	   *fwidth += (temp - *fwidth);
Packit b099d7
         AssignValue(a,temp);
Packit b099d7
	 break;
Packit b099d7
	 
Packit b099d7
       case TOP:
Packit b099d7
	 temp = Value(&c->att[BOTTOM]) - size;
Packit b099d7
	 if ((fheight != NULL) && (temp < 0))
Packit b099d7
	   {
Packit b099d7
	     *fheight += abs(temp);
Packit b099d7
	     temp = 0;
Packit b099d7
	   }
Packit b099d7
         AssignValue(a, temp);
Packit b099d7
	 break;
Packit b099d7
	 
Packit b099d7
       case BOTTOM:
Packit b099d7
	 temp = Value(&c->att[TOP]) + size;
Packit b099d7
	 if ((fheight != NULL) && (temp > 0) && (temp > *fheight))
Packit b099d7
	   *fheight += (temp - *fheight);
Packit b099d7
         AssignValue(a, temp);
Packit b099d7
	 break;
Packit b099d7
       }
Packit b099d7
   else /* Left to right */
Packit b099d7
     switch (which) 
Packit b099d7
       {
Packit b099d7
       case LEFT:
Packit b099d7
	 temp =  Value(&c->att[RIGHT]) - size;
Packit b099d7
	 if ((fwidth != NULL) && (temp < 0))
Packit b099d7
	   {
Packit b099d7
	     *fwidth += abs(temp);
Packit b099d7
	     temp = 0;
Packit b099d7
	   }
Packit b099d7
	 AssignValue(a,temp);
Packit b099d7
	 break;
Packit b099d7
	 
Packit b099d7
       case RIGHT:
Packit b099d7
	 temp = Value(&c->att[LEFT]) + size;
Packit b099d7
	 if ((fwidth != NULL) && (temp > 0) && (temp > *fwidth))
Packit b099d7
	   *fwidth += (temp - *fwidth);
Packit b099d7
	 AssignValue(a,temp);
Packit b099d7
	 break;
Packit b099d7
	 
Packit b099d7
       case TOP:
Packit b099d7
	 temp = Value(&c->att[BOTTOM]) - size;
Packit b099d7
	 if ((fheight != NULL) && (temp < 0))
Packit b099d7
	   {
Packit b099d7
	     *fheight += abs(temp);
Packit b099d7
	     temp = 0;
Packit b099d7
	   }
Packit b099d7
	 AssignValue(a, temp);
Packit b099d7
	 break;
Packit b099d7
	 
Packit b099d7
       case BOTTOM:
Packit b099d7
	 temp = Value(&c->att[TOP]) + size;
Packit b099d7
	 if ((fheight != NULL) && (temp > 0) && (temp > *fheight))
Packit b099d7
	   *fheight += (temp - *fheight);
Packit b099d7
	 AssignValue(a, temp);
Packit b099d7
	 break;
Packit b099d7
       }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GetFormOffset
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static int 
Packit b099d7
GetFormOffset(
Packit b099d7
        XmFormWidget fw,
Packit b099d7
        int which,
Packit b099d7
        XmFormAttachment att )
Packit b099d7
{
Packit b099d7
    int o;
Packit b099d7
    
Packit b099d7
    o = att[which].offset;
Packit b099d7
    
Packit b099d7
    if (o == XmINVALID_DIMENSION) {
Packit b099d7
	switch (att[which].type) {
Packit b099d7
	case XmATTACH_NONE:
Packit b099d7
	case XmATTACH_SELF:
Packit b099d7
	case XmATTACH_POSITION:
Packit b099d7
	    o = 0;
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	case XmATTACH_FORM:
Packit b099d7
	case XmATTACH_OPPOSITE_FORM:
Packit b099d7
	    if ((which == LEFT) || (which == RIGHT))
Packit b099d7
		{
Packit b099d7
		    if (fw->bulletin_board.margin_width
Packit b099d7
			== XmINVALID_DIMENSION)
Packit b099d7
			o = fw->form.horizontal_spacing;
Packit b099d7
		    else
Packit b099d7
			o = fw->bulletin_board.margin_width;
Packit b099d7
		}
Packit b099d7
	    else
Packit b099d7
		{
Packit b099d7
		    if (fw->bulletin_board.margin_height 
Packit b099d7
			== XmINVALID_DIMENSION)
Packit b099d7
			o = fw->form.vertical_spacing;
Packit b099d7
		    else
Packit b099d7
			o = fw->bulletin_board.margin_height;
Packit b099d7
		}
Packit b099d7
	    break;
Packit b099d7
	    
Packit b099d7
	case XmATTACH_WIDGET:
Packit b099d7
	case XmATTACH_OPPOSITE_WIDGET:
Packit b099d7
	    if ((which == LEFT) || (which == RIGHT))
Packit b099d7
		o = fw->form.horizontal_spacing;
Packit b099d7
	    else
Packit b099d7
		o = fw->form.vertical_spacing;
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    return o;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *		Application Accessible External Functions
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  XmCreateForm
Packit b099d7
 *	Create an instance of a form and return the widget id.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Widget 
Packit b099d7
XmCreateForm(
Packit b099d7
        Widget parent,
Packit b099d7
        char *name,
Packit b099d7
        ArgList arglist,
Packit b099d7
        Cardinal argcount )
Packit b099d7
{
Packit b099d7
   return(XtCreateWidget(name, xmFormWidgetClass, parent, arglist, argcount));
Packit b099d7
}
Packit b099d7
Packit b099d7
Widget 
Packit b099d7
XmVaCreateForm(
Packit b099d7
        Widget parent,
Packit b099d7
        char *name,
Packit b099d7
        ...)
Packit b099d7
{
Packit b099d7
    register Widget w;
Packit b099d7
    va_list var;
Packit b099d7
    int count;
Packit b099d7
    
Packit b099d7
    Va_start(var,name);
Packit b099d7
    count = XmeCountVaListSimple(var);
Packit b099d7
    va_end(var);
Packit b099d7
Packit b099d7
    
Packit b099d7
    Va_start(var, name);
Packit b099d7
    w = XmeVLCreateWidget(name, 
Packit b099d7
                         xmFormWidgetClass,
Packit b099d7
                         parent, False, 
Packit b099d7
                         var, count);
Packit b099d7
    va_end(var);   
Packit b099d7
    return w;
Packit b099d7
}
Packit b099d7
Packit b099d7
Widget
Packit b099d7
XmVaCreateManagedForm(
Packit b099d7
        Widget parent,
Packit b099d7
        char *name,
Packit b099d7
        ...)
Packit b099d7
{
Packit b099d7
    Widget w = NULL;
Packit b099d7
    va_list var;
Packit b099d7
    int count;
Packit b099d7
    
Packit b099d7
    Va_start(var, name);
Packit b099d7
    count = XmeCountVaListSimple(var);
Packit b099d7
    va_end(var);
Packit b099d7
    
Packit b099d7
    Va_start(var, name);
Packit b099d7
    w = XmeVLCreateWidget(name, 
Packit b099d7
                         xmFormWidgetClass,
Packit b099d7
                         parent, True, 
Packit b099d7
                         var, count);
Packit b099d7
    va_end(var);   
Packit b099d7
    return w;
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  XmCreateFormDialog
Packit b099d7
 *	Create an instance of a form dialog and return the widget id.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Widget 
Packit b099d7
XmCreateFormDialog(
Packit b099d7
        Widget parent,
Packit b099d7
        char *name,
Packit b099d7
        ArgList arglist,
Packit b099d7
        Cardinal argcount )
Packit b099d7
{
Packit b099d7
   return XmeCreateClassDialog (xmFormWidgetClass,
Packit b099d7
				parent, name, arglist, argcount) ;
Packit b099d7
}