/*
* Motif
*
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* HISTORY
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef REV_INFO
#ifndef lint
static char rcsid[] = "$TOG: ToggleBG.c /main/46 1999/12/06 18:10:15 samborn $"
#endif
#endif
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
#include <stdio.h>
#include "XmI.h"
#include <X11/ShellP.h>
#include <Xm/CareVisualT.h>
#include <Xm/CascadeB.h>
#include <Xm/DisplayP.h>
#include <Xm/DrawP.h>
#include <Xm/ManagerP.h>
#include <Xm/MenuT.h>
#include <Xm/ToggleBGP.h>
#include <Xm/TraitP.h>
#include <Xm/VaSimpleP.h>
#include "BaseClassI.h"
#include "CacheI.h"
#include "ColorI.h"
#include "ExtObjectI.h"
#include "LabelGI.h"
#include "LabelI.h"
#include "MenuProcI.h"
#include "MenuStateI.h"
#include "MenuUtilI.h"
#include "RepTypeI.h"
#include "SyntheticI.h"
#include "ToggleBGI.h"
#include "TravActI.h"
#include "TraversalI.h"
#include "UniqueEvnI.h"
#define XmINVALID_TYPE 255 /* special flag for IndicatorType */
#define XmINVALID_BOOLEAN 85 /* special flag for VisibleWhenOff */
#define MIN_GLYPH_SIZE 5 /* Threshold for rendering glyphs. */
#define PixmapOn(w) (TBG_OnPixmap(w))
#define PixmapOff(w) (LabG_Pixmap(w))
#define PixmapInd(w) (TBG_IndeterminatePixmap(w))
#define PixmapInsenOn(w) (TBG_InsenPixmap(w))
#define PixmapInsenOff(w) (LabG_PixmapInsensitive(w))
#define PixmapInsenInd(w) (TBG_IndeterminateInsensitivePixmap(w))
#define IsNull(p) ((p) == XmUNSPECIFIED_PIXMAP)
#define IsOn(w) (TBG_VisualSet(w))
#define IsOneOfMany(ind_type) (((ind_type) == XmONE_OF_MANY) || \
((ind_type) == XmONE_OF_MANY_ROUND) || \
((ind_type) == XmONE_OF_MANY_DIAMOND))
/* Constants used to decompose XmNindicatorOn values. */
#define XmINDICATOR_BOX_MASK 0x0f
#define XmINDICATOR_GLYPH_MASK 0xf0
/* The indicator value should already have been normalized! */
#define DRAW3DBOX(ind_on) ((ind_on) & XmINDICATOR_3D_BOX)
#define DRAWFLATBOX(ind_on) ((ind_on) & XmINDICATOR_FLAT_BOX)
#define DRAWBOX(ind_on) ((ind_on) & XmINDICATOR_BOX_MASK)
#define DRAWCHECK(ind_on) ((ind_on) & XmINDICATOR_CHECK_GLYPH)
#define DRAWCROSS(ind_on) ((ind_on) & XmINDICATOR_CROSS_GLYPH)
#define DRAWGLYPH(ind_on) ((ind_on) & XmINDICATOR_GLYPH_MASK)
/******** Static Function Declarations ********/
static void ClassInitialize( void ) ;
static void ClassPartInitialize(
WidgetClass wc) ;
static void SecondaryObjectCreate(
Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args) ;
static void InitializePrehook(
Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args) ;
static void InitializePosthook(
Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args) ;
int _XmToggleBCacheCompare(
XtPointer A,
XtPointer B );
static void InputDispatch(
Widget wid,
XEvent *event,
Mask event_mask) ;
static void SetAndDisplayPixmap(
XmToggleButtonGadget w,
XEvent *event,
Region region) ;
static void Help(
XmToggleButtonGadget tb,
XEvent *event) ;
static void ToggleButtonCallback(
XmToggleButtonGadget data,
unsigned int reason,
unsigned int value,
XEvent *event) ;
static void Leave(
XmToggleButtonGadget w,
XEvent *event) ;
static void Enter(
XmToggleButtonGadget w,
XEvent *event) ;
static void Arm(
Widget w,
XEvent *event) ;
static void Select(
XmToggleButtonGadget tb,
XEvent *event) ;
static void Disarm(
XmToggleButtonGadget tb,
XEvent *event) ;
static void ArmAndActivate(
Widget wid,
XEvent *event,
String *params,
Cardinal *num_params) ;
static void BtnDown(
XmToggleButtonGadget tb,
XEvent *event) ;
static void BtnUp(
XmToggleButtonGadget tb,
XEvent *event) ;
static void GetGC(
XmToggleButtonGadget tw) ;
static void GetUnselectGC(
XmToggleButtonGadget tw) ;
static void Initialize(
Widget rw,
Widget nw,
ArgList args,
Cardinal *num_args) ;
static void Destroy(
Widget w) ;
static void DrawToggle(
XmToggleButtonGadget w) ;
static void BorderHighlight(
Widget wid) ;
static void BorderUnhighlight(
Widget wid) ;
static void KeySelect(
XmToggleButtonGadget tb,
XEvent *event) ;
static void ComputeSpace(
XmToggleButtonGadget tb) ;
static void Redisplay(
Widget w,
XEvent *event,
Region region) ;
static void Resize(
Widget w) ;
static Boolean SetValuesPrehook(
Widget oldParent,
Widget refParent,
Widget newParent,
ArgList args,
Cardinal *num_args) ;
static void GetValuesPrehook(
Widget newParent,
ArgList args,
Cardinal *num_args) ;
static void GetValuesPosthook(
Widget new_w,
ArgList args,
Cardinal *num_args) ;
static Boolean SetValuesPosthook(
Widget current,
Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args) ;
static Boolean SetValues(
Widget current,
Widget request,
Widget new_w,
ArgList args,
Cardinal *num_args) ;
static Cardinal GetToggleBGClassSecResData(
WidgetClass w_class,
XmSecondaryResourceData **data_rtn) ;
static XtPointer GetToggleBGClassSecResBase(
Widget widget,
XtPointer client_data) ;
static void DrawToggleLabel(
XmToggleButtonGadget tb) ;
static void DrawEtchedInMenu(
XmToggleButtonGadget tb) ;
static void DrawToggleShadow(
XmToggleButtonGadget tb) ;
static void SetToggleSize(
XmToggleButtonGadget newtbg) ;
static void NextState(unsigned char *state);
static void DrawBox(
XmToggleButtonGadget w,
GC top_gc,
GC bot_gc,
GC fillgc,
int x, int y, int edge,
Dimension margin);
static Boolean HandleRedraw (Widget kid,
Widget cur_parent,
Widget new_parent,
Mask visual_flag);
static Boolean ToggleBGCVTRedraw (Widget kid,
Widget cur_parent,
Widget new_parent,
Mask visual_flag);
static void DefaultSelectColor(Widget widget,
int offset,
XrmValue *value);
static void TBG_FixTearoff( XmToggleButtonGadget tb);
static unsigned char NormalizeIndOn(XmToggleButtonGadget tb);
static unsigned char NormalizeIndType(XmToggleButtonGadget tb);
/******** End Static Function Declarations ********/
/*************************************<->*************************************
*
*
* Description: resource list for class: ToggleButton
* -----------
*
* Provides default resource settings for instances of this class.
* To get full set of default settings, examine resouce list of super
* classes of this class.
*
*************************************<->***********************************/
#define Offset(field) XtOffsetOf(XmToggleButtonGadgetRec, field)
#define CacheOffset(field) XtOffsetOf(XmToggleButtonGCacheObjRec, field)
static XtResource cache_resources[] =
{
{
XmNindicatorSize, XmCIndicatorSize,
XmRVerticalDimension, sizeof(Dimension),
CacheOffset(toggle_cache.indicator_dim),
XmRImmediate, (XtPointer) XmINVALID_DIMENSION
},
{
XmNindicatorType, XmCIndicatorType,
XmRIndicatorType, sizeof(unsigned char),
CacheOffset(toggle_cache.ind_type),
XmRImmediate, (XtPointer) XmINVALID_TYPE
},
{
XmNvisibleWhenOff, XmCVisibleWhenOff,
XmRBoolean, sizeof(Boolean),
CacheOffset(toggle_cache.visible),
XmRImmediate, (XtPointer) XmINVALID_BOOLEAN
},
{
XmNspacing, XmCSpacing,
XmRHorizontalDimension, sizeof(Dimension),
CacheOffset(toggle_cache.spacing),
XmRImmediate, (XtPointer) 4
},
{
XmNselectPixmap, XmCSelectPixmap,
XmRDynamicPixmap, sizeof(Pixmap),
CacheOffset(toggle_cache.on_pixmap),
XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
},
{
XmNselectInsensitivePixmap, XmCSelectInsensitivePixmap,
XmRDynamicPixmap, sizeof(Pixmap),
CacheOffset(toggle_cache.insen_pixmap),
XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
},
{
XmNindicatorOn, XmCIndicatorOn,
XmRIndicatorOn, sizeof(unsigned char),
CacheOffset(toggle_cache.ind_on),
XmRImmediate, (XtPointer) XmINDICATOR_FILL
},
{
XmNfillOnSelect, XmCFillOnSelect,
XmRBoolean, sizeof(Boolean),
CacheOffset(toggle_cache.fill_on_select),
XmRImmediate, (XtPointer) XmINVALID_BOOLEAN
},
{
XmNselectColor, XmCSelectColor,
XmRSelectColor, sizeof(Pixel),
CacheOffset(toggle_cache.select_color),
XmRImmediate, (XtPointer) INVALID_PIXEL
},
{
XmNtoggleMode, XmCToggleMode,
XmRToggleMode, sizeof(unsigned char),
CacheOffset(toggle_cache.toggle_mode),
XmRImmediate, (XtPointer) XmTOGGLE_BOOLEAN
},
{
XmNindeterminatePixmap, XmCIndeterminatePixmap,
XmRDynamicPixmap, sizeof(Pixmap),
CacheOffset(toggle_cache.indeterminate_pixmap),
XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
},
{
XmNindeterminateInsensitivePixmap, XmCIndeterminateInsensitivePixmap,
XmRDynamicPixmap, sizeof(Pixmap),
CacheOffset(toggle_cache.indeterminate_insensitive_pixmap),
XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
},
{
XmNunselectColor, XmCUnselectColor,
XmRPixel, sizeof(Pixel),
CacheOffset(toggle_cache.unselect_color),
XmRImmediate, (XtPointer) INVALID_PIXEL
}
};
/************************************************
* The uncached resources for ToggleButton
************************************************/
static XtResource resources[] =
{
{
XmNset, XmCSet,
XmRSet, sizeof(unsigned char),
Offset(toggle.set),
XmRImmediate, (XtPointer) XmUNSET
},
{
XmNvalueChangedCallback, XmCValueChangedCallback,
XmRCallback, sizeof(XtCallbackList),
Offset(toggle.value_changed_CB),
XmRPointer, (XtPointer)NULL
},
{
XmNarmCallback, XmCArmCallback, XmRCallback,
sizeof(XtCallbackList),
Offset(toggle.arm_CB),
XmRPointer, (XtPointer)NULL
},
{
XmNdisarmCallback, XmCDisarmCallback,
XmRCallback, sizeof(XtCallbackList),
Offset(toggle.disarm_CB),
XmRPointer, (XtPointer)NULL
},
{
XmNtraversalOn, XmCTraversalOn,
XmRBoolean, sizeof(Boolean),
XtOffsetOf(struct _XmGadgetRec, gadget.traversal_on),
XmRImmediate, (XtPointer) True
},
{
XmNhighlightThickness, XmCHighlightThickness,
XmRHorizontalDimension, sizeof(Dimension),
XtOffsetOf(struct _XmGadgetRec, gadget.highlight_thickness),
XmRCallProc, (XtPointer) _XmSetThickness
},
{
XmNdetailShadowThickness, XmCShadowThickness, XmRHorizontalDimension,
sizeof (Dimension),
Offset(toggle.detail_shadow_thickness),
XmRCallProc, (XtPointer) _XmSetThickness
}
};
/* Resources that need special processing in get/set values. */
static XmSyntheticResource cache_syn_resources[] =
{
{
XmNspacing, sizeof(Dimension),
CacheOffset(toggle_cache.spacing),
XmeFromHorizontalPixels,
XmeToHorizontalPixels
},
{
XmNindicatorSize, sizeof(Dimension),
CacheOffset(toggle_cache.indicator_dim),
XmeFromVerticalPixels,
XmeToVerticalPixels
}
};
static XmSyntheticResource syn_resources[] =
{
{
XmNdetailShadowThickness,
sizeof(Dimension),
XtOffsetOf(XmToggleButtonGadgetRec, toggle.detail_shadow_thickness),
XmeFromHorizontalPixels,XmeToHorizontalPixels
}
};
#undef CacheOffset
#undef Offset
/*****************************************************************
*
* Class Record definitions
*
****************************************************************/
static XmCacheClassPart ToggleButtonClassCachePart =
{
{ NULL, 0, 0 }, /* head of class cache list */
_XmCacheCopy, /* Copy routine */
_XmCacheDelete, /* Delete routine */
_XmToggleBCacheCompare, /* Comparison routine */
};
static XmBaseClassExtRec ToggleBGClassExtensionRec =
{
NULL, /* next_extension */
NULLQUARK, /* record_type */
XmBaseClassExtVersion, /* version */
sizeof(XmBaseClassExtRec), /* record_size */
InitializePrehook, /* initializePrehook */
SetValuesPrehook, /* setValuesPrehook */
InitializePosthook, /* initializePosthook */
SetValuesPosthook, /* setValuesPosthook */
(WidgetClass)&xmToggleButtonGCacheObjClassRec, /* secondaryObjectClass */
SecondaryObjectCreate, /* secondaryObjectCreate */
GetToggleBGClassSecResData, /* getSecResData */
{ 0 }, /* Other Flags */
GetValuesPrehook, /* getValuesPrehook */
GetValuesPosthook, /* getValuesPosthook */
(XtWidgetClassProc)NULL, /* classPartInitPrehook */
(XtWidgetClassProc)NULL, /* classPartInitPosthook */
NULL, /* ext_resources */
NULL, /* compiled_ext_resources */
0, /* num_ext_resources */
FALSE, /* use_sub_resources */
XmInheritWidgetNavigable, /* widgetNavigable */
XmInheritFocusChange, /* focusChange */
(XmWrapperData)NULL, /* wrapperData */
};
/* ext rec static initialization */
externaldef(xmtogglebuttongcacheobjclassrec)
XmToggleButtonGCacheObjClassRec xmToggleButtonGCacheObjClassRec =
{
{
/* superclass */ (WidgetClass) &xmLabelGCacheObjClassRec,
/* class_name */ "XmToggleButtonGadget",
/* widget_size */ sizeof(XmToggleButtonGCacheObjRec),
/* class_initialize */ (XtProc)NULL,
/* chained class init */ (XtWidgetClassProc)NULL,
/* class_inited */ False,
/* initialize */ (XtInitProc)NULL,
/* initialize hook */ (XtArgsProc)NULL,
/* realize */ NULL,
/* actions */ NULL,
/* num_actions */ 0,
/* resources */ cache_resources,
/* num_resources */ XtNumber(cache_resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ False,
/* compress_exposure */ False,
/* compress enter/exit*/ False,
/* visible_interest */ False,
/* destroy */ (XtWidgetProc)NULL,
/* resize */ NULL,
/* expose */ NULL,
/* set_values */ (XtSetValuesFunc)NULL,
/* set values hook */ (XtArgsFunc)NULL,
/* set values almost */ NULL,
/* get values hook */ (XtArgsProc)NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback offsetlst */ NULL,
/* default trans */ NULL,
/* query geo proc */ NULL,
/* display accelerator*/ NULL,
/* extension record */ NULL,
},
{
/* synthetic resources */ cache_syn_resources,
/* num_syn_resources */ XtNumber(cache_syn_resources),
/* extension */ NULL,
}
};
/*************************************<->*************************************
*
*
* Description: global class record for instances of class: ToggleButton
* -----------
*
* Defines default field settings for this class record.
*
*************************************<->***********************************/
static XmGadgetClassExtRec _XmToggleBGadClassExtRec =
{
NULL, /* next_extension */
NULLQUARK, /* record_type */
XmGadgetClassExtVersion, /* version */
sizeof(XmGadgetClassExtRec), /* record_size */
XmInheritBaselineProc, /* widget_baseline */
XmInheritDisplayRectProc, /* widget_display_rect */
XmInheritMarginsProc, /* widget_margins */
};
externaldef(xmtogglebuttongadgetclassrec)
XmToggleButtonGadgetClassRec xmToggleButtonGadgetClassRec =
{
{
/* superclass */ (WidgetClass) &xmLabelGadgetClassRec,
/* class_name */ "XmToggleButtonGadget",
/* widget_size */ sizeof(XmToggleButtonGadgetRec),
/* class_initialize */ ClassInitialize,
/* class_part_init */ ClassPartInitialize,
/* class_inited */ FALSE,
/* initialize */ Initialize,
/* initialize_hook */ (XtArgsProc)NULL,
/* realize */ NULL,
/* actions */ NULL,
/* num_actions */ 0,
/* resources */ resources,
/* num_resources */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ XtExposeCompressMaximal,
/* compress_enterlv */ TRUE,
/* visible_interest */ FALSE,
/* destroy */ Destroy,
/* resize */ Resize,
/* expose */ Redisplay,
/* set_values */ SetValues,
/* set_values_hook */ (XtArgsFunc)NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ (XtArgsProc)NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ NULL,
/* query_geometry */ XtInheritQueryGeometry,
/* display_accelerator */ NULL,
/* extension */ (XtPointer)&ToggleBGClassExtensionRec
},
{ /* gadget class record */
/* border_highlight */ BorderHighlight,
/* border_unhighlight */ BorderUnhighlight,
/* arm_and_activate */ ArmAndActivate,
/* input_dispatch */ InputDispatch,
/* visual_change */ XmInheritVisualChange,
/* syn resources */ syn_resources,
/* num_syn_resources */ XtNumber(syn_resources),
/* extension */ &ToggleButtonClassCachePart,
/* extension */ (XtPointer)&_XmToggleBGadClassExtRec
},
{ /* label class record */
/* SetOverrideCallback */ XmInheritWidgetProc,
/* menu proc entry */ XmInheritMenuProc,
/* extension */ NULL
},
{ /* toggle class record */
/* extension */ NULL
}
};
externaldef(xmtogglebuttongadgetclass)
WidgetClass xmToggleButtonGadgetClass =
(WidgetClass)&xmToggleButtonGadgetClassRec;
/* Menu Savvy trait record */
static XmMenuSavvyTraitRec MenuSavvyRecord =
{
-1, /* version */
NULL, /* disableCallback */
NULL, /* getAccelerator */
NULL, /* getMnemonic */
_XmCBNameValueChanged /* getActivateCBName */
};
/* Care about parent Visual trait record. */
static XmConst XmCareVisualTraitRec ToggleBGCVT =
{
0, /* version */
HandleRedraw /* redraw */
};
/***********************************************************
*
* ClassInitialize
*
************************************************************/
static void
ClassInitialize( void )
{
Cardinal wc_num_res, sc_num_res;
XtResource *merged_list;
int i, j;
XtResourceList uncompiled;
Cardinal num;
/*
* Label's and Togglebutton's resource lists are being merged into one
* and assigned to xmToggleButtonGCacheObjClassRec. This is for performance
* reasons, since, instead of two calls to XtGetSubResources XtGetSubvaluse
* and XtSetSubvalues for both the superclass and the widget class, now
* we have just one call with a merged resource list.
* NOTE: At this point the resource lists for Label and Togglebutton do
* have unique entries, but if there are resources in the superclass
* that are being overwritten by the subclass then the merged_lists
* need to be created differently.
*/
wc_num_res = xmToggleButtonGCacheObjClassRec.object_class.num_resources;
sc_num_res = xmLabelGCacheObjClassRec.object_class.num_resources;
merged_list = (XtResource *)
XtMalloc((sizeof(XtResource) * (wc_num_res + sc_num_res)));
_XmTransformSubResources(xmLabelGCacheObjClassRec.object_class.resources,
sc_num_res, &uncompiled, &num);
for (i = 0; i < num; i++)
merged_list[i] = uncompiled[i];
XtFree((char *)uncompiled);
for (i = 0, j = num; i < wc_num_res; i++, j++)
merged_list[j] = xmToggleButtonGCacheObjClassRec.object_class.resources[i];
xmToggleButtonGCacheObjClassRec.object_class.resources = merged_list;
xmToggleButtonGCacheObjClassRec.object_class.num_resources =
wc_num_res + sc_num_res ;
ToggleBGClassExtensionRec.record_type = XmQmotif;
}
/************************************************************************
*
* ClassPartInitialize
* Set up fast subclassing for the gadget.
*
***********************************************************************/
static void
ClassPartInitialize(
WidgetClass wc )
{
_XmFastSubclassInit (wc, XmTOGGLE_BUTTON_GADGET_BIT);
/* Install the menu savvy trait record, copying fields from XmLabelG */
_XmLabelGCloneMenuSavvy (wc, &MenuSavvyRecord);
/* Install the careParentVisual trait for all subclasses as well. */
XmeTraitSet((XtPointer)(WidgetClass) wc,
XmQTcareParentVisual, (XtPointer)&ToggleBGCVT);
}
/*******************************************************************
*
* _XmToggleBCacheCompare
*
*******************************************************************/
int
_XmToggleBCacheCompare(
XtPointer A,
XtPointer B )
{
XmToggleButtonGCacheObjPart *toggleB_inst =
(XmToggleButtonGCacheObjPart *) A ;
XmToggleButtonGCacheObjPart *toggleB_cache_inst =
(XmToggleButtonGCacheObjPart *) B ;
if ((toggleB_inst->ind_type == toggleB_cache_inst->ind_type) &&
(toggleB_inst->visible == toggleB_cache_inst->visible) &&
(toggleB_inst->spacing == toggleB_cache_inst->spacing) &&
(toggleB_inst->indicator_dim == toggleB_cache_inst->indicator_dim) &&
(toggleB_inst->on_pixmap == toggleB_cache_inst->on_pixmap) &&
(toggleB_inst->insen_pixmap == toggleB_cache_inst->insen_pixmap) &&
(toggleB_inst->ind_on == toggleB_cache_inst->ind_on) &&
(toggleB_inst->fill_on_select == toggleB_cache_inst->fill_on_select) &&
(toggleB_inst->select_color == toggleB_cache_inst->select_color) &&
(toggleB_inst->select_GC == toggleB_cache_inst->select_GC) &&
(toggleB_inst->unselect_GC == toggleB_cache_inst->unselect_GC) &&
(toggleB_inst->unselect_color == toggleB_cache_inst->unselect_color) &&
(toggleB_inst->indeterminate_pixmap ==
toggleB_cache_inst->indeterminate_pixmap) &&
(toggleB_inst->indeterminate_insensitive_pixmap ==
toggleB_cache_inst->indeterminate_insensitive_pixmap) &&
(toggleB_inst->indeterminate_GC ==
toggleB_cache_inst->indeterminate_GC) &&
(toggleB_inst->indeterminate_box_GC ==
toggleB_cache_inst->indeterminate_box_GC) &&
(toggleB_inst->toggle_mode == toggleB_cache_inst->toggle_mode) &&
(toggleB_inst->reversed_select == toggleB_cache_inst->reversed_select) &&
(toggleB_inst->background_gc == toggleB_cache_inst->background_gc) &&
(toggleB_inst->ind_left_delta == toggleB_cache_inst->ind_left_delta) &&
(toggleB_inst->ind_right_delta == toggleB_cache_inst->ind_right_delta) &&
(toggleB_inst->ind_top_delta == toggleB_cache_inst->ind_top_delta) &&
(toggleB_inst->ind_bottom_delta == toggleB_cache_inst->ind_bottom_delta))
return 1;
else
return 0;
}
/************************************************************************
*
* SecondaryObjectCreate
*
************************************************************************/
/* ARGSUSED */
static void
SecondaryObjectCreate(
Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args )
{
XmBaseClassExt *cePtr;
XmWidgetExtData extData;
WidgetClass wc;
Cardinal size;
XtPointer newSec, reqSec;
_XmProcessLock();
cePtr = _XmGetBaseClassExtPtr(XtClass(new_w), XmQmotif);
wc = (*cePtr)->secondaryObjectClass;
size = wc->core_class.widget_size;
newSec = _XmExtObjAlloc(size);
reqSec = _XmExtObjAlloc(size);
_XmProcessUnlock();
/*
* Update pointers in instance records now so references to resources
* in the cache record will be valid for use in CallProcs.
* CallProcs are invoked by XtGetSubresources().
*/
LabG_Cache(new_w) = &(((XmLabelGCacheObject)newSec)->label_cache);
LabG_Cache(req) = &(((XmLabelGCacheObject)reqSec)->label_cache);
TBG_Cache(new_w) = &(((XmToggleButtonGCacheObject)newSec)->toggle_cache);
TBG_Cache(req) = &(((XmToggleButtonGCacheObject)reqSec)->toggle_cache);
/*
* Since the resource lists for label and togglebutton were merged at
* ClassInitialize time we need to make only one call to
* XtGetSubresources()
*/
XtGetSubresources(new_w,
newSec,
NULL, NULL,
wc->core_class.resources,
wc->core_class.num_resources,
args, *num_args );
extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec));
extData->widget = (Widget)newSec;
extData->reqWidget = (Widget)reqSec;
((XmToggleButtonGCacheObject)newSec)->ext.extensionType = XmCACHE_EXTENSION;
((XmToggleButtonGCacheObject)newSec)->ext.logicalParent = new_w;
_XmPushWidgetExtData(new_w, extData,
((XmToggleButtonGCacheObject)newSec)->ext.extensionType);
memcpy(reqSec, newSec, size);
}
/************************************************************************
*
* InitializePosthook
*
************************************************************************/
/* ARGSUSED */
static void
InitializePrehook(
Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args )
{
/* CR 2990: Use XmNbuttonFontList as the default. */
if (LabG_Font(new_w) == NULL)
LabG_Font(new_w) = XmeGetDefaultRenderTable (new_w, XmBUTTON_FONTLIST);
}
/************************************************************************
*
* InitializePosthook
*
************************************************************************/
/* ARGSUSED */
static void
InitializePosthook(
Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args )
{
XmWidgetExtData ext;
XmToggleButtonGadget tbw = (XmToggleButtonGadget)new_w;
/*
* - register parts in cache.
* - update cache pointers
* - and free req
*/
_XmProcessLock();
LabG_Cache(tbw) = (XmLabelGCacheObjPart *)
_XmCachePart( LabG_ClassCachePart(tbw),
(XtPointer) LabG_Cache(tbw),
sizeof(XmLabelGCacheObjPart));
TBG_Cache(tbw) = (XmToggleButtonGCacheObjPart *)
_XmCachePart( TBG_ClassCachePart(tbw),
(XtPointer) TBG_Cache(tbw),
sizeof(XmToggleButtonGCacheObjPart));
/*
* might want to break up into per-class work that gets explicitly
* chained. For right now, each class has to replicate all
* superclass logic in hook routine
*/
/*
* free the req subobject used for comparisons
*/
_XmPopWidgetExtData((Widget) tbw, &ext, XmCACHE_EXTENSION);
_XmExtObjFree((XtPointer) ext->widget);
_XmExtObjFree((XtPointer) ext->reqWidget);
_XmProcessUnlock();
XtFree( (char *) ext);
}
static Boolean
HandleRedraw (
Widget kid,
Widget cur_parent,
Widget new_parent,
Mask visual_flag)
{
Boolean redraw = False;
redraw = _XmLabelGCVTRedraw (kid, cur_parent, new_parent, visual_flag);
redraw = ToggleBGCVTRedraw (kid, cur_parent, new_parent, visual_flag) ||
redraw;
if (redraw)
{
XtExposeProc expose;
_XmProcessLock();
expose = ((XmToggleButtonGadgetClassRec *)
(XtClass(kid)))->rect_class.expose;
_XmProcessUnlock();
if (! XtIsRealized(kid))
return redraw;
else
(* (expose)) ((Widget)kid, NULL, (Region) NULL);
}
return False;
}
static Boolean
ToggleBGCVTRedraw (
Widget kid,
Widget cur_parent,
Widget new_parent,
Mask visual_flag)
{
XmToggleButtonGadget tw = (XmToggleButtonGadget) kid ;
XmManagerWidget mw = (XmManagerWidget) new_parent;
XmManagerWidget curmw = (XmManagerWidget) cur_parent;
Boolean redraw = False;
XmToggleButtonGCacheObjPart oldCopy;
/*
* For the purposes of backward compatibility the existance of
* UnselectColor is obscured here. That is it is made to follow
* background.
*
* Unless of course someone sets it.
*/
/* Deal with the Evil gadget cache */
_XmProcessLock();
_XmCacheCopy((XtPointer) TBG_Cache(tw), (XtPointer) &oldCopy,
sizeof(XmToggleButtonGCacheObjPart));
_XmCacheDelete ((XtPointer) TBG_Cache(tw));
_XmProcessUnlock();
TBG_Cache(tw) = &oldCopy;
if ((visual_flag & VisualBackgroundPixel) &&
(TBG_UnselectColor(tw) == curmw->core.background_pixel))
{
XtReleaseGC (XtParent(tw), TBG_UnselectGC(tw));
TBG_UnselectColor(tw) = mw->core.background_pixel;
GetUnselectGC(tw);
redraw = True;
}
_XmProcessLock();
TBG_Cache(tw) = (XmToggleButtonGCacheObjPart *)
_XmCachePart(TBG_ClassCachePart(tw), (XtPointer) TBG_Cache(tw),
sizeof(XmToggleButtonGCacheObjPart));
_XmProcessUnlock();
return redraw ;
}
/************************************************************************
*
* InputDispatch
* This function catches input sent by a manager and dispatches it
* to the individual routines.
*
************************************************************************/
static void
InputDispatch(
Widget wid,
XEvent *event,
Mask event_mask )
{
XmToggleButtonGadget tb = (XmToggleButtonGadget) wid ;
if (event_mask & XmARM_EVENT)
{
if (LabG_IsMenupane(tb))
BtnDown(tb, event);
else
Arm ((Widget) tb, event);
}
/* BEGIN OSF Fix pir 2097 */
else if (event_mask & XmMULTI_ARM_EVENT)
{
if (! LabG_IsMenupane(tb))
{
Arm ((Widget) tb, event);
}
}
/* END OSF Fix pir 2097 */
else if (event_mask & XmACTIVATE_EVENT)
{
if (LabG_IsMenupane(tb))
{
if (event->type == ButtonRelease)
BtnUp(tb, event);
else /* Assume KeyPress or KeyRelease */
KeySelect (tb, event);
}
else
{
Select(tb, event);
Disarm (tb, event);
}
}
/* BEGIN OSF Fix pir 2097 */
else if (event_mask & XmMULTI_ACTIVATE_EVENT)
{
if (! LabG_IsMenupane(tb))
{
Select(tb, event);
Disarm (tb, event);
}
}
/* END OSF Fix pir 2097 */
else if (event_mask & XmHELP_EVENT)
Help (tb, event);
else if (event_mask & XmENTER_EVENT)
Enter (tb, event);
else if (event_mask & XmLEAVE_EVENT)
Leave (tb, event);
else if (event_mask & XmFOCUS_IN_EVENT)
(*(((XmToggleButtonGadgetClass) XtClass( tb))
->gadget_class.border_highlight))( (Widget) tb) ;
else if (event_mask & XmFOCUS_OUT_EVENT)
(*(((XmToggleButtonGadgetClass) XtClass( tb))
->gadget_class.border_unhighlight))
( (Widget) tb) ;
else if (event_mask & XmBDRAG_EVENT)
_XmProcessDrag ((Widget) tb, event, NULL, NULL);
}
/*********************************************************************
*
* redisplayPixmap
* does the apropriate calculations based on the toggle button's
* current pixmap and calls label's Redisplay routine.
*
* This routine was added to fix CR 4839 and CR 4838
* D. Rand 7/6/92
*
***********************************************************************/
static void
redisplayPixmap(XmToggleButtonGadget tb, XEvent *event, Region region)
{
Pixmap todo;
unsigned int onH = 0, onW = 0;
int w, h;
int x, y, offset;
XRectangle saved_Text;
LRectangle background_box;
memcpy(&saved_Text, &LabG_TextRect(tb), sizeof(XRectangle));
offset = tb->gadget.highlight_thickness + tb->gadget.shadow_thickness;
x = offset + LabG_MarginWidth(tb) + LabG_MarginLeft(tb);
y = offset + LabG_MarginHeight(tb) + LabG_MarginTop(tb);
w = tb->rectangle.width - x - offset
- LabG_MarginRight(tb) - LabG_MarginWidth(tb);
ASSIGN_MAX(w, 0);
h = tb->rectangle.height - y - offset - LabG_MarginBottom(tb)
- LabG_MarginHeight(tb);
ASSIGN_MAX(h, 0);
x += tb->rectangle.x;
y += tb->rectangle.y;
/* CR 6023: As of release 2.0 the LabelG will clear it's own background. */
background_box.x = x;
background_box.y = y;
background_box.width = w;
background_box.height = h;
/* CR 7041: ... but not when label.fill_bg_box is False! */
if (!tb->label.fill_bg_box)
XClearArea(XtDisplay(tb), XtWindow(tb), x, y, w, h, False);
todo = tb->label.pixmap;
if ((! XtIsSensitive((Widget) tb)) && tb->label.pixmap_insen)
todo = tb->label.pixmap_insen;
if (! IsNull(todo))
XmeGetPixmapData(XtScreen(tb), todo,
NULL, NULL, NULL, NULL, NULL, NULL,
&onW, &onH);
h = (tb->rectangle.height - onH) / 2 ;
LabG_TextRect_y(tb) = MAX(h, 0);
LabG_TextRect_height(tb) = onH;
LabG_TextRect_width(tb) = onW;
_XmRedisplayLabG ((Widget) tb, event, region, &background_box);
memcpy(&LabG_TextRect(tb), &saved_Text, sizeof(XRectangle));
}
static void
HandlePixmap(XmToggleButtonGadget tb,
Pixmap pix,
Pixmap insen_pix,
XEvent * event,
Region region)
{
if (XtIsSensitive((Widget) tb))
{
if (! IsNull (pix))
{
Pixmap tempPix = LabG_Pixmap(tb);
LabG_Pixmap(tb) = pix;
redisplayPixmap(tb, event, region);
LabG_Pixmap(tb) = tempPix;
}
else
redisplayPixmap(tb, event, region);
}
else
{
if (! IsNull (insen_pix))
{
Pixmap tempPix = LabG_PixmapInsensitive(tb);
LabG_PixmapInsensitive(tb) = insen_pix;
redisplayPixmap(tb, event, region);
LabG_PixmapInsensitive(tb) = tempPix;
}
else
redisplayPixmap(tb, event, region);
}
}
/***********************************************************************
*
* SetAndDisplayPixmap
* Sets the appropriate on, off pixmap in label's pixmap field and
* calls label's Redisplay routine.
*
***********************************************************************/
static void
SetAndDisplayPixmap(
XmToggleButtonGadget w,
XEvent *event,
Region region )
{
XmToggleButtonGadget tb = (XmToggleButtonGadget) w ;
if (TBG_ToggleMode(tb) == XmTOGGLE_INDETERMINATE)
{
if (TBG_VisualSet(tb) == XmUNSET)
HandlePixmap(tb, PixmapOff(tb), PixmapInsenOff(tb), event, region);
else if (TBG_VisualSet(tb) == XmSET)
HandlePixmap(tb, PixmapOn(tb), PixmapInsenOn(tb), event, region);
else if (TBG_VisualSet(tb) == XmINDETERMINATE)
HandlePixmap(tb, PixmapInd(tb), PixmapInsenInd(tb), event, region);
}
else
{
if (IsOn (tb) == XmSET)
HandlePixmap(tb, PixmapOn(tb), PixmapInsenOn(tb), event, region);
else
redisplayPixmap(tb, event, region);
}
}
/*************************************************************************
*
* Help
* This routine is called if the user has made a help selection
* on the gadget.
*
************************************************************************/
static void
Help(
XmToggleButtonGadget tb,
XEvent *event )
{
Boolean is_menupane = LabG_IsMenupane(tb);
XmMenuSystemTrait menuSTrait;
menuSTrait = (XmMenuSystemTrait)
XmeTraitGet((XtPointer) XtClass(XtParent(tb)), XmQTmenuSystem);
if (is_menupane && menuSTrait != NULL)
menuSTrait->buttonPopdown(XtParent(tb), event);
ToggleButtonCallback(tb, XmCR_HELP, TBG_Set(tb), event);
if (is_menupane && menuSTrait != NULL)
menuSTrait->reparentToTearOffShell(XtParent(tb), event);
}
/*************************************************************************
*
* ToggleButtonCallback
* This is the widget's application callback routine
*
*************************************************************************/
static void
ToggleButtonCallback(
XmToggleButtonGadget data,
unsigned int reason,
unsigned int value,
XEvent *event )
{
XmToggleButtonCallbackStruct temp;
temp.reason = reason;
temp.set = value;
temp.event = event;
switch (reason)
{
case XmCR_VALUE_CHANGED:
XtCallCallbackList ((Widget) data, TBG_ValueChangedCB(data), &temp);
break;
case XmCR_ARM:
XtCallCallbackList ((Widget) data, TBG_ArmCB(data), &temp);
break;
case XmCR_DISARM:
XtCallCallbackList ((Widget) data, TBG_DisarmCB(data), &temp);
break;
case XmCR_HELP:
_XmSocorro( (Widget) data, event, NULL, NULL);
break;
}
}
static void
NextState(
unsigned char *state)
{
switch(*state)
{
case XmUNSET:
*state = XmSET;
break;
case XmSET:
*state = XmINDETERMINATE;
break;
case XmINDETERMINATE:
*state = XmUNSET;
break;
}
}
/* Update the toggle after an Enter or Leave action. */
static void
ActionDraw(XmToggleButtonGadget w,
XEvent *event,
Boolean leave)
{
if (TBG_Armed(w))
{
/* CR 7301: We may have armed while outside the toggle. */
if (leave)
TBG_VisualSet(w) = TBG_Set(w);
else if (TBG_ToggleMode(w) == XmTOGGLE_INDETERMINATE)
NextState(&TBG_VisualSet(w));
else
IsOn(w) = !TBG_Set(w);
if (TBG_IndOn(w))
DrawToggle(w);
else
{
if (w->gadget.shadow_thickness > 0)
DrawToggleShadow(w);
if (TBG_FillOnSelect(w) && !LabG_IsPixmap(w))
DrawToggleLabel(w);
}
if (LabG_IsPixmap(w) || LabG_IsPixmapAndText(w))
SetAndDisplayPixmap(w, event, NULL);
}
}
/**************************************************************************
*
* Leave
* This procedure is called when the mouse button is pressed and the
* cursor moves out of the widget's window. This procedure is used
* to change the visuals.
*
*************************************************************************/
static void
Leave(
XmToggleButtonGadget w,
XEvent *event )
{
if (LabG_IsMenupane(w))
{
if (_XmGetInDragMode((Widget)w) && TBG_Armed(w))
{
XmDisplay dpy;
Boolean etched_in;
dpy = (XmDisplay) XmGetXmDisplay(XtDisplayOfObject((Widget) w));
etched_in = dpy->display.enable_etched_in_menu;
((XmManagerWidget) XtParent(w))->manager.active_child = NULL;
TBG_Armed(w) = FALSE;
if ((etched_in) &&
(TBG_IndOn(w) ||
(!(TBG_IndOn(w)) && !(TBG_FillOnSelect(w)))))
{
DrawEtchedInMenu(w);
if (TBG_IndOn(w))
DrawToggle(w);
}
XmeDrawHighlight(XtDisplay(w),
XtWindow(w),
LabG_BackgroundGC(w),
w->rectangle.x + w->gadget.highlight_thickness,
w->rectangle .y + w->gadget.highlight_thickness,
w->rectangle.width - 2 *
w->gadget.highlight_thickness,
w->rectangle.height - 2 *
w->gadget.highlight_thickness,
w->gadget.shadow_thickness);
if (TBG_DisarmCB(w))
{
XFlush (XtDisplay (w));
ToggleButtonCallback(w, XmCR_DISARM, TBG_Set(w), event);
}
}
}
else
{
_XmLeaveGadget( (Widget) w, event, NULL, NULL);
ActionDraw(w, event, TRUE);
}
}
/**************************************************************************
*
* Enter
* This procedure is called when the mouse button is pressed and the
* cursor reenters the widget's window. This procedure changes the visuals
* accordingly.
*
**************************************************************************/
static void
Enter(
XmToggleButtonGadget w,
XEvent *event )
{
XmDisplay xm_dpy = (XmDisplay) XmGetXmDisplay(XtDisplay((Widget) w));
Boolean etched_in = xm_dpy->display.enable_etched_in_menu;
if (LabG_IsMenupane(w))
{
if ((((ShellWidget) XtParent(XtParent(w)))->shell.popped_up) &&
_XmGetInDragMode((Widget)w))
{
XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay((Widget) w));
Boolean etched_in = dpy->display.enable_etched_in_menu;
if (TBG_Armed(w))
return;
/* So KHelp event is delivered correctly */
_XmSetFocusFlag( XtParent(XtParent(w)), XmFOCUS_IGNORE, TRUE);
XtSetKeyboardFocus(XtParent(XtParent(w)), (Widget)w);
_XmSetFocusFlag( XtParent(XtParent(w)), XmFOCUS_IGNORE, FALSE);
((XmManagerWidget) XtParent(w))->manager.active_child = (Widget) w;
TBG_Armed(w) = TRUE;
if ((etched_in) &&
(TBG_IndOn(w) ||
(!(TBG_IndOn(w)) && !(TBG_FillOnSelect(w)))))
{
DrawEtchedInMenu(w);
if (TBG_IndOn(w))
DrawToggle(w);
}
XmeDrawShadows (XtDisplay (w), XtWindow (w),
LabG_TopShadowGC(w),
LabG_BottomShadowGC(w),
w->rectangle.x + w->gadget.highlight_thickness,
w->rectangle.y + w->gadget.highlight_thickness,
w->rectangle.width -
2 * w->gadget.highlight_thickness,
w->rectangle.height -
2 * w->gadget.highlight_thickness,
w->gadget.shadow_thickness,
etched_in ? XmSHADOW_IN : XmSHADOW_OUT);
if (TBG_ArmCB(w))
{
XFlush (XtDisplay (w));
ToggleButtonCallback(w, XmCR_ARM, TBG_Set(w), event);
}
}
}
else
{
_XmEnterGadget( (Widget) w, event, NULL, NULL);
ActionDraw(w, event, FALSE);
}
}
/************************************************************************
*
* Arm
* This function processes button 1 down occuring on the togglebutton.
* Mark the togglebutton as armed and display it armed.
* The callbacks for XmNarmCallback are called.
*
************************************************************************/
static void
Arm(
Widget w,
XEvent *event )
{
XmToggleButtonGadget tb = (XmToggleButtonGadget)w;
if (TBG_ToggleMode(tb) == XmTOGGLE_INDETERMINATE)
{
NextState(&TBG_VisualSet(tb));
TBG_Armed(tb) = TRUE;
}
else
{
IsOn(tb) = (TBG_Set(tb) == XmSET) ? XmUNSET : XmSET;
TBG_Armed(tb) = TRUE;
}
if (TBG_IndOn(tb))
DrawToggle((XmToggleButtonGadget) w);
else
{
if (tb->gadget.shadow_thickness> 0) DrawToggleShadow (tb);
if (TBG_FillOnSelect(w) && !LabG_IsPixmap(w)) DrawToggleLabel (tb);
}
if (LabG_IsPixmap(tb) || LabG_IsPixmapAndText(tb))
SetAndDisplayPixmap(tb, event, NULL);
if (TBG_ArmCB(tb))
{
XFlush(XtDisplay(tb));
ToggleButtonCallback(tb, XmCR_ARM, TBG_Set(tb), event);
}
}
/************************************************************************
*
* Select
* Mark the togglebutton as unarmed (i.e. inactive).
* If the button release occurs inside of the ToggleButton, the
* callbacks for XmNvalueChangedCallback are called.
*
************************************************************************/
static void
Select(
XmToggleButtonGadget tb,
XEvent *event )
{
XmToggleButtonCallbackStruct call_value;
Boolean hit;
XmMenuSystemTrait menuSTrait;
Boolean radio = TRUE, always = TRUE;
if ( TBG_Armed(tb) == FALSE)
return;
TBG_Armed(tb) = FALSE;
if (XmIsRowColumn(XtParent(tb))) {
XtVaGetValues(XtParent(tb),
XmNradioBehavior, &radio,
XmNradioAlwaysOne, &always,
NULL);
}
/* CR 8068: Verify that this is in fact a button event. */
/* CR 9181: Consider clipping when testing visibility. */
hit = (((event->xany.type == ButtonPress) ||
(event->xany.type == ButtonRelease)) &&
_XmGetPointVisibility((Widget) tb,
event->xbutton.x_root,
event->xbutton.y_root));
if (hit)
{
if (TBG_ToggleMode(tb) == XmTOGGLE_INDETERMINATE)
NextState(&TBG_Set(tb));
else
TBG_Set(tb) = !TBG_Set(tb);
}
/* CR 7803: Suppress redundant redraws. */
if (tb->toggle.set != tb->toggle.visual_set)
{
XtExposeProc expose;
_XmProcessLock();
expose = ((XmToggleButtonGadgetClassRec *)(tb->object.widget_class))->
rect_class.expose;
_XmProcessUnlock();
/* Redisplay after changing state. */
(* (expose)) ((Widget) tb, event, (Region) NULL);
}
if (hit)
{
/* UNDOING this fix ... */
/* CR 8904: Notify value_changed before entry so that state is */
/* reported correctly even if the entry callback resets it. */
menuSTrait = (XmMenuSystemTrait)
XmeTraitGet((XtPointer) XtClass(XtParent(tb)), XmQTmenuSystem);
if (menuSTrait != NULL)
{
call_value.reason = XmCR_VALUE_CHANGED;
call_value.event = event;
call_value.set = TBG_Set(tb);
menuSTrait->entryCallback(XtParent(tb), (Widget) tb, &call_value);
}
if ((! LabG_SkipCallback(tb)) &&
(TBG_ValueChangedCB(tb)))
{
XFlush(XtDisplay(tb));
ToggleButtonCallback(tb, XmCR_VALUE_CHANGED, TBG_Set(tb), event);
}
}
}
/**********************************************************************
*
* Disarm
* The callbacks for XmNdisarmCallback are called..
*
************************************************************************/
static void
Disarm(
XmToggleButtonGadget tb,
XEvent *event )
{
if (TBG_DisarmCB(tb))
ToggleButtonCallback(tb, XmCR_DISARM, TBG_Set(tb), event);
if (tb->toggle.set != tb->toggle.visual_set)
{
tb->toggle.visual_set = tb->toggle.set;
Redisplay((Widget) tb, event, (Region) NULL);
}
}
static void
TBG_FixTearoff( XmToggleButtonGadget tb)
{
if (XmMENU_PULLDOWN == LabG_MenuType(tb))
{
Widget mwid = XmGetPostedFromWidget(XtParent(tb));
if (mwid && XmIsRowColumn(mwid)
&& (XmMENU_OPTION == RC_Type(mwid))
&& _XmIsActiveTearOff(XtParent(tb)))
XmProcessTraversal((Widget) tb, XmTRAVERSE_CURRENT);
}
}
/************************************************************************
*
* ArmAndActivate
* This routine arms and activates a ToggleButton. It is called on
* <Key> Return and a <Key> Space, as well as when a mnemonic or
* button accelerator has been activated.
* Modify: Current implementation does care to draw shadows if indicator
* is set to false; This is being modified.
************************************************************************/
/*ARGSUSED*/
static void
ArmAndActivate(
Widget wid,
XEvent *event,
String *params, /* unused */
Cardinal *num_params ) /* unused */
{
XmToggleButtonGadget tb = (XmToggleButtonGadget) wid ;
XmToggleButtonCallbackStruct call_value;
Boolean already_armed = TBG_Armed(tb);
Boolean is_menupane = LabG_IsMenupane(tb);
Boolean torn_has_focus = FALSE;
XmMenuSystemTrait menuSTrait;
Boolean radio = TRUE, always = TRUE, no_change;
if (XmIsRowColumn(XtParent(tb))) {
XtVaGetValues(XtParent(tb),
XmNradioBehavior, &radio,
XmNradioAlwaysOne, &always,
NULL);
}
no_change = False;
menuSTrait = (XmMenuSystemTrait)
XmeTraitGet((XtPointer) XtClass(XtParent(wid)), XmQTmenuSystem);
if (is_menupane && !XmIsMenuShell(XtParent(XtParent(tb))) &&
menuSTrait != NULL)
{
if (XmeFocusIsInShell((Widget)tb))
{
/* In case allowAcceleratedInsensitiveUnmanagedMenuItems is True */
if (!XtIsSensitive((Widget)tb) || (!XtIsManaged((Widget)tb)))
return;
torn_has_focus = TRUE;
}
}
TBG_Armed(tb) = FALSE;
if (!no_change)
{
if (TBG_ToggleMode(tb) == XmTOGGLE_INDETERMINATE)
{
NextState(&TBG_VisualSet(tb));
NextState(&TBG_Set(tb));
}
else
{
TBG_Set(tb) = (TBG_Set(tb) == TRUE) ? FALSE : TRUE;
IsOn(tb) = TBG_Set(tb);
}
}
if (is_menupane && menuSTrait != NULL)
{
/* CR 7799: Torn off menus shouldn't be shared, so don't reparent. */
if (torn_has_focus)
menuSTrait->popdown(XtParent(tb), event);
else
menuSTrait->buttonPopdown(XtParent(tb), event);
if (torn_has_focus)
XmProcessTraversal((Widget) tb, XmTRAVERSE_CURRENT);
/* Draw the toggle indicator in case of tear off */
if (TBG_IndOn(tb))
DrawToggle(tb);
else if (TBG_FillOnSelect(tb) && !LabG_IsPixmap(tb))
DrawToggleLabel (tb);
if (LabG_IsPixmap(tb) || LabG_IsPixmapAndText(tb))
SetAndDisplayPixmap(tb, NULL, NULL);
}
else
{
if (TBG_IndOn(tb))
DrawToggle(tb);
else
{
if (tb->gadget.shadow_thickness> 0)
DrawToggleShadow (tb);
if (TBG_FillOnSelect(tb) && !LabG_IsPixmap(tb))
DrawToggleLabel (tb);
}
if (LabG_IsPixmap(tb) || LabG_IsPixmapAndText(tb))
SetAndDisplayPixmap(tb, event, NULL);
}
/* If the parent is menu system able, set the lastSelectToplevel before
* the arm. It's ok if this is recalled later.
*/
if (menuSTrait != NULL)
menuSTrait->getLastSelectToplevel(XtParent(tb));
if (TBG_ArmCB(tb) && !already_armed)
ToggleButtonCallback(tb, XmCR_ARM, TBG_Set(tb), event);
if (!no_change)
{
/* UNDOING this fix ... */
/* CR 8904: Notify value_changed before entry so that state is */
/* reported correctly even if the entry callback resets it. */
/* if the parent is menu system able, notify it about the select */
if (menuSTrait != NULL)
{
call_value.reason = XmCR_VALUE_CHANGED;
call_value.event = event;
call_value.set = TBG_Set(tb);
menuSTrait->entryCallback(XtParent(tb), (Widget) tb, &call_value);
}
if ((! LabG_SkipCallback(tb)) &&
(TBG_ValueChangedCB(tb)))
{
XFlush(XtDisplay(tb));
ToggleButtonCallback(tb, XmCR_VALUE_CHANGED, TBG_Set(tb), event);
}
}
if (TBG_DisarmCB(tb))
{
XFlush(XtDisplay(tb));
ToggleButtonCallback(tb, XmCR_DISARM, TBG_Set(tb), event);
}
if (is_menupane && menuSTrait != NULL)
{
if (torn_has_focus && XtIsSensitive(wid))
{
TBG_Armed(tb) = TRUE;
if (TBG_ArmCB(tb))
{
XFlush(XtDisplay(tb));
ToggleButtonCallback(tb, XmCR_ARM, TBG_Set(tb), event);
}
}
else
{
menuSTrait->reparentToTearOffShell(XtParent(tb), event);
TBG_FixTearoff(tb);
}
}
}
/************************************************************************
*
* BtnDown
* This function processes a button down occuring on the togglebutton
* when it is in a popup, pulldown, or option menu.
* Popdown the posted menu.
* Turn parent's traversal off.
* Mark the togglebutton as armed (i.e. active).
* The callbacks for XmNarmCallback are called.
*
************************************************************************/
static void
BtnDown(
XmToggleButtonGadget tb,
XEvent *event )
{
Boolean already_armed;
ShellWidget popup;
XmMenuSystemTrait menuSTrait;
XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(tb));
Boolean etched_in = dpy->display.enable_etched_in_menu;
menuSTrait = (XmMenuSystemTrait)
XmeTraitGet((XtPointer) XtClass(XtParent(tb)), XmQTmenuSystem);
if (menuSTrait == NULL) return;
_XmSetInDragMode((Widget)tb, True);
/* Popdown other popups that may be up */
if (!(popup = (ShellWidget)_XmGetRC_PopupPosted(XtParent(tb))))
{
if (!XmIsMenuShell(XtParent(XtParent(tb))))
{
/* In case tear off not armed and no grabs in place, do it now.
* Ok if already armed and grabbed - nothing done.
*/
menuSTrait->tearOffArm(XtParent(tb));
}
}
if (popup)
{
if (popup->shell.popped_up)
menuSTrait->popdownEveryone((Widget) popup, event);
}
/* Set focus to this button. This must follow the possible
* unhighlighting of the CascadeButton else it'll screw up active_child.
*/
(void)XmProcessTraversal( (Widget) tb, XmTRAVERSE_CURRENT);
/* get the location cursor - get consistent with Gadgets */
already_armed = TBG_Armed(tb);
TBG_Armed(tb) = TRUE;
if ((etched_in) &&
(TBG_IndOn(tb) ||
(!(TBG_IndOn(tb)) && !(TBG_FillOnSelect(tb)))))
{
DrawEtchedInMenu(tb);
if (TBG_IndOn(tb))
DrawToggle(tb);
}
XmeDrawShadows (XtDisplay (tb), XtWindow (tb),
LabG_TopShadowGC(tb),
LabG_BottomShadowGC(tb),
tb->rectangle.x + tb->gadget.highlight_thickness,
tb->rectangle.y + tb->gadget.highlight_thickness,
tb->rectangle.width - 2 * tb->gadget.highlight_thickness,
tb->rectangle.height - 2 * tb->gadget.highlight_thickness,
tb->gadget.shadow_thickness,
etched_in ? XmSHADOW_IN : XmSHADOW_OUT);
if (TBG_ArmCB(tb) && !already_armed)
{
XFlush (XtDisplay (tb));
ToggleButtonCallback(tb, XmCR_ARM, TBG_Set(tb), event);
}
_XmRecordEvent (event);
}
/************************************************************************
*
* BtnUp
* This function processes a button up occuring on the togglebutton
* when it is in a popup, pulldown, or option menu.
* Mark the togglebutton as unarmed (i.e. inactive).
* The callbacks for XmNvalueChangedCallback are called.
* The callbacks for XmNdisarmCallback are called.
*
************************************************************************/
static void
BtnUp(
XmToggleButtonGadget tb,
XEvent *event )
{
XmToggleButtonCallbackStruct call_value;
Boolean popped_up;
Boolean valid_event;
Boolean is_menupane = LabG_IsMenupane(tb);
Widget shell = XtParent(XtParent(tb));
XmMenuSystemTrait menuSTrait;
menuSTrait = (XmMenuSystemTrait)
XmeTraitGet((XtPointer) XtClass(XtParent(tb)), XmQTmenuSystem);
if (menuSTrait == NULL) return;
TBG_Armed(tb) = FALSE;
/* We need to validate the event in case the XmMENU_POPDOWN restores the
* submenu to the transient shell. The tear off control becomes unmanaged
* and the submenu's (and menu item children) layout/geometry changes.
*/
/* CR 9181: Consider clipping when testing visibility. */
valid_event = (((event->xany.type == ButtonPress) ||
(event->xany.type == ButtonRelease)) &&
_XmGetPointVisibility((Widget)tb,
event->xbutton.x_root,
event->xbutton.y_root));
if (is_menupane && !XmIsMenuShell(shell))
popped_up = menuSTrait->popdown((Widget) tb, event);
else
popped_up = menuSTrait->buttonPopdown((Widget) tb, event);
_XmRecordEvent(event);
if (popped_up)
return;
if (valid_event)
{
if (TBG_ToggleMode(tb) == XmTOGGLE_INDETERMINATE)
{
NextState(&TBG_VisualSet(tb));
NextState(&TBG_Set(tb));
}
else
{
TBG_Set(tb) = (TBG_Set(tb) == TRUE) ? FALSE : TRUE;
IsOn(tb) = TBG_Set(tb);
}
/* UNDOING this fix ... */
/* CR 8904: Notify value_changed before entry so that state is */
/* reported correctly even if the entry callback resets it. */
/* notify the parent about the select */
call_value.reason = XmCR_VALUE_CHANGED;
call_value.event = event;
call_value.set = TBG_Set(tb);
menuSTrait->entryCallback(XtParent(tb), (Widget) tb, &call_value);
if ((! LabG_SkipCallback(tb)) &&
(TBG_ValueChangedCB(tb)))
{
XFlush(XtDisplay(tb));
ToggleButtonCallback(tb, XmCR_VALUE_CHANGED, TBG_Set(tb), event);
}
if (TBG_DisarmCB(tb))
ToggleButtonCallback(tb, XmCR_DISARM, TBG_Set(tb), event);
/* If the original shell does not indicate an active menu, but rather a
* tear off pane, leave the button in an armed state.
*/
if (!XmIsMenuShell(shell))
{
if (XtIsSensitive((Widget)tb))
{
TBG_Armed(tb) = TRUE;
if (TBG_IndOn(tb))
DrawToggle(tb);
else if (TBG_FillOnSelect(tb) && !LabG_IsPixmap(tb))
DrawToggleLabel (tb);
if (LabG_IsPixmap(tb) || LabG_IsPixmapAndText(tb))
SetAndDisplayPixmap( tb, event, NULL);
if (TBG_ArmCB(tb))
{
XFlush(XtDisplay(tb));
ToggleButtonCallback(tb, XmCR_ARM, TBG_Set(tb), event);
}
}
}
else
menuSTrait->reparentToTearOffShell(XtParent(tb), event);
}
_XmSetInDragMode((Widget)tb, False);
/* For the benefit of tear off menus, we must set the focus item
* to this button. In normal menus, this would not be a problem
* because the focus is cleared when the menu is unposted.
*/
if (!XmIsMenuShell(shell))
XmProcessTraversal((Widget) tb, XmTRAVERSE_CURRENT);
TBG_FixTearoff(tb);
}
/************************************************************************
*
* GetUnselectGC
* Get the graphics context to be used to fill the interior of
* a square or diamond when unselected.
*
************************************************************************/
static void
GetUnselectGC(
XmToggleButtonGadget tw )
{
XGCValues values;
XtGCMask valueMask;
valueMask = GCForeground | GCBackground | GCFillStyle | GCGraphicsExposures;
values.foreground = TBG_UnselectColor(tw);
values.background = LabG_Background(tw);
values.fill_style = FillSolid;
values.graphics_exposures = FALSE;
TBG_UnselectGC(tw) = XtGetGC((Widget) tw, valueMask, &values);
}
/************************************************************************
*
* GetGC
* Get the graphics context to be used to fill the interior of
* a square or diamond when selected, and the arm GC used in a
* menu if enableEtchedInMenu is True.
*
************************************************************************/
static void
GetGC(
XmToggleButtonGadget tw )
{
XmManagerWidget mw = (XmManagerWidget) XtParent(tw);
XGCValues values;
XtGCMask valueMask;
XFontStruct *fs = (XFontStruct *) NULL;
Pixel sel_color, select_pixel;
XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay((Widget) tw));
Boolean etched_in = dpy->display.enable_etched_in_menu;
/* Differentiate background and select colors on monochrome displays or
** others on which we have indistinguishable colors. */
if ((DefaultDepthOfScreen (XtScreen (tw)) == 1) ||
(LabG_Background(tw) == TBG_SelectColor(tw)))
sel_color = LabG_Foreground(tw);
else
sel_color = TBG_SelectColor(tw);
valueMask = 0;
valueMask |= GCForeground, values.foreground = sel_color;
valueMask |= GCBackground, values.background = LabG_Background(tw);
valueMask |= GCFillStyle, values.fill_style = FillSolid;
valueMask |= GCGraphicsExposures, values.graphics_exposures = FALSE;
TBG_SelectGC(tw) = XtAllocateGC((Widget) mw, 0, valueMask, &values, 0, 0);
/* When foreground and select colors coincide, this GC is used
* by XmLabel to draw the text. It requires a font to pacify
* the XmString draw functions.
*/
valueMask = 0;
if (XmeRenderTableGetDefaultFont(LabG_Font(tw), &fs))
valueMask |= GCFont, values.font = fs->fid;
valueMask |= GCForeground, values.foreground = LabG_Background(tw);
valueMask |= GCBackground, values.background = LabG_Foreground(tw);
valueMask |= GCFillStyle, values.fill_style = FillSolid;
valueMask |= GCGraphicsExposures, values.graphics_exposures = FALSE;
valueMask |= GCLineWidth, values.line_width = 1;
TBG_BackgroundGC(tw) = XtGetGC((Widget) mw, valueMask, &values);
valueMask = 0;
valueMask |= GCFillStyle, values.fill_style = FillOpaqueStippled;
valueMask |= GCGraphicsExposures, values.graphics_exposures = FALSE;
valueMask |= GCStipple, values.stipple =
XmGetPixmapByDepth(XtScreen((Widget)(tw)), XmS50_foreground, 1, 0, 1);
valueMask |= GCLineWidth, values.line_width = 1;
TBG_IndeterminateGC(tw) = XtAllocateGC((Widget) tw, 0, valueMask, &values,
GCForeground | GCBackground, 0);
/* The valueMask and values are inherited from above. */
valueMask &= ~GCLineWidth;
valueMask |= GCForeground, values.foreground = LabG_Background(tw);
valueMask |= GCBackground, values.background = LabG_Foreground(tw);
TBG_IndeterminateBoxGC(tw) = XtGetGC((Widget) tw, valueMask, &values);
/* Create the ArmGC for filling in background if we are in a menu
and enableEtchedInMenu is True. */
if ((LabG_IsMenupane(tw)) && etched_in) {
Widget wid = (Widget) XtParent(tw);
XmGetColors(XtScreen(wid), wid->core.colormap,
wid->core.background_pixel,
NULL, NULL, NULL, &select_pixel);
valueMask = 0;
valueMask |= GCForeground, values.foreground = select_pixel;
valueMask |= GCBackground, values.background = LabG_Foreground(tw);
if (fs != NULL)
valueMask |= GCFont, values.font = fs->fid;
valueMask |= GCGraphicsExposures, values.graphics_exposures = FALSE;
TBG_ArmGC(tw) = XtGetGC((Widget) tw, valueMask, &values);
}
}
/*************************************<->*************************************
*
* Initialize
* If the rectangle height and width fields are set to 0, treat that as a
* flag, and compute the optimum size for this button. Then using what ever
* the rectangle fields are set to, compute the text placement fields.
*************************************<->***********************************/
/*ARGSUSED*/
static void
Initialize(
Widget rw,
Widget nw,
ArgList args, /* unused */
Cardinal *num_args ) /* unused */
{
XmToggleButtonGadget request = (XmToggleButtonGadget) rw ;
XmToggleButtonGadget new_w = (XmToggleButtonGadget) nw ;
XtWidgetProc resize;
TBG_Armed(new_w) = FALSE;
/* if menuProcs is not set up yet, try again */
_XmProcessLock();
resize = xmLabelGadgetClassRec.rect_class.resize;
if (xmLabelGadgetClassRec.label_class.menuProcs == (XmMenuProc)NULL)
xmLabelGadgetClassRec.label_class.menuProcs =
(XmMenuProc) _XmGetMenuProcContext();
_XmProcessUnlock();
if (LabG_IsMenupane(new_w))
{
/* If the shadow thickness hasn't been set yet, inherit it
from the menu parent, instead of a hard-coded 2, as before.
The only draw back is that is the parent has also 0, then
the toggle shadow is 0, which is not very good in a menu,
but at least consistent with the other buttons */
if (new_w->gadget.shadow_thickness <= 0) {
Dimension parent_st ;
XtVaGetValues(XtParent(nw), XmNshadowThickness, &parent_st, NULL);
new_w->gadget.shadow_thickness = parent_st;
}
if (TBG_Visible(new_w) == XmINVALID_BOOLEAN)
TBG_Visible(new_w) = FALSE;
new_w->gadget.traversal_on = TRUE;
}
else
{
if (TBG_Visible(new_w) == XmINVALID_BOOLEAN)
TBG_Visible(new_w) = TRUE;
}
/*
* if the indicatorType has not been set, then
* find out if radio behavior is set for RowColumn parents and
* then set indicatorType. If radio behavior is true, default to
* one of many, else default to n of many.
*/
if ((TBG_IndType( new_w) == XmINVALID_TYPE) ||
!XmRepTypeValidValue(XmRID_INDICATOR_TYPE,
TBG_IndType( new_w), (Widget) new_w))
{
Boolean radio = FALSE;
if (XmIsRowColumn(XtParent(new_w)))
{
XtVaGetValues(XtParent(new_w),
XmNradioBehavior, &radio,
NULL);
}
if (radio)
TBG_IndType(new_w) = XmONE_OF_MANY;
else
TBG_IndType(new_w) = XmN_OF_MANY;
}
/*
* This resource defaults to true if an indicator box is drawn.
*/
if (TBG_FillOnSelect(new_w) == XmINVALID_BOOLEAN)
{
if (DRAWBOX(NormalizeIndOn(new_w)))
TBG_FillOnSelect(new_w) = True;
else if (IsOneOfMany(TBG_IndType(new_w)) &&
TBG_IndOn(new_w))
TBG_FillOnSelect(new_w) = True;
else
TBG_FillOnSelect(new_w) = False;
}
/* Tristate buttons ain't allowed in one-of-many land. */
if (IsOneOfMany(TBG_IndType(new_w)))
TBG_ToggleMode(new_w) = XmTOGGLE_BOOLEAN;
/* Use the On pixmaps if there are no indeterminate pixmaps. */
if (IsNull(PixmapInd(new_w)) && !IsNull(PixmapOn(new_w)))
PixmapInd(new_w) = PixmapOn(new_w);
if (IsNull(PixmapInsenInd(new_w)) && !IsNull(PixmapInsenOn(new_w)))
PixmapInsenInd(new_w) = PixmapInsenOn(new_w);
/* Use the On pixmap if no Off pixmap is available. */
if (IsNull(PixmapOff(new_w)) && !IsNull(PixmapOn(new_w)))
{
PixmapOff(new_w) = PixmapOn(new_w);
if (request->rectangle.width == 0)
new_w->rectangle.width = 0;
if (request->rectangle.height == 0)
new_w->rectangle.height = 0;
_XmCalcLabelGDimensions(nw);
(* resize)( (Widget) new_w);
}
/* Use the insensitive On pixmap if there is no insensitive Off pixmap. */
if (IsNull(PixmapInsenOff(new_w)) && !IsNull(PixmapInsenOn(new_w)))
{
PixmapInsenOff(new_w) = PixmapInsenOn(new_w);
if (request->rectangle.width == 0)
new_w->rectangle.width = 0;
if (request->rectangle.height == 0)
new_w->rectangle.height = 0;
_XmCalcLabelGDimensions(nw);
(* resize)( (Widget) new_w);
}
/* BEGIN OSF Fix pir 1778 */
if (LabG_IsPixmap(new_w) &&
(!IsNull(PixmapOff(new_w)) || !IsNull(PixmapInsenOff(new_w)) ||
!IsNull(PixmapOn(new_w)) || !IsNull(PixmapInsenOn(new_w)) ||
!IsNull(PixmapInd(new_w)) || !IsNull(PixmapInsenInd(new_w))))
{
if (request->rectangle.width == 0)
new_w->rectangle.width = 0;
if (request->rectangle.height == 0)
new_w->rectangle.height = 0;
SetToggleSize(new_w);
}
/* END OSF Fix pir 1778 */
if (TBG_IndicatorDim(new_w) == XmINVALID_DIMENSION) {
if (TBG_IndOn(new_w))
{
/* Determine how high the toggle indicator should be. */
if (LabG_IsPixmap(new_w) || LabG_IsPixmapAndText(new_w))
{
/* Set indicatorSize proportional to size of pixmap. */
if (!IsNull(PixmapOff(new_w)) || !IsNull(PixmapInsenOff(new_w)) ||
!IsNull(PixmapOn(new_w)) || !IsNull(PixmapInsenOn(new_w)) ||
!IsNull(PixmapInd(new_w)) || !IsNull(PixmapInsenInd(new_w)))
if (LabG_TextRect(new_w).height < 13)
TBG_IndicatorDim(new_w) = LabG_TextRect(new_w).height;
else
TBG_IndicatorDim(new_w) = 13 + (LabG_TextRect(new_w).height/13);
else
TBG_IndicatorDim(new_w) = XmDEFAULT_INDICATOR_DIM;
}
else /* Set indicatorSize proportional to size of font. */
{
Dimension height;
int line_count;
height = XmStringHeight (LabG_Font(new_w), LabG__label(new_w));
if ((line_count = XmStringLineCount (LabG__label(new_w))) < 1)
line_count = 1;
/* Shiz recommends toggles in menus have smaller indicators */
if (LabG_IsMenupane(new_w))
TBG_IndicatorDim(new_w) =
MAX(XmDEFAULT_INDICATOR_DIM,
(height / ((Dimension)line_count)) * 2/3);
else
TBG_IndicatorDim(new_w) =
MAX(XmDEFAULT_INDICATOR_DIM, height / ((Dimension)line_count));
}
} else {
TBG_IndicatorDim(new_w) = 0;
}
TBG_IndicatorSet(new_w) = FALSE;
} else {
TBG_IndicatorSet(new_w) = TRUE;
}
/* CR 2337: Maintain original margin values. */
TBG_IndLeftDelta(new_w) = 0;
TBG_IndRightDelta(new_w) = 0;
TBG_IndTopDelta(new_w) = 0;
TBG_IndBottomDelta(new_w) = 0;
if (TBG_IndOn(new_w))
{
/*
* Enlarge the text rectangle if needed to accomodate the size of
* indicator button. Adjust the dimensions of superclass Label-Gadget
* so that the toggle-button may be accommodated in it.
*/
int maxIndicatorSize; /* Max Indicator size permissible */
int delta;
int boxSize;
/* BEGIN OSF Fix pir 2480 */
if (! LabG_IsMenupane(new_w))
maxIndicatorSize = TBG_IndicatorDim(new_w) + 2 * Xm3D_ENHANCE_PIXEL;
else
maxIndicatorSize = TBG_IndicatorDim(new_w);
/* END OSF Fix pir 2480 */
boxSize = ((int) LabG_TextRect(new_w).height +
(int) LabG_MarginTop (new_w) +
(int) LabG_MarginBottom (new_w));
if (maxIndicatorSize > boxSize)
{
delta = (maxIndicatorSize - boxSize) / 2;
TBG_IndTopDelta(new_w) = delta;
LabG_MarginTop(new_w) += delta;
TBG_IndBottomDelta(new_w) = delta;
LabG_MarginBottom(new_w) += delta;
}
/* CR 2337: Make room for toggle indicator and spacing */
if (LayoutIsRtoLG(new_w))
{
delta = (TBG_IndicatorDim(new_w) + TBG_Spacing(new_w) -
LabG_MarginRight(new_w));
if (delta > 0)
{
TBG_IndRightDelta(new_w) = delta;
LabG_MarginRight(new_w) += delta;
}
}
else
{
delta = (TBG_IndicatorDim(new_w) + TBG_Spacing(new_w) -
LabG_MarginLeft(new_w));
if (delta > 0)
{
TBG_IndLeftDelta(new_w) = delta;
LabG_MarginLeft(new_w) += delta;
}
}
}
if (request->rectangle.width == 0)
{
new_w->rectangle.width = LabG_TextRect(new_w).width +
2 * LabG_MarginHeight(new_w) +
LabG_MarginRight(new_w) + LabG_MarginLeft(new_w) +
2 * (new_w->gadget.highlight_thickness +
new_w->gadget.shadow_thickness);
if (new_w->rectangle.width == 0)
new_w->rectangle.width = 1;
if ((LabG__acceleratorText(new_w) != NULL) && (TBG_IndOn(new_w)))
{
if (LayoutIsRtoLG(new_w))
{
LabG_AccTextRect(new_w).x = new_w->gadget.highlight_thickness +
new_w->gadget.shadow_thickness + LabG_MarginHeight(new_w);
}
else
{
LabG_AccTextRect(new_w).x = new_w->rectangle.width -
new_w->gadget.highlight_thickness -
new_w->gadget.shadow_thickness -
LabG_MarginHeight(new_w) -
LabG_MarginRight(new_w) + LABELG_ACC_PAD;
}
}
}
if (request->rectangle.height == 0)
new_w->rectangle.height =
MAX(TBG_IndicatorDim(new_w),
LabG_TextRect(new_w).height + 2 * LabG_MarginHeight(new_w) +
LabG_MarginTop(new_w) + LabG_MarginBottom(new_w)) +
2 * (new_w->gadget.highlight_thickness +
new_w->gadget.shadow_thickness);
LabG_TextRect(new_w).y = new_w->gadget.highlight_thickness
+ new_w->gadget.shadow_thickness
+ LabG_MarginHeight(new_w) + LabG_MarginTop(new_w) +
((new_w->rectangle.height - LabG_MarginTop(new_w)
- LabG_MarginBottom(new_w)
- (2 * (LabG_MarginHeight(new_w)
+ new_w->gadget.highlight_thickness
+ new_w->gadget.shadow_thickness))
- LabG_TextRect(new_w).height) / 2);
if (new_w->rectangle.height == 0)
new_w->rectangle.height = 1;
/* Display toggles as set if XmNset is True initially. */
IsOn(new_w) = TBG_Set(new_w);
/* BEGIN OSF Fix pir 2097 */
new_w->gadget.event_mask = XmARM_EVENT | XmACTIVATE_EVENT |
XmMULTI_ARM_EVENT | XmMULTI_ACTIVATE_EVENT | XmHELP_EVENT |
XmFOCUS_IN_EVENT | XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT |
XmBDRAG_EVENT;
/* END OSF Fix pir 2097 */
(* (resize)) ((Widget) new_w);
/* Unselect same as background unless set. */
if (TBG_UnselectColor(new_w) == INVALID_PIXEL)
TBG_UnselectColor(new_w) = LabG_Background(new_w);
TBG_ReversedSelect(new_w) =
(TBG_SelectColor(new_w) == XmREVERSED_GROUND_COLORS);
if ((TBG_SelectColor(new_w) == INVALID_PIXEL) ||
(TBG_SelectColor(new_w) == XmDEFAULT_SELECT_COLOR))
{
XrmValue value;
value.size = sizeof(Pixel);
DefaultSelectColor((Widget) new_w,
XtOffsetOf(XmToggleButtonGCacheObjRec,
toggle_cache.select_color),
&value);
memcpy((char*) &TBG_SelectColor(new_w), value.addr, value.size);
}
else if (TBG_SelectColor(new_w) == XmREVERSED_GROUND_COLORS)
{
TBG_SelectColor(new_w) = LabG_Foreground(new_w);
}
else if (TBG_SelectColor(new_w) == XmHIGHLIGHT_COLOR)
{
TBG_SelectColor(new_w) = LabG_HighlightColor(new_w);
}
GetGC (new_w);
GetUnselectGC(new_w);
}
/************************************************************************
*
* Destroy
* Free toggleButton's graphic context.
*
************************************************************************/
static void
Destroy(
Widget w )
{
XmToggleButtonGadget tw = (XmToggleButtonGadget) w;
XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(w));
Boolean etched_in = dpy->display.enable_etched_in_menu;
XtReleaseGC (XtParent(tw), TBG_SelectGC(tw));
XtReleaseGC (XtParent(tw), TBG_BackgroundGC(tw));
XtReleaseGC (XtParent(tw), TBG_UnselectGC(tw));
XtReleaseGC (XtParent(tw), TBG_IndeterminateGC(tw));
XtReleaseGC (XtParent(tw), TBG_IndeterminateBoxGC(tw));
if (LabG_IsMenupane(tw) && etched_in)
XtReleaseGC ((Widget) tw, TBG_ArmGC(tw));
_XmProcessLock();
_XmCacheDelete( (XtPointer) TBG_Cache(tw));
_XmProcessUnlock();
}
static void
DrawBox(XmToggleButtonGadget w,
GC top_gc,
GC bot_gc,
GC fillgc,
int x,
int y,
int edge,
Dimension margin)
{
int shadow = w->toggle.detail_shadow_thickness;
XmeDrawShadows(XtDisplay ((Widget) w),
XtWindow ((Widget) w),
top_gc,
bot_gc,
x, y, edge, edge,
shadow, XmSHADOW_OUT);
/* Don't fill the background on mono screens if we're going to */
/* draw a glyph */
if (DefaultDepthOfScreen(XtScreen(w)) == 1 && DRAWGLYPH(NormalizeIndOn(w)))
return;
shadow += margin;
if (edge > (shadow * 2))
XFillRectangle (XtDisplay ((Widget) w),
XtWindow ((Widget) w),
fillgc,
x + shadow,
y + shadow,
edge - (shadow * 2),
edge - (shadow * 2));
}
/*************************************<->*************************************
*
* DrawToggle
* Depending on the state of this widget, draw the ToggleButton.
*
*************************************<->***********************************/
static void
DrawToggle(
XmToggleButtonGadget w )
{
int x, y, edge;
Dimension margin;
XGCValues values;
Display *dpy = XtDisplay((Widget) w);
Drawable drawable = XtWindow(XtParent((Widget) w));
XmDisplay dpyxm = (XmDisplay) XmGetXmDisplay(XtDisplay(w));
Boolean etched_in = dpyxm->display.enable_etched_in_menu;
if (LabG_IsPixmap(w) || XmStringEmpty(LabG__label(w)))
edge = TBG_IndicatorDim(w);
else
edge =
MIN((int)TBG_IndicatorDim(w),
MAX(0,
(int)w->rectangle.height -
2 * (w->gadget.highlight_thickness + w->gadget.shadow_thickness +
(int)LabG_MarginHeight(w)) +
LabG_MarginTop(w) + LabG_MarginBottom(w)));
if ((DefaultDepthOfScreen(XtScreen(w)) > 1) &&
(LabG_TopShadowColor(w) != TBG_SelectColor(w)) &&
(LabG_BottomShadowColor (w)!= TBG_SelectColor(w)))
margin = 0;
else
margin = 1;
if (LayoutIsRtoLG(w))
x = w->rectangle.x + w->rectangle.width -
w->gadget.highlight_thickness - w->gadget.shadow_thickness -
LabG_MarginHeight(w) - TBG_IndicatorDim(w);
else
x = w->rectangle.x +
w->gadget.highlight_thickness + w->gadget.shadow_thickness +
LabG_MarginHeight(w);
if (LabG_IsPixmap(w) || XmStringEmpty(LabG__label(w)))
y = w->rectangle.y +
(int)((w->rectangle.height - TBG_IndicatorDim(w)))/2;
else
{
/* Center indicator vertically next to the first line of text. */
int fudge = Xm3D_ENHANCE_PIXEL;
Dimension text_height;
int line_count, height_diff;
text_height = XmStringHeight(LabG_Font(w), LabG__label(w));
if ((line_count = XmStringLineCount(LabG__label(w))) < 1)
line_count = 1;
height_diff = ((int)text_height / line_count) - (int)TBG_IndicatorDim(w);
if (height_diff < 0)
height_diff = 0;
y = w->rectangle.y + LabG_TextRect(w).y + (height_diff / 2);
/* CR 2337: Keep large indicators inside the toggle. */
/* Is this definition of fudge right??? */
if (TBG_IndTopDelta(w) > fudge)
y -= (TBG_IndTopDelta(w) - fudge);
}
if (TBG_Visible(w) || (IsOn(w) == XmSET))
{
/* The toggle indicator should be visible. */
GC top_gc, bot_gc, fill_gc, glyph_gc;
unsigned char normal_ind_on = NormalizeIndOn(w);
switch (TBG_VisualSet(w))
{
case XmUNSET:
top_gc = LabG_TopShadowGC(w);
bot_gc = LabG_BottomShadowGC(w);
/* use the arm GC in a menu if armed and enableEtchedInMenu is set */
if (LabG_IsMenupane(w) && etched_in && TBG_Armed(w))
fill_gc = (TBG_FillOnSelect(w) ?
TBG_UnselectGC(w) : TBG_ArmGC(w));
else
fill_gc = (TBG_FillOnSelect(w) ?
TBG_UnselectGC(w) : LabG_BackgroundGC(w));
glyph_gc = None;
break;
case XmSET:
top_gc = LabG_BottomShadowGC(w);
bot_gc = LabG_TopShadowGC(w);
/* use the arm GC in a menu if armed and enableEtchedInMenu is set */
if (LabG_IsMenupane(w) && etched_in && TBG_Armed(w))
fill_gc = (TBG_FillOnSelect(w) ?
TBG_SelectGC(w) : TBG_ArmGC(w));
else
fill_gc = (TBG_FillOnSelect(w) ?
TBG_SelectGC(w) : LabG_BackgroundGC(w));
glyph_gc = ((TBG_ReversedSelect(w) && DRAWBOX(normal_ind_on)) ?
LabG_BackgroundGC(w) : LabG_NormalGC(w));
/* CR 9791: Label's normal_gc has a dynamic clip_mask. */
if (glyph_gc == LabG_NormalGC(w))
XSetClipMask(dpy, glyph_gc, None);
break;
case XmINDETERMINATE:
top_gc = bot_gc = TBG_IndeterminateBoxGC(w);
/* use the arm GC in a menu if armed and enableEtchedInMenu is set */
if (LabG_IsMenupane(w) && etched_in && TBG_Armed(w))
fill_gc = (TBG_FillOnSelect(w) ?
TBG_IndeterminateGC(w) : TBG_ArmGC(w));
else
fill_gc = (TBG_FillOnSelect(w) ?
TBG_IndeterminateGC(w) : LabG_BackgroundGC(w));
glyph_gc = TBG_IndeterminateGC(w);
break;
default:
assert(False);
return;
}
switch (NormalizeIndType(w))
{
case XmN_OF_MANY:
{
/* If the toggle indicator is square shaped then adjust the
* indicator width and height, so that it looks proportional
* to a diamond shaped indicator of the same width and height
*/
int new_edge;
Dimension box_margin = (DRAWBOX(normal_ind_on) ?
w->toggle.detail_shadow_thickness : 0);
/* Subtract 3 pixels + 10% from the width and height. */
new_edge = edge - 3 - ((edge - 10)/10);
/* Adjust x,y to center the indicator relative to the label. */
y = y + ((edge - new_edge) / 2);
x = x + ((edge - new_edge) / 2);
edge = new_edge;
switch(TBG_VisualSet(w))
{
case XmUNSET:
if (edge > 0)
{
if (w->label.fill_bg_box || TBG_FillOnSelect(w))
XFillRectangle(dpy, drawable, fill_gc, x, y, edge, edge);
else
XClearArea(dpy, drawable, x, y, edge, edge, False);
}
if (DRAW3DBOX(normal_ind_on))
DrawBox(w, top_gc, bot_gc, fill_gc, x, y, edge, margin);
else if (DRAWFLATBOX(normal_ind_on))
DrawBox(w, bot_gc, bot_gc, fill_gc, x, y, edge, margin);
break;
case XmSET:
if (DRAW3DBOX(normal_ind_on))
DrawBox(w, top_gc, bot_gc, fill_gc, x, y, edge, margin);
else if (DRAWFLATBOX(normal_ind_on))
DrawBox(w, top_gc, top_gc, fill_gc, x, y, edge, margin);
else if (edge > 0)
{
if (w->label.fill_bg_box || TBG_FillOnSelect(w))
XFillRectangle(dpy, drawable, fill_gc, x, y, edge, edge);
else
XClearArea(dpy, drawable, x, y, edge, edge, False);
}
if (!DRAWBOX(normal_ind_on) ||
((edge - 2 * box_margin) >= MIN_GLYPH_SIZE))
{
if (DRAWCHECK(normal_ind_on))
XmeDrawIndicator(dpy, drawable, glyph_gc,
x, y, edge, edge, box_margin,
normal_ind_on);
else if (DRAWCROSS(normal_ind_on))
XmeDrawIndicator(dpy, drawable, glyph_gc,
x, y, edge, edge, box_margin,
normal_ind_on);
}
break;
case XmINDETERMINATE:
if (TBG_FillOnSelect(w))
{
/* Fetch the select_color GetGC() actually used. */
XGetGCValues(dpy, TBG_SelectGC(w), GCForeground, &values);
values.background = values.foreground;
values.foreground = TBG_UnselectColor(w);
XChangeGC(dpy, fill_gc,
GCForeground|GCBackground, &values);
}
else
{
/* This GC should have the right values already. */
fill_gc = TBG_IndeterminateBoxGC(w);
}
if (DRAWBOX(normal_ind_on))
DrawBox(w, bot_gc, bot_gc, fill_gc, x, y, edge, margin);
else if (edge > 0)
{
if (w->label.fill_bg_box || TBG_FillOnSelect(w))
XFillRectangle(dpy, drawable, fill_gc, x, y, edge, edge);
else
XClearArea(dpy, drawable, x, y, edge, edge, False);
}
if (TBG_ReversedSelect(w))
{
values.foreground = LabG_Background(w);
values.background = LabG_Foreground(w);
}
else
{
values.foreground = LabG_Foreground(w);
values.background = LabG_Background(w);
}
if (!DRAWBOX(normal_ind_on) ||
((edge - 2 * box_margin) >= MIN_GLYPH_SIZE))
{
if (DRAWCHECK(normal_ind_on))
{
XChangeGC(dpy, glyph_gc,
GCForeground|GCBackground, &values);
XmeDrawIndicator(dpy, drawable, glyph_gc, x, y,
edge, edge, box_margin,
normal_ind_on);
}
else if (DRAWCROSS(normal_ind_on))
{
XChangeGC(dpy, glyph_gc,
GCForeground|GCBackground, &values);
XmeDrawIndicator(dpy, drawable, glyph_gc, x, y,
edge, edge, box_margin,
normal_ind_on);
}
}
break;
}
break;
}
case XmONE_OF_MANY:
/* This value should have been normalized away! */
assert(FALSE);
case XmONE_OF_MANY_DIAMOND:
XmeDrawDiamond(dpy, drawable, top_gc, bot_gc, fill_gc, x, y,
edge, edge, w->toggle.detail_shadow_thickness,margin);
break;
case XmONE_OF_MANY_ROUND:
#ifdef FIX_1402
XmeDrawCircle(dpy, drawable, top_gc, bot_gc, fill_gc, x, y,
edge, edge, w->toggle.detail_shadow_thickness, margin);
#else
XmeDrawCircle(dpy, drawable, top_gc, bot_gc, fill_gc, x, y,
edge, edge, w->toggle.detail_shadow_thickness, 1);
#endif
break;
}
}
else
{
/* The toggle indicator should be invisibile. */
if (edge > 0)
{
if (LabG_IsMenupane(w) && etched_in) {
if (w->toggle.Armed)
/* use the arm GC in a menu if armed and enableEtchedInMenu is set */
XFillRectangle(dpy, drawable, TBG_ArmGC(w), x, y,
edge, edge);
else
XFillRectangle(dpy, drawable, TBG_BackgroundGC(w), x, y,
edge, edge);
}
else
if (w->label.fill_bg_box)
XFillRectangle(dpy, drawable, TBG_BackgroundGC(w), x, y,
edge, edge);
else
XClearArea(dpy, drawable, x, y, edge, edge, False);
}
}
}
/*************************************<->*************************************
*
* BorderHighlight
*
*************************************<->***********************************/
static void
BorderHighlight(
Widget wid )
{
XmToggleButtonGadget tb = (XmToggleButtonGadget) wid ;
XEvent * event = NULL;
if (LabG_IsMenupane(tb))
{
XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid));
Boolean etched_in = dpy->display.enable_etched_in_menu;
TBG_Armed(tb) = TRUE;
if ((etched_in) &&
(TBG_IndOn(tb) ||
(!(TBG_IndOn(tb)) && !(TBG_FillOnSelect(tb)))))
{
DrawEtchedInMenu(tb);
if (TBG_IndOn(tb))
DrawToggle(tb);
}
XmeDrawShadows (XtDisplay (tb), XtWindow (tb),
LabG_TopShadowGC(tb),
LabG_BottomShadowGC(tb),
tb->rectangle.x + tb->gadget.highlight_thickness,
tb->rectangle.y + tb->gadget.highlight_thickness,
tb->rectangle.width -
2 * tb->gadget.highlight_thickness,
tb->rectangle.height -
2 * tb->gadget.highlight_thickness,
tb->gadget.shadow_thickness,
etched_in ? XmSHADOW_IN : XmSHADOW_OUT);
if (TBG_ArmCB(tb))
{
XFlush (XtDisplay (tb));
ToggleButtonCallback(tb, XmCR_ARM, TBG_Set(tb), event);
}
}
else
{
(*(xmLabelGadgetClassRec.gadget_class.border_highlight))((Widget) tb) ;
}
}
/*************************************<->*************************************
*
* BorderUnhighlight
*
*************************************<->***********************************/
static void
BorderUnhighlight(
Widget wid )
{
XmToggleButtonGadget tb = (XmToggleButtonGadget) wid ;
XEvent * event = NULL;
if (LabG_IsMenupane(tb))
{
XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid));
Boolean etched_in = dpy->display.enable_etched_in_menu;
if (!TBG_Armed(tb))
return;
TBG_Armed(tb) = FALSE;
if ((etched_in) &&
(TBG_IndOn(tb) ||
(!(TBG_IndOn(tb)) && !(TBG_FillOnSelect(tb)))))
{
DrawEtchedInMenu(tb);
if (TBG_IndOn(tb))
DrawToggle(tb);
}
XmeClearBorder (XtDisplay (tb), XtWindow (tb),
tb->rectangle.x + tb->gadget.highlight_thickness,
tb->rectangle.y + tb->gadget.highlight_thickness,
tb->rectangle.width -
2 * tb->gadget.highlight_thickness,
tb->rectangle.height -
2 * tb->gadget.highlight_thickness,
tb->gadget.shadow_thickness);
if (TBG_DisarmCB(tb))
{
XFlush (XtDisplay (tb));
ToggleButtonCallback(tb, XmCR_DISARM, TBG_Set(tb), event);
}
}
else
{
(*(xmLabelGadgetClassRec.gadget_class.border_unhighlight)) ((Widget) tb) ;
}
}
/*************************************<->*************************************
*
* KeySelect
* If the menu system traversal is enabled, do an activate and disarm
*
*************************************<->***********************************/
static void
KeySelect(
XmToggleButtonGadget tb,
XEvent *event )
{
XmToggleButtonCallbackStruct call_value;
XmMenuSystemTrait menuSTrait;
menuSTrait = (XmMenuSystemTrait)
XmeTraitGet((XtPointer) XtClass(XtParent(tb)), XmQTmenuSystem);
if (menuSTrait == NULL) return;
if (!_XmIsEventUnique(event))
return;
if (!_XmGetInDragMode((Widget)tb))
{
if (TBG_IndOn(tb))
DrawToggle(tb);
else if (TBG_FillOnSelect(tb) && !LabG_IsPixmap(tb))
DrawToggleLabel (tb);
if (LabG_IsPixmap(tb) || LabG_IsPixmapAndText(tb))
SetAndDisplayPixmap( tb, NULL, NULL);
TBG_Armed(tb) = FALSE;
TBG_Set(tb) = (TBG_Set(tb) == TRUE) ? FALSE : TRUE;
menuSTrait->buttonPopdown(XtParent(tb), event);
_XmRecordEvent(event);
/* UNDOING this fix ... */
/* CR 8904: Notify value_changed before entry so that state is */
/* reported correctly even if the entry callback resets it. */
/* Notify parent about the select. */
call_value.reason = XmCR_VALUE_CHANGED;
call_value.event = event;
call_value.set = TBG_Set(tb);
menuSTrait->entryCallback(XtParent(tb), (Widget) tb, &call_value);
menuSTrait->reparentToTearOffShell(XtParent(tb), event);
if ((! LabG_SkipCallback(tb)) &&
(TBG_ValueChangedCB(tb)))
{
XFlush(XtDisplay(tb));
ToggleButtonCallback(tb, XmCR_VALUE_CHANGED, TBG_Set(tb), event);
}
}
}
/************************************************************************
*
* Compute Space
*
***********************************************************************/
static void
ComputeSpace(
XmToggleButtonGadget tb )
{
int needed_width;
int needed_height;
/* Compute space for drawing toggle. */
needed_width = LabG_TextRect(tb).width +
LabG_MarginLeft(tb) + LabG_MarginRight(tb) +
(2 * (tb->gadget.shadow_thickness +
tb->gadget.highlight_thickness +
LabG_MarginWidth(tb)));
needed_height = LabG_TextRect(tb).height +
LabG_MarginTop(tb) + LabG_MarginBottom(tb) +
(2 * (tb->gadget.shadow_thickness +
tb->gadget.highlight_thickness +
LabG_MarginHeight(tb)));
if (needed_height > tb->rectangle.height)
if (TBG_IndOn(tb))
LabG_TextRect(tb).y = tb->gadget.shadow_thickness +
tb->gadget.highlight_thickness +
LabG_MarginHeight(tb) +
LabG_MarginTop(tb) +
((tb->rectangle.height - LabG_MarginTop(tb)
- LabG_MarginBottom(tb)
- (2 * (LabG_MarginHeight(tb)
+ tb->gadget.highlight_thickness
+ tb->gadget.shadow_thickness))
- LabG_TextRect(tb).height) / 2);
if (LayoutIsRtoLG(tb))
{
if ((needed_width > tb->rectangle.width) ||
((LabG_Alignment(tb) == XmALIGNMENT_BEGINNING)
&& (needed_width < tb->rectangle.width)) ||
((LabG_Alignment(tb) == XmALIGNMENT_CENTER)
&& (needed_width < tb->rectangle.width)
&& (tb->rectangle.width - needed_width < LabG_MarginRight(tb))) ||
(needed_width == tb->rectangle.width))
{
if (TBG_IndOn(tb))
LabG_TextRect(tb).x = tb->rectangle.x + tb->rectangle.width -
(tb->gadget.shadow_thickness +
tb->gadget.highlight_thickness +
LabG_MarginHeight(tb) +
LabG_MarginRight(tb) +
LabG_TextRect(tb).width);
}
}
else
{
if ((needed_width > tb->rectangle.width) ||
((LabG_Alignment(tb) == XmALIGNMENT_BEGINNING)
&& (needed_width < tb->rectangle.width)) ||
((LabG_Alignment(tb) == XmALIGNMENT_CENTER)
&& (needed_width < tb->rectangle.width)
&& (tb->rectangle.width - needed_width < LabG_MarginLeft(tb))) ||
(needed_width == tb->rectangle.width))
{
if (TBG_IndOn(tb))
LabG_TextRect(tb).x = tb->gadget.shadow_thickness +
tb->gadget.highlight_thickness +
LabG_MarginHeight(tb) +
LabG_MarginLeft(tb);
}
}
}
/*************************************<->*************************************
*
* Redisplay(w, event, region)
* Cause the widget, identified by w, to be redisplayed.
*
*************************************<->***********************************/
static void
Redisplay(
Widget w,
XEvent *event,
Region region )
{
register XmToggleButtonGadget tb = (XmToggleButtonGadget) w;
/* Fix CR #4884, D. Rand 6/4/92 */
if (! XtIsRealized(w) ) return;
/* End Fix */
if (LabG_IsMenupane(tb))
{
ShellWidget mshell = (ShellWidget) XtParent(XtParent(tb));
if (! mshell->shell.popped_up)
return;
}
ComputeSpace(tb);
if (LabG_IsPixmap (tb) || LabG_IsPixmapAndText(tb))
SetAndDisplayPixmap(tb, event, region);
else
{
if (!TBG_IndOn(tb) && TBG_FillOnSelect(tb))
DrawToggleLabel (tb);
else {
XtExposeProc expose;
_XmProcessLock();
expose = xmLabelGadgetClassRec.rect_class.expose;
_XmProcessUnlock();
(* expose) ((Widget)tb, event, region);
}
}
if (TBG_IndOn(tb))
{
if (! TBG_Armed(tb))
IsOn(tb) = TBG_Set(tb);
DrawToggle(tb);
}
if (LabG_IsMenupane(tb))
{
XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(w));
Boolean etched_in = dpy -> display.enable_etched_in_menu;
if (TBG_Armed(tb))
XmeDrawShadows(XtDisplay (tb), XtWindow (tb),
LabG_TopShadowGC(tb),
LabG_BottomShadowGC(tb),
tb->rectangle.x + tb->gadget.highlight_thickness,
tb->rectangle.y + tb->gadget.highlight_thickness,
tb->rectangle.width - 2*tb->gadget.highlight_thickness,
tb->rectangle.height - 2*tb->gadget.highlight_thickness,
tb->gadget.shadow_thickness,
etched_in ? XmSHADOW_IN : XmSHADOW_OUT);
}
else
{
DrawToggleShadow (tb);
}
}
/**************************************************************************
* Resize(w, event)
**************************************************************************/
static void
Resize(
Widget w )
{
register XmToggleButtonGadget tb = (XmToggleButtonGadget) w;
if (LabG_IsPixmap(w))
SetToggleSize(tb);
else {
XtWidgetProc resize;
_XmProcessLock();
resize = xmLabelGadgetClassRec.rect_class.resize;
_XmProcessUnlock();
(* resize)( (Widget) tb);
}
}
/************************************************************************
*
* SetValuesPrehook
*
************************************************************************/
/* ARGSUSED */
static Boolean
SetValuesPrehook(
Widget oldParent,
Widget refParent,
Widget newParent,
ArgList args,
Cardinal *num_args )
{
XmWidgetExtData extData;
XmBaseClassExt *cePtr;
WidgetClass ec;
Cardinal size;
XmToggleButtonGCacheObject newSec, reqSec;
_XmProcessLock();
cePtr = _XmGetBaseClassExtPtr(XtClass(newParent), XmQmotif);
ec = (*cePtr)->secondaryObjectClass;
size = ec->core_class.widget_size;
newSec = (XmToggleButtonGCacheObject)_XmExtObjAlloc(size);
reqSec = (XmToggleButtonGCacheObject)_XmExtObjAlloc(size);
_XmProcessUnlock();
newSec->object.self = (Widget)newSec;
newSec->object.widget_class = ec;
newSec->object.parent = XtParent(newParent);
newSec->object.xrm_name = newParent->core.xrm_name;
newSec->object.being_destroyed = False;
newSec->object.destroy_callbacks = NULL;
newSec->object.constraints = NULL;
newSec->ext.logicalParent = newParent;
newSec->ext.extensionType = XmCACHE_EXTENSION;
memcpy (&(newSec->label_cache),
LabG_Cache(newParent),
sizeof(XmLabelGCacheObjPart));
memcpy(&(newSec->toggle_cache),
TBG_Cache(newParent),
sizeof(XmToggleButtonGCacheObjPart));
extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec));
extData->widget = (Widget)newSec;
extData->reqWidget = (Widget)reqSec;
_XmPushWidgetExtData(newParent, extData, XmCACHE_EXTENSION);
/*
* Since the resource lists for label and togglebutton were merged at
* ClassInitialize time we need to make only one call to
* XtSetSubvalues()
*/
XtSetSubvalues((XtPointer)newSec,
ec->core_class.resources,
ec->core_class.num_resources,
args, *num_args);
memcpy((XtPointer)reqSec, (XtPointer)newSec, size);
LabG_Cache(newParent) = &(((XmLabelGCacheObject)newSec)->label_cache);
LabG_Cache(refParent) = &(((XmLabelGCacheObject)
extData->reqWidget)->label_cache);
TBG_Cache(newParent) =
&(((XmToggleButtonGCacheObject)newSec)->toggle_cache);
TBG_Cache(refParent) =
&(((XmToggleButtonGCacheObject)extData->reqWidget)->toggle_cache);
_XmExtImportArgs((Widget)newSec, args, num_args);
/* CR 2990: Use XmNbuttonFontList as the default font. */
if (LabG_Font(newParent) == NULL)
LabG_Font(newParent) = XmeGetDefaultRenderTable (newParent,
XmBUTTON_FONTLIST);
return FALSE;
}
/************************************************************************
*
* GetValuesPrehook
*
************************************************************************/
/* ARGSUSED */
static void
GetValuesPrehook(
Widget newParent,
ArgList args,
Cardinal *num_args )
{
XmWidgetExtData extData;
XmBaseClassExt *cePtr;
WidgetClass ec;
Cardinal size;
XmToggleButtonGCacheObject newSec;
_XmProcessLock();
cePtr = _XmGetBaseClassExtPtr(XtClass(newParent), XmQmotif);
ec = (*cePtr)->secondaryObjectClass;
size = ec->core_class.widget_size;
newSec = (XmToggleButtonGCacheObject)_XmExtObjAlloc(size);
_XmProcessUnlock();
newSec->object.self = (Widget)newSec;
newSec->object.widget_class = ec;
newSec->object.parent = XtParent(newParent);
newSec->object.xrm_name = newParent->core.xrm_name;
newSec->object.being_destroyed = False;
newSec->object.destroy_callbacks = NULL;
newSec->object.constraints = NULL;
newSec->ext.logicalParent = newParent;
newSec->ext.extensionType = XmCACHE_EXTENSION;
memcpy (&(newSec->label_cache),
LabG_Cache(newParent),
sizeof(XmLabelGCacheObjPart));
memcpy (&(newSec->toggle_cache),
TBG_Cache(newParent),
sizeof(XmToggleButtonGCacheObjPart));
extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec));
extData->widget = (Widget)newSec;
_XmPushWidgetExtData(newParent, extData, XmCACHE_EXTENSION);
/*
* Note that if a resource is defined in the superclass's as well as a
* subclass's resource list and if a NULL is passed in as the third
* argument to XtSetArg, then when a GetSubValues() is done by the
* superclass the NULL is replaced by a value. Now when the subclass
* gets the arglist it doesn't see a NULL and thinks it's an address
* it needs to stuff a value into and sure enough it breaks.
* This means that we have to pass the same arglist with the NULL to
* both the superclass and subclass and propagate the values up once
* the XtGetSubValues() are done.
*/
/*
* Since the resource lists for label and togglebutton were merged at
* ClassInitialize time we need to make only one call to
* XtGetSubvalues()
*/
XtGetSubvalues((XtPointer)newSec,
ec->core_class.resources,
ec->core_class.num_resources,
args, *num_args);
_XmExtGetValuesHook((Widget)newSec, args, num_args);
}
/************************************************************************
*
* GetValuesPosthook
*
************************************************************************/
/*ARGSUSED*/
static void
GetValuesPosthook(
Widget new_w,
ArgList args, /* unused */
Cardinal *num_args ) /* unused */
{
XmWidgetExtData ext;
_XmPopWidgetExtData(new_w, &ext, XmCACHE_EXTENSION);
_XmProcessLock();
_XmExtObjFree((XtPointer) ext->widget);
_XmProcessUnlock();
XtFree( (char *) ext);
}
/************************************************************************
*
* SetValuesPosthook
*
************************************************************************/
/*ARGSUSED*/
static Boolean
SetValuesPosthook(
Widget current,
Widget req, /* unused */
Widget new_w,
ArgList args, /* unused */
Cardinal *num_args ) /* unused */
{
XmWidgetExtData ext;
/*
* - register parts in cache.
* - update cache pointers
* - and free req
*/
/* assign if changed! */
_XmProcessLock();
if (!_XmLabelCacheCompare((XtPointer)LabG_Cache(new_w),
(XtPointer)LabG_Cache(current)))
{ /* delete the old one */
_XmCacheDelete( (XtPointer) LabG_Cache(current));
LabG_Cache(new_w) = (XmLabelGCacheObjPart *)
_XmCachePart(LabG_ClassCachePart(new_w),
(XtPointer) LabG_Cache(new_w),
sizeof(XmLabelGCacheObjPart));
}
else
LabG_Cache(new_w) = LabG_Cache(current);
/* assign if changed! */
if (!_XmToggleBCacheCompare((XtPointer)TBG_Cache(new_w),
(XtPointer)TBG_Cache(current)))
{ /* delete the old one */
_XmCacheDelete( (XtPointer) TBG_Cache(current));
TBG_Cache(new_w) = (XmToggleButtonGCacheObjPart *)
_XmCachePart(TBG_ClassCachePart(new_w),
(XtPointer) TBG_Cache(new_w),
sizeof(XmToggleButtonGCacheObjPart));
}
else
TBG_Cache(new_w) = TBG_Cache(current);
_XmPopWidgetExtData(new_w, &ext, XmCACHE_EXTENSION);
_XmExtObjFree((XtPointer) ext->widget);
_XmExtObjFree((XtPointer) ext->reqWidget);
_XmProcessUnlock();
XtFree( (char *) ext);
return FALSE;
}
/***************************************************************************
*
* SetValues(current, request, new_w)
* This is the set values procedure for the ToggleButton class. It is
* called last (the set values rtnes for its superclasses are called
* first).
*
*************************************<->***********************************/
/*ARGSUSED*/
static Boolean
SetValues(
Widget current,
Widget request,
Widget new_w,
ArgList args, /* unused */
Cardinal *num_args ) /* unused */
{
XmToggleButtonGadget curcbox = (XmToggleButtonGadget) current;
XmToggleButtonGadget reqcbox = (XmToggleButtonGadget) request;
XmToggleButtonGadget newcbox = (XmToggleButtonGadget) new_w;
Boolean flag = FALSE; /* our return value */
XtWidgetProc resize;
/* CR 2337: Preserve the user's margins. */
if (LabG_MarginRight(curcbox) != LabG_MarginRight(reqcbox))
TBG_IndRightDelta(newcbox) = 0;
if (LabG_MarginLeft(curcbox) != LabG_MarginLeft(reqcbox))
TBG_IndLeftDelta(newcbox) = 0;
if (LabG_MarginTop(curcbox) != LabG_MarginTop(reqcbox))
TBG_IndTopDelta(newcbox) = 0;
if (LabG_MarginBottom(curcbox) != LabG_MarginBottom(reqcbox))
TBG_IndBottomDelta(newcbox) = 0;
/**********************************************************************
* Calculate the window size: The assumption here is that if
* the width and height are the same in the new and current instance
* record that those fields were not changed with set values. Therefore
* its okay to recompute the necessary width and height. However, if
* the new and current do have different width/heights then leave them
* alone because that's what the user wants.
*********************************************************************/
_XmProcessLock();
resize = xmLabelGadgetClassRec.rect_class.resize;
_XmProcessUnlock();
/* Use the On pixmaps if no Indeterminate pixmaps are found. */
if (IsNull(PixmapInd(newcbox)) && !IsNull(PixmapOn(newcbox)))
PixmapInd(newcbox) = PixmapOn(newcbox);
if (IsNull(PixmapInsenInd(newcbox)) && !IsNull(PixmapInsenOn(newcbox)))
PixmapInsenInd(newcbox) = PixmapInsenOn(newcbox);
/* Use the On pixmap if no Off pixmap is found. */
if (IsNull(PixmapOff(newcbox)) && !IsNull(PixmapOn(newcbox)))
{
PixmapOff(newcbox) = PixmapOn(newcbox);
if ((LabG_RecomputeSize(newcbox)) &&
(request->core.width == current->core.width))
new_w->core.width = 0;
if ((LabG_RecomputeSize(newcbox)) &&
(request->core.height == current->core.height))
new_w->core.height = 0;
_XmCalcLabelGDimensions(new_w);
(* resize)( (Widget) newcbox);
}
/* Use the insensitive On pixmap if no insensitive Off pixmap is found. */
if (IsNull(PixmapInsenOff(newcbox)) && !IsNull(PixmapInsenOn(newcbox)))
{
PixmapInsenOff(newcbox) = PixmapInsenOn(newcbox);
if ((LabG_RecomputeSize(newcbox)) &&
(request->core.width == current->core.width))
new_w->core.width = 0;
if ((LabG_RecomputeSize(newcbox)) &&
(request->core.height == current->core.height))
new_w->core.height = 0;
_XmCalcLabelGDimensions(new_w);
(* resize)( (Widget) newcbox);
}
/* BEGIN OSF Fix pir 1778 */
/* Have to reset the TextRect width because label's resize will have
mucked with it. */
if (LabG_IsPixmap(newcbox) &&
(!IsNull(PixmapOff(newcbox)) || !IsNull(PixmapInsenOff(newcbox)) ||
!IsNull(PixmapOn(newcbox)) || !IsNull(PixmapInsenOn(newcbox)) ||
!IsNull(PixmapInd(newcbox)) || !IsNull(PixmapInsenInd(newcbox))))
{
if (LabG_RecomputeSize(newcbox))
{
if (request->core.width == current->core.width)
new_w->core.width = 0;
if (request->core.height == current->core.height)
new_w->core.height = 0;
}
SetToggleSize(newcbox);
}
/* END OSF Fix pir 1778 */
/* CR 9922: Changing fillOnSelect requires a redraw. */
if (TBG_FillOnSelect(newcbox) != TBG_FillOnSelect(curcbox))
{
flag = TRUE;
}
if ((LabG__label(newcbox) != LabG__label(curcbox)) ||
(PixmapOff(newcbox) != PixmapOff(curcbox)) ||
(LabG_Font(newcbox) != LabG_Font(curcbox)) ||
(TBG_Spacing(newcbox) != TBG_Spacing(curcbox)) ||
(PixmapOn(newcbox) != PixmapOn(curcbox)) ||
(PixmapInsenOn(newcbox) != PixmapInsenOn(curcbox)) ||
(PixmapInd(newcbox) != PixmapInd(curcbox)) ||
(PixmapInsenInd(newcbox) != PixmapInsenInd(curcbox)) ||
(TBG_IndOn(newcbox) != TBG_IndOn(curcbox)) ||
(TBG_IndicatorDim(newcbox) != TBG_IndicatorDim(curcbox)) ||
(LabG_IsPixmap(newcbox) != LabG_IsPixmap(curcbox)) ||
(LabG_IsPixmapAndText(newcbox) != LabG_IsPixmapAndText(curcbox)))
{
int right_delta = 0; /* Our desired margin adjustments. */
int left_delta = 0;
int top_delta = 0;
int bottom_delta = 0;
if (LabG_RecomputeSize(newcbox))
{
if (reqcbox->rectangle.width == curcbox->rectangle.width)
newcbox->rectangle.width = 0;
if (reqcbox->rectangle.height == curcbox->rectangle.height)
newcbox->rectangle.height = 0;
}
if (LabG_IsPixmap(newcbox) &&
((PixmapOn(newcbox) != PixmapOn(curcbox)) ||
(PixmapInsenOn(newcbox) != PixmapInsenOn(curcbox)) ||
(PixmapInd(newcbox) != PixmapInd(curcbox)) ||
(PixmapInsenInd(newcbox) != PixmapInsenInd(curcbox))) )
{
_XmCalcLabelGDimensions(new_w);
/* OSF Fix 1778 */
SetToggleSize(newcbox);
}
TBG_IndicatorSet(newcbox) = TBG_IndicatorSet(curcbox);
if ( TBG_IndicatorDim(newcbox) != TBG_IndicatorDim(curcbox))
TBG_IndicatorSet(newcbox) = TRUE;
/* CR 8415: Honor explicit requests for XmNindicatorSize. */
if (!TBG_IndicatorSet(newcbox) &&
(TBG_IndicatorDim(newcbox) == TBG_IndicatorDim(curcbox)))
{
if ((LabG_IsPixmap(newcbox) != LabG_IsPixmap(curcbox)) ||
(LabG_IsPixmapAndText(newcbox) != LabG_IsPixmapAndText(curcbox)) ||
(LabG__label(newcbox) != LabG__label(curcbox)) ||
(PixmapOff(newcbox) != PixmapOff(curcbox)) ||
(LabG_Font(newcbox) != LabG_Font(curcbox)) ||
(TBG_IndOn(newcbox) != TBG_IndOn(curcbox)))
{
if (LabG_IsPixmap(newcbox) || LabG_IsPixmapAndText(newcbox))
{
if (!IsNull(PixmapOff(newcbox)) || !IsNull(PixmapInsenOff(newcbox)) ||
!IsNull(PixmapOn(newcbox)) || !IsNull(PixmapInsenOn(newcbox)) ||
!IsNull(PixmapInd(newcbox)) || !IsNull(PixmapInsenInd(newcbox)))
if (LabG_TextRect(newcbox).height < 13)
TBG_IndicatorDim(newcbox) = LabG_TextRect(newcbox).height;
else
TBG_IndicatorDim(newcbox) = 13 +
(LabG_TextRect(newcbox).height/13);
else
TBG_IndicatorDim(newcbox) = XmDEFAULT_INDICATOR_DIM;
}
else
{
Dimension height;
int line_count;
height = XmStringHeight(LabG_Font(newcbox),
LabG__label(newcbox));
line_count = XmStringLineCount (LabG__label(newcbox));
if (line_count < 1)
line_count = 1;
/*
* CR 5203 - Make the calculation for the
* indicator_dim be the same as in the Initialize
* procedure, i.e. Popup and Pulldown menus should
* have smaller indicators
*/
if (LabG_IsMenupane(new_w))
TBG_IndicatorDim(newcbox) =
MAX(XmDEFAULT_INDICATOR_DIM,
(height / ((Dimension)line_count))*2/3);
else
TBG_IndicatorDim(newcbox) =
MAX(XmDEFAULT_INDICATOR_DIM,
height / ((Dimension)line_count));
}
/* End 5203 Fix */
}
}
if (TBG_IndOn(newcbox))
{
/*
* Fix CR 5568 - If the indicator is on and the user has changed the
* indicator dimension, calculate the new top and bottom
* margins in a place where they can effect the core width
* and height.
*/
/* Recompute the Top and bottom margins and the height of the text
* rectangle to accommodate the size of toggle indicator.
* if (we are given a new toggleIndicator size)
* { if (user has given new top or bottom margin)
* { compute to accomodate new toggle button size; }
* else (user has set new top/bottom margin)
* { Recompute margin to accommodate new IndicatorSize }
* }
*/
if (TBG_IndicatorDim(newcbox) != TBG_IndicatorDim(curcbox))
{
int maxIndicatorSize =
(int) (TBG_IndicatorDim(newcbox)) + 2*Xm3D_ENHANCE_PIXEL;
int boxSize = ((int) LabG_TextRect(newcbox).height +
(int) LabG_MarginTop(newcbox) +
(int) LabG_MarginBottom(newcbox));
top_delta = bottom_delta = (maxIndicatorSize - boxSize) / 2;
}
if (LayoutIsRtoLG(newcbox))
right_delta = (TBG_IndicatorDim(newcbox) +
TBG_Spacing(newcbox) -
LabG_MarginRight(newcbox));
else
left_delta = (TBG_IndicatorDim(newcbox) +
TBG_Spacing(newcbox) -
LabG_MarginLeft(newcbox));
}
else if (TBG_IndOn(curcbox))
{
/* CR 2337: Redisplay when the indicator is turned off. */
flag = TRUE;
top_delta = -TBG_IndTopDelta(newcbox);
bottom_delta = -TBG_IndBottomDelta(newcbox);
if (LayoutIsRtoLG(newcbox))
right_delta = -TBG_IndRightDelta(newcbox);
else
left_delta = -TBG_IndLeftDelta(newcbox);
}
/* CR 2337: Let the toggle button shrink if necessary. */
if (right_delta || left_delta || top_delta || bottom_delta)
{
flag = TRUE;
/* Adjust vertical margins based on the indicator. */
if ((int)TBG_IndTopDelta(newcbox) + top_delta > 0)
{
LabG_MarginTop(newcbox) += top_delta;
TBG_IndTopDelta(newcbox) += top_delta;
}
else
{
LabG_MarginTop(newcbox) -= TBG_IndTopDelta(newcbox);
TBG_IndTopDelta(newcbox) = 0;
}
if ((int)TBG_IndBottomDelta(newcbox) + bottom_delta > 0)
{
LabG_MarginBottom(newcbox) += bottom_delta;
TBG_IndBottomDelta(newcbox) += bottom_delta;
}
else
{
LabG_MarginBottom(newcbox) -= TBG_IndBottomDelta(newcbox);
TBG_IndBottomDelta(newcbox) = 0;
}
/* Adjust horizontal margins based on the indicator. */
if (LayoutIsRtoLG(newcbox))
{
if ((int)TBG_IndRightDelta(newcbox) + right_delta > 0)
{
LabG_MarginRight(newcbox) += right_delta;
TBG_IndRightDelta(newcbox) += right_delta;
}
else
{
LabG_MarginRight(newcbox) -= TBG_IndRightDelta(newcbox);
TBG_IndRightDelta(newcbox) = 0;
}
}
else
{
if ((int)TBG_IndLeftDelta(newcbox) + left_delta > 0)
{
LabG_MarginLeft(newcbox) += left_delta;
TBG_IndLeftDelta(newcbox) += left_delta;
}
else
{
LabG_MarginLeft(newcbox) -= TBG_IndLeftDelta(newcbox);
TBG_IndLeftDelta(newcbox) = 0;
}
}
/* Realign the label. */
if (! LabG_RecomputeSize(newcbox))
(* resize) ((Widget) new_w);
}
if (LabG_RecomputeSize(newcbox))
{
if (reqcbox->rectangle.width == curcbox->rectangle.width)
newcbox->rectangle.width = 0;
if (reqcbox->rectangle.height == curcbox->rectangle.height)
newcbox->rectangle.height = 0;
}
if (newcbox->rectangle.width == 0)
{
newcbox->rectangle.width =
LabG_TextRect(newcbox).width +
LabG_MarginLeft(newcbox) + LabG_MarginRight(newcbox) +
2 * (newcbox->gadget.highlight_thickness +
newcbox->gadget.shadow_thickness +
LabG_MarginHeight(newcbox));
if (newcbox->rectangle.width == 0)
newcbox->rectangle.width = 1;
flag = TRUE;
}
if (newcbox->rectangle.height == 0)
{
newcbox->rectangle.height =
MAX(TBG_IndicatorDim(newcbox),
LabG_TextRect(newcbox).height + 2*LabG_MarginHeight(newcbox) +
LabG_MarginTop(newcbox) + LabG_MarginBottom(newcbox)) +
2 * (newcbox->gadget.highlight_thickness +
newcbox->gadget.shadow_thickness);
if (newcbox->rectangle.height == 0)
newcbox->rectangle.height = 1;
flag = TRUE;
}
}
if ((TBG_IndType(curcbox) != TBG_IndType(newcbox)) &&
(!XmRepTypeValidValue(XmRID_INDICATOR_TYPE,
TBG_IndType( newcbox), (Widget) newcbox)))
{
TBG_IndType(newcbox) = TBG_IndType(curcbox);
}
if ((LabG_Foreground(newcbox) != LabG_Foreground(curcbox)) ||
(LabG_Background(newcbox) != LabG_Background(curcbox)) ||
(TBG_SelectColor(newcbox) != TBG_SelectColor(curcbox)))
{
XtReleaseGC (XtParent(newcbox), TBG_SelectGC(newcbox));
XtReleaseGC (XtParent(newcbox), TBG_BackgroundGC(newcbox));
XtReleaseGC (XtParent(newcbox), TBG_IndeterminateGC(newcbox));
XtReleaseGC (XtParent(newcbox), TBG_IndeterminateBoxGC(newcbox));
TBG_ReversedSelect(newcbox) =
(TBG_SelectColor(newcbox) == XmREVERSED_GROUND_COLORS);
if ((TBG_SelectColor(newcbox) == INVALID_PIXEL) ||
(TBG_SelectColor(newcbox) == XmDEFAULT_SELECT_COLOR))
{
XrmValue value;
value.size = sizeof(Pixel);
DefaultSelectColor((Widget) newcbox,
XtOffsetOf(XmToggleButtonGCacheObjRec,
toggle_cache.select_color),
&value);
memcpy((char*) &TBG_SelectColor(newcbox), value.addr, value.size);
}
else if (TBG_SelectColor(newcbox) == XmREVERSED_GROUND_COLORS)
{
TBG_SelectColor(newcbox) = LabG_Foreground(newcbox);
}
else if (TBG_SelectColor(newcbox) == XmHIGHLIGHT_COLOR)
{
TBG_SelectColor(newcbox) = LabG_HighlightColor(newcbox);
}
GetGC(newcbox);
flag = TRUE;
}
if (TBG_UnselectColor(newcbox) != TBG_UnselectColor(curcbox))
{
XtReleaseGC (XtParent(curcbox), TBG_UnselectGC(curcbox));
GetUnselectGC(newcbox);
flag = TRUE;
}
if (TBG_Set(curcbox) != TBG_Set(newcbox))
{
if (TBG_ToggleMode(newcbox) == XmTOGGLE_BOOLEAN &&
TBG_Set(newcbox) == XmINDETERMINATE)
TBG_Set(newcbox) = TBG_Set(curcbox);
else
{
IsOn(newcbox) = TBG_Set(newcbox);
if (flag == False && XtIsRealized((Widget)newcbox))
{
if (TBG_IndOn(newcbox))
DrawToggle (newcbox);
else
{
if (newcbox->gadget.shadow_thickness > 0)
DrawToggleShadow (newcbox);
if (TBG_FillOnSelect(newcbox)&& !LabG_IsPixmap(newcbox))
DrawToggleLabel (newcbox);
if ((LabG_IsPixmap(newcbox)) || LabG_IsPixmapAndText(newcbox))
{
SetAndDisplayPixmap(newcbox, NULL, NULL);
flag = True;
}
}
}
}
}
if ((TBG_IndType(curcbox) != TBG_IndType(newcbox)) ||
( (TBG_Visible(curcbox) != TBG_Visible(newcbox)) && (XmUNSET == TBG_Set(newcbox))))
{
flag = True;
}
/* One-of-many forces boolean mode. */
if (IsOneOfMany(TBG_IndType(newcbox)) &&
(TBG_ToggleMode(newcbox) == XmTOGGLE_INDETERMINATE))
{
TBG_ToggleMode(newcbox) = XmTOGGLE_BOOLEAN;
}
if (TBG_ToggleMode(curcbox) != TBG_ToggleMode(newcbox))
{
if ((TBG_ToggleMode(newcbox) == XmTOGGLE_BOOLEAN) &&
(TBG_Set(newcbox) == XmINDETERMINATE))
{
TBG_VisualSet(newcbox) = TBG_Set(newcbox) = False;
flag = True;
}
}
/* Fix br 1211: we need to compare and set label cache of new_w
if differs from current.*/
if(!_XmLabelCacheCompare(LabG_Cache(new_w), LabG_Cache(current)))
{
_XmCacheCopy((XtPointer)LabG_Cache(new_w),
(XtPointer)LabG_Cache(current), sizeof(XmLabelGCacheObjPart));
}
/* End of fix br 1251 */
/* BEGIN OSF Fix pir 2097 */
newcbox->gadget.event_mask = XmARM_EVENT | XmACTIVATE_EVENT |
XmMULTI_ARM_EVENT | XmMULTI_ACTIVATE_EVENT | XmHELP_EVENT |
XmFOCUS_IN_EVENT | XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT |
XmBDRAG_EVENT;
/* END OSF Fix pir 2097 */
return(flag);
}
/***************************************************************
*
* XmToggleButtonGadgetGetState
* This function gets the state of the toggle gadget.
*
***************************************************************/
Boolean
XmToggleButtonGadgetGetState(
Widget w )
{
XmToggleButtonGadget tg = (XmToggleButtonGadget) w;
Boolean ret_val;
XtAppContext app = XtWidgetToApplicationContext(w);
_XmAppLock(app);
ret_val = TBG_Set(tg);
_XmAppUnlock(app);
return (ret_val);
}
/****************************************************************
*
* XmToggleButtonGadgetSetState
* This function sets the state of the toggle gadget.
*
****************************************************************/
void
XmToggleButtonGadgetSetState(
Widget w,
#if NeedWidePrototypes
int bnewstate,
int notify )
#else
Boolean bnewstate,
Boolean notify )
#endif /* NeedWidePrototypes */
{
XmToggleButtonGadget tg = (XmToggleButtonGadget) w;
XmMenuSystemTrait menuSTrait;
XmToggleButtonState newstate;
XtAppContext app = XtWidgetToApplicationContext(w);
_XmAppLock(app);
newstate = (bnewstate == XmSET)? XmSET : XmUNSET;
if (TBG_Set(tg) != newstate)
{
TBG_Set(tg) = newstate;
IsOn(tg) = newstate;
if (XtIsRealized ((Widget)tg))
{
if (TBG_IndOn(tg))
DrawToggle(tg);
else
{
if (tg->gadget.shadow_thickness> 0)
DrawToggleShadow (tg);
if (TBG_FillOnSelect(tg) && !LabG_IsPixmap(tg))
DrawToggleLabel (tg);
}
if (LabG_IsPixmap(tg) || LabG_IsPixmapAndText(tg))
SetAndDisplayPixmap(tg, NULL, NULL);
}
if (notify)
{
/* UNDOING this fix ... */
/* CR 8904: Notify value_changed before entry so that state is */
/* reported correctly even if the entry callback resets it. */
menuSTrait = (XmMenuSystemTrait)
XmeTraitGet((XtPointer) XtClass(XtParent(tg)), XmQTmenuSystem);
if (menuSTrait != NULL)
{
XmToggleButtonCallbackStruct call_value;
call_value.reason = XmCR_VALUE_CHANGED;
call_value.event = NULL;
call_value.set = TBG_Set(tg);
menuSTrait->entryCallback(XtParent(tg), (Widget)tg, &call_value);
}
if ((! LabG_SkipCallback(tg)) &&
(TBG_ValueChangedCB(tg)))
{
if (XtIsRealized ((Widget)tg))
XFlush (XtDisplay (tg));
ToggleButtonCallback(tg, XmCR_VALUE_CHANGED, TBG_Set(tg), NULL);
}
}
}
_XmAppUnlock(app);
}
/****************************************************************
*
* XmToggleButtonGadgetSetValue
* This function sets the state of the toggle gadget.
*
****************************************************************/
Boolean
XmToggleButtonGadgetSetValue(
Widget w,
#if NeedWidePrototypes
int newstate,
int notify )
#else
XmToggleButtonState newstate,
Boolean notify )
#endif /* NeedWidePrototypes */
{
XmToggleButtonGadget tg = (XmToggleButtonGadget) w;
XmMenuSystemTrait menuSTrait;
XtAppContext app = XtWidgetToApplicationContext(w);
_XmAppLock(app);
/* Can't set third state if we aren't in three state mode */
if ((newstate == XmINDETERMINATE) &&
(TBG_ToggleMode(tg) != XmTOGGLE_INDETERMINATE)) {
_XmAppUnlock(app);
return False;
}
if (TBG_Set(tg) != newstate)
{
TBG_Set(tg) = newstate;
IsOn(tg) = newstate;
if (XtIsRealized ((Widget)tg))
{
if (TBG_IndOn(tg))
DrawToggle(tg);
else
{
if (tg->gadget.shadow_thickness> 0)
DrawToggleShadow (tg);
if (TBG_FillOnSelect(tg) && !LabG_IsPixmap(tg))
DrawToggleLabel (tg);
}
if (LabG_IsPixmap(tg) || LabG_IsPixmapAndText(tg))
SetAndDisplayPixmap(tg, NULL, NULL);
}
if (notify)
{
/* UNDOING this fix ... */
/* CR 8904: Notify value_changed before entry so that state is */
/* reported correctly even if the entry callback resets it. */
menuSTrait = (XmMenuSystemTrait)
XmeTraitGet((XtPointer) XtClass(XtParent(tg)), XmQTmenuSystem);
if (menuSTrait != NULL)
{
XmToggleButtonCallbackStruct call_value;
call_value.reason = XmCR_VALUE_CHANGED;
call_value.event = NULL;
call_value.set = TBG_Set(tg);
menuSTrait->entryCallback(XtParent(tg), (Widget)tg, &call_value);
}
if ((! LabG_SkipCallback(tg)) &&
(TBG_ValueChangedCB(tg)))
{
if (XtIsRealized ((Widget)tg))
XFlush (XtDisplay (tg));
ToggleButtonCallback(tg, XmCR_VALUE_CHANGED, TBG_Set(tg), NULL);
}
}
}
_XmAppUnlock(app);
return True;
}
/***********************************************************************
*
* XmCreateToggleButtonGadget
* Creates an instance of a togglebutton and returns the widget id.
*
***********************************************************************/
Widget
XmCreateToggleButtonGadget(
Widget parent,
char *name,
Arg *arglist,
Cardinal argCount )
{
return XtCreateWidget(name,xmToggleButtonGadgetClass,parent,arglist,argCount);
}
Widget
XmVaCreateToggleButtonGadget(
Widget parent,
char *name,
...)
{
register Widget w;
va_list var;
int count;
Va_start(var,name);
count = XmeCountVaListSimple(var);
va_end(var);
Va_start(var, name);
w = XmeVLCreateWidget(name,
xmToggleButtonGadgetClass,
parent, False,
var, count);
va_end(var);
return w;
}
Widget
XmVaCreateManagedToggleButtonGadget(
Widget parent,
char *name,
...)
{
Widget w = NULL;
va_list var;
int count;
Va_start(var, name);
count = XmeCountVaListSimple(var);
va_end(var);
Va_start(var, name);
w = XmeVLCreateWidget(name,
xmToggleButtonGadgetClass,
parent, True,
var, count);
va_end(var);
return w;
}
/*********************************************************
* Functions for manipulating Secondary Resources.
*********************************************************/
/*
* GetPushBGSecResData()
* Create a XmSecondaryResourceDataRec for each secondary resource;
* Put the pointers to these records in an array of pointers;
* Return the pointer to the array of pointers.
*/
/*ARGSUSED*/
static Cardinal
GetToggleBGClassSecResData(
WidgetClass w_class, /* unused */
XmSecondaryResourceData **data_rtn )
{
int arrayCount = 0;
XmBaseClassExt bcePtr;
String resource_class, resource_name;
XtPointer client_data;
_XmProcessLock();
bcePtr = &( ToggleBGClassExtensionRec );
client_data = NULL;
resource_class = NULL;
resource_name = NULL;
arrayCount =
_XmSecondaryResourceData ( bcePtr, data_rtn, client_data,
resource_name, resource_class,
GetToggleBGClassSecResBase) ;
_XmProcessUnlock();
return (arrayCount);
}
/*
* GetToggleBGClassResBase ()
* return the address of the base of resources.
*/
/*ARGSUSED*/
static XtPointer
GetToggleBGClassSecResBase(
Widget widget,
XtPointer client_data ) /* unused */
{
XtPointer widgetSecdataPtr;
int labg_cache_size = sizeof (XmLabelGCacheObjPart);
int togglebg_cache_size = sizeof (XmToggleButtonGCacheObjPart);
char *cp;
widgetSecdataPtr = (XtPointer)
(XtMalloc ( labg_cache_size + togglebg_cache_size + 1));
_XmProcessLock();
if (widgetSecdataPtr)
{
cp = (char *) widgetSecdataPtr;
memcpy (cp, LabG_Cache(widget), labg_cache_size);
cp += labg_cache_size;
memcpy (cp, TBG_Cache(widget), togglebg_cache_size);
}
/* else Warning: error cannot allocate Memory */
_XmProcessUnlock();
return ( widgetSecdataPtr);
}
/*
* DrawToggleLabel (tb)
* Called when XmNindicatorOn is TRUE and XmNfillOnSelect is FALSE.
* Fill toggle with selectColor or background depending on toggle
* value, and draw label.
*/
static void
DrawToggleLabel(
XmToggleButtonGadget tb )
{
Dimension margin =
tb->gadget.highlight_thickness + tb->gadget.shadow_thickness;
Position fx = tb->rectangle.x + margin;
Position fy = tb->rectangle.y + margin;
int fw = tb->rectangle.width - 2 * margin;
int fh = tb->rectangle.height - 2 * margin;
Boolean restore_gc = False;
GC tmp_gc = NULL, fill_gc;
if ((LabG_TopShadowColor(tb) == TBG_SelectColor(tb)) ||
(LabG_BottomShadowColor(tb) == TBG_SelectColor(tb)))
{
fx += 1;
fy += 1;
fw -= 2;
fh -= 2;
}
if (fw < 0 || fh < 0)
return;
switch (tb->toggle.visual_set)
{
case XmUNSET:
fill_gc = TBG_UnselectGC(tb);
break;
case XmSET:
fill_gc = TBG_SelectGC(tb);
break;
case XmINDETERMINATE:
{
XGCValues values;
/* Fetch the select_color GetGC() actually used. */
XGetGCValues(XtDisplay(tb), TBG_SelectGC(tb), GCForeground, &values);
values.background = TBG_UnselectColor(tb);
XChangeGC(XtDisplay((Widget)tb), TBG_IndeterminateGC(tb),
GCForeground|GCBackground, &values);
fill_gc = TBG_IndeterminateGC(tb);
break;
}
default:
assert(False);
return;
}
XFillRectangle (XtDisplay(tb), XtWindow(tb), fill_gc, fx, fy, fw, fh);
if (LabG_Foreground(tb) == TBG_SelectColor(tb) && (IsOn(tb) == XmSET))
{
tmp_gc = LabG_NormalGC(tb);
LabG_NormalGC(tb) = TBG_BackgroundGC(tb);
restore_gc = True;
}
{
XtExposeProc expose;
_XmProcessLock();
expose = xmLabelGadgetClassRec.rect_class.expose;
_XmProcessUnlock();
(* expose) ((Widget)tb, NULL, NULL);
}
if (restore_gc)
{
/* CR 9791: Label's normal_gc has a dynamic clip_mask. */
XSetClipMask(XtDisplay(tb), TBG_BackgroundGC(tb), None);
LabG_NormalGC(tb) = tmp_gc;
}
}
/*
* DrawEtchedInMenu (tb)
* Called when in a Menu and EtchedInMenu is TRUE.
* And when XmNindicatorOn is FALSE and XmNfillOnSelect is FALSE;
* or when XmNindicatorOn is TRUE.
* Fill background with the arm_gc and draw label.
*/
static void
DrawEtchedInMenu(
XmToggleButtonGadget tb )
{
Dimension margin =
tb->gadget.highlight_thickness + tb->gadget.shadow_thickness;
Position fx = tb->rectangle.x + margin;
Position fy = tb->rectangle.y + margin;
int fw = tb->rectangle.width - 2 * margin;
int fh = tb->rectangle.height - 2 * margin;
Boolean restore_gc = False;
GC tmp_gc = NULL;
#ifdef FIX_1395
Boolean restore_bgc = False;
GC tmp_bgc = NULL;
#endif
XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay((Widget) tb));
Boolean etched_in = dpy->display.enable_etched_in_menu;
if ((LabG_TopShadowColor(tb) == TBG_SelectColor(tb)) ||
(LabG_BottomShadowColor(tb) == TBG_SelectColor(tb)))
{
fx += 1;
fy += 1;
fw -= 2;
fh -= 2;
}
if (fw < 0 || fh < 0)
return;
XFillRectangle (XtDisplay(tb), XtWindow(tb),
TBG_Armed(tb) ? TBG_ArmGC(tb) : TBG_BackgroundGC(tb),
fx, fy, fw, fh);
if (TBG_Armed(tb))
{
Pixel select_pix;
Widget wid = XtParent(tb);
XmGetColors(XtScreen(wid), wid->core.colormap,
wid->core.background_pixel,
NULL, NULL, NULL, &select_pix);
if (LabG_Foreground(tb) == select_pix)
{
tmp_gc = LabG_NormalGC(tb);
LabG_NormalGC(tb) = TBG_BackgroundGC(tb);
restore_gc = True;
}
#ifdef FIX_1395
{
XGCValues values;
/* Fetch the select_color GetGC() actually used. */
XGetGCValues(XtDisplay(tb), TBG_SelectGC(tb), GCBackground, &values);
/* Before label expose call we should change bgc
to correct color and then restore it.
*/
if (values.background != select_pix)
{
XChangeGC(XtDisplay((Widget)tb), TBG_SelectGC(tb),
GCBackground, &values);
tmp_bgc = LabG_BackgroundGC(tb);
LabG_BackgroundGC(tb) = TBG_SelectGC(tb);
restore_bgc = True;
}
}
#endif
}
{
XtExposeProc expose;
_XmProcessLock();
expose = xmLabelGadgetClassRec.rect_class.expose;
_XmProcessUnlock();
(* expose) ((Widget)tb, NULL, NULL);
}
if (restore_gc)
{
/* CR 9791: Label's normal_gc has a dynamic clip_mask. */
XSetClipMask(XtDisplay(tb), TBG_BackgroundGC(tb), None);
LabG_NormalGC(tb) = tmp_gc;
}
#ifdef FIX_1395
if (restore_bgc)
{
LabG_BackgroundGC(tb) = tmp_bgc;
}
#endif
}
/*
* DrawToggleShadow (tb)
* - Should be called only if ToggleShadow are to be drawn ;
* if the IndicatorOn resource is set to false top and bottom shadows
* will be switched depending on whether the Toggle is selected or
* unselected.
*/
static void
DrawToggleShadow(
XmToggleButtonGadget tb )
{
GC top_gc, bot_gc;
int dx, dy, width, height;
int hilite_thickness;
if (TBG_IndOn(tb) || (IsOn(tb) == XmUNSET))
{
top_gc = LabG_TopShadowGC(tb);
bot_gc = LabG_BottomShadowGC(tb);
}
else if (IsOn(tb) == XmINDETERMINATE)
{
top_gc = bot_gc = TBG_IndeterminateBoxGC(tb);
}
else
{
top_gc = LabG_BottomShadowGC(tb);
bot_gc = LabG_TopShadowGC(tb);
}
hilite_thickness = tb->gadget.highlight_thickness;
dx = (int)(tb->rectangle.x + hilite_thickness);
dy = (int)(tb->rectangle.y + hilite_thickness);
width = (int) ( tb->rectangle.width - (hilite_thickness << 1));
height = (int) ( tb->rectangle.height - (hilite_thickness << 1));
XmeDrawShadows (XtDisplay (tb), XtWindow (tb),
top_gc, bot_gc, dx, dy, width, height,
tb->gadget.shadow_thickness, XmSHADOW_OUT);
}
/* BEGIN OSF Fix pir 1778 */
/************************************************************************
*
* SetToggleSize(newtbg)
* Set size properly when XmNselectPixmap or XmNselectInsensitivePixmaps
* are set in addition to the corresponding labelPixmaps. Have to pick
* the largest dimensions.
*
************************************************************************/
static void
SetToggleSize(
XmToggleButtonGadget newtbg)
{
unsigned int maxW, maxH, tmpW, tmpH;
maxW = maxH = tmpW = tmpH = 0;
/* We know it's a pixmap so find out how how big it is */
if (XtIsSensitive ((Widget) newtbg))
{
if (!IsNull(PixmapOn(newtbg)))
{
XmeGetPixmapData(XtScreen(newtbg), PixmapOn(newtbg),
NULL, NULL, NULL, NULL, NULL, NULL,
&tmpW, &tmpH);
ASSIGN_MAX(maxW, tmpW);
ASSIGN_MAX(maxH, tmpH);
}
if (!IsNull(PixmapOff(newtbg)))
{
XmeGetPixmapData(XtScreen(newtbg), PixmapOff(newtbg),
NULL, NULL, NULL, NULL, NULL, NULL,
&tmpW, &tmpH);
ASSIGN_MAX(maxW, tmpW);
ASSIGN_MAX(maxH, tmpH);
}
if (!IsNull(PixmapInd(newtbg)))
{
XmeGetPixmapData(XtScreen(newtbg), PixmapInd(newtbg),
NULL, NULL, NULL, NULL, NULL, NULL,
&tmpW, &tmpH);
ASSIGN_MAX(maxW, tmpW);
ASSIGN_MAX(maxH, tmpH);
}
}
else
{
if (!IsNull(PixmapInsenOn(newtbg)))
{
XmeGetPixmapData(XtScreen(newtbg), PixmapInsenOn(newtbg),
NULL, NULL, NULL, NULL, NULL, NULL,
&tmpW, &tmpH);
ASSIGN_MAX(maxW, tmpW);
ASSIGN_MAX(maxH, tmpH);
}
if (!IsNull(PixmapInsenOff(newtbg)))
{
XmeGetPixmapData(XtScreen(newtbg), PixmapInsenOff(newtbg),
NULL, NULL, NULL, NULL, NULL, NULL,
&tmpW, &tmpH);
ASSIGN_MAX(maxW, tmpW);
ASSIGN_MAX(maxH, tmpH);
}
if (!IsNull(PixmapInsenInd(newtbg)))
{
XmeGetPixmapData(XtScreen(newtbg), PixmapInsenInd(newtbg),
NULL, NULL, NULL, NULL, NULL, NULL,
&tmpW, &tmpH);
ASSIGN_MAX(maxW, tmpW);
ASSIGN_MAX(maxH, tmpH);
}
}
LabG_TextRect(newtbg).width = (unsigned short) maxW;
LabG_TextRect(newtbg).height = (unsigned short) maxH;
/* Invoke Label's SetSize procedure. */
{
XtWidgetProc resize;
_XmProcessLock();
resize = xmLabelGadgetClassRec.rect_class.resize;
_XmProcessUnlock();
(* resize) ((Widget) newtbg);
}
}
/* END OSF Fix pir 1778 */
/*
* DefaultSelectColor - an XtResourceDefaultProc for generating the
* default select color. This may require examining the
* XmNindicatorType and XmNhighlightColor resources, which will
* happen to have real values only because they appear before
* XmNselectColor in the resource list.
*/
static void
DefaultSelectColor(Widget widget,
int offset,
XrmValue *value)
{
XmToggleButtonGadget tb = (XmToggleButtonGadget) widget;
Boolean force_highlight = FALSE;
XmDisplay xm_dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(widget));
Boolean enable_toggle_color = xm_dpy->display.enable_toggle_color;
if (enable_toggle_color)
{
/* This code may misbehave for erroneous ind_type values. */
if (IsOneOfMany(TBG_IndType(tb)))
{
force_highlight = TRUE;
}
else if ((TBG_IndType(tb) == XmINVALID_TYPE) &&
XmIsRowColumn(XtParent(widget)))
{
XtVaGetValues(XtParent(widget),
XmNradioBehavior, &force_highlight,
NULL);
}
}
if (force_highlight)
{
value->size = sizeof(LabG_HighlightColor(tb));
value->addr = (char *) &LabG_HighlightColor(tb);
}
else
_XmSelectColorDefault(widget, offset, value);
}
/*
* NormalizeIndOn - return the normalized value of XmNindicatorOn,
* replacing XmINDICATOR_FILL and XmINDICATOR_BOX with the proper
* absolute values.
*/
static unsigned char
NormalizeIndOn(XmToggleButtonGadget tb)
{
unsigned char value = TBG_IndOn(tb);
/* Convert XmINDICATOR_FILL to XmINDICATOR_CHECK_BOX? */
if (value == XmINDICATOR_FILL)
{
/* This routine may be called frequently, so reach directly into */
/* the XmDisplay rather than calling XtGetValues. */
XmDisplay xm_dpy = (XmDisplay) XmGetXmDisplay(XtDisplay((Widget) tb));
if (xm_dpy->display.enable_toggle_visual)
value = XmINDICATOR_CHECK_BOX;
}
/* Convert XmINDICATOR_BOX to XmINDICATOR_3D_BOX (XmINDICATOR_FILL). */
else if (value == XmINDICATOR_BOX)
{
value = XmINDICATOR_3D_BOX;
}
return value;
}
/*
* NormalizeIndType - return the normalized value of XmNindicatorType,
* replacing XmONE_OF_MANY with the proper absolute value.
*/
static unsigned char
NormalizeIndType(XmToggleButtonGadget tb)
{
unsigned char value = TBG_IndType(tb);
if (value == XmONE_OF_MANY)
{
/* This routine may be called frequently, so reach directly into */
/* the XmDisplay rather than calling XtGetValues. */
XmDisplay xm_dpy = (XmDisplay) XmGetXmDisplay(XtDisplay((Widget) tb));
if (xm_dpy->display.enable_toggle_visual)
value = XmONE_OF_MANY_ROUND;
else
value = XmONE_OF_MANY_DIAMOND;
}
return value;
}