man Tk::Internals () - what is Perl Tk interface doing when you call Tk functions.
NAME
CallingTk - what is Perl Tk interface doing when you call Tk functions.
This information is worse than useless for CWperlTk users, but can of some help for people interested in using modified Tk source with CWperlTk.
This document is under construction. The information is believed to be pertinent to the version of CWportableTk available when it was created. All the details are subject to change.
DESCRIPTION
- PreCompiling
- Before the actual compilation stage a script scans the source and extracts the subcommands of different commands. This information resides in the file CWpTk/Methods.def.
- Compilation
-
During compilation the above file is included in the source of booting
routine of dynamic (or static) library. More precisely, the booting
code of module CWTk calls the subroutine Boot_Glue() from the module
CWtkGlue.c, and this subroutine includes the file (with appropriate
macro definitions).
The module bootstraps the C code, then loads the Perl libraries. The
heart of the Perl code is contained in the CWTk::Widget library, all the
widgets inherit from this module. Code for toplevels is loaded from
CWTk::MainWindow.
During bootstrap of the C glue code the CWXevent::? codes and a
handful of CWTk::Widget and CWTk::Image routines are defined. (Much
more XSUBs are created from CWTk.xs code.) The widget subcommands are
glued to Perl basing on the list included from CWpTk/Methods.def. In
fact all the subcommands are glued to XSUBs that are related to the
same C subroutine XStoWidget(), but have different data parts.
During the Perl code bootstrap the method CWTk::Widget::import is
called. This call requires all the code from particular widget
packages.
Code from the widget packages calls an obscure command like
(bless \"Text")->WidgetClass;
This command (actually Tk::Widget::WidgetClass()) creates three routines: Tk::Widget::Text(), Tk::Widget::isText(), and Tk::Text::isText(). The first one is basically CWnew of CWTk::Text, the other two return constants. It also puts the class into depository. This is quite intuitive. This call goes direct to CWTk::MainWindow::new, that calls XSUB CWTk::MainWindow::CreateMainWindow, that calls C subroutine Tk_CreateMainWindow(). It is a CWTk subroutine, so here black magic ends (almost). The only remaining black magic is that the CWTk initialization routine creates a lot of commands, but the subroutine for creation is usurped by portableTk and the commands are created in the package CWTk. They are associated to XSUBs that are related to one of three C subroutines XStoSubCmd(), XStoBind(), or XStoTk(), but have different data parts. The result of the call is blessed into CWTk::MainWindow, as it should. The package CWTk::Toplevel defines a lot of subroutines on the fly on some list. All the commands from the list are converted to the corresponding subcommands of CWwm method of the widget. Here subcommand is a command with some particular second argument (in this case CW"title"). Recall that the first argument is CW$self. Now CWTk::Toplevel CW@ISA CWTk::Widget, that in turn CW@ISA CWTk. So a call to CW$top->wm('title','Text demo') calls CWTk::wm, that is defined during call to Tk_CreateMainWindow(). As it is described above, the XSUB associated to XStoSubCmd() is called. This C routine is defined in CWtkGlue.c. It gets the data part of XSUB, creates a CWSV with the name of the command, and calls Call_Tk() with the XSUB data as the first argument, and with the name of XSUB stuffed into the Perl stack in the place there CWtk expects it. (In fact it can also reorder the arguments if it thinks it is what you want). The latter procedure extracts name of CWtk procedure and CWclientData from the first argument and makes a call, using Perl stack as CWargv for the procedure. A lot of black magic is performed afterwards to convert result of the procedure to a Perl array return. Above we discussed how the command CWTk::Widget::Text is created. The above command calls it via inheritance. It is translated toTk::Text::new($top, background => $txtBg);
The package CWTk::Text has no method CWnew, so the CWTk::Widget::new is called. In turn it calls CWTk::Text->DoInit($top), that is CWTk::Widget::DoInit(Tk::Text,$top), that initializes the bindings if necessary. Then it creates the name for the widget of the form CW.text0, and calls CWTk::text('.text0', background => $txtBg) (note lowercase). The result of the call is blessed into CWTk::Text, and the method CWbindtags for this object is called. Now the only thing to discuss is who defines the methods CWtext and CWbindtags. The answer is that they are defined in CWtkWindow.c, and these commands are created in the package CWTk in the same sweep that created the command CWTk::wm discussed above. So the the same C code that corresponds to the processing of corresponding TCL commands is called here as well (this time via CWXStoTk interface). As we discussed above, the subcommands of widget procedures correspond to XSUB CWXStoWidget. This XSUB substitutes the first argument CW$text (that is a hash reference) to an appropriate value from this hash, adds the additional argument after the first one that contains the name of the subcommand extracted from the data part of XSUB, and calls the corresponding Tk C subroutine via CWCall_Tk.
Ilya Zakharevich <ilya@math.ohio-state.edu>