|
|
| |
Internals(3) |
User Contributed Perl Documentation |
Internals(3) |
Tk::Internals - 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.
- PreCompiling
- Before the actual compilation stage a script scans the source and extracts
the subcommands of different commands. This information resides in the
file "pTk/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 "Tk" calls the subroutine
Boot_Glue() from the module
"tkGlue.c", and this subroutine includes
the file (with appropriate macro definitions).
- Inside "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.
- Inside "$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.
- Inside "$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.
- Inside "$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).
- Inside "$text->insert('insert','Hello, world!');"
- As we discussed above, the subcommands of widget procedures correspond to
XSUB "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>
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |