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