Blame lib/Xm/SpinB.c

Packit b099d7
/* $TOG: SpinB.c /main/27 1999/04/16 08:48:58 mgreess $ */
Packit b099d7
/*
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * (c) Copyright 1995 Digital Equipment Corporation.
Packit b099d7
 * (c) Copyright 1995 Hewlett-Packard Company.
Packit b099d7
 * (c) Copyright 1995 International Business Machines Corp.
Packit b099d7
 * (c) Copyright 1995 Sun Microsystems, Inc.
Packit b099d7
 * (c) Copyright 1995 Novell, Inc. 
Packit b099d7
 * (c) Copyright 1995 FUJITSU LIMITED.
Packit b099d7
 * (c) Copyright 1995 Hitachi.
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * HISTORY
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC. 
Packit b099d7
 * ALL RIGHTS RESERVED 
Packit b099d7
 */
Packit b099d7
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#include <stdio.h>
Packit b099d7
#include <stdlib.h>
Packit b099d7
#include <string.h>
Packit b099d7
#include <ctype.h>
Packit b099d7
#include <X11/StringDefs.h>
Packit b099d7
#include <X11/Intrinsic.h>
Packit b099d7
#include <X11/IntrinsicP.h>
Packit b099d7
#include <X11/cursorfont.h>
Packit b099d7
#include <X11/Shell.h>
Packit b099d7
#include <X11/Xutil.h>
Packit b099d7
#include <X11/keysym.h>
Packit b099d7
Packit b099d7
#include <Xm/AccTextT.h>
Packit b099d7
#include <Xm/DrawP.h>
Packit b099d7
#include <Xm/NavigatorT.h>
Packit b099d7
#include <Xm/PrimitiveP.h>
Packit b099d7
#include <Xm/Text.h>
Packit b099d7
#include <Xm/TextF.h>
Packit b099d7
#include <Xm/TraitP.h>
Packit b099d7
#include <Xm/TransltnsP.h>
Packit b099d7
#include <Xm/VaSimpleP.h>
Packit b099d7
#include "GeoUtilsI.h"
Packit b099d7
#include "GMUtilsI.h"
Packit b099d7
#include "MessagesI.h"
Packit b099d7
#include "RepTypeI.h"
Packit b099d7
#include "ScreenI.h"
Packit b099d7
#include "TravActI.h"
Packit b099d7
#include "TraversalI.h"
Packit b099d7
#include "XmI.h"
Packit b099d7
Packit b099d7
#include <Xm/SpinBP.h>
Packit b099d7
Packit b099d7
#define FIX_1519
Packit b099d7
Packit b099d7
static void ClassInitialize(void);
Packit b099d7
static void ClassPartInitialize(WidgetClass classPart);
Packit b099d7
static void Initialize(Widget req, Widget w,
Packit b099d7
		       ArgList args, Cardinal *num_args);
Packit b099d7
static void Destroy(Widget w);
Packit b099d7
static void Resize(Widget w);
Packit b099d7
static void Redisplay(Widget w, XEvent *event, Region region);
Packit b099d7
static Boolean SetValues(Widget old, Widget req, Widget new_w,
Packit b099d7
			 ArgList args, Cardinal *num_args);
Packit b099d7
static XtGeometryResult QueryGeometry(Widget w,
Packit b099d7
				      XtWidgetGeometry*req,
Packit b099d7
				      XtWidgetGeometry*rep );
Packit b099d7
static XtGeometryResult GeometryManager(Widget w,
Packit b099d7
					XtWidgetGeometry *req,
Packit b099d7
					XtWidgetGeometry *rep);
Packit b099d7
static void ChangeManaged(Widget w);
Packit b099d7
static void InsertChild(Widget newChild);
Packit b099d7
static void ConstraintInitialize(Widget req, Widget new_w,
Packit b099d7
				 ArgList args, Cardinal *num_args);
Packit b099d7
static void ConstraintDestroy(Widget w);
Packit b099d7
static Boolean ConstraintSetValues(Widget old, Widget req, Widget new_w,
Packit b099d7
				   ArgList args, Cardinal *num_args);
Packit b099d7
static void SpinChildFocusChange(Widget    focusWidget, XtPointer focusClient,
Packit b099d7
				 XEvent    *focusEvent,
Packit b099d7
				 Boolean   *focusContinue);
Packit b099d7
static void SpinBArm(Widget   armWidget, XEvent   *armEvent,
Packit b099d7
		     String   *armParams, Cardinal *armCount );
Packit b099d7
static void SpinBDisarm(Widget   disarmWidget, XEvent   *disarmEvent,
Packit b099d7
			String   *disarmParams, Cardinal *disarmCount);
Packit b099d7
static void SpinBFirst(Widget   firstWidget, XEvent   *firstEvent,
Packit b099d7
		       String   *firstParams, Cardinal *firstCount );
Packit b099d7
static void SpinBLast(Widget   lastWidget, XEvent   *lastEvent,
Packit b099d7
		      String   *lastParams, Cardinal *lastCount );
Packit b099d7
static void SpinBLeft(Widget   leftWidget, XEvent   *leftEvent,
Packit b099d7
		      String   *leftParams, Cardinal *leftCount );
Packit b099d7
static void SpinBNext(Widget   nextWidget, XEvent   *nextEvent,
Packit b099d7
		      String   *nextParams, Cardinal *nextCount );
Packit b099d7
static void SpinBPrior(Widget   priorWidget, XEvent   *priorEvent,
Packit b099d7
		       String   *priorParams, Cardinal *priorCount );
Packit b099d7
static void SpinBRight(Widget   rightWidget, XEvent   *rightEvent, 
Packit b099d7
		       String   *rightParams, Cardinal *rightCount );
Packit b099d7
static void SpinBEnter(Widget, XEvent*, String*, Cardinal*);
Packit b099d7
static void SpinBLeave(Widget, XEvent*, String*, Cardinal*);
Packit b099d7
static void ClearArrows(Widget clearW);
Packit b099d7
static Boolean UpArrowSensitive(XmSpinBoxWidget spinW);
Packit b099d7
static Boolean DownArrowSensitive(XmSpinBoxWidget spinW);
Packit b099d7
static int NumericChildCount(XmSpinBoxWidget spinW);
Packit b099d7
static Boolean WidgetIsChild(XmSpinBoxWidget spinW, Widget child);
Packit b099d7
static Boolean ChildIsTraversable(Widget w);
Packit b099d7
static int GetArrowDirection(Widget w, int spinDir);
Packit b099d7
static void LayoutSpinBox(Widget w, XtWidgetGeometry *spinG, Widget child);
Packit b099d7
static void NumToString(char **buffer, int min, int max,
Packit b099d7
			int decimal, int value );
Packit b099d7
static void DrawSpinArrow(Widget arrowWidget, int arrowFlag);
Packit b099d7
static void SpinTimeOut(Widget w, int spinDelay);
Packit b099d7
static void UpdateChildText(Widget textW);
Packit b099d7
static Boolean ArrowWasHit(Widget arrowW, int arrowType, XEvent *arrowEvent);
Packit b099d7
static void SpinBArrow(XtPointer spinData, XtIntervalId *spinInterval);
Packit b099d7
static void SpinBAction(Widget   actionWidget, short    arrowHit );
Packit b099d7
static void FireCallbacks(XmSpinBoxCallbackStruct   *spinBoxCallData,
Packit b099d7
			  XtCallbackList callbackList,
Packit b099d7
			  Widget arrowWidget,
Packit b099d7
			  XEvent *arrowEvent,
Packit b099d7
			  int    arrowReason);
Packit b099d7
static void ArrowCallback(Widget arrowWidget,
Packit b099d7
			  XEvent *arrowEvent,
Packit b099d7
			  int    arrowReason);
Packit b099d7
static Boolean ArrowVerify(Widget arrowWidget,
Packit b099d7
			   XEvent *arrowEvent,
Packit b099d7
			   int    arrowReason );
Packit b099d7
static void ArrowSpinUp(Widget w, XEvent *callEvent);
Packit b099d7
static void ArrowSpinDown(Widget w, XEvent *callEvent);
Packit b099d7
static void GetSpinSize(Widget w, Dimension *wide, Dimension *high);
Packit b099d7
static void SpinNChangeMoveCB(Widget nav, XtCallbackProc moveCB,
Packit b099d7
			      XtPointer closure, Boolean setunset );
Packit b099d7
static void SpinNSetValue(Widget nav, XmNavigatorData nav_data, 
Packit b099d7
			  Boolean notify );
Packit b099d7
static void SpinNGetValue(Widget nav, XmNavigatorData nav_data );
Packit b099d7
static void GetPositionValue(Widget w, int offset, XtArgVal *value);
Packit b099d7
static XmImportOperator SetPositionValue(Widget w, int offset, XtArgVal *value);
Packit b099d7
static int GetMaximumPositionValue(XmSpinBoxConstraint sc);
Packit b099d7
static int GetMinimumPositionValue(XmSpinBoxConstraint sc);
Packit b099d7
static char * ValidatePositionValue(XmSpinBoxConstraint sc, int *position);
Packit b099d7
static Boolean CvtStringToPositionValue(Display *dpy,
Packit b099d7
                                        XrmValue *args,
Packit b099d7
                                        Cardinal *num_args,
Packit b099d7
                                        XrmValue *from,
Packit b099d7
                                        XrmValue *to,
Packit b099d7
                                        XtPointer *converter_data);
Packit b099d7
Packit b099d7
Packit b099d7
/* Macros */
Packit b099d7
Packit b099d7
#define SB_ArrowLayout(w)	(((XmSpinBoxWidget) (w))->spinBox.arrow_layout)
Packit b099d7
#define SB_ArrowsAreStacked(w) \
Packit b099d7
	((SB_ArrowLayout(w) == XmARROWS_END) || \
Packit b099d7
	 (SB_ArrowLayout(w) == XmARROWS_BEGINNING))
Packit b099d7
#define SB_NumArrowsWide(w)	((SB_ArrowsAreStacked(w)) ? 1 : 2)
Packit b099d7
#define SB_NumArrowsHigh(w)	((SB_ArrowsAreStacked(w)) ? 2 : 1)
Packit b099d7
#define SB_ShadowMargin		2
Packit b099d7
#define SB_ShadowPixels(w) \
Packit b099d7
    ( (((XmSpinBoxWidget) (w))->manager.shadow_thickness) ? \
Packit b099d7
       (((XmSpinBoxWidget) (w))->manager.shadow_thickness + SB_ShadowMargin) : \
Packit b099d7
       0 )
Packit b099d7
Packit b099d7
/* Actions table */
Packit b099d7
Packit b099d7
static XtActionsRec actionsTable [] =
Packit b099d7
{
Packit b099d7
  {"SpinBArm",	           SpinBArm },
Packit b099d7
  {"SpinBDisarm",	   SpinBDisarm },
Packit b099d7
  {"SpinBPrior",	   SpinBPrior },
Packit b099d7
  {"SpinBNext",		   SpinBNext },
Packit b099d7
  {"SpinBLeft",		   SpinBLeft },
Packit b099d7
  {"SpinBRight",	   SpinBRight },
Packit b099d7
  {"SpinBFirst",	   SpinBFirst },
Packit b099d7
  {"SpinBLast",		   SpinBLast },
Packit b099d7
  {"SpinBEnter",	   SpinBEnter },
Packit b099d7
  {"SpinBLeave",	   SpinBLeave },
Packit b099d7
};
Packit b099d7
Packit b099d7
#define BAD_SPIN_VALUES			_XmMMsgSpinB_0003
Packit b099d7
#define BAD_SPIN_INCREMENT		_XmMMsgSpinB_0004
Packit b099d7
#define BAD_SPIN_DIRECTION		_XmMMsgSpinB_0005
Packit b099d7
#define BAD_SPIN_POSITION_MIN		_XmMMsgSpinB_0006
Packit b099d7
#define BAD_SPIN_POSITION_MAX		_XmMMsgSpinB_0007
Packit b099d7
#define BAD_SPIN_POSITION_TYPE		_XmMMsgSpinB_0008
Packit b099d7
Packit b099d7
#define DEFAULT_ARROW_SIZE 16
Packit b099d7
Packit b099d7
#define defaultTranslations _XmSpinB_defaultTranslations
Packit b099d7
Packit b099d7
static XtAccelerators    spinAccel;
Packit b099d7
Packit b099d7
/* Resources */
Packit b099d7
#define Offset(field) XtOffsetOf(XmSpinBoxRec,spinBox.field)
Packit b099d7
static XtResource resources[] = {
Packit b099d7
  { XmNarrowLayout, XmCArrowLayout, XmRArrowLayout,
Packit b099d7
    sizeof(unsigned char), Offset(arrow_layout),
Packit b099d7
    XmRImmediate, (XtPointer) XmARROWS_END
Packit b099d7
  },
Packit b099d7
  { XmNarrowOrientation, XmCArrowOrientation, XmRArrowOrientation,
Packit b099d7
    sizeof(unsigned char), Offset(arrow_orientation),
Packit b099d7
    XmRImmediate, (XtPointer) XmARROWS_VERTICAL
Packit b099d7
  },
Packit b099d7
  { XmNarrowSize, XmCArrowSize, XmRHorizontalDimension,
Packit b099d7
    sizeof(Dimension), Offset(arrow_size),
Packit b099d7
    XmRImmediate, (XtPointer) DEFAULT_ARROW_SIZE
Packit b099d7
  },
Packit b099d7
  { XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension,
Packit b099d7
    sizeof(Dimension), Offset(margin_width),
Packit b099d7
    XmRImmediate, (XtPointer) 2
Packit b099d7
  },
Packit b099d7
  { XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension,
Packit b099d7
    sizeof(Dimension), Offset(margin_height),
Packit b099d7
    XmRImmediate, (XtPointer) 2
Packit b099d7
  },
Packit b099d7
  { XmNspacing, XmCSpacing, XmRHorizontalDimension,
Packit b099d7
    sizeof(Dimension), Offset(spacing),
Packit b099d7
    XmRImmediate, (XtPointer) 0
Packit b099d7
  },
Packit b099d7
  { XmNinitialDelay, XmCInitialDelay, XmRInt,
Packit b099d7
    sizeof(unsigned int), Offset(initial_delay),
Packit b099d7
    XmRImmediate, (XtPointer) 250
Packit b099d7
  },
Packit b099d7
  { XmNrepeatDelay, XmCRepeatDelay, XmRInt,
Packit b099d7
    sizeof(unsigned int), Offset(repeat_delay),
Packit b099d7
    XmRImmediate, (XtPointer) 200
Packit b099d7
  },
Packit b099d7
  { XmNdefaultArrowSensitivity, XmCDefaultArrowSensitivity, 
Packit b099d7
    XmRArrowSensitivity,
Packit b099d7
    sizeof(unsigned char), Offset(default_arrow_sensitivity),
Packit b099d7
    XmRImmediate, (XtPointer) XmARROWS_SENSITIVE
Packit b099d7
  },
Packit b099d7
  { XmNmodifyVerifyCallback, XmCCallback, XmRCallback,
Packit b099d7
    sizeof(XtCallbackList), Offset(modify_verify_cb),
Packit b099d7
    XmRPointer, NULL
Packit b099d7
  },
Packit b099d7
  { XmNvalueChangedCallback, XmCCallback, XmRCallback, 
Packit b099d7
    sizeof(XtCallbackList), Offset(value_changed_cb), 
Packit b099d7
    XmRPointer, NULL, 
Packit b099d7
  },
Packit b099d7
  { XmNdetailShadowThickness, XmCShadowThickness, XmRHorizontalDimension,
Packit b099d7
    sizeof(Dimension), Offset(detail_shadow_thickness),
Packit b099d7
    XmRCallProc, (XtPointer) _XmSetThickness
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
/* Resources */
Packit b099d7
Packit b099d7
#define ConstraintOffset(field)\
Packit b099d7
  XtOffsetOf(XmSpinBoxConstraintRec,spinBox.field)
Packit b099d7
Packit b099d7
static XtResource constraints[] = {
Packit b099d7
  { XmNspinBoxChildType, XmCSpinBoxChildType, XmRSpinBoxChildType,
Packit b099d7
    sizeof(unsigned char), ConstraintOffset(sb_child_type),
Packit b099d7
    XmRImmediate, (XtPointer) XmSTRING
Packit b099d7
  },
Packit b099d7
  { XmNpositionType, XmCPositionType, XmRPositionType,
Packit b099d7
    sizeof(unsigned char), ConstraintOffset(position_type),
Packit b099d7
    XmRImmediate, (XtPointer) XmPOSITION_VALUE
Packit b099d7
  },
Packit b099d7
  { XmNnumValues, XmCNumValues, XmRInt,
Packit b099d7
    sizeof(int), ConstraintOffset(num_values),
Packit b099d7
    XmRImmediate, (XtPointer) 0
Packit b099d7
  },
Packit b099d7
  { XmNvalues, XmCValues, XmRXmStringTable, 
Packit b099d7
    sizeof(XmStringTable), ConstraintOffset(values), 
Packit b099d7
    XmRStringTable, NULL
Packit b099d7
  },
Packit b099d7
  { XmNminimumValue, XmCMinimumValue, XmRInt, 
Packit b099d7
    sizeof(int), ConstraintOffset(minimum_value), 
Packit b099d7
    XmRImmediate, (XtPointer) 0
Packit b099d7
  },
Packit b099d7
  { XmNmaximumValue, XmCMaximumValue, XmRInt, 
Packit b099d7
    sizeof(int), ConstraintOffset(maximum_value), 
Packit b099d7
    XmRImmediate, (XtPointer) 10
Packit b099d7
  },
Packit b099d7
  { XmNincrementValue, XmCIncrementValue, XmRInt, 
Packit b099d7
    sizeof(int), ConstraintOffset(increment_value), 
Packit b099d7
    XmRImmediate, (XtPointer) 1
Packit b099d7
  },
Packit b099d7
  { XmNdecimalPoints, XmCDecimalPoints, XmRShort,
Packit b099d7
    sizeof(short), ConstraintOffset(decimal_points), 
Packit b099d7
    XmRImmediate, (XtPointer) 0
Packit b099d7
  },
Packit b099d7
  { XmNarrowSensitivity, XmCArrowSensitivity, XmRArrowSensitivity,
Packit b099d7
    sizeof(unsigned char), ConstraintOffset(arrow_sensitivity), 
Packit b099d7
    XmRImmediate, (XtPointer) XmARROWS_DEFAULT_SENSITIVITY
Packit b099d7
  },
Packit b099d7
  { XmNwrap, XmCWrap, XmRBoolean,
Packit b099d7
    sizeof(Boolean), ConstraintOffset(wrap), 
Packit b099d7
    XmRImmediate, (XtPointer) True
Packit b099d7
  },
Packit b099d7
  { XmNposition, XmCPosition, XmRPositionValue,
Packit b099d7
    sizeof(int), ConstraintOffset(position),
Packit b099d7
    XmRImmediate, (XtPointer) 0
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
static XmSyntheticResource syn_resources[] = 
Packit b099d7
{
Packit b099d7
  { XmNspacing, sizeof(Dimension),
Packit b099d7
    Offset(spacing),
Packit b099d7
    XmeFromHorizontalPixels,
Packit b099d7
    XmeToHorizontalPixels
Packit b099d7
  },
Packit b099d7
  { XmNmarginHeight, sizeof(Dimension),
Packit b099d7
    Offset(margin_height),
Packit b099d7
    XmeFromVerticalPixels,
Packit b099d7
    XmeToVerticalPixels
Packit b099d7
  },
Packit b099d7
  { XmNmarginWidth, sizeof(Dimension),
Packit b099d7
    Offset(margin_width), 
Packit b099d7
    XmeFromHorizontalPixels,
Packit b099d7
    XmeToHorizontalPixels
Packit b099d7
  },
Packit b099d7
  { XmNdetailShadowThickness, sizeof(Dimension), 
Packit b099d7
    Offset(detail_shadow_thickness),
Packit b099d7
    XmeFromHorizontalPixels,
Packit b099d7
    XmeToHorizontalPixels
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
static XmSyntheticResource syn_constraints[] = 
Packit b099d7
{
Packit b099d7
  { XmNposition, sizeof(int), 
Packit b099d7
    ConstraintOffset(position),
Packit b099d7
    GetPositionValue,
Packit b099d7
    SetPositionValue
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
static XmBaseClassExtRec spinBoxBaseClassExtRec = {
Packit b099d7
  NULL,
Packit b099d7
  NULLQUARK,
Packit b099d7
  XmBaseClassExtVersion,
Packit b099d7
  sizeof(XmBaseClassExtRec),
Packit b099d7
  NULL,				/* InitializePrehook	*/
Packit b099d7
  NULL,				/* SetValuesPrehook	*/
Packit b099d7
  NULL,				/* InitializePosthook	*/
Packit b099d7
  NULL,				/* SetValuesPosthook	*/
Packit b099d7
  NULL,				/* secondaryObjectClass	*/
Packit b099d7
  NULL,				/* secondaryCreate	*/
Packit b099d7
  NULL,               		/* getSecRes data	*/
Packit b099d7
  { 0 },      			/* fastSubclass flags	*/
Packit b099d7
  NULL,				/* getValuesPrehook	*/
Packit b099d7
  NULL,				/* getValuesPosthook	*/
Packit b099d7
  NULL,                         /* ClassPartInitPrehook */
Packit b099d7
  NULL,                         /* classPartInitPosthook*/
Packit b099d7
  NULL,                         /* ext_resources        */
Packit b099d7
  NULL,                         /* compiled_ext_resources*/
Packit b099d7
  0,                            /* num_ext_resources    */
Packit b099d7
  FALSE,                        /* use_sub_resources    */
Packit b099d7
  XmInheritWidgetNavigable,     /* widgetNavigable      */
Packit b099d7
  NULL                          /* focusChange          */
Packit b099d7
  };
Packit b099d7
Packit b099d7
/*  The Spin class record definition  */
Packit b099d7
Packit b099d7
externaldef (xmspinboxclassrec) XmSpinBoxClassRec xmSpinBoxClassRec= {
Packit b099d7
  {
Packit b099d7
    (WidgetClass)&xmManagerClassRec,    /* superclass */   
Packit b099d7
    "XmSpinBox",                        /* class_name */	
Packit b099d7
    sizeof(XmSpinBoxRec),               /* widget_size */	
Packit b099d7
    ClassInitialize,    		/* class_initialize */    
Packit b099d7
    ClassPartInitialize,                /* class_part_initialize */
Packit b099d7
    FALSE,    		                /* class_inited */	
Packit b099d7
    Initialize,    	                /* initialize */	
Packit b099d7
    NULL,    		                /* initialize_hook */
Packit b099d7
    XtInheritRealize,		        /* realize */	
Packit b099d7
    actionsTable,      	                /* actions */
Packit b099d7
    XtNumber(actionsTable),             /* num_actions */	
Packit b099d7
    resources,    	                /* resources */
Packit b099d7
    XtNumber(resources),                /* num_resources */
Packit b099d7
    NULLQUARK,    	                /* xrm_class */	
Packit b099d7
    TRUE,    		                /* compress_motion */	
Packit b099d7
    XtExposeCompressMaximal |          	/* compress_exposure */	
Packit b099d7
	XtExposeNoRegion,
Packit b099d7
    TRUE,    		              	/* compress_enterleave */
Packit b099d7
    FALSE,    		              	/* visible_interest */	
Packit b099d7
    Destroy,    		      	/* destroy */	
Packit b099d7
    Resize,			      	/* resize */
Packit b099d7
    Redisplay,    	              	/* expose */	
Packit b099d7
    SetValues,    	              	/* set_values */	
Packit b099d7
    NULL,    		              	/* set_values_hook */
Packit b099d7
    XtInheritSetValuesAlmost,          	/* set_values_almost */
Packit b099d7
    NULL,    		              	/* get_values_hook */
Packit b099d7
    XtInheritAcceptFocus,	      	/* accept_focus */	
Packit b099d7
    XtVersion,    	              	/* version */
Packit b099d7
    NULL,    		              	/* callback private */
Packit b099d7
    defaultTranslations,	        /* tm_table */
Packit b099d7
    QueryGeometry,    		      	/* query_geometry */
Packit b099d7
    NULL,    		              	/* display_accelerator */
Packit b099d7
    (XtPointer)&spinBoxBaseClassExtRec,	/* extension */
Packit b099d7
  },
Packit b099d7
  
Packit b099d7
  {    /* composite_class fields */
Packit b099d7
    GeometryManager,                	/* geometry_manager */
Packit b099d7
    ChangeManaged,    	              	/* change_managed */
Packit b099d7
    InsertChild,		        /* insert_child */
Packit b099d7
    XtInheritDeleteChild,	        /* delete_child */
Packit b099d7
    NULL,    		                /* extension */
Packit b099d7
  },
Packit b099d7
  
Packit b099d7
  {    /* constraint_class fields */
Packit b099d7
    constraints,    		      	/* resource list */
Packit b099d7
    XtNumber(constraints),	      	/* num resources */
Packit b099d7
    sizeof(XmSpinBoxConstraintRec),    	/* constraint size */
Packit b099d7
    ConstraintInitialize,              	/* init proc */
Packit b099d7
    ConstraintDestroy,			/* destroy proc */
Packit b099d7
    ConstraintSetValues,		/* set values proc */
Packit b099d7
    NULL,    		             	/* extension */
Packit b099d7
  },
Packit b099d7
      /* manager_class fields */
Packit b099d7
  {
Packit b099d7
    NULL,    		              	/* translations */
Packit b099d7
    syn_resources,              	/* syn_resources */
Packit b099d7
    XtNumber(syn_resources),           	/* num_syn_resources */
Packit b099d7
    syn_constraints,	              	/* syn_cont_resources */
Packit b099d7
    XtNumber(syn_constraints),         	/* num_syn_cont_resources */
Packit b099d7
    NULL,    		              	/* parent_process */
Packit b099d7
    NULL,    		              	/* extension */
Packit b099d7
  },
Packit b099d7
      /* spinbox_class fields */
Packit b099d7
  {
Packit b099d7
    NULL,    		              	/* get_callback_widget */
Packit b099d7
    NULL    		              	/* extension */
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
};
Packit b099d7
Packit b099d7
externaldef(xmspinboxwidgetclass) WidgetClass xmSpinBoxWidgetClass =
Packit b099d7
       (WidgetClass)&xmSpinBoxClassRec;
Packit b099d7
     
Packit b099d7
static XmConst XmNavigatorTraitRec spinBoxNT =
Packit b099d7
{
Packit b099d7
  0,
Packit b099d7
  SpinNChangeMoveCB,
Packit b099d7
  SpinNSetValue,
Packit b099d7
  SpinNGetValue,
Packit b099d7
};
Packit b099d7
Packit b099d7
static XtConvertArgRec selfConvertArgs[] = {
Packit b099d7
    { XtBaseOffset, (XtPointer) 0, sizeof(int) }
Packit b099d7
};
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 **
Packit b099d7
 ***			METHODS
Packit b099d7
 **
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
ClassInitialize(void)
Packit b099d7
{
Packit b099d7
  spinAccel = XtParseAcceleratorTable(_XmSpinB_defaultAccelerators);
Packit b099d7
Packit b099d7
  /* set up base class extension quark */
Packit b099d7
  spinBoxBaseClassExtRec.record_type = XmQmotif;
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
ClassPartInitialize(WidgetClass classPart)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidgetClass spinC;
Packit b099d7
  
Packit b099d7
  spinC = (XmSpinBoxWidgetClass) classPart;
Packit b099d7
  
Packit b099d7
  _XmFastSubclassInit(classPart, XmSPINBOX_BIT);
Packit b099d7
  
Packit b099d7
  /* Install the navigator trait for all subclasses */
Packit b099d7
  XmeTraitSet((XtPointer)spinC, XmQTnavigator, (XtPointer) &spinBoxNT);
Packit b099d7
Packit b099d7
  XtSetTypeConverter( XmRString, XmRPositionValue, CvtStringToPositionValue,
Packit b099d7
                      selfConvertArgs, XtNumber(selfConvertArgs),
Packit b099d7
                      XtCacheNone, (XtDestructor) NULL) ;
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
Initialize(Widget req,		/* unused */
Packit b099d7
	   Widget new_w, 
Packit b099d7
	   ArgList args,	/* unused */
Packit b099d7
	   Cardinal *num_args)	/* unused */
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)new_w;
Packit b099d7
  XGCValues	  GCvalues;
Packit b099d7
  XtGCMask	  GCmask, unusedMask;
Packit b099d7
Packit b099d7
  spinW->spinBox.textw = 0;
Packit b099d7
  spinW->spinBox.dim_mask = 0;
Packit b099d7
  spinW->spinBox.last_hit = 0;
Packit b099d7
  spinW->spinBox.spin_timer = 0;
Packit b099d7
  spinW->spinBox.make_change = 0;
Packit b099d7
  
Packit b099d7
  spinW->spinBox.boundary = 0;
Packit b099d7
Packit b099d7
  spinW->spinBox.ideal_height = 0;
Packit b099d7
  spinW->spinBox.ideal_width = 0;
Packit b099d7
  
Packit b099d7
  spinW->spinBox.up_arrow_pressed = False;
Packit b099d7
  spinW->spinBox.down_arrow_pressed = False;
Packit b099d7
Packit b099d7
  spinW->spinBox.up_arrow_rect.x = 0;
Packit b099d7
  spinW->spinBox.up_arrow_rect.y = 0;
Packit b099d7
  spinW->spinBox.up_arrow_rect.width = 0;
Packit b099d7
  spinW->spinBox.up_arrow_rect.height = 0;
Packit b099d7
Packit b099d7
  spinW->spinBox.down_arrow_rect.x = 0;
Packit b099d7
  spinW->spinBox.down_arrow_rect.y = 0;
Packit b099d7
  spinW->spinBox.down_arrow_rect.width = 0;
Packit b099d7
  spinW->spinBox.down_arrow_rect.height = 0;
Packit b099d7
  
Packit b099d7
  if (!spinW->core.accelerators)
Packit b099d7
    spinW->core.accelerators = spinAccel;
Packit b099d7
  
Packit b099d7
  if (spinW->spinBox.initial_delay < 1)
Packit b099d7
    spinW->spinBox.initial_delay = spinW->spinBox.repeat_delay;
Packit b099d7
  
Packit b099d7
  /* Get arrow GC */
Packit b099d7
  GCmask = GCForeground | GCBackground | GCGraphicsExposures;
Packit b099d7
  GCvalues.foreground = spinW->core.background_pixel;
Packit b099d7
  GCvalues.background = spinW->manager.foreground;
Packit b099d7
  GCvalues.graphics_exposures = False;
Packit b099d7
  
Packit b099d7
  /* Share gc with scrollbar */
Packit b099d7
  spinW->spinBox.arrow_gc = XtAllocateGC(new_w, 0, GCmask, &GCvalues, 
Packit b099d7
					 0, GCFont);
Packit b099d7
  
Packit b099d7
  GCmask |= GCFillStyle | GCStipple;
Packit b099d7
  unusedMask = GCClipXOrigin | GCClipYOrigin | GCFont;
Packit b099d7
Packit b099d7
  GCvalues.background = spinW->core.background_pixel;
Packit b099d7
  GCvalues.foreground = spinW->manager.foreground;
Packit b099d7
  GCvalues.fill_style = FillOpaqueStippled;
Packit b099d7
  GCvalues.stipple = _XmGetInsensitiveStippleBitmap(new_w);
Packit b099d7
  
Packit b099d7
  /* share GC with ArrowButton */
Packit b099d7
  spinW->spinBox.insensitive_gc = XtAllocateGC(new_w, 0, GCmask, &GCvalues, 
Packit b099d7
					       GCClipMask, unusedMask);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
Destroy(Widget w)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)w;
Packit b099d7
  
Packit b099d7
  if (spinW->spinBox.arrow_gc != NULL)
Packit b099d7
    {
Packit b099d7
      XtReleaseGC(w, spinW->spinBox.arrow_gc);
Packit b099d7
      spinW->spinBox.arrow_gc = NULL;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  if (spinW->spinBox.insensitive_gc != NULL)
Packit b099d7
    {
Packit b099d7
      XtReleaseGC(w, spinW->spinBox.insensitive_gc);
Packit b099d7
      spinW->spinBox.insensitive_gc = NULL;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
Resize(Widget w)
Packit b099d7
{
Packit b099d7
  XtWidgetGeometry spinG;
Packit b099d7
  
Packit b099d7
  spinG.width = XtWidth(w);
Packit b099d7
  spinG.height = XtHeight(w);
Packit b099d7
  
Packit b099d7
  LayoutSpinBox(w, &spinG, NULL);
Packit b099d7
Packit b099d7
  if (XtIsRealized(w))
Packit b099d7
     XClearArea(XtDisplay(w), XtWindow(w), 0, 0, 0, 0, True);			/*  Force Redisplay */
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
Redisplay(Widget w, 
Packit b099d7
	  XEvent *event,	/* unused */
Packit b099d7
	  Region region)	/* unused */
Packit b099d7
{
Packit b099d7
Packit b099d7
  XmSpinBoxWidget	spinW = (XmSpinBoxWidget) w;
Packit b099d7
  
Packit b099d7
  if (XtIsRealized(w))
Packit b099d7
    {
Packit b099d7
      ClearArrows(w);
Packit b099d7
      
Packit b099d7
      if (spinW->manager.shadow_thickness > 0)
Packit b099d7
	{
Packit b099d7
	  int	width, height;
Packit b099d7
Packit b099d7
	  width = (spinW->spinBox.ideal_width < XtWidth(spinW)) ? 
Packit b099d7
		  spinW->spinBox.ideal_width :
Packit b099d7
		  XtWidth(spinW);
Packit b099d7
Packit b099d7
	  height = (spinW->spinBox.ideal_height < XtHeight(spinW)) ? 
Packit b099d7
		  spinW->spinBox.ideal_height :
Packit b099d7
		  XtHeight(spinW);
Packit b099d7
Packit b099d7
	  XmeDrawShadows(
Packit b099d7
			 XtDisplay(w), XtWindow(w),
Packit b099d7
		         spinW->manager.top_shadow_GC,
Packit b099d7
		         spinW->manager.bottom_shadow_GC,
Packit b099d7
		         0, 0, width, height,
Packit b099d7
		         spinW->manager.shadow_thickness,
Packit b099d7
			 XmSHADOW_OUT
Packit b099d7
		        );
Packit b099d7
	}
Packit b099d7
      
Packit b099d7
      _XmSetFocusFlag(w,XmFOCUS_IGNORE, False);
Packit b099d7
      
Packit b099d7
      DrawSpinArrow(w, XmARROW_UP);
Packit b099d7
      DrawSpinArrow(w, XmARROW_DOWN);
Packit b099d7
    }
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean
Packit b099d7
SetValues(Widget old, 
Packit b099d7
	  Widget req, 
Packit b099d7
	  Widget new_w, 
Packit b099d7
	  ArgList args,		/* unused */
Packit b099d7
	  Cardinal *num_args )	/* unused */
Packit b099d7
{
Packit b099d7
  XtWidgetGeometry spinG;
Packit b099d7
  XmSpinBoxWidget	 oldW = (XmSpinBoxWidget)old;
Packit b099d7
  XmSpinBoxWidget	 reqW = (XmSpinBoxWidget)req;
Packit b099d7
  XmSpinBoxWidget	 newW = (XmSpinBoxWidget)new_w;
Packit b099d7
  Boolean		 displayFlag;
Packit b099d7
  
Packit b099d7
  displayFlag = False;
Packit b099d7
  
Packit b099d7
  /*  Initial delay must be positive	*/
Packit b099d7
  if (newW->spinBox.initial_delay < 1)
Packit b099d7
    newW->spinBox.initial_delay = newW->spinBox.repeat_delay;
Packit b099d7
Packit b099d7
  if ((newW->core.sensitive != oldW->core.sensitive) ||
Packit b099d7
      (newW->core.ancestor_sensitive != oldW->core.ancestor_sensitive))
Packit b099d7
    displayFlag = True;				
Packit b099d7
Packit b099d7
  /*  Check for geo changes, if realized	*/
Packit b099d7
  if (XtIsRealized(new_w) &&
Packit b099d7
      (reqW->spinBox.arrow_layout  != oldW->spinBox.arrow_layout ||
Packit b099d7
      reqW->spinBox.margin_width  != oldW->spinBox.margin_width ||
Packit b099d7
      reqW->spinBox.margin_height != oldW->spinBox.margin_height ||
Packit b099d7
      reqW->spinBox.spacing       != oldW->spinBox.spacing ||
Packit b099d7
      reqW->spinBox.arrow_size    != oldW->spinBox.arrow_size))
Packit b099d7
    {
Packit b099d7
      spinG.width = 0;
Packit b099d7
      spinG.height = 0;
Packit b099d7
      
Packit b099d7
      GetSpinSize(new_w, &spinG.width, &spinG.height);
Packit b099d7
      XtWidth(new_w) = spinG.width;
Packit b099d7
      XtHeight(new_w) = spinG.height;
Packit b099d7
      
Packit b099d7
      if (XtIsRealized(old))
Packit b099d7
        ClearArrows(old);
Packit b099d7
      
Packit b099d7
      LayoutSpinBox(new_w, &spinG, NULL);
Packit b099d7
      displayFlag = True;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  if (reqW->spinBox.default_arrow_sensitivity
Packit b099d7
      !=  oldW->spinBox.default_arrow_sensitivity ||
Packit b099d7
      reqW->spinBox.detail_shadow_thickness
Packit b099d7
      != oldW->spinBox.detail_shadow_thickness)
Packit b099d7
    displayFlag = True;
Packit b099d7
Packit b099d7
  return(displayFlag);
Packit b099d7
}
Packit b099d7
Packit b099d7
static XtGeometryResult
Packit b099d7
QueryGeometry(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *rep)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget	 spinW = (XmSpinBoxWidget)w;
Packit b099d7
  
Packit b099d7
  if (!XtIsRealized((Widget)spinW))
Packit b099d7
    {
Packit b099d7
      rep->width = XtWidth(w);
Packit b099d7
      rep->height = XtHeight(w);
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      rep->width = 0;
Packit b099d7
      rep->height = 0;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  GetSpinSize(w, &rep->width, &rep->height);
Packit b099d7
  
Packit b099d7
  return(XmeReplyToQueryGeometry(w, req, rep));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static XtGeometryResult
Packit b099d7
GeometryManager(Widget w, 
Packit b099d7
		XtWidgetGeometry *req, 
Packit b099d7
		XtWidgetGeometry *rep) /* unused */
Packit b099d7
{
Packit b099d7
  XtGeometryResult spinResult;
Packit b099d7
  XtWidgetGeometry spinG;
Packit b099d7
  XtWidgetGeometry origG;
Packit b099d7
 
Packit b099d7
  if (IsX(req))
Packit b099d7
    if (w->core.x != req->x)
Packit b099d7
      return(XtGeometryNo);
Packit b099d7
 
Packit b099d7
  if (IsY(req))
Packit b099d7
    if (w->core.y != req->y)
Packit b099d7
      return(XtGeometryNo);
Packit b099d7
Packit b099d7
  origG.width = w->core.width;
Packit b099d7
  origG.height = w->core.height;
Packit b099d7
  
Packit b099d7
  if (IsWidth(req))
Packit b099d7
    w->core.width = req->width;
Packit b099d7
Packit b099d7
  if (IsHeight(req))
Packit b099d7
    w->core.height = req->height;
Packit b099d7
  
Packit b099d7
  spinG.width = 0;
Packit b099d7
  spinG.height = 0;
Packit b099d7
Packit b099d7
  GetSpinSize(XtParent(w), &spinG.width, &spinG.height);
Packit b099d7
Packit b099d7
  spinG.request_mode = (CWWidth | CWHeight);
Packit b099d7
  
Packit b099d7
  spinResult = _XmMakeGeometryRequest(XtParent(w), &spinG);
Packit b099d7
  
Packit b099d7
  if (spinResult == XtGeometryYes)
Packit b099d7
   {
Packit b099d7
     LayoutSpinBox(XtParent(w), &spinG, w);
Packit b099d7
Packit b099d7
     /*  Force Redisplay */
Packit b099d7
     if (XtIsRealized(w))
Packit b099d7
       XClearArea(XtDisplay(w), XtWindow(w), 0, 0, 0, 0, True);
Packit b099d7
   }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      w->core.width = origG.width;
Packit b099d7
      w->core.height = origG.height;
Packit b099d7
      
Packit b099d7
      spinResult = XtGeometryNo;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  return(spinResult);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
ChangeManaged(Widget w)
Packit b099d7
{
Packit b099d7
  XtWidgetGeometry spinG;
Packit b099d7
  XmSpinBoxWidget	 spinW = (XmSpinBoxWidget) w;
Packit b099d7
  int		 i;
Packit b099d7
  
Packit b099d7
  if (XtIsRealized(w))
Packit b099d7
    {
Packit b099d7
      spinG.width = 0; 
Packit b099d7
      spinG.height =  0;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      spinG.width = XtWidth(w);
Packit b099d7
      spinG.height = XtHeight(w);
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  GetSpinSize(w, &spinG.width, &spinG.height);
Packit b099d7
Packit b099d7
  spinG.request_mode = CWWidth | CWHeight;
Packit b099d7
  
Packit b099d7
  _XmMakeGeometryRequest(w, &spinG);
Packit b099d7
  
Packit b099d7
  LayoutSpinBox(w, &spinG, NULL);
Packit b099d7
Packit b099d7
  /* Update managed children */
Packit b099d7
  /* Also make sure that focus is on the last created and managed
Packit b099d7
   * text/text_field child. If the last text/text_field child is not managed, 
Packit b099d7
   * focus should be on the one previous to that. XmQTaccessTextual trait can 
Packit b099d7
   * not be used to confirm the child to be text or text_field as this trait 
Packit b099d7
   * is held by other widgets such as label as well.
Packit b099d7
   */
Packit b099d7
  for (i = 0; i < SB_ChildCount(spinW); i++) {
Packit b099d7
    if (XtIsManaged(spinW->composite.children[i])) {
Packit b099d7
      if (XmIsTextField(spinW->composite.children[i]) ||
Packit b099d7
	  XmIsText(spinW->composite.children[i])) {
Packit b099d7
	 spinW->spinBox.textw  = spinW->composite.children[i];
Packit b099d7
     }
Packit b099d7
      UpdateChildText(spinW->composite.children[i]);
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
InsertChild(Widget newChild)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget      spinW = (XmSpinBoxWidget)XtParent(newChild);
Packit b099d7
  XtWidgetProc insert_child;
Packit b099d7
  
Packit b099d7
  /* call manager's InsertChild method */
Packit b099d7
  _XmProcessLock();
Packit b099d7
  insert_child = ((XmManagerWidgetClass)xmManagerWidgetClass)
Packit b099d7
     			->composite_class.insert_child;
Packit b099d7
  _XmProcessUnlock();
Packit b099d7
  (*insert_child)(newChild);
Packit b099d7
  
Packit b099d7
  if (XmeTraitGet((XtPointer)XtClass(newChild), XmQTaccessTextual) != NULL)
Packit b099d7
    {
Packit b099d7
      spinW->spinBox.textw  = newChild;
Packit b099d7
      
Packit b099d7
      XtInsertEventHandler(
Packit b099d7
			   newChild,
Packit b099d7
			   FocusChangeMask,
Packit b099d7
			   False,
Packit b099d7
			   SpinChildFocusChange,
Packit b099d7
			   (XtPointer) spinW,
Packit b099d7
			   XtListHead
Packit b099d7
			   );
Packit b099d7
Packit b099d7
      /* To handle implicit mode,  we also call the focus change
Packit b099d7
	 if a button is clicked.  The work is finished in the event
Packit b099d7
	 handler */
Packit b099d7
      XtInsertEventHandler(
Packit b099d7
			   newChild,
Packit b099d7
			   ButtonPressMask,
Packit b099d7
			   False,
Packit b099d7
			   SpinChildFocusChange,
Packit b099d7
			   (XtPointer) spinW,
Packit b099d7
			   XtListHead
Packit b099d7
			   );
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  XtInstallAccelerators(newChild, (Widget)spinW);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
Packit b099d7
static void
Packit b099d7
ConstraintInitialize(Widget req, 
Packit b099d7
		     Widget new_w, 
Packit b099d7
		     ArgList args, /* unused */
Packit b099d7
		     Cardinal *num_args) /* unused */
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint	newC = SB_GetConstraintRec(new_w);
Packit b099d7
  XmSpinBoxConstraint	reqC = SB_GetConstraintRec(req);
Packit b099d7
  XmSpinBoxWidget	spinW;
Packit b099d7
  int			valLoop;
Packit b099d7
  char			*error = (char *) NULL;
Packit b099d7
  
Packit b099d7
  spinW = (XmSpinBoxWidget)XtParent(new_w);
Packit b099d7
  
Packit b099d7
  /* Numeric Child*/
Packit b099d7
  if (SB_ChildIsNumeric(newC))
Packit b099d7
    {
Packit b099d7
      /* enforce reasonable parameters */
Packit b099d7
      if (newC->increment_value == 0)
Packit b099d7
	{
Packit b099d7
	  XmeWarning(new_w, BAD_SPIN_INCREMENT);
Packit b099d7
	  newC->increment_value = 1;
Packit b099d7
	}
Packit b099d7
      
Packit b099d7
      if ((newC->minimum_value < newC->maximum_value
Packit b099d7
	  && newC->increment_value < 0)
Packit b099d7
      ||  (newC->minimum_value > newC->maximum_value 
Packit b099d7
	  && newC->increment_value > 0))
Packit b099d7
	{
Packit b099d7
	  XmeWarning(new_w, BAD_SPIN_DIRECTION);
Packit b099d7
	  newC->increment_value *= -1;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
  /* String Child*/
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
    if (reqC->values != NULL)
Packit b099d7
      {
Packit b099d7
  /* buffer the values XmStringTable */
Packit b099d7
      newC->values = (XmString *)XtMalloc(reqC->num_values * sizeof(XmString));
Packit b099d7
      
Packit b099d7
      if (newC->values != NULL)
Packit b099d7
	for (valLoop = 0; valLoop < reqC->num_values; valLoop++)
Packit b099d7
	  newC->values[valLoop] = XmStringCopy(reqC->values[valLoop]);
Packit b099d7
      }
Packit b099d7
Packit b099d7
#if 0
Packit b099d7
    /*
Packit b099d7
     * This is ifdef'ed out to be BC with DtSpinBox warning messages.
Packit b099d7
     */
Packit b099d7
    if (newC->values == NULL || newC->num_values == 0)
Packit b099d7
      if (ChildIsTraversable(new_w))
Packit b099d7
	if (XmeTraitGet((XtPointer)XtClass(new_w), XmQTaccessTextual) != NULL)
Packit b099d7
          XmeWarning(new_w, BAD_SPIN_VALUES);
Packit b099d7
#endif
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  if (newC->position_type != XmPOSITION_VALUE &&
Packit b099d7
      newC->position_type != XmPOSITION_INDEX)
Packit b099d7
    {
Packit b099d7
      newC->position_type = XmPOSITION_VALUE;
Packit b099d7
      XmeWarning(new_w, BAD_SPIN_POSITION_TYPE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
  error = ValidatePositionValue(newC, &newC->position);
Packit b099d7
  if (error)
Packit b099d7
    XmeWarning(new_w, error);
Packit b099d7
Packit b099d7
  spinW->spinBox.up_arrow_pressed = False;
Packit b099d7
  spinW->spinBox.down_arrow_pressed = False;
Packit b099d7
  
Packit b099d7
  /* No reason to do the work until the child is managed */
Packit b099d7
  if (XtIsManaged(new_w))
Packit b099d7
    UpdateChildText(new_w);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
ConstraintDestroy(
Packit b099d7
        Widget w )
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint	spinC = SB_GetConstraintRec(w);
Packit b099d7
  int			itemLoop;
Packit b099d7
      
Packit b099d7
      /* give back the old values XmStringTable */
Packit b099d7
  if (spinC->values != NULL)
Packit b099d7
    {
Packit b099d7
      for (itemLoop = 0; itemLoop < spinC->num_values; itemLoop++)
Packit b099d7
	XmStringFree(spinC->values[itemLoop]);
Packit b099d7
	  
Packit b099d7
      XtFree((char*)spinC->values);
Packit b099d7
	  
Packit b099d7
      spinC->values = NULL;
Packit b099d7
      spinC->num_values = 0;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean
Packit b099d7
ConstraintSetValues(Widget   old, 
Packit b099d7
		    Widget   req, 
Packit b099d7
		    Widget   new_w,
Packit b099d7
		    ArgList  args, /* unused */
Packit b099d7
		    Cardinal *num_args ) /* unused */
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint  oldC = SB_GetConstraintRec(old);
Packit b099d7
  XmSpinBoxConstraint  reqC = SB_GetConstraintRec(req);
Packit b099d7
  XmSpinBoxConstraint  newC = SB_GetConstraintRec(new_w);
Packit b099d7
  XmSpinBoxWidget      spinW = (XmSpinBoxWidget)XtParent(new_w);
Packit b099d7
  Boolean	       redisplayText = False;
Packit b099d7
  int		       nvi;
Packit b099d7
  int		       valLoop;
Packit b099d7
  char		       *error = (char *) NULL;
Packit b099d7
Packit b099d7
  
Packit b099d7
  /*
Packit b099d7
   * These resources have CG permissions only:
Packit b099d7
   *	XmNspinBoxChildType XmNpositionType
Packit b099d7
   */
Packit b099d7
  if (newC->position_type != oldC->position_type)
Packit b099d7
    {
Packit b099d7
      newC->position_type = oldC->position_type;
Packit b099d7
      XmeWarning(new_w, BAD_SPIN_POSITION_TYPE);
Packit b099d7
    }
Packit b099d7
  /*
Packit b099d7
   * BINARY COMPATIBILITY with DTSPINBOX
Packit b099d7
   *
Packit b099d7
   * However, DtSpinBox does not prevent setting XmNspinBoxChildType
Packit b099d7
   * so we have to allow it.
Packit b099d7
   * newC->sb_child_type = oldC->sb_child_type;
Packit b099d7
   */
Packit b099d7
  if (newC->sb_child_type != oldC->sb_child_type)
Packit b099d7
    redisplayText = True;
Packit b099d7
  
Packit b099d7
  /**** Numeric Child ****/
Packit b099d7
  if (SB_ChildIsNumeric(newC))
Packit b099d7
    {
Packit b099d7
      /* enforce reasonable parameters */
Packit b099d7
      if (newC->increment_value == 0)
Packit b099d7
	{
Packit b099d7
          XmeWarning(new_w, BAD_SPIN_INCREMENT);
Packit b099d7
	  newC->increment_value = 1;
Packit b099d7
	}
Packit b099d7
      
Packit b099d7
      /* if something has changed ... */
Packit b099d7
      if (newC->minimum_value  != oldC->minimum_value 
Packit b099d7
	  ||  newC->maximum_value  != oldC->maximum_value
Packit b099d7
	  ||  newC->increment_value != oldC->increment_value
Packit b099d7
	  ||  newC->decimal_points != oldC->decimal_points
Packit b099d7
	  ||  newC->position != oldC->position)
Packit b099d7
	{
Packit b099d7
	  redisplayText = True;
Packit b099d7
Packit b099d7
	  /* force the step to go the right way */
Packit b099d7
	  if ((newC->minimum_value < newC->maximum_value
Packit b099d7
	      && newC->increment_value < 0)
Packit b099d7
	  ||  (newC->minimum_value > newC->maximum_value
Packit b099d7
	      && newC->increment_value > 0))
Packit b099d7
	      {
Packit b099d7
	        XmeWarning(new_w, BAD_SPIN_DIRECTION);
Packit b099d7
	        newC->increment_value *= -1;
Packit b099d7
	      }
Packit b099d7
	  
Packit b099d7
	  error = ValidatePositionValue(newC, &newC->position);
Packit b099d7
	  if (error)
Packit b099d7
 	    XmeWarning(new_w, error);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /****  String Child  ****/
Packit b099d7
  else  if (ChildIsTraversable(new_w)) {
Packit b099d7
  /* buffer the new values XmStringTable */
Packit b099d7
      if (reqC->values == NULL)
Packit b099d7
	reqC->values = oldC->values;
Packit b099d7
      else if (reqC->values != oldC->values)
Packit b099d7
	{
Packit b099d7
	  newC->values =
Packit b099d7
	   (XmString *)XtMalloc(reqC->num_values * sizeof(XmString));
Packit b099d7
	  
Packit b099d7
	  if (newC->values != NULL)
Packit b099d7
	    for (valLoop = 0; valLoop < reqC->num_values; valLoop++)
Packit b099d7
	      newC->values[valLoop] = XmStringCopy(reqC->values[valLoop]);
Packit b099d7
	}
Packit b099d7
      
Packit b099d7
      error = ValidatePositionValue(newC, &newC->position);
Packit b099d7
      if (error)
Packit b099d7
 	XmeWarning(new_w, error);
Packit b099d7
Packit b099d7
#if 0
Packit b099d7
      if (newC->values == NULL || newC->num_values == 0)
Packit b099d7
	if (XmeTraitGet((XtPointer)XtClass(new_w), XmQTaccessTextual) != NULL)
Packit b099d7
	  XmeWarning(new_w, BAD_SPIN_VALUES);
Packit b099d7
#endif
Packit b099d7
Packit b099d7
      if ((newC->position != oldC->position)
Packit b099d7
      ||  (newC->values != oldC->values)
Packit b099d7
      ||  (newC->num_values < oldC->num_values
Packit b099d7
	   && newC->position > newC->num_values))
Packit b099d7
	redisplayText = True;
Packit b099d7
  
Packit b099d7
    /* give back the old values XmStringTable */
Packit b099d7
    if (reqC->values != oldC->values) {
Packit b099d7
        if (oldC->values != NULL)
Packit b099d7
	  for (nvi = 0; nvi < oldC->num_values; nvi++)
Packit b099d7
	    XmStringFree(oldC->values[nvi]);
Packit b099d7
      
Packit b099d7
        XtFree((char*)oldC->values);
Packit b099d7
      
Packit b099d7
        oldC->values = NULL;
Packit b099d7
    }
Packit b099d7
   }
Packit b099d7
  
Packit b099d7
  /* If the current focus child is the one requesting the change */
Packit b099d7
  if (XtIsRealized((Widget)spinW) && spinW->spinBox.textw == new_w)
Packit b099d7
    {
Packit b099d7
    if (newC->arrow_sensitivity != oldC->arrow_sensitivity)
Packit b099d7
      {
Packit b099d7
      DrawSpinArrow((Widget) spinW, XmARROW_UP);
Packit b099d7
      DrawSpinArrow((Widget) spinW, XmARROW_DOWN);
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  if (redisplayText)
Packit b099d7
    UpdateChildText(new_w);
Packit b099d7
Packit b099d7
  return(False);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 **
Packit b099d7
 ***			EVENT HANDLERS
Packit b099d7
 **
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinChildFocusChange
Packit b099d7
 *   Event Handler for Focus Change.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
SpinChildFocusChange(Widget focusWidget, 
Packit b099d7
		     XtPointer focusClient,
Packit b099d7
		     XEvent *focusEvent, 
Packit b099d7
		     Boolean *focusContinue) /* unused */
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)focusClient;
Packit b099d7
  
Packit b099d7
  if (_XmGetFocusPolicy((Widget) focusClient) == XmEXPLICIT) {
Packit b099d7
    if (focusEvent->type == FocusIn) {
Packit b099d7
      if (spinW->spinBox.textw != focusWidget)
Packit b099d7
	{
Packit b099d7
	  spinW->spinBox.textw = focusWidget;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
  } else {
Packit b099d7
    /* Only care if this is BSelect */
Packit b099d7
    if (focusEvent->type == ButtonPress && 
Packit b099d7
	focusEvent->xbutton.button == Button1) {
Packit b099d7
      if (spinW->spinBox.textw != (Widget) NULL) {
Packit b099d7
	Widget child = spinW->spinBox.textw;
Packit b099d7
	WidgetClass wc = XtClass(child);
Packit b099d7
Packit b099d7
	if (XmIsPrimitive(child)) {   
Packit b099d7
	  (*(((XmPrimitiveWidgetClass) wc)
Packit b099d7
	     ->primitive_class.border_unhighlight))(child) ;
Packit b099d7
	}
Packit b099d7
      }
Packit b099d7
      spinW->spinBox.textw = focusWidget;
Packit b099d7
      if (spinW->spinBox.textw != (Widget) NULL) {
Packit b099d7
	Widget child = spinW->spinBox.textw;
Packit b099d7
      	WidgetClass wc = XtClass(child);
Packit b099d7
Packit b099d7
	if (XmIsPrimitive(child)) {   
Packit b099d7
	  (*(((XmPrimitiveWidgetClass) wc)
Packit b099d7
	     ->primitive_class.border_highlight))(child) ;
Packit b099d7
	}
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
Packit b099d7
Packit b099d7
  if (focusWidget != (Widget) NULL) {
Packit b099d7
    DrawSpinArrow((Widget)focusClient, XmARROW_UP);
Packit b099d7
    DrawSpinArrow((Widget)focusClient, XmARROW_DOWN);
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 **
Packit b099d7
 ***			ACTIONS
Packit b099d7
 **
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 * The Enter and Leave actions deal with implicit mode 
Packit b099d7
 * (keyboardFocusPolicy == POINTER),  where we need to indicate to the user
Packit b099d7
 * which child widget is to be updated on a mouse action.  
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void 
Packit b099d7
SpinBEnter(Widget widget, XEvent *event, String *params, Cardinal *num_params)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)widget;
Packit b099d7
  Widget child = (Widget) spinW -> spinBox.textw;
Packit b099d7
Packit b099d7
  /* We only perform this action for POINTER mode */
Packit b099d7
  if (_XmGetFocusPolicy(widget) != XmPOINTER) return;
Packit b099d7
Packit b099d7
  if (child != (Widget) NULL) {
Packit b099d7
    WidgetClass wc = XtClass(child);
Packit b099d7
Packit b099d7
    if (XmIsPrimitive(child)) {   
Packit b099d7
      (*(((XmPrimitiveWidgetClass) wc)
Packit b099d7
	 ->primitive_class.border_highlight))(child) ;
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
SpinBLeave(Widget widget, XEvent *event, String *params, Cardinal *num_params)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)widget;
Packit b099d7
  Widget child = (Widget) spinW -> spinBox.textw;
Packit b099d7
Packit b099d7
  /* We only perform this action for POINTER mode */
Packit b099d7
  if (_XmGetFocusPolicy(widget) != XmPOINTER) return;
Packit b099d7
Packit b099d7
  if (child != (Widget) NULL) {
Packit b099d7
    WidgetClass wc = XtClass(child);
Packit b099d7
Packit b099d7
    if (XmIsPrimitive(child)) {
Packit b099d7
      (*(((XmPrimitiveWidgetClass) wc)
Packit b099d7
	 ->primitive_class.border_unhighlight))(child) ;
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBArm
Packit b099d7
 *	Action for BSelect Down.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
SpinBArm(Widget armWidget, 
Packit b099d7
	 XEvent *armEvent, 
Packit b099d7
	 String *armParams,	/* unused */
Packit b099d7
	 Cardinal *armCount)	/* unused */
Packit b099d7
{
Packit b099d7
  if (armEvent->type == ButtonPress)
Packit b099d7
  {
Packit b099d7
    if (ArrowWasHit(armWidget, XmARROW_UP, armEvent))
Packit b099d7
      SpinBAction(armWidget, XmARROW_UP);
Packit b099d7
    else if (ArrowWasHit(armWidget, XmARROW_DOWN, armEvent))
Packit b099d7
      SpinBAction(armWidget, XmARROW_DOWN);
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBDisarm
Packit b099d7
 *	Action for BSelect Up.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
SpinBDisarm(Widget   disarmWidget, 
Packit b099d7
	    XEvent   *disarmEvent,
Packit b099d7
	    String   *disarmParams, /* unused */
Packit b099d7
	    Cardinal *disarmCount) /* unused */
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)disarmWidget;
Packit b099d7
  
Packit b099d7
  if (spinW->spinBox.up_arrow_pressed || spinW->spinBox.down_arrow_pressed)
Packit b099d7
    {
Packit b099d7
      if (spinW->spinBox.initial_delay > 0 && spinW->spinBox.repeat_delay > 0)
Packit b099d7
	if (spinW->spinBox.spin_timer)
Packit b099d7
	  XtRemoveTimeOut(spinW->spinBox.spin_timer);
Packit b099d7
      
Packit b099d7
      spinW->spinBox.up_arrow_pressed = False;
Packit b099d7
      spinW->spinBox.down_arrow_pressed = False;
Packit b099d7
      
Packit b099d7
      DrawSpinArrow(disarmWidget, XmARROW_UP);
Packit b099d7
      DrawSpinArrow(disarmWidget, XmARROW_DOWN);
Packit b099d7
      
Packit b099d7
      if (spinW->spinBox.make_change)
Packit b099d7
	{
Packit b099d7
	  if (spinW->spinBox.last_hit == XmARROW_UP)
Packit b099d7
	    ArrowSpinUp(disarmWidget, disarmEvent);
Packit b099d7
	  else if (spinW->spinBox.last_hit == XmARROW_DOWN)
Packit b099d7
	    ArrowSpinDown(disarmWidget, disarmEvent);
Packit b099d7
	}
Packit b099d7
      
Packit b099d7
      ArrowCallback(disarmWidget, disarmEvent, XmCR_OK);
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  spinW->spinBox.make_change = False;
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBFirst
Packit b099d7
 *	Action for BeginData Key.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
SpinBFirst(Widget   firstWidget, 
Packit b099d7
	   XEvent   *firstEvent, 
Packit b099d7
	   String   *firstParams, /* unused */
Packit b099d7
	   Cardinal *firstCount) /* unused */
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint spinC;
Packit b099d7
  XmSpinBoxWidget	  spinW = (XmSpinBoxWidget)firstWidget;
Packit b099d7
  Widget		  child;
Packit b099d7
  int		  savePosition;
Packit b099d7
  
Packit b099d7
  child = XtWindowToWidget(XtDisplay(firstWidget), firstEvent->xany.window);
Packit b099d7
  
Packit b099d7
  child = spinW->spinBox.textw;
Packit b099d7
  
Packit b099d7
  if (WidgetIsChild(spinW, child) && DownArrowSensitive(spinW))
Packit b099d7
    {
Packit b099d7
      spinW->spinBox.textw = child;
Packit b099d7
      
Packit b099d7
      spinC = SB_GetConstraintRec(child);
Packit b099d7
      
Packit b099d7
      savePosition = spinC->position;
Packit b099d7
      spinC->position = SB_ChildMinimumPositionValue(spinC);
Packit b099d7
      
Packit b099d7
      if (ArrowVerify((Widget)spinW, firstEvent, XmCR_SPIN_FIRST))
Packit b099d7
	{
Packit b099d7
	  UpdateChildText(spinW->spinBox.textw);
Packit b099d7
	  ArrowCallback((Widget)spinW, firstEvent, XmCR_SPIN_FIRST);
Packit b099d7
	  ArrowCallback((Widget)spinW, firstEvent, XmCR_OK);
Packit b099d7
	}
Packit b099d7
      else
Packit b099d7
	spinC->position = savePosition;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBLast
Packit b099d7
 *	Action for EndOfData Key.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
SpinBLast(Widget lastWidget, 
Packit b099d7
	  XEvent *lastEvent, 
Packit b099d7
	  String *lastParams,	/* unused */
Packit b099d7
	  Cardinal *lastCount)	/* unused */
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint spinC;
Packit b099d7
  XmSpinBoxWidget 	  spinW = (XmSpinBoxWidget)lastWidget;
Packit b099d7
  Widget		  child;
Packit b099d7
  int 		  savePosition;
Packit b099d7
  
Packit b099d7
  child = XtWindowToWidget(XtDisplay(lastWidget), lastEvent->xany.window);
Packit b099d7
  child = spinW->spinBox.textw;
Packit b099d7
  
Packit b099d7
  if (WidgetIsChild(spinW, child) && UpArrowSensitive(spinW))
Packit b099d7
    {
Packit b099d7
      spinW->spinBox.textw = child;
Packit b099d7
      spinC = SB_GetConstraintRec(child);
Packit b099d7
      
Packit b099d7
      savePosition = spinC->position;
Packit b099d7
      spinC->position = SB_ChildMaximumPositionValue(spinC);
Packit b099d7
      
Packit b099d7
      if (ArrowVerify((Widget)spinW, lastEvent, XmCR_SPIN_LAST))
Packit b099d7
	{
Packit b099d7
	  UpdateChildText(spinW->spinBox.textw);
Packit b099d7
	  ArrowCallback((Widget)spinW, lastEvent, XmCR_SPIN_LAST);
Packit b099d7
	  ArrowCallback((Widget)spinW, lastEvent, XmCR_OK);
Packit b099d7
	}
Packit b099d7
      else
Packit b099d7
	spinC->position = savePosition;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBLeft
Packit b099d7
 *	Action for Left Arrow.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
static void
Packit b099d7
SpinBLeft(Widget   leftWidget, XEvent   *leftEvent,
Packit b099d7
	  String   *leftParams, Cardinal *leftCount)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)leftWidget;
Packit b099d7
  
Packit b099d7
  if (LayoutIsRtoLM(spinW))
Packit b099d7
    SpinBNext(leftWidget, leftEvent, leftParams, leftCount);
Packit b099d7
  else
Packit b099d7
    SpinBPrior(leftWidget, leftEvent, leftParams, leftCount);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBNext
Packit b099d7
 *	Action for UpArrow Key.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
SpinBNext(Widget nextWidget, 
Packit b099d7
	  XEvent *nextEvent,	/* unused */
Packit b099d7
	  String *nextParams,	/* unused */
Packit b099d7
	  Cardinal *nextCount)	/* unused */
Packit b099d7
{
Packit b099d7
  SpinBAction(nextWidget, XmARROW_UP);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBPrior
Packit b099d7
 *	Action for DownArrow Key.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
SpinBPrior(Widget   priorWidget, 
Packit b099d7
	   XEvent   *priorEvent, /* unused */
Packit b099d7
	   String   *priorParams, /* unused */
Packit b099d7
	   Cardinal *priorCount ) /* unused */
Packit b099d7
{
Packit b099d7
  SpinBAction(priorWidget, XmARROW_DOWN);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBRight
Packit b099d7
 *	Action for RightArrow Key.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
SpinBRight(Widget   rightWidget, XEvent   *rightEvent,
Packit b099d7
	   String   *rightParams, Cardinal *rightCount)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)rightWidget;
Packit b099d7
  
Packit b099d7
  if (LayoutIsRtoLM(spinW))
Packit b099d7
    SpinBPrior(rightWidget, rightEvent, rightParams, rightCount);
Packit b099d7
  else
Packit b099d7
    SpinBNext(rightWidget, rightEvent, rightParams, rightCount);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 **
Packit b099d7
 ***			OTHER FUNCTIONS
Packit b099d7
 **
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 *  ClearArrows
Packit b099d7
 *	Erase Exisiting Arrows
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
ClearArrows(Widget clearW)
Packit b099d7
{
Packit b099d7
  XClearArea(XtDisplay(clearW), XtWindow(clearW), 0, 0, 0, 0, False);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * UpArrowSensitive
Packit b099d7
 *   Returns sensitive/insensitive for arrow.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static Boolean
Packit b099d7
UpArrowSensitive(XmSpinBoxWidget spinW)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint spinC;
Packit b099d7
  unsigned char upState;
Packit b099d7
Packit b099d7
  if (XtIsSensitive((Widget) spinW) != True)
Packit b099d7
    upState = (unsigned char)XmARROWS_INSENSITIVE;
Packit b099d7
  else if (SB_ChildCount(spinW) && SB_WithChild(spinW))
Packit b099d7
    {
Packit b099d7
      spinC = SB_GetConstraintRec(spinW->spinBox.textw);
Packit b099d7
      
Packit b099d7
      upState = spinC->arrow_sensitivity;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    upState = (unsigned char)XmARROWS_DEFAULT_SENSITIVITY;
Packit b099d7
  
Packit b099d7
  if (upState == (unsigned char)XmARROWS_DEFAULT_SENSITIVITY)
Packit b099d7
    upState = spinW->spinBox.default_arrow_sensitivity;
Packit b099d7
Packit b099d7
  return(upState & (unsigned char)XmARROWS_INCREMENT_SENSITIVE);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * DownArrowSensitive
Packit b099d7
 *   Returns sensitive/insensitive for arrow.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static Boolean
Packit b099d7
DownArrowSensitive(XmSpinBoxWidget spinW)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint spinC;
Packit b099d7
  unsigned char	  downState;
Packit b099d7
  
Packit b099d7
  if (XtIsSensitive((Widget) spinW) != True)
Packit b099d7
    downState = (unsigned char)XmARROWS_INSENSITIVE;
Packit b099d7
  else if (SB_ChildCount(spinW) && SB_WithChild(spinW))
Packit b099d7
    {
Packit b099d7
      spinC = SB_GetConstraintRec(spinW->spinBox.textw);
Packit b099d7
      
Packit b099d7
      downState = spinC->arrow_sensitivity;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    downState = (unsigned char)XmARROWS_DEFAULT_SENSITIVITY;
Packit b099d7
  
Packit b099d7
  if (downState == (unsigned char)XmARROWS_DEFAULT_SENSITIVITY)
Packit b099d7
    downState = spinW->spinBox.default_arrow_sensitivity;
Packit b099d7
  
Packit b099d7
  return(downState & (unsigned char)XmARROWS_DECREMENT_SENSITIVE);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * NumericChildCount
Packit b099d7
 *	Return Number of Numeric Children.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static int
Packit b099d7
NumericChildCount(XmSpinBoxWidget spinW)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint  spinC;
Packit b099d7
  int		   i;
Packit b099d7
  int		   childCount;
Packit b099d7
  
Packit b099d7
  childCount = 0;
Packit b099d7
  
Packit b099d7
  if (SB_WithChild(spinW))
Packit b099d7
    for (i = 0; i < SB_ChildCount(spinW); i++)
Packit b099d7
      {
Packit b099d7
	spinC = SB_GetConstraintRec(spinW->composite.children[i]);
Packit b099d7
	
Packit b099d7
	if (SB_ChildIsNumeric(spinC))
Packit b099d7
	  childCount++;
Packit b099d7
      }
Packit b099d7
  
Packit b099d7
  return(childCount);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * WidgetIsChild
Packit b099d7
 *	Return True if Widget is SpinBox Child
Packit b099d7
 *****************************************************************************/
Packit b099d7
static Boolean
Packit b099d7
WidgetIsChild(XmSpinBoxWidget spinW, Widget child)
Packit b099d7
{
Packit b099d7
  Boolean childFlag;
Packit b099d7
  int     i;
Packit b099d7
  
Packit b099d7
  childFlag = False;
Packit b099d7
  
Packit b099d7
  if (SB_WithChild(spinW))
Packit b099d7
    for (i = 0; i < SB_ChildCount(spinW); i++)
Packit b099d7
      if (spinW->composite.children[i] == child)
Packit b099d7
	{
Packit b099d7
	  childFlag = True;
Packit b099d7
	  break;
Packit b099d7
	}
Packit b099d7
  
Packit b099d7
  return(childFlag);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 *  ChildIsTraversable
Packit b099d7
 *	Return True if XmNtraversalOn is set for child.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static Boolean
Packit b099d7
ChildIsTraversable(Widget w)
Packit b099d7
{
Packit b099d7
  Boolean traverseFlag;
Packit b099d7
  Arg	  argList[2];
Packit b099d7
  int	  n = 0;
Packit b099d7
Packit b099d7
  XtSetArg(argList[n], XmNtraversalOn, &traverseFlag); n++;
Packit b099d7
  XtGetValues(w, argList, n);
Packit b099d7
Packit b099d7
  return(traverseFlag);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 *  GetArrowDirection
Packit b099d7
 *	Returns the direction in which the arrow should be drawn
Packit b099d7
 *
Packit b099d7
 *	widget	- the spin box widget whose arrows are being drawn.
Packit b099d7
 *	spinDir - the direction the arrow should cause the spinbox to spin.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static int
Packit b099d7
GetArrowDirection(Widget w, int spinDir)
Packit b099d7
{
Packit b099d7
  int arrowDirection;
Packit b099d7
  int downDirection;
Packit b099d7
  int upDirection;
Packit b099d7
  int isRtoL;
Packit b099d7
Packit b099d7
  isRtoL = (int) LayoutIsRtoLM(w);
Packit b099d7
Packit b099d7
  if (SB_GetArrowOrientation(w) == (unsigned char) XmARROWS_VERTICAL)
Packit b099d7
    {
Packit b099d7
      upDirection = XmARROW_UP;
Packit b099d7
      downDirection = XmARROW_DOWN;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      if (isRtoL)
Packit b099d7
	{
Packit b099d7
	  upDirection   = XmARROW_LEFT;
Packit b099d7
	  downDirection = XmARROW_RIGHT;
Packit b099d7
        }
Packit b099d7
      else
Packit b099d7
	{
Packit b099d7
	  upDirection   = XmARROW_RIGHT;
Packit b099d7
	  downDirection = XmARROW_LEFT;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
  if (spinDir == XmARROW_UP)
Packit b099d7
	arrowDirection = upDirection;
Packit b099d7
  else
Packit b099d7
	arrowDirection = downDirection;
Packit b099d7
Packit b099d7
  return(arrowDirection);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * LayoutSpinBox
Packit b099d7
 *	Position Children and Arrows.
Packit b099d7
 * 
Packit b099d7
 * The ideal layout of the children and arrows have the centerline of
Packit b099d7
 * the arrow layout running through the center of the median child
Packit b099d7
 * position.  The median child position is roughly at the center of the
Packit b099d7
 * widget,  modified by the baseline positions.
Packit b099d7
 * 
Packit b099d7
 * Degradation behavior will first sacrifice the margins if the widget
Packit b099d7
 * isn't given enough room.  Following this will be the spacing between
Packit b099d7
 * widgets,  then finally the children will be shrunk (although the arrows
Packit b099d7
 * will not be).
Packit b099d7
 * 
Packit b099d7
 * At beta,  this code will use the approximation of the centerline
Packit b099d7
 * of the widget for the center of the child position and will not
Packit b099d7
 * perform the widget shrinking part of the graceful degradation of
Packit b099d7
 * layout.
Packit b099d7
 * 
Packit b099d7
 * At final,  this should be updated.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
typedef XmSpinBoxRec MySpinBoxRec;
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
LayoutSpinBox(Widget w, 
Packit b099d7
	      XtWidgetGeometry *spinG, 
Packit b099d7
	      Widget child)	/* unused */
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget) w;
Packit b099d7
  MySpinBoxRec  *myW = (MySpinBoxRec *) w;
Packit b099d7
  int		arrowLayout;
Packit b099d7
  int		arrowSize;
Packit b099d7
  int		i;
Packit b099d7
Packit b099d7
  int		marginX, marginY;
Packit b099d7
  int		numArrowsX, numArrowsY;
Packit b099d7
  int		spacingX, spacingY;
Packit b099d7
  int		posX, posY;
Packit b099d7
  int		Xposition, Xmargin;
Packit b099d7
Packit b099d7
  /* May need to update this if stacked arrows are put back */
Packit b099d7
  Position	upX =0 ;
Packit b099d7
  Position	downX  = 0;
Packit b099d7
Packit b099d7
  arrowLayout = (int) spinW->spinBox.arrow_layout;
Packit b099d7
  arrowSize = spinW->spinBox.arrow_size;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Figure the starting position of the arrows and children
Packit b099d7
   * in the X direction:
Packit b099d7
   *
Packit b099d7
   *	1.  If there is enough room for our ideal width, then use the
Packit b099d7
   *	    .margin_width and .spacing resources to arrange the SpinBox.
Packit b099d7
   *    2.  If not enough room, give up the .margin_width spacing.
Packit b099d7
   *	3.  If still not enough room, shrink the spacing between
Packit b099d7
   *	    subwidgets.
Packit b099d7
   */
Packit b099d7
  spacingX = spinW->spinBox.spacing;
Packit b099d7
  marginX = spinW->spinBox.margin_width + SB_ShadowPixels(spinW);
Packit b099d7
  numArrowsX = SB_NumArrowsWide(spinW);
Packit b099d7
  if (spinW->spinBox.ideal_width > spinG->width)
Packit b099d7
    {
Packit b099d7
      int requiredWidth = spinW->spinBox.ideal_width -
Packit b099d7
		          (2 * spinW->spinBox.margin_width);
Packit b099d7
Packit b099d7
      marginX = 0;
Packit b099d7
      if (requiredWidth > spinG->width)
Packit b099d7
	{
Packit b099d7
          int spacesX = SB_ChildCount(spinW) + numArrowsX;
Packit b099d7
	  int deltaX = requiredWidth - spinG->width;
Packit b099d7
Packit b099d7
	  spacingX = ((spacesX * spinW->spinBox.spacing) - deltaX) / spacesX;
Packit b099d7
	  if (spacingX < 0)
Packit b099d7
	    spacingX = 0;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  /*
Packit b099d7
   * Figure the starting position of the arrows and children
Packit b099d7
   * in the Y direction.  Use the same algorithm as for the 
Packit b099d7
   * X direction with the following addition:
Packit b099d7
   *
Packit b099d7
   *	1a. If there is more room than required for our ideal width,
Packit b099d7
   *        expand the margins 'til the arrows are centered vertically.
Packit b099d7
   */
Packit b099d7
  spacingY = spinW->spinBox.spacing;
Packit b099d7
  numArrowsY = SB_NumArrowsHigh(spinW);
Packit b099d7
  if (spinW->spinBox.ideal_height > spinG->height)
Packit b099d7
    {
Packit b099d7
      int requiredHeight = spinW->spinBox.ideal_height -
Packit b099d7
		          (2 * spinW->spinBox.margin_height);
Packit b099d7
Packit b099d7
      marginY = 0;
Packit b099d7
      if (requiredHeight > spinG->height)
Packit b099d7
	{
Packit b099d7
	  int deltaY = requiredHeight - spinG->width;
Packit b099d7
Packit b099d7
	  spacingY =
Packit b099d7
	    ((numArrowsY * spinW->spinBox.spacing) - deltaY) / numArrowsY;
Packit b099d7
	  if (spacingY < 0)
Packit b099d7
	    spacingY = 0;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      int arrowsSpace = ((numArrowsY * arrowSize) +
Packit b099d7
			 ((numArrowsY - 1) * spinW->spinBox.spacing));
Packit b099d7
      marginY = (spinG->height - arrowsSpace) / 2;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  /*
Packit b099d7
   * Get the starting position of the first SpinBox child in the X direction.
Packit b099d7
   */
Packit b099d7
  posX = marginX;
Packit b099d7
  switch(arrowLayout)
Packit b099d7
    {
Packit b099d7
      case XmARROWS_BEGINNING:
Packit b099d7
      case XmARROWS_FLAT_BEGINNING:
Packit b099d7
	if (!LayoutIsRtoLM(w))
Packit b099d7
          posX += (numArrowsX * (arrowSize + spacingX));
Packit b099d7
        break;
Packit b099d7
      case XmARROWS_SPLIT:
Packit b099d7
        posX += ((numArrowsX / 2) * (arrowSize + spacingX));
Packit b099d7
        break;
Packit b099d7
      case XmARROWS_END:
Packit b099d7
      case XmARROWS_FLAT_END:
Packit b099d7
	if (LayoutIsRtoLM(w))
Packit b099d7
          posX += (numArrowsX * (arrowSize + spacingX));
Packit b099d7
        break;
Packit b099d7
      default:
Packit b099d7
        break;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  /*
Packit b099d7
   * Now position the managed children of the SpinBox.
Packit b099d7
   */
Packit b099d7
  for (i = 0; i < SB_ChildCount(spinW); i++)
Packit b099d7
    {
Packit b099d7
      Widget	childW = spinW->composite.children[i];
Packit b099d7
      
Packit b099d7
      if (w != childW && XtIsManaged(childW))
Packit b099d7
	{
Packit b099d7
	  posY = (spinG->height - XtHeight(childW)) / 2;
Packit b099d7
	  XmeConfigureObject(childW, posX, posY,
Packit b099d7
			     ((Widget)childW)->core.width,	
Packit b099d7
			     ((Widget)childW)->core.height,
Packit b099d7
			     ((Widget)childW)->core.border_width
Packit b099d7
			     );
Packit b099d7
	  
Packit b099d7
	  posX += XtWidth(childW) + spacingX;
Packit b099d7
	} 
Packit b099d7
    } 
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Save the dimensions of the up and down arrows
Packit b099d7
   * for use by the arrow drawing procedure.
Packit b099d7
   */
Packit b099d7
  spinW->spinBox.up_arrow_rect.width =
Packit b099d7
    spinW->spinBox.up_arrow_rect.height = 
Packit b099d7
      spinW->spinBox.down_arrow_rect.width = 
Packit b099d7
	spinW->spinBox.down_arrow_rect.height = arrowSize;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Save the X and Y positions of the up and down arrows
Packit b099d7
   * for use by the arrow drawing procedure.
Packit b099d7
   * NOTE:  The window origin for X windows is the upper left-hand
Packit b099d7
   *        corner.  Therefore, the .up_arrow_rect.y gets the smaller
Packit b099d7
   *	    Y component.
Packit b099d7
   */
Packit b099d7
  spinW->spinBox.up_arrow_rect.y = marginY;
Packit b099d7
  spinW->spinBox.down_arrow_rect.y =
Packit b099d7
    marginY + ((numArrowsY - 1) * (spacingY + arrowSize));
Packit b099d7
  
Packit b099d7
  if (LayoutIsRtoLM(w)) 
Packit b099d7
    {
Packit b099d7
      Xposition = marginX;
Packit b099d7
      Xmargin   = posX;
Packit b099d7
    }
Packit b099d7
  else 
Packit b099d7
    {
Packit b099d7
      Xposition = posX;
Packit b099d7
      Xmargin   = marginX;
Packit b099d7
    }
Packit b099d7
  switch(arrowLayout)
Packit b099d7
    {
Packit b099d7
      case XmARROWS_BEGINNING:
Packit b099d7
	downX = upX = Xmargin;
Packit b099d7
	break;
Packit b099d7
      case XmARROWS_FLAT_BEGINNING:
Packit b099d7
	if(LayoutIsRtoLM(w))
Packit b099d7
	  {
Packit b099d7
	    upX   = Xmargin;
Packit b099d7
	    downX = Xmargin + spacingX + arrowSize;
Packit b099d7
	  }
Packit b099d7
	else
Packit b099d7
	  {
Packit b099d7
	    upX   = Xmargin + spacingX + arrowSize;
Packit b099d7
	    downX = Xmargin;	
Packit b099d7
	  }
Packit b099d7
	break;
Packit b099d7
      case XmARROWS_SPLIT:
Packit b099d7
	upX   = Xposition;
Packit b099d7
	downX = Xmargin;
Packit b099d7
	break;
Packit b099d7
      case XmARROWS_END:
Packit b099d7
	downX = upX = Xposition;
Packit b099d7
	break;
Packit b099d7
      case XmARROWS_FLAT_END:
Packit b099d7
	if(LayoutIsRtoLM(w))
Packit b099d7
	  {
Packit b099d7
	    upX   = Xposition;
Packit b099d7
	    downX = Xposition + spacingX + arrowSize;
Packit b099d7
	  }
Packit b099d7
	else
Packit b099d7
	  {
Packit b099d7
	    upX   = Xposition + spacingX + arrowSize;
Packit b099d7
	    downX = Xposition;
Packit b099d7
	  }
Packit b099d7
	break;
Packit b099d7
      default:
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    spinW->spinBox.up_arrow_rect.x = upX;
Packit b099d7
    spinW->spinBox.down_arrow_rect.x = downX;
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * NumToString
Packit b099d7
 *   Convert Number to String to Be Displayed in Child
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
NumToString(char **buffer, int min, int max, int decimal, int value)
Packit b099d7
{
Packit b099d7
  float result;
Packit b099d7
  int   digits;
Packit b099d7
  int   test;
Packit b099d7
  
Packit b099d7
  digits = 0;
Packit b099d7
Packit b099d7
  if (decimal < 1)
Packit b099d7
    decimal = 0;
Packit b099d7
  
Packit b099d7
  /*
Packit b099d7
   * BINARY COMPATIBILITY with DTSPINBOX
Packit b099d7
   *
Packit b099d7
   * This causes spaces to be insterted in the string passed back in
Packit b099d7
   * buffer.  DtSpinBox does not do this so we have to alter the
Packit b099d7
   * behavior.
Packit b099d7
   *
Packit b099d7
   * test = MAX((int)abs(min), (int)abs(max));
Packit b099d7
   */
Packit b099d7
  if (value == 0)
Packit b099d7
  {
Packit b099d7
    digits = 1;
Packit b099d7
    if (decimal > 0)
Packit b099d7
      digits += decimal + 1;
Packit b099d7
  }
Packit b099d7
  else
Packit b099d7
  {
Packit b099d7
    test = abs(value);
Packit b099d7
Packit b099d7
    while (test > 0)
Packit b099d7
    {
Packit b099d7
      test = test / 10;
Packit b099d7
      digits++;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (decimal > 0)
Packit b099d7
      digits = (digits <= decimal) ? decimal + 2 : digits + 1;
Packit b099d7
Packit b099d7
    if (value < 0)
Packit b099d7
      digits++;
Packit b099d7
  }
Packit b099d7
Packit b099d7
  test = decimal;
Packit b099d7
  result = (float)value;
Packit b099d7
  while (test > 0)
Packit b099d7
  {
Packit b099d7
    test--;
Packit b099d7
    result/=10.0;
Packit b099d7
  }
Packit b099d7
Packit b099d7
  *buffer = (char *)XtMalloc((digits + 1) * sizeof(char));
Packit b099d7
  if (*buffer)
Packit b099d7
  {
Packit b099d7
#ifdef __osf__
Packit b099d7
    if (decimal == 0)
Packit b099d7
      sprintf(*buffer, "%*.0f", digits, result);
Packit b099d7
    else
Packit b099d7
#endif
Packit b099d7
      sprintf(*buffer, "%*.*f", digits, decimal, result);
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * DrawSpinArrow
Packit b099d7
 *	Draw a Left or Right Arrow.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
DrawSpinArrow(Widget arrowWidget, int arrowFlag)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget	spinW = (XmSpinBoxWidget)arrowWidget;
Packit b099d7
  Dimension	arrowHeight;
Packit b099d7
  Dimension	arrowWidth;
Packit b099d7
  Position	arrowX;
Packit b099d7
  Position	arrowY;
Packit b099d7
  Boolean	arrowPressed;
Packit b099d7
  int		arrowDirection;
Packit b099d7
  GC		arrowGC;
Packit b099d7
  
Packit b099d7
  if (XtIsRealized((Widget)spinW))
Packit b099d7
    {
Packit b099d7
      arrowPressed = False;
Packit b099d7
      
Packit b099d7
      if (arrowFlag == XmARROW_UP)
Packit b099d7
	{
Packit b099d7
	  arrowX = spinW->spinBox.up_arrow_rect.x;
Packit b099d7
	  arrowY = spinW->spinBox.up_arrow_rect.y;
Packit b099d7
	  arrowWidth = spinW->spinBox.up_arrow_rect.width;
Packit b099d7
	  arrowHeight = spinW->spinBox.up_arrow_rect.height;
Packit b099d7
	  
Packit b099d7
	  if (UpArrowSensitive(spinW))
Packit b099d7
	    {
Packit b099d7
	      arrowGC = spinW->spinBox.arrow_gc;
Packit b099d7
	      arrowPressed = spinW->spinBox.up_arrow_pressed;
Packit b099d7
	    }
Packit b099d7
	  else {
Packit b099d7
	    arrowGC = spinW->spinBox.insensitive_gc;
Packit b099d7
	    XSetClipMask(XtDisplay(arrowWidget), arrowGC, None);
Packit b099d7
	  }
Packit b099d7
	}
Packit b099d7
      else
Packit b099d7
	{
Packit b099d7
	  arrowX = spinW->spinBox.down_arrow_rect.x;
Packit b099d7
	  arrowY = spinW->spinBox.down_arrow_rect.y;
Packit b099d7
	  arrowWidth = spinW->spinBox.down_arrow_rect.width;
Packit b099d7
	  arrowHeight = spinW->spinBox.down_arrow_rect.height;
Packit b099d7
	  
Packit b099d7
	  if (DownArrowSensitive(spinW))
Packit b099d7
	    {
Packit b099d7
	      arrowGC = spinW->spinBox.arrow_gc;
Packit b099d7
	      arrowPressed = spinW->spinBox.down_arrow_pressed;
Packit b099d7
	    }
Packit b099d7
	  else {
Packit b099d7
	    arrowGC = spinW->spinBox.insensitive_gc;
Packit b099d7
	    XSetClipMask(XtDisplay(arrowWidget), arrowGC, None);
Packit b099d7
	  }
Packit b099d7
	}
Packit b099d7
 
Packit b099d7
      arrowWidth  = (arrowWidth  > 1) ? arrowWidth  - 1 : 0;
Packit b099d7
      arrowHeight = (arrowHeight > 1) ? arrowHeight - 1 : 0;
Packit b099d7
      arrowDirection = GetArrowDirection(arrowWidget, arrowFlag);
Packit b099d7
      
Packit b099d7
      XmeDrawArrow(
Packit b099d7
		   XtDisplay(arrowWidget),
Packit b099d7
		   XtWindow(arrowWidget),
Packit b099d7
		   arrowPressed ? spinW->manager.bottom_shadow_GC :
Packit b099d7
		   spinW->manager.top_shadow_GC,
Packit b099d7
		   arrowPressed ? spinW->manager.top_shadow_GC :
Packit b099d7
		   spinW->manager.bottom_shadow_GC,
Packit b099d7
		   arrowGC,
Packit b099d7
		   arrowX,
Packit b099d7
		   arrowY,
Packit b099d7
		   arrowWidth,
Packit b099d7
		   arrowHeight,
Packit b099d7
		   spinW->spinBox.detail_shadow_thickness,
Packit b099d7
		   arrowDirection
Packit b099d7
		   );
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinTimeOut
Packit b099d7
 *	Add TimeOut for Spinning.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
SpinTimeOut(Widget w, int spinDelay)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)w;
Packit b099d7
  
Packit b099d7
  if (spinW->spinBox.initial_delay > 0 && spinW->spinBox.repeat_delay > 0)
Packit b099d7
    spinW->spinBox.spin_timer = XtAppAddTimeOut(
Packit b099d7
					       XtWidgetToApplicationContext(w),
Packit b099d7
					       spinDelay,
Packit b099d7
					       SpinBArrow,
Packit b099d7
					       (XtPointer)w
Packit b099d7
					       );
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * UpdateChildText()
Packit b099d7
 *   Updates the text widget with the current selection, by position.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
UpdateChildText(Widget textW)
Packit b099d7
{
Packit b099d7
  XmAccessTextualTrait  textT;
Packit b099d7
  XmSpinBoxConstraint   textC;
Packit b099d7
  char                 *buffer = NULL;
Packit b099d7
  
Packit b099d7
  textT = (XmAccessTextualTrait)
Packit b099d7
    XmeTraitGet((XtPointer)XtClass(textW), XmQTaccessTextual);
Packit b099d7
  
Packit b099d7
  if (textT == NULL)
Packit b099d7
    return;
Packit b099d7
  
Packit b099d7
  if (textW)
Packit b099d7
    {
Packit b099d7
      textC = SB_GetConstraintRec(textW);
Packit b099d7
      
Packit b099d7
      if (SB_ChildIsNumeric(textC))
Packit b099d7
	{
Packit b099d7
	  NumToString(&buffer,
Packit b099d7
		      textC->minimum_value,
Packit b099d7
		      textC->maximum_value,
Packit b099d7
		      textC->decimal_points,
Packit b099d7
		      textC->position );
Packit b099d7
	  
Packit b099d7
	  textT->setValue(textW, (XtPointer) buffer, XmFORMAT_MBYTE);
Packit b099d7
Packit b099d7
	  if (buffer)
Packit b099d7
	    XtFree(buffer);
Packit b099d7
	}
Packit b099d7
      else
Packit b099d7
	if (textC->values != NULL && textC->num_values)
Packit b099d7
	  {
Packit b099d7
	    textT->setValue(textW,
Packit b099d7
			    (XtPointer)
Packit b099d7
			    textC->values[textC->position],
Packit b099d7
			    XmFORMAT_XmSTRING);
Packit b099d7
	  }
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * ArrowWasHit
Packit b099d7
 *  Returns True if Pointer was Over Arrow When Bselect was Issued.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static Boolean
Packit b099d7
ArrowWasHit(Widget arrowW, int arrowType, XEvent *arrowEvent)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget  spinW;
Packit b099d7
  XButtonEvent *hitEvent;
Packit b099d7
  XRectangle   arrowArea;
Packit b099d7
  int          arrowHit;
Packit b099d7
  int	     hitX;
Packit b099d7
  int	     hitY;
Packit b099d7
  
Packit b099d7
  arrowHit = False;
Packit b099d7
  
Packit b099d7
  if (arrowEvent->type == ButtonPress)
Packit b099d7
    {
Packit b099d7
      spinW = (XmSpinBoxWidget)arrowW;
Packit b099d7
      
Packit b099d7
      hitEvent = (XButtonEvent *)arrowEvent;
Packit b099d7
      
Packit b099d7
      if (arrowType == XmARROW_UP)
Packit b099d7
	arrowArea = spinW->spinBox.up_arrow_rect;
Packit b099d7
      else
Packit b099d7
	arrowArea = spinW->spinBox.down_arrow_rect;
Packit b099d7
      
Packit b099d7
      hitX = hitEvent->x - arrowArea.x;		/* Normalize Event Position */
Packit b099d7
      hitY = hitEvent->y - arrowArea.y;
Packit b099d7
      
Packit b099d7
      if (hitX < 0 || hitX > arrowArea.width
Packit b099d7
	  ||  hitY < 0 || hitY > arrowArea.height)
Packit b099d7
	arrowHit = False;
Packit b099d7
      else
Packit b099d7
	arrowHit = True;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  return(arrowHit);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBArrow
Packit b099d7
 *	Function Called by TimeOut.
Packit b099d7
 *****************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
SpinBArrow(XtPointer spinData, 
Packit b099d7
	   XtIntervalId *spinInterval) /* unused */
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW = (XmSpinBoxWidget)spinData;
Packit b099d7
  
Packit b099d7
  spinW->spinBox.make_change = False;
Packit b099d7
  
Packit b099d7
  if (spinW->spinBox.up_arrow_pressed)
Packit b099d7
    {
Packit b099d7
      if (UpArrowSensitive(spinW))
Packit b099d7
	{
Packit b099d7
	  SpinTimeOut((Widget) spinData, spinW->spinBox.repeat_delay);
Packit b099d7
	  DrawSpinArrow((Widget) spinData, XmARROW_UP);
Packit b099d7
	  ArrowSpinUp((Widget) spinData, (XEvent *) NULL);
Packit b099d7
	}
Packit b099d7
      else
Packit b099d7
	{
Packit b099d7
	  spinW->spinBox.up_arrow_pressed = False; 
Packit b099d7
	  
Packit b099d7
	  DrawSpinArrow((Widget) spinData, XmARROW_UP);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
  else if (spinW->spinBox.down_arrow_pressed)
Packit b099d7
    {
Packit b099d7
      if (DownArrowSensitive(spinW))
Packit b099d7
	{
Packit b099d7
	  SpinTimeOut((Widget) spinData, spinW->spinBox.repeat_delay);
Packit b099d7
	  DrawSpinArrow((Widget) spinData, XmARROW_DOWN);
Packit b099d7
	  ArrowSpinDown((Widget) spinData, (XEvent *) NULL);
Packit b099d7
	}
Packit b099d7
      else
Packit b099d7
	{
Packit b099d7
	  spinW->spinBox.down_arrow_pressed = False; 
Packit b099d7
	  
Packit b099d7
	  DrawSpinArrow((Widget)spinData, XmARROW_DOWN);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinBAction
Packit b099d7
 *	This Function Does the Work.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
SpinBAction(Widget   actionWidget, short    arrowHit)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget	spinW = (XmSpinBoxWidget)actionWidget;
Packit b099d7
  Boolean		upHit;
Packit b099d7
  Boolean		downHit;
Packit b099d7
  
Packit b099d7
  upHit = (arrowHit == XmARROW_UP);
Packit b099d7
  downHit = (arrowHit == XmARROW_DOWN);
Packit b099d7
  
Packit b099d7
  if ((upHit && UpArrowSensitive(spinW))
Packit b099d7
      || (downHit && DownArrowSensitive(spinW)))
Packit b099d7
    {
Packit b099d7
      spinW->spinBox.make_change = True;
Packit b099d7
      spinW->spinBox.last_hit = arrowHit;
Packit b099d7
      
Packit b099d7
      if (SB_ChildCount(spinW) && SB_WithChild(spinW))
Packit b099d7
	XmProcessTraversal(spinW->spinBox.textw, XmTRAVERSE_CURRENT);
Packit b099d7
      
Packit b099d7
      if (upHit)
Packit b099d7
	{
Packit b099d7
	  spinW->spinBox.up_arrow_pressed = True;
Packit b099d7
	  DrawSpinArrow(actionWidget, XmARROW_UP);
Packit b099d7
	}
Packit b099d7
      else if (downHit)
Packit b099d7
	{
Packit b099d7
	  spinW->spinBox.down_arrow_pressed = True;
Packit b099d7
	  DrawSpinArrow(actionWidget, XmARROW_DOWN);
Packit b099d7
	}
Packit b099d7
      
Packit b099d7
      if (spinW->spinBox.initial_delay)
Packit b099d7
	SpinTimeOut(actionWidget, spinW->spinBox.initial_delay);
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    spinW->spinBox.make_change = False;
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * FireCallbacks()
Packit b099d7
 *	Setup Callback(s) for SpinBox.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
FireCallbacks(XmSpinBoxCallbackStruct	*spinBoxCallData,
Packit b099d7
	      XtCallbackList	callbackList,
Packit b099d7
     	      Widget		arrowWidget,
Packit b099d7
     	      XEvent		*arrowEvent,
Packit b099d7
     	      int		arrowReason)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint		spinC;
Packit b099d7
  XmSpinBoxWidget               spinW;
Packit b099d7
  XmSpinBoxWidgetClass          spinWC;
Packit b099d7
  XmString			xmString = (XmString) NULL;
Packit b099d7
  
Packit b099d7
  spinW = (XmSpinBoxWidget) arrowWidget;
Packit b099d7
  spinWC = (XmSpinBoxWidgetClass) XtClass(arrowWidget);
Packit b099d7
  
Packit b099d7
  spinBoxCallData->reason = arrowReason;
Packit b099d7
  spinBoxCallData->event  = arrowEvent;
Packit b099d7
  spinBoxCallData->widget =
Packit b099d7
	(spinWC->spinBox_class.get_callback_widget) ?
Packit b099d7
	(Widget) (*(spinWC->spinBox_class.get_callback_widget))((Widget)spinW) :
Packit b099d7
	(Widget) spinW->spinBox.textw;
Packit b099d7
Packit b099d7
  if (SB_ChildCount(spinW) && SB_WithChild(spinW))
Packit b099d7
    {
Packit b099d7
      XtArgVal position;
Packit b099d7
      spinC = SB_GetConstraintRec(spinW->spinBox.textw);
Packit b099d7
      
Packit b099d7
      spinBoxCallData->doit = True;
Packit b099d7
      position = spinC->position;
Packit b099d7
      GetPositionValue( (Widget) spinW->spinBox.textw,
Packit b099d7
			XtOffset(XmSpinBoxConstraint, position),
Packit b099d7
			&position);
Packit b099d7
      spinBoxCallData->position = position;
Packit b099d7
      if (spinC->sb_child_type == XmSTRING)
Packit b099d7
	{
Packit b099d7
	  if ((spinC->num_values > 0) && (spinC->position < spinC->num_values))
Packit b099d7
	    spinBoxCallData->value  = spinC->values[spinC->position];
Packit b099d7
          else
Packit b099d7
	    spinBoxCallData->value  = NULL;
Packit b099d7
	}
Packit b099d7
      else
Packit b099d7
        {
Packit b099d7
          char	*buffer = (char *) NULL;
Packit b099d7
Packit b099d7
          NumToString(&buffer,
Packit b099d7
		      spinC->minimum_value,
Packit b099d7
		      spinC->maximum_value,
Packit b099d7
		      spinC->decimal_points,
Packit b099d7
		      spinC->position );
Packit b099d7
          if (buffer)
Packit b099d7
            xmString = XmStringCreateLocalized(buffer);
Packit b099d7
Packit b099d7
	  spinBoxCallData->value = xmString;
Packit b099d7
Packit b099d7
          if (buffer)
Packit b099d7
	    XtFree(buffer);
Packit b099d7
        }
Packit b099d7
      
Packit b099d7
      if (arrowReason == XmCR_SPIN_NEXT
Packit b099d7
	  ||  arrowReason == XmCR_SPIN_PRIOR)
Packit b099d7
	spinBoxCallData->crossed_boundary = spinW->spinBox.boundary;
Packit b099d7
      else
Packit b099d7
	spinBoxCallData->crossed_boundary = False;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      spinBoxCallData->doit = False;
Packit b099d7
      spinBoxCallData->position = 0;
Packit b099d7
      spinBoxCallData->value  = NULL;
Packit b099d7
      spinBoxCallData->crossed_boundary = False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /* inform the application of the change */
Packit b099d7
  XtCallCallbackList((Widget) spinW, callbackList, (XtPointer) spinBoxCallData);
Packit b099d7
Packit b099d7
  /* Clean up the temporary XmString created to hold the XmNUMERIC value. */
Packit b099d7
  if (xmString != (XmString) NULL)
Packit b099d7
    XmStringFree(xmString);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * ArrowCallback()
Packit b099d7
 *	Setup and Call ValueChanged Callback(s) for SpinBox.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
ArrowCallback(Widget arrowWidget, XEvent *arrowEvent, int arrowReason)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget               spinW = (XmSpinBoxWidget) arrowWidget;
Packit b099d7
  XmSpinBoxCallbackStruct	spinBoxCallData;
Packit b099d7
Packit b099d7
  FireCallbacks(&spinBoxCallData,
Packit b099d7
	        spinW->spinBox.value_changed_cb,
Packit b099d7
	        arrowWidget,
Packit b099d7
	        arrowEvent,
Packit b099d7
	        arrowReason);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * ArrowVerify()
Packit b099d7
 *	Setup and Call ModifyVerify Callback(s) for SpinBox.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static Boolean
Packit b099d7
ArrowVerify(Widget arrowWidget, XEvent *arrowEvent, int arrowReason)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget		spinW = (XmSpinBoxWidget) arrowWidget;
Packit b099d7
  XmSpinBoxCallbackStruct	spinBoxCallData;
Packit b099d7
  
Packit b099d7
  FireCallbacks(&spinBoxCallData,
Packit b099d7
	        spinW->spinBox.modify_verify_cb,
Packit b099d7
	        arrowWidget,
Packit b099d7
	        arrowEvent,
Packit b099d7
	        arrowReason);
Packit b099d7
Packit b099d7
  if (SB_ChildCount(spinW) && SB_WithChild(spinW) && spinBoxCallData.doit)
Packit b099d7
  {
Packit b099d7
    char		*error = (char *) NULL;
Packit b099d7
    XtArgVal		position = spinBoxCallData.position;
Packit b099d7
    int			int_pos;
Packit b099d7
    XmSpinBoxConstraint	spinC = SB_GetConstraintRec(spinW->spinBox.textw);
Packit b099d7
Packit b099d7
    (void) SetPositionValue((Widget) spinW->spinBox.textw,
Packit b099d7
			    XtOffset(XmSpinBoxConstraint, position),
Packit b099d7
			    &position);
Packit b099d7
    int_pos = position;
Packit b099d7
Packit b099d7
    error = ValidatePositionValue(spinC, &int_pos);
Packit b099d7
    if (error)
Packit b099d7
      XmeWarning((Widget) spinW, error);
Packit b099d7
Packit b099d7
    spinC->position = int_pos;
Packit b099d7
  }
Packit b099d7
Packit b099d7
  return(spinBoxCallData.doit);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * ArrowSpinUp()
Packit b099d7
 *	Spin Increment Arrow.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
ArrowSpinUp(Widget w, XEvent *callEvent)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint  spinC;
Packit b099d7
  XmSpinBoxWidget	 spinW;
Packit b099d7
  int              inPosition;
Packit b099d7
  
Packit b099d7
  spinW = (XmSpinBoxWidget)w;
Packit b099d7
  
Packit b099d7
  if (SB_ChildCount(spinW) && SB_WithChild(spinW))
Packit b099d7
    {
Packit b099d7
      spinC = SB_GetConstraintRec(spinW->spinBox.textw);
Packit b099d7
      
Packit b099d7
      inPosition = spinC->position;
Packit b099d7
      spinW->spinBox.boundary = False;
Packit b099d7
      spinC->position += (SB_ChildIsNumeric(spinC) ?
Packit b099d7
			  spinC->increment_value : 1);
Packit b099d7
      
Packit b099d7
      if (spinC->position > SB_ChildMaximumPositionValue(spinC))
Packit b099d7
	{
Packit b099d7
	  if (spinC->wrap)
Packit b099d7
            {
Packit b099d7
              spinW->spinBox.boundary = True;
Packit b099d7
              spinC->position = SB_ChildMinimumPositionValue(spinC);
Packit b099d7
            }
Packit b099d7
          else
Packit b099d7
	    {
Packit b099d7
	      spinC->position = inPosition;
Packit b099d7
	      XBell(XtDisplay(spinW), 0);
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
Packit b099d7
      
Packit b099d7
      /* Update the Text Widget */
Packit b099d7
      if (inPosition != spinC->position)
Packit b099d7
      {
Packit b099d7
	if (ArrowVerify((Widget)spinW, callEvent, XmCR_SPIN_NEXT))
Packit b099d7
	  {
Packit b099d7
	    UpdateChildText(spinW->spinBox.textw);
Packit b099d7
	    ArrowCallback((Widget)spinW, callEvent, XmCR_SPIN_NEXT);
Packit b099d7
	  }
Packit b099d7
	else
Packit b099d7
        {
Packit b099d7
	  spinC->position = inPosition;
Packit b099d7
        }
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    ArrowCallback((Widget)spinW, callEvent, XmCR_SPIN_NEXT);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * ArrowSpinDown
Packit b099d7
 *	Spin Decrement Arrow.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
ArrowSpinDown(Widget w, XEvent *callEvent)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint  spinC;
Packit b099d7
  XmSpinBoxWidget	 spinW;
Packit b099d7
  int              inPosition;
Packit b099d7
  
Packit b099d7
  spinW = (XmSpinBoxWidget)w;
Packit b099d7
  
Packit b099d7
  if (SB_ChildCount(spinW) && SB_WithChild(spinW))
Packit b099d7
    {
Packit b099d7
      spinC = SB_GetConstraintRec(spinW->spinBox.textw);
Packit b099d7
      
Packit b099d7
      inPosition = spinC->position;
Packit b099d7
      spinW->spinBox.boundary = False;
Packit b099d7
      spinC->position -= (SB_ChildIsNumeric(spinC) ?
Packit b099d7
			  spinC->increment_value : 1);
Packit b099d7
      
Packit b099d7
      if (spinC->position < SB_ChildMinimumPositionValue(spinC))
Packit b099d7
	{
Packit b099d7
	  if (spinC->wrap)
Packit b099d7
            {
Packit b099d7
              spinW->spinBox.boundary = True;
Packit b099d7
              spinC->position = SB_ChildMaximumPositionValue(spinC);
Packit b099d7
            }
Packit b099d7
          else
Packit b099d7
	    {
Packit b099d7
	      spinC->position = inPosition;
Packit b099d7
	      XBell(XtDisplay(spinW), 0);
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
      
Packit b099d7
      /* Update the Text Widget */
Packit b099d7
      if (inPosition != spinC->position)
Packit b099d7
      {
Packit b099d7
	if (ArrowVerify((Widget)spinW, callEvent, XmCR_SPIN_PRIOR))
Packit b099d7
	  {
Packit b099d7
	    UpdateChildText(spinW->spinBox.textw);
Packit b099d7
	    ArrowCallback((Widget)spinW, callEvent, XmCR_SPIN_PRIOR);
Packit b099d7
	  }
Packit b099d7
	else
Packit b099d7
        {
Packit b099d7
	  spinC->position = inPosition;
Packit b099d7
        }
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    ArrowCallback((Widget)spinW, callEvent, XmCR_SPIN_PRIOR);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 * GetSpinSize
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
GetSpinSize(Widget w, Dimension *wide, Dimension *high)
Packit b099d7
{
Packit b099d7
  XmSpinBoxWidget spinW;
Packit b099d7
  Dimension	 childHeight;
Packit b099d7
  Dimension	 saveWide;
Packit b099d7
  Dimension	 saveHigh;
Packit b099d7
  Widget	 childW;
Packit b099d7
  int		 i;
Packit b099d7
  int            arrowSize;
Packit b099d7
  int            arrowsWide;
Packit b099d7
  int            arrowsHigh;
Packit b099d7
  int            spacing;
Packit b099d7
  
Packit b099d7
  spinW = (XmSpinBoxWidget)w;
Packit b099d7
  
Packit b099d7
  saveWide = XtWidth(spinW);
Packit b099d7
  saveHigh = XtHeight(spinW);
Packit b099d7
  
Packit b099d7
  XtWidth(spinW) = *wide;
Packit b099d7
  XtHeight(spinW) = *high;
Packit b099d7
  
Packit b099d7
  
Packit b099d7
  arrowSize = spinW->spinBox.arrow_size;
Packit b099d7
  arrowsWide = SB_NumArrowsWide(spinW);
Packit b099d7
  arrowsHigh = SB_NumArrowsHigh(spinW);
Packit b099d7
  spacing = spinW->spinBox.spacing;
Packit b099d7
Packit b099d7
  if (*wide == 0)
Packit b099d7
    {
Packit b099d7
      *wide = arrowsWide * arrowSize;
Packit b099d7
      *wide += (arrowsWide - 1) * spacing;
Packit b099d7
      *wide += 2 * spinW->spinBox.margin_width;
Packit b099d7
      *wide += 2 * SB_ShadowPixels(spinW);
Packit b099d7
      
Packit b099d7
      if (SB_WithChild(spinW))
Packit b099d7
	for (i = 0; i < SB_ChildCount(spinW); i++)
Packit b099d7
	  {
Packit b099d7
	    childW = spinW->composite.children[i];
Packit b099d7
	    
Packit b099d7
	    if (XtIsManaged(childW))
Packit b099d7
	      *wide += XtWidth(childW) + spinW->spinBox.spacing;
Packit b099d7
	  }
Packit b099d7
Packit b099d7
      /* Remember our best width */
Packit b099d7
      spinW->spinBox.ideal_width = *wide;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  if (!*high)
Packit b099d7
    {
Packit b099d7
      *high = arrowsHigh * arrowSize;
Packit b099d7
      *high += (arrowsHigh - 1) * spacing;
Packit b099d7
      *high += 2 * spinW->spinBox.margin_height;
Packit b099d7
Packit b099d7
      if (SB_WithChild(spinW))
Packit b099d7
	for (i = 0; i < SB_ChildCount(spinW); i++)
Packit b099d7
	  {
Packit b099d7
	    childW = spinW->composite.children[i];
Packit b099d7
	    
Packit b099d7
	    if (XtIsManaged(childW))
Packit b099d7
	      {
Packit b099d7
		childHeight = XtHeight(childW);
Packit b099d7
		*high = MAX(*high, childHeight);
Packit b099d7
	      }
Packit b099d7
	  }
Packit b099d7
Packit b099d7
      /* Factor in the shadow thickness and remember our best size */
Packit b099d7
      *high += 2 * SB_ShadowPixels(spinW);
Packit b099d7
      spinW->spinBox.ideal_height = *high;
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  if (*wide == 0)
Packit b099d7
    *wide = 1;
Packit b099d7
  
Packit b099d7
  if (*high == 0)
Packit b099d7
    *high = 1;
Packit b099d7
  
Packit b099d7
  XtWidth(spinW) = saveWide;
Packit b099d7
  XtHeight(spinW) = saveHigh;
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinNChangeMoveCB
Packit b099d7
 *	Navigator Trait Change/Move Callback.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
SpinNChangeMoveCB(Widget nav, XtCallbackProc moveCB,
Packit b099d7
		  XtPointer closure, Boolean setunset)
Packit b099d7
{
Packit b099d7
  if (setunset)
Packit b099d7
    XtAddCallback (nav, XmNvalueChangedCallback, moveCB, closure);
Packit b099d7
  else
Packit b099d7
    XtRemoveCallback (nav, XmNvalueChangedCallback, moveCB, closure);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinNSetValue
Packit b099d7
 *	Navigator SetValue Function.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
SpinNSetValue(Widget nav, XmNavigatorData nav_data, Boolean notify)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint spinC;
Packit b099d7
  XmSpinBoxWidget	spinW = (XmSpinBoxWidget)nav;
Packit b099d7
  Arg		arglist[6];
Packit b099d7
  Cardinal	argCount;
Packit b099d7
  int		lastValue;
Packit b099d7
  int		numericCount;
Packit b099d7
  int		i;
Packit b099d7
  int		minimum;
Packit b099d7
  int		increment;
Packit b099d7
  Mask mask ;
Packit b099d7
 
Packit b099d7
  if (nav_data->valueMask & NavDimMask)
Packit b099d7
      spinW->spinBox.dim_mask = nav_data->dimMask ;
Packit b099d7
  
Packit b099d7
  if (!(numericCount = NumericChildCount(spinW))) return;
Packit b099d7
Packit b099d7
  if (!(spinW->spinBox.dim_mask & nav_data->dimMask))
Packit b099d7
    return ;
Packit b099d7
  
Packit b099d7
  /* Spin box can be a 2d dimensional navigator at most.
Packit b099d7
     If there is only one dimension set, the following loop is only
Packit b099d7
     rnu once since the mask is update at the end of it */
Packit b099d7
Packit b099d7
  mask = spinW->spinBox.dim_mask ;
Packit b099d7
Packit b099d7
  for (numericCount = 0, i = 0;
Packit b099d7
       i < SB_ChildCount(spinW) && numericCount < 2 && mask;
Packit b099d7
       i++)
Packit b099d7
    {
Packit b099d7
      spinC = SB_GetConstraintRec(spinW->composite.children[i]);
Packit b099d7
      
Packit b099d7
      if (SB_ChildIsNumeric(spinC))
Packit b099d7
	{
Packit b099d7
	  argCount = 0;
Packit b099d7
	  numericCount++;
Packit b099d7
	  
Packit b099d7
	  lastValue = spinC->position;
Packit b099d7
	  minimum=spinC->minimum_value;
Packit b099d7
	  increment=spinC->increment_value;
Packit b099d7
	  
Packit b099d7
	  if ((nav_data->valueMask & NavMinimum)
Packit b099d7
	      && (spinC->minimum_value != 
Packit b099d7
		  ACCESS_DIM(mask, nav_data->minimum)))
Packit b099d7
	    {
Packit b099d7
	      XtSetArg (arglist[argCount], XmNminimumValue,
Packit b099d7
			ACCESS_DIM(mask, nav_data->minimum));
Packit b099d7
	      minimum = ACCESS_DIM(mask, nav_data->minimum);
Packit b099d7
	      argCount++;
Packit b099d7
	    }
Packit b099d7
	  
Packit b099d7
	  if ((nav_data->valueMask & NavIncrement)
Packit b099d7
	      && (spinC->increment_value != 
Packit b099d7
		  ACCESS_DIM(mask, nav_data->increment)))
Packit b099d7
	    {
Packit b099d7
	      XtSetArg (arglist[argCount], XmNincrementValue,
Packit b099d7
			ACCESS_DIM(mask, nav_data->increment));
Packit b099d7
	      increment = ACCESS_DIM(mask, nav_data->increment);
Packit b099d7
	      argCount++;
Packit b099d7
	    }
Packit b099d7
	  
Packit b099d7
	  /* Process value if different from current value or either
Packit b099d7
	     increment or minimumValue changed (which will change the
Packit b099d7
	     calculation */
Packit b099d7
Packit b099d7
	  if ((nav_data->valueMask & NavValue)
Packit b099d7
	      &&  ((argCount != 0) ||
Packit b099d7
		   (lastValue != ACCESS_DIM(mask, nav_data->value))))
Packit b099d7
	    {
Packit b099d7
	      XtArgVal position = ACCESS_DIM(mask, nav_data->value);
Packit b099d7
Packit b099d7
	      GetPositionValue(
Packit b099d7
			(Widget) spinW->composite.children[i],
Packit b099d7
			XtOffset(XmSpinBoxConstraint, position),
Packit b099d7
			&position);
Packit b099d7
Packit b099d7
	      XtSetArg (arglist[argCount], XmNposition, ((int)position));
Packit b099d7
	      argCount++;
Packit b099d7
	    }
Packit b099d7
	  
Packit b099d7
	  if ((nav_data->valueMask & NavMaximum)
Packit b099d7
	      && (spinC->maximum_value !=  
Packit b099d7
		  ACCESS_DIM(mask, nav_data->maximum)))
Packit b099d7
	    {
Packit b099d7
	      XtSetArg (arglist[argCount], XmNmaximumValue,
Packit b099d7
			ACCESS_DIM(mask, nav_data->maximum) - 1);
Packit b099d7
	      argCount++;
Packit b099d7
	    }
Packit b099d7
	  
Packit b099d7
	  if (argCount)
Packit b099d7
	    XtSetValues (spinW->composite.children[i],
Packit b099d7
			 arglist, argCount);
Packit b099d7
	  
Packit b099d7
	  if (notify && 
Packit b099d7
	      ACCESS_DIM(mask, nav_data->value) != lastValue)
Packit b099d7
	    ArrowCallback((Widget)spinW, NULL, XmCR_OK);
Packit b099d7
Packit b099d7
Packit b099d7
	  /* mark the dimMask as x goes. So that if there is a second
Packit b099d7
	     numeric child, it only gets y setting. If there was no
Packit b099d7
	     X in the current mask, just stop here */
Packit b099d7
	  if (mask & NavigDimensionX) mask &= ~NavigDimensionX ;
Packit b099d7
	  else mask = 0 ;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SpinNGetValue
Packit b099d7
 *	Navigator GetValue Function.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
SpinNGetValue(Widget nav, XmNavigatorData nav_data)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint   spinC;
Packit b099d7
  XmSpinBoxWidget	spinW;
Packit b099d7
  int		i;
Packit b099d7
  int		numericCount;
Packit b099d7
  Mask mask ; 
Packit b099d7
Packit b099d7
  spinW = (XmSpinBoxWidget) nav;
Packit b099d7
  
Packit b099d7
  if (!(numericCount = NumericChildCount(spinW))) return;
Packit b099d7
  
Packit b099d7
  mask = nav_data->dimMask =  spinW->spinBox.dim_mask;
Packit b099d7
  
Packit b099d7
  if (nav_data->valueMask & (NavValue|NavMinimum|NavMaximum|NavIncrement)) {
Packit b099d7
      /* get the value out of the numeric children, in order  */
Packit b099d7
      for (numericCount = 0, i = 0; 
Packit b099d7
	   i < SB_ChildCount(spinW) && numericCount < 2 && mask;
Packit b099d7
	   i++)
Packit b099d7
	{
Packit b099d7
	  spinC = SB_GetConstraintRec(spinW->composite.children[i]);
Packit b099d7
	  if (SB_ChildIsNumeric(spinC)) {
Packit b099d7
	      numericCount++;
Packit b099d7
	      
Packit b099d7
	      ASSIGN_DIM(mask, nav_data->value, spinC->position);
Packit b099d7
	      ASSIGN_DIM(mask, nav_data->minimum, spinC->minimum_value);
Packit b099d7
	      ASSIGN_DIM(mask, nav_data->maximum, spinC->maximum_value + 1);
Packit b099d7
	      ASSIGN_DIM(mask, nav_data->increment, spinC->increment_value);
Packit b099d7
Packit b099d7
	      mask &= ~NavigDimensionX ;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
      
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * GetPositionValue
Packit b099d7
 *	XmExportProc conversion routine for converting between internal
Packit b099d7
 *	and external representation for XmNposition resource.  Internal
Packit b099d7
 *	representation is always POSITION_VALUE.  External representation
Packit b099d7
 *	can be either POSITION_VALUE or POSITION_INDEX as determined
Packit b099d7
 *	by XmNpositionType.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static void
Packit b099d7
GetPositionValue(Widget w, int offset, XtArgVal *value)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint	wc = SB_GetConstraintRec(w);
Packit b099d7
  
Packit b099d7
  if (SB_ChildIsNumeric(wc) && (!SB_ChildPositionTypeIsValue(wc)))
Packit b099d7
      *value = (*value - wc->minimum_value) / wc->increment_value;
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * SetPositionValue
Packit b099d7
 *	XmImportProc conversion routine for converting between external
Packit b099d7
 *	and internal representation for XmNposition resource.  Internal
Packit b099d7
 *	representation is always POSITION_VALUE.  External representation
Packit b099d7
 *	can be either POSITION_VALUE or POSITION_INDEX as determined
Packit b099d7
 *	by XmNpositionType.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static XmImportOperator
Packit b099d7
SetPositionValue(Widget w, int offset, XtArgVal *value)
Packit b099d7
{
Packit b099d7
  XmSpinBoxConstraint	wc = SB_GetConstraintRec(w);
Packit b099d7
  
Packit b099d7
  if (SB_ChildIsNumeric(wc) && (!SB_ChildPositionTypeIsValue(wc)))
Packit b099d7
      *value = wc->minimum_value + (*value * wc->increment_value);
Packit b099d7
Packit b099d7
  return(XmSYNTHETIC_LOAD);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * GetMaximumPositionValue
Packit b099d7
 *	Returns the maximum allowable position for this widget.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static int
Packit b099d7
GetMaximumPositionValue(XmSpinBoxConstraint sc)
Packit b099d7
{
Packit b099d7
  int	max;
Packit b099d7
      
Packit b099d7
  if (sc == (XmSpinBoxConstraint) NULL)
Packit b099d7
    max = 0;
Packit b099d7
  else if (SB_ChildIsNumeric(sc))
Packit b099d7
    max = sc->maximum_value;
Packit b099d7
  else
Packit b099d7
    max = (sc->num_values  > 0) ? (sc->num_values - 1) : 0;
Packit b099d7
Packit b099d7
  return(max);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * GetMinimumPositionValue
Packit b099d7
 *	Returns the minimum allowable position for this widget.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static int
Packit b099d7
GetMinimumPositionValue(XmSpinBoxConstraint sc)
Packit b099d7
{
Packit b099d7
  int	min;
Packit b099d7
      
Packit b099d7
  if (sc == (XmSpinBoxConstraint) NULL)
Packit b099d7
    min = 0;
Packit b099d7
  else if (SB_ChildIsNumeric(sc))
Packit b099d7
    min = sc->minimum_value;
Packit b099d7
  else
Packit b099d7
    min = 0;
Packit b099d7
Packit b099d7
  return(min);
Packit b099d7
}
Packit b099d7
Packit b099d7
/******************************************************************************
Packit b099d7
 * ValidatePositionValue
Packit b099d7
 *	Returns the minimum allowable position for this widget.
Packit b099d7
 *****************************************************************************/
Packit b099d7
static char *
Packit b099d7
ValidatePositionValue(XmSpinBoxConstraint sc, int *position)
Packit b099d7
{
Packit b099d7
  int	val;
Packit b099d7
  char	*err = (char *) NULL;
Packit b099d7
Packit b099d7
  val = SB_ChildMaximumPositionValue(sc);
Packit b099d7
  if (*position > val) {
Packit b099d7
    *position = val;
Packit b099d7
    err = BAD_SPIN_POSITION_MAX;
Packit b099d7
  }
Packit b099d7
Packit b099d7
  val = SB_ChildMinimumPositionValue(sc);
Packit b099d7
  if (*position < val) {
Packit b099d7
    *position = val;
Packit b099d7
    err = BAD_SPIN_POSITION_MIN;
Packit b099d7
  }
Packit b099d7
Packit b099d7
  return(err);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean
Packit b099d7
CvtStringToPositionValue(
Packit b099d7
        Display *display,
Packit b099d7
        XrmValue *args,		/* unused */
Packit b099d7
        Cardinal *num_args,	/* unused */
Packit b099d7
        XrmValue *from,
Packit b099d7
        XrmValue *to,
Packit b099d7
        XtPointer *converter_data) /* unused */
Packit b099d7
{
Packit b099d7
  XtArgVal		value;
Packit b099d7
  int			offset = XtOffset(XmSpinBoxConstraint, position);
Packit b099d7
  Widget		w = *((Widget *) args[0].addr);
Packit b099d7
Packit b099d7
  if (sscanf(from->addr, "%ld", (long*)&value) == 0)
Packit b099d7
    {
Packit b099d7
      XtDisplayStringConversionWarning(display,
Packit b099d7
				       (char *)from->addr,
Packit b099d7
				       XmRPositionValue);
Packit b099d7
      return False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  (void) SetPositionValue(w, offset, &value);
Packit b099d7
  _XM_CONVERTER_DONE( to, int, (int)value, ; )
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *
Packit b099d7
 * Public API
Packit b099d7
 *
Packit b099d7
 */
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *  XmCreateSpinBox()
Packit b099d7
 *  XmVaCreateSpinBox()
Packit b099d7
 *  XmVaCreateManagedSpinBox()
Packit b099d7
 *	Create an instance of a Spin widget and return the widget id.
Packit b099d7
 ************************************************************************/
Packit b099d7
Widget 
Packit b099d7
XmCreateSpinBox(Widget parent, String name, 
Packit b099d7
		ArgList arglist, Cardinal argcount)
Packit b099d7
{
Packit b099d7
  return(XtCreateWidget(name, xmSpinBoxWidgetClass, parent,
Packit b099d7
			arglist, argcount));
Packit b099d7
}
Packit b099d7
Widget 
Packit b099d7
XmVaCreateSpinBox(
Packit b099d7
        Widget parent,
Packit b099d7
        char *name,
Packit b099d7
        ...)
Packit b099d7
{
Packit b099d7
    register Widget w;
Packit b099d7
    va_list var;
Packit b099d7
    int count;
Packit b099d7
    
Packit b099d7
    Va_start(var,name);
Packit b099d7
    count = XmeCountVaListSimple(var);
Packit b099d7
    va_end(var);
Packit b099d7
Packit b099d7
    
Packit b099d7
    Va_start(var, name);
Packit b099d7
    w = XmeVLCreateWidget(name, 
Packit b099d7
                         xmSpinBoxWidgetClass, 
Packit b099d7
                         parent, False, 
Packit b099d7
                         var, count);
Packit b099d7
    va_end(var);   
Packit b099d7
    return w;
Packit b099d7
    
Packit b099d7
}
Packit b099d7
Widget 
Packit b099d7
XmVaCreateManagedSpinBox(
Packit b099d7
        Widget parent,
Packit b099d7
        char *name,
Packit b099d7
        ...)
Packit b099d7
{
Packit b099d7
    Widget w = NULL;
Packit b099d7
    va_list var;
Packit b099d7
    int count;
Packit b099d7
    
Packit b099d7
    Va_start(var, name);
Packit b099d7
    count = XmeCountVaListSimple(var);
Packit b099d7
    va_end(var);
Packit b099d7
    
Packit b099d7
    Va_start(var, name);
Packit b099d7
    w = XmeVLCreateWidget(name, 
Packit b099d7
                         xmSpinBoxWidgetClass, 
Packit b099d7
                         parent, True, 
Packit b099d7
                         var, count);
Packit b099d7
    va_end(var);   
Packit b099d7
    return w;
Packit b099d7
    
Packit b099d7
}
Packit b099d7
/************************************************************************
Packit b099d7
 *  XmSpinBoxValidatePosition
Packit b099d7
 *	Validate the position value specified in string.
Packit b099d7
 ************************************************************************/
Packit b099d7
int 
Packit b099d7
XmSpinBoxValidatePosition(Widget text_field, int *position)
Packit b099d7
{
Packit b099d7
  int			i;
Packit b099d7
  float			fPosition;
Packit b099d7
  int			iPosition;
Packit b099d7
  int			positionOffset =
Packit b099d7
				XtOffset(XmSpinBoxConstraint, position);
Packit b099d7
#ifdef FIX_1519
Packit b099d7
  int           iOffset;
Packit b099d7
#endif
Packit b099d7
  String		string;
Packit b099d7
  XmAccessTextualTrait  textT;
Packit b099d7
  XmSpinBoxConstraint	wc;
Packit b099d7
  XtAppContext 		app;
Packit b099d7
  
Packit b099d7
  if (text_field == (Widget) NULL)
Packit b099d7
    return(XmCURRENT_VALUE);
Packit b099d7
Packit b099d7
  app = XtWidgetToApplicationContext(text_field);
Packit b099d7
  _XmAppLock(app);
Packit b099d7
Packit b099d7
  textT = (XmAccessTextualTrait)
Packit b099d7
    XmeTraitGet((XtPointer) XtClass(text_field), XmQTaccessTextual);
Packit b099d7
  if (textT == NULL) {
Packit b099d7
    _XmAppUnlock(app);
Packit b099d7
    return(XmCURRENT_VALUE);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  wc = SB_GetConstraintRec(text_field);
Packit b099d7
  if ((wc == (XmSpinBoxConstraint) NULL) || (! SB_ChildIsNumeric(wc)))
Packit b099d7
    {
Packit b099d7
      if ((wc) && (position))
Packit b099d7
	*position = wc->position;
Packit b099d7
      _XmAppUnlock(app);
Packit b099d7
      return(XmCURRENT_VALUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
  string = textT->getValue(text_field, XmFORMAT_MBYTE);
Packit b099d7
  if (sscanf(string, "%f", &fPosition) == 0)
Packit b099d7
    {
Packit b099d7
      if (position)
Packit b099d7
	{
Packit b099d7
	  XtArgVal external_position = wc->position;
Packit b099d7
          GetPositionValue(text_field, positionOffset, &external_position);
Packit b099d7
	  *position = (int)external_position;
Packit b099d7
	}
Packit b099d7
Packit b099d7
      _XmAppUnlock(app);
Packit b099d7
      return(XmCURRENT_VALUE);
Packit b099d7
    }
Packit b099d7
  XtFree(string);
Packit b099d7
Packit b099d7
  for (i=0; i<wc->decimal_points; i++)
Packit b099d7
    fPosition *= 10.0;
Packit b099d7
Packit b099d7
  iPosition = (int) fPosition;
Packit b099d7
Packit b099d7
  if (iPosition < SB_ChildMinimumPositionValue(wc))
Packit b099d7
    {
Packit b099d7
      if (position)
Packit b099d7
	{
Packit b099d7
	  XtArgVal external_position = SB_ChildMinimumPositionValue(wc);
Packit b099d7
          GetPositionValue(text_field, positionOffset, &external_position);
Packit b099d7
	  *position = (int)external_position;
Packit b099d7
	}
Packit b099d7
Packit b099d7
      _XmAppUnlock(app);
Packit b099d7
      return(XmMINIMUM_VALUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
  if (iPosition > SB_ChildMaximumPositionValue(wc))
Packit b099d7
    {
Packit b099d7
      if (position)
Packit b099d7
	{
Packit b099d7
	  XtArgVal external_position = SB_ChildMaximumPositionValue(wc);
Packit b099d7
          GetPositionValue(text_field, positionOffset, &external_position);
Packit b099d7
	  *position = (int)external_position;
Packit b099d7
	}
Packit b099d7
Packit b099d7
      _XmAppUnlock(app);
Packit b099d7
      return(XmMAXIMUM_VALUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
#ifdef FIX_1519
Packit b099d7
  iOffset = iPosition - SB_ChildMinimumPositionValue(wc);
Packit b099d7
Packit b099d7
  if ((iOffset % wc->increment_value) != 0)
Packit b099d7
#else
Packit b099d7
  if ((iPosition % wc->increment_value) != 0)
Packit b099d7
#endif
Packit b099d7
    {
Packit b099d7
      int	iValue = wc->increment_value;
Packit b099d7
Packit b099d7
      if (position)
Packit b099d7
	{
Packit b099d7
#ifdef FIX_1519
Packit b099d7
	  XtArgVal external_position = SB_ChildMinimumPositionValue(wc) + (iOffset / iValue) * iValue;
Packit b099d7
#else
Packit b099d7
	  XtArgVal external_position = (iPosition / iValue) * iValue;
Packit b099d7
#endif
Packit b099d7
          GetPositionValue(text_field, positionOffset, &external_position);
Packit b099d7
          *position = (int)external_position;
Packit b099d7
	}
Packit b099d7
Packit b099d7
      _XmAppUnlock(app);
Packit b099d7
      return(XmINCREMENT_VALUE);
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  if (position)
Packit b099d7
    {
Packit b099d7
      XtArgVal external_position = iPosition;
Packit b099d7
      GetPositionValue(text_field, positionOffset, &external_position);
Packit b099d7
      *position = (int)external_position;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  _XmAppUnlock(app);
Packit b099d7
  return(XmVALID_VALUE);
Packit b099d7
}