Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / man / man3 / Tk::pTk.3
.\" Automatically generated by Pod::Man v1.34, Pod::Parser v1.13
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sh \" Subsection heading
.br
.if t .Sp
.ne 5
.PP
\fB\\$1\fR
.PP
..
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. | will give a
.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
.\" expand to `' in nroff, nothing in troff, for use with C<>.
.tr \(*W-|\(bv\*(Tr
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
'br\}
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
.\"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.hy 0
.if n .na
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "PTK 1"
.TH PTK 1 "2000-12-30" "perl v5.8.0" "User Contributed Perl Documentation"
.SH "NAME"
Tk2portableTk \- how to make your \fBTk\fR source portable to other
interpreted languages.
.SH "Author"
.IX Header "Author"
Ilya Zakharevich <ilya@math.ohio\-state.edu> has contributed most of
this document. Many thanks.
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
\&\fBPortableTk\fR is an attempt to make \fBTk\fR useful from other
languages. Currently tk4.0 runs under Perl using this
approach. Below, \fILang\fR is the notation for an external language to
which \fBPortableTk\fR glues \fBTk\fR code.
.PP
The main problem with using the code developed for \fB\s-1TCL\s0\fR with
different languages is the absence of data types: almost anything is
\&\f(CW\*(C`char*\*(C'\fR. It makes automatic translation hopeless. However, if you
\&\f(CW\*(C`typedef\*(C'\fR several new symbols to be \f(CW\*(C`char*\*(C'\fR, you can still use your
code in \fB\s-1TCL\s0\fR, \fIand\fR it will make the automatic translation
possible.
.PP
Another problem with the approach that \*(L"everything is a string\*(R" is
impossibility to have a result that says \*(L"NotApplicable\*(R" without
setting an error. Thus different \fBTk\fR command return different string
values that mean \*(L"error happened\*(R", like \f(CW""\fR, \f(CW" "\fR or
\&\f(CW"??"\fR. Other languages can be more flexible, so in \fBportableTk\fR you
should inform the compiler that what you want to return means \*(L"error\*(R"
(see \*(L"Setting variables\*(R").
.PP
Currently \fBPortableTk\fR uses several different approachs
to simplify translation: several \fB\s-1TCL\s0\fR functions that are especially
dangerous to use are undefined, so you can easily find places that
need to be updated to use Language-independent functions based on
compiler warnings. Eventually a way to use these Language-independent
functions under proper \fB\s-1TCL\s0\fR will be also provided. The end of this
document provides a starting point for such a project.
.SH "Structure of \fBpTk\fP, porting your code"
.IX Header "Structure of pTk, porting your code"
\&\fBpTk\fR, that is a port of \fBTk\fR, is very special with respect to porting
of other code to \fBportableTk\fR. The problem is that currently there is
very little hope to merge the modifications back into \fBTk\fR, so a
special strategy is needed to maintain this port. Do not use this
strategy to port your own code.
.PP
\&\fBpTk\fR is produced from \fBTk\fR via a two-step process: first, some
manual editing (the result is in the subdirectory \f(CW\*(C`mTk\*(C'\fR), and second,
automatic conversion by the \f(CW\*(C`munge\*(C'\fR script (written in Perl). Thus the
subdirectory \f(CW\*(C`pTk/mTk\*(C'\fR contains code with minimal possible difference
from the virgin \fBTk\fR code, so it is easier to \fImerge\fR\|(1) the
differences between \fBTk\fR versions into modified code.
.PP
It looks like the strategy for a portable code should be exactly
opposite: starting from \fB\s-1TCL\s0\fR\-based code, apply \f(CW\*(C`munge\*(C'\fR, and then
hand-edit the resulting code. Probably it is also possible to target
your code to \fBportableTk\fR from scratch, since this will make it
possible to run it under a lot of \fILang\fRuages.
.PP
The only reason anyone would like to look into contents of \f(CW\*(C`pTk/mTk\*(C'\fR
directory is to find out which constructs are not supported by
\&\f(CW\*(C`munge\*(C'\fR. On the other hand, \f(CW\*(C`pTk\*(C'\fR directory contains code that is
conformant to \fBportableTk\fR, so you can look there to find example code.
.PP
\&\f(CW\*(C`munge\*(C'\fR is the script that converts most common \fBTk\fR constructs to
their \f(CW\*(C`portableTk\*(C'\fR equivalent. For your code to qualify, you should
follow \fBTk\fR conventions on indentation and names of variables, in
particular, the array of arguments for the \f(CW\*(C`...CmdProc\*(C'\fR should be
called \f(CW\*(C`argv\*(C'\fR.
.PP
For details on what \f(CW\*(C`munge\*(C'\fR can do, see
\&\*(L"Translation of some \s-1TCL\s0 functions\*(R".
.SH "\fBPortableTk\fP API"
.IX Header "PortableTk API"
.Sh "Checking what you are running under"
.IX Subsection "Checking what you are running under"
\&\fBPortableTk\fR provides a symbol \f(CW\*(C`????\*(C'\fR. If this symbol is defined,
your source is compiled with it.
.Sh "New types of configuration options"
.IX Subsection "New types of configuration options"
\&\fBPortableTk\fR defines several new types of configuration options:
.PP
.Vb 6
\& TK_CONFIG_CALLBACK
\& TK_CONFIG_LANGARG
\& TK_CONFIG_SCALARVAR
\& TK_CONFIG_HASHVAR
\& TK_CONFIG_ARRAYVAR
\& TK_CONFIG_IMAGE
.Ve
.PP
You should use them instead of \s-1TK_CONFIG_STRING\s0 whenever
appropriate. This allows your application to receive a direct
representation of the corresponding resource instead of the string
representation, if this is possible under given language.
.PP
???? It looks like \f(CW\*(C`TK_CONFIG_IMAGE\*(C'\fR and \f(CW\*(C`TK_CONFIG_SCALARVAR\*(C'\fR set
variables of type \f(CW\*(C`char*\*(C'\fR.
.Sh "Language data"
.IX Subsection "Language data"
The following data types are defined:
.ie n .IP """Arg""" 4
.el .IP "\f(CWArg\fR" 4
.IX Item "Arg"
is the main datatype of the language. This is a type that your C
function gets pointers to for arguments when the corresponding \fILang\fR
function is called. The corresponding config type is
\&\f(CW\*(C`TK_CONFIG_LANGARG\*(C'\fR.
.Sp
This is also a type that keeps information about contents of \fILang\fR
variable.
.ie n .IP """Var""" 4
.el .IP "\f(CWVar\fR" 4
.IX Item "Var"
Is a substitute for a \f(CW\*(C`char *\*(C'\fR that contains name of variable. In
\&\fILang\fR it is an object that contains reference to another \fILang\fR
variable.
.ie n .IP """LangResultSave""" 4
.el .IP "\f(CWLangResultSave\fR" 4
.IX Item "LangResultSave"
????
.ie n .IP """LangCallback""" 4
.el .IP "\f(CWLangCallback\fR" 4
.IX Item "LangCallback"
\&\f(CW\*(C`LangCallback*\*(C'\fR a substitute for a \f(CW\*(C`char *\*(C'\fR that contains command to
call. The corresponding config type is \f(CW\*(C`TK_CONFIG_CALLBACK\*(C'\fR.
.ie n .IP """LangFreeProc""" 4
.el .IP "\f(CWLangFreeProc\fR" 4
.IX Item "LangFreeProc"
It is the type that the \f(CW\*(C`Lang_SplitList\*(C'\fR sets. Before you call it,
declare
.Sp
.Vb 5
\& Args *args;
\& LangFreeProc *freeProc = NULL;
\& ...
\& code = Lang_SplitList(interp, value,
\& &argc, &args, &freeProc);
.Ve
.Sp
After you use the split values, call
.Sp
.Vb 1
\& if (args != NULL && freeProc) (*freeProc)(argc,args);
.Ve
.Sp
It is not guaranteed that the \f(CW\*(C`args\*(C'\fR can survive deletion of \f(CW\*(C`value\*(C'\fR.
.Sh "Conversion"
.IX Subsection "Conversion"
The following macros and functions are used for conversion between
strings and the additional types:
.PP
.Vb 3
\& LangCallback * LangMakeCallback(Arg)
\& Arg LangCallbackArg(LangCallback *)
\& char * LangString(Arg)
.Ve
.PP
After you use the result of \fILangCallbackArg()\fR, you should free it with
\&\f(CW\*(C`freeProc\*(C'\fR \f(CW\*(C`LANG_DYNAMIC\*(C'\fR (it is not guaranteed that any change of
\&\f(CW\*(C`Arg\*(C'\fR will not be reflected in <LangCallback>, so you cannot do
LangSet...() in between, and you should reset it to \f(CW\*(C`NULL\*(C'\fR if you
want to do any further assignments to this \f(CW\*(C`Arg\*(C'\fR).
.PP
The following function returns the \f(CW\*(C`Arg\*(C'\fR that is a reference to \f(CW\*(C`Var\*(C'\fR:
.PP
.Vb 1
\& Arg LangVarArg(Var)
.Ve
.PP
???? It is very anti\-intuitive, I hope the name is changed.
.PP
.Vb 1
\& int LangCmpCallback(LangCallback *a,Arg b)
.Ve
.PP
(currently only a stub), and, at last,
.PP
.Vb 1
\& LangCallback * LangCopyCallback(LangCallback *)
.Ve
.Sh "Callbacks"
.IX Subsection "Callbacks"
Above we have seen the new datatype \f(CW\*(C`LangCallback\*(C'\fR and the
corresponding \fIConfig option\fR \f(CW\*(C`TK_CONFIG_CALLBACK\*(C'\fR. The following
functions are provided for manipulation of \f(CW\*(C`LangCallback\*(C'\fRs:
.PP
.Vb 3
\& void LangFreeCallback(LangCallback *)
\& int LangDoCallback(Tcl_Interp *,LangCallback *,
\& int result,int argc, char *format,...)
.Ve
.PP
The argument \f(CW\*(C`format\*(C'\fR of \f(CW\*(C`LangDoCallback\*(C'\fR should contain a string that is
suitable for \f(CW\*(C`sprintf\*(C'\fR with optional arguments of \f(CW\*(C`LangDoCallback\*(C'\fR.
\&\f(CW\*(C`result\*(C'\fR should be false if result of callback is not needed.
.PP
.Vb 2
\& int LangMethodCall(Tcl_Interp *,Arg,char *method,
\& int result,int argc,...)
.Ve
.PP
????
.PP
Conceptually, \f(CW\*(C`LangCallback*\*(C'\fR is a substitute for ubiquitous \f(CW\*(C`char *\*(C'\fR
in \fB\s-1TCL\s0\fR. So you should use \f(CW\*(C`LangFreeCallback\*(C'\fR instead of \f(CW\*(C`ckfree\*(C'\fR
or \f(CW\*(C`free\*(C'\fR if appropriate.
.Sh "Setting variables"
.IX Subsection "Setting variables"
.Vb 5
\& void LangFreeArg (Arg, Tcl_FreeProc *freeProc)
\& Arg LangCopyArg (Arg);
\& void Tcl_AppendArg (Tcl_Interp *interp, Arg)
\& void LangSetString(Arg *, char *s)
\& void LangSetDefault(Arg *, char *s)
.Ve
.PP
These two are equivalent unless s is an empty string. In this case
\&\f(CW\*(C`LangSetDefault\*(C'\fR behaves like \f(CW\*(C`LangSetString\*(C'\fR with \f(CW\*(C`s==NULL\*(C'\fR, i.e.,
it sets the current value of the \fILang\fR variable to be false.
.PP
.Vb 2
\& void LangSetInt(Arg *,int)
\& void LangSetDouble(Arg *,double)
.Ve
.PP
The \fILang\fR functions separate uninitialized and initialized data
comparing data with \f(CW\*(C`NULL\*(C'\fR. So the declaration for an \f(CW\*(C`Arg\*(C'\fR should
look like
.PP
.Vb 1
\& Arg arg = NULL;
.Ve
.PP
if you want to use this \f(CW\*(C`arg\*(C'\fR with the above functions. After you are
done, you should use \f(CW\*(C`LangFreeArg\*(C'\fR with \f(CW\*(C`TCL_DYNAMIC\*(C'\fR as \f(CW\*(C`freeProc\*(C'\fR.
.Sh "Language functions"
.IX Subsection "Language functions"
Use
.ie n .IP """int LangNull(Arg)""" 4
.el .IP "\f(CWint LangNull(Arg)\fR" 4
.IX Item "int LangNull(Arg)"
to check that an object is false;
.ie n .IP """int LangStringMatch(char *string, Arg match)""" 4
.el .IP "\f(CWint LangStringMatch(char *string, Arg match)\fR" 4
.IX Item "int LangStringMatch(char *string, Arg match)"
????
.ie n .IP """void LangExit(int)""" 4
.el .IP "\f(CWvoid LangExit(int)\fR" 4
.IX Item "void LangExit(int)"
to make a proper shutdown;
.ie n .IP """int LangEval(Tcl_Interp *interp, char *cmd, int global)""" 4
.el .IP "\f(CWint LangEval(Tcl_Interp *interp, char *cmd, int global)\fR" 4
.IX Item "int LangEval(Tcl_Interp *interp, char *cmd, int global)"
to call \fILang\fR \f(CW\*(C`eval\*(C'\fR;
.ie n .IP """void Lang_SetErrorCode(Tcl_Interp *interp,char *code)""" 4
.el .IP "\f(CWvoid Lang_SetErrorCode(Tcl_Interp *interp,char *code)\fR" 4
.IX Item "void Lang_SetErrorCode(Tcl_Interp *interp,char *code)"
.PD 0
.ie n .IP """char *Lang_GetErrorCode(Tcl_Interp *interp)""" 4
.el .IP "\f(CWchar *Lang_GetErrorCode(Tcl_Interp *interp)\fR" 4
.IX Item "char *Lang_GetErrorCode(Tcl_Interp *interp)"
.ie n .IP """char *Lang_GetErrorInfo(Tcl_Interp *interp)""" 4
.el .IP "\f(CWchar *Lang_GetErrorInfo(Tcl_Interp *interp)\fR" 4
.IX Item "char *Lang_GetErrorInfo(Tcl_Interp *interp)"
.ie n .IP """void LangCloseHandler(Tcl_Interp *interp,Arg arg,FILE *f,Lang_FileCloseProc *proc)""" 4
.el .IP "\f(CWvoid LangCloseHandler(Tcl_Interp *interp,Arg arg,FILE *f,Lang_FileCloseProc *proc)\fR" 4
.IX Item "void LangCloseHandler(Tcl_Interp *interp,Arg arg,FILE *f,Lang_FileCloseProc *proc)"
.PD
currently stubs only;
.ie n .IP """int LangSaveVar(Tcl_Interp *,Arg arg,Var *varPtr,int type)""" 4
.el .IP "\f(CWint LangSaveVar(Tcl_Interp *,Arg arg,Var *varPtr,int type)\fR" 4
.IX Item "int LangSaveVar(Tcl_Interp *,Arg arg,Var *varPtr,int type)"
to save the structure \f(CW\*(C`arg\*(C'\fR into \fILang\fR variable \f(CW*varPtr\fR;
.ie n .IP """void LangFreeVar(Var var)""" 4
.el .IP "\f(CWvoid LangFreeVar(Var var)\fR" 4
.IX Item "void LangFreeVar(Var var)"
to free the result;
.ie n .IP """int LangEventCallback(Tcl_Interp *,LangCallback *,XEvent *,KeySym)""" 4
.el .IP "\f(CWint LangEventCallback(Tcl_Interp *,LangCallback *,XEvent *,KeySym)\fR" 4
.IX Item "int LangEventCallback(Tcl_Interp *,LangCallback *,XEvent *,KeySym)"
????
.ie n .IP """int LangEventHook(int flags)""" 4
.el .IP "\f(CWint LangEventHook(int flags)\fR" 4
.IX Item "int LangEventHook(int flags)"
.PD 0
.ie n .IP """void LangBadFile(int fd)""" 4
.el .IP "\f(CWvoid LangBadFile(int fd)\fR" 4
.IX Item "void LangBadFile(int fd)"
.ie n .IP """int LangCmpConfig(char *spec, char *arg, size_t length)""" 4
.el .IP "\f(CWint LangCmpConfig(char *spec, char *arg, size_t length)\fR" 4
.IX Item "int LangCmpConfig(char *spec, char *arg, size_t length)"
.PD
unsupported????;
.ie n .IP """void Tcl_AppendArg (Tcl_Interp *interp, Arg)""" 4
.el .IP "\f(CWvoid Tcl_AppendArg (Tcl_Interp *interp, Arg)\fR" 4
.IX Item "void Tcl_AppendArg (Tcl_Interp *interp, Arg)"
.PP
Another useful construction is
.PP
.Vb 1
\& Arg variable = LangFindVar(interp, Tk_Window tkwin, char *name);
.Ve
.PP
After using the above function, you should call
.PP
.Vb 1
\& LangFreeVar(Var variable);
.Ve
.PP
???? Note discrepancy in types!
.PP
If you want to find the value of a variable (of type \f(CW\*(C`Arg\*(C'\fR) given the
variable name, use \f(CW\*(C`Tcl_GetVar(interp, varName, flags)\*(C'\fR. If you are
interested in the string value of this variable, use
\&\f(CW\*(C`LangString(Tcl_GetVar(...))\*(C'\fR.
.PP
To get a \fBC\fR array of \f(CW\*(C`Arg\*(C'\fR of length \f(CW\*(C`n\*(C'\fR, use
.PP
.Vb 3
\& Arg *args = LangAllocVec(n);
\& ...
\& LangFreeVec(n,args);
.Ve
.PP
You can set the values of the \f(CW\*(C`Arg\*(C'\fRs using \f(CW\*(C`LangSet...\*(C'\fR functions,
and get string value using \f(CW\*(C`LangString\*(C'\fR.
.PP
If you want to merge an array of \f(CW\*(C`Arg\*(C'\fRs into one \f(CW\*(C`Arg\*(C'\fR (that will
be an array variable), use
.PP
.Vb 1
\& result = Tcl_Merge(listLength, list);
.Ve
.Sh "Translation of some \s-1TCL\s0 functions"
.IX Subsection "Translation of some TCL functions"
We mark items that can be dealt with by \f(CW\*(C`munge\*(C'\fR by \fIAutoconverted\fR.
.ie n .IP """Tcl_AppendResult""" 4
.el .IP "\f(CWTcl_AppendResult\fR" 4
.IX Item "Tcl_AppendResult"
does not take \f(CW\*(C`(char*)NULL\*(C'\fR, but \f(CW\*(C`NULL\*(C'\fR as delimiter. \fIAutoconverted\fR.
.ie n .IP """Tcl_CreateCommand""\fR, \f(CW""Tcl_DeleteCommand""" 4
.el .IP "\f(CWTcl_CreateCommand\fR, \f(CWTcl_DeleteCommand\fR" 4
.IX Item "Tcl_CreateCommand, Tcl_DeleteCommand"
\&\f(CW\*(C`Tk_CreateWidget\*(C'\fR, \f(CW\*(C`Tk_DeleteWidget\*(C'\fR, the second argument is the
window itself, not the pathname. \fIAutoconverted\fR.
.ie n .IP """sprintf(interp\->result, ""%d %d %d %d"",...)""" 4
.el .IP "\f(CWsprintf(interp\->result, ``%d %d %d %d'',...)\fR" 4
.IX Item "sprintf(interp->result, ""%d %d %d %d"",...)"
\&\f(CW\*(C`Tcl_IntResults(interp,4,0,...)\*(C'\fR. \fIAutoconverted\fR.
.ie n .IP """interp\->result = ""1"";""" 4
.el .IP "\f(CWinterp\->result = ``1'';\fR" 4
.IX Item "interp->result = ""1"";"
\&\f(CW\*(C`Tcl_SetResult(interp,"1", TCL_STATIC)\*(C'\fR. \fIAutoconverted\fR.
.ie n .IP "Reading ""interp\->result""" 4
.el .IP "Reading \f(CWinterp\->result\fR" 4
.IX Item "Reading interp->result"
\&\f(CW\*(C`Tcl_GetResult(interp)\*(C'\fR. \fIAutoconverted\fR.
.ie n .IP """interp\->result = Tk_PathName(textPtr\->tkwin);""" 4
.el .IP "\f(CWinterp\->result = Tk_PathName(textPtr\->tkwin);\fR" 4
.IX Item "interp->result = Tk_PathName(textPtr->tkwin);"
\&\f(CW\*(C`Tk_WidgetResult(interp,textPtr\->tkwin)\*(C'\fR. \fIAutoconverted\fR.
.ie n .IP "Sequence ""Tcl_PrintDouble, Tcl_PrintDouble, ..., Tcl_AppendResult""" 4
.el .IP "Sequence \f(CWTcl_PrintDouble, Tcl_PrintDouble, ..., Tcl_AppendResult\fR" 4
.IX Item "Sequence Tcl_PrintDouble, Tcl_PrintDouble, ..., Tcl_AppendResult"
Use a single command
.Sp
.Vb 2
\& void Tcl_DoubleResults(Tcl_Interp *interp, int append,
\& int argc,...);
.Ve
.Sp
\&\f(CW\*(C`append\*(C'\fR governs whether it is required to clear the result first.
.Sp
A similar command for \f(CW\*(C`int\*(C'\fR arguments is \f(CW\*(C`Tcl_IntResults\*(C'\fR.
.ie n .IP """Tcl_SplitList""" 4
.el .IP "\f(CWTcl_SplitList\fR" 4
.IX Item "Tcl_SplitList"
Use \f(CW\*(C`Lang_SplitList\*(C'\fR (see the description above).
.SH "Translation back to TCL"
.IX Header "Translation back to TCL"
To use your \fBportableTk\fR program with \fB\s-1TCL\s0\fR, put
.PP
.Vb 1
\& #include "ptcl.h"
.Ve
.PP
\&\fIbefore\fR inclusion of \f(CW\*(C`tk.h\*(C'\fR, and link the resulting code with
\&\f(CW\*(C`ptclGlue.c\*(C'\fR.
.PP
These files currently implement the following:
.IP "Additional config types:" 4
.IX Item "Additional config types:"
.Vb 6
\& TK_CONFIG_CALLBACK
\& TK_CONFIG_LANGARG
\& TK_CONFIG_SCALARVAR
\& TK_CONFIG_HASHVAR
\& TK_CONFIG_ARRAYVAR
\& TK_CONFIG_IMAGE
.Ve
.IP "Types:" 4
.IX Item "Types:"
.Vb 1
\& Var, Arg, LangCallback, LangFreeProc.
.Ve
.IP "Functions and macros:" 4
.IX Item "Functions and macros:"
.Vb 6
\& Lang_SplitList, LangString, LangSetString, LangSetDefault,
\& LangSetInt, LangSetDouble Tcl_ArgResult, LangCallbackArg,
\& LangSaveVar, LangFreeVar,
\& LangFreeSplitProc, LangFreeArg, Tcl_DoubleResults, Tcl_IntResults,
\& LangDoCallback, Tk_WidgetResult, Tcl_CreateCommand,
\& Tcl_DeleteCommand, Tcl_GetResult.
.Ve
.PP
Current implementation contains enough to make it possible to compile
\&\f(CW\*(C`mTk/tkText*.[ch]\*(C'\fR with the virgin \fBTk\fR.
.Sh "New types of events ????"
.IX Subsection "New types of events ????"
PortableTk defines following new types of events:
.PP
.Vb 7
\& TK_EVENTTYPE_NONE
\& TK_EVENTTYPE_STRING
\& TK_EVENTTYPE_NUMBER
\& TK_EVENTTYPE_WINDOW
\& TK_EVENTTYPE_ATOM
\& TK_EVENTTYPE_DISPLAY
\& TK_EVENTTYPE_DATA
.Ve
.PP
and a function
.PP
.Vb 4
\& char * Tk_EventInfo(int letter,
\& Tk_Window tkwin, XEvent *eventPtr,
\& KeySym keySym, int *numPtr, int *isNum, int *type,
\& int num_size, char *numStorage)
.Ve
.SH "Checking for trouble"
.IX Header "Checking for trouble"
If you start with working \s-1TCL\s0 code, you can start convertion using
the above hints. Good indication that you are doing is \s-1OK\s0 is absence
of \f(CW\*(C`sprintf\*(C'\fR and \f(CW\*(C`sscanf\*(C'\fR in your code (at least in the part that is
working with interpreter).
.SH "Additional API"
.IX Header "Additional API"
What is described here is not included into base \fBportableTk\fR
distribution. Currently it is coded in \fB\s-1TCL\s0\fR and as Perl macros (core
is coded as functions, so theoretically you can use the same object
files with different interpreted languages).
.ie n .Sh """ListFactory"""
.el .Sh "\f(CWListFactory\fP"
.IX Subsection "ListFactory"
Dynamic arrays in \fB\s-1TCL\s0\fR are used for two different purposes: to
construct strings, and to construct lists. These two usages will have
separate interfaces in other languages (since list is a different type
from a string), so you should use a different interface in your code.
.PP
The type for construction of dynamic lists is \f(CW\*(C`ListFactory\*(C'\fR. The \s-1API\s0
below is a counterpart of the \s-1API\s0 for construction of dynamic lists
in \fB\s-1TCL\s0\fR:
.PP
.Vb 9
\& void ListFactoryInit(ListFactory *)
\& void ListFactoryFinish(ListFactory *)
\& void ListFactoryFree(ListFactory *)
\& Arg * ListFactoryArg(ListFactory *)
\& void ListFactoryAppend(ListFactory *, Arg *arg)
\& void ListFactoryAppendCopy(ListFactory *, Arg *arg)
\& ListFactory * ListFactoryNewLevel(ListFactory *)
\& ListFactory * ListFactoryEndLevel(ListFactory *)
\& void ListFactoryResult(Tcl_Interp *, ListFactory *)
.Ve
.PP
The difference is that a call to \f(CW\*(C`ListFactoryFinish\*(C'\fR should precede the
actual usage of the value of \f(CW\*(C`ListFactory\*(C'\fR, and there are two
different ways to append an \f(CW\*(C`Arg\*(C'\fR to a \f(CW\*(C`ListFactory\*(C'\fR:
\&\fIListFactoryAppendCopy()\fR guarantees that the value of \f(CW\*(C`arg\*(C'\fR is copied
to the list, but \fIListFactoryAppend()\fR may append to the list a
reference to the current value of \f(CW\*(C`arg\*(C'\fR. If you are not going to change
the value of \f(CW\*(C`arg\*(C'\fR after appending, the call to ListFactoryAppend may
be quicker.
.PP
As in \fB\s-1TCL\s0\fR, the call to \fIListFactoryFree()\fR does not free the
\&\f(CW\*(C`ListFactory\*(C'\fR, only the objects it references.
.PP
The functions \fIListFactoryNewLevel()\fR and \fIListFactoryEndLevel()\fR return a
pointer to a \f(CW\*(C`ListFactory\*(C'\fR to fill. The argument of
\&\fIListFactoryEndLevel()\fR cannot be used after a call to this function.
.Sh "DStrings"
.IX Subsection "DStrings"
Production of strings are still supported in \fBportableTk\fR.
.ie n .Sh "Accessing ""Arg""s"
.el .Sh "Accessing \f(CWArg\fPs"
.IX Subsection "Accessing Args"
The following functions for getting a value of an \f(CW\*(C`Arg\*(C'\fR \fImay\fR be
provided:
.PP
.Vb 4
\& double LangDouble(Arg)
\& int LangInt(Arg)
\& long LangLong(Arg)
\& int LangIsList(Arg arg)
.Ve
.PP
The function \fILangIsList()\fR is supported only partially under \fB\s-1TCL\s0\fR,
since there is no data types. It checks whether there is a space
inside the string \f(CW\*(C`arg\*(C'\fR.
.ie n .Sh "Assigning numbers to ""Arg""s"
.el .Sh "Assigning numbers to \f(CWArg\fPs"
.IX Subsection "Assigning numbers to Args"
While \fILangSetDouble()\fR and \fILangSetInt()\fR are supported ways to assign
numbers to assign an integer value to a variable, for the sake of
efficiency under \fB\s-1TCL\s0\fR it is supposed that the destination of these
commands was massaged before the call so it contains a long enough
string to \fIsprintf()\fR the numbers inside it. If you are going to
immediately use the resulting \f(CW\*(C`Arg\*(C'\fR, the best way to do this is to
declare a buffer in the beginning of a block by
.PP
.Vb 1
\& dArgBuffer;
.Ve
.PP
and assign this buffer to the \f(CW\*(C`Arg\*(C'\fR by
.PP
.Vb 1
\& void LangSetDefaultBuffer(Arg *)
.Ve
.PP
You can also create the buffer(s) manually and assign them using
.PP
.Vb 1
\& void LangSetBuffer(Arg *, char *)
.Ve
.PP
This is the only choice if you need to assign numeric values to
several \f(CW\*(C`Arg\*(C'\fRs simultaneously. The advantage of the first approach is
that the above declarations can be made \f(CW\*(C`nop\*(C'\fRs in different languages.
.PP
Note that if you apply \f(CW\*(C`LangSetDefaultBuffer\*(C'\fR to an \f(CW\*(C`Arg\*(C'\fR that
contains some value, you can create a leak if you do not free that
\&\f(CW\*(C`Arg\*(C'\fR first. This is a non-problem in real languages, but can be a
trouble in \f(CW\*(C`TCL\*(C'\fR, unless you use only the above \s-1API\s0.
.ie n .Sh "Creating new ""Arg""s"
.el .Sh "Creating new \f(CWArg\fPs"
.IX Subsection "Creating new Args"
The \s-1API\s0 for creating a new \f(CW\*(C`Arg\*(C'\fR is
.PP
.Vb 1
\& void LangNewArg(Arg *, LangFreeProc *)
.Ve
.PP
The \s-1API\s0 for creating a new \f(CW\*(C`Arg\*(C'\fR is absent. Just initialize \f(CW\*(C`Arg\*(C'\fR to
be \f(CW\*(C`NULL\*(C'\fR, and apply one of \f(CW\*(C`LangSet...\*(C'\fR methods.
.PP
After you use this \f(CW\*(C`Arg\*(C'\fR, it should be freed thusly:
.PP
\&\f(CW\*(C`LangFreeArg(arg, freeProc)\*(C'\fR.
.Sh "Evaluating a list"
.IX Subsection "Evaluating a list"
Use
.PP
.Vb 1
\& int LangArgEval(Tcl_Interp *, Arg arg)
.Ve
.PP
Here \f(CW\*(C`arg\*(C'\fR should be a list to evaluate, in particular, the first
element should be a \f(CW\*(C`LangCallback\*(C'\fR massaged to be an \f(CW\*(C`Arg\*(C'\fR. The
arguments can be send to the subroutine by reference or by value in
different languages.
.ie n .Sh "Getting result as ""Arg"""
.el .Sh "Getting result as \f(CWArg\fP"
.IX Subsection "Getting result as Arg"
Use \f(CW\*(C`Tcl_ArgResult\*(C'\fR. It is not guaranteed that result survives this
operation, so the \f(CW\*(C`Arg\*(C'\fR you get should be the only mean to access the
data from this moment on. After you use this \f(CW\*(C`Arg\*(C'\fR, you should free
it with \f(CW\*(C`freeProc\*(C'\fR \f(CW\*(C`LANG_DYNAMIC\*(C'\fR (you can do LangSet...() in between).