/** *** *** XmpSpinbox widget class -- an extensible data selection widget. *** Copyright (C) 1995 Charles S. Kerr (cskerr@delenn.jccbi.gov) *** Comments, and criticisms, will all be greatly appreciated. *** *** Use of this library has certain conditions that are easy to *** fulfill. For more information, read the file LICENSE.html that *** came with this widget. *** *** This widget is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** file LICENSE.html for more details. *** *** Advance warning: set your term to 132 cols. :) *** **/ static const char *version = "XmpSpinbox Version 1.3 96/01/18 Author Charles S. Kerr"; /** *** Header Files **/ #include #include #include #include #include #if defined( SUN4 ) && !defined( SVR4 ) #include extern long strtol(); #else #include #endif #ifdef SPRINTF_BROKEN #include #endif #include #include #include "SpinboxP.h" /** *** XmTextFieldPeek* will allow us to avoid having to call *** XmTextFieldGetString (which involves an unnecessary call to *** XtMalloc and XtFree) and strlen(). These are the only *** two places where we use the info from the TextFP header. *** *** DO NOT USE XmTextFieldPeek* if you are working with *** wide character sets (usually for I18N). **/ #if defined(XMTF_PEEK) #include #define XmTextFieldPeekString(w) ((const char*)TextF_Value(w)) #define XmTextFieldPeekLength(w) ((int)(((XmTextFieldWidget)(w))->text.string_length)) #endif /** *** My compiler complains when I try to convert ints to *** pointers, implicitly or explicitly, because I'm running *** on an AXP where sizeof(int)==32 and sizeof(XtPointer)==64. *** Creating an intermediate step that converts the int to *** whatever the integral of the same size as a pointer *** satisfies the compiler. **/ #define int2xtp(a) ((XtPointer)((PointerSizedIntegral)(a))) #define xtp2int(a) ((int)((PointerSizedIntegral)(a))) /** *** When user presses arrowbutton down, the value will click *** up/down XmNincrement. If the arrowbutton is held down, after *** INITIAL_DELAY milliseconds the values will start scrolling *** at the rate of once per SECOND_DELAY milliseconds, *** speeding up until we are scrolling at the rate of *** once per MINIMUM_DELAY seconds. Every time we speed up, *** we cut DELAY_INCREMENT ms off of our time. **/ #define INITIAL_DELAY 300 #define SECOND_DELAY 100 #define MINIMUM_DELAY 5 #define DELAY_DECREMENT 3 /** *** Convenience macros, mainly used when determining *** the layout of the textfield and arrowbuttons. **/ #define min2(a,b) ((a)<(b)?(a):(b)) #define max2(a,b) ((a)>(b)?(a):(b)) #define min3(a,b,c) (min2(min2((a),(b)),(c))) #define max3(a,b,c) (max2(max2((a),(b)),(c))) #ifndef XtWidth #define XtWidth(w) ((w)->core.width) #endif #ifndef XtHeight #define XtHeight(w) ((w)->core.height) #endif /** *** the *_show_value functions for the various XmNspinboxTypes. **/ static SpinboxShowValueProc alpha_show_value, bc_show_value, clock_hm_show_value, clock_hms_show_value, clock_dhms_show_value, decimal_show_value, dollar_show_value, long_show_value; /** *** the *_get_value functions for the various XmNspinboxTypes. **/ static SpinboxGetValueProc alpha_get_value, bc_get_value, clock_hm_get_value, clock_hms_get_value, clock_dhms_get_value, decimal_get_value, dollar_get_value, long_get_value; /** *** callbacks to keep the values spinning when the arrowbuttons *** are pressed and held down. **/ static void up_activate_cb ( Widget, XtPointer, XtPointer ); static void up_arm_cb ( Widget, XtPointer, XtPointer ); static void down_activate_cb ( Widget, XtPointer, XtPointer ); static void down_arm_cb ( Widget, XtPointer, XtPointer ); static void ab_disarm_cb ( Widget, XtPointer, XtPointer ); /** *** Actions **/ static void Action_Decrement_Small ( Widget, XEvent*, String*, Cardinal* ); static void Action_Decrement_Large ( Widget, XEvent*, String*, Cardinal* ); static void Action_Increment_Small ( Widget, XEvent*, String*, Cardinal* ); static void Action_Increment_Large ( Widget, XEvent*, String*, Cardinal* ); /** *** Miscellaneous Prototypes **/ static Boolean CvtStringToLong ( Display *dpy, XrmValuePtr args, Cardinal *num_args, XrmValuePtr from, XrmValuePtr to, XtPointer *data ); #ifdef SPRINTF_BROKEN static int int_sprintf ( char *buffer, const char *fmt, ... ); #else #define int_sprintf sprintf #endif static Boolean did_user_specify ( const char *res, const ArgList, Cardinal ); static void set_tf_cb ( XmpSpinboxWidget cw, Boolean is_on ); static void get_text_field ( XmpSpinboxWidget ); static void set_text_field ( XmpSpinboxWidget ); static Boolean validate_new_inc_large ( XmpSpinboxWidget, long value ); static Boolean validate_new_minimum ( XmpSpinboxWidget, long value ); static Boolean validate_new_maximum ( XmpSpinboxWidget, long value ); static Boolean validate_new_delay ( XmpSpinboxWidget, int value ); static Boolean validate_new_type ( XmpSpinboxWidget, int value ); static Boolean validate_new_style ( XmpSpinboxWidget, int value ); static Boolean validate_new_value ( XmpSpinboxWidget, long *value ); static void set_spinbox_value ( XmpSpinboxWidget cw, int value, Boolean notify ); static void set_getshow_procs ( XmpSpinboxWidget cw ); static void set_default_min ( XmpSpinboxWidget cw ); static void set_default_max ( XmpSpinboxWidget cw ); static void set_default_inc_large ( XmpSpinboxWidget cw ); static void set_default_button_ratio ( XmpSpinboxWidget cw ); static void set_arrow_orientation ( XmpSpinboxWidget cw ); static void set_sensitive ( XmpSpinboxWidget cw, Boolean sensitive ); static Boolean validate_new_button_size_ratio ( XmpSpinboxWidget, int ratio ); /** *** Manditory Widget Functions **/ static void ClassInitialize ( void ); static void Initialize ( Widget, Widget, ArgList, Cardinal* ); static Boolean SetValues ( Widget, Widget, Widget, ArgList, Cardinal* ); static void Size ( Widget, Dimension*, Dimension* ); static void Resize ( Widget ); /** *** *** Translation Table *** **/ static XtTranslations Translations; static char translations[] = "osfUp: IncrementSmall() \n\ osfDown: DecrementSmall() \n\ osfPageUp: IncrementLarge() \n\ osfPageDown: DecrementLarge()"; /** *** *** Action Table *** **/ static XtActionsRec actions[] = { { "DecrementSmall", Action_Decrement_Small }, { "DecrementLarge", Action_Decrement_Large }, { "IncrementSmall", Action_Increment_Small }, { "IncrementLarge", Action_Increment_Large }, { NULL, NULL } }; /** *** *** Resources List *** **/ static XtResource resources[] = { { XmNarrowOrientation, XmCArrowOrientation, XmROrientation, sizeof (unsigned char), XtOffsetOf(struct _XmpSpinboxRec, spinbox.arrow_orientation), XtRImmediate, int2xtp(XmVERTICAL), }, { XmNcolumns, XmCColumns, XmRShort, sizeof(short), XtOffsetOf(struct _XmpSpinboxRec, spinbox.tf_columns), XtRImmediate, int2xtp(8) }, { XmNbuttonSizeRatio, XmCButtonSizeRatio, XmRInt, sizeof(int), XtOffsetOf(struct _XmpSpinboxRec, spinbox.button_size_ratio), XtRImmediate, int2xtp(5) }, { XmNbuttonSizeFixed, XmCButtonSizeFixed, XmRBoolean, sizeof(Boolean), XtOffsetOf(struct _XmpSpinboxRec, spinbox.button_size_fixed), XtRImmediate, int2xtp(0) }, { XmNdecimalPoints, XmCDecimalPoints, XmRShort, sizeof (short), XtOffsetOf(struct _XmpSpinboxRec, spinbox.decimal_points), XtRImmediate, int2xtp(0), }, { XmNgetValueData, XmCGetValueData, XtRPointer, sizeof(XtPointer), XtOffsetOf(struct _XmpSpinboxRec, spinbox.get_value_data), XtRImmediate, (XtPointer)0 }, { XmNgetValueProc, XmCGetValueProc, XmRGetValueProc, sizeof(SpinboxGetValueProc*), XtOffsetOf(struct _XmpSpinboxRec, spinbox.get_value_proc), XtRImmediate, (XtPointer)long_get_value }, { XmNincrement, XmCIncrement, XmRLong, sizeof(long), XtOffsetOf(struct _XmpSpinboxRec, spinbox.increment), XtRImmediate, int2xtp(1) }, { XmNincrementLarge, XmCIncrementLarge, XmRLong, sizeof(long), XtOffsetOf(struct _XmpSpinboxRec, spinbox.increment_large), XtRImmediate, int2xtp(5) }, { XmNitemCount, XmCItemCount, XtRInt, sizeof(int), XtOffsetOf(struct _XmpSpinboxRec, spinbox.item_count), XtRImmediate, int2xtp(0) }, { XmNitems, XmCItems, XtRStringArray, sizeof(String*), XtOffsetOf(struct _XmpSpinboxRec, spinbox.items), XtRImmediate, (XtPointer)0 }, { XmNitemsAreSorted, XmCItemsAreSorted, XmRBoolean, sizeof(Boolean), XtOffsetOf(struct _XmpSpinboxRec, spinbox.items_are_sorted), XtRImmediate, int2xtp(0) }, { XmNmaximum, XmCMaximum, XmRLong, sizeof(long), XtOffsetOf(struct _XmpSpinboxRec, spinbox.val_max), XtRImmediate, int2xtp(LONG_MAX-1) /* before int2xtp(0) */ }, { XmNminimum, XmCMinimum, XmRLong, sizeof(long), XtOffsetOf(struct _XmpSpinboxRec, spinbox.val_min), XtRImmediate, int2xtp(LONG_MIN+1) /* before int2xtp(0) */ }, { XmNshowValueData, XmCShowValueData, XtRPointer, sizeof(XtPointer), XtOffsetOf(struct _XmpSpinboxRec, spinbox.show_value_data), XtRImmediate, (XtPointer)0 }, { XmNshowValueProc, XmCShowValueProc, XmRShowValueProc, sizeof(SpinboxShowValueProc*), XtOffsetOf(struct _XmpSpinboxRec, spinbox.show_value_proc), XtRImmediate, (XtPointer)long_show_value }, { XmNspinboxCycle, XmCSpinboxCycle, XmRBoolean, sizeof(Boolean), XtOffsetOf(struct _XmpSpinboxRec, spinbox.cycle), XtRImmediate, int2xtp(0) }, { XmNspinboxStyle, XmCSpinboxStyle, XmRSpinboxStyle, sizeof (unsigned char), XtOffsetOf(struct _XmpSpinboxRec, spinbox.spinbox_style), XtRImmediate, int2xtp(XmSPINBOX_STACKED_RIGHT), }, { XmNspinboxType, XmCSpinboxType, XmRSpinboxType, sizeof (unsigned char), XtOffsetOf(struct _XmpSpinboxRec, spinbox.spinbox_type), XtRImmediate, int2xtp(XmSPINBOX_NUMBER), }, { XmNspinboxUseClosestValue, XmCSpinboxUseClosestValue, XmRBoolean, sizeof(Boolean), XtOffsetOf(struct _XmpSpinboxRec, spinbox.use_closest_value), XtRImmediate, int2xtp(0) }, { XmNspinboxAutoCorrect, XmCSpinboxAutoCorrect, XmRBoolean, sizeof(Boolean), XtOffsetOf(struct _XmpSpinboxRec, spinbox.auto_correct), XtRImmediate, int2xtp(0) }, { XmNupdateText, XmCUpdateText, XmRBoolean, sizeof(Boolean), XtOffsetOf(struct _XmpSpinboxRec, spinbox.text_update_constantly), XtRImmediate, int2xtp(False) }, { XmNvalue, XmCValue, XmRLong, sizeof(long), XtOffsetOf(struct _XmpSpinboxRec, spinbox.val_now), XtRImmediate, int2xtp(0) }, { XmNvalueChangedCallback, XmCCallback, XmRCallback, sizeof (XtCallbackList), XtOffsetOf(struct _XmpSpinboxRec, spinbox.ValueChangedCBL), XtRCallback, (XtPointer)0, } }; /** *** *** The Widget CLASS RECORD *** **/ externaldef(xmspinboxclassrec) XmpSpinboxClassRec xmpSpinboxClassRec = { { /* core_class */ (WidgetClass)&xmpGeometryClassRec, /* superclass */ "XmpSpinbox", /* class_name */ sizeof(XmpSpinboxRec), /* widget_size */ ClassInitialize, /* class_initialize */ NULL, /* class_part_initialize */ FALSE, /* class_inited */ Initialize, /* initialize */ NULL, /* initialize_hook */ XtInheritRealize, /* realize */ NULL, /* actions */ 0, /* num_actions */ resources, /* resources */ XtNumber(resources), /* num_resources */ NULLQUARK, /* xrm_class */ TRUE, /* compress_motion */ XtExposeCompressMaximal, /* compress_exposure */ TRUE, /* compress_enterleave */ FALSE, /* visible_interest */ NULL, /* destroy */ Resize, /* resize */ XtInheritExpose, /* expose */ SetValues, /* set_values */ NULL, /* set_values_hook */ XtInheritSetValuesAlmost, /* set_values_almost */ NULL, /* get_values_hook */ NULL, /* accept_focus */ XtVersion, /* version */ NULL, /* callback_private */ XtInheritTranslations, /* tm_table */ XtInheritQueryGeometry, /* query_geometry */ NULL, /* display_accelerator */ NULL /* extension */ }, { /* composite_class */ XtInheritGeometryManager, /* geometry_manager */ XtInheritChangeManaged, /* change_managed */ XtInheritInsertChild, /* insert_child */ XtInheritDeleteChild, /* delete_child */ NULL /* extension */ }, { /* constraint_class */ NULL, /* resources */ 0, /* num_resources */ sizeof(XmpSpinboxConstraintRec), /* constraint_size */ NULL, /* constraint_initialize */ NULL, /* destroy */ NULL, /* set_values */ NULL /* extension */ }, { /* manager class */ XtInheritTranslations, /* translations */ NULL, /* syn_resources */ 0, /* num_syn_resources */ NULL, /* syn_constraint_resources */ 0, /* num_syn_constraint_resources */ XmInheritParentProcess, /* parent_process */ NULL /* extension */ }, { /* geometry class */ XmpInheritBitGravity, /* bit_gravity */ XmpInheritInitializePostHook, /* initialize_post_hook */ XmpInheritSetValuesPostHook, /* set_values_post_hook */ XmpInheritConstraintInitializePostHook, /* constraint_initialize_post_hook*/ XmpInheritConstraintSetValuesPostHook, /* constraint_set_values_post_hook*/ Size, /* size */ NULL /* extension */ }, { /* spinbox class */ #if XmVersion > 1001 0, /* spinbox_type_id */ 0, /* spinbox_style_id */ #endif NULL /* extension */ } }; externaldef(xmpspinboxwidgetclass) WidgetClass xmpSpinboxWidgetClass = (WidgetClass) &xmpSpinboxClassRec; static String SpinboxTypeNames[] = { "spinbox_number", "spinbox_clock_hm", "spinbox_clock_hms", "spinbox_clock_dhms", "spinbox_beaconcode", "spinbox_dollars", "spinbox_strings", "spinbox_userdefined" }; static String SpinboxStyleNames[] = { "spinbox_stacked", "spinbox_stacked_left", "spinbox_stacked_right", "spinbox_left", "spinbox_right", "spinbox_separate" }; #if XmVersion <= 1001 static String SpinboxPrefixes[] = {"Xm", NULL}; static int SpinboxTypeValues[] = { XmSPINBOX_NUMBER, XmSPINBOX_CLOCK_HM, XmSPINBOX_CLOCK_HMS, XmSPINBOX_CLOCK_DHMS, XmSPINBOX_BEACONCODE, XmSPINBOX_DOLLARS, XmSPINBOX_STRINGS, XmSPINBOX_USER_DEFINED }; static int SpinboxStyleValues[] = { XmSPINBOX_STACKED, XmSPINBOX_STACKED_LEFT, XmSPINBOX_STACKED_RIGHT, XmSPINBOX_LEFT, XmSPINBOX_RIGHT, XmSPINBOX_SEPARATE }; #endif /* ** And finally, after 500+ lines, the program begins. . . */ /************************************************************************ * * ClassInitialize * ************************************************************************/ static void ClassInitialize(void) { /** *** Make the compiler happy, it wants "version" to be used *** if it's defined. **/ version = version; #if XmVersion > 1001 SpinboxStyleId = XmRepTypeRegister ( XmRSpinboxStyle, SpinboxStyleNames, NULL, XtNumber(SpinboxStyleNames)); SpinboxTypeId = XmRepTypeRegister ( XmRSpinboxType, SpinboxTypeNames, NULL, XtNumber(SpinboxTypeNames)); #else XmtRegisterEnumConverter(XmRSpinboxStyle, SpinboxStyleNames, SpinboxStyleValues, XtNumber(SpinboxStyleNames), SpinboxPrefixes); XmtRegisterEnumConverter(XmRSpinboxType, SpinboxTypeNames, SpinboxTypeValues, XtNumber(SpinboxTypeNames), SpinboxPrefixes); #endif XtSetTypeConverter ( XmRString, XmRLong, CvtStringToLong, NULL, 0, XtCacheNone, NULL ); Translations = XtParseTranslationTable ( translations ); } static Boolean did_user_specify ( const char *resource_name, const ArgList args, Cardinal qty ) { Cardinal i; for ( i=0; i= MINIMUM_DELAY ) SpinboxDelay(cw) -= DELAY_DECREMENT; SpinboxInterval(cw) = XtAppAddTimeOut( SpinboxContext(cw), SpinboxDelay(cw), up_armloop_cb, client ); } static void up_arm_cb ( Widget w, XtPointer client, XtPointer call ) { XmpSpinboxWidget cw = (XmpSpinboxWidget)client; SpinboxDelay(cw) = INITIAL_DELAY; set_tf_cb ( cw, False ); SpinboxInterval(cw) = XtAppAddTimeOut( SpinboxContext(cw), SpinboxDelay(cw), up_armloop_cb, client ); } static void ab_disarm_cb ( Widget w, XtPointer client, XtPointer call ) { XmpSpinboxWidget cw = (XmpSpinboxWidget)client; XtRemoveTimeOut ( SpinboxInterval(cw) ); set_tf_cb ( cw, True ); } static void down_activate_cb ( Widget w, XtPointer client, XtPointer call ) { XmpSpinboxWidget cw = (XmpSpinboxWidget)client; XmpSpinboxSetValue((Widget)cw, SpinboxValue(cw)-SpinboxIncrement(cw), True); } static void down_armloop_cb ( XtPointer client, XtIntervalId *pId ) { XmpSpinboxWidget cw = (XmpSpinboxWidget)client; down_activate_cb ( NULL, client, NULL ); if ( SpinboxDelay(cw)==INITIAL_DELAY ) SpinboxDelay(cw) = SECOND_DELAY; else if ( SpinboxDelay(cw)-DELAY_DECREMENT >= MINIMUM_DELAY ) SpinboxDelay(cw) -= DELAY_DECREMENT; SpinboxInterval(cw) = XtAppAddTimeOut( SpinboxContext(cw), SpinboxDelay(cw), down_armloop_cb, client ); } static void down_arm_cb ( Widget w, XtPointer client, XtPointer call ) { XmpSpinboxWidget cw = (XmpSpinboxWidget)client; SpinboxDelay(cw) = INITIAL_DELAY; set_tf_cb ( cw, False ); SpinboxInterval(cw) = XtAppAddTimeOut ( SpinboxContext(cw), SpinboxDelay(cw), down_armloop_cb, client ); } /** *** *** SET routines... *** **/ static void set_getshow_procs ( XmpSpinboxWidget cw ) { switch ( SpinboxType(cw) ) { case XmSPINBOX_CLOCK_HM : SpinboxShowValue(cw) = clock_hm_show_value; SpinboxGetValue(cw) = clock_hm_get_value; break; case XmSPINBOX_CLOCK_HMS : SpinboxShowValue(cw) = clock_hms_show_value; SpinboxGetValue(cw) = clock_hms_get_value; break; case XmSPINBOX_CLOCK_DHMS : SpinboxShowValue(cw) = clock_dhms_show_value; SpinboxGetValue(cw) = clock_dhms_get_value; break; case XmSPINBOX_BEACONCODE : SpinboxShowValue(cw) = bc_show_value; SpinboxGetValue(cw) = bc_get_value; break; case XmSPINBOX_DOLLARS : SpinboxShowValue(cw) = dollar_show_value; SpinboxGetValue(cw) = dollar_get_value; break; case XmSPINBOX_STRINGS : SpinboxShowValue(cw) = alpha_show_value; SpinboxGetValue(cw) = alpha_get_value; break; case XmSPINBOX_USER_DEFINED : break; case XmSPINBOX_NUMBER : if ( SpinboxDecimalPoints(cw) ) { SpinboxShowValue(cw) = decimal_show_value; SpinboxGetValue(cw) = decimal_get_value; } else { SpinboxShowValue(cw) = long_show_value; SpinboxGetValue(cw) = long_get_value; } break; default : assert ( 0 ); break; } } static void set_default_inc_large ( XmpSpinboxWidget cw ) { switch ( SpinboxType(cw) ) { case XmSPINBOX_CLOCK_HM : case XmSPINBOX_CLOCK_HMS : case XmSPINBOX_CLOCK_DHMS : SpinboxIncLarge(cw) = 60; break; case XmSPINBOX_DOLLARS : SpinboxIncLarge(cw) = 100; break; case XmSPINBOX_NUMBER : if ( SpinboxDecimalPoints(cw) ) { int i; for ( i=0, SpinboxIncLarge(cw)=1; i 0 ); } static Boolean validate_new_inc_large ( XmpSpinboxWidget cw, long value ) { unsigned range = SpinboxMaxValue(cw) - SpinboxMinValue(cw); if ( (unsigned)value > range ) { char tmpstr[512]; (void) sprintf ( tmpstr, "Requested Large Increment (%ld) is larger than the range of the spinbox [%ld...%ld]!", value, SpinboxMinValue(cw), SpinboxMaxValue(cw) ); XmpWarning ( (Widget)cw, tmpstr ); return False; } if ( value < 0 ) { XmpWarning ( (Widget)cw, "\nRequested spinbox large increment must be greater than zero!" ); return False; } return True; } static Boolean validate_new_type ( XmpSpinboxWidget cw, int value ) { if ( value != XmSPINBOX_NUMBER && value != XmSPINBOX_CLOCK_HM && value != XmSPINBOX_CLOCK_HMS && value != XmSPINBOX_CLOCK_DHMS && value != XmSPINBOX_BEACONCODE && value != XmSPINBOX_DOLLARS && value != XmSPINBOX_STRINGS && value != XmSPINBOX_USER_DEFINED ) { XmpWarning ( (Widget)cw, "\nRequested spinbox type not recognized!" ); return False; } return True; } static Boolean validate_new_style ( XmpSpinboxWidget cw, int value ) { if ( value != XmSPINBOX_STACKED && value != XmSPINBOX_STACKED_LEFT && value != XmSPINBOX_STACKED_RIGHT && value != XmSPINBOX_LEFT && value != XmSPINBOX_RIGHT && value != XmSPINBOX_SEPARATE ) { XmpWarning ( (Widget)cw, "\nRequested spinbox style not recognized!" ); return False; } return True; } static Boolean validate_new_minimum ( XmpSpinboxWidget cw, long value ) { if (value > SpinboxValue(cw) ) { if (SpinboxAutoCorrect(cw)) { SpinboxValue(cw) = value; } else { XmpWarning ( (Widget)cw, "\nRequested minimum is greater than current Spinbox value!" ); return False; } } return True; } static Boolean validate_new_maximum ( XmpSpinboxWidget cw, long value ) { if ( value < SpinboxValue(cw) ) { if (SpinboxAutoCorrect(cw)) SpinboxValue(cw) = value; else { XmpWarning ( (Widget)cw, "\nRequested maximum is less than current spinbox value!" ); return False; } } return True; } static Boolean validate_new_delay ( XmpSpinboxWidget cw, int value ) { if ( value<1 ) { XmpWarning ( (Widget)cw, "\nNew delay is smaller than minimum spinbox delay!" ); return False; } return True; } static Boolean validate_new_value ( XmpSpinboxWidget cw, long *value ) { if ( SpinboxCycle(cw) ) return True; if ( *valueSpinboxMaxValue(cw) ) { if ( SpinboxUseClosestValue(cw) ) { *value = SpinboxMaxValue(cw); return ( True ); } return False; } return True; } /** *** SET SPINBOX && CALL VALUE CHANGED CALLBACKS **/ static void set_spinbox_value ( XmpSpinboxWidget cw, int value, Boolean notify ) { if ( value>SpinboxMaxValue(cw) && SpinboxCycle(cw) ) value = SpinboxMinValue(cw); if ( value 0 ) { right *= 10; len--; } while ( len < 0 ) { right /= 10; len++; } } } *value = left + right; return True; } static void dollar_show_value ( Widget w, XtPointer client, long value, char *buffer, size_t maxlen ) { register char *src, *tgt; int i, len, commas; char tmpbuf[32]; Boolean neg; if (( neg = value < 0 )) value = -value; src = tmpbuf; tgt = buffer; len = int_sprintf ( src, "%01d", (int)value/100 ); if ( neg ) *tgt++ = '('; *tgt++ = '$'; commas = (len-1)/3; i = len - commas*3; while ( i-- ) *tgt++ = *src++; while ( commas-- ) { *tgt++ = ','; *tgt++ = *src++; *tgt++ = *src++; *tgt++ = *src++; } if (( i = value % 100 )) /* cents */ tgt += int_sprintf ( tgt, ".%02d", i ); if ( neg ) *tgt++ = ')'; *tgt = '\0'; } static Boolean dollar_get_value ( Widget w, XtPointer client, const char *buffer, size_t buflen, long *value ) { register char ch; Boolean dot = False; Boolean neg = False; long val = 0; while ( buflen-- ) { ch = *buffer++; if ( isdigit ( ch ) ) val = (val*10) + (ch-'0'); else if ( ch==',' || ch=='$' ) continue; else if ( ch=='.' ) { buflen=2; dot=True; } else if ( ch=='(' || ch=='-' || ch==')' ) neg = True; else return False; } if ( !dot ) val *= 100; if ( neg ) val = -val; *value = val; return True; } static void long_show_value ( Widget w, XtPointer client, long value, char *buffer, size_t maxlen ) { (void) sprintf ( buffer, "%ld", value ); } static Boolean long_get_value ( Widget w, XtPointer client, const char *buffer, size_t buflen, long *value ) { #ifdef CRAY errno = 0; #elif !defined(LINUX) && !defined(SOLARIS) && !defined(DARWIN) && !defined(FREEBSD) && !defined(NETBSD) && \ !defined(AIX) && !defined(ALPHA) && !defined(HP1164) && !defined(HPUX) && !defined(IRIX) int errno = 0; #endif *value = strtol ( buffer, NULL, 10 ); return ( !errno ); } static void clock_dhms_show_value ( Widget w, XtPointer client, long value, char *buffer, size_t maxlen ) { int sec, min, hr, day; sec = value % 60; value /= 60; min = value % 60; value /= 60; hr = value % 24; day = value/24; (void) sprintf ( buffer, "%01d:%02d:%02d:%02d", day, hr, min, sec ); } static void clock_hms_show_value ( Widget w, XtPointer client, long value, char *buffer, size_t maxlen ) { int sec = value % 60; value /= 60; (void) sprintf ( buffer, "%01d:%02d:%02d", (int)value/60, (int)value%60, sec ); } static void clock_hm_show_value ( Widget w, XtPointer client, long value, char *buffer, size_t maxlen ) { (void) sprintf ( buffer, "%01d:%02d", (int)value/60, (int)value%60 ); } static Boolean clock_dhms_get_value ( Widget w, XtPointer client, const char *buffer, size_t buflen, long *value ) { long day=0, hr=0, min=0, sec=0; char *pchar; /* get day */ errno=0; day = strtol ( buffer, &pchar, 10); if ( errno ) return(False); /* get hour */ errno = 0; hr = strtol ( buffer, &pchar, 10 ); if ( errno ) return ( False ); /* get minute */ if ( *pchar ) { pchar++; min = strtol ( pchar, &pchar, 10 ); } if ( errno ) return ( False ); /* get seconds */ if ( *pchar ) { pchar++; sec = strtol ( pchar, &pchar, 10 ); } if ( errno ) return ( False ); *value = day*24 + hr*3600 + min*60 + sec; return True; } static Boolean clock_hms_get_value ( Widget w, XtPointer client, const char *buffer, size_t buflen, long *value ) { long hr=0, min=0, sec=0; char *pchar; /* get hour */ errno = 0; hr = strtol ( buffer, &pchar, 10 ); if ( errno ) return ( False ); /* get minute */ if ( *pchar ) { pchar++; min = strtol ( pchar, &pchar, 10 ); } if ( errno ) return ( False ); /* get seconds */ if ( *pchar ) { pchar++; sec = strtol ( pchar, &pchar, 10 ); } if ( errno ) return ( False ); *value = hr*3600 + min*60 + sec; return True; } static Boolean clock_hm_get_value ( Widget w, XtPointer client, const char *buffer, size_t buflen, long *value ) { long hr, min=0; char *pchar; /* get hour */ errno = 0; hr = strtol ( buffer, &pchar, 10 ); if ( errno ) return ( False ); /* get minute */ if ( *pchar ) { pchar++; min = strtol ( pchar, &pchar, 10 ); } if ( errno ) return ( False ); /* set value */ *value = hr*60 + min; return True; } static void bc_show_value ( Widget w, XtPointer client, long value, char *buffer, size_t maxlen ) { (void) sprintf ( buffer, "%04o", (int)value ); } static Boolean bc_get_value ( Widget w, XtPointer client, const char *buffer, size_t buflen, long *value ) { char *pchar; long val; /* get number */ errno = 0; val = strtol ( buffer, &pchar, 8 ); if ( errno ) return ( False ); /* we only want digits, nothing else. */ if ( *pchar ) return False; *value = val; return True; } static void alpha_show_value ( Widget w, XtPointer client, long value, char *buffer, size_t maxlen ) { XmpSpinboxWidget cw = (XmpSpinboxWidget)w; assert ( value >= 0 ); assert ( value < SpinboxItemCount(cw) ); (void) strcpy ( buffer, ((char**)SpinboxItems(cw))[value] ); } static int alpha_cmp ( const void *a, const void *b ) { const String sa = *(const String *)a; const String sb = *(const String *)b; assert ( sa && (isprint(*sa)||!*sa) ); assert ( sb && (isprint(*sb)||!*sb) ); return ( strcmp ( sa, sb ) ); } static String* alpha_search ( const char *findme, const String *base, int qty, Boolean are_sorted ) { int i; if ( are_sorted ) return ( (String*) bsearch( &findme, (const void*) base, qty, sizeof(String), alpha_cmp ) ); for ( i=0; iaddr ); assert ( to->addr ); assert ( to->size == sizeof(long) ); errno = 0; *(long*)to->addr = strtol ( (char*)from->addr, NULL, 10 ); return ( !errno ); }