Blame lib/Xm/IconBox.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
Packit b099d7
/************************************************************
Packit b099d7
*	INCLUDE FILES
Packit b099d7
*************************************************************/
Packit b099d7
#include <stdio.h>
Packit b099d7
Packit b099d7
#include "XmI.h"
Packit b099d7
#include <Xm/IconBoxP.h>
Packit b099d7
#include <Xm/ExtP.h>
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	TYPEDEFS AND DEFINES
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
#define SUPERCLASS ((WidgetClass) &xmManagerClassRec)
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	MACROS
Packit b099d7
*************************************************************/
Packit b099d7
#define GetIconInfo(w) ((IconInfo*) \
Packit b099d7
           &(((XmIconBoxConstraintsRec*)((char*)((w)->core.constraints)))->icon))
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	GLOBAL DECLARATIONS
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC FUNCTION DECLARATIONS
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
static void ClassInitialize();
Packit b099d7
static void ClassPartInitialize(WidgetClass w_class);
Packit b099d7
static void Realize(Widget, Mask *, XSetWindowAttributes *);
Packit b099d7
static void Resize(Widget), ChangeManaged(Widget), InsertChild(Widget);
Packit b099d7
static void Initialize(Widget, Widget, ArgList, Cardinal *);
Packit b099d7
static void ConstraintInitialize(Widget, Widget, ArgList, Cardinal *);
Packit b099d7
static Boolean ConstraintSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
Packit b099d7
Packit b099d7
static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
Packit b099d7
Packit b099d7
static XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *,
Packit b099d7
					XtWidgetGeometry *);
Packit b099d7
static XtGeometryResult QueryGeometry(Widget,
Packit b099d7
				      XtWidgetGeometry *, XtWidgetGeometry *);
Packit b099d7
Packit b099d7
/************************
Packit b099d7
 * Actions and callbacks.
Packit b099d7
 ************************/
Packit b099d7
Packit b099d7
/*********************
Packit b099d7
 * Internal Routines.
Packit b099d7
 *********************/
Packit b099d7
Packit b099d7
static void FindNearestCellLocation(Widget, Position *, Position *);
Packit b099d7
static void GetMinCells(Widget, Cardinal *, Cardinal *);
Packit b099d7
static void PlaceChildren(Widget, Widget);
Packit b099d7
static void GetMaxCellSize(Widget, Widget, Dimension *, Dimension *);
Packit b099d7
static void GetCellFromXY(Widget, Position, Position, Position *, Position *);
Packit b099d7
static void GetXYFromCell(Widget, IconInfo *, Position *, Position *);
Packit b099d7
static void CalcCellSizes(Widget, Widget,
Packit b099d7
			  Boolean, Boolean, Dimension *, Dimension *);
Packit b099d7
Packit b099d7
static Boolean SetToEmptyCell(Widget);
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC DECLARATIONS
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
static XtResource resources[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNminimumVerticalCells, XmCDefaultCells, XmRDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmIconBoxRec, box.min_v_cells),
Packit b099d7
    XmRImmediate, (XtPointer) 2
Packit b099d7
  },
Packit b099d7
  {
Packit b099d7
    XmNminimumHorizontalCells, XmCDefaultCells, XmRHorizontalDimension, 
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmIconBoxRec, box.min_h_cells),
Packit b099d7
    XmRImmediate, (XtPointer) 2
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNminimumCellWidth, XmCMinimumCellSize, XmRHorizontalDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmIconBoxRec, box.min_cell_width),
Packit b099d7
    XmRImmediate, (XtPointer) 20
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNminimumCellHeight, XmCMinimumCellSize, XmRDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmIconBoxRec, box.min_cell_height),
Packit b099d7
    XmRImmediate, (XtPointer) 10
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNverticalMargin, XmCMargin, XmRVerticalDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmIconBoxRec, box.v_margin),
Packit b099d7
    XmRImmediate, (XtPointer) 4
Packit b099d7
  },
Packit b099d7
  
Packit b099d7
  {
Packit b099d7
    XmNhorizontalMargin, XmCMargin, XmRHorizontalDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmIconBoxRec, box.h_margin),
Packit b099d7
    XmRImmediate, (XtPointer) 4
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
static XmSyntheticResource get_resources[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNhorizontalMargin, sizeof(Dimension),
Packit b099d7
    XtOffsetOf(XmIconBoxRec, box.h_margin),
Packit b099d7
    XmeFromHorizontalPixels, (XmImportProc) XmeToHorizontalPixels
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNverticalMargin, sizeof(Dimension),
Packit b099d7
    XtOffsetOf(XmIconBoxRec, box.v_margin),
Packit b099d7
    XmeFromVerticalPixels, (XmImportProc) XmeToVerticalPixels
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNminimumCellWidth, sizeof(Dimension),
Packit b099d7
    XtOffsetOf(XmIconBoxRec, box.min_cell_width),
Packit b099d7
    XmeFromHorizontalPixels, (XmImportProc) XmeToHorizontalPixels
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNminimumCellHeight, sizeof(Dimension),
Packit b099d7
    XtOffsetOf(XmIconBoxRec, box.min_cell_height),
Packit b099d7
    XmeFromVerticalPixels, (XmImportProc) XmeToVerticalPixels
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
static short G_any_cell = XmIconBoxAnyCell;
Packit b099d7
Packit b099d7
static XtResource constraints[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNcellX, XmCCellX, XmRShort,
Packit b099d7
    sizeof(short), XtOffsetOf(XmIconBoxConstraintsRec, icon.cell_x),
Packit b099d7
    XmRShort, (XtPointer) &G_any_cell
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNcellY, XmCCellY, XmRShort,
Packit b099d7
    sizeof(short), XtOffsetOf(XmIconBoxConstraintsRec, icon.cell_y),
Packit b099d7
    XmRShort, (XtPointer) &G_any_cell
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
 
Packit b099d7
XmIconBoxClassRec xmIconBoxClassRec = {
Packit b099d7
  { /* core fields */
Packit b099d7
    /* superclass		*/	SUPERCLASS,
Packit b099d7
    /* class_name		*/	"XmIconBox",
Packit b099d7
    /* widget_size		*/	sizeof(XmIconBoxRec),
Packit b099d7
    /* class_initialize		*/	ClassInitialize,
Packit b099d7
    /* class_part_initialize	*/	ClassPartInitialize,
Packit b099d7
    /* class_inited		*/	FALSE,
Packit b099d7
    /* initialize		*/	Initialize,
Packit b099d7
    /* initialize_hook		*/	NULL,
Packit b099d7
    /* realize			*/	Realize,
Packit b099d7
    /* actions			*/	NULL,
Packit b099d7
    /* num_actions		*/	0,
Packit b099d7
    /* resources		*/	(XtResource*)resources,
Packit b099d7
    /* num_resources		*/	XtNumber(resources),
Packit b099d7
    /* xrm_class		*/	NULLQUARK,
Packit b099d7
    /* compress_motion		*/	TRUE,
Packit b099d7
    /* compress_exposure	*/	TRUE,
Packit b099d7
    /* compress_enterleave	*/	TRUE,
Packit b099d7
    /* visible_interest		*/	FALSE,
Packit b099d7
    /* destroy			*/	NULL,
Packit b099d7
    /* resize			*/	Resize,
Packit b099d7
    /* expose			*/	NULL,
Packit b099d7
    /* set_values		*/	SetValues,
Packit b099d7
    /* set_values_hook		*/	NULL,
Packit b099d7
    /* set_values_almost	*/	XtInheritSetValuesAlmost,
Packit b099d7
    /* get_values_hook		*/	NULL,
Packit b099d7
    /* accept_focus		*/	NULL,
Packit b099d7
    /* version			*/	XtVersion,
Packit b099d7
    /* callback_private		*/	NULL,
Packit b099d7
    /* tm_table			*/	XtInheritTranslations,
Packit b099d7
    /* query_geometry		*/	(XtGeometryHandler) QueryGeometry,
Packit b099d7
    /* display_accelerator	*/	XtInheritDisplayAccelerator,
Packit b099d7
    /* extension		*/	NULL
Packit b099d7
  },
Packit b099d7
   {		/* composite_class fields */
Packit b099d7
    /* geometry_manager   */      GeometryManager,
Packit b099d7
    /* change_managed     */      ChangeManaged,
Packit b099d7
    /* insert_child       */      InsertChild,			
Packit b099d7
    /* delete_child       */      XtInheritDeleteChild,			
Packit b099d7
    /* extension          */      NULL,                                     
Packit b099d7
   },
Packit b099d7
   {		/* constraint_class fields */
Packit b099d7
    /* resource list        */         (XtResource*)constraints,
Packit b099d7
    /* num resources        */         XtNumber(constraints),	
Packit b099d7
    /* constraint size      */         sizeof(XmIconBoxConstraintsRec),
Packit b099d7
    /* init proc            */         ConstraintInitialize,
Packit b099d7
    /* destroy proc         */         NULL,
Packit b099d7
    /* set values proc      */         ConstraintSetValues,
Packit b099d7
    /* extension            */         NULL, 
Packit b099d7
   },
Packit b099d7
   {		/* manager_class fields */
Packit b099d7
    /* default translations   */      XtInheritTranslations,	
Packit b099d7
    /* syn_resources          */      get_resources,
Packit b099d7
    /* num_syn_resources      */      XtNumber(get_resources),
Packit b099d7
    /* syn_cont_resources     */      NULL,
Packit b099d7
    /* num_syn_cont_resources */      0,
Packit b099d7
    /* parent_process         */      XmInheritParentProcess,
Packit b099d7
    /* extension	      */      NULL,	
Packit b099d7
   },
Packit b099d7
  { /* Icon Box fields */
Packit b099d7
      NULL                      /* extension          */
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
WidgetClass xmIconBoxWidgetClass = (WidgetClass)&xmIconBoxClassRec;
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC CODE
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: Initialize
Packit b099d7
 *	Description:   Called to initialize information specific
Packit b099d7
 *                     to this widget.
Packit b099d7
 *	Arguments:     req - what was originally requested.
Packit b099d7
 *                     set - what will be created (our superclassed have
Packit b099d7
 *                           already mucked with this)
Packit b099d7
 *                     args, num_args - The arguments passed to 
Packit b099d7
 *                                      the creation call.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
Packit b099d7
static void
Packit b099d7
ClassInitialize()
Packit b099d7
{
Packit b099d7
  /* do nothing */
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
Initialize(Widget req, Widget set, ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) set;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * This is needed so that the right thing happens if an icon box is 
Packit b099d7
     * created w/o any children.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    CalcCellSizes(set, NULL, FALSE, FALSE, 
Packit b099d7
		  &(XmIconBox_cell_width(ibw)), &(XmIconBox_cell_height(ibw)));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: Realize
Packit b099d7
 *	Description:   Called to realize this widget.
Packit b099d7
 *	Arguments:     w - Widget to realize.
Packit b099d7
 *                     valueMask, attributes - attributes to use when creating
Packit b099d7
 *                     this widget's window.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 *
Packit b099d7
 * This overrides the Manager's frobbing with various values.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void 
Packit b099d7
Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
Packit b099d7
{
Packit b099d7
    XtCreateWindow (w, InputOutput, CopyFromParent, *valueMask, attributes);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: Resize
Packit b099d7
 *	Description:   Called when this widget has been resized.
Packit b099d7
 *	Arguments:     w - the widget to resize. 
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void 
Packit b099d7
Resize(Widget w)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
Packit b099d7
    CalcCellSizes(w, NULL, TRUE, FALSE, 
Packit b099d7
		  &(XmIconBox_cell_width(ibw)), &(XmIconBox_cell_height(ibw)));
Packit b099d7
    PlaceChildren(w, NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: SetValues
Packit b099d7
 *	Description:   Called when some widget data needs to be modified on-
Packit b099d7
 *                     the-fly.
Packit b099d7
 *	Arguments:     current - the current (old) widget values.
Packit b099d7
 *                     request - before superclassed have changed things.
Packit b099d7
 *                     set - what will acutally be the set values. 
Packit b099d7
 *                     args, num_args - the arguments in the list.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
SetValues(Widget current, Widget request, Widget set,
Packit b099d7
	  ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget old_ibw = (XmIconBoxWidget) current;
Packit b099d7
    XmIconBoxWidget set_ibw = (XmIconBoxWidget) set;
Packit b099d7
Packit b099d7
    if ((XmIconBox_min_v_cells(old_ibw) != XmIconBox_min_v_cells(set_ibw))           ||
Packit b099d7
	(XmIconBox_min_h_cells(old_ibw) != XmIconBox_min_h_cells(set_ibw))           ||
Packit b099d7
	(XmIconBox_min_cell_width(old_ibw) != XmIconBox_min_cell_width(set_ibw))     ||
Packit b099d7
	(XmIconBox_min_cell_height(old_ibw) != XmIconBox_min_cell_height(set_ibw))   ||
Packit b099d7
	(XmIconBox_v_margin(old_ibw) != XmIconBox_v_margin(set_ibw))                 ||
Packit b099d7
	(XmIconBox_h_margin(old_ibw) != XmIconBox_h_margin(set_ibw)) ) 
Packit b099d7
    {
Packit b099d7
	CalcCellSizes(set, NULL, FALSE, FALSE, 
Packit b099d7
		      &(XmIconBox_cell_width(set_ibw)), &(XmIconBox_cell_height(set_ibw)));
Packit b099d7
	PlaceChildren(set, NULL);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return(FALSE);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: QueryGeometry
Packit b099d7
 *	Description:   Called when my parent wants to know what size
Packit b099d7
 *                     I would like to be.
Packit b099d7
 *	Arguments:     w - the widget to check.
Packit b099d7
 *                     indended - constriants imposed by the parent.
Packit b099d7
 *                     preferred - what I would like.
Packit b099d7
 *	Returns:       See Xt Manual.
Packit b099d7
 */
Packit b099d7
    
Packit b099d7
static XtGeometryResult 
Packit b099d7
QueryGeometry(Widget w,XtWidgetGeometry *intended, XtWidgetGeometry *preferred)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
    Cardinal min_x, min_y;
Packit b099d7
    Dimension max_w, max_h;
Packit b099d7
Packit b099d7
    GetMinCells(w, &min_x, &min_y);
Packit b099d7
    GetMaxCellSize(w, NULL, &max_w, &max_h);
Packit b099d7
Packit b099d7
    min_x++;
Packit b099d7
    min_y++;
Packit b099d7
Packit b099d7
    preferred->width = XmIconBox_h_margin(ibw) + min_x * (max_w + XmIconBox_h_margin(ibw));
Packit b099d7
    preferred->height= XmIconBox_v_margin(ibw) + min_y * (max_h + XmIconBox_v_margin(ibw));
Packit b099d7
Packit b099d7
    return(_XmHWQuery(w, intended, preferred));
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Composite and Constraint Information.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: GeometryManager
Packit b099d7
 *	Description:   handles requests from children for a size change.
Packit b099d7
 *	Arguments:     child - the child to change.
Packit b099d7
 *                     request - the geometry that the child wants.
Packit b099d7
 *                     return - what we will allow if this is an almost.
Packit b099d7
 *	Returns:       status.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static XtGeometryResult
Packit b099d7
GeometryManager(Widget w, XtWidgetGeometry * request, 
Packit b099d7
		XtWidgetGeometry * result)
Packit b099d7
{
Packit b099d7
    Dimension cwidth, cheight;
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) XtParent(w);
Packit b099d7
    IconInfo * info = GetIconInfo(w);
Packit b099d7
    Boolean w_req = (request->request_mode & CWWidth);
Packit b099d7
    Boolean h_req = (request->request_mode & CWHeight);
Packit b099d7
    Boolean x_req = (request->request_mode & CWX);
Packit b099d7
    Boolean y_req = (request->request_mode & CWY);
Packit b099d7
Packit b099d7
    if (!(request->request_mode & (CWWidth | CWHeight | CWX | CWY)))
Packit b099d7
	return(XtGeometryNo);
Packit b099d7
    
Packit b099d7
    result->request_mode = 0;
Packit b099d7
Packit b099d7
    if (w_req || h_req) {
Packit b099d7
	CalcCellSizes((Widget) ibw, w, FALSE, TRUE, &cwidth, &cheight);
Packit b099d7
Packit b099d7
	if(w_req)
Packit b099d7
	    ASSIGN_MAX(cwidth, request->width);
Packit b099d7
	else
Packit b099d7
	    ASSIGN_MAX(cwidth, w->core.width);
Packit b099d7
	
Packit b099d7
	if(h_req)
Packit b099d7
	    ASSIGN_MAX(cheight, request->height);
Packit b099d7
	else
Packit b099d7
	    ASSIGN_MAX(cheight, w->core.height);
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * Do not allow an x, y width and height request at the same time.
Packit b099d7
	 * since it is unclear what this would mean.  I want to place the
Packit b099d7
	 * widget in the cell the center of it is over.  With a multiple
Packit b099d7
	 * request like this is it tough to find out which cell to use
Packit b099d7
	 * since there are two reasonable values for height and width.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	result->x = w->core.x;
Packit b099d7
	result->y = w->core.y;
Packit b099d7
	result->width  = cwidth;
Packit b099d7
	result->height = cheight;
Packit b099d7
	result->request_mode |= CWX | CWY | CWHeight | CWWidth;
Packit b099d7
    }
Packit b099d7
    else if ( x_req || y_req ) {
Packit b099d7
	Position x, y;
Packit b099d7
	short cell_x, cell_y;
Packit b099d7
Packit b099d7
	if (x_req) 
Packit b099d7
	    x = request->x;
Packit b099d7
	else
Packit b099d7
	    x = w->core.x;
Packit b099d7
Packit b099d7
	if (y_req)
Packit b099d7
	    y = request->y;
Packit b099d7
	else
Packit b099d7
	    y = w->core.y;
Packit b099d7
Packit b099d7
	FindNearestCellLocation((Widget) ibw, &x, &y);
Packit b099d7
Packit b099d7
	GetCellFromXY((Widget) ibw, x, y, &cell_x, &cell_y);
Packit b099d7
	if (XmIconBoxIsCellEmpty((Widget) ibw, cell_x, cell_y, w)) {
Packit b099d7
	    result->x = x;
Packit b099d7
	    result->y = y;
Packit b099d7
	    result->request_mode |= CWX | CWY;
Packit b099d7
	}
Packit b099d7
	else			/* Cell is full, return NO. */
Packit b099d7
	    return(XtGeometryNo);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (((request->x == result->x) || !x_req) &&
Packit b099d7
	((request->y == result->y) || !y_req) &&
Packit b099d7
	((request->width == result->width) || !w_req) &&
Packit b099d7
	((request->height == result->height) || !h_req))
Packit b099d7
    {
Packit b099d7
	if (request->request_mode & 
Packit b099d7
	    (CWBorderWidth | CWStackMode | CWSibling)) 
Packit b099d7
	{
Packit b099d7
	    return(XtGeometryAlmost);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (request->request_mode & XtCWQueryOnly) 
Packit b099d7
	    return(XtGeometryYes);
Packit b099d7
Packit b099d7
	if (w_req || h_req) {
Packit b099d7
	    if (w_req) 
Packit b099d7
		info->pref_width = w->core.width = request->width;
Packit b099d7
Packit b099d7
	    if (h_req)
Packit b099d7
		info->pref_height = w->core.height = request->height;
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
	    /*
Packit b099d7
	     * NOTE: We are assuming here that the cell height/width
Packit b099d7
	     * did not change.  This is valid because this code is
Packit b099d7
	     * only executed if w_req and h_req are false.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    GetCellFromXY((Widget) ibw, result->x, result->y, 
Packit b099d7
			  &(info->cell_x), &(info->cell_y));
Packit b099d7
	}
Packit b099d7
	    
Packit b099d7
	CalcCellSizes((Widget) ibw, NULL, FALSE, FALSE, 
Packit b099d7
		      &(XmIconBox_cell_width(ibw)), &(XmIconBox_cell_height(ibw)));
Packit b099d7
Packit b099d7
	PlaceChildren((Widget) ibw, w);
Packit b099d7
	return(XtGeometryYes);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    info->pref_width = info->pref_height = 0; /* invalidate cache. */
Packit b099d7
Packit b099d7
    if (((request->x == result->x) || !x_req)         ||
Packit b099d7
	((request->y == result->y) || !y_req)         ||
Packit b099d7
	((request->width == result->width) || !w_req) ||
Packit b099d7
	((request->height == result->height) || !h_req))
Packit b099d7
    {
Packit b099d7
	return(XtGeometryAlmost);
Packit b099d7
    }
Packit b099d7
    else 
Packit b099d7
	return(XtGeometryNo);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: InsertChild
Packit b099d7
 *	Description: called when a new child is to be added.
Packit b099d7
 *	Arguments: w - the new child.
Packit b099d7
 *	Returns: none.
Packit b099d7
 *
Packit b099d7
 * This routine simply makes sure that no gadgets are added.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void 
Packit b099d7
InsertChild(Widget w)
Packit b099d7
{
Packit b099d7
   if (_XmGadgetWarning(w))
Packit b099d7
       return;
Packit b099d7
Packit b099d7
   {
Packit b099d7
      XtWidgetProc insert_child;
Packit b099d7
Packit b099d7
      _XmProcessLock();
Packit b099d7
      insert_child = ( (CompositeWidgetClass) SUPERCLASS)->composite_class.insert_child;
Packit b099d7
      _XmProcessUnlock();
Packit b099d7
Packit b099d7
      (*insert_child)(w);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ChangeManaged
Packit b099d7
 *	Description:   When a management change has occured...
Packit b099d7
 *	Arguments:     w - the icon box widget.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ChangeManaged(Widget w)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
    Widget * childp;
Packit b099d7
Packit b099d7
    CalcCellSizes(w, NULL, FALSE, TRUE, 
Packit b099d7
		  &(XmIconBox_cell_width(ibw)), &(XmIconBox_cell_height(ibw)));
Packit b099d7
Packit b099d7
    ForAllChildren(ibw, childp) {   
Packit b099d7
	IconInfo * info = GetIconInfo(*childp);
Packit b099d7
Packit b099d7
	if ((info->cell_x != XmIconBoxAnyCell) && 
Packit b099d7
	    (info->cell_y != XmIconBoxAnyCell) &&
Packit b099d7
	    !XmIconBoxIsCellEmpty((Widget) ibw, 
Packit b099d7
				  info->cell_x, info->cell_y, *childp))
Packit b099d7
	{
Packit b099d7
	    static String params[1];
Packit b099d7
	    Cardinal num = 1;
Packit b099d7
	    char buf[BUFSIZ];
Packit b099d7
	    
Packit b099d7
	    params[0] = buf;
Packit b099d7
	    snprintf(buf, BUFSIZ, "(%d, %d)", info->cell_x, info->cell_y);
Packit b099d7
	    
Packit b099d7
	    _XmWarningMsg(w, XmNcellNotEmpty,
Packit b099d7
		    XmNcellNotEmptyMsg, params, num);
Packit b099d7
	    /*
Packit b099d7
	     * tell it to reset this to an empty cell.
Packit b099d7
	     */
Packit b099d7
	    
Packit b099d7
	    info->cell_y = XmIconBoxAnyCell; 
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if ((info->cell_x == XmIconBoxAnyCell) || 
Packit b099d7
	    (info->cell_y == XmIconBoxAnyCell))
Packit b099d7
	{
Packit b099d7
	    Position x = (*childp)->core.x;
Packit b099d7
	    Position y = (*childp)->core.y;
Packit b099d7
	    Position cell_x, cell_y;
Packit b099d7
	    
Packit b099d7
	    /*
Packit b099d7
	     * If the cell location is not specified try to find the
Packit b099d7
	     * cell nearest the X and Y coords specified.
Packit b099d7
	     */
Packit b099d7
	    
Packit b099d7
	    FindNearestCellLocation((Widget) ibw, &x, &y);
Packit b099d7
	    GetCellFromXY((Widget) ibw, x, y, &cell_x, &cell_y);
Packit b099d7
	    
Packit b099d7
	    if (XmIconBoxIsCellEmpty((Widget) ibw, cell_x, cell_y, w))
Packit b099d7
	    {
Packit b099d7
		info->cell_x = cell_x;
Packit b099d7
		info->cell_y = cell_y;
Packit b099d7
	    }
Packit b099d7
	    /*
Packit b099d7
	     * If this cell is full the just find any empty cell.
Packit b099d7
	     */
Packit b099d7
	    else if (!SetToEmptyCell(*childp)) {
Packit b099d7
		XmeWarning(w, XmNnoEmptyCellsMsg);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    CalcCellSizes(w, NULL, FALSE, FALSE, 
Packit b099d7
		  &(XmIconBox_cell_width(ibw)), &(XmIconBox_cell_height(ibw)));
Packit b099d7
Packit b099d7
    PlaceChildren(w, NULL);
Packit b099d7
Packit b099d7
   XmeNavigChangeManaged(w);	/* For Motif navigation */
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * ClassPartInitialize sets up the fast subclassing for the widget.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
#ifdef _NO_PROTO
Packit b099d7
ClassPartInitialize(w_class)
Packit b099d7
        WidgetClass w_class ;
Packit b099d7
#else
Packit b099d7
ClassPartInitialize(WidgetClass w_class)
Packit b099d7
#endif /* _NO_PROTO */
Packit b099d7
{
Packit b099d7
    _XmFastSubclassInit (w_class, XmICONBOX_BIT);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*	Function Name: ConstraintInitialize
Packit b099d7
 *	Description:   Called when a childs constriaints need initializing.
Packit b099d7
 *	Arguments:     req - the widget being requested.
Packit b099d7
 *                     set - what this will become.
Packit b099d7
 *                     args, num_args - the argument list.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
ConstraintInitialize(Widget req, Widget set, ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    IconInfo * info = GetIconInfo(set);
Packit b099d7
Packit b099d7
    info->pref_width = req->core.width;
Packit b099d7
    info->pref_height = req->core.height;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ConstraintSetValues
Packit b099d7
 *	Description:   Called when some constraint data needs to be modified 
Packit b099d7
 *                     on-the-fly.
Packit b099d7
 *	Arguments:     current - the current (old) widget values.
Packit b099d7
 *                     request - before superclassed have changed things.
Packit b099d7
 *                     set - what will acutally be the new values. 
Packit b099d7
 *                     args, num_args - the arguments in the list.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
ConstraintSetValues(Widget current, Widget request, Widget set,
Packit b099d7
		    ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    IconInfo * set_info = GetIconInfo(set);
Packit b099d7
    IconInfo * old_info = GetIconInfo(current);
Packit b099d7
Packit b099d7
    if (set->core.width != set_info->pref_width)
Packit b099d7
	set_info->pref_width = 0;
Packit b099d7
Packit b099d7
    if (set->core.height != set_info->pref_height)
Packit b099d7
	set_info->pref_height = 0;
Packit b099d7
Packit b099d7
    if ((set_info->cell_x != old_info->cell_x) ||
Packit b099d7
	(set_info->cell_y != old_info->cell_y)) 
Packit b099d7
    {
Packit b099d7
	if ( XmIconBoxIsCellEmpty(XtParent(set), 
Packit b099d7
				  set_info->cell_x, set_info->cell_y, set)) 
Packit b099d7
	{
Packit b099d7
	    GetXYFromCell(XtParent(set), 
Packit b099d7
			  set_info, &(set->core.x), &(set->core.y));
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
	    static String params[1];
Packit b099d7
	    Cardinal num = 1;
Packit b099d7
	    char buf[BUFSIZ];
Packit b099d7
	    
Packit b099d7
	    params[0] = buf;
Packit b099d7
	    snprintf(buf, BUFSIZ, "(%d, %d)", set_info->cell_x, set_info->cell_y);
Packit b099d7
Packit b099d7
	    _XmWarningMsg(set, XmNcellNotEmpty,
Packit b099d7
		    XmNcellNotEmptyMsg, params, num);
Packit b099d7
Packit b099d7
	    set_info->cell_x = old_info->cell_x;
Packit b099d7
	    set_info->cell_y = old_info->cell_y;
Packit b099d7
	}			 
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    return(False);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Actions and Callbacks.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Internal routines.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: GetCellFromXY
Packit b099d7
 *	Description:   Gets the cell located at this location.
Packit b099d7
 *	Arguments:     w - the icon box.
Packit b099d7
 *                     x, y - the coordinates in X space.
Packit b099d7
 * RETURNED            cell_x, cell_y - the corrdinates in cell space.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
GetCellFromXY(Widget w, 
Packit b099d7
	      Position x, Position y, Position * cell_x, Position * cell_y)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
    
Packit b099d7
    *cell_x = (int)x / (int)(XmIconBox_cell_width(ibw) + XmIconBox_h_margin(ibw));
Packit b099d7
    *cell_y = (int)y / (int)(XmIconBox_cell_height(ibw) + XmIconBox_v_margin(ibw));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: Find Nearest Cell Location
Packit b099d7
 *	Description: Finds the nearest cell
Packit b099d7
 *	Arguments: ibw - the icon box widget.
Packit b099d7
 * IN/OUT          x, y - Used as an input for the current location
Packit b099d7
 *                        is output with the new location.
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
FindNearestCellLocation(Widget w, Position *x, Position *y)
Packit b099d7
{
Packit b099d7
    IconInfo temp;
Packit b099d7
    Dimension width, height;
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
Packit b099d7
    width = XmIconBox_cell_width(ibw);
Packit b099d7
    height = XmIconBox_cell_height(ibw);
Packit b099d7
Packit b099d7
    GetCellFromXY(w, *x + width/2, 
Packit b099d7
		  *y + height/2, &(temp.cell_x), &(temp.cell_y));
Packit b099d7
    
Packit b099d7
    GetXYFromCell(w, &temp, x, y);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetXYFromCell
Packit b099d7
 *	Description:   Gets the X and Y position for this cell.
Packit b099d7
 *	Arguments:     info - the cell info.
Packit b099d7
 * RETURNED            x, y - the coordinates in X space.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
GetXYFromCell(Widget w, IconInfo * info, Position * x, Position * y)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
    Position x_temp = (info->cell_x < 0) ? 0 : info->cell_x;
Packit b099d7
    Position y_temp = (info->cell_y < 0) ? 0 : info->cell_y;
Packit b099d7
Packit b099d7
    *x = XmIconBox_h_margin(ibw) + 
Packit b099d7
	 x_temp * (XmIconBox_cell_width(ibw) + XmIconBox_h_margin(ibw));
Packit b099d7
    
Packit b099d7
    *y = XmIconBox_v_margin(ibw) + 
Packit b099d7
	 y_temp * (XmIconBox_cell_height(ibw) + XmIconBox_v_margin(ibw));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: PlaceChildren
Packit b099d7
 *	Description:   Places all managed children correctly.
Packit b099d7
 *	Arguments:     w - the icon box widget.
Packit b099d7
 *                     child - set attributes rather than configure this child.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void 
Packit b099d7
PlaceChildren(Widget w, Widget child)
Packit b099d7
{
Packit b099d7
    Widget * childp;
Packit b099d7
    Position x, y;
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
Packit b099d7
    ForAllChildren(ibw, childp) {
Packit b099d7
	if (!XtIsManaged(*childp))
Packit b099d7
	    continue;
Packit b099d7
Packit b099d7
	GetXYFromCell(w, GetIconInfo(*childp), &x, &y);
Packit b099d7
Packit b099d7
	if (*childp == child) {
Packit b099d7
	    child->core.x = x;
Packit b099d7
	    child->core.y = y;
Packit b099d7
	    child->core.width = XmIconBox_cell_width(ibw);
Packit b099d7
	    child->core.height = XmIconBox_cell_height(ibw);
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
	    _XmConfigureWidget(*childp, x, y, 
Packit b099d7
			       XmIconBox_cell_width(ibw), XmIconBox_cell_height(ibw),
Packit b099d7
			       (*childp)->core.border_width);
Packit b099d7
	}	
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: CalcCellSizes
Packit b099d7
 *	Description:   Calculates the height and width of each cell.
Packit b099d7
 *	Arguments:     w - the icon box widget.
Packit b099d7
 *                     ignore - ignore this child when calculating cell sizes.
Packit b099d7
 *                     noresize - If true then never attempt a resize.
Packit b099d7
 *                     query_only - only ask, don't change anything.
Packit b099d7
 *                     cell_width, cell_height - new size of each cell.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
CalcCellSizes(Widget w, Widget ignore, Boolean noresize, Boolean query_only, 
Packit b099d7
	      Dimension * cell_width, Dimension * cell_height)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
Packit b099d7
    Cardinal min_x, min_y;
Packit b099d7
    Dimension max_w, max_h, d_width, d_height, width, height;
Packit b099d7
    
Packit b099d7
    GetMinCells(w, &min_x, &min_y);
Packit b099d7
    GetMaxCellSize(w, ignore, &max_w, &max_h);
Packit b099d7
Packit b099d7
    min_x++;
Packit b099d7
    min_y++;
Packit b099d7
Packit b099d7
    d_width = XmIconBox_h_margin(ibw) + min_x * (max_w + XmIconBox_h_margin(ibw));
Packit b099d7
    d_height = XmIconBox_v_margin(ibw) + min_y * (max_h + XmIconBox_v_margin(ibw));
Packit b099d7
Packit b099d7
    if (noresize ||
Packit b099d7
	(_XmRequestNewSize(w, query_only, d_width, d_height, 
Packit b099d7
			   &width, &height) != XtGeometryYes))
Packit b099d7
    {
Packit b099d7
	if (noresize) {
Packit b099d7
	    width = w->core.width;
Packit b099d7
	    height = w->core.height;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * We may need to adjust the cell size.
Packit b099d7
	 */
Packit b099d7
	
Packit b099d7
	if (width < d_width)
Packit b099d7
	    max_w = (width - XmIconBox_h_margin(ibw))/ min_x - XmIconBox_h_margin(ibw); 
Packit b099d7
	if (height < d_height)
Packit b099d7
	    max_h = (height - XmIconBox_v_margin(ibw))/ min_y - XmIconBox_v_margin(ibw); 
Packit b099d7
    }
Packit b099d7
Packit b099d7
    *cell_width = max_w;
Packit b099d7
    *cell_height = max_h;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetMinCells
Packit b099d7
 *	Description:   Returns the minimum number of cells that should
Packit b099d7
 *                     be displayed in each direction.
Packit b099d7
 *	Arguments:     w - the Icon Box widget.
Packit b099d7
 * RETURN              min_x, min_y - minimum number of cells needed
Packit b099d7
 *                                    in each direction.
Packit b099d7
 *                     
Packit b099d7
 *	Returns:       
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
GetMinCells(Widget w, Cardinal * min_x, Cardinal * min_y)
Packit b099d7
{
Packit b099d7
    Widget * childp;
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
Packit b099d7
    *min_x = XmIconBox_min_h_cells(ibw) - 1;
Packit b099d7
    *min_y = XmIconBox_min_v_cells(ibw) - 1;
Packit b099d7
Packit b099d7
    ForAllChildren(ibw, childp) {
Packit b099d7
	Position x, y;
Packit b099d7
	IconInfo * info;
Packit b099d7
Packit b099d7
	if (!XtIsManaged(*childp))
Packit b099d7
	    continue;
Packit b099d7
Packit b099d7
	info = GetIconInfo(*childp);
Packit b099d7
Packit b099d7
	x = (info->cell_x < 0) ? 0 : info->cell_x;
Packit b099d7
	y = (info->cell_y < 0) ? 0 : info->cell_y;
Packit b099d7
Packit b099d7
	if (x > *min_x)
Packit b099d7
	    *min_x = x;
Packit b099d7
Packit b099d7
	if (y > *min_y)
Packit b099d7
	    *min_y = y;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetMaxCellSize
Packit b099d7
 *	Description:   Gets the maximum size of each cell.
Packit b099d7
 *	Arguments:     w - the Icon Box widget.
Packit b099d7
 *                     ignore - ignore this child.
Packit b099d7
 *                     max_w, max_h - the maximum size of each cell.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
GetMaxCellSize(Widget w, Widget ignore, Dimension * max_w, Dimension * max_h)
Packit b099d7
{
Packit b099d7
    Widget * childp;
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
    XtWidgetGeometry preferred;
Packit b099d7
    register Dimension temp;
Packit b099d7
Packit b099d7
    *max_w = XmIconBox_min_cell_width(ibw);
Packit b099d7
    *max_h = XmIconBox_min_cell_height(ibw);
Packit b099d7
Packit b099d7
    ForAllChildren(ibw, childp) {
Packit b099d7
	IconInfo * info = GetIconInfo(*childp);
Packit b099d7
Packit b099d7
	if (!XtIsManaged(*childp) || (*childp == ignore))
Packit b099d7
	    continue;
Packit b099d7
Packit b099d7
	if ((info->pref_width != 0) && (info->pref_height != 0)) {
Packit b099d7
	    preferred.width = info->pref_width;
Packit b099d7
	    preferred.height = info->pref_height;
Packit b099d7
	    preferred.border_width = (*childp)->core.border_width;
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
	    (void) XtQueryGeometry(*childp, NULL, &preferred);
Packit b099d7
	    info->pref_width = preferred.width;
Packit b099d7
	    info->pref_height = preferred.height;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	temp = preferred.width + 2 * preferred.border_width;
Packit b099d7
	ASSIGN_MAX(*max_w, temp);
Packit b099d7
Packit b099d7
	temp = preferred.height + 2 * preferred.border_width;
Packit b099d7
	ASSIGN_MAX(*max_h, temp);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: SetToEmptyCell
Packit b099d7
 *	Description:   Puts the widget passed into an empty node as
Packit b099d7
 *                     close to 0, 0 as possible.
Packit b099d7
 *	Arguments:     child - the child.
Packit b099d7
 *	Returns:       True if an empty cell was found.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
SetToEmptyCell(Widget child)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) XtParent(child);
Packit b099d7
Packit b099d7
    register Position x, y, cur_x, cur_y;
Packit b099d7
    register unsigned long square, cur_square;
Packit b099d7
    Cardinal max_x, max_y;
Packit b099d7
Packit b099d7
    GetMinCells((Widget) ibw, &max_x, &max_y);
Packit b099d7
Packit b099d7
    cur_x = cur_y = XmIconBoxAnyCell;
Packit b099d7
    cur_square = max_x * max_x + max_y * max_y;
Packit b099d7
Packit b099d7
    for (y = 0; y <= max_y; y++) 
Packit b099d7
	for (x = 0; x <= max_x; x++) {
Packit b099d7
	    square = x * x + y * y;
Packit b099d7
Packit b099d7
	    if (square <= cur_square &&
Packit b099d7
		XmIconBoxIsCellEmpty(XtParent(child), x, y, NULL)) {
Packit b099d7
		cur_square = square;
Packit b099d7
		cur_x = x;
Packit b099d7
		cur_y = y;
Packit b099d7
		break;
Packit b099d7
	    }
Packit b099d7
	    else if (square >= cur_square)
Packit b099d7
		continue;
Packit b099d7
	}
Packit b099d7
Packit b099d7
    if (cur_x == XmIconBoxAnyCell) {
Packit b099d7
	IconInfo * info = GetIconInfo(child);
Packit b099d7
Packit b099d7
	info->cell_x = 0;
Packit b099d7
	info->cell_y = max_y + 1;
Packit b099d7
    }
Packit b099d7
    else {
Packit b099d7
	IconInfo * info = GetIconInfo(child);
Packit b099d7
Packit b099d7
	info->cell_x = cur_x;
Packit b099d7
	info->cell_y = cur_y;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return(TRUE);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Public Functions.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: XmIconBoxIsCellEmpty
Packit b099d7
 *	Description:   Returns true if this cell is unused.
Packit b099d7
 *	Arguments:     w - the icon box.
Packit b099d7
 *                     x, y - cell to check.
Packit b099d7
 *                     ignore - ignore this widget when checking.
Packit b099d7
 *	Returns:       Returns true if this cell is unused.
Packit b099d7
 */
Packit b099d7
Packit b099d7
Boolean
Packit b099d7
XmIconBoxIsCellEmpty(Widget w, Position x, Position y, Widget ignore)
Packit b099d7
{
Packit b099d7
    XmIconBoxWidget ibw = (XmIconBoxWidget) w;
Packit b099d7
    Widget * childp;
Packit b099d7
Packit b099d7
    _XmWidgetToAppContext(w);
Packit b099d7
    _XmAppLock(app);
Packit b099d7
Packit b099d7
    ForAllChildren(ibw, childp) {   
Packit b099d7
	IconInfo * info;
Packit b099d7
Packit b099d7
	if (!XtIsManaged(*childp) || 
Packit b099d7
	    (*childp == ignore) || (*childp)->core.being_destroyed)
Packit b099d7
	{
Packit b099d7
	    continue;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	info = GetIconInfo(*childp);
Packit b099d7
	if ((x == info->cell_x) && (y == info->cell_y))
Packit b099d7
	  {
Packit b099d7
	    _XmAppUnlock(app);
Packit b099d7
	    return(False);
Packit b099d7
	  }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    _XmAppUnlock(app);
Packit b099d7
    return(True);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: XmCreateIconBox
Packit b099d7
 *	Description: Creation Routine for UIL and ADA.
Packit b099d7
 *	Arguments: parent - the parent widget.
Packit b099d7
 *                 name - the name of the widget.
Packit b099d7
 *                 args, num_args - the number and list of args.
Packit b099d7
 *	Returns: The created widget.
Packit b099d7
 */
Packit b099d7
Packit b099d7
Widget
Packit b099d7
XmCreateIconBox(Widget parent, String name,
Packit b099d7
		ArgList args, Cardinal num_args)
Packit b099d7
{
Packit b099d7
    return(XtCreateWidget(name, xmIconBoxWidgetClass, parent, args, num_args));
Packit b099d7
}