Index: doc/SetOptions.3 ================================================================== --- doc/SetOptions.3 +++ doc/SetOptions.3 @@ -318,10 +318,21 @@ If this bit is set for an option then no default value will be set in \fBTk_InitOptions\fR for this option. Neither the option database, nor any system default value, nor \fIoptionTable\fR are used to give a default value to this option. Instead it is assumed that the caller has already supplied a default value in the widget code. +.TP +\fBTK_OPTION_ENUM_VAR\fR +If this value is set for an option, then it indicates the the +internalOffset points to an enum variable in stead of an int variable. +Only useful in combination with \fBTK_OPTION_STRING_TABLE\fR +.TP +\fBTK_OPTION_VAR(type)\fR +If this value is set for an option, then it indicates the the +internalOffset points to a \fItype\fR variable in stead of an int variable. +Only useful in combination with \fBTK_OPTION_STRING_TABLE\fR or +\fBTK_OPTION_BOOLEAN\fR .PP The \fItype\fR field of each Tk_OptionSpec structure determines how to parse the value of that configuration option. The legal value for \fItype\fR, and the corresponding actions, are described below. If the type requires a \fItkwin\fR value to be Index: generic/tk.h ================================================================== --- generic/tk.h +++ generic/tk.h @@ -228,10 +228,12 @@ * Tk_ConfigSpec structures, so be sure to coordinate any changes carefully. */ #define TK_OPTION_NULL_OK (1 << 0) #define TK_OPTION_DONT_SET_DEFAULT (1 << 3) +#define TK_OPTION_VAR(type) ((int)(sizeof(type)&(sizeof(int)-1))<<6) +#define TK_OPTION_ENUM_VAR TK_OPTION_VAR(Tk_OptionType) /* * The following structure and function types are used by TK_OPTION_CUSTOM * options; the structure holds pointers to the functions needed by the Tk * option config code to handle a custom option. Index: generic/tkConfig.c ================================================================== --- generic/tkConfig.c +++ generic/tkConfig.c @@ -25,17 +25,16 @@ #include "tkInt.h" #include "tkFont.h" /* - * The following encoding is used in TYPE_FLAGS: + * The following encoding is used in TK_OPTION_VAR: * - * if sizeof(type) == sizeof(int) => TYPE_FLAGS(type) = 0 - * if sizeof(type) == 1 => TYPE_FLAGS(type) = 64 - * if sizeof(type) == 2 => TYPE_FLAGS(type) = 128 + * if sizeof(type) == sizeof(int) => TK_OPTION_VAR(type) = 0 + * if sizeof(type) == 1 => TK_OPTION_VAR(type) = 64 + * if sizeof(type) == 2 => TK_OPTION_VAR(type) = 128 */ -#define TYPE_FLAGS(type) (((int)(sizeof(type)&(sizeof(int)-1))<<6)) #define TYPE_MASK (((((int)sizeof(int)-1))|3)<<6) /* * The following definition keeps track of all of * the option tables that have been created for a thread. @@ -633,12 +632,24 @@ Tcl_GetString(valuePtr), "\"", NULL); } return TCL_ERROR; } if (internalPtr != NULL) { - *((int *) oldInternalPtr) = *((int *) internalPtr); - *((int *) internalPtr) = newBool; + if (optionPtr->specPtr->flags & TYPE_MASK) { + if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) { + *((char *) oldInternalPtr) = *((char *) internalPtr); + *((char *) internalPtr) = newBool; + } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) { + *((short *) oldInternalPtr) = *((short *) internalPtr); + *((short *) internalPtr) = newBool; + } else { + Tcl_Panic("Invalid flags for %s", "TK_OPTION_BOOLEAN"); + } + } else { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = newBool; + } } break; } case TK_OPTION_INT: { int newInt; @@ -748,14 +759,14 @@ return TCL_ERROR; } } if (internalPtr != NULL) { if (optionPtr->specPtr->flags & TYPE_MASK) { - if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(char)) { + if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) { *((char *) oldInternalPtr) = *((char *) internalPtr); *((char *) internalPtr) = newValue; - } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(short)) { + } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) { *((short *) oldInternalPtr) = *((short *) internalPtr); *((short *) internalPtr) = newValue; } else { Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE"); } @@ -1479,10 +1490,22 @@ char *ptr = (char *) &savePtr->items[i].internalForm; CLANG_ASSERT(internalPtr); switch (specPtr->type) { case TK_OPTION_BOOLEAN: + if (optionPtr->specPtr->flags & TYPE_MASK) { + if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) { + *((char *) internalPtr) = *((char *) ptr); + } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) { + *((short *) internalPtr) = *((short *) ptr); + } else { + Tcl_Panic("Invalid flags for %s", "TK_OPTION_BOOLEAN"); + } + } else { + *((int *) internalPtr) = *((int *) ptr); + } + break; case TK_OPTION_INT: case TK_OPTION_INDEX: *((int *) internalPtr) = *((int *) ptr); break; case TK_OPTION_DOUBLE: @@ -1491,13 +1514,13 @@ case TK_OPTION_STRING: *((char **) internalPtr) = *((char **) ptr); break; case TK_OPTION_STRING_TABLE: if (optionPtr->specPtr->flags & TYPE_MASK) { - if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(char)) { + if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) { *((char *) internalPtr) = *((char *) ptr); - } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(short)) { + } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) { *((short *) internalPtr) = *((short *) ptr); } else { Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE"); } } else { @@ -1958,15 +1981,28 @@ void *internalPtr; /* Points to internal value of option in record. */ if (optionPtr->specPtr->internalOffset != TCL_INDEX_NONE) { internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset; switch (optionPtr->specPtr->type) { - case TK_OPTION_BOOLEAN: - if (*((int *) internalPtr) != -1) { - objPtr = Tcl_NewBooleanObj(*((int *)internalPtr)); + case TK_OPTION_BOOLEAN: { + int value; + if (optionPtr->specPtr->flags & TYPE_MASK) { + if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) { + value = *((signed char *)internalPtr); + } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) { + value = *((short *)internalPtr); + } else { + Tcl_Panic("Invalid flags for %s", "TK_OPTION_BOOLEAN"); + } + } else { + value = *((int *)internalPtr); + } + if (value != -1) { + objPtr = Tcl_NewBooleanObj(value); } break; + } case TK_OPTION_INT: if (!(optionPtr->specPtr->flags & (TK_OPTION_NULL_OK|TCL_NULL_OK)) || *((int *) internalPtr) != INT_MIN) { objPtr = Tcl_NewWideIntObj(*((int *)internalPtr)); } break; @@ -1994,13 +2030,13 @@ objPtr = Tcl_NewStringObj(*((char **)internalPtr), -1); break; case TK_OPTION_STRING_TABLE: { int value; if (optionPtr->specPtr->flags & TYPE_MASK) { - if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(char)) { + if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) { value = *((signed char *)internalPtr); - } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(short)) { + } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) { value = *((short *)internalPtr); } else { Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE"); } } else { Index: generic/tkEntry.c ================================================================== --- generic/tkEntry.c +++ generic/tkEntry.c @@ -314,11 +314,11 @@ {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, "-validatecommand", 0}, {TK_OPTION_INT, "-width", "width", "Width", DEF_ENTRY_WIDTH, TCL_INDEX_NONE, offsetof(Entry, prefWidth), 0, 0, 0}, {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap", - DEF_SPINBOX_WRAP, TCL_INDEX_NONE, offsetof(Spinbox, wrap), 0, 0, 0}, + DEF_SPINBOX_WRAP, TCL_INDEX_NONE, offsetof(Spinbox, wrap), TK_OPTION_VAR(bool), 0, 0}, {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", DEF_ENTRY_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Entry, scrollCmd), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0} }; Index: generic/tkEntry.h ================================================================== --- generic/tkEntry.h +++ generic/tkEntry.h @@ -13,10 +13,11 @@ #define _TKENTRY #ifndef _TKINT #include "tkInt.h" #endif +#include enum EntryType { TK_ENTRY, TK_SPINBOX }; @@ -213,11 +214,11 @@ /* * Spinbox specific fields for use with configuration settings above. */ - int wrap; /* whether to wrap around when spinning */ + bool wrap; /* whether to wrap around when spinning */ int selElement; /* currently selected control */ int curElement; /* currently mouseover control */ int repeatDelay; /* repeat delay */ Index: generic/tkInt.h ================================================================== --- generic/tkInt.h +++ generic/tkInt.h @@ -17,12 +17,10 @@ #ifndef _TKPORT #include "tkPort.h" #endif -#define TK_OPTION_ENUM_VAR ((int)(sizeof(Tk_OptionType)&(sizeof(int)-1))<<6) - /* * Ensure WORDS_BIGENDIAN is defined correctly: * Needs to happen here in addition to configure to work with fat compiles on * Darwin (where configure runs only once for multiple architectures). */