Tk_ConfigureWidget(3)

🌸 NAME 🌸

Tk_ConfigureWidget(3) β€” Tk Library Procedures, bestie. The whole squad is Tk_ConfigureWidget, Tk_ConfigureInfo, Tk_ConfigureValue, and Tk_FreeOptions, and their job is literally to process configuration options for widgets. πŸ’…


✨ SYNOPSIS ✨

#include <tk.h>

int
Tk_ConfigureWidget(interp, tkwin, specs, objc, objv, 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)

🧚 ARGUMENTS 🧚

  • Tcl_Interp *interp (in) β€” the interpreter used for returning error messages.
  • Tk_Window tkwin (in) β€” the window used to represent the widget (needed to set up X resources).
  • const Tk_ConfigSpec *specs (in) β€” pointer to the table specifying the legal configuration options for this widget.
  • Tcl_Size objc (in) β€” number of arguments in objv.
  • Tcl_Obj *const * objv (in) β€” command-line options for configuring the widget.
  • char *widgRec (in/out) β€” points to the widget record structure. Fields in this structure get modified by Tk_ConfigureWidget to hold configuration information.
  • int flags (in) β€” if non-zero, then it specifies an OR-ed combination of flags that control the processing of configuration information. TK_CONFIG_ARGV_ONLY causes the option database and defaults to be ignored, and flag bits TK_CONFIG_USER_BIT and higher are used to selectively disable entries in specs.
  • type name type (in) β€” the name of the type of a widget record.
  • field name field (in) β€” the name of a field in records of type type.
  • const char *argvName (in) β€” the name used on Tcl command lines to refer to a particular option (e.g. when creating a widget or invoking the configure widget command). If non-NULL, then information is returned only for this option. If NULL, then information is returned for all available options.
  • Display *display (in) β€” display containing the widget whose record is being freed; needed in order to free up resources.

πŸ’… DESCRIPTION πŸ’…

⚠️ Real talk, bestie: 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 objc-objv 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 (objc and objv) 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 objv. 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 interpreter interp's 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;
    const char *argvName;
    const char *dbName;
    const char *dbClass;
    const char *defValue;
    Tcl_Size offset;
    int specFlags;
    const Tk_CustomOption *customPtr;
} Tk_ConfigSpec;

The type field indicates what type of configuration option this is (e.g. TK_CONFIG_COLOR for a color value, or TK_CONFIG_INT for an integer value). The type field indicates how to use the value of the option (more on this below). The argvName field is a string such as -font or -bg, which is compared with the values in objv (if argvName is NULL it means this is a grouped entry; see GROUPED ENTRIES below). The dbName and dbClass fields are used to look up a value for this option in the option database. The defValue field specifies a default value for this configuration option if no value is specified in either objv or the option database. offset indicates where in widgRec to store information about this option, and specFlags contains additional information to control the processing of this configuration option (see FLAGS below). The last field, customPtr, is only used if type is TK_CONFIG_CUSTOM; see CUSTOM OPTION TYPES below.

Tk_ConfigureWidget first processes objv 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 objv, 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 objv 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 offsetof macro to generate offset values. 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:

  • TK_CONFIG_ACTIVE_CURSOR β€” the value must be an ASCII string identifying a cursor in a form suitable for passing to Tk_GetCursor. The value is converted to a Tk_Cursor by calling Tk_GetCursor and the result is stored in the target. In addition, the resulting cursor is made the active cursor for tkwin by calling XDefineCursor. If TK_CONFIG_NULL_OK is specified in specFlags then the value may be an empty string, in which case the target and tkwin's active cursor will be set to None. If the previous value of the target was not None, then it is freed by passing it to Tk_FreeCursor.
  • TK_CONFIG_ANCHOR β€” the value must be an ASCII string identifying an anchor point in one of the ways accepted by Tk_GetAnchor. The string is converted to a Tk_Anchor by calling Tk_GetAnchor and the result is stored in the target.
  • TK_CONFIG_BITMAP β€” the value must be an ASCII string identifying a bitmap in a form suitable for passing to Tk_GetBitmap. The value is converted to a Pixmap by calling Tk_GetBitmap and the result is stored in the target. If TK_CONFIG_NULL_OK is specified in specFlags then the value may be an empty string, in which case the target is set to None. If the previous value of the target was not None, then it is freed by passing it to Tk_FreeBitmap.
  • TK_CONFIG_BOOLEAN β€” the value must be an ASCII string specifying a boolean value. Any of the values true, yes, on, or 1, or an abbreviation of one of these values, means true; any of the values false, no, off, or 0, or an abbreviation of one of these values, means false. The target is expected to be an integer; for true values it will be set to 1 and for false values it will be set to 0.
  • TK_CONFIG_BORDER β€” the value must be an ASCII string identifying a border color in a form suitable for passing to Tk_Get3DBorder. The value is converted to a (Tk_3DBorder *) by calling Tk_Get3DBorder and the result is stored in the target. If TK_CONFIG_NULL_OK is specified in specFlags then the value may be an empty string, in which case the target will be set to NULL. If the previous value of the target was not NULL, then it is freed by passing it to Tk_Free3DBorder.
  • TK_CONFIG_CAP_STYLE β€” the value must be an ASCII string identifying a cap style in one of the ways accepted by Tk_GetCapStyle. The string is converted to an integer value corresponding to the cap style by calling Tk_GetCapStyle and the result is stored in the target.
  • TK_CONFIG_COLOR β€” your value has to be an ASCII string that names a color in whatever form Tk_GetColor will accept, k? It gets converted to an (XColor *) by calling Tk_GetColor and then the result gets parked in the target. If TK_CONFIG_NULL_OK is sitting in specFlags then an empty string is allowed and the target gets set to None. And bestie, if the target's previous value wasn't NULL, it gets freed by handing it over to Tk_FreeColor. No leaks here πŸ’…
  • TK_CONFIG_CURSOR β€” literally identical to TK_CONFIG_ACTIVE_CURSOR, with exactly one tiny difference: the new cursor does not get made the active one for tkwin. That's it, that's the whole vibe.
  • TK_CONFIG_CUSTOM β€” this one's for the apps that wanna invent brand-new option types ✨. The customPtr field of the entry points at a structure that defines the new option type. The deets live in the CUSTOM OPTION TYPES section below, iykyk.
  • TK_CONFIG_DOUBLE β€” the value must be an ASCII floating-point number in the format accepted by strtol. The string gets converted to a double value and that value goes in the target. (Yes, strtol, we're just reporting what the page says πŸ”₯)
  • TK_CONFIG_END β€” the "we're so done here" marker for the table πŸŽ€. The last entry in specs must have this type; every one of its other fields is ignored and it will never ever match any arguments. Iconic, unbothered, never matching.
  • TK_CONFIG_FONT β€” the value has to be an ASCII string naming a font in a form suitable for passing to Tk_GetFont. It gets converted to a Tk_Font by calling Tk_GetFont and the result lands in the target. If TK_CONFIG_NULL_OK is in specFlags, an empty string is fine and the target becomes NULL. If the previous value wasn't NULL, it gets freed by passing it to Tk_FreeFont. Cleanup queen 🧚
  • TK_CONFIG_INT β€” value's gotta be an ASCII integer string in the format strtol accepts (like, the 0 and 0x prefixes may be used to specify octal or hexadecimal numbers, respectively πŸ‘€). String β†’ integer value, integer β†’ stored in the target.
  • TK_CONFIG_JOIN_STYLE β€” the value must be an ASCII string identifying a join style, in one of the ways Tk_GetJoinStyle accepts. The string gets converted to an integer value corresponding to the join style by calling Tk_GetJoinStyle, and that result gets stored in the target.
  • TK_CONFIG_JUSTIFY β€” the value is an ASCII string naming a justification method, in one of the ways Tk_GetJustify accepts. It gets converted to a Tk_Justify by calling Tk_GetJustify, and the result goes in the target. Justified, fr.
  • TK_CONFIG_MM β€” the value specifies a screen distance in one of the forms acceptable to Tk_GetScreenMM. The string gets converted to a double-precision floating-point distance in millimeters and that value gets stored in the target 🌸
  • TK_CONFIG_PIXELS β€” the value specifies screen units in one of the forms acceptable to Tk_GetPixels. String β†’ integer distance in pixels, and the value goes right into the target.
  • TK_CONFIG_RELIEF β€” the value must be an ASCII string identifying a relief, in a form suitable for passing to Tk_GetRelief. It gets converted to an integer relief value by calling Tk_GetRelief and the result gets stored in the target. Give it that 3-D texture, bestie πŸ¦‹
  • TK_CONFIG_STRING β€” a copy of the value gets made by allocating memory with Tcl_Alloc and copying the value into that dynamically-allocated space. A pointer to the new string gets stored in the target. If TK_CONFIG_NULL_OK is in specFlags then an empty string is allowed and the target gets set to NULL. And if the previous value of the target wasn't NULL, it gets freed by passing it to Tcl_Free. So thorough 🫢
  • TK_CONFIG_SYNONYM β€” this type value marks special entries in specs that are synonyms for other entries πŸ‘‘. If an objv value matches the argvName of a TK_CONFIG_SYNONYM entry, that entry is not used directly. Instead, Tk_ConfigureWidget searches specs for another entry whose argvName is the same as the dbName field in the TK_CONFIG_SYNONYM entry; that new entry gets used just as if its argvName had matched the objv value. The synonym mechanism is what lets multiple objv values point at a single configuration option β€” like -background and -bg. Two names, one iconic option ✨
  • TK_CONFIG_UID β€” the value gets translated to a Tk_Uid (by passing it to Tk_GetUid) and the resulting value gets stored in the target. If TK_CONFIG_NULL_OK is in specFlags and the value is an empty string, then the target gets set to NULL.
  • TK_CONFIG_WINDOW β€” the value must be a window path name. It gets translated to a Tk_Window token, and the token gets stored in the target. Path name β†’ token, slay πŸ”₯

🫢 GROUPED ENTRIES 🫢

So sometimes it's genuinely useful to generate multiple resources out of a single configuration value, and that's the whole point of grouping. Picture this: a color name might get used both to generate the background color for a widget (via TK_CONFIG_COLOR) and to generate a 3-D border to draw around that widget (via TK_CONFIG_BORDER). Two resources, one value, main character energy 🌈

In cases like that, you can specify that several consecutive entries in specs get treated as a group. The first entry is the one that determines a value β€” it uses its argvName, dbName, dbClass, and defValue fields to do it. Then that value gets processed several times (once for each entry in the group), which generates multiple different resources and modifies multiple targets within widgRec πŸŽ€

The rules for the follow-ons, no cap:

  • Each of the entries after the first must have a NULL value in its argvName field.
  • That NULL is the signal that the entry is to be grouped with the entry that precedes it.
  • From these follow-on entries, only the type and offset fields are used. That's it, nothing else.

πŸ’… FLAGS πŸ’…

The flags argument you pass to Tk_ConfigureWidget works together with the specFlags fields in the entries of specs to give you extra control over how configuration options get processed. These values get used in three different ways, and we're gonna walk through all of them πŸ’–

✨ 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 that case, if an entry in specs doesn't match a field in objv, then nothing happens at all β€” the corresponding target is not modified. This is lowkey the move when your goal is to modify certain configuration options while leaving the others in whatever state they're currently in, like 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 can be an OR-ed combination of these values, and yes, we're listing every single one:

  • TK_CONFIG_COLOR_ONLY β€” if this bit is set, the entry will only be considered if the display for tkwin has more than one bit plane. If the display is monochromatic, this specs entry gets ignored. Color-only babes only 🎨
  • TK_CONFIG_MONO_ONLY β€” if this bit is set, the entry will only be considered if the display for tkwin has exactly one bit plane. If the display is not monochromatic, this specs entry gets ignored. Mono girlies stay winning πŸ–€
  • TK_CONFIG_NULL_OK β€” this bit is only relevant for some types of entries (peep the descriptions of the various entry types above, bestie). If it's set, it means an empty string value for the field is acceptable, and if that happens then the target should be set to NULL or None, depending on the type of the target. This flag is typically used to let a feature get turned off entirely β€” like setting a cursor value to None so a window just inherits its parent's cursor. If this bit is not set, then empty strings get processed as strings, which generally results in an error πŸ’€ so like, be aware.
  • TK_CONFIG_DONT_SET_DEFAULT β€” if this bit is one, it means the defValue field of the entry should only be used for returning the default value in Tk_ConfigureInfo. In calls to Tk_ConfigureWidget no default will be supplied for entries with this flag set; it's assumed that the caller already supplied a default value in the target location. It's a performance optimization for when processing the default string is expensive: the client can compute the default once, save the value, and provide it before calling Tk_ConfigureWidget. Work smarter, not harder πŸ’…

The TK_CONFIG_MONO_ONLY and TK_CONFIG_COLOR_ONLY flags are typically used to specify different default values for monochrome and color displays. How do you do it? Create two entries in specs that are identical except for their defValue and specFlags fields 🫢

  1. One entry should have the value TK_CONFIG_MONO_ONLY in its specFlags and the default value for monochrome displays in its defValue.
  2. The other entry should have the value TK_CONFIG_COLOR_ONLY in its specFlags and the appropriate defValue for color displays.

Two entries, one vibe check, everyone's happy 🌈

πŸ”₯ Third πŸ”₯

It's also possible to use flags and specFlags together to selectively disable some entries. This feature is not needed very often β€” ngl, it's a bit of a niche one β€” but it's useful in cases where several similar kinds of widgets are implemented in one place. What it gives you is a single specs table created with all the configuration options for all the widget types. Then, when you're processing a particular widget type, only the entries relevant to that type get used πŸ‘‘

Here's how that effect is achieved: you set the high-order bits (those in positions equal to or greater than TK_CONFIG_USER_BIT) in specFlags values or in flags. For a particular entry in specs to actually get used, its high-order bits must match exactly the high-order bits of the flags value passed to Tk_ConfigureWidget. So if a specs table is being used for N different widget types, then N of those high-order bits will be used. Each specs entry will have one or more of those bits set in its specFlags field to indicate the widget types for which this entry is valid. Then when you call 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. Go look, it's giving reference implementation πŸŽ€

πŸ’– TK_CONFIGUREINFO πŸ’–

okay so Tk_ConfigureInfo is the one you call when you want the tea β˜• on one option or literally all the options for a widget. Give it 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, and Tk_ConfigureInfo generates a string describing all of the configuration options for the window. The string is placed in interpreter interp's result. Under normal circumstances it returns TCL_OK; if an error occurs then it returns TCL_ERROR and the interpreter's result will contain an error message.

If argvName is NULL, then the value left in the interpreter's 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 the interpreter's 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 🫢

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, bestie β€” no cap). The value is returned in interpreter interp's 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 the interpreter's result. This procedure is typically called to implement cget widget commands.


🌸 TK_FREEOPTIONS 🌸

Tk_FreeOptions is the cleanup queen 🧹. It 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.


πŸ¦‹ CUSTOM OPTION TYPES πŸ¦‹

Applications can extend the built-in configuration types with additional configuration types by writing procedures to parse and print options of the new type and creating a structure pointing to those procedures:

typedef struct {
    Tk_OptionParseProc *parseProc;
    Tk_OptionPrintProc *printProc;
    void *clientData;
} Tk_CustomOption;

typedef int Tk_OptionParseProc(
        void *clientData,
        Tcl_Interp *interp,
        Tk_Window tkwin,
        const char *value,
        char *widgRec,
        Tcl_Size offset);

typedef const char *Tk_OptionPrintProc(
        void *clientData,
        Tk_Window tkwin,
        char *widgRec,
        Tcl_Size offset,
        Tcl_FreeProc **freeProcPtr);

The Tk_CustomOption structure contains three fields, which are pointers to the two procedures and a clientData value to be passed to those procedures when they are invoked. The clientData value typically points to a structure containing information that is needed by the procedures when they are parsing and printing options.

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 interpreter interp's 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.


✨ EXAMPLES ✨

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.


πŸ‘€ SEE ALSO πŸ‘€

Tk_SetOptions(3)


πŸ”₯ KEYWORDS πŸ”₯

anchor, bitmap, boolean, border, cap style, color, configuration options, cursor, custom, double, font, integer, join style, justify, millimeters, pixels, relief, synonym, uid


and that's the whole page, bestie 🫢 source/version is Tk 4.1, dated 4.1, and the manpage is Tk_ConfigureWidget(3) β€” iconic, honestly πŸ’…βœ¨

πŸ“¦ where this page comes from