#include <tk.h> int Tk_ConfigureWidget(interp, tkwin, specs, argc, argv, widgRec, flags) int Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags) int Tk_ConfigureValue(interp, tkwin, specs, widgRec, argvName, flags) Tk_FreeOptions(specs, widgRec, display, flags)
Note: Tk_ConfigureWidget should be replaced with the new Tcl_Obj based API Tk_SetOptions. The old interface is retained for backward compatibility.
Tk_ConfigureWidget is called to configure various aspects of a widget, such as colors, fonts, border width, etc. It is intended as a convenience procedure to reduce the amount of code that must be written in individual widget managers to handle configuration information. It is typically invoked when widgets are created, and again when the configure command is invoked for a widget. Although intended primarily for widgets, Tk_ConfigureWidget can be used in other situations where argc-argv information is to be used to fill in a record structure, such as configuring graphical elements for a canvas widget or entries of a menu.
Tk_ConfigureWidget processes a table specifying the configuration options that are supported (specs) and a collection of command-line arguments (argc and argv) to fill in fields of a record (widgRec). It uses the option database and defaults specified in specs to fill in fields of widgRec that are not specified in argv. Tk_ConfigureWidget normally returns the value TCL_OK; in this case it does not modify interp. If an error occurs then TCL_ERROR is returned and Tk_ConfigureWidget will leave an error message in interp->result in the standard Tcl fashion. In the event of an error return, some of the fields of widgRec could already have been set, if configuration information for them was successfully processed before the error occurred. The other fields will be set to reasonable initial values so that Tk_FreeOptions can be called for cleanup.
The specs array specifies the kinds of configuration options expected by the widget. Each of its entries specifies one configuration option and has the following structure:
typedef struct { int type; char *argvName; char *dbName; char *dbClass; char *defValue; int offset; int specFlags; Tk_CustomOption *customPtr; } Tk_ConfigSpec;
Tk_ConfigureWidget first processes argv to see which (if any) configuration options are specified there. Argv must contain an even number of fields; the first of each pair of fields must match the argvName of some entry in specs (unique abbreviations are acceptable), and the second field of the pair contains the value for that configuration option. If there are entries in spec for which there were no matching entries in argv, Tk_ConfigureWidget uses the dbName and dbClass fields of the specs entry to probe the option database; if a value is found, then it is used as the value for the option. Finally, if no entry is found in the option database, the defValue field of the specs entry is used as the value for the configuration option. If the defValue is NULL, or if the TK_CONFIG_DONT_SET_DEFAULT bit is set in flags, then there is no default value and this specs entry will be ignored if no value is specified in argv or the option database.
Once a string value has been determined for a configuration option, Tk_ConfigureWidget translates the string value into a more useful form, such as a color if type is TK_CONFIG_COLOR or an integer if type is TK_CONFIG_INT. This value is then stored in the record pointed to by widgRec. This record is assumed to contain information relevant to the manager of the widget; its exact type is unknown to Tk_ConfigureWidget. The offset field of each specs entry indicates where in widgRec to store the information about this configuration option. You should use the Tk_Offset macro to generate offset values (see below for a description of Tk_Offset). The location indicated by widgRec and offset will be referred to as the ``target'' in the descriptions below.
The type field of each entry in specs determines what to do with the string value of that configuration option. The legal values for type, and the corresponding actions, are:
In some cases it is useful to generate multiple resources from a single configuration value. For example, a color name might be used both to generate the background color for a widget (using TK_CONFIG_COLOR) and to generate a 3-D border to draw around the widget (using TK_CONFIG_BORDER). In cases like this it is possible to specify that several consecutive entries in specs are to be treated as a group. The first entry is used to determine a value (using its argvName, dbName, dbClass, and defValue fields). The value will be processed several times (one for each entry in the group), generating multiple different resources and modifying multiple targets within widgRec. Each of the entries after the first must have a NULL value in its argvName field; this indicates that the entry is to be grouped with the entry that precedes it. Only the type and offset fields are used from these follow-on entries.
The flags argument passed to Tk_ConfigureWidget is used in conjunction with the specFlags fields in the entries of specs to provide additional control over the processing of configuration options. These values are used in three different ways as described below.
First, if the flags argument to Tk_ConfigureWidget has the TK_CONFIG_ARGV_ONLY bit set (i.e., flags | TK_CONFIG_ARGV_ONLY != 0), then the option database and defValue fields are not used. In this case, if an entry in specs does not match a field in argv then nothing happens: the corresponding target is not modified. This feature is useful when the goal is to modify certain configuration options while leaving others in their current state, such as when a configure widget command is being processed.
Second, the specFlags field of an entry in specs may be used to control the processing of that entry. Each specFlags field may consists of an OR-ed combination of the following values:
The TK_CONFIG_MONO_ONLY and TK_CONFIG_COLOR_ONLY flags are typically used to specify different default values for monochrome and color displays. This is done by creating two entries in specs that are identical except for their defValue and specFlags fields. One entry should have the value TK_CONFIG_MONO_ONLY in its specFlags and the default value for monochrome displays in its defValue; the other entry should have the value TK_CONFIG_COLOR_ONLY in its specFlags and the appropriate defValue for color displays.
Third, it is possible to use flags and specFlags together to selectively disable some entries. This feature is not needed very often. It is useful in cases where several similar kinds of widgets are implemented in one place. It allows a single specs table to be created with all the configuration options for all the widget types. When processing a particular widget type, only entries relevant to that type will be used. This effect is achieved by setting the high-order bits (those in positions equal to or greater than TK_CONFIG_USER_BIT) in specFlags values or in flags. In order for a particular entry in specs to be used, its high-order bits must match exactly the high-order bits of the flags value passed to Tk_ConfigureWidget. If a specs table is being used for N different widget types, then N of the high-order bits will be used. Each specs entry will have one of more of those bits set in its specFlags field to indicate the widget types for which this entry is valid. When calling Tk_ConfigureWidget, flags will have a single one of these bits set to select the entries for the desired widget type. For a working example of this feature, see the code in tkButton.c.
The Tk_Offset macro is provided as a safe way of generating the offset values for entries in Tk_ConfigSpec structures. It takes two arguments: the name of a type of record, and the name of a field in that record. It returns the byte offset of the named field in records of the given type.
The Tk_ConfigureInfo procedure may be used to obtain information about one or all of the options for a given widget. Given a token for a window (tkwin), a table describing the configuration options for a class of widgets (specs), a pointer to a widget record containing the current information for a widget (widgRec), and a NULL argvName argument, Tk_ConfigureInfo generates a string describing all of the configuration options for the window. The string is placed in interp->result. Under normal circumstances it returns TCL_OK; if an error occurs then it returns TCL_ERROR and interp->result contains an error message.
If argvName is NULL, then the value left in interp->result by Tk_ConfigureInfo consists of a list of one or more entries, each of which describes one configuration option (i.e. one entry in specs). Each entry in the list will contain either two or five values. If the corresponding entry in specs has type TK_CONFIG_SYNONYM, then the list will contain two values: the argvName for the entry and the dbName (synonym name). Otherwise the list will contain five values: argvName, dbName, dbClass, defValue, and current value. The current value is computed from the appropriate field of widgRec by calling procedures like Tk_NameOfColor.
If the argvName argument to Tk_ConfigureInfo is non-NULL, then it indicates a single option, and information is returned only for that option. The string placed in interp->result will be a list containing two or five values as described above; this will be identical to the corresponding sublist that would have been returned if argvName had been NULL.
The flags argument to Tk_ConfigureInfo is used to restrict the specs entries to consider, just as for Tk_ConfigureWidget.
Tk_ConfigureValue takes arguments similar to Tk_ConfigureInfo; instead of returning a list of values, it just returns the current value of the option given by argvName (argvName must not be NULL). The value is returned in interp->result and TCL_OK is normally returned as the procedure's result. If an error occurs in Tk_ConfigureValue (e.g., argvName is not a valid option name), TCL_ERROR is returned and an error message is left in interp->result. This procedure is typically called to implement cget widget commands.
The Tk_FreeOptions procedure may be invoked during widget cleanup to release all of the resources associated with configuration options. It scans through specs and for each entry corresponding to a resource that must be explicitly freed (e.g. those with type TK_CONFIG_COLOR), it frees the resource in the widget record. If the field in the widget record does not refer to a resource (e.g. it contains a null pointer) then no resource is freed for that entry. After freeing a resource, Tk_FreeOptions sets the corresponding field of the widget record to null.
Applications can extend the built-in configuration types with additional configuration types by writing procedures to parse and print options of the a type and creating a structure pointing to those procedures:
typedef struct Tk_CustomOption { Tk_OptionParseProc *parseProc; Tk_OptionPrintProc *printProc; ClientData clientData; } Tk_CustomOption; typedef int Tk_OptionParseProc( ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, char *value, char *widgRec, int offset); typedef char *Tk_OptionPrintProc( ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr);
The parseProc procedure is invoked by Tk_ConfigureWidget to parse a string and store the resulting value in the widget record. The clientData argument is a copy of the clientData field in the Tk_CustomOption structure. The interp argument points to a Tcl interpreter used for error reporting. Tkwin is a copy of the tkwin argument to Tk_ConfigureWidget. The value argument is a string describing the value for the option; it could have been specified explicitly in the call to Tk_ConfigureWidget or it could come from the option database or a default. Value will never be a null pointer but it may point to an empty string. RecordPtr is the same as the widgRec argument to Tk_ConfigureWidget; it points to the start of the widget record to modify. The last argument, offset, gives the offset in bytes from the start of the widget record to the location where the option value is to be placed. The procedure should translate the string to whatever form is appropriate for the option and store the value in the widget record. It should normally return TCL_OK, but if an error occurs in translating the string to a value then it should return TCL_ERROR and store an error message in interp->result.
The printProc procedure is called by Tk_ConfigureInfo to produce a string value describing an existing option. Its clientData, tkwin, widgRec, and offset arguments all have the same meaning as for Tk_OptionParseProc procedures. The printProc procedure should examine the option whose value is stored at offset in widgRec, produce a string describing that option, and return a pointer to the string. If the string is stored in dynamically-allocated memory, then the procedure must set *freeProcPtr to the address of a procedure to call to free the string's memory; Tk_ConfigureInfo will call this procedure when it is finished with the string. If the result string is stored in static memory then printProc need not do anything with the freeProcPtr argument.
Once parseProc and printProc have been defined and a Tk_CustomOption structure has been created for them, options of this new type may be manipulated with Tk_ConfigSpec entries whose type fields are TK_CONFIG_CUSTOM and whose customPtr fields point to the Tk_CustomOption structure.
Although the explanation of Tk_ConfigureWidget is fairly complicated, its actual use is pretty straightforward. The easiest way to get started is to copy the code from an existing widget. The library implementation of frames (tkFrame.c) has a simple configuration table, and the library implementation of buttons (tkButton.c) has a much more complex table that uses many of the fancy specFlags mechanisms.