Widget compilation

Adding a new Tk widget to the interpreter is generally a simple hack. Most of the time, extension widgets written for Tcl/Tk can be added to the interpreter without modifying the source code of the widget. However, there is no unique method to add a widget to the Tcl interpreter; consequently, what is given below is a set of hints to widget integration rather than a always working recipe. To illustrate this section, we will see how we can add the fscale widget (a floating-point scale widget available on the Tcl/Tk repository in the tkFScale-?.?.tar.gz file)2.

Generally, the code of a Tcl/Tk extension widget can be divided in two parts: the code which implement widget's behavior and the extension initialization code. Extension initialization code, in Tcl/Tk, must be placed in the procedure Tcl_AppInit which is located in the file tkAppInit.c. If the extension package adds a lot of widgets, it generally defines a function to do all the initializations. On the other hand, if the extension only defines a single widget, the extension code generally consists to call the C function Tcl_CreateCommand for each new widget defined in the extension. Tcl_CreateCommand is the Tcl standard way to add a new command. This function also exists in the interpreter; it creates a new Tk command object [#!Gallesio95-1!#]. The prototype of this function is:
\begin{Code}
\begin{listing}[200]{2}
void Tcl_CreateCommand(Tcl_Interp *interp,
...
...ClientData clientData,
Tcl_CmdDeleteProc *deleteProc));
\end{listing}\end{Code}

For ,

The usual way to integrate this initialization code in a Tcl interpreter consists to patch the tkAppInit.c file to add the call to the initialization (or the Tcl_CreateCommand) function. To add an extension written for Tcl/Tk to , all that is needed consists to adapt the initialization code for . For example, the fscale widget initialization code adds the following call in the body of the Tcl_AppInit function:
\begin{Code}
\begin{listing}[200]{2}
Tcl_CreateCommand(interp, ''fscale'', Tk_FScaleCmd,
(ClientData) main,
(void (*)()) NULL);
\end{listing}\end{Code}

For , this call can be written
\begin{Code}
\begin{listing}[200]{2}
Tcl_CreateCommand(STk_main_interp, ''fscale...
...a) Tk_MainWindow(STk_main_interp),
(void (*)()) NULL);
\end{listing}\end{Code}

This call must executed before trying to create a new fscale widget.