Blame lib/Xm/CascadeB.c

Packit b099d7
/* 
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
*/ 
Packit b099d7
/* 
Packit b099d7
 * HISTORY
Packit b099d7
*/ 
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char rcsid[] = "$TOG: CascadeB.c /main/27 1999/08/11 14:26:35 mgreess $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
Packit b099d7
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
Packit b099d7
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#include "XmI.h"		/* ShellP.h doesn't define externalref. */
Packit b099d7
#include <X11/ShellP.h>
Packit b099d7
#include <X11/keysymdef.h>
Packit b099d7
#include <Xm/BaseClassP.h>
Packit b099d7
#include <Xm/DisplayP.h>
Packit b099d7
#include <Xm/DrawP.h>
Packit b099d7
#include <Xm/LabelGP.h>
Packit b099d7
#include <Xm/LabelP.h>
Packit b099d7
#include <Xm/MenuShellP.h>
Packit b099d7
#include <Xm/MenuStateP.h>
Packit b099d7
#include <Xm/MenuT.h>
Packit b099d7
#include <Xm/RowColumnP.h>
Packit b099d7
#include <Xm/TearOffP.h>
Packit b099d7
#include <Xm/TraitP.h>
Packit b099d7
#include <Xm/TransltnsP.h>
Packit b099d7
#include <Xm/VaSimpleP.h>
Packit b099d7
#include "CascadeBI.h"
Packit b099d7
#include "CascadeBGI.h"
Packit b099d7
#include "LabelI.h"
Packit b099d7
#include "GadgetUtiI.h"
Packit b099d7
#include "MenuStateI.h"
Packit b099d7
#include "MenuProcI.h"
Packit b099d7
#include "MenuUtilI.h"
Packit b099d7
#include "MessagesI.h"
Packit b099d7
#include "PrimitiveI.h"
Packit b099d7
#include "RCMenuI.h"
Packit b099d7
#include "TearOffI.h"
Packit b099d7
#include "TraversalI.h"
Packit b099d7
#include "UniqueEvnI.h"
Packit b099d7
Packit b099d7
#define FIX_1509
Packit b099d7
Packit b099d7
#define CASCADE_PIX_SPACE    4	 /* pixels between label and bit map */
Packit b099d7
#define MAP_DELAY_DEFAULT   180
Packit b099d7
#define EVENTS              ((unsigned int) (ButtonPressMask | \
Packit b099d7
			     ButtonReleaseMask | EnterWindowMask | \
Packit b099d7
			     LeaveWindowMask))
Packit b099d7
Packit b099d7
Packit b099d7
#define WRONGPARENT	_XmMMsgCascadeB_0000
Packit b099d7
#define WRONGSUBMENU	_XmMMsgCascadeB_0001
Packit b099d7
#define WRONGMAPDELAY	_XmMMsgCascadeB_0002
Packit b099d7
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static void ClassInitialize( void ) ;
Packit b099d7
static void ClassPartInitialize( 
Packit b099d7
                        WidgetClass wc) ;
Packit b099d7
static void BorderHighlight( 
Packit b099d7
                        Widget wid) ;
Packit b099d7
static void BorderUnhighlight( 
Packit b099d7
                        Widget wid) ;
Packit b099d7
static void DrawShadow( 
Packit b099d7
                        register XmCascadeButtonWidget cb) ;
Packit b099d7
static void DrawCascade( 
Packit b099d7
                        register XmCascadeButtonWidget cb) ;
Packit b099d7
static void Redisplay( 
Packit b099d7
                        register Widget cb,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        Region region) ;
Packit b099d7
static void Arm( 
Packit b099d7
                        register XmCascadeButtonWidget cb) ;
Packit b099d7
static void ArmAndPost( 
Packit b099d7
                        XmCascadeButtonWidget cb,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void ArmAndActivate( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *params,
Packit b099d7
                        Cardinal *num_params) ;
Packit b099d7
static void Disarm( 
Packit b099d7
                        register XmCascadeButtonWidget cb,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int unpost) ;
Packit b099d7
#else
Packit b099d7
                        Boolean unpost) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static void PostTimeout( 
Packit b099d7
                        XtPointer closure,
Packit b099d7
                        XtIntervalId *id) ;
Packit b099d7
static void DelayedArm( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *param,
Packit b099d7
                        Cardinal *num_param) ;
Packit b099d7
static void CheckDisarm( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *param,
Packit b099d7
                        Cardinal *num_param) ;
Packit b099d7
static void StartDrag( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *param,
Packit b099d7
                        Cardinal *num_param) ;
Packit b099d7
static void Select( 
Packit b099d7
                        register XmCascadeButtonWidget cb,
Packit b099d7
                        XEvent *event,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int doCascade) ;
Packit b099d7
#else
Packit b099d7
                        Boolean doCascade) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static void DoSelect( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *param,
Packit b099d7
                        Cardinal *num_param) ;
Packit b099d7
static void KeySelect( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *param,
Packit b099d7
                        Cardinal *num_param) ;
Packit b099d7
static void MenuBarSelect( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *param,
Packit b099d7
                        Cardinal *num_param) ;
Packit b099d7
static void MenuBarEnter( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *param,
Packit b099d7
                        Cardinal *num_param) ;
Packit b099d7
static void MenuBarLeave( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *param,
Packit b099d7
                        Cardinal *num_param) ;
Packit b099d7
static void CleanupMenuBar( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        String *param,
Packit b099d7
                        Cardinal *num_param) ;
Packit b099d7
static void PopdownGrandChildren( 
Packit b099d7
                        XmRowColumnWidget rowcol) ;
Packit b099d7
static void Cascading( 
Packit b099d7
                        Widget w,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void Popup( 
Packit b099d7
                        Widget cb,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void size_cascade( 
Packit b099d7
                        XmCascadeButtonWidget cascadebtn) ;
Packit b099d7
static void position_cascade( 
Packit b099d7
                        XmCascadeButtonWidget cascadebtn) ;
Packit b099d7
static void setup_cascade( 
Packit b099d7
                        XmCascadeButtonWidget cascadebtn,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int adjustWidth,
Packit b099d7
                        int adjustHeight) ;
Packit b099d7
#else
Packit b099d7
                        Boolean adjustWidth,
Packit b099d7
                        Boolean adjustHeight) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static void Destroy( 
Packit b099d7
                        Widget wid) ;
Packit b099d7
static void Resize( 
Packit b099d7
                        Widget cb) ;
Packit b099d7
static Boolean SetValuesPrehook( 
Packit b099d7
			Widget cw,
Packit b099d7
                        Widget rw,
Packit b099d7
                        Widget nw,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static Boolean SetValues( 
Packit b099d7
                        Widget cw,
Packit b099d7
                        Widget rw,
Packit b099d7
                        Widget nw,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void InitializePrehook( 
Packit b099d7
                        Widget req,
Packit b099d7
                        Widget new_w,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void InitializePosthook( 
Packit b099d7
                        Widget req,
Packit b099d7
                        Widget new_w,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void GetArmGC( 
Packit b099d7
                        XmCascadeButtonWidget cb) ;
Packit b099d7
static void GetBackgroundGC( 
Packit b099d7
                        XmCascadeButtonWidget cb) ;
Packit b099d7
static void Initialize( 
Packit b099d7
                        Widget w_req,
Packit b099d7
                        Widget w_new,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * event translation tables for cascadebutton.  There are different
Packit b099d7
 * ones for the different menus a cascadebutton widget can appear in
Packit b099d7
 */
Packit b099d7
Packit b099d7
static XtTranslations menubar_events_parsed;
Packit b099d7
Packit b099d7
#define menubar_events	_XmCascadeB_menubar_events
Packit b099d7
Packit b099d7
static XtTranslations p_events_parsed;
Packit b099d7
Packit b099d7
#define p_events 	_XmCascadeB_p_events
Packit b099d7
Packit b099d7
static XtActionsRec action_table [] =
Packit b099d7
{
Packit b099d7
    {"DelayedArm",	DelayedArm},
Packit b099d7
    {"CheckDisarm",	CheckDisarm},
Packit b099d7
    {"StartDrag",	StartDrag},
Packit b099d7
    {"DoSelect", 	DoSelect},
Packit b099d7
    {"KeySelect",	KeySelect},
Packit b099d7
    {"MenuBarSelect",	MenuBarSelect},
Packit b099d7
    {"MenuBarEnter",	MenuBarEnter},
Packit b099d7
    {"MenuBarLeave",	MenuBarLeave},
Packit b099d7
    {"MenuButtonTakeFocus", _XmMenuButtonTakeFocus },
Packit b099d7
    {"MenuButtonTakeFocusUp", _XmMenuButtonTakeFocusUp },
Packit b099d7
    {"CleanupMenuBar",	CleanupMenuBar},
Packit b099d7
    {"Help",		_XmCBHelp},
Packit b099d7
};
Packit b099d7
Packit b099d7

Packit b099d7
static XtResource resources[] = 
Packit b099d7
{
Packit b099d7
    {	XmNactivateCallback, 
Packit b099d7
	XmCCallback, 
Packit b099d7
	XmRCallback,
Packit b099d7
	sizeof (XtCallbackList),
Packit b099d7
	XtOffsetOf( struct _XmCascadeButtonRec, cascade_button.activate_callback), 
Packit b099d7
	XmRCallback,
Packit b099d7
	NULL
Packit b099d7
    },
Packit b099d7
    {	XmNcascadingCallback, 
Packit b099d7
	XmCCallback, 
Packit b099d7
	XmRCallback,
Packit b099d7
	sizeof (XtCallbackList),
Packit b099d7
	XtOffsetOf( struct _XmCascadeButtonRec, cascade_button.cascade_callback), 
Packit b099d7
	XmRCallback,
Packit b099d7
	NULL
Packit b099d7
    },
Packit b099d7
    {	XmNsubMenuId, 
Packit b099d7
	XmCMenuWidget,				/* submenu */
Packit b099d7
	XmRMenuWidget, 
Packit b099d7
	sizeof (Widget),
Packit b099d7
	XtOffsetOf( struct _XmCascadeButtonRec, cascade_button.submenu), 
Packit b099d7
	XmRMenuWidget, 
Packit b099d7
	(XtPointer) NULL
Packit b099d7
    },
Packit b099d7
    {	XmNcascadePixmap, 
Packit b099d7
	XmCPixmap, 
Packit b099d7
	XmRDynamicPixmap,
Packit b099d7
	sizeof(Pixmap),
Packit b099d7
	XtOffsetOf( struct _XmCascadeButtonRec, cascade_button.cascade_pixmap), 
Packit b099d7
	XmRImmediate,
Packit b099d7
	(XtPointer) XmUNSPECIFIED_PIXMAP
Packit b099d7
    },
Packit b099d7
    {   XmNmappingDelay,
Packit b099d7
	XmCMappingDelay,
Packit b099d7
	XmRInt,
Packit b099d7
	sizeof (int),
Packit b099d7
	XtOffsetOf( struct _XmCascadeButtonRec, cascade_button.map_delay),
Packit b099d7
	XmRImmediate,
Packit b099d7
	(XtPointer) MAP_DELAY_DEFAULT
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNshadowThickness,
Packit b099d7
        XmCShadowThickness,
Packit b099d7
        XmRHorizontalDimension,
Packit b099d7
        sizeof (Dimension),
Packit b099d7
        XtOffsetOf( struct _XmCascadeButtonRec, primitive.shadow_thickness),
Packit b099d7
        XmRCallProc,
Packit b099d7
        (XtPointer) _XmSetThickness
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
	XmNtraversalOn,
Packit b099d7
	XmCTraversalOn,
Packit b099d7
	XmRBoolean,
Packit b099d7
	sizeof(Boolean),
Packit b099d7
	XtOffsetOf( struct _XmPrimitiveRec, primitive.traversal_on),
Packit b099d7
	XmRImmediate,
Packit b099d7
	(XtPointer) True
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNhighlightThickness,
Packit b099d7
        XmCHighlightThickness,
Packit b099d7
        XmRHorizontalDimension,
Packit b099d7
        sizeof (Dimension),
Packit b099d7
        XtOffsetOf( struct _XmPrimitiveRec, primitive.highlight_thickness),
Packit b099d7
        XmRCallProc,
Packit b099d7
        (XtPointer) _XmSetThickness
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
 	XmNmarginWidth, 
Packit b099d7
	XmCMarginWidth, 
Packit b099d7
	XmRHorizontalDimension, 
Packit b099d7
	sizeof (Dimension),
Packit b099d7
	XtOffsetOf( struct _XmLabelRec, label.margin_width), 
Packit b099d7
	XmRImmediate,
Packit b099d7
	(XtPointer) XmINVALID_DIMENSION
Packit b099d7
    },
Packit b099d7
};       
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * static initialization of the cascade button widget class record, 
Packit b099d7
 * must do each field
Packit b099d7
 */
Packit b099d7
static XmBaseClassExtRec       cascadeBBaseClassExtRec = {
Packit b099d7
    NULL,                                     /* Next extension       */
Packit b099d7
    NULLQUARK,                                /* record type XmQmotif */
Packit b099d7
    XmBaseClassExtVersion,                    /* version              */
Packit b099d7
    sizeof(XmBaseClassExtRec),                /* size                 */
Packit b099d7
    InitializePrehook,                        /* initialize prehook   */
Packit b099d7
    SetValuesPrehook,			      /* set_values prehook   */
Packit b099d7
    InitializePosthook,                       /* initialize posthook  */
Packit b099d7
    XmInheritSetValuesPosthook,               /* set_values posthook  */
Packit b099d7
    XmInheritClass,                           /* secondary class      */
Packit b099d7
    XmInheritSecObjectCreate,                 /* creation proc        */
Packit b099d7
    XmInheritGetSecResData,                   /* getSecResData        */
Packit b099d7
    {0},                                      /* fast subclass        */
Packit b099d7
    XmInheritGetValuesPrehook,                /* get_values prehook   */
Packit b099d7
    XmInheritGetValuesPosthook,               /* get_values posthook  */
Packit b099d7
    NULL,                                     /* classPartInitPrehook */
Packit b099d7
    NULL,                                     /* classPartInitPosthook*/
Packit b099d7
    NULL,                                     /* ext_resources        */
Packit b099d7
    NULL,                                     /* compiled_ext_resources*/
Packit b099d7
    0,                                        /* num_ext_resources    */
Packit b099d7
    FALSE,                                    /* use_sub_resources    */
Packit b099d7
    XmInheritWidgetNavigable,                 /* widgetNavigable      */
Packit b099d7
    XmInheritFocusChange,                     /* focusChange          */
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
externaldef(xmcascadebuttonclassrec) XmCascadeButtonClassRec xmCascadeButtonClassRec = 
Packit b099d7
{
Packit b099d7
    {			/* core class record */
Packit b099d7
	(WidgetClass) &xmLabelClassRec,		/* superclass ptr	*/
Packit b099d7
	"XmCascadeButton",			/* class_name	*/
Packit b099d7
	sizeof (XmCascadeButtonWidgetRec),	/* size of Pulldown widget */
Packit b099d7
	ClassInitialize,			/* class init proc */
Packit b099d7
	ClassPartInitialize,			/* chained class init */
Packit b099d7
	FALSE,					/* class is not init'ed */
Packit b099d7
	Initialize,				/* widget init proc */
Packit b099d7
	NULL,					/* init_hook proc */
Packit b099d7
    	XtInheritRealize,       		/* widget realize proc */
Packit b099d7
    	action_table,				/* class action table */
Packit b099d7
    	XtNumber (action_table),
Packit b099d7
	resources,				/* this class's resource list*/
Packit b099d7
	XtNumber (resources),			/*  "	  " resource_count */
Packit b099d7
    	NULLQUARK,				/* xrm_class	        */
Packit b099d7
    	TRUE,					/* compress motion */
Packit b099d7
    	XtExposeCompressMaximal,		/* compress exposure */
Packit b099d7
	TRUE,					/* compress enter-leave */
Packit b099d7
   	FALSE,					/* no VisibilityNotify */
Packit b099d7
	Destroy,				/* class destroy proc */
Packit b099d7
	Resize,					/* class resize proc */
Packit b099d7
	Redisplay,				/* expose proc */
Packit b099d7
	SetValues,				/* set_value proc */
Packit b099d7
	NULL,					/* set_value_hook proc */
Packit b099d7
	XtInheritSetValuesAlmost,		/* set_value_almost proc */
Packit b099d7
	NULL,					/* get_values_hook */
Packit b099d7
	NULL,					/* class accept focus proc */
Packit b099d7
	XtVersion,				/* current version */
Packit b099d7
    	NULL,					/* callback offset list */
Packit b099d7
    	NULL,					/* default translation table */
Packit b099d7
						  /* this is manually set */
Packit b099d7
	XtInheritQueryGeometry,			/* query geo proc */
Packit b099d7
	NULL,				        /* display accelerator*/
Packit b099d7
	(XtPointer)&cascadeBBaseClassExtRec,	/* extension */
Packit b099d7
    },
Packit b099d7
	{
Packit b099d7
			/* Primitive Class record */
Packit b099d7
	BorderHighlight,			/* border_highlight */
Packit b099d7
	BorderUnhighlight,			/* border_uhighlight */
Packit b099d7
	XtInheritTranslations,		        /* translations */
Packit b099d7
	ArmAndActivate,				/* arm & activate */
Packit b099d7
	NULL,					/* get resources */
Packit b099d7
	0,					/* num get_resources */
Packit b099d7
	NULL,	                                /* extension */
Packit b099d7
	},
Packit b099d7
    {			/* Label Class record */
Packit b099d7
	XmInheritWidgetProc,		        /* set override callback */
Packit b099d7
	XmInheritMenuProc,		        /* menu procedures       */
Packit b099d7
	XtInheritTranslations,		        /* menu traversal xlation */
Packit b099d7
	NULL,					/* extension */
Packit b099d7
    },
Packit b099d7
    {			/* cascade_button class record */
Packit b099d7
        NULL,					/* extension */  
Packit b099d7
    }
Packit b099d7
};
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * now make a public symbol that points to this class record
Packit b099d7
 */
Packit b099d7
Packit b099d7
externaldef(xmcascadebuttonwidgetclass) WidgetClass xmCascadeButtonWidgetClass = (WidgetClass) &xmCascadeButtonClassRec;
Packit b099d7
Packit b099d7
/* Menu Savvy trait record */
Packit b099d7
static XmMenuSavvyTraitRec MenuSavvyRecord = {
Packit b099d7
    /* version: */
Packit b099d7
    -1,
Packit b099d7
    NULL,
Packit b099d7
    NULL,
Packit b099d7
    NULL,
Packit b099d7
    _XmCBNameActivate,
Packit b099d7
};
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * parse the translation tables for the different menutypes
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
ClassInitialize( void )
Packit b099d7
{
Packit b099d7
    menubar_events_parsed  = XtParseTranslationTable (menubar_events);
Packit b099d7
    p_events_parsed	   = XtParseTranslationTable (p_events);
Packit b099d7
	
Packit b099d7
   /* set up base class extension quark */
Packit b099d7
   cascadeBBaseClassExtRec.record_type = XmQmotif;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * set up fast subclassing
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void 
Packit b099d7
ClassPartInitialize(
Packit b099d7
        WidgetClass wc )
Packit b099d7
{
Packit b099d7
  _XmFastSubclassInit (wc, XmCASCADE_BUTTON_BIT);
Packit b099d7
Packit b099d7
  /* Install the menu savvy trait record,  copying fields from XmLabel */
Packit b099d7
  _XmLabelCloneMenuSavvy (wc, &MenuSavvyRecord);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * The button is armed (does not pop up submenus).
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
BorderHighlight(
Packit b099d7
        Widget wid )
Packit b099d7
{
Packit b099d7
      Arm ((XmCascadeButtonWidget) wid);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * The button is disarmed (does not pop down submenus).
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
BorderUnhighlight(
Packit b099d7
        Widget wid )
Packit b099d7
{
Packit b099d7
    XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid;
Packit b099d7
    Boolean popdown;
Packit b099d7
Packit b099d7
    if (Lab_IsMenupane(cb) &&
Packit b099d7
	(((XmManagerWidget)XtParent(cb))->manager.active_child == wid) &&
Packit b099d7
	CB_Submenu(cb))
Packit b099d7
    {
Packit b099d7
	XmMenuShellWidget mshell =
Packit b099d7
	    (XmMenuShellWidget) XtParent(CB_Submenu(cb));
Packit b099d7
	
Packit b099d7
	if ((mshell->composite.children[0] == CB_Submenu(cb)) &&
Packit b099d7
	    (XmIsMenuShell(mshell)) &&
Packit b099d7
	    (mshell->shell.popped_up))
Packit b099d7
	{
Packit b099d7
	    popdown = True;
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	    popdown = False;
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
	popdown = False;
Packit b099d7
Packit b099d7
    Disarm ((XmCascadeButtonWidget) wid, popdown);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Draw the 3D shadow around the widget if its is armed.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
DrawShadow(
Packit b099d7
        register XmCascadeButtonWidget cb )
Packit b099d7
{
Packit b099d7
  XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay((Widget) cb));
Packit b099d7
  Boolean etched_in = dpy -> display.enable_etched_in_menu;
Packit b099d7
Packit b099d7
  if (CB_IsArmed(cb))
Packit b099d7
    {
Packit b099d7
      if (XtIsRealized((Widget)cb))
Packit b099d7
      {
Packit b099d7
	 XmeDrawShadows (XtDisplay (cb), XtWindow (cb),
Packit b099d7
			cb->primitive.top_shadow_GC,
Packit b099d7
			cb->primitive.bottom_shadow_GC,
Packit b099d7
			cb->primitive.highlight_thickness,
Packit b099d7
			cb->primitive.highlight_thickness,
Packit b099d7
			cb->core.width - 2 * 
Packit b099d7
			cb->primitive.highlight_thickness,
Packit b099d7
			cb->core.height - 2 * 
Packit b099d7
			cb->primitive.highlight_thickness,
Packit b099d7
			cb->primitive.shadow_thickness,
Packit b099d7
			etched_in ? XmSHADOW_IN : XmSHADOW_OUT);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static void 
Packit b099d7
DrawCascade(
Packit b099d7
        register XmCascadeButtonWidget cb )
Packit b099d7
{
Packit b099d7
   if ((CB_HasCascade(cb)) && (CB_Cascade_width(cb) != 0))
Packit b099d7
   {
Packit b099d7
      Pixmap pixmap ;
Packit b099d7
      int depth ;
Packit b099d7
Packit b099d7
      pixmap = CB_IsArmed(cb) && 
Packit b099d7
	  (CB_ArmedPixmap(cb) != XmUNSPECIFIED_PIXMAP) ? 
Packit b099d7
	      CB_ArmedPixmap(cb) : CB_CascadePixmap(cb) ;
Packit b099d7
Packit b099d7
      XmeGetPixmapData(XtScreen(cb),
Packit b099d7
		       pixmap,
Packit b099d7
		       NULL,    
Packit b099d7
		       &depth,
Packit b099d7
		       NULL, NULL,
Packit b099d7
		       NULL, NULL,
Packit b099d7
		       NULL, NULL); 
Packit b099d7
Packit b099d7
      if (depth == cb->core.depth)
Packit b099d7
	  XCopyArea (XtDisplay(cb), 
Packit b099d7
		     pixmap, 
Packit b099d7
		     XtWindow(cb),
Packit b099d7
		     cb->label.normal_GC, 0, 0, 
Packit b099d7
		     CB_Cascade_width(cb), CB_Cascade_height(cb),
Packit b099d7
		     CB_Cascade_x(cb), CB_Cascade_y(cb));
Packit b099d7
      else 
Packit b099d7
      if (depth == 1) 
Packit b099d7
	  XCopyPlane (XtDisplay(cb), 
Packit b099d7
		      pixmap, 
Packit b099d7
		      XtWindow(cb),
Packit b099d7
		      cb->label.normal_GC, 0, 0, 
Packit b099d7
		      CB_Cascade_width(cb), CB_Cascade_height(cb),
Packit b099d7
		      CB_Cascade_x(cb), CB_Cascade_y(cb), 1);
Packit b099d7
  
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * redisplay the widget
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Redisplay(
Packit b099d7
        register Widget cb,
Packit b099d7
        XEvent *event,
Packit b099d7
        Region region )
Packit b099d7
{
Packit b099d7
#ifdef FIX_1395
Packit b099d7
    Pixel tmpc;
Packit b099d7
#endif
Packit b099d7
    if (XtIsRealized (cb)) 
Packit b099d7
    {
Packit b099d7
	XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(cb));
Packit b099d7
	Boolean etched_in = dpy->display.enable_etched_in_menu;
Packit b099d7
	GC tmpGC = NULL;
Packit b099d7
	XtExposeProc expose;
Packit b099d7
Packit b099d7
	if (etched_in) {
Packit b099d7
#ifdef FIX_1509
Packit b099d7
		if (CB_IsArmed(cb))
Packit b099d7
		    XFillRectangle(XtDisplay(cb), XtWindow(cb), CB_ArmGC(cb),
Packit b099d7
				   0, 0, cb->core.width, cb->core.height);
Packit b099d7
		else
Packit b099d7
	        XClearArea(XtDisplay(cb), XtWindow(cb),
Packit b099d7
				0, 0, cb->core.width, cb->core.height, False);
Packit b099d7
#else
Packit b099d7
	    XFillRectangle(XtDisplay(cb), XtWindow(cb),
Packit b099d7
		           CB_IsArmed(cb) ? CB_ArmGC(cb) : CB_BackgroundGC(cb),
Packit b099d7
			   0, 0, cb->core.width, cb->core.height);
Packit b099d7
#endif
Packit b099d7
#ifdef USE_XFT
Packit b099d7
	} else if (Lab_MenuType(cb) != XmWORK_AREA) { /* adeed with XFT support */
Packit b099d7
        XClearArea(XtDisplay(cb), XtWindow(cb),
Packit b099d7
			0, 0, cb->core.width, cb->core.height, False);
Packit b099d7
#endif
Packit b099d7
	}
Packit b099d7
	if (etched_in && CB_IsArmed(cb)) {
Packit b099d7
	    Pixel junk, select_pix;
Packit b099d7
	    Boolean replaceGC = False;
Packit b099d7
Packit b099d7
	    XmGetColors(XtScreen(cb), cb->core.colormap,
Packit b099d7
			cb->core.background_pixel,
Packit b099d7
			&junk, &junk, &junk, &select_pix);
Packit b099d7
Packit b099d7
	    if (select_pix == 
Packit b099d7
		((XmCascadeButtonWidget)cb)->primitive.foreground) {
Packit b099d7
		replaceGC = True;
Packit b099d7
		tmpGC = ((XmCascadeButtonWidget)cb)->label.normal_GC;
Packit b099d7
		((XmCascadeButtonWidget)cb)->label.normal_GC = 
Packit b099d7
		    CB_BackgroundGC(cb);
Packit b099d7
	    }
Packit b099d7
#ifdef FIX_1395
Packit b099d7
	    /* 1395:
Packit b099d7
	     By default (if not etched and not armed) window (widget) have 
Packit b099d7
	     background color that used to draw widget bg. When widget is 
Packit b099d7
	     etched, background selected correctly (as selected color), 
Packit b099d7
	     but label exposr method will use default background color 
Packit b099d7
	     to fill area bellow lable text. Result is ugly menus.
Packit b099d7
	     We should replace colors before expose from label
Packit b099d7
	     and change it back after repainting.
Packit b099d7
	    */
Packit b099d7
            tmpc = cb->core.background_pixel;
Packit b099d7
            XSetWindowBackground(XtDisplay(cb), XtWindow(cb), select_pix);
Packit b099d7
#endif
Packit b099d7
Packit b099d7
	    _XmProcessLock();
Packit b099d7
	    expose = xmLabelClassRec.core_class.expose;
Packit b099d7
	    _XmProcessUnlock();
Packit b099d7
	    (*expose)((Widget) cb, event, region);
Packit b099d7
#ifdef FIX_1395
Packit b099d7
	    /*
Packit b099d7
	     Set correct window background (label is repainted, role back)
Packit b099d7
	    */
Packit b099d7
	    XSetWindowBackground(XtDisplay(cb), XtWindow(cb), tmpc);
Packit b099d7
	    if (cb->core.background_pixmap != XmUNSPECIFIED_PIXMAP)
Packit b099d7
	    	XSetWindowBackgroundPixmap(XtDisplay(cb), XtWindow(cb),
Packit b099d7
	    			cb->core.background_pixmap);
Packit b099d7
#endif
Packit b099d7
Packit b099d7
	    if (replaceGC)
Packit b099d7
		((XmCascadeButtonWidget)cb)->label.normal_GC = tmpGC;
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
	
Packit b099d7
	    /* Label class does most of the work */
Packit b099d7
Packit b099d7
	    _XmProcessLock();
Packit b099d7
	    expose = xmLabelClassRec.core_class.expose;
Packit b099d7
	    _XmProcessUnlock();
Packit b099d7
	    (*expose)(cb, event, region);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	DrawCascade((XmCascadeButtonWidget) cb);
Packit b099d7
	DrawShadow ((XmCascadeButtonWidget) cb);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Arming the cascadebutton consists of setting the armed bit
Packit b099d7
 * and drawing the 3D shadow.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Arm(
Packit b099d7
        register XmCascadeButtonWidget cb )
Packit b099d7
{
Packit b099d7
  if (!CB_IsArmed(cb))
Packit b099d7
    {
Packit b099d7
      XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(cb));
Packit b099d7
      Boolean etched_in = dpy->display.enable_etched_in_menu;
Packit b099d7
      
Packit b099d7
      CB_SetArmed(cb, TRUE);
Packit b099d7
Packit b099d7
      if (etched_in) 
Packit b099d7
	  Redisplay((Widget) cb, NULL, NULL);
Packit b099d7
      else {
Packit b099d7
	  DrawCascade(cb);
Packit b099d7
	  DrawShadow (cb);
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
Packit b099d7
  XmProcessTraversal((Widget) cb, XmTRAVERSE_CURRENT);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Post the submenu and then arm the button.  The arming is done
Packit b099d7
 * second so that the post can be quickly as possible.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
ArmAndPost(
Packit b099d7
        XmCascadeButtonWidget cb,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
   if (!CB_IsArmed(cb))
Packit b099d7
   {
Packit b099d7
      _XmCascadingPopup ((Widget) cb, event, TRUE);
Packit b099d7
      Arm (cb);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * class function to cause the cascade button to be armed and selected
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
ArmAndActivate(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *params,		/* unused */
Packit b099d7
        Cardinal *num_params )	/* unused */
Packit b099d7
{
Packit b099d7
    XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
    XmRowColumnWidget parent = (XmRowColumnWidget) XtParent(cb);
Packit b099d7
    XmMenuSystemTrait menuSTrait;
Packit b099d7
    Time _time;
Packit b099d7
Packit b099d7
    /* check if event has been processed  - if it's NULL, override processing */
Packit b099d7
    if (event && !_XmIsEventUnique(event))
Packit b099d7
       return;
Packit b099d7
Packit b099d7
    _time = _XmGetDefaultTime(wid, event);
Packit b099d7
Packit b099d7
    menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
      XmeTraitGet((XtPointer) XtClass(XtParent(wid)), XmQTmenuSystem);
Packit b099d7
Packit b099d7
    if (menuSTrait == NULL) {
Packit b099d7
      /* We're in trouble.  This isn't a valid menu that we're 
Packit b099d7
	 in and Arm and Activate has been called.  Abort ! */
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    switch (Lab_MenuType (cb))
Packit b099d7
    {
Packit b099d7
       case XmMENU_BAR:
Packit b099d7
       {
Packit b099d7
          ShellWidget myShell = NULL;
Packit b099d7
Packit b099d7
          /* Shared menupanes require some additional checks */
Packit b099d7
          if (CB_Submenu(cb))
Packit b099d7
              myShell = (ShellWidget)XtParent(CB_Submenu(cb));
Packit b099d7
Packit b099d7
          if (myShell && 
Packit b099d7
	      XmIsMenuShell(myShell) &&         /* not torn ?! */
Packit b099d7
	      (myShell->shell.popped_up) &&
Packit b099d7
	      (myShell->composite.children[0] == CB_Submenu(cb)) &&
Packit b099d7
	      (cb == (XmCascadeButtonWidget)RC_CascadeBtn(CB_Submenu(cb))))
Packit b099d7
          {
Packit b099d7
	     menuSTrait -> popdown((Widget) parent, event);
Packit b099d7
	     Disarm (cb, FALSE);
Packit b099d7
	  }
Packit b099d7
          else 
Packit b099d7
          {
Packit b099d7
             /* call the cascading callbacks first thing */
Packit b099d7
             Cascading ((Widget) cb, event);
Packit b099d7
Packit b099d7
	     /*
Packit b099d7
	      * check if the traversing flag is set true.  This indicates
Packit b099d7
	      * that we are in a traverse and don't want to activate if
Packit b099d7
	      * there is no submenu attached.  Set during KDown in menubar.
Packit b099d7
	      */
Packit b099d7
	     if (CB_Traversing(cb) && !CB_Submenu(cb))
Packit b099d7
		 return;
Packit b099d7
Packit b099d7
             if (! RC_IsArmed (parent))
Packit b099d7
	     {
Packit b099d7
		_XmMenuFocus((Widget) parent, XmMENU_BEGIN, _time);
Packit b099d7
Packit b099d7
		menuSTrait -> arm((Widget) cb);
Packit b099d7
	     }
Packit b099d7
             else
Packit b099d7
	       menuSTrait -> menuBarCleanup((Widget) parent);
Packit b099d7
Packit b099d7
             /* do the select without calling the cascading callbacks again */
Packit b099d7
             Select (cb, event, FALSE);
Packit b099d7
Packit b099d7
	     /* To support menu replay, keep the pointer in sync mode */
Packit b099d7
	     XAllowEvents(XtDisplay(cb), SyncPointer, CurrentTime);
Packit b099d7
Packit b099d7
             if (CB_Submenu(cb))
Packit b099d7
             {
Packit b099d7
                /*
Packit b099d7
                 * if XmProcessTraversal() fails, it's possible that the pane
Packit b099d7
                 * has no traversable children, so reset the focus to the pane.
Packit b099d7
                 */
Packit b099d7
                if (!XmProcessTraversal(CB_Submenu(cb), XmTRAVERSE_CURRENT))
Packit b099d7
		{
Packit b099d7
		   /* Must clear focus path first for shared menushells.
Packit b099d7
		    * Otherwise, moving the focus back will have old stale
Packit b099d7
		    * (old) focus_item.
Packit b099d7
		    */
Packit b099d7
		   _XmClearFocusPath(CB_Submenu(cb));
Packit b099d7
                   XtSetKeyboardFocus(XtParent(CB_Submenu(cb)), CB_Submenu(cb));
Packit b099d7
		}
Packit b099d7
             }
Packit b099d7
             else
Packit b099d7
             {
Packit b099d7
	        menuSTrait -> disarm((Widget) parent);
Packit b099d7
		_XmMenuFocus(XtParent(cb), XmMENU_END, _time);
Packit b099d7
                XtUngrabPointer( (Widget) cb, _time);
Packit b099d7
             }
Packit b099d7
          }
Packit b099d7
	  
Packit b099d7
          break;
Packit b099d7
       }
Packit b099d7
Packit b099d7
       case XmMENU_PULLDOWN:
Packit b099d7
       case XmMENU_POPUP:
Packit b099d7
       {
Packit b099d7
	  /* In case the tear off is active but not armed or grabbed */
Packit b099d7
	  menuSTrait -> tearOffArm((Widget) parent);
Packit b099d7
          Select (cb, event, TRUE);
Packit b099d7
	  if (CB_Submenu(cb))
Packit b099d7
	  {
Packit b099d7
             /*
Packit b099d7
              * if XmProcessTraversal() fails, it's possible that the pane
Packit b099d7
              * has no traversable children, so reset the focus to the pane.
Packit b099d7
              */
Packit b099d7
             if (!XmProcessTraversal(CB_Submenu(cb), XmTRAVERSE_CURRENT))
Packit b099d7
	     {
Packit b099d7
		/* Must clear focus path first for shared menushells.
Packit b099d7
		 * Otherwise, moving the focus back will have old stale
Packit b099d7
		 * (old) focus_item.
Packit b099d7
		 */
Packit b099d7
		_XmClearFocusPath(CB_Submenu(cb));
Packit b099d7
                XtSetKeyboardFocus(XtParent(CB_Submenu(cb)), CB_Submenu(cb));
Packit b099d7
	     }
Packit b099d7
	  }
Packit b099d7
          break;
Packit b099d7
       }
Packit b099d7
    }
Packit b099d7
    /* Record so spring loaded DispatchEvent() doesn't recall this routine.  */
Packit b099d7
    if (event)
Packit b099d7
       _XmRecordEvent(event);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * disarm the menu.  This may include popping down any submenu that is up or
Packit b099d7
 * removing the timeout to post a submenu
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Disarm(
Packit b099d7
        register XmCascadeButtonWidget cb,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int unpost )
Packit b099d7
#else
Packit b099d7
        Boolean unpost )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   Widget rowcol = XtParent (cb);
Packit b099d7
Packit b099d7
   if (CB_IsArmed(cb))
Packit b099d7
   {
Packit b099d7
      CB_SetArmed(cb, FALSE);
Packit b099d7
Packit b099d7
      /* popdown any posted submenus */
Packit b099d7
      if (unpost && RC_PopupPosted(rowcol))
Packit b099d7
      {
Packit b099d7
	  (*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
Packit b099d7
	     menu_shell_class.popdownEveryone))(RC_PopupPosted(rowcol),NULL,
Packit b099d7
						NULL, NULL);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      /* if a delayed arm is pending, remove it */
Packit b099d7
      if (cb->cascade_button.timer)
Packit b099d7
      {
Packit b099d7
         XtRemoveTimeOut (cb->cascade_button.timer);
Packit b099d7
         cb->cascade_button.timer = 0;
Packit b099d7
      }
Packit b099d7
Packit b099d7
      /* if the shadow is drawn and the menupane is not going down, erase it */
Packit b099d7
      if ((! RC_PoppingDown(rowcol)) || RC_TornOff(rowcol))
Packit b099d7
      {
Packit b099d7
	 if (XtIsRealized ((Widget)cb))
Packit b099d7
	 {
Packit b099d7
	     /* etched in menu button */
Packit b099d7
	     XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(cb));
Packit b099d7
	     Boolean etched_in = dpy->display.enable_etched_in_menu;
Packit b099d7
Packit b099d7
	     if (etched_in) 
Packit b099d7
		 Redisplay((Widget) cb, NULL, NULL);
Packit b099d7
	     else
Packit b099d7
		 XmeClearBorder (XtDisplay (cb), XtWindow (cb),
Packit b099d7
				 cb->primitive.highlight_thickness,
Packit b099d7
				 cb->primitive.highlight_thickness,
Packit b099d7
				 cb->core.width - 2 * 
Packit b099d7
				 cb->primitive.highlight_thickness,
Packit b099d7
				 cb->core.height - 2 * 
Packit b099d7
				 cb->primitive.highlight_thickness,
Packit b099d7
				 cb->primitive.shadow_thickness);
Packit b099d7
	 }
Packit b099d7
      }
Packit b099d7
      DrawCascade(cb);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * called when the post delay timeout occurs.
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
PostTimeout(
Packit b099d7
        XtPointer closure,
Packit b099d7
        XtIntervalId *id)	/* unused */
Packit b099d7
{
Packit b099d7
        XmCascadeButtonWidget cb = (XmCascadeButtonWidget) closure ;
Packit b099d7
Packit b099d7
   if (cb->cascade_button.timer)
Packit b099d7
   {
Packit b099d7
      cb->cascade_button.timer = 0;
Packit b099d7
    
Packit b099d7
      _XmCascadingPopup ((Widget) cb, NULL, TRUE);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * set the timer to post the submenu if a leave event does
Packit b099d7
 * not occur first.
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
DelayedArm(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
        XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
   if ((! CB_IsArmed(cb)) &&
Packit b099d7
       (((XmMenuShellWidget) XtParent(XtParent(cb)))->shell.popped_up) &&
Packit b099d7
       _XmGetInDragMode((Widget) cb))
Packit b099d7
   {
Packit b099d7
      if (cb->cascade_button.map_delay <= 0)
Packit b099d7
	 ArmAndPost (cb, event);
Packit b099d7
  
Packit b099d7
      else
Packit b099d7
      {
Packit b099d7
 	 /* To fix CR 8172,  the following two lines were reversed.  
Packit b099d7
	    Because calling Arm seems to cause a focus change (temporary)
Packit b099d7
	    out of the widget,  the timer was incorrectly removed and
Packit b099d7
	    the menu wouldn't post. */
Packit b099d7
         Arm(cb);
Packit b099d7
         cb->cascade_button.timer = 
Packit b099d7
               XtAppAddTimeOut(XtWidgetToApplicationContext( (Widget) cb), 
Packit b099d7
			       (unsigned long) cb->cascade_button.map_delay,
Packit b099d7
                                                 PostTimeout, (XtPointer) cb) ;
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * if traversal is not on and the mouse
Packit b099d7
 * has not entered its cascading submenu, disarm the
Packit b099d7
 * cascadebutton.
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
CheckDisarm(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
   XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
   register XmMenuShellWidget submenushell;
Packit b099d7
   XEnterWindowEvent * entEvent = (XEnterWindowEvent *) event;
Packit b099d7
Packit b099d7
   if (_XmGetInDragMode((Widget) cb) &&
Packit b099d7
       (/* !ActiveTearOff || */ event->xcrossing.mode == NotifyNormal))
Packit b099d7
   {
Packit b099d7
      if ((CB_IsArmed(cb)) && 
Packit b099d7
          (CB_Submenu(cb)))
Packit b099d7
      {
Packit b099d7
         submenushell = (XmMenuShellWidget) XtParent (CB_Submenu(cb));
Packit b099d7
   
Packit b099d7
         if (submenushell->shell.popped_up)
Packit b099d7
         {
Packit b099d7
            if ((entEvent->x_root >= submenushell->core.x) &&
Packit b099d7
                (entEvent->x_root <  submenushell->core.x + 
Packit b099d7
                                     submenushell->core.width +
Packit b099d7
                                     (submenushell->core.border_width << 1)) &&
Packit b099d7
                (entEvent->y_root >= submenushell->core.y) &&
Packit b099d7
                (entEvent->y_root <  submenushell->core.y + 
Packit b099d7
                                     submenushell->core.height +
Packit b099d7
	   			     (submenushell->core.border_width << 1)))
Packit b099d7
Packit b099d7
  	        /* then we are in the cascading submenu, don't disarm */
Packit b099d7
 	        return;
Packit b099d7
Packit b099d7
             /*
Packit b099d7
              * When kick-starting a cascading menu from a tear off, we grab
Packit b099d7
              * the pointer to the parent rc when the cascade has the focus
Packit b099d7
              * (In StartDrag().  A leave window event is generated (with
Packit b099d7
              * mode = NotifyGrab) which we don't wish to recognize.
Packit b099d7
              */
Packit b099d7
             if ((entEvent->mode == NotifyGrab) &&
Packit b099d7
                 !XmIsMenuShell(XtParent(XtParent(cb))))
Packit b099d7
                return;
Packit b099d7
         }
Packit b099d7
      }
Packit b099d7
      Disarm (cb, TRUE);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * post submenu and disable menu's traversal.  The order of these 
Packit b099d7
 * function calls is critical.
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
StartDrag(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
   XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
   Boolean validButton;
Packit b099d7
   XmRowColumnWidget parent = (XmRowColumnWidget)XtParent(cb);
Packit b099d7
   XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
   menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
     XmeTraitGet((XtPointer) XtClass((Widget) parent), XmQTmenuSystem);
Packit b099d7
Packit b099d7
   /* If no menu system trait then parent isn't a menu as it
Packit b099d7
      should be */
Packit b099d7
   if (menuSTrait == NULL) return;
Packit b099d7
Packit b099d7
   /* Start with posted submenu bit reset */
Packit b099d7
   CB_SetWasPosted(cb, FALSE);
Packit b099d7
Packit b099d7
   if (CB_Submenu(cb) &&
Packit b099d7
       RC_IsArmed ((XmRowColumnWidget) CB_Submenu(cb))) {
Packit b099d7
     CB_SetWasPosted(cb, TRUE);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * make sure the shell is popped up, this takes care of a corner case
Packit b099d7
    * that can occur with rapid pressing of the mouse button
Packit b099d7
    */
Packit b099d7
   if (Lab_IsMenupane(cb) &&
Packit b099d7
       (!((XmMenuShellWidget) XtParent(parent))->shell.popped_up))
Packit b099d7
   {
Packit b099d7
      /* To support menu replay, keep the pointer in sync mode */
Packit b099d7
      XAllowEvents(XtDisplay(cb), SyncPointer, CurrentTime);
Packit b099d7
Packit b099d7
      return;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   validButton = menuSTrait -> verifyButton((Widget) parent, event);
Packit b099d7
   
Packit b099d7
   if (validButton)
Packit b099d7
   {
Packit b099d7
      /* In case the tear off is active but not armed or grabbed */
Packit b099d7
      menuSTrait -> tearOffArm((Widget) parent);
Packit b099d7
Packit b099d7
      _XmSetInDragMode((Widget) cb, True);
Packit b099d7
Packit b099d7
      _XmCascadingPopup ((Widget) cb, event, TRUE);
Packit b099d7
      Arm (cb);
Packit b099d7
Packit b099d7
      /* record event so MenuShell does not process it */
Packit b099d7
      _XmRecordEvent (event);
Packit b099d7
   } 
Packit b099d7
Packit b099d7
   /* To support menu replay, keep the pointer in sync mode */
Packit b099d7
   XAllowEvents(XtDisplay(cb), SyncPointer, CurrentTime);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * do the popup (either w/ or w/o the cascade callbacks).
Packit b099d7
 * If there is not a submenu, bring down the menu system.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Select(
Packit b099d7
        register XmCascadeButtonWidget cb,
Packit b099d7
        XEvent *event,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int doCascade )
Packit b099d7
#else
Packit b099d7
        Boolean doCascade )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   XmAnyCallbackStruct cback;
Packit b099d7
   XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
   menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
     XmeTraitGet((XtPointer) XtClass(XtParent(cb)), XmQTmenuSystem);
Packit b099d7
   if (menuSTrait == NULL) return;
Packit b099d7
Packit b099d7
   if (CB_WasPosted(cb)) {
Packit b099d7
     Disarm(cb, TRUE);
Packit b099d7
     if ((CB_Submenu(cb) != NULL) && (Lab_MenuType(cb) == XmMENU_BAR))
Packit b099d7
       _XmMenuPopDown(XtParent((Widget) cb), event, NULL);
Packit b099d7
     return;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   _XmCascadingPopup ((Widget) cb, event, doCascade);
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * check if there is a submenu here in case this changed during 
Packit b099d7
    * the cascading callbacks
Packit b099d7
    */
Packit b099d7
   if (CB_Submenu(cb) == NULL)
Packit b099d7
   {
Packit b099d7
      menuSTrait -> popdown(XtParent(cb), event);
Packit b099d7
Packit b099d7
      Disarm (cb, FALSE);
Packit b099d7
Packit b099d7
      menuSTrait -> disarm(XtParent(cb));
Packit b099d7
Packit b099d7
      cback.event = event;
Packit b099d7
      cback.reason = XmCR_ACTIVATE;
Packit b099d7
Packit b099d7
      if (menuSTrait != NULL)
Packit b099d7
      {
Packit b099d7
	menuSTrait -> entryCallback(XtParent(cb), (Widget) cb, &cback);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      if ((! cb->label.skipCallback) &&
Packit b099d7
	  (cb->cascade_button.activate_callback))
Packit b099d7
      {
Packit b099d7
      
Packit b099d7
	XtCallCallbackList ((Widget) cb, cb->cascade_button.activate_callback, &cback);
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
   else
Packit b099d7
     {
Packit b099d7
       Arm(cb);
Packit b099d7
     }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * if there is a submenu, enable traversal.
Packit b099d7
 * call select to do the work
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
DoSelect(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
   register XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
   Boolean validButton;
Packit b099d7
   XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
   menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
     XmeTraitGet((XtPointer) XtClass(XtParent(wid)), XmQTmenuSystem);
Packit b099d7
   if (menuSTrait == NULL) return;
Packit b099d7
   
Packit b099d7
   /* To support menu replay, keep the pointer in sync mode */
Packit b099d7
   XAllowEvents(XtDisplay(cb), SyncPointer, CurrentTime);
Packit b099d7
Packit b099d7
   if (event && event -> type == ButtonRelease &&
Packit b099d7
       event -> xbutton.button == 2)
Packit b099d7
     return;
Packit b099d7
Packit b099d7
   if (!CB_IsArmed(cb))
Packit b099d7
      return;
Packit b099d7
Packit b099d7
   if ((Lab_MenuType(cb) == XmMENU_BAR) && !RC_IsArmed (XtParent(cb)))
Packit b099d7
      return;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * make sure the shell is popped up, this takes care of a corner case
Packit b099d7
    * that can occur with rapid pressing of the mouse button
Packit b099d7
    */
Packit b099d7
   if (Lab_IsMenupane(cb) &&
Packit b099d7
       (!((XmMenuShellWidget) XtParent(XtParent(cb)))->shell.popped_up))
Packit b099d7
   {
Packit b099d7
      return;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   validButton = menuSTrait -> verifyButton(XtParent(cb), event);
Packit b099d7
   
Packit b099d7
   if (validButton)
Packit b099d7
   {
Packit b099d7
      Select (cb, event, (Boolean)(CB_Submenu(cb) != NULL));
Packit b099d7
Packit b099d7
      /* don't let the menu shell widget process this event */
Packit b099d7
      _XmRecordEvent (event);
Packit b099d7
Packit b099d7
      _XmSetInDragMode((Widget) cb, False);
Packit b099d7
Packit b099d7
      if (CB_Submenu(cb))
Packit b099d7
      {
Packit b099d7
         /*
Packit b099d7
          * if XmProcessTraversal() fails, it's possible that the pane
Packit b099d7
          * has no traversable children, so reset the focus to the pane.
Packit b099d7
          */
Packit b099d7
         if (!XmProcessTraversal(CB_Submenu(cb), XmTRAVERSE_CURRENT))
Packit b099d7
	 {
Packit b099d7
	    /* Must clear focus path first for shared menushells.
Packit b099d7
	     * Otherwise, moving the focus back will have old stale
Packit b099d7
	     * (old) focus_item.
Packit b099d7
	     */
Packit b099d7
	    _XmClearFocusPath(CB_Submenu(cb));
Packit b099d7
            XtSetKeyboardFocus(XtParent(CB_Submenu(cb)), CB_Submenu(cb));
Packit b099d7
	 }
Packit b099d7
      }
Packit b099d7
      else
Packit b099d7
      {
Packit b099d7
	 /* Move this call into Select().
Packit b099d7
	  *
Packit b099d7
	  * (* xmLabelClassRec.label_class.menuProcs) (XmMENU_DISARM,
Packit b099d7
	  *					    XtParent(cb));
Packit b099d7
	  */
Packit b099d7
Packit b099d7
         if (Lab_MenuType(cb) == XmMENU_BAR)
Packit b099d7
         {
Packit b099d7
	    _XmMenuFocus(XtParent(cb), XmMENU_END, CurrentTime);
Packit b099d7
            XtUngrabPointer( (Widget) cb, CurrentTime);
Packit b099d7
         }
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * if the menu system traversal is enabled, do a select
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
KeySelect(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
   XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
Packit b099d7
   if (!_XmGetInDragMode((Widget) cb) && 
Packit b099d7
       (RC_IsArmed(XtParent(cb)) ||
Packit b099d7
	(RC_Type(XtParent(cb)) != XmMENU_BAR &&
Packit b099d7
	 !XmIsMenuShell(XtParent(XtParent(cb))))))
Packit b099d7
      (* (((XmCascadeButtonClassRec *)(cb->core.widget_class))->
Packit b099d7
		primitive_class.arm_and_activate))
Packit b099d7
			((Widget) cb, event, NULL, NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * If the menu system is not active, arm it and arm this cascadebutton
Packit b099d7
 * else start the drag mode
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
MenuBarSelect(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
   XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
   Boolean validButton;
Packit b099d7
   Time _time = _XmGetDefaultTime(wid, event);
Packit b099d7
   XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
   menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
     XmeTraitGet((XtPointer) XtClass(XtParent(wid)), XmQTmenuSystem);
Packit b099d7
   if (menuSTrait == NULL) return;
Packit b099d7
Packit b099d7
   CB_SetWasPosted(cb, FALSE);
Packit b099d7
Packit b099d7
   if (RC_IsArmed ((XmRowColumnWidget) XtParent(cb)))
Packit b099d7
   {
Packit b099d7
      /* Cleanup the PM menubar mode, if enabled */
Packit b099d7
      menuSTrait -> menuBarCleanup(XtParent(cb));
Packit b099d7
Packit b099d7
      if (!CB_Submenu(cb))
Packit b099d7
      {
Packit b099d7
	 _XmMenuFocus(XtParent(cb), XmMENU_MIDDLE, _time);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      StartDrag ((Widget) cb, event, param, num_param);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      /* XAllowEvents() is called here because StartDrag also calls it */
Packit b099d7
      /* To support menu replay, keep the pointer in sync mode */
Packit b099d7
      XAllowEvents(XtDisplay(cb), SyncPointer, CurrentTime);
Packit b099d7
Packit b099d7
      validButton = menuSTrait -> verifyButton(XtParent(cb), event);
Packit b099d7
   
Packit b099d7
      if (validButton)
Packit b099d7
      {
Packit b099d7
         /*
Packit b099d7
         * Don't post the menu if the menu cannot control grabs!
Packit b099d7
         */
Packit b099d7
Packit b099d7
	 if (_XmMenuGrabKeyboardAndPointer(XtParent(cb), _time) != GrabSuccess)
Packit b099d7
         {
Packit b099d7
	     _XmRecordEvent (event);
Packit b099d7
	     return;
Packit b099d7
	 }
Packit b099d7
Packit b099d7
	 _XmMenuFocus(XtParent(cb), XmMENU_BEGIN, _time);
Packit b099d7
Packit b099d7
	 menuSTrait -> arm((Widget) cb);
Packit b099d7
Packit b099d7
         _XmSetInDragMode((Widget) cb, True);
Packit b099d7
Packit b099d7
         _XmCascadingPopup ((Widget) cb, event, TRUE);
Packit b099d7
Packit b099d7
	 if (!CB_Submenu(cb))
Packit b099d7
	 {  
Packit b099d7
	    /*
Packit b099d7
	     * since no submenu is posted, check if the grab has occured
Packit b099d7
	     * and if not, do the pointer grab now.
Packit b099d7
	     */
Packit b099d7
	    if (RC_BeingArmed(XtParent(cb)))
Packit b099d7
	    {
Packit b099d7
Packit b099d7
               _XmGrabPointer(XtParent(cb), True, EVENTS,
Packit b099d7
                  GrabModeAsync, GrabModeAsync, None, 
Packit b099d7
		  XmGetMenuCursor(XtDisplay(cb)), _time);
Packit b099d7
Packit b099d7
	       RC_SetBeingArmed(XtParent(cb), False);
Packit b099d7
	    }
Packit b099d7
	 }
Packit b099d7
Packit b099d7
          /* To support menu replay, keep the pointer in sync mode */
Packit b099d7
          XAllowEvents(XtDisplay(cb), SyncPointer, CurrentTime);
Packit b099d7
Packit b099d7
	 /* record so that menuShell doesn't process this event */
Packit b099d7
	 _XmRecordEvent (event);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/* 
Packit b099d7
 * If the menu is active, post submenu and arm.
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
MenuBarEnter(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
        register XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
   XmRowColumnWidget rc = (XmRowColumnWidget)XtParent(cb);
Packit b099d7
Packit b099d7
   if (RC_IsArmed(rc) && !CB_IsArmed(cb) && _XmGetInDragMode((Widget) cb))
Packit b099d7
   {
Packit b099d7
      if (!CB_Submenu(cb))
Packit b099d7
      {
Packit b099d7
	 _XmMenuFocus((Widget) rc, XmMENU_MIDDLE, 
Packit b099d7
		      _XmGetDefaultTime(wid, event));
Packit b099d7
      }
Packit b099d7
Packit b099d7
      _XmCascadingPopup ((Widget) cb, event, TRUE);
Packit b099d7
      Arm(cb);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * unless our submenu is posted or traversal is on, disarm
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
MenuBarLeave(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
   register XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
   XmMenuShellWidget submenuShell;
Packit b099d7
Packit b099d7
   if (RC_IsArmed (XtParent (cb)))
Packit b099d7
   {
Packit b099d7
      /* Reset this bit so that we don't unpost if the user
Packit b099d7
	 reenters the cascade button */
Packit b099d7
      CB_SetWasPosted(cb, FALSE);
Packit b099d7
Packit b099d7
      if (CB_Submenu(cb))
Packit b099d7
      {
Packit b099d7
         submenuShell = (XmMenuShellWidget) XtParent(CB_Submenu(cb));
Packit b099d7
Packit b099d7
         if (submenuShell->shell.popped_up)
Packit b099d7
            return;
Packit b099d7
      }  
Packit b099d7
   
Packit b099d7
      if (_XmGetInDragMode((Widget) cb))
Packit b099d7
         Disarm (cb, TRUE);   
Packit b099d7
   }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Cleanup the menubar, if its in the PM traversal mode
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
CleanupMenuBar(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
        XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
    XmRowColumnWidget parent = (XmRowColumnWidget)XtParent(cb);
Packit b099d7
Packit b099d7
    if (RC_IsArmed(parent))
Packit b099d7
    {
Packit b099d7
        (* ((XmRowColumnWidgetClass) XtClass(parent))->
Packit b099d7
             row_column_class.armAndActivate) ( (Widget) parent,
Packit b099d7
                          (XEvent *) NULL, (String *) NULL, (Cardinal *) NULL);
Packit b099d7
	_XmRecordEvent(event);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * CascadeButton Widget and Gadget help routine - first bring down the
Packit b099d7
 * menu and then do the help callback.
Packit b099d7
 */
Packit b099d7
void 
Packit b099d7
_XmCBHelp(
Packit b099d7
        Widget w,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *params,
Packit b099d7
        Cardinal *num_params )
Packit b099d7
{
Packit b099d7
   XmRowColumnWidget parent = (XmRowColumnWidget) XtParent(w);
Packit b099d7
Packit b099d7
   if (RC_Type(parent) == XmMENU_BAR)
Packit b099d7
   {
Packit b099d7
      /* Cannot call CleanupMenubar() 'cause it calls _XmRecordEvent */
Packit b099d7
      if (RC_IsArmed(parent))
Packit b099d7
      {
Packit b099d7
	 (* ((XmRowColumnWidgetClass) XtClass(parent))->
Packit b099d7
	      row_column_class.armAndActivate) ( (Widget) parent,
Packit b099d7
			   (XEvent *) NULL, (String *) NULL, (Cardinal *) NULL);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else if ((RC_Type(parent) == XmMENU_PULLDOWN) ||
Packit b099d7
            (RC_Type(parent) == XmMENU_POPUP))
Packit b099d7
   {
Packit b099d7
      (*(((XmMenuShellClassRec *) xmMenuShellWidgetClass)->
Packit b099d7
          menu_shell_class.popdownDone)) (XtParent(parent), event,
Packit b099d7
                                                           params, num_params);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   if (XmIsGadget(w))
Packit b099d7
      _XmSocorro(w, event, params, num_params);
Packit b099d7
   else
Packit b099d7
      _XmPrimitiveHelp( w, event, params, num_params) ;
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * When moving between a shared menupane, we only want to unpost the
Packit b099d7
 * descendant panes, not the shared one.
Packit b099d7
 * We only need to check the first popup child, since the menushell
Packit b099d7
 * has always forced the popped up shell to be the first child.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
PopdownGrandChildren(
Packit b099d7
        XmRowColumnWidget rowcol )
Packit b099d7
{
Packit b099d7
   CompositeWidget menuShell;
Packit b099d7
Packit b099d7
   if ((menuShell = (CompositeWidget) RC_PopupPosted(rowcol)) == NULL)
Packit b099d7
       return;
Packit b099d7
Packit b099d7
   if ((menuShell = (CompositeWidget) 
Packit b099d7
	RC_PopupPosted (menuShell->composite.children[0])) != NULL)
Packit b099d7
   {
Packit b099d7
      (*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
Packit b099d7
	 menu_shell_class.popdownEveryone))( (Widget) menuShell, NULL,
Packit b099d7
                                                                   NULL, NULL);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * call the cascading callbacks.  The cb parameter can be either a 
Packit b099d7
 * cascadebutton widget or gadget.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Cascading(
Packit b099d7
        Widget w,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
    XmAnyCallbackStruct cback;
Packit b099d7
Packit b099d7
    cback.reason = XmCR_CASCADING;
Packit b099d7
    cback.event = event;
Packit b099d7
Packit b099d7
    if (XmIsCascadeButton(w))
Packit b099d7
    {
Packit b099d7
       XmCascadeButtonWidget cb = (XmCascadeButtonWidget)w;
Packit b099d7
       XmRowColumnWidget submenu = (XmRowColumnWidget) CB_Submenu(cb);
Packit b099d7
Packit b099d7
       /* if the submenu is already up, just return */
Packit b099d7
       /* In case of shared menupanes, check the cascade button attachment */
Packit b099d7
Packit b099d7
       if (submenu)
Packit b099d7
       {
Packit b099d7
           XmMenuShellWidget ms = (XmMenuShellWidget) XtParent(submenu);
Packit b099d7
	   if (XmIsMenuShell(ms) &&
Packit b099d7
	       ms->shell.popped_up &&
Packit b099d7
 	       ms->composite.children[0] == (Widget) submenu &&
Packit b099d7
 	       submenu->row_column.cascadeBtn == (Widget) cb)
Packit b099d7
           {
Packit b099d7
	      return;
Packit b099d7
           }
Packit b099d7
       } 
Packit b099d7
       XtCallCallbackList ((Widget) cb, cb->cascade_button.cascade_callback, &cback);
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
       XmCascadeButtonGadget cb = (XmCascadeButtonGadget)w;
Packit b099d7
       XmRowColumnWidget submenu = (XmRowColumnWidget) CBG_Submenu(cb);
Packit b099d7
Packit b099d7
       /* if the submenu is already up, just return */
Packit b099d7
       if (submenu)
Packit b099d7
       {	
Packit b099d7
           XmMenuShellWidget ms = (XmMenuShellWidget) XtParent(submenu);
Packit b099d7
	   if (XmIsMenuShell(ms) &&
Packit b099d7
	       ms->shell.popped_up &&
Packit b099d7
 	       ms->composite.children[0] == (Widget) submenu &&
Packit b099d7
 	       submenu->row_column.cascadeBtn == (Widget) cb)
Packit b099d7
           {
Packit b099d7
	      return;
Packit b099d7
           }
Packit b099d7
       }
Packit b099d7
       
Packit b099d7
       XtCallCallbackList ((Widget) cb, cb->cascade_button.cascade_callback, &cback);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * call the cascading callbacks and the popup any submenu.  This is called
Packit b099d7
 * by both the cascadebutton widget and gadget.
Packit b099d7
 */
Packit b099d7
void 
Packit b099d7
_XmCascadingPopup(
Packit b099d7
        Widget cb,
Packit b099d7
        XEvent *event,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int doCascade )
Packit b099d7
#else
Packit b099d7
        Boolean doCascade )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   /* We must make sure the tear off to menushell restoration/callbacks are
Packit b099d7
    * called before the cascading callback.  Exclude the pane in case Popup()
Packit b099d7
    * tries to restore it back to a transient if shared and already posted.
Packit b099d7
    */
Packit b099d7
   XmDisplay dd = (XmDisplay)XmGetXmDisplay(XtDisplay(cb));
Packit b099d7
   XmExcludedParentPaneRec *excPP =
Packit b099d7
		&(((XmDisplayInfo *)(dd->display.displayInfo))->excParentPane);
Packit b099d7
Packit b099d7
   if (!excPP->pane)
Packit b099d7
   {
Packit b099d7
      excPP->pane_list_size = 4;
Packit b099d7
      excPP->pane = (Widget *)XtMalloc(sizeof(Widget) * excPP->pane_list_size);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   if (XmIsCascadeButtonGadget(cb))
Packit b099d7
      *(excPP->pane) = CBG_Submenu(cb);
Packit b099d7
   else
Packit b099d7
      *(excPP->pane) = CB_Submenu(cb);
Packit b099d7
   
Packit b099d7
   if (*(excPP->pane))
Packit b099d7
   {
Packit b099d7
      excPP->num_panes = 1;
Packit b099d7
Packit b099d7
      if (RC_TornOff(*(excPP->pane)) &&
Packit b099d7
          !XmIsMenuShell(XtParent(*(excPP->pane))))
Packit b099d7
      {
Packit b099d7
 	 /* If a subpane is already posted and it is not the pane that
Packit b099d7
 	  * will be posted from cb.  Then it must be lowered so that
Packit b099d7
 	  * its tear off can be repainted.
Packit b099d7
 	  */
Packit b099d7
 	 if (RC_PopupPosted(XtParent(cb)))
Packit b099d7
 	 {
Packit b099d7
 	    XmRowColumnWidget postedPane = (XmRowColumnWidget)
Packit b099d7
 	       ((CompositeWidget)RC_PopupPosted(XtParent(cb)))->
Packit b099d7
 	          composite.children[0];
Packit b099d7
 
Packit b099d7
 	    if ((Widget)postedPane != *(excPP->pane))
Packit b099d7
 	    {
Packit b099d7
 	       _XmLowerTearOffObscuringPoppingDownPanes( (Widget)postedPane,
Packit b099d7
 		  *(excPP->pane));
Packit b099d7
 	    }
Packit b099d7
 	 }
Packit b099d7
	 _XmRestoreTearOffToMenuShell(*(excPP->pane), event);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
   
Packit b099d7
   if (doCascade)
Packit b099d7
       Cascading (cb, event);
Packit b099d7
   Popup (cb, event);
Packit b099d7
}
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * pop up the pulldown menu associated with this cascadebutton
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Popup(
Packit b099d7
        Widget cb,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
    Widget oldActiveChild;
Packit b099d7
    Boolean popped_up = False;
Packit b099d7
    register XmRowColumnWidget   submenu;
Packit b099d7
    XmMenuShellWidget shell = NULL;
Packit b099d7
    register XmRowColumnWidget	parent   = (XmRowColumnWidget) XtParent (cb);
Packit b099d7
    XmMenuSystemTrait menuSTrait;
Packit b099d7
    XmDisplay dd = (XmDisplay)XmGetXmDisplay(XtDisplay(cb));
Packit b099d7
    XmExcludedParentPaneRec *excPP =
Packit b099d7
		&(((XmDisplayInfo *)(dd->display.displayInfo))->excParentPane);
Packit b099d7
Packit b099d7
    menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
      XmeTraitGet((XtPointer) XtClass((Widget) parent), XmQTmenuSystem);
Packit b099d7
    if (menuSTrait == NULL) return;
Packit b099d7
Packit b099d7
    if (XmIsCascadeButtonGadget(cb))
Packit b099d7
       submenu = (XmRowColumnWidget) CBG_Submenu(cb);
Packit b099d7
    else
Packit b099d7
       submenu = (XmRowColumnWidget) CB_Submenu(cb);
Packit b099d7
Packit b099d7
    /* if its already up, popdown submenus and then return */
Packit b099d7
    if (submenu &&
Packit b099d7
	(shell = (XmMenuShellWidget)XtParent(submenu)) &&
Packit b099d7
	XmIsMenuShell(shell) &&
Packit b099d7
	(popped_up = shell->shell.popped_up))
Packit b099d7
    {
Packit b099d7
Packit b099d7
        /* Just in case the menu shell is being shared.
Packit b099d7
	 * Shell's 0th child is currently posted submenu.  In case of shared
Packit b099d7
	 * menupanes we must check to make sure that it is not posted from 
Packit b099d7
	 * the same cascade button before popping down.
Packit b099d7
	 * Also this is as good a time as any to clear have_traversal field
Packit b099d7
	 * of submenu's active child.  Updating this internal state allows
Packit b099d7
	 * this gadget to highlight next time the submenu is posted.
Packit b099d7
	 */
Packit b099d7
        if ((XmRowColumnWidget)shell->composite.children[0] == submenu) 
Packit b099d7
	{
Packit b099d7
	   if (cb == RC_CascadeBtn(submenu))
Packit b099d7
	   {
Packit b099d7
	       if (RC_PopupPosted(submenu))
Packit b099d7
		   (*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
Packit b099d7
		      menu_shell_class.popdownEveryone))
Packit b099d7
		       (RC_PopupPosted(submenu),NULL,NULL, NULL);
Packit b099d7
Packit b099d7
              if (submenu->manager.active_child)
Packit b099d7
              {
Packit b099d7
                 /* update visible focus/highlighting */
Packit b099d7
                 if (XmIsPrimitive(submenu->manager.active_child))
Packit b099d7
                 {
Packit b099d7
                     (*(((XmPrimitiveClassRec *)XtClass(submenu->manager.
Packit b099d7
                     active_child))->primitive_class.border_unhighlight))
Packit b099d7
                     (submenu->manager.active_child);
Packit b099d7
                 }
Packit b099d7
                 else if (XmIsGadget(submenu->manager.active_child))
Packit b099d7
                 {
Packit b099d7
                     (*(((XmGadgetClassRec *)XtClass(submenu->manager.
Packit b099d7
                     active_child))->gadget_class.border_unhighlight))
Packit b099d7
                     (submenu->manager.active_child);
Packit b099d7
                 }
Packit b099d7
                 /* update internal focus state */
Packit b099d7
                 _XmClearFocusPath((Widget) submenu);
Packit b099d7
              }
Packit b099d7
	      *(excPP->pane) = NULL;
Packit b099d7
	      excPP->num_panes = 0;
Packit b099d7
	      return;
Packit b099d7
	   }
Packit b099d7
	   else
Packit b099d7
	   {
Packit b099d7
	      oldActiveChild = submenu->manager.active_child;
Packit b099d7
	      if (oldActiveChild && XmIsGadget(oldActiveChild))
Packit b099d7
		 ((XmGadget)oldActiveChild)->gadget.have_traversal = False;
Packit b099d7
	   }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XtIsManaged ((Widget)parent))
Packit b099d7
    {
Packit b099d7
        if ((RC_Type(parent) == XmMENU_BAR) && !RC_IsArmed (parent))
Packit b099d7
	   return;
Packit b099d7
Packit b099d7
        /*
Packit b099d7
         * If the old active child for the menupane was a cascadeB gadget, 
Packit b099d7
         * and it did not have its submenu posted, then
Packit b099d7
         * we need to manually send it FocusOut notification, since
Packit b099d7
         * when we managed our submenu, the active_child field for
Packit b099d7
         * our parent was set to us, and the parent now no longer knows
Packit b099d7
         * who previously had the focus.
Packit b099d7
         */
Packit b099d7
        oldActiveChild = parent->manager.active_child;
Packit b099d7
        if (oldActiveChild && 
Packit b099d7
            (oldActiveChild != (Widget)cb) &&
Packit b099d7
            XmIsCascadeButtonGadget(oldActiveChild) &&
Packit b099d7
            CBG_Submenu(oldActiveChild) &&
Packit b099d7
            (((XmMenuShellWidget)XtParent(CBG_Submenu(oldActiveChild)))->
Packit b099d7
               shell.popped_up == False))
Packit b099d7
        {
Packit b099d7
            parent->manager.active_child = NULL;
Packit b099d7
            _XmDispatchGadgetInput((Widget) oldActiveChild, NULL,
Packit b099d7
                                                            XmFOCUS_OUT_EVENT);
Packit b099d7
            ((XmGadget)oldActiveChild)->gadget.have_traversal = False;
Packit b099d7
        }
Packit b099d7
        else 
Packit b099d7
	  /*
Packit b099d7
	   * Fix for CR 5683 - If the RC_CascadeBtn == cb, then the menupane 
Packit b099d7
	   *		       should not be popped down (it probably already
Packit b099d7
	   *		       is popped down), so do not pop down the 
Packit b099d7
	   *		       menupane (it messes up the traversal)
Packit b099d7
	   */
Packit b099d7
	if (!submenu || 
Packit b099d7
	    !popped_up || 
Packit b099d7
	    (RC_PopupPosted(parent) != (Widget)shell) ||
Packit b099d7
	    (submenu && RC_CascadeBtn(submenu) &&
Packit b099d7
	     (RC_CascadeBtn(submenu) != cb) &&
Packit b099d7
	     ((Widget)parent == XtParent(RC_CascadeBtn(submenu)))) )
Packit b099d7
        {
Packit b099d7
	   /* popdown all visible subpanes of this parent when:
Packit b099d7
	    * - moving to a button without a submenu
Packit b099d7
	    * - between non-shared menushells
Packit b099d7
	    *   = then menushell will not be popped_up
Packit b099d7
	    *   = the old shell is different than the new shell
Packit b099d7
	    *     (old shell nonshared, new shell shared)
Packit b099d7
	    * - special case when same pane attached to > 1 cb in same parent
Packit b099d7
	    */
Packit b099d7
	    if (RC_PopupPosted(parent))
Packit b099d7
	    {
Packit b099d7
		(*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
Packit b099d7
		   menu_shell_class.popdownEveryone))
Packit b099d7
		    (RC_PopupPosted(parent),NULL,NULL, NULL);
Packit b099d7
	    }
Packit b099d7
Packit b099d7
	   /* Focus is not being handled perfectly for tear offs whose parent
Packit b099d7
	    * is a top level shell.  So force cascade unhighlighting here.
Packit b099d7
	    */
Packit b099d7
	   if (NULL != oldActiveChild &&
Packit b099d7
	       oldActiveChild != cb &&
Packit b099d7
	       ((parent->row_column.type == XmMENU_PULLDOWN) ||
Packit b099d7
		(parent->row_column.type == XmMENU_POPUP)) &&
Packit b099d7
	       !XmIsMenuShell(XtParent(parent)))
Packit b099d7
	       XmCascadeButtonHighlight(oldActiveChild, FALSE);
Packit b099d7
        }
Packit b099d7
        else
Packit b099d7
        {
Packit b099d7
           /*
Packit b099d7
            * Handle shared menupanes */
Packit b099d7
           PopdownGrandChildren (parent);
Packit b099d7
        }
Packit b099d7
Packit b099d7
	/* We don't allow the possibility of the submenu to be restored 
Packit b099d7
	 * from the menushell back to the transient shell during the 
Packit b099d7
	 * previous popdown code.  This occurs when the tear off is shared 
Packit b099d7
	 * and previously posted.
Packit b099d7
	 */
Packit b099d7
	*(excPP->pane) = NULL;
Packit b099d7
	excPP->num_panes = 0;
Packit b099d7
Packit b099d7
	if (submenu)
Packit b099d7
	{
Packit b099d7
           if (((ShellWidget)XtParent(submenu))->composite.num_children == 1)
Packit b099d7
	   {
Packit b099d7
	      menuSTrait -> cascade((Widget) submenu, cb, event);
Packit b099d7
Packit b099d7
	      /* Map the window first to sync up the server in case the 
Packit b099d7
	       * menushell was previously shared
Packit b099d7
	       */
Packit b099d7
	      XMapWindow(XtDisplay(submenu), XtWindow(submenu));
Packit b099d7
	      XtManageChild( (Widget) submenu);
Packit b099d7
	   }
Packit b099d7
           else
Packit b099d7
           {
Packit b099d7
	      /* We will call menuprocs XmMENU_CASCADING from
Packit b099d7
	       * popupSharedMenuShell routine so that it occurs between
Packit b099d7
	       * shared menupane window configurations.
Packit b099d7
	       */
Packit b099d7
              (*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
Packit b099d7
                   menu_shell_class.popupSharedMenupane))(cb,
Packit b099d7
                                                      (Widget) submenu, event);
Packit b099d7
           }
Packit b099d7
	   /* So help is delivered correctly when in drag mode */
Packit b099d7
	   if (_XmGetInDragMode((Widget)cb))
Packit b099d7
	      XtSetKeyboardFocus((Widget)submenu, None);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * get the cascade size set up
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
size_cascade(
Packit b099d7
        XmCascadeButtonWidget cascadebtn )
Packit b099d7
{
Packit b099d7
    Window rootwin;
Packit b099d7
    int x,y;					       /* must be int */
Packit b099d7
    unsigned int width, height, border, depth;	       /* must be int */
Packit b099d7
Packit b099d7
    if (CB_CascadePixmap(cascadebtn) != XmUNSPECIFIED_PIXMAP)
Packit b099d7
    {
Packit b099d7
       XGetGeometry(XtDisplay(cascadebtn), CB_CascadePixmap(cascadebtn),
Packit b099d7
		    &rootwin, &x, &y, &width, &height,
Packit b099d7
		    &border, &depth);
Packit b099d7
Packit b099d7
       CB_Cascade_width(cascadebtn) = (Dimension) width;
Packit b099d7
       CB_Cascade_height(cascadebtn) = (Dimension) height;
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
       CB_Cascade_width(cascadebtn) = 0;
Packit b099d7
       CB_Cascade_height(cascadebtn) = 0;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * set up the cascade position.  
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
position_cascade(
Packit b099d7
        XmCascadeButtonWidget cascadebtn )
Packit b099d7
{
Packit b099d7
   Dimension buffer;
Packit b099d7
Packit b099d7
   if (CB_HasCascade(cascadebtn))
Packit b099d7
   { 
Packit b099d7
      if (LayoutIsRtoLP(cascadebtn))
Packit b099d7
         CB_Cascade_x(cascadebtn) = cascadebtn->primitive.highlight_thickness +
Packit b099d7
                                    cascadebtn->primitive.shadow_thickness +
Packit b099d7
                                    Lab_MarginWidth(cascadebtn);
Packit b099d7
      else
Packit b099d7
	CB_Cascade_x(cascadebtn) = XtWidth (cascadebtn) -
Packit b099d7
                               cascadebtn->primitive.highlight_thickness -
Packit b099d7
                               cascadebtn->primitive.shadow_thickness -
Packit b099d7
			       Lab_MarginWidth(cascadebtn) -
Packit b099d7
                               CB_Cascade_width(cascadebtn);
Packit b099d7
Packit b099d7
      buffer = cascadebtn->primitive.highlight_thickness +
Packit b099d7
             cascadebtn->primitive.shadow_thickness +
Packit b099d7
             Lab_MarginHeight(cascadebtn);
Packit b099d7
Packit b099d7
      CB_Cascade_y(cascadebtn) = buffer +
Packit b099d7
                               ((XtHeight(cascadebtn) -  2*buffer) -
Packit b099d7
                                CB_Cascade_height(cascadebtn)) / 2;
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      CB_Cascade_y(cascadebtn) = 0;
Packit b099d7
      CB_Cascade_x(cascadebtn) = 0;
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * set up the cascade size and location
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
setup_cascade(
Packit b099d7
        XmCascadeButtonWidget cascadebtn,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int adjustWidth,
Packit b099d7
        int adjustHeight )
Packit b099d7
#else
Packit b099d7
        Boolean adjustWidth,
Packit b099d7
        Boolean adjustHeight )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   Dimension delta;
Packit b099d7
Packit b099d7
   if (CB_HasCascade(cascadebtn))
Packit b099d7
   {
Packit b099d7
      /*
Packit b099d7
       *  modify the size of the cascadebutton to acommadate the cascade, if
Packit b099d7
       *  needed.  The cascade should fit inside MarginRight.
Packit b099d7
       */
Packit b099d7
      if (LayoutIsRtoLP(cascadebtn))
Packit b099d7
      {
Packit b099d7
        if ((CB_Cascade_width(cascadebtn) + CASCADE_PIX_SPACE) >
Packit b099d7
             Lab_MarginLeft(cascadebtn))
Packit b099d7
        {
Packit b099d7
            delta = CB_Cascade_width(cascadebtn) + CASCADE_PIX_SPACE -
Packit b099d7
                Lab_MarginLeft(cascadebtn);
Packit b099d7
            Lab_MarginLeft(cascadebtn) += delta;
Packit b099d7
Packit b099d7
            if (adjustWidth)
Packit b099d7
                XtWidth(cascadebtn) += delta;
Packit b099d7
Packit b099d7
            else
Packit b099d7
            {
Packit b099d7
               if (cascadebtn->label.alignment == XmALIGNMENT_BEGINNING)
Packit b099d7
                   Lab_TextRect_x(cascadebtn) += delta;
Packit b099d7
               else if (cascadebtn->label.alignment == XmALIGNMENT_CENTER)
Packit b099d7
                   Lab_TextRect_x(cascadebtn) += delta/2;
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
Packit b099d7
      }
Packit b099d7
      else
Packit b099d7
      {
Packit b099d7
	if ((CB_Cascade_width(cascadebtn) + CASCADE_PIX_SPACE) >
Packit b099d7
	    Lab_MarginRight(cascadebtn))
Packit b099d7
	  {
Packit b099d7
	    delta = CB_Cascade_width(cascadebtn) + CASCADE_PIX_SPACE -
Packit b099d7
	      Lab_MarginRight(cascadebtn);
Packit b099d7
	    Lab_MarginRight(cascadebtn) += delta;
Packit b099d7
	    
Packit b099d7
	    if (adjustWidth)
Packit b099d7
	      XtWidth(cascadebtn) += delta;
Packit b099d7
	    
Packit b099d7
	    else
Packit b099d7
	      {
Packit b099d7
		if (cascadebtn->label.alignment == XmALIGNMENT_END)
Packit b099d7
		  Lab_TextRect_x(cascadebtn) -= delta;
Packit b099d7
		else if (cascadebtn->label.alignment == XmALIGNMENT_CENTER)
Packit b099d7
		  Lab_TextRect_x(cascadebtn) -= delta/2;
Packit b099d7
	      }
Packit b099d7
	  }
Packit b099d7
      }
Packit b099d7
	
Packit b099d7
      /*
Packit b099d7
       * the cascade height should fit inside of 
Packit b099d7
       * TextRect + marginTop + marginBottom
Packit b099d7
       */
Packit b099d7
      delta = CB_Cascade_height(cascadebtn) +
Packit b099d7
	  2 * (Lab_MarginHeight(cascadebtn) +
Packit b099d7
	       cascadebtn->primitive.shadow_thickness +
Packit b099d7
	       cascadebtn->primitive.highlight_thickness);
Packit b099d7
		
Packit b099d7
      if (delta > XtHeight(cascadebtn))
Packit b099d7
      {
Packit b099d7
	 delta -= XtHeight(cascadebtn);
Packit b099d7
	 Lab_MarginTop(cascadebtn) += delta/2;
Packit b099d7
	 Lab_TextRect_y(cascadebtn) += delta/2;
Packit b099d7
	 Lab_MarginBottom(cascadebtn) += delta - (delta/2);
Packit b099d7
	 
Packit b099d7
	 if (adjustHeight)
Packit b099d7
	     XtHeight(cascadebtn) += delta;
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
Packit b099d7
   position_cascade(cascadebtn);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Destroy the widget
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Destroy(
Packit b099d7
        Widget wid )
Packit b099d7
{
Packit b099d7
  XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
  XmRowColumnWidget submenu = (XmRowColumnWidget) CB_Submenu(cb);
Packit b099d7
  XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
  menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
    XmeTraitGet((XtPointer) XtClass(XtParent(wid)), XmQTmenuSystem);
Packit b099d7
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * If the armed pixmap exists, both pixmaps must be cached arrows
Packit b099d7
   */
Packit b099d7
  if (CB_ArmedPixmap(cb))
Packit b099d7
    {
Packit b099d7
	_XmProcessLock();
Packit b099d7
	_XmArrowPixmapCacheDelete((XtPointer) CB_ArmedPixmap(cb));
Packit b099d7
	_XmArrowPixmapCacheDelete((XtPointer) CB_CascadePixmap(cb));
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * break the submenu link
Packit b099d7
   */
Packit b099d7
  if (submenu != NULL && menuSTrait != NULL)
Packit b099d7
    menuSTrait -> recordPostFromWidget((Widget) submenu, (Widget) cb, FALSE);
Packit b099d7
Packit b099d7
  if (cb->cascade_button.timer)
Packit b099d7
    XtRemoveTimeOut (cb->cascade_button.timer);
Packit b099d7
Packit b099d7
  /* Release the GCs */
Packit b099d7
Packit b099d7
  XtReleaseGC (wid, CB_ArmGC(wid));
Packit b099d7
  XtReleaseGC (wid, CB_BackgroundGC(wid));
Packit b099d7
  
Packit b099d7
}
Packit b099d7
                         
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * routine to resize a cascade button, called by the parent
Packit b099d7
 * geometery manager
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Resize(
Packit b099d7
        Widget cb )
Packit b099d7
{
Packit b099d7
    /*
Packit b099d7
     */
Packit b099d7
     if (cb)
Packit b099d7
     {
Packit b099d7
	XtWidgetProc resize;
Packit b099d7
Packit b099d7
	/* Label class does it's work */
Packit b099d7
Packit b099d7
	_XmProcessLock();
Packit b099d7
        resize = xmLabelClassRec.core_class.resize;
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	(* resize) (cb);
Packit b099d7
Packit b099d7
	/* move the cascade too */
Packit b099d7
	position_cascade ((XmCascadeButtonWidget) cb);
Packit b099d7
     }
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SetValuesPrehook
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
SetValuesPrehook(
Packit b099d7
        Widget cw,		/* unused */
Packit b099d7
        Widget rw,		/* unused */
Packit b099d7
        Widget nw,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal *num_args )	/* unused */
Packit b099d7
{
Packit b099d7
  XmCascadeButtonWidget new_w = (XmCascadeButtonWidget) nw ;
Packit b099d7
Packit b099d7
  /* CR 2990: Use XmNbuttonFontList as the default font. */
Packit b099d7
  if (new_w->label.font == NULL)
Packit b099d7
    new_w->label.font = XmeGetDefaultRenderTable (nw, XmBUTTON_FONTLIST);
Packit b099d7
Packit b099d7
  return False;
Packit b099d7
}
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Set Values
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
SetValues(
Packit b099d7
        Widget cw,
Packit b099d7
        Widget rw,
Packit b099d7
        Widget nw,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal *num_args )	/* unused */
Packit b099d7
{
Packit b099d7
  XmCascadeButtonWidget old = (XmCascadeButtonWidget) cw ;
Packit b099d7
  XmCascadeButtonWidget requested = (XmCascadeButtonWidget) rw ;
Packit b099d7
  XmCascadeButtonWidget new_w = (XmCascadeButtonWidget) nw ;
Packit b099d7
  Boolean flag = FALSE;
Packit b099d7
  Boolean adjustWidth = FALSE;
Packit b099d7
  Boolean adjustHeight = FALSE;
Packit b099d7
  XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
  menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
    XmeTraitGet((XtPointer) XtClass(XtParent(cw)), XmQTmenuSystem);
Packit b099d7
Packit b099d7
  if (old->primitive.foreground != new_w->primitive.foreground
Packit b099d7
    || old->core.background_pixel != new_w->core.background_pixel) {
Packit b099d7
      GetBackgroundGC(new_w);
Packit b099d7
  }
Packit b099d7
Packit b099d7
  if ((CB_Submenu(new_w)) &&
Packit b099d7
      ((! XmIsRowColumn(CB_Submenu(new_w))) ||
Packit b099d7
       (RC_Type(CB_Submenu(new_w)) != XmMENU_PULLDOWN)))
Packit b099d7
    {
Packit b099d7
      CB_Submenu(new_w) = NULL;
Packit b099d7
      XmeWarning( (Widget)new_w, WRONGSUBMENU);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (new_w->cascade_button.map_delay < 0) 
Packit b099d7
    {
Packit b099d7
       new_w->cascade_button.map_delay = old->cascade_button.map_delay;
Packit b099d7
       XmeWarning( (Widget)new_w, WRONGMAPDELAY);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* if there is a change to submenu, notify menu system */
Packit b099d7
    if (CB_Submenu(old) != CB_Submenu(new_w))
Packit b099d7
    {
Packit b099d7
      /* We must pass nw as the parameter to recordPostFromWidget
Packit b099d7
       * because old is a copy!  The call to recordPostFromWidget() does
Packit b099d7
       * a widget ID comparison and we must pass the real widget (nw).
Packit b099d7
       */
Packit b099d7
Packit b099d7
      if (CB_Submenu(old) && menuSTrait)
Packit b099d7
	menuSTrait -> recordPostFromWidget(CB_Submenu(old), nw, FALSE);
Packit b099d7
Packit b099d7
      if (CB_Submenu(new_w) && menuSTrait)
Packit b099d7
	menuSTrait -> recordPostFromWidget(CB_Submenu(new_w), nw, TRUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* don't let traversal be changed */
Packit b099d7
    if (Lab_MenuType(new_w) == XmMENU_BAR)
Packit b099d7
	new_w->primitive.traversal_on = TRUE;
Packit b099d7
Packit b099d7
    /* handle the cascade pixmap indicator */
Packit b099d7
    else if (Lab_IsMenupane(new_w))
Packit b099d7
    {
Packit b099d7
       /* don't let traversal be changed */
Packit b099d7
       new_w->primitive.traversal_on = TRUE;
Packit b099d7
Packit b099d7
       if ((new_w->label.recompute_size)  || (requested->core.width <= 0))
Packit b099d7
	  adjustWidth = TRUE;
Packit b099d7
Packit b099d7
       if ((new_w->label.recompute_size)  || (requested->core.height <= 0))
Packit b099d7
	  adjustHeight = TRUE;
Packit b099d7
Packit b099d7
       /* get new pixmap size */
Packit b099d7
       if (CB_CascadePixmap(old) != CB_CascadePixmap (new_w))
Packit b099d7
       {
Packit b099d7
	  if (CB_ArmedPixmap(old) != XmUNSPECIFIED_PIXMAP)
Packit b099d7
	  {
Packit b099d7
	     _XmProcessLock();
Packit b099d7
	     _XmArrowPixmapCacheDelete((XtPointer) CB_ArmedPixmap(old));
Packit b099d7
	     _XmArrowPixmapCacheDelete((XtPointer) CB_CascadePixmap(old));
Packit b099d7
	     _XmProcessUnlock();
Packit b099d7
	  }
Packit b099d7
	  CB_ArmedPixmap(new_w) = XmUNSPECIFIED_PIXMAP;
Packit b099d7
	  size_cascade (new_w);
Packit b099d7
       } else
Packit b099d7
          if ( ((CB_CascadePixmap(new_w) ==  XmUNSPECIFIED_PIXMAP) &&
Packit b099d7
                  (!CB_Submenu(old) && CB_Submenu(new_w))) ||
Packit b099d7
               ((CB_ArmedPixmap(old) != XmUNSPECIFIED_PIXMAP) &&
Packit b099d7
                  ((Lab_TextRect_height(old) != Lab_TextRect_height(new_w)) ||
Packit b099d7
		   (old->primitive.foreground != new_w->primitive.foreground) ||
Packit b099d7
		   (old->core.background_pixel != 
Packit b099d7
		      new_w->core.background_pixel))))
Packit b099d7
	  {
Packit b099d7
	     _XmProcessLock();
Packit b099d7
	     _XmArrowPixmapCacheDelete((XtPointer) CB_ArmedPixmap(old));
Packit b099d7
	     _XmArrowPixmapCacheDelete((XtPointer) CB_CascadePixmap(old));
Packit b099d7
	     CB_ArmedPixmap(new_w) = XmUNSPECIFIED_PIXMAP;
Packit b099d7
	     CB_CascadePixmap(new_w) = XmUNSPECIFIED_PIXMAP;
Packit b099d7
	     _XmCreateArrowPixmaps((Widget) new_w);
Packit b099d7
	     _XmProcessUnlock();
Packit b099d7
	     size_cascade (new_w);
Packit b099d7
	  }
Packit b099d7
Packit b099d7
       /*
Packit b099d7
        * resize widget if cascade appeared or disappeared, or if the
Packit b099d7
	* cascade pixmap changed size.
Packit b099d7
	*/
Packit b099d7
       if ((CB_CascadePixmap (old) != CB_CascadePixmap (new_w))  ||
Packit b099d7
	   (old->label.label_type != new_w->label.label_type) ||
Packit b099d7
	   (old->cascade_button.submenu != new_w->cascade_button.submenu))
Packit b099d7
       {
Packit b099d7
	  setup_cascade (new_w, adjustWidth, adjustHeight);
Packit b099d7
Packit b099d7
	  /* if there wasn't a cascade, and still isn't, don't redraw */
Packit b099d7
	  if (old->cascade_button.submenu || new_w->cascade_button.submenu)
Packit b099d7
	      flag = TRUE;
Packit b099d7
       }
Packit b099d7
Packit b099d7
       /* make sure that other changes did not scrunch our pixmap */
Packit b099d7
       else if (new_w->cascade_button.submenu)
Packit b099d7
       {
Packit b099d7
	  if ((new_w->primitive.highlight_thickness !=
Packit b099d7
	       old->primitive.highlight_thickness)               ||
Packit b099d7
	      (new_w->primitive.shadow_thickness !=
Packit b099d7
	       old->primitive.shadow_thickness)                  ||
Packit b099d7
	      (Lab_MarginRight (new_w) != Lab_MarginRight (old))   ||
Packit b099d7
	      (Lab_MarginHeight (new_w) != Lab_MarginHeight (old)) ||
Packit b099d7
	      (Lab_MarginTop (new_w) != Lab_MarginTop (old))	 ||
Packit b099d7
	      (Lab_MarginBottom (new_w) != Lab_MarginBottom (old)))
Packit b099d7
	  {
Packit b099d7
	     setup_cascade (new_w,adjustWidth, adjustHeight);
Packit b099d7
	     flag = TRUE;
Packit b099d7
	  }
Packit b099d7
Packit b099d7
	  else if ((Lab_MarginWidth(new_w) != Lab_MarginWidth(old)) ||
Packit b099d7
		   (new_w->core.width != old->core.width)           ||
Packit b099d7
		   (new_w->core.height != old->core.height))
Packit b099d7
Packit b099d7
	  {
Packit b099d7
	     position_cascade (new_w);
Packit b099d7
	     flag = TRUE;
Packit b099d7
	  }
Packit b099d7
       }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return (flag);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * InitializePrehook
Packit b099d7
 *
Packit b099d7
 * Put the proper translations in core_class tm_table so that
Packit b099d7
 * the data is massaged correctly
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
InitializePrehook(
Packit b099d7
        Widget req,		/* unused */
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal *num_args )	/* unused */
Packit b099d7
{
Packit b099d7
  unsigned char type;
Packit b099d7
  XmMenuSystemTrait menuSTrait;
Packit b099d7
  XmCascadeButtonWidget bw = (XmCascadeButtonWidget) new_w ;
Packit b099d7
Packit b099d7
  _XmSaveCoreClassTranslations (new_w);
Packit b099d7
Packit b099d7
  menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
    XmeTraitGet((XtPointer) XtClass((Widget) XtParent(new_w)), XmQTmenuSystem);
Packit b099d7
Packit b099d7
  if (menuSTrait != NULL)
Packit b099d7
    type = menuSTrait->type(XtParent(new_w));
Packit b099d7
  else
Packit b099d7
    type = XmWORK_AREA;
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (type == XmMENU_PULLDOWN ||
Packit b099d7
      type == XmMENU_POPUP)
Packit b099d7
    new_w->core.widget_class->core_class.tm_table = (String) p_events_parsed;
Packit b099d7
  else
Packit b099d7
    new_w->core.widget_class->core_class.tm_table =(String)menubar_events_parsed;
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  
Packit b099d7
  /* CR 2990: Use XmNbuttonFontList as the default font. */
Packit b099d7
  if (bw->label.font == NULL)
Packit b099d7
    bw->label.font = XmeGetDefaultRenderTable (new_w, XmBUTTON_FONTLIST);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * InitializePosthook
Packit b099d7
 *
Packit b099d7
 * restore core class translations
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
InitializePosthook(
Packit b099d7
        Widget req,		/* unused */
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal *num_args )	/* unused */
Packit b099d7
{
Packit b099d7
  _XmRestoreCoreClassTranslations (new_w);
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GetArmGC
Packit b099d7
 *     Get the graphics context used for filling in background of the
Packit b099d7
 *     cascade button when armed.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
GetArmGC(
Packit b099d7
        XmCascadeButtonWidget cb )
Packit b099d7
{
Packit b099d7
  XGCValues values;
Packit b099d7
  XtGCMask  valueMask;
Packit b099d7
  Pixel     junk, select_pixel;
Packit b099d7
  
Packit b099d7
  XmGetColors(XtScreen(cb), cb->core.colormap, cb->core.background_pixel,
Packit b099d7
	      &junk, &junk, &junk, &select_pixel);
Packit b099d7
Packit b099d7
  valueMask = GCForeground | GCBackground | GCGraphicsExposures;
Packit b099d7
  
Packit b099d7
  values.foreground = select_pixel;
Packit b099d7
  values.background = cb->primitive.foreground;
Packit b099d7
  values.graphics_exposures = False;
Packit b099d7
  
Packit b099d7
  CB_ArmGC(cb) = XtGetGC ((Widget) cb, valueMask, &values);
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GetBackgroundGC
Packit b099d7
 *     Get the graphics context used for filling in background of 
Packit b099d7
 *     the cascade button when not armed.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
GetBackgroundGC(
Packit b099d7
        XmCascadeButtonWidget cb )
Packit b099d7
{
Packit b099d7
  XGCValues       values;
Packit b099d7
  XtGCMask        valueMask;
Packit b099d7
  XFontStruct     *fs;
Packit b099d7
  
Packit b099d7
  valueMask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
Packit b099d7
  
Packit b099d7
  values.foreground = cb->core.background_pixel;
Packit b099d7
  values.background = cb->primitive.foreground;
Packit b099d7
  values.graphics_exposures = False;
Packit b099d7
  
Packit b099d7
  if (XmeRenderTableGetDefaultFont(cb->label.font, &fs))
Packit b099d7
    values.font = fs->fid;
Packit b099d7
  else
Packit b099d7
    valueMask &= ~GCFont;
Packit b099d7
  
Packit b099d7
  CB_BackgroundGC(cb) = XtGetGC ((Widget) cb, valueMask, &values);
Packit b099d7
}
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Initialize
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
Initialize(
Packit b099d7
        Widget w_req,
Packit b099d7
        Widget w_new,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal *num_args )	/* unused */
Packit b099d7
{
Packit b099d7
    XmCascadeButtonWidget  req = (XmCascadeButtonWidget) w_req ;
Packit b099d7
    XmCascadeButtonWidget  new_w = (XmCascadeButtonWidget) w_new ;
Packit b099d7
    Boolean adjustWidth = FALSE;
Packit b099d7
    Boolean adjustHeight = FALSE;
Packit b099d7
    XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
    XmRowColumnWidget    submenu = (XmRowColumnWidget) CB_Submenu(new_w);
Packit b099d7
    XmRowColumnWidget    parent = (XmRowColumnWidget) XtParent(new_w);
Packit b099d7
Packit b099d7
    menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
      XmeTraitGet((XtPointer) XtClass((Widget) parent), XmQTmenuSystem);
Packit b099d7
Packit b099d7
    if ((! XmIsRowColumn (parent)) &&
Packit b099d7
	((Lab_MenuType(new_w) == XmMENU_PULLDOWN) ||
Packit b099d7
	 (Lab_MenuType(new_w) == XmMENU_POPUP)    ||
Packit b099d7
	 (Lab_MenuType(new_w) == XmMENU_BAR)))
Packit b099d7
    {
Packit b099d7
       XmeWarning( (Widget)new_w, WRONGPARENT);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* if menuProcs is not set up yet, try again */
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (xmLabelClassRec.label_class.menuProcs == NULL)
Packit b099d7
	xmLabelClassRec.label_class.menuProcs =
Packit b099d7
	    (XmMenuProc) _XmGetMenuProcContext();
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    /* CR 7651: Clear before setting. */
Packit b099d7
    new_w->cascade_button.armed = 0;
Packit b099d7
    CB_SetArmed(new_w, FALSE);
Packit b099d7
    new_w->cascade_button.timer = 0;
Packit b099d7
    CB_SetTraverse (new_w, FALSE);
Packit b099d7
    CB_SetWasPosted (new_w, FALSE);
Packit b099d7
    CB_ArmedPixmap(new_w) = XmUNSPECIFIED_PIXMAP;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * if the user did not specify a margin width, set the default.
Packit b099d7
     * The menubar cbs have a larger margin.
Packit b099d7
     */
Packit b099d7
    if (Lab_MarginWidth(req) == XmINVALID_DIMENSION)
Packit b099d7
    {
Packit b099d7
       if (Lab_MenuType(new_w) == XmMENU_BAR)
Packit b099d7
          Lab_MarginWidth(new_w) = 6;
Packit b099d7
       else
Packit b099d7
          Lab_MarginWidth(new_w) = 2;
Packit b099d7
    }
Packit b099d7
	   
Packit b099d7
    
Packit b099d7
Packit b099d7
    if (submenu &&
Packit b099d7
	(! XmIsRowColumn(submenu) ||
Packit b099d7
	 (RC_Type(submenu) != XmMENU_PULLDOWN)))
Packit b099d7
    {
Packit b099d7
       submenu = NULL;
Packit b099d7
       XmeWarning( (Widget)new_w, WRONGSUBMENU);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (new_w->cascade_button.map_delay < 0) 
Packit b099d7
    {
Packit b099d7
       new_w->cascade_button.map_delay = MAP_DELAY_DEFAULT;
Packit b099d7
       XmeWarning( (Widget)new_w, WRONGMAPDELAY);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* call submenu's class function to set the link */
Packit b099d7
    if (submenu != NULL && menuSTrait != NULL)
Packit b099d7
      menuSTrait -> recordPostFromWidget((Widget) submenu, (Widget) new_w, TRUE);
Packit b099d7
    
Packit b099d7
   if (submenu && (CB_CascadePixmap(new_w) == XmUNSPECIFIED_PIXMAP)) {
Packit b099d7
      _XmProcessLock();
Packit b099d7
      _XmCreateArrowPixmaps((Widget) new_w);
Packit b099d7
      _XmProcessUnlock();
Packit b099d7
   }
Packit b099d7
	 
Packit b099d7
    if (Lab_IsMenupane(new_w))
Packit b099d7
    {
Packit b099d7
      if (req->core.width <= 0)
Packit b099d7
	adjustWidth = TRUE;
Packit b099d7
      
Packit b099d7
      if (req->core.height <= 0)
Packit b099d7
	adjustHeight = TRUE;
Packit b099d7
      
Packit b099d7
      /* get pixmap size and set up widget to allow room for it */
Packit b099d7
      size_cascade (new_w);
Packit b099d7
      setup_cascade (new_w, adjustWidth, adjustHeight);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    new_w->primitive.traversal_on = TRUE;
Packit b099d7
Packit b099d7
    /* Initialize GCs for armed button select and background only */
Packit b099d7
    GetArmGC (new_w);
Packit b099d7
    GetBackgroundGC (new_w);
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *************************************************************************
Packit b099d7
 *
Packit b099d7
 * Public Routines                                                        
Packit b099d7
 *
Packit b099d7
 *************************************************************************
Packit b099d7
 */
Packit b099d7
Widget 
Packit b099d7
XmCreateCascadeButton(
Packit b099d7
        Widget parent,
Packit b099d7
        char *name,
Packit b099d7
        ArgList al,
Packit b099d7
        Cardinal ac )
Packit b099d7
{
Packit b099d7
    Widget cb;
Packit b099d7
Packit b099d7
    cb = XtCreateWidget(name, xmCascadeButtonWidgetClass, parent, al, ac);
Packit b099d7
Packit b099d7
    return (cb);
Packit b099d7
}
Packit b099d7
Packit b099d7
Widget 
Packit b099d7
XmVaCreateCascadeButton(
Packit b099d7
        Widget parent,
Packit b099d7
        char *name,
Packit b099d7
        ...)
Packit b099d7
{
Packit b099d7
    register Widget w;
Packit b099d7
    va_list var;
Packit b099d7
    int count;
Packit b099d7
    
Packit b099d7
    Va_start(var,name);
Packit b099d7
    count = XmeCountVaListSimple(var);
Packit b099d7
    va_end(var);
Packit b099d7
Packit b099d7
    
Packit b099d7
    Va_start(var, name);
Packit b099d7
    w = XmeVLCreateWidget(name, 
Packit b099d7
                         xmCascadeButtonWidgetClass,
Packit b099d7
                         parent, False, 
Packit b099d7
                         var, count);
Packit b099d7
    va_end(var);   
Packit b099d7
    return w;
Packit b099d7
}
Packit b099d7
Packit b099d7
Widget
Packit b099d7
XmVaCreateManagedCascadeButton(
Packit b099d7
        Widget parent,
Packit b099d7
        char *name,
Packit b099d7
        ...)
Packit b099d7
{
Packit b099d7
    Widget w = NULL;
Packit b099d7
    va_list var;
Packit b099d7
    int count;
Packit b099d7
    
Packit b099d7
    Va_start(var, name);
Packit b099d7
    count = XmeCountVaListSimple(var);
Packit b099d7
    va_end(var);
Packit b099d7
    
Packit b099d7
    Va_start(var, name);
Packit b099d7
    w = XmeVLCreateWidget(name, 
Packit b099d7
                         xmCascadeButtonWidgetClass,
Packit b099d7
                         parent, True, 
Packit b099d7
                         var, count);
Packit b099d7
    va_end(var);   
Packit b099d7
    return w;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * This routine is called for both cascadebutton gadgets and widgets.
Packit b099d7
 * The button is armed or disarmed but it does not pop up or down submenus.
Packit b099d7
 */
Packit b099d7
void 
Packit b099d7
XmCascadeButtonHighlight(
Packit b099d7
        Widget cb,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int highlight )
Packit b099d7
#else
Packit b099d7
        Boolean highlight )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
  XtAppContext app;
Packit b099d7
Packit b099d7
  if (NULL == cb) return;
Packit b099d7
  app = XtWidgetToApplicationContext(cb);
Packit b099d7
  _XmAppLock(app);
Packit b099d7
   if ((cb) && XmIsCascadeButton(cb))
Packit b099d7
   {
Packit b099d7
      if (highlight)
Packit b099d7
         Arm ((XmCascadeButtonWidget) cb);
Packit b099d7
Packit b099d7
      else
Packit b099d7
         Disarm ((XmCascadeButtonWidget) cb, FALSE);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else if ((cb) && XmIsCascadeButtonGadget(cb))
Packit b099d7
      XmCascadeButtonGadgetHighlight ((Widget) cb, highlight);
Packit b099d7
  _XmAppUnlock(app);
Packit b099d7
}