/* 
 * Motif
 *
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
 *
 * These libraries and programs are free software; you can
 * redistribute them and/or modify them under the terms of the GNU
 * Lesser General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * These libraries and programs are distributed in the hope that
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with these librararies and programs; if not, write
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301 USA
*/ 
/* 
 * HISTORY
*/ 
#ifdef REV_INFO
#ifndef lint
static char rcsid[] = "$TOG: BulletinB.c /main/22 1999/10/13 16:15:40 mgreess $"
#endif
#endif
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif


#include "BulletinBI.h"
#include <Xm/AtomMgr.h>
#include <Xm/BaseClassP.h>
#include <Xm/DialogS.h>
#include <Xm/DrawP.h>
#include <Xm/LabelG.h>
#include <Xm/MwmUtil.h>
#include <Xm/PushBGP.h>
#include <Xm/PushBP.h>
#include <Xm/Text.h>
#include <Xm/TextF.h>
#include <Xm/TransltnsP.h>
#include <Xm/VendorS.h>
#include <Xm/VendorSEP.h>
#include <Xm/TraitP.h>
#include <Xm/DialogSavvyT.h>
#include <Xm/SpecRenderT.h>
#include <Xm/TakesDefT.h>
#include <Xm/VaSimpleP.h>
#include "XmI.h"
#include "BaseClassI.h"
#include "CallbackI.h"
#include "GeoUtilsI.h"
#include "GMUtilsI.h"
#include "MessagesI.h"
#include "RepTypeI.h"
#include "TraversalI.h"

/****************************************************************/
/* Local defines:
*/

#define STRING_CHARSET          "ISO8859-1"
#define	MARGIN_DEFAULT		10

#define DONT_CARE               -1L
#define COMMON_FUNCS     (MWM_FUNC_CLOSE | MWM_FUNC_MOVE | MWM_FUNC_RESIZE)
#define DIALOG_FUNCS     COMMON_FUNCS
#define CLIENT_FUNCS     (COMMON_FUNCS | MWM_FUNC_MAXIMIZE | MWM_FUNC_MINIMIZE)

#define WARN_DIALOG_STYLE	_XmMMsgBulletinB_0001


/********    Static Function Declarations    ********/

static void ClassPartInitialize( 
                        WidgetClass w_class) ;
static void Initialize( 
                        Widget wid_req,
                        Widget wid_new,
                        ArgList args,
                        Cardinal *numArgs) ;
static void Destroy( 
                        Widget wid) ;
static Boolean SetValues( 
                        Widget cw,
                        Widget rw,
                        Widget nw,
                        ArgList args,
                        Cardinal *num_args) ;
static Boolean SetValuesHook( 
                        Widget wid,
                        ArgList args,
                        Cardinal *num_args) ;
static void HandleChangeManaged( 
                        XmBulletinBoardWidget bbWid,
                        XmGeoCreateProc geoMatrixCreate) ;
static void HandleResize( 
                        XmBulletinBoardWidget bbWid,
                        XmGeoCreateProc geoMatrixCreate) ;
static XtGeometryResult HandleGeometryManager( 
                        Widget instigator,
                        XtWidgetGeometry *desired,
                        XtWidgetGeometry *allowed,
                        XmGeoCreateProc geoMatrixCreate) ;
static void ChangeManaged( 
                        Widget wid) ;
static void UnmanageCallback( 
                        Widget w,
                        XtPointer client_data,
                        XtPointer call_data) ;
static void InsertChild( 
                        Widget child) ;
static void DeleteChild( 
                        Widget child) ;
static XtGeometryResult GeometryManager( 
                        Widget w,
                        XtWidgetGeometry *request,
                        XtWidgetGeometry *reply) ;
static XtGeometryResult QueryGeometry( 
                        Widget wid,
                        XtWidgetGeometry *intended,
                        XtWidgetGeometry *desired) ;
static void Resize( 
                        Widget wid) ;
static void Redisplay( 
                        Widget wid,
                        XEvent *event,
                        Region region) ;
static Boolean BulletinBoardParentProcess( 
                        Widget wid,
                        XmParentProcessData event) ;
static void GetDialogTitle( 
                        Widget bb,
                        int resource,
                        XtArgVal *value) ;
static Widget GetBBWithDB( 
                        Widget wid) ;
static XmFontList GetTable(Widget wid,
			   XtEnum type);
static void CallMapUnmap(Widget wid,
			 Boolean map_unmap) ;
static void BulletinBoardSetDefaultShadow( 
                        Widget button) ;
static void BBUpdateDynDefaultButton( 
                         Widget bb) ;
static void CheckSetRenderTables(Widget wid,
				int offset,
				XrmValue *value); 

/********    End Static Function Declarations    ********/


/*  default translation table and action list  */

#define defaultTranslations	_XmBulletinB_defaultTranslations

static XtActionsRec actionsList[] =
{
	{ "Return",	_XmBulletinBoardReturn },       /*Motif 1.0 BC. */
	{ "BulletinBoardReturn", _XmBulletinBoardReturn },
        { "BulletinBoardCancel", _XmBulletinBoardCancel },
	{ "BulletinBoardMap",    _XmBulletinBoardMap },
};



/*  Resource definitions for BulletinBoard
 */

static XmSyntheticResource syn_resources[] =
{
	{	XmNdialogTitle,
		sizeof (XmString),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.dialog_title),
		GetDialogTitle,
		NULL
	},
	{	XmNmarginWidth,
		sizeof (Dimension),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.margin_width),
		XmeFromHorizontalPixels,
		XmeToHorizontalPixels
	},

	{	XmNmarginHeight,
		sizeof (Dimension),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.margin_height),
		XmeFromVerticalPixels,
		XmeToVerticalPixels
	},
};



static XtResource resources[] =
{
	{	XmNshadowType,
		XmCShadowType, XmRShadowType, sizeof (unsigned char),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.shadow_type),
		XmRImmediate, (XtPointer) XmSHADOW_OUT
	},

	{
		XmNshadowThickness,
		XmCShadowThickness, XmRHorizontalDimension, sizeof (Dimension),
		XtOffsetOf( struct _XmBulletinBoardRec, manager.shadow_thickness),
		XmRImmediate, (XtPointer) XmINVALID_DIMENSION
	},

	{	XmNmarginWidth,
		XmCMarginWidth, XmRHorizontalDimension, sizeof (Dimension),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.margin_width),
		XmRImmediate, (XtPointer) MARGIN_DEFAULT
	},

	{	XmNmarginHeight,
		XmCMarginHeight, XmRVerticalDimension, sizeof (Dimension),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.margin_height),
		XmRImmediate, (XtPointer) MARGIN_DEFAULT
	},

	{	XmNdefaultButton,
		XmCWidget, XmRWidget, sizeof (Widget), 
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.default_button),
		XmRImmediate, (XtPointer) NULL
	},

	{	XmNcancelButton,
		XmCWidget, XmRWidget, sizeof (Widget),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.cancel_button),
		XmRImmediate, (XtPointer) NULL
	},

	{	XmNfocusCallback,
		XmCCallback, XmRCallback, sizeof (XtCallbackList),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.focus_callback),
		XmRImmediate, (XtPointer) NULL
	},
	{	XmNmapCallback,
		XmCCallback, XmRCallback, sizeof (XtCallbackList),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.map_callback),
		XmRImmediate, (XtPointer) NULL
	},

	{	XmNunmapCallback,
		XmCCallback, XmRCallback, sizeof (XtCallbackList),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.unmap_callback),
		XmRImmediate, (XtPointer) NULL
	},
	{	"pri.vate", "Pri.vate", 
	 	XmRUnsignedChar, sizeof (unsigned char), 
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.check_set),
		XmRImmediate, 0
	},
	{	XmNbuttonFontList,
		XmCButtonFontList, XmRButtonFontList, sizeof (XmFontList),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.button_font_list),
		XmRCallProc, (XtPointer) CheckSetRenderTables
	},

	{	XmNlabelFontList,
		XmCLabelFontList, XmRLabelFontList, sizeof (XmFontList),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.label_font_list),
		XmRCallProc, (XtPointer) CheckSetRenderTables
	},

	{	XmNtextFontList,
		XmCTextFontList, XmRTextFontList, sizeof (XmFontList),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.text_font_list),
		XmRCallProc, (XtPointer) CheckSetRenderTables
	},

	{	XmNbuttonRenderTable,
		XmCButtonRenderTable, XmRButtonRenderTable, sizeof (XmRenderTable),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.button_font_list),
		XmRCallProc, (XtPointer)CheckSetRenderTables
	},

	{	XmNlabelRenderTable,
		XmCLabelRenderTable, XmRLabelRenderTable, sizeof (XmRenderTable),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.label_font_list),
		XmRCallProc, (XtPointer)CheckSetRenderTables
	},

	{	XmNtextRenderTable,
		XmCTextRenderTable, XmRTextRenderTable, sizeof (XmRenderTable),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.text_font_list),
		XmRCallProc, (XtPointer)CheckSetRenderTables
	},

	{	XmNtextTranslations,
		XmCTranslations, XmRTranslationTable, sizeof (XtTranslations),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.text_translations),
		XmRImmediate, (XtPointer) NULL
	},

	{	XmNallowOverlap,
		XmCAllowOverlap, XmRBoolean, sizeof (Boolean),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.allow_overlap),
		XmRImmediate, (XtPointer) True
	},

	{	XmNautoUnmanage,
		XmCAutoUnmanage, XmRBoolean, sizeof (Boolean),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.auto_unmanage),
		XmRImmediate, (XtPointer) True
	},

	{	XmNdefaultPosition,
		XmCDefaultPosition, XmRBoolean, sizeof (Boolean),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.default_position),
		XmRImmediate, (XtPointer) True
	},

	{	XmNresizePolicy,
		XmCResizePolicy, XmRResizePolicy, sizeof (unsigned char),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.resize_policy),
		XmRImmediate, (XtPointer) XmRESIZE_ANY
	},

	{	XmNnoResize,
		XmCNoResize, XmRBoolean, sizeof (Boolean),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.no_resize),
		XmRImmediate, (XtPointer) False
	},

	{	XmNdialogStyle,
		XmCDialogStyle, XmRDialogStyle, sizeof (unsigned char),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.dialog_style),
		XmRImmediate, (XtPointer) XmDIALOG_MODELESS
	},

	{	XmNdialogTitle,
		XmCDialogTitle, XmRXmString, sizeof (XmString),
		XtOffsetOf( struct _XmBulletinBoardRec, bulletin_board.dialog_title),
		XmRImmediate, (XtPointer) NULL
	},
                  
};



/****************************************************************
 *
 *	BulletinBoard class record
 *
 ****************************************************************/

externaldef( xmbulletinboardclassrec) XmBulletinBoardClassRec
                                                      xmBulletinBoardClassRec =
{
   {			/* core_class fields      */
      (WidgetClass) &xmManagerClassRec,		/* superclass         */
      "XmBulletinBoard",			/* class_name         */
      sizeof(XmBulletinBoardRec),		/* widget_size        */
      NULL,					/* class_initialize   */
      ClassPartInitialize,			/* class_part_init    */
      FALSE,					/* class_inited       */
      Initialize,				/* initialize         */
      NULL,					/* initialize_hook    */
      XtInheritRealize,                    	/* realize            */
      actionsList,		                /* actions	      */
      XtNumber(actionsList),			/* num_actions	      */
      resources,	                	/* resources          */
      XtNumber(resources),			/* num_resources      */
      NULLQUARK,				/* xrm_class          */
      TRUE,					/* compress_motion    */
      XtExposeCompressMaximal,			/* compress_exposure  */
      TRUE,					/* compress_enterlv   */
      FALSE,					/* visible_interest   */
      Destroy,                                  /* destroy            */
      Resize,					/* resize             */
      Redisplay,        			/* expose             */
      SetValues,	                	/* set_values         */
      SetValuesHook,				/* set_values_hook    */
      XtInheritSetValuesAlmost, 		/* set_values_almost  */
      NULL,					/* get_values_hook    */
      NULL,					/* accept_focus       */
      XtVersion,				/* version            */
      NULL,					/* callback_private   */
      defaultTranslations,                      /* tm_table           */
      QueryGeometry,	                        /* query_geometry     */
      NULL,             	                /* display_accelerator*/
      NULL,		                        /* extension          */
   },

   {		/* composite_class fields */
      GeometryManager,    	                /* geometry_manager   */
      ChangeManaged,		                /* change_managed     */
      InsertChild,				/* insert_child       */
      DeleteChild,				/* delete_child       */
      NULL,                                     /* extension          */
   },

   {		/* constraint_class fields */
      NULL,					/* resource list        */   
      0,					/* num resources        */   
      sizeof(XmManagerConstraintRec),		/* constraint size      */
      NULL,					/* init proc            */   
      NULL,             			/* destroy proc         */   
      NULL,					/* set values proc      */   
      NULL,                                     /* extension            */
   },

   {		/* manager_class fields */
      XtInheritTranslations,			/* default translations   */
      syn_resources,				/* syn_resources      	  */
      XtNumber (syn_resources),			/* num_syn_resources 	  */
      NULL,					/* syn_cont_resources     */
      0,					/* num_syn_cont_resources */
      BulletinBoardParentProcess,               /* parent_process         */
      NULL,					/* extension		  */
   },

   {		/* bulletinBoard class fields */     
      FALSE,                                    /*always_install_accelerators*/
      NULL,                                     /* geo_matrix_create */
      _XmBulletinBoardFocusMoved,               /* focus_moved_proc */
      NULL					/* extension */
   }
};

externaldef( xmbulletinboardwidgetclass) WidgetClass xmBulletinBoardWidgetClass
                                     = (WidgetClass) &xmBulletinBoardClassRec ;


/* Trait record for BulletinB specify render table */

static XmConst XmSpecRenderTraitRec bulletinbSRT = {
  0,		/* version */
  GetTable,
};


/* Trait record for BulletinB dialog shell savvy */

static XmConst XmDialogSavvyTraitRec bulletinbDST = {
  0,		/* version */
  CallMapUnmap,
};


/*
 * Copy the XmString in XmNdialogTitle before returning it to the user.
 */
/*ARGSUSED*/
static void
GetDialogTitle(
        Widget bb,
        int resource,		/* unused */
        XtArgVal *value)
{
    XmString      data ;
/****************/

    data = XmStringCopy((XmString) ((XmBulletinBoardWidget) bb)
                                                ->bulletin_board.dialog_title);
    *value = (XtArgVal) data ;

    return ;
    }


/****************************************************************/
static void 
ClassPartInitialize(
        WidgetClass w_class )
{
    XmBulletinBoardWidgetClass bbClass
	= (XmBulletinBoardWidgetClass) w_class ;
    XmBulletinBoardWidgetClass bbSuper
	= (XmBulletinBoardWidgetClass) w_class->core_class.superclass ;


    _XmFastSubclassInit (w_class, XmBULLETIN_BOARD_BIT);

    if (bbClass->bulletin_board_class.geo_matrix_create
       == XmInheritGeoMatrixCreate    )
	{   bbClass->bulletin_board_class.geo_matrix_create
		= bbSuper->bulletin_board_class.geo_matrix_create ;
        } 
    if (bbClass->bulletin_board_class.focus_moved_proc
	== XmInheritFocusMovedProc    )
	{   bbClass->bulletin_board_class.focus_moved_proc
		= bbSuper->bulletin_board_class.focus_moved_proc ;
        } 
    
    /* Install the specifyrendertable trait for all subclasses */
    XmeTraitSet((XtPointer)w_class, XmQTspecifyRenderTable, 
		(XtPointer) &bulletinbSRT);

    /* Install the dialogShellsavyy trait for all subclasses */
    XmeTraitSet((XtPointer)w_class, XmQTdialogShellSavvy, 
		(XtPointer) &bulletinbDST);

    return ;
}


/****************************************************************
 * Initialize a BulletinBoard instance.
 ****************/
/*ARGSUSED*/
static void 
Initialize(
        Widget wid_req,
        Widget wid_new,
        ArgList args,		/* unused */
        Cardinal *numArgs )	/* unused */
{   
            XmBulletinBoardWidget request = (XmBulletinBoardWidget) wid_req ;
            XmBulletinBoardWidget new_w = (XmBulletinBoardWidget) wid_new ;
            Arg             al[5] ;
    register Cardinal       ac ;
            int             mwm_functions ;
            char *          text_value ;
            XmFontList      defaultFL ;
            int             mwmStyle ;
            Widget          ancestor ;
            XmWidgetExtData extData ;
            XmBulletinBoardWidgetClass bbClass ;
            XmVendorShellExtObject vendorExt;
/****************/

    new_w->bulletin_board.in_set_values = False ;
    new_w->bulletin_board.geo_cache = (XmGeoMatrix) NULL ;
    new_w->bulletin_board.initial_focus = TRUE ;

    /*	Copy font list data.
    */
    defaultFL = BB_ButtonFontList( new_w) ;
    if(    !defaultFL    )
    {   defaultFL = XmeGetDefaultRenderTable( (Widget) new_w, XmBUTTON_FONTLIST) ;
        } 
    BB_ButtonFontList( new_w) = XmFontListCopy( defaultFL) ;

    defaultFL = BB_LabelFontList( new_w) ;
    if(    !defaultFL    )
    {   defaultFL = XmeGetDefaultRenderTable( (Widget) new_w, XmLABEL_FONTLIST) ;
        } 
    BB_LabelFontList( new_w) = XmFontListCopy( defaultFL) ;

    defaultFL = BB_TextFontList( new_w) ;
    if(    !defaultFL    )
    {   defaultFL = XmeGetDefaultRenderTable( (Widget) new_w, XmTEXT_FONTLIST) ;
        } 
    BB_TextFontList( new_w) = XmFontListCopy( defaultFL) ;

    if(    (request->manager.shadow_thickness == XmINVALID_DIMENSION)
       && XtIsShell( XtParent( request))    ){   
	new_w->manager.shadow_thickness = 1 ;
    }
    if(new_w->manager.shadow_thickness == XmINVALID_DIMENSION)   
	new_w->manager.shadow_thickness = 0 ;

    /* Default and Cancel buttons are Set/Get resources only.  The
    *   DefaultButton field is used as a marker for the state of buttons
    *   in the child list.  As such, it is essential that it is NULL at
    *   the end of Initialize.
    */
    BB_DefaultButton( new_w) = NULL ;
    BB_CancelButton( new_w) = NULL ;

    /* The DynamicButton fields are managed and will be set appropriately
    *   in the focus moved callback routine.
    */
    BB_DynamicDefaultButton( new_w) = NULL ;
    BB_DynamicCancelButton( new_w) = NULL ;

    new_w->bulletin_board.old_shadow_thickness = 0 ;

    if(    request->bulletin_board.dialog_title    )
    {   
        new_w->bulletin_board.dialog_title = XmStringCopy( 
                                        request->bulletin_board.dialog_title) ;
        XmeSetWMShellTitle(new_w->bulletin_board.dialog_title,
			   XtParent(new_w)) ;
        }
    /*	Set parent attributes.
    */
    ac = 0 ;
    text_value = NULL ;

    /*	Turn off window manager resize.
    */
    if(    request->bulletin_board.no_resize
        && XmIsVendorShell( XtParent( new_w))    )
    {   
        int old_mwm_functions ;

        XtSetArg( al[0], XmNmwmFunctions, &old_mwm_functions) ;
	XtGetValues( XtParent( new_w), al, 1) ;

	mwm_functions = (int)
	  (XmIsDialogShell(XtParent(new_w)) ? DIALOG_FUNCS : CLIENT_FUNCS);
	if(    old_mwm_functions != DONT_CARE    )
	  {
            mwm_functions |= old_mwm_functions ;
	  }
        mwm_functions &= ~MWM_FUNC_RESIZE ;
        XtSetArg( al[ac], XmNmwmFunctions, mwm_functions) ;  ac++ ;
        }
          
    /* If parent is DialogShell, set dialog attributes and realize.
    */
    if(    XmIsDialogShell (XtParent (request))    )
    {   
        new_w->bulletin_board.shell = XtParent( request) ;

        switch(    request->bulletin_board.dialog_style    )
        {   
            case XmDIALOG_PRIMARY_APPLICATION_MODAL:
            {   mwmStyle = MWM_INPUT_PRIMARY_APPLICATION_MODAL ;
                break ;
                } 
            case XmDIALOG_FULL_APPLICATION_MODAL:
            {   mwmStyle = MWM_INPUT_FULL_APPLICATION_MODAL ;
                break; 
                } 
            case XmDIALOG_SYSTEM_MODAL:
            {   mwmStyle = MWM_INPUT_SYSTEM_MODAL ;
                break ;
                } 
            case XmDIALOG_MODELESS:
            default:
            {   mwmStyle = MWM_INPUT_MODELESS ;
                break ;
                } 
            } 
        XtSetArg( al[ac], XmNmwmInputMode, mwmStyle) ;  ac++ ;
        XtSetValues( new_w->bulletin_board.shell, al, ac) ;
        XtRealizeWidget( new_w->bulletin_board.shell) ;
        } 
    else
    {   new_w->bulletin_board.shell = NULL ;
        if(    ac    )
        {   XtSetValues( XtParent (request), al, (Cardinal) ac) ;
            } 
        }
    XtFree( text_value) ;

    if(    !XmRepTypeValidValue( XmRID_SHADOW_TYPE,
                            new_w->bulletin_board.shadow_type, (Widget) new_w)    )
    {   new_w->bulletin_board.shadow_type = XmSHADOW_OUT ;
        }

    if(    !XmRepTypeValidValue( XmRID_RESIZE_POLICY,
                          new_w->bulletin_board.resize_policy, (Widget) new_w)    )
    {   new_w->bulletin_board.resize_policy = XmRESIZE_ANY ;
        }

    if(    new_w->bulletin_board.shell    )
    {   
        if(    !XmRepTypeValidValue( XmRID_DIALOG_STYLE,
                           new_w->bulletin_board.dialog_style, (Widget) new_w)    )
        {   new_w->bulletin_board.dialog_style = XmDIALOG_MODELESS ;
            } 
        } 
    else
    {   if(    new_w->bulletin_board.dialog_style != XmDIALOG_MODELESS    )
        {   
            XmeWarning( (Widget) new_w, WARN_DIALOG_STYLE) ;
            new_w->bulletin_board.dialog_style = XmDIALOG_MODELESS ;
            } 
        }
    /* Set source widget for accelerators used 
    *   by Manager in ConstraintInitialize.
    */
    if(    new_w->core.accelerators    )
    {   new_w->manager.accelerator_widget = (Widget) new_w ;
        } 

    bbClass = (XmBulletinBoardWidgetClass) new_w->core.widget_class ;

    if(    bbClass->bulletin_board_class.focus_moved_proc    )
    {   
        /* Walk up hierarchy to find vendor shell.  Then setup moved focus
        *   callback so default button can be maintained.
        */
        ancestor = XtParent( new_w) ;
        while(    ancestor  &&  !XmIsVendorShell( ancestor)    )
        {   ancestor = XtParent( ancestor) ;
            } 
        if(    ancestor
	   && (extData = _XmGetWidgetExtData( ancestor, XmSHELL_EXTENSION)) 
	   && (extData->widget)  )
        {   
             vendorExt = (XmVendorShellExtObject) extData->widget;

            _XmAddCallback((InternalCallbackList *) &(vendorExt->vendor.focus_moved_callback),
                            (XtCallbackProc) bbClass->bulletin_board_class.focus_moved_proc,
                            (XtPointer) new_w) ;
        } 
    } 
    new_w->bulletin_board.old_width = new_w->core.width;  /* may be 0 */
    new_w->bulletin_board.old_height = new_w->core.height;        /* may be 0 */

    return ;
}


/****************************************************************
 * Free fontlists, etc.
 ****************/
static void 
Destroy(
        Widget wid )
{   
    XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;
    Widget          ancestor ;
    XmWidgetExtData extData ;
    XmBulletinBoardWidgetClass bbClass ;
    XmVendorShellExtObject vendorExt;
    int num_children, i;
    Widget *childList;

 /*
  * Fix for 5209 - Check all ancestors to see if they are also bulletin
  *                boards.  If they are, check the values in the ancestor's
  *                default_button, cancel_button, and dynamic buttons to
  *                see if they match those of the bb being destroyed.  If
  *                they do, set those fields on the ancestor to NULL to
  *                avoid accessing freed memory in the future.
  */
    ancestor = XtParent( bb) ;
    while(    ancestor  &&  !XmIsVendorShell( ancestor)    )
       {   
           if (XmIsBulletinBoard(ancestor))
           {
             num_children = bb->composite.num_children;
             childList = bb->composite.children;
             for (i = 0; i < num_children; i++)
             {
               if (BB_CancelButton(ancestor) == childList[i])
                 BB_CancelButton(ancestor) = NULL; 
               if (BB_DynamicCancelButton(ancestor) == childList[i])
                 BB_DynamicCancelButton(ancestor) = NULL; 
               if (BB_DefaultButton(ancestor) == childList[i])
                 BB_DefaultButton(ancestor) = NULL; 
               if (BB_DynamicDefaultButton(ancestor) == childList[i])
                 BB_DynamicDefaultButton(ancestor) = NULL; 
             }
           }
           ancestor = XtParent( ancestor) ;
       }
  /* End 5209 */
  

    XmStringFree( bb->bulletin_board.dialog_title) ;

    /*  Free geometry cache.
    */
    if(    bb->bulletin_board.geo_cache    )
    {   _XmGeoMatrixFree( bb->bulletin_board.geo_cache) ;
        } 
    /*	Free fontlists.
    */
    if(    bb->bulletin_board.button_font_list    )
    {   XmFontListFree( bb->bulletin_board.button_font_list) ;
        } 
    if(    bb->bulletin_board.label_font_list    )
    {   XmFontListFree( bb->bulletin_board.label_font_list) ;
        } 
    if(    bb->bulletin_board.text_font_list    )
    {   XmFontListFree( bb->bulletin_board.text_font_list) ;
        } 

    bbClass = (XmBulletinBoardWidgetClass) bb->core.widget_class ;


    if(    bbClass->bulletin_board_class.focus_moved_proc    )
    {   
        /* Walk up hierarchy to find vendor shell.  Then remove focus moved
        *   callback.
        */
        ancestor = XtParent( bb) ;
        while(    ancestor  &&  !XmIsVendorShell( ancestor)    )
        {   ancestor = XtParent( ancestor) ;
            } 
        if(    ancestor
            && !ancestor->core.being_destroyed
            && (extData = _XmGetWidgetExtData( ancestor, XmSHELL_EXTENSION))  )
        {   
             vendorExt = (XmVendorShellExtObject) extData->widget;

            _XmRemoveCallback((InternalCallbackList *) &(vendorExt->vendor.focus_moved_callback),
                             (XtCallbackProc) bbClass->bulletin_board_class.focus_moved_proc,
                             (XtPointer) bb) ;
        } 
    } 
}


/****************************************************************
 * Modify attributes of a BulletinBoard instance.
 ****************/
/*ARGSUSED*/
static Boolean 
SetValues(
        Widget cw,
        Widget rw,
        Widget nw,
        ArgList args,		/* unused */
        Cardinal *num_args )	/* unused */
{   
    XmBulletinBoardWidget current = (XmBulletinBoardWidget) cw ;
    XmBulletinBoardWidget request = (XmBulletinBoardWidget) rw ;
    XmBulletinBoardWidget new_w = (XmBulletinBoardWidget) nw ;
    Arg		    al[10] ;
    register Cardinal       ac ;
    int             mwm_functions ;
    int             mwmStyle ;
    unsigned int    numChildren ;
    unsigned int    childIndex ;
    Widget *        childList ;
    Boolean flag = False ;

/****************/

    current->bulletin_board.in_set_values = True ;

    if(new_w->bulletin_board.shadow_type
       != current->bulletin_board.shadow_type) {
	if (XmRepTypeValidValue( XmRID_SHADOW_TYPE,
				new_w->bulletin_board.shadow_type, 
				(Widget) new_w) )
	    flag = True ;
	else 
	    new_w->bulletin_board.shadow_type = 
		current->bulletin_board.shadow_type ;
    } 
    
    if(    (new_w->bulletin_board.resize_policy 
                                      != current->bulletin_board.resize_policy)
        && !XmRepTypeValidValue( XmRID_RESIZE_POLICY,
                          new_w->bulletin_board.resize_policy, (Widget) new_w)    )
    {   new_w->bulletin_board.resize_policy 
                                      = current->bulletin_board.resize_policy ;
        }

    if(    new_w->bulletin_board.dialog_style
                                   != current->bulletin_board.dialog_style    )
    {   if(    new_w->bulletin_board.shell    )
        {   
            if(    !XmRepTypeValidValue( XmRID_DIALOG_STYLE, 
                           new_w->bulletin_board.dialog_style, (Widget) new_w)    )
            {   new_w->bulletin_board.dialog_style
                                       = current->bulletin_board.dialog_style ;
                } 
            } 
        else
        {   if(    new_w->bulletin_board.dialog_style != XmDIALOG_MODELESS    )
            {   
                XmeWarning( (Widget) new_w, WARN_DIALOG_STYLE) ;
                new_w->bulletin_board.dialog_style
                                       = current->bulletin_board.dialog_style ;
                } 
            }
        } 
    /*	Update shell attributes.
    */
    if(    new_w->bulletin_board.dialog_title !=
                                      current->bulletin_board.dialog_title    )
    {   /* Update window manager title.
        */
        XmStringFree( current->bulletin_board.dialog_title) ;
        new_w->bulletin_board.dialog_title = XmStringCopy(
                                        request->bulletin_board.dialog_title) ;
        XmeSetWMShellTitle(new_w->bulletin_board.dialog_title,
				    XtParent(new_w)) ;
        }

/*
 * Fix for 2940 - If the parent of the BulletinBoard is a VendorShell or
 *                related to VendorShell, check the no_resize and 
 *		  change it if necessary
 */
    if (XmIsVendorShell(XtParent(new_w)))
    {   
        ac = 0 ;
        /*	Turn window manager resize on or off.
        */
        if(    new_w->bulletin_board.no_resize != current->bulletin_board.no_resize    )
        {   
            XtSetArg( al[0], XmNmwmFunctions, &mwm_functions) ;
	    XtGetValues( XtParent( new_w), al, 1) ;

	    if(    mwm_functions == DONT_CARE    )
	      {
		mwm_functions = (int) (XmIsDialogShell(XtParent(new_w)) ? 
				       DIALOG_FUNCS : CLIENT_FUNCS);
	      }
            if(    new_w->bulletin_board.no_resize    )
            {   mwm_functions &= ~MWM_FUNC_RESIZE ;
                } 
            else
            {   mwm_functions |= MWM_FUNC_RESIZE ;
                } 
            XtSetArg( al[ac], XmNmwmFunctions, mwm_functions) ;  ac++ ;
            }
        if(    new_w->bulletin_board.shell    )
        {
          if(    new_w->bulletin_board.dialog_style
                                   != current->bulletin_board.dialog_style    )
          {   if(    !XmRepTypeValidValue( XmRID_DIALOG_STYLE,
                             new_w->bulletin_board.dialog_style, (Widget) new_w)    )
              {   
                  new_w->bulletin_board.dialog_style 
                                       = current->bulletin_board.dialog_style ;
                  } 
              else
              {   switch(    new_w->bulletin_board.dialog_style    )
                  {   
                      case XmDIALOG_PRIMARY_APPLICATION_MODAL:
                      {   mwmStyle = MWM_INPUT_PRIMARY_APPLICATION_MODAL ;
                          break ;
                          } 
                      case XmDIALOG_FULL_APPLICATION_MODAL:
                      {   mwmStyle = MWM_INPUT_FULL_APPLICATION_MODAL ;
                          break ; 
                          } 
                      case XmDIALOG_SYSTEM_MODAL:
                      {   mwmStyle = MWM_INPUT_SYSTEM_MODAL ;
                          break ;
                          } 
                      case XmDIALOG_MODELESS:
	              default:
                      {   mwmStyle = MWM_INPUT_MODELESS ;
                          break ;
                          } 
                      } 
                  XtSetArg( al[ac], XmNmwmInputMode, mwmStyle) ; ac++ ;
                  }
              }
          }
        if(    ac    )
        {   
            XtSetValues( XtParent (new_w), al, ac) ;
            }
        }
    /*	Copy new font list data, free previous.
    */
    if(    request->bulletin_board.button_font_list
                               != current->bulletin_board.button_font_list    )
    {   if(    current->bulletin_board.button_font_list    )
        {   XmFontListFree( current->bulletin_board.button_font_list) ;
            } 
        if(    new_w->bulletin_board.button_font_list    )
        {   new_w->bulletin_board.button_font_list = XmFontListCopy( 
                                    request->bulletin_board.button_font_list) ;
            } 
        if(    !new_w->bulletin_board.button_font_list    )
        {   new_w->bulletin_board.button_font_list = XmFontListCopy( 
                     XmeGetDefaultRenderTable( (Widget) new_w, XmBUTTON_FONTLIST)) ;
            } 
        }
    if(    request->bulletin_board.label_font_list
                                != current->bulletin_board.label_font_list    )
    {   if(    current->bulletin_board.label_font_list    )
        {   XmFontListFree( current->bulletin_board.label_font_list) ;
            } 
        if(    new_w->bulletin_board.label_font_list    )
        {   new_w->bulletin_board.label_font_list = XmFontListCopy( 
                                     request->bulletin_board.label_font_list) ;
            } 
        if(    !new_w->bulletin_board.label_font_list    )
        {   new_w->bulletin_board.label_font_list = XmFontListCopy( 
                      XmeGetDefaultRenderTable( (Widget) new_w, XmLABEL_FONTLIST)) ;
            } 
        }
    if(    request->bulletin_board.text_font_list
                                 != current->bulletin_board.text_font_list    )
    {   if(    current->bulletin_board.text_font_list    )
        {   XmFontListFree( current->bulletin_board.text_font_list) ;
            } 
        if(    new_w->bulletin_board.text_font_list    )
        {   new_w->bulletin_board.text_font_list = XmFontListCopy( 
                                      request->bulletin_board.text_font_list) ;
            } 
        if(    !new_w->bulletin_board.text_font_list    )
        {   new_w->bulletin_board.text_font_list = XmFontListCopy( 
                       XmeGetDefaultRenderTable( (Widget) new_w, XmTEXT_FONTLIST)) ;
            } 
        }
    if(    BB_DefaultButton( new_w) != BB_DefaultButton( current)    )
    {   
        if(    !BB_DefaultButton( current)    )
        {   
            /* This is the a new default button.  Notify all potential 
	       default button that they might turn default on sooner
            */
            numChildren = new_w->composite.num_children ;
            childList = new_w->composite.children ;
            childIndex = 0 ;
            while(childIndex < numChildren    )
            {   
                BulletinBoardSetDefaultShadow( childList[childIndex]) ;
		 
                ++childIndex ;
	    } 
	}
	BBUpdateDynDefaultButton( (Widget) new_w) ;
    } 
    if(    !(new_w->manager.initial_focus) && BB_DefaultButton( new_w)    )
      {
	_XmSetInitialOfTabGroup( (Widget) new_w, BB_DefaultButton( new_w)) ;
      }


    if(new_w->manager.shadow_thickness
       != current->manager.shadow_thickness) {
	flag = True ;
	new_w->bulletin_board.old_shadow_thickness =
	    new_w->manager.shadow_thickness ;
    } 


    if(    XtClass( new_w) == xmBulletinBoardWidgetClass    )
    {   
     /* do the margin enforcement only for pure BB, not subclasses,
       which have their own layout */

	if (((new_w->bulletin_board.margin_width != 
	      current->bulletin_board.margin_width) ||
	     (new_w->bulletin_board.margin_height !=
	      current->bulletin_board.margin_height))) {
	    /*
	       Do not change size if not realized; otherwise, ChangeManaged
	       will assume that the user set a size resource, and will not
	       resize to fit children added after this call, but before
	       realizing. ChangeManaged will perform layout at realize-time.
	    */
	    if (XtIsRealized((Widget)new_w)) {
		/* move the child around if necessary */
		_XmGMEnforceMargin((XmManagerWidget)new_w,
			       new_w->bulletin_board.margin_width,
			       new_w->bulletin_board.margin_height,
			       False); /* use movewidget, no request */
		_XmGMCalcSize ((XmManagerWidget)new_w, 
			   new_w->bulletin_board.margin_width, 
			   new_w->bulletin_board.margin_height, 
			   &new_w->core.width, &new_w->core.height);
	    }  
	}
    } 

    current->bulletin_board.in_set_values = False ;

    return( flag) ;
}

/****************************************************************/
static Boolean 
SetValuesHook(
        Widget wid,
        ArgList args,
        Cardinal *num_args )
{
        XmBulletinBoardWidget   bb = (XmBulletinBoardWidget) wid ;
	int			i;
	Widget			shell = bb->bulletin_board.shell;

/****************/
/* look the comments on MAGIC in DialogSavvyT.h */

    if (!shell)
      return (False);
    
    for (i=0; i<*num_args; i++)
      {
	  if (strcmp (args[i].name, XmNx) == 0)
	    {
		if ((args[i].value == 0) && (XtX (bb) == 0))
		  {
		      XtX (bb) = XmDIALOG_SAVVY_FORCE_ORIGIN;
		  }
	    } 
	  if (strcmp (args[i].name, XmNy) == 0)
	    {
		if ((args[i].value == 0) && (XtY (bb) == 0))
		  {
		      XtY (bb) = XmDIALOG_SAVVY_FORCE_ORIGIN;
		  }
	    }
      }
    return (False);
}


/****************************************************************
 * Arrange widgets and make geometry request if necessary.
 ****************/
static void 
HandleChangeManaged(
        XmBulletinBoardWidget bbWid,
        XmGeoCreateProc geoMatrixCreate)
{
            Dimension       desired_w = 0 ;
            Dimension       desired_h = 0 ;
            Dimension       allowed_w ;
            Dimension       allowed_h ;
            XmGeoMatrix     geoSpec ;
/****************/

	/* honor initial sizes if given and resize_none sizes */
    if (!XtIsRealized((Widget)bbWid)) {
	if (XtWidth(bbWid)) desired_w = XtWidth(bbWid) ;
	if (XtHeight(bbWid)) desired_h = XtHeight(bbWid) ;
    } else {
	if(BB_ResizePolicy(bbWid) == XmRESIZE_NONE) {
	    desired_w = XtWidth(bbWid) ;
	    desired_h = XtHeight(bbWid) ;
	}
    }

    geoSpec = (*geoMatrixCreate)( (Widget) bbWid, NULL, NULL) ;

    _XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;

    _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0,
                                                      &desired_w, &desired_h) ;
    /*	Adjust desired width and height if resize_grow.
    */
    if(    BB_ResizePolicy( bbWid) == XmRESIZE_GROW    )
    {
	Boolean		reset_w = False ;
        Boolean         reset_h = False ;

        if(    desired_w < XtWidth( bbWid)    )
	{
	    desired_w = XtWidth( bbWid) ;
	    reset_w = True ;
	    }
	if(    desired_h < XtHeight( bbWid)    )
	{
	    desired_h = XtHeight( bbWid) ;
	    reset_h = True ;
	    }
	if(    reset_w  ||  reset_h    )
	{   
            _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0,
                     &desired_w, &desired_h) ;
            }
	}

    /*	Request new geometry from parent.
    */
    if(    (desired_h != XtHeight( bbWid))
        || (desired_w != XtWidth( bbWid))    )
    {   
        switch(    XtMakeResizeRequest( (Widget) bbWid, desired_w, desired_h, 
                                     &allowed_w, &allowed_h)    )
        {   
            case XtGeometryYes:
            {   break ;
                } 
            case XtGeometryAlmost:
            {   
                XtMakeResizeRequest( (Widget) bbWid, allowed_w, allowed_h, 
                                  NULL, NULL) ;
                _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, 
                                 &allowed_w, &allowed_h) ;
                break ;
                } 
            case XtGeometryNo:
	    default:
            {   allowed_w = XtWidth( bbWid) ;
                allowed_h = XtHeight( bbWid) ;
                _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, 
                                 &allowed_w, &allowed_h) ;
                break ;
                } 
            }
        /*	Clear shadow if necessary.
        */
        if(    bbWid->bulletin_board.old_shadow_thickness
            && (   (allowed_w > bbWid->bulletin_board.old_width)
                || (allowed_h > bbWid->bulletin_board.old_height))    )
        {   
            _XmClearShadowType( (Widget) bbWid,
			       bbWid->bulletin_board.old_width,
			       bbWid->bulletin_board.old_height,
			       bbWid->bulletin_board.old_shadow_thickness, 
			       (Dimension) 0) ;
            bbWid->bulletin_board.old_shadow_thickness = 0 ;
            }
        }
    /*	Update children.
    */
    _XmGeoMatrixSet( geoSpec) ;

    _XmGeoMatrixFree( geoSpec) ;

    if(    bbWid->manager.shadow_thickness
        && (XtWidth( bbWid) <= bbWid->bulletin_board.old_width)
        && (XtHeight( bbWid) <= bbWid->bulletin_board.old_height)    )
    {   
        XmeDrawShadows(XtDisplay((Widget) bbWid), 
			XtWindow((Widget) bbWid),
			bbWid->manager.top_shadow_GC,
			bbWid->manager.bottom_shadow_GC,
			0, 0,
			bbWid->core.width, bbWid->core.height,
			bbWid->manager.shadow_thickness, 
			bbWid->bulletin_board.shadow_type) ;
        bbWid->bulletin_board.old_shadow_thickness 
                                            = bbWid->manager.shadow_thickness ;
        }
    bbWid->bulletin_board.old_width = bbWid->core.width ;
    bbWid->bulletin_board.old_height = bbWid->core.height ;

    XmeNavigChangeManaged( (Widget) bbWid) ;

    return ;
    }
/****************************************************************
 * Arrange widgets based on new size.
 ****************/
static void 
HandleResize(
        XmBulletinBoardWidget bbWid,
        XmGeoCreateProc geoMatrixCreate)
{
            Dimension       new_w = XtWidth( bbWid) ;
            Dimension       new_h = XtHeight( bbWid) ;
            XmGeoMatrix     geoSpec ;
/*********** draw_shadow is not used **************
            Boolean         draw_shadow = False ;
****************/
    
    /*	Clear shadow.
    */
    if(    bbWid->bulletin_board.old_shadow_thickness
        && (   (bbWid->bulletin_board.old_width != bbWid->core.width)
            || (bbWid->bulletin_board.old_height != bbWid->core.height))    )
    {
	_XmClearShadowType( (Widget) bbWid, bbWid->bulletin_board.old_width,
                              bbWid->bulletin_board.old_height, 
                               bbWid->bulletin_board.old_shadow_thickness, 
                                                               (Dimension) 0) ;
        bbWid->bulletin_board.old_shadow_thickness = 0 ;
	}

    geoSpec = (*geoMatrixCreate)( (Widget) bbWid, NULL, NULL) ;

    _XmGeoMatrixGet( geoSpec, XmGET_PREFERRED_SIZE) ;

    _XmGeoArrangeBoxes( geoSpec, (Position) 0, (Position) 0, &new_w, &new_h) ;

    _XmGeoMatrixSet( geoSpec) ;

    if(    bbWid->manager.shadow_thickness
        && (XtWidth( bbWid) <= bbWid->bulletin_board.old_width)
        && (XtHeight( bbWid) <= bbWid->bulletin_board.old_height)    )
    {   
        XmeDrawShadows(XtDisplay((Widget) bbWid), 
			XtWindow((Widget) bbWid),
			bbWid->manager.top_shadow_GC,
			bbWid->manager.bottom_shadow_GC,
			0, 0,
			bbWid->core.width, bbWid->core.height,
			bbWid->manager.shadow_thickness, 
			bbWid->bulletin_board.shadow_type) ;
        bbWid->bulletin_board.old_shadow_thickness 
                                            = bbWid->manager.shadow_thickness ;
        } 
    bbWid->bulletin_board.old_width = bbWid->core.width ;
    bbWid->bulletin_board.old_height = bbWid->core.height ;

    _XmGeoMatrixFree( geoSpec) ;
    return ;
    }
/****************************************************************
 * Handle geometry requests from children.
 ****************/
static XtGeometryResult 
HandleGeometryManager(
        Widget instigator,
        XtWidgetGeometry *desired,
        XtWidgetGeometry *allowed,
        XmGeoCreateProc geoMatrixCreate)
{
            XmBulletinBoardWidget bbWid ;
            XtGeometryResult result ;
/****************/

    bbWid = (XmBulletinBoardWidget) XtParent( instigator) ;

    if(    !(desired->request_mode & (CWWidth | CWHeight))    )
    {   return (XtGeometryYes) ;
        } 

    /*	Clear shadow if necessary.
    */
    if(    bbWid->bulletin_board.old_shadow_thickness
        && (BB_ResizePolicy( bbWid) != XmRESIZE_NONE)    )
    {
        _XmClearShadowType( (Widget) bbWid, bbWid->bulletin_board.old_width, 
                              bbWid->bulletin_board.old_height, 
                               bbWid->bulletin_board.old_shadow_thickness, 0) ;
        bbWid->bulletin_board.old_shadow_thickness = 0 ;
	}

    result = _XmHandleGeometryManager( (Widget) bbWid,
                         instigator, desired, allowed, BB_ResizePolicy( bbWid),
                           &bbWid->bulletin_board.geo_cache, geoMatrixCreate) ;

    if(    !bbWid->bulletin_board.in_set_values
        && bbWid->manager.shadow_thickness
        && (XtWidth( bbWid) <= bbWid->bulletin_board.old_width)
        && (XtHeight( bbWid) <= bbWid->bulletin_board.old_height)    )
    {   
        XmeDrawShadows(XtDisplay((Widget) bbWid), 
			XtWindow((Widget) bbWid),
			bbWid->manager.top_shadow_GC,
			bbWid->manager.bottom_shadow_GC,
			0, 0,
			bbWid->core.width, bbWid->core.height,
			bbWid->manager.shadow_thickness, 
			bbWid->bulletin_board.shadow_type) ;
        bbWid->bulletin_board.old_shadow_thickness
                                            = bbWid->manager.shadow_thickness ;
        } 
    bbWid->bulletin_board.old_width = bbWid->core.width ;
    bbWid->bulletin_board.old_height = bbWid->core.height ;

    return( result) ;
    }

/****************************************************************/
void 
_XmBulletinBoardSizeUpdate(
        Widget wid )
{
            XmBulletinBoardWidget bbWid = (XmBulletinBoardWidget) wid ;
            XmBulletinBoardWidgetClass classPtr = 
                        (XmBulletinBoardWidgetClass) bbWid->core.widget_class ;
/****************/

    if(    !XtIsRealized((Widget)bbWid)    )
    {   return ;
        } 

    if(    classPtr->bulletin_board_class.geo_matrix_create    )
    {   
        /*	Clear shadow if necessary.
        */
        if(    bbWid->bulletin_board.old_shadow_thickness
            && (BB_ResizePolicy( bbWid) != XmRESIZE_NONE)    )
        {
            _XmClearShadowType( (Widget) bbWid,
                         bbWid->bulletin_board.old_width,
                            bbWid->bulletin_board.old_height,
                               bbWid->bulletin_board.old_shadow_thickness, 0) ;
            bbWid->bulletin_board.old_shadow_thickness = 0 ;
            }

        _XmHandleSizeUpdate( (Widget) bbWid, BB_ResizePolicy( bbWid),
                            classPtr->bulletin_board_class.geo_matrix_create) ;

        if(    bbWid->manager.shadow_thickness
            && (XtWidth( bbWid) <= bbWid->bulletin_board.old_width)
            && (XtHeight( bbWid) <= bbWid->bulletin_board.old_height)    )
        {   
            XmeDrawShadows(XtDisplay((Widget) bbWid), 
			    XtWindow((Widget) bbWid),
			    bbWid->manager.top_shadow_GC,
			    bbWid->manager.bottom_shadow_GC,
			    0, 0,
			    bbWid->core.width, bbWid->core.height,
			    bbWid->manager.shadow_thickness, 
			    bbWid->bulletin_board.shadow_type) ;
	    bbWid->bulletin_board.old_shadow_thickness
		= bbWid->manager.shadow_thickness ;
            }
        } 
    bbWid->bulletin_board.old_width = bbWid->core.width ;
    bbWid->bulletin_board.old_height = bbWid->core.height ;

    return ;
    }

/****************************************************************
 * Layout children of the BulletinBoard.
 ****************/
static void 
ChangeManaged(
        Widget wid )
{   
            XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;
            XmBulletinBoardWidgetClass classPtr = 
                           (XmBulletinBoardWidgetClass) bb->core.widget_class ;
/****************/

    if(    classPtr->bulletin_board_class.geo_matrix_create    )
    {   HandleChangeManaged( bb, 
                            classPtr->bulletin_board_class.geo_matrix_create) ;
        return ;
        } 

    /* function shared with Bulletin Board */
    _XmGMEnforceMargin((XmManagerWidget)bb,
                     bb->bulletin_board.margin_width,
                     bb->bulletin_board.margin_height, 
                     False); /* use movewidget, not setvalue */

    /*	Clear shadow if necessary.
    */
    if(    bb->bulletin_board.old_shadow_thickness    )
    {   
        _XmClearShadowType( (Widget) bb, bb->bulletin_board.old_width, 
				bb->bulletin_board.old_height, 
				bb->bulletin_board.old_shadow_thickness, 0) ;
        bb->bulletin_board.old_shadow_thickness = 0 ;
        }
  
    /* The first time, reconfigure only if explicit size were not given */

    if (XtIsRealized((Widget)bb) || (!XtWidth(bb)) || (!XtHeight(bb))) {
      /* function shared with DrawingArea */
      (void)_XmGMDoLayout((XmManagerWidget)bb,
                          bb->bulletin_board.margin_width,
                          bb->bulletin_board.margin_height,
                          bb->bulletin_board.resize_policy,
                          False);  /* queryonly not specified */
    }

    if(    bb->manager.shadow_thickness
        && (XtWidth( bb) <= bb->bulletin_board.old_width)
        && (XtHeight( bb) <= bb->bulletin_board.old_height)    )
    {   
        XmeDrawShadows(XtDisplay((Widget) bb), 
			XtWindow((Widget) bb),
			bb->manager.top_shadow_GC,
			bb->manager.bottom_shadow_GC,
			0, 0,
			bb->core.width, bb->core.height,
			bb->manager.shadow_thickness, 
			bb->bulletin_board.shadow_type) ;
        bb->bulletin_board.old_shadow_thickness 
                                               = bb->manager.shadow_thickness ;
        }
    bb->bulletin_board.old_width = bb->core.width ;
    bb->bulletin_board.old_height = bb->core.height ;

    XmeNavigChangeManaged( (Widget) bb) ;

    return ;
    }
   
/****************************************************************
 * Unmanage BulletinBoard after button is activated.
 ****************/
/*ARGSUSED*/
static void 
UnmanageCallback(
        Widget w,		/* unused */
        XtPointer client_data,
        XtPointer call_data )	/* unused */
{
            Widget          bb = (Widget) client_data ;
/****************/

    XtUnmanageChild( bb) ;

    return ;
    }

/****************************************************************
 * Add a child to the BulletinBoard.
 ****************/
static void 
InsertChild(
        Widget child )
{   
    XmBulletinBoardWidget bb = (XmBulletinBoardWidget) XtParent( child) ;
    Boolean         is_button = False ;
    XtWidgetProc insert_child;

    _XmProcessLock();
    insert_child = ((XmManagerWidgetClass) xmManagerWidgetClass)
				  ->composite_class.insert_child;
    _XmProcessUnlock();
    (*insert_child)(child);

    if(    !XtIsRectObj( child)    )
    {   return ;
        }

    if(XmeTraitGet((XtPointer)XtClass(child), XmQTtakesDefault))
    {   is_button = TRUE ;

        if(    BB_DefaultButton( bb)    )
        {   
            /* Notify child that it has to be ready for default visual
            */
            BulletinBoardSetDefaultShadow( child) ;
            } 
        } 
    if(    XmIsDrawnButton( child)    )
    {   is_button = True ;
        } 

    /* Now, here I could use the activatable trait to add the
       auto_unmanage callback but I'm afraid that by covering the 
       Arrow button I introduce behavior compatibility problem, so
       I keep the DrawnButton check for now */

    if(    is_button && bb->bulletin_board.shell
                                       && bb->bulletin_board.auto_unmanage    )
    {   
        XtAddCallback( child, XmNactivateCallback,
                                            UnmanageCallback, (XtPointer) bb) ;
        }
    if(    XmIsText (child)
        || XmIsTextField (child)    )
    {   
        if(    bb->bulletin_board.text_translations    )
        {   XtOverrideTranslations( child, 
				bb->bulletin_board.text_translations) ;
            } 
        }
    return ;
    }

/****************************************************************
 * Clear widget id in instance record
 ****************/
static void 
DeleteChild(
        Widget child )
{   
  XmBulletinBoardWidget bb ;
  XtWidgetProc      delete_child;
/****************/

  if(    XtIsRectObj( child)    )
    {   
      bb = (XmBulletinBoardWidget) XtParent( child) ;

      /* To fix CR #4882, unnest the following to allow
	 for one button to be more than one of the defined buttons */
      if(    child == BB_DefaultButton( bb)    )
	BB_DefaultButton( bb) = NULL ;
      if(    child == BB_DynamicDefaultButton( bb)    )
	BB_DynamicDefaultButton( bb) = NULL ;
      if(    child == BB_CancelButton( bb)    )
	BB_CancelButton( bb) = NULL ;
      if(    child == BB_DynamicCancelButton( bb)    )
	BB_DynamicCancelButton( bb) = NULL ;
    }
  _XmProcessLock();
  delete_child = ((XmManagerWidgetClass) xmManagerWidgetClass)
	     			->composite_class.delete_child;
  _XmProcessUnlock();
  (*delete_child)(child);
  return ;
}

/****************************************************************/
static XtGeometryResult 
GeometryManager(
        Widget w,
        XtWidgetGeometry *request,
        XtWidgetGeometry *reply )
{   
            XmBulletinBoardWidget bb ;
            XmBulletinBoardWidgetClass classPtr ;
/****************/

    bb = (XmBulletinBoardWidget) w->core.parent ;
    classPtr = (XmBulletinBoardWidgetClass) bb->core.widget_class ;

    if(    classPtr->bulletin_board_class.geo_matrix_create    )
    {   return( HandleGeometryManager( w, request, reply,
                           classPtr->bulletin_board_class.geo_matrix_create)) ;
        } 

    /* function shared with DrawingArea */
    return(_XmGMHandleGeometryManager((Widget)bb, w, request, reply, 
                                    bb->bulletin_board.margin_width, 
                                    bb->bulletin_board.margin_height, 
                                    bb->bulletin_board.resize_policy,
                                    bb->bulletin_board.allow_overlap));
    }
   
/****************************************************************
 * Handle query geometry requests
 ****************/
static XtGeometryResult 
QueryGeometry(
        Widget wid,
        XtWidgetGeometry *intended,
        XtWidgetGeometry *desired )
{   
            XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;
            XmBulletinBoardWidgetClass classPtr = 
                           (XmBulletinBoardWidgetClass) bb->core.widget_class ;
/****************/

    if(    classPtr->bulletin_board_class.geo_matrix_create    )
    {   
        return( _XmHandleQueryGeometry( (Widget) bb,
                        intended, desired, BB_ResizePolicy( bb),
                           classPtr->bulletin_board_class.geo_matrix_create)) ;
        } 
    /* function shared with DrawingArea */
    return(_XmGMHandleQueryGeometry(wid, intended, desired, 
                                  bb->bulletin_board.margin_width, 
                                  bb->bulletin_board.margin_height, 
                                  bb->bulletin_board.resize_policy));
    }

/****************************************************************
 * Conform to new size.
 ****************/
static void 
Resize(
        Widget wid )
{   
            XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;
            XmBulletinBoardWidgetClass classPtr = 
                           (XmBulletinBoardWidgetClass) bb->core.widget_class ;
/****************/

    if(    classPtr->bulletin_board_class.geo_matrix_create    )
    {   
        HandleResize( bb, classPtr->bulletin_board_class.geo_matrix_create) ;
        return ;
        } 
    /*	Clear shadow.
    */
    if(    bb->bulletin_board.old_shadow_thickness    )
    {   
        _XmClearShadowType( (Widget) bb, bb->bulletin_board.old_width, 
				bb->bulletin_board.old_height, 
				bb->bulletin_board.old_shadow_thickness, 0) ;
        bb->bulletin_board.old_shadow_thickness = 0 ;
        }
    if(    bb->manager.shadow_thickness
        && (XtWidth( bb) <= bb->bulletin_board.old_width)
        && (XtHeight( bb) <= bb->bulletin_board.old_height)    )
    {   
        XmeDrawShadows(XtDisplay((Widget) bb), 
			XtWindow((Widget) bb),
			bb->manager.top_shadow_GC,
			bb->manager.bottom_shadow_GC,
			0, 0,
			bb->core.width, bb->core.height,
			bb->manager.shadow_thickness, 
			bb->bulletin_board.shadow_type) ;
        bb->bulletin_board.old_shadow_thickness 
                                               = bb->manager.shadow_thickness ;
        }
    bb->bulletin_board.old_width = bb->core.width ;
    bb->bulletin_board.old_height = bb->core.height ;

    return ;
    }

/****************************************************************
 * Redisplay gadgets and draw shadow.
 ****************/
static void 
Redisplay(
        Widget wid,
        XEvent *event,
        Region region )
{   
            XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;
/****************/

    /*	Redisplay gadgets.
    */
    XmeRedisplayGadgets( wid, event, region) ;

    /*	Draw shadow.
    */
    if(    bb->manager.shadow_thickness    )
    {   
        XmeDrawShadows(XtDisplay((Widget) bb), 
			XtWindow((Widget) bb),
			bb->manager.top_shadow_GC,
			bb->manager.bottom_shadow_GC,
			0, 0,
			bb->core.width, bb->core.height,
			bb->manager.shadow_thickness, 
			bb->bulletin_board.shadow_type) ;
        bb->bulletin_board.old_shadow_thickness 
                                               = bb->manager.shadow_thickness ;
        } 
    bb->bulletin_board.old_width = bb->core.width ;
    bb->bulletin_board.old_height = bb->core.height ;

    return ;
    }



/****************************************************************/
/*ARGSUSED*/
void 
_XmBulletinBoardFocusMoved(
        Widget wid,		/* unused */
        XtPointer client_data,
        XtPointer data )
{   
            XmFocusMovedCallbackStruct * call_data 
                                        = (XmFocusMovedCallbackStruct *) data ;
            Widget          ancestor ;
	    XmBulletinBoardWidget bb = (XmBulletinBoardWidget) client_data ;
            XmAnyCallbackStruct	cb ;
            Boolean         BBHasFocus = FALSE ;
            Boolean         BBHadFocus = FALSE ;
            Widget          dbutton = NULL ;
            Widget          cbutton = NULL ;
/****************/

    if(    !call_data->cont    )
    {   /* Preceding callback routine wants focus-moved processing
        *   to be discontinued.
        */
        return ;
        } 

    /* Walk the heirarchy above the widget that is getting the focus to
    *   determine the correct default and cancel buttons for the current 
    *   context.
    *  Note that no changes are made to the Bulletin Board instance record
    *   until after the possibility of a forced traversal is evaluated.
    */
    ancestor = call_data->new_focus ;
    while(    ancestor  &&  !XtIsShell( ancestor)    )
    {   
        if(    ancestor == (Widget) bb    )
        {   BBHasFocus = TRUE ;
            break ;
            } 
        if(    XmIsBulletinBoard( ancestor)    )
        {   
            if(    !dbutton    )
            {   dbutton = BB_DefaultButton( ancestor) ;
                } 
            if(    !cbutton    )
            {   cbutton = BB_CancelButton( ancestor) ;
                } 
            } 
        ancestor = XtParent( ancestor) ;
        } 
    ancestor = call_data->old_focus ;
    while(    ancestor  &&  !XtIsShell( ancestor)    )
    {   
        if(    ancestor == (Widget) bb    )
        {   BBHadFocus = TRUE ;
            break ;
            } 
        ancestor = XtParent( ancestor) ;
        }

    if(    BBHasFocus    )
    {   
        /* The widget getting the input focus is a descendent of
        *   or is this Bulletin Board.
        * If there were no descendent Bulletin Boards with default or cancel
        *   buttons, use our own.
        */
        if(    !dbutton    ) dbutton = BB_DefaultButton( bb) ;
	
        if(    !cbutton    ) cbutton = BB_CancelButton( bb) ;

        if(    !dbutton    )
        {   
	    /* No descendant has active default button, so be sure
             *   that the dynamic_default_button field for this
             *   ancestor is NULL.
             */
            BB_DynamicDefaultButton( bb) = NULL ;
	} else {   
            if(XmeTraitGet((XtPointer)XtClass(call_data->new_focus), 
			   XmQTtakesDefault))
            {   
                /* Any defaultable which gets the focus
                *   gets the default visuals and behavior.
                */
                _XmBulletinBoardSetDynDefaultButton( (Widget) bb,
                                                        call_data->new_focus) ;
                } 
            else /* call_data->new_focus is not a push button */
            {   
                if(    (call_data->focus_policy == XmEXPLICIT)
                    || !XmIsManager( call_data->new_focus)
                    || !call_data->old_focus
                    || (!XmeTraitGet((XtPointer)XtClass(call_data->old_focus), 
				     XmQTtakesDefault)))
                {   
                    /* Avoid setting the default button when in pointer mode,
                    *   leaving a button, and entering the background area.
                    *   The appropriate default button will be set when the
                    *   next focus moved event occurs.
                    *   This will avoid unnecessary flashing of default
                    *   button shadow when moving pointer between buttons.
                    */
                    if(    XtIsManaged( dbutton)    )
                    {   
                        _XmBulletinBoardSetDynDefaultButton((Widget) bb,
							    dbutton) ;
                        } 
                    } 
                } 
          }
        BB_DynamicCancelButton( bb) = cbutton ;

        if(    !BBHadFocus    )
        {   
            cb.reason = XmCR_FOCUS ;
            cb.event = NULL ;
            XtCallCallbackList( (Widget) bb,
                                      bb->bulletin_board.focus_callback, &cb) ;
            } 
        }
    else /* Bulletin Board does not have focus */
    {   
        if(    BBHadFocus    )
        {   
 	  if(    call_data->new_focus != NULL    )
 	    {
 	      _XmBulletinBoardSetDynDefaultButton( (Widget) bb, NULL) ;
 	    }
	} 
    }
    BB_InitialFocus( bb) = FALSE ;

    return ;
    }

/****************************************************************/
static Boolean 
BulletinBoardParentProcess(
        Widget wid,
        XmParentProcessData event )
{
            XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;
/****************/

    if(    (event->any.process_type == XmINPUT_ACTION)
        && (   (    (event->input_action.action == XmPARENT_ACTIVATE)
                 && BB_DynamicDefaultButton( bb))
            || (    (event->input_action.action == XmPARENT_CANCEL)
                 && BB_DynamicCancelButton( bb)))    )
    {   
        if(    event->input_action.action == XmPARENT_ACTIVATE    )
        {   
            _XmBulletinBoardReturn( (Widget)bb, event->input_action.event,
                                      event->input_action.params,
                                         event->input_action.num_params) ;
            } 
        else
        {   _XmBulletinBoardCancel( (Widget)bb, event->input_action.event,
                                      event->input_action.params,
                                         event->input_action.num_params) ;
            } 
        return( TRUE) ;
        } 

    return( _XmParentProcess( XtParent( bb), event)) ;
    }

/****************************************************************
 * Process Return and Enter key events in the BulletinBoard.
 *   If there is a default button, call its Activate callbacks.
 ****************/
void 
_XmBulletinBoardReturn(Widget wid,
		       XEvent *event,
		       String *params,
		       Cardinal *numParams )
{   
  XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;
  XmGadgetClass   gadget_class ;
  XmPrimitiveWidgetClass primitive_class ;
  Widget          dbutton = BB_DynamicDefaultButton( bb) ;

  if (!dbutton)
    {   
      XmParentInputActionRec parentEvent ;

      parentEvent.process_type = XmINPUT_ACTION ;
      parentEvent.action = XmPARENT_ACTIVATE ;
      parentEvent.event = event ;
      parentEvent.params = params ;
      parentEvent.num_params = numParams ;

      _XmParentProcess( XtParent( bb), (XmParentProcessData) &parentEvent) ;
    }
  else if (XmIsGadget( dbutton) && XtIsManaged( dbutton))
    {   
      gadget_class = (XmGadgetClass) XtClass( dbutton) ;
      if (gadget_class->gadget_class.arm_and_activate &&
	  XtIsSensitive(dbutton))
	{  
	  (*(gadget_class->gadget_class.arm_and_activate))
	    (dbutton, event, params, numParams) ;
	} 
    }
  else if (XmIsPrimitive( dbutton) && XtIsManaged( dbutton))
    {   
      primitive_class = (XmPrimitiveWidgetClass) XtClass( dbutton) ;
      if (primitive_class->primitive_class.arm_and_activate &&
	  XtIsSensitive(dbutton))
	{ 
	  (*(primitive_class->primitive_class.arm_and_activate))
	    (dbutton, event, params, numParams);
	} 
    }
  else
    {
      if (XtIsSensitive(dbutton))
	{
	  XmAnyCallbackStruct cb ;

	  cb.reason = XmCR_ACTIVATE ;
	  cb.event = event ;
	  XtCallCallbacks(dbutton, XmNactivateCallback, (XtPointer) &cb) ;
	} 
    }
}

/****************************************************************
 * Process Cancel key events in the BulletinBoard.
 * If there is a cancel button, call its Activate callbacks.
 ****************/
void 
_XmBulletinBoardCancel(Widget wid,
		       XEvent *event,
		       String *params,
		       Cardinal *numParams )
{   
  XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;
  XmGadgetClass   gadget_class ;
  XmPrimitiveWidgetClass primitive_class ;
  Widget          cbutton = BB_DynamicCancelButton( bb) ;

  if (!cbutton)
    {   
      XmParentInputActionRec parentEvent ;

      parentEvent.process_type = XmINPUT_ACTION ;
      parentEvent.action = XmPARENT_CANCEL ;
      parentEvent.event = event ;
      parentEvent.params = params ;
      parentEvent.num_params = numParams ;

      _XmParentProcess( XtParent( bb), (XmParentProcessData) &parentEvent) ;
    } 
  else if (XmIsGadget(cbutton) && XtIsManaged(cbutton))
    {   
      gadget_class = (XmGadgetClass) XtClass( cbutton) ;
      if (gadget_class->gadget_class.arm_and_activate &&
	  XtIsSensitive( cbutton))
	{
	  (*(gadget_class->gadget_class.arm_and_activate))
	    (cbutton, event, params, numParams) ;
	} 
    }
  else if (XmIsPrimitive( cbutton) && XtIsManaged( cbutton))
    {   
      primitive_class = (XmPrimitiveWidgetClass) XtClass( cbutton) ;
      if (primitive_class->primitive_class.arm_and_activate &&
	  XtIsSensitive(cbutton))
	{   
	  (*(primitive_class->primitive_class.arm_and_activate))
	    (cbutton, event, params, numParams) ;
	} 
    }
  else
    {
      if (XtIsSensitive(cbutton))
	{   
	  XmAnyCallbackStruct cb ;

	  cb.reason = XmCR_ACTIVATE ;
	  cb.event = event ;
	  XtCallCallbacks( cbutton, XmNactivateCallback, (XtPointer) &cb) ;
	} 
    }
}

/*ARGSUSED*/ 
void 
_XmBulletinBoardMap(
         Widget wid,
         XEvent *event,		/* unused */
         String *params,	/* unused */
         Cardinal *numParams )	/* unused */
 {   
   if(    BB_DefaultButton( wid)    )
     {
       Widget focus_hier = _XmGetFirstFocus( wid) ;
 
       while(    focus_hier
 	    &&  !XtIsShell( focus_hier)    )
 	{
 	  if(    focus_hier == wid    )
 	    {
 	      _XmBulletinBoardSetDynDefaultButton( wid,
 						      BB_DefaultButton( wid)) ;
 	      break ;
 	    }
 	  if(    XmIsBulletinBoard( focus_hier)
 	     &&  BB_DefaultButton( focus_hier)    )
 	    {
 	      break ;
 	    }
 	  focus_hier = XtParent( focus_hier) ;
 	}
     }
 }
 
/****************************************************************/
static void 
BulletinBoardSetDefaultShadow(
        Widget button )
{   
    XmTakesDefaultTrait trait_default ;
    
    trait_default = (XmTakesDefaultTrait) XmeTraitGet((XtPointer)
						      XtClass(button), 
						      XmQTtakesDefault) ;
    if (trait_default) 
	trait_default->showAsDefault  (button, XmDEFAULT_READY);
}


/****************************************************************
 * If the default button of the bulletin board widget (wid) is not equal to
 *   the specified default button (newDefaultButton), then the trait is used
 *   to turn off/on the appropriate default borders and the default button
 *   field of the bulletin board instance record is updated appropriately.
  ****************/
void 
_XmBulletinBoardSetDynDefaultButton(
        Widget wid,
        Widget newDefaultButton )
{
    XmBulletinBoardWidget bbWid = (XmBulletinBoardWidget) wid ;
    XmTakesDefaultTrait trait_default ;


    if (newDefaultButton != BB_DynamicDefaultButton( bbWid)) {   
        if (BB_DynamicDefaultButton(bbWid)) {   
	    trait_default = (XmTakesDefaultTrait) 
		XmeTraitGet((XtPointer) 
			    XtClass(BB_DynamicDefaultButton(bbWid)), 
			    XmQTtakesDefault) ;

	    if (trait_default) 
		trait_default->showAsDefault ((Widget)
					      BB_DynamicDefaultButton(bbWid),
					      XmDEFAULT_OFF);
	} 

        BB_DynamicDefaultButton( bbWid) = newDefaultButton ;

        if (newDefaultButton) {   
            trait_default = (XmTakesDefaultTrait) 
		XmeTraitGet((XtPointer) 
			    XtClass(BB_DynamicDefaultButton(bbWid)), 
			    XmQTtakesDefault) ;

	    if (trait_default) 
		trait_default->showAsDefault ((Widget)
					      BB_DynamicDefaultButton(bbWid),
					      XmDEFAULT_ON);
	} 
    } 
    return ;
}



static void
BBUpdateDynDefaultButton(
 	Widget bb)
{
    Widget bbwdb = GetBBWithDB( bb) ;
 
    if(    bbwdb == NULL    ) {
	if(    ((XmBulletinBoardWidget) bb)
	   ->bulletin_board.dynamic_default_button    )
 	{
	    _XmBulletinBoardSetDynDefaultButton( bb, NULL) ;
 	}
    }
    else {
	if(    bbwdb == bb    ) {
	    _XmBulletinBoardSetDynDefaultButton( bb, BB_DefaultButton( bb)) ;
 	}
    }
}
 
static Widget
GetBBWithDB(
 	Widget wid)
 {
   Widget focus ;
 
   if(    (_XmGetFocusPolicy( wid) == XmEXPLICIT)
      &&  (    (focus = XmGetFocusWidget( wid))
 	  ||  (focus = _XmGetFirstFocus( wid)))    )
     {
       while(    focus
 	    &&  !XtIsShell( focus)    )
 	{
 	  if(    XmIsBulletinBoard( focus)
 	     &&  BB_DefaultButton( focus)    )
 	    {
 	      return focus ;
 	    }
 	  focus = XtParent( focus) ;
 	}
 
     }
   return NULL ;
 }

/*
 * XmRCallProc routine for checking font before setting it to NULL
 * if no value is specified for both XmNrenderTable and XmNfontList.
 * If the appropriate bit in "check_state" is True, this function has 
 * been called twice on same widget for that resource, thus 
 * the resource needs to be set NULL, otherwise leave it alone.
 */
/* ARGSUSED */
static void 
CheckSetRenderTables(Widget wid,
		     int offset,
		     XrmValue *value )
{

#define SET_BFL(state) (state |= 0x01)
#define IS_SET_BFL(state) (state & 0x01)
#define SET_LFL(state) (state |= 0x02)
#define IS_SET_LFL(state) (state & 0x02)
#define SET_TFL(state) (state |= 0x04)
#define IS_SET_TFL(state) (state & 0x04)

  XmBulletinBoardWidget bbw = (XmBulletinBoardWidget)wid;

  if (((char*)bbw + offset) == 
      (char*) &(bbw->bulletin_board.button_font_list)) {
	if (IS_SET_BFL(bbw->bulletin_board.check_set))
		value->addr = NULL;
	else {
		SET_BFL(bbw->bulletin_board.check_set);
		value->addr = ((char *)bbw + offset);
	}
  }
  else if (((char*)bbw + offset) == 
	   (char*) &(bbw->bulletin_board.label_font_list)) {
	if (IS_SET_LFL(bbw->bulletin_board.check_set))
		value->addr = NULL;
	else {
		SET_LFL(bbw->bulletin_board.check_set);
		value->addr = ((char *)bbw + offset);
	}
  }
  else if (((char*)bbw + offset) ==
	   (char*) &(bbw->bulletin_board.text_font_list)) {
	if (IS_SET_TFL(bbw->bulletin_board.check_set))
		value->addr = NULL;
	else {
		SET_TFL(bbw->bulletin_board.check_set);
		value->addr = ((char *)bbw + offset);
	}
  }
}



/****************************************************************
 *
 * Trait method for specify render table 
 *
 **************************************************************/
static XmFontList 
GetTable(
	 Widget wid,
	 XtEnum type)
{
    XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;

    switch(type) {
    case XmLABEL_RENDER_TABLE : return bb->bulletin_board.label_font_list ;
    case XmBUTTON_RENDER_TABLE : return bb->bulletin_board.button_font_list ;
    case XmTEXT_RENDER_TABLE : return bb->bulletin_board.text_font_list ;
    }
   
    return NULL ;
}




/****************************************************************
 *
 * Trait method for dialog shell savvy
 *
 **************************************************************/
static void
CallMapUnmap(
	 Widget wid,
	 Boolean map_unmap)
{
    XmBulletinBoardWidget bb = (XmBulletinBoardWidget) wid ;
    XmAnyCallbackStruct call_data;	

    call_data.reason = (map_unmap)? XmCR_MAP : XmCR_UNMAP;
    call_data.event  = NULL;			

    if (map_unmap) {
	XtCallCallbackList (wid, bb->bulletin_board.map_callback, 
			    &call_data);
    } else {
	XtCallCallbackList (wid, bb->bulletin_board.unmap_callback, 
			    &call_data);
    }
}



/****************************************************************
 * This function creates and returns a BulletinBoard widget.
 ****************/
Widget 
XmCreateBulletinBoard(
        Widget p,
        String name,
        ArgList args,
        Cardinal n )
{   

    return( XtCreateWidget( name, xmBulletinBoardWidgetClass, p, args, n)) ;
}




/****************************************************************
 * This convenience function creates a DialogShell and a BulletinBoard
 *   child of the shell; returns the BulletinBoard widget.
 ****************/
Widget 
XmCreateBulletinBoardDialog(
        Widget ds_p,
        String name,
        ArgList bb_args,
        Cardinal bb_n )
{   
    return XmeCreateClassDialog (xmBulletinBoardWidgetClass, 
				 ds_p, name, bb_args, bb_n) ;
}

Widget 
XmVaCreateBulletinBoard(
        Widget parent,
        char *name,
        ...)
{
    register Widget w;
    va_list var;
    int count;
    
    Va_start(var,name);
    count = XmeCountVaListSimple(var);
    va_end(var);

    
    Va_start(var, name);
    w = XmeVLCreateWidget(name, 
                         xmBulletinBoardWidgetClass,
                         parent, False, 
                         var, count);
    va_end(var);   
    return w;
}

Widget
XmVaCreateManagedBulletinBoard(
        Widget parent,
        char *name,
        ...)
{
    Widget w = NULL;
    va_list var;
    int count;
    
    Va_start(var, name);
    count = XmeCountVaListSimple(var);
    va_end(var);
    
    Va_start(var, name);
    w = XmeVLCreateWidget(name, 
                         xmBulletinBoardWidgetClass,
                         parent, True, 
                         var, count);
    va_end(var);   
    return w;
}
