Blame lib/Xm/GeoUtils.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[] = "$XConsortium: GeoUtils.c /main/13 1996/08/15 17:11:25 pascale $"
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>
Packit b099d7
#endif
Packit b099d7
#include "XmI.h"
Packit b099d7
#include "GeoUtilsI.h"
Packit b099d7
#include "GMUtilsI.h"
Packit b099d7
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static XtGeometryResult QueryAnyPolicy( 
Packit b099d7
                        XmGeoMatrix geoSpec,
Packit b099d7
                        XtWidgetGeometry *parentRequestRtn) ;
Packit b099d7
static XtGeometryResult QueryGrowPolicy( 
Packit b099d7
                        XmGeoMatrix geoSpec,
Packit b099d7
                        XtWidgetGeometry *parentRequestRtn) ;
Packit b099d7
static XtGeometryResult QueryNonePolicy( 
Packit b099d7
                        XmGeoMatrix geoSpec,
Packit b099d7
                        XtWidgetGeometry *parentRequestRtn) ;
Packit b099d7
static Dimension _XmGeoStretchVertical( 
Packit b099d7
                        XmGeoMatrix geoSpec,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int actualH,
Packit b099d7
                        int desiredH) ;
Packit b099d7
#else
Packit b099d7
                        Dimension actualH,
Packit b099d7
                        Dimension desiredH) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static Dimension _XmGeoFillVertical( 
Packit b099d7
                        XmGeoMatrix geoSpec,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int actualH,
Packit b099d7
                        int desiredH) ;
Packit b099d7
#else
Packit b099d7
                        Dimension actualH,
Packit b099d7
                        Dimension desiredH) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static void _XmGeoCalcFill( 
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int fillSpace,
Packit b099d7
                        int margin,
Packit b099d7
#else
Packit b099d7
                        Dimension fillSpace,
Packit b099d7
                        Dimension margin,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        unsigned int numBoxes,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int endSpec,
Packit b099d7
                        int betweenSpec,
Packit b099d7
#else
Packit b099d7
                        Dimension endSpec,
Packit b099d7
                        Dimension betweenSpec,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        Dimension *pEndSpace,
Packit b099d7
                        Dimension *pBetweenSpace) ;
Packit b099d7
static int boxWidthCompare( 
Packit b099d7
                        XmConst void *boxPtr1,
Packit b099d7
                        XmConst void *boxPtr2) ;
Packit b099d7
static void FitBoxesAveraging( 
Packit b099d7
                        XmKidGeometry rowPtr,
Packit b099d7
                        unsigned int numBoxes,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int boxWidth,
Packit b099d7
#else
Packit b099d7
                        Dimension boxWidth,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        int amtOffset) ;
Packit b099d7
static void FitBoxesProportional( 
Packit b099d7
                        XmKidGeometry rowPtr,
Packit b099d7
                        unsigned int numBoxes,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int boxWidth,
Packit b099d7
#else
Packit b099d7
                        Dimension boxWidth,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        int amtOffset) ;
Packit b099d7
static void SegmentFill( 
Packit b099d7
                        XmKidGeometry rowBoxes,
Packit b099d7
                        unsigned int numBoxes,
Packit b099d7
                        XmGeoRowLayout layoutPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int x,
Packit b099d7
                        int width,
Packit b099d7
                        int marginW,
Packit b099d7
                        int endX,
Packit b099d7
                        int maxX,
Packit b099d7
                        int endSpace,
Packit b099d7
                        int betweenSpace) ;
Packit b099d7
#else
Packit b099d7
                        Position x,
Packit b099d7
                        Dimension width,
Packit b099d7
                        Dimension marginW,
Packit b099d7
                        Position endX,
Packit b099d7
                        Position maxX,
Packit b099d7
                        Dimension endSpace,
Packit b099d7
                        Dimension betweenSpace) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static Position _XmGeoLayoutWrap( 
Packit b099d7
                        XmKidGeometry rowPtr,
Packit b099d7
                        XmGeoRowLayout layoutPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int x,
Packit b099d7
                        int y,
Packit b099d7
                        int endSpace,
Packit b099d7
                        int betweenSpace,
Packit b099d7
                        int maxX,
Packit b099d7
                        int width,
Packit b099d7
                        int marginW) ;
Packit b099d7
#else
Packit b099d7
                        Position x,
Packit b099d7
                        Position y,
Packit b099d7
                        Dimension endSpace,
Packit b099d7
                        Dimension betweenSpace,
Packit b099d7
                        Position maxX,
Packit b099d7
                        Dimension width,
Packit b099d7
                        Dimension marginW) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static Position _XmGeoLayoutSimple( 
Packit b099d7
                        XmKidGeometry rowPtr,
Packit b099d7
                        XmGeoRowLayout layoutPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int x,
Packit b099d7
                        int y,
Packit b099d7
                        int maxX,
Packit b099d7
                        int endSpace,
Packit b099d7
                        int betweenSpace) ;
Packit b099d7
#else
Packit b099d7
                        Position x,
Packit b099d7
                        Position y,
Packit b099d7
                        Position maxX,
Packit b099d7
                        Dimension endSpace,
Packit b099d7
                        Dimension betweenSpace) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static Position _XmGeoArrangeList( 
Packit b099d7
                        XmKidGeometry rowBoxes,
Packit b099d7
                        XmGeoRowLayout layoutPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int x,
Packit b099d7
                        int y,
Packit b099d7
                        int width,
Packit b099d7
                        int marginW,
Packit b099d7
                        int marginH) ;
Packit b099d7
#else
Packit b099d7
                        Position x,
Packit b099d7
                        Position y,
Packit b099d7
                        Dimension width,
Packit b099d7
                        Dimension marginW,
Packit b099d7
                        Dimension marginH) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
/****************************************************************/
Packit b099d7
Packit b099d7
Packit b099d7
#ifdef DEBUG_GEOUTILS
Packit b099d7
Packit b099d7
void PrintBox( char * hdr, XmKidGeometry box) ;
Packit b099d7
void PrintList( char * hdr, XmKidGeometry listPtr) ;
Packit b099d7
void PrintMatrix( char * hdr, XmGeoMatrix spec) ;
Packit b099d7
Packit b099d7
#endif /* DEBUG_GEOUTILS */
Packit b099d7
Packit b099d7
   
Packit b099d7
/****************************************************************/
Packit b099d7
XtGeometryResult 
Packit b099d7
_XmHandleQueryGeometry(
Packit b099d7
        Widget widget,
Packit b099d7
        XtWidgetGeometry *intended,
Packit b099d7
        XtWidgetGeometry *desired,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        unsigned int resize_policy,
Packit b099d7
#else
Packit b099d7
        unsigned char resize_policy,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        XmGeoCreateProc createMatrix)
Packit b099d7
{
Packit b099d7
    Dimension       width = 0 ;
Packit b099d7
    Dimension       height = 0 ;
Packit b099d7
    XmGeoMatrix     geoSpec ;
Packit b099d7
Packit b099d7
    /* first determine what is the desired size, using the resize_policy. */
Packit b099d7
    if (resize_policy == XmRESIZE_NONE) {
Packit b099d7
	desired->width = XtWidth(widget) ;
Packit b099d7
	desired->height = XtHeight(widget) ;
Packit b099d7
    } else {
Packit b099d7
	if (GMode( intended) & CWWidth) width = intended->width;
Packit b099d7
	if (GMode( intended) & CWHeight) height = intended->height;
Packit b099d7
Packit b099d7
	geoSpec = (*createMatrix)( widget, NULL, NULL) ;
Packit b099d7
	_XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;
Packit b099d7
	_XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, 
Packit b099d7
			   &width, &height) ;
Packit b099d7
	_XmGeoMatrixFree( geoSpec) ;
Packit b099d7
	if ((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
XtGeometryResult 
Packit b099d7
_XmHandleGeometryManager(
Packit b099d7
        Widget wid,
Packit b099d7
        Widget instigator,
Packit b099d7
        XtWidgetGeometry *desired,
Packit b099d7
        XtWidgetGeometry *allowed,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        unsigned int policy,
Packit b099d7
#else
Packit b099d7
        unsigned char policy,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        XmGeoMatrix *cachePtr,
Packit b099d7
        XmGeoCreateProc createMatrix)
Packit b099d7
{
Packit b099d7
            XmGeoMatrix     geoSpec ;
Packit b099d7
            XtWidgetGeometry parentRequest ;
Packit b099d7
            XtGeometryResult queryResult ;
Packit b099d7
            XtGeometryResult result ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    if(    !cachePtr    )
Packit b099d7
    {   
Packit b099d7
        /* Almost replies are not entertained unless caching is supported.
Packit b099d7
        */
Packit b099d7
        allowed = NULL ; 
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   geoSpec = *cachePtr ;
Packit b099d7
Packit b099d7
        if(    geoSpec    )
Packit b099d7
        {   
Packit b099d7
            if(    (geoSpec->composite == wid)
Packit b099d7
                && (geoSpec->instigator == instigator)
Packit b099d7
                && _XmGeometryEqual( instigator, geoSpec->in_layout, desired)    )
Packit b099d7
            {   
Packit b099d7
                /* This is a successive geometry request which matches the
Packit b099d7
                *   cached geometry record.
Packit b099d7
                */
Packit b099d7
                if(    GMode( desired) & XtCWQueryOnly    )
Packit b099d7
                {   return( XtGeometryYes) ;
Packit b099d7
                    }
Packit b099d7
                else
Packit b099d7
                {   /* If we get here, we should have already verified that
Packit b099d7
                    *   the current layout is acceptable to the parent, so 
Packit b099d7
                    *   we will ignore the result of the request.
Packit b099d7
                    */
Packit b099d7
                    if(    geoSpec->parent_request.request_mode    )
Packit b099d7
                    {   
Packit b099d7
                        geoSpec->parent_request.request_mode &= ~XtCWQueryOnly ;
Packit b099d7
    
Packit b099d7
                        XtMakeGeometryRequest( wid, &geoSpec->parent_request,
Packit b099d7
                                                                            NULL) ;
Packit b099d7
                        } 
Packit b099d7
                    _XmGeoMatrixSet( geoSpec) ;
Packit b099d7
Packit b099d7
                    _XmGeoMatrixFree( geoSpec) ;
Packit b099d7
                    *cachePtr = NULL ;
Packit b099d7
Packit b099d7
                    return( XtGeometryYes) ;
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   /* Cached geometry is different than current request, so clear
Packit b099d7
                *   existing cache record and allow request to be processed.
Packit b099d7
                */
Packit b099d7
                _XmGeoMatrixFree( geoSpec) ;
Packit b099d7
                *cachePtr = NULL ;
Packit b099d7
                } 
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
    /*	Get box list and arrange boxes according to policy.
Packit b099d7
    */
Packit b099d7
    geoSpec = (*createMatrix)( wid, instigator, desired) ;
Packit b099d7
Packit b099d7
    if(    geoSpec->no_geo_request
Packit b099d7
        && (*geoSpec->no_geo_request)( geoSpec)    )
Packit b099d7
    {   
Packit b099d7
        _XmGeoMatrixFree( geoSpec) ;
Packit b099d7
        return( XtGeometryNo) ;
Packit b099d7
        } 
Packit b099d7
Packit b099d7
    /* The following Query routines only respond with XtGeometryYes or
Packit b099d7
    *    XtGeometryNo.  All requests made to the parent are strictly
Packit b099d7
    *    queries.
Packit b099d7
    *  A return value (from these routines!) of XtGeometryNo means that
Packit b099d7
    *    the composite widget would need to change size in order to
Packit b099d7
    *    entertain the child's request, and that the parent said "no"
Packit b099d7
    *    to the request.  A XtGeometryNo leaves no alternatives to the
Packit b099d7
    *    child's geometry request.
Packit b099d7
    *  A return value of XtGeometryYes means that either the composite
Packit b099d7
    *    widget does not need to change size to entertain the child's
Packit b099d7
    *    request, or that negotiation with the parent yielded a viable
Packit b099d7
    *    geometry layout.  If the composite widget does not need to 
Packit b099d7
    *    change size, then request_mode field of the returned geometry
Packit b099d7
    *    structure will contain zero.  Otherwise, the returned geometry
Packit b099d7
    *    structure will contain a request which is guaranteed to be 
Packit b099d7
    *    accepted by a subsequent request to the parent.
Packit b099d7
    *  A return value of XtGeometryYes always loads the return geometry
Packit b099d7
    *    structure with valid data.
Packit b099d7
    */
Packit b099d7
    switch(    policy    )
Packit b099d7
    {   
Packit b099d7
        case XmRESIZE_GROW:
Packit b099d7
        {   queryResult = QueryGrowPolicy( geoSpec, &parentRequest) ;
Packit b099d7
	    break;
Packit b099d7
            } 
Packit b099d7
	case XmRESIZE_NONE:
Packit b099d7
        {   queryResult = QueryNonePolicy( geoSpec, &parentRequest) ;
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
	case XmRESIZE_ANY:
Packit b099d7
        default:
Packit b099d7
        {   queryResult = QueryAnyPolicy( geoSpec, &parentRequest) ;
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    result = XtGeometryNo ; /* Setup default response. */
Packit b099d7
Packit b099d7
    /* If parent replies XtGeometryYes, then build appropriate reply for
Packit b099d7
    *   instigator.  Otherwise, it is not reasonable to try to find a child
Packit b099d7
    *   size which would result in an acceptable overall size, so just say no.
Packit b099d7
    */
Packit b099d7
    if(    queryResult == XtGeometryYes    )
Packit b099d7
    {   
Packit b099d7
        if(    _XmGeoReplyYes( instigator, desired, geoSpec->in_layout)    )
Packit b099d7
        {   
Packit b099d7
            /* Reply Yes since desired geometry is same as the
Packit b099d7
            *   instigator geometry in this layout.
Packit b099d7
            */
Packit b099d7
            if(    GMode( desired) & XtCWQueryOnly    )
Packit b099d7
            {   
Packit b099d7
                geoSpec->parent_request = parentRequest ;
Packit b099d7
                result = XtGeometryYes ;
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   /* Don't need almost reply and this is not a query, so do it!
Packit b099d7
                */
Packit b099d7
                if(    parentRequest.request_mode    )
Packit b099d7
                {   
Packit b099d7
                    /* The geometry request in parentRequest has already
Packit b099d7
                    *   been tested by a query to the parent, so should
Packit b099d7
                    *   always be honored.
Packit b099d7
                    */
Packit b099d7
                    parentRequest.request_mode &= ~XtCWQueryOnly ;
Packit b099d7
Packit b099d7
                    XtMakeGeometryRequest( wid, &parentRequest, NULL) ;
Packit b099d7
                    } 
Packit b099d7
                _XmGeoMatrixSet( geoSpec) ;
Packit b099d7
Packit b099d7
                result = XtGeometryYes ;
Packit b099d7
                }
Packit b099d7
            } 
Packit b099d7
        else 
Packit b099d7
        {   /* If allowed and not an exception then reply Almost, since 
Packit b099d7
            *   desired geometry is different than geometry in this layout.
Packit b099d7
            */
Packit b099d7
            if(    allowed
Packit b099d7
                && (    !geoSpec->almost_except
Packit b099d7
                     || !(*(geoSpec->almost_except))(geoSpec))    )
Packit b099d7
            {   
Packit b099d7
                geoSpec->parent_request = parentRequest ;
Packit b099d7
                result = XtGeometryAlmost ;
Packit b099d7
                }
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
    switch(    result    )
Packit b099d7
    {   
Packit b099d7
        case XtGeometryAlmost:
Packit b099d7
        {   
Packit b099d7
            /* Cache "almost" replies.  Variables cachePtr and allowed are
Packit b099d7
            *   guaranteed to be non-null since almost replies are prevented
Packit b099d7
            *   if either is null.
Packit b099d7
            */
Packit b099d7
            if(geoSpec->in_layout) {
Packit b099d7
		*cachePtr = geoSpec ;
Packit b099d7
		*allowed = *(geoSpec->in_layout) ;
Packit b099d7
            } else /* For fixing OSF CR 5956 */ {
Packit b099d7
		allowed = NULL ;
Packit b099d7
		*cachePtr = NULL ;
Packit b099d7
		result = XtGeometryNo ;
Packit b099d7
	    }
Packit b099d7
            break ;
Packit b099d7
	} 
Packit b099d7
        case XtGeometryYes:
Packit b099d7
        {   
Packit b099d7
            /* This must be a query-only request, or the response would
Packit b099d7
            *   be XtGeometryYes.  Cache this reply if caching is
Packit b099d7
            *   supported.  Otherwise, drop through and free geoSpec.
Packit b099d7
            */
Packit b099d7
            if(    cachePtr    )
Packit b099d7
            {   *cachePtr = geoSpec ;
Packit b099d7
                break ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        default:
Packit b099d7
        {   _XmGeoMatrixFree( geoSpec) ;
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return( result) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * Handle geometry request for XmRESIZE_ANY resize policy.
Packit b099d7
 * Accept request allowed by parent.
Packit b099d7
 * Reject request to change both width and height if both
Packit b099d7
 *   are disallowed by parent, but return almost if one is
Packit b099d7
 *   allowed.
Packit b099d7
 ****************/
Packit b099d7
static XtGeometryResult 
Packit b099d7
QueryAnyPolicy(
Packit b099d7
        XmGeoMatrix geoSpec,
Packit b099d7
        XtWidgetGeometry *parentRequestRtn )
Packit b099d7
{
Packit b099d7
            Widget          wid ;
Packit b099d7
            Dimension       layoutW ;
Packit b099d7
            Dimension       layoutH ;
Packit b099d7
            XtWidgetGeometry parentResponse ;
Packit b099d7
            XtGeometryResult queryResult ;
Packit b099d7
            Dimension       almostW ;
Packit b099d7
            Dimension       almostH ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    wid = geoSpec->composite ;
Packit b099d7
Packit b099d7
    _XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;
Packit b099d7
Packit b099d7
    layoutW = 0 ;
Packit b099d7
    layoutH = 0 ;
Packit b099d7
    _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, &layoutW,
Packit b099d7
                                                                    &layoutH) ;
Packit b099d7
    /*	Load request.
Packit b099d7
    */
Packit b099d7
    parentRequestRtn->request_mode = CWWidth | CWHeight ;
Packit b099d7
    parentRequestRtn->width = layoutW ;
Packit b099d7
    parentRequestRtn->height = layoutH ;
Packit b099d7
Packit b099d7
    /*	Query parent only if necessary.
Packit b099d7
    */
Packit b099d7
    if(    (layoutW == XtWidth( wid))
Packit b099d7
        && (layoutH == XtHeight( wid))    )
Packit b099d7
    {   
Packit b099d7
        parentRequestRtn->request_mode = 0 ;
Packit b099d7
        queryResult = XtGeometryYes ;
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   parentRequestRtn->request_mode |= XtCWQueryOnly ;
Packit b099d7
Packit b099d7
        queryResult = XtMakeGeometryRequest( wid, parentRequestRtn,
Packit b099d7
                                                             &parentResponse) ;
Packit b099d7
        if(    queryResult == XtGeometryAlmost    )
Packit b099d7
        {   
Packit b099d7
            if(    (parentResponse.request_mode & (CWWidth | CWHeight))
Packit b099d7
                                                   != (CWWidth | CWHeight)    )
Packit b099d7
            {   queryResult = XtGeometryNo ;
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   /* The protocol guarantees an XtGeometryYes reply for
Packit b099d7
                *   for an immediately subsequent request which is 
Packit b099d7
                *   identical to the XtGeometryAlmost reply.
Packit b099d7
                */
Packit b099d7
                *parentRequestRtn = parentResponse ;
Packit b099d7
                queryResult = XtGeometryYes ;
Packit b099d7
Packit b099d7
                almostW = parentResponse.width ;
Packit b099d7
                almostH = parentResponse.height ;
Packit b099d7
Packit b099d7
                if(    (almostW != layoutW)  ||  (almostH != layoutH)    )
Packit b099d7
                {   
Packit b099d7
                    /* Response to geometry request was different than 
Packit b099d7
                    *   requested geometry in fields that we care about. 
Packit b099d7
                    *   So, try a new arrangement with the area being 
Packit b099d7
                    *   offered by the parent.
Packit b099d7
                    */
Packit b099d7
                    _XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;
Packit b099d7
                    layoutW = almostW ;
Packit b099d7
                    layoutH = almostH ;
Packit b099d7
                    _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0,
Packit b099d7
                                                          &layoutW, &layoutH) ;
Packit b099d7
                    if(    (almostW != layoutW)  ||  (almostH != layoutH)    )
Packit b099d7
                    {   
Packit b099d7
                        /* The children cannot be laid-out in the area offered
Packit b099d7
                        *   by the parent, so parent result is No.
Packit b099d7
                        */
Packit b099d7
                        queryResult = XtGeometryNo ;
Packit b099d7
                        } 
Packit b099d7
                    } 
Packit b099d7
                }
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
    return( queryResult) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * Handle geometry request for XmRESIZE_GROW resize policy.
Packit b099d7
 * Accept request which would increase or maintain current size.
Packit b099d7
 * Reject request which would decrease both preferred width
Packit b099d7
 *   and preferred height, but return almost if only one
Packit b099d7
 *   would decrease.
Packit b099d7
 ****************/
Packit b099d7
static XtGeometryResult 
Packit b099d7
QueryGrowPolicy(
Packit b099d7
        XmGeoMatrix geoSpec,
Packit b099d7
        XtWidgetGeometry *parentRequestRtn )
Packit b099d7
{
Packit b099d7
            Widget          wid ;
Packit b099d7
            Dimension       layoutW ;
Packit b099d7
            Dimension       layoutH ;
Packit b099d7
            XtWidgetGeometry parentResponse ;
Packit b099d7
            XtGeometryResult queryResult ;
Packit b099d7
            Dimension       almostW ;
Packit b099d7
            Dimension       almostH ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    wid = geoSpec->composite ;
Packit b099d7
    
Packit b099d7
    _XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;
Packit b099d7
Packit b099d7
    if(    geoSpec->instig_request.request_mode & CWWidth    )
Packit b099d7
    {   layoutW = 0 ;               /* Let the layout routine choose a width.*/
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   layoutW = XtWidth( wid) ;   /* All changes will be reflected in      */
Packit b099d7
        }                           /*   vertical dimension.                 */
Packit b099d7
    layoutH = XtHeight( wid) ;  /* Layout routine will grow vert., if needed.*/
Packit b099d7
Packit b099d7
    _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, &layoutW,
Packit b099d7
                                                                    &layoutH) ;
Packit b099d7
    if(    layoutW < XtWidth( wid)    )
Packit b099d7
    {   
Packit b099d7
        /* Try again, this time passing the width to _XmGeoArrangeBoxes.
Packit b099d7
        */
Packit b099d7
        _XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;
Packit b099d7
Packit b099d7
        layoutW = XtWidth( wid) ;
Packit b099d7
        layoutH = XtHeight( wid) ;
Packit b099d7
        _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, &layoutW,
Packit b099d7
                                                                    &layoutH) ;
Packit b099d7
        } 
Packit b099d7
    /*	Load request.
Packit b099d7
    */
Packit b099d7
    parentRequestRtn->request_mode = CWWidth | CWHeight ;
Packit b099d7
    parentRequestRtn->width = layoutW ;
Packit b099d7
    parentRequestRtn->height = layoutH ;
Packit b099d7
Packit b099d7
    /*	Query parent only if necessary.
Packit b099d7
    */
Packit b099d7
    if(    (layoutW == XtWidth( wid))
Packit b099d7
        && (layoutH == XtHeight( wid))    )
Packit b099d7
    {   
Packit b099d7
        parentRequestRtn->request_mode = 0 ;
Packit b099d7
        queryResult = XtGeometryYes ;
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   parentRequestRtn->request_mode |= XtCWQueryOnly ;
Packit b099d7
Packit b099d7
        queryResult = XtMakeGeometryRequest( wid, parentRequestRtn,
Packit b099d7
                                                             &parentResponse) ;
Packit b099d7
        if(    queryResult == XtGeometryAlmost    )
Packit b099d7
        {   
Packit b099d7
            if(    (parentResponse.request_mode & (CWWidth | CWHeight))
Packit b099d7
                                                   != (CWWidth | CWHeight)    )
Packit b099d7
            {   queryResult = XtGeometryNo ;
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   /* The protocol guarantees an XtGeometryYes reply for
Packit b099d7
                *   for an immediately subsequent request which is 
Packit b099d7
                *   identical to the XtGeometryAlmost reply.
Packit b099d7
                */
Packit b099d7
                *parentRequestRtn = parentResponse ;
Packit b099d7
                queryResult = XtGeometryYes ;
Packit b099d7
Packit b099d7
                almostW = parentResponse.width ;
Packit b099d7
                almostH = parentResponse.height ;
Packit b099d7
Packit b099d7
                if(    (almostW < XtWidth( wid))
Packit b099d7
                    || (almostH < XtHeight( wid))    )
Packit b099d7
                {   
Packit b099d7
                    queryResult = XtGeometryNo ;
Packit b099d7
                    } 
Packit b099d7
                else
Packit b099d7
                {   if(    (almostW != layoutW)  ||  (almostH != layoutH)    )
Packit b099d7
                    {   
Packit b099d7
                        /* Response to geometry request was different than 
Packit b099d7
                        *   requested geometry in fields that we care about.
Packit b099d7
                        *   So, try a new arrangement with the area being 
Packit b099d7
                        *   offered by the parent.
Packit b099d7
                        */
Packit b099d7
                        _XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;
Packit b099d7
                        layoutW = almostW ;
Packit b099d7
                        layoutH = almostH ;
Packit b099d7
                        _XmGeoArrangeBoxes( geoSpec, (Position) 0,
Packit b099d7
                                            (Position) 0, &layoutW, &layoutH) ;
Packit b099d7
                        if(    (almostW != layoutW)  ||  (almostH != layoutH) )
Packit b099d7
                        {   
Packit b099d7
                            /* The children cannot be laid-out in the area
Packit b099d7
                            *   offered by the parent, so parent result is No.
Packit b099d7
                            */
Packit b099d7
                            queryResult = XtGeometryNo ;
Packit b099d7
                            } 
Packit b099d7
                        } 
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return( queryResult) ;
Packit b099d7
    }
Packit b099d7
/****************************************************************
Packit b099d7
 * Handle geometry request for XmRESIZE_NONE resize policy.
Packit b099d7
 * Accept request which would not change preferred size and
Packit b099d7
 *   allowed by parent.
Packit b099d7
 * Reject request which would change both preferred width
Packit b099d7
 *   and preferred height, but return almost if only one
Packit b099d7
 *   would change and parent allows the other.
Packit b099d7
 ****************/
Packit b099d7
static XtGeometryResult 
Packit b099d7
QueryNonePolicy(
Packit b099d7
        XmGeoMatrix geoSpec,
Packit b099d7
        XtWidgetGeometry *parentRequestRtn )
Packit b099d7
{
Packit b099d7
            Widget          wid ;
Packit b099d7
            Dimension       layoutW ;
Packit b099d7
            Dimension       layoutH ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    wid = geoSpec->composite ;
Packit b099d7
Packit b099d7
    _XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;
Packit b099d7
Packit b099d7
    layoutW = XtWidth( wid) ;
Packit b099d7
    layoutH = XtHeight( wid) ;
Packit b099d7
    _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0,
Packit b099d7
                                                          &layoutW, &layoutH) ;
Packit b099d7
    parentRequestRtn->request_mode = 0 ;
Packit b099d7
Packit b099d7
    if(    (layoutW != XtWidth( wid))  ||  (layoutH != XtHeight( wid))    )
Packit b099d7
    {   return( XtGeometryNo) ;
Packit b099d7
        }
Packit b099d7
Packit b099d7
    return( XtGeometryYes) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************/
Packit b099d7
void 
Packit b099d7
_XmHandleSizeUpdate(
Packit b099d7
        Widget wid,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        unsigned int policy,
Packit b099d7
#else
Packit b099d7
        unsigned char policy,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        XmGeoCreateProc createMatrix)
Packit b099d7
{
Packit b099d7
            XmGeoMatrix     geoSpec ;
Packit b099d7
            Dimension       w ;
Packit b099d7
            Dimension       h ;
Packit b099d7
            Dimension       r_w ;
Packit b099d7
            Dimension       r_h ;
Packit b099d7
            XtGeometryResult parentResult = XtGeometryNo ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    geoSpec = (*createMatrix)( wid, NULL, NULL) ;
Packit b099d7
Packit b099d7
    _XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;
Packit b099d7
Packit b099d7
    switch(    policy    )
Packit b099d7
    {   
Packit b099d7
        case XmRESIZE_NONE:
Packit b099d7
        {   
Packit b099d7
            w = XtWidth( wid) ;
Packit b099d7
            h = XtHeight( wid) ;
Packit b099d7
            _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, &w, &h) ;
Packit b099d7
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        case XmRESIZE_GROW:
Packit b099d7
        {   
Packit b099d7
            w = 0 ;
Packit b099d7
            h = XtHeight( wid) ;
Packit b099d7
            _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, &w, &h) ;
Packit b099d7
Packit b099d7
            if(    w < XtWidth( wid)    )
Packit b099d7
            {   w = XtWidth( wid) ;
Packit b099d7
                h = XtHeight( wid) ;
Packit b099d7
                _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0,
Packit b099d7
                                                                      &w, &h) ;
Packit b099d7
                }
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        case XmRESIZE_ANY:
Packit b099d7
        default:
Packit b099d7
        {   
Packit b099d7
            w = 0 ;
Packit b099d7
            h = 0 ;
Packit b099d7
            _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, &w, &h) ;
Packit b099d7
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
Packit b099d7
    if(    ((w == XtWidth( wid))  &&  (h == XtHeight( wid)))    )
Packit b099d7
    {   parentResult = XtGeometryYes ;
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   if(    policy != XmRESIZE_NONE    )
Packit b099d7
        {   
Packit b099d7
            parentResult = XtMakeResizeRequest( wid, w, h, &r_w, &r_h) ;
Packit b099d7
Packit b099d7
            if(    parentResult == XtGeometryAlmost    )
Packit b099d7
            {   
Packit b099d7
                if(    (policy == XmRESIZE_GROW)
Packit b099d7
                    && (   (r_w < XtWidth( wid))
Packit b099d7
                        || (r_h < XtHeight( wid)))    )
Packit b099d7
                {   
Packit b099d7
                    parentResult = XtGeometryNo ;
Packit b099d7
                    } 
Packit b099d7
                else
Packit b099d7
                {   w = r_w ;
Packit b099d7
                    h = r_h ;
Packit b099d7
                    _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0,
Packit b099d7
                                                                      &w, &h) ;
Packit b099d7
                    if(    (w == r_w)  &&  (h == r_h)    )
Packit b099d7
                    {   XtMakeResizeRequest( wid, w, h, NULL, NULL) ;
Packit b099d7
                        } 
Packit b099d7
                    else
Packit b099d7
                    {   parentResult = XtGeometryNo ;
Packit b099d7
                        } 
Packit b099d7
                    } 
Packit b099d7
                }
Packit b099d7
            } 
Packit b099d7
        }
Packit b099d7
    if(    parentResult != XtGeometryNo    )
Packit b099d7
    {   _XmGeoMatrixSet( geoSpec) ;
Packit b099d7
        } 
Packit b099d7
    _XmGeoMatrixFree( geoSpec) ;
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * This routine allocates and initializes the data structure used
Packit b099d7
 *   to describe a matrix of geometry boxes.  Supplemental initialization
Packit b099d7
 *   may be required for some of the fields of the data structure, if 
Packit b099d7
 *   the user uses these fields in its supplied co-routines.
Packit b099d7
 * Rows of the GeoMatrix are lists of kid boxes which are terminated with
Packit b099d7
 *   a NULL in the kid widget field of the box structure.  This routine
Packit b099d7
 *   automatically allocates extra boxes to use to mark the end of each
Packit b099d7
 *   row list.
Packit b099d7
 * This routine initializes all fields to NULL.
Packit b099d7
 * The pointer returned by this routine should be freed by the user
Packit b099d7
 *   using the _XmGeoMatrixFree() routine.
Packit b099d7
 ****************/
Packit b099d7
XmGeoMatrix 
Packit b099d7
_XmGeoMatrixAlloc(
Packit b099d7
        unsigned int numRows,       /* Number of rows of widgets to layout.*/
Packit b099d7
        unsigned int numBoxes,      /* Total number of widgets of matrix.*/
Packit b099d7
        unsigned int extSize )      /* Extension record size (bytes).*/
Packit b099d7
{
Packit b099d7
            XmGeoMatrix     geoSpecPtr ;
Packit b099d7
            unsigned int    matrixRecSize ;
Packit b099d7
            unsigned int    layoutRecSize ;
Packit b099d7
            unsigned int    kidGeoRecSize ;
Packit b099d7
            unsigned int    layoutSize ;
Packit b099d7
            unsigned int    boxesSize ;
Packit b099d7
            unsigned int    totalSize ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    /* Get sizes of the various components of the GeoMatrix.  Round up to
Packit b099d7
    *   prevent alignment problems.
Packit b099d7
    */
Packit b099d7
    matrixRecSize = sizeof( XmGeoMatrixRec) ;
Packit b099d7
    if(    matrixRecSize & 0x03    )
Packit b099d7
    {   matrixRecSize = (matrixRecSize + 4) & ~((unsigned int) 0x03) ;
Packit b099d7
        } 
Packit b099d7
    layoutRecSize = sizeof( XmGeoRowLayoutRec) ;
Packit b099d7
    if(    layoutRecSize & 0x03    )
Packit b099d7
    {   layoutRecSize = (layoutRecSize + 4) & ~((unsigned int) 0x03) ;
Packit b099d7
        } 
Packit b099d7
    kidGeoRecSize = sizeof( XmKidGeometryRec) ;
Packit b099d7
    if(    kidGeoRecSize & 0x03    )
Packit b099d7
    {   kidGeoRecSize = (kidGeoRecSize + 4) & ~((unsigned int) 0x03) ;
Packit b099d7
        } 
Packit b099d7
    layoutSize = (numRows + 1) * layoutRecSize ;
Packit b099d7
    /* Extra boxes are used to mark the end of each row.
Packit b099d7
    */
Packit b099d7
    boxesSize = (numBoxes + numRows) * kidGeoRecSize ; 
Packit b099d7
    totalSize = matrixRecSize + layoutSize + boxesSize + extSize ;
Packit b099d7
Packit b099d7
    geoSpecPtr = (XmGeoMatrix) XtCalloc( 1, totalSize) ;   /* Must be zeroed.*/
Packit b099d7
Packit b099d7
    /* Set locations of arrays of row layout, box, and extension records.
Packit b099d7
    */
Packit b099d7
    geoSpecPtr->layouts = (XmGeoMajorLayout) (((char *) geoSpecPtr)
Packit b099d7
                                                             + matrixRecSize) ;
Packit b099d7
    geoSpecPtr->boxes = (XmKidGeometry) (((char *) geoSpecPtr)
Packit b099d7
                                                + matrixRecSize + layoutSize) ;
Packit b099d7
    if(    extSize    )
Packit b099d7
    {   geoSpecPtr->extension = (XtPointer) (((char *) geoSpecPtr)
Packit b099d7
                                    + matrixRecSize + layoutSize + boxesSize) ;
Packit b099d7
        } 
Packit b099d7
    return( geoSpecPtr) ;
Packit b099d7
    }
Packit b099d7
void
Packit b099d7
_XmGeoMatrixFree(
Packit b099d7
	XmGeoMatrix geo_spec)
Packit b099d7
{
Packit b099d7
  if(    geo_spec->ext_destructor    )
Packit b099d7
    {
Packit b099d7
      (*(geo_spec->ext_destructor))( geo_spec->extension) ;
Packit b099d7
    }
Packit b099d7
  XtFree( (char *) geo_spec) ;
Packit b099d7
}
Packit b099d7
Packit b099d7
/****************************************************************
Packit b099d7
 * If the widget specified by the "kidWid" parameter is non-NULL and is managed,
Packit b099d7
 *   its value is copied into the appropriate field of the kid geometry 
Packit b099d7
 *   structure provided by the "geo" parameter and TRUE is returned.
Packit b099d7
 * Otherwise, nothing is done and FALSE is returned.
Packit b099d7
 ****************/
Packit b099d7
Boolean 
Packit b099d7
_XmGeoSetupKid(
Packit b099d7
        XmKidGeometry geo,          /* Must be non-NULL.*/
Packit b099d7
        Widget kidWid )
Packit b099d7
{
Packit b099d7
/****************/
Packit b099d7
    if(    !kidWid  ||  !XtIsManaged( kidWid)    )
Packit b099d7
    {   return( FALSE) ;
Packit b099d7
        } 
Packit b099d7
    /* The widget ID will be used for subsequent "get" operation.
Packit b099d7
    */
Packit b099d7
    geo->kid = (Widget) kidWid;
Packit b099d7
Packit b099d7
    /* Return TRUE so the user knows that the box record was filled with
Packit b099d7
    *   a widget ID and can then increment the box pointer for the next
Packit b099d7
    *   managed widget to be setup.
Packit b099d7
    */
Packit b099d7
    return( TRUE) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * This routine goes through the widget matrix and retrieves the appropriate
Packit b099d7
 *   values for the KidGeometry boxes.  Field values of the boxes may be
Packit b099d7
 *   altered according to requirements specified in each row structure of
Packit b099d7
 *   the geoSpec.
Packit b099d7
 * If the widget id within the matrix matches the instigator field of the
Packit b099d7
 *   geoSpec, then the value for the box is taken from the request field of
Packit b099d7
 *   the geoSpec or the widget itself as appropriate.
Packit b099d7
 ****************/
Packit b099d7
void 
Packit b099d7
_XmGeoMatrixGet(
Packit b099d7
        XmGeoMatrix geoSpec,
Packit b099d7
        int geoType )               /* XmGET_PREFERRED_SIZE or */
Packit b099d7
{
Packit b099d7
    register XmKidGeometry   boxPtr ;
Packit b099d7
            XmKidGeometry   rowPtr ;
Packit b099d7
            XmGeoRowLayout  layoutPtr ;
Packit b099d7
            XtWidgetGeometry * request ;
Packit b099d7
            Widget          instigator ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    request = &geoSpec->instig_request ;
Packit b099d7
    instigator = geoSpec->instigator ;
Packit b099d7
    rowPtr = geoSpec->boxes ;
Packit b099d7
    layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
Packit b099d7
    while(    !(layoutPtr->end)    )
Packit b099d7
    {   
Packit b099d7
        boxPtr = rowPtr ;
Packit b099d7
        while(    boxPtr->kid    )
Packit b099d7
        {   
Packit b099d7
            _XmGeoLoadValues( boxPtr->kid, geoType, instigator, request,
Packit b099d7
                                                              &(boxPtr->box)) ;
Packit b099d7
            if(    boxPtr->kid == instigator    )
Packit b099d7
            {   geoSpec->in_layout = &(boxPtr->box) ;
Packit b099d7
                } 
Packit b099d7
            ++boxPtr ;
Packit b099d7
            } 
Packit b099d7
        if(    layoutPtr->fix_up    )
Packit b099d7
        {   
Packit b099d7
            (*(layoutPtr->fix_up))( geoSpec, geoType,
Packit b099d7
				        (XmGeoMajorLayout) layoutPtr, rowPtr) ;
Packit b099d7
            } 
Packit b099d7
        rowPtr = boxPtr + 1 ;   /* Skip over NULL box marking the end of row.*/
Packit b099d7
        ++layoutPtr ;           /* Go to next row layout record.*/
Packit b099d7
        } 
Packit b099d7
#ifdef DEBUG_GEOUTILS
Packit b099d7
    PrintMatrix( "(get) ", geoSpec) ; 
Packit b099d7
#endif
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * The XtConfigureWidget routine is called on all widgets of the geoSpec
Packit b099d7
 *   matrix as needed (when the geometry values of the box have changed).
Packit b099d7
 *   If a widget ID matches that of the instigator field of the geoSpec, 
Packit b099d7
 *   then that widget is not configured.
Packit b099d7
 * Any layout "fixup" routines which are specified in the row structure
Packit b099d7
 *   of the geoSpec are called before and after the call 
Packit b099d7
 *   to XmeConfigureObject, with appropriate parameter values.
Packit b099d7
 ****************/
Packit b099d7
void 
Packit b099d7
_XmGeoMatrixSet(
Packit b099d7
        XmGeoMatrix geoSpec )
Packit b099d7
{
Packit b099d7
    register XmKidGeometry   rowPtr ;
Packit b099d7
    register XmGeoRowLayout  layoutPtr ;
Packit b099d7
            Boolean         fixUps = FALSE ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
#ifdef DEBUG_GEOUTILS
Packit b099d7
    PrintMatrix( "(set) ", geoSpec) ; 
Packit b099d7
#endif
Packit b099d7
Packit b099d7
    /* Give the user a chance to avoid setting the widgets to box values.
Packit b099d7
    */
Packit b099d7
    if(    !geoSpec->set_except  ||  !(*geoSpec->set_except)( geoSpec)    )
Packit b099d7
    {   
Packit b099d7
        /* Give the user a chance to modify box sizes before setting
Packit b099d7
        *   the widget to the values defined in the box record.
Packit b099d7
        */
Packit b099d7
        layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
        rowPtr = geoSpec->boxes ;
Packit b099d7
        while(    !(layoutPtr->end)    )
Packit b099d7
        {   
Packit b099d7
            if(    layoutPtr->fix_up    )
Packit b099d7
            {   
Packit b099d7
                /* Call the user's routine which may modify boxes of this row.
Packit b099d7
                */
Packit b099d7
                (*(layoutPtr->fix_up))( geoSpec, XmGEO_PRE_SET, 
Packit b099d7
                                        (XmGeoMajorLayout) layoutPtr, rowPtr) ;
Packit b099d7
                fixUps = TRUE ;
Packit b099d7
                } 
Packit b099d7
            rowPtr += layoutPtr->box_count + 1 ;         /* Skip to next row.*/
Packit b099d7
            ++layoutPtr ;
Packit b099d7
            } 
Packit b099d7
        /* Now set the widgets to the values in the boxes.
Packit b099d7
        */
Packit b099d7
        layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
        rowPtr = geoSpec->boxes ;
Packit b099d7
        while(    !(layoutPtr->end)    )
Packit b099d7
        {   
Packit b099d7
            _XmSetKidGeo( rowPtr, geoSpec->instigator) ;
Packit b099d7
Packit b099d7
            rowPtr += layoutPtr->box_count + 1 ;         /* Skip to next row.*/
Packit b099d7
            ++layoutPtr ;
Packit b099d7
            } 
Packit b099d7
        if(    fixUps    )
Packit b099d7
        {   
Packit b099d7
            /* Now call the fix_up routines again, to give the user a chance to
Packit b099d7
            *   undo the chances to the boxes in order to keep consistency for
Packit b099d7
            *   subsequent layout operations.
Packit b099d7
            */
Packit b099d7
            layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
            rowPtr = geoSpec->boxes ;
Packit b099d7
            while(    !(layoutPtr->end)    )
Packit b099d7
            {   
Packit b099d7
                if(    layoutPtr->fix_up    )
Packit b099d7
                {   
Packit b099d7
                    (*(layoutPtr->fix_up))( geoSpec, XmGEO_POST_SET,
Packit b099d7
                                        (XmGeoMajorLayout) layoutPtr, rowPtr) ;
Packit b099d7
                    } 
Packit b099d7
                rowPtr += layoutPtr->box_count + 1 ;     /* Skip to next row.*/
Packit b099d7
                ++layoutPtr ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * This routine adjusts boxes according to policies regarding border size
Packit b099d7
 *   and even-sized boxes.  Box dimensions are altered appropriately if
Packit b099d7
 *   even_width or even_height parameters are set.  Borders are set if
Packit b099d7
 *   uniform_border is TRUE.
Packit b099d7
 ****************/
Packit b099d7
void 
Packit b099d7
_XmGeoAdjustBoxes(
Packit b099d7
        XmGeoMatrix geoSpec )
Packit b099d7
{
Packit b099d7
    register XmKidGeometry   rowPtr ;
Packit b099d7
    register XmKidGeometry   boxPtr ;
Packit b099d7
            XmGeoRowLayout  layoutPtr ;
Packit b099d7
            Dimension       globalSetBorder ;
Packit b099d7
            Dimension       globalBorder ;
Packit b099d7
            Dimension       borderValue ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    globalSetBorder = geoSpec->uniform_border ;
Packit b099d7
    globalBorder = geoSpec->border ;
Packit b099d7
Packit b099d7
    rowPtr = geoSpec->boxes ;
Packit b099d7
    layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
Packit b099d7
    while(    !(layoutPtr->end)    )
Packit b099d7
    {   
Packit b099d7
        if(    layoutPtr->even_width    )
Packit b099d7
        {   _XmGeoBoxesSameWidth( rowPtr, layoutPtr->even_width) ;
Packit b099d7
            } 
Packit b099d7
        if(    layoutPtr->even_height    )
Packit b099d7
        {   _XmGeoBoxesSameHeight( rowPtr, layoutPtr->even_height) ;
Packit b099d7
            } 
Packit b099d7
        if(    globalSetBorder  ||  layoutPtr->uniform_border    )
Packit b099d7
        {   if(    globalSetBorder    )
Packit b099d7
            {   borderValue = globalBorder ;
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   borderValue = layoutPtr->border ;
Packit b099d7
                } 
Packit b099d7
            boxPtr = rowPtr ;
Packit b099d7
            while(    boxPtr->kid    )
Packit b099d7
            {   boxPtr->box.border_width = borderValue ;
Packit b099d7
                ++boxPtr ;
Packit b099d7
                } 
Packit b099d7
            }
Packit b099d7
        while(    (rowPtr++)->kid    )  /* Go to next row of boxes. */
Packit b099d7
        { /*EMPTY*/  }
Packit b099d7
        ++layoutPtr ;           /* Go to next row layout record.*/
Packit b099d7
        }
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * This routine traverses the matrix and collects data regarding the
Packit b099d7
 *   sizes of boxes, the minimum fill area expected, and various other
Packit b099d7
 *   parameters which are used during the layout process.
Packit b099d7
 ****************/
Packit b099d7
void 
Packit b099d7
_XmGeoGetDimensions(
Packit b099d7
        XmGeoMatrix geoSpec )
Packit b099d7
{
Packit b099d7
    register XmKidGeometry   rowPtr ;
Packit b099d7
    register XmKidGeometry   boxPtr ;
Packit b099d7
            XmGeoRowLayout  layoutPtr ;
Packit b099d7
            Dimension       boxH ;
Packit b099d7
            Dimension       rowH ;
Packit b099d7
            Dimension       rowW ;
Packit b099d7
            Dimension       matrixFillH ;
Packit b099d7
            Dimension       matrixBoxesH ;
Packit b099d7
            Dimension       matrixW ;
Packit b099d7
            Dimension       endSpaceW ;
Packit b099d7
            unsigned int    numBoxes ;
Packit b099d7
            Dimension       marginW ;
Packit b099d7
            Dimension       marginH ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    marginH = geoSpec->margin_h ;
Packit b099d7
    marginW = geoSpec->margin_w ;
Packit b099d7
    rowPtr = geoSpec->boxes ;
Packit b099d7
    layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
    matrixW = 0 ;
Packit b099d7
    matrixBoxesH = 0 ;
Packit b099d7
    matrixFillH = layoutPtr->space_above ;
Packit b099d7
    if(    matrixFillH < marginH    )
Packit b099d7
    {   matrixFillH = 0 ;
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   matrixFillH -= marginH ;  /* This dimension does not include margins.*/
Packit b099d7
        } 
Packit b099d7
    geoSpec->stretch_boxes = FALSE ;
Packit b099d7
    while(    !(layoutPtr->end)    )
Packit b099d7
    {   
Packit b099d7
        /* Gather information about the height, width, and number of boxes
Packit b099d7
        *   in the row.
Packit b099d7
        */
Packit b099d7
        rowW = 0 ;
Packit b099d7
        rowH = 0 ;
Packit b099d7
        numBoxes = 0 ;
Packit b099d7
        boxPtr = rowPtr ;
Packit b099d7
        while(    boxPtr->kid    )
Packit b099d7
        {   rowW += boxPtr->box.width + (boxPtr->box.border_width << 1) ;
Packit b099d7
            boxH = boxPtr->box.height + (boxPtr->box.border_width << 1) ;
Packit b099d7
            ASSIGN_MAX( rowH, boxH) ;   /* The tallest box is the row height.*/
Packit b099d7
            ++numBoxes ;
Packit b099d7
            ++boxPtr ;
Packit b099d7
            } 
Packit b099d7
        /* Fill row layout record with info about row.
Packit b099d7
        */
Packit b099d7
        layoutPtr->max_box_height = rowH ;/* Tallest box in row, with border.*/
Packit b099d7
        layoutPtr->boxes_width = rowW ; /* Sum of box widths and borders.*/
Packit b099d7
        layoutPtr->box_count = numBoxes ;
Packit b099d7
Packit b099d7
        /* Check for vertical stetch row.
Packit b099d7
        */
Packit b099d7
        if(    layoutPtr->stretch_height    )
Packit b099d7
        {   if(    layoutPtr->fit_mode != XmGEO_WRAP    )
Packit b099d7
            {   geoSpec->stretch_boxes = TRUE ;
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   layoutPtr->stretch_height = FALSE ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        /* Compute row width to generate matrix width.  Exclude margins.
Packit b099d7
        */
Packit b099d7
        if(    layoutPtr->space_end > marginW    )
Packit b099d7
        {   endSpaceW = layoutPtr->space_end - marginW ;
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   endSpaceW = 0 ;
Packit b099d7
            } 
Packit b099d7
        /* Fill width is the minimum spacing between (borders of) boxes plus
Packit b099d7
        *   any extra space required at ends.  Margins are not included.
Packit b099d7
        */
Packit b099d7
        layoutPtr->fill_width = (endSpaceW << 1) 
Packit b099d7
                                + ((numBoxes - 1) * layoutPtr->space_between) ;
Packit b099d7
        /* Maximum row width is the overall matrix width, less margins.  Add
Packit b099d7
        *   box width to fill width for total width this row.
Packit b099d7
        */
Packit b099d7
        rowW += layoutPtr->fill_width ;
Packit b099d7
        ASSIGN_MAX( matrixW, rowW) ;
Packit b099d7
        rowPtr = boxPtr + 1 ;   /* Skip over NULL box marking the end of row.*/
Packit b099d7
        ++layoutPtr ;           /* Go to next row layout record.*/
Packit b099d7
        /* Accumulate heights of each row.
Packit b099d7
        */
Packit b099d7
        matrixFillH += layoutPtr->space_above ;
Packit b099d7
        matrixBoxesH += rowH ;
Packit b099d7
        } 
Packit b099d7
    /* The matrixFillH variable already has fill space included from the final
Packit b099d7
    *   row layout record.  This must be reduced by the amount of the margin,
Packit b099d7
    *   or a smaller amount if the amount specified was less than the margin.
Packit b099d7
    */
Packit b099d7
    if(    layoutPtr->space_above < marginH    )
Packit b099d7
    {   matrixFillH -= layoutPtr->space_above ;
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   matrixFillH -= marginH ;
Packit b099d7
        } 
Packit b099d7
    geoSpec->max_major = matrixW ;         /* Widest row, excluding margins. */
Packit b099d7
    geoSpec->boxes_minor = matrixBoxesH ;  /* Sum of tallest box in each row.*/
Packit b099d7
    geoSpec->fill_minor = matrixFillH ;    /* Sum of vertical fill spacing.  */
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * After the boxes have been layed-out according to the minimum vertical fill
Packit b099d7
 *   requirements of the matrix, this routine stretches the layout to fill
Packit b099d7
 *   any extra space required by the managing widget.
Packit b099d7
 * Returns new height after extra spacing is inserted.
Packit b099d7
 ****************/
Packit b099d7
static Dimension 
Packit b099d7
_XmGeoStretchVertical(
Packit b099d7
        XmGeoMatrix geoSpec,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int actualH,
Packit b099d7
        int desiredH )
Packit b099d7
#else
Packit b099d7
        Dimension actualH,
Packit b099d7
        Dimension desiredH )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{   
Packit b099d7
    register XmGeoRowLayout  layoutPtr ;
Packit b099d7
    register XmKidGeometry   rowPtr ;
Packit b099d7
            int             fillOffset ;
Packit b099d7
            int             stretchableSpace ;
Packit b099d7
            int             deltaY ;
Packit b099d7
            int             deltaH ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
    stretchableSpace = 0 ;
Packit b099d7
    fillOffset = ((int) desiredH) - ((int) actualH) ;
Packit b099d7
    if(    fillOffset < 0    )
Packit b099d7
    {   /* Must shrink stretchable boxes.
Packit b099d7
        */
Packit b099d7
        while(    !layoutPtr->end    )
Packit b099d7
        {   if(    layoutPtr->stretch_height
Packit b099d7
                    && (layoutPtr->max_box_height > layoutPtr->min_height)    )
Packit b099d7
            {   
Packit b099d7
                stretchableSpace += layoutPtr->max_box_height
Packit b099d7
                                                      - layoutPtr->min_height ;
Packit b099d7
                } 
Packit b099d7
            ++layoutPtr ;
Packit b099d7
            } 
Packit b099d7
        if(    -fillOffset > stretchableSpace    )
Packit b099d7
        {   fillOffset = -stretchableSpace ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    else 
Packit b099d7
    {   /* Must grow stretchable boxes.
Packit b099d7
        */
Packit b099d7
        while(    !layoutPtr->end    )
Packit b099d7
        {   if(    layoutPtr->stretch_height    )
Packit b099d7
            {   stretchableSpace += layoutPtr->max_box_height ;
Packit b099d7
                } 
Packit b099d7
            ++layoutPtr ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    if(    !stretchableSpace    )
Packit b099d7
    {   /* No stretchable boxes, so return with current height.
Packit b099d7
        */
Packit b099d7
        return( actualH) ;
Packit b099d7
        } 
Packit b099d7
    deltaY = 0 ;
Packit b099d7
    rowPtr = geoSpec->boxes ;
Packit b099d7
    layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
    while(    !layoutPtr->end    )
Packit b099d7
    {   if(    layoutPtr->stretch_height    )
Packit b099d7
        {   
Packit b099d7
            if(    fillOffset < 0    )
Packit b099d7
            {   if(    layoutPtr->max_box_height > layoutPtr->min_height    )
Packit b099d7
                {   deltaH = (((int) (layoutPtr->max_box_height
Packit b099d7
                                        - layoutPtr->min_height)) * fillOffset)
Packit b099d7
                                                           / stretchableSpace ;
Packit b099d7
                    } 
Packit b099d7
                else
Packit b099d7
                {   deltaH = 0 ;
Packit b099d7
                    } 
Packit b099d7
                /* deltaH is now <= 0.
Packit b099d7
                */
Packit b099d7
                while(    rowPtr->kid    )
Packit b099d7
                {   
Packit b099d7
		    int boxCorrection = layoutPtr->max_box_height
Packit b099d7
                                                         - rowPtr->box.height ;
Packit b099d7
		    if(    boxCorrection > -deltaH    )
Packit b099d7
		    {   boxCorrection = -deltaH ;
Packit b099d7
			}
Packit b099d7
		    rowPtr->box.height += deltaH + boxCorrection ;
Packit b099d7
		    rowPtr->box.y += deltaY - (boxCorrection >> 1) ;
Packit b099d7
                    ++rowPtr ;
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            else /* fillOffset >= 0 */
Packit b099d7
            {   
Packit b099d7
                deltaH = (layoutPtr->max_box_height * fillOffset)
Packit b099d7
                                                           / stretchableSpace ;
Packit b099d7
                while(    rowPtr->kid    )
Packit b099d7
                {   rowPtr->box.height += deltaH ;
Packit b099d7
                    rowPtr->box.y += deltaY ;
Packit b099d7
                    ++rowPtr ;
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            deltaY += deltaH ;
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   while(    rowPtr->kid    )
Packit b099d7
            {   rowPtr->box.y += deltaY ;
Packit b099d7
                ++rowPtr ;
Packit b099d7
                } 
Packit b099d7
            }
Packit b099d7
        ++rowPtr ;
Packit b099d7
        ++layoutPtr ;
Packit b099d7
        }
Packit b099d7
    return( actualH + deltaY) ;                    /* Return new height.*/
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * After the boxes have been layed-out according to the minimum vertical fill
Packit b099d7
 *   requirements of the matrix, this routine stretches the layout to fill
Packit b099d7
 *   any extra space required by the managing widget.
Packit b099d7
 * Returns new height after extra spacing is inserted.
Packit b099d7
 ****************/
Packit b099d7
static Dimension 
Packit b099d7
_XmGeoFillVertical(
Packit b099d7
        XmGeoMatrix geoSpec,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int actualH,
Packit b099d7
        int desiredH )
Packit b099d7
#else
Packit b099d7
        Dimension actualH,
Packit b099d7
        Dimension desiredH )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{   
Packit b099d7
    register XmGeoRowLayout  layoutPtr ;
Packit b099d7
    register XmKidGeometry   rowPtr ;
Packit b099d7
            unsigned long   fillAmount ;
Packit b099d7
            unsigned long   totalSpecSpace ;
Packit b099d7
            Dimension       marginH ;
Packit b099d7
            Dimension       firstSpecSpace ;
Packit b099d7
            Dimension       lastSpecSpace ;
Packit b099d7
            Dimension       currentFirstSpace ;
Packit b099d7
            Dimension       currentLastSpace ;
Packit b099d7
            Dimension       newFirstSpace ;
Packit b099d7
            Dimension       newLastSpace ;
Packit b099d7
            int             deltaY ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    /* Need to accumulate specified spacing factors, saving first and last
Packit b099d7
    *   ends separately.
Packit b099d7
    */
Packit b099d7
    layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
    totalSpecSpace = 0 ;
Packit b099d7
    firstSpecSpace = layoutPtr->space_above ;
Packit b099d7
    while(    !(++layoutPtr)->end    )
Packit b099d7
    {   totalSpecSpace += layoutPtr->space_above ;
Packit b099d7
        } 
Packit b099d7
    lastSpecSpace = layoutPtr->space_above ;
Packit b099d7
    totalSpecSpace += firstSpecSpace + lastSpecSpace ;
Packit b099d7
    if(    !totalSpecSpace    )
Packit b099d7
    {   /* Zero spacing specified, so just return as is.
Packit b099d7
        */
Packit b099d7
        return( actualH) ;
Packit b099d7
        } 
Packit b099d7
    /* Must reconstruct the actual spacing, which is the specified minimum.
Packit b099d7
    * Save current end spacing separately, since everything done here is
Packit b099d7
    *   relative to the actual coordinates of the matrix and it will be
Packit b099d7
    *   needed later.
Packit b099d7
    */
Packit b099d7
    marginH = geoSpec->margin_h ;
Packit b099d7
    currentFirstSpace = (firstSpecSpace < marginH) ? marginH : firstSpecSpace ;
Packit b099d7
    currentLastSpace  = (lastSpecSpace < marginH) ? marginH : lastSpecSpace ;
Packit b099d7
Packit b099d7
    /* Fill amount includes the current fill plus margins and extra
Packit b099d7
    *   spacing.
Packit b099d7
    */
Packit b099d7
    fillAmount = (desiredH - actualH) + geoSpec->fill_minor
Packit b099d7
                                       + currentFirstSpace + currentLastSpace ;
Packit b099d7
    newFirstSpace = (Dimension) ((fillAmount * (unsigned long) firstSpecSpace)
Packit b099d7
                                                            / totalSpecSpace) ;
Packit b099d7
    newLastSpace = (Dimension) ((fillAmount * (unsigned long) lastSpecSpace)
Packit b099d7
                                                            / totalSpecSpace) ;
Packit b099d7
    if(    newFirstSpace < marginH    )
Packit b099d7
    {   fillAmount -= marginH ;
Packit b099d7
        totalSpecSpace -= firstSpecSpace ;
Packit b099d7
        newFirstSpace = marginH ;
Packit b099d7
        } 
Packit b099d7
    if(    newLastSpace < marginH    )
Packit b099d7
    {   fillAmount -= marginH ;
Packit b099d7
        totalSpecSpace -= lastSpecSpace ;
Packit b099d7
        newLastSpace = marginH ;
Packit b099d7
        } 
Packit b099d7
    /* Now traverse the matrix, offsetting all y-ccordinates according to
Packit b099d7
    *   additional spacing.  Wrapped lines receive no extra spacing between
Packit b099d7
    *   them.
Packit b099d7
    */
Packit b099d7
    deltaY = newFirstSpace - currentFirstSpace ;
Packit b099d7
    rowPtr = geoSpec->boxes ;
Packit b099d7
    layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
    for(;;)
Packit b099d7
    {   while(    rowPtr->kid    )
Packit b099d7
        {   rowPtr->box.y += deltaY ;
Packit b099d7
            ++rowPtr ;
Packit b099d7
            } 
Packit b099d7
        ++rowPtr ;
Packit b099d7
        ++layoutPtr ;
Packit b099d7
        if(    layoutPtr->end    )
Packit b099d7
        {   break ;
Packit b099d7
            } 
Packit b099d7
        deltaY += (int) (((((unsigned long) layoutPtr->space_above)
Packit b099d7
                    * fillAmount) / totalSpecSpace) - layoutPtr->space_above) ;
Packit b099d7
        }
Packit b099d7
    deltaY += newLastSpace - currentLastSpace ;
Packit b099d7
Packit b099d7
    return( actualH + deltaY) ;                    /* Return new height.*/
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * Calculates and returns appropriate fill factor from given layout
Packit b099d7
 *   parameters.  Also returns appropriate spacing for ends.
Packit b099d7
 * The fill factor returned is for use with all spacing between boxes, but
Packit b099d7
 *   not the ends (use provided spacing).
Packit b099d7
 ****************/
Packit b099d7
static void 
Packit b099d7
_XmGeoCalcFill(
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int fillSpace,
Packit b099d7
        int margin,
Packit b099d7
#else
Packit b099d7
        Dimension fillSpace,        /* Fill space, including margins.*/
Packit b099d7
        Dimension margin,           /* Margin (included in fillSpace).*/
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        unsigned int numBoxes,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int endSpec,
Packit b099d7
        int betweenSpec,
Packit b099d7
#else
Packit b099d7
        Dimension endSpec,
Packit b099d7
        Dimension betweenSpec,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        Dimension *pEndSpace,       /* Receives end spacing.*/
Packit b099d7
        Dimension *pBetweenSpace )  /* Receives between spacing.*/
Packit b099d7
{   
Packit b099d7
            Dimension       totalSpecSpace ;/* Sum of specified spacing.*/
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    if(    !endSpec    )
Packit b099d7
    {   if(    numBoxes == 1    )
Packit b099d7
        {   endSpec = 1 ;
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   if(    !betweenSpec    )
Packit b099d7
            {   betweenSpec = (Dimension) (numBoxes - 1) ;
Packit b099d7
                } 
Packit b099d7
            }
Packit b099d7
        } 
Packit b099d7
    totalSpecSpace = (betweenSpec * (numBoxes - 1)) + (endSpec << 1) ;
Packit b099d7
    *pEndSpace = (endSpec * fillSpace) / totalSpecSpace ;
Packit b099d7
Packit b099d7
    if(    *pEndSpace < margin    )
Packit b099d7
    {   
Packit b099d7
        if(    (endSpec << 1) < totalSpecSpace    )
Packit b099d7
        {   totalSpecSpace -= endSpec << 1 ;
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   totalSpecSpace = 1 ;
Packit b099d7
            } 
Packit b099d7
        if(    (margin << 1) < fillSpace    )
Packit b099d7
        {   fillSpace -= margin << 1 ;
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   fillSpace = 0 ;
Packit b099d7
            } 
Packit b099d7
        *pEndSpace = margin ;
Packit b099d7
        } 
Packit b099d7
    *pBetweenSpace = (betweenSpec * fillSpace) / totalSpecSpace ;
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * The x, y, width, and height fields of the boxes in the geoSpec matrix
Packit b099d7
 *   are modified with values appropriate for the layout parameters specified
Packit b099d7
 *   by x, y, pW, and pH.
Packit b099d7
 * The overall width and height dimensions at the specified locations
Packit b099d7
 *   of pW and pH must be initially set to their desired values, or zero
Packit b099d7
 *   for the default layout.
Packit b099d7
 * The actual values of the width and height (after layout) are returned at
Packit b099d7
 *   the locations pW and pH.
Packit b099d7
 ****************/
Packit b099d7
void 
Packit b099d7
_XmGeoArrangeBoxes(
Packit b099d7
        XmGeoMatrix geoSpec,        /* Array of box lists (rows).*/
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int x,
Packit b099d7
        int y,
Packit b099d7
#else
Packit b099d7
        Position x,                 /* X coordinate of composite.*/
Packit b099d7
        Position y,                 /* Y coordinate of composite.*/
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        Dimension *pW,              /* Initial value is minimum width.*/
Packit b099d7
        Dimension *pH )             /* Initial value is minimum height.*/
Packit b099d7
{
Packit b099d7
            Dimension       marginW ;   /* Margin between sides and boxes.*/
Packit b099d7
            Dimension       marginH ;   /* Margin between top/bot and boxes.*/
Packit b099d7
            XmKidGeometry   rowPtr ;
Packit b099d7
            XmGeoRowLayout  layoutPtr ;
Packit b099d7
            Dimension       actualW ;
Packit b099d7
            Dimension       actualH ;
Packit b099d7
            Dimension       initY ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    if(    geoSpec->arrange_boxes
Packit b099d7
       &&  (geoSpec->arrange_boxes != _XmGeoArrangeBoxes)    )
Packit b099d7
      {
Packit b099d7
	(*(geoSpec->arrange_boxes))( geoSpec, x, y, pW, pH) ;
Packit b099d7
	return ;
Packit b099d7
      }
Packit b099d7
    /* Fix box dimensions according to even_height/width and uniform_border
Packit b099d7
    *   specifications.
Packit b099d7
    */
Packit b099d7
    _XmGeoAdjustBoxes( geoSpec) ;
Packit b099d7
Packit b099d7
    /* Compute layout dimensions.
Packit b099d7
    */
Packit b099d7
    _XmGeoGetDimensions( geoSpec) ;
Packit b099d7
Packit b099d7
    /* Initialize global layout dimensions.
Packit b099d7
    */
Packit b099d7
    marginW = geoSpec->margin_w ;
Packit b099d7
    marginH = geoSpec->margin_h ;
Packit b099d7
    actualW = geoSpec->max_major + (marginW << 1) ;
Packit b099d7
Packit b099d7
/****** the value of this assignment is never used **********
Packit b099d7
    actualH = geoSpec->boxes_minor + geoSpec->fill_minor + (marginH << 1) ;
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
    /* Adjust layout dimensions to requested dimensions.
Packit b099d7
    */
Packit b099d7
    if(    *pW    )
Packit b099d7
    {   actualW = *pW ;
Packit b099d7
        } 
Packit b099d7
Packit b099d7
/******* the value assigned to actualH is never used *************
Packit b099d7
    if(    *pH    )
Packit b099d7
    {   actualH = *pH ;
Packit b099d7
        } 
Packit b099d7
******************************************************************/
Packit b099d7
Packit b099d7
    /* Save initial Y coordinate for later computation of height.
Packit b099d7
    */
Packit b099d7
    initY = y ;
Packit b099d7
    
Packit b099d7
    /* Layout horizontal position of each box in row, one row at a time.
Packit b099d7
    */
Packit b099d7
    layoutPtr = &(geoSpec->layouts->row) ;
Packit b099d7
    rowPtr = geoSpec->boxes ;
Packit b099d7
    /* Add first end spacing.
Packit b099d7
    */
Packit b099d7
    if(    layoutPtr->space_above > marginH    )
Packit b099d7
    {   y += layoutPtr->space_above ;
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   y += marginH ;
Packit b099d7
        } 
Packit b099d7
    while(    !(layoutPtr->end)    )
Packit b099d7
    {   
Packit b099d7
        /* Arrange one row of boxes at a time.
Packit b099d7
        */
Packit b099d7
        y = _XmGeoArrangeList( rowPtr, layoutPtr, x, y, actualW,
Packit b099d7
                                                            marginW, marginH) ;
Packit b099d7
        rowPtr += layoutPtr->box_count + 1 ;             /* Skip to next row.*/
Packit b099d7
        ++layoutPtr ;
Packit b099d7
Packit b099d7
        /* Add between-row spacing.
Packit b099d7
        */
Packit b099d7
        y += layoutPtr->space_above ;
Packit b099d7
        } 
Packit b099d7
    if(    layoutPtr->space_above < marginH    )
Packit b099d7
    {   /* Fill out to the minimum margin if previous spacing is less
Packit b099d7
        *   than margin.
Packit b099d7
        */
Packit b099d7
        y += marginH - layoutPtr->space_above ;
Packit b099d7
        } 
Packit b099d7
    actualH = y - initY ;
Packit b099d7
    if(    *pH  &&  (actualH != *pH)    )
Packit b099d7
    {   if(    geoSpec->stretch_boxes    )
Packit b099d7
        {   /* Has stretchable boxes, so grow or shrink using stretch.
Packit b099d7
            */
Packit b099d7
            actualH = _XmGeoStretchVertical( geoSpec, actualH, *pH) ;
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   if(    actualH < *pH    )
Packit b099d7
            {   /* Layout is smaller than specified height, so fill vertically.
Packit b099d7
                */
Packit b099d7
                actualH = _XmGeoFillVertical( geoSpec, actualH, *pH) ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    /* Set return values of actual width and height of matrix.
Packit b099d7
    */
Packit b099d7
    geoSpec->width = actualW ;
Packit b099d7
    if(    *pW < actualW    )
Packit b099d7
    {   *pW = actualW ;
Packit b099d7
        } 
Packit b099d7
    geoSpec->height = actualH ;
Packit b099d7
    if(    *pH < actualH    )
Packit b099d7
    {   *pH = actualH ;
Packit b099d7
        } 
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************/
Packit b099d7
static int 
Packit b099d7
boxWidthCompare(
Packit b099d7
        XmConst void * boxPtr1,
Packit b099d7
        XmConst void * boxPtr2 )
Packit b099d7
{
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    return( (*((XmKidGeometry *) boxPtr1))->box.width
Packit b099d7
                                 > (*((XmKidGeometry *) boxPtr2))->box.width) ;
Packit b099d7
    }
Packit b099d7
/****************************************************************
Packit b099d7
 * This routine alters box sizes such that the composite width is reduced
Packit b099d7
 *   by the offset amount specified.  The boxWidth parameter is assumed to 
Packit b099d7
 *   contain the sum of the all box widths, including borders.
Packit b099d7
 * The algorithm used by this routine tends to average the width of all boxes.
Packit b099d7
 *   In other words, to achieve the desired width reduction, the largest boxes
Packit b099d7
 *   are reduced first, possibly until all boxes are the same width
Packit b099d7
 *   (thereafter reducing all boxes evenly).
Packit b099d7
 ****************/
Packit b099d7
static void 
Packit b099d7
FitBoxesAveraging(
Packit b099d7
        XmKidGeometry rowPtr,
Packit b099d7
        unsigned int numBoxes,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int boxWidth,
Packit b099d7
#else
Packit b099d7
        Dimension boxWidth,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        int amtOffset )
Packit b099d7
{
Packit b099d7
            unsigned int    Index ;
Packit b099d7
            XmKidGeometry * sortedBoxes ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    /* Get memory to use for sorting the list of boxes.
Packit b099d7
    */
Packit b099d7
    sortedBoxes = (XmKidGeometry *) XtMalloc( numBoxes 
Packit b099d7
                                                    * sizeof( XmKidGeometry)) ;
Packit b099d7
    /* Enter the boxes into the array and sort.
Packit b099d7
    */
Packit b099d7
    Index = 0 ;
Packit b099d7
    while(    Index < numBoxes    )
Packit b099d7
    {   sortedBoxes[Index] = &rowPtr[Index] ;
Packit b099d7
        /* Need to remove the border_width component from boxWidth.
Packit b099d7
        */
Packit b099d7
        boxWidth -= (rowPtr[Index].box.border_width << 1) ;
Packit b099d7
        ++Index ;
Packit b099d7
        } 
Packit b099d7
    qsort( (void *) sortedBoxes, (size_t) numBoxes, sizeof( XmKidGeometry), 
Packit b099d7
                                                             boxWidthCompare) ;
Packit b099d7
    /* Now sorted with smallest box first.
Packit b099d7
    */
Packit b099d7
    Index = 0 ;
Packit b099d7
    while(    Index < numBoxes    )
Packit b099d7
    {   
Packit b099d7
        /* The right-hand side of the comparison represents the amount of
Packit b099d7
        *   area that would be truncated if all boxes were the same width
Packit b099d7
        *   as sortedBoxes[Index].  The loop will break when the Index 
Packit b099d7
        *   points to the smallest box in the list to be truncated.
Packit b099d7
        */
Packit b099d7
        if(   amtOffset >= ((int) (boxWidth - ((sortedBoxes[Index]->box.width)
Packit b099d7
                                                   * (numBoxes - Index))))    )
Packit b099d7
        {   break ;
Packit b099d7
            } 
Packit b099d7
        /* This keeps the above comparison simple.
Packit b099d7
        */
Packit b099d7
        boxWidth -= sortedBoxes[Index]->box.width ;
Packit b099d7
        ++Index ;
Packit b099d7
        } 
Packit b099d7
    if(    Index < numBoxes    )
Packit b099d7
    {   
Packit b099d7
        if(    (int) boxWidth > amtOffset    )
Packit b099d7
        {   
Packit b099d7
            boxWidth = (boxWidth - amtOffset) / (numBoxes - Index) ;
Packit b099d7
            
Packit b099d7
            if(    !boxWidth    )
Packit b099d7
            {   boxWidth = 1 ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   boxWidth = 1 ;
Packit b099d7
            } 
Packit b099d7
        /* boxWidth is now the truncated width of the remaining boxes
Packit b099d7
        *   in the sorted list.  Set these boxes appropriately.
Packit b099d7
        */
Packit b099d7
        while(    Index < numBoxes    )
Packit b099d7
        {   sortedBoxes[Index]->box.width = boxWidth ;
Packit b099d7
            ++Index ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    XtFree( (char *) sortedBoxes) ;
Packit b099d7
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * This routine alters the width of boxes in proportion to the width of each
Packit b099d7
 *   box such that the total change is equal to amtOffset.  If amtOffset is
Packit b099d7
 *   greater than zero, the total width is reduced (a "fit").  Otherwise,
Packit b099d7
 *   the total width is increased (a "fill").
Packit b099d7
 ****************/
Packit b099d7
static void 
Packit b099d7
FitBoxesProportional(
Packit b099d7
        XmKidGeometry rowPtr,
Packit b099d7
        unsigned int numBoxes,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int boxWidth,
Packit b099d7
#else
Packit b099d7
        Dimension boxWidth,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        int amtOffset )
Packit b099d7
{   
Packit b099d7
            int             deltaX ;
Packit b099d7
            int             deltaW ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
Packit b099d7
    if(    boxWidth >= numBoxes    )
Packit b099d7
    {   
Packit b099d7
        deltaX = 0 ;
Packit b099d7
        while(    rowPtr->kid    )
Packit b099d7
        {   
Packit b099d7
            deltaW = (amtOffset * (int)(rowPtr->box.width 
Packit b099d7
                       + (rowPtr->box.border_width << 1))) / ((int) boxWidth) ;
Packit b099d7
            if(    deltaW < ((int) rowPtr->box.width)    )
Packit b099d7
            {   rowPtr->box.width -= deltaW ;
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   rowPtr->box.width = 1 ;
Packit b099d7
                } 
Packit b099d7
            rowPtr->box.x += deltaX ;
Packit b099d7
            deltaX -= deltaW ;
Packit b099d7
            ++rowPtr ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    else /* boxWidth < numBoxes */
Packit b099d7
    {   
Packit b099d7
        if(    (-amtOffset) > numBoxes    )
Packit b099d7
        {   
Packit b099d7
            boxWidth = (-amtOffset) / numBoxes ;
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   boxWidth = 1 ;
Packit b099d7
            } 
Packit b099d7
        deltaX = 0 ;
Packit b099d7
        while(    rowPtr->kid    )
Packit b099d7
        {   
Packit b099d7
            rowPtr->box.width = boxWidth ;
Packit b099d7
            rowPtr->box.x += deltaX ;
Packit b099d7
            deltaX += boxWidth ;
Packit b099d7
            ++rowPtr ;
Packit b099d7
            } 
Packit b099d7
Packit b099d7
        } 
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************/
Packit b099d7
static void 
Packit b099d7
SegmentFill(
Packit b099d7
        XmKidGeometry rowBoxes,
Packit b099d7
        unsigned int numBoxes,
Packit b099d7
        XmGeoRowLayout layoutPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int x,
Packit b099d7
        int width,
Packit b099d7
        int marginW,
Packit b099d7
        int endX,
Packit b099d7
        int maxX,
Packit b099d7
        int endSpace,
Packit b099d7
        int betweenSpace )
Packit b099d7
#else
Packit b099d7
        Position x,
Packit b099d7
        Dimension width,
Packit b099d7
        Dimension marginW,
Packit b099d7
        Position endX,
Packit b099d7
        Position maxX,
Packit b099d7
        Dimension endSpace,
Packit b099d7
        Dimension betweenSpace )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{   
Packit b099d7
            Widget          holdEnd ;
Packit b099d7
            Dimension       spacedWidth ;
Packit b099d7
            Dimension       boxWidth ;
Packit b099d7
            Dimension       sumW ;
Packit b099d7
            int             amtOffset ;
Packit b099d7
            Dimension       totalFill ;
Packit b099d7
            Position        rowX ;
Packit b099d7
            XmKidGeometry   rowPtr ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    holdEnd = rowBoxes[numBoxes].kid ;
Packit b099d7
    rowBoxes[numBoxes].kid = NULL ;
Packit b099d7
Packit b099d7
    spacedWidth = (betweenSpace * (numBoxes - 1)) + (endSpace << 1) ;
Packit b099d7
    amtOffset = ((int) spacedWidth + (maxX - endX)) ;
Packit b099d7
    if(    (amtOffset > 0)  &&  (amtOffset < width)    )
Packit b099d7
    {   boxWidth = width - amtOffset ;
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   boxWidth = 1 ;
Packit b099d7
        } 
Packit b099d7
    sumW = boxWidth + spacedWidth ;
Packit b099d7
Packit b099d7
    amtOffset = ((int) sumW) - ((int) width) ;
Packit b099d7
    /* Setup the default spacing.
Packit b099d7
    */
Packit b099d7
    betweenSpace = layoutPtr->space_between ;
Packit b099d7
    endSpace = (layoutPtr->space_end < marginW) 
Packit b099d7
                                             ? marginW : layoutPtr->space_end ;
Packit b099d7
    switch(    layoutPtr->fill_mode    )
Packit b099d7
    {   case XmGEO_CENTER:
Packit b099d7
        {   
Packit b099d7
            /* Compute new spacing values to result in a centered
Packit b099d7
            *   layout when passed to the simple layout routine.
Packit b099d7
            */
Packit b099d7
            if(    width > sumW    )
Packit b099d7
            {   totalFill = (spacedWidth + width) - sumW ;
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   totalFill = marginW << 1 ;
Packit b099d7
                } 
Packit b099d7
            {   /* This little exercise is needed for when NeedWidePrototypes
Packit b099d7
                *   has value 1 which causes endSpace and betweenSpace to
Packit b099d7
                *   become "int"s, and a pointer to an int cannot be passed
Packit b099d7
                *   as an argument where a pointer to a dimension is required.
Packit b099d7
                */
Packit b099d7
                        Dimension eSpace ;
Packit b099d7
                        Dimension bSpace ;
Packit b099d7
                _XmGeoCalcFill( totalFill, marginW, numBoxes,
Packit b099d7
                                layoutPtr->space_end, layoutPtr->space_between,
Packit b099d7
                                                            &eSpace, &bSpace) ;
Packit b099d7
                endSpace = eSpace ;
Packit b099d7
                betweenSpace = bSpace ;
Packit b099d7
                } 
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        case XmGEO_PACK:
Packit b099d7
        {   /* For a packed layout, just layout with extra space
Packit b099d7
            *   at the end of the row.
Packit b099d7
            */
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        case XmGEO_EXPAND:
Packit b099d7
        default:
Packit b099d7
        {   /* FitBoxesProportional will fill if amtOffset < 0,
Packit b099d7
            *    as it is here.
Packit b099d7
            */
Packit b099d7
            FitBoxesProportional( rowBoxes, numBoxes, boxWidth, amtOffset) ;
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    rowX = x + endSpace ;
Packit b099d7
    rowPtr = rowBoxes ;
Packit b099d7
    while(    rowPtr->kid    )
Packit b099d7
    {   
Packit b099d7
        rowPtr->box.x = rowX ;
Packit b099d7
        rowX += rowPtr->box.width + (rowPtr->box.border_width << 1)
Packit b099d7
                                                               + betweenSpace ;
Packit b099d7
        ++rowPtr ;
Packit b099d7
        } 
Packit b099d7
    rowBoxes[numBoxes].kid = holdEnd ;
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * This routine lays out the row of boxes with the spacing specified in
Packit b099d7
 *   the endSpace and betweenSpace parameters.  If the width of a row
Packit b099d7
 *   which contains more than one box causes the right edge of the 
Packit b099d7
 *   row to be greater than maxX, then the boxes will wrap to the next
Packit b099d7
 *   line.
Packit b099d7
 * The Y coordinate of the space following the layout is returned.
Packit b099d7
 ****************/
Packit b099d7
static Position 
Packit b099d7
_XmGeoLayoutWrap(
Packit b099d7
        XmKidGeometry rowPtr,
Packit b099d7
        XmGeoRowLayout layoutPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int x,
Packit b099d7
        int y,
Packit b099d7
        int endSpace,
Packit b099d7
        int betweenSpace,
Packit b099d7
        int maxX,
Packit b099d7
        int width,
Packit b099d7
        int marginW )
Packit b099d7
#else
Packit b099d7
        Position x,
Packit b099d7
        Position y,
Packit b099d7
        Dimension endSpace,
Packit b099d7
        Dimension betweenSpace,
Packit b099d7
        Position maxX,
Packit b099d7
        Dimension width,
Packit b099d7
        Dimension marginW )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
            Position        rowX ;
Packit b099d7
            Dimension       rowH ;
Packit b099d7
            Position        boxMaxX ;
Packit b099d7
            unsigned int    numBoxes ;
Packit b099d7
            Dimension       boxH ;
Packit b099d7
            int             deltaW ;
Packit b099d7
            XmKidGeometry   rowBegin ;
Packit b099d7
    register XmKidGeometry  boxPtr ;
Packit b099d7
            Position        endX ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    rowX = x + endSpace ;
Packit b099d7
    rowH = layoutPtr->max_box_height ;
Packit b099d7
    numBoxes = 0 ;
Packit b099d7
    rowBegin = rowPtr ;
Packit b099d7
    boxPtr = rowPtr ;
Packit b099d7
    while(    boxPtr->kid    )
Packit b099d7
    {   boxMaxX = rowX + boxPtr->box.width + (boxPtr->box.border_width << 1) ;
Packit b099d7
Packit b099d7
        if(    (boxMaxX > maxX)  &&  numBoxes    )
Packit b099d7
        {   /* Wrap the line.  Also adjust preceding segment according to
Packit b099d7
            *   fill policy.
Packit b099d7
            */
Packit b099d7
            endX = rowX - betweenSpace ;
Packit b099d7
            SegmentFill( rowBegin, numBoxes, layoutPtr, x, width, 
Packit b099d7
                                 marginW, endX, maxX, endSpace, betweenSpace) ;
Packit b099d7
            numBoxes = 0 ;
Packit b099d7
            rowX = x + endSpace ;
Packit b099d7
            y += rowH ;
Packit b099d7
            rowBegin = boxPtr ;
Packit b099d7
            boxMaxX = rowX + boxPtr->box.width 
Packit b099d7
                                            + (boxPtr->box.border_width << 1) ;
Packit b099d7
            }
Packit b099d7
        if(    boxMaxX > maxX    )
Packit b099d7
        {   /* Since it wasn't wrapped, there must be only one box in this
Packit b099d7
            *   segment.  It is too wide, so simply truncate it.
Packit b099d7
            */
Packit b099d7
            deltaW = ((int) (endSpace + boxMaxX)) - ((int) (maxX + marginW)) ;
Packit b099d7
            if(    (deltaW < ((int) boxPtr->box.width))  &&  (deltaW > 0)    )
Packit b099d7
            {   boxPtr->box.width -= deltaW ;
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   boxPtr->box.width = 1 ;
Packit b099d7
                } 
Packit b099d7
            boxMaxX = rowX + boxPtr->box.width
Packit b099d7
                                            + (boxPtr->box.border_width << 1) ;
Packit b099d7
            } 
Packit b099d7
        boxPtr->box.x = rowX ;
Packit b099d7
        boxPtr->box.y = y ;
Packit b099d7
        boxH = boxPtr->box.height + (boxPtr->box.border_width << 1) ;
Packit b099d7
        if(    boxH != rowH    )
Packit b099d7
        {   /* If box height is not the same as the maximum box height
Packit b099d7
            *   of the row, then adjust y to center the box in the row.
Packit b099d7
            */
Packit b099d7
            boxPtr->box.y += (((int) rowH - (int) boxH) >> 1) ;
Packit b099d7
            } 
Packit b099d7
        rowX = boxMaxX + betweenSpace ;
Packit b099d7
        ++numBoxes ;
Packit b099d7
        ++boxPtr ;
Packit b099d7
        } 
Packit b099d7
    endX = rowX - betweenSpace ;
Packit b099d7
    SegmentFill( rowBegin, numBoxes, layoutPtr, x, width, 
Packit b099d7
                                 marginW, endX, maxX, endSpace, betweenSpace) ;
Packit b099d7
    if(    layoutPtr->sticky_end    )
Packit b099d7
    {   
Packit b099d7
        boxPtr = &rowPtr[layoutPtr->box_count - 1] ;
Packit b099d7
        endX = maxX - (boxPtr->box.width + (boxPtr->box.border_width << 1)) ;
Packit b099d7
        if(    endX > boxPtr->box.x    )
Packit b099d7
        {   boxPtr->box.x = endX ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return( y + rowH) ;
Packit b099d7
    }
Packit b099d7
/****************************************************************
Packit b099d7
 * This routine does a simple layout of the boxes in the row.  It assumes
Packit b099d7
 *   that all boxes have been conditioned to fit appropriately with the
Packit b099d7
 *   spacing specified by the endSpace and betweenSpace parameters.
Packit b099d7
 * The Y coordinate of the space following the layout is returned.
Packit b099d7
 ****************/
Packit b099d7
static Position 
Packit b099d7
_XmGeoLayoutSimple(
Packit b099d7
        XmKidGeometry rowPtr,
Packit b099d7
        XmGeoRowLayout layoutPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int x,
Packit b099d7
        int y,
Packit b099d7
        int maxX,
Packit b099d7
        int endSpace,
Packit b099d7
        int betweenSpace )
Packit b099d7
#else
Packit b099d7
        Position x,
Packit b099d7
        Position y,
Packit b099d7
        Position maxX,
Packit b099d7
        Dimension endSpace,
Packit b099d7
        Dimension betweenSpace )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
            Position        rowX ;
Packit b099d7
            Position        newX ;
Packit b099d7
            Dimension       rowH ;
Packit b099d7
            Dimension       boxH ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    rowH = layoutPtr->max_box_height ;
Packit b099d7
    rowX = x + endSpace ;
Packit b099d7
    while(    rowPtr->kid    )
Packit b099d7
    {   
Packit b099d7
        rowPtr->box.x = rowX ;
Packit b099d7
        rowPtr->box.y = y ;
Packit b099d7
        boxH = rowPtr->box.height + (rowPtr->box.border_width << 1) ;
Packit b099d7
        if(    boxH != rowH    )
Packit b099d7
        {   /* If box height is not the same as the maximum box height
Packit b099d7
            *   of the row, then adjust y to center the box in the row.
Packit b099d7
            */
Packit b099d7
            rowPtr->box.y += ((rowH - boxH) >> 1) ;
Packit b099d7
            } 
Packit b099d7
        rowX += rowPtr->box.width + (rowPtr->box.border_width << 1)
Packit b099d7
                                                               + betweenSpace ;
Packit b099d7
        ++rowPtr ;
Packit b099d7
        } 
Packit b099d7
    if(    layoutPtr->sticky_end    )
Packit b099d7
    {   
Packit b099d7
        --rowPtr ;
Packit b099d7
        newX = maxX - (rowPtr->box.width + (rowPtr->box.border_width << 1)) ;
Packit b099d7
        if(    newX > rowPtr->box.x    )
Packit b099d7
        {   rowPtr->box.x = newX ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return( y + rowH) ;
Packit b099d7
    }
Packit b099d7
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * This routines lays out the boxes in this row according to the specified
Packit b099d7
 *   paramaters and the policies specified in the layout record at layoutPtr.
Packit b099d7
 ****************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Position 
Packit b099d7
_XmGeoArrangeList(
Packit b099d7
        XmKidGeometry rowBoxes,
Packit b099d7
        XmGeoRowLayout layoutPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int x,
Packit b099d7
        int y,
Packit b099d7
        int width,
Packit b099d7
        int marginW,
Packit b099d7
        int marginH )		/* unused */
Packit b099d7
#else
Packit b099d7
        Position x,
Packit b099d7
        Position y,
Packit b099d7
        Dimension width,
Packit b099d7
        Dimension marginW,
Packit b099d7
        Dimension marginH )	/* unused */
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
            Dimension       sumW ;
Packit b099d7
            unsigned int    numBoxes ;
Packit b099d7
            Dimension       betweenBoxes ;
Packit b099d7
            Dimension       endsOfBoxes ;
Packit b099d7
            int             amtOffset ;
Packit b099d7
            Dimension       boxWidth ;
Packit b099d7
            Position        maxX ;
Packit b099d7
            Dimension       totalFill ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    numBoxes = layoutPtr->box_count ;
Packit b099d7
    boxWidth = layoutPtr->boxes_width ;
Packit b099d7
    sumW = boxWidth + layoutPtr->fill_width + (marginW << 1) ;
Packit b099d7
    amtOffset = ((int) sumW) - ((int) width) ;
Packit b099d7
    /* Setup the default spacing.
Packit b099d7
    */
Packit b099d7
    betweenBoxes = layoutPtr->space_between ;
Packit b099d7
    endsOfBoxes = (layoutPtr->space_end < marginW) 
Packit b099d7
                                             ? marginW : layoutPtr->space_end ;
Packit b099d7
    maxX = x + width - marginW ;
Packit b099d7
Packit b099d7
    if(    (sumW > width)  &&  (layoutPtr->fit_mode == XmGEO_WRAP)    )
Packit b099d7
    {   /* Wrapping is required, so fill routines and other policy decisions
Packit b099d7
        *   are not needed.  Do the layout using the wrap routine and we're 
Packit b099d7
        *   done.
Packit b099d7
        */
Packit b099d7
        y = _XmGeoLayoutWrap( rowBoxes, layoutPtr, x, y, endsOfBoxes,
Packit b099d7
                                          betweenBoxes, maxX, width, marginW) ;
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   if(    sumW > width    )
Packit b099d7
        {   switch(    layoutPtr->fit_mode    )
Packit b099d7
            {   case XmGEO_AVERAGING:
Packit b099d7
                {   FitBoxesAveraging( rowBoxes, numBoxes, boxWidth, 
Packit b099d7
                                                                   amtOffset) ;
Packit b099d7
                    break ;
Packit b099d7
                    } 
Packit b099d7
                case XmGEO_PROPORTIONAL:
Packit b099d7
                default:
Packit b099d7
                {   FitBoxesProportional( rowBoxes, numBoxes, boxWidth,
Packit b099d7
                                                                   amtOffset) ;
Packit b099d7
                    }
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        else 
Packit b099d7
        {   if(    sumW < width    )
Packit b099d7
            {   switch(    layoutPtr->fill_mode    )
Packit b099d7
                {   case XmGEO_CENTER:
Packit b099d7
                    {   
Packit b099d7
                        /* Compute new spacing values to result in a centered
Packit b099d7
                        *   layout when passed to the simple layout routine.
Packit b099d7
                        */
Packit b099d7
                        totalFill = (marginW << 1) + layoutPtr->fill_width
Packit b099d7
                                                               + width - sumW ;
Packit b099d7
                        _XmGeoCalcFill( totalFill, marginW, numBoxes, 
Packit b099d7
                                layoutPtr->space_end, layoutPtr->space_between,
Packit b099d7
                                                 &endsOfBoxes, &betweenBoxes) ;
Packit b099d7
                        break ;
Packit b099d7
                        } 
Packit b099d7
                    case XmGEO_PACK:
Packit b099d7
                    {   /* For a packed layout, just layout with extra space
Packit b099d7
                        *   at the end of the row.
Packit b099d7
                        */
Packit b099d7
                        break ;
Packit b099d7
                        } 
Packit b099d7
                    case XmGEO_EXPAND:
Packit b099d7
                    default:
Packit b099d7
                    {   /* FitBoxesProportional will fill if amtOffset < 0,
Packit b099d7
                        *    as it is here.
Packit b099d7
                        */
Packit b099d7
                        FitBoxesProportional( rowBoxes, numBoxes, boxWidth,
Packit b099d7
                                                                   amtOffset) ;
Packit b099d7
                        break ;
Packit b099d7
                        } 
Packit b099d7
                    } 
Packit b099d7
                }
Packit b099d7
            } 
Packit b099d7
        y = _XmGeoLayoutSimple( rowBoxes, layoutPtr, x, y, maxX,
Packit b099d7
                                                   endsOfBoxes, betweenBoxes) ;
Packit b099d7
        }
Packit b099d7
    return( y) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * Changes boxes in the kid geometry list to have desired width.
Packit b099d7
 * If width > 1, then use the specified width.  
Packit b099d7
 * If width == 1, then use the width of the widest box.
Packit b099d7
 * If width == 0, then do not change the boxes but return the width of
Packit b099d7
 *   the widest box.
Packit b099d7
 * Returns the value of the width actually used.
Packit b099d7
 ****************/
Packit b099d7
Dimension 
Packit b099d7
_XmGeoBoxesSameWidth(
Packit b099d7
        XmKidGeometry rowPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int width )
Packit b099d7
#else
Packit b099d7
        Dimension width )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
    register XmKidGeometry   boxPtr ;
Packit b099d7
    register Dimension       useW ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    useW = width ;  /* Setup default width of each box in row, as specified.*/
Packit b099d7
Packit b099d7
    if(    width <= 1    )
Packit b099d7
    {   
Packit b099d7
        /* If user specified width parameter of zero or one, then find the
Packit b099d7
        *   width of the widest box.
Packit b099d7
        */
Packit b099d7
        boxPtr = rowPtr ;
Packit b099d7
        while(    boxPtr->kid    )
Packit b099d7
        {   ASSIGN_MAX( useW, boxPtr->box.width) ;
Packit b099d7
            ++boxPtr ;
Packit b099d7
            } 
Packit b099d7
        }
Packit b099d7
    if(    width    )
Packit b099d7
    {   
Packit b099d7
        /* If width parameter is non-zero, then set the boxes appropriately.
Packit b099d7
        */
Packit b099d7
        boxPtr = rowPtr ;
Packit b099d7
        while(    boxPtr->kid    )
Packit b099d7
        {   boxPtr->box.width = useW ;
Packit b099d7
            ++boxPtr ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return( useW) ;
Packit b099d7
    }
Packit b099d7
/****************************************************************
Packit b099d7
 * Changes boxes in the kid geometry list to have desired height.
Packit b099d7
 * If height > 1, then use the specified height.  
Packit b099d7
 * If height == 1, then use the height of the tallest box.
Packit b099d7
 * If height == 0, then do not change the boxes but return the height of
Packit b099d7
 *   the tallest box.
Packit b099d7
 * Returns the value of the height actually used.
Packit b099d7
 ****************/
Packit b099d7
Dimension 
Packit b099d7
_XmGeoBoxesSameHeight(
Packit b099d7
        XmKidGeometry rowPtr,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int height )
Packit b099d7
#else
Packit b099d7
        Dimension height )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
    register XmKidGeometry   boxPtr ;
Packit b099d7
    register Dimension       useH ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    useH = height ; /* Setup default height of each box in row, as specified.*/
Packit b099d7
Packit b099d7
    if(    height <= 1    )
Packit b099d7
    {   
Packit b099d7
        /* If user specified height parameter of zero or one, then find the
Packit b099d7
        *   height of the tallest box.
Packit b099d7
        */
Packit b099d7
        boxPtr = rowPtr ;
Packit b099d7
        while(    boxPtr->kid    )
Packit b099d7
        {   ASSIGN_MAX( useH, boxPtr->box.height) ;
Packit b099d7
            ++boxPtr ;
Packit b099d7
            } 
Packit b099d7
        }
Packit b099d7
    if(    height    )
Packit b099d7
    {   
Packit b099d7
        /* If height parameter is non-zero, then set the boxes appropriately.
Packit b099d7
        */
Packit b099d7
        boxPtr = rowPtr ;
Packit b099d7
        while(    boxPtr->kid    )
Packit b099d7
        {   boxPtr->box.height = useH ;
Packit b099d7
            ++boxPtr ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return( useH) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/**************************************************************** ARGSUSED
Packit b099d7
 * This routine is a fixup routine which can be used for rows which consist
Packit b099d7
 *   of a single separator widget.  The effect of this routine is to have 
Packit b099d7
 *   the separator ignore the margin width.
Packit b099d7
 ****************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmSeparatorFix(
Packit b099d7
        XmGeoMatrix geoSpec,
Packit b099d7
        int action,
Packit b099d7
        XmGeoMajorLayout layoutPtr, /* unused */
Packit b099d7
        XmKidGeometry rowPtr )
Packit b099d7
{
Packit b099d7
    register Dimension       marginW ;
Packit b099d7
    register Dimension       twoMarginW ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    marginW = geoSpec->margin_w ;
Packit b099d7
    twoMarginW = (marginW << 1) ;
Packit b099d7
Packit b099d7
    switch(    action    )
Packit b099d7
    {   
Packit b099d7
        case XmGEO_PRE_SET:
Packit b099d7
        {   rowPtr->box.x -= marginW ;
Packit b099d7
            rowPtr->box.width += twoMarginW ;
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        default:
Packit b099d7
        {   if(    rowPtr->box.width > twoMarginW    )
Packit b099d7
            {   
Packit b099d7
                /* Avoid subtracting a margin from box width which would
Packit b099d7
                *   result in underflow.
Packit b099d7
                */
Packit b099d7
                rowPtr->box.x += marginW ;
Packit b099d7
                rowPtr->box.width -= twoMarginW ;
Packit b099d7
                } 
Packit b099d7
            if(    action == XmGET_PREFERRED_SIZE    )
Packit b099d7
            {   
Packit b099d7
                /* Set width to some small value so it does not 
Packit b099d7
                *   effect total width of matrix.
Packit b099d7
                */
Packit b099d7
                rowPtr->box.width = 1 ;
Packit b099d7
                } 
Packit b099d7
            break ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return ;
Packit b099d7
    } 
Packit b099d7
Packit b099d7

Packit b099d7
/**************************************************************** ARGSUSED
Packit b099d7
 * This routine is a fixup routine which can be used for rows which consist
Packit b099d7
 *   of a single MenuBar RowColumn.  The effect of this routine is to have
Packit b099d7
 *   the RowColumn ignore the margin width and height.
Packit b099d7
 ****************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void
Packit b099d7
_XmMenuBarFix(
Packit b099d7
        XmGeoMatrix geoSpec,
Packit b099d7
        int action,
Packit b099d7
        XmGeoMajorLayout layoutPtr, /* unused */
Packit b099d7
        XmKidGeometry rowPtr )
Packit b099d7
{
Packit b099d7
    register Dimension       marginW ;
Packit b099d7
    register Dimension       marginH ;
Packit b099d7
    register Dimension       twoMarginW ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    marginW = geoSpec->margin_w ;
Packit b099d7
    twoMarginW = (marginW << 1) ;
Packit b099d7
    marginH = geoSpec->margin_h ;
Packit b099d7
Packit b099d7
    switch(    action    )
Packit b099d7
    {
Packit b099d7
        case XmGEO_PRE_SET:
Packit b099d7
        {   rowPtr->box.x -= marginW ;
Packit b099d7
            rowPtr->box.width += twoMarginW ;
Packit b099d7
            rowPtr->box.y -= marginH ;
Packit b099d7
            break ;
Packit b099d7
            }
Packit b099d7
        default:
Packit b099d7
        {   if(    rowPtr->box.width > twoMarginW    )
Packit b099d7
            {
Packit b099d7
                /* Avoid subtracting a margin from box width which would
Packit b099d7
                *   result in underflow.
Packit b099d7
                */
Packit b099d7
                rowPtr->box.x += marginW ;
Packit b099d7
                rowPtr->box.width -= twoMarginW ;
Packit b099d7
                }
Packit b099d7
            if(    action == XmGET_PREFERRED_SIZE    )
Packit b099d7
            {
Packit b099d7
                /* Set width to some small value so it does not
Packit b099d7
                *   effect total width of matrix.
Packit b099d7
                */
Packit b099d7
                rowPtr->box.width = 1 ;
Packit b099d7
                }
Packit b099d7
            break ;
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
    return ;
Packit b099d7
    } 
Packit b099d7
Packit b099d7
/****************************************************************/
Packit b099d7
void 
Packit b099d7
_XmGeoLoadValues(
Packit b099d7
        Widget wid,
Packit b099d7
        int geoType,
Packit b099d7
        Widget instigator,
Packit b099d7
        XtWidgetGeometry *request,
Packit b099d7
        XtWidgetGeometry *geoResult )
Packit b099d7
{   
Packit b099d7
            XtWidgetGeometry reply ;
Packit b099d7
            XtWidgetGeometry * geoSource ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    if(    wid == instigator    )
Packit b099d7
    {   /* If this widget is making the request, then use the request info.
Packit b099d7
        */
Packit b099d7
        geoSource = request ;
Packit b099d7
        } 
Packit b099d7
    else
Packit b099d7
    {   geoSource = &reply ;
Packit b099d7
Packit b099d7
        switch(    geoType    )
Packit b099d7
        {   
Packit b099d7
            case XmGET_PREFERRED_SIZE:
Packit b099d7
            {   XtQueryGeometry( wid, NULL, &reply) ;
Packit b099d7
                break ;
Packit b099d7
                } 
Packit b099d7
            case XmGET_ACTUAL_SIZE:
Packit b099d7
            default:
Packit b099d7
            {   reply.request_mode = 0 ;  /* Will cause geoSpec to be loaded.*/
Packit b099d7
                break ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    geoResult->x = IsX( geoSource) ? geoSource->x : XtX( wid) ;
Packit b099d7
    geoResult->y = IsY( geoSource) ? geoSource->y : XtY( wid) ;
Packit b099d7
    geoResult->width = IsWidth( geoSource) ? geoSource->width : XtWidth( wid) ;
Packit b099d7
    geoResult->height = IsHeight( geoSource) 
Packit b099d7
                                         ? geoSource->height : XtHeight( wid) ;
Packit b099d7
    geoResult->border_width = IsBorder( geoSource) 
Packit b099d7
                              ? geoSource->border_width : XtBorderWidth( wid) ;
Packit b099d7
    geoResult->request_mode = CWX | CWY | CWWidth | CWHeight | CWBorderWidth ;
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * Get a count of the managed kids of a parent, it is assumed that all 
Packit b099d7
 *   gadgets are always managed
Packit b099d7
 ****************/
Packit b099d7
int 
Packit b099d7
_XmGeoCount_kids(
Packit b099d7
        register CompositeWidget c )
Packit b099d7
{   
Packit b099d7
    register int i, n = 0 ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    for(    i = 0 ; i < c->composite.num_children ; i++    )
Packit b099d7
    {   
Packit b099d7
        if(    c->composite.children[i]->core.managed    ) 
Packit b099d7
        {   n++ ;
Packit b099d7
            } 
Packit b099d7
        }
Packit b099d7
    return( n) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/**************************************************************** ARGSUSED
Packit b099d7
 * Assemble a kid box for each child widget and gadget, fill in data about 
Packit b099d7
 *   each widget and optionally set up uniform border widths.
Packit b099d7
 * Returns a list of records, last one has a 'kid' field of NULL.  This memory
Packit b099d7
 *   for this list should eventually be freed with a call to XtFree().
Packit b099d7
 ****************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
XmKidGeometry 
Packit b099d7
_XmGetKidGeo(
Packit b099d7
        Widget wid,                     /* Widget w/ children. */
Packit b099d7
        Widget instigator,              /* May point to a child who */
Packit b099d7
        XtWidgetGeometry *request,      /*   is asking to change. */
Packit b099d7
        int uniform_border,             /* T/F, enforce it. */
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int border,
Packit b099d7
#else
Packit b099d7
        Dimension border,               /* Value to use if enforcing.*/
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        int uniform_width_margins,      /* unused.  T/F, enforce it. */
Packit b099d7
        int uniform_height_margins,     /* unused.  T/F, enforce it. */
Packit b099d7
        Widget help,                    /* May point to a help kid. */
Packit b099d7
        int geo_type )                  /* Actual or preferred. */
Packit b099d7
{   
Packit b099d7
            CompositeWidget c = (CompositeWidget) wid ;
Packit b099d7
            XmKidGeometry   geo ;
Packit b099d7
            Widget          kidWid ;
Packit b099d7
            int             i ;
Packit b099d7
            int             j = 0 ;
Packit b099d7
            Boolean         helpFound = FALSE ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    geo = (XmKidGeometry) XtMalloc( 
Packit b099d7
                            (_XmGeoCount_kids (c) + 1) * sizeof (XmKidGeometryRec)) ;
Packit b099d7
    /* load all managed kids */
Packit b099d7
    for(    i = 0 ; i < c->composite.num_children ; i++    )
Packit b099d7
    {   
Packit b099d7
        kidWid = c->composite.children[i] ;
Packit b099d7
        if(    XtIsManaged( kidWid)    )
Packit b099d7
        {   if(    kidWid == help    )
Packit b099d7
            {   /* Save to put help widget at the end of the widget list.*/
Packit b099d7
                helpFound = TRUE ;
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   geo[j].kid = kidWid ;
Packit b099d7
Packit b099d7
                _XmGeoLoadValues( kidWid, geo_type, instigator, request,
Packit b099d7
                                                               &(geo[j].box)) ;
Packit b099d7
                if(    uniform_border    )     /* if asked override border */
Packit b099d7
                {   geo[j].box.border_width = border ;
Packit b099d7
                    } 
Packit b099d7
                j++ ;
Packit b099d7
                }
Packit b099d7
            } 
Packit b099d7
        }
Packit b099d7
    if(    helpFound    )                 /* put help guy into list */
Packit b099d7
    {   
Packit b099d7
        geo[j].kid = help ;
Packit b099d7
Packit b099d7
        _XmGeoLoadValues( help, geo_type, instigator, request, &(geo[j].box)) ;
Packit b099d7
Packit b099d7
        if(    uniform_border    )         /* if asked override border */
Packit b099d7
        {   geo[j].box.border_width = border ;
Packit b099d7
            } 
Packit b099d7
        j++ ;
Packit b099d7
        }
Packit b099d7
    geo[j].kid = NULL ;                /* signal end of list */
Packit b099d7
Packit b099d7
    return( geo) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************/
Packit b099d7
void 
Packit b099d7
_XmGeoClearRectObjAreas(
Packit b099d7
        RectObj r,
Packit b099d7
        XWindowChanges *old )
Packit b099d7
{
Packit b099d7
            Widget          parent = XtParent( r) ;
Packit b099d7
            int             bw2 ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    bw2 = old->border_width << 1;
Packit b099d7
    XClearArea( XtDisplay( parent), XtWindow( parent), old->x, old->y,
Packit b099d7
                                   old->width + bw2, old->height + bw2, TRUE) ;
Packit b099d7
Packit b099d7
    bw2 = r->rectangle.border_width << 1;
Packit b099d7
    XClearArea( XtDisplay( parent), XtWindow( parent), (int) r->rectangle.x,
Packit b099d7
               (int) r->rectangle.y, (unsigned int) (r->rectangle.width + bw2),
Packit b099d7
                            (unsigned int) (r->rectangle.height + bw2), TRUE) ;
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/**************************************************************** ARGSUSED
Packit b099d7
 * Take the kid geometry array and change each kid to match them.
Packit b099d7
 *   remember not to do the resize of the instigator.
Packit b099d7
 * The kid geometry "kg" is assumed to be fully specified.
Packit b099d7
 ****************/
Packit b099d7
void 
Packit b099d7
_XmSetKidGeo(
Packit b099d7
        XmKidGeometry kg,
Packit b099d7
        Widget instigator )
Packit b099d7
{   
Packit b099d7
    Widget          w ;
Packit b099d7
    XtWidgetGeometry * b ;
Packit b099d7
    int             i ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    for(    i=0 ; kg[i].kid != NULL ; i++    )  {   
Packit b099d7
        w = (Widget) kg[i].kid ;
Packit b099d7
        b = &(kg[i].box) ;
Packit b099d7
Packit b099d7
        if(    w != instigator    ) {   
Packit b099d7
	    XmeConfigureObject( w, b->x, b->y,
Packit b099d7
			       b->width, b->height, b->border_width) ;
Packit b099d7
	}  else {   
Packit b099d7
	    XtX( w) = b->x ;
Packit b099d7
	    XtY( w) = b->y ;
Packit b099d7
	    XtWidth( w) = b->width ;
Packit b099d7
	    XtHeight( w) = b->height ;
Packit b099d7
	    XtBorderWidth( w) = b->border_width ;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    return ;
Packit b099d7
}
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * Returns TRUE if all specified geometries of geoA are equal to either the
Packit b099d7
 *   specified geometries of geoB or to the geometry of the widget, and 
Packit b099d7
 *   vice versa.  The XtCWQueryOnly bit is ignored.
Packit b099d7
 ****************/
Packit b099d7
Boolean 
Packit b099d7
_XmGeometryEqual(
Packit b099d7
        Widget wid,
Packit b099d7
        XtWidgetGeometry *geoA,
Packit b099d7
        XtWidgetGeometry *geoB )
Packit b099d7
{
Packit b099d7
/****************/
Packit b099d7
    if(!geoA){ /* For fixing OSF CR 5956 */
Packit b099d7
         return(False);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if(    IsWidth( geoA)  ||  IsWidth( geoB)    )
Packit b099d7
    {   
Packit b099d7
        if(    IsWidth( geoA)  &&  IsWidth( geoB)    )
Packit b099d7
        {   if(    geoA->width != geoB->width    )
Packit b099d7
            {   return( FALSE) ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   if(    IsWidth( geoA)    )
Packit b099d7
            {   if(    geoA->width != XtWidth( wid)    )
Packit b099d7
                {   return( FALSE) ;
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   if(    IsWidth( geoB)    )
Packit b099d7
                {   if(    geoB->width != XtWidth( wid)    )
Packit b099d7
                    {   return( FALSE) ;
Packit b099d7
                        } 
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    if(    IsHeight( geoA)  ||  IsHeight( geoB)    )
Packit b099d7
    {   
Packit b099d7
        if(    IsHeight( geoA)  &&  IsHeight( geoB)    )
Packit b099d7
        {   if(    geoA->height != geoB->height    )
Packit b099d7
            {   return( FALSE) ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   if(    IsHeight( geoA)    )
Packit b099d7
            {   if(    geoA->height != XtHeight( wid)    )
Packit b099d7
                {   return( FALSE) ;
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   if(    IsHeight( geoB)    )
Packit b099d7
                {   if(    geoB->height != XtHeight( wid)    )
Packit b099d7
                    {   return( FALSE) ;
Packit b099d7
                        } 
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    if(    IsBorder( geoA)  ||  IsBorder( geoB)    )
Packit b099d7
    {   
Packit b099d7
        if(    IsBorder( geoA)  &&  IsBorder( geoB)    )
Packit b099d7
        {   if(    geoA->border_width != geoB->border_width    )
Packit b099d7
            {   return( FALSE) ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   if(    IsBorder( geoA)    )
Packit b099d7
            {   if(    geoA->border_width != XtBorderWidth( wid)    )
Packit b099d7
                {   return( FALSE) ;
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   if(    IsBorder( geoB)    )
Packit b099d7
                {   if(    geoB->border_width != XtBorderWidth( wid)    )
Packit b099d7
                    {   return( FALSE) ;
Packit b099d7
                        } 
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    if(    IsX( geoA)  ||  IsX( geoB)    )
Packit b099d7
    {   
Packit b099d7
        if(    IsX( geoA)  &&  IsX( geoB)    )
Packit b099d7
        {   if(    geoA->x != geoB->x    )
Packit b099d7
            {   return( FALSE) ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   if(    IsX( geoA)    )
Packit b099d7
            {   if(    geoA->x != XtX( wid)    )
Packit b099d7
                {   return( FALSE) ;
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   if(    IsX( geoB)    )
Packit b099d7
                {   if(    geoB->x != XtX( wid)    )
Packit b099d7
                    {   return( FALSE) ;
Packit b099d7
                        } 
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    if(    IsY( geoA)  ||  IsY( geoB)    )
Packit b099d7
    {   
Packit b099d7
        if(    IsY( geoA)  &&  IsY( geoB)    )
Packit b099d7
        {   if(    geoA->y != geoB->y    )
Packit b099d7
            {   return( FALSE) ;
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        else
Packit b099d7
        {   if(    IsY( geoA)    )
Packit b099d7
            {   if(    geoA->y != XtY( wid)    )
Packit b099d7
                {   return( FALSE) ;
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            else
Packit b099d7
            {   if(    IsY( geoB)    )
Packit b099d7
                {   if(    geoB->y != XtY( wid)    )
Packit b099d7
                    {   return( FALSE) ;
Packit b099d7
                        } 
Packit b099d7
                    } 
Packit b099d7
                } 
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return( TRUE) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * Returns TRUE if all specified geometries of "desired" correspond to
Packit b099d7
 *   specified geometries of "response" and are equal to them.
Packit b099d7
 * The XtCWQueryOnly bit is ignored.
Packit b099d7
 ****************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
Boolean 
Packit b099d7
_XmGeoReplyYes(
Packit b099d7
        Widget wid,		/* unused */
Packit b099d7
        XtWidgetGeometry *desired,
Packit b099d7
        XtWidgetGeometry *response )
Packit b099d7
{
Packit b099d7
/****************/
Packit b099d7
    if(!response){ /* For fixing OSF CR 5956 */
Packit b099d7
         return(False); 
Packit b099d7
    }
Packit b099d7
    if(    IsWidth( desired)    )
Packit b099d7
    {   
Packit b099d7
        if(    !IsWidth( response)
Packit b099d7
            || (desired->width != response->width)    )
Packit b099d7
        {   
Packit b099d7
            return( FALSE) ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    if(    IsHeight( desired)    )
Packit b099d7
    {   
Packit b099d7
        if(    !IsHeight( response)
Packit b099d7
            || (desired->height != response->height)    )
Packit b099d7
        {   
Packit b099d7
            return( FALSE) ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    if(    IsBorder( desired)    )
Packit b099d7
    {   
Packit b099d7
        if(    !IsBorder( response)
Packit b099d7
            || (desired->border_width != response->border_width)    )
Packit b099d7
        {   
Packit b099d7
            return( FALSE) ;
Packit b099d7
            } 
Packit b099d7
        }
Packit b099d7
    if(    IsX( desired)    )
Packit b099d7
    {   
Packit b099d7
        if(    !IsX( response)
Packit b099d7
            || (desired->x != response->x)    )
Packit b099d7
        {   
Packit b099d7
            return( FALSE) ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    if(    IsY( desired)    )
Packit b099d7
    {   
Packit b099d7
        if(    !IsY( response)
Packit b099d7
            || (desired->y != response->y)    )
Packit b099d7
        {   
Packit b099d7
            return( FALSE) ;
Packit b099d7
            } 
Packit b099d7
        } 
Packit b099d7
    return( TRUE) ;
Packit b099d7
    }
Packit b099d7

Packit b099d7
/****************************************************************
Packit b099d7
 * This routine calls the geometry manager and accept the almost
Packit b099d7
 ****************/
Packit b099d7
XtGeometryResult 
Packit b099d7
_XmMakeGeometryRequest(
Packit b099d7
        Widget w,
Packit b099d7
        XtWidgetGeometry *geom )
Packit b099d7
{
Packit b099d7
  XtWidgetGeometry allowed ;
Packit b099d7
  XtGeometryResult answer ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
  answer = XtMakeGeometryRequest( w, geom, &allowed) ;
Packit b099d7
Packit b099d7
  /* On an almost, accept the returned value and make 
Packit b099d7
   *   a second request to get an XtGeometryYes returned.
Packit b099d7
   */
Packit b099d7
  if(    answer == XtGeometryAlmost    )
Packit b099d7
    {   
Packit b099d7
      /* The Intrinsics protocol guarantees a Yes response
Packit b099d7
       * to a request with identical geometry to that which
Packit b099d7
       * was returned by a previous request returning almost.
Packit b099d7
       */
Packit b099d7
      *geom = allowed ;
Packit b099d7
      answer = XtMakeGeometryRequest( w, geom, &allowed) ;
Packit b099d7
    }
Packit b099d7
  return answer ;
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/****************************************************************/
Packit b099d7
#ifdef DEBUG_GEOUTILS
Packit b099d7
/****************************************************************/
Packit b099d7
void
Packit b099d7
PrintBox(
Packit b099d7
            char *          hdr,
Packit b099d7
            XmKidGeometry   box)
Packit b099d7
/****************
Packit b099d7
 * 
Packit b099d7
 ****************/
Packit b099d7
{
Packit b099d7
/****************/
Packit b099d7
    printf( "%sw: %X, m: 0x%X, x: %d, y: %d, w: %d, h: %d, b: %d\n",
Packit b099d7
                  hdr, box->kid, box->box.request_mode, box->box.x, box->box.y,
Packit b099d7
                      box->box.width, box->box.height, box->box.border_width) ;
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7
/****************************************************************/
Packit b099d7
void
Packit b099d7
PrintList(
Packit b099d7
            char *          hdr,
Packit b099d7
            XmKidGeometry   listPtr)
Packit b099d7
/****************
Packit b099d7
 * 
Packit b099d7
 ****************/
Packit b099d7
{
Packit b099d7
            int             num ;
Packit b099d7
            char            subhdr[256] ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    num = 0 ;
Packit b099d7
    while(    listPtr->kid    )
Packit b099d7
    {   sprintf( subhdr, "%si: %d ", hdr, num) ;
Packit b099d7
        PrintBox( subhdr, listPtr) ;
Packit b099d7
        ++num ;
Packit b099d7
        ++listPtr ;
Packit b099d7
        } 
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
/****************************************************************/
Packit b099d7
void
Packit b099d7
PrintMatrix(
Packit b099d7
            char *          hdr,
Packit b099d7
            XmGeoMatrix     spec)
Packit b099d7
/****************
Packit b099d7
 * 
Packit b099d7
 ****************/
Packit b099d7
{
Packit b099d7
            int             row ;
Packit b099d7
            int             col ;
Packit b099d7
            XmKidGeometry   boxPtr ;
Packit b099d7
            XmGeoRowLayout  layoutPtr ;
Packit b099d7
            char            subhdr[256] ;
Packit b099d7
/****************/
Packit b099d7
    row = 1 ;
Packit b099d7
    boxPtr = spec->boxes ;
Packit b099d7
    layoutPtr = spec->layouts.row ;
Packit b099d7
    while(    !(layoutPtr->end)    )
Packit b099d7
    {   col = 1 ;
Packit b099d7
        while(    boxPtr->kid    )
Packit b099d7
        {   sprintf( subhdr, "%srow: %d, col: %d, ", hdr, row, col) ;
Packit b099d7
            PrintBox( subhdr, boxPtr) ;
Packit b099d7
            ++col ;
Packit b099d7
            ++boxPtr ;
Packit b099d7
            } 
Packit b099d7
        ++row ;
Packit b099d7
        ++boxPtr ;
Packit b099d7
        ++layoutPtr ;
Packit b099d7
        } 
Packit b099d7
    return ;
Packit b099d7
    }
Packit b099d7
/****************************************************************/
Packit b099d7
#endif /* DEBUG_GEOUTILS */
Packit b099d7
/****************************************************************/