Blame lib/Xm/Outline.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
#include <Xm/OutlineP.h>
Packit b099d7
#include <Xm/DropSMgr.h>
Packit b099d7
#include "XmI.h"
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	TYPEDEFS AND DEFINES
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
#define SUPERCLASS (&xmHierarchyClassRec)
Packit b099d7
#define DEF_INDENT_SPACE 30
Packit b099d7
Packit b099d7
#define MOVE_TIME    200
Packit b099d7
Packit b099d7
typedef struct {
Packit b099d7
  int x;
Packit b099d7
  int y;
Packit b099d7
} LadderPoint;
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	MACROS
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 Resize(Widget), ClassPartInitialize(WidgetClass);
Packit b099d7
static void Redisplay(Widget, XEvent *, Region);
Packit b099d7
static void Initialize(Widget, Widget, ArgList, Cardinal *);
Packit b099d7
static void Destroy(Widget widget);
Packit b099d7
static void ConstraintInitialize(Widget, Widget, ArgList, Cardinal *);
Packit b099d7
static void ConstraintDestroy(Widget);
Packit b099d7
static void ToggleNodeState(Widget, XtPointer, XtPointer);
Packit b099d7
Packit b099d7
static XtGeometryResult QueryGeometry(Widget, 
Packit b099d7
				      XtWidgetGeometry *, XtWidgetGeometry *);
Packit b099d7
Packit b099d7
static Boolean ConstraintSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
Packit b099d7
static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal*);
Packit b099d7
Packit b099d7
static XtGeometryResult GeometryManager(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 Bool CheckExpose(Display *, XEvent *, char *);
Packit b099d7
static OutlineConstraints GetNodeInfo(Widget);
Packit b099d7
static int CalcMaxWidth(Widget);
Packit b099d7
static void ChangeManaged(Widget);
Packit b099d7
static void RequestNewSize(Widget), CalcLocations(Widget, Boolean);
Packit b099d7
static void GetNodeDimensions(Widget, OutlineConstraints, 
Packit b099d7
			      Cardinal, Cardinal *);
Packit b099d7
static void GetNodeHeightAndWidth(Widget, OutlineConstraints,
Packit b099d7
				  Cardinal, Boolean, Cardinal *);
Packit b099d7
static void GetDesiredSize(Widget, Dimension*, Dimension*,
Packit b099d7
			   Dimension *, Dimension *,
Packit b099d7
			   Boolean, Boolean);
Packit b099d7
static void LayoutChildren(Widget, Widget);
Packit b099d7
static Boolean LocInRect(XRectangle *, Widget, Position, Position);
Packit b099d7
static Boolean WidgetInRect(XRectangle *, Widget);
Packit b099d7
static Boolean CheckWidget(XRectangle *, OutlineConstraints);
Packit b099d7
static void ProcessChildQueue(XmOutlineWidget, XRectangle *);
Packit b099d7
static void MoveNode(XmOutlineWidget, OutlineConstraints, Position,
Packit b099d7
		     Position, Position, Position, Boolean);
Packit b099d7
static void ProcessNode(OutlineConstraints);
Packit b099d7
static Boolean MoveNodesTimer(XtPointer);
Packit b099d7
static void UnmapNode(XmOutlineWidget ow, OutlineConstraints node);
Packit b099d7
static void UnmapAllExtraNodes(Widget w, HierarchyConstraints node);
Packit b099d7
static void NegotiateNodeWidth(Widget w, OutlineConstraints node);
Packit b099d7
Packit b099d7
static void RedrawOutlineLines(Widget, XRectangle *);
Packit b099d7
static void DrawOutlineLine(Widget, XRectangle *, OutlineConstraints);
Packit b099d7
static void _CalcNodeMidPoint( OutlineConstraints node, Widget w, LadderPoint *ret_point );
Packit b099d7
static void _OutlineDrawLine(Widget w, XRectangle *rect, OutlineConstraints parent, 
Packit b099d7
	  OutlineConstraints child, LadderPoint from_ladder_point,
Packit b099d7
	  LadderPoint *to_ladder_point );
Packit b099d7
static void CreateGC(XmOutlineWidget ow);
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC DECLARATIONS
Packit b099d7
*************************************************************/
Packit b099d7
static XtResource resources[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNindentSpace, XmCIndentSpace, XmRHorizontalDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmOutlineRec, outline.indent_space),
Packit b099d7
    XmRImmediate, (XtPointer)DEF_INDENT_SPACE
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNconstrainWidth, XmCConstrainWidth, XmRBoolean,
Packit b099d7
    sizeof(Boolean), XtOffsetOf(XmOutlineRec, outline.constrain_width),
Packit b099d7
    XmRImmediate, (XtPointer)False
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNconnectNodes, XmCBoolean, XmRBoolean,
Packit b099d7
    sizeof(Boolean), XtOffsetOf(XmOutlineRec, outline.connect_nodes),
Packit b099d7
    XmRImmediate, (XtPointer)False
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
static XmSyntheticResource get_resources[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNindentSpace, sizeof(Dimension),
Packit b099d7
    XtOffsetOf(XmOutlineRec, outline.indent_space),
Packit b099d7
    XmeFromHorizontalPixels, (XmImportProc) XmeToHorizontalPixels
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
XmOutlineClassRec xmOutlineClassRec = {
Packit b099d7
  { /* core fields */
Packit b099d7
    /* superclass		*/	((WidgetClass) SUPERCLASS),
Packit b099d7
    /* class_name		*/	"XmOutline",
Packit b099d7
    /* widget_size		*/	sizeof(XmOutlineRec),
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			*/	XtInheritRealize,
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	*/	XtExposeCompressMultiple,
Packit b099d7
    /* compress_enterleave	*/	TRUE,
Packit b099d7
    /* visible_interest		*/	FALSE,
Packit b099d7
    /* destroy			*/	Destroy,
Packit b099d7
    /* resize			*/	Resize,
Packit b099d7
    /* expose			*/	Redisplay,
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       */      XtInheritInsertChild,
Packit b099d7
    /* delete_child       */      XtInheritDeleteChild,
Packit b099d7
    /* extension          */      NULL,                                     
Packit b099d7
   },
Packit b099d7
   {		/* constraint_class fields */
Packit b099d7
    /* resource list        */         NULL,
Packit b099d7
    /* num resources        */         0,
Packit b099d7
    /* constraint size      */         sizeof(XmOutlineConstraintRec),	
Packit b099d7
    /* init proc            */         ConstraintInitialize,
Packit b099d7
    /* destroy proc         */         ConstraintDestroy,
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         */      NULL,
Packit b099d7
    /* extension	      */      NULL,	
Packit b099d7
   },
Packit b099d7
   { /* Hierarchy fields */
Packit b099d7
      XtInheritChangeNodeState,	/* The function for changing the node state. */
Packit b099d7
      XtInheritMapNode,			/* Maps a given node. */
Packit b099d7
      XtInheritUnmapNode,		/* Unmaps a given node. */
Packit b099d7
      UnmapAllExtraNodes,		/* Unmaps all extra nodes. */
Packit b099d7
      XtInheritBuildNodeTable,		/* Builds up the node table. */
Packit b099d7
      XtInheritResetOpenCloseButton, 	/* Resets the the o/c button. */
Packit b099d7
      ToggleNodeState,		/* Called to toggle the state of node. */
Packit b099d7
      NULL,			/* extension          */
Packit b099d7
   },
Packit b099d7
   { /* Outline fields */
Packit b099d7
      CalcMaxWidth,		/* calculates the max width of the outline. */
Packit b099d7
      CalcLocations,		/* calculates were children will be placed. */
Packit b099d7
      NULL                      /* extension    */
Packit b099d7
   }
Packit b099d7
};
Packit b099d7
Packit b099d7
WidgetClass xmOutlineWidgetClass = (WidgetClass) &xmOutlineClassRec;
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC CODE
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
/*      Function Name: ClassInitialize
Packit b099d7
 *      Description:   Initializes class-specific data (offsets)
Packit b099d7
 *      Arguments:     none
Packit b099d7
 *      Returns:       nothing
Packit b099d7
 */
Packit b099d7
static void
Packit b099d7
ClassInitialize()
Packit b099d7
{
Packit b099d7
  /* do nothing */
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ClassPartInitialize
Packit b099d7
 *	Description: handles inheritance of class functions.
Packit b099d7
 *	Arguments: class - the widget class of this widget.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ClassPartInitialize(WidgetClass class)
Packit b099d7
{
Packit b099d7
    XmOutlineWidgetClass wc = (XmOutlineWidgetClass) class;
Packit b099d7
    XmOutlineWidgetClass superC;
Packit b099d7
    
Packit b099d7
    _XmProcessLock();
Packit b099d7
Packit b099d7
    superC = (XmOutlineWidgetClass) wc->core_class.superclass;
Packit b099d7
Packit b099d7
/* 
Packit b099d7
 * We don't need to check for NULL super since we'll get to The functions
Packit b099d7
 * defined by the Outline class eventually.
Packit b099d7
 */
Packit b099d7
Packit b099d7
    if (wc->outline_class.calc_max_width == XtInheritCalcMaxWidth)
Packit b099d7
	wc->outline_class.calc_max_width= superC->outline_class.calc_max_width;
Packit b099d7
Packit b099d7
    if (wc->outline_class.calc_locations == XtInheritCalcLocations)
Packit b099d7
	wc->outline_class.calc_locations= superC->outline_class.calc_locations;
Packit b099d7
Packit b099d7
    _XmProcessUnlock();
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
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
Initialize(Widget req, Widget set, ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) set;
Packit b099d7
Packit b099d7
    XmHierarchy_top_node(ow) = ((HierarchyConstraints) 
Packit b099d7
			      XtRealloc((XtPointer) XmHierarchy_top_node(ow),
Packit b099d7
					sizeof(OutlineConstraintRec)));
Packit b099d7
Packit b099d7
    XmOutline_top_node_of_display(ow) = NULL;
Packit b099d7
Packit b099d7
    XmOutline_max_width(ow) = 0;	
Packit b099d7
    XmOutline_max_widget_width(ow) = 0;
Packit b099d7
    XmOutline_ul_point(ow).x = ow->core.width;
Packit b099d7
    XmOutline_ul_point(ow).y = ow->core.height;
Packit b099d7
    XmOutline_lr_point(ow).x = 0;
Packit b099d7
    XmOutline_lr_point(ow).y = 0;
Packit b099d7
Packit b099d7
    XmOutline_child_op_list(ow) = _XmListInit();
Packit b099d7
Packit b099d7
    CreateGC(ow);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void CreateGC(XmOutlineWidget ow)
Packit b099d7
{
Packit b099d7
    	XGCValues values;
Packit b099d7
	values.foreground = ow->manager.foreground;
Packit b099d7
	XmOutline_draw_gc(ow) = XtGetGC((Widget)ow, GCForeground, &values);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*    Function Name: Destroy
Packit b099d7
 *    Description:   Destroys all data allocated by the widget
Packit b099d7
 *    Arguments:     w - the widget.
Packit b099d7
 *    Returns:       none.
Packit b099d7
 */
Packit b099d7
static void
Packit b099d7
Destroy(Widget widget)
Packit b099d7
{
Packit b099d7
  XmOutlineWidget ow = (XmOutlineWidget) widget;
Packit b099d7
Packit b099d7
  _XmListFree(XmOutline_child_op_list(ow)); 
Packit b099d7
  XtReleaseGC(widget,XmOutline_draw_gc(ow));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: Resize
Packit b099d7
 *	Description:   Called when this widget has been resized.
Packit b099d7
 *	Arguments:     w - Extended List Widget to resize.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void 
Packit b099d7
Resize(Widget w)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) w;
Packit b099d7
Packit b099d7
    if (XmHierarchy_refigure_mode(ow)) {
Packit b099d7
	if(XmOutline_constrain_width(ow))
Packit b099d7
	    CalcLocations(w, False);
Packit b099d7
	
Packit b099d7
	LayoutChildren(w, NULL);
Packit b099d7
	if (XtIsRealized((Widget)ow)) {
Packit b099d7
	    XClearArea(XtDisplay(ow), XtWindow(ow),
Packit b099d7
		       0, 0, ow->core.width, ow->core.height, True);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: Redisplay
Packit b099d7
 *	Description:   This function deals with any pending moves/maps/unmaps
Packit b099d7
 *                     in the queue before redisplay
Packit b099d7
 *	Arguments:     w - the Outline widget.
Packit b099d7
 *                     event - event that caused the exposure.
Packit b099d7
 *                     region - the region containing all the exposures.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
typedef struct _RedispInfo {
Packit b099d7
    Window window;
Packit b099d7
    Boolean found;
Packit b099d7
} RedispInfo;
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
Redisplay(Widget w, XEvent * event, Region region)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) w;
Packit b099d7
    XEvent junk;
Packit b099d7
    RedispInfo info;
Packit b099d7
    int lrx, lry;		/* local variables for lower left corner. */
Packit b099d7
Packit b099d7
Packit b099d7
    XmDropSiteStartUpdate(w);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Make sure that there are not more expose events pending in the queue
Packit b099d7
     */
Packit b099d7
Packit b099d7
    info.window = XtWindow(w);
Packit b099d7
    info.found = False;
Packit b099d7
    XCheckIfEvent(XtDisplay(w), &junk, CheckExpose, (char *) &info;;
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * Compute the maximum bounding rectangle for all expose events
Packit b099d7
     * that have yet to be processed.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (event->xexpose.x < XmOutline_ul_point(ow).x) 
Packit b099d7
	XmOutline_ul_point(ow).x = event->xexpose.x;
Packit b099d7
    if (event->xexpose.y < XmOutline_ul_point(ow).y) 
Packit b099d7
	XmOutline_ul_point(ow).y = event->xexpose.y;
Packit b099d7
Packit b099d7
    lrx = event->xexpose.x + event->xexpose.width;
Packit b099d7
    lry = event->xexpose.y + event->xexpose.height;
Packit b099d7
Packit b099d7
    if (lrx > XmOutline_lr_point(ow).x) 
Packit b099d7
	XmOutline_lr_point(ow).x = lrx;
Packit b099d7
    if (lry > XmOutline_lr_point(ow).y) 
Packit b099d7
	XmOutline_lr_point(ow).y = lry;
Packit b099d7
Packit b099d7
    if (!info.found) {	/* No more expose events waiting - process these. */
Packit b099d7
	XRectangle rect;
Packit b099d7
Packit b099d7
	rect.x = XmOutline_ul_point(ow).x;
Packit b099d7
	rect.y = XmOutline_ul_point(ow).y;
Packit b099d7
	rect.width = XmOutline_lr_point(ow).x - XmOutline_ul_point(ow).x;
Packit b099d7
	rect.height = XmOutline_lr_point(ow).y - XmOutline_ul_point(ow).y;
Packit b099d7
Packit b099d7
	ProcessChildQueue((XmOutlineWidget) w, &rect);
Packit b099d7
	if (XmOutline_connect_nodes(w))
Packit b099d7
		RedrawOutlineLines(w,&rect);
Packit b099d7
	
Packit b099d7
	/*
Packit b099d7
	 * Reset upper right and lower left points.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	XmOutline_ul_point(ow).x = w->core.width;
Packit b099d7
	XmOutline_ul_point(ow).y = w->core.height;
Packit b099d7
	XmOutline_lr_point(ow).x = XmOutline_lr_point(ow).y = 0;
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    XmDropSiteEndUpdate(w);
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
/*    Function Name: CheckExpose
Packit b099d7
 *    Description: Checks to see if there is an expose event on the queue.
Packit b099d7
 *    Arguments: disp - the X Display.
Packit b099d7
 *                 event - the event to check for.
Packit b099d7
 *                 info_ptr - a pointer to the redispInfo.
Packit b099d7
 *    Returns: Always False.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static Bool
Packit b099d7
CheckExpose(Display *disp, XEvent *event, char *info_ptr)
Packit b099d7
{
Packit b099d7
    RedispInfo *info = (RedispInfo *) info_ptr;
Packit b099d7
Packit b099d7
    if (info->found || event->xany.type != Expose)
Packit b099d7
      return(False);
Packit b099d7
Packit b099d7
    if (event->xexpose.window == info->window)
Packit b099d7
      info->found = True;
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 drt widget.
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
    Dimension *width_intended = NULL;
Packit b099d7
    Dimension *height_intended = NULL;
Packit b099d7
Packit b099d7
    if(!(intended->request_mode & XtCWQueryOnly)) {
Packit b099d7
	if(intended->request_mode & CWWidth)
Packit b099d7
	    width_intended = &(intended->width);
Packit b099d7
	if(intended->request_mode & CWHeight)
Packit b099d7
	    height_intended = &(intended->height);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    GetDesiredSize(w, width_intended, height_intended,
Packit b099d7
		   &(preferred->width), &(preferred->height), True, False);
Packit b099d7
    preferred->request_mode = CWWidth | CWHeight;
Packit b099d7
Packit b099d7
    return(_XmHWQuery(w, intended, preferred));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: SetValues
Packit b099d7
 *	Description:   Called a resources is changed.
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
SetValues(Widget current, Widget request, Widget set,
Packit b099d7
	  ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget c_outline = (XmOutlineWidget) current; 
Packit b099d7
    XmOutlineWidget outline = (XmOutlineWidget) set;
Packit b099d7
    Boolean layout = False;
Packit b099d7
    Boolean retval = False;
Packit b099d7
Packit b099d7
    if ((XmHierarchy_v_margin(c_outline) != XmHierarchy_v_margin(outline)) ||
Packit b099d7
	(XmHierarchy_h_margin(c_outline) != XmHierarchy_h_margin(outline)))
Packit b099d7
    {
Packit b099d7
	layout = True;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmOutline_indent_space(c_outline) != XmOutline_indent_space(outline))
Packit b099d7
    {
Packit b099d7
	layout = True;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmOutline_constrain_width(c_outline)
Packit b099d7
	!= XmOutline_constrain_width(outline))
Packit b099d7
    {
Packit b099d7
	layout = True;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchy_refigure_mode(c_outline) != XmHierarchy_refigure_mode(outline))
Packit b099d7
	layout = XmHierarchy_refigure_mode(outline);
Packit b099d7
Packit b099d7
    if (XmOutline_connect_nodes(c_outline) != XmOutline_connect_nodes(outline))
Packit b099d7
	retval = True;
Packit b099d7
Packit b099d7
    if (layout) {
Packit b099d7
	XmOutlineWidgetClass oc = (XmOutlineWidgetClass) XtClass(set);
Packit b099d7
	XmOutlineCalcLocationProc calc_locations;
Packit b099d7
	
Packit b099d7
        _XmProcessLock()
Packit b099d7
	calc_locations = oc->outline_class.calc_locations;
Packit b099d7
        _XmProcessUnlock()
Packit b099d7
	(*calc_locations)(set, True);
Packit b099d7
	
Packit b099d7
	LayoutChildren(set, NULL);
Packit b099d7
	retval = True;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (c_outline->manager.foreground != outline->manager.foreground)
Packit b099d7
	{
Packit b099d7
  	XtReleaseGC(current,XmOutline_draw_gc(c_outline));
Packit b099d7
	CreateGC(outline);
Packit b099d7
	retval = True;
Packit b099d7
	}
Packit b099d7
Packit b099d7
    return(retval);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 *  Composite Widget class procedures.
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
    XmOutlineWidgetClass oc = (XmOutlineWidgetClass) XtClass(w);
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) w;
Packit b099d7
      
Packit b099d7
    if (XmHierarchy_refigure_mode(ow)) {
Packit b099d7
	XmOutlineCalcLocationProc calc_locations;
Packit b099d7
	
Packit b099d7
	_XmProcessLock()
Packit b099d7
	calc_locations = oc->outline_class.calc_locations;
Packit b099d7
	_XmProcessUnlock()
Packit b099d7
	(*calc_locations)(w, True);
Packit b099d7
	
Packit b099d7
	LayoutChildren(w, NULL);
Packit b099d7
	if (XtIsRealized((Widget)ow)) {
Packit b099d7
	    XClearArea(XtDisplay(ow), XtWindow(ow),
Packit b099d7
		       0, 0, ow->core.width, ow->core.height, True);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
   XmeNavigChangeManaged(w);	/* for Motif navigation */
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
    XmOutlineWidgetClass oc = (XmOutlineWidgetClass) XtClass(XtParent(w));
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget)(XtParent(w));
Packit b099d7
Packit b099d7
    result->request_mode = 0;
Packit b099d7
Packit b099d7
    /* if nothing we're interested in, say No */
Packit b099d7
    if (!(request->request_mode & (CWWidth | CWHeight | CWBorderWidth)))
Packit b099d7
	return(XtGeometryNo);
Packit b099d7
Packit b099d7
    if((XmOutline_constrain_width(ow)) &&
Packit b099d7
       (request->request_mode & CWWidth) &&
Packit b099d7
       (request->width > w->core.width))
Packit b099d7
    {
Packit b099d7
	result->request_mode = CWWidth;
Packit b099d7
	result->width = w->core.width;
Packit b099d7
	return XtGeometryAlmost;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    /* else we have something that we're interested in. Do we also have
Packit b099d7
    ** something that we're not granting? If so, say that we'll grant the
Packit b099d7
    ** stuff that we're interested in but not the other items
Packit b099d7
    */
Packit b099d7
    if (request->request_mode & (CWX | CWY | CWStackMode | CWSibling))
Packit b099d7
	{
Packit b099d7
	result->request_mode = request->request_mode & (CWWidth | CWHeight | CWBorderWidth);
Packit b099d7
	result->width = request->width;
Packit b099d7
	result->height = request->height;
Packit b099d7
	result->border_width = request->border_width;
Packit b099d7
	return(XtGeometryAlmost);
Packit b099d7
	}
Packit b099d7
    
Packit b099d7
    if (!(request->request_mode & CWWidth)) {
Packit b099d7
	request->width = w->core.width;
Packit b099d7
	result->request_mode |= CWWidth;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!(request->request_mode & CWBorderWidth)) {
Packit b099d7
	request->border_width = w->core.border_width;
Packit b099d7
	result->request_mode |= CWBorderWidth;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!(request->request_mode & CWHeight)) {
Packit b099d7
	request->height = w->core.height;
Packit b099d7
	result->request_mode |= CWHeight;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    *result = *request;
Packit b099d7
Packit b099d7
    if (request->request_mode & XtCWQueryOnly) 
Packit b099d7
	return(XtGeometryYes);
Packit b099d7
	
Packit b099d7
    /*
Packit b099d7
     * Correct for stupid children
Packit b099d7
     */
Packit b099d7
    if(result->width  <= 0) result->width  = 1;
Packit b099d7
    if(result->height <= 0) result->height = 1;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * A real allowed request, make the change.
Packit b099d7
     */
Packit b099d7
    _XmResizeWidget(w, result->width, result->height, result->border_width);
Packit b099d7
Packit b099d7
    if (XmHierarchy_refigure_mode(ow)) {
Packit b099d7
	XmOutlineCalcLocationProc calc_locations;
Packit b099d7
	
Packit b099d7
	_XmProcessLock()
Packit b099d7
	calc_locations = oc->outline_class.calc_locations;
Packit b099d7
	_XmProcessUnlock()
Packit b099d7
	(*calc_locations)(XtParent(w), True);
Packit b099d7
	
Packit b099d7
	LayoutChildren(XtParent(w), w);
Packit b099d7
	if (XtIsRealized((Widget)ow)) {
Packit b099d7
	    XClearArea(XtDisplay(ow), XtWindow(ow),
Packit b099d7
		       0, 0, ow->core.width, ow->core.height, True);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return(XtGeometryYes);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 * 
Packit b099d7
 * Constraint widget class procedures.
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
    XmOutlineC_widget_x(set->core.constraints)
Packit b099d7
      = XmOutlineC_open_close_x(set->core.constraints) = 0;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ConstraintSetValues
Packit b099d7
 *	Description:   Called a constraint is changed on my children.
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
    Widget ow = XtParent(set);
Packit b099d7
    OutlineConstraints set_node = GetNodeInfo(set);
Packit b099d7
    OutlineConstraints old_node = GetNodeInfo(current);
Packit b099d7
    Boolean insert_change = False, redisplay = False;
Packit b099d7
    int i;
Packit b099d7
Packit b099d7
    for (i = 0; i < *num_args; i++) 
Packit b099d7
	if (streq(args[i].name, XmNinsertBefore)) {
Packit b099d7
	    insert_change = True;
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Nothing below here needs to be done before we are realized.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!XtIsRealized(set))
Packit b099d7
	return(False);
Packit b099d7
Packit b099d7
    if ((XmHierarchyC_parent(set_node) != XmHierarchyC_parent(old_node)) ||
Packit b099d7
	(XmHierarchyC_state(set_node) != XmHierarchyC_state(old_node)) ||
Packit b099d7
	(insert_change))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Other operations have already been performed by my superclass. 
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	if (XmHierarchy_refigure_mode((XmOutlineWidget)ow)) {
Packit b099d7
	    CalcLocations(ow, True);
Packit b099d7
	    LayoutChildren(ow, NULL);
Packit b099d7
	    redisplay = True;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	 /*
Packit b099d7
	  * Since Layout children has (possibily) moved this widget
Packit b099d7
	  * to a new location.  The current state of the widget
Packit b099d7
	  * must be updated so that neither the intrinsics nor
Packit b099d7
	  * any sub-classes of this widget attempt to move it
Packit b099d7
	  * to the new location, since it is already there.
Packit b099d7
	  */
Packit b099d7
Packit b099d7
	 current->core.x = set->core.x;
Packit b099d7
	 current->core.y = set->core.y;
Packit b099d7
     }
Packit b099d7
Packit b099d7
    if (XtIsRealized(ow) && redisplay && 
Packit b099d7
        (XmHierarchy_refigure_mode((XmOutlineWidget)ow)))
Packit b099d7
    {
Packit b099d7
	XClearArea(XtDisplay(ow), XtWindow(ow),
Packit b099d7
		   0, 0, ow->core.width, ow->core.height, True);
Packit b099d7
    }
Packit b099d7
	
Packit b099d7
    return(False);   
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ConstraintDestroy
Packit b099d7
 *	Description:   Destroys all data allocated by the constraint 
Packit b099d7
 *                     record.
Packit b099d7
 *	Arguments:     w - the widget.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 *
Packit b099d7
 * Removes the destroyed children from the list of children that still
Packit b099d7
 * need to be moved.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ConstraintDestroy(Widget w)
Packit b099d7
{
Packit b099d7
    OutlineConstraints node = GetNodeInfo(w);
Packit b099d7
    XmListElem *elem, *next;
Packit b099d7
    XmOutlineWidget ow;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) == XmNotInHierarchy) 
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    ow = (XmOutlineWidget) XtParent(w);
Packit b099d7
Packit b099d7
    elem = XmListFirst(XmOutline_child_op_list(ow)); 
Packit b099d7
    while(elem != NULL) {
Packit b099d7
	OutlineConstraints info = (OutlineConstraints) XmListElemData(elem);
Packit b099d7
Packit b099d7
	next = XmListElemNext(elem);
Packit b099d7
Packit b099d7
	if (XmHierarchyC_widget(info) == w) {
Packit b099d7
	    /*
Packit b099d7
	     * Each widget will only be in the list once.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    _XmListRemove(XmOutline_child_op_list(ow), elem);
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	elem = next;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 *  Hierarchy Widget class proceedures.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: ToggleNodeState
Packit b099d7
 *	Description:   Toggles the open/close state of a toggle button.
Packit b099d7
 *	Arguments:     w - the command button that activated this.
Packit b099d7
 *                     node_ptr - a pointer to the node info.
Packit b099d7
 *                     call_data - UNUSED.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
ToggleNodeState(Widget w, XtPointer node_ptr, XtPointer call_data)
Packit b099d7
{
Packit b099d7
    Widget ow = XtParent(w);
Packit b099d7
    XmOutlineWidgetClass oc = (XmOutlineWidgetClass) XtClass(ow);
Packit b099d7
Packit b099d7
    {
Packit b099d7
	XtCallbackProc toggle_node_state;
Packit b099d7
	
Packit b099d7
	_XmProcessLock()
Packit b099d7
	toggle_node_state = SUPERCLASS->hierarchy_class.toggle_node_state;
Packit b099d7
	_XmProcessUnlock()
Packit b099d7
	(*toggle_node_state)(w, node_ptr, call_data);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    {
Packit b099d7
	XmOutlineCalcLocationProc calc_locations;
Packit b099d7
	
Packit b099d7
	_XmProcessLock()
Packit b099d7
	calc_locations = oc->outline_class.calc_locations;
Packit b099d7
	_XmProcessUnlock()
Packit b099d7
	(*calc_locations)(ow, True);
Packit b099d7
    }
Packit b099d7
    LayoutChildren(ow, NULL);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Could check for a size change and abort if we really wanted
Packit b099d7
     * to be clever.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XtIsRealized(ow)) {
Packit b099d7
	XClearArea(XtDisplay(ow), XtWindow(ow),
Packit b099d7
		   0, 0, ow->core.width, ow->core.height, True);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 *  Outline widget class proceedures.
Packit b099d7
 *
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: CalcLocations
Packit b099d7
 *	Description:   Calculates the location of each widget in the outline.
Packit b099d7
 *	Arguments:     w - the outline widget.
Packit b099d7
 *                     allow_resize - allow shell to resize?
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
CalcLocations(Widget w, Boolean allow_resize)
Packit b099d7
{
Packit b099d7
    Cardinal             outline_depth, current_index;
Packit b099d7
    XmOutlineWidget      ow = (XmOutlineWidget) w;
Packit b099d7
    OutlineConstraints   node;
Packit b099d7
    XmOutlineWidgetClass oc = (XmOutlineWidgetClass) XtClass(w);
Packit b099d7
    register int         i;
Packit b099d7
    unsigned int         num_nodes;
Packit b099d7
    
Packit b099d7
    if (!XmHierarchy_refigure_mode(ow))
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    XmOutline_max_widget_width(ow) = 0;	/* reset max_width. */
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Reset each node to be hidden;
Packit b099d7
     */
Packit b099d7
Packit b099d7
    for( i = 0; i < ow->composite.num_children; ++i )
Packit b099d7
    {
Packit b099d7
	node = GetNodeInfo(ow->composite.children[i]);
Packit b099d7
	XmHierarchyC_status(node) |= IS_COMPRESSED;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    num_nodes = 0;
Packit b099d7
    outline_depth = 0;
Packit b099d7
Packit b099d7
    GetNodeDimensions(w, (OutlineConstraints) XmHierarchy_top_node(ow),
Packit b099d7
		      outline_depth, &num_nodes);
Packit b099d7
Packit b099d7
    {
Packit b099d7
	XmOutlineMaxWidthProc calc_max_width;
Packit b099d7
	
Packit b099d7
	_XmProcessLock();
Packit b099d7
	calc_max_width = oc->outline_class.calc_max_width;
Packit b099d7
	_XmProcessUnlock()
Packit b099d7
	XmOutline_max_width(ow) = (*calc_max_width)(w);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmHierarchy_num_nodes(ow) = num_nodes;
Packit b099d7
			  
Packit b099d7
    current_index = 0;
Packit b099d7
    {
Packit b099d7
	XmHierarchyBuildTableProc build_node_table;
Packit b099d7
Packit b099d7
	_XmProcessLock();
Packit b099d7
	build_node_table = oc->hierarchy_class.build_node_table;
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	(*build_node_table)(w, XmHierarchy_top_node(ow), &current_index);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (num_nodes != 0) {
Packit b099d7
	XmOutline_top_node_of_display(ow) = 
Packit b099d7
	                     (OutlineConstraints) XmHierarchy_node_table(ow)[0];
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
	XmOutline_top_node_of_display(ow) = NULL;
Packit b099d7
Packit b099d7
    if (allow_resize)
Packit b099d7
	RequestNewSize(w);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name:	GetNodeDimensions
Packit b099d7
	Description:	Calls GetNodeHeightAndWidth, but first resets maximum
Packit b099d7
	Arguments:	w - outline widget
Packit b099d7
			node - the starting node
Packit b099d7
			depth - outline depth
Packit b099d7
			num_nodes - like num_nuts... hahaha
Packit b099d7
	Returns:	none
Packit b099d7
Packit b099d7
 */
Packit b099d7
static void
Packit b099d7
GetNodeDimensions(Widget w, OutlineConstraints node, 
Packit b099d7
		  Cardinal depth, Cardinal *num)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) w;
Packit b099d7
Packit b099d7
    XmOutline_max_widget_width(ow) = 2 * XmHierarchy_h_margin(ow);
Packit b099d7
Packit b099d7
    GetNodeHeightAndWidth(w, node, depth, TRUE, num);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: RequestNewSize
Packit b099d7
 *	Description:   Asks our parent for a new size.
Packit b099d7
 *	Arguments:     w - the data request outline widget.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
RequestNewSize(Widget w)
Packit b099d7
{
Packit b099d7
    Dimension width, height, rwidth, rheight;
Packit b099d7
    XtGeometryResult ret_val;
Packit b099d7
Packit b099d7
    GetDesiredSize(w, NULL, NULL, &width, &height, False, True);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * It is just barely possible that our height or width could go to
Packit b099d7
     * zero.  If this happens then do no request a new size because the
Packit b099d7
     * X server will generate a protocol error.  It is best to just
Packit b099d7
     * stay where we are.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if ((width == 0) || (height == 0))
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    ret_val = XtMakeResizeRequest(w, width, height, &rwidth, &rheight);
Packit b099d7
    
Packit b099d7
    while (ret_val == XtGeometryAlmost) {
Packit b099d7
	Dimension fwidth, fheight;  /* Final values */
Packit b099d7
	if(XmOutline_constrain_width(w)) {
Packit b099d7
	    GetDesiredSize(w, &rwidth, &rheight, &fwidth, &fheight,
Packit b099d7
			   False, True);
Packit b099d7
	    ret_val = XtMakeResizeRequest(w, fwidth, fheight,
Packit b099d7
					  &rwidth, &rheight);
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
	    ret_val = XtMakeResizeRequest(w, rwidth, rheight, NULL, NULL);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetDesiredSize
Packit b099d7
 *	Description:   Returns the desired size of the outline widget.
Packit b099d7
 *	Arguments:     w - the outline widget.
Packit b099d7
 *                     width - the intended width
Packit b099d7
 *                     height - the intended height
Packit b099d7
 *                     width_ret - the desired width.
Packit b099d7
 *                     height_ret - the desired height.
Packit b099d7
 *                     recalc - recalculate the new size if row height unset?
Packit b099d7
 *                     allow_resize - allow the outline to attempt a resize?
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
GetDesiredSize(Widget w, Dimension *width, Dimension *height,
Packit b099d7
	       Dimension *width_ret, Dimension *height_ret, 
Packit b099d7
	       Boolean recalc, Boolean allow_resize)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) w;
Packit b099d7
    register int i, num, temp_height;
Packit b099d7
    OutlineConstraints * node;
Packit b099d7
    XmOutlineWidgetClass oc = (XmOutlineWidgetClass) XtClass(w);
Packit b099d7
Packit b099d7
    if (recalc) {
Packit b099d7
	if(XmOutline_constrain_width(w)) {
Packit b099d7
	    Dimension tmp_width, tmp_height;
Packit b099d7
	    tmp_height = w->core.height;
Packit b099d7
	    tmp_width = w->core.width;
Packit b099d7
Packit b099d7
	    if(width)
Packit b099d7
		w->core.width = *width;
Packit b099d7
	    if(height)
Packit b099d7
		w->core.height = *height;
Packit b099d7
Packit b099d7
	    {
Packit b099d7
		XmOutlineCalcLocationProc calc_locations;
Packit b099d7
		
Packit b099d7
		_XmProcessLock();
Packit b099d7
		calc_locations = oc->outline_class.calc_locations;
Packit b099d7
		_XmProcessUnlock();
Packit b099d7
		(*calc_locations)(w, allow_resize);
Packit b099d7
	    }
Packit b099d7
	    
Packit b099d7
	    if(width)
Packit b099d7
		w->core.width = tmp_width;
Packit b099d7
	    if(height)
Packit b099d7
		w->core.height = tmp_height;
Packit b099d7
	} else {
Packit b099d7
	    {
Packit b099d7
		XmOutlineCalcLocationProc calc_locations;
Packit b099d7
		
Packit b099d7
		_XmProcessLock();
Packit b099d7
		calc_locations = oc->outline_class.calc_locations;
Packit b099d7
		_XmProcessUnlock();
Packit b099d7
		(*calc_locations)(w, allow_resize);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if(XmOutline_constrain_width(ow) && width) {
Packit b099d7
	*width_ret = *width;
Packit b099d7
    } else {
Packit b099d7
	*width_ret = XmOutline_max_width(ow);
Packit b099d7
    }
Packit b099d7
    temp_height = 0;
Packit b099d7
    node = (OutlineConstraints *) XmHierarchy_node_table(ow);
Packit b099d7
    num = XmHierarchy_num_nodes(ow);
Packit b099d7
    for (i = 0; i < num; i++, node++)
Packit b099d7
	temp_height += XmOutlineC_height(*node) + XmHierarchy_v_margin(ow);
Packit b099d7
Packit b099d7
    *height_ret = temp_height + XmHierarchy_v_margin(ow);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: LayoutChildren
Packit b099d7
 *	Description:   all the fun stuff for positioning the children is here.
Packit b099d7
 *	Arguments:     w - the outline widget.
Packit b099d7
 *                     assign_child - The child to assign values to rather
Packit b099d7
 *                                    than _XiMove.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
LayoutChildren(Widget w, Widget assign_child)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) w;
Packit b099d7
    XmOutlineWidgetClass oc = (XmOutlineWidgetClass) XtClass(w);
Packit b099d7
    register OutlineConstraints disp_top = XmOutline_top_node_of_display(ow);
Packit b099d7
    register HierarchyConstraints * node_table = XmHierarchy_node_table(ow);
Packit b099d7
    register Cardinal num_nodes = XmHierarchy_num_nodes(ow);
Packit b099d7
    register Position cur_y;
Packit b099d7
    register int cur_node, v_margin;
Packit b099d7
    int oc_x = 0, oc_y = 0;
Packit b099d7
    Boolean register_workproc = True;
Packit b099d7
Packit b099d7
    if (!XmHierarchy_refigure_mode(ow))
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    XmDropSiteStartUpdate(w);
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Remove the old list, replace it with the new one.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XmListFirst(XmOutline_child_op_list(ow)) != NULL) {
Packit b099d7
	if( XmHierarchy_work_proc_id(ow) != (XtWorkProcId) NULL )
Packit b099d7
	{
Packit b099d7
	    XtRemoveWorkProc(XmHierarchy_work_proc_id(ow));
Packit b099d7
	    XmHierarchy_work_proc_id(ow) = (XtWorkProcId) NULL;
Packit b099d7
	}
Packit b099d7
	_XmListFree(XmOutline_child_op_list(ow));
Packit b099d7
	XmOutline_child_op_list(ow) = _XmListInit();
Packit b099d7
	register_workproc = False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Unmap all nodes that no longer are visible.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    {
Packit b099d7
	XmHierarchyExtraNodeProc unmap_all_extra_nodes;
Packit b099d7
Packit b099d7
	_XmProcessLock();
Packit b099d7
	unmap_all_extra_nodes = oc->hierarchy_class.unmap_all_extra_nodes;
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	(*unmap_all_extra_nodes)(w, XmHierarchy_top_node(ow));
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Find the first node to be displayed, and unmap all nodes that would be
Packit b099d7
     * above that one.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    for (cur_node = 0; cur_node < num_nodes; cur_node++, node_table++) {
Packit b099d7
	if (*node_table == (HierarchyConstraints) disp_top)
Packit b099d7
	    break;
Packit b099d7
Packit b099d7
	UnmapNode(ow, (OutlineConstraints) *node_table);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    cur_y = (Position) (v_margin = XmHierarchy_v_margin(ow));
Packit b099d7
    
Packit b099d7
    while ( 
Packit b099d7
	   ((int)cur_node < (int)num_nodes)
Packit b099d7
	   &&
Packit b099d7
	   (XmOutline_connect_nodes(ow) || ((int)cur_y < (int)ow->core.height) )
Packit b099d7
		) 
Packit b099d7
    {
Packit b099d7
	register Widget w;
Packit b099d7
	OutlineConstraints node = (OutlineConstraints) *node_table;
Packit b099d7
Packit b099d7
	if (XmHierarchyC_open_close_button(node) != NULL) {
Packit b099d7
	    Position offset;
Packit b099d7
	    Widget w;
Packit b099d7
	    
Packit b099d7
	    w = XmHierarchyC_open_close_button(node);
Packit b099d7
	    offset = (XmOutlineC_height(node) - 
Packit b099d7
		      (w->core.height + 2 * w->core.border_width));
Packit b099d7
Packit b099d7
	    oc_x = XmOutlineC_open_close_x(node);
Packit b099d7
	    oc_y = cur_y + offset/2;
Packit b099d7
	}
Packit b099d7
	
Packit b099d7
	w = XmHierarchyC_widget(node);
Packit b099d7
	if (assign_child == w) {
Packit b099d7
	    w->core.x = XmOutlineC_widget_x(node);
Packit b099d7
	    w->core.y = cur_y;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	MoveNode(ow, node, XmOutlineC_widget_x(node), cur_y, oc_x, oc_y, True);
Packit b099d7
Packit b099d7
	cur_y += XmOutlineC_height(node) + v_margin;
Packit b099d7
Packit b099d7
	cur_node++;
Packit b099d7
	node_table++;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    /*
Packit b099d7
     * We have used all the window, unmap all other nodes.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    while(cur_node < num_nodes) {
Packit b099d7
	UnmapNode(ow, (OutlineConstraints) *node_table);
Packit b099d7
Packit b099d7
	cur_node++;
Packit b099d7
	node_table++;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (register_workproc) {
Packit b099d7
	XmHierarchy_work_proc_id(ow) = 
Packit b099d7
	    XtAppAddWorkProc(XtWidgetToApplicationContext(w),
Packit b099d7
			     MoveNodesTimer, (XtPointer) w);
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    XmDropSiteEndUpdate(w);
Packit b099d7
Packit b099d7
}
Packit b099d7
    
Packit b099d7
/*	Function Name: GetNodeHeightAndWidth
Packit b099d7
 *	Description:   Gets the size of each node.
Packit b099d7
 *	Arguments:     w - the drt widget.
Packit b099d7
 *                     node - the node to get the height and width of.
Packit b099d7
 *                     outline_depth - depth of the outline at this node.
Packit b099d7
 *                     recurse - recurse all subnodes?.
Packit b099d7
 * IN/OUT              num - number of nodes.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
GetNodeHeightAndWidth(Widget w, OutlineConstraints node, 
Packit b099d7
		      Cardinal outline_depth, Boolean recurse, Cardinal * num)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) w;
Packit b099d7
    register int i;
Packit b099d7
    XtWidgetGeometry geom_pref;
Packit b099d7
Packit b099d7
    if ((node == NULL) || ((XmHierarchyC_widget(node) != NULL) &&
Packit b099d7
			   !XtIsManaged(XmHierarchyC_widget(node)))) 
Packit b099d7
    {
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) != XmHidden) {
Packit b099d7
	Arg args[5];
Packit b099d7
	Cardinal num_args;
Packit b099d7
	Dimension width, open_height, node_height, width2, border_width;
Packit b099d7
Packit b099d7
	if (XmHierarchyC_open_close_button(node) != NULL) {
Packit b099d7
	    num_args = 0;
Packit b099d7
	    XtSetArg(args[num_args], XmNwidth, &width); num_args++;
Packit b099d7
	    XtSetArg(args[num_args], XmNheight, &open_height); num_args++;
Packit b099d7
	    XtSetArg(args[num_args], XmNborderWidth, &border_width);num_args++;
Packit b099d7
	    XtGetValues(XmHierarchyC_open_close_button(node), args, num_args);
Packit b099d7
Packit b099d7
	    border_width *= 2;
Packit b099d7
	    width += border_width;
Packit b099d7
	    open_height += border_width;
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
	    width = 0;
Packit b099d7
	    open_height = 0;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	num_args = 0;
Packit b099d7
/* 	XtSetArg(args[num_args], XmNwidth, &width2); num_args++; */
Packit b099d7
/* 	XtSetArg(args[num_args], XmNheight, &node_height); num_args++; */
Packit b099d7
	XtSetArg(args[num_args], XmNborderWidth, &border_width); num_args++;
Packit b099d7
	XtGetValues(XmHierarchyC_widget(node), args, num_args);
Packit b099d7
Packit b099d7
	XtQueryGeometry(XmHierarchyC_widget(node), NULL, &geom_pref);
Packit b099d7
	width2 = geom_pref.width;
Packit b099d7
	node_height = geom_pref.height;
Packit b099d7
Packit b099d7
	border_width *= 2;
Packit b099d7
	width2 += border_width;
Packit b099d7
	node_height += border_width;
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * indent_level = outline_depth;
Packit b099d7
	 */
Packit b099d7
	
Packit b099d7
	XmOutlineC_open_close_x(node) = ((outline_depth *XmOutline_indent_space(ow)) +
Packit b099d7
				      XmHierarchy_h_margin(ow));
Packit b099d7
	if (XmHierarchyC_open_close_button(node) == NULL) 
Packit b099d7
	    XmOutlineC_widget_x(node) = XmOutlineC_open_close_x(node);
Packit b099d7
	else
Packit b099d7
	    XmOutlineC_widget_x(node) = (XmOutlineC_open_close_x(node) + 
Packit b099d7
				      width + XmHierarchy_h_margin(ow));
Packit b099d7
	
Packit b099d7
	width2 += XmOutlineC_widget_x(node) + XmHierarchy_h_margin(ow);
Packit b099d7
	if ( width2 > XmOutline_max_widget_width(ow) )
Packit b099d7
	    XmOutline_max_widget_width(ow) = width2;
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * Now, if we are set to constrain our childrens' widths, we need
Packit b099d7
	 * to do a geometry negotiation and reset the width to whatever we
Packit b099d7
	 * decide.
Packit b099d7
	 */
Packit b099d7
	if(XmOutline_constrain_width(w))
Packit b099d7
	{
Packit b099d7
	    NegotiateNodeWidth(w, node);
Packit b099d7
	    num_args = 0;
Packit b099d7
	    XtSetArg(args[num_args], XmNheight, &node_height); num_args++;
Packit b099d7
	    XtGetValues(XmHierarchyC_widget(node), args, num_args);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	XmOutlineC_height(node) = MAX(node_height, open_height);
Packit b099d7
	
Packit b099d7
	(*num)++;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!recurse || (XmHierarchyC_state(node) == XmClosed))
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Hidden nodes don't count as another level down the outline.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) != XmHidden)
Packit b099d7
	outline_depth++;
Packit b099d7
Packit b099d7
    for (i = 0; i < XmHierarchyC_num_children(node); i++) {
Packit b099d7
	GetNodeHeightAndWidth(w,
Packit b099d7
			      (OutlineConstraints) XmHierarchyC_children(node)[i],
Packit b099d7
			      outline_depth, TRUE, num);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) != XmHidden)
Packit b099d7
	outline_depth--;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetNodeInfo
Packit b099d7
 *	Description:   Gets the node info associated with this widget.
Packit b099d7
 *	Arguments:     w - the widget.
Packit b099d7
 *	Returns:       the node info about this widget.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static OutlineConstraints
Packit b099d7
GetNodeInfo(Widget w)
Packit b099d7
{
Packit b099d7
    return((OutlineConstraints) w->core.constraints);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: CalcMaxWidth
Packit b099d7
 *	Description:   Calculates the maximum width of the outline.
Packit b099d7
 *	Arguments:     w - the outline.
Packit b099d7
 *	Returns:       The max width the outline would like to be.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static int
Packit b099d7
CalcMaxWidth(Widget w)
Packit b099d7
{
Packit b099d7
    return XmOutline_max_widget_width(w) + 2 * XmHierarchy_h_margin(w);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 *  Code for handling the node queue.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: UnmapAllExtraNodes
Packit b099d7
 *	Description:   Correctly unmaps each node in the hierarchy that is 
Packit b099d7
 *                     currently compressed out.
Packit b099d7
 *	Arguments:     w - the ow.
Packit b099d7
 *                     node - node to work one.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
UnmapAllExtraNodes(Widget w, HierarchyConstraints node)
Packit b099d7
{
Packit b099d7
    register int i, num;
Packit b099d7
    register HierarchyConstraints * ptr;
Packit b099d7
Packit b099d7
    if ((XmHierarchyC_status(node) & IS_COMPRESSED) && 
Packit b099d7
	(XmHierarchyC_status(node) & IS_MAPPED))
Packit b099d7
    {
Packit b099d7
	UnmapNode((XmOutlineWidget) w, (OutlineConstraints) node);
Packit b099d7
    }
Packit b099d7
	
Packit b099d7
    ptr = XmHierarchyC_children(node);
Packit b099d7
    for (num = XmHierarchyC_num_children(node), i = 0; i < num; i++, ptr++) 
Packit b099d7
	UnmapAllExtraNodes(w, *ptr);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: MoveNode
Packit b099d7
 *	Description: This function adds a widget to the movment queue
Packit b099d7
 *                   but does not move it until it becomes visible.
Packit b099d7
 *	Arguments: ow - the outline widget.
Packit b099d7
 *                 node - the node to move.
Packit b099d7
 *                 x, y - the X and Y location.
Packit b099d7
 *                 oc_x, oc_y - the X and Y location of the open close button.
Packit b099d7
 *                 map - map this child?
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
MoveNode(XmOutlineWidget ow, OutlineConstraints node, Position x, Position y,
Packit b099d7
	   Position oc_x, Position oc_y, Boolean map)
Packit b099d7
{
Packit b099d7
    XmOutlineC_new_x(node) = x;
Packit b099d7
    XmOutlineC_new_y(node) = y;
Packit b099d7
    XmOutlineC_oc_new_x(node) = oc_x;
Packit b099d7
    XmOutlineC_oc_new_y(node) = oc_y;
Packit b099d7
    XmOutlineC_map(node) = map;
Packit b099d7
    XmOutlineC_move(node) = True;
Packit b099d7
    XmOutlineC_unmap(node) = False;	
Packit b099d7
Packit b099d7
    _XmListAddBefore(XmOutline_child_op_list(ow), NULL, (XtPointer) node);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: UnmapNode
Packit b099d7
 *	Description: This function adds a widget to the movment queue
Packit b099d7
 *                   telling it to be unmapped.
Packit b099d7
 *	Arguments: ow - the outline widget.
Packit b099d7
 *                 node - the node to move.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
UnmapNode(XmOutlineWidget ow, OutlineConstraints node)
Packit b099d7
{
Packit b099d7
    XmOutlineC_map(node) = False;
Packit b099d7
    XmOutlineC_move(node) = False;
Packit b099d7
    XmOutlineC_unmap(node) = True;	
Packit b099d7
Packit b099d7
    _XmListAddBefore(XmOutline_child_op_list(ow), NULL, (XtPointer) node);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ProcessChildQueue
Packit b099d7
 *	Description: Processes the child queue.
Packit b099d7
 *	Arguments: ow - the outline widget.
Packit b099d7
 *                 vis - the visible rect.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ProcessChildQueue(XmOutlineWidget ow, XRectangle *vis)
Packit b099d7
{
Packit b099d7
    XmListElem *elem, *next;
Packit b099d7
Packit b099d7
    elem = XmListFirst(XmOutline_child_op_list(ow)); 
Packit b099d7
    while(elem != NULL) {
Packit b099d7
	OutlineConstraints info = (OutlineConstraints) XmListElemData(elem);
Packit b099d7
Packit b099d7
	next = XmListElemNext(elem);
Packit b099d7
Packit b099d7
	if (CheckWidget(vis, info))
Packit b099d7
	    _XmListRemove(XmOutline_child_op_list(ow), elem);
Packit b099d7
Packit b099d7
	elem = next;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: CheckWidget
Packit b099d7
 *	Description: This function checks a widget to see if it
Packit b099d7
 *                   needs to be operated on.
Packit b099d7
 *	Arguments:  visible - visible rect.
Packit b099d7
 *                  info - the child op info.
Packit b099d7
 *	Returns: True if operation complete.
Packit b099d7
 * 
Packit b099d7
 * NOTES: A widget will need to be operated on if it is mapped an will show 
Packit b099d7
 *        on the screen, or if the new location is on the screen.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
CheckWidget(XRectangle * visible, OutlineConstraints node)
Packit b099d7
{
Packit b099d7
    if (( ((XmHierarchyC_status(node) & IS_MAPPED) || XmOutlineC_map(node))  &&
Packit b099d7
	( WidgetInRect(visible, XmHierarchyC_open_close_button(node))        ||
Packit b099d7
	  WidgetInRect(visible, XmHierarchyC_parent(node))                   ||
Packit b099d7
	  WidgetInRect(visible, XmHierarchyC_widget(node)) ) )               ||
Packit b099d7
	LocInRect(visible, XmHierarchyC_open_close_button(node),
Packit b099d7
		    XmOutlineC_oc_new_x(node), XmOutlineC_oc_new_y(node))               ||
Packit b099d7
	LocInRect(visible, XmHierarchyC_widget(node),
Packit b099d7
		    XmOutlineC_new_x(node), XmOutlineC_new_y(node)) )
Packit b099d7
    {
Packit b099d7
	ProcessNode(node);
Packit b099d7
	return(True);
Packit b099d7
    }
Packit b099d7
    return(False);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ProcessNode
Packit b099d7
 *	Description: Processes the request made of this outline node.
Packit b099d7
 *	Arguments: node - the Outline node to process.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ProcessNode(OutlineConstraints node)
Packit b099d7
{
Packit b099d7
    XmOutlineWidgetClass tc;
Packit b099d7
    Widget w = XmHierarchyC_widget(node);
Packit b099d7
Packit b099d7
    if (w == NULL)
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    tc = (XmOutlineWidgetClass) XtClass(XtParent(w));
Packit b099d7
    
Packit b099d7
    if (XmOutlineC_move(node)) {
Packit b099d7
	_XmMoveWidget(XmHierarchyC_widget(node), 
Packit b099d7
		      XmOutlineC_new_x(node), XmOutlineC_new_y(node));
Packit b099d7
	
Packit b099d7
	if (XmHierarchyC_open_close_button(node) != NULL) 
Packit b099d7
	    _XmMoveWidget(XmHierarchyC_open_close_button(node),
Packit b099d7
			  XmOutlineC_oc_new_x(node), XmOutlineC_oc_new_y(node));
Packit b099d7
	XmOutlineC_move(node) = False;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (XmOutlineC_map(node)) {
Packit b099d7
	{
Packit b099d7
	    XmHierarchyNodeProc map_node;
Packit b099d7
	    _XmProcessLock();
Packit b099d7
	    map_node = tc->hierarchy_class.map_node
Packit b099d7
	    _XmProcessUnlock();
Packit b099d7
	    (*map_node)((HierarchyConstraints) node);
Packit b099d7
	}
Packit b099d7
	XmOutlineC_map(node) = False;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (XmOutlineC_unmap(node)) {
Packit b099d7
	{
Packit b099d7
	    XmHierarchyNodeProc	unmap_node;
Packit b099d7
	    _XmProcessLock();
Packit b099d7
	    unmap_node = tc->hierarchy_class.unmap_node
Packit b099d7
	    _XmProcessUnlock();
Packit b099d7
	    (*unmap_node)((HierarchyConstraints) node);
Packit b099d7
	}
Packit b099d7
	XmOutlineC_unmap(node) = False;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: WidgetInRect
Packit b099d7
 *	Description: Checks to see if widget is in the rect specified.
Packit b099d7
 *	Arguments: rect - the rect to check.
Packit b099d7
 *                 w - the widget to check.
Packit b099d7
 *	Returns: True if the widget is in the regien specified.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
WidgetInRect(XRectangle *rect, Widget w)
Packit b099d7
{
Packit b099d7
    if (w == NULL)
Packit b099d7
	return(False);
Packit b099d7
Packit b099d7
    return(LocInRect(rect, w, w->core.x, w->core.y));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: LocInRect
Packit b099d7
 *	Description: Checks to see if widget is in the rect specified.
Packit b099d7
 *                   given new X and Y locations.
Packit b099d7
 *	Arguments: rect - the rectangle to check.
Packit b099d7
 *                 w - the widget to check.
Packit b099d7
 *                 x, y - the new x and y locations.
Packit b099d7
 *	Returns: True if the widget is in the regien specified.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
LocInRect(XRectangle *rect, Widget w, Position x, Position y)
Packit b099d7
{ 
Packit b099d7
    register int x1, x2;
Packit b099d7
    register int y1, y2;
Packit b099d7
Packit b099d7
    if (w == NULL) return(False);
Packit b099d7
Packit b099d7
    x1 = x + w->core.width;
Packit b099d7
    y1 = y + w->core.height;
Packit b099d7
Packit b099d7
    x2 = rect->x + rect->width;
Packit b099d7
    y2 = rect->y + rect->height;
Packit b099d7
Packit b099d7
    return (!((x > x2) || (y > y2) || (x1 < rect->x) || (y1 < rect->y)));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: MoveNodesTimer
Packit b099d7
 *	Description: processes one node from the movement queue.
Packit b099d7
 *	Arguments: data - A Pointer to the outline widget.
Packit b099d7
 *                 id - th ext interval id.
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static Boolean
Packit b099d7
MoveNodesTimer(XtPointer data)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) data;
Packit b099d7
    XmListElem *elem = XmListFirst(XmOutline_child_op_list(ow));
Packit b099d7
Packit b099d7
    if (elem != NULL) { 
Packit b099d7
	OutlineConstraints node = (OutlineConstraints) XmListElemData(elem);
Packit b099d7
	ProcessNode(node);
Packit b099d7
	_XmListRemove(XmOutline_child_op_list(ow), elem);
Packit b099d7
	return (False);
Packit b099d7
    }
Packit b099d7
    XmHierarchy_work_proc_id(ow) = (XtWorkProcId) NULL;
Packit b099d7
    return (True);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: NegotiateNodeWidth
Packit b099d7
 *	Description:   Does a geometry negoation with the child
Packit b099d7
 *                     specified by node with the intent of fitting
Packit b099d7
 *                     the child within the existing width of the
Packit b099d7
 *                     Outline widget.
Packit b099d7
 *	Arguments:     w    - The XmOutline widget
Packit b099d7
 *                     node - The constraint record for the child in
Packit b099d7
 *                            question
Packit b099d7
 *	Returns:       The width negotiated
Packit b099d7
 */
Packit b099d7
static void
Packit b099d7
NegotiateNodeWidth(Widget w, OutlineConstraints node)
Packit b099d7
{
Packit b099d7
    Dimension width_avail;
Packit b099d7
    XtWidgetGeometry geom_asked, geom_agreed;
Packit b099d7
    XtGeometryResult result;
Packit b099d7
    Dimension curr_width, curr_height;
Packit b099d7
Packit b099d7
    width_avail = w->core.width - XmOutlineC_widget_x(node);
Packit b099d7
Packit b099d7
    curr_width = XmHierarchyC_widget(node)->core.width;
Packit b099d7
    curr_height = XmHierarchyC_widget(node)->core.height;
Packit b099d7
Packit b099d7
    geom_asked.request_mode = XtCWQueryOnly;
Packit b099d7
    result = XtQueryGeometry(XmHierarchyC_widget(node),
Packit b099d7
			     &geom_asked, &geom_agreed);
Packit b099d7
Packit b099d7
    if(geom_agreed.width  < 1) geom_agreed.width  = 1;
Packit b099d7
    if(geom_agreed.height < 1) geom_agreed.height = 1;
Packit b099d7
Packit b099d7
    if(geom_agreed.width <= width_avail) {
Packit b099d7
	/*
Packit b099d7
	 * If it's the right size already, just return
Packit b099d7
	 */
Packit b099d7
	if(curr_width  == geom_agreed.width &&
Packit b099d7
	   curr_height == geom_agreed.height)
Packit b099d7
	{
Packit b099d7
	    return;
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    _XmResizeWidget(XmHierarchyC_widget(node),
Packit b099d7
			    geom_agreed.width,
Packit b099d7
			    geom_agreed.height,
Packit b099d7
			    geom_agreed.border_width);
Packit b099d7
	    return;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Otherwise tell the widget to size itself to the right width and
Packit b099d7
     * see what we get
Packit b099d7
     */
Packit b099d7
    geom_asked.request_mode = CWWidth;
Packit b099d7
    geom_asked.width        = width_avail;
Packit b099d7
    result = XtQueryGeometry(XmHierarchyC_widget(node),
Packit b099d7
			     &geom_asked, &geom_agreed);
Packit b099d7
Packit b099d7
    if(geom_agreed.width  < 1) geom_agreed.width  = 1;
Packit b099d7
    if(geom_agreed.height < 1) geom_agreed.height = 1;
Packit b099d7
Packit b099d7
    if(result == XtGeometryYes)
Packit b099d7
    {
Packit b099d7
	_XmResizeWidget(XmHierarchyC_widget(node),
Packit b099d7
			width_avail,
Packit b099d7
			geom_agreed.height,
Packit b099d7
			geom_agreed.border_width);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
    else if(result == XtGeometryAlmost)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * See if it lied and set the width correctly anyway
Packit b099d7
	 */
Packit b099d7
	if(geom_agreed.width <= width_avail) {
Packit b099d7
	    _XmResizeWidget(XmHierarchyC_widget(node),
Packit b099d7
			    geom_agreed.width,
Packit b099d7
			    geom_agreed.height,
Packit b099d7
			    geom_agreed.border_width);
Packit b099d7
	    return;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    /*
Packit b099d7
     * If we get here, the sucker tried to deny the request, so just
Packit b099d7
     * clip the thing.  Thbbbt!
Packit b099d7
     */
Packit b099d7
    _XmResizeWidget(XmHierarchyC_widget(node),
Packit b099d7
		    width_avail,
Packit b099d7
		    geom_agreed.height,
Packit b099d7
		    geom_agreed.border_width);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/* drawing on expose; taken from XmTree in horizontal mode with 
Packit b099d7
** ladder drawing 
Packit b099d7
** Note: it looks not so good when indentSpace is very small
Packit b099d7
*/
Packit b099d7
Packit b099d7
static void
Packit b099d7
RedrawOutlineLines(Widget w, XRectangle * rect)
Packit b099d7
{
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) w;
Packit b099d7
Packit b099d7
    if (XtIsRealized(w))	/* && has children */
Packit b099d7
	DrawOutlineLine(w, rect, (OutlineConstraints) XmHierarchy_top_node(ow));
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
DrawOutlineLine(Widget w, XRectangle *rect, OutlineConstraints node)
Packit b099d7
{
Packit b099d7
Packit b099d7
    OutlineConstraints from_node = node;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_widget(node) != NULL && !XtIsManaged(XmHierarchyC_widget(node)))
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Hunt up the list until we find a non-hidden parent to be the from
Packit b099d7
     * node.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    while ((XmHierarchyC_parent(from_node) != NULL) && 
Packit b099d7
	   (XmHierarchyC_state(from_node) == XmHidden))
Packit b099d7
    {
Packit b099d7
	from_node = GetNodeInfo(XmHierarchyC_parent(from_node));
Packit b099d7
    }
Packit b099d7
Packit b099d7
   {
Packit b099d7
    OutlineConstraints * kids;
Packit b099d7
    register int i, num_kids;
Packit b099d7
    Boolean anyKidManaged = False; /* CR03730 Support Case 22066 */
Packit b099d7
    LadderPoint from_node_point, kid_point;
Packit b099d7
    LadderPoint last_kid_point;
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget)w;
Packit b099d7
Packit b099d7
    num_kids = XmHierarchyC_num_children(node);
Packit b099d7
    kids = (OutlineConstraints *) XmHierarchyC_children(node);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * This only executes if the root is hidden.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(from_node) == XmHidden) {
Packit b099d7
	for (i = 0; i < num_kids; i++, kids++) 
Packit b099d7
	    DrawOutlineLine(w, rect, *kids);	/* recurse to descendants. */
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(from_node) == XmClosed)
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    _CalcNodeMidPoint( from_node, w, &from_node_point );
Packit b099d7
Packit b099d7
    for (i = 0; i < num_kids; i++, kids++) {
Packit b099d7
      if (XtIsManaged(XmHierarchyC_widget((*kids)))) {
Packit b099d7
	anyKidManaged = True; /* CR03730 Support Case 22066 */
Packit b099d7
	if (XmHierarchyC_state((*kids)) != XmHidden) {
Packit b099d7
	  _OutlineDrawLine(w, rect, from_node, *kids, from_node_point, &kid_point);
Packit b099d7
Packit b099d7
	  /* set up the points to draw ladder lines */
Packit b099d7
Packit b099d7
	    last_kid_point.x = kid_point.x;
Packit b099d7
	    last_kid_point.y = kid_point.y;
Packit b099d7
	    
Packit b099d7
	}
Packit b099d7
	DrawOutlineLine(w, rect, *kids);	/* recurse to descendants. */
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* Draw extra ladder lines if necessary.
Packit b099d7
     */
Packit b099d7
    if (num_kids > 0 && anyKidManaged) 
Packit b099d7
	{ /* CR03730 Support Case 22066 anyKidManaged added to prevent draw needless
Packit b099d7
	     (x & y are not initialized if no kid managed) line */
Packit b099d7
          XDrawLine(XtDisplay(w), XtWindow(w), XmOutline_draw_gc(ow), from_node_point.x, from_node_point.y,
Packit b099d7
		from_node_point.x, last_kid_point.y );
Packit b099d7
	}
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
_CalcNodeMidPoint( OutlineConstraints node, Widget w, LadderPoint *ret_point )
Packit b099d7
{
Packit b099d7
  if (!XmHierarchyC_widget(node)) return;
Packit b099d7
Packit b099d7
  {
Packit b099d7
  XmOutlineWidget ow = (XmOutlineWidget)w;
Packit b099d7
  Widget which;
Packit b099d7
  int value;
Packit b099d7
Packit b099d7
  if (XmHierarchyC_open_close_button(node))
Packit b099d7
	value = (int)XtWidth(which=XmHierarchyC_open_close_button(node));
Packit b099d7
  else
Packit b099d7
	{
Packit b099d7
	value = (int)XmOutline_indent_space(ow);
Packit b099d7
	which = XmHierarchyC_widget(node);
Packit b099d7
	}
Packit b099d7
Packit b099d7
    ret_point->x = XmOutlineC_open_close_x(node) + value/2;
Packit b099d7
    ret_point->y = XtY(which)+XtHeight(which);	/* plus possible pad */
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
_OutlineDrawLine(Widget w, XRectangle *rect, OutlineConstraints parent, 
Packit b099d7
	  OutlineConstraints child, LadderPoint from_ladder_point,
Packit b099d7
	  LadderPoint *to_ladder_point )
Packit b099d7
	  
Packit b099d7
{
Packit b099d7
    GC gc;
Packit b099d7
    XmOutlineWidget ow = (XmOutlineWidget) w;
Packit b099d7
    register int x2, y2;
Packit b099d7
    register int rx2, ry2, cx1, cx2, cy1, cy2;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * (from_ladder_point.x, from_ladder_point.y) are the coordinates
Packit b099d7
     *     of the parent's midpoint
Packit b099d7
     * (x2, y2) are the coordinates of the child midpoint
Packit b099d7
     *
Packit b099d7
     * We will end up drawing a partial ladder line from 
Packit b099d7
     *     (cx1, cy1) to (cx2, cy2) 
Packit b099d7
     *
Packit b099d7
     * (rx2, ry2) are the coordinates of the lower right of clip rectangle
Packit b099d7
     */
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Must always do the first node since it is what draws the root
Packit b099d7
     * of the ladder.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (child != (OutlineConstraints) XmHierarchyC_children(parent)[0] && 
Packit b099d7
	(!(XmHierarchyC_status(child) & IS_MAPPED) || 
Packit b099d7
	 (XmHierarchyC_status(child) & IS_COMPRESSED)))
Packit b099d7
    {
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    gc = XmOutline_draw_gc(ow);
Packit b099d7
	
Packit b099d7
      x2 = XmOutlineC_open_close_x(child);
Packit b099d7
      y2 = XtY(XmHierarchyC_widget(child)) + XtHeight(XmHierarchyC_widget(child))/2;
Packit b099d7
Packit b099d7
    cx1 = MIN(from_ladder_point.x, x2);
Packit b099d7
    cx2 = MAX(from_ladder_point.x, x2);
Packit b099d7
Packit b099d7
    cy1 = MIN(from_ladder_point.y, y2);
Packit b099d7
    cy2 = MAX(from_ladder_point.y, y2);
Packit b099d7
Packit b099d7
    cy1 = cy2 = y2;
Packit b099d7
Packit b099d7
    rx2 = rect->x + rect->width;
Packit b099d7
    ry2 = rect->y + rect->height;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Not very pretty, only checks to see if the rect containing the
Packit b099d7
     * line is partially within the exposed rectangle.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!((cx1 > rx2) || (cy1 > ry2) || (cx2 < rect->x) || (cy2 < rect->y)))
Packit b099d7
	    XDrawLine(XtDisplay(w), XtWindow(w), gc, cx1, cy1, cx2, cy2);
Packit b099d7
Packit b099d7
    /* This is sent back because the ladder lines get connected later */
Packit b099d7
    to_ladder_point->x = cx1;
Packit b099d7
    to_ladder_point->y = cy1;
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 *  Public functions.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: XmCreateOutline
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
XmCreateOutline(Widget parent, String name,
Packit b099d7
		ArgList args, Cardinal num_args)
Packit b099d7
{
Packit b099d7
    return(XtCreateWidget(name, xmOutlineWidgetClass,
Packit b099d7
			  parent, args, num_args));
Packit b099d7
}