Blame lib/Xm/Hierarchy.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/HierarchyP.h>
Packit b099d7
#include <Xm/PushB.h>
Packit b099d7
#include <Xm/IconButton.h>
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * The bits for the default folder images. 
Packit b099d7
 */
Packit b099d7
Packit b099d7
#define open_file_width 12
Packit b099d7
#define open_file_height 8
Packit b099d7
static unsigned char open_file_bits[] = {
Packit b099d7
   0x06, 0x00, 0xf9, 0x01, 0x01, 0x01, 0x01, 0x01, 0xf9, 0x0f, 0x05, 0x04,
Packit b099d7
   0x03, 0x02, 0xff, 0x01};
Packit b099d7
Packit b099d7
#define close_file_width 12
Packit b099d7
#define close_file_height 8
Packit b099d7
static unsigned char close_file_bits[] = {
Packit b099d7
   0x0e, 0x00, 0xf1, 0x01, 0xff, 0x02, 0x81, 0x02, 0x81, 0x02, 0x81, 0x02,
Packit b099d7
   0x81, 0x02, 0xff, 0x01};
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	TYPEDEFS AND DEFINES
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
#define SUPERCLASS ((WidgetClass) &xmManagerClassRec)
Packit b099d7
Packit b099d7
#define ALLOC_INC 10
Packit b099d7
Packit b099d7
typedef enum {YES, NO, DONT_CARE} SuccessType;
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 ClassInit(), ClassPartInitialize(WidgetClass), InsertChild(Widget);
Packit b099d7
static void Destroy(Widget), ConstraintDestroy(Widget);
Packit b099d7
static void Realize(Widget, Mask *, XSetWindowAttributes *);
Packit b099d7
static void Initialize(Widget, Widget, ArgList, Cardinal *);
Packit b099d7
static void ConstraintInitialize(Widget, Widget, ArgList, Cardinal *);
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 void ChangeNodeState(HierarchyConstraints);
Packit b099d7
static void MapNode(HierarchyConstraints), UnmapNode(HierarchyConstraints);
Packit b099d7
static void UnmapAllExtraNodes(Widget, HierarchyConstraints);
Packit b099d7
static void BuildNodeTable(Widget, HierarchyConstraints, Cardinal *);
Packit b099d7
static void ResetOpenCloseButton(Widget, HierarchyConstraints);
Packit b099d7
static void ToggleNodeState(Widget, XtPointer, XtPointer);
Packit b099d7
Packit b099d7
/******************
Packit b099d7
 * Action Routines
Packit b099d7
 ******************/
Packit b099d7
Packit b099d7
/******************
Packit b099d7
 * Type Converters
Packit b099d7
 ******************/
Packit b099d7
Packit b099d7
static Boolean CvtStringToNodeState(Display *, XrmValuePtr, Cardinal *, 
Packit b099d7
				    XrmValuePtr, XrmValuePtr, XtPointer *);
Packit b099d7
Packit b099d7
/*********************
Packit b099d7
 * Internal Routines.
Packit b099d7
 *********************/
Packit b099d7
Packit b099d7
static void BumpChildren(HierarchyConstraints *, int, int);
Packit b099d7
static void RemoveNodeFromParent(HierarchyConstraints);
Packit b099d7
static void AddChild(HierarchyConstraints, HierarchyConstraints);
Packit b099d7
static void AddChildToList(HierarchyConstraints **, Cardinal *, Cardinal *,
Packit b099d7
			   HierarchyConstraints);
Packit b099d7
static void RemoveChildren(HierarchyConstraints *, Cardinal);
Packit b099d7
static void DestroyFolderImages(Widget);
Packit b099d7
static Boolean LoadFolderImages(Widget,Widget);
Packit b099d7
Packit b099d7
static HierarchyConstraints GetNodeInfo(Widget);
Packit b099d7
Packit b099d7
static Boolean AncestorClosed(HierarchyConstraints);
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC DECLARATIONS
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
static char defaultTranslations[] =
Packit b099d7
	"<EnterWindow>:  ManagerEnter()    \n\
Packit b099d7
	 <LeaveWindow>:  ManagerLeave()    \n\
Packit b099d7
	 <FocusOut>:     ManagerFocusOut() \n\
Packit b099d7
	 <FocusIn>:      ManagerFocusIn()";
Packit b099d7
Packit b099d7
static XtResource resources[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNwidth, XmCWidth, XmRHorizontalDimension,
Packit b099d7
        sizeof(Dimension), XtOffsetOf(CoreRec, core.width),
Packit b099d7
        XmRImmediate, (XtPointer) 300
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNheight, XmCHeight, XmRVerticalDimension,
Packit b099d7
        sizeof(Dimension), XtOffsetOf(CoreRec, core.height),
Packit b099d7
        XmRImmediate, (XtPointer) 300
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNautoClose, XmCAutoClose, XmRBoolean,
Packit b099d7
        sizeof(Boolean), XtOffsetOf(XmHierarchyRec, hierarchy.auto_close),
Packit b099d7
        XmRImmediate, (XtPointer) True
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNrefigureMode, XmCBoolean, XmRBoolean,
Packit b099d7
        sizeof(Boolean), XtOffsetOf(XmHierarchyRec, hierarchy.refigure_mode),
Packit b099d7
        XmRImmediate, (XtPointer) True
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNnodeStateCallback, XmCNodeStateCallback, XmRCallback,
Packit b099d7
        sizeof(XtCallbackList), XtOffsetOf(XmHierarchyRec, hierarchy.node_state_callback),
Packit b099d7
        XmRPointer, (XtPointer) NULL
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNverticalMargin, XmCDimension, XmRVerticalDimension,
Packit b099d7
        sizeof(Dimension), XtOffsetOf(XmHierarchyRec, hierarchy.v_margin),
Packit b099d7
        XmRImmediate, (XtPointer) 2
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNhorizontalMargin, XmCDimension, XmRHorizontalDimension,
Packit b099d7
        sizeof(Dimension), XtOffsetOf(XmHierarchyRec, hierarchy.h_margin),
Packit b099d7
        XmRImmediate, (XtPointer) 2
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNopenFolderPixmap, XmCPixmap, XmRPrimForegroundPixmap,
Packit b099d7
        sizeof(Pixmap), XtOffsetOf(XmHierarchyRec, hierarchy.open_folder),
Packit b099d7
        XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNcloseFolderPixmap, XmCPixmap, XmRPrimForegroundPixmap,
Packit b099d7
        sizeof(Pixmap), XtOffsetOf(XmHierarchyRec, hierarchy.close_folder),
Packit b099d7
        XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNnodeStateChangedCallback, XmCNodeStateChangedCallback, XmRCallback,
Packit b099d7
        sizeof(XtCallbackList),  XtOffsetOf(XmHierarchyRec, hierarchy.node_state_changed_callback),
Packit b099d7
        XmRPointer, (XtPointer) NULL
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNnodeStateBegEndCallback, XmCCallback, XmRCallback,
Packit b099d7
        sizeof(XtCallbackList), XtOffsetOf(XmHierarchyRec, hierarchy.node_state_beg_end_callback),
Packit b099d7
        XmRPointer, (XtPointer) NULL
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNnodeStateBeginEndCallback, XmCCallback, XmRCallback,
Packit b099d7
        sizeof(XtCallbackList), XtOffsetOf(XmHierarchyRec, hierarchy.node_state_beg_end_callback),
Packit b099d7
        XmRPointer, (XtPointer) NULL
Packit b099d7
      }
Packit b099d7
    };
Packit b099d7
Packit b099d7
    static XmSyntheticResource get_resources[] =
Packit b099d7
    {
Packit b099d7
      {
Packit b099d7
        XmNhorizontalMargin, sizeof(Dimension),
Packit b099d7
        XtOffsetOf(XmHierarchyRec, hierarchy.h_margin),
Packit b099d7
        XmeFromHorizontalPixels, (XmImportProc) XmeToHorizontalPixels
Packit b099d7
      },
Packit b099d7
      {
Packit b099d7
        XmNverticalMargin, sizeof(Dimension),
Packit b099d7
        XtOffsetOf(XmHierarchyRec, hierarchy.v_margin),
Packit b099d7
        XmeFromVerticalPixels, (XmImportProc) XmeToVerticalPixels
Packit b099d7
      }
Packit b099d7
    };
Packit b099d7
Packit b099d7
    static XtResource constraints[] =
Packit b099d7
    {
Packit b099d7
      {
Packit b099d7
        XmNnodeState, XmCNodeState, XmRXmHierarchyNodeState,
Packit b099d7
        sizeof(XmHierarchyNodeState), XtOffsetOf(XmHierarchyConstraintRec, hierarchy.state),
Packit b099d7
        XmRImmediate, (XtPointer) XmOpen
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNparentNode, XmCParentNode, XmRWidget,
Packit b099d7
        sizeof(Widget), XtOffsetOf(XmHierarchyConstraintRec, hierarchy.parent),
Packit b099d7
        XmRImmediate, (XtPointer) NULL
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNinsertBefore, XmCInsertBefore, XmRWidget,
Packit b099d7
        sizeof(Widget), XtOffsetOf(XmHierarchyConstraintRec, hierarchy.insert_before),
Packit b099d7
        XmRImmediate, (XtPointer) NULL
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNnodeOpenFolderPixmap, XmCPixmap, XmRPrimForegroundPixmap,
Packit b099d7
        sizeof(Pixmap), XtOffsetOf(XmHierarchyConstraintRec, hierarchy.open_folder),
Packit b099d7
        XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
Packit b099d7
      },
Packit b099d7
Packit b099d7
      {
Packit b099d7
        XmNnodeCloseFolderPixmap, XmCPixmap, XmRPrimForegroundPixmap,
Packit b099d7
        sizeof(Pixmap), XtOffsetOf(XmHierarchyConstraintRec, hierarchy.close_folder),
Packit b099d7
        XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
Packit b099d7
      }
Packit b099d7
    };
Packit b099d7
Packit b099d7
    XmHierarchyClassRec xmHierarchyClassRec = {
Packit b099d7
  { /* core fields */
Packit b099d7
    /* superclass		*/	SUPERCLASS,
Packit b099d7
    /* class_name		*/	"XmHierarchy",
Packit b099d7
    /* widget_size		*/	sizeof(XmHierarchyRec),
Packit b099d7
    /* class_initialize		*/	ClassInit,
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			*/	Destroy,
Packit b099d7
    /* resize			*/	NULL,
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			*/	defaultTranslations,
Packit b099d7
    /* query_geometry		*/	NULL,
Packit b099d7
    /* display_accelerator	*/	XtInheritDisplayAccelerator,
Packit b099d7
    /* extension		*/	NULL
Packit b099d7
  },
Packit b099d7
   {		/* composite_class fields */
Packit b099d7
    /* geometry_manager   */      XtInheritGeometryManager,
Packit b099d7
    /* change_managed     */      XtInheritChangeManaged,
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(XmHierarchyConstraintRec),
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         */      XmInheritParentProcess,
Packit b099d7
    /* extension	      */      NULL,	
Packit b099d7
   },
Packit b099d7
  { /* Hierarchy fields */
Packit b099d7
      ChangeNodeState,		/* The function for changing the node state. */
Packit b099d7
      MapNode,			/* Maps a given node. */
Packit b099d7
      UnmapNode,		/* Unmaps a given node. */
Packit b099d7
      UnmapAllExtraNodes,	/* Unmaps all extra nodes. */
Packit b099d7
      BuildNodeTable,		/* Builds up the node table. */
Packit b099d7
      ResetOpenCloseButton,  /* Resets the information about the o/c button. */
Packit b099d7
      ToggleNodeState,		/* node_toggle function. */
Packit b099d7
      NULL,			/* extension          */
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
WidgetClass xmHierarchyWidgetClass = (WidgetClass) &xmHierarchyClassRec;
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC CODE
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: ClassInit
Packit b099d7
 *	Description:   Called to initialize information specific
Packit b099d7
 *                     to this widget class.
Packit b099d7
 *	Arguments:     none.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
ClassInit()
Packit b099d7
{
Packit b099d7
    XmHierarchyClassRec* wc = &xmHierarchyClassRec;
Packit b099d7
Packit b099d7
    XtSetTypeConverter(XmRString, XmRXmHierarchyNodeState,CvtStringToNodeState,
Packit b099d7
		       NULL, (Cardinal) 0, XtCacheAll, (XtDestructor) NULL);
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
    XmHierarchyWidgetClass superC, wc = (XmHierarchyWidgetClass) class;
Packit b099d7
    
Packit b099d7
    _XmProcessLock();
Packit b099d7
    superC = (XmHierarchyWidgetClass)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 Hierarchy class eventually.
Packit b099d7
 */
Packit b099d7
Packit b099d7
    if (wc->hierarchy_class.change_node_state == XtInheritChangeNodeState) 
Packit b099d7
    {
Packit b099d7
	wc->hierarchy_class.change_node_state =
Packit b099d7
	                            superC->hierarchy_class.change_node_state;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (wc->hierarchy_class.map_node == XtInheritMapNode) 
Packit b099d7
	wc->hierarchy_class.map_node = superC->hierarchy_class.map_node;
Packit b099d7
Packit b099d7
    if (wc->hierarchy_class.unmap_node == XtInheritUnmapNode) 
Packit b099d7
	wc->hierarchy_class.unmap_node = superC->hierarchy_class.unmap_node;
Packit b099d7
Packit b099d7
    if (wc->hierarchy_class.unmap_all_extra_nodes==XtInheritUnmapAllExtraNodes)
Packit b099d7
    {
Packit b099d7
	wc->hierarchy_class.unmap_all_extra_nodes =
Packit b099d7
	                         superC->hierarchy_class.unmap_all_extra_nodes;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (wc->hierarchy_class.build_node_table == XtInheritBuildNodeTable)
Packit b099d7
    {
Packit b099d7
	wc->hierarchy_class.build_node_table =
Packit b099d7
	                             superC->hierarchy_class.build_node_table;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (wc->hierarchy_class.reset_open_close_button ==
Packit b099d7
	XtInheritResetOpenCloseButton) 
Packit b099d7
    {
Packit b099d7
	wc->hierarchy_class.reset_open_close_button = 
Packit b099d7
	                      superC->hierarchy_class.reset_open_close_button;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (wc->hierarchy_class.toggle_node_state == XtInheritToggleNodeState) {
Packit b099d7
Packit b099d7
	wc->hierarchy_class.toggle_node_state = 
Packit b099d7
	                            superC->hierarchy_class.toggle_node_state;
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
    XmHierarchyWidget hw = (XmHierarchyWidget) set;
Packit b099d7
    HierarchyConstraints top_node;
Packit b099d7
    Window root = RootWindowOfScreen(XtScreen(set));
Packit b099d7
Packit b099d7
    top_node = ((HierarchyConstraints) 
Packit b099d7
		XtMalloc(sizeof(HierarchyConstraintRec)));
Packit b099d7
Packit b099d7
    XmHierarchy_work_proc_id(hw) = (XtWorkProcId) NULL;
Packit b099d7
    XmHierarchy_node_table(hw) = NULL;
Packit b099d7
    XmHierarchy_num_nodes(hw) = XmHierarchy_alloc_nodes(hw) = 0;
Packit b099d7
Packit b099d7
    XmHierarchy_top_node(hw) = top_node;
Packit b099d7
Packit b099d7
    /* make default folder button images */
Packit b099d7
Packit b099d7
    XmHierarchy_def_open_folder(hw) = 
Packit b099d7
      XCreateBitmapFromData(XtDisplay(set),root, (char *)open_file_bits, 
Packit b099d7
			    open_file_width, open_file_height);
Packit b099d7
    
Packit b099d7
    XmHierarchy_def_close_folder(hw) = 
Packit b099d7
      XCreateBitmapFromData(XtDisplay(set), root,(char *)close_file_bits,
Packit b099d7
			    close_file_width, close_file_height);
Packit b099d7
Packit b099d7
    XmHierarchyC_state(top_node) = XmHidden;
Packit b099d7
    XmHierarchyC_parent(top_node) = NULL;
Packit b099d7
    XmHierarchyC_widget(top_node) = NULL;
Packit b099d7
    XmHierarchyC_status(top_node) = IS_COMPRESSED;
Packit b099d7
    XmHierarchyC_num_children(top_node) = XmHierarchyC_alloc(top_node) = 0;
Packit b099d7
    XmHierarchyC_children(top_node) = NULL;
Packit b099d7
Packit b099d7
    (void)LoadFolderImages(req, set );
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: Destroy
Packit b099d7
 *	Description:   Cleans up after my widget.
Packit b099d7
 *	Arguments:     w - the widget.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
Destroy(Widget w)
Packit b099d7
{
Packit b099d7
    XmHierarchyWidget hw = (XmHierarchyWidget) w;    
Packit b099d7
Packit b099d7
    if( XmHierarchy_work_proc_id(hw) != (XtWorkProcId) NULL )
Packit b099d7
    {
Packit b099d7
	XtRemoveWorkProc(XmHierarchy_work_proc_id(hw));
Packit b099d7
	XmHierarchy_work_proc_id(hw) = (XtWorkProcId) NULL;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    DestroyFolderImages(w);
Packit b099d7
Packit b099d7
    XtFree((char *) XmHierarchy_node_table(hw));
Packit b099d7
    XtFree((char *) XmHierarchyC_children(XmHierarchy_top_node(hw)));
Packit b099d7
    XtFree((char *) XmHierarchy_top_node(hw));
Packit b099d7
Packit b099d7
    XtRemoveAllCallbacks(w, XmNnodeStateBegEndCallback);
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
Packit b099d7
XtWidgetProc insert_child;
Packit b099d7
   if (_XmGadgetWarning(w))
Packit b099d7
       return;
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
 * 
Packit b099d7
 * Functions for handling the Constraint resources.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: ConstraintInitialize
Packit b099d7
 *	Description:   Called when a child's constriaint's 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
    XmHierarchyWidget hw = (XmHierarchyWidget) XtParent(set);    
Packit b099d7
    XmHierarchyWidgetClass hc = (XmHierarchyWidgetClass) XtClass(hw);
Packit b099d7
    HierarchyConstraints node = GetNodeInfo(set);
Packit b099d7
Packit b099d7
    if (XmHierarchyC_parent(node) == set) {
Packit b099d7
	XmeWarning(set,	XmNnodeParentIsSelfMsg);
Packit b099d7
	XmHierarchyC_parent(node) = NULL;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmHierarchyC_widget(node) = set;
Packit b099d7
    XmHierarchyC_status(node) = IS_COMPRESSED;
Packit b099d7
    XmHierarchyC_num_children(node) = XmHierarchyC_alloc(node) = 0;
Packit b099d7
    XmHierarchyC_children(node) = NULL;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * I will be handling the mapped state of this widget
Packit b099d7
     * myself, not letting the Intrinsics get in the way.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XtSetMappedWhenManaged(set, False);
Packit b099d7
Packit b099d7
    XmHierarchyC_open_close_button(node) = NULL;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) != XmNotInHierarchy) {
Packit b099d7
        XmHierarchyResetButtonProc reset_open_close_button;
Packit b099d7
Packit b099d7
        _XmProcessLock();
Packit b099d7
        reset_open_close_button = hc->hierarchy_class.reset_open_close_button;
Packit b099d7
        _XmProcessUnlock();
Packit b099d7
Packit b099d7
        (*reset_open_close_button)((Widget) hw, node);
Packit b099d7
Packit b099d7
	if (XmHierarchyC_parent(node) == NULL) 
Packit b099d7
	    AddChild(XmHierarchy_top_node(hw), node);
Packit b099d7
	else
Packit b099d7
	    AddChild(GetNodeInfo(XmHierarchyC_parent(node)), node);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ConstraintDestroy
Packit b099d7
 *	Description:   Destroys all data allocated by the constriaint 
Packit b099d7
 *                     record.
Packit b099d7
 *	Arguments:     w - the widget.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Packit b099d7
 * DANGER DANGER DANGER
Packit b099d7
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Packit b099d7
 * 
Packit b099d7
 * This code exercises a bug in the MIT R4 Xt Intrinsics 
Packit b099d7
 * that will occur if a large number of widgets deleted from within
Packit b099d7
 * a ConstraintDestroy procedure or a Destroy Proceedure.
Packit b099d7
 *
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ConstraintDestroy(Widget w)
Packit b099d7
{
Packit b099d7
    HierarchyConstraints node = GetNodeInfo(w);
Packit b099d7
    XmHierarchyWidget hw = (XmHierarchyWidget) XtParent(w);
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) == XmNotInHierarchy) 
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * If the Hierarchy is being destroyed then we do not want to
Packit b099d7
     * destroy widgets that may already be gone.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!hw->core.being_destroyed) {
Packit b099d7
	XmHierarchyWidgetClass hc;
Packit b099d7
	Cardinal current;
Packit b099d7
Packit b099d7
	hc = (XmHierarchyWidgetClass) XtClass((Widget) hw);
Packit b099d7
Packit b099d7
	RemoveNodeFromParent(node);
Packit b099d7
	RemoveChildren(XmHierarchyC_children(node), XmHierarchyC_num_children(node));
Packit b099d7
Packit b099d7
	if (XmHierarchyC_open_close_button(node) != NULL)
Packit b099d7
	    XtDestroyWidget(XmHierarchyC_open_close_button(node));
Packit b099d7
Packit b099d7
	current = 0;
Packit b099d7
    {
Packit b099d7
        XmHierarchyBuildTableProc build_node_table;
Packit b099d7
Packit b099d7
        _XmProcessLock();
Packit b099d7
        build_node_table = hc->hierarchy_class.build_node_table;
Packit b099d7
        _XmProcessUnlock();
Packit b099d7
Packit b099d7
    	(*build_node_table) ((Widget)hw, XmHierarchy_top_node(hw), ¤t;;
Packit b099d7
    }
Packit b099d7
Packit b099d7
	XmHierarchy_num_nodes(hw) = current;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XtFree((char *) XmHierarchyC_children(node));
Packit b099d7
}
Packit b099d7
    
Packit b099d7
/*	Function Name: RecursiveChildSetValues
Packit b099d7
 *	Description:   Gets the id of the old pixmap and then sets the 
Packit b099d7
 *                     folder buttons 
Packit b099d7
 *	Arguments:     HierarchyConstraints node - current node
Packit b099d7
 *                     Pixmap open_folder - new open folder image
Packit b099d7
 *		       Pixmap close_folder - new close folder image
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
static void
Packit b099d7
SetChildValues( HierarchyConstraints node, Pixmap open_folder,
Packit b099d7
	       Pixmap close_folder )
Packit b099d7
{
Packit b099d7
  Arg args[1];
Packit b099d7
  Pixmap which = None;	
Packit b099d7
Packit b099d7
  if (XmHierarchyC_state(node) == XmOpen) 
Packit b099d7
  {
Packit b099d7
	if ( (XmUNSPECIFIED_PIXMAP != XmHierarchyC_open_folder(node)) && XmHierarchyC_open_folder(node))
Packit b099d7
		which = XmHierarchyC_open_folder(node);
Packit b099d7
	else 
Packit b099d7
		which = open_folder;	/* can be None */
Packit b099d7
	XtSetArg(args[0], XmNpixmap, which ); 
Packit b099d7
	XtSetValues(XmHierarchyC_open_close_button(node), args, 1 );
Packit b099d7
  }
Packit b099d7
  else 
Packit b099d7
  if (XmHierarchyC_state(node) == XmClosed) 
Packit b099d7
  {
Packit b099d7
	if ( (XmUNSPECIFIED_PIXMAP != XmHierarchyC_close_folder(node)) && XmHierarchyC_close_folder(node))
Packit b099d7
		which = XmHierarchyC_close_folder(node);
Packit b099d7
	else 
Packit b099d7
		which = close_folder;	/* can be None */
Packit b099d7
	XtSetArg(args[0], XmNpixmap, which ); 
Packit b099d7
	XtSetValues(XmHierarchyC_open_close_button(node), args, 1 );
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*	Function Name: RecursiveChildSetValues
Packit b099d7
 *	Description:   Traverses the tree, and calls SetChildValues on each
Packit b099d7
 *                     node 
Packit b099d7
 *	Arguments:     HierarchyConstraints curr_node
Packit b099d7
 *                     Pixmap open_folder
Packit b099d7
 *		       Pixmap close_folder
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
static void
Packit b099d7
RecursiveSetChildValues( HierarchyConstraints curr_node, Pixmap open_folder,
Packit b099d7
			Pixmap close_folder )
Packit b099d7
{
Packit b099d7
  HierarchyConstraints *curr_child;
Packit b099d7
  Cardinal num=0, i;
Packit b099d7
  
Packit b099d7
  if (XmHierarchyC_widget(curr_node) != NULL)
Packit b099d7
    SetChildValues( curr_node, open_folder, close_folder );
Packit b099d7
  
Packit b099d7
  if (XmHierarchyC_num_children(curr_node) == 0) return;
Packit b099d7
Packit b099d7
  curr_child = XmHierarchyC_children(curr_node);
Packit b099d7
  num = XmHierarchyC_num_children(curr_node);
Packit b099d7
Packit b099d7
  for (i = 0; i < num; i++, curr_child++) {
Packit b099d7
    RecursiveSetChildValues( *curr_child, open_folder, close_folder );
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/*	Function Name: SetValues
Packit b099d7
 *	Description:   Called when XtSetValues is called 
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:       Boolean
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
SetValues(Widget w, Widget request, Widget set, ArgList args, 
Packit b099d7
	  Cardinal *num_args)
Packit b099d7
{
Packit b099d7
  XmHierarchyWidget setw = (XmHierarchyWidget)set;
Packit b099d7
Packit b099d7
  if (!LoadFolderImages( w, set )) return(False);
Packit b099d7
  
Packit b099d7
  RecursiveSetChildValues(XmHierarchy_top_node(setw), 
Packit b099d7
			  XmHierarchy_open_folder(setw), 
Packit b099d7
			  XmHierarchy_close_folder(setw));
Packit b099d7
  return(True);
Packit b099d7
}
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
    XmHierarchyWidgetClass hc;
Packit b099d7
    XmHierarchyWidget hw = (XmHierarchyWidget) XtParent(set);
Packit b099d7
    HierarchyConstraints new_node = GetNodeInfo(set);
Packit b099d7
    HierarchyConstraints old_node = GetNodeInfo(current);
Packit b099d7
    Boolean insert_change = 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
    hc = (XmHierarchyWidgetClass) XtClass(XtParent(set));
Packit b099d7
Packit b099d7
    if ((XmHierarchyC_parent(new_node) != XmHierarchyC_parent(old_node)) ||
Packit b099d7
	(insert_change))
Packit b099d7
    {
Packit b099d7
	Widget parent = XmHierarchyC_parent(new_node);
Packit b099d7
	
Packit b099d7
	if (XmHierarchyC_parent(new_node) == set) {
Packit b099d7
	    XmeWarning(set, XmNnodeParentIsSelfMsg);
Packit b099d7
	    
Packit b099d7
	    XmHierarchyC_parent(new_node) = XmHierarchyC_parent(old_node);
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
	    /*
Packit b099d7
	     * We can't just remove old_node because it is a copy of
Packit b099d7
	     * the widget and our compare to see if exists in the parent
Packit b099d7
	     * will fail.  So we store the new parent in a temp variable.
Packit b099d7
	     * reset parent to the old one, then remove it from the old parent,
Packit b099d7
	     * and finnally add it to the new parent.
Packit b099d7
	     */
Packit b099d7
	    
Packit b099d7
	    XmHierarchyC_parent(new_node) = XmHierarchyC_parent(old_node);
Packit b099d7
	    RemoveNodeFromParent(new_node);
Packit b099d7
	    XmHierarchyC_parent(new_node) = parent;
Packit b099d7
	    if (parent == NULL) {
Packit b099d7
		XmHierarchyWidget hw = (XmHierarchyWidget) XtParent(set);
Packit b099d7
		
Packit b099d7
		AddChild(XmHierarchy_top_node(hw), new_node);
Packit b099d7
	    }
Packit b099d7
	    else 
Packit b099d7
		AddChild(GetNodeInfo(XmHierarchyC_parent(new_node)), new_node);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(new_node) != XmHierarchyC_state(old_node)) {
Packit b099d7
	XtCallCallbackList((Widget) hw,
Packit b099d7
			   XmHierarchy_node_state_beg_end_callback(hw),
Packit b099d7
			   (XtPointer) True);
Packit b099d7
Packit b099d7
    {
Packit b099d7
        XmHierarchyNodeProc change_node_state;
Packit b099d7
Packit b099d7
        _XmProcessLock();
Packit b099d7
        change_node_state = hc->hierarchy_class.change_node_state;
Packit b099d7
        _XmProcessUnlock();
Packit b099d7
        
Packit b099d7
    	(*change_node_state)(new_node);
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
	XtCallCallbackList((Widget) hw,
Packit b099d7
			   XmHierarchy_node_state_beg_end_callback(hw),
Packit b099d7
			   (XtPointer) False);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if ((XmHierarchyC_open_folder(new_node) != XmHierarchyC_open_folder(old_node))
Packit b099d7
	|| (XmHierarchyC_close_folder(new_node) != XmHierarchyC_close_folder(old_node)) )
Packit b099d7
    		SetChildValues(new_node, XmHierarchy_open_folder(hw), XmHierarchy_close_folder(hw));
Packit b099d7
	
Packit b099d7
    return(False);   
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: Change node state
Packit b099d7
 *	Description:   Responds to changes in this node's state.
Packit b099d7
 *	Arguments:     node - the node that has changed.
Packit b099d7
 *	Returns:       none
Packit b099d7
 *
Packit b099d7
 * This function closes all ancestors
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
ChangeNodeState(HierarchyConstraints node)
Packit b099d7
{
Packit b099d7
    register int i, num;
Packit b099d7
    HierarchyConstraints * childp;
Packit b099d7
    XmHierarchyWidget hw = (XmHierarchyWidget)
Packit b099d7
	                   XtParent(XmHierarchyC_widget(node));
Packit b099d7
    XmHierarchyWidgetClass hc = (XmHierarchyWidgetClass) XtClass(hw);
Packit b099d7
    XmHierarchyNodeStateData node_data;
Packit b099d7
    
Packit b099d7
    XmHierarchyNodeProc change_node_state;
Packit b099d7
    XmHierarchyResetButtonProc reset_open_close_button;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    change_node_state = hc->hierarchy_class.change_node_state;
Packit b099d7
    reset_open_close_button = hc->hierarchy_class.reset_open_close_button;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    
Packit b099d7
Packit b099d7
    (*reset_open_close_button) (XtParent(XmHierarchyC_widget(node)), node);
Packit b099d7
Packit b099d7
    node_data.widget = XmHierarchyC_widget(node);
Packit b099d7
    node_data.state = XmHierarchyC_state(node);
Packit b099d7
    XtCallCallbackList((Widget) hw, XmHierarchy_node_state_changed_callback(hw),
Packit b099d7
		       &node_data);
Packit b099d7
Packit b099d7
    if (XmHierarchy_auto_close(hw)) {
Packit b099d7
	if ((XmHierarchyC_state(node) == XmClosed) ||
Packit b099d7
	    ((XmHierarchyC_state(node) == XmHidden) && AncestorClosed(node)))
Packit b099d7
	{
Packit b099d7
	    childp = XmHierarchyC_children(node);
Packit b099d7
	    num = XmHierarchyC_num_children(node);
Packit b099d7
	    for (i = 0; i < num; i++, childp++) {
Packit b099d7
		if (XmHierarchyC_state(*childp) == XmOpen) {
Packit b099d7
		    XmHierarchyC_state(*childp) = XmClosed;
Packit b099d7
		}
Packit b099d7
		(*change_node_state)(*childp);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: AncestorClosed
Packit b099d7
 *	Description: Returns true if the first non-hidden ancestor of 
Packit b099d7
 *                   this widget is closed.
Packit b099d7
 *	Arguments: node - node to check.
Packit b099d7
 *	Returns: A Boolean
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
AncestorClosed(HierarchyConstraints node)
Packit b099d7
{
Packit b099d7
    while ((XmHierarchyC_parent(node) != NULL) &&
Packit b099d7
	   (XmHierarchyC_state(node) == XmHidden)) 
Packit b099d7
    {
Packit b099d7
	node = GetNodeInfo(XmHierarchyC_parent(node));
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return(XmHierarchyC_state(node) == XmClosed);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: UnmapAllExtraNodes
Packit b099d7
 *	Description:   Correctly unmaps each node in the hierarchy that is 
Packit b099d7
 *                     currently compresed 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;
Packit b099d7
    XmHierarchyWidgetClass hc = (XmHierarchyWidgetClass) (XtClass(w));
Packit b099d7
    register int num;
Packit b099d7
    register HierarchyConstraints * ptr;
Packit b099d7
Packit b099d7
    void (*unmap_extra)(Widget, HierarchyConstraints);
Packit b099d7
    XmHierarchyNodeProc unmap_node;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    unmap_extra = hc->hierarchy_class.unmap_all_extra_nodes;
Packit b099d7
    unmap_node = hc->hierarchy_class.unmap_node;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    if (XmHierarchyC_status(node) & IS_COMPRESSED)
Packit b099d7
	(*unmap_node)(node);
Packit b099d7
	
Packit b099d7
    ptr = XmHierarchyC_children(node);
Packit b099d7
    for (num = XmHierarchyC_num_children(node), i = 0; i < num; i++, ptr++) 
Packit b099d7
	(*unmap_extra)(w, *ptr);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: MapNode
Packit b099d7
 *	Description:   Maps all children of a given node.
Packit b099d7
 *	Arguments:     node - node to map.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
MapNode(HierarchyConstraints node)
Packit b099d7
{
Packit b099d7
    if (XmHierarchyC_status(node) & IS_MAPPED)
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_widget(node) != NULL) {
Packit b099d7
	XmHierarchyC_status(node) |= IS_MAPPED;
Packit b099d7
	XtSetMappedWhenManaged(XmHierarchyC_widget(node), True);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchyC_open_close_button(node) != NULL)
Packit b099d7
	XtSetMappedWhenManaged(XmHierarchyC_open_close_button(node), True);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: UnmapNode
Packit b099d7
 *	Description:   Unmaps all children of a given node.
Packit b099d7
 *	Arguments:     node - node to unmap.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
UnmapNode(HierarchyConstraints node)
Packit b099d7
{
Packit b099d7
    if (!(XmHierarchyC_status(node) & IS_MAPPED))
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_widget(node) != NULL) {
Packit b099d7
	XmHierarchyC_status(node) &= ~(IS_MAPPED); /* Unset the IS_MAPPED bit. */
Packit b099d7
	XtSetMappedWhenManaged(XmHierarchyC_widget(node), False);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchyC_open_close_button(node) != NULL) 
Packit b099d7
	XtSetMappedWhenManaged(XmHierarchyC_open_close_button(node), False);
Packit b099d7
}
Packit b099d7
    
Packit b099d7
/*	Function Name: _BuildNodeTable
Packit b099d7
 *	Description:   Recursive part of code that builds the table of 
Packit b099d7
 *                     nodes to display.
Packit b099d7
 *	Arguments:     w - the hw widget.
Packit b099d7
 *                     node - node to add.
Packit b099d7
 *                     current_index - where to add this node.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
_BuildNodeTable(Widget w, HierarchyConstraints node, Cardinal * current_index)
Packit b099d7
{
Packit b099d7
    XmHierarchyWidget hw = (XmHierarchyWidget) w;
Packit b099d7
    register int i;
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
	XmHierarchyC_status(node) &= ~(IS_COMPRESSED); /* No longer compressed. */
Packit b099d7
	
Packit b099d7
	XmHierarchy_node_table(hw)[*current_index] = node;
Packit b099d7
	(*current_index)++;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) == XmClosed)
Packit b099d7
	return;
Packit b099d7
	
Packit b099d7
    for (i = 0; i < XmHierarchyC_num_children(node); i++) 
Packit b099d7
	_BuildNodeTable(w, XmHierarchyC_children(node)[i], current_index);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: BuildNodeTable
Packit b099d7
 *	Description:   builds the table of nodes to display.
Packit b099d7
 *	Arguments:     w - the hw widget.
Packit b099d7
 *                     node - node to add.
Packit b099d7
 *                     current_index - where to add this node.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
BuildNodeTable(Widget w, HierarchyConstraints node, Cardinal * current_index)
Packit b099d7
{
Packit b099d7
    XmHierarchyWidget hw = (XmHierarchyWidget) w;
Packit b099d7
Packit b099d7
    if ((XmHierarchy_node_table(hw) == NULL) || 
Packit b099d7
	(XmHierarchy_alloc_nodes(hw) < hw->composite.num_children))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * This will allocate more space than we need, but shouldn't be too
Packit b099d7
	 * terrible.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	XmHierarchy_node_table(hw) = (HierarchyConstraints *)
Packit b099d7
	    XtRealloc((XtPointer) XmHierarchy_node_table(hw),
Packit b099d7
		    sizeof(HierarchyConstraints) * hw->composite.num_children);
Packit b099d7
Packit b099d7
	XmHierarchy_alloc_nodes(hw) = hw->composite.num_children;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    _BuildNodeTable(w, node, current_index);
Packit b099d7
}
Packit b099d7
 
Packit b099d7
/*	Function Name: ResetOpenCloseButton
Packit b099d7
 *	Description:   Creates or Destroys the Open/Close button
Packit b099d7
 *                     as appropriate.
Packit b099d7
 *	Arguments:     node - the node to check.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ResetOpenCloseButton(Widget w, HierarchyConstraints node)
Packit b099d7
{
Packit b099d7
    Arg args[5];
Packit b099d7
    Pixmap image;
Packit b099d7
    Cardinal num_args;
Packit b099d7
    XmHierarchyWidget hw = (XmHierarchyWidget) w;
Packit b099d7
    XmHierarchyWidgetClass hc = (XmHierarchyWidgetClass) XtClass(w);
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) == XmAlwaysOpen) {
Packit b099d7
	if (XmHierarchyC_open_close_button(node) != NULL) {
Packit b099d7
	    XtDestroyWidget(XmHierarchyC_open_close_button(node));
Packit b099d7
	    XmHierarchyC_open_close_button(node) = NULL;
Packit b099d7
	}
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    switch(XmHierarchyC_state(node)) {
Packit b099d7
    case XmOpen:
Packit b099d7
    case XmHidden:
Packit b099d7
    default:
Packit b099d7
	if ( (XmUNSPECIFIED_PIXMAP != XmHierarchyC_open_folder(node)) && XmHierarchyC_open_folder(node))
Packit b099d7
		image = XmHierarchyC_open_folder(node);
Packit b099d7
	else
Packit b099d7
		image = XmHierarchy_open_folder(hw);
Packit b099d7
	break;
Packit b099d7
    case XmClosed:
Packit b099d7
	if ( (XmUNSPECIFIED_PIXMAP != XmHierarchyC_close_folder(node)) && XmHierarchyC_close_folder(node))
Packit b099d7
		image = XmHierarchyC_close_folder(node);
Packit b099d7
	else
Packit b099d7
		image = XmHierarchy_close_folder(hw);
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    num_args = 0;
Packit b099d7
    XtSetArg(args[num_args], XmNpixmap, image); num_args++;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_open_close_button(node) == NULL) {
Packit b099d7
	XtSetArg(args[num_args], XmNmappedWhenManaged, False); num_args++;
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * Special node state for items that should not be
Packit b099d7
	 * considered part of the hierarchy, but are children of this
Packit b099d7
	 * widget.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
        XtSetArg(args[num_args], XmNnodeState, XmNotInHierarchy); num_args++;
Packit b099d7
	XtSetArg(args[num_args], XmNiconPlacement, XmIconOnly); num_args++;
Packit b099d7
Packit b099d7
	XmHierarchyC_open_close_button(node) = 
Packit b099d7
	    XtCreateManagedWidget("openAndClose", xmIconButtonWidgetClass,
Packit b099d7
				  w, args, num_args);
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * Make sure the mapped state of open/close button matches the
Packit b099d7
	 * node button that it corrosponds to.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	XtSetMappedWhenManaged(XmHierarchyC_open_close_button(node),
Packit b099d7
		((XmHierarchyC_status(node) & IS_MAPPED) ? True: False));
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
	XtAddCallback(XmHierarchyC_open_close_button(node),
Packit b099d7
		      XmNactivateCallback,
Packit b099d7
		      hc->hierarchy_class.toggle_node_state, (XtPointer) node);
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    }
Packit b099d7
    else {
Packit b099d7
	XtSetValues(XmHierarchyC_open_close_button(node), args, num_args);
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
static void
Packit b099d7
ToggleNodeState ( Widget w,
Packit b099d7
				  XtPointer node_ptr,
Packit b099d7
				  XtPointer call_data )
Packit b099d7
{
Packit b099d7
	Arg args[1];
Packit b099d7
	XmHierarchyWidget hw = ( XmHierarchyWidget ) XtParent ( w );
Packit b099d7
	HierarchyConstraints node = ( HierarchyConstraints ) node_ptr;
Packit b099d7
Packit b099d7
	XmHierarchyWidgetClass hc = (XmHierarchyWidgetClass) XtClass ((Widget) hw );
Packit b099d7
	XmHierarchyNodeStateData node_data;
Packit b099d7
Packit b099d7
    XmHierarchyNodeProc change_node_state;
Packit b099d7
Packit b099d7
    _XmProcessLock();    
Packit b099d7
    change_node_state = hc->hierarchy_class.change_node_state;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
	/*
Packit b099d7
	 * Unset the icon button.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	XtSetArg ( args[0], XmNset, False );
Packit b099d7
	XtSetValues ( w, args, ( Cardinal ) 1 );
Packit b099d7
Packit b099d7
	if (XmHierarchyC_state(node) == XmOpen )
Packit b099d7
	{
Packit b099d7
		XtCallCallbackList( (Widget) hw,
Packit b099d7
		    XmHierarchy_node_state_beg_end_callback ( hw ),
Packit b099d7
			(XtPointer) True );
Packit b099d7
Packit b099d7
		XmHierarchyC_state ( node ) = XmClosed;
Packit b099d7
Packit b099d7
		(*change_node_state) ( (HierarchyConstraints) node );
Packit b099d7
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
    if ( XmHierarchyC_state ( node ) == XmClosed )
Packit b099d7
	{
Packit b099d7
		XtCallCallbackList ( ( Widget ) hw,
Packit b099d7
			XmHierarchy_node_state_beg_end_callback ( hw ),
Packit b099d7
			( XtPointer ) True );
Packit b099d7
Packit b099d7
		XmHierarchyC_state ( node ) = XmOpen;
Packit b099d7
Packit b099d7
		(*change_node_state) ( (HierarchyConstraints) node );
Packit b099d7
        
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
		return;
Packit b099d7
Packit b099d7
	node_data.widget = XmHierarchyC_widget ( node );
Packit b099d7
	node_data.state = XmHierarchyC_state ( node );
Packit b099d7
Packit b099d7
	XtCallCallbackList ( ( Widget ) hw,
Packit b099d7
        XmHierarchy_node_state_callback ( hw ),
Packit b099d7
		&node_data );
Packit b099d7
Packit b099d7
	XtCallCallbackList ( ( Widget ) hw,
Packit b099d7
        XmHierarchy_node_state_beg_end_callback ( hw ),
Packit b099d7
		( XtPointer ) False );
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Type Converters.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: CvtStringToNodeState
Packit b099d7
 *	Description:   Converts a string to a NodeState.
Packit b099d7
 *	Arguments:     dpy - the X Display.
Packit b099d7
 *                     args, num_args - *** NOT USED ***
Packit b099d7
 *                     fromVal - contains the string to convert.
Packit b099d7
 *                     toVal - contains the converted node state.
Packit b099d7
 *                     junk - *** UNUSED ***.
Packit b099d7
 *	Returns:       
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean
Packit b099d7
CvtStringToNodeState(Display * dpy, XrmValuePtr args, Cardinal *num_args, 
Packit b099d7
		     XrmValuePtr fromVal, XrmValuePtr toVal, XtPointer *junk)
Packit b099d7
{
Packit b099d7
    static XmHierarchyNodeState type;
Packit b099d7
    static XrmQuark XtQEAlwaysOpen, XtQEOpen, XtQEClosed, XtQEHidden;
Packit b099d7
    static XrmQuark XtQENotInHierarchy;
Packit b099d7
    static Boolean haveQuarks = FALSE;
Packit b099d7
    XrmQuark q;
Packit b099d7
    char lowerName[BUFSIZ];
Packit b099d7
    
Packit b099d7
    if (!haveQuarks) {
Packit b099d7
	XtQEAlwaysOpen = XrmStringToQuark("alwaysopen");
Packit b099d7
	XtQEOpen = XrmStringToQuark("open");
Packit b099d7
	XtQEClosed = XrmStringToQuark("closed");
Packit b099d7
	XtQEHidden = XrmStringToQuark("hidden");
Packit b099d7
	XtQENotInHierarchy = XrmStringToQuark("notinhierarchy");
Packit b099d7
	haveQuarks = TRUE;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    XmCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr);
Packit b099d7
    q = XrmStringToQuark(lowerName);
Packit b099d7
    
Packit b099d7
    if (q == XtQEAlwaysOpen) 
Packit b099d7
	type = XmAlwaysOpen;
Packit b099d7
    else if (q == XtQEOpen) 
Packit b099d7
	type = XmOpen;
Packit b099d7
    else if (q == XtQEClosed) 
Packit b099d7
	type = XmClosed;
Packit b099d7
    else if (q == XtQEHidden) 
Packit b099d7
	type = XmHidden;
Packit b099d7
    else if (q == XtQENotInHierarchy) 	/* note! shouldn't ever be needed */
Packit b099d7
	type = XmNotInHierarchy;
Packit b099d7
    else {
Packit b099d7
	XtDisplayStringConversionWarning(dpy, fromVal->addr,
Packit b099d7
					 XmRXmHierarchyNodeState);
Packit b099d7
	return(False);		/* Conversion failed. */
Packit b099d7
    }
Packit b099d7
Packit b099d7
    toVal->size = sizeof(XmHierarchyNodeState);
Packit b099d7
    
Packit b099d7
    if (toVal->addr == NULL) {
Packit b099d7
	toVal->addr = (XtPointer) &type;
Packit b099d7
	return(TRUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (toVal->size >= sizeof(XmHierarchyNodeState)) {
Packit b099d7
	*((XmHierarchyNodeState *) toVal->addr) = type;
Packit b099d7
	return(TRUE);
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: LoadFolderImages
Packit b099d7
 *	Description: Loads the folder images.
Packit b099d7
 *	Arguments: w - the hierarchy widget.
Packit b099d7
 *	Returns: none.
Packit b099d7
 *     
Packit b099d7
 *      If the new image resource value is XmUNSPECIFIED_PIXMAP,
Packit b099d7
 *      the image is given the default value. If the image has
Packit b099d7
 *      changed return True, otherwise return False
Packit b099d7
 *
Packit b099d7
 * It would be nice if these values were cached per screen or display.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
LoadFolderImages(Widget old, Widget set)
Packit b099d7
{
Packit b099d7
  XmHierarchyWidget setw = (XmHierarchyWidget) set;
Packit b099d7
  XmHierarchyWidget oldw = (XmHierarchyWidget) old;
Packit b099d7
Packit b099d7
  if (XmHierarchy_open_folder(setw) == XmUNSPECIFIED_PIXMAP){
Packit b099d7
    XmHierarchy_open_folder(setw) = XmHierarchy_def_open_folder(setw);
Packit b099d7
  }
Packit b099d7
  if (XmHierarchy_close_folder(setw) == XmUNSPECIFIED_PIXMAP){
Packit b099d7
    XmHierarchy_close_folder(setw) = XmHierarchy_def_close_folder(setw);
Packit b099d7
  }
Packit b099d7
Packit b099d7
  if (XmHierarchy_open_folder(oldw) != XmHierarchy_open_folder(setw))
Packit b099d7
    return(True);
Packit b099d7
  if (XmHierarchy_close_folder(oldw) != XmHierarchy_close_folder(setw))
Packit b099d7
    return(True);
Packit b099d7
Packit b099d7
  return(False);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: DestroyFolderImages
Packit b099d7
 *	Description: Destroys the internal default folder images.
Packit b099d7
 *	Arguments: w - the hierarchy widget.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
DestroyFolderImages(Widget w)
Packit b099d7
{
Packit b099d7
  XmHierarchyWidget hw = (XmHierarchyWidget) w;
Packit b099d7
Packit b099d7
  XFreePixmap(XtDisplay(w), XmHierarchy_def_open_folder(hw));
Packit b099d7
  XFreePixmap(XtDisplay(w), XmHierarchy_def_close_folder(hw));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: RemoveChildren
Packit b099d7
 *	Description:   removes a list of children from this node.
Packit b099d7
 *	Arguments:     list - list of children to remove.
Packit b099d7
 *                     num - number of children in the list.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
RemoveChildren(HierarchyConstraints * list, Cardinal num)
Packit b099d7
{
Packit b099d7
    register int i;
Packit b099d7
Packit b099d7
    for (i = 0 ; i < num ; i++, list++ ) {
Packit b099d7
	/*
Packit b099d7
	 * Our parent is already gone.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	XmHierarchyC_status(*list) |= PARENT_GONE;
Packit b099d7
	XtDestroyWidget(XmHierarchyC_widget(*list));
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: AddChild
Packit b099d7
 *	Description:   Adds the child specified to the parent.
Packit b099d7
 *	Arguments:     parent - parent to add this child to.
Packit b099d7
 *                     child  - child to add to this parent.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
AddChild(HierarchyConstraints parent, HierarchyConstraints child)
Packit b099d7
{
Packit b099d7
    if (parent == NULL)
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    AddChildToList(&(XmHierarchyC_children(parent)), 
Packit b099d7
		   &(XmHierarchyC_num_children(parent)), 
Packit b099d7
		   &(XmHierarchyC_alloc(parent)), child);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: AddChildToList
Packit b099d7
 *	Description: Adds a child the the specified list.
Packit b099d7
 *	Arguments: 
Packit b099d7
 * IN/OUT         list - pointer to the list of children to add child to.
Packit b099d7
 * IN/OUT         num - pointer to the number of children.
Packit b099d7
 * IN/OUT         alloc - the amount of space allocated for children.
Packit b099d7
 *                child - child to insert.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
AddChildToList(HierarchyConstraints ** list, Cardinal * num, Cardinal * alloc,
Packit b099d7
	       HierarchyConstraints child)
Packit b099d7
{
Packit b099d7
    register int i, j;
Packit b099d7
    HierarchyConstraints *l_child;
Packit b099d7
    SuccessType success = DONT_CARE;
Packit b099d7
    Widget insert_before = XmHierarchyC_insert_before(child);
Packit b099d7
    
Packit b099d7
    if (*alloc <= *num) {
Packit b099d7
	Cardinal size;
Packit b099d7
	
Packit b099d7
	(*alloc) += ALLOC_INC;
Packit b099d7
	size = sizeof(HierarchyConstraints) * (*alloc);
Packit b099d7
	*list = (HierarchyConstraints *) XtRealloc((XtPointer)*list, size);
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (insert_before != NULL) {
Packit b099d7
	success = NO;
Packit b099d7
	
Packit b099d7
	/*
Packit b099d7
	 * Hunt for the sibling that matches the insert_before widget.
Packit b099d7
	 */
Packit b099d7
	
Packit b099d7
	for (l_child = (*list) + (i = (*num - 1)); i >= 0; i--, l_child--)
Packit b099d7
	    if (XmHierarchyC_widget(*l_child) == insert_before) {
Packit b099d7
		/*
Packit b099d7
		 * Bump each child down and then insert the new child.
Packit b099d7
		 */
Packit b099d7
		for (j = (*num - 1); j >= i; j--) 
Packit b099d7
		    (*list)[j + 1] = (*list)[j];
Packit b099d7
		(*list)[i] = child;
Packit b099d7
Packit b099d7
		success = YES;
Packit b099d7
		break;
Packit b099d7
	    }
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (success == NO) {
Packit b099d7
	String params[1];
Packit b099d7
	Cardinal num = 1;
Packit b099d7
Packit b099d7
	params[0] = XtName(XmHierarchyC_widget(child));
Packit b099d7
	_XmWarningMsg(XmHierarchyC_widget(child), XmNinsertBeforeNotSibling,
Packit b099d7
		XmNinsertBeforeNotSiblingMsg, params, num);
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (success != YES)		/* Stick it on the end of the list. */
Packit b099d7
	(*list)[*num] = child;
Packit b099d7
    
Packit b099d7
    (*num)++; /* It always goes somewhere. */
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 HierarchyConstraints
Packit b099d7
GetNodeInfo(Widget w)
Packit b099d7
{
Packit b099d7
    return((HierarchyConstraints) ((HierarchyConstraints)w->core.constraints));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: RemoveNodeFromParent
Packit b099d7
 *	Description:   Removes the node from its parents children list.
Packit b099d7
 *	Arguments:     node  - the node to remove.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
RemoveNodeFromParent(HierarchyConstraints node)
Packit b099d7
{
Packit b099d7
    register int i;
Packit b099d7
    HierarchyConstraints pnode;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_status(node) & PARENT_GONE)
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_parent(node) == NULL) {
Packit b099d7
	XmHierarchyWidget hw;
Packit b099d7
	
Packit b099d7
	hw = (XmHierarchyWidget) XtParent(XmHierarchyC_widget(node));
Packit b099d7
	pnode = XmHierarchy_top_node(hw);
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
	pnode = GetNodeInfo(XmHierarchyC_parent(node));
Packit b099d7
Packit b099d7
    for (i = 0; i < XmHierarchyC_num_children(pnode); i++) {
Packit b099d7
	if (XmHierarchyC_children(pnode)[i] == node) {
Packit b099d7
	    BumpChildren(XmHierarchyC_children(pnode), i,
Packit b099d7
			 (int) XmHierarchyC_num_children(pnode));
Packit b099d7
	    XmHierarchyC_num_children(pnode)--;
Packit b099d7
	    return;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: BumpChildren
Packit b099d7
 *	Description:   Bumps the children after this node up one.
Packit b099d7
 *	Arguments:     nlist - the node list
Packit b099d7
 *                     i - where to begin bumping.
Packit b099d7
 *                     num - number of children in list.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
BumpChildren(HierarchyConstraints * nlist, int i, int num)
Packit b099d7
{
Packit b099d7
    for (i++ ; i < num ; i++ )
Packit b099d7
	nlist[i - 1] = nlist[i];
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Public Functions
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: XmHierarchyOpenAllAncestors
Packit b099d7
 *	Description: This function opens all ancestors of the given node.
Packit b099d7
 *	Arguments: nw - the node (widget) that will be changed.
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
Packit b099d7
void
Packit b099d7
XmHierarchyOpenAllAncestors(Widget nw)
Packit b099d7
{
Packit b099d7
    Widget parent;
Packit b099d7
    HierarchyConstraints node;
Packit b099d7
    static Arg args[] = {
Packit b099d7
	{ XmNnodeState, (XtArgVal) XmOpen }
Packit b099d7
    };
Packit b099d7
Packit b099d7
    _XmWidgetToAppContext(nw);
Packit b099d7
    _XmAppLock(app);
Packit b099d7
Packit b099d7
    if (!XtParent(nw) || !XtIsSubclass(XtParent(nw), xmHierarchyWidgetClass))
Packit b099d7
      {
Packit b099d7
	_XmAppUnlock(app);
Packit b099d7
	return;
Packit b099d7
      }
Packit b099d7
Packit b099d7
    node = GetNodeInfo(nw);
Packit b099d7
Packit b099d7
    while ((parent = XmHierarchyC_parent(node)) != NULL) {
Packit b099d7
	node = GetNodeInfo(parent);
Packit b099d7
Packit b099d7
	if (XmHierarchyC_state(node) == XmClosed) 
Packit b099d7
	    XtSetValues(XmHierarchyC_widget(node), args, XtNumber(args));
Packit b099d7
    }
Packit b099d7
Packit b099d7
    _XmAppUnlock(app);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: XmHierarchyGetChildNodes
Packit b099d7
 *	Description: This function returns the node children of a node
Packit b099d7
 *	Arguments: nw - the node (widget) that will be examined
Packit b099d7
 *	Returns: a list of Widgets (must be XtFree'd) or NULL
Packit b099d7
 */
Packit b099d7
WidgetList XmHierarchyGetChildNodes(Widget nw)
Packit b099d7
{
Packit b099d7
    HierarchyConstraints node;
Packit b099d7
    WidgetList retval = (WidgetList)NULL;
Packit b099d7
    int i;
Packit b099d7
Packit b099d7
    _XmWidgetToAppContext(nw);
Packit b099d7
    _XmAppLock(app);
Packit b099d7
Packit b099d7
    if (!XtParent(nw) || !XtIsSubclass(XtParent(nw), xmHierarchyWidgetClass))
Packit b099d7
      {
Packit b099d7
	_XmAppUnlock(app);
Packit b099d7
	return retval;
Packit b099d7
      }
Packit b099d7
Packit b099d7
    node = GetNodeInfo(nw);
Packit b099d7
Packit b099d7
    if (0 == XmHierarchyC_num_children(node))
Packit b099d7
      {
Packit b099d7
	_XmAppUnlock(app);
Packit b099d7
	return retval;
Packit b099d7
      }
Packit b099d7
Packit b099d7
    retval = (WidgetList)XtMalloc((XmHierarchyC_num_children(node) + 1) * sizeof(Widget));
Packit b099d7
Packit b099d7
    for (i=0; i < XmHierarchyC_num_children(node); i++)
Packit b099d7
	retval[i] = XmHierarchyC_widget(XmHierarchyC_children(node)[i]);
Packit b099d7
    retval[i] = (Widget)NULL;
Packit b099d7
Packit b099d7
    _XmAppUnlock(app);
Packit b099d7
    return retval;
Packit b099d7
}
Packit b099d7