Blame lib/Xm/CascadeBG.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: CascadeBG.c /main/28 1999/02/01 18:47:11 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 <string.h>
Packit b099d7
#include "XmI.h"
Packit b099d7
#include <X11/ShellP.h>
Packit b099d7
#include <X11/keysymdef.h>
Packit b099d7
#include <Xm/CacheP.h>
Packit b099d7
#include <Xm/CascadeBP.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/TraitP.h>
Packit b099d7
#include <Xm/VaSimpleP.h>
Packit b099d7
#include "BaseClassI.h"
Packit b099d7
#include "CacheI.h"
Packit b099d7
#include "CascadeBI.h"
Packit b099d7
#include "CascadeBGI.h"
Packit b099d7
#include "ExtObjectI.h"
Packit b099d7
#include "GadgetUtiI.h"
Packit b099d7
#include "LabelI.h"
Packit b099d7
#include "LabelGI.h"
Packit b099d7
#include "MessagesI.h"
Packit b099d7
#include "MenuProcI.h"
Packit b099d7
#include "MenuStateI.h"
Packit b099d7
#include "MenuUtilI.h"
Packit b099d7
#include "RCMenuI.h"
Packit b099d7
#include "SyntheticI.h"
Packit b099d7
#include "TravActI.h"
Packit b099d7
#include "TraversalI.h"
Packit b099d7
#include "UniqueEvnI.h"
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
#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 SecondaryObjectCreate( 
Packit b099d7
                        Widget req,
Packit b099d7
                        Widget new_w,
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 int _XmCascadeBCacheCompare( 
Packit b099d7
                        XtPointer A,
Packit b099d7
                        XtPointer B) ;
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
                        XmCascadeButtonGadget cb) ;
Packit b099d7
static void DrawCascade( 
Packit b099d7
                        register XmCascadeButtonGadget cb) ;
Packit b099d7
static void position_cascade( 
Packit b099d7
                        XmCascadeButtonGadget cascadebtn) ;
Packit b099d7
static void Redisplay( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        Region region) ;
Packit b099d7
static void InputDispatch( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        Mask event_mask) ;
Packit b099d7
static void Arm( 
Packit b099d7
                        XmCascadeButtonGadget cb) ;
Packit b099d7
static void ArmAndPost( 
Packit b099d7
                        XmCascadeButtonGadget 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
                        XmCascadeButtonGadget 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
                        XmCascadeButtonGadget cb,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void CheckDisarm( 
Packit b099d7
                        XmCascadeButtonGadget cb,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void StartDrag( 
Packit b099d7
                        XmCascadeButtonGadget cb,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void Select( 
Packit b099d7
                        XmCascadeButtonGadget 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
                        XmCascadeButtonGadget cb,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void KeySelect( 
Packit b099d7
                        XmCascadeButtonGadget cb,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void MenuBarSelect( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void MenuBarEnter( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XEvent *event) ;
Packit b099d7
static void MenuBarLeave( 
Packit b099d7
                        Widget wid) ;
Packit b099d7
static void size_cascade( 
Packit b099d7
                        XmCascadeButtonGadget cascadebtn) ;
Packit b099d7
static void setup_cascade( 
Packit b099d7
                        XmCascadeButtonGadget 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 wid) ;
Packit b099d7
static Boolean SetValuesPrehook( 
Packit b099d7
                        Widget oldParent,
Packit b099d7
                        Widget refParent,
Packit b099d7
                        Widget newParent,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void GetValuesPrehook( 
Packit b099d7
                        Widget newParent,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void GetValuesPosthook( 
Packit b099d7
                        Widget new_w,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static Boolean SetValuesPosthook( 
Packit b099d7
                        Widget current,
Packit b099d7
                        Widget req,
Packit b099d7
                        Widget new_w,
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 GetArmGC( 
Packit b099d7
                        XmCascadeButtonGadget cb) ;
Packit b099d7
static void GetBackgroundGC( 
Packit b099d7
                        XmCascadeButtonGadget cb) ;
Packit b099d7
static void Initialize( 
Packit b099d7
                        Widget rw,
Packit b099d7
                        Widget nw,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static Cardinal GetCascadeBGClassSecResData( 
Packit b099d7
                        WidgetClass w_class,
Packit b099d7
                        XmSecondaryResourceData **data_rtn) ;
Packit b099d7
static XtPointer GetCascadeBGClassSecResBase( 
Packit b099d7
                        Widget widget,
Packit b099d7
                        XtPointer client_data) ;
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
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 _XmCascadeButtonGadgetRec, cascade_button.activate_callback),
Packit b099d7
        XmRCallback,
Packit b099d7
        NULL
Packit b099d7
    },
Packit b099d7
Packit b099d7
    {   XmNcascadingCallback,
Packit b099d7
        XmCCallback,
Packit b099d7
        XmRCallback,
Packit b099d7
        sizeof (XtCallbackList),
Packit b099d7
        XtOffsetOf( struct _XmCascadeButtonGadgetRec,
Packit b099d7
		   cascade_button.cascade_callback),
Packit b099d7
        XmRCallback,
Packit b099d7
        NULL
Packit b099d7
    },
Packit b099d7
Packit b099d7
    {	XmNsubMenuId, 
Packit b099d7
	XmCMenuWidget,				/* submenu */
Packit b099d7
	XmRMenuWidget, 
Packit b099d7
	sizeof (Widget),
Packit b099d7
	XtOffsetOf( struct _XmCascadeButtonGadgetRec, cascade_button.submenu), 
Packit b099d7
	XmRMenuWidget, 
Packit b099d7
	(XtPointer) 0
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNshadowThickness,
Packit b099d7
        XmCShadowThickness,
Packit b099d7
        XmRHorizontalDimension,
Packit b099d7
        sizeof (Dimension),
Packit b099d7
        XtOffsetOf( struct _XmCascadeButtonGadgetRec, gadget.shadow_thickness),
Packit b099d7
        XmRCallProc,
Packit b099d7
	(XtPointer) _XmSetThickness
Packit b099d7
    },
Packit b099d7
Packit b099d7
    {
Packit b099d7
        XmNtraversalOn,
Packit b099d7
        XmCTraversalOn,
Packit b099d7
        XmRBoolean,
Packit b099d7
        sizeof (Boolean),
Packit b099d7
        XtOffsetOf( struct _XmGadgetRec, gadget.traversal_on),
Packit b099d7
        XmRImmediate,
Packit b099d7
        (XtPointer) True
Packit b099d7
    },
Packit b099d7
Packit b099d7
    {
Packit b099d7
        XmNhighlightThickness,
Packit b099d7
        XmCHighlightThickness,
Packit b099d7
        XmRHorizontalDimension,
Packit b099d7
        sizeof (Dimension),
Packit b099d7
        XtOffsetOf( struct _XmGadgetRec, gadget.highlight_thickness),
Packit b099d7
        XmRCallProc,
Packit b099d7
	(XtPointer) _XmSetThickness
Packit b099d7
    },
Packit b099d7
};       
Packit b099d7
Packit b099d7
Packit b099d7
static XtResource cache_resources[] =
Packit b099d7
{
Packit b099d7
Packit b099d7
   {   XmNcascadePixmap, 
Packit b099d7
       XmCPixmap, 
Packit b099d7
       XmRDynamicPixmap,
Packit b099d7
       sizeof(Pixmap),
Packit b099d7
       XtOffsetOf( struct _XmCascadeButtonGCacheObjRec,
Packit b099d7
                 cascade_button_cache.cascade_pixmap), 
Packit b099d7
       XmRImmediate,
Packit b099d7
       (XtPointer) XmUNSPECIFIED_PIXMAP
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {   XmNmappingDelay,
Packit b099d7
       XmCMappingDelay,
Packit b099d7
       XmRInt,
Packit b099d7
       sizeof (int),
Packit b099d7
       XtOffsetOf( struct _XmCascadeButtonGCacheObjRec,
Packit b099d7
	         cascade_button_cache.map_delay),
Packit b099d7
       XmRImmediate,
Packit b099d7
       (XtPointer) MAP_DELAY_DEFAULT
Packit b099d7
   },
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
static XmCacheClassPart CascadeButtonClassCachePart = {
Packit b099d7
    {NULL, 0, 0},        /* head of class cache list */
Packit b099d7
    _XmCacheCopy,       /* Copy routine     */
Packit b099d7
    _XmCacheDelete,     /* Delete routine   */
Packit b099d7
    _XmCascadeBCacheCompare,    /* Comparison routine   */
Packit b099d7
};
Packit b099d7
Packit b099d7
static XmBaseClassExtRec   CascadeBGClassExtensionRec = {
Packit b099d7
    NULL,    					    /* next_extension        */
Packit b099d7
    NULLQUARK,    				    /* record_typ  	     */
Packit b099d7
    XmBaseClassExtVersion,      		    /* version  	     */
Packit b099d7
    sizeof(XmBaseClassExtRec),  		    /* record_size  	     */
Packit b099d7
    InitializePrehook,				    /* initializePrehook     */
Packit b099d7
    SetValuesPrehook,   			    /* setValuesPrehook	     */
Packit b099d7
    InitializePosthook,   			    /* initializePosthook    */
Packit b099d7
    SetValuesPosthook,   			    /* setValuesPosthook     */
Packit b099d7
    (WidgetClass)&xmCascadeButtonGCacheObjClassRec, /* secondaryObjectClass  */
Packit b099d7
    SecondaryObjectCreate,                 	    /* secondaryObjectCreate */
Packit b099d7
    GetCascadeBGClassSecResData,                    /* getSecResData         */
Packit b099d7
    {0},           				    /* fast subclass         */
Packit b099d7
    GetValuesPrehook,				    /* getValuesPrehook      */
Packit b099d7
    GetValuesPosthook,				    /* getValuesPosthook     */
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
/* ext rec static initialization */
Packit b099d7
externaldef(xmcascadebuttongcacheobjclassrec)
Packit b099d7
XmCascadeButtonGCacheObjClassRec xmCascadeButtonGCacheObjClassRec =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
      /* superclass         */    (WidgetClass) &xmLabelGCacheObjClassRec,
Packit b099d7
      /* class_name         */    "XmCascadeButtonGadget",
Packit b099d7
      /* widget_size        */    sizeof(XmCascadeButtonGCacheObjRec),
Packit b099d7
      /* class_initialize   */    NULL,
Packit b099d7
      /* chained class init */    NULL,
Packit b099d7
      /* class_inited       */    False,
Packit b099d7
      /* initialize         */    NULL,
Packit b099d7
      /* initialize hook    */    NULL,
Packit b099d7
      /* realize            */    NULL,
Packit b099d7
      /* actions            */    NULL,
Packit b099d7
      /* num_actions        */    0,
Packit b099d7
      /* resources          */    cache_resources,
Packit b099d7
      /* num_resources      */    XtNumber(cache_resources),
Packit b099d7
      /* xrm_class          */    NULLQUARK,
Packit b099d7
      /* compress_motion    */    False,
Packit b099d7
      /* compress_exposure  */    False,
Packit b099d7
      /* compress enter/exit*/    False,
Packit b099d7
      /* visible_interest   */    False,
Packit b099d7
      /* destroy            */    NULL,
Packit b099d7
      /* resize             */    NULL,
Packit b099d7
      /* expose             */    NULL,
Packit b099d7
      /* set_values         */    NULL,
Packit b099d7
      /* set values hook    */    NULL,
Packit b099d7
      /* set values almost  */    NULL,
Packit b099d7
      /* get values hook    */    NULL,
Packit b099d7
      /* accept_focus       */    NULL,
Packit b099d7
      /* version            */    XtVersion,
Packit b099d7
      /* callback offsetlst */    NULL,
Packit b099d7
      /* default trans      */    NULL,
Packit b099d7
      /* query geo proc     */    NULL,
Packit b099d7
      /* display accelerator*/    NULL,
Packit b099d7
      /* extension record   */    NULL,
Packit b099d7
   },
Packit b099d7
Packit b099d7
   {
Packit b099d7
      /* synthetic resources */   NULL,
Packit b099d7
      /* num_syn_resources   */   0,
Packit b099d7
      /* extension           */   NULL,
Packit b099d7
   },
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
Packit b099d7
static XmGadgetClassExtRec _XmCascadeBGadClassExtRec = {
Packit b099d7
     NULL,
Packit b099d7
     NULLQUARK,
Packit b099d7
     XmGadgetClassExtVersion,
Packit b099d7
     sizeof(XmGadgetClassExtRec),
Packit b099d7
     XmInheritBaselineProc,                  /* widget_baseline */
Packit b099d7
     XmInheritDisplayRectProc,               /* widget_display_rect */
Packit b099d7
     XmInheritMarginsProc,                   /* widget_margins */
Packit b099d7
};
Packit b099d7
Packit b099d7
externaldef(xmcascadebuttongadgetclassrec) XmCascadeButtonGadgetClassRec
Packit b099d7
	xmCascadeButtonGadgetClassRec = 
Packit b099d7
{
Packit b099d7
    {
Packit b099d7
	(WidgetClass) &xmLabelGadgetClassRec,	/* superclass ptr	*/
Packit b099d7
	"XmCascadeButtonGadget",		/* class_name	*/
Packit b099d7
	sizeof (XmCascadeButtonGadgetRec),	/* 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
    	NULL,					/* widget realize proc */
Packit b099d7
    	NULL,					/* class action table */
Packit b099d7
	0,
Packit b099d7
	resources,			       /* this class's resource list */
Packit b099d7
	XtNumber (resources),			/*  "	  " resource_count */
Packit b099d7
    	NULLQUARK,				/* xrm_class	        */
Packit b099d7
    	TRUE,					/* do compress motion */
Packit b099d7
    	XtExposeCompressMaximal,		/* do compress exposure */
Packit b099d7
	TRUE,				       /* don't 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
	XtInheritQueryGeometry,			/* query geo proc */
Packit b099d7
	NULL,				        /* display accelerator*/
Packit b099d7
	(XtPointer)&CascadeBGClassExtensionRec,	/* extension */
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
			/* Gadget Class record */
Packit b099d7
	BorderHighlight,			/* border_highlight */
Packit b099d7
	BorderUnhighlight,			/* border_uhighlight */
Packit b099d7
	ArmAndActivate,				/* arm_and_activate */
Packit b099d7
	InputDispatch,				/* input_dispatch routine */
Packit b099d7
	XmInheritVisualChange,			/* visual_change routine */
Packit b099d7
	NULL,					/* syn_resources */
Packit b099d7
	0,					/* num_syn_resources */
Packit b099d7
	&CascadeButtonClassCachePart,		/* class cache_part   */
Packit b099d7
	(XtPointer)&_XmCascadeBGadClassExtRec,	/* extension */
Packit b099d7
    },
Packit b099d7
    {			/* Label Class record */
Packit b099d7
	XmInheritWidgetProc,	        	/* set override callback */
Packit b099d7
	XmInheritMenuProc,      		/* menu procedures       */
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(xmcascadebuttongadgetclass) WidgetClass
Packit b099d7
	xmCascadeButtonGadgetClass = 
Packit b099d7
                          (WidgetClass) &xmCascadeButtonGadgetClassRec;
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * use caching to share arrow data
Packit b099d7
 */
Packit b099d7
static XmCacheClassPart ArrowPixmapCache = {
Packit b099d7
   {NULL, 0, 0},                /* head of class cache list */
Packit b099d7
   _XmCacheCopy,                /* Copy routine     */
Packit b099d7
   _XmArrowPixmapCacheDelete,   /* Delete routine   */
Packit b099d7
   _XmArrowPixmapCacheCompare,  /* Comparison routine   */
Packit b099d7
};
Packit b099d7
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
static void 
Packit b099d7
ClassInitialize( void )
Packit b099d7
{
Packit b099d7
  Cardinal                    wc_num_res, sc_num_res;
Packit b099d7
  XtResource                  *merged_list;
Packit b099d7
  int                         i, j;
Packit b099d7
  XtResourceList              uncompiled;
Packit b099d7
  Cardinal                    num;
Packit b099d7
Packit b099d7
/**************************************************************************
Packit b099d7
   Label's and Cascadebutton's resource lists are being merged into one
Packit b099d7
   and assigned to xmCascadeButtonGCacheObjClassRec. This is for performance
Packit b099d7
   reasons, since, instead of two calls to XtGetSubResources() XtGetSubvaluse()
Packit b099d7
   and XtSetSubvalues() for both the superclass and the widget class, now
Packit b099d7
   we have just one call with a merged resource list.
Packit b099d7
   NOTE: At this point the resource lists for Label and Cascadebutton do
Packit b099d7
         have unique entries, but if there are resources in the superclass
Packit b099d7
         that are being overwritten by the subclass then the merged_lists
Packit b099d7
         need to be created differently.
Packit b099d7
****************************************************************************/
Packit b099d7
Packit b099d7
  wc_num_res = xmCascadeButtonGCacheObjClassRec.object_class.num_resources;
Packit b099d7
Packit b099d7
  sc_num_res = xmLabelGCacheObjClassRec.object_class.num_resources;
Packit b099d7
Packit b099d7
  merged_list = (XtResource *)XtMalloc((sizeof(XtResource) * (wc_num_res +
Packit b099d7
                                                                 sc_num_res)));
Packit b099d7
Packit b099d7
  _XmTransformSubResources(xmLabelGCacheObjClassRec.object_class.resources,
Packit b099d7
                           sc_num_res, &uncompiled, &num);
Packit b099d7
Packit b099d7
  for (i = 0; i < num; i++)
Packit b099d7
  {
Packit b099d7
Packit b099d7
  merged_list[i] = uncompiled[i];
Packit b099d7
Packit b099d7
  }
Packit b099d7
  XtFree((char *)uncompiled);
Packit b099d7
Packit b099d7
  for (i = 0, j = num; i < wc_num_res; i++, j++)
Packit b099d7
  {
Packit b099d7
   merged_list[j] =
Packit b099d7
        xmCascadeButtonGCacheObjClassRec.object_class.resources[i];
Packit b099d7
  }
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
  xmCascadeButtonGCacheObjClassRec.object_class.resources = merged_list;
Packit b099d7
  xmCascadeButtonGCacheObjClassRec.object_class.num_resources =
Packit b099d7
                wc_num_res + sc_num_res ;
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
Packit b099d7
  CascadeBGClassExtensionRec.record_type = XmQmotif;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * set up fast subclassing
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
ClassPartInitialize(
Packit b099d7
        WidgetClass wc )
Packit b099d7
{
Packit b099d7
  _XmFastSubclassInit (wc, XmCASCADE_BUTTON_GADGET_BIT);
Packit b099d7
Packit b099d7
  _XmLabelGCloneMenuSavvy (wc, &MenuSavvyRecord);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
*
Packit b099d7
*  SecondaryObjectCreate
Packit b099d7
*
Packit b099d7
************************************************************************/
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
SecondaryObjectCreate(
Packit b099d7
        Widget req,
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,
Packit b099d7
        Cardinal *num_args )
Packit b099d7
{
Packit b099d7
  XmBaseClassExt              *cePtr;
Packit b099d7
  XmWidgetExtData             extData;
Packit b099d7
  WidgetClass                 wc;
Packit b099d7
  Cardinal                    size;
Packit b099d7
  XtPointer                   newSec, reqSec;
Packit b099d7
Packit b099d7
  _XmProcessLock();
Packit b099d7
Packit b099d7
  cePtr = _XmGetBaseClassExtPtr(XtClass(new_w), XmQmotif);
Packit b099d7
  wc = (*cePtr)->secondaryObjectClass;
Packit b099d7
  size = wc->core_class.widget_size;
Packit b099d7
Packit b099d7
  newSec = _XmExtObjAlloc(size);
Packit b099d7
  reqSec = _XmExtObjAlloc(size);
Packit b099d7
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Since the resource lists for label and cascadebutton were merged at
Packit b099d7
     * ClassInitialize time we need to make only one call to
Packit b099d7
     * XtGetSubresources()
Packit b099d7
     */
Packit b099d7
   
Packit b099d7
/*
Packit b099d7
 *  Update pointers in instance records now so references to resources
Packit b099d7
 * in the cache record will be valid for use in CallProcs.
Packit b099d7
 * CallProcs are invoked by XtGetSubresources().
Packit b099d7
 */
Packit b099d7
 
Packit b099d7
  LabG_Cache(new_w) = &(((XmLabelGCacheObject)newSec)->label_cache);
Packit b099d7
    LabG_Cache(req) = &(((XmLabelGCacheObject)reqSec)->label_cache);
Packit b099d7
   CBG_Cache(new_w) = &(((XmCascadeButtonGCacheObject)newSec)->
Packit b099d7
			cascade_button_cache);
Packit b099d7
     CBG_Cache(req) = &(((XmCascadeButtonGCacheObject)reqSec)->
Packit b099d7
			cascade_button_cache);
Packit b099d7
Packit b099d7
  XtGetSubresources(new_w,
Packit b099d7
                    newSec,
Packit b099d7
                    NULL, NULL,
Packit b099d7
                    wc->core_class.resources,
Packit b099d7
                    wc->core_class.num_resources,
Packit b099d7
                    args, *num_args );
Packit b099d7
Packit b099d7
  extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec));
Packit b099d7
  extData->widget = (Widget)newSec;
Packit b099d7
  extData->reqWidget = (Widget)reqSec;
Packit b099d7
Packit b099d7
  ((XmCascadeButtonGCacheObject)newSec)->ext.extensionType = XmCACHE_EXTENSION;
Packit b099d7
  ((XmCascadeButtonGCacheObject)newSec)->ext.logicalParent = new_w;
Packit b099d7
Packit b099d7
  _XmPushWidgetExtData(new_w, extData,
Packit b099d7
		       ((XmCascadeButtonGCacheObject)newSec)->
Packit b099d7
		                                   ext.extensionType);
Packit b099d7
  memcpy(reqSec, newSec, size);
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  InitializePosthook
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
InitializePrehook(
Packit b099d7
        Widget req,
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,
Packit b099d7
        Cardinal *num_args )
Packit b099d7
{
Packit b099d7
  /* CR 2990: Use XmNbuttonFontList as the default. */
Packit b099d7
  if (LabG_Font(new_w) == NULL)
Packit b099d7
    LabG_Font(new_w) = XmeGetDefaultRenderTable (new_w, XmBUTTON_FONTLIST);
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  InitializePosthook
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
InitializePosthook(
Packit b099d7
        Widget req,
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,
Packit b099d7
        Cardinal *num_args )
Packit b099d7
{
Packit b099d7
    XmWidgetExtData     ext;
Packit b099d7
    XmCascadeButtonGadget  cbw = (XmCascadeButtonGadget)new_w;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
    * - register parts in cache.
Packit b099d7
    * - update cache pointers
Packit b099d7
    * - and free req
Packit b099d7
    */
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
Packit b099d7
    LabG_Cache(cbw) = (XmLabelGCacheObjPart *)
Packit b099d7
      _XmCachePart( LabG_ClassCachePart(cbw),
Packit b099d7
                    (XtPointer) LabG_Cache(cbw),
Packit b099d7
                    sizeof(XmLabelGCacheObjPart));
Packit b099d7
Packit b099d7
    CBG_Cache(cbw) = (XmCascadeButtonGCacheObjPart *)
Packit b099d7
           _XmCachePart( CBG_ClassCachePart(cbw),
Packit b099d7
                         (XtPointer) CBG_Cache(cbw),
Packit b099d7
                         sizeof(XmCascadeButtonGCacheObjPart));
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * might want to break up into per-class work that gets explicitly
Packit b099d7
    * chained. For right now, each class has to replicate all
Packit b099d7
    * superclass logic in hook routine
Packit b099d7
    */
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * free the req subobject used for comparisons
Packit b099d7
    */
Packit b099d7
    _XmPopWidgetExtData((Widget) cbw, &ext, XmCACHE_EXTENSION);
Packit b099d7
    _XmExtObjFree((XtPointer) ext->widget);
Packit b099d7
    _XmExtObjFree((XtPointer) ext->reqWidget);
Packit b099d7
    XtFree( (char *) ext);
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
/*******************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmCascadeBCacheCompare
Packit b099d7
 *
Packit b099d7
 *******************************************************************/
Packit b099d7
static int 
Packit b099d7
_XmCascadeBCacheCompare(
Packit b099d7
        XtPointer A,
Packit b099d7
        XtPointer B )
Packit b099d7
    {
Packit b099d7
    XmCascadeButtonGCacheObjPart *cascadeB_inst =
Packit b099d7
	(XmCascadeButtonGCacheObjPart *) A ;
Packit b099d7
    XmCascadeButtonGCacheObjPart *cascadeB_cache_inst =
Packit b099d7
	(XmCascadeButtonGCacheObjPart *) B ;
Packit b099d7
   if((cascadeB_inst->cascade_pixmap == cascadeB_cache_inst->cascade_pixmap) &&
Packit b099d7
      (cascadeB_inst->map_delay == cascadeB_cache_inst->map_delay) &&
Packit b099d7
      (cascadeB_inst->armed_pixmap == cascadeB_cache_inst->armed_pixmap) &&
Packit b099d7
      (cascadeB_inst->arm_gc == cascadeB_cache_inst->arm_gc) &&
Packit b099d7
      (cascadeB_inst->background_gc == cascadeB_cache_inst->background_gc)) 
Packit b099d7
        return 1;
Packit b099d7
   else
Packit b099d7
        return 0;
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
/*******************************************************************
Packit b099d7
 * _XmArrowPixmapCacheCompare()
Packit b099d7
 *******************************************************************/
Packit b099d7
int 
Packit b099d7
_XmArrowPixmapCacheCompare(
Packit b099d7
        XtPointer A,
Packit b099d7
        XtPointer B )
Packit b099d7
{
Packit b099d7
   XmArrowPixmap *arrowpix_rec = (XmArrowPixmap *) A ;
Packit b099d7
   XmArrowPixmap *arrowpix_cache_rec = (XmArrowPixmap *) B ;
Packit b099d7
Packit b099d7
   if ((arrowpix_rec->height == arrowpix_cache_rec->height) &&
Packit b099d7
       (arrowpix_rec->width == arrowpix_cache_rec->width) &&
Packit b099d7
       (arrowpix_rec->screen == arrowpix_cache_rec->screen) &&
Packit b099d7
       (arrowpix_rec->depth == arrowpix_cache_rec->depth) &&
Packit b099d7
       (arrowpix_rec->direction == arrowpix_cache_rec->direction) &&
Packit b099d7
    (arrowpix_rec->top_shadow_color ==
Packit b099d7
          arrowpix_cache_rec->top_shadow_color) &&
Packit b099d7
       (arrowpix_rec->bottom_shadow_color ==
Packit b099d7
          arrowpix_cache_rec->bottom_shadow_color) &&
Packit b099d7
       (arrowpix_rec->foreground_color ==
Packit b099d7
          arrowpix_cache_rec->foreground_color))
Packit b099d7
      return 1;
Packit b099d7
   else
Packit b099d7
      return 0;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*******************************************************************
Packit b099d7
 * _XmArrowPixmapCacheDelete()
Packit b099d7
 *******************************************************************/
Packit b099d7
void 
Packit b099d7
_XmArrowPixmapCacheDelete(
Packit b099d7
        XtPointer data )
Packit b099d7
{
Packit b099d7
        Pixmap pixmap = (Pixmap) data ;
Packit b099d7
   XmGadgetCachePtr ptr;
Packit b099d7
   XmArrowPixmap *arrowpix_rec;
Packit b099d7
Packit b099d7
   ptr =  (XmGadgetCachePtr)(ClassCacheHead(&ArrowPixmapCache)).next;
Packit b099d7
   while (ptr)
Packit b099d7
   {
Packit b099d7
     arrowpix_rec = (XmArrowPixmap *)(CacheDataPtr(ptr));
Packit b099d7
     if (pixmap == arrowpix_rec->pixmap)
Packit b099d7
     {
Packit b099d7
        if (--ptr->ref_count <= 0)
Packit b099d7
        {
Packit b099d7
          (ptr->prev)->next = ptr->next;
Packit b099d7
          if (ptr->next)                    /* not the last record */
Packit b099d7
            (ptr->next)->prev = ptr->prev;
Packit b099d7
          XmDestroyPixmap(arrowpix_rec->screen, arrowpix_rec->pixmap);
Packit b099d7
          XtFree( (char *) ptr);
Packit b099d7
        }
Packit b099d7
        return;
Packit b099d7
     }
Packit b099d7
     else
Packit b099d7
        ptr = (XmGadgetCachePtr)ptr->next;
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Border highlighting is only allowed for option menus.  Otherwise
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
        XmCascadeButtonGadget cb = (XmCascadeButtonGadget) wid ;
Packit b099d7
   if (LabG_MenuType(cb) == XmMENU_OPTION)
Packit b099d7
      (* ((XmGadgetClass) xmGadgetClass)->
Packit b099d7
             gadget_class.border_highlight) ((Widget) cb);
Packit b099d7
Packit b099d7
   else
Packit b099d7
      Arm (cb);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Border unhighlighting only done in option menus.  Otherwise the button
Packit b099d7
 * is disarmed (does not pop down submenus).
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
BorderUnhighlight(
Packit b099d7
        Widget wid )
Packit b099d7
{
Packit b099d7
        XmCascadeButtonGadget cb = (XmCascadeButtonGadget) wid ;
Packit b099d7
   if (LabG_MenuType(cb) == XmMENU_OPTION)
Packit b099d7
      (* ((XmGadgetClass) xmGadgetClass)->
Packit b099d7
             gadget_class.border_unhighlight) ((Widget) cb);
Packit b099d7
Packit b099d7
   else
Packit b099d7
      Disarm (cb, False);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Draw the 3D shadow around the widget if its in an option menu or if the
Packit b099d7
 * widget is armed.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
DrawShadow(
Packit b099d7
        XmCascadeButtonGadget cb )
Packit b099d7
{
Packit b099d7
  XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay((Widget) cb));
Packit b099d7
  Boolean etched_in;
Packit b099d7
Packit b099d7
  etched_in = dpy -> display.enable_etched_in_menu 
Packit b099d7
    && (! (LabG_MenuType(cb) == XmMENU_OPTION)) ;
Packit b099d7
Packit b099d7
  if (CBG_IsArmed(cb) ||
Packit b099d7
      (LabG_MenuType(cb) == XmMENU_OPTION))
Packit b099d7
    {
Packit b099d7
      if (XtIsRealized(XtParent(cb)))
Packit b099d7
      {
Packit b099d7
	 XmeDrawShadows (XtDisplay (cb), XtWindow (XtParent(cb)),
Packit b099d7
			LabG_TopShadowGC(cb),
Packit b099d7
			LabG_BottomShadowGC(cb),
Packit b099d7
			cb->gadget.highlight_thickness + cb->rectangle.x,
Packit b099d7
			cb->gadget.highlight_thickness + cb->rectangle.y,
Packit b099d7
			 cb->rectangle.width - 2 * 
Packit b099d7
			cb->gadget.highlight_thickness,
Packit b099d7
			 cb->rectangle.height - 2 * 
Packit b099d7
			cb->gadget.highlight_thickness,
Packit b099d7
			cb->gadget.shadow_thickness,
Packit b099d7
			etched_in ? XmSHADOW_IN : XmSHADOW_OUT);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
DrawCascade(
Packit b099d7
        register XmCascadeButtonGadget cb )
Packit b099d7
{
Packit b099d7
   if ((CBG_HasCascade(cb)) && (CBG_Cascade_width(cb) != 0))
Packit b099d7
   {
Packit b099d7
      /* draw the casacade */
Packit b099d7
      if ((LabG_MenuType(cb) == XmMENU_OPTION) &&
Packit b099d7
	  (CBG_CascadePixmap(cb) == XmUNSPECIFIED_PIXMAP))
Packit b099d7
      {
Packit b099d7
	 Dimension height, width;
Packit b099d7
	 Dimension offset_y;
Packit b099d7
         Dimension offset_x;
Packit b099d7
Packit b099d7
	 switch(CBG_Cascade_height(cb) - 2*G_ShadowThickness(cb)) {
Packit b099d7
	    case 5:
Packit b099d7
	    case 6:
Packit b099d7
	       height = 1;
Packit b099d7
	       width =  CBG_Cascade_width(cb) - 3;
Packit b099d7
	       break;
Packit b099d7
	    case 7:
Packit b099d7
	    case 8:
Packit b099d7
	    case 9:
Packit b099d7
	       height = 2;
Packit b099d7
	       width =  CBG_Cascade_width(cb) - 4;
Packit b099d7
	       break;
Packit b099d7
	    case 10:
Packit b099d7
	    case 11:
Packit b099d7
	    case 12:
Packit b099d7
	    case 13:
Packit b099d7
	       height = 3;
Packit b099d7
	       width =  CBG_Cascade_width(cb) - 5;
Packit b099d7
	       break;
Packit b099d7
	    default:
Packit b099d7
	       height = 4;
Packit b099d7
	       width =  CBG_Cascade_width(cb) - 6;
Packit b099d7
	       break;
Packit b099d7
	 }
Packit b099d7
	 width -= 2*G_ShadowThickness(cb);
Packit b099d7
	 offset_y =  (CBG_Cascade_height(cb)- height)/2;
Packit b099d7
Packit b099d7
	 if (LayoutIsRtoLG(cb))
Packit b099d7
	   {
Packit b099d7
	     offset_x = (CBG_Cascade_width(cb) - width - G_ShadowThickness(cb));
Packit b099d7
	     XFillRectangle(XtDisplay(cb), XtWindow(XtParent(cb)),
Packit b099d7
			    LabG_BackgroundGC(cb),
Packit b099d7
			    cb->rectangle.x + CBG_Cascade_x(cb) + offset_x,
Packit b099d7
			    cb->rectangle.y + CBG_Cascade_y(cb) + offset_y,
Packit b099d7
			    width, height);
Packit b099d7
	     
Packit b099d7
	     XmeDrawShadows(XtDisplay(cb), XtWindow(XtParent(cb)),
Packit b099d7
			    LabG_TopShadowGC(cb), LabG_BottomShadowGC(cb),
Packit b099d7
			    cb->rectangle.x + CBG_Cascade_x(cb) + offset_x -
Packit b099d7
			    G_ShadowThickness(cb),
Packit b099d7
			    cb->rectangle.y + CBG_Cascade_y(cb) + offset_y -
Packit b099d7
			    G_ShadowThickness(cb),
Packit b099d7
			    width + (2* G_ShadowThickness(cb)),
Packit b099d7
			    height +  (2* G_ShadowThickness(cb)),
Packit b099d7
			    G_ShadowThickness(cb),
Packit b099d7
			    XmSHADOW_OUT);
Packit b099d7
	   }
Packit b099d7
	 else
Packit b099d7
	   {
Packit b099d7
	     XFillRectangle(XtDisplay(cb), XtWindow(XtParent(cb)),
Packit b099d7
			    LabG_BackgroundGC(cb),
Packit b099d7
			    cb->rectangle.x + CBG_Cascade_x(cb) + 
Packit b099d7
			    G_ShadowThickness(cb),
Packit b099d7
			    cb->rectangle.y + CBG_Cascade_y(cb) + offset_y,
Packit b099d7
			    width, height);
Packit b099d7
	    
Packit b099d7
	     XmeDrawShadows(XtDisplay(cb), XtWindow(XtParent(cb)),
Packit b099d7
			    LabG_TopShadowGC(cb), LabG_BottomShadowGC(cb),
Packit b099d7
			    cb->rectangle.x + CBG_Cascade_x(cb),
Packit b099d7
			    cb->rectangle.y + CBG_Cascade_y(cb) + offset_y -
Packit b099d7
			    G_ShadowThickness(cb),
Packit b099d7
			    width + (2* G_ShadowThickness(cb)),
Packit b099d7
			    height +  (2* G_ShadowThickness(cb)),
Packit b099d7
			    G_ShadowThickness(cb), XmSHADOW_OUT);
Packit b099d7
	   }
Packit b099d7
      }
Packit b099d7
      else {
Packit b099d7
	  Pixmap pixmap ;
Packit b099d7
	  int depth ;
Packit b099d7
Packit b099d7
	  pixmap = CBG_IsArmed(cb) && 
Packit b099d7
	      (CBG_ArmedPixmap(cb) != XmUNSPECIFIED_PIXMAP) ?
Packit b099d7
		  CBG_ArmedPixmap(cb) : CBG_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 == XtParent(cb)->core.depth)
Packit b099d7
	      XCopyArea (XtDisplay(cb), pixmap, 
Packit b099d7
			 XtWindow(XtParent(cb)),
Packit b099d7
			 LabG_NormalGC(cb), 0, 0, 
Packit b099d7
			 CBG_Cascade_width(cb), CBG_Cascade_height(cb),
Packit b099d7
			 cb->rectangle.x + CBG_Cascade_x(cb), 
Packit b099d7
			 cb->rectangle.y + CBG_Cascade_y(cb));
Packit b099d7
	 else 
Packit b099d7
	 if (depth == 1) 
Packit b099d7
	     XCopyPlane (XtDisplay(cb), pixmap, 
Packit b099d7
			 XtWindow(XtParent(cb)),
Packit b099d7
			 LabG_NormalGC(cb), 0, 0, 
Packit b099d7
			 CBG_Cascade_width(cb), CBG_Cascade_height(cb),
Packit b099d7
			 cb->rectangle.x + CBG_Cascade_x(cb), 
Packit b099d7
			 cb->rectangle.y + CBG_Cascade_y(cb), 1);
Packit b099d7
      }
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
        XmCascadeButtonGadget cascadebtn )
Packit b099d7
{
Packit b099d7
   Dimension buffer;
Packit b099d7
Packit b099d7
   if (CBG_HasCascade(cascadebtn))
Packit b099d7
   { 
Packit b099d7
      if (LayoutIsRtoLG(cascadebtn))
Packit b099d7
         CBG_Cascade_x(cascadebtn) = cascadebtn->gadget.highlight_thickness +
Packit b099d7
                                     cascadebtn->gadget.shadow_thickness +
Packit b099d7
                                     LabG_MarginWidth(cascadebtn);
Packit b099d7
      else
Packit b099d7
	CBG_Cascade_x(cascadebtn) = cascadebtn->rectangle.width -
Packit b099d7
	                            cascadebtn->gadget.highlight_thickness -
Packit b099d7
	                            cascadebtn->gadget.shadow_thickness -
Packit b099d7
	                            LabG_MarginWidth(cascadebtn) -
Packit b099d7
		                    CBG_Cascade_width(cascadebtn);
Packit b099d7
Packit b099d7
      buffer = cascadebtn->gadget.highlight_thickness +
Packit b099d7
             cascadebtn->gadget.shadow_thickness +
Packit b099d7
             LabG_MarginHeight(cascadebtn);
Packit b099d7
Packit b099d7
      CBG_Cascade_y(cascadebtn) = buffer +
Packit b099d7
                               ((cascadebtn->rectangle.height -  2*buffer) -
Packit b099d7
                                CBG_Cascade_height(cascadebtn)) / 2;
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      CBG_Cascade_y(cascadebtn) = 0;
Packit b099d7
      CBG_Cascade_x(cascadebtn) = 0;
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * redisplay the widget
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Redisplay(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        Region region )
Packit b099d7
{
Packit b099d7
        XmCascadeButtonGadget cb = (XmCascadeButtonGadget) wid ;
Packit b099d7
	XtExposeProc expose;
Packit b099d7
Packit b099d7
    if (XtIsRealized ((Widget)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
       
Packit b099d7
       if (LabG_IsMenupane(cb))
Packit b099d7
       {
Packit b099d7
	  XmMenuShellWidget mshell = (XmMenuShellWidget)XtParent(XtParent(cb));
Packit b099d7
Packit b099d7
	  if (!mshell->shell.popped_up)
Packit b099d7
	      return;
Packit b099d7
       }
Packit b099d7
Packit b099d7
       /*
Packit b099d7
	* This might be necessary in an option menu to keep the glyph from
Packit b099d7
	* moving when it's items vary in size.
Packit b099d7
	*/
Packit b099d7
       if (LabG_MenuType(cb) == XmMENU_OPTION)
Packit b099d7
          position_cascade(cb);
Packit b099d7
Packit b099d7
	if (etched_in) {
Packit b099d7
	    XFillRectangle (XtDisplay(cb), XtWindow(XtParent(cb)),
Packit b099d7
	                CBG_IsArmed(cb) ? CBG_ArmGC(cb) : CBG_BackgroundGC(cb),
Packit b099d7
			    cb->rectangle.x, cb->rectangle.y,
Packit b099d7
			    cb->rectangle.width, cb->rectangle.height);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (etched_in && CBG_IsArmed(cb)) {
Packit b099d7
	    Pixel	junk, select_pix;
Packit b099d7
	    XmManagerWidget mw = (XmManagerWidget) XtParent(cb);
Packit b099d7
	    Boolean replaceGC = False;
Packit b099d7
#ifdef FIX_1395
Packit b099d7
	    XGCValues values;
Packit b099d7
	    GC tmp_bgc = NULL;
Packit b099d7
#endif
Packit b099d7
Packit b099d7
	    XmGetColors(XtScreen(mw), mw->core.colormap,
Packit b099d7
		mw->core.background_pixel,
Packit b099d7
                &junk, &junk, &junk, &select_pix);
Packit b099d7
Packit b099d7
	    if (select_pix == mw->manager.foreground) {
Packit b099d7
		/* mw->core.background_pixel */
Packit b099d7
		replaceGC = True;
Packit b099d7
		tmpGC = LabG_NormalGC(cb);
Packit b099d7
		LabG_NormalGC(cb) = CBG_BackgroundGC(cb);
Packit b099d7
	    }
Packit b099d7
#ifdef FIX_1395
Packit b099d7
	    /* Fetch the select_color GetGC() actually used. */
Packit b099d7
	    XGetGCValues(XtDisplay(cb), LabG_BackgroundGC(cb), GCBackground, &values);
Packit b099d7
	    if (values.background != select_pix)
Packit b099d7
	    {
Packit b099d7
			values.background = select_pix;
Packit b099d7
			XChangeGC(XtDisplay((Widget)cb), LabG_BackgroundGC(cb), GCBackground, &values);
Packit b099d7
		}
Packit b099d7
	    tmp_bgc = LabG_BackgroundGC(cb);
Packit b099d7
	    LabG_BackgroundGC(cb) = CBG_ArmGC(cb);
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
	    _XmProcessLock();
Packit b099d7
	    expose = xmLabelGadgetClassRec.rect_class.expose;
Packit b099d7
	    _XmProcessUnlock();
Packit b099d7
	    (* expose)((Widget)cb, event, region);
Packit b099d7
Packit b099d7
#ifdef FIX_1395	    
Packit b099d7
	    /* Restore default bg GC*/
Packit b099d7
	    LabG_BackgroundGC(cb) = tmp_bgc;
Packit b099d7
#endif
Packit b099d7
Packit b099d7
	    if (replaceGC)
Packit b099d7
		LabG_NormalGC(cb) = tmpGC;
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
       
Packit b099d7
	    /* Label class does most of the work */
Packit b099d7
	    _XmProcessLock();
Packit b099d7
	    expose = xmLabelGadgetClassRec.rect_class.expose;
Packit b099d7
	    _XmProcessUnlock();
Packit b099d7
	    (* expose)((Widget)cb, event, region);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	DrawCascade(cb);
Packit b099d7
	DrawShadow (cb);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Input sent by a manager is dispatched here.  The gadget handles Arm,
Packit b099d7
 * Activate, Enter, Leave, FocusIn, FocusOut and Help events.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
InputDispatch(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        Mask event_mask )
Packit b099d7
{
Packit b099d7
        XmCascadeButtonGadget cb = (XmCascadeButtonGadget) wid ;
Packit b099d7
   if (event_mask & XmARM_EVENT)
Packit b099d7
   {
Packit b099d7
      if (LabG_MenuType(cb) == XmMENU_OPTION)
Packit b099d7
         ArmAndPost (cb, event);
Packit b099d7
Packit b099d7
      else if (LabG_MenuType(cb) == XmMENU_BAR)
Packit b099d7
	  MenuBarSelect ((Widget) cb, event);
Packit b099d7
      
Packit b099d7
      else 
Packit b099d7
         StartDrag (cb, event);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else if (event_mask & XmBDRAG_EVENT)
Packit b099d7
   {
Packit b099d7
      _XmProcessDrag ((Widget) cb, event, NULL, NULL);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else if (event_mask & XmACTIVATE_EVENT)
Packit b099d7
   {
Packit b099d7
      if ((LabG_MenuType(cb) == XmMENU_PULLDOWN) ||
Packit b099d7
          (LabG_MenuType(cb) == XmMENU_POPUP) ||
Packit b099d7
	  (LabG_MenuType(cb) == XmMENU_BAR))
Packit b099d7
      {
Packit b099d7
          if (event->type == ButtonRelease)
Packit b099d7
             DoSelect (cb, event);
Packit b099d7
Packit b099d7
          else if (event->type == KeyPress)
Packit b099d7
             KeySelect (cb, event);
Packit b099d7
      }
Packit b099d7
      /* else option menu - do nothing if menu was not posted on btndown */
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else if (event_mask & XmENTER_EVENT)
Packit b099d7
   {
Packit b099d7
      if (LabG_MenuType(cb) == XmMENU_BAR)
Packit b099d7
	  MenuBarEnter ((Widget) cb, event);
Packit b099d7
Packit b099d7
      else if (LabG_MenuType(cb) == XmMENU_OPTION)
Packit b099d7
	  _XmEnterGadget ((Widget) cb, event, NULL, NULL);
Packit b099d7
Packit b099d7
      else 
Packit b099d7
	  DelayedArm (cb, event);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else if (event_mask & XmLEAVE_EVENT)
Packit b099d7
   {
Packit b099d7
      if (LabG_MenuType(cb) == XmMENU_BAR)
Packit b099d7
	  MenuBarLeave ((Widget) cb);
Packit b099d7
      else if (LabG_MenuType(cb) == XmMENU_OPTION)
Packit b099d7
	  _XmLeaveGadget( (Widget) cb, event, NULL, NULL);
Packit b099d7
      else
Packit b099d7
	  CheckDisarm (cb, event);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else if (event_mask & XmFOCUS_IN_EVENT)
Packit b099d7
      (* (((XmCascadeButtonGadgetClassRec *)(cb->object.widget_class))->
Packit b099d7
		gadget_class.border_highlight)) ((Widget) cb);
Packit b099d7
Packit b099d7
   else if (event_mask & XmFOCUS_OUT_EVENT)
Packit b099d7
   {
Packit b099d7
      if (LabG_IsMenupane(cb) &&
Packit b099d7
          (((XmManagerWidget)XtParent(cb))->manager.active_child == wid) &&
Packit b099d7
	  CBG_Submenu(cb))
Packit b099d7
      {
Packit b099d7
	  XmMenuShellWidget mshell =
Packit b099d7
	      (XmMenuShellWidget) XtParent(CBG_Submenu(cb));
Packit b099d7
Packit b099d7
	  if ((mshell->composite.children[0] == CBG_Submenu(cb)) &&
Packit b099d7
	      (XmIsMenuShell(mshell)) &&
Packit b099d7
	      (mshell->shell.popped_up))
Packit b099d7
	  {
Packit b099d7
	    return;
Packit b099d7
	  }
Packit b099d7
      }
Packit b099d7
Packit b099d7
      (* (((XmCascadeButtonGadgetClassRec *)(cb->object.widget_class))->
Packit b099d7
		gadget_class.border_unhighlight)) ((Widget) cb);
Packit b099d7
    } 
Packit b099d7
    else if (event_mask & XmHELP_EVENT)
Packit b099d7
       _XmCBHelp((Widget) cb, event, NULL, NULL); 
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Arming the CascadeButtonGadget consists of setting the armed bit
Packit b099d7
 * and drawing the 3D shadow.  CascadeButtonGadgets in
Packit b099d7
 * option menus are never armed since they will never get the event
Packit b099d7
 * to cause it to unarm.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Arm(
Packit b099d7
        XmCascadeButtonGadget cb )
Packit b099d7
{
Packit b099d7
   if ((LabG_MenuType(cb) != XmMENU_OPTION) &&
Packit b099d7
       (! CBG_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
      CBG_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
   XmProcessTraversal((Widget) cb, XmTRAVERSE_CURRENT);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Post any submenus and then arm the gadget.  The order is important for
Packit b099d7
 * performance.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
ArmAndPost(
Packit b099d7
        XmCascadeButtonGadget cb,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
   XmMenuState mst = _XmGetMenuState((Widget)cb);
Packit b099d7
   XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
   menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
     XmeTraitGet((XtPointer) XtClass(XtParent(cb)), XmQTmenuSystem);
Packit b099d7
Packit b099d7
   if (menuSTrait == NULL) return;
Packit b099d7
Packit b099d7
   if (!CBG_IsArmed(cb))
Packit b099d7
   {
Packit b099d7
      if ((LabG_MenuType(cb) == XmMENU_OPTION) &&
Packit b099d7
	  (XtParent(cb) == mst->RC_ReplayInfo.toplevel_menu) &&
Packit b099d7
	  (event->xbutton.time == mst->RC_ReplayInfo.time))
Packit b099d7
	 return;
Packit b099d7
Packit b099d7
      _XmCascadingPopup ((Widget) cb, event, TRUE);
Packit b099d7
      Arm(cb);
Packit b099d7
Packit b099d7
      /*
Packit b099d7
       * Option menus must be armed since the post just arms the
Packit b099d7
       * submenu
Packit b099d7
       */
Packit b099d7
      if (LabG_MenuType(cb) == XmMENU_OPTION)
Packit b099d7
      {
Packit b099d7
	menuSTrait -> arm((Widget) cb);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      /*
Packit b099d7
       * Record so spring loaded DispatchEvent() doesn't handle this event
Packit b099d7
       */
Packit b099d7
      if (event)
Packit b099d7
	  _XmRecordEvent(event);
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
   XmCascadeButtonGadget cb = (XmCascadeButtonGadget) wid ;
Packit b099d7
   XmAnyCallbackStruct cback;
Packit b099d7
   XmRowColumnWidget parent = (XmRowColumnWidget) XtParent(cb);
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
Packit b099d7
   /* check if event has been processed */
Packit b099d7
   if (event && !_XmIsEventUnique(event))
Packit b099d7
      return;
Packit b099d7
Packit b099d7
   if (menuSTrait == NULL) return;
Packit b099d7
Packit b099d7
   switch (LabG_MenuType(cb))
Packit b099d7
   {
Packit b099d7
    case XmMENU_OPTION:
Packit b099d7
    {
Packit b099d7
       ArmAndPost (cb, event);
Packit b099d7
       if (CBG_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(CBG_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(CBG_Submenu(cb));
Packit b099d7
             XtSetKeyboardFocus(XtParent(CBG_Submenu(cb)), CBG_Submenu(cb));
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
Packit b099d7
       Select (cb, event, TRUE);
Packit b099d7
       if (CBG_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(CBG_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(CBG_Submenu(cb));
Packit b099d7
             XtSetKeyboardFocus(XtParent(CBG_Submenu(cb)), CBG_Submenu(cb));
Packit b099d7
	  }
Packit b099d7
       }
Packit b099d7
       break;
Packit b099d7
    }
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 (CBG_Submenu(cb))
Packit b099d7
	   myShell = (ShellWidget)XtParent(CBG_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] == CBG_Submenu(cb)) &&
Packit b099d7
	   (cb == (XmCascadeButtonGadget)RC_CascadeBtn(CBG_Submenu(cb))))
Packit b099d7
       {
Packit b099d7
	  menuSTrait -> popdown((Widget) parent, event);
Packit b099d7
	  Disarm (cb, FALSE);
Packit b099d7
       }
Packit b099d7
Packit b099d7
       else 
Packit b099d7
       {
Packit b099d7
	  /* call the cascading callbacks first thing */
Packit b099d7
	  cback.reason = XmCR_CASCADING;
Packit b099d7
	  cback.event = event;
Packit b099d7
	  XtCallCallbackList ((Widget) cb, CBG_CascadeCall(cb), &cback);
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 (CBG_Traversing(cb) && !CBG_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
	     if (CBG_Submenu (cb) && menuSTrait != NULL)
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 (CBG_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(CBG_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(CBG_Submenu(cb));
Packit b099d7
                XtSetKeyboardFocus(XtParent(CBG_Submenu(cb)), CBG_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(XtParent(cb), _time);
Packit b099d7
	  }
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
Packit b099d7
 * and removing the timeout to post a submenu.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Disarm(
Packit b099d7
        XmCascadeButtonGadget 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 (CBG_IsArmed(cb))
Packit b099d7
   {
Packit b099d7
      CBG_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))
Packit b099d7
	      (RC_PopupPosted(rowcol),NULL, NULL, NULL);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      /* if a delayed arm is pending, remove it */
Packit b099d7
      if (CBG_Timer(cb))
Packit b099d7
      {
Packit b099d7
         XtRemoveTimeOut (CBG_Timer(cb));
Packit b099d7
         CBG_Timer(cb) = 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(rowcol))
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
		 XmeDrawHighlight(XtDisplay(cb),
Packit b099d7
				  XtWindow(cb), 
Packit b099d7
				  LabG_BackgroundGC(cb), 
Packit b099d7
			    cb->gadget.highlight_thickness + cb->rectangle.x,
Packit b099d7
			    cb->gadget.highlight_thickness + cb->rectangle.y,
Packit b099d7
				  cb->rectangle.width - 2 * 
Packit b099d7
				  cb->gadget.highlight_thickness,
Packit b099d7
				  cb->rectangle.height - 2 * 
Packit b099d7
				  cb->gadget.highlight_thickness,
Packit b099d7
				  cb->gadget.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
        XmCascadeButtonGadget cb = (XmCascadeButtonGadget) closure ;
Packit b099d7
Packit b099d7
   if (CBG_Timer(cb))
Packit b099d7
   {
Packit b099d7
      CBG_Timer(cb) = 0;
Packit b099d7
    
Packit b099d7
      _XmCascadingPopup ((Widget) cb, NULL, TRUE);
Packit b099d7
Packit b099d7
   }
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
static void 
Packit b099d7
DelayedArm(
Packit b099d7
        XmCascadeButtonGadget cb,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
   if ((! CBG_IsArmed(cb)) &&
Packit b099d7
       (((XmMenuShellWidget) XtParent(XtParent(cb)))->shell.popped_up) &&
Packit b099d7
       _XmGetInDragMode((Widget) cb))
Packit b099d7
Packit b099d7
   {
Packit b099d7
      if (CBG_MapDelay(cb) <= 0)
Packit b099d7
      {
Packit b099d7
	 /* don't delay, just do it */
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
	 /* NOTE!! XtAppAddTimeOut returns XtIntervalId (unsigned long)
Packit b099d7
	  * but the timer field was declared as an int in this gadget.
Packit b099d7
	  * 
Packit b099d7
	  */
Packit b099d7
         CBG_Timer(cb) = 
Packit b099d7
	   XtAppAddTimeOut(XtWidgetToApplicationContext( (Widget) cb), 
Packit b099d7
			   (unsigned long) CBG_MapDelay(cb),
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
 * CascadeButtonGadget.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
CheckDisarm(
Packit b099d7
        XmCascadeButtonGadget cb,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
   XmMenuShellWidget submenushell;
Packit b099d7
   XMotionEvent * entEvent = (XMotionEvent *) event;
Packit b099d7
Packit b099d7
   if (_XmGetInDragMode((Widget) cb))
Packit b099d7
   {
Packit b099d7
      if ((CBG_IsArmed(cb)) && 
Packit b099d7
          (CBG_Submenu(cb)))
Packit b099d7
      {
Packit b099d7
         submenushell = (XmMenuShellWidget) XtParent (CBG_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
      Disarm (cb, TRUE);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * post submenu and disable traversal.  These functions must be called
Packit b099d7
 * in this order.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
StartDrag(
Packit b099d7
        XmCascadeButtonGadget cb,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
   XmRowColumnWidget parent = (XmRowColumnWidget) XtParent(cb);
Packit b099d7
   XmMenuShellWidget mshell = (XmMenuShellWidget) XtParent(parent);
Packit b099d7
   XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
   menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
     XmeTraitGet((XtPointer) XtClass(XtParent(cb)), XmQTmenuSystem);
Packit b099d7
Packit b099d7
   /* Start with posted submenu bit reset */
Packit b099d7
   CBG_SetWasPosted(cb, FALSE);
Packit b099d7
Packit b099d7
   if (CBG_Submenu(cb) &&
Packit b099d7
       RC_IsArmed ((XmRowColumnWidget) CBG_Submenu(cb))) {
Packit b099d7
     CBG_SetWasPosted(cb, TRUE);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   if (LabG_IsMenupane(cb) &&
Packit b099d7
       ! mshell->shell.popped_up)
Packit b099d7
   {
Packit b099d7
      return;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /* In case the tear off is active but not armed or grabbed */
Packit b099d7
   if (menuSTrait != NULL) 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

Packit b099d7
/*
Packit b099d7
 * do the popup and if there is not a submenu, bring down the menu system.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Select(
Packit b099d7
        XmCascadeButtonGadget 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 (CBG_WasPosted(cb)) {
Packit b099d7
     Disarm(cb, TRUE);
Packit b099d7
     if ((CBG_Submenu(cb) != NULL) && (LabG_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 cascadeing callbacks
Packit b099d7
    */
Packit b099d7
   if (CBG_Submenu(cb) == NULL)
Packit b099d7
   {
Packit b099d7
      if (menuSTrait != NULL) 
Packit b099d7
	menuSTrait -> popdown(XtParent(cb), event); 
Packit b099d7
Packit b099d7
      Disarm (cb, FALSE);
Packit b099d7
Packit b099d7
      if (menuSTrait != NULL) 
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
	menuSTrait -> entryCallback(XtParent(cb), (Widget) cb,
Packit b099d7
					     &cback);
Packit b099d7
Packit b099d7
      if ((! LabG_SkipCallback(cb)) &&
Packit b099d7
	  (CBG_ActivateCall(cb)))
Packit b099d7
      {
Packit b099d7
	 XtCallCallbackList ((Widget) cb, CBG_ActivateCall(cb), &cback);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
   else 
Packit b099d7
   { 
Packit b099d7
      Arm (cb); 
Packit b099d7
   }
Packit b099d7
}
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
static void 
Packit b099d7
DoSelect(
Packit b099d7
        XmCascadeButtonGadget cb,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
  Time _time = _XmGetDefaultTime((Widget) cb, event);
Packit b099d7
Packit b099d7
   if ((LabG_MenuType(cb) == XmMENU_BAR) &&
Packit b099d7
       ! 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 (LabG_IsMenupane(cb) &&
Packit b099d7
       (!((XmMenuShellWidget) XtParent(XtParent(cb)))->shell.popped_up))
Packit b099d7
   {
Packit b099d7
      return;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   Select(cb, event, (Boolean)(CBG_Submenu(cb) != NULL));
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * don't let the menu shell widget process this event
Packit b099d7
    */
Packit b099d7
   _XmRecordEvent (event);
Packit b099d7
   
Packit b099d7
   _XmSetInDragMode((Widget) cb, False);
Packit b099d7
Packit b099d7
   if (CBG_Submenu(cb))
Packit b099d7
   {
Packit b099d7
      /*
Packit b099d7
       * if XmProcessTraversal() fails, it's possible that the pane has
Packit b099d7
       * no traversable children, so reset the focus to the pane.
Packit b099d7
       */
Packit b099d7
      if (!XmProcessTraversal(CBG_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(CBG_Submenu(cb));
Packit b099d7
         XtSetKeyboardFocus(XtParent(CBG_Submenu(cb)), CBG_Submenu(cb));
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      /* *** Move this call to Select() ***
Packit b099d7
       *
Packit b099d7
       * (* xmLabelGadgetClassRec.label_class.menuProcs)
Packit b099d7
       *    (XmMENU_DISARM, XtParent(cb));
Packit b099d7
       */
Packit b099d7
Packit b099d7
      if (LabG_MenuType(cb) == XmMENU_BAR)
Packit b099d7
      {
Packit b099d7
	 _XmMenuFocus(XtParent(cb), XmMENU_END, _time);
Packit b099d7
	 XtUngrabPointer(XtParent(cb), _time);
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
static void 
Packit b099d7
KeySelect(
Packit b099d7
        XmCascadeButtonGadget cb,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
   XmRowColumnWidget parent = (XmRowColumnWidget) XtParent(cb);
Packit b099d7
   XmMenuSystemTrait menuSTrait;
Packit b099d7
Packit b099d7
   /* check if event has been processed */
Packit b099d7
   if (!_XmIsEventUnique(event))
Packit b099d7
      return;
Packit b099d7
Packit b099d7
   if (!_XmGetInDragMode((Widget) cb) && RC_IsArmed(parent))
Packit b099d7
   {
Packit b099d7
      if (LabG_MenuType(cb) == XmMENU_BAR) {
Packit b099d7
	menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
	  XmeTraitGet((XtPointer) XtClass(XtParent(cb)), XmQTmenuSystem);
Packit b099d7
	if (menuSTrait != NULL)
Packit b099d7
	  menuSTrait -> menuBarCleanup((Widget) parent);
Packit b099d7
      }
Packit b099d7
	  
Packit b099d7
      Select(cb, event, TRUE);
Packit b099d7
Packit b099d7
      if (CBG_Submenu(cb)) 
Packit b099d7
      {
Packit b099d7
         XmProcessTraversal(CBG_Submenu(cb), XmTRAVERSE_CURRENT);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /* record so that menuShell does not process this event */
Packit b099d7
   _XmRecordEvent(event);
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
{
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
Packit b099d7
   if (menuSTrait == NULL) return;
Packit b099d7
Packit b099d7
   CBG_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 (!CBG_Submenu(cb))
Packit b099d7
      {
Packit b099d7
	 _XmMenuFocus(XtParent(cb), XmMENU_MIDDLE, _time);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      StartDrag ((XmCascadeButtonGadget) cb, event);
Packit b099d7
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      validButton = menuSTrait -> verifyButton(XtParent(cb), event);
Packit b099d7
   
Packit b099d7
      if (validButton)
Packit b099d7
      {
Packit b099d7
         /* Don't post the menu if the menu cannot control grabs! */
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
	 /* To support menu replay, keep the pointer in sync mode */
Packit b099d7
	 XAllowEvents(XtDisplay(cb), SyncPointer, CurrentTime);
Packit b099d7
Packit b099d7
	 if (!CBG_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
	       Cursor cursor;
Packit b099d7
Packit b099d7
	       cursor = XmGetMenuCursor(XtDisplay(cb));
Packit b099d7
Packit b099d7
               _XmGrabPointer(XtParent(cb), True, EVENTS,
Packit b099d7
                  GrabModeAsync, GrabModeAsync, None, cursor, _time);
Packit b099d7
Packit b099d7
	       RC_SetBeingArmed(XtParent(cb), False);
Packit b099d7
	    }
Packit b099d7
	 } 
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
static void 
Packit b099d7
MenuBarEnter(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
   register XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
   XmRowColumnWidget rc = (XmRowColumnWidget)XtParent(cb);
Packit b099d7
Packit b099d7
   if ((RC_IsArmed (rc)) && (! CBG_IsArmed(cb))
Packit b099d7
       && _XmGetInDragMode((Widget) cb))
Packit b099d7
   {
Packit b099d7
      if (!CBG_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((XmCascadeButtonGadget) 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
static void 
Packit b099d7
MenuBarLeave(
Packit b099d7
        Widget wid )
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
      CBG_SetWasPosted(cb, FALSE);
Packit b099d7
Packit b099d7
      if (CBG_Submenu(cb))
Packit b099d7
      {
Packit b099d7
         submenuShell = (XmMenuShellWidget) XtParent(CBG_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 ((XmCascadeButtonGadget) cb, TRUE);   
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Create the CB and CBG 3d arrows.
Packit b099d7
 * The Pixmaps must be unspecified going into this routine.  This helps to
Packit b099d7
 * make sure arrow cache is sync'd up as well as not accidentally overwriting
Packit b099d7
 * application's pixmap arrow if set.
Packit b099d7
 */
Packit b099d7
void 
Packit b099d7
_XmCreateArrowPixmaps(
Packit b099d7
        Widget wid )
Packit b099d7
{
Packit b099d7
   XmCascadeButtonWidget cb = (XmCascadeButtonWidget) wid ;
Packit b099d7
   XmArrowPixmap cpart;
Packit b099d7
   XmArrowPixmap *armed_arrow, *unarmed_arrow;
Packit b099d7
   GC gc, tsGC, bsGC;
Packit b099d7
   XGCValues values;
Packit b099d7
   Pixmap pixmap;
Packit b099d7
   int ht, st;
Packit b099d7
   Pixel tsc, bsc, bg;
Packit b099d7
   Dimension side;
Packit b099d7
   Screen *screen;
Packit b099d7
   int depth;
Packit b099d7
   unsigned char arrow_direction;
Packit b099d7
   unsigned short text_height;
Packit b099d7
   GC armGC = NULL;
Packit b099d7
   XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(cb));   
Packit b099d7
   Boolean etched_in = dpy->display.enable_etched_in_menu;
Packit b099d7
Packit b099d7
   screen = XtScreen(cb);
Packit b099d7
   if (XmIsGadget(cb))
Packit b099d7
   {
Packit b099d7
      if ((CBG_CascadePixmap(cb) != XmUNSPECIFIED_PIXMAP) &&
Packit b099d7
          (CBG_ArmedPixmap(cb) != XmUNSPECIFIED_PIXMAP))
Packit b099d7
        return;
Packit b099d7
Packit b099d7
      ht = G_HighlightThickness(cb);
Packit b099d7
      st = G_ShadowThickness(cb);
Packit b099d7
      tsc = LabG_TopShadowColor(cb);
Packit b099d7
      bsc = LabG_BottomShadowColor(cb);
Packit b099d7
      bg = LabG_Background(cb);
Packit b099d7
      tsGC = LabG_TopShadowGC(cb);
Packit b099d7
      bsGC = LabG_BottomShadowGC(cb);
Packit b099d7
      arrow_direction = (LayoutIsRtoLP(cb)) ? XmARROW_LEFT : XmARROW_RIGHT;
Packit b099d7
      text_height = LabG_TextRect_height(cb);
Packit b099d7
      depth = XtParent(cb)->core.depth;
Packit b099d7
Packit b099d7
      if (etched_in)
Packit b099d7
          armGC = CBG_ArmGC(wid);
Packit b099d7
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      Pixel       select_pixel;
Packit b099d7
Packit b099d7
      if ((CB_CascadePixmap(cb) != XmUNSPECIFIED_PIXMAP) &&
Packit b099d7
          (CB_ArmedPixmap(cb) != XmUNSPECIFIED_PIXMAP))
Packit b099d7
        return;
Packit b099d7
Packit b099d7
      XmGetColors(XtScreen(wid), wid->core.colormap,
Packit b099d7
		  wid -> core.background_pixel,
Packit b099d7
		  NULL, NULL, NULL, &select_pixel);
Packit b099d7
Packit b099d7
      if (etched_in)
Packit b099d7
      {
Packit b099d7
          values.foreground = values.background = select_pixel;
Packit b099d7
          values.graphics_exposures = False;
Packit b099d7
          armGC = XtGetGC ((Widget) wid,
Packit b099d7
              GCForeground | GCBackground | GCGraphicsExposures, &values);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      ht = cb->primitive.highlight_thickness;
Packit b099d7
      st = cb->primitive.shadow_thickness;
Packit b099d7
      tsc =  cb->primitive.top_shadow_color;
Packit b099d7
      bsc =  cb->primitive.bottom_shadow_color;
Packit b099d7
      bg = cb->core.background_pixel;
Packit b099d7
      tsGC = cb->primitive.top_shadow_GC;
Packit b099d7
      bsGC = cb->primitive.bottom_shadow_GC;
Packit b099d7
      arrow_direction = (LayoutIsRtoLP(cb)) ? XmARROW_LEFT : XmARROW_RIGHT;
Packit b099d7
      text_height = Lab_TextRect_height(cb);
Packit b099d7
      depth = cb->core.depth;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   side = MAX( (text_height * 2 / 3) + 2 * (ht + st),
Packit b099d7
	      (2*(ht + (st-1) +1)) +1 );       /* see _XmGetArrowDrawRects() */
Packit b099d7
Packit b099d7
   cpart.height = cpart.width = side;
Packit b099d7
   cpart.depth = depth;
Packit b099d7
   cpart.direction = arrow_direction;
Packit b099d7
   cpart.top_shadow_color = tsc;
Packit b099d7
   cpart.bottom_shadow_color = bsc;
Packit b099d7
   cpart.foreground_color = bg;
Packit b099d7
   cpart.display = XtDisplay(cb);
Packit b099d7
   cpart.screen = screen;
Packit b099d7
   cpart.pixmap = XmUNSPECIFIED_PIXMAP;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * Create or get an existing arrow cache record for the unarmed arrow
Packit b099d7
    */
Packit b099d7
   _XmProcessLock();
Packit b099d7
   unarmed_arrow = (XmArrowPixmap *)
Packit b099d7
       _XmCachePart(&ArrowPixmapCache, (XtPointer) &cpart,
Packit b099d7
		    sizeof(XmArrowPixmap));
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * Create or get an existing arrow cache record for the armed arrow
Packit b099d7
    */
Packit b099d7
   cpart.top_shadow_color = bsc;
Packit b099d7
   cpart.bottom_shadow_color = tsc;
Packit b099d7
Packit b099d7
   armed_arrow =  (XmArrowPixmap *)
Packit b099d7
      _XmCachePart(&ArrowPixmapCache, (XtPointer) &cpart,
Packit b099d7
		   sizeof(XmArrowPixmap));
Packit b099d7
   _XmProcessUnlock();
Packit b099d7
Packit b099d7
   if ((unarmed_arrow->pixmap == XmUNSPECIFIED_PIXMAP) ||
Packit b099d7
       (armed_arrow->pixmap == XmUNSPECIFIED_PIXMAP))
Packit b099d7
   {
Packit b099d7
      values.foreground = values.background = bg;
Packit b099d7
      values.graphics_exposures = False;
Packit b099d7
      gc = XtGetGC ((Widget) cb,
Packit b099d7
                   GCForeground | GCBackground | GCGraphicsExposures, &values);
Packit b099d7
Packit b099d7
      /* armed arrow */
Packit b099d7
      if (armed_arrow->pixmap == XmUNSPECIFIED_PIXMAP)
Packit b099d7
      {
Packit b099d7
         pixmap = XCreatePixmap(XtDisplay(cb), RootWindowOfScreen(screen),
Packit b099d7
            side, side, depth);
Packit b099d7
Packit b099d7
         armed_arrow->pixmap = pixmap;
Packit b099d7
Packit b099d7
         XFillRectangle(XtDisplay(cb), pixmap, etched_in? armGC : gc, 
Packit b099d7
			0, 0, side, side);
Packit b099d7
	 XmeDrawArrow(XtDisplay((Widget)cb), pixmap,
Packit b099d7
		bsGC, tsGC, gc,
Packit b099d7
		ht + st - 1,
Packit b099d7
		ht + st - 1,
Packit b099d7
		side - 2*(ht + st - 1),
Packit b099d7
		side - 2*(ht + st - 1),
Packit b099d7
		st, arrow_direction);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      /* standard (unarmed) pixmap */
Packit b099d7
      if (unarmed_arrow->pixmap == XmUNSPECIFIED_PIXMAP)
Packit b099d7
      {
Packit b099d7
         pixmap = XCreatePixmap(XtDisplay(cb),  RootWindowOfScreen(screen),
Packit b099d7
            side, side, depth);
Packit b099d7
Packit b099d7
         unarmed_arrow->pixmap = pixmap;
Packit b099d7
Packit b099d7
         XFillRectangle(XtDisplay(cb), pixmap, gc, 0, 0, side, side);
Packit b099d7
	 XmeDrawArrow(XtDisplay((Widget)cb), pixmap,
Packit b099d7
	 tsGC, bsGC, gc, 
Packit b099d7
	 	ht + st - 1, 
Packit b099d7
	 	ht + st - 1, 
Packit b099d7
	 	side - 2*(ht + st - 1),
Packit b099d7
	 	side - 2*(ht + st - 1), 
Packit b099d7
	 	st, arrow_direction);
Packit b099d7
      }
Packit b099d7
      XtReleaseGC( (Widget) cb, gc);
Packit b099d7
   }
Packit b099d7
   if (XmIsGadget(cb))
Packit b099d7
   {
Packit b099d7
      CBG_ArmedPixmap(cb) = armed_arrow->pixmap;
Packit b099d7
      CBG_CascadePixmap(cb) = unarmed_arrow->pixmap;
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      CB_ArmedPixmap(cb) = armed_arrow->pixmap;
Packit b099d7
      CB_CascadePixmap(cb) = unarmed_arrow->pixmap;
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
        XmCascadeButtonGadget 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 unsigned int */
Packit b099d7
Packit b099d7
    if (CBG_CascadePixmap(cascadebtn) != XmUNSPECIFIED_PIXMAP)
Packit b099d7
    {
Packit b099d7
       XGetGeometry(XtDisplay(cascadebtn), CBG_CascadePixmap(cascadebtn),
Packit b099d7
		    &rootwin, &x, &y, &width, &height,
Packit b099d7
		    &border, &depth);
Packit b099d7
Packit b099d7
       CBG_Cascade_width(cascadebtn) = (Dimension) width;
Packit b099d7
       CBG_Cascade_height(cascadebtn) = (Dimension) height;
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
       if (LabG_MenuType(cascadebtn) == XmMENU_OPTION)
Packit b099d7
       {
Packit b099d7
	  CBG_Cascade_width(cascadebtn) = 
Packit b099d7
	     CBG_Cascade_height(cascadebtn) = 
Packit b099d7
		MAX(LabG_TextRect(cascadebtn).height,
Packit b099d7
		    LabG_AccTextRect(cascadebtn).height) + 
Packit b099d7
	        2 * cascadebtn->gadget.shadow_thickness;     /* glyph shadow */
Packit b099d7
Packit b099d7
       }
Packit b099d7
       else
Packit b099d7
       {
Packit b099d7
	  CBG_Cascade_width(cascadebtn) = 0;
Packit b099d7
	  CBG_Cascade_height(cascadebtn) = 0;
Packit b099d7
       }
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
        XmCascadeButtonGadget 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 (CBG_HasCascade(cascadebtn))
Packit b099d7
   {
Packit b099d7
      /*
Packit b099d7
       *  modify the size of the CascadeButtonGadget to acommadate the
Packit b099d7
       *  cascade, if needed.  The cascade should fit inside MarginRight.
Packit b099d7
       */
Packit b099d7
      if (LayoutIsRtoLG(cascadebtn))
Packit b099d7
      {
Packit b099d7
        if ((CBG_Cascade_width(cascadebtn) + CASCADE_PIX_SPACE) >
Packit b099d7
             LabG_MarginLeft(cascadebtn))
Packit b099d7
        {
Packit b099d7
            delta = CBG_Cascade_width(cascadebtn) + CASCADE_PIX_SPACE -
Packit b099d7
                LabG_MarginLeft(cascadebtn);
Packit b099d7
            LabG_MarginLeft(cascadebtn) += delta;
Packit b099d7
Packit b099d7
            if (adjustWidth)
Packit b099d7
                cascadebtn->rectangle.width += delta;
Packit b099d7
Packit b099d7
            else
Packit b099d7
            {
Packit b099d7
               if (LabG_Alignment(cascadebtn) == XmALIGNMENT_BEGINNING)
Packit b099d7
                   LabG_TextRect_x(cascadebtn) += delta;
Packit b099d7
               else if (LabG_Alignment(cascadebtn) == XmALIGNMENT_CENTER)
Packit b099d7
                   LabG_TextRect_x(cascadebtn) += delta/2;
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
Packit b099d7
      }
Packit b099d7
      else
Packit b099d7
      {
Packit b099d7
	
Packit b099d7
	if ((CBG_Cascade_width(cascadebtn) + CASCADE_PIX_SPACE) >
Packit b099d7
	    LabG_MarginRight(cascadebtn))
Packit b099d7
	  {
Packit b099d7
	    delta = CBG_Cascade_width(cascadebtn) + CASCADE_PIX_SPACE -
Packit b099d7
	      LabG_MarginRight(cascadebtn);
Packit b099d7
	    LabG_MarginRight(cascadebtn) = LabG_MarginRight(cascadebtn) +
Packit b099d7
	      delta;
Packit b099d7
	    
Packit b099d7
	    if (adjustWidth)
Packit b099d7
	      cascadebtn->rectangle.width += delta;
Packit b099d7
	    
Packit b099d7
	    else
Packit b099d7
	      {
Packit b099d7
		if (LabG_Alignment(cascadebtn) == XmALIGNMENT_END)
Packit b099d7
		  LabG_TextRect_x(cascadebtn) -= delta;
Packit b099d7
	    else if (LabG_Alignment(cascadebtn) == XmALIGNMENT_CENTER)
Packit b099d7
	      LabG_TextRect_x(cascadebtn) -= delta/2;
Packit b099d7
		
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 = CBG_Cascade_height(cascadebtn) +
Packit b099d7
                   2 * (LabG_MarginHeight(cascadebtn) +
Packit b099d7
		         cascadebtn->gadget.shadow_thickness +
Packit b099d7
		         cascadebtn->gadget.highlight_thickness);
Packit b099d7
      
Packit b099d7
      if (delta > cascadebtn->rectangle.height)
Packit b099d7
      {
Packit b099d7
	 delta -= cascadebtn->rectangle.height;
Packit b099d7
	 LabG_MarginTop(cascadebtn) = LabG_MarginTop(cascadebtn) + 
Packit b099d7
	   (delta/2);
Packit b099d7
	 LabG_TextRect_y(cascadebtn) += delta/2;
Packit b099d7
	 LabG_MarginBottom(cascadebtn) = LabG_MarginBottom(cascadebtn) + 
Packit b099d7
	   delta - (delta/2);
Packit b099d7
	 
Packit b099d7
	 if (adjustHeight)
Packit b099d7
	     cascadebtn->rectangle.height += 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
    XmCascadeButtonGadget cb = (XmCascadeButtonGadget) wid ;
Packit b099d7
    XmRowColumnWidget submenu = (XmRowColumnWidget) CBG_Submenu(cb);
Packit b099d7
    XmMenuSystemTrait menuSTrait;
Packit b099d7
    XmManagerWidget mw = (XmManagerWidget) XtParent(cb);
Packit b099d7
Packit b099d7
    menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
      XmeTraitGet((XtPointer) XtClass(XtParent(wid)), XmQTmenuSystem);
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 (CBG_Timer(cb))
Packit b099d7
         XtRemoveTimeOut (CBG_Timer(cb));
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (CBG_ArmedPixmap(cb) != XmUNSPECIFIED_PIXMAP)
Packit b099d7
    {
Packit b099d7
       _XmArrowPixmapCacheDelete((XtPointer) CBG_ArmedPixmap(cb));
Packit b099d7
       _XmArrowPixmapCacheDelete((XtPointer) CBG_CascadePixmap(cb));
Packit b099d7
    }
Packit b099d7
 
Packit b099d7
   /* Release the GCs */
Packit b099d7
   XtReleaseGC ((Widget) mw, CBG_ArmGC(cb));
Packit b099d7
   XtReleaseGC ((Widget) mw, CBG_BackgroundGC(cb));
Packit b099d7
Packit b099d7
    _XmCacheDelete((XtPointer) CBG_Cache(cb));
Packit b099d7
    _XmProcessUnlock();
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 wid )
Packit b099d7
{
Packit b099d7
  XmCascadeButtonGadget cb = (XmCascadeButtonGadget) wid;
Packit b099d7
  XtWidgetProc resize;
Packit b099d7
  if (cb)
Packit b099d7
    {
Packit b099d7
      /* Label class does it's work */
Packit b099d7
      _XmProcessLock();
Packit b099d7
      resize = xmLabelGadgetClassRec.rect_class.resize;
Packit b099d7
      _XmProcessUnlock();
Packit b099d7
      (* resize) ((Widget) cb);
Packit b099d7
Packit b099d7
      /* move the cascade too */
Packit b099d7
      position_cascade (cb);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SetValuesPrehook
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/* ARGSUSED */
Packit b099d7
static Boolean 
Packit b099d7
SetValuesPrehook(
Packit b099d7
        Widget oldParent,
Packit b099d7
        Widget refParent,
Packit b099d7
        Widget newParent,
Packit b099d7
        ArgList args,
Packit b099d7
        Cardinal *num_args )
Packit b099d7
{
Packit b099d7
    XmWidgetExtData             extData;
Packit b099d7
    XmBaseClassExt              *cePtr;
Packit b099d7
    WidgetClass                 ec;
Packit b099d7
    Cardinal                    size;
Packit b099d7
    XmCascadeButtonGCacheObject newSec, reqSec;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
Packit b099d7
    cePtr = _XmGetBaseClassExtPtr(XtClass(newParent), XmQmotif);
Packit b099d7
    ec = (*cePtr)->secondaryObjectClass;
Packit b099d7
    size = ec->core_class.widget_size;
Packit b099d7
Packit b099d7
    newSec = (XmCascadeButtonGCacheObject)_XmExtObjAlloc(size);
Packit b099d7
    reqSec = (XmCascadeButtonGCacheObject)_XmExtObjAlloc(size);
Packit b099d7
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    newSec->object.self = (Widget)newSec;
Packit b099d7
    newSec->object.widget_class = ec;
Packit b099d7
    newSec->object.parent = XtParent(newParent);
Packit b099d7
    newSec->object.xrm_name = newParent->core.xrm_name;
Packit b099d7
    newSec->object.being_destroyed = False;
Packit b099d7
    newSec->object.destroy_callbacks = NULL;
Packit b099d7
    newSec->object.constraints = NULL;
Packit b099d7
Packit b099d7
    newSec->ext.logicalParent = newParent;
Packit b099d7
    newSec->ext.extensionType = XmCACHE_EXTENSION;
Packit b099d7
Packit b099d7
    memcpy( &(newSec->label_cache),
Packit b099d7
            LabG_Cache(newParent),
Packit b099d7
            sizeof(XmLabelGCacheObjPart));
Packit b099d7
Packit b099d7
    memcpy( &(newSec->cascade_button_cache),
Packit b099d7
            CBG_Cache(newParent),
Packit b099d7
            sizeof(XmCascadeButtonGCacheObjPart));
Packit b099d7
Packit b099d7
    extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec));
Packit b099d7
    extData->widget = (Widget)newSec;
Packit b099d7
    extData->reqWidget = (Widget)reqSec;
Packit b099d7
    _XmPushWidgetExtData(newParent, extData, XmCACHE_EXTENSION);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Since the resource lists for label and cascadebutton were merged at
Packit b099d7
     * ClassInitialize time we need to make only one call to
Packit b099d7
     * XtSetSubvalues()
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XtSetSubvalues((XtPointer)newSec,
Packit b099d7
                    ec->core_class.resources,
Packit b099d7
                    ec->core_class.num_resources,
Packit b099d7
                    args, *num_args);
Packit b099d7
Packit b099d7
    memcpy((XtPointer)reqSec, (XtPointer)newSec, size);
Packit b099d7
Packit b099d7
    LabG_Cache(newParent) = &(((XmLabelGCacheObject)newSec)->label_cache);
Packit b099d7
    LabG_Cache(refParent) = &(((XmLabelGCacheObject)extData->reqWidget)->
Packit b099d7
			      label_cache);
Packit b099d7
Packit b099d7
    CBG_Cache(newParent) =
Packit b099d7
        &(((XmCascadeButtonGCacheObject)newSec)->cascade_button_cache);
Packit b099d7
    CBG_Cache(refParent) =
Packit b099d7
        &(((XmCascadeButtonGCacheObject)extData->reqWidget)->
Packit b099d7
	  cascade_button_cache);
Packit b099d7
Packit b099d7
    _XmExtImportArgs((Widget)newSec, args, num_args);
Packit b099d7
Packit b099d7
Packit b099d7
    /* CR 2990: Use XmNbuttonFontList as the default font. */
Packit b099d7
    if (LabG_Font(newParent) == NULL)
Packit b099d7
      LabG_Font(newParent) = XmeGetDefaultRenderTable (newParent,
Packit b099d7
						       XmBUTTON_FONTLIST);
Packit b099d7
Packit b099d7
    return FALSE;
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GetValuesPrehook
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
GetValuesPrehook(
Packit b099d7
        Widget newParent,
Packit b099d7
        ArgList args,
Packit b099d7
        Cardinal *num_args )
Packit b099d7
{
Packit b099d7
    XmWidgetExtData             extData;
Packit b099d7
    XmBaseClassExt              *cePtr;
Packit b099d7
    WidgetClass                 ec;
Packit b099d7
    Cardinal 			size;
Packit b099d7
    XmCascadeButtonGCacheObject newSec;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    cePtr = _XmGetBaseClassExtPtr(XtClass(newParent), XmQmotif);
Packit b099d7
    ec = (*cePtr)->secondaryObjectClass;
Packit b099d7
    size = ec->core_class.widget_size;
Packit b099d7
Packit b099d7
    newSec = (XmCascadeButtonGCacheObject)_XmExtObjAlloc(size);
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    newSec->object.self = (Widget)newSec;
Packit b099d7
    newSec->object.widget_class = ec;
Packit b099d7
    newSec->object.parent = XtParent(newParent);
Packit b099d7
    newSec->object.xrm_name = newParent->core.xrm_name;
Packit b099d7
    newSec->object.being_destroyed = False;
Packit b099d7
    newSec->object.destroy_callbacks = NULL;
Packit b099d7
    newSec->object.constraints = NULL;
Packit b099d7
Packit b099d7
    newSec->ext.logicalParent = newParent;
Packit b099d7
    newSec->ext.extensionType = XmCACHE_EXTENSION;
Packit b099d7
Packit b099d7
    memcpy( &(newSec->label_cache),
Packit b099d7
            LabG_Cache(newParent),
Packit b099d7
            sizeof(XmLabelGCacheObjPart));
Packit b099d7
Packit b099d7
    memcpy( &(newSec->cascade_button_cache),
Packit b099d7
            CBG_Cache(newParent),
Packit b099d7
            sizeof(XmCascadeButtonGCacheObjPart));
Packit b099d7
Packit b099d7
    extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec));
Packit b099d7
    extData->widget = (Widget)newSec;
Packit b099d7
    _XmPushWidgetExtData(newParent, extData, XmCACHE_EXTENSION);
Packit b099d7
Packit b099d7
    /* Note that if a resource is defined in the superclass's as well as a
Packit b099d7
   subclass's resource list and if a NULL is passed in as the third
Packit b099d7
   argument to XtSetArg, then when a GetSubValues() is done by the
Packit b099d7
   superclass the NULL is replaced by a value. Now when the subclass
Packit b099d7
   gets the arglist it doesn't see a NULL and thinks it's an address
Packit b099d7
   it needs to stuff a value into and sure enough it breaks.
Packit b099d7
   This means that we have to pass the same arglist with the NULL to
Packit b099d7
   both the superclass and subclass and propagate the values up once
Packit b099d7
   the XtGetSubValues() are done.*/
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Since the resource lists for label and cascadebutton were merged at
Packit b099d7
     * ClassInitialize time we need to make only one call to
Packit b099d7
     * XtGetSubvalues()
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XtGetSubvalues((XtPointer)newSec,
Packit b099d7
                   ec->core_class.resources,
Packit b099d7
                   ec->core_class.num_resources,
Packit b099d7
                   args, *num_args);    
Packit b099d7
Packit b099d7
    _XmExtGetValuesHook((Widget)newSec, args, num_args);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GetValuesPosthook
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
GetValuesPosthook(
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,
Packit b099d7
        Cardinal *num_args )
Packit b099d7
{
Packit b099d7
    XmWidgetExtData             ext;
Packit b099d7
Packit b099d7
    _XmPopWidgetExtData(new_w, &ext, XmCACHE_EXTENSION);
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    _XmExtObjFree((XtPointer) ext->widget);
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    XtFree( (char *) ext);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SetValuesPosthook
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/* ARGSUSED */
Packit b099d7
static Boolean 
Packit b099d7
SetValuesPosthook(
Packit b099d7
        Widget current,
Packit b099d7
        Widget req,
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,
Packit b099d7
        Cardinal *num_args )
Packit b099d7
{
Packit b099d7
   XmWidgetExtData                  ext;
Packit b099d7
   /*
Packit b099d7
    * - register parts in cache.
Packit b099d7
    * - update cache pointers
Packit b099d7
    * - and free req
Packit b099d7
    */
Packit b099d7
Packit b099d7
  /* assign if changed! */
Packit b099d7
  _XmProcessLock();
Packit b099d7
  if (!_XmLabelCacheCompare((XtPointer)LabG_Cache(new_w),
Packit b099d7
			    (XtPointer)LabG_Cache(current)))
Packit b099d7
  {
Packit b099d7
  _XmCacheDelete((XtPointer) LabG_Cache(current));  /* delete the old one */
Packit b099d7
  LabG_Cache(new_w) = (XmLabelGCacheObjPart *)
Packit b099d7
      _XmCachePart(LabG_ClassCachePart(new_w),
Packit b099d7
		   (XtPointer) LabG_Cache(new_w),
Packit b099d7
		   sizeof(XmLabelGCacheObjPart));
Packit b099d7
  }
Packit b099d7
  else
Packit b099d7
       LabG_Cache(new_w) = LabG_Cache(current);
Packit b099d7
Packit b099d7
  /* assign if changed! */
Packit b099d7
  if (!_XmCascadeBCacheCompare((XtPointer)CBG_Cache(new_w),
Packit b099d7
                              (XtPointer)CBG_Cache(current)))
Packit b099d7
      {
Packit b099d7
      _XmCacheDelete((XtPointer) CBG_Cache(current));  /* delete the old one */
Packit b099d7
      CBG_Cache(new_w) = (XmCascadeButtonGCacheObjPart *)
Packit b099d7
	  _XmCachePart(CBG_ClassCachePart(new_w),
Packit b099d7
		       (XtPointer) CBG_Cache(new_w),
Packit b099d7
		       sizeof(XmCascadeButtonGCacheObjPart));
Packit b099d7
      }
Packit b099d7
  else
Packit b099d7
      CBG_Cache(new_w) = CBG_Cache(current);
Packit b099d7
Packit b099d7
  _XmPopWidgetExtData(new_w, &ext, XmCACHE_EXTENSION);
Packit b099d7
Packit b099d7
  _XmExtObjFree((XtPointer) ext->widget);
Packit b099d7
  _XmExtObjFree((XtPointer) ext->reqWidget);
Packit b099d7
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
Packit b099d7
  XtFree( (char *) ext);
Packit b099d7
Packit b099d7
  return FALSE;
Packit b099d7
}
Packit b099d7
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
    XmCascadeButtonGadget old = (XmCascadeButtonGadget) cw ;
Packit b099d7
    XmCascadeButtonGadget requested = (XmCascadeButtonGadget) rw ;
Packit b099d7
    XmCascadeButtonGadget new_w = (XmCascadeButtonGadget) 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 ((CBG_Submenu(new_w)) &&
Packit b099d7
	((! XmIsRowColumn(CBG_Submenu(new_w))) ||
Packit b099d7
	 (RC_Type(CBG_Submenu(new_w)) != XmMENU_PULLDOWN)))
Packit b099d7
    {
Packit b099d7
       CBG_Submenu(new_w) = NULL;
Packit b099d7
       XmeWarning( (Widget) new_w, WRONGSUBMENU);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (CBG_MapDelay(new_w) < 0) 
Packit b099d7
    {
Packit b099d7
       CBG_MapDelay(new_w) = CBG_MapDelay(old);
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 (CBG_Submenu(old) != CBG_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
       if (CBG_Submenu(old) && menuSTrait != NULL)
Packit b099d7
	 menuSTrait -> recordPostFromWidget(CBG_Submenu(old), nw, FALSE);
Packit b099d7
Packit b099d7
       if (CBG_Submenu(new_w) && menuSTrait != NULL)
Packit b099d7
	 menuSTrait -> recordPostFromWidget(CBG_Submenu(new_w), nw, TRUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (LabG_MenuType(new_w) == XmMENU_BAR)
Packit b099d7
	new_w->gadget.traversal_on = TRUE;
Packit b099d7
    
Packit b099d7
    /* handle the cascade pixmap indicator */
Packit b099d7
    else if (LabG_MenuType(new_w) == XmMENU_PULLDOWN ||
Packit b099d7
	     LabG_MenuType(new_w) == XmMENU_POPUP ||
Packit b099d7
	     LabG_MenuType(new_w) == XmMENU_OPTION)
Packit b099d7
    {
Packit b099d7
       /* don't let traversal change */
Packit b099d7
       if (LabG_MenuType(new_w) != XmMENU_OPTION)
Packit b099d7
          new_w->gadget.traversal_on = TRUE;
Packit b099d7
Packit b099d7
       if (LabG_RecomputeSize(new_w) || (requested->rectangle.width <= 0))
Packit b099d7
	  adjustWidth = TRUE;
Packit b099d7
       
Packit b099d7
       if (LabG_RecomputeSize(new_w) || (requested->rectangle.height <= 0))
Packit b099d7
	  adjustHeight = TRUE;
Packit b099d7
Packit b099d7
       /* get new pixmap size */
Packit b099d7
       if (CBG_CascadePixmap (old) != CBG_CascadePixmap (new_w))
Packit b099d7
       {
Packit b099d7
          if (CBG_ArmedPixmap(old) != XmUNSPECIFIED_PIXMAP)
Packit b099d7
          {
Packit b099d7
	     _XmProcessLock();
Packit b099d7
             _XmArrowPixmapCacheDelete((XtPointer) CBG_ArmedPixmap(old));
Packit b099d7
             _XmArrowPixmapCacheDelete((XtPointer) CBG_CascadePixmap(old));
Packit b099d7
	     _XmProcessUnlock();
Packit b099d7
          }
Packit b099d7
          CBG_ArmedPixmap(new_w) = XmUNSPECIFIED_PIXMAP;
Packit b099d7
	  size_cascade (new_w);
Packit b099d7
       } else
Packit b099d7
	   if ( (LabG_MenuType(new_w) != XmMENU_OPTION) &&
Packit b099d7
	       (((CBG_CascadePixmap(new_w) ==  XmUNSPECIFIED_PIXMAP) &&
Packit b099d7
		 (!CBG_Submenu(old) && CBG_Submenu(new_w))) ||
Packit b099d7
	        ((CBG_ArmedPixmap(old) != XmUNSPECIFIED_PIXMAP) &&
Packit b099d7
		 (LabG_TextRect_height(old) != LabG_TextRect_height(new_w)))))
Packit b099d7
          {
Packit b099d7
	        _XmProcessLock();
Packit b099d7
                _XmArrowPixmapCacheDelete((XtPointer) CBG_ArmedPixmap(old));
Packit b099d7
                _XmArrowPixmapCacheDelete((XtPointer) CBG_CascadePixmap(old));
Packit b099d7
                CBG_ArmedPixmap(new_w) = XmUNSPECIFIED_PIXMAP;
Packit b099d7
                CBG_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 gadget if cascade appeared or disappeared, or if the
Packit b099d7
	* cascade pixmap changed size.
Packit b099d7
	*/
Packit b099d7
       if ((CBG_CascadePixmap (old) != CBG_CascadePixmap (new_w))  ||
Packit b099d7
	    (LabG_LabelType(old) != LabG_LabelType(new_w)) ||
Packit b099d7
	    (CBG_Submenu(old) != CBG_Submenu(new_w)))
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 (CBG_Submenu(old) || CBG_Submenu(new_w))
Packit b099d7
	      flag = TRUE;
Packit b099d7
       }
Packit b099d7
Packit b099d7
       /* make sure that other changes did not scrunch our pixmap */
Packit b099d7
       else if (CBG_Submenu(new_w))
Packit b099d7
       {
Packit b099d7
	  if ((new_w->gadget.highlight_thickness !=
Packit b099d7
	       old->gadget.highlight_thickness)                     ||
Packit b099d7
	      (new_w->gadget.shadow_thickness !=
Packit b099d7
	       old->gadget.shadow_thickness)                        ||
Packit b099d7
	      (LabG_MarginRight (new_w) != LabG_MarginRight (old))    ||
Packit b099d7
	      (LabG_MarginHeight (new_w) != LabG_MarginHeight (old))  ||
Packit b099d7
	      (LabG_MarginTop (new_w) != LabG_MarginTop (old))	    ||
Packit b099d7
	      (LabG_MarginBottom (new_w) != LabG_MarginBottom (old)))
Packit b099d7
	  {
Packit b099d7
Packit b099d7
             setup_cascade (new_w, adjustWidth, adjustHeight);
Packit b099d7
	     flag = TRUE;
Packit b099d7
	  }
Packit b099d7
Packit b099d7
	  else if ((LabG_MarginWidth(new_w) != LabG_MarginWidth(old)) ||
Packit b099d7
		   (new_w->rectangle.width != old->rectangle.width)   ||
Packit b099d7
		   (new_w->rectangle.height != old->rectangle.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
    /* don't allow this to change */
Packit b099d7
    new_w->gadget.event_mask = XmARM_EVENT | XmACTIVATE_EVENT | 
Packit b099d7
                             XmFOCUS_IN_EVENT | XmFOCUS_OUT_EVENT |
Packit b099d7
                             XmENTER_EVENT | XmLEAVE_EVENT | XmHELP_EVENT |
Packit b099d7
			     XmBDRAG_EVENT ;
Packit b099d7
Packit b099d7
    return (flag);
Packit b099d7
}
Packit b099d7
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
        XmCascadeButtonGadget cb )
Packit b099d7
{
Packit b099d7
  XGCValues values;
Packit b099d7
  XtGCMask  valueMask;
Packit b099d7
  Pixel     junk, select_pixel;
Packit b099d7
  XmManagerWidget mw = (XmManagerWidget) XtParent(cb);  
Packit b099d7
Packit b099d7
  XmGetColors(XtScreen(mw), mw->core.colormap, mw->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 = select_pixel;
Packit b099d7
  values.graphics_exposures = False;
Packit b099d7
  
Packit b099d7
  CBG_ArmGC(cb) = XtGetGC ((Widget) mw, 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 the
Packit b099d7
 *     cascade button when not armed.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
GetBackgroundGC(
Packit b099d7
        XmCascadeButtonGadget cb )
Packit b099d7
{
Packit b099d7
  XGCValues values;
Packit b099d7
  XtGCMask  valueMask;
Packit b099d7
  XFontStruct  *fs;
Packit b099d7
Packit b099d7
  XmManagerWidget mw = (XmManagerWidget) XtParent(cb);  
Packit b099d7
Packit b099d7
  valueMask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
Packit b099d7
  values.foreground = mw -> core.background_pixel;
Packit b099d7
  values.background = mw -> core.background_pixel;
Packit b099d7
  values.graphics_exposures = False;
Packit b099d7
Packit b099d7
  if (XmeRenderTableGetDefaultFont(LabG_Font(cb), &fs))
Packit b099d7
      values.font = fs->fid;
Packit b099d7
  else
Packit b099d7
      valueMask &= ~GCFont;
Packit b099d7
Packit b099d7
  CBG_BackgroundGC(cb) = XtGetGC( (Widget) mw, valueMask, &values);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Initialize
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
Initialize(
Packit b099d7
        Widget rw,
Packit b099d7
        Widget nw,
Packit b099d7
        ArgList args,
Packit b099d7
        Cardinal *num_args )
Packit b099d7
{
Packit b099d7
   XmCascadeButtonGadget req = (XmCascadeButtonGadget) rw ;
Packit b099d7
   XmCascadeButtonGadget new_w = (XmCascadeButtonGadget) nw ;
Packit b099d7
   Boolean adjustWidth = FALSE;
Packit b099d7
   Boolean adjustHeight = FALSE;
Packit b099d7
   XmMenuSystemTrait menuSTrait;
Packit b099d7
   XmRowColumnWidget    submenu = (XmRowColumnWidget) CBG_Submenu (new_w);
Packit b099d7
Packit b099d7
   menuSTrait = (XmMenuSystemTrait) 
Packit b099d7
     XmeTraitGet((XtPointer) XtClass(XtParent(nw)), XmQTmenuSystem);
Packit b099d7
Packit b099d7
   if (! (LabG_MenuType(new_w) == XmMENU_BAR ||
Packit b099d7
	  LabG_MenuType(new_w) == XmMENU_PULLDOWN ||
Packit b099d7
	  LabG_MenuType(new_w) == XmMENU_POPUP    ||
Packit b099d7
	  LabG_MenuType(new_w) == XmMENU_OPTION))
Packit b099d7
   {
Packit b099d7
      XmeWarning( (Widget) new_w, WRONGPARENT);
Packit b099d7
   }
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
   /* if menuProcs is not set up yet, try again */
Packit b099d7
Packit b099d7
   _XmProcessLock();
Packit b099d7
   if (xmLabelGadgetClassRec.label_class.menuProcs == NULL)
Packit b099d7
       xmLabelGadgetClassRec.label_class.menuProcs =
Packit b099d7
	   (XmMenuProc) _XmGetMenuProcContext();
Packit b099d7
   _XmProcessUnlock();
Packit b099d7
Packit b099d7
   CBG_ArmedPixmap(new_w) =  XmUNSPECIFIED_PIXMAP;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * if the user did not specify a margin width, and we are
Packit b099d7
    * in a menuBar, set up the default.  First, find out what was the
Packit b099d7
    * request value (not in request since this is in the cached data)
Packit b099d7
    */
Packit b099d7
   if (LabG_MenuType(new_w) == XmMENU_BAR)
Packit b099d7
   {
Packit b099d7
      Dimension requestedMarginWidth;
Packit b099d7
      XtResource request_resources;
Packit b099d7
Packit b099d7
      request_resources.resource_name = XmNmarginWidth;
Packit b099d7
      request_resources.resource_class = XmCMarginWidth;
Packit b099d7
      request_resources.resource_type = XmRHorizontalDimension;
Packit b099d7
      request_resources.resource_size = sizeof (Dimension);
Packit b099d7
      request_resources.default_type = XmRImmediate;
Packit b099d7
      request_resources.resource_offset = 0;
Packit b099d7
      request_resources.default_addr = (XtPointer) XmINVALID_DIMENSION;
Packit b099d7
   
Packit b099d7
      XtGetSubresources(XtParent(new_w), &requestedMarginWidth, 
Packit b099d7
			XtName((Widget)new_w),
Packit b099d7
			new_w->object.widget_class->core_class.class_name,
Packit b099d7
			&request_resources, 1, args, *num_args);
Packit b099d7
Packit b099d7
      if (requestedMarginWidth == XmINVALID_DIMENSION)
Packit b099d7
      {
Packit b099d7
	 LabG_MarginWidth(new_w) = 6;
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /* for other menu types, we may need to initialize the cascade pixmap */
Packit b099d7
   else
Packit b099d7
   if ((LabG_MenuType(new_w) != XmMENU_OPTION))
Packit b099d7
   {
Packit b099d7
      if (submenu && CBG_CascadePixmap(new_w) == XmUNSPECIFIED_PIXMAP) {
Packit b099d7
	 _XmProcessLock();
Packit b099d7
	 _XmCreateArrowPixmaps((Widget) new_w);
Packit b099d7
	 _XmProcessUnlock();
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /* Clear before setting  */
Packit b099d7
   CBG_Armed(new_w) = 0;
Packit b099d7
   CBG_SetArmed(new_w, FALSE);
Packit b099d7
   CBG_SetTraverse (new_w, FALSE);
Packit b099d7
   CBG_SetWasPosted (new_w, FALSE);
Packit b099d7
   CBG_Timer(new_w) = 0;
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 (CBG_MapDelay(new_w) < 0) 
Packit b099d7
   {
Packit b099d7
      CBG_MapDelay(new_w) = 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(CBG_Submenu(new_w), (Widget) new_w, TRUE);
Packit b099d7
Packit b099d7
   if (LabG_MenuType(new_w) == XmMENU_PULLDOWN	||
Packit b099d7
       LabG_MenuType(new_w) == XmMENU_POPUP ||
Packit b099d7
       LabG_MenuType(new_w) == XmMENU_OPTION)
Packit b099d7
   {
Packit b099d7
      if (req->rectangle.width <= 0)
Packit b099d7
	  adjustWidth = TRUE;
Packit b099d7
      
Packit b099d7
      if (req->rectangle.height <= 0)
Packit b099d7
	  adjustHeight = TRUE;
Packit b099d7
      
Packit b099d7
      /* get pixmap size and set up gadget 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
   if (LabG_MenuType(new_w) == XmMENU_BAR ||
Packit b099d7
       LabG_MenuType(new_w) == XmMENU_PULLDOWN	||
Packit b099d7
       LabG_MenuType(new_w) == XmMENU_POPUP)
Packit b099d7
   {
Packit b099d7
      new_w->gadget.traversal_on = TRUE;
Packit b099d7
   }
Packit b099d7
	
Packit b099d7
   /* 
Packit b099d7
    * initialize the input types 
Packit b099d7
    */
Packit b099d7
   new_w->gadget.event_mask = XmARM_EVENT | XmACTIVATE_EVENT | 
Packit b099d7
       XmFOCUS_IN_EVENT | XmFOCUS_OUT_EVENT |
Packit b099d7
	   XmENTER_EVENT | XmLEAVE_EVENT | XmHELP_EVENT;
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
XmCreateCascadeButtonGadget(
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, xmCascadeButtonGadgetClass, parent, al, ac);
Packit b099d7
Packit b099d7
    return (cb);
Packit b099d7
}
Packit b099d7
Packit b099d7
Widget 
Packit b099d7
XmVaCreateCascadeButtonGadget(
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
                         xmCascadeButtonGadgetClass,
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
XmVaCreateManagedCascadeButtonGadget(
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
                         xmCascadeButtonGadgetClass,
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
 * Arm or disarm the gadget.  This routine does not pop up or down submenus
Packit b099d7
 */
Packit b099d7
void 
Packit b099d7
XmCascadeButtonGadgetHighlight(
Packit b099d7
        Widget wid,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int highlight )
Packit b099d7
#else
Packit b099d7
        Boolean highlight )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   XmCascadeButtonGadget cb  = (XmCascadeButtonGadget) wid;
Packit b099d7
   _XmWidgetToAppContext(wid);
Packit b099d7
Packit b099d7
   _XmAppLock(app);
Packit b099d7
   if ((cb) && XmIsCascadeButtonGadget(cb))
Packit b099d7
   {
Packit b099d7
      if (highlight)
Packit b099d7
         Arm (cb);
Packit b099d7
Packit b099d7
      else
Packit b099d7
         Disarm (cb, FALSE);
Packit b099d7
   }
Packit b099d7
   _XmAppUnlock(app);
Packit b099d7
}
Packit b099d7
Packit b099d7
/****************************************************
Packit b099d7
 *   Functions for manipulating Secondary Resources.
Packit b099d7
 *********************************************************/
Packit b099d7
/*
Packit b099d7
 * GetCascadeBGSecResData()
Packit b099d7
 *    Create a XmSecondaryResourceDataRec for each secondary resource;
Packit b099d7
 *    Put the pointers to these records in an array of pointers;
Packit b099d7
 *    Return the pointer to the array of pointers.
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Cardinal 
Packit b099d7
GetCascadeBGClassSecResData(
Packit b099d7
        WidgetClass w_class,
Packit b099d7
        XmSecondaryResourceData **data_rtn )
Packit b099d7
{   int arrayCount /* = 0 */;
Packit b099d7
    XmBaseClassExt  bcePtr;
Packit b099d7
    String  resource_class, resource_name;
Packit b099d7
    XtPointer  client_data;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    bcePtr = &(CascadeBGClassExtensionRec );
Packit b099d7
    client_data = NULL;
Packit b099d7
    resource_class = NULL;
Packit b099d7
    resource_name = NULL;
Packit b099d7
    arrayCount =
Packit b099d7
      _XmSecondaryResourceData ( bcePtr, data_rtn, client_data,
Packit b099d7
                                resource_name, resource_class,
Packit b099d7
                                GetCascadeBGClassSecResBase) ;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    return (arrayCount);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * GetCascadeBGClassResBase ()
Packit b099d7
 *   retrun the address of the base of resources.
Packit b099d7
 */
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static XtPointer 
Packit b099d7
GetCascadeBGClassSecResBase(
Packit b099d7
        Widget widget,
Packit b099d7
        XtPointer client_data )	/* unused */
Packit b099d7
{       XtPointer  widgetSecdataPtr;
Packit b099d7
    XtPointer ret_val;
Packit b099d7
    size_t labg_cache_size = sizeof (XmLabelGCacheObjPart);
Packit b099d7
    size_t cascadebg_cache_size = sizeof (XmCascadeButtonGCacheObjPart);
Packit b099d7
        char *cp;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    widgetSecdataPtr = (XtPointer)
Packit b099d7
                      (XtMalloc ( labg_cache_size + cascadebg_cache_size + 1));
Packit b099d7
Packit b099d7
    if (widgetSecdataPtr)
Packit b099d7
          { cp = (char *) widgetSecdataPtr;
Packit b099d7
            memcpy( cp, LabG_Cache(widget), labg_cache_size);
Packit b099d7
            cp += labg_cache_size;
Packit b099d7
            memcpy( cp, CBG_Cache(widget), cascadebg_cache_size);
Packit b099d7
          }
Packit b099d7
/* else Warning: error cannot allocate Memory */
Packit b099d7
/*     widgetSecdataPtr = (XtPointer) ( LabG_Cache(widget)); */
Packit b099d7
Packit b099d7
	ret_val = widgetSecdataPtr;
Packit b099d7
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
        return (widgetSecdataPtr);
Packit b099d7
}