CallingTk - what is Perl Tk interface doing when you call Tk functions.
This information is worse than useless for perlTk
users, but can of
some help for people interested in using modified Tk source with
perlTk
.
This document is under construction. The information is believed to
be pertinent to the version of portableTk
available when it was
created. All the details are subject to change.
pTk/Methods.def
.
Tk
calls the subroutine Boot_Glue() from the module
tkGlue.c
, and this subroutine includes the file (with appropriate
macro definitions).
use Tk;
The module bootstraps the C code, then loads the Perl libraries. The
heart of the Perl code is contained in the Tk::Widget
library, all the
widgets inherit from this module. Code for toplevels is loaded from
Tk::MainWindow
.
During bootstrap of the C glue code the Xevent::?
codes and a
handful of Tk::Widget
and Tk::Image
routines are defined. (Much
more XSUBs are created from Tk.xs
code.) The widget subcommands are
glued to Perl basing on the list included from pTk/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 Tk::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 new
of Tk::Text
,
the other two return constants. It also puts the class into
depository.
$top = MainWindow->new;
This is quite intuitive. This call goes direct to
Tk::MainWindow::new
, that calls XSUB
Tk::MainWindow::CreateMainWindow
, that calls C subroutine
Tk_CreateMainWindow(). It is a Tk
subroutine, so here black magic
ends (almost).
The only remaining black magic is that the Tk
initialization
routine creates a lot of commands, but the subroutine for creation is
usurped by portableTk and the commands are created in the package
Tk
. 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 Tk::MainWindow
, as it should.
$top->title('Text demo');
The package Tk::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 wm
method of the widget. Here
subcommand is a command with some particular second argument (in this
case "title"
). Recall that the first argument is $self.
Now Tk::Toplevel
@ISA Tk::Widget
, that in turn @ISA Tk
. So a
call to $top->wm('title','Text demo')
calls Tk::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 tkGlue.c
. It gets the data part of
XSUB, creates a SV
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 tk
expects
it. (In fact it can also reorder the arguments if it thinks it is
what you want).
The latter procedure extracts name of tk
procedure and
clientData
from the first argument and makes a call, using Perl
stack as argv
for the procedure. A lot of black magic is performed
afterwards to convert result of the procedure to a Perl array return.
$text = $top->Text(background => $txtBg);
Above we discussed how the command Tk::Widget::Text
is created. The
above command calls it via inheritance. It is translated to
Tk::Text::new($top, background => $txtBg);
The package Tk::Text
has no method new
, so the
Tk::Widget::new
is called. In turn it calls
Tk::Text->DoInit($top)
, that is
Tk::Widget::DoInit(Tk::Text,$top)
, that initializes the bindings if
necessary. Then it creates the name for the widget of the form
.text0
, and calls Tk::text('.text0', background => $txtBg)
(note lowercase). The result of the call is blessed into Tk::Text
,
and the method bindtags
for this object is called.
Now the only thing to discuss is who defines the methods text
and
bindtags
. The answer is that they are defined in tkWindow.c
,
and these commands are created in the package Tk
in the same sweep
that created the command Tk::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
XStoTk
interface).
$text->insert('insert','Hello, world!');
XStoWidget
. This XSUB substitutes the first argument $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 Call_Tk
.
Ilya Zakharevich <ilya@math.ohio-state.edu>