Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | =head1 NAME |
2 | ||
3 | CallingTk - what is Perl Tk interface doing when you call Tk functions. | |
4 | ||
5 | =for category C Programming | |
6 | ||
7 | This information is worse than useless for C<perlTk> users, but can of | |
8 | some help for people interested in using modified Tk source with | |
9 | C<perlTk>. | |
10 | ||
11 | I<This document is under construction. The information is believed to | |
12 | be pertinent to the version of> C<portableTk> I<available when it was | |
13 | created. All the details are subject to change.> | |
14 | ||
15 | =head1 DESCRIPTION | |
16 | ||
17 | =over 4 | |
18 | ||
19 | =item PreCompiling | |
20 | ||
21 | Before the actual compilation stage a script scans the source | |
22 | and extracts the subcommands of different commands. This information | |
23 | resides in the file C<pTk/Methods.def>. | |
24 | ||
25 | =item Compilation | |
26 | ||
27 | During compilation the above file is included in the source of booting | |
28 | routine of dynamic (or static) library. More precisely, the booting | |
29 | code of module C<Tk> calls the subroutine Boot_Glue() from the module | |
30 | C<tkGlue.c>, and this subroutine includes the file (with appropriate | |
31 | macro definitions). | |
32 | ||
33 | =item Inside C<use Tk;> | |
34 | ||
35 | The module bootstraps the C code, then loads the Perl libraries. The | |
36 | heart of the Perl code is contained in the C<Tk::Widget> library, all the | |
37 | widgets inherit from this module. Code for toplevels is loaded from | |
38 | C<Tk::MainWindow>. | |
39 | ||
40 | During bootstrap of the C glue code the C<Xevent::?> codes and a | |
41 | handful of C<Tk::Widget> and C<Tk::Image> routines are defined. (Much | |
42 | more XSUBs are created from C<Tk.xs> code.) The widget subcommands are | |
43 | glued to Perl basing on the list included from C<pTk/Methods.def>. In | |
44 | fact all the subcommands are glued to XSUBs that are related to the | |
45 | same C subroutine XStoWidget(), but have different data parts. | |
46 | ||
47 | During the Perl code bootstrap the method C<Tk::Widget::import> is | |
48 | called. This call requires all the code from particular widget | |
49 | packages. | |
50 | ||
51 | Code from the widget packages calls an obscure command like | |
52 | ||
53 | (bless \"Text")->WidgetClass; | |
54 | ||
55 | This command (actually Tk::Widget::WidgetClass()) creates three | |
56 | routines: Tk::Widget::Text(), Tk::Widget::isText(), and | |
57 | Tk::Text::isText(). The first one is basically C<new> of C<Tk::Text>, | |
58 | the other two return constants. It also puts the class into | |
59 | depository. | |
60 | ||
61 | =item Inside C<$top = MainWindow-E<gt>new;> | |
62 | ||
63 | This is quite intuitive. This call goes direct to | |
64 | C<Tk::MainWindow::new>, that calls XSUB | |
65 | C<Tk::MainWindow::CreateMainWindow>, that calls C subroutine | |
66 | Tk_CreateMainWindow(). It is a C<Tk> subroutine, so here black magic | |
67 | ends (almost). | |
68 | ||
69 | The only remaining black magic is that the C<Tk> initialization | |
70 | routine creates a lot of commands, but the subroutine for creation is | |
71 | usurped by B<portableTk> and the commands are created in the package | |
72 | C<Tk>. They are associated to XSUBs that are related to one of three C | |
73 | subroutines XStoSubCmd(), XStoBind(), or XStoTk(), but have different | |
74 | data parts. | |
75 | ||
76 | The result of the call is blessed into C<Tk::MainWindow>, as it should. | |
77 | ||
78 | =item Inside C<$top-E<gt>title('Text demo');> | |
79 | ||
80 | The package C<Tk::Toplevel> defines a lot of subroutines on the fly on | |
81 | some list. All the commands from the list are converted to the | |
82 | corresponding subcommands of C<wm> method of the widget. Here | |
83 | subcommand is a command with some particular second argument (in this | |
84 | case C<"title">). Recall that the first argument is $self. | |
85 | ||
86 | Now C<Tk::Toplevel> @ISA C<Tk::Widget>, that in turn @ISA C<Tk>. So a | |
87 | call to C<$top-E<gt>wm('title','Text demo')> calls C<Tk::wm>, that is | |
88 | defined during call to Tk_CreateMainWindow(). As it is described | |
89 | above, the XSUB associated to XStoSubCmd() is called. | |
90 | ||
91 | This C routine is defined in C<tkGlue.c>. It gets the data part of | |
92 | XSUB, creates a C<SV> with the name of the command, and calls | |
93 | Call_Tk() with the XSUB data as the first argument, and with the name | |
94 | of XSUB stuffed into the Perl stack in the place there C<tk> expects | |
95 | it. (In fact it can also reorder the arguments if it thinks it is | |
96 | what you want). | |
97 | ||
98 | The latter procedure extracts name of C<tk> procedure and | |
99 | C<clientData> from the first argument and makes a call, using Perl | |
100 | stack as C<argv> for the procedure. A lot of black magic is performed | |
101 | afterwards to convert result of the procedure to a Perl array return. | |
102 | ||
103 | =item Inside C<$text = $top-E<gt>Text(background =E<gt> $txtBg);> | |
104 | ||
105 | Above we discussed how the command C<Tk::Widget::Text> is created. The | |
106 | above command calls it via inheritance. It is translated to | |
107 | ||
108 | Tk::Text::new($top, background => $txtBg); | |
109 | ||
110 | The package C<Tk::Text> has no method C<new>, so the | |
111 | C<Tk::Widget::new> is called. In turn it calls | |
112 | C<Tk::Text-E<gt>DoInit($top)>, that is | |
113 | C<Tk::Widget::DoInit(Tk::Text,$top)>, that initializes the bindings if | |
114 | necessary. Then it creates the name for the widget of the form | |
115 | C<.text0>, and calls C<Tk::text('.text0', background =E<gt> $txtBg)> | |
116 | (note lowercase). The result of the call is blessed into C<Tk::Text>, | |
117 | and the method C<bindtags> for this object is called. | |
118 | ||
119 | Now the only thing to discuss is who defines the methods C<text> and | |
120 | C<bindtags>. The answer is that they are defined in C<tkWindow.c>, | |
121 | and these commands are created in the package C<Tk> in the same sweep | |
122 | that created the command C<Tk::wm> discussed above. | |
123 | ||
124 | So the the same C code that corresponds to the processing of | |
125 | corresponding TCL commands is called here as well (this time via | |
126 | C<XStoTk> interface). | |
127 | ||
128 | =item Inside C<$text-E<gt>insert('insert','Hello, world!');> | |
129 | ||
130 | As we discussed above, the subcommands of widget procedures correspond | |
131 | to XSUB C<XStoWidget>. This XSUB substitutes the first argument $text | |
132 | (that is a hash reference) to an appropriate value from this hash, | |
133 | adds the additional argument after the first one that contains the | |
134 | name of the subcommand extracted from the data part of XSUB, and calls | |
135 | the corresponding Tk C subroutine via C<Call_Tk>. | |
136 | ||
137 | =back | |
138 | ||
139 | Ilya Zakharevich <ilya@math.ohio-state.edu> | |
140 | ||
141 | =cut | |
142 |