From d19378fbabbb63234cec1902fbbe7c50fb061a98 Mon Sep 17 00:00:00 2001 From: baloan Date: Mon, 14 Mar 2011 23:41:59 +0100 Subject: [PATCH] tktable added --HG-- branch : aspn --- .pydevproject | 1 + src/stoppable_thread.py | 4 +- tktable/ChangeLog | 1700 ++++ tktable/Makefile.in | 488 ++ tktable/README.blt | 20 + tktable/README.txt | 149 + tktable/TODO.txt | 63 + tktable/aclocal.m4 | 9 + tktable/configure | 12133 ++++++++++++++++++++++++++ tktable/configure.in | 187 + tktable/demos/basic.tcl | 61 + tktable/demos/buttons.tcl | 82 + tktable/demos/command.tcl | 85 + tktable/demos/debug.tcl | 112 + tktable/demos/dynarows.tcl | 87 + tktable/demos/loadtable.tcl | 52 + tktable/demos/maxsize.tcl | 76 + tktable/demos/spreadsheet.tcl | 122 + tktable/demos/tcllogo.gif | Bin 0 -> 2341 bytes tktable/demos/tktable.py | 344 + tktable/demos/valid.tcl | 95 + tktable/doc/tkTable.html | 2039 +++++ tktable/doc/tkTable.n | 1432 +++ tktable/generic/tkAppInit.c | 132 + tktable/generic/tkTable.c | 4090 +++++++++ tktable/generic/tkTable.h | 658 ++ tktable/generic/tkTableCell.c | 1420 +++ tktable/generic/tkTableCellSort.c | 400 + tktable/generic/tkTableCmds.c | 1306 +++ tktable/generic/tkTableEdit.c | 723 ++ tktable/generic/tkTableInitScript.h | 90 + tktable/generic/tkTablePs.c | 1299 +++ tktable/generic/tkTableTag.c | 1354 +++ tktable/generic/tkTableUtil.c | 372 + tktable/generic/tkTableWin.c | 955 ++ tktable/generic/version.h | 8 + tktable/library/tkTable.tcl | 825 ++ tktable/library/tktable.py | 651 ++ tktable/license.txt | 41 + tktable/release.txt | 38 + tktable/tclconfig/install-sh | 119 + tktable/tclconfig/tcl.m4 | 4093 +++++++++ tktable/tests/all.tcl | 58 + tktable/tests/tkTable.test | 869 ++ tktable/unix/tktable.spec | 56 + tktable/win/makefile.vc | 264 + 46 files changed, 39160 insertions(+), 2 deletions(-) create mode 100644 tktable/ChangeLog create mode 100644 tktable/Makefile.in create mode 100644 tktable/README.blt create mode 100644 tktable/README.txt create mode 100644 tktable/TODO.txt create mode 100644 tktable/aclocal.m4 create mode 100644 tktable/configure create mode 100644 tktable/configure.in create mode 100644 tktable/demos/basic.tcl create mode 100644 tktable/demos/buttons.tcl create mode 100644 tktable/demos/command.tcl create mode 100644 tktable/demos/debug.tcl create mode 100644 tktable/demos/dynarows.tcl create mode 100644 tktable/demos/loadtable.tcl create mode 100644 tktable/demos/maxsize.tcl create mode 100644 tktable/demos/spreadsheet.tcl create mode 100644 tktable/demos/tcllogo.gif create mode 100644 tktable/demos/tktable.py create mode 100644 tktable/demos/valid.tcl create mode 100644 tktable/doc/tkTable.html create mode 100644 tktable/doc/tkTable.n create mode 100644 tktable/generic/tkAppInit.c create mode 100644 tktable/generic/tkTable.c create mode 100644 tktable/generic/tkTable.h create mode 100644 tktable/generic/tkTableCell.c create mode 100644 tktable/generic/tkTableCellSort.c create mode 100644 tktable/generic/tkTableCmds.c create mode 100644 tktable/generic/tkTableEdit.c create mode 100644 tktable/generic/tkTableInitScript.h create mode 100644 tktable/generic/tkTablePs.c create mode 100644 tktable/generic/tkTableTag.c create mode 100644 tktable/generic/tkTableUtil.c create mode 100644 tktable/generic/tkTableWin.c create mode 100644 tktable/generic/version.h create mode 100644 tktable/library/tkTable.tcl create mode 100644 tktable/library/tktable.py create mode 100644 tktable/license.txt create mode 100644 tktable/release.txt create mode 100644 tktable/tclconfig/install-sh create mode 100644 tktable/tclconfig/tcl.m4 create mode 100644 tktable/tests/all.tcl create mode 100644 tktable/tests/tkTable.test create mode 100644 tktable/unix/tktable.spec create mode 100644 tktable/win/makefile.vc diff --git a/.pydevproject b/.pydevproject index 9621a0d..4e723c5 100644 --- a/.pydevproject +++ b/.pydevproject @@ -6,5 +6,6 @@ python 2.6 /aspn/src +/aspn/tktable diff --git a/src/stoppable_thread.py b/src/stoppable_thread.py index 96ef9ba..a4b248e 100644 --- a/src/stoppable_thread.py +++ b/src/stoppable_thread.py @@ -12,8 +12,8 @@ class StoppableThread(Thread): """Thread class with a stop() method. The thread itself has to check regularly for the stopped() condition.""" - def __init__(self): - super(StoppableThread, self).__init__() + def __init__(self, *args, **kwargs): + super(StoppableThread, self).__init__(*args, **kwargs) self._stop = Event() def stop(self): diff --git a/tktable/ChangeLog b/tktable/ChangeLog new file mode 100644 index 0000000..4c4bb70 --- /dev/null +++ b/tktable/ChangeLog @@ -0,0 +1,1700 @@ +2008-11-14 Jeff Hobbs + + **** 2.10 TAGGED FOR RELEASE **** + + * generic/tkTable.c: Set NO_XSETCLIP universally as Tk 8.5/Xft + seems to ignore XSetClipRectangles. This may slow things down a + little, but draws correctly. [Bug 1805350] + + * UPGRADING.txt (removed): no longer need this old v1 upgrade doc. + + * README.txt: remove refs to mac classic stuff, update notes + + * configure, configure.in, tclconfig/tcl.m4: Update to TEA 3.7 + * tests/tkTable.test, unix/tktable.spec, generic/version.h: + * demos/loadtable.tcl: Update version to 2.10 + * Makefile.in: update dist target, include library/tktable.py + + * demos/tktable.py: note that this version is outdated + * library/tktable.py (NEW): Added new version of tktable wrapper + for Python/Tkinter from GPolo. Not 100% compatible with previous + version. [Patch 2244167] + + * generic/tkTableTag.c (Table_TagCmd): remove interp->result set + work-around for old bug as i->result is no longer exposed in 8.6. + + * generic/tkTable.c: Use safe Tcl_SetObjResult instead of trying + * generic/tkTableCell.c: to set existing objResult value. + * generic/tkTableCmds.c: + +2006-07-10 Jeff Hobbs + + * license.txt (bourbon_ware): Be less restrictive in the + bourbon_ware clause. + +2006-01-25 Jeff Hobbs + + * configure.in, configure, tclconfig/tcl.m4: update to TEA 3.5 + +2006-01-22 Jeff Hobbs + + * tclconfig/tcl.m4, configure: update to TEA 3.4 interim + +2005-12-13 Jeff Hobbs + + * generic/tkTableCmds.c (Table_ActivateCmd): remove potential + undefined behavior warning. + +2005-12-02 Jeff Hobbs + + * tclconfig/tcl.m4, configure.in, configure: update to TEA 3.4 + +2005-05-11 Jeff Hobbs + + * Makefile.in (html): switch to groff to fix botched html output. + * doc/tkTable.html: regen [Bug 1198478] + * doc/tkTable.n: use '' around \\ items. + +2005-03-18 Jeff Hobbs + + * Makefile.in (AR): use @AR@, improve html doc target + * configure, configure.in, tclconfig/tcl.m4: TEA 3.2 patch update + + * doc/tkTable.n, doc/kTable.html: doc cleanup + +2005-02-01 Jeff Hobbs + + * configure, configure.in, tclconfig/tcl.m4: update to TEA 3.2 + +2004-11-18 Jeff Hobbs + + * library/tkTable.tcl (::tk::table::SelectAll): remove invalid ref + to HandleType proc. [Bug 1068874] (ade) + +2004-07-22 Jeff Hobbs + + **** 2.9 TAGGED FOR RELEASE **** + + * configure, tclconfig/tcl.m4: update tcl.m4 TEA_PATH_X that adds + Aqua build recognition and TEA_WINDOWINGSYSTEM variable. + +2004-07-20 Jeff Hobbs + + * generic/version.h, unix/tktable.spec: updated for v2.9 + * demos/loadtable.tcl, tests/tkTable.test: + + * Makefile.in, configure.in, configure, tclconfig/tcl.m4: update + to TEA 3.1, use CFLAGS instead of EXTRA_CFLAGS and bump the + version number of Tktable to 2.9. + + * generic/tkTable.h: add #include + + * generic/tkTableCell.c (TableGetCellValue, TableSetCellValue): + Do faster cache checks when DATA_CACHE is the only data source. + In fallback from command that errors to array var, retrieve array + value immediately on current get|set request. + When setting the value with cache and array sources, don't do the + caching branch as the array trace will do that already. + (TableMoveCellValue): Do the efficient cache value management when + cache is the only data source, otherwise the regular fallback has + all the necessary checks. [Bug #919872] + + * generic/tkTable.c (TableVarProc): allow setting NULL value in + cache hash from array trace. + +2004-06-10 Jeff Hobbs + + * generic/tkTableWin.c (EmbWinDisplay): make min window displayed + have width/height 1 pixel min (was 3px) + + * generic/tkTable.c (TableDisplay): Don't draw when we don't have + the space for it. [Bug 747038] + + * doc/tkTable.html, doc/tkTable.n: improve docs to note + requirement of specifying a data source. [Bug 963204] + +2004-02-17 Jeff Hobbs + + * generic/tkTableCmds.c (Table_ActivateCmd): test implementation + of an "unactivate" ($table activate "") command to remove the + active cell. (becroft) + +2004-02-13 Jeff Hobbs + + * library/tkTable.tcl (::tk::table::Button1): account for what + resizeborders are set when selecting cell [Bug 876320] (ferenc) + ( ): activate topleft, not @0,0 (accounts for title + rows) [Bug 879347] (ferenc) + +2003-12-10 Jeff Hobbs + + * Makefile.in: updated to TEA3 spec + * configure: + * configure.in: + * generic/tkTable.c: + * generic/tkTableInitScript.h: + * generic/version.h: + * mac/mac_tkTable.r: + * tclconfig/tcl.m4: + + * win/makefile.vc: minor updates, probably still out of date + + * tclconfig/ChangeLog (removed): not necessary + + * generic/tkTable.c: added Tk_ClassProcs and TableWorldChanged + proc if built against 8.4 + + * generic/tkTable.h: add 8.4 ifdef, remove ANSI_ARGS usage + +2003-07-16 Jeff Hobbs + + * doc/tkTable.n: add note about -window "" behavior + +2003-04-10 Jeff Hobbs + + * configure: regen + * tclconfig/tcl.m4: updated + + * library/tkTable.tcl (BeginExtend): avoid error in tables that + have no anchor index yet. (renshaw) + +2003-04-09 Jeff Hobbs + + * configure: regen + * tclconfig/tcl.m4: Updated to newest tcl.m4, (WinCE support) + + * demos/loadtable.tcl: redefine 'puts' on Windows CE + + * generic/tkTable.c (TableDisplay): correctly copy clipwindow area + for NO_XSETCLIP case and use that when UNDER_CE as well. Also add + support for drawing ellipsis in NO_XSETCLIP case. + Comment out OffsetClipRgn call - it was a noop. + +2003-04-04 Andreas Kupries + + * configure.in: + * tclconfig/tcl.m4: Updated to newest tcl.m4, regenerated + configure's. + +2003-02-24 Jeff Hobbs + + * generic/tkTable.c (TableDisplay): do not use buffer pixmap for + slow -drawmode on Win32 because we aren't clipping it correctly. + +2003-01-30 Jeff Hobbs + + * Makefile.in: remove use of nested $(PACKAGE) to enable building + on older, cruftier make versions + + * doc/tkTable.n: add -ellipsis tag /global option which + * tests/tkTable.test: takes a char string (ie: "...") to display + * generic/tkTableTag.c: as an ellipsis. These will only be shown + * generic/tkTable.h: on non-wrapping, non-multiline cells. + * generic/tkTable.c: + +2002-12-10 Jeff Hobbs + + * tests/tkTable.test: + * generic/tkTableCell.c (TableGetCellValue): make caching allows + NULLs throughout to save mem. + Do not call Tcl_FreeResult as it will be freed before the next + result is set, and causes us to lose large results. [Bug #651685] + +2002-10-16 Jeff Hobbs + + **** 2.8 TAGGED FOR RELEASE **** + + * Makefile.in: updated dist target to get changed fileset. + + * generic/tkTableEdit.c (Table_EditCmd): Ensure that embedded + widgets being moved offscreen get unmapped. [Bug #551325] + + * generic/tkTableCell.c (TableAtBorder): refine border detection + in the midst of spanned cells. [Patch #544117] (duxbury) + + * doc/tkTable.n: + * doc/tkTable.html: + * tests/tkTable.test: + * generic/tkTable.c: Add global -justify option. [Bug #623557] + + * generic/tkTableTag.c: more CONST84 casting fixes. + Allowing setting of tag relief to "". [Bug #233619] + + * generic/tkTable.h: + * generic/tkTableUtil.c: + * generic/tkTableWin.c: more CONST84 casting fixes. + + * library/tkTable.tcl: Add as a default auto-commit + event. [Bug #611132] + (::tk::table::Motion): abort "extended" arm if the anchor cell + isn't defined. [Bug #604470] + +2002-10-15 Jeff Hobbs + + * tclconfig/tcl.m4: + * configure: + * configure.in: move the CFLAGS definition into TEA_MAKE_LIB + and make it pick up the env CFLAGS at configure time. + +2002-10-15 Andreas Kupries + + * configure.in: Changed to propagate an initial CFLAGS value to + the final definition. A TEA condition (SHARED_BUILD == 1) + squashed it, causing it the build system to loose the + +DAportable we specify for the AS PA-RISC2.2 build host. This is + a problem for _all_ TEA and TEA 2 based configure files. + +2002-10-09 Jeff Hobbs + + * configure: + * configure.in: move TEA_PATH_X below TEA_CONFIG_CFLAGS as it can + mess with the configure results. + + * unix/tktable.spec (new): RPM spec file. (fontaine) + + * demos/tktable.py: added a contributed tktable wrapper for + Python/Tkinter from Klaus Roethemeyer. + +2002-09-27 Jeff Hobbs + + * Makefile.in: correct tkTable.tcl.h target to work with FreeBSD's + default make. + +2002-09-25 Jeff Hobbs + + * generic/tkTable.c: + * generic/tkTable.h: added support for building on OS X (steffen) + +2002-06-21 Jeff Hobbs + + * Makefile.in: call cygpath on INCLUDES $(srcdir)/generic. + + * tests/all.tcl: minor cleanup + + * tests/tkTable.test (table-30.1): + * generic/tkTableEdit.c (Table_EditCmd): fixed problem where row + insertion could segfault. [Bug #487747] + +2002-04-11 Jeff Hobbs + + * tclconfig/tcl.m4: + * configure: Enabled COFF as well as CV style debug info with + --enable-symbols to allow Dr. Watson users to see function info. + More info on debugging levels can be obtained at: + http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp + +2002-04-03 Jeff Hobbs + + * Makefile.in: improved use of DESTDIR in install targets. + Removed need for installdirs target. + Broke TCLSH_PROG into TCLSH_ENV and TCLSH_PROG with TCLSH var and + added comments about TCLSH_ENV. + Added default shell and gdb targets. + + * tclconfig/tcl.m4: + * configure: + * configure.in: updated to new TEA base that: prefixes all macros + with TEA_* instead of SC_*; adds TEA_PREFIX, which defaults the + prefix and exec_prefix values to what Tcl used; adds + TEA_SETUP_COMPILER, which handles basic compiler / support program + checks and simplifies the configure.in. Turn on --enable-threads + by default and do sanity checking as well. + +2002-04-02 Jeff Hobbs + + * configure: regened + * configure.in: added user32.lib to LIBS for Windows + * tclconfig/tcl.m4: updated from TEA sample + +2002-03-27 Jeff Hobbs + + * Makefile.in (WISH_PROG): moved and updated env var definitions + to have wish work from build dir. Removed TCL_EXTRA_CFLAGS, + TCL_LD_FLAGS, TCL_SHLIB_LD_LIBS, TCL_DBGX, TCL_STUB_LIB_FILE, + TCL_STUB_LIB_SPEC as they aren't needed (configure acquires all + that info for us). TCL_LIBS is also not needed, but left in as a + reference to the libs Tcl used. + + * configure: regen based on updated tclconfig/tcl.m4 + * configure.in: moved the SHLIB_LD_LIBS magic into + tclconfig/tcl.m4 and noted where users can modify (SHLIB_LD_)LIBS. + * tclconfig/tcl.m4: updated from sample to be more independent of + *Config.sh. + + * unix/Makefile.in (removed): + * unix/configure.in (removed): + * unix/configure (removed): + * unix/install-sh (removed): removed old makefile files to force + use of new toplevel TEA 2002 configure/make. + +2002-03-21 Jeff Hobbs + + * tests/tkTable.test: more icursor tests + * generic/tkTable.c (TableWidgetObjCmd): corrected placing the + icursor and retaining the position. + +2002-03-20 Jeff Hobbs + + * generic/tkTable.c: + * generic/tkTable.h: + * generic/tkTableCmds.c: + * generic/tkTableUtil.c: cleaned up several areas where cache data + was not getting freed. [Bug #532447] (bloisi) + +2002-03-19 Jeff Hobbs + + * tests/tkTable.test: added tag configure tests + + * generic/tkTableTag.c (Table_TagCmd): work-around for bug in + Tk_ConfigureValue that sets interp->result to NULL. [Bug #522882] + + * generic/tkTable.c (TableDisplay): when building with threads on + WIN32, use NO_XSETCLIP instead of direct DC hacks because Tk + doesn't use CS_CLASSDC on threaded builds. + (Tktable_Init) Corrected to use BUILD_Tktable for EXTERN changes. + + * configure: + * configure.in: use double-eval to substitute DBGX var for + ${PACKAGE}_LIB_FILE. + + * Makefile.in: cleaned up install target + +2002-03-13 Jeff Hobbs + + * demos/loadtable.tcl: + * tests/tkTable.test: adapted load to new configure style where + unix gets the 'lib' suffix for the library. + + * tclconfig/ChangeLog: + * tclconfig/README.txt: + * tclconfig/install-sh: + * tclconfig/tcl.m4: + * README.txt: + * Makefile.in: + * aclocal.m4: + * configure: + * configure.in: introduction of next-gen TEA based config files. + The unix/ configure files should no longer be used. + + * generic/tkTable.c: + * generic/tkTableCell.c: + * generic/tkTableCellSort.c: + * generic/tkTableCmds.c: + * generic/tkTableEdit.c: + * generic/tkTableTag.c: + * generic/tkTableUtil.c: + * generic/tkTableWin.c: + * generic/tkTable.h: introduced CONST84 define for compatibility + with new 8.4 CONST-ed headers and older headers and fixed up + sources where necessary. + + * generic/tkTableInitScript.h: + * generic/tkTable.c: + * generic/version.h: + * mac/mac_tkTable.r: + * win/makefile.vc: changed TBL_VERSION to VERSION, upped to 2.8. + Added Win64 build support to makefile.vc + +2002-03-07 Jeff Hobbs + + * library/tkTable.tcl (tk_tablePasteHandler): "string comp" fixed + to "string compare" [Bug #500449] + +2002-01-16 Jeff Hobbs + + * generic/tkTable.c (TableWidgetObjCmd): corrected dangerous + caching of resultPtr that could lead to segfault. + +2001-08-24 Jeff Hobbs + + * README.txt: corrected outdated notes. [Bug #455116] (kriehbel) + +2001-08-23 Jeff Hobbs + + * unix/Makefile.in (tkTable.tcl.h): corrected target to sed \'s + properly in the .tcl file. + + * library/tkTable.tcl: added the ability to select borders with + button 1. (backe) The user can turn off this ability by calling + [set ::tk::table::Priv(borderB1) 0] in their code. button 3 is + still active for selecting borders as well. + fixed a couple references to work on Mac/Tk. (steffen) + + * mac/mac_tkTable_prefix.h: + * mac/mac_tkTable.r: corrected Mac build. (steffen) + + * doc/tkTable.html: regen'd + * doc/tkTable.n: Clarified that any , index + specification will always return a valid cell. [Bug #450397] + Corrected what 'units' scrolls. [Bug #448837] + + * mac/mac_tkTable.mcp: removed in favor of XML project file + * mac/mac_tkTable.mcp.xml: XML CodeWarrior project file for the + mac. (steffen) + +2001-07-18 Jeff Hobbs + + * generic/tkTable.c (TableDestroy): freed cached values in destroy. + +2001-06-30 Jeff Hobbs + + **** 2.7 RELEASE **** + + * generic/tkTable.h: added STREQ #def to replace strcmp(a,b) == 0 + * generic/tkTable.c: + * generic/tkTableTag.c: made use of STREQ #define. + Redid tag merging to make use of only one allocated tag. + + * doc/tkTable.html: + * doc/tkTable.n: updated docs with feature change info + + * tests/tkTable.test: added more tests + + * generic/tkTableCmds.c (Table_ActivateCmd): made table refresh + when moving the cursor in the active cell. + +2001-06-24 Jeff Hobbs + + * generic/tkTableTag.c (Table_TagCmd): corrected patch for Patch + #423332 that does prevent excess refresh in the simple case. + +2001-06-23 Jeff Hobbs + + * generic/tkTable.c (TableConfigure): corrected possible crash + during configure when switching array vars and changed name of + 'restrict' var to something that is not a reserved word. (berggren) + + * library/tkTable.tcl: support for future UTF8_STRING selection on + unix. + + * generic/tkTable.c: + * generic/tkTable.h: + * generic/tkTableTag.c: added support for priorities in tags. + There are new 'tag lower' and 'tag raise' methods. This may lead + to different view characteristics because the default priority + order is creation order, starting with flash, active, sel, title, + followed by whatever the user creates. The old order was fixed at + flash, active, sel, , title, , + **** POTENTIAL INCOMPATABILITY **** + + * tests/tkTable.test: makings of an initial test suite + + * generic/tkTableCmds.c (Table_CurvalueCmd): removed extra curvalue + in error message. + +2001-06-22 Jeff Hobbs + + * generic/tkTableTag.c (Table_TagCmd): made adding tags to + cell/row/col create the tag if it didn't exist. This was + previously an error. + + * generic/tkTable.c (TableDisplay): changed use of NO_XSETCLIP to + only operate on Macintosh, added new Windows code that is the + equivalent of XSetClipRectangles. (teske) + Removed XFillRectangle function that was there for support with + 8.1 (nobody should use 8.1 anymore). + (TableDisplay): Corrected clearing of the area beyond the last + cell to not be incorrect when there is a span on the last cell. + (TableAdjustParams): handle possible div-by-zero for scrollbar + calculations. (christian brunner) + + * generic/tkTable.h: added TableMoveCellValue decl. + * generic/tkTableEdit.c (TableModifyRC): made use of + TableMoveCellValue. + * generic/tkTableCell.c (TableSetCellValue): fixed mem leak in + -cache option. + (TableMoveCellValue): new function to support possible speedier + movement of cells when caching is being used. (michael teske) + + * generic/tkTableCell.c (TableCellCoords): corrected + rowspan/colspan dimension calculation for title cells. + (Table_SetCmd): correct possible abuse in setting result object + pointer. + + * README.txt: updated links + + * win/makefile.vc (pkgIndex.tcl): + * unix/Makefile.in (pkgIndex.tcl): made 8.2 the required base for + the stubs version + + * generic/tkTableCmds.c (Table_GetCmd): fixed potential crash from + abusing object pointer. (jonas hodges) Bug #230701 + + * generic/tkTableTag.c (Table_TagCmd): fix possible hang situation + by preventing refresh when setting the same tag on a cell/row/col. + (Michael Shulz) + +2001-03-28 Jeff Hobbs + + * generic/tkTable.h: change 'char *new' -> 'char *newVal' to not + stump C++ compilers + +2000-10-19 Jeff Hobbs + + * tests/all.tcl: new file + * tests/tkTable.test: copied listbox.test in to serve as a base + for tests on the table widget. Conversion still needs to be done. + + * generic/tkTableCmds.c: #if 0'd stub function Table_Cmd + + * generic/tkTable.h: + * generic/tkTable.c: corrected headers, made TableConfigure static + +2000-08-30 Jeff Hobbs + + * generic/tkTable.h: + * generic/tkTableWin.c (EmbWinConfigure): + * generic/tkTableTag.c (Table_TagCmd): + * generic/tkTable.c (TableConfigure): changed -borderwidth to use + TK_CONFIG_CUSTOM functions for option parsing. + + * win/makefile.vc: + * unix/Makefile.in: updated for added/removed source files + + * generic/cmd.c (removed): + * generic/mm.h (removed): + * generic/tkTableUtil.c (new): moved the few used Cmd_* functions + into tkTableUtil.c (Cmd_Struct moved to tkTable.h), removing the + need for the other accessory files. + + * unix/configure: + * unix/configure.in (uname check): added support for systems where + uname has no -p option (ie HP). + +2000-08-21 Jeff Hobbs + + * generic/tkTable.c (TableConfigure): added check for NULL + oldBorders during configure. + +2000-08-18 Jeff Hobbs + + * generic/tkTable.c: changed the -ipad* defaults to 0, to go along + with the -pad* defaults. For users looking for backwards + compatability with 2.5 padding, add: + option add *Table.ipadX 2 + option add *Table.ipadY 1 + Users will likely find that -pad* is more intuitive though. + **** POTENTIAL INCOMPATABILITY **** + + * doc/tkTable.html: + * doc/tkTable.n: updated docs to reflect new -(i)pad* definitions + and enhanced -bd behavior. + + * generic/tkTable.c (TableCursorEvent, TableConfigCursor): reduced + unnecessary redraws when the cursor was in a non-editable cell. + +2000-08-17 Jeff Hobbs + + * generic/tkTable.c: enhanced -borderwidth option to support + per-edge configuration of borderwith. -bd now takes a list of + pixel sizes, 1, 2 or 4 in length. 1 is traditional, 2 specifies + just the left and right border sizes (to emulate a multicolumn + listbox), and 4 specifies {left right top bottom} for ultimate + control. Tags may override the default. + Also redid the handling of -(i)pad[xy]. Swapped the basic meaning + (-pad* from v2.5 should now be -ipad* in 2.7). -pad* now enforces + absolute empty padding for cells, expanding the default size. + Embedded windows can override the -pad* value. See docs for more. + **** POTENTIAL INCOMPATABILITY **** + + * generic/tkTable.h: removed use of INLINE, added new border style + support to structures. + + * generic/tkTableCell.c (TableAtBorder): made it aware of the new + configurable border style. It bases its calculations off the + default border width(s). Also did lots of comment cleanup. + + * generic/tkTableWin.c (EmbWinDisplay): changed interpretation of + -pad* for windows to be per side (instead of overall). This is + more intuitive. Added support of new border styles. + + * generic/tkTableTag.c: Added new border style control per tag. + New TableGetTagBorders function to determine border values based + on input. Lots of comment/code cleanup. + + * generic/tkTableEdit.c (Table_EditCmd): corrected code to ensure + that when rows where deleted, rows/cols would not fall below 1, + the minimum dimension size (otherwise "bad things" happen). + (Table_EditCmd): corrected problem when specifying a negative + count deleting more rows than exist before the specified index. + + * unix/Makefile.in ($(DLL)): corrected ld build line to not use + SHLIB_CFLAGS, instead adding TK_LD_SEARCH_FLAGS. (virden) + +2000-08-10 Jeff Hobbs + + * unix/Makefile.in: cleaned up Makefile to correctly use the right + flags for building with stubs support. + + * generic/version.h: bumped version to 2.7 + + * generic/tkTable.h: added ipadX, ipadY to table struct. + * generic/tkTable.c (TableConfigure): removed code setting + forceUpdate to 1 for any configure options. + (TableAdjustParams): added -ipdax/-ipday, giving them the meaning + that -pad* was extended to use in 2.6. -pad* are as they were in + 2.5, and -ipad* does the extended cell padding for 2.7+. See docs + for details. + (TableEventProc): removed xexpose.count check that would delay + necessary invalidate calls. (Wangnick) + + * library/tkTable.tcl: added ::tk::table::BackSpace proc instead + of inlined event binding, taking out \ at eol that confused the + tcl2c converter when inlining the tkTable.tcl.h runtime. + +2000-08-02 Jeff Hobbs + + 2.6 RELEASE + + * unix/Makefile.in: added bindist and cleanall targets, and + cleared up the use of some variables to allow for correct building + of the tktable library across platforms (including AIX). + The distclean target no longer removes the generated html doc. + * unix/configure: + * unix/configure.in: added check of available compression program + and SYSID for Unix make bindist target. Also cleaned up the use + of some other variables. + + * generic/tkTable.c (TableConfigCursor, TableCursorEvent) + (TableFlashEvent, TableEventProc): + * generic/tkTableEdit.c (TableDeleteChars, TableInsertChars): + * generic/tkTableCmds.c (Table_CurvalueCmd): removed INV_FORCE + from TableRefresh call. This means more refreshes are delayed. + + * generic/tkTable.c (BUILD_tkTable): corrected EXTERN def'n of + Init funcs. + +2000-08-01 Jeff Hobbs + + * library/tkTable.tcl: rewritten to use ::tk::table namespace + + * generic/tkTable.h: added CONSTRAIN and BETWEEN macros to simply + some MIN/MAX cases. + * generic/tkTable.c: + * generic/tkTableCell.c: + * generic/tkTableCmds.c: updated to use CONSTRAIN/BETWEEN instead + of MIN(MAX()). + + * generic/tkTable.c (TableRefresh): changed to not do anything + when coords < 0 are passed in (like asking to refresh non-existent + active cell). + (TableEventProc): added (likely redundant) check for xexpose.count + == 0 before redisplaying in Expose case. (Halpin) + + * generic/tkTable.c (XFillRectangle): added compat XFillRectangle + to make up for lack of one in Tk8.1. (Nijtmans) + (TableAdjustParams): Made -padx and -pady actually work as + intended for each cell. This actually affects the default size + for a table, as more spacing is given to each cell by default. + Use -padx/y to control this. (Lennard, Hobbs) + (TableDisplay): removed extra call to TableCellCoords (leftover + from NO_SPANS). (Deich) + + * generic/tkTableCmds.c (Table_SelSetCmd): Corrected the selection + of title cells when only title cells are available. (Brutti) + + * library/tkTable.tcl (tkTableChangeWidth): changed -$a to + [expr {-$a}]. (Dubiner) + (tkTableBeginSelect): Changed behavior for extended selectmode to + select in the topleft title area when appropriate. (Dubiner) + (tkTableSelectAll): Changed behavior to select *all* cells + (including title cells) when -selecttitles is 1. + + * demos/loadtable.tcl: corrected to search better in new directory + structure. + +2000-03-22 Jeff Hobbs + + * */*: complete restructure of tktable sources + * CHANGES.txt: moved to ChangeLog, will now use ChangeLog format + +########################################################################## +## TkTable CHANGES +## +## Newest changes at the top of the file. +## Release dates between "****"s. +## +## changes by Hobbs COPYRIGHT 1996-1997 Jeffrey Hobbs, CADIX International +## changes by Hobbs COPYRIGHT 1998-2000 Jeffrey Hobbs +## jeff at hobbs org +## +# * tkTable v0.55-1.x includes additions contributed by: +# * tmoore@spatial.ca (Tom Moore) +# * sebastian.wangnick@eurocontrol.de (Sebastian Wangnick) +# * paulf@lamont.ldgo.columbia.edu +# * peter@bj-ig.de (Peter Brueckner) +# * jeff at hobbs org (Jeffrey Hobbs) +# * ellson@lucent.com (John Ellson) +## +## Mac support provided by Chuck Houpt (choupt@als.com). (v2.3+) +## +########################################################################## + +**** v2.6alpha 29 February 2000 **** + +Fixed row/col insertion/deletion to correctly handle embedded windows. +(fix in part by albrecht@DAnalyse.de) + +Added stubs support to makefile. + +Added support for safe init script (requires embedded runtime) to +be used in safe interpreters. + +Fixed bug in Table_BorderCmd on passing the 6th arg (the optional +row|col). (rickm@vsl.com) + +Added -holdselection arg to row/col insert/delete. (Paolo.Brutti@tlsoft.it) + +Added -DNO_SORT_CELLS ... + +Created tkTableCellSort.c with cell sorting routines. Redid ... + +Fixed bug in tk_tableCut due to change in curselection syntax. + +Fixed missing comma in tkTableEdit.c:32 (Brutti) + +**** v2.5 31 May 1999 **** + +Fixed row/col insertion/deletion to move embedded windows, added +-holdwindows option and Table_Win(Delete|Move). + +Removed -rows/-cols switch to insert/delete row/col, as it could +cause very odd behavioral problems. + +Removed ckfree/ckalloc's between a quick delete/init of a hash table. + +Upgraded ExpandPercents for UTF awareness. + +Changed "tag cell|row|col" to complain when the tag is unknown. + +Fixed bug in UTF char length handling (actually due to change in +the Tk API from 8.1beta to final) for active cell. + +fixed bug where scanMark* weren't properly initialized. + +Changed icursor method to always return an int, being -1 if there +really isn't a valid cursor in the active cell (ie - it's disabled). + +Converted table widget to mostly Tcl_Obj in/output. +Reorganized a lot of code in the process. + +**** v2.4 10 December 1998 **** + +Changed exit handler to not be used (unless -DUSE_EXIT_HANDLER is specified). + +Changed distribution directory name to go with new 'make distrib'. + +Changed TableUndisplay to properly handle unmapping embedded windows +in title areas. Added TableTrueCell for this. + +Changed EmbWinUnmapNow to always call Tk_UnmapWindow. + +Changed cell border drawing so that any 1-pixel border would use the +fast drawing mode (except for when single drawmode is set). + +Changed borderWidth to be a tag-definable value. + +Removed used of borderWidth in border resize cmd calculations. + +Modified various C and Tcl procs to support spanning cells. + +Changed ckfree(value) to Tcl_Free(value) in TableFetchSelection. + +Streamlined use of NO_XSETCLIP, improved boundary checking for +determining whether the cell needs clipping at all. + +Fixed bug in drawing with NO_XSETCLIP to copy the area from the source +window to the clip window, draw on it, then copy it back. Before the +clip window was drawn on clean, losing what might be important stuff in +the source (like an image). + +Added row/col spanning. This involved a lot of code changes, mostly +in tkTableCell.c, mostly #ifndef'ed with NO_SPANS. See docs for behavior. +Added 'spans' and 'hidden' command. + +Fixed bug in TableAtBorder that was messing up certain border cases. + +Added delta error of 1 pixel to the B1-Motion routine, so that the mouse +must move more than a pixel for the tkTableMotion routine to kick in. + +Fixed tkTableBeginToggle to handle Control-B1 properly. (rickm@vsl.com) + +Fixed seg fault in Table_BorderCmd when called with too few args +(reported by rbansal@ltcm.com). + +Added TableGeometryRequest to TableModifyRC to update a table's +geometry according to the new row/col size. + +Fixed EmbWinDelete to clean up properly (it wouldn't clean up if there +wasn't a window associated with the tag). + +Removed unused type arg from TableModifyRCaux. + +Fixed EmbWinRemove to actually remove all info about the window from +the table (as advertised). + *** BEHAVIORAL CHANGE *** + +Fixed "window delete ..." to actually delete the window entry. + +Fixed flashing so that it will flash if any valid data source is +being used (before only the Tcl array source caused flashes). + +Removed deprecated 'flush' command. [.t flush ...] is equivalent +to [.t clear cache ...]. + +Improved TableUndisplay to really work within the proper seen +constraints. (rickm@vsl.com) + +Removed dependency on source for Windows (only for the XSync call). +Should now be able to compile against a binary installed version of wish. + +Use of EXTERN and EXPORT reworked to follow 8.0.3 guidelines. EXPORT +was dropped, meaning that compiling for older versions of the Borland +compiler is not possible. + +Changed use of "$*.h" in Makefile.in to "$@" - some makes seemed to +choke on the proper interpretation of $* (notably HP-UX). + +Added "-fg SELECT_FG" to the default sel tag definition. + +Swapped proto define of Tcl_DStringAppendAll with actual header. + +Fixed #endif SPANS syntax error in Makefile. + +Changed #define CELL from (ROW|COL) to it's own significant bit (this +is used by TableRefresh). + +Added -sparsearray option to allow the user to choose whether the +table treats associated arrays as "sparse", deleting the empty +elements (default), or whether every element set is kept. + +Fixed demos/spreadsheet.tcl to start column labeling with "A". + +Changed Tcl_StaticPackage call in tkAppInit.c to include +SafeInit function. + +Added "empty" bindings to tkTable.tcl to prevent the magic Alt-"menu" +bindings from inserting chars into the table as well. + +**** v2.3 23 July 1998 **** + +Moved the 'set' command into tkTableCell.c and extended it to +understand full row/col setting with Tcl lists. + +Created tkTableInitScript.h to mirror the spirit of tclInitScript.h. +The user can now define a tkTableInit to be eval'ed at load time +that finds the appropriate tkTable.tcl file. Also added env support +for these locations. + +Changed version.in to version.h, a file that is both readable in C +(for the Mac build) and by make (for Unix/Windows). + +Changed TableDisplay #ifdef's to be more specific (NO_XSETCLIP). +Expecting XSetClipRectangles to be available in Tk8.0.3 for Win, +and maybe also in the future for Mac. + +Attempted row/col spanning with limited success. Half functional +code left in for reference, delimited by #ifdef SPANS/#endif. + +Changed TableCellCoords to no longer do bounds checking on row/col. + +Changed several more instances of TableCellCoords/TableInvalidate +to TableRefresh. + +Fixed bug in table insertion/deletion concerning the calculation of +the minkey (minimum valid row/col to insert/delete) when titles were +allowed to be moved. + +Mac support courtesy Chuck Houpt (choupt@als.com). + +**** v2.2 10 July 1998 **** + +Undid caching of activeLayout in favor of activeTagPtr because I was +abusing the nature of the token returned by Tk_ComputeTextLayout, +causing amazingly odd cores. + +Changed TableGetLastCell definition to fix scrollbar bug. (Brutti) + +Changed "#if (TK_MINOR_VERSION > 0)" to "#ifdef TCL_UTF_MAX" to +remove the ambiguity of purpose (for UTF code). + +Fixed bug in TableInsertChars that mangled the purpose of -autoclear, +as well as confusing icursor index when using it. + +**** v2.1 2 July 1998 **** + +Updated man pages, generated new HTML file. + +Reworked directory structure, updated makefiles. + +Removed -batchmode. It was pretty useless, and potentially confusing. + **** POTENTIAL INCOMPATIBILITY **** + +Fixed bug for Tk8.1a2 Unicode display in TableDisplay where the length +of the display string was not calculated correctly. + +Fixed background area redraw bug in Windows. Reworked to take out the +#ifdef WIN32 code without too much compromise. + +Added TableRefresh command that subsumes many CellVCoords/Invalidate +call combos. + +Adjusted TableWhatCell to what it was in v1.82, and made fix in +TableDisplay for bounds to prevent <=0 invalidWidth|Height. + +Added clear command, subsumes flush command, plus adds features. + +Made some cleanup from DestroyNotify repetitive in TableDestroy. + +Added MapNotify event handler to ensure that changes to the table +made when iconified will still cause an update. + +Changed "single" and "fast" drawmodes to not set -bd 1 as a side +effect, but instead to force 0..1 to allow for fast drawing without +any borders. Skipped border drawing case statement when -bd is 0. + +Changed "tag cell ..." to only invalidate for redraw when the affected +cell is visible. + +Added check for NULL tablePtr->tkwin in TableCellVCoords. Could +cause problems where it was used to replace TableCellCoords. + +Fixed bug in TableFetchSelection that truncated the string returned +by -selectioncommand to the length of the original string. Also +fixed mem leak (didn't free all DStrings in an error), and changed +it so that a background error is triggered if there is a problem +with the -selectioncommand. + +Fixed bug in TableDisplay where last row, if one pixel hi, wouldn't +get redrawn properly. + +Changed default fonts to those used for entry widgets. + **** POTENTIAL INCOMPATIBILITY **** + +Added UTF char (Unicode) support, based on 8.1a2 tkEntry.c. Had +to be conditionalized because it doesn't exist in 8.0. + +Added -multiline option for tags to allow old one-line text only, +Reworked tag options so that tag values that aren't ever set won't +affect other tags. + +Fixed seg fault bug in CMD_ACTIVATE when Tk_PointToChar could be called +on double-click, but TableDisplay hadn't yet been called (because it is +waiting for idle) which is required to set tablePtr->activeLayout +properly. Also fixed mem leak with old activeLayout not being freed when +it changed. + +Speed improvement - changed from using Tk_GetGC/Tk_FreeGC to XCreateGc/ +XChangeGC/XFreeGC. Since it was highly unlikely that the caching +provided in the Tk routines would ever benefit us, moving to direct +X calls and manipulating just one GC should be faster. + +**** v2.00 24 April 1998 **** + +Update man pages, generated new HTML version. + +Added "single" drawing mode, and made "single" and "fast" both set +-borderwidth to 1 as a side effect. + +Fixed seg fault on Windows involving large numbers of rows. Unsure +exactly what fixed it, but the problem disappeared amidst all the +changes since v1.82... + +Updated tkAppInit.c to Tk8.1 version. + +Added ifdef for Win32 default colors. + +Since we can now have multi-line cells, changed -rowheight and height +to work the same as -colwidth and width did (+ nums for size in line, +- for sizes in pixels). + **** POTENTIAL INCOMPATIBILITY **** + +Added new "make static" option for making a static library. + +Reworked scrollbar calcs again based on pixels. Fixes all funny off by +half a cell problems. Also prevents scrolling when only title areas are +visible (those are, by design, not scrollable). + +Changed stretching to stretch the last row/col for any stretchmode but +"none", to prevent empty space from appearing. + +Fixed interpretation of CellVCoords to return 1 on slightly visible +cells (now only a 1 pixel square size is required to be considered +visible - used to be 1/4 the desired cell size). + +Added support to allow the second click into the active cell to select +the nearest character. + +Changed binding to work with multi-line cells. + **** POTENTIAL INCOMPATIBILITY **** + +*** Undid 60.06.98 - bad fix +Fixed bug in TableWhatCell that caused the returned cell to be one more +than expected when the edge was passed in. +*** + +Made TableVarProc not cause an Invalidate call if it was +triggered by SetActiveIndex. + +Changed around some function names for sense of modularity (preparing +better C API). + +Commented all procedures in tkTable.c. + +Broke up tkTable.c into constituent files. + +Added support for embedded windows via "window" submethod. + +Fixed quirk in xscrollbar that would make it appear as it all was +in view when the last column was only partially visible. (Brutti) + +Changed several CellCoord calls to CellVCoord calls to only invalidate +if necessary. + +Reworked merging of tags and determination of active cell. State +disabled cells no longer receive the "active" look, although they +are still indexed as active. + +New -selecttitles option, removed prohibition of selecting title areas. + **** POTENTIAL INCOMPATIBILITY **** + +Removed all KANJI, IMP and TK4 #ifdef code. tkTable development now +focused 100% on Tk8+. Also removed Itcl stuff since itcl for Tcl8 +should be different. + **** INCOMPATIBILITY FOR TK4/KANJI/ITCL USERS **** + +**** v1.82 3 April 1998 **** + +Update man pages, generated new HTML version. + +Fixed bug in row start location calculation, reorg'ed some code +for row stretch fill mode. + +Simplified caching of col tags for display. + +Changed code that referenced interp->result to use accessor functions. + +Fixed problem where flat reliefs would be eliminated because they +were assumed to be undefined (TK_RELIEF_FLAT changed in Tk8.1). + +Added -bordercursor and -resizeborders option, added PointerMotionMask +to event handler, moving the tkTableCheckBorder event into C. Should +be much more efficient. + **** POTENTIAL INCOMPATIBILITY **** + +Changed "$(COMPILE.c)" to "$(CC) $(CFLAGS) $(CPPFLAGS) -c" in Makefile.in. +Should be equivalent, but some make's don't understand. + +Change border dragging routines for column to support pixel movement. + +Fixed problem with column widths and row heights being shifted improperly +during row/col deletion (didn't account for - row/col offset). + +Updated tkTable.itcl to same versions as tkTable.tcl (ignored over +several revisions). + +Fixed binding bug in tkTable.tcl for . (Becker) + +changed TableModifyRC to be more selective about what is invalidated +for redraw. (Brutti) + +made 'title' tag have -state disabled by default (an oversight from +the addition of -state tag option in 1.80). + +**** v1.81 March 20 1998 **** + +added support for exact pixel dimensions for column width by using +negative numbers, also supported in -colwidth. Changed width|height +to support 'default' key instead of assuming negative number means default. + **** POTENTIAL INCOMPATIBILITY **** + +added -state tag option (cheap hack, must be improved). + +changed handling of -state table option. (Ellson) + +added -invertselected option. (Brutti) + +added FocusOut binding to commit cell on FocusOut events. + +made the cell commit changes anytime "activate" is called, regardless +of whether the active cell was moved or not. + +"tag cell|col|row|includes tagName" no longer return an error if the tag name +is unknown (just returns empty string, or 0 for "includes"). Only "tag cget" +complains about unknown tag names. + **** POTENTIAL INCOMPATIBILITY **** + +Improved makefiles. (patches courtesy Dukhovni) + +Fixed bug in tkTable.itcl (improperly handled backslash). + +Fix for 8.0 w/ plus/dash patch (Ellson). + +Fixed minor -Wall complaints. + +Changed the way row/col tags were determined to be on a cell. (JMH) + +Made title tag have lower priority than a cell tag. + +Fixed bug where the last table row/col would be deleted when table -state was +disabled (should be a no op). + +**** v1.8 May 28 1997 **** (changes hobbs) + +Moved the instantiation of the tk*Uid variables from the DLLEntryPoint +into the *Init functions for those not compiling this as a DLL. + +Fixed bug where "active" index for an array might not update properly after +the table changes arrays if the previous array's cell had the same value +for the active cell. + +Updated Windows makefile.vc (still far from perfect). + +Fixed calculation error where WhatCell would look for the bottomright +cell a few pixels off (didn't account for highlightWidth). + +Fixed numerous places where cells weren't being invalidated (to be +redrawn) but should have been. + +Fixed bug in curvalue that didn't mark the active text as changed which +would cause editions to be lost when the active cell changed. + +Changed default font for Tk8 from "Helvetica 12" to just "Helvetica" because +the 12 was a tweaking large font on my Sol2.5 machine. + +Renamed -width to -colwidth and -height to -rowheight, replaced with +different interpretation such that -width, -height set the viewable +# of cols, rows (a la listbox or text widget). + **** POTENTIAL INCOMPATIBILITY **** + +Made default title foreground white for better readability. + +Fixed INF/divide by zero possible error for scrollbars when no editable +cells are in view. Possible funky behavior still exists when no editable +cells are available (for selection). + +Fixed possible access violation where TableInvalidate would be called +after the tkwin had been destroyed. + +Enhancement ideas from Pawel Gorazda : + * Added TCL_DEFS to TCL_CFLAGS in Makefile.in + * Make "tag cell tagName" list cells for the special tags + * new "tag includes" method for finding if a cell has a specific tag + * changed selection to not change selection (do nothing) when + the user clicks on a title cell + **** BEHAVIORAL CHANGE **** + +Fixed missing 'q' in tkTable.itcl + +Fixed interaction with -command to only blow up when an error occurs, +not for return/break/ok. + +Changed tkTableCheckBorder to use crosshair instead of fleur because of +complaint of lack of fleur cursor on WinNT. + +Added internal caching with -cache option and flush method for speed +improvements. + +Changed "sel clear all" to use old iterated method of clearing selection +for people who use "sel clear all" in Motion events and such. + +**** v1.7 Apr 11 1997 **** (changes hobbs) + +Changed instances of clearing selection to delete and reinit the +sel hash table instead of going through each entry. + +Updated docs and added demo and basic spreadsheet class for [incr Tcl]. + +Changed default selectmode to browse, same as listbox. + **** POTENTIAL INCOMPATIBLITY **** + +Added forceUpdate arg to TableConfigure to make sure that necessary +parameters will be adjusted at instantiation. + +Changed TableSetCellValue to *unset* empty valued indices instead of +setting them to "". + +Introduced support for row/col insertion/deletion with numerous options. + +Fixed geometry bug that didn't account for highlightWidth in GeometryRequest. + +Added selecttype option to alter the way selection is handled. + +Added padx and pady configuration options. + +Some changes to Makefile.in to get better behavior out of it. + +Changed "see" to ensure cell is fully visible by adding param to +TableCellVCoords. + +Added support for [incr Tcl] (tested against v2.2). + +Fixed TableGetIndex to properly account for row/colOffset > 0. Also +adjusted constraining of user index in TableGetIndex. + +**** v1.6 Feb 7 1997 **** (changes hobbs) + +Fixed x && y offset bug for SLOW drawmode (reported by Michael Johnson). + +Now whenever you move from a cell where an edit has occured, it will +save that edition. You can always use (reread) to get the +old value back before you move the cell. + **** BEHAVIORAL CHANGE **** + +Fixed the bug where inserting characters with autoclear off didn't set +TEXT_CHANGED properly, so you could move without a cell registering the +change (reported by Eric Dolce). + +**** v1.5 Feb 6 1997 **** (changes hobbs) + +Fixed xview/yview scroll page/units problems. + +Fixed TableConfigure error return problems. + +Fixed font display problem for Tk8 (stupid reference error). + +Fixed "set" && "curselection" to understand need for command OR array +existence. + +Fixed conceptual bug in -command %-substitution - there was no way to +get the write value! Redefined %s/S value for -command. + **** POTENTIAL INCOMPATIBLITY **** + +Fixed bug in "see" method reported by PHIL SMITH . +It did the opposite of what it should, caused by the change from +TableCellHidden to TableCellVCoords. + +Optimized TableDisplay. offsetX, offsetY were useless because they were +always subtracted from x && y (so why not do it once... doh!). + +Removed CheckTagCmd and inlined some code. This optimizes certain things +(there was no reason to cache row tags, just move the lookup code!). + +changed TableSetCellValue to not use GetVar, thus a write always occurs, +even if the value is the same. This prevents a read trace from triggering, +but now a write trace will always trigger. + +**** v1.4 Feb 2 1997 **** (changes hobbs) + +Changed default unix font to medium weight (from bold). + +Updated "bbox" method to allow range. + +Added auto-resizable border code with new "border" method, TableAtBorder +function and new Table bindings. + +Changed TableCellHidden to TableCellVCoords & extended it. Now understands +highlightWidth variation and clips area to actual visible coords. + +Added code in TableConfigure to prevent spurious redisplays of the +entire table for any config request. + +fixed index bug where "ROW,COL" translated to "ROW,COL" and +a couple other similar interpretive bugs. + +fixed potential segfault in unsetting "active" element of attached array. + +changed min()/max() to MIN()/MAX() - avoids Windoze warning. + +changed textCurPosn to icursor. + +greatly simplified KANJI interoperability by making activeBuf a regular +char *, changing a few interfaces, and some other stuff. This reduced +the number of KANJI #ifdef's significantly. + +added -command and -usecommand options. + +**** v1.3 Jan 28 1997 **** (changes hobbs) + +Included precompiled Win95/Tk8.0a2 DLL. + +Fixed several compiler warning problems. + +Moved header code to its own header file. + +Fixed some potential mem leaks. + +Added Windows support. HACK ALERT! Without an XSetClipRectangles, an +extra Drawable is used for WIN32. There may be a better way to do this. +If so, make me a patch. + +Data struct / Cmd name changes to avoid any conflict when compiling older +version of Table with newer version in same executable. + +Added -image option to tags. + +Removed NO_TOP_LEFT ifdef'ed code. Topleft should be showing. + +**** v1.2 Jan 18 1997 **** (changes hobbs) + +Updated man page and HTML help page. + +Added TableCellSort to sort a row,col properly. + +Added arg for curvalue method to set the current active buffer. + +Added validation mechanism, validate method and -validate, -validatecommand +options. See docs for details. + +Added "active" key element to traced Tcl array for table. This holds +the activeBuf value of the table. + +Change arrayVar configuration in TableConfigure to only trigger if +the arrayVar actually changed. + +Moved inserting/deleting in active cell to separate functions and +bullet-proofed the code. + +Removed TableFlashConfigure. Not used since "flash" became permanent tag. + +Changed TableSetCellValue to only set the variable if the value +has changed. This will prevent spurious flashing. + +Removed Roland King's COPYRIGHT, replaced with acknowledgements. +This code represents a 90% rewrite of his original code. + +Added -O as default CFLAGS in Makefile.in, along with HP cc note. + +Fixed bug with cursor at position 0 for KANJI (appears to be a bug +in TkWSTextExtents). + +Get/Set variable overhaul to ensure that everything works correctly +for KANJI support (without compile warnings). + +Changed TableBufLengthen to a #define which uses ckrealloc. + +Removed -rowfirstmode and its use in code. It actually didn't work for +many functions and indices would be incorrectly returned. + **** POTENTIAL INCOMPATIBLITY **** + +Fixed handling of arrayVar to accept vars with funny chars (including spaces). + +Added "see active" to tkTableMoveCell. + +Changed calculation of hidden cell to require at least 3/4 of +the cell to be off the screen. + +Cleaned up, optimized lots of code. Cleaned up some memory leaks. + +Removed undocumented "setlist" functionality - it was never used +and I deemed it extraneous. + +Numerous name changes in tkTable.tcl (conforming to standards). Also +added full row/col selection capability && cut/copy/paste functionality. + **** POTENTIAL INCOMPATIBLITY **** + +Changed ".table get ..." to return items in the same way as that +of listbox (only affects handling of spaced values being returned). + **** POTENTIAL INCOMPATIBLITY **** + +Changed Table_GetIndex to TableGetIndex (it was the only _ func). + +Optimized calling of TableAdjustParams in [xy]view and scan dragto +as well as TAP code. + +Removed useless selectionOn C var and "select" index. + **** POTENTIAL INCOMPATIBLITY **** + +Changed the [xy]scrollcmd to receive Tk4+ style args (2 doubles +instead of 4 ints). + +Fixed problems with [xy]view and scan. Might not be perfect yet. +Removed boundary command as it reiterates [yx]view and index, +added "bottomright" special index. Change of code example: + .table bound bottom => .table index bottomright row|col + **** POTENTIAL INCOMPATIBLITY **** + +Fixed problem with cursor not disappearing on focus out. + +Added -browsecommand option for monitoring active cell movement. + +Added selection handler and -rowseparator, -colseparator, +-selectioncommand, -exportselection options. + +Fixed problem with changing var to a simple variable. + +Fixed problems with compiling for KANJI, now seems to work again. + +Fixed highlight border bug. (bruecker) + +Fixed typo that prevented IMP from working. + +**** v1.1 Dec 30 1996 **** (changes hobbs) + +Updated code to handle Tk8 font mechanism. Now works with Tk8. + +Added Tktable_SafeInit procedure so it could be loaded into a safe +interpreter. + +Integrated Bruecker's (peter@bj-ig.de) changes to 0.63: + - Moved IMP-Code to one place, needs testing. + - Some changes to TableCreate and TableDestroy: + Hashtables ever needed are created in Create + so no tests in configure and later needed. + - Removed GcCache (will be placed in TableDisplay) + - Repaired Focus-Code little bug remains in the right + and bottom of HL-Frame. + +Updated README to reflect file name changes. + +Changed tkAppInit.c to reflect tk4.2 appinit. + +Changed Makefile.in to support get X_INCLUDES right. + +**** v1.0 Dec 19 1996 **** (changes hobbs) + +BUMPED VERSION TO 1.0 for initial (re)release. + +Updated man pages, in particular documenting bindings. + +Updated tkTable.tcl to use origin where appropriate. + +Added origin index. + +Added extra arg to insert/delete to specify what is really being +inserted/deleted to/from. + +Corrected insert/delete/icursor to not do edit the active cell if +it has not been set yet. + +Fixed TableScanTo. + +Enabled the display of the topleft title cells. + +Fixed cursor constraint for oversized fonts in a row. + +**** v0.63 Dec 18 96 **** (changes hobbs) + +Removed TableSetCell from tkTable.tcl, rearranged bindings as well. + +Rewrote checkTagCmd, fixed spurious return values. + +Reordered trigger path for Table_GetIndex. + +Fixed see to not be forceful, but to only move if necessary, and to +use the +1,+1 offset from topleft (more like centering). + +Added topleft index. + +ellson patch: + Fixed package require in Makefile.in and demo files + Moved Table_GetIndex to avoid implicit declaration warning. + +Changed how "anchor" was indexed internally. + +Fixed cursor showing in an active cell of width 0. + +Removed check for bounds in SEL_CLEAR (SEL_SET did it for us). + +**** v0.62 Dec 18 96 **** (changes hobbs) + +Updated man pages. + +Removed "#ifdef KANJI0" code (it was useless). + +Added in use of the active tag (it was previously ignored). + +Removed restriction on see method that kept the active cell in the view. + +Changed xview/yview/scan methods to not adjust selRow/Col. + +Changed code to use active cell as active, rather then sel cell. + +Made "flash" tag have higher display priority than "sel". + +Added pattern match support for "tag names". + +Added "tag exists" and "tag cget" submethods. + +Changed "tag celltag" to use Table_GetIndex instead of sscanf + +**** v0.61 patch Dec 14 96 **** (ellson@lucent.com) + +Change "tag celltag" to use index form of cell address,"x,y" instead of list +form "{x y}" + +Add back support for zero width columns and zero height rows. + +Added installation of tkTable.tcl in + [lindex $tcl_pkgPath 0]/Tktable/tkTable.tcl +(0.61 was using the built-in copy of tkTable.tcl so the lack of +installation wasn't noticed. Perhaps we don't need the built-in +version???) I put the runtime script in this directory to make it +trivial to generate binary distributions of the widget consisting of +a single Tktable directory that is just dropped into lib/. + +Added a make target for tablewish (not normally needed with dynamic loading +but sometimes handy for debugging) + +Corrected package name (Wasn't loading from tkcon Interp->Packages menu. +Package name should start with capital letter to match Init entry point.) + +Added configure code to automatically discover --prefix from existing +tclsh installation. Installation is now simply: + ./configure + make install + +**** v0.61 Dec 13 96 **** (all changes jhobbs except noted) + +Updated, corrected, expanded man pages. + +Updated internal code comments, fixed result strings. + +Fixed see problem (reported by Jean-Paul). + +Removed getwidth && getheight and rewrote width && height to be more +flexible and subsume the previous methods. + +Changed flashtime to really be a number representing 1/4 sec and +changed the default to 3 (750ms). Added "flash" as a permanent tag +(like "title", "active", and "sel"). Added options: + -flashmode + -flashtime + +Changed "Title" tag to "title". Why cap it? + +Reformatted most code to fit in 80 cols. + +Fixed activate index offset bug. + +Changed -*title options to -title*. The original version was too +misleading as to its purpose. + +Added fixes from ellson@lucent.com. + test.tcl updates + SIGSEV bug from improper argc count + +Added some changes from peter@bj-ig.de. + New stretch modes LAST && FILL + Highlight/Focus fixes + More options instead of methods + +Improved curselection code. + +added the following options: + -autoclear replaces editmode method + -state replaces editmode method + -insert* from Tk entry, manipulate cursor style + -batchmode replaces batch method + +Changed the dynamic load path for tkTable.tcl from +"$tk_library/tkTable/tkTable.tcl" to "$tk_library/tkTable.tcl". + +**** v0.60 Dec 10 96 **** (all changes jhobbs) +OPTIONS: + +Altered man pages to properly reflect what options are handled (there +were numerous extra, plus many missing). + +changed -procrowtag => -rowtagcommand +changed -proccoltag => -coltagcommand + +Added -bd synonym + +Fixed all internal coding for readability, concise representation + +changed -cursorbg => -insertbackground + +METHODS: + +Fixed lack of break in CMD_*STRETCH + +removed whatcell: code change: + .table whatcell x y => .table index @x,y + +removed whereis, changed to bbox: code change: + .table whereis row col => .table bbox +This needs to be improved to take multiple indices. + +removed toprow && leftcol, added boundary: code change: + .table leftcol|toprow|bottomrow|rightcol ?rowOrCol? + => + .table boundary left|right|top|bottom ?rowOrCol? +rowOrCol can only be specified for top|left, as appropriate (though +a bug in the code didn't check properly). + +removed [rc]index: code change: + .table [rc]index => .table index row|col + +changed get so (1) it works and (2) it returns values more like the +listbox command + +removed setcell. This has been subsumed by the improved selection method. +code likeness: + .table setcell => .table index select + OR => .table curselection + .table setcell 4 2 => .table selection set 4,2 +The "index select" is there for 100% compatibility, but curselection is +what should be used to properly represent all selected cells. + +MISC: + +fixed parse_command to handle full non-ambiguous method names + +updated man pages to include all methods/options in Tk4 style. + +reordered a lot of code to be in "alphabetical" order. + +**** v0.56 Nov 96 **** + - merged changes from tkSpread from Jeffrey Hobbs + - added support for Japanization patch + - added multi-node select support + - removed -underline option for tags + - included default bindings in loadable library + +**** v0.5 Oct 96 **** + - merged changes from Peter Brueckner + - takefocus + - highlight border + - "gcc -Wall -pedantic" cleanup + - updated for tcl7.6/tk4.2 + - autoconf + - only one c-file + +**** v0.4p8 **** + - added patch from wangnick@orthogon.de to make tkTable accept -rows 0 + - added patch from tmoore@pnfi.forestry.ca for handling of bad + array indexes + - added patch from tmoore@pnfi.forestry.ca to add rowTagProc and + colTagProc + - added patch from ellson@lucent.com to support cget so that + tkTable can be used with the dragdrop extension by + fellowsd@cs.man.ac.uk (Donal K. Fellows). + +version 0.3 --> version 0.4 +--------------------------- +tk4.1 and tk4.0 compatability (ellson@lucent.com) + - dynamically loadable library (SunOS 4.1.3 only so far) + - changed BISQUE to GRAY + - statically included TableInit.tcl into dynamic library + - fixed various compiler warnings + (now none with tk4.1, but still one with tk4.0) + - upgraded tkAppInit.c + - changed a few names: library: libtktable.so.0.4 + entry point: Tktable_Init + extended wish: tablewish + +version 0.2 --> version 0.3 +--------------------------- +Upgraded to tk4.0 (Paul Friberg) + +version 0.1 --> version 0.2 +--------------------------- +Changed the tag code to apply the effects of multiple tags to a cell. + +Fixed a bug with the flash code which forgot to delete the flash when +a table was deleted + +Fixed a bug which meant that row, column and cell tag changes didn't +update to the screen immediately when there was a row or column offset. + +Fixed the anchor code which was adding/subtracting a pixel from the +string in certain circumstances + +Fixed a cursor movement bug which caused the same cell to appear twice +when the cursor was moved + +Thanks particularly to Lou Salkind for pointing out some of the above +and suggesting fixes. + + diff --git a/tktable/Makefile.in b/tktable/Makefile.in new file mode 100644 index 0000000..275c625 --- /dev/null +++ b/tktable/Makefile.in @@ -0,0 +1,488 @@ +# Makefile.in -- +# +# This file is a Makefile for Sample TEA Extension. If it has the name +# "Makefile.in" then it is a template for a Makefile; to generate the +# actual Makefile, run "./configure", which is a configuration script +# generated by the "autoconf" program (constructs like "@foo@" will get +# replaced in the actual Makefile. +# +# Copyright (c) 1999 Scriptics Corporation. +# Copyright (c) 2003-2008 ActiveState Software +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: Makefile.in,v 1.15 2008/11/14 23:16:52 hobbs Exp $ + +#======================================================================== +# Nothing of the variables below this line need to be changed. Please +# check the TARGETS section below to make sure the make targets are +# correct. +#======================================================================== + +#======================================================================== +# The names of the source files is defined in the configure script. +# The object files are used for linking into the final library. +# This will be used when a dist target is added to the Makefile. +# It is not important to specify the directory, as long as it is the +# $(srcdir) or in the generic, win or unix subdirectory. +#======================================================================== + +PKG_SOURCES = @PKG_SOURCES@ +PKG_OBJECTS = @PKG_OBJECTS@ + +#======================================================================== +# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with +# this package that need to be installed, if any. +#======================================================================== + +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ + +#======================================================================== +# This is a list of public header files to be installed, if any. +#======================================================================== + +PKG_HEADERS = @PKG_HEADERS@ + +PKG_EXTRA_FILES = license.txt README.txt + +PKG_MAN_PAGES = tkTable.n + +#======================================================================== +# "PKG_LIB_FILE" refers to the library (dynamic or static as per +# configuration options) composed of the named objects. +#======================================================================== + +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ + +lib_BINARIES = $(PKG_LIB_FILE) +BINARIES = tkTable.tcl.h $(lib_BINARIES) + +SHELL = @SHELL@ + +srcdir = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +libdir = @libdir@ +datadir = @datadir@ +mandir = @mandir@ +includedir = @includedir@ + +DESTDIR = + +PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION) +pkgdatadir = $(datadir)/$(PKG_DIR) +pkglibdir = $(libdir)/$(PKG_DIR) +pkgincludedir = $(includedir)/$(PKG_DIR) + +top_builddir = . + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ + +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +CC = @CC@ +CFLAGS_DEFAULT = @CFLAGS_DEFAULT@ +CFLAGS_WARNING = @CFLAGS_WARNING@ +CLEANFILES = @CLEANFILES@ +EXEEXT = @EXEEXT@ +LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@ +MAKE_LIB = @MAKE_LIB@ +MAKE_SHARED_LIB = @MAKE_SHARED_LIB@ +MAKE_STATIC_LIB = @MAKE_STATIC_LIB@ +MAKE_STUB_LIB = @MAKE_STUB_LIB@ +OBJEXT = @OBJEXT@ +RANLIB = @RANLIB@ +RANLIB_STUB = @RANLIB_STUB@ +SHLIB_CFLAGS = @SHLIB_CFLAGS@ +SHLIB_LD = @SHLIB_LD@ +SHLIB_LD_FLAGS = @SHLIB_LD_FLAGS@ +SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ +STLIB_LD = @STLIB_LD@ +TCL_DEFS = @TCL_DEFS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_BIN_DIR = @TK_BIN_DIR@ + +# Not used by sample, but retained for reference of what Tcl required +TCL_LIBS = @TCL_LIBS@ +TK_LIBS = @TK_LIBS@ + +#======================================================================== +# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our +# package without installing. The other environment variables allow us +# to test against an uninstalled Tcl. Add special env vars that you +# require for testing here (like TCLX_LIBRARY). +#======================================================================== + +EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR) +TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \ + TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library` \ + @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \ + PATH="$(EXTRA_PATH):$(PATH)" \ + TCLLIBPATH="$(top_builddir)" +TCLSH_PROG = @TCLSH_PROG@ +WISH_PROG = @WISH_PROG@ +TCLSH = $(TCLSH_ENV) $(TCLSH_PROG) +WISH = $(TCLSH_ENV) $(WISH_PROG) + +# The local includes must come first, because the TK_XINCLUDES can be +# just a comment +INCLUDES = @PKG_INCLUDES@ \ + @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@ + +## NO_EMBEDDED_RUNTIME means that the tkTable.tcl file will not be embedded +## into the executable, thus the default tkTable.tcl library file will not +## be available when the library is loaded. +## If this is defined, the tkTable.tcl file must be available in a +## predefined set of directories (see docs). +#TBL_CFLAGS += -DNO_EMBEDDED_RUNTIME + +## USE_EXIT_HANDLER is necessary for 8.1 before b3 and 8.0 +## It is a work-around for the improper unloading of DLLs when exiting +#TBL_CFLAGS += -DUSE_EXIT_HANDLER + +## NO_SORT_CELLS changes the behavior of certain commands (like curselection) +## to not sort the cells before returning them. If this is not important to +## you, it can cut save significant time for large return sets (> 1000 cells). +## You can always pass the data to [lsort -dictionary $cells] to get the same +## result. +#TBL_CFLAGS += -DNO_SORT_CELLS + +## Experimental, not documented, not complete... +#TBL_CFLAGS += -DPROCS + +## Jeff's magic extra debug flag +#TBL_CFLAGS += -DDEBUG + +PKG_CFLAGS = $(TBL_CFLAGS) @PKG_CFLAGS@ + +DEFS = @DEFS@ $(PKG_CFLAGS) \ + -DTBL_COMMAND=\"table\" \ + -DTBL_RUNTIME=\"tkTable.tcl\" \ + -DTBL_RUNTIME_DIR=\"$(pkglibdir)\" + +CONFIG_CLEAN_FILES = Makefile + +CPPFLAGS = @CPPFLAGS@ +LIBS = @PKG_LIBS@ @LIBS@ +AR = @AR@ +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) + +#======================================================================== +# Start of user-definable TARGETS section +#======================================================================== + +#======================================================================== +# TEA TARGETS. Please note that the "libraries:" target refers to platform +# independent files, and the "binaries:" target inclues executable programs and +# platform-dependent libraries. Modify these targets so that they install +# the various pieces of your package. The make and install rules +# for the BINARIES that you specified above have already been done. +#======================================================================== + +all: binaries libraries doc + +#======================================================================== +# The binaries target builds executable programs, Windows .dll's, unix +# shared/static libraries, and any other platform-dependent files. +# The list of targets to build for "binaries:" is specified at the top +# of the Makefile, in the "BINARIES" variable. +#======================================================================== + +binaries: $(BINARIES) pkgIndex.tcl + +libraries: + +doc: + +install: all install-binaries install-libraries install-doc + +install-binaries: binaries install-lib-binaries install-bin-binaries + @mkdir -p $(DESTDIR)$(pkglibdir) + $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir) + @list='$(PKG_EXTRA_FILES)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + destp=`basename $$p`; \ + echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \ + fi; \ + done + +#======================================================================== +# This rule installs platform-independent files, such as header files. +#======================================================================== + +install-libraries: libraries + +#======================================================================== +# Install documentation. Unix manpages should go in the $(mandir) +# directory. +#======================================================================== + +install-doc: doc + @mkdir -p $(DESTDIR)$(pkglibdir)/html + @list='$(PKG_MAN_PAGES)'; for p in $$list; do \ + html=`basename $$p|sed -e 's/.[^.]*$$//'`.html; \ + $(INSTALL_DATA) $(srcdir)/doc/$$html $(DESTDIR)$(pkglibdir)/html/; \ + done + +html: + cd $(srcdir)/doc; \ + list='$(PKG_MAN_PAGES)'; for p in $$list; do \ + html=`basename $$p|sed -e 's/.[^.]*$$//'`.html; \ + echo "Creating \"$$html\" from \"$$p\""; \ + rm -f $$html; \ + groff -Tascii -man $$p \ + | rman -f HTML \ + > $$html; \ + done + +# Piping to cat is necessary on Windows to see the output, and +# harmless on Unix +test: binaries libraries + $(WISH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) | cat + +demo: binaries libraries + $(WISH) `@CYGPATH@ $(srcdir)/demos/debug.tcl` $(TESTFLAGS) | cat + +shell: binaries libraries + @$(WISH) $(SCRIPT) + +gdb: + $(TCLSH_ENV) gdb $(WISH_PROG) $(SCRIPT) + +depend: + +#======================================================================== +# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable +# mentioned above. That will ensure that this target is built when you +# run "make binaries". +# +# The $(PKG_OBJECTS) objects are created and linked into the final +# library. In most cases these object files will correspond to the +# source files above. +#======================================================================== + +$(PKG_LIB_FILE): $(PKG_OBJECTS) + -rm -f $(PKG_LIB_FILE) + ${MAKE_LIB} + $(RANLIB) $(PKG_LIB_FILE) + +#======================================================================== +# In the following lines, $(srcdir) refers to the toplevel directory +# containing your extension. If your sources are in a subdirectory, +# you will have to modify the paths to reflect this: +# +# tkpkg.$(OBJEXT): $(srcdir)/src/win/tkpkg.c +# $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/tkpkg.c` -o $@ +# +# Setting the VPATH variable to a list of paths will cause the +# makefile to look into these paths when resolving .c to .obj +# dependencies. +#======================================================================== + +# I added leading $(srcdir) because autoconf 2.53 strips it off +VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win + +# I would prefer to use $< over $?, but FreeBSD's can't handle it, and +# with only one prereq, $? is sufficient +tkTable.tcl.h: $(srcdir)/library/tkTable.tcl + sed -e '/^\#/d' -e '/^$$/d' -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' < `@CYGPATH@ $?` > '$@' || { rm -f $@; exit 1; } + +.SUFFIXES: .c .$(OBJEXT) + +.c.@OBJEXT@: + $(COMPILE) -c `@CYGPATH@ $<` -o $@ + +pkgIndex.tcl: + (\ + echo 'if {[catch {package require Tcl 8.2}]} return';\ + echo 'package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \ + [list load [file join $$dir $(PKG_LIB_FILE)] $(PACKAGE_NAME)]'\ + ) > pkgIndex.tcl + +#======================================================================== +# End of user-definable section +#======================================================================== + +#======================================================================== +# Don't modify the file to clean here. Instead, set the "CLEANFILES" +# variable in configure.in +#======================================================================== + +clean: + -test -z "$(BINARIES)" || rm -f $(BINARIES) + -rm -f *.$(OBJEXT) core *.core + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean: clean + -rm -f *.tab.c + -rm -f $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log config.status + +#======================================================================== +# Install binary object libraries. On Windows this includes both .dll and +# .lib files. Because the .lib files are not explicitly listed anywhere, +# we need to deduce their existence from the .dll file of the same name. +# +# You should not have to modify this target. +#======================================================================== + +install-lib-binaries: + @mkdir -p $(DESTDIR)$(pkglibdir) + @list='$(lib_BINARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \ + echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \ + $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \ + ext=`echo $$p|sed -e "s/.*\.//"`; \ + if test "x$$ext" = "xdll"; then \ + lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ + if test -f $$lib; then \ + echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \ + $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \ + fi; \ + fi; \ + fi; \ + done + @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + destp=`basename $$p`; \ + echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \ + fi; \ + done + +#======================================================================== +# Install binary executables (e.g. .exe files) +# +# You should not have to modify this target. +#======================================================================== + +install-bin-binaries: + @mkdir -p $(DESTDIR)$(bindir) + @list='$(bin_BINARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \ + fi; \ + done + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +uninstall-binaries: + list='$(lib_BINARIES)'; for p in $$list; do \ + rm -f $(DESTDIR)$(pkglibdir)/$$p; \ + done + list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ + p=`basename $$p`; \ + rm -f $(DESTDIR)$(pkglibdir)/$$p; \ + done + list='$(bin_BINARIES)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/$$p; \ + done + +#======================================================================== +# Starkit creation - requires ActiveTcl or compatible tclsh +# You should not have to modify this target. +#======================================================================== + +STARKIT_EXT = .kit.tcl +STARKIT_TCLSH = $(TCLSH) +STARKIT_BASE = tclsh +STARKIT = $(PACKAGE_NAME)$(STARKIT_EXT) + +starkit-clean: + rm -f $(STARKIT) + +starkit: starkit-clean + @echo "Building $(STARKIT)" + (\ + echo 'package require vfs'; \ + echo 'package require Mk4tcl'; \ + echo ''; \ + echo 'set HEADER {#!/bin/sh';\ + echo '# \\'; \ + echo 'exec %1s "$$0" $${1+"$$@"}'; \ + echo 'package require starkit'; \ + echo 'starkit::header mk4 -readonly}'; \ + echo ''; \ + echo 'set HEADER [format "$$HEADER\n%c" [file tail [info nameofexe]] 0x1a]'; \ + echo 'set file "$(STARKIT)"'; \ + echo 'set fid [open $$file w]'; \ + echo 'puts $$fid $$HEADER'; \ + echo 'close $$fid'; \ + echo ''; \ + echo 'vfs::mk4::Mount $$file $$file'; \ + echo 'file copy $(PKG_LIB_FILE) $$file/'; \ + echo 'vfs::unmount $$file'; \ + ) | $(STARKIT_TCLSH) + +#======================================================================== +# Distribution creation +# You should not have to modify this target. +#======================================================================== + +TAR = tar +#COMPRESS = $(TAR) cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar +COMPRESS = $(TAR) zcvf $(PKG_DIR).tar.gz $(PKG_DIR) +DIST_ROOT = /tmp/dist +DIST_DIR = $(DIST_ROOT)/$(PKG_DIR) + +dist-clean: + rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.* + +dist: dist-clean + mkdir -p $(DIST_DIR) + cp -p $(srcdir)/README.* $(srcdir)/*.txt $(srcdir)/ChangeLog \ + $(srcdir)/Makefile.in $(srcdir)/aclocal.m4 \ + $(srcdir)/configure $(srcdir)/configure.in $(DIST_DIR)/ + chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4 + chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in + + mkdir $(DIST_DIR)/tclconfig + cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \ + $(DIST_DIR)/tclconfig/ + chmod 664 $(DIST_DIR)/tclconfig/tcl.m4 + chmod +x $(DIST_DIR)/tclconfig/install-sh + + mkdir $(DIST_DIR)/demos + cp -p $(srcdir)/demos/*.{tcl,py,gif} $(DIST_DIR)/demos/ + + mkdir $(DIST_DIR)/doc + cp -p $(srcdir)/doc/*.{html,n} $(DIST_DIR)/doc/ + + mkdir $(DIST_DIR)/generic + cp -p $(srcdir)/generic/*.[ch] $(DIST_DIR)/generic/ + + mkdir $(DIST_DIR)/library + cp -p $(srcdir)/library/*.{tcl,py} $(DIST_DIR)/library/ + + mkdir $(DIST_DIR)/tests + cp -p $(srcdir)/tests/*.{tcl,test} $(DIST_DIR)/tests/ + + mkdir $(DIST_DIR)/unix + cp -p $(srcdir)/unix/tktable.spec $(DIST_DIR)/unix/ + + mkdir $(DIST_DIR)/win + cp -p $(srcdir)/win/makefile.vc $(DIST_DIR)/win/ + + (cd $(DIST_ROOT); $(COMPRESS);) + +.PHONY: all binaries clean depend distclean doc install libraries test + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tktable/README.blt b/tktable/README.blt new file mode 100644 index 0000000..ced2559 --- /dev/null +++ b/tktable/README.blt @@ -0,0 +1,20 @@ +If tkTable is used at the same time as BLT then there are two name +conflicts to be aware of. + +BLT also has a table.n man page. TkTable's man page will still be +available as tkTable.n. + +BLT also has a "table" command. The table command of the last +extension loaded will be in effect. If you need to use both table +commands then eval "rename table blttable" after loading blt and +before loading tkTable, or perhaps "rename table tkTable" if you +load the tkTable extension first. + +In general this shouldn't be a problem as long as you load tkTable +last. The BLT "table" command facilities have been subsumed by the +Tk "grid" command (available in Tk4.1+), so the BLT table should +only be used in legacy code. + +Alternatively, if you want both or have another "table" command, +then change the TBL_COMMAND macro in the makefile before compiling, +and it tkTable will define your named command for the table widget. diff --git a/tktable/README.txt b/tktable/README.txt new file mode 100644 index 0000000..d857716 --- /dev/null +++ b/tktable/README.txt @@ -0,0 +1,149 @@ +/* + * Conceptually based on Tk3 table widget by Roland King (rols@lehman.com) + * + * see ChangeLog file for details + * + * current maintainer: jeff at hobbs org + * + * Copyright 1997-2002, Jeffrey Hobbs (jeff@hobbs.org) + */ + + ************************************* + The Tk Table Widget Version 2.0+ + ************************************* + +INTRODUCTION + +TkTable is a table/matrix widget extension to tk/tcl. +The basic features of the widget are: + + * multi-line cells + * support for embedded windows (one per cell) + * row & column spanning + * variable width columns / height rows (interactively resizable) + * row and column titles + * multiple data sources ((Tcl array || Tcl command) &| internal caching) + * supports standard Tk reliefs, fonts, colors, etc. + * x/y scrollbar support + * 'tag' styles per row, column or cell to change visual appearance + * in-cell editing - returns value back to data source + * support for disabled (read-only) tables or cells (via tags) + * multiple selection modes, with "active" cell + * multiple drawing modes to get optimal performance for larger tables + * optional 'flashes' when things update + * cell validation support + * Works everywhere Tk does (including Windows and Mac!) + * Unicode support (Tk8.1+) + +FINDING THE WIDGET + +0. The newest version is most likely found at: + http://tktable.sourceforge.net/ + http://www.purl.org/net/hobbs/tcl/capp/ + +BUILDING AND INSTALLING THE WIDGET + +1. Uncompress and unpack the distribution + + ON UNIX and OS X: + gzip -cd Tktable.tar.gz | tar xf - + + ON WINDOWS: + use something like WinZip to unpack the archive. + + ON MACINTOSH: + use StuffIt Expander to unstuff the archive. + + This will create a subdirectory tkTable with all the files in it. + +2. Configure + + ON UNIX and OS X: + cd Tktable + ./configure + + tkTable uses information left in tkConfig.sh when you built tk. This + file will be found in $exec_prefix/lib/. You might set the --prefix and + --exec-prefix options of configure if you don't want the default + (/usr/local). If building on multiple unix platforms, the following is + recommended to isolate build conflicts: + mkdir / + cd !$ + /path/to/Tktable/configure + + ON WINDOWS: + + Version 2.8 added support for building in the cygwin environment on + Windows based on TEA (http://www.tcl.tk/doc/tea/). You can retrieve + cygwin from: + http://sources.redhat.com/cygwin/ + + Inside the cygwin environment, you build the same as on Unix. + + Otherwise, hack makefile.vc until it works and compile. It has problems + executing wish from a path with a space in it, but the DLL builds just + fine. A DLL should be available where you found this archive. + +3. Make and Install + + ON UNIX< OS X or WINDOWS (with cygwin): + make + make test (OPTIONAL) + make demo (OPTIONAL) + make install + + ON WINDOWS (makefile.vc): + nmake -f makefile.vc + nmake -f makefile.vc test (OPTIONAL) + nmake -f makefile.vc install + + tkTable is built to comply to the latest tcl package conventions. + There is also a specific "make static" for those who need it. + +4. Use it + + Start a regular wish interpreter, 'load' the library, and use the table. + There are a few test scripts in the demos directory which you can source. + +5. Read the documentation + + There is a Unix manpage and HTML translation provided in the doc/ + subdirectory. These describe the table widget's features and commands + in depth. If something is confusing, just to try it out. + +6. Python users + + There is a library/tktable.py wrapper for use with Python/Tkinter. + +THINGS TO WATCH OUT FOR + +Packing + The table tries not to allocate huge chunks of screen real estate if + you ask it for a lot of rows and columns. You can always stretch out + the frame or explicitly tell it how big it can be. If you want to + stretch the table, remember to pack it with fill both and expand on, + or with grid, give it -sticky news and configure the grid row and column + for some weighting. + +Array + The array elements for the table are of the form array(2,3) etc. Make + sure there are no spaces around the ','. Negative indices are allowed. + +Editing + If you can't edit, remember that the focus model in tk is explicit, so + you need to click on the table or give it the focus command. Just + having a selected cell is not the same thing as being able to edit. + You also need the editing cursor. If you can't get the cursor, make + sure that you actually have a variable assigned to the table, and that + the "state" of the cell is not disabled. + +COMMENTS, BUGS, etc. + +* Please can you send comments and bug reports to the current maintainer + and their best will be done to address them. A mailing list for + tktable discussion is tktable-users@lists.sourceforge.net. + +* If you find a bug, a short piece of Tcl that exercises it would be very + useful, or even better, compile with debugging and specify where it + crashed in that short piece of Tcl. Use the SourceForge site to check + for known bugs or submit new ones. diff --git a/tktable/TODO.txt b/tktable/TODO.txt new file mode 100644 index 0000000..38b79c3 --- /dev/null +++ b/tktable/TODO.txt @@ -0,0 +1,63 @@ +## TODO LIST +## +## updated 1 June 1999, jeff at hobbs org +## +## Any information in here may be out of date. For up-to-date info see: +## http://tktable.sourceforge.net/ +## + +These are recommendations, not all of the same priority, and not +all necessarily will be implemented. If you see something you +feel is important, email me and say so. Very democratic. + +* some sort of textbbox command that will return the size of the + text in a cell, to allow for perfect cell sizing. + +* anchor title areas in different parts of the screen + +* -rowstretchmode fill ignores initial # of rows, or config requests for more. +* interpret 0 rows/cols to be FILL +* add -colstretchmode fill +* scratch stretchmode "fill" in favor of "dynamic" which would monitor + the max extent of row/col (difficult) + +* fix selection routines to properly handle title area movement + +* support smooth scrolling of rows/cols + +* add ability to index by tagname +* overhaul tag mechanism (include way to query for tags on a cell, add + priority) + +* add internal sort procedures +pathName sort -row {the list of rows we want to sort | all} + -col {the list of cols we use for sorting} + -master row,col + -command _command_to_use_ + -type {for each column specifies the type of sort: + ascii | dictionary | integer | real } + -order {for each column specify the order of sort: + increasing | decreasing | none } + +* row/column swap (maybe only in terms of visual remapping) + += BBBB U U GGG SSS +== B B U U G S +==- B BB U U G GGG SSS +== B B U U G G S += BBBB UUU GGGG SSS + +MINOR: + +Windows: With "-colstretchmode last", the scrollbar behaves oddly in + handling the space for the last cell properly when moving the + main part of the scrollbar with the mouse. This seems to be + that even though the scrollbar receives the "set 0.6xxx 1", + the scrollbar immediately jumps back to what the mouse says, + although this isn't a problem in X... + +Windows: when moving windows in "Show Window While Dragging" mode, + the column titles don't refresh properly. + +Windows: When using bitmaps in cells, they occasionally don't redraw + correctly. The work-around is to use -drawmode slow. diff --git a/tktable/aclocal.m4 b/tktable/aclocal.m4 new file mode 100644 index 0000000..0b05739 --- /dev/null +++ b/tktable/aclocal.m4 @@ -0,0 +1,9 @@ +# +# Include the TEA standard macro set +# + +builtin(include,tclconfig/tcl.m4) + +# +# Add here whatever m4 macros you want to define for your package +# diff --git a/tktable/configure b/tktable/configure new file mode 100644 index 0000000..4cdcc3c --- /dev/null +++ b/tktable/configure @@ -0,0 +1,12133 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59 for Tktable 2.10. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='Tktable' +PACKAGE_TARNAME='tktable' +PACKAGE_VERSION='2.10' +PACKAGE_STRING='Tktable 2.10' +PACKAGE_BUGREPORT='' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS TK_VERSION TK_BIN_DIR TK_SRC_DIR TK_LIB_FILE TK_LIB_FLAG TK_LIB_SPEC TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_STUB_LIB_SPEC TK_LIBS TK_XINCLUDES CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS PKG_SOURCES PKG_OBJECTS TCL_INCLUDES TK_INCLUDES CLEANFILES TCL_THREADS SHARED_BUILD AR CELIB_DIR LIBOBJS DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS LD_LIBRARY_PATH_VAR CFLAGS_DEFAULT LDFLAGS_DEFAULT TCL_DBGX MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB TCLSH_PROG WISH_PROG LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures Tktable 2.10 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +X features: + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of Tktable 2.10:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-threads build with threads + --enable-shared build and link with shared libraries (default: on) + --enable-64bit enable 64bit support (default: off) + --enable-64bit-vis enable 64bit Sparc VIS support (default: off) + --disable-rpath disable rpath support (default: on) + --enable-wince enable Win/CE support (where applicable) + --enable-load allow dynamic loading and "load" command (default: + on) + --enable-symbols build with debugging symbols (default: off) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-tcl directory containing tcl configuration + (tclConfig.sh) + --with-tk directory containing tk configuration (tkConfig.sh) + --with-tclinclude directory containing the public Tcl header files + --with-tkinclude directory containing the public Tk header files + --with-x use the X Window System + --with-celib=DIR use Windows/CE support library from DIR + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +Tktable configure 2.10 +generated by GNU Autoconf 2.59 + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by Tktable $as_me 2.10, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#-------------------------------------------------------------------- +# Call TEA_INIT as the first TEA_ macro to set up initial vars. +# This will define a ${TEA_PLATFORM} variable == "unix" or "windows" +# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. +#-------------------------------------------------------------------- + + + # TEA extensions pass this us the version of TEA they think they + # are compatible with. + TEA_VERSION="3.7" + + echo "$as_me:$LINENO: checking for correct TEA configuration" >&5 +echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6 + if test x"${PACKAGE_NAME}" = x ; then + { { echo "$as_me:$LINENO: error: +The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5 +echo "$as_me: error: +The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;} + { (exit 1); exit 1; }; } + fi + if test x"3.7" = x ; then + { { echo "$as_me:$LINENO: error: +TEA version not specified." >&5 +echo "$as_me: error: +TEA version not specified." >&2;} + { (exit 1); exit 1; }; } + elif test "3.7" != "${TEA_VERSION}" ; then + echo "$as_me:$LINENO: result: warning: requested TEA version \"3.7\", have \"${TEA_VERSION}\"" >&5 +echo "${ECHO_T}warning: requested TEA version \"3.7\", have \"${TEA_VERSION}\"" >&6 + else + echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5 +echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6 + fi + case "`uname -s`" in + *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*) + # Extract the first word of "cygpath", so it can be a program name with args. +set dummy cygpath; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CYGPATH+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CYGPATH"; then + ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CYGPATH="cygpath -w" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo" +fi +fi +CYGPATH=$ac_cv_prog_CYGPATH +if test -n "$CYGPATH"; then + echo "$as_me:$LINENO: result: $CYGPATH" >&5 +echo "${ECHO_T}$CYGPATH" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + EXEEXT=".exe" + TEA_PLATFORM="windows" + ;; + *) + CYGPATH=echo + EXEEXT="" + TEA_PLATFORM="unix" + ;; + esac + + # Check if exec_prefix is set. If not use fall back to prefix. + # Note when adjusted, so that TEA_PREFIX can correct for this. + # This is needed for recursive configures, since autoconf propagates + # $prefix, but not $exec_prefix (doh!). + if test x$exec_prefix = xNONE ; then + exec_prefix_default=yes + exec_prefix=$prefix + fi + + + + + # This package name must be replaced statically for AC_SUBST to work + + # Substitute STUB_LIB_FILE in case package creates a stub library too. + + + # We AC_SUBST these here to ensure they are subst'ed, + # in case the user doesn't call TEA_ADD_... + + + + + + + + + +ac_aux_dir= +for ac_dir in tclconfig $srcdir/tclconfig; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + + +#-------------------------------------------------------------------- +# Load the tclConfig.sh file +#-------------------------------------------------------------------- + + + + # + # Ok, lets find the tcl configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tcl + # + + if test x"${no_tcl}" = x ; then + # we reset no_tcl in case something fails here + no_tcl=true + +# Check whether --with-tcl or --without-tcl was given. +if test "${with_tcl+set}" = set; then + withval="$with_tcl" + with_tclconfig=${withval} +fi; + echo "$as_me:$LINENO: checking for Tcl configuration" >&5 +echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6 + if test "${ac_cv_c_tclconfig+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + + # First check to see if --with-tcl was specified. + if test x"${with_tclconfig}" != x ; then + case ${with_tclconfig} in + */tclConfig.sh ) + if test -f ${with_tclconfig}; then + { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5 +echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;} + with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'` + fi ;; + esac + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` + else + { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 +echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} + { (exit 1); exit 1; }; } + fi + fi + + # then check for a private Tcl installation + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ../tcl \ + `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../tcl \ + `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../../tcl \ + `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/unix; pwd)` + break + fi + done + fi + + # on Darwin, check in Framework installation locations + if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ + `ls -d /Library/Frameworks 2>/dev/null` \ + `ls -d /Network/Library/Frameworks 2>/dev/null` \ + `ls -d /System/Library/Frameworks 2>/dev/null` \ + ; do + if test -f "$i/Tcl.framework/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` + break + fi + done + fi + + # TEA specific: on Windows, check in common installation locations + if test "${TEA_PLATFORM}" = "windows" \ + -a x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d C:/Tcl/lib 2>/dev/null` \ + `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ${srcdir}/../tcl \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/unix; pwd)` + break + fi + done + fi + +fi + + + if test x"${ac_cv_c_tclconfig}" = x ; then + TCL_BIN_DIR="# no Tcl configs found" + { { echo "$as_me:$LINENO: error: Can't find Tcl configuration definitions" >&5 +echo "$as_me: error: Can't find Tcl configuration definitions" >&2;} + { (exit 1); exit 1; }; } + else + no_tcl= + TCL_BIN_DIR=${ac_cv_c_tclconfig} + echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5 +echo "${ECHO_T}found ${TCL_BIN_DIR}/tclConfig.sh" >&6 + fi + fi + + + echo "$as_me:$LINENO: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5 +echo $ECHO_N "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... $ECHO_C" >&6 + + if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then + echo "$as_me:$LINENO: result: loading" >&5 +echo "${ECHO_T}loading" >&6 + . "${TCL_BIN_DIR}/tclConfig.sh" + else + echo "$as_me:$LINENO: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5 +echo "${ECHO_T}could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6 + fi + + # eval is required to do the TCL_DBGX substitution + eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" + eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" + + # If the TCL_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TCL_LIB_SPEC will be set to the value + # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC + # instead of TCL_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + if test -f "${TCL_BIN_DIR}/Makefile" ; then + TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} + TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} + TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} + elif test "`uname -s`" = "Darwin"; then + # If Tcl was built as a framework, attempt to use the libraries + # from the framework at the given location so that linking works + # against Tcl.framework installed in an arbitary location. + case ${TCL_DEFS} in + *TCL_FRAMEWORK*) + if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then + for i in "`cd ${TCL_BIN_DIR}; pwd`" \ + "`cd ${TCL_BIN_DIR}/../..; pwd`"; do + if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then + TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}" + break + fi + done + fi + if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then + TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}" + TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" + fi + ;; + esac + fi + + # eval is required to do the TCL_DBGX substitution + eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" + eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" + eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" + eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" + + + + + + + + + + + + + + # TEA specific: + + + + + + + +#-------------------------------------------------------------------- +# Load the tkConfig.sh file if necessary (Tk extension) +#-------------------------------------------------------------------- + + + # + # Ok, lets find the tk configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tk + # + + if test x"${no_tk}" = x ; then + # we reset no_tk in case something fails here + no_tk=true + +# Check whether --with-tk or --without-tk was given. +if test "${with_tk+set}" = set; then + withval="$with_tk" + with_tkconfig=${withval} +fi; + echo "$as_me:$LINENO: checking for Tk configuration" >&5 +echo $ECHO_N "checking for Tk configuration... $ECHO_C" >&6 + if test "${ac_cv_c_tkconfig+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + + # First check to see if --with-tkconfig was specified. + if test x"${with_tkconfig}" != x ; then + case ${with_tkconfig} in + */tkConfig.sh ) + if test -f ${with_tkconfig}; then + { echo "$as_me:$LINENO: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&5 +echo "$as_me: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&2;} + with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'` + fi ;; + esac + if test -f "${with_tkconfig}/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` + else + { { echo "$as_me:$LINENO: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&5 +echo "$as_me: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&2;} + { (exit 1); exit 1; }; } + fi + fi + + # then check for a private Tk library + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ../tk \ + `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \ + ../../tk \ + `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \ + ../../../tk \ + `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/unix/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd $i/unix; pwd)` + break + fi + done + fi + + # on Darwin, check in Framework installation locations + if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ + `ls -d /Library/Frameworks 2>/dev/null` \ + `ls -d /Network/Library/Frameworks 2>/dev/null` \ + `ls -d /System/Library/Frameworks 2>/dev/null` \ + ; do + if test -f "$i/Tk.framework/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)` + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + ; do + if test -f "$i/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd $i; pwd)` + break + fi + done + fi + + # TEA specific: on Windows, check in common installation locations + if test "${TEA_PLATFORM}" = "windows" \ + -a x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d C:/Tcl/lib 2>/dev/null` \ + `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ + ; do + if test -f "$i/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd $i; pwd)` + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ${srcdir}/../tk \ + `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/unix/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd $i/unix; pwd)` + break + fi + done + fi + +fi + + + if test x"${ac_cv_c_tkconfig}" = x ; then + TK_BIN_DIR="# no Tk configs found" + { { echo "$as_me:$LINENO: error: Can't find Tk configuration definitions" >&5 +echo "$as_me: error: Can't find Tk configuration definitions" >&2;} + { (exit 1); exit 1; }; } + else + no_tk= + TK_BIN_DIR=${ac_cv_c_tkconfig} + echo "$as_me:$LINENO: result: found ${TK_BIN_DIR}/tkConfig.sh" >&5 +echo "${ECHO_T}found ${TK_BIN_DIR}/tkConfig.sh" >&6 + fi + fi + + + echo "$as_me:$LINENO: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5 +echo $ECHO_N "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... $ECHO_C" >&6 + + if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then + echo "$as_me:$LINENO: result: loading" >&5 +echo "${ECHO_T}loading" >&6 + . "${TK_BIN_DIR}/tkConfig.sh" + else + echo "$as_me:$LINENO: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5 +echo "${ECHO_T}could not find ${TK_BIN_DIR}/tkConfig.sh" >&6 + fi + + # eval is required to do the TK_DBGX substitution + eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" + eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" + + # If the TK_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TK_LIB_SPEC will be set to the value + # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC + # instead of TK_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + if test -f "${TK_BIN_DIR}/Makefile" ; then + TK_LIB_SPEC=${TK_BUILD_LIB_SPEC} + TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC} + TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH} + elif test "`uname -s`" = "Darwin"; then + # If Tk was built as a framework, attempt to use the libraries + # from the framework at the given location so that linking works + # against Tk.framework installed in an arbitary location. + case ${TK_DEFS} in + *TK_FRAMEWORK*) + if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then + for i in "`cd ${TK_BIN_DIR}; pwd`" \ + "`cd ${TK_BIN_DIR}/../..; pwd`"; do + if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then + TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}" + break + fi + done + fi + if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then + TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}" + TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" + fi + ;; + esac + fi + + # eval is required to do the TK_DBGX substitution + eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" + eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" + eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" + eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" + + # TEA specific: Ensure windowingsystem is defined + if test "${TEA_PLATFORM}" = "unix" ; then + case ${TK_DEFS} in + *MAC_OSX_TK*) + +cat >>confdefs.h <<\_ACEOF +#define MAC_OSX_TK 1 +_ACEOF + + TEA_WINDOWINGSYSTEM="aqua" + ;; + *) + TEA_WINDOWINGSYSTEM="x11" + ;; + esac + elif test "${TEA_PLATFORM}" = "windows" ; then + TEA_WINDOWINGSYSTEM="win32" + fi + + + + + + + + + + + + + + # TEA specific: + + + + +#----------------------------------------------------------------------- +# Handle the --prefix=... option by defaulting to what Tcl gave. +# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. +#----------------------------------------------------------------------- + + + if test "${prefix}" = "NONE"; then + prefix_default=yes + if test x"${TCL_PREFIX}" != x; then + { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5 +echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;} + prefix=${TCL_PREFIX} + else + { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5 +echo "$as_me: --prefix defaulting to /usr/local" >&6;} + prefix=/usr/local + fi + fi + if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ + -o x"${exec_prefix_default}" = x"yes" ; then + if test x"${TCL_EXEC_PREFIX}" != x; then + { echo "$as_me:$LINENO: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5 +echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;} + exec_prefix=${TCL_EXEC_PREFIX} + else + { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5 +echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;} + exec_prefix=$prefix + fi + fi + + +#----------------------------------------------------------------------- +# Standard compiler checks. +# This sets up CC by using the CC env var, or looks for gcc otherwise. +# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create +# the basic setup necessary to compile executables. +#----------------------------------------------------------------------- + + + # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) + # in this macro, they need to go into TEA_SETUP_COMPILER instead. + + # If the user did not set CFLAGS, set it now to keep + # the AC_PROG_CC macro from adding "-g -O2". + if test "${CFLAGS+set}" != "set" ; then + CFLAGS="" + fi + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + + #-------------------------------------------------------------------- + # Checks to see if the make program sets the $MAKE variable. + #-------------------------------------------------------------------- + + echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + + #-------------------------------------------------------------------- + # Find ranlib + #-------------------------------------------------------------------- + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + #-------------------------------------------------------------------- + # Determines the correct binary file extension (.o, .obj, .exe etc.) + #-------------------------------------------------------------------- + + + + + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. + + + #------------------------------------------------------------------------ + # If we're using GCC, see if the compiler understands -pipe. If so, use it. + # It makes compiling go faster. (This is only a performance feature.) + #------------------------------------------------------------------------ + + if test -z "$no_pipe" -a -n "$GCC"; then + echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5 +echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6 +if test "${tcl_cv_cc_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_cc_pipe=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_pipe=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$hold_cflags +fi +echo "$as_me:$LINENO: result: $tcl_cv_cc_pipe" >&5 +echo "${ECHO_T}$tcl_cv_cc_pipe" >&6 + if test $tcl_cv_cc_pipe = yes; then + CFLAGS="$CFLAGS -pipe" + fi + fi + + #-------------------------------------------------------------------- + # Common compiler flag setup + #-------------------------------------------------------------------- + + echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_bigendian=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int +main () +{ + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + if test "${TEA_PLATFORM}" = "unix" ; then + + #-------------------------------------------------------------------- + # On a few very rare systems, all of the libm.a stuff is + # already in libc.a. Set compiler flags accordingly. + # Also, Linux requires the "ieee" library for math to work + # right (and it must appear before "-lm"). + #-------------------------------------------------------------------- + + echo "$as_me:$LINENO: checking for sin" >&5 +echo $ECHO_N "checking for sin... $ECHO_C" >&6 +if test "${ac_cv_func_sin+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define sin to an innocuous variant, in case declares sin. + For example, HP-UX 11i declares gettimeofday. */ +#define sin innocuous_sin + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char sin (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef sin + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char sin (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_sin) || defined (__stub___sin) +choke me +#else +char (*f) () = sin; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != sin; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_sin=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_sin=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5 +echo "${ECHO_T}$ac_cv_func_sin" >&6 +if test $ac_cv_func_sin = yes; then + MATH_LIBS="" +else + MATH_LIBS="-lm" +fi + + echo "$as_me:$LINENO: checking for main in -lieee" >&5 +echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6 +if test "${ac_cv_lib_ieee_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lieee $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_ieee_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_ieee_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5 +echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6 +if test $ac_cv_lib_ieee_main = yes; then + MATH_LIBS="-lieee $MATH_LIBS" +fi + + + #-------------------------------------------------------------------- + # Interactive UNIX requires -linet instead of -lsocket, plus it + # needs net/errno.h to define the socket-related error codes. + #-------------------------------------------------------------------- + + echo "$as_me:$LINENO: checking for main in -linet" >&5 +echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6 +if test "${ac_cv_lib_inet_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-linet $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_inet_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_inet_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5 +echo "${ECHO_T}$ac_cv_lib_inet_main" >&6 +if test $ac_cv_lib_inet_main = yes; then + LIBS="$LIBS -linet" +fi + + if test "${ac_cv_header_net_errno_h+set}" = set; then + echo "$as_me:$LINENO: checking for net/errno.h" >&5 +echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 +if test "${ac_cv_header_net_errno_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 +echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking net/errno.h usability" >&5 +echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking net/errno.h presence" >&5 +echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: net/errno.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for net/errno.h" >&5 +echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 +if test "${ac_cv_header_net_errno_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_net_errno_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 +echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 + +fi +if test $ac_cv_header_net_errno_h = yes; then + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_NET_ERRNO_H 1 +_ACEOF + +fi + + + + #-------------------------------------------------------------------- + # Check for the existence of the -lsocket and -lnsl libraries. + # The order here is important, so that they end up in the right + # order in the command line generated by make. Here are some + # special considerations: + # 1. Use "connect" and "accept" to check for -lsocket, and + # "gethostbyname" to check for -lnsl. + # 2. Use each function name only once: can't redo a check because + # autoconf caches the results of the last check and won't redo it. + # 3. Use -lnsl and -lsocket only if they supply procedures that + # aren't already present in the normal libraries. This is because + # IRIX 5.2 has libraries, but they aren't needed and they're + # bogus: they goof up name resolution if used. + # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. + # To get around this problem, check for both libraries together + # if -lsocket doesn't work by itself. + #-------------------------------------------------------------------- + + tcl_checkBoth=0 + echo "$as_me:$LINENO: checking for connect" >&5 +echo $ECHO_N "checking for connect... $ECHO_C" >&6 +if test "${ac_cv_func_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define connect to an innocuous variant, in case declares connect. + For example, HP-UX 11i declares gettimeofday. */ +#define connect innocuous_connect + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char connect (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef connect + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_connect) || defined (__stub___connect) +choke me +#else +char (*f) () = connect; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != connect; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_connect=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_connect=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 +echo "${ECHO_T}$ac_cv_func_connect" >&6 +if test $ac_cv_func_connect = yes; then + tcl_checkSocket=0 +else + tcl_checkSocket=1 +fi + + if test "$tcl_checkSocket" = 1; then + echo "$as_me:$LINENO: checking for setsockopt" >&5 +echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6 +if test "${ac_cv_func_setsockopt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define setsockopt to an innocuous variant, in case declares setsockopt. + For example, HP-UX 11i declares gettimeofday. */ +#define setsockopt innocuous_setsockopt + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char setsockopt (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef setsockopt + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char setsockopt (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_setsockopt) || defined (__stub___setsockopt) +choke me +#else +char (*f) () = setsockopt; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != setsockopt; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_setsockopt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_setsockopt=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 +echo "${ECHO_T}$ac_cv_func_setsockopt" >&6 +if test $ac_cv_func_setsockopt = yes; then + : +else + echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 +echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_setsockopt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char setsockopt (); +int +main () +{ +setsockopt (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_setsockopt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_setsockopt=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6 +if test $ac_cv_lib_socket_setsockopt = yes; then + LIBS="$LIBS -lsocket" +else + tcl_checkBoth=1 +fi + +fi + + fi + if test "$tcl_checkBoth" = 1; then + tk_oldLibs=$LIBS + LIBS="$LIBS -lsocket -lnsl" + echo "$as_me:$LINENO: checking for accept" >&5 +echo $ECHO_N "checking for accept... $ECHO_C" >&6 +if test "${ac_cv_func_accept+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define accept to an innocuous variant, in case declares accept. + For example, HP-UX 11i declares gettimeofday. */ +#define accept innocuous_accept + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char accept (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef accept + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char accept (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_accept) || defined (__stub___accept) +choke me +#else +char (*f) () = accept; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != accept; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_accept=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_accept=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5 +echo "${ECHO_T}$ac_cv_func_accept" >&6 +if test $ac_cv_func_accept = yes; then + tcl_checkNsl=0 +else + LIBS=$tk_oldLibs +fi + + fi + echo "$as_me:$LINENO: checking for gethostbyname" >&5 +echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 +if test "${ac_cv_func_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define gethostbyname to an innocuous variant, in case declares gethostbyname. + For example, HP-UX 11i declares gettimeofday. */ +#define gethostbyname innocuous_gethostbyname + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef gethostbyname + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +char (*f) () = gethostbyname; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != gethostbyname; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_gethostbyname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 +if test $ac_cv_func_gethostbyname = yes; then + : +else + echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 +echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_nsl_gethostbyname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 +if test $ac_cv_lib_nsl_gethostbyname = yes; then + LIBS="$LIBS -lnsl" +fi + +fi + + + # TEA specific: Don't perform the eval of the libraries here because + # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS + + TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' + + + + + echo "$as_me:$LINENO: checking dirent.h" >&5 +echo $ECHO_N "checking dirent.h... $ECHO_C" >&6 +if test "${tcl_cv_dirent_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +int +main () +{ + +#ifndef _POSIX_SOURCE +# ifdef __Lynx__ + /* + * Generate compilation error to make the test fail: Lynx headers + * are only valid if really in the POSIX environment. + */ + + missing_procedure(); +# endif +#endif +DIR *d; +struct dirent *entryPtr; +char *p; +d = opendir("foobar"); +entryPtr = readdir(d); +p = entryPtr->d_name; +closedir(d); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_dirent_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_dirent_h=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5 +echo "${ECHO_T}$tcl_cv_dirent_h" >&6 + + if test $tcl_cv_dirent_h = no; then + +cat >>confdefs.h <<\_ACEOF +#define NO_DIRENT_H 1 +_ACEOF + + fi + + # TEA specific: + if test "${ac_cv_header_errno_h+set}" = set; then + echo "$as_me:$LINENO: checking for errno.h" >&5 +echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 +if test "${ac_cv_header_errno_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 +echo "${ECHO_T}$ac_cv_header_errno_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking errno.h usability" >&5 +echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking errno.h presence" >&5 +echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: errno.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: errno.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for errno.h" >&5 +echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 +if test "${ac_cv_header_errno_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_errno_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 +echo "${ECHO_T}$ac_cv_header_errno_h" >&6 + +fi +if test $ac_cv_header_errno_h = yes; then + : +else + +cat >>confdefs.h <<\_ACEOF +#define NO_ERRNO_H 1 +_ACEOF + +fi + + + if test "${ac_cv_header_float_h+set}" = set; then + echo "$as_me:$LINENO: checking for float.h" >&5 +echo $ECHO_N "checking for float.h... $ECHO_C" >&6 +if test "${ac_cv_header_float_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 +echo "${ECHO_T}$ac_cv_header_float_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking float.h usability" >&5 +echo $ECHO_N "checking float.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking float.h presence" >&5 +echo $ECHO_N "checking float.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for float.h" >&5 +echo $ECHO_N "checking for float.h... $ECHO_C" >&6 +if test "${ac_cv_header_float_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_float_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 +echo "${ECHO_T}$ac_cv_header_float_h" >&6 + +fi +if test $ac_cv_header_float_h = yes; then + : +else + +cat >>confdefs.h <<\_ACEOF +#define NO_FLOAT_H 1 +_ACEOF + +fi + + + if test "${ac_cv_header_values_h+set}" = set; then + echo "$as_me:$LINENO: checking for values.h" >&5 +echo $ECHO_N "checking for values.h... $ECHO_C" >&6 +if test "${ac_cv_header_values_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 +echo "${ECHO_T}$ac_cv_header_values_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking values.h usability" >&5 +echo $ECHO_N "checking values.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking values.h presence" >&5 +echo $ECHO_N "checking values.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: values.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for values.h" >&5 +echo $ECHO_N "checking for values.h... $ECHO_C" >&6 +if test "${ac_cv_header_values_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_values_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 +echo "${ECHO_T}$ac_cv_header_values_h" >&6 + +fi +if test $ac_cv_header_values_h = yes; then + : +else + +cat >>confdefs.h <<\_ACEOF +#define NO_VALUES_H 1 +_ACEOF + +fi + + + if test "${ac_cv_header_limits_h+set}" = set; then + echo "$as_me:$LINENO: checking for limits.h" >&5 +echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 +if test "${ac_cv_header_limits_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 +echo "${ECHO_T}$ac_cv_header_limits_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking limits.h usability" >&5 +echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking limits.h presence" >&5 +echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: limits.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for limits.h" >&5 +echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 +if test "${ac_cv_header_limits_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_limits_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 +echo "${ECHO_T}$ac_cv_header_limits_h" >&6 + +fi +if test $ac_cv_header_limits_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIMITS_H 1 +_ACEOF + +else + +cat >>confdefs.h <<\_ACEOF +#define NO_LIMITS_H 1 +_ACEOF + +fi + + + if test "${ac_cv_header_stdlib_h+set}" = set; then + echo "$as_me:$LINENO: checking for stdlib.h" >&5 +echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 +if test "${ac_cv_header_stdlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking stdlib.h usability" >&5 +echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking stdlib.h presence" >&5 +echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: stdlib.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for stdlib.h" >&5 +echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 +if test "${ac_cv_header_stdlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_stdlib_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 + +fi +if test $ac_cv_header_stdlib_h = yes; then + tcl_ok=1 +else + tcl_ok=0 +fi + + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strtol" >/dev/null 2>&1; then + : +else + tcl_ok=0 +fi +rm -f conftest* + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strtoul" >/dev/null 2>&1; then + : +else + tcl_ok=0 +fi +rm -f conftest* + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strtod" >/dev/null 2>&1; then + : +else + tcl_ok=0 +fi +rm -f conftest* + + if test $tcl_ok = 0; then + +cat >>confdefs.h <<\_ACEOF +#define NO_STDLIB_H 1 +_ACEOF + + fi + if test "${ac_cv_header_string_h+set}" = set; then + echo "$as_me:$LINENO: checking for string.h" >&5 +echo $ECHO_N "checking for string.h... $ECHO_C" >&6 +if test "${ac_cv_header_string_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 +echo "${ECHO_T}$ac_cv_header_string_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking string.h usability" >&5 +echo $ECHO_N "checking string.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking string.h presence" >&5 +echo $ECHO_N "checking string.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: string.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for string.h" >&5 +echo $ECHO_N "checking for string.h... $ECHO_C" >&6 +if test "${ac_cv_header_string_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_string_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 +echo "${ECHO_T}$ac_cv_header_string_h" >&6 + +fi +if test $ac_cv_header_string_h = yes; then + tcl_ok=1 +else + tcl_ok=0 +fi + + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strstr" >/dev/null 2>&1; then + : +else + tcl_ok=0 +fi +rm -f conftest* + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strerror" >/dev/null 2>&1; then + : +else + tcl_ok=0 +fi +rm -f conftest* + + + # See also memmove check below for a place where NO_STRING_H can be + # set and why. + + if test $tcl_ok = 0; then + +cat >>confdefs.h <<\_ACEOF +#define NO_STRING_H 1 +_ACEOF + + fi + + if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo "$as_me:$LINENO: checking for sys/wait.h" >&5 +echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking sys/wait.h usability" >&5 +echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking sys/wait.h presence" >&5 +echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/wait.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for sys/wait.h" >&5 +echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_wait_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 + +fi +if test $ac_cv_header_sys_wait_h = yes; then + : +else + +cat >>confdefs.h <<\_ACEOF +#define NO_SYS_WAIT_H 1 +_ACEOF + +fi + + + if test "${ac_cv_header_dlfcn_h+set}" = set; then + echo "$as_me:$LINENO: checking for dlfcn.h" >&5 +echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 +if test "${ac_cv_header_dlfcn_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 +echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 +echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 +echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for dlfcn.h" >&5 +echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 +if test "${ac_cv_header_dlfcn_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_dlfcn_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 +echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 + +fi +if test $ac_cv_header_dlfcn_h = yes; then + : +else + +cat >>confdefs.h <<\_ACEOF +#define NO_DLFCN_H 1 +_ACEOF + +fi + + + + # OS/390 lacks sys/param.h (and doesn't need it, by chance). + +for ac_header in sys/param.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ---------------------------------- ## +## Report this to the Tktable lists. ## +## ---------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + # Let the user call this, because if it triggers, they will + # need a compat/strtod.c that is correct. Users can also + # use Tcl_GetDouble(FromObj) instead. + #TEA_BUGGY_STRTOD + fi + + +#----------------------------------------------------------------------- +# __CHANGE__ +# Specify the C source files to compile in TEA_ADD_SOURCES, +# public headers that need to be installed in TEA_ADD_HEADERS, +# stub library C source files to compile in TEA_ADD_STUB_SOURCES, +# and runtime Tcl library files in TEA_ADD_TCL_SOURCES. +# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS +# and PKG_TCL_SOURCES. +#----------------------------------------------------------------------- + + + vars="tkTable.c tkTableWin.c tkTableTag.c tkTableEdit.c + tkTableCell.c tkTableCellSort.c tkTableCmds.c tkTableUtil.c" + for i in $vars; do + case $i in + \$*) + # allow $-var names + PKG_SOURCES="$PKG_SOURCES $i" + PKG_OBJECTS="$PKG_OBJECTS $i" + ;; + *) + # check for existence - allows for generic/win/unix VPATH + # To add more dirs here (like 'src'), you have to update VPATH + # in Makefile.in as well + if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ + -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ + ; then + { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 +echo "$as_me: error: could not find source file '$i'" >&2;} + { (exit 1); exit 1; }; } + fi + PKG_SOURCES="$PKG_SOURCES $i" + # this assumes it is in a VPATH dir + i=`basename $i` + # handle user calling this before or after TEA_SETUP_COMPILER + if test x"${OBJEXT}" != x ; then + j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" + else + j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" + fi + PKG_OBJECTS="$PKG_OBJECTS $j" + ;; + esac + done + + + +# PostScript is on the drawing board +#TEA_ADD_SOURCES([tkTablePs.c]) +# This header isn't really meant for distribution +#TEA_ADD_HEADERS([generic/tkTable.h]) + + vars="-I. -I\"`${CYGPATH} ${srcdir}/generic`\"" + for i in $vars; do + PKG_INCLUDES="$PKG_INCLUDES $i" + done + + + + PKG_CFLAGS="$PKG_CFLAGS " + + + + vars="" + for i in $vars; do + # check for existence - allows for generic/win/unix VPATH + if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ + -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ + ; then + { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5 +echo "$as_me: error: could not find stub source file '$i'" >&2;} + { (exit 1); exit 1; }; } + fi + PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" + # this assumes it is in a VPATH dir + i=`basename $i` + # handle user calling this before or after TEA_SETUP_COMPILER + if test x"${OBJEXT}" != x ; then + j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" + else + j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" + fi + PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" + done + + + + + vars="library/tkTable.tcl library/tktable.py" + for i in $vars; do + # check for existence, be strict because it is installed + if test ! -f "${srcdir}/$i" ; then + { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5 +echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;} + { (exit 1); exit 1; }; } + fi + PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" + done + + + +#-------------------------------------------------------------------- +# __CHANGE__ +# Choose which headers you need. Extension authors should try very +# hard to only rely on the Tcl public header files. Internal headers +# contain private data structures and are subject to change without +# notice. +# This MUST be called after TEA_PATH_TCLCONFIG/TEA_LOAD_TCLCONFIG +#-------------------------------------------------------------------- + + + echo "$as_me:$LINENO: checking for Tcl public headers" >&5 +echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6 + + +# Check whether --with-tclinclude or --without-tclinclude was given. +if test "${with_tclinclude+set}" = set; then + withval="$with_tclinclude" + with_tclinclude=${withval} +fi; + + if test "${ac_cv_c_tclh+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + # Use the value from --with-tclinclude, if it was given + + if test x"${with_tclinclude}" != x ; then + if test -f "${with_tclinclude}/tcl.h" ; then + ac_cv_c_tclh=${with_tclinclude} + else + { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5 +echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;} + { (exit 1); exit 1; }; } + fi + else + if test "`uname -s`" = "Darwin"; then + # If Tcl was built as a framework, attempt to use + # the framework's Headers directory + case ${TCL_DEFS} in + *TCL_FRAMEWORK*) + list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" + ;; + esac + fi + + # Look in the source dir only if Tcl is not installed, + # and in that situation, look there before installed locations. + if test -f "${TCL_BIN_DIR}/Makefile" ; then + list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" + fi + + # Check order: pkg --prefix location, Tcl's --prefix location, + # relative to directory of tclConfig.sh. + + eval "temp_includedir=${includedir}" + list="$list \ + `ls -d ${temp_includedir} 2>/dev/null` \ + `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ + `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" + if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then + list="$list /usr/local/include /usr/include" + if test x"${TCL_INCLUDE_SPEC}" != x ; then + d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` + list="$list `ls -d ${d} 2>/dev/null`" + fi + fi + for i in $list ; do + if test -f "$i/tcl.h" ; then + ac_cv_c_tclh=$i + break + fi + done + fi + +fi + + + # Print a message based on how we determined the include path + + if test x"${ac_cv_c_tclh}" = x ; then + { { echo "$as_me:$LINENO: error: tcl.h not found. Please specify its location with --with-tclinclude" >&5 +echo "$as_me: error: tcl.h not found. Please specify its location with --with-tclinclude" >&2;} + { (exit 1); exit 1; }; } + else + echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5 +echo "${ECHO_T}${ac_cv_c_tclh}" >&6 + fi + + # Convert to a native path and substitute into the output files. + + INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` + + TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" + + + + + echo "$as_me:$LINENO: checking for Tk public headers" >&5 +echo $ECHO_N "checking for Tk public headers... $ECHO_C" >&6 + + +# Check whether --with-tkinclude or --without-tkinclude was given. +if test "${with_tkinclude+set}" = set; then + withval="$with_tkinclude" + with_tkinclude=${withval} +fi; + + if test "${ac_cv_c_tkh+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + # Use the value from --with-tkinclude, if it was given + + if test x"${with_tkinclude}" != x ; then + if test -f "${with_tkinclude}/tk.h" ; then + ac_cv_c_tkh=${with_tkinclude} + else + { { echo "$as_me:$LINENO: error: ${with_tkinclude} directory does not contain tk.h" >&5 +echo "$as_me: error: ${with_tkinclude} directory does not contain tk.h" >&2;} + { (exit 1); exit 1; }; } + fi + else + if test "`uname -s`" = "Darwin"; then + # If Tk was built as a framework, attempt to use + # the framework's Headers directory. + case ${TK_DEFS} in + *TK_FRAMEWORK*) + list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" + ;; + esac + fi + + # Look in the source dir only if Tk is not installed, + # and in that situation, look there before installed locations. + if test -f "${TK_BIN_DIR}/Makefile" ; then + list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" + fi + + # Check order: pkg --prefix location, Tk's --prefix location, + # relative to directory of tkConfig.sh, Tcl's --prefix location, + # relative to directory of tclConfig.sh. + + eval "temp_includedir=${includedir}" + list="$list \ + `ls -d ${temp_includedir} 2>/dev/null` \ + `ls -d ${TK_PREFIX}/include 2>/dev/null` \ + `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ + `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ + `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" + if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then + list="$list /usr/local/include /usr/include" + fi + for i in $list ; do + if test -f "$i/tk.h" ; then + ac_cv_c_tkh=$i + break + fi + done + fi + +fi + + + # Print a message based on how we determined the include path + + if test x"${ac_cv_c_tkh}" = x ; then + { { echo "$as_me:$LINENO: error: tk.h not found. Please specify its location with --with-tkinclude" >&5 +echo "$as_me: error: tk.h not found. Please specify its location with --with-tkinclude" >&2;} + { (exit 1); exit 1; }; } + else + echo "$as_me:$LINENO: result: ${ac_cv_c_tkh}" >&5 +echo "${ECHO_T}${ac_cv_c_tkh}" >&6 + fi + + # Convert to a native path and substitute into the output files. + + INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` + + TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" + + + + if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then + # On Windows and Aqua, we need the X compat headers + echo "$as_me:$LINENO: checking for X11 header files" >&5 +echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 + if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then + INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" + TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" + + fi + echo "$as_me:$LINENO: result: ${INCLUDE_DIR_NATIVE}" >&5 +echo "${ECHO_T}${INCLUDE_DIR_NATIVE}" >&6 + fi + +#TEA_PRIVATE_TCL_HEADERS +#TEA_PRIVATE_TK_HEADERS + +#-------------------------------------------------------------------- +# For Unix/Tk builds, make sure that the X libraries/headers are found. +#-------------------------------------------------------------------- + + + if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then + + echo "$as_me:$LINENO: checking for X" >&5 +echo $ECHO_N "checking for X... $ECHO_C" >&6 + + +# Check whether --with-x or --without-x was given. +if test "${with_x+set}" = set; then + withval="$with_x" + +fi; +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then + # Both variables are already set. + have_x=yes + else + if test "${ac_cv_have_x+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=no ac_x_libraries=no +rm -fr conftest.dir +if mkdir conftest.dir; then + cd conftest.dir + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat >Imakefile <<'_ACEOF' +acfindx: + @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' +_ACEOF + if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which would confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl; do + if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && + test -f $ac_im_libdir/libX11.$ac_extension; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case $ac_im_incroot in + /usr/include) ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; + esac + case $ac_im_usrlibdir in + /usr/lib | /lib) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; + esac + fi + cd .. + rm -fr conftest.dir +fi + +# Standard set of common directories for X headers. +# Check X11 before X11Rn because it is often a symlink to the current release. +ac_x_header_dirs=' +/usr/X11/include +/usr/X11R6/include +/usr/X11R5/include +/usr/X11R4/include + +/usr/include/X11 +/usr/include/X11R6 +/usr/include/X11R5 +/usr/include/X11R4 + +/usr/local/X11/include +/usr/local/X11R6/include +/usr/local/X11R5/include +/usr/local/X11R4/include + +/usr/local/include/X11 +/usr/local/include/X11R6 +/usr/local/include/X11R5 +/usr/local/include/X11R4 + +/usr/X386/include +/usr/x386/include +/usr/XFree86/include/X11 + +/usr/include +/usr/local/include +/usr/unsupported/include +/usr/athena/include +/usr/local/x11r5/include +/usr/lpp/Xamples/include + +/usr/openwin/include +/usr/openwin/share/include' + +if test "$ac_x_includes" = no; then + # Guess where to find include files, by looking for Intrinsic.h. + # First, try using that file with no special directory specified. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # We can compile using X headers with no special include directory. +ac_x_includes= +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + for ac_dir in $ac_x_header_dirs; do + if test -r "$ac_dir/X11/Intrinsic.h"; then + ac_x_includes=$ac_dir + break + fi +done +fi +rm -f conftest.err conftest.$ac_ext +fi # $ac_x_includes = no + +if test "$ac_x_libraries" = no; then + # Check for the libraries. + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS=$LIBS + LIBS="-lXt $LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +XtMalloc (0) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + LIBS=$ac_save_LIBS +# We can link X programs with no special library path. +ac_x_libraries= +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +LIBS=$ac_save_LIBS +for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` +do + # Don't even attempt the hair of trying to link an X program! + for ac_extension in a so sl; do + if test -r $ac_dir/libXt.$ac_extension; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi # $ac_x_libraries = no + +if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then + # Didn't find X anywhere. Cache the known absence of X. + ac_cv_have_x="have_x=no" +else + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" +fi +fi + + fi + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + echo "$as_me:$LINENO: result: $have_x" >&5 +echo "${ECHO_T}$have_x" >&6 + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$x_includes ac_x_libraries=$x_libraries" + echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 +echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6 +fi + + not_really_there="" + if test "$no_x" = ""; then + if test "$x_includes" = ""; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + not_really_there="yes" +fi +rm -f conftest.err conftest.$ac_ext + else + if test ! -r $x_includes/X11/Intrinsic.h; then + not_really_there="yes" + fi + fi + fi + if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then + echo "$as_me:$LINENO: checking for X11 header files" >&5 +echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 + found_xincludes="no" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + found_xincludes="yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + found_xincludes="no" +fi +rm -f conftest.err conftest.$ac_ext + if test "$found_xincludes" = "no"; then + dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" + for i in $dirs ; do + if test -r $i/X11/Intrinsic.h; then + echo "$as_me:$LINENO: result: $i" >&5 +echo "${ECHO_T}$i" >&6 + XINCLUDES=" -I$i" + found_xincludes="yes" + break + fi + done + fi + else + if test "$x_includes" != ""; then + XINCLUDES="-I$x_includes" + found_xincludes="yes" + fi + fi + if test found_xincludes = "no"; then + echo "$as_me:$LINENO: result: couldn't find any!" >&5 +echo "${ECHO_T}couldn't find any!" >&6 + fi + + if test "$no_x" = yes; then + echo "$as_me:$LINENO: checking for X11 libraries" >&5 +echo $ECHO_N "checking for X11 libraries... $ECHO_C" >&6 + XLIBSW=nope + dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" + for i in $dirs ; do + if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then + echo "$as_me:$LINENO: result: $i" >&5 +echo "${ECHO_T}$i" >&6 + XLIBSW="-L$i -lX11" + x_libraries="$i" + break + fi + done + else + if test "$x_libraries" = ""; then + XLIBSW=-lX11 + else + XLIBSW="-L$x_libraries -lX11" + fi + fi + if test "$XLIBSW" = nope ; then + echo "$as_me:$LINENO: checking for XCreateWindow in -lXwindow" >&5 +echo $ECHO_N "checking for XCreateWindow in -lXwindow... $ECHO_C" >&6 +if test "${ac_cv_lib_Xwindow_XCreateWindow+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXwindow $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char XCreateWindow (); +int +main () +{ +XCreateWindow (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_Xwindow_XCreateWindow=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_Xwindow_XCreateWindow=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_Xwindow_XCreateWindow" >&5 +echo "${ECHO_T}$ac_cv_lib_Xwindow_XCreateWindow" >&6 +if test $ac_cv_lib_Xwindow_XCreateWindow = yes; then + XLIBSW=-lXwindow +fi + + fi + if test "$XLIBSW" = nope ; then + echo "$as_me:$LINENO: result: could not find any! Using -lX11." >&5 +echo "${ECHO_T}could not find any! Using -lX11." >&6 + XLIBSW=-lX11 + fi + # TEA specific: + if test x"${XLIBSW}" != x ; then + PKG_LIBS="${PKG_LIBS} ${XLIBSW}" + fi + + fi + + +#-------------------------------------------------------------------- +# __CHANGE__ +# A few miscellaneous platform-specific items: +# +# Define a special symbol for Windows (BUILD_Tktable in this case) so +# that we create the export library with the dll. +# +# Windows creates a few extra files that need to be cleaned up. +# You can add more files to clean if your extension creates any extra +# files. +# +# TEA_ADD any extra compiler/build info here. +#-------------------------------------------------------------------- + +if test "${TEA_PLATFORM}" = "windows" ; then + cat >>confdefs.h <<_ACEOF +#define BUILD_Tktable 1 +_ACEOF + + CLEANFILES="pkgIndex.tcl tkTable.tcl.h *.lib *.dll *.exp *.ilk *.pdb *.pch" + + vars="gdi32.lib user32.lib" + for i in $vars; do + if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then + # Convert foo.lib to -lfoo for GCC. No-op if not *.lib + i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` + fi + PKG_LIBS="$PKG_LIBS $i" + done + + +else + CLEANFILES="pkgIndex.tcl tkTable.tcl.h" +fi + + +#-------------------------------------------------------------------- +# Check whether --enable-threads or --disable-threads was given. +# So far only Tcl responds to this one. +#-------------------------------------------------------------------- + + + # Check whether --enable-threads or --disable-threads was given. +if test "${enable_threads+set}" = set; then + enableval="$enable_threads" + tcl_ok=$enableval +else + tcl_ok=yes +fi; + + if test "${enable_threads+set}" = set; then + enableval="$enable_threads" + tcl_ok=$enableval + else + tcl_ok=yes + fi + + if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + TCL_THREADS=1 + + if test "${TEA_PLATFORM}" != "windows" ; then + # We are always OK on Windows, so check what this platform wants: + + # USE_THREAD_ALLOC tells us to try the special thread-based + # allocator that significantly reduces lock contention + +cat >>confdefs.h <<\_ACEOF +#define USE_THREAD_ALLOC 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _REENTRANT 1 +_ACEOF + + if test "`uname -s`" = "SunOS" ; then + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_PTHREAD_SEMANTICS 1 +_ACEOF + + fi + +cat >>confdefs.h <<\_ACEOF +#define _THREAD_SAFE 1 +_ACEOF + + echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 +echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6 +if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_mutex_init (); +int +main () +{ +pthread_mutex_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthread_pthread_mutex_init=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthread_pthread_mutex_init=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6 +if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then + tcl_ok=yes +else + tcl_ok=no +fi + + if test "$tcl_ok" = "no"; then + # Check a little harder for __pthread_mutex_init in the same + # library, as some systems hide it there until pthread.h is + # defined. We could alternatively do an AC_TRY_COMPILE with + # pthread.h, but that will work with libpthread really doesn't + # exist, like AIX 4.2. [Bug: 4359] + echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5 +echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6 +if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char __pthread_mutex_init (); +int +main () +{ +__pthread_mutex_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthread___pthread_mutex_init=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthread___pthread_mutex_init=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6 +if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then + tcl_ok=yes +else + tcl_ok=no +fi + + fi + + if test "$tcl_ok" = "yes"; then + # The space is needed + THREADS_LIBS=" -lpthread" + else + echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5 +echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6 +if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthreads $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_mutex_init (); +int +main () +{ +pthread_mutex_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthreads_pthread_mutex_init=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthreads_pthread_mutex_init=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6 +if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then + tcl_ok=yes +else + tcl_ok=no +fi + + if test "$tcl_ok" = "yes"; then + # The space is needed + THREADS_LIBS=" -lpthreads" + else + echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5 +echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6 +if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_mutex_init (); +int +main () +{ +pthread_mutex_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_c_pthread_mutex_init=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_c_pthread_mutex_init=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6 +if test $ac_cv_lib_c_pthread_mutex_init = yes; then + tcl_ok=yes +else + tcl_ok=no +fi + + if test "$tcl_ok" = "no"; then + echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5 +echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6 +if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc_r $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_mutex_init (); +int +main () +{ +pthread_mutex_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_c_r_pthread_mutex_init=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_c_r_pthread_mutex_init=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6 +if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then + tcl_ok=yes +else + tcl_ok=no +fi + + if test "$tcl_ok" = "yes"; then + # The space is needed + THREADS_LIBS=" -pthread" + else + TCL_THREADS=0 + { echo "$as_me:$LINENO: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5 +echo "$as_me: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&2;} + fi + fi + fi + fi + fi + else + TCL_THREADS=0 + fi + # Do checking message here to not mess up interleaved configure output + echo "$as_me:$LINENO: checking for building with threads" >&5 +echo $ECHO_N "checking for building with threads... $ECHO_C" >&6 + if test "${TCL_THREADS}" = 1; then + +cat >>confdefs.h <<\_ACEOF +#define TCL_THREADS 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes (default)" >&5 +echo "${ECHO_T}yes (default)" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + # TCL_THREADS sanity checking. See if our request for building with + # threads is the same as the way Tcl was built. If not, warn the user. + case ${TCL_DEFS} in + *THREADS=1*) + if test "${TCL_THREADS}" = "0"; then + { echo "$as_me:$LINENO: WARNING: + Building ${PACKAGE_NAME} without threads enabled, but building against Tcl + that IS thread-enabled. It is recommended to use --enable-threads." >&5 +echo "$as_me: WARNING: + Building ${PACKAGE_NAME} without threads enabled, but building against Tcl + that IS thread-enabled. It is recommended to use --enable-threads." >&2;} + fi + ;; + *) + if test "${TCL_THREADS}" = "1"; then + { echo "$as_me:$LINENO: WARNING: + --enable-threads requested, but building against a Tcl that is NOT + thread-enabled. This is an OK configuration that will also run in + a thread-enabled core." >&5 +echo "$as_me: WARNING: + --enable-threads requested, but building against a Tcl that is NOT + thread-enabled. This is an OK configuration that will also run in + a thread-enabled core." >&2;} + fi + ;; + esac + + + +#-------------------------------------------------------------------- +# The statement below defines a collection of symbols related to +# building as a shared library instead of a static library. +#-------------------------------------------------------------------- + + + echo "$as_me:$LINENO: checking how to build libraries" >&5 +echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6 + # Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + tcl_ok=$enableval +else + tcl_ok=yes +fi; + + if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + tcl_ok=$enableval + else + tcl_ok=yes + fi + + if test "$tcl_ok" = "yes" ; then + echo "$as_me:$LINENO: result: shared" >&5 +echo "${ECHO_T}shared" >&6 + SHARED_BUILD=1 + else + echo "$as_me:$LINENO: result: static" >&5 +echo "${ECHO_T}static" >&6 + SHARED_BUILD=0 + +cat >>confdefs.h <<\_ACEOF +#define STATIC_BUILD 1 +_ACEOF + + fi + + + +#-------------------------------------------------------------------- +# This macro figures out what flags to use with the compiler/linker +# when building shared/static debug/optimized objects. This information +# can be taken from the tclConfig.sh file, but this figures it all out. +#-------------------------------------------------------------------- + + + + + # Step 0.a: Enable 64 bit support? + + echo "$as_me:$LINENO: checking if 64bit support is requested" >&5 +echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6 + # Check whether --enable-64bit or --disable-64bit was given. +if test "${enable_64bit+set}" = set; then + enableval="$enable_64bit" + do64bit=$enableval +else + do64bit=no +fi; + echo "$as_me:$LINENO: result: $do64bit" >&5 +echo "${ECHO_T}$do64bit" >&6 + + # Step 0.b: Enable Solaris 64 bit VIS support? + + echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5 +echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6 + # Check whether --enable-64bit-vis or --disable-64bit-vis was given. +if test "${enable_64bit_vis+set}" = set; then + enableval="$enable_64bit_vis" + do64bitVIS=$enableval +else + do64bitVIS=no +fi; + echo "$as_me:$LINENO: result: $do64bitVIS" >&5 +echo "${ECHO_T}$do64bitVIS" >&6 + # Force 64bit on with VIS + if test "$do64bitVIS" = "yes"; then + do64bit=yes +fi + + + # Step 0.c: Check if visibility support is available. Do this here so + # that platform specific alternatives can be used below if this fails. + + echo "$as_me:$LINENO: checking if compiler supports visibility \"hidden\"" >&5 +echo $ECHO_N "checking if compiler supports visibility \"hidden\"... $ECHO_C" >&6 +if test "${tcl_cv_cc_visibility_hidden+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + extern __attribute__((__visibility__("hidden"))) void f(void); + void f(void) {} +int +main () +{ +f(); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_cc_visibility_hidden=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_visibility_hidden=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS=$hold_cflags +fi +echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5 +echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6 + if test $tcl_cv_cc_visibility_hidden = yes; then + + +cat >>confdefs.h <<\_ACEOF +#define MODULE_SCOPE extern __attribute__((__visibility__("hidden"))) +_ACEOF + + +fi + + + # Step 0.d: Disable -rpath support? + + echo "$as_me:$LINENO: checking if rpath support is requested" >&5 +echo $ECHO_N "checking if rpath support is requested... $ECHO_C" >&6 + # Check whether --enable-rpath or --disable-rpath was given. +if test "${enable_rpath+set}" = set; then + enableval="$enable_rpath" + doRpath=$enableval +else + doRpath=yes +fi; + echo "$as_me:$LINENO: result: $doRpath" >&5 +echo "${ECHO_T}$doRpath" >&6 + + # TEA specific: Cross-compiling options for Windows/CE builds? + + if test "${TEA_PLATFORM}" = windows; then + + echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5 +echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6 + # Check whether --enable-wince or --disable-wince was given. +if test "${enable_wince+set}" = set; then + enableval="$enable_wince" + doWince=$enableval +else + doWince=no +fi; + echo "$as_me:$LINENO: result: $doWince" >&5 +echo "${ECHO_T}$doWince" >&6 + +fi + + + # Step 1: set the variable "system" to hold the name and version number + # for the system. + + + echo "$as_me:$LINENO: checking system version" >&5 +echo $ECHO_N "checking system version... $ECHO_C" >&6 +if test "${tcl_cv_sys_version+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + # TEA specific: + if test "${TEA_PLATFORM}" = "windows" ; then + tcl_cv_sys_version=windows + elif test -f /usr/lib/NextStep/software_version; then + tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` + else + tcl_cv_sys_version=`uname -s`-`uname -r` + if test "$?" -ne 0 ; then + { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5 +echo "$as_me: WARNING: can't find uname command" >&2;} + tcl_cv_sys_version=unknown + else + # Special check for weird MP-RAS system (uname returns weird + # results, and the version is kept in special file). + + if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then + tcl_cv_sys_version=MP-RAS-`awk '{print $3}' /etc/.relid` + fi + if test "`uname -s`" = "AIX" ; then + tcl_cv_sys_version=AIX-`uname -v`.`uname -r` + fi + fi + fi + +fi +echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5 +echo "${ECHO_T}$tcl_cv_sys_version" >&6 + system=$tcl_cv_sys_version + + + # Step 2: check for existence of -ldl library. This is needed because + # Linux can use either -ldl or -ldld for dynamic loading. + + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + have_dl=yes +else + have_dl=no +fi + + + # Require ranlib early so we can override it in special cases below. + + + + # Step 3: set configuration options based on system name and version. + # This is similar to Tcl's unix/tcl.m4 except that we've added a + # "windows" case. + + do64bit_ok=no + LDFLAGS_ORIG="$LDFLAGS" + # When ld needs options to work in 64-bit mode, put them in + # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load] + # is disabled by the user. [Bug 1016796] + LDFLAGS_ARCH="" + TCL_EXPORT_FILE_SUFFIX="" + UNSHARED_LIB_SUFFIX="" + # TEA specific: use PACKAGE_VERSION instead of VERSION + TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' + ECHO_VERSION='`echo ${PACKAGE_VERSION}`' + TCL_LIB_VERSIONS_OK=ok + CFLAGS_DEBUG=-g + CFLAGS_OPTIMIZE=-O + if test "$GCC" = yes; then + + # TEA specific: + CFLAGS_OPTIMIZE=-O2 + CFLAGS_WARNING="-Wall -Wno-implicit-int" + +else + CFLAGS_WARNING="" +fi + + TCL_NEEDS_EXP_FILE=0 + TCL_BUILD_EXP_FILE="" + TCL_EXP_FILE="" + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STLIB_LD='${AR} cr' + LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" + case $system in + # TEA specific: + windows) + # This is a 2-stage check to make sure we have the 64-bit SDK + # We have to know where the SDK is installed. + # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs + # MACHINE is IX86 for LINK, but this is used by the manifest, + # which requires x86|amd64|ia64. + MACHINE="X86" + if test "$do64bit" != "no" ; then + if test "x${MSSDK}x" = "xx" ; then + MSSDK="C:/Progra~1/Microsoft Platform SDK" + fi + MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` + PATH64="" + case "$do64bit" in + amd64|x64|yes) + MACHINE="AMD64" ; # default to AMD64 64-bit build + PATH64="${MSSDK}/Bin/Win64/x86/AMD64" + ;; + ia64) + MACHINE="IA64" + PATH64="${MSSDK}/Bin/Win64" + ;; + esac + if test ! -d "${PATH64}" ; then + { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5 +echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;} + { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5 +echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;} + do64bit="no" + else + echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 +echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 + do64bit_ok="yes" + fi + fi + + if test "$doWince" != "no" ; then + if test "$do64bit" != "no" ; then + { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5 +echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;} + { (exit 1); exit 1; }; } + fi + if test "$GCC" = "yes" ; then + { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5 +echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;} + { (exit 1); exit 1; }; } + fi + + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-celib + + if test x"${no_celib}" = x ; then + # we reset no_celib in case something fails here + no_celib=true + +# Check whether --with-celib or --without-celib was given. +if test "${with_celib+set}" = set; then + withval="$with_celib" + with_celibconfig=${withval} +fi; + echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5 +echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6 + if test "${ac_cv_c_celibconfig+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + # First check to see if --with-celibconfig was specified. + if test x"${with_celibconfig}" != x ; then + if test -d "${with_celibconfig}/inc" ; then + ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` + else + { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5 +echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;} + { (exit 1); exit 1; }; } + fi + fi + + # then check for a celib library + if test x"${ac_cv_c_celibconfig}" = x ; then + for i in \ + ../celib-palm-3.0 \ + ../celib \ + ../../celib-palm-3.0 \ + ../../celib \ + `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \ + ${srcdir}/../celib-palm-3.0 \ + ${srcdir}/../celib \ + `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \ + ; do + if test -d "$i/inc" ; then + ac_cv_c_celibconfig=`(cd $i; pwd)` + break + fi + done + fi + +fi + + if test x"${ac_cv_c_celibconfig}" = x ; then + { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5 +echo "$as_me: error: Cannot find celib support library directory" >&2;} + { (exit 1); exit 1; }; } + else + no_celib= + CELIB_DIR=${ac_cv_c_celibconfig} + CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` + echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5 +echo "${ECHO_T}found $CELIB_DIR" >&6 + fi + fi + + # Set defaults for common evc4/PPC2003 setup + # Currently Tcl requires 300+, possibly 420+ for sockets + CEVERSION=420; # could be 211 300 301 400 420 ... + TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... + ARCH=ARM; # could be ARM MIPS X86EM ... + PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" + if test "$doWince" != "yes"; then + # If !yes then the user specified something + # Reset ARCH to allow user to skip specifying it + ARCH= + eval `echo $doWince | awk -F, '{ \ + if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \ + if ($1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ + if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \ + if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \ + if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \ + }'` + if test "x${ARCH}" = "x" ; then + ARCH=$TARGETCPU; + fi + fi + OSVERSION=WCE$CEVERSION; + if test "x${WCEROOT}" = "x" ; then + WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" + if test ! -d "${WCEROOT}" ; then + WCEROOT="C:/Program Files/Microsoft eMbedded Tools" + fi + fi + if test "x${SDKROOT}" = "x" ; then + SDKROOT="C:/Program Files/Windows CE Tools" + if test ! -d "${SDKROOT}" ; then + SDKROOT="C:/Windows CE Tools" + fi + fi + WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` + SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` + if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ + -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then + { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5 +echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;} + { (exit 1); exit 1; }; } + doWince="no" + else + # We could PATH_NOSPACE these, but that's not important, + # as long as we quote them when used. + CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" + if test -d "${CEINCLUDE}/${TARGETCPU}" ; then + CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" + fi + CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" + fi + fi + + if test "$GCC" != "yes" ; then + if test "${SHARED_BUILD}" = "0" ; then + runtime=-MT + else + runtime=-MD + fi + + if test "$do64bit" != "no" ; then + # All this magic is necessary for the Win64 SDK RC1 - hobbs + CC="\"${PATH64}/cl.exe\"" + CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" + RC="\"${MSSDK}/bin/rc.exe\"" + lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" + LINKBIN="\"${PATH64}/link.exe\"" + CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" + CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" + # Avoid 'unresolved external symbol __security_cookie' + # errors, c.f. http://support.microsoft.com/?id=894573 + + vars="bufferoverflowU.lib" + for i in $vars; do + if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then + # Convert foo.lib to -lfoo for GCC. No-op if not *.lib + i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` + fi + PKG_LIBS="$PKG_LIBS $i" + done + + + elif test "$doWince" != "no" ; then + CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" + if test "${TARGETCPU}" = "X86"; then + CC="\"${CEBINROOT}/cl.exe\"" + else + CC="\"${CEBINROOT}/cl${ARCH}.exe\"" + fi + CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" + RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" + arch=`echo ${ARCH} | awk '{print tolower($0)}'` + defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" + if test "${SHARED_BUILD}" = "1" ; then + # Static CE builds require static celib as well + defs="${defs} _DLL" + fi + for i in $defs ; do + +cat >>confdefs.h <<_ACEOF +#define $i 1 +_ACEOF + + done + +cat >>confdefs.h <<_ACEOF +#define _WIN32_WCE $CEVERSION +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define UNDER_CE $CEVERSION +_ACEOF + + CFLAGS_DEBUG="-nologo -Zi -Od" + CFLAGS_OPTIMIZE="-nologo -Ox" + lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` + lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" + LINKBIN="\"${CEBINROOT}/link.exe\"" + + else + RC="rc" + lflags="-nologo" + LINKBIN="link" + CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" + CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" + fi + fi + + if test "$GCC" = "yes"; then + # mingw gcc mode + RC="windres" + CFLAGS_DEBUG="-g" + CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" + SHLIB_LD="$CC -shared" + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' + LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" + LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" + else + SHLIB_LD="${LINKBIN} -dll ${lflags}" + # link -lib only works when -lib is the first arg + STLIB_LD="${LINKBIN} -lib ${lflags}" + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' + PATHTYPE=-w + # For information on what debugtype is most useful, see: + # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp + # and also + # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx + # This essentially turns it all on. + LDFLAGS_DEBUG="-debug -debugtype:cv" + LDFLAGS_OPTIMIZE="-release" + if test "$doWince" != "no" ; then + LDFLAGS_CONSOLE="-link ${lflags}" + LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} + else + LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" + LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" + fi + fi + + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".dll" + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' + + TCL_LIB_VERSIONS_OK=nodots + # Bogus to avoid getting this turned off + DL_OBJS="tclLoadNone.obj" + ;; + AIX-*) + if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then + + # AIX requires the _r compiler when gcc isn't being used + case "${CC}" in + *_r) + # ok ... + ;; + *) + CC=${CC}_r + ;; + esac + echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5 +echo "${ECHO_T}Using $CC for compiling with threads" >&6 + +fi + + LIBS="$LIBS -lc" + SHLIB_CFLAGS="" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + + DL_OBJS="tclLoadDl.o" + LD_LIBRARY_PATH_VAR="LIBPATH" + + # Check to enable 64-bit flags for compiler/linker on AIX 4+ + if test "$do64bit" = yes -a "`uname -v`" -gt 3; then + + if test "$GCC" = yes; then + + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 +echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} + +else + + do64bit_ok=yes + CFLAGS="$CFLAGS -q64" + LDFLAGS_ARCH="-q64" + RANLIB="${RANLIB} -X64" + AR="${AR} -X64" + SHLIB_LD_FLAGS="-b64" + +fi + + +fi + + + if test "`uname -m`" = ia64; then + + # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC + SHLIB_LD="/usr/ccs/bin/ld -G -z text" + # AIX-5 has dl* in libc.so + DL_LIBS="" + if test "$GCC" = yes; then + + CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' + +else + + CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' + +fi + + LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' + +else + + if test "$GCC" = yes; then + SHLIB_LD='${CC} -shared' +else + + SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry" + +fi + + SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}" + DL_LIBS="-ldl" + CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + TCL_NEEDS_EXP_FILE=1 + # TEA specific: use PACKAGE_VERSION instead of VERSION + TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp' + +fi + + + # AIX v<=4.1 has some different flags than 4.2+ + if test "$system" = "AIX-4.1" -o "`uname -v`" -lt 4; then + + case $LIBOBJS in + "tclLoadAix.$ac_objext" | \ + *" tclLoadAix.$ac_objext" | \ + "tclLoadAix.$ac_objext "* | \ + *" tclLoadAix.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;; +esac + + DL_LIBS="-lld" + +fi + + + # On AIX <=v4 systems, libbsd.a has to be linked in to support + # non-blocking file IO. This library has to be linked in after + # the MATH_LIBS or it breaks the pow() function. The way to + # insure proper sequencing, is to add it to the tail of MATH_LIBS. + # This library also supplies gettimeofday. + # + # AIX does not have a timezone field in struct tm. When the AIX + # bsd library is used, the timezone global and the gettimeofday + # methods are to be avoided for timezone deduction instead, we + # deduce the timezone by comparing the localtime result on a + # known GMT value. + + echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5 +echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6 +if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gettimeofday (); +int +main () +{ +gettimeofday (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_bsd_gettimeofday=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_bsd_gettimeofday=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5 +echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6 +if test $ac_cv_lib_bsd_gettimeofday = yes; then + libbsd=yes +else + libbsd=no +fi + + if test $libbsd = yes; then + + MATH_LIBS="$MATH_LIBS -lbsd" + +cat >>confdefs.h <<\_ACEOF +#define USE_DELTA_FOR_TZ 1 +_ACEOF + + +fi + + ;; + BeOS*) + SHLIB_CFLAGS="-fPIC" + SHLIB_LD='${CC} -nostart' + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + + #----------------------------------------------------------- + # Check for inet_ntoa in -lbind, for BeOS (which also needs + # -lsocket, even if the network functions are in -lnet which + # is always linked to, for compatibility. + #----------------------------------------------------------- + echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5 +echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6 +if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbind $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char inet_ntoa (); +int +main () +{ +inet_ntoa (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_bind_inet_ntoa=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_bind_inet_ntoa=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5 +echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6 +if test $ac_cv_lib_bind_inet_ntoa = yes; then + LIBS="$LIBS -lbind -lsocket" +fi + + ;; + BSD/OS-2.1*|BSD/OS-3*) + SHLIB_CFLAGS="" + SHLIB_LD="shlicc -r" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + BSD/OS-4.*) + SHLIB_CFLAGS="-export-dynamic -fPIC" + SHLIB_LD='${CC} -shared' + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + LDFLAGS="$LDFLAGS -export-dynamic" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + dgux*) + SHLIB_CFLAGS="-K PIC" + SHLIB_LD='${CC} -G' + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + HP-UX-*.11.*) + # Use updated header definitions where possible + +cat >>confdefs.h <<\_ACEOF +#define _XOPEN_SOURCE_EXTENDED 1 +_ACEOF + + # TEA specific: Needed by Tcl, but not most extensions + #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?]) + #LIBS="$LIBS -lxnet" # Use the XOPEN network library + + if test "`uname -m`" = ia64; then + + SHLIB_SUFFIX=".so" + # Use newer C++ library for C++ extensions + #if test "$GCC" != "yes" ; then + # CPPFLAGS="-AA" + #fi + +else + + SHLIB_SUFFIX=".sl" + +fi + + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + tcl_ok=yes +else + tcl_ok=no +fi + + if test "$tcl_ok" = yes; then + + SHLIB_CFLAGS="+z" + SHLIB_LD="ld -b" + SHLIB_LD_LIBS='${LIBS}' + DL_OBJS="tclLoadShl.o" + DL_LIBS="-ldld" + LDFLAGS="$LDFLAGS -Wl,-E" + CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' + LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' + LD_LIBRARY_PATH_VAR="SHLIB_PATH" + +fi + + if test "$GCC" = yes; then + + SHLIB_LD='${CC} -shared' + SHLIB_LD_LIBS='${LIBS}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + +fi + + + # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc + #CFLAGS="$CFLAGS +DAportable" + + # Check to enable 64-bit flags for compiler/linker + if test "$do64bit" = "yes"; then + + if test "$GCC" = yes; then + + case `${CC} -dumpmachine` in + hppa64*) + # 64-bit gcc in use. Fix flags for GNU ld. + do64bit_ok=yes + SHLIB_LD='${CC} -shared' + SHLIB_LD_LIBS='${LIBS}' + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' +fi + + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + ;; + *) + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 +echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} + ;; + esac + +else + + do64bit_ok=yes + CFLAGS="$CFLAGS +DD64" + LDFLAGS_ARCH="+DD64" + +fi + + +fi + ;; + HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) + SHLIB_SUFFIX=".sl" + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + tcl_ok=yes +else + tcl_ok=no +fi + + if test "$tcl_ok" = yes; then + + SHLIB_CFLAGS="+z" + SHLIB_LD="ld -b" + SHLIB_LD_LIBS="" + DL_OBJS="tclLoadShl.o" + DL_LIBS="-ldld" + LDFLAGS="$LDFLAGS -Wl,-E" + CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' + LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' + LD_LIBRARY_PATH_VAR="SHLIB_PATH" + +fi + ;; + IRIX-5.*) + SHLIB_CFLAGS="" + SHLIB_LD="ld -shared -rdata_shared" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' +fi + + ;; + IRIX-6.*) + SHLIB_CFLAGS="" + SHLIB_LD="ld -n32 -shared -rdata_shared" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' +fi + + if test "$GCC" = yes; then + + CFLAGS="$CFLAGS -mabi=n32" + LDFLAGS="$LDFLAGS -mabi=n32" + +else + + case $system in + IRIX-6.3) + # Use to build 6.2 compatible binaries on 6.3. + CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" + ;; + *) + CFLAGS="$CFLAGS -n32" + ;; + esac + LDFLAGS="$LDFLAGS -n32" + +fi + + ;; + IRIX64-6.*) + SHLIB_CFLAGS="" + SHLIB_LD="ld -n32 -shared -rdata_shared" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' +fi + + + # Check to enable 64-bit flags for compiler/linker + + if test "$do64bit" = yes; then + + if test "$GCC" = yes; then + + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5 +echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} + +else + + do64bit_ok=yes + SHLIB_LD="ld -64 -shared -rdata_shared" + CFLAGS="$CFLAGS -64" + LDFLAGS_ARCH="-64" + +fi + + +fi + + ;; + Linux*) + SHLIB_CFLAGS="-fPIC" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + + # TEA specific: + CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" + # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings + # when you inline the string and math operations. Turn this off to + # get rid of the warnings. + #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" + + # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS + SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}' + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + LDFLAGS="$LDFLAGS -Wl,--export-dynamic" + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' +fi + + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + if test "`uname -m`" = "alpha"; then + CFLAGS="$CFLAGS -mieee" +fi + + if test $do64bit = yes; then + + echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5 +echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6 +if test "${tcl_cv_cc_m64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + hold_cflags=$CFLAGS + CFLAGS="$CFLAGS -m64" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_cc_m64=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_m64=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS=$hold_cflags +fi +echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5 +echo "${ECHO_T}$tcl_cv_cc_m64" >&6 + if test $tcl_cv_cc_m64 = yes; then + + CFLAGS="$CFLAGS -m64" + do64bit_ok=yes + +fi + + +fi + + + # The combo of gcc + glibc has a bug related to inlining of + # functions like strtod(). The -fno-builtin flag should address + # this problem but it does not work. The -fno-inline flag is kind + # of overkill but it works. Disable inlining only when one of the + # files in compat/*.c is being linked in. + + if test x"${USE_COMPAT}" != x; then + CFLAGS="$CFLAGS -fno-inline" +fi + + + ;; + GNU*) + SHLIB_CFLAGS="-fPIC" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + + SHLIB_LD='${CC} -shared' + DL_OBJS="" + DL_LIBS="-ldl" + LDFLAGS="$LDFLAGS -Wl,--export-dynamic" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + if test "`uname -m`" = "alpha"; then + CFLAGS="$CFLAGS -mieee" +fi + + ;; + Lynx*) + SHLIB_CFLAGS="-fPIC" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + CFLAGS_OPTIMIZE=-02 + SHLIB_LD='${CC} -shared' + DL_OBJS="tclLoadDl.o" + DL_LIBS="-mshared -ldl" + LD_FLAGS="-Wl,--export-dynamic" + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' +fi + + ;; + MP-RAS-02*) + SHLIB_CFLAGS="-K PIC" + SHLIB_LD='${CC} -G' + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + MP-RAS-*) + SHLIB_CFLAGS="-K PIC" + SHLIB_LD='${CC} -G' + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + LDFLAGS="$LDFLAGS -Wl,-Bexport" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + NetBSD-1.*|FreeBSD-[1-2].*) + SHLIB_CFLAGS="-fPIC" + SHLIB_LD="ld -Bshareable -x" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' +fi + + echo "$as_me:$LINENO: checking for ELF" >&5 +echo $ECHO_N "checking for ELF... $ECHO_C" >&6 +if test "${tcl_cv_ld_elf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#ifdef __ELF__ + yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "yes" >/dev/null 2>&1; then + tcl_cv_ld_elf=yes +else + tcl_cv_ld_elf=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5 +echo "${ECHO_T}$tcl_cv_ld_elf" >&6 + if test $tcl_cv_ld_elf = yes; then + + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' + +else + + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' + +fi + + + # Ancient FreeBSD doesn't handle version numbers with dots. + + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' + TCL_LIB_VERSIONS_OK=nodots + ;; + OpenBSD-*) + SHLIB_CFLAGS="-fPIC" + SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' +fi + + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' + echo "$as_me:$LINENO: checking for ELF" >&5 +echo $ECHO_N "checking for ELF... $ECHO_C" >&6 +if test "${tcl_cv_ld_elf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#ifdef __ELF__ + yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "yes" >/dev/null 2>&1; then + tcl_cv_ld_elf=yes +else + tcl_cv_ld_elf=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5 +echo "${ECHO_T}$tcl_cv_ld_elf" >&6 + if test $tcl_cv_ld_elf = yes; then + + LDFLAGS=-Wl,-export-dynamic + +else + LDFLAGS="" +fi + + + # OpenBSD doesn't do version numbers with dots. + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' + TCL_LIB_VERSIONS_OK=nodots + ;; + NetBSD-*|FreeBSD-*) + # FreeBSD 3.* and greater have ELF. + # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs + SHLIB_CFLAGS="-fPIC" + SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + LDFLAGS="$LDFLAGS -export-dynamic" + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' +fi + + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + if test "${TCL_THREADS}" = "1"; then + + # The -pthread needs to go in the CFLAGS, not LIBS + LIBS=`echo $LIBS | sed s/-pthread//` + CFLAGS="$CFLAGS -pthread" + LDFLAGS="$LDFLAGS -pthread" + +fi + + case $system in + FreeBSD-3.*) + # FreeBSD-3 doesn't handle version numbers with dots. + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' + TCL_LIB_VERSIONS_OK=nodots + ;; + esac + ;; + Darwin-*) + CFLAGS_OPTIMIZE="-Os" + SHLIB_CFLAGS="-fno-common" + # To avoid discrepancies between what headers configure sees during + # preprocessing tests and compiling tests, move any -isysroot and + # -mmacosx-version-min flags from CFLAGS to CPPFLAGS: + CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \ + awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ + if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`" + CFLAGS="`echo " ${CFLAGS}" | \ + awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ + if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`" + if test $do64bit = yes; then + + case `arch` in + ppc) + echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5 +echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6 +if test "${tcl_cv_cc_arch_ppc64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + hold_cflags=$CFLAGS + CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_cc_arch_ppc64=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_arch_ppc64=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS=$hold_cflags +fi +echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5 +echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6 + if test $tcl_cv_cc_arch_ppc64 = yes; then + + CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" + do64bit_ok=yes + +fi +;; + i386) + echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5 +echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6 +if test "${tcl_cv_cc_arch_x86_64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + hold_cflags=$CFLAGS + CFLAGS="$CFLAGS -arch x86_64" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_cc_arch_x86_64=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_arch_x86_64=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS=$hold_cflags +fi +echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5 +echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6 + if test $tcl_cv_cc_arch_x86_64 = yes; then + + CFLAGS="$CFLAGS -arch x86_64" + do64bit_ok=yes + +fi +;; + *) + { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5 +echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};; + esac + +else + + # Check for combined 32-bit and 64-bit fat build + if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \ + && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then + + fat_32_64=yes +fi + + +fi + + # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS + SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}' + echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5 +echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6 +if test "${tcl_cv_ld_single_module+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + hold_ldflags=$LDFLAGS + LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_ld_single_module=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_ld_single_module=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$hold_ldflags +fi +echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5 +echo "${ECHO_T}$tcl_cv_ld_single_module" >&6 + if test $tcl_cv_ld_single_module = yes; then + + SHLIB_LD="${SHLIB_LD} -Wl,-single_module" + +fi + + # TEA specific: link shlib with current and compatiblity version flags + vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([0-9]\{1,5\}\)\(\(\.[0-9]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d` + SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}" + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".dylib" + DL_OBJS="tclLoadDyld.o" + DL_LIBS="" + # Don't use -prebind when building for Mac OS X 10.4 or later only: + if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \ + "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then + + LDFLAGS="$LDFLAGS -prebind" +fi + + LDFLAGS="$LDFLAGS -headerpad_max_install_names" + echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5 +echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6 +if test "${tcl_cv_ld_search_paths_first+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + hold_ldflags=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-search_paths_first" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_ld_search_paths_first=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_ld_search_paths_first=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$hold_ldflags +fi +echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5 +echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6 + if test $tcl_cv_ld_search_paths_first = yes; then + + LDFLAGS="$LDFLAGS -Wl,-search_paths_first" + +fi + + if test "$tcl_cv_cc_visibility_hidden" != yes; then + + +cat >>confdefs.h <<\_ACEOF +#define MODULE_SCOPE __private_extern__ +_ACEOF + + +fi + + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" + # TEA specific: for combined 32 & 64 bit fat builds of Tk + # extensions, verify that 64-bit build is possible. + if test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"; then + + if test "${TEA_WINDOWINGSYSTEM}" = x11; then + + echo "$as_me:$LINENO: checking for 64-bit X11" >&5 +echo $ECHO_N "checking for 64-bit X11... $ECHO_C" >&6 +if test "${tcl_cv_lib_x11_64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + for v in CFLAGS CPPFLAGS LDFLAGS; do + eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' + done + CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include" + LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +XrmInitialize(); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_lib_x11_64=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_lib_x11_64=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + for v in CFLAGS CPPFLAGS LDFLAGS; do + eval $v'="$hold_'$v'"' + done +fi +echo "$as_me:$LINENO: result: $tcl_cv_lib_x11_64" >&5 +echo "${ECHO_T}$tcl_cv_lib_x11_64" >&6 + +fi + + # remove 64-bit arch flags from CFLAGS et al. if configuration + # does not support 64-bit. + if test "${TEA_WINDOWINGSYSTEM}" = aqua -o "$tcl_cv_lib_x11_64" = no; then + + { echo "$as_me:$LINENO: Removing 64-bit architectures from compiler & linker flags" >&5 +echo "$as_me: Removing 64-bit architectures from compiler & linker flags" >&6;} + for v in CFLAGS CPPFLAGS LDFLAGS; do + eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' + done +fi + + +fi + + ;; + NEXTSTEP-*) + SHLIB_CFLAGS="" + SHLIB_LD='${CC} -nostdlib -r' + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadNext.o" + DL_LIBS="" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + OS/390-*) + CFLAGS_OPTIMIZE="" # Optimizer is buggy + +cat >>confdefs.h <<\_ACEOF +#define _OE_SOCKETS 1 +_ACEOF + + ;; + OSF1-1.0|OSF1-1.1|OSF1-1.2) + # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 + SHLIB_CFLAGS="" + # Hack: make package name same as library name + SHLIB_LD='ld -R -export :' + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadOSF.o" + DL_LIBS="" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + OSF1-1.*) + # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 + SHLIB_CFLAGS="-fPIC" + if test "$SHARED_BUILD" = 1; then + SHLIB_LD="ld -shared" +else + + SHLIB_LD="ld -non_shared" + +fi + + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + OSF1-V*) + # Digital OSF/1 + SHLIB_CFLAGS="" + if test "$SHARED_BUILD" = 1; then + + SHLIB_LD='ld -shared -expect_unresolved "*"' + +else + + SHLIB_LD='ld -non_shared -expect_unresolved "*"' + +fi + + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + if test $doRpath = yes; then + + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' +fi + + if test "$GCC" = yes; then + CFLAGS="$CFLAGS -mieee" +else + + CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" +fi + + # see pthread_intro(3) for pthread support on osf1, k.furukawa + if test "${TCL_THREADS}" = 1; then + + CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" + CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" + LIBS=`echo $LIBS | sed s/-lpthreads//` + if test "$GCC" = yes; then + + LIBS="$LIBS -lpthread -lmach -lexc" + +else + + CFLAGS="$CFLAGS -pthread" + LDFLAGS="$LDFLAGS -pthread" + +fi + + +fi + + ;; + QNX-6*) + # QNX RTP + # This may work for all QNX, but it was only reported for v6. + SHLIB_CFLAGS="-fPIC" + SHLIB_LD="ld -Bshareable -x" + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + # dlopen is in -lc on QNX + DL_LIBS="" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + SCO_SV-3.2*) + # Note, dlopen is available only on SCO 3.2.5 and greater. However, + # this test works, since "uname -s" was non-standard in 3.2.4 and + # below. + if test "$GCC" = yes; then + + SHLIB_CFLAGS="-fPIC -melf" + LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" + +else + + SHLIB_CFLAGS="-Kpic -belf" + LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" + +fi + + SHLIB_LD="ld -G" + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + SINIX*5.4*) + SHLIB_CFLAGS="-K PIC" + SHLIB_LD='${CC} -G' + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + SunOS-4*) + SHLIB_CFLAGS="-PIC" + SHLIB_LD="ld" + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + + # SunOS can't handle version numbers with dots in them in library + # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it + # requires an extra version number at the end of .so file names. + # So, the library has to have a name like libtcl75.so.1.0 + + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' + TCL_LIB_VERSIONS_OK=nodots + ;; + SunOS-5.[0-6]) + # Careful to not let 5.10+ fall into this case + + # Note: If _REENTRANT isn't defined, then Solaris + # won't define thread-safe library routines. + + +cat >>confdefs.h <<\_ACEOF +#define _REENTRANT 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_PTHREAD_SEMANTICS 1 +_ACEOF + + + SHLIB_CFLAGS="-KPIC" + + # Note: need the LIBS below, otherwise Tk won't find Tcl's + # symbols when dynamically loaded into tclsh. + + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + if test "$GCC" = yes; then + + SHLIB_LD='${CC} -shared' + CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + +else + + SHLIB_LD="/usr/ccs/bin/ld -G -z text" + CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + +fi + + ;; + SunOS-5*) + # Note: If _REENTRANT isn't defined, then Solaris + # won't define thread-safe library routines. + + +cat >>confdefs.h <<\_ACEOF +#define _REENTRANT 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_PTHREAD_SEMANTICS 1 +_ACEOF + + + SHLIB_CFLAGS="-KPIC" + + # Check to enable 64-bit flags for compiler/linker + if test "$do64bit" = yes; then + + arch=`isainfo` + if test "$arch" = "sparcv9 sparc"; then + + if test "$GCC" = yes; then + + if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then + + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 +echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} + +else + + do64bit_ok=yes + CFLAGS="$CFLAGS -m64 -mcpu=v9" + LDFLAGS="$LDFLAGS -m64 -mcpu=v9" + SHLIB_CFLAGS="-fPIC" + +fi + + +else + + do64bit_ok=yes + if test "$do64bitVIS" = yes; then + + CFLAGS="$CFLAGS -xarch=v9a" + LDFLAGS_ARCH="-xarch=v9a" + +else + + CFLAGS="$CFLAGS -xarch=v9" + LDFLAGS_ARCH="-xarch=v9" + +fi + + # Solaris 64 uses this as well + #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" + +fi + + +else + if test "$arch" = "amd64 i386"; then + + if test "$GCC" = yes; then + + case $system in + SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*) + do64bit_ok=yes + CFLAGS="$CFLAGS -m64" + LDFLAGS="$LDFLAGS -m64";; + *) + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 +echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};; + esac + +else + + do64bit_ok=yes + case $system in + SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*) + CFLAGS="$CFLAGS -m64" + LDFLAGS="$LDFLAGS -m64";; + *) + CFLAGS="$CFLAGS -xarch=amd64" + LDFLAGS="$LDFLAGS -xarch=amd64";; + esac + +fi + + +else + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5 +echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} +fi + +fi + + +fi + + + # Note: need the LIBS below, otherwise Tk won't find Tcl's + # symbols when dynamically loaded into tclsh. + + SHLIB_LD_LIBS='${LIBS}' + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + if test "$GCC" = yes; then + + SHLIB_LD='${CC} -shared' + CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + if test "$do64bit_ok" = yes; then + + if test "$arch" = "sparcv9 sparc"; then + + # We need to specify -static-libgcc or we need to + # add the path to the sparv9 libgcc. + # JH: static-libgcc is necessary for core Tcl, but may + # not be necessary for extensions. + SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" + # for finding sparcv9 libgcc, get the regular libgcc + # path, remove so name and append 'sparcv9' + #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." + #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" + +else + if test "$arch" = "amd64 i386"; then + + # JH: static-libgcc is necessary for core Tcl, but may + # not be necessary for extensions. + SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" + +fi + +fi + + +fi + + +else + + case $system in + SunOS-5.[1-9][0-9]*) + SHLIB_LD='${CC} -G -z text ${LDFLAGS}';; + *) + SHLIB_LD='/usr/ccs/bin/ld -G -z text';; + esac + CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' + +fi + + ;; + UNIX_SV* | UnixWare-5*) + SHLIB_CFLAGS="-KPIC" + SHLIB_LD='${CC} -G' + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="-ldl" + # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers + # that don't grok the -Bexport option. Test that it does. + echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5 +echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6 +if test "${tcl_cv_ld_Bexport+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + hold_ldflags=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-Bexport" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_ld_Bexport=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_ld_Bexport=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$hold_ldflags +fi +echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5 +echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6 + if test $tcl_cv_ld_Bexport = yes; then + + LDFLAGS="$LDFLAGS -Wl,-Bexport" + +fi + + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + esac + + if test "$do64bit" = yes -a "$do64bit_ok" = no; then + + { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 +echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} + +fi + + + + + # Step 4: disable dynamic loading if requested via a command-line switch. + + # Check whether --enable-load or --disable-load was given. +if test "${enable_load+set}" = set; then + enableval="$enable_load" + tcl_ok=$enableval +else + tcl_ok=yes +fi; + if test "$tcl_ok" = no; then + DL_OBJS="" +fi + + + if test "x$DL_OBJS" != x; then + BUILD_DLTEST="\$(DLTEST_TARGETS)" +else + + { echo "$as_me:$LINENO: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5 +echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;} + SHLIB_CFLAGS="" + SHLIB_LD="" + SHLIB_SUFFIX="" + DL_OBJS="tclLoadNone.o" + DL_LIBS="" + LDFLAGS="$LDFLAGS_ORIG" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + BUILD_DLTEST="" + +fi + + LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" + + # If we're running gcc, then change the C flags for compiling shared + # libraries to the right flags for gcc, instead of those for the + # standard manufacturer compiler. + + if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then + + case $system in + AIX-*) ;; + BSD/OS*) ;; + IRIX*) ;; + NetBSD-*|FreeBSD-*) ;; + Darwin-*) ;; + SCO_SV-3.2*) ;; + *) SHLIB_CFLAGS="-fPIC" ;; + esac +fi + + + if test "$SHARED_LIB_SUFFIX" = ""; then + + # TEA specific: use PACKAGE_VERSION instead of VERSION + SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}' +fi + + if test "$UNSHARED_LIB_SUFFIX" = ""; then + + # TEA specific: use PACKAGE_VERSION instead of VERSION + UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' +fi + + + + + + + + + + + + + + + + + # These must be called after we do the basic CFLAGS checks and + # verify any possible 64-bit or similar switches are necessary + + echo "$as_me:$LINENO: checking for required early compiler flags" >&5 +echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6 + tcl_flags="" + + if test "${tcl_cv_flag__isoc99_source+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *)strtoll; char *q = (char *)strtoull; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_flag__isoc99_source=no +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _ISOC99_SOURCE 1 +#include +int +main () +{ +char *p = (char *)strtoll; char *q = (char *)strtoull; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_flag__isoc99_source=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_flag__isoc99_source=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then + +cat >>confdefs.h <<\_ACEOF +#define _ISOC99_SOURCE 1 +_ACEOF + + tcl_flags="$tcl_flags _ISOC99_SOURCE" + fi + + + if test "${tcl_cv_flag__largefile64_source+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +struct stat64 buf; int i = stat64("/", &buf); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_flag__largefile64_source=no +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _LARGEFILE64_SOURCE 1 +#include +int +main () +{ +struct stat64 buf; int i = stat64("/", &buf); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_flag__largefile64_source=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_flag__largefile64_source=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then + +cat >>confdefs.h <<\_ACEOF +#define _LARGEFILE64_SOURCE 1 +_ACEOF + + tcl_flags="$tcl_flags _LARGEFILE64_SOURCE" + fi + + + if test "${tcl_cv_flag__largefile_source64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *)open64; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_flag__largefile_source64=no +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _LARGEFILE_SOURCE64 1 +#include +int +main () +{ +char *p = (char *)open64; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_flag__largefile_source64=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_flag__largefile_source64=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then + +cat >>confdefs.h <<\_ACEOF +#define _LARGEFILE_SOURCE64 1 +_ACEOF + + tcl_flags="$tcl_flags _LARGEFILE_SOURCE64" + fi + + if test "x${tcl_flags}" = "x" ; then + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 + else + echo "$as_me:$LINENO: result: ${tcl_flags}" >&5 +echo "${ECHO_T}${tcl_flags}" >&6 + fi + + + echo "$as_me:$LINENO: checking for 64-bit integer type" >&5 +echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6 + if test "${tcl_cv_type_64bit+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + tcl_cv_type_64bit=none + # See if the compiler knows natively about __int64 + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +__int64 value = (__int64) 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_type_64bit=__int64 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_type_64bit="long long" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + # See if we should use long anyway Note that we substitute in the + # type that is our current guess for a 64-bit type inside this check + # program, so it should be modified only carefully... + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +switch (0) { + case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ; + } + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_type_64bit=${tcl_type_64bit} +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + if test "${tcl_cv_type_64bit}" = none ; then + +cat >>confdefs.h <<\_ACEOF +#define TCL_WIDE_INT_IS_LONG 1 +_ACEOF + + echo "$as_me:$LINENO: result: using long" >&5 +echo "${ECHO_T}using long" >&6 + elif test "${tcl_cv_type_64bit}" = "__int64" \ + -a "${TEA_PLATFORM}" = "windows" ; then + # TEA specific: We actually want to use the default tcl.h checks in + # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* + echo "$as_me:$LINENO: result: using Tcl header defaults" >&5 +echo "${ECHO_T}using Tcl header defaults" >&6 + else + +cat >>confdefs.h <<_ACEOF +#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit} +_ACEOF + + echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5 +echo "${ECHO_T}${tcl_cv_type_64bit}" >&6 + + # Now check for auxiliary declarations + echo "$as_me:$LINENO: checking for struct dirent64" >&5 +echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6 +if test "${tcl_cv_struct_dirent64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +int +main () +{ +struct dirent64 p; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_struct_dirent64=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_struct_dirent64=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5 +echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6 + if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STRUCT_DIRENT64 1 +_ACEOF + + fi + + echo "$as_me:$LINENO: checking for struct stat64" >&5 +echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6 +if test "${tcl_cv_struct_stat64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +struct stat64 p; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_struct_stat64=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_struct_stat64=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5 +echo "${ECHO_T}$tcl_cv_struct_stat64" >&6 + if test "x${tcl_cv_struct_stat64}" = "xyes" ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STRUCT_STAT64 1 +_ACEOF + + fi + + + +for ac_func in open64 lseek64 +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + echo "$as_me:$LINENO: checking for off64_t" >&5 +echo $ECHO_N "checking for off64_t... $ECHO_C" >&6 + if test "${tcl_cv_type_off64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +off64_t offset; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_type_off64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_type_off64_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + if test "x${tcl_cv_type_off64_t}" = "xyes" && \ + test "x${ac_cv_func_lseek64}" = "xyes" && \ + test "x${ac_cv_func_open64}" = "xyes" ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TYPE_OFF64_T 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + fi + + + +#-------------------------------------------------------------------- +# Set the default compiler switches based on the --enable-symbols +# option. +#-------------------------------------------------------------------- + + + + echo "$as_me:$LINENO: checking for build with symbols" >&5 +echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6 + # Check whether --enable-symbols or --disable-symbols was given. +if test "${enable_symbols+set}" = set; then + enableval="$enable_symbols" + tcl_ok=$enableval +else + tcl_ok=no +fi; + DBGX="" + if test "$tcl_ok" = "no"; then + CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" + LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + else + CFLAGS_DEFAULT="${CFLAGS_DEBUG}" + LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" + if test "$tcl_ok" = "yes"; then + echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 +echo "${ECHO_T}yes (standard debugging)" >&6 + fi + fi + # TEA specific: + if test "${TEA_PLATFORM}" != "windows" ; then + LDFLAGS_DEFAULT="${LDFLAGS}" + fi + + + + + if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then + +cat >>confdefs.h <<\_ACEOF +#define TCL_MEM_DEBUG 1 +_ACEOF + + fi + + if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then + if test "$tcl_ok" = "all"; then + echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5 +echo "${ECHO_T}enabled symbols mem debugging" >&6 + else + echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 +echo "${ECHO_T}enabled $tcl_ok debugging" >&6 + fi + fi + + +#-------------------------------------------------------------------- +# Everyone should be linking against the Tcl stub library. If you +# can't for some reason, remove this definition. If you aren't using +# stubs, you also need to modify the SHLIB_LD_LIBS setting below to +# link against the non-stubbed Tcl library. +#-------------------------------------------------------------------- + +cat >>confdefs.h <<\_ACEOF +#define USE_TCL_STUBS 1 +_ACEOF + +cat >>confdefs.h <<\_ACEOF +#define USE_TK_STUBS 1 +_ACEOF + + +#-------------------------------------------------------------------- +# This macro generates a line to use when building a library. It +# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, +# and TEA_LOAD_TCLCONFIG macros above. +#-------------------------------------------------------------------- + + + if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then + MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)" + MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)" + MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)" + else + MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)" + MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" + MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)" + fi + + if test "${SHARED_BUILD}" = "1" ; then + MAKE_LIB="${MAKE_SHARED_LIB} " + else + MAKE_LIB="${MAKE_STATIC_LIB} " + fi + + #-------------------------------------------------------------------- + # Shared libraries and static libraries have different names. + # Use the double eval to make sure any variables in the suffix is + # substituted. (@@@ Might not be necessary anymore) + #-------------------------------------------------------------------- + + if test "${TEA_PLATFORM}" = "windows" ; then + if test "${SHARED_BUILD}" = "1" ; then + # We force the unresolved linking of symbols that are really in + # the private libraries of Tcl and Tk. + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" + if test x"${TK_BIN_DIR}" != x ; then + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\"" + fi + eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" + else + eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" + fi + # Some packages build their own stubs libraries + eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" + if test "$GCC" = "yes"; then + PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE} + fi + # These aren't needed on Windows (either MSVC or gcc) + RANLIB=: + RANLIB_STUB=: + else + RANLIB_STUB="${RANLIB}" + if test "${SHARED_BUILD}" = "1" ; then + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}" + if test x"${TK_BIN_DIR}" != x ; then + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}" + fi + eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" + RANLIB=: + else + eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" + fi + # Some packages build their own stubs libraries + eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" + fi + + # These are escaped so that only CFLAGS is picked up at configure time. + # The other values will be substituted at make time. + CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" + if test "${SHARED_BUILD}" = "1" ; then + CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" + fi + + + + + + + + +#-------------------------------------------------------------------- +# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl +# file during the install process. Don't run the TCLSH_PROG through +# ${CYGPATH} because it's being used directly by make. +# Require that we use a tclsh shell version 8.2 or later since earlier +# versions have bugs in the pkg_mkIndex routine. +#-------------------------------------------------------------------- + + + echo "$as_me:$LINENO: checking for tclsh" >&5 +echo $ECHO_N "checking for tclsh... $ECHO_C" >&6 + if test -f "${TCL_BIN_DIR}/Makefile" ; then + # tclConfig.sh is in Tcl build directory + if test "${TEA_PLATFORM}" = "windows"; then + TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" + else + TCLSH_PROG="${TCL_BIN_DIR}/tclsh" + fi + else + # tclConfig.sh is in install location + if test "${TEA_PLATFORM}" = "windows"; then + TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" + else + TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" + fi + list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \ + `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \ + `ls -d ${TCL_PREFIX}/bin 2>/dev/null`" + for i in $list ; do + if test -f "$i/${TCLSH_PROG}" ; then + REAL_TCL_BIN_DIR="`cd "$i"; pwd`/" + break + fi + done + TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}" + fi + echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5 +echo "${ECHO_T}${TCLSH_PROG}" >&6 + + + + echo "$as_me:$LINENO: checking for wish" >&5 +echo $ECHO_N "checking for wish... $ECHO_C" >&6 + if test -f "${TK_BIN_DIR}/Makefile" ; then + # tkConfig.sh is in Tk build directory + if test "${TEA_PLATFORM}" = "windows"; then + WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" + else + WISH_PROG="${TK_BIN_DIR}/wish" + fi + else + # tkConfig.sh is in install location + if test "${TEA_PLATFORM}" = "windows"; then + WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" + else + WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}" + fi + list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \ + `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \ + `ls -d ${TK_PREFIX}/bin 2>/dev/null`" + for i in $list ; do + if test -f "$i/${WISH_PROG}" ; then + REAL_TK_BIN_DIR="`cd "$i"; pwd`/" + break + fi + done + WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}" + fi + echo "$as_me:$LINENO: result: ${WISH_PROG}" >&5 +echo "${ECHO_T}${WISH_PROG}" >&6 + + + +#-------------------------------------------------------------------- +# Finally, substitute all of the various values into the Makefile. +#-------------------------------------------------------------------- + + ac_config_files="$ac_config_files Makefile" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\_ACEOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS="" + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by Tktable $as_me 2.10, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +Tktable config.status 2.10 +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@CYGPATH@,$CYGPATH,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@PKG_LIB_FILE@,$PKG_LIB_FILE,;t t +s,@PKG_STUB_LIB_FILE@,$PKG_STUB_LIB_FILE,;t t +s,@PKG_STUB_SOURCES@,$PKG_STUB_SOURCES,;t t +s,@PKG_STUB_OBJECTS@,$PKG_STUB_OBJECTS,;t t +s,@PKG_TCL_SOURCES@,$PKG_TCL_SOURCES,;t t +s,@PKG_HEADERS@,$PKG_HEADERS,;t t +s,@PKG_INCLUDES@,$PKG_INCLUDES,;t t +s,@PKG_LIBS@,$PKG_LIBS,;t t +s,@PKG_CFLAGS@,$PKG_CFLAGS,;t t +s,@TCL_VERSION@,$TCL_VERSION,;t t +s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t +s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t +s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t +s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t +s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t +s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t +s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t +s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t +s,@TCL_LIBS@,$TCL_LIBS,;t t +s,@TCL_DEFS@,$TCL_DEFS,;t t +s,@TCL_EXTRA_CFLAGS@,$TCL_EXTRA_CFLAGS,;t t +s,@TCL_LD_FLAGS@,$TCL_LD_FLAGS,;t t +s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t +s,@TK_VERSION@,$TK_VERSION,;t t +s,@TK_BIN_DIR@,$TK_BIN_DIR,;t t +s,@TK_SRC_DIR@,$TK_SRC_DIR,;t t +s,@TK_LIB_FILE@,$TK_LIB_FILE,;t t +s,@TK_LIB_FLAG@,$TK_LIB_FLAG,;t t +s,@TK_LIB_SPEC@,$TK_LIB_SPEC,;t t +s,@TK_STUB_LIB_FILE@,$TK_STUB_LIB_FILE,;t t +s,@TK_STUB_LIB_FLAG@,$TK_STUB_LIB_FLAG,;t t +s,@TK_STUB_LIB_SPEC@,$TK_STUB_LIB_SPEC,;t t +s,@TK_LIBS@,$TK_LIBS,;t t +s,@TK_XINCLUDES@,$TK_XINCLUDES,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CPP@,$CPP,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@EGREP@,$EGREP,;t t +s,@MATH_LIBS@,$MATH_LIBS,;t t +s,@PKG_SOURCES@,$PKG_SOURCES,;t t +s,@PKG_OBJECTS@,$PKG_OBJECTS,;t t +s,@TCL_INCLUDES@,$TCL_INCLUDES,;t t +s,@TK_INCLUDES@,$TK_INCLUDES,;t t +s,@CLEANFILES@,$CLEANFILES,;t t +s,@TCL_THREADS@,$TCL_THREADS,;t t +s,@SHARED_BUILD@,$SHARED_BUILD,;t t +s,@AR@,$AR,;t t +s,@CELIB_DIR@,$CELIB_DIR,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@DL_LIBS@,$DL_LIBS,;t t +s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t +s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t +s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t +s,@STLIB_LD@,$STLIB_LD,;t t +s,@SHLIB_LD@,$SHLIB_LD,;t t +s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t +s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t +s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t +s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t +s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t +s,@TCL_DBGX@,$TCL_DBGX,;t t +s,@MAKE_LIB@,$MAKE_LIB,;t t +s,@MAKE_SHARED_LIB@,$MAKE_SHARED_LIB,;t t +s,@MAKE_STATIC_LIB@,$MAKE_STATIC_LIB,;t t +s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t +s,@RANLIB_STUB@,$RANLIB_STUB,;t t +s,@TCLSH_PROG@,$TCLSH_PROG,;t t +s,@WISH_PROG@,$WISH_PROG,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/tktable/configure.in b/tktable/configure.in new file mode 100644 index 0000000..6a51f66 --- /dev/null +++ b/tktable/configure.in @@ -0,0 +1,187 @@ +#! /bin/bash -norc +# +# RCS: @(#) $Id: configure.in,v 1.16 2008/11/14 23:16:52 hobbs Exp $ +# +#-------------------------------------------------------------------- +# Sample configure.in for Tcl Extensions. The only places you should +# need to modify this file are marked by the string __CHANGE__ +#-------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# __CHANGE__ +# Set your package name and version numbers here. +# +# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION +# set as provided. These will also be added as -D defs in your Makefile +# so you can encode the package version directly into the source files. +#----------------------------------------------------------------------- + +AC_INIT([Tktable], [2.10]) + +#-------------------------------------------------------------------- +# Call TEA_INIT as the first TEA_ macro to set up initial vars. +# This will define a ${TEA_PLATFORM} variable == "unix" or "windows" +# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. +#-------------------------------------------------------------------- + +TEA_INIT([3.7]) + +AC_CONFIG_AUX_DIR(tclconfig) + +#-------------------------------------------------------------------- +# Load the tclConfig.sh file +#-------------------------------------------------------------------- + +TEA_PATH_TCLCONFIG +TEA_LOAD_TCLCONFIG + +#-------------------------------------------------------------------- +# Load the tkConfig.sh file if necessary (Tk extension) +#-------------------------------------------------------------------- + +TEA_PATH_TKCONFIG +TEA_LOAD_TKCONFIG + +#----------------------------------------------------------------------- +# Handle the --prefix=... option by defaulting to what Tcl gave. +# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. +#----------------------------------------------------------------------- + +TEA_PREFIX + +#----------------------------------------------------------------------- +# Standard compiler checks. +# This sets up CC by using the CC env var, or looks for gcc otherwise. +# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create +# the basic setup necessary to compile executables. +#----------------------------------------------------------------------- + +TEA_SETUP_COMPILER + +#----------------------------------------------------------------------- +# __CHANGE__ +# Specify the C source files to compile in TEA_ADD_SOURCES, +# public headers that need to be installed in TEA_ADD_HEADERS, +# stub library C source files to compile in TEA_ADD_STUB_SOURCES, +# and runtime Tcl library files in TEA_ADD_TCL_SOURCES. +# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS +# and PKG_TCL_SOURCES. +#----------------------------------------------------------------------- + +TEA_ADD_SOURCES([tkTable.c tkTableWin.c tkTableTag.c tkTableEdit.c + tkTableCell.c tkTableCellSort.c tkTableCmds.c tkTableUtil.c]) +# PostScript is on the drawing board +#TEA_ADD_SOURCES([tkTablePs.c]) +# This header isn't really meant for distribution +#TEA_ADD_HEADERS([generic/tkTable.h]) +TEA_ADD_INCLUDES([-I. -I\"`${CYGPATH} ${srcdir}/generic`\"]) +TEA_ADD_CFLAGS([]) +TEA_ADD_STUB_SOURCES([]) +TEA_ADD_TCL_SOURCES([library/tkTable.tcl library/tktable.py]) + +#-------------------------------------------------------------------- +# __CHANGE__ +# Choose which headers you need. Extension authors should try very +# hard to only rely on the Tcl public header files. Internal headers +# contain private data structures and are subject to change without +# notice. +# This MUST be called after TEA_PATH_TCLCONFIG/TEA_LOAD_TCLCONFIG +#-------------------------------------------------------------------- + +TEA_PUBLIC_TCL_HEADERS +TEA_PUBLIC_TK_HEADERS +#TEA_PRIVATE_TCL_HEADERS +#TEA_PRIVATE_TK_HEADERS + +#-------------------------------------------------------------------- +# For Unix/Tk builds, make sure that the X libraries/headers are found. +#-------------------------------------------------------------------- + +TEA_PATH_X + +#-------------------------------------------------------------------- +# __CHANGE__ +# A few miscellaneous platform-specific items: +# +# Define a special symbol for Windows (BUILD_Tktable in this case) so +# that we create the export library with the dll. +# +# Windows creates a few extra files that need to be cleaned up. +# You can add more files to clean if your extension creates any extra +# files. +# +# TEA_ADD any extra compiler/build info here. +#-------------------------------------------------------------------- + +if test "${TEA_PLATFORM}" = "windows" ; then + AC_DEFINE_UNQUOTED(BUILD_Tktable) + CLEANFILES="pkgIndex.tcl tkTable.tcl.h *.lib *.dll *.exp *.ilk *.pdb *.pch" + TEA_ADD_LIBS([gdi32.lib user32.lib]) +else + CLEANFILES="pkgIndex.tcl tkTable.tcl.h" +fi +AC_SUBST(CLEANFILES) + +#-------------------------------------------------------------------- +# Check whether --enable-threads or --disable-threads was given. +# So far only Tcl responds to this one. +#-------------------------------------------------------------------- + +TEA_ENABLE_THREADS + +#-------------------------------------------------------------------- +# The statement below defines a collection of symbols related to +# building as a shared library instead of a static library. +#-------------------------------------------------------------------- + +TEA_ENABLE_SHARED + +#-------------------------------------------------------------------- +# This macro figures out what flags to use with the compiler/linker +# when building shared/static debug/optimized objects. This information +# can be taken from the tclConfig.sh file, but this figures it all out. +#-------------------------------------------------------------------- + +TEA_CONFIG_CFLAGS + +#-------------------------------------------------------------------- +# Set the default compiler switches based on the --enable-symbols +# option. +#-------------------------------------------------------------------- + +TEA_ENABLE_SYMBOLS + +#-------------------------------------------------------------------- +# Everyone should be linking against the Tcl stub library. If you +# can't for some reason, remove this definition. If you aren't using +# stubs, you also need to modify the SHLIB_LD_LIBS setting below to +# link against the non-stubbed Tcl library. +#-------------------------------------------------------------------- + +AC_DEFINE(USE_TCL_STUBS) +AC_DEFINE(USE_TK_STUBS) + +#-------------------------------------------------------------------- +# This macro generates a line to use when building a library. It +# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, +# and TEA_LOAD_TCLCONFIG macros above. +#-------------------------------------------------------------------- + +TEA_MAKE_LIB + +#-------------------------------------------------------------------- +# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl +# file during the install process. Don't run the TCLSH_PROG through +# ${CYGPATH} because it's being used directly by make. +# Require that we use a tclsh shell version 8.2 or later since earlier +# versions have bugs in the pkg_mkIndex routine. +#-------------------------------------------------------------------- + +TEA_PROG_TCLSH +TEA_PROG_WISH + +#-------------------------------------------------------------------- +# Finally, substitute all of the various values into the Makefile. +#-------------------------------------------------------------------- + +AC_OUTPUT([Makefile]) diff --git a/tktable/demos/basic.tcl b/tktable/demos/basic.tcl new file mode 100644 index 0000000..0d9a0ab --- /dev/null +++ b/tktable/demos/basic.tcl @@ -0,0 +1,61 @@ +#!/bin/sh +# the next line restarts using wish \ +exec wish "$0" ${1+"$@"} + +## basic.tcl +## +## This demo shows the basic use of the table widget +## +## jeff at hobbs org + +source [file join [file dirname [info script]] loadtable.tcl] + +array set table { + rows 8 + cols 8 + table .t + array t +} + +proc fill { array x y } { + upvar $array f + for {set i -$x} {$i<$x} {incr i} { + for {set j -$y} {$j<$y} {incr j} { set f($i,$j) "r$i,c$j" } + } +} + +## Test out the use of a procedure to define tags on rows and columns +proc rowProc row { if {$row>0 && $row%2} { return OddRow } } +proc colProc col { if {$col>0 && $col%2} { return OddCol } } + +label .label -text "TkTable v1 Example" + +fill $table(array) $table(rows) $table(cols) +table $table(table) -rows $table(rows) -cols $table(cols) \ + -variable $table(array) \ + -width 6 -height 6 \ + -titlerows 1 -titlecols 2 \ + -roworigin -1 -colorigin -2 \ + -yscrollcommand {.sy set} -xscrollcommand {.sx set} \ + -rowtagcommand rowProc -coltagcommand colProc \ + -colstretchmode last -rowstretchmode last \ + -selectmode extended -sparsearray 0 + +scrollbar .sy -command [list $table(table) yview] +scrollbar .sx -command [list $table(table) xview] -orient horizontal +button .exit -text "Exit" -command {exit} + +grid .label - -sticky ew +grid $table(table) .sy -sticky news +grid .sx -sticky ew +grid .exit -sticky ew -columnspan 2 +grid columnconfig . 0 -weight 1 +grid rowconfig . 1 -weight 1 + +$table(table) tag config OddRow -bg orange -fg purple +$table(table) tag config OddCol -bg brown -fg pink + +$table(table) width -2 7 -1 7 1 5 2 8 4 14 + +puts [list Table is $table(table) with array [$table(table) cget -var]] + diff --git a/tktable/demos/buttons.tcl b/tktable/demos/buttons.tcl new file mode 100644 index 0000000..29ffddf --- /dev/null +++ b/tktable/demos/buttons.tcl @@ -0,0 +1,82 @@ +#!/bin/sh +# next line is a comment in tcl \ +exec wish "$0" ${1+"$@"} + +## buttons.tcl +## +## demonstrates the simulation of a button array +## +## ellson@lucent.com +## modifications made by jeff at hobbs org + +source [file join [file dirname [info script]] loadtable.tcl] + +array set table { + rows 20 + cols 20 + table .table +} + +# create the table +set t $table(table) +table $t -rows [expr {$table(rows)+1}] -cols [expr {$table(cols)+1}] \ + -titlerows 1 -titlecols 1 \ + -roworigin -1 -colorigin -1 \ + -colwidth 4 \ + -width 8 -height 8 \ + -variable tab \ + -flashmode off \ + -cursor top_left_arrow \ + -borderwidth 2 \ + -state disabled \ + -xscrollcommand ".sx set" -yscrollcommand ".sy set" + +scrollbar .sx -orient h -command "$t xview" +scrollbar .sy -orient v -command "$t yview" + +grid $t .sy -sticky nsew +grid .sx -sticky ew +grid columnconfig . 0 -weight 1 +grid rowconfig . 0 -weight 1 + +# set up tags for the various states of the buttons +$t tag configure OFF -bg red -relief raised +$t tag configure ON -bg green -relief sunken +$t tag configure sel -bg gray75 -relief flat + +# clean up if mouse leaves the widget +bind $t { + %W selection clear all +} + +# highlight the cell under the mouse +bind $t { + if {[%W selection includes @%x,%y]} break + %W selection clear all + %W selection set @%x,%y + break + ## "break" prevents the call to tkTableCheckBorder +} + +# mousebutton 1 toggles the value of the cell +# use of "selection includes" would work here +bind $t <1> { + set rc [%W cursel] + if {[string match ON $tab($rc)]} { + set tab($rc) OFF + %W tag celltag OFF $rc + } { + set tab($rc) ON + %W tag celltag ON $rc + } +} + +# inititialize the array, titles, and celltags +for {set i 0} {$i < $table(rows)} {incr i} { + set tab($i,-1) $i + for {set j 0} {$j < $table(cols)} {incr j} { + if {! $i} {set tab(-1,$j) $j} + set tab($i,$j) "OFF" + $t tag celltag OFF $i,$j + } +} diff --git a/tktable/demos/command.tcl b/tktable/demos/command.tcl new file mode 100644 index 0000000..e0da582 --- /dev/null +++ b/tktable/demos/command.tcl @@ -0,0 +1,85 @@ +#!/bin/sh +# the next line restarts using wish \ + exec wish "$0" ${1+"$@"} + +## command.tcl +## +## This demo shows the use of the table widget's -command options +## +## jeff at hobbs org + +source [file join [file dirname [info script]] loadtable.tcl] + +array set table { + rows 10 + cols 10 + table .table + array DATA +} + +proc fill { array x y } { + upvar $array f + for {set i -$x} {$i<$x} {incr i} { + for {set j -$y} {$j<$y} {incr j} { set f($i,$j) "$i x $j" } + } +} + +## Test out the use of a procedure to define tags on rows and columns +proc rowProc row { if {$row>0 && $row%2} { return OddRow } } +proc colProc col { if {$col>0 && $col%2} { return OddCol } } + +proc tblCmd { arrayName set cell val } { + upvar \#0 $arrayName data + + if {$set} { + #echo set $cell $val + set data($cell) $val + } else { + #echo get $cell + if {[info exists data($cell)]} { + return $data($cell) + } else { + return + } + } +} + +label .label -text "TkTable -command Example" +label .current -textvar CURRENT -width 5 +entry .active -textvar ACTIVE + +bind .active "$table(table) curvalue \[%W get\]" + +fill $table(array) $table(rows) $table(cols) +set t $table(table) +table $table(table) -rows $table(rows) -cols $table(cols) \ + -command [list tblCmd $table(array) %i %C %s] -cache 1 \ + -width 6 -height 6 \ + -titlerows 1 -titlecols 1 \ + -yscrollcommand {.sy set} -xscrollcommand {.sx set} \ + -roworigin -1 -colorigin -1 \ + -rowtagcommand rowProc -coltagcommand colProc \ + -selectmode extended \ + -rowstretch unset -colstretch unset \ + -flashmode on -browsecommand { + set CURRENT %S + set ACTIVE [%W get %S] +} -validate 1 -validatecommand { + set ACTIVE %S + return 1 +} + +scrollbar .sy -command [list $table(table) yview] -orient v +scrollbar .sx -command [list $table(table) xview] -orient h +grid .label - - -sticky ew +grid .current .active - -sticky ew +grid $table(table) - .sy -sticky nsew +grid .sx - -sticky ew +grid columnconfig . 1 -weight 1 +grid rowconfig . 2 -weight 1 + +$table(table) tag config OddRow -bg orange -fg purple +$table(table) tag config OddCol -bg brown -fg pink + +puts [list Table is $table(table)] + diff --git a/tktable/demos/debug.tcl b/tktable/demos/debug.tcl new file mode 100644 index 0000000..c384920 --- /dev/null +++ b/tktable/demos/debug.tcl @@ -0,0 +1,112 @@ +#!/bin/sh +# the next line restarts using wish \ +exec wish "$0" ${1+"$@"} + +## version2.tcl +## +## This demo uses most features of the table widget +## +## jeff at hobbs org + +source [file join [file dirname [info script]] loadtable.tcl] + +array set table { + rows 25 + cols 20 + table .t + array t +} + +proc fill { array x y } { + upvar $array f + for {set i -$x} {$i<$x} {incr i} { + for {set j -$y} {$j<$y} {incr j} { set f($i,$j) "r$i,c$j" } + } +} + +## Test out the use of a procedure to define tags on rows and columns +proc colProc col { if {$col > 0 && $col % 2} { return OddCol } } + +label .label -text "TkTable v2 Example" + +fill $table(array) $table(rows) $table(cols) +table $table(table) \ + -rows $table(rows) -cols $table(cols) \ + -variable $table(array) \ + -width 6 -height 8 \ + -titlerows 1 -titlecols 2 \ + -roworigin -5 -colorigin -2 \ + -yscrollcommand {.sy set} \ + -xscrollcommand {.sx set} \ + -coltagcommand colProc \ + -selectmode extended \ + -rowstretch unset \ + -colstretch unset \ + -selecttitles 0 \ + -drawmode single + +scrollbar .sy -command [list $table(table) yview] +scrollbar .sx -command [list $table(table) xview] -orient horizontal +button .exit -text "Exit" -command {exit} +grid .label - -sticky ew +grid $table(table) .sy -sticky news +grid .sx -sticky ew +grid .exit -sticky ew -columnspan 2 +grid columnconfig . 0 -weight 1 +grid rowconfig . 1 -weight 1 + +$table(table) tag config OddCol -bg brown -fg pink +$table(table) tag config title -bg red -fg green -relief sunken +$table(table) tag config dis -state disabled + +set i -1 +set first [$table(table) cget -colorigin] +foreach anchor {n s e w nw ne sw se c} { + $table(table) tag config $anchor -anchor $anchor + $table(table) tag row $anchor [incr i] + $table(table) set $i,$first $anchor +} +font create courier -family Courier -size 10 +$table(table) tag config s -font courier -justify center + +image create photo logo \ + -file [file join [file dirname [info script]] tcllogo.gif] +$table(table) tag config logo -image logo -showtext 1 +$table(table) tag cell logo 1,2 2,3 4,1 +$table(table) tag cell dis 2,1 1,-1 3,0 +$table(table) width -2 8 -1 9 0 12 4 14 + +$table(table) set \ + 1,1 "multi-line\ntext\nmight be\ninteresting" \ + 3,2 "more\nmulti-line\nplaying\n" \ + 2,2 "null\0byte" + +set i -1 + +# This is in the row span +set l [label $table(table).s -text "Window s" -bg yellow] +$table(table) window config 6,0 -sticky s -window $l + +# This is in the row titles +set l [label $table(table).ne -text "Window ne" -bg yellow] +$table(table) window config 4,-1 -sticky ne -window $l + +# This will get swallowed by a span +set l [label $table(table).ew -text "Window ew" -bg yellow] +$table(table) window config 5,3 -sticky ew -window $l + +# This is in the col titles +set l [label $table(table).news -text "Window news" -bg yellow] +$table(table) window config -5,1 -sticky news -window $l + +set l [label [winfo parent $table(table)].l -text "Sibling l" -bg orange] +$table(table) window config 5,1 -sticky news -window $l + +if {![catch {$table(table) span}]} { + $table(table) span -1,-2 0,3 1,2 0,5 3,2 2,2 6,0 4,0 +} + +puts [list Table is $table(table) with array [$table(table) cget -var]] + +#$table(table) postscript -file out.ps -first origin -last 2,2 +#if {[string match {} [info commands tkcon]]} exit diff --git a/tktable/demos/dynarows.tcl b/tktable/demos/dynarows.tcl new file mode 100644 index 0000000..9006953 --- /dev/null +++ b/tktable/demos/dynarows.tcl @@ -0,0 +1,87 @@ +#!/bin/sh +# the next line restarts using wish \ +exec wish "$0" ${1+"$@"} + +## dynarows.tcl +## +## This demos shows the use of the validation mechanism of the table +## and uses the table's cache (no -command or -variable) with a cute +## dynamic row routine. +## +## jeff at hobbs org + +source [file join [file dirname [info script]] loadtable.tcl] + +proc table_validate {w idx} { + if {[scan $idx %d,%d row col] != 2} return + set val [$w get $idx] + + ## Entries in the last row are allowed to be empty + set nrows [$w cget -rows] + if {$row == ${nrows}-1 && [string match {} $val]} { return } + + if {[catch {clock scan $val} time]} { + bell + $w activate $idx + $w selection clear all + $w selection set active + $w see active + } else { + set date {} + foreach item [clock format $time -format "%m %d %Y"] { + lappend date [string trimleft $item "0"] + } + $w set $idx [join $date "/"] + if {$row == ${nrows}-1} { + ## if this is the last row and both cols 1 && 2 are not empty + ## then add a row and redo configs + if {[string comp [$w get $row,1] {}] && \ + [string comp [$w get $row,2] {}]} { + $w tag row {} $row + $w set $row,0 $row + $w configure -rows [incr nrows] + $w tag row unset [incr row] + $w set $row,0 "*" + $w see $row,1 + $w activate $row,1 + } + } + } +} + +label .example -text "Dynamic Date Validated Rows" + +set t .table +table $t -rows 2 -cols 3 -cache 1 -selecttype row \ + -titlerows 1 -titlecols 1 \ + -yscrollcommand { .sy set } \ + -xscrollcommand { .sx set } \ + -height 5 -colstretch unset -rowstretch unset \ + -autoclear 1 -browsecommand {table_validate %W %s} + +$t set 0,1 "Begin" 0,2 "End" 1,0 "*" +$t tag config unset -fg \#008811 +$t tag config title -fg red +$t tag row unset 1 +$t width 0 3 + +scrollbar .sy -command [list $t yview] +scrollbar .sx -command [list $t xview] -orient horizontal +grid .example - -sticky ew +grid $t .sy -sticky news +grid .sx -sticky ew +grid columnconfig . 0 -weight 1 +grid rowconfig . 1 -weight 1 + +bind $t { + set r [%W index active row] + set c [%W index active col] + if {$c == 2} { + %W activate [incr r],1 + } else { + %W activate $r,[incr c] + } + %W see active + break +} +bind $t [bind $t ] diff --git a/tktable/demos/loadtable.tcl b/tktable/demos/loadtable.tcl new file mode 100644 index 0000000..c691ac7 --- /dev/null +++ b/tktable/demos/loadtable.tcl @@ -0,0 +1,52 @@ +# loadtable.tcl +# +# Ensures that the table library extension is loaded + +if {[string equal "Windows CE" $::tcl_platform(os)]} { + if {[info proc puts] != "puts" || ![llength [info command ::tcl::puts]]} { + # Rename puts to something innocuous on Windows CE, + # but only if it wasn't already renamed (thus it's a proc) + rename puts ::tcl::puts + proc puts args { + set la [llength $args] + if {$la<1 || $la>3} { + error "usage: puts ?-nonewline? ?channel? string" + } + set nl \n + if {[lindex $args 0]=="-nonewline"} { + set nl "" + set args [lrange $args 1 end] + } + if {[llength $args]==1} { + set args [list stdout [join $args]] ;# (2) + } + foreach {channel s} $args break + if {$channel=="stdout" || $channel=="stderr"} { + #$::putsw insert end $s$nl + } else { + set cmd ::tcl::puts + if {$nl==""} {lappend cmd -nonewline} + lappend cmd $channel $s + uplevel 1 $cmd + } + } + } +} + +set ::VERSION 2.10 +if {[string compare unix $tcl_platform(platform)]} { + set table(library) Tktable$::VERSION[info sharedlibextension] +} else { + set table(library) libTktable$::VERSION[info sharedlibextension] +} +if { + [string match {} [info commands table]] + && [catch {package require Tktable $::VERSION} err] + && [catch {load [file join [pwd] $table(library)]} err] + && [catch {load [file join [pwd] .. unix $table(library)]} err] + && [catch {load [file join [pwd] .. win $table(library)]} err] +} { + error $err +} else { + puts "Tktable v[package provide Tktable] loaded" +} diff --git a/tktable/demos/maxsize.tcl b/tktable/demos/maxsize.tcl new file mode 100644 index 0000000..198eefb --- /dev/null +++ b/tktable/demos/maxsize.tcl @@ -0,0 +1,76 @@ +#!/bin/sh +# the next line restarts using wish \ +exec wish "$0" ${1+"$@"} + +## maxsize.tcl +## +## This demo uses a really big table. The big startup time is in +## filling the table's Tcl array var. +## +## jeff at hobbs org + +source [file join [file dirname [info script]] loadtable.tcl] + +array set table { + rows 40000 + cols 10 + table .t + array t +} + +proc fill { array x y } { + upvar $array f + for {set row 0} {$row<$x} {incr row} { + for {set col 0} {$col<$y} {incr col} { + set f($row,$col) "$row,$col" + } + } +} + +## Test out the use of a procedure to define tags on rows and columns +proc colProc col { if {$col > 0 && $col % 2} { return OddCol } } + +label .label -text "TkTable v2 Example" + +fill $table(array) $table(rows) $table(cols) +table $table(table) \ + -rows $table(rows) -cols $table(cols) \ + -variable $table(array) \ + -width 6 -height 8 \ + -titlerows 1 -titlecols 1 \ + -yscrollcommand {.sy set} \ + -xscrollcommand {.sx set} \ + -coltagcommand colProc \ + -selectmode extended \ + -rowstretch unset \ + -colstretch unset \ + -selecttitles 0 \ + -drawmode slow + +scrollbar .sy -command [list $table(table) yview] +scrollbar .sx -command [list $table(table) xview] -orient horizontal +button .exit -text "Exit" -command {exit} +grid .label - -sticky ew +grid $table(table) .sy -sticky news +grid .sx -sticky ew +grid .exit -sticky ew -columnspan 2 +grid columnconfig . 0 -weight 1 +grid rowconfig . 1 -weight 1 + +$table(table) tag config OddCol -bg brown -fg pink +$table(table) tag config title -bg red -fg blue -relief sunken +$table(table) tag config dis -state disabled + +set i -1 +set first [$table(table) cget -colorigin] +foreach anchor {n s e w nw ne sw se c} { + $table(table) tag config $anchor -anchor $anchor + $table(table) tag row $anchor [incr i] + $table(table) set $i,$first $anchor +} +font create courier -family Courier -size 10 +$table(table) tag config s -font courier -justify center + +$table(table) width -2 8 -1 9 0 12 4 14 + +puts [list Table is $table(table) with array [$table(table) cget -var]] diff --git a/tktable/demos/spreadsheet.tcl b/tktable/demos/spreadsheet.tcl new file mode 100644 index 0000000..9a36c7e --- /dev/null +++ b/tktable/demos/spreadsheet.tcl @@ -0,0 +1,122 @@ +#!/bin/sh +# the next line restarts using wish \ + exec wish "$0" ${1+"$@"} + +## spreadsheet.tcl +## +## This demos shows how you can simulate a 3D table +## and has other basic features to begin a basic spreadsheet +## +## jeff at hobbs org + +source [file join [file dirname [info script]] loadtable.tcl] + +array set table { + rows 10 + cols 10 + page AA + table .table + default pink + AA orange + BB blue + CC green +} + +proc colorize num { if {$num>0 && $num%2} { return colored } } + +proc fill {array {r 10} {c 10}} { + upvar \#0 $array ary + for {set i 0} {$i < $r} {incr i} { + for {set j 0} {$j < $c} {incr j} { + if {$j && $i} { + set ary($i,$j) "$array $i,$j" + } elseif {$i} { + set ary($i,$j) "$i" + } elseif {$j} { + set ary($i,$j) [format %c [expr 64+$j]] + } + } + } +} + +proc changepage {w e name el op} { + global $name table + if {[string comp {} $el]} { set name [list $name\($el\)] } + set i [set $name] + if {[string comp $i [$w cget -var]]} { + $w sel clear all + $w config -variable $i + $e config -textvar ${i}(active) + $w activate origin + if {[info exists table($i)]} { + $w tag config colored -bg $table($i) + } else { + $w tag config colored -bg $table(default) + } + $w see active + } +} + +label .example -text "TkTable v1 Spreadsheet Example" + +label .current -textvar table(current) -width 5 +entry .active -textvar $table(page)(active) +label .lpage -text "PAGE:" -width 6 -anchor e +tk_optionMenu .page table(page) AA BB CC DD + +fill $table(page) +fill BB [expr {$table(rows)/2}] [expr {$table(cols)/2}] + +trace var table(page) w [list changepage $table(table) .active] + +set t $table(table) +table $t \ + -rows $table(rows) \ + -cols $table(cols) \ + -variable $table(page) \ + -titlerows 1 \ + -titlecols 1 \ + -yscrollcommand { .sy set } \ + -xscrollcommand { .sx set } \ + -coltagcommand colorize \ + -flashmode on \ + -selectmode extended \ + -colstretch unset \ + -rowstretch unset \ + -width 5 -height 5 \ + -browsecommand {set table(current) %S} + +$t tag config colored -bg $table($table(page)) +$t tag config title -fg red -relief groove +$t tag config blue -bg blue +$t tag config green -bg green +$t tag cell green 6,3 5,7 4,9 +$t tag cell blue 8,8 +$t tag row blue 7 +$t tag col blue 6 8 +$t width 0 3 2 7 + +scrollbar .sy -command [list $t yview] +scrollbar .sx -command [list $t xview] -orient horizontal +button .exit -text "Exit" -command exit + +grid .example - - - - -sticky ew +grid .current .active .lpage .page - -sticky ew +grid $t - - - .sy -sticky ns +grid .sx - - - -sticky ew +grid .exit - - - - -sticky ew +grid columnconfig . 1 -weight 1 +grid rowconfig . 2 -weight 1 +grid config $t -sticky news + +bind .active [list tkTableMoveCell $t 1 0] + +menu .menu +menu .menu.file +. config -menu .menu +.menu add cascade -label "File" -underline 0 -menu .menu.file +.menu.file add command -label "Fill Array" -command { fill $table(page) } +.menu.file add command -label "Quit" -command exit + +puts [list Table is $table(table) with array [$table(table) cget -var]] + diff --git a/tktable/demos/tcllogo.gif b/tktable/demos/tcllogo.gif new file mode 100644 index 0000000000000000000000000000000000000000..4603d4ff417d9ec1cc1ba3c0d1eeec29120a3f8d GIT binary patch literal 2341 zcmbu7{XdlX8ppq$AF{I}#1t}vjX@{w9%f?NQRAtER>qJbbnBJFK{-0ksl`Zx)TE-D zvL0)iG>J{5(;BQM?nG4Da#EhM#a5f@RIl!H-TsC1eZA&~>%P9<&-MO%uJH@-*A_&_Z-_bQ@|o7>*-4Nbm<^p~5g6Ly#-j1qx{52*VNN z2uVW#zy;SKXmATrLLPt#uOSX#0>j`Cs6h;%;U!=J2Mh*nkVf>1=-beS8V-VuL6G1N z#zKW5L@#iD{WQh=M(KUdFNubl&z)ZHe3Uffd^+^D=MB@y^B(Bs&tuUJ<|lzP{2gFR z5FU7%MQ8+}HiVQ2$q>pwC=4MHLL7ul0ptH@&(6+{jEuCkwJDWKnM{_Ekr5UaCK8D_ z9FD0et?ddw7!{9@A%(OIt^FG+)lx$sy*{P!+)P}OWqL{-(xamv|+40bI!q5 zC>+T4Il@Xu5v?Aw-qICu+C*x5+guHAC&kF?V`BoDyiGGn2Z#VbpQ#wyE*9JYvjVUjLKJ9}{0B zuXmT$Ev?vLUDed9(aUK$IFqKYezeKnFJ*gW_w3osx#p{DnIG@<|MS>T!^qx0e9zqK z%(QqB<-D(S!I5yvAk92WVE5=+vO)jI`FD>!)6Rci-D#VZ8LS-IEC1@|ZKKFvq?>Sm z+HR|bhF4Q*F_RQ#i})#5Eq6V#*%B_ObyBcBwpZ?YDl|==Ba+=C_Gbx<_9)n_g!?`r zvh4fagQkWGd38abJbQDYo?3A#?v~9Pl*d~uCE1=GC!_KOJKx7jgxrY8JReoZAfrlc zIT3W_o0U?T&f9%LTOY3GdC)3z;Ye0uu{h+1>{a4e#`}}gCdC@Ps&fe*Z-?rHDf(9G zAVYaXEw{-zqr9SXM7*KK(|rwdTj9>>vO`WK7vh*f>eFS3tK`FB-Y50_hU>nyDi~v* z>4_<24E#!+zn>YMzn>e(2+1GgD(%J+ZJEB|+kW&ENL(U?^(i%H`*gM2O>&Z2PhK&s z^oh10mBT&_7nA0mML(FV+|yh)QTec@t0&&FCBf#nR7I*fOf$Vr%9aPpOlu{Q*^b01 z_QKA^}ED~f9%P7)u{Q{W*qS0(~x_H z=DGjIj!)LY%aY=+B_-U&w#C66Vy}?KVD~kp54bLoT4|MW0|kweVVi0;b6BYemTo(> zi(SYAedf#HL*~)+EMpfJnM~(wy~f*Dqxu|w zKUhKecMGnowEaaI&UoCAQdM04%ZJyu#=H+FhAHw25|q^f3&ovKHI<*9tCRoms;l!{ z`=^gX6`nDN@;(n;bG2hl9bgV^G-|zmT-M)OZ=uy6)bO8mf0j#4j5#OTinx(iE=!*F zke3-ie%F(^^M26b|%Uvsy5|A@g(SfYtc<)(Tf<#J68|eB63c zT3S_?kP)znG48vpN8NpJqZV7ovPP;q(U&&ZWbmo)d3jE~JchMa#E>UA+Kt+0?dC^Z zpd8F|!>o?*i+0cUU&Xg@x}+O6=u3m-0iz4=3;4XujiEbeK07 zb;P3e(u*w4iquE{&U%e>e@=}QtUo&0qir3nKh2x?jpdf{+Q4t-dv8SC60e8eLw&4gX>r zLiLvRD+Nz(6h(7#%{5+Tyf4O7l>lG^{xdGn@&N*Cc zHw)(x+0!|~o0U4>(#y>l6m$=$>kbVoj_!eaYr|tah8= zzlv*G_-N)*JU1b!R;pj^*QgTNdsNCq@u!*9GLeI$^X-6;g%+3b)r~BpOFF&_yvmJ- Q-#541xs+_MkcmA12d>*S0{{R3 literal 0 HcmV?d00001 diff --git a/tktable/demos/tktable.py b/tktable/demos/tktable.py new file mode 100644 index 0000000..0d51340 --- /dev/null +++ b/tktable/demos/tktable.py @@ -0,0 +1,344 @@ +# +# #### OUTDATE MODULE #### +# This has been superceded by the tktable.py that ships in the lib area. +# This is kept for compatibility as the newer wrapper is not 100% compatible. +# #### OUTDATE MODULE #### +# +# This file is taken from the usenet: +# http://groups.google.com/groups?selm=351A52BC.27EA0BE2%40desys.de +# From: Klaus Roethemeyer +# +# It is provided here as an example of using Tktable with Python/Tkinter. + +#============================================================================ +# +# MODULE: This module contains the wrapper class for the tktable widget +# +# CREATED: Roethemeyer, 20.01.98 +# +# VERSION: $Id: tktable.py,v 1.2 2008/11/14 22:49:35 hobbs Exp $ +# +#============================================================================ + +#============================================================================ +# import modules +#---------------------------------------------------------------------------- +import string, types, Tkinter +#---------------------------------------------------------------------------- + +#============================================================================ +# ArrayVar +#---------------------------------------------------------------------------- +class ArrayVar(Tkinter.Variable): + _default = '' + + def __init__(self, master = None): + Tkinter.Variable.__init__(self, master) + + def get(self, index = None): + if not index: + res = {} + for i in self.names(): + res[i] = self._tk.globalgetvar(self._name, i) + try: del res['None'] + except KeyError: pass + return res + else: + return self._tk.globalgetvar(self._name, index) + + def names(self): + return string.split(self._tk.call('array', 'names', self._name)) + + def set(self, index, value = ''): + if value == None: + value = '' + return self._tk.globalsetvar(self._name, index, value) +#---------------------------------------------------------------------------- + + +#============================================================================ +# Table +#---------------------------------------------------------------------------- +class Table(Tkinter.Widget): + + _switches1 = ('cols', 'holddimensions', 'holdtags', 'keeptitles', 'rows', '-') + _tabsubst_format = ('%c', '%C', '%i', '%r', '%s', '%S', '%W') + _tabsubst_commands = ('browsecommand', 'browsecmd', 'command', + 'selectioncommand', 'selcmd', + 'validatecommand', 'valcmd') + + def __init__(self, master, cnf={}, **kw): + try: + master.tk.call('package', 'require', 'Tktable') + except Tkinter.TclError: + master.tk.call('load', '', 'Tktable') + Tkinter.Widget.__init__(self, master, 'table', cnf, kw) + + def _options(self, cnf, kw = None): + if kw: + cnf = Tkinter._cnfmerge((cnf, kw)) + else: + cnf = Tkinter._cnfmerge(cnf) + res = () + for k, v in cnf.items(): + if v is not None: + if k[-1] == '_': k = k[:-1] + if callable(v): + if k in self._tabsubst_commands: + v = "%s %s" % (self._register(v, self._tabsubst), + string.join(self._tabsubst_format)) + else: + v = self._register(v) + res = res + ('-'+k, v) + return res + + def _tabsubst(self, *args): + tk = self.tk + if len(args) != len(self._tabsubst_format): return args + c, C, i, r, s, S, W = args + e = Tkinter.Event() + e.widget = self + e.c = tk.getint(c) + e.i = tk.getint(i) + e.r = tk.getint(r) + e.C = (e.r, e.c) + try: e.s = tk.getint(s) + except Tkinter.TclError: e.s = s + try: e.S = tk.getint(S) + except Tkinter.TclError: e.S = S + e.W = W + return (e,) + + + def _getCells(self, cellString): + res = [] + for i in string.split(cellString): + res.append(tuple(map(int, string.split(i, ',')))) + return res + + def _getLines(self, lineString): + return map(int, string.split(lineString)) + + def _prepareArgs1(self, args): + args = list(args) + + for i in xrange(len(args)): + if args[i] in self._switches1: + args[i] = "-" + args[i] + + return tuple(args) + + + def activate(self, index): + self.tk.call(self._w, 'activate', index) + + def bbox(self, first, last=None): + return self._getints(self.tk.call(self._w, 'bbox', first, last)) or None + + def border_mark(self, x, y, row=None, col=None): + self.tk.call(self._w, 'border', 'mark', x, y, row, col) + + def border_dragto(self, x, y): + self.tk.call(self._w, 'border', 'dragto', x, y) + + def curselection(self, setValue = None): + if setValue != None: + self.tk.call(self._w, 'curselection', 'set', setValue) + + else: + return self._getCells(self.tk.call(self._w, 'curselection')) + + def delete_active(self, index, more = None): + self.tk.call(self._w, 'delete', 'active', index, more) + + def delete_cols(self, *args): + apply(self.tk.call, (self._w, 'delete', 'cols') + self._prepareArgs1(args)) + + def delete_rows(self, *args): + apply(self.tk.call, (self._w, 'delete', 'rows') + self._prepareArgs1(args)) + + def flush(self, first=None, last=None): + self.tk.call(self._w, 'flush', first, last) + + def get(self, first, last=None): + return self.tk.call(self._w, 'get', first, last) + + def height(self, *args): + apply(self.tk.call, (self._w, 'height') + args) + + def icursor(self, arg): + self.tk.call(self._w, 'icursor', arg) + + def index(self, index, rc = None): + if rc == None: + return self._getCells(self.tk.call(self._w, 'index', index, rc))[0] + else: + return self._getCells(self.tk.call(self._w, 'index', index, rc))[0][0] + + def insert_active(self, index, value): + self.tk.call(self._w, 'insert', 'active', index, value) + + def insert_cols(self, *args): + apply(self.tk.call, (self._w, 'insert', 'cols') + self._prepareArgs1(args)) + + def insert_rows(self, *args): + apply(self.tk.call, (self._w, 'insert', 'rows') + self._prepareArgs1(args)) + + def reread(self): + self.tk.call(self._w, 'reread') + + def scan_mark(self, x, y): + self.tk.call(self._w, 'scan', 'mark', x, y) + + def scan_dragto(self, x, y): + self.tk.call(self._w, 'scan', 'dragto', x, y) + + def see(self, index): + self.tk.call(self._w, 'see', index) + + def selection_anchor(self, index): + self.tk.call(self._w, 'selection', 'anchor', index) + + def selection_clear(self, first, last=None): + self.tk.call(self._w, 'selection', 'clear', first, last) + + def selection_includes(self, index): + return int(self.tk.call(self._w, 'selection', 'includes', index)) + + def selection_set(self, first, last=None): + self.tk.call(self._w, 'selection', 'set', first, last) + + def set(self, *args): + apply(self.tk.call, (self._w, 'set') + args) + + def tag_cell(self, tagName, *args): + result = apply(self.tk.call, (self._w, 'tag', 'cell', tagName) + args) + if not args: return self._getCells(result) + + def tag_cget(self, tagName, option): + return self.tk.call(self._w, 'tag', 'cget', tagName, '-' + option) + + def tag_col(self, tagName, *args): + result = apply(self.tk.call, (self._w, 'tag', 'col', tagName) + args) + if not args: return self._getLines(result) + + def tag_configure(self, tagName, cnf={}, **kw): + if not cnf and not kw: + return self.tk.call(self._w, 'tag', 'configure', tagName) + if type(cnf) == types.StringType and not kw: + return self.tk.call(self._w, 'tag', 'configure', tagName, '-' + cnf) + if type(cnf) == types.DictType: + apply(self.tk.call, + (self._w, 'tag', 'configure', tagName) + + self._options(cnf, kw)) + else: + raise TypeError, "usage: .tag_configure tagName [option] | [option=value]+" + + def tag_delete(self, tagName): + self.tk.call(self._w, 'tag', 'delete', tagName) + + def tag_exists(self, tagName): + return self.getboolean(self.tk.call(self._w, 'tag', 'exists', tagName)) + + def tag_includes(self, tagName, index): + return self.getboolean(self.tk.call(self._w, 'tag', 'includes', tagName, index)) + + def tag_names(self, pattern=None): + return self.tk.call(self._w, 'tag', 'names', pattern) + + def tag_row(self, tagName, *args): + result = apply(self.tk.call, (self._w, 'tag', 'row', tagName) + args) + if not args: return self._getLines(result) + + def validate(self, index): + self.tk.call(self._w, 'validate', index) + + def width(self, *args): + result = apply(self.tk.call, (self._w, 'width') + args) + if not args: + str = string.replace(result, '{', '') + str = string.replace(str, '}', '') + lst = string.split(str) + x = len(lst) + x2 = x / 2 + return tuple(map(lambda i, j, l=lst: (int(l[i]), int(l[j])), + xrange(x2), xrange(x2, x))) + elif len(args) == 1: + return int(result) + else: + return result + + def xview(self, *args): + if not args: + return self._getdoubles(self.tk.call(self._w, 'xview')) + apply(self.tk.call, (self._w, 'xview') + args) + + def yview(self, *args): + if not args: + return self._getdoubles(self.tk.call(self._w, 'yview')) + apply(self.tk.call, (self._w, 'yview') + args) +#---------------------------------------------------------------------------- + + +#============================================================================ +# Test-Function +#---------------------------------------------------------------------------- +if __name__ == '__main__': + from Tkinter import Tk, Label, Button + import pprint + + prn = pprint.PrettyPrinter(indent = 6).pprint + + def test_cmd(event=None): + if event.i == 0: + return '%i, %i' % (event.r, event.c) + else: + return 'set' + + + def browsecmd(event): + print "event:", event.__dict__ + print "curselection:", test.curselection() + print "active:", test.index('active', 'row') + print "anchor:", test.index('anchor', 'row') + + root = Tk() + #root.tk.call('load', '', 'Tktable') + + var = ArrayVar(root) + for y in range(-1, 4): + for x in range(-1, 5): + index = "%i,%i" % (y, x) + var.set(index, index) + + label = Label(root, text="Proof-of-existence test for Tktable") + label.pack(side = 'top', fill = 'x') + + quit = Button(root, text="QUIT", command=root.destroy) + quit.pack(side = 'bottom', fill = 'x') + + test = Table(root, + rows=10, + cols=5, + state='disabled', + width=6, + height=6, + titlerows=1, + titlecols=1, + roworigin=-1, + colorigin=-1, + selectmode='browse', + selecttype='row', + rowstretch='unset', + colstretch='last', + browsecmd=browsecmd, + flashmode='on', + variable=var, + usecommand=0, + command=test_cmd) + test.pack(expand=1, fill='both') + test.tag_configure('sel', background = 'yellow') + test.tag_configure('active', background = 'blue') + test.tag_configure('title', anchor='w', bg='red', relief='sunken') + root.mainloop() +#---------------------------------------------------------------------------- diff --git a/tktable/demos/valid.tcl b/tktable/demos/valid.tcl new file mode 100644 index 0000000..8a16a11 --- /dev/null +++ b/tktable/demos/valid.tcl @@ -0,0 +1,95 @@ +#!/bin/sh +# the next line restarts using wish \ +exec wish "$0" ${1+"$@"} + +## valid.tcl +## +## This demos shows the use of the validation mechanism of the table +## and uses the table's cache (no -command or -variable) +## +## jeff at hobbs org + +source [file join [file dirname [info script]] loadtable.tcl] + +array set table { + rows 10 + cols 10 + table .table +} + +proc colorize num { + if {$num>0 && $num%2} { return colored } +} + +proc fill_headers {w {r 10} {c 10}} { + for {set i 1} {$i < $r} {incr i} { + $w set $i,0 "$i" + } + for {set j 1} {$j < $c} {incr j} { + if {$j%3==1} { + $w set 0,$j AlphaNum + } elseif {$j%2==1} { + $w set 0,$j Alpha + } elseif {$j} { + $w set 0,$j Real + } + } +} + +proc validate {c val} { + if {$c%3==1} { + ## Alphanum + set expr {^[A-Za-z0-9 ]*$} + } elseif {$c%2==1} { + ## Alpha + set expr {^[A-Za-z ]*$} + } elseif {$c} { + ## Real + set expr {^[-+]?[0-9]*\.?[0-9]*([0-9]\.?e[-+]?[0-9]*)?$} + } + if {[regexp $expr $val]} { + return 1 + } else { + bell + return 0 + } +} + +label .example -text "TkTable v1 Validated Table Example" + +set t $table(table) +table $t \ + -rows $table(rows) \ + -cols $table(cols) \ + -cache 1 \ + -titlerows 1 \ + -titlecols 1 \ + -yscrollcommand { .tsy set } \ + -xscrollcommand { .tsx set } \ + -width 5 -height 5 \ + -coltagcommand colorize \ + -flashmode on \ + -selectmode extended \ + -colstretch unset \ + -rowstretch unset \ + -validate yes \ + -vcmd {if {![%W tag includes title %C]} { validate %c %S } } + +fill_headers $t +$t tag config colored -bg lightblue +$t tag config title -fg red +$t width 0 3 + +scrollbar .tsy -command [list $t yview] +scrollbar .tsx -command [list $t xview] -orient horizontal +button .exit -text "Exit" -command {exit} + +grid .example - -sticky ew +grid $t .tsy -sticky news +grid .tsx -sticky ew +grid .exit - -sticky ew +grid columnconfig . 0 -weight 1 +grid rowconfig . 1 -weight 1 + +puts [list Table is $table(table)] + diff --git a/tktable/doc/tkTable.html b/tktable/doc/tkTable.html new file mode 100644 index 0000000..4b264ff --- /dev/null +++ b/tktable/doc/tkTable.html @@ -0,0 +1,2039 @@ + + + + + +man page(1) manual page + + +Table of Contents

+______________________________________________________________________________ + +

+

Name

+ +

+table - Create and manipulate tables + +

+

Synopsis

+ +

+table pathName ?options? + +

+

Standard Options

+ + +
+ +
-anchor
+
-background -cursor +
+ +
-exportselection
+
-font -foreground +
+ +
-highlightbackground
+
-highlightcolor -highlightthickness +
+ +
-insertbackground
+
-insertborderwidth-insertofftime +-insertontime -insertwidth -invertselected +
+ +
-relief
+
-takefocus -xscrollcommand +-yscrollcommand + +

+
+

+See the options manual entry for details on the standard options. + +

+

Widget-specific Options

+ +

+Command-Line Name:-autoclear
+ +Database Name: autoClear
+ +Database Class: AutoClear + +

+A boolean value which specifies whether the first keypress in a +cell will delete whatever text was previously there. Defaults +to 0. + +

+Command-Line Name:-bordercursor
+ +Database Name: borderCursor
+ +Database Class: Cursor + +

+Specifies the name of the cursor to show when over borders, a +visual indication that interactive resizing is allowed (it is +thus affect by the value of -resizeborders). Defaults to +crosshair. + +

+Command-Line Name:-borderwidth or -bd
+ +Database Name: borderWidth
+ +Database Class: BorderWidth + +

+Specifies a non-negative pixel value or list of values indicating +the width of the 3-D border to draw on interior table cells +(if such a border is being drawn; the relief option typically +determines this). If one value is specified, a rectangle of +this width will be drawn. If two values are specified, then +only the left and right edges of the cell will have borders. If +four values are specified, then the values correspond to the +{left right top bottom} edges. This can be overridden by the a +tag's borderwidth option. It can also be affected by the +defined -drawmode for the table. Each value in the list must +have one of the forms acceptable to Tk_GetPixels. + +

+Command-Line Name:-browsecommand or -browsecmd +Database Name: browseCommand
+ +Database Class: BrowseCommand + +

+Specifies a command which will be evaluated anytime the active +cell changes. It uses the %-substition model described in COMMAND +SUBSTITUTION below. Any changes to the active cell while +the command is running are ignored to prevent recursion. + +

+Command-Line Name:-cache
+ +Database Name: cache
+ +Database Class: Cache + +

+A boolean value that specifies whether an internal cache of the +table contents should be kept. This greatly enhances speed performance +when used with -command but uses extra memory. Can +maintain state when both -command and -variable are empty. The +cache is automatically flushed whenever the value of -cache or +-variable changes, otherwise you have to explicitly call clear +on it. Defaults to off. + +

+Command-Line Name:-colorigin
+ +Database Name: colOrigin
+ +Database Class: Origin + +

+Specifies what column index to interpret as the leftmost column +in the table. This value is used for user indices in the table. +Defaults to 0. + +

+Command-Line Name:-cols
+ +Database Name: cols
+ +Database Class: Cols + +

+Number of cols in the table. Defaults to 10. + +

+Command-Line Name:-colseparator
+ +Database Name: colSeparator
+ +Database Class: Separator + +

+Specifies a separator character that will be interpreted as the +column separator when cutting or pasting data in a table. By +default, columns are separated as elements of a tcl list. + +

+Command-Line Name:-colstretchmode
+ +Database Name: colStretchMode
+ +Database Class: StretchMode + +

+Specifies one of the following stretch modes for columns to fill +extra allocated window space: + +

+none Columns will not stretch to fill the assigned window +space. If the columns are too narrow, there will be a +blank space at the right of the table. This is the +default. + +

+unset Only columns that do not have a specific width set will +be stretched. + +

+

+ +
all
+
All columns will be stretched by the same number of pixels +to fill the window space allocated to the table. +This mode can interfere with interactive border resizing +which tries to force column width. + +

+
+

+last The last column will be stretched to fill the window +space allocated to the table. + +

+fill (only valid for -rowstretch currently) +The table will get more or less columns according to the +window space allocated to the table. This mode has +numerous quirks and may disappear in the future. + +

+Command-Line Name:-coltagcommand
+ +Database Name: colTagCommand
+ +Database Class: TagCommand + +

+Provides the name of a procedure that will be evaluated by the +widget to determine the tag to be used for a given column. When +displaying a cell, the table widget will first check to see if a +tag has been defined using the tag col widget method. If no tag +is found, it will evaluate the named procedure passing the column +number in question as the sole argument. The procedure is +expected to return the name of a tag to use, or a null string. +Errors occurring during the evaluation of the procedure, or the +return of an invalid tag name are silently ignored. + +

+Command-Line Name:-colwidth
+ +Database Name: colWidth
+ +Database Class: ColWidth + +

+Default column width, interpreted as characters in the default +font when the number is positive, or pixels if it is negative. +Defaults to 10. + +

+Command-Line Name:-command
+ +Database Name: command
+ +Database Class: Command + +

+Specified a command to use as a procedural interface to cell +values. If -usecommand is true, this command will be used +instead of any reference to the -variable array. When retrieving +cell values, the return value of the command is used as the +value for the cell. It uses the %-substition model described in +COMMAND SUBSTITUTION below. + +

+Command-Line Name:-drawmode
+ +Database Name: drawMode
+ +Database Class: DrawMode + +

+Sets the table drawing mode to one of the following options: + +

+slow The table is drawn to an offscreen pixmap using the Tk +bordering functions (double-buffering). This means there +will be no flashing, but this mode is slow for larger +tables. + +

+compatible
+ +The table is drawn directly to the screen using the Tk +border functions. It is faster, but the screen may flash +on update. This is the default. + +

+

+ +
fast
+
The table is drawn directly to the screen and the borders +are done with fast X calls, so they are always one pixel +wide only. As a side effect, it restricts -borderwidth +to a range of 0 or 1. This mode provides best performance +for large tables, but can flash on redraw and is +not 100% Tk compatible on the border mode. + +

+
+

+single The table is drawn to the screen as in fast mode, but +only single pixel lines are drawn (not square borders). + +

+Command-Line Name:-ellipsis
+ +Database Name: ellipsis
+ +Database Class: Ellipsis + +

+This specifies a string to display at the end of a line that +would be clipped by its cell, like ``...''. An ellipsis will be +displayed only on non-wrapping, non-multiline cells that would +be clipped. The ellipsis will display on the left for east +anchored cells, otherwise it displays on the right. Defaults to + (no ellipsis). + +

+Command-Line Name:-flashmode
+ +Database Name: flashMode
+ +Database Class: FlashMode + +

+A boolean value which specifies whether cells should flash when +their value changes. The table tag flash will be applied to +these cells for the duration specified by -flashtime. Defaults +to 0. + +

+Command-Line Name:-flashtime
+ +Database Name: flashTime
+ +Database Class: FlashTime + +

+The amount of time, in 1/4 second increments, for which a cell +should flash when its value has changed. -flashmode must be on. +Defaults to 2. + +

+Command-Line Name:-height
+ +Database Name: height
+ +Database Class: Height + +

+Specifies the desired height for the window, in rows. If zero +or less, then the desired height for the window is made just +large enough to hold all the rows in the table. The height can +be further limited by -maxheight. + +

+Command-Line Name:-invertselected
+ +Database Name: invertSelected
+ +Database Class: InvertSelected + +

+Specifies whether the foreground and background of an item +should simply have their values swapped instead of merging the +sel tag options when the cell is selected. Defaults to 0 (merge +sel tag). + +

+Command-Line Name:-ipadx
+ +Database Name: ipadX
+ +Database Class: Pad + +

+A pixel value specifying the internal offset X padding for text +in a cell. This value does not grow the size of the cell, it +just causes the text to be drawn further from the cell border. +It only affects one side (depending on anchor). Defaults to 0. +See -padx for an alternate padding style. + +

+Command-Line Name:-ipady
+ +Database Name: ipadY
+ +Database Class: Pad + +

+A pixel value specifying the internal offset Y padding for text +in a cell. This value does not grow the size of the cell, it +just causes the text to be drawn further from the cell border. +It only affects one side (depending on anchor). Defaults to 0. +See -pady for an alternate padding style. + +

+Command-Line Name:-justify
+ +Database Name: justify
+ +Database Class: Justify + +

+How to justify multi-line text in a cell. It must be one of +left, right, or center. Defaults to left. + +

+Command-Line Name:-maxheight
+ +Database Name: maxHeight
+ +Database Class: MaxHeight + +

+The max height in pixels that the window will request. Defaults +to 600. + +

+Command-Line Name:-maxwidth
+ +Database Name: maxWidth
+ +Database Class: MaxWidth + +

+The max width in pixels that the window will request. Defaults +to 800. + +

+Command-Line Name:-multiline
+ +Database Name: multiline
+ +Database Class: Multiline + +

+Specifies the default setting for the multiline tag option. +Defaults to 1. + +

+Command-Line Name:-padx
+ +Database Name: padX
+ +Database Class: Pad + +

+A pixel value specifying the offset X padding for a cell. This +value causes the default size of the cell to increase by two +times the value (one for each side), unless a specific pixel +size is chosen for the cell with the width command. This will +force an empty area on the left and right of each cell edge. +This padding affects all types of data in the cell. Defaults to +0. See -ipadx for an alternate padding style. + +

+Command-Line Name:-pady
+ +Database Name: padY
+ +Database Class: Pad + +

+A pixel value specifying the offset Y padding for a cell. This +value causes the default size of the cell to increase by two +times the value (one for each side), unless a specific pixel +size is chosen for the cell with the height command. This will +force an empty area on the top and bottom of each cell edge. +This padding affects all types of data in the cell. Defaults to +0. See -ipadx for an alternate padding style. + +

+Command-Line Name:-resizeborders
+ +Database Name: resizeBorders
+ +Database Class: ResizeBorders + +

+Specifies what kind of interactive border resizing to allow, +must be one of row, col, both (default) or none. + +

+Command-Line Name:-rowheight
+ +Database Name: rowHeight
+ +Database Class: RowHeight + +

+Default row height, interpreted as lines in the default font +when the number is positive, or pixels if it is negative. +Defaults to 1. + +

+Command-Line Name:-roworigin
+ +Database Name: rowOrigin
+ +Database Class: Origin + +

+Specifies what row index to interpret as the topmost row in the +table. This value is used for user indices in the table. +Defaults to 0. + +

+Command-Line Name:-rows
+ +Database Name: rows
+ +Database Class: Rows + +

+Number of rows in the table. Defaults to 10. + +

+Command-Line Name:-rowseparator
+ +Database Name: rowSeparator
+ +Database Class: Separator + +

+Specifies a separator character that will be interpreted as the +row separator when cutting or pasting data in a table. By +default, rows are separated as tcl lists. + +

+Command-Line Name:-rowstretchmode
+ +Database Name: rowStretchMode
+ +Database Class: StretchMode + +

+Specifies the stretch modes for rows to fill extra allocated +window space. See -colstretchmode for valid options. + +

+Command-Line Name:-rowtagcommand
+ +Database Name: rowTagCommand
+ +Database Class: TagCommand + +

+Provides the name of a procedure that can evaluated by the widget +to determine the tag to be used for a given row. The procedure +must be defined by the user to accept a single argument +(the row number), and return a tag name or null string. This +operates in a similar manner as -coltagcommand, except that it +applies to row tags. + +

+Command-Line Name:-selectioncommand or -selcmd +Database Name: selectionCommand
+ +Database Class: SelectionCommand + +

+Specifies a command to evaluate when the selection is retrieved +from a table via the selection mechanism (ie: evaluating +``selection get''). The return value from this command will +become the string passed on by the selection mechanism. It uses +the %-substition model described in COMMAND SUBSTITUTION below. +If an error occurs, a Tcl background error is generated and +nothing is returned. + +

+Command-Line Name:-selectmode
+ +Database Name: selectMode
+ +Database Class: SelectMode + +

+Specifies one of several styles for manipulating the selection. +The value of the option may be arbitrary, but the default bindings +expect it to be either single, browse, multiple, or +extended; the default value is browse. These styles are like +those for the Tk listbox, except expanded for 2 dimensions. + +

+Command-Line Name:-selecttitle
+ +Database Name: selectTitles
+ +Database Class: SelectTitles + +

+Specifies whether title cells should be allowed in the selection. +Defaults to 0 (disallowed). + +

+Command-Line Name:-selecttype
+ +Database Name: selectType
+ +Database Class: SelectType + +

+Specifies one of several types of selection for the table. The +value of the option may be one of row, col, cell, or both +(meaning row && col); the default value is cell. These types +define whether an entire row/col is affected when a cell's +selection is changed (set or clear). + +

+Command-Line Name:-sparsearray
+ +Database Name: sparseArray
+ +Database Class: SparseArray + +

+A boolean value that specifies whether an associated Tcl array +should be kept as a sparse array (1, the default) or as a full +array (0). If true, then cell values that are empty will be +deleted from the array (taking less memory). If false, then all +values in the array will be maintained. + +

+Command-Line Name:-state
+ +Database Name: state
+ +Database Class: State + +

+Specifies one of two states for the entry: normal or disabled. +If the table is disabled then the value may not be changed using +widget commands and no insertion cursor will be displayed, even +if the input focus is in the widget. Also, all insert or delete +methods will be ignored. Defaults to normal. + +

+Command-Line Name:-titlecols
+ +Database Name: titleCols
+ +Database Class: TitleCols + +

+Number of columns to use as a title area. Defaults to 0. + +

+Command-Line Name:-titlerows
+ +Database Name: titleRows
+ +Database Class: TitleRows + +

+Number of rows to use as a title area. Defaults to 0. + +

+Command-Line Name:-usecommand
+ +Database Name: useCommand
+ +Database Class: UseCommand + +

+A boolean value which specifies whether to use the command +option. This value sets itself to zero if command is used and +returns an error. Defaults to 1 (will use command if specified). + +

+Command-Line Name:-validate
+ +Database Name: validate
+ +Database Class: Validate + +

+A boolean specifying whether validation should occur for the +active buffer. Defaults to 0. + +

+Command-Line Name:-validatecommand or -vcmd +Database Name: validateCommand
+ +Database Class: ValidateCommand + +

+Specifies a command to execute when the active cell is edited. +This command is expected to return a Tcl boolean. If it returns +true, then it is assumed the new value is OK, otherwise the new +value is rejected (the edition will not take place). Errors in +this command are handled in the background. It uses the %-substition +model described in COMMAND SUBSTITUTION below. + +

+Command-Line Name:-variable
+ +Database Name: variable
+ +Database Class: Variable + +

+Global Tcl array variable to attach to the table's C array. It +will be created if it doesn't already exist or is a simple variable. +Keys used by the table in the array are of the form +row,col for cells and the special key active which contains the +value of the active cell buffer. The Tcl array is managed as a +sparse array (the table does not require that all valid indices +have values). No stored value for an index is equivalent to the +empty string, and clearing a cell will remove that index from +the Tcl array, unless the -sparsearray options is set to 0. + +

+Command-Line Name:-width
+ +Database Name: width
+ +Database Class: Width + +

+Specifies the desired width for the window, in columns. If zero +or less, then the desired width for the window is made just +large enough to hold all the columns in the table. The width +can be further limited by -maxwidth. + +

+Command-Line Name:-wrap
+ +Database Name: wrap
+ +Database Class: Wrap + +

+Specifies the default wrap value for tags. Defaults to 0. +_________________________________________________________________ + +

+

Description

+ +

+The table command creates a 2-dimensional grid of cells. The table can +use a Tcl array variable or Tcl command for data storage and retrieval, +as well as optionally cache data in memory for speed. One of these +data sources must be configured before any data is retained by the table. +The widget has an active cell, the contents of which can be +edited (when the state is normal). The widget supports a default style +for the cells and also multiple tags, which can be used to change the +style of a row, column or cell (see TAGS for details). A cell flash +can be set up so that changed cells will change color for a specified +amount of time ("blink"). Cells can have embedded images or windows, +as described in TAGS and EMBEDDED WINDOWS respectively. + +

+One or more cells may be selected as described below. If a table is +exporting its selection (see -exportselection option), then it will +observe the standard X11 protocols for handling the selection. See THE +SELECTION for details. + +

+It is not necessary for all the cells to be displayed in the table window +at once; commands described below may be used to change the view in +the window. Tables allow scrolling in both directions using the standard +-xscrollcommand and -yscrollcommand options. They also support +scanning, as described below. + +

+In order to obtain good performance, the table widget supports multiple +drawing modes, two of which are fully Tk compatible. + +

+

Initialization

+ +

+When the table command is loaded into an interpreter, a built-in Tcl +command, tkTableInit, is evaluated. This will search for the appropriate +table binding init file to load. The directories searched are +those in $tcl_pkgPath, both with Tktable(version) appended and without, +$tk_library and [pwd] (the current directory). You can also define an +$env(TK_TABLE_LIBRARY) to head this search list. By default, the file +searched for is called tkTable.tcl, but this can be overridden by setting +$env(TK_TABLE_LIBRARY_FILE). + +

+This entire init script can be overridden by providing your own +tkTableInit procedure before the library is loaded. Otherwise, the +aforementioned env(TK_TABLE_LIBRARY) variable will be set with the +directory in which $env(TK_TABLE_LIBRARY_FILE) was found. + +

+

Indices

+ +

+Many of the widget commands for tables take one or more indices as +arguments. An index specifies a particular cell of the table, in any +of the following ways: + +

+number,number
+ +Specifies the cell as a numerical index of row,col which +corresponds to the index of the associated Tcl array, where +-roworigin,-colorigin corresponds to the first cell in the +table (0,0 by default). The values for row and column will +be constrained to actual values in the table, which means a +valid cell is always found. + +

+

+ +
active
+
Indicates the cell that has the location cursor. It is +specified with the activate widget command. + +

+ +
anchor
+
Indicates the anchor point for the selection, which is set +with the selection anchor widget command. + +

+
+

+bottomright Indicates the bottom-rightmost cell visible in the table. + +

+

+ +
end
+
Indicates the bottom right cell of the table. + +

+ +
origin
+
Indicates the top-leftmost editable cell of the table, not +necessarily in the display. This takes into account the +user specified origin and title area. + +

+ +
topleft
+
Indicates the top-leftmost editable cell visible in the table +(this excludes title cells). + +

+ +
@x,y
+
Indicates the cell that covers the point in the table window +specified by x and y (in pixel coordinates). If no +cell covers that point, then the closest cell to that point +is used. + +

+
+

+In the widget command descriptions below, arguments named index, first, +and last always contain text indices in one of the above forms. + +

+

Tags

+ +

+A tag is a textual string that is associated with zero or more rows, +columns or cells in a table. Tags may contain arbitrary characters, +but it is probably best to avoid using names which look like indices to +reduce coding confusion. A tag can apply to an entire row or column, +or just a single cell. There are several permanent tags in each table +that can be configured by the user and will determine the attributes +for special cells: + +

+

+ +
active
+
This tag is given to the active cell + +

+ +
flash
+
If flash mode is on, this tag is given to any recently +edited cells. + +

+ +
sel
+
This tag is given to any selected cells. + +

+ +
title
+
This tag is given to any cells in the title rows and +columns. This tag has -state disabled by default. + +

+
+

+Tags control the way cells are displayed on the screen. Where appropriate, +the default for displaying cells is determined by the options +for the table widget. However, display options may be associated with +individual tags using the ``pathName tag configure'' widget command. +If a cell, row or column has been tagged, then the display options +associated with the tag override the default display style. The following +options are currently supported for tags: + +

+

+ +
-anchor anchor
+
+Anchor for item in the cell space. + +

+ +
-background or -bg color
+
+Background color of the cell. + +

+ +
-borderwidth or -bd pixelList
+
+Borderwidth of the cell, of the same format for the table, +but may also be empty to inherit the default table +borderwidth value (the default). + +

+ +
-ellipsis string
+
+String to display at the end of a line that would be +clipped by its cell, like ``...''. An ellipsis will be +displayed only on non-wrapping, non-multiline cells that +would be clipped. The ellipsis will display on the left +for east anchored cells, otherwise it displays on the +right. + +

+ +
-font fontName
+
+Font for text in the cell. + +

+ +
-foreground or -fg color
+
+Foreground color of the cell. + +

+ +
-justify justify
+
+How to justify multi-line text in a cell. It must be one +of left, right, or center. + +

+ +
-image imageName
+
+An image to display in the cell instead of text. + +

+ +
-multiline boolean
+
+Whether to display text with newlines on multiple lines. + +

+ +
-relief relief
+
+The relief for the cell. May be the empty string to +cause this tag to not disturb the value. + +

+ +
-showtext boolean
+
+Whether to show the text over an image. + +

+ +
-state state
+
+The state of the cell, to allow for certain cells to be +disabled. This prevents the cell from being edited by +the insert or delete methods, but a direct set will not +be prevented. + +

+ +
-wrap boolean
+
+Whether characters should wrap in a cell that is not wide +enough. + +

+
+

+A priority order is defined among tags based on creation order (first +created tag has highest default priority), and this order is used in +implementing some of the tag-related functions described below. When a +cell is displayed, its properties are determined by the tags which are +assigned to it. The priority of a tag can be modified by the ``path_Name +tag lower'' and ``pathName tag raise'' widget commands. + +

+If a cell has several tags associated with it that define the same +display options (eg - a title cell with specific row and cell tags), +then the options of the highest priority tag are used. If a particular +display option hasn't been specified for a particular tag, or if it is +specified as an empty string, then that option will not be used; the +next-highest-priority tag's option will be used instead. If no tag +specifies a particular display option, then the default style for the +widget will be used. + +

+Images are used for display purposes only. Editing in that cell will +still be enabled and any querying of the cell will show the text value +of the cell, regardless of the value of -showtext. + +

+

Embedded Windows

+ +

+There may be any number of embedded windows in a table widget (one per +cell), and any widget may be used as an embedded window (subject to the +usual rules for geometry management, which require the table window to +be the parent of the embedded window or a descendant of its parent). +The embedded window's position on the screen will be updated as the table +is modified or scrolled, and it will be mapped and unmapped as it +moves into and out of the visible area of the table widget. Each +embedded window occupies one cell's worth of space in the table widget, +and it is referred to by the index of the cell in the table. Windows +associated with the table widget are destroyed when the table widget is +destroyed. + +

+Windows are used for display purposes only. A value still exists for +that cell, but will not be shown unless the window is deleted in some +way. If the window is destroyed or lost by the table widget to another +geometry manager, then any data associated with it is lost (the cell it +occupied will no longer appear in window names). + +

+When an embedded window is added to a table widget with the window configure +widget command, several configuration options may be associated +with it. These options may be modified with later calls to the window +configure widget command. The following options are currently supported: + +

+

+ +
-create script
+
+NOT CURRENTLY SUPPORTED. Specifies a Tcl script that may +be evaluated to create the window for the annotation. If +no -window option has been specified for this cell then +this script will be evaluated when the cell is about to +be displayed on the screen. Script must create a window +for the cell and return the name of that window as its +result. If the cell's window should ever be deleted, the +script will be evaluated again the next time the cell is +displayed. + +

+ +
-background or -bg color
+
+Background color of the cell. If not specified, it uses +the table's default background. + +

+ +
-borderwidth or -bd pixelList
+
+Borderwidth of the cell, of the same format for the table, +but may also be empty to inherit the default table +borderwidth value (the default). + +

+ +
-padx pixels
+
+As defined in the Tk options man page. + +

+ +
-pady pixels
+
+As defined in the Tk options man page. + +

+ +
-relief relief
+
+The relief to use for the cell in which the window lies. +If not specified, it uses the table's default relief. + +

+ +
-sticky sticky
+
+Stickiness of the window inside the cell, as defined by +the grid command. + +

+ +
-window pathName
+
+Specifies the name of a window (widget) to display in the +annotation. It must exist before being specified here. +When an empty string is specified, if a window was displayed +it will cease to be managed by the table widget. + +

+
+ +

the Selection

+ +

+Table selections are available as type STRING. By default, the value +of the selection will be the values of the selected cells in nested Tcl +list form where each row is a list and each column is an element of a +row list. You can change the way this value is interpreted by setting +the -rowseparator and -colseparator options. For example, default +Excel format would be to set -rowseparator to `\n' and -colseparator to +`\t'. Changing these values affects both how the table sends out the +selection and reads in pasted data, ensuring that the table should +always be able to cut and paste to itself. It is possible to change +how pastes are handled by editing the table library procedure +tk_tablePasteHandler. This might be necessary if -selectioncommand is +set. + +

+

Row/Col Spanning

+ +

+Individual cells can span multiple rows and/or columns. This is done +via the spans command (see below for exact arguments). Cells in the +title area that span are not permitted to span beyond the title area, +and will be constrained accordingly. If the title area shrinks during +a configure, sanity checking will occur to ensure the above. You may +set spans on regular cells that extend beyond the defined row/col area. +These spans will not be constrained, so that when the defined row/col +area expands, the span will expand with it. + +

+When setting a span, checks are made as to whether the span would overlap +an already spanning or hidden cell. This is an error and it not +allowed. Spans can affect the overall speed of table drawing, although +not significantly. If spans are not used, then there is no performance +loss. + +

+Cells hidden by spanning cells still have valid data. This will be +seen during cut and paste operations that involve hidden cells, or +through direct access by a command like get or set. + +

+The drawing properties of spanning cells apply to only the visual area +of the cell. For example, if a cell is center justified over 5 +columns, then when viewing any portion of those columns, it will appear +centered in the visible area. The non-visible column area will not be +considered in the centering calculations. + +

+

Command Substitution

+ +

+The various option based commands that the table supports all support +the familiar Tk %-substitution model (see bind for more details). The +following %-sequences are recognized and substituted by the table widget: + +

+%c For SelectionCommand, it is the maximum number of columns in any +row in the selection. Otherwise it is the column of the triggered +cell. + +

+

+ +
%C
+
A convenience substitution for %r,%c. + +

+
+

+%i For SelectionCommand, it is the total number of cells in the +selection. For Command, it is 0 for a read (get) and 1 for a +write (set). Otherwise it is the current cursor position in the +cell. + +

+%r For SelectionCommand, it is the number of rows in the selection. +Otherwise it is the row of the triggered cell. + +

+%s For ValidateCommand, it is the current value of the cell being +validated. For SelectionCommand, it is the default value of the +selection. For BrowseCommand, it is the index of the last active +cell. For Command, it is empty for reads (get) and the current +value of the cell for writes (set). + +

+%S For ValidateCommand, it is the potential new value of the cell +being validated. For BrowseCommand, it is the index of the new +active cell. + +

+

+ +
%W
+
The pathname to the window for which the command was generated. + +

+
+ +

Widget Command

+ +

+The table command creates a new Tcl command whose name is pathName. +This command may be used to invoke various operations on the widget. +It has the following general form:
+ +pathName option ?arg arg ...?
+ +Option and the args determine the exact behavior of the command. + +

+The following commands are possible for table widgets: + +

+pathName activate index
+ +Sets the active cell to the one indicated by index. + +

+pathName bbox first ?last?
+ +It returns the bounding box for the specified cell (range) as a +4-tuple of x, y, width and height in pixels. It clips the box +to the visible portion, if any, otherwise an empty string is +returned. + +

+pathName border option args
+ +This command is a voodoo hack to implement border sizing for +tables. This is normally called through bindings, with the following +as valid options: + +

+pathName border mark x y ?row|col? +Records x and y and the row and/or column border under +that point in the table window, if any; used in conjunction +with later border dragto commands. Typically this +command is associated with a mouse button press in the +widget. If row or col is not specified, it returns a +tuple of both border indices (an empty item means no border). +Otherwise, just the specified item is returned. + +

+pathName border dragto x y
+ +This command computes the difference between its x and y +arguments and the x and y arguments to the last border +mark command for the widget. It then adjusts the previously +marked border by the difference. This command is +typically associated with mouse motion events in the widget, +to produce the effect of interactive border resizing. + +

+pathName cget option
+ +Returns the current value of the configuration option given by +option. Option may have any of the values accepted by the table +command. + +

+pathName clear option ?first? ?last?
+ +This command is a convenience routine to clear certain state +information managed by the table. first and last represent +valid table indices. If neither are specified, then the command +operates on the whole table. The following options are recognized: + +

+pathName clear cache ?first? ?last? +Clears the specified section of the cache, if the table +has been keeping one. + +

+pathName clear sizes ?first? ?last? +Clears the specified row and column areas of specific +height/width dimensions. When just one index is specified, +for example 2,0, that is interpreted as row 2 and +column 0. + +

+pathName clear tags ?first? ?last? +Clears the specified area of tags (all row, column and +cell tags). + +

+pathName clear all ?first? ?last? +Performs all of the above clear functions on the specified +area. + +

+pathName configure ?option? ?value option value ...? +Query or modify the configuration options of the widget. If no +option is specified, returns a list describing all of the available +options for pathName (see Tk_ConfigureInfo for information +on the format of this list). If option is specified with no +value, then the command returns a list describing the one named +option (this list will be identical to the corresponding sublist +of the value returned if no option is specified). If one or +more option-value pairs are specified, then the command modifies +the given widget option(s) to have the given value(s); in this +case the command returns an empty string. Option may have any +of the values accepted by the table command. + +

+pathName curselection ?value?
+ +With no arguments, it returns the sorted indices of the currently +selected cells. Otherwise it sets all the selected cells +to the given value. The set has no effect if there is no associated +Tcl array or the state is disabled. + +

+pathName curvalue ?value?
+ +If no value is given, the value of the cell being edited +(indexed by active) is returned, else it is set to the given +value. + +

+pathName delete option arg ?arg?
+ +This command is used to delete various things in a table. It +has several forms, depending on the option: + +

+pathName delete active index ?index? +Deletes text from the active cell. If only one index is +given, it deletes the character after that index, otherwise +it deletes from the first index to the second. +index can be a number, insert or end. + +

+pathName delete cols ?switches? index ?count? +Deletes count cols starting at (and including) col index. +The index will be constrained to the limits of the +tables. If count is negative, it deletes cols to the +left. Otherwise it deletes cols to the right. count +defaults to 1 (meaning just the column specified). At +the moment, spans are not adjusted with this action. +Optional switches are: + +

+

+ +
-holddimensions
+
+Causes the table cols to be unaffected by the +deletion (empty cols may appear). By default the +dimensions are adjusted by count. + +

+ +
-holdselection
+
+Causes the selection to be maintained on the +absolute cells values. Otherwise, the selection +will be cleared.. + +

+ +
-holdtags
+
+Causes the tags specified by the tag method to +not move along with the data. Also prevents specific +widths set by the width method from being +adjusted. By default, these tags are properly +adjusted. + +

+ +
-holdwindows
+
+Causes the embedded windows created with the win_dow +method to not move along with the data. By +default, these windows are properly adjusted. + +

+ +
-keeptitles
+
+Prevents title area cells from being changed. +Otherwise they are treated just like regular +cells and will move as specified. + +

+ +
--
+
Signifies the end of the switches. + +

+
+

+pathName delete rows ?switches? index ?count? +Deletes count rows starting at (and including) row index. +If count is negative, it deletes rows going up. Otherwise +it deletes rows going down. The selection will be +cleared. The switches are the same as those for column +deletion. + +

+pathName get first ?last?
+ +Returns the value of the cells specified by the table indices +first and (optionally) last in a list. + +

+pathName height ?row? ?value row value ...? +If no row is specified, returns a list describing all rows for +which a height has been set. If row is specified with no value, +it prints out the height of that row in characters (positive +number) or pixels (negative number). If one or more row-value +pairs are specified, then it sets each row to be that height in +lines (positive number) or pixels (negative number). If value +is default, then the row uses the default height, specified by +-rowheight. + +

+pathName hidden ?index? ?index ...?
+ +When called without args, it returns all the hidden cells (those +cells covered by a spanning cell). If one index is specified, +it returns the spanning cell covering that index, if any. If +multiple indices are specified, it returns 1 if all indices are +hidden cells, 0 otherwise. + +

+pathName icursor ?arg?
+ +With no arguments, prints out the location of the insertion cursor +in the active cell. With one argument, sets the cursor to +that point in the string. 0 is before the first character, you +can also use insert or end for the current insertion point or +the end of the text. If there is no active cell, or the cell or +table is disabled, this will return -1. + +

+pathName index index ?row|col?
+ +Returns the integer cell coordinate that corresponds to index in +the form row,col. If row or col is specified, then only the row +or column index is returned. + +

+pathName insert option arg arg
+ +This command is used to into various things into a table. It +has several forms, depending on the option: + +

+pathName insert active index value +The value is a text string which is inserted at the index +position of the active cell. The cursor is then positioned +after the new text. index can be a number, insert +or end. + +

+pathName insert cols ?switches? index ?count? +Inserts count cols starting at col index. If count is +negative, it inserts before the specified col. Otherwise +it inserts after the specified col. The selection will +be cleared. The switches are the same as those for column +deletion. + +

+pathName insert rows ?switches? index ?count? +Inserts count rows starting at row index. If count is +negative, it inserts before the specified row. Otherwise +it inserts after the specified row. The selection will +be cleared. The switches are the same as those for column +deletion. + +

+pathName reread
+ +Rereads the old contents of the cell back into the editing +buffer. Useful for a key binding when <Escape> is pressed to +abort the edit (a default binding). + +

+pathName scan option args
+ +This command is used to implement scanning on tables. It has +two forms, depending on option: + +

+pathName scan mark x y
+ +Records x and y and the current view in the table window; +used in conjunction with later scan dragto commands. +Typically this command is associated with a mouse button +press in the widget. It returns an empty string. + +

+pathName scan dragto x y.
+ +This command computes the difference between its x and y +arguments and the x and y arguments to the last scan mark +command for the widget. It then adjusts the view by 5 +times the difference in coordinates. This command is +typically associated with mouse motion events in the widget, +to produce the effect of dragging the list at high +speed through the window. The return value is an empty +string. + +

+pathName see index
+ +Adjust the view in the table so that the cell given by index is +positioned as the cell one off from top left (excluding title +rows and columns) if the cell is not currently visible on the +screen. The actual cell may be different to keep the screen +full. + +

+pathName selection option arg
+ +This command is used to adjust the selection within a table. It +has several forms, depending on option: + +

+pathName selection anchor index
+ +Sets the selection anchor to the cell given by index. +The selection anchor is the end of the selection that is +fixed while dragging out a selection with the mouse. The +index anchor may be used to refer to the anchor cell. + +

+pathName selection clear first ?last? +If any of the cells between first and last (inclusive) +are selected, they are deselected. The selection state +is not changed for cells outside this range. first may +be specified as all to remove the selection from all +cells. + +

+pathName selection includes index +Returns 1 if the cell indicated by index is currently +selected, 0 if it isn't. + +

+pathName selection set first ?last? +Selects all of the cells in the range between first and +last, inclusive, without affecting the selection state of +cells outside that range. + +

+pathName set ?row|col? index ?value? ?index value ...? +Sets the specified index to the associated value. Table validation +will not be triggered via this method. If row or col precedes +the list of index/value pairs, then the value is assumed +to be a Tcl list whose values will be split and set into the +subsequent columns (if row is specified) or rows (for col). For +example, set row 2,3 {2,3 2,4 2,5} will set 3 cells, from 2,3 to +2,5. The setting of cells is silently bounded by the known table +dimensions. + +

+pathName spans ?index? ?rows,cols index rows,cols ...? +This command is used to manipulate row/col spans. When called +with no arguments, all known spans are returned as a list of +tuples of the form {index span}. When called with only the +index, the span for that index only is returned, if any. Otherwise +an even number of index rows,cols pairs are used to set +spans. A span starts at the index and continues for the specified +number of rows and cols. Negative spans are not supported. +A span of 0,0 unsets any span on that cell. See EXAMPLES for +more info. + +

+pathName tag option ?arg arg ...?
+ +This command is used to manipulate tags. The exact behavior of +the command depends on the option argument that follows the tag +argument. cget, cell, and row|col complain about unknown tag +names. The following forms of the command are currently supported: + +

+pathName tag cell tagName ?index ...? +With no arguments, prints out the list of cells that use +the tag. Otherwise it sets the specified cells to use +the named tag, replacing any tag that may have been set +using this method before. If tagName is {}, the cells +are reset to the default tag. Tags added during -*tagcommand +evaluation do not register here. If tagName does +not exist, it will be created with the default options. + +

+pathName tag cget tagName option +This command returns the current value of the option +named option associated with the tag given by tagName. +Option may have any of the values accepted by the tag +configure widget command. + +

+pathName tag col tagName ?col ...? +With no arguments, prints out the list of cols that use +the tag. Otherwise it sets the specified columns to use +the named tag, replacing any tag that may have been set +using this method before. If tagName is {}, the cols are +reset to the default tag. Tags added during -coltagcommand +evaluation do not register here. If tagName does +not exist, it will be created with the default options. + +

+pathName tag configure tagName ?option? ?value? ?option value +...?
+ +This command is similar to the configure widget command +except that it modifies options associated with the tag +given by tagName instead of modifying options for the +overall table widget. If no option is specified, the +command returns a list describing all of the available +options for tagName (see Tk_ConfigureInfo for information +on the format of this list). If option is specified with +no value, then the command returns a list describing the +one named option (this list will be identical to the corresponding +sublist of the value returned if no option is +specified). If one or more option-value pairs are specified, +then the command modifies the given option(s) to +have the given value(s) in tagName; in this case the command +returns an empty string. See TAGS above for details +on the options available for tags. + +

+pathName tag delete tagName
+ +Deletes a tag. No error if the tag does not exist. + +

+pathName tag exists tagName
+ +Returns 1 if the named tag exists, 0 otherwise. + +

+pathName tag includes tagName index +Returns 1 if the specified index has the named tag, 0 +otherwise. + +

+pathName tag lower tagName ?belowThis? +Lower the priority of the named tag. If belowThis is not +specified, then the tag's priority is lowered to the bottom, +otherwise it is lowered to one below belowThis. + +

+pathName tag names ?pattern?
+ +If no pattern is specified, shows the names of all +defined tags. Otherwise the pattern is used as a glob +pattern to show only tags matching that pattern. Tag +names are returned in priority order (highest priority +tag first). + +

+pathName tag raise tagName ?aboveThis? +Raise the priority of the named tag. If aboveThis is not +specified, then the tag's priority is raised to the top, +otherwise it is raised to one above aboveThis. + +

+pathName tag row tagName ?row ...? +With no arguments, prints out the list of rows that use +the tag. Otherwise it sets the specified rows to use the +named tag, replacing any tag that may have been set using +this method before. If tagName is {}, the rows are reset +to use the default tag. Tags added during -rowtagcommand +evaluation do not register here. If tagName does not +exist, it will be created with the default options. + +

+pathName validate index
+ +Explicitly validates the specified index based on the current +-validatecommand and returns 0 or 1 based on whether the cell +was validated. + +

+pathName width ?col? ?value col value ...? +If no col is specified, returns a list describing all cols for +which a width has been set. If col is specified with no value, +it prints out the width of that col in characters (positive number) +or pixels (negative number). If one or more col-value +pairs are specified, then it sets each col to be that width in +characters (positive number) or pixels (negative number). If +value is default, then the col uses the default width, specified +by -colwidth. + +

+pathName window option ?arg arg ...?
+ +This command is used to manipulate embedded windows. The exact +behavior of the command depends on the option argument that follows +the window argument. The following forms of the command +are currently supported: + +

+pathName window cget index option +This command returns the current value of the option +named option associated with the window given by index. +Option may have any of the values accepted by the window +configure widget command. + +

+pathName window configure index ?option? ?value? ?option value +...?
+ +This command is similar to the configure widget command +except that it modifies options associated with the +embedded window given by index instead of modifying +options for the overall table widget. If no option is +specified, the command returns a list describing all of +the available options for index (see Tk_ConfigureInfo for +information on the format of this list). If option is +specified with no value, then the command returns a list +describing the one named option (this list will be identical +to the corresponding sublist of the value returned +if no option is specified). If one or more option-value +pairs are specified, then the command modifies the given +option(s) to have the given value(s) in index; in this +case the command returns an empty string. See EMBEDDED +WINDOWS above for details on the options available for +windows. + +

+pathName window delete index ?index ...? +Deletes an embedded window from the table. The associated +window will also be deleted. + +

+pathName window move indexFrom indexTo +Moves an embedded window from one cell to another. If a +window already exists in the target cell, it will be +deleted. + +

+pathName window names ?pattern?
+ +If no pattern is specified, shows the cells of all embedded +windows. Otherwise the pattern is used as a glob +pattern to show only cells matching that pattern. + +

+pathName xview args
+ +This command is used to query and change the horizontal position +of the information in the widget's window. It can take any of +the following forms: + +

+pathName xview
+ +Returns a list containing two elements. Each element is +a real fraction between 0 and 1; together they describe +the horizontal span that is visible in the window. For +example, if the first element is .2 and the second element +is .6, 20% of the table's text is off-screen to the +left, the middle 40% is visible in the window, and 40% of +the text is off-screen to the right. These are the same +values passed to scrollbars via the -xscrollcommand +option. + +

+pathName xview index
+ +Adjusts the view in the window so that the column given +by index is displayed at the left edge of the window. + +

+pathName xview moveto fraction
+ +Adjusts the view in the window so that fraction of the +total width of the table text is off-screen to the left. +fraction must be a fraction between 0 and 1. + +

+pathName xview scroll number what +This command shifts the view in the window left or right +according to number and what. Number must be an integer. +What must be either units or pages or an abbreviation of +one of these. If what is units, the view adjusts left or +right by number cells on the display; if it is pages then +the view adjusts by number screenfuls. If number is negative +then cells farther to the left become visible; if +it is positive then cells farther to the right become +visible. + +

+pathName yview ?args?
+ +This command is used to query and change the vertical position +of the text in the widget's window. It can take any of the following +forms: + +

+pathName yview
+ +Returns a list containing two elements, both of which are +real fractions between 0 and 1. The first element gives +the position of the table element at the top of the window, +relative to the table as a whole (0.5 means it is +halfway through the table, for example). The second element +gives the position of the table element just after +the last one in the window, relative to the table as a +whole. These are the same values passed to scrollbars +via the -yscrollcommand option. + +

+pathName yview index
+ +Adjusts the view in the window so that the row given by +index is displayed at the top of the window. + +

+pathName yview moveto fraction
+ +Adjusts the view in the window so that the element given +by fraction appears at the top of the window. Fraction +is a fraction between 0 and 1; 0 indicates the first +element in the table, 0.33 indicates the element +one-third the way through the table, and so on. + +

+pathName yview scroll number what +This command adjusts the view in the window up or down +according to number and what. Number must be an integer. +What must be either units or pages. If what is units, +the view adjusts up or down by number cells; if it is +pages then the view adjusts by number screenfuls. If +number is negative then earlier elements become visible; +if it is positive then later elements become visible. + +

+

Default Bindings

+ +

+The initialization creates class bindings that give the following +default behaviour: + +

+

+ +
[1]
+
Clicking Button-1 in a cell activates that cell. Clicking into +an already active cell moves the insertion cursor to the character +nearest the mouse. + +

+ +
[2]
+
Moving the mouse while Button-1 is pressed will stroke out a +selection area. Exiting while Button-1 is pressed causing scanning +to occur on the table along with selection. + +

+ +
[3]
+
Moving the mouse while Button-2 is pressed causes scanning to +occur without any selection. + +

+ +
[4]
+
Home moves the table to have the origin in view. + +

+ +
[5]
+
End moves the table to have the end cell in view. + +

+ +
[6]
+
Control-Home moves the table to the origin and activates that +cell. + +

+ +
[7]
+
Control-End moves the table to the end and activates that cell. + +

+ +
[8]
+
Shift-Control-Home extends the selection to the origin. + +

+ +
[9]
+
Shift-Control-End extends the selection to the end. + +

+ +
[10]
+
The left, right, up and down arrows move the active cell. + +

+ +
[11]
+
Shift-<arrow> extends the selection in that direction. + +

+ +
[12]
+
Control-leftarrow and Control-rightarrow move the insertion cursor +within the cell. + +

+ +
[13]
+
Control-slash selects all the cells. + +

+ +
[14]
+
Control-backslash clears selection from all the cells. + +

+
+

+[15] Backspace deletes the character before the insertion cursor in +the active cell. + +

+[16] Delete deletes the character after the insertion cursor in the +active cell. + +

+[17] Escape rereads the value of the active cell from the specified +data source, discarding any edits that have may been performed +on the cell. + +

+[18] Control-a moves the insertion cursor to the beginning of the +active cell. + +

+[19] Control-e moves the insertion cursor to the end of the active +cell. + +

+

+ +
[20]
+
Control-minus and Control-equals decrease and increase the width +of the column with the active cell in it. + +

+ +
[21]
+
Moving the mouse while Button-3 (the right button on Windows) is +pressed while you are over a border will cause interactive +resizing of that row and/or column to occur, based on the value +of -resizeborders. + +

+
+

+Some bindings may have slightly different behavior dependent on the +-selectionmode of the widget. + +

+If the widget is disabled using the -state option, then its view can +still be adjusted and cells can still be selected, but no insertion +cursor will be displayed and no cell modifications will take place. + +

+The behavior of tables can be changed by defining new bindings for +individual widgets or by redefining the class bindings. The default +bindings are either compiled in or read from a file expected to correspond +to: [lindex $tcl_pkgPath 0]/Tktable<version>/tkTable.tcl". + +

+

Performance Issues

+ +

+The number of rows and columns or a table widget should not significantly +affect the speed of redraw. Recalculation and redraw of table +parameters and cells is restricted as much as possible. + +

+The display cell with the insert cursor is redrawn each time the cursor +blinks, which causes a steady stream of graphics traffic. Set the +-insertofftime option to 0 avoid this. The use of a -command with the +table without a cache can cause significant slow-down, as the command +is called once for each request of a cell value. + +

+

Examples

+ +

+Set the topleft title area to be one spanning cell. This overestimates +both row and column span by one, but the command does all the constraining +for us.
+ +$table span [$table cget -roworigin],[$table cget -colorigin] [$table cget -titlerows],[$table cget -titlecols] +Force a table window refresh (useful for the slight chance that a bug +in the table is not causing proper refresh): +$table configure -padx [$table cget -padx] + +

+

Keywords

+ +

+table, widget, extension +

+ +


+Table of Contents

+

+ + diff --git a/tktable/doc/tkTable.n b/tktable/doc/tkTable.n new file mode 100644 index 0000000..7b7b432 --- /dev/null +++ b/tktable/doc/tkTable.n @@ -0,0 +1,1432 @@ +'\" +'\" The definitions below are for supplemental macros used in Tcl/Tk +'\" manual entries. +'\" +'\" RCS: @(#) $Id: tkTable.n,v 1.13 2008/11/14 22:51:30 hobbs Exp $ +'\" +'\" .AP type name in/out ?indent? +'\" Start paragraph describing an argument to a library procedure. +'\" type is type of argument (int, etc.), in/out is either "in", "out", +'\" or "in/out" to describe whether procedure reads or modifies arg, +'\" and indent is equivalent to second arg of .IP (shouldn't ever be +'\" needed; use .AS below instead) +'\" +'\" .AS ?type? ?name? +'\" Give maximum sizes of arguments for setting tab stops. Type and +'\" name are examples of largest possible arguments that will be passed +'\" to .AP later. If args are omitted, default tab stops are used. +'\" +'\" .BS +'\" Start box enclosure. From here until next .BE, everything will be +'\" enclosed in one large box. +'\" +'\" .BE +'\" End of box enclosure. +'\" +'\" .CS +'\" Begin code excerpt. +'\" +'\" .CE +'\" End code excerpt. +'\" +'\" .VS ?br? +'\" Begin vertical sidebar, for use in marking newly-changed parts +'\" of man pages. If an argument is present, then a line break is +'\" forced before starting the sidebar. +'\" +'\" .VE +'\" End of vertical sidebar. +'\" +'\" .DS +'\" Begin an indented unfilled display. +'\" +'\" .DE +'\" End of indented unfilled display. +'\" +'\" .SO +'\" Start of list of standard options for a Tk widget. The +'\" options follow on successive lines, in four columns separated +'\" by tabs. +'\" +'\" .SE +'\" End of list of standard options for a Tk widget. +'\" +'\" .OP cmdName dbName dbClass +'\" Start of description of a specific option. cmdName gives the +'\" option's name as specified in the class command, dbName gives +'\" the option's name in the option database, and dbClass gives +'\" the option's class in the option database. +'\" +'\" .UL arg1 arg2 +'\" Print arg1 underlined, then print arg2 normally. +'\" +'\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +'\" # Start an argument description +.de AP +.ie !'\\$4'' .TP \\$4 +.el \{\ +. ie !'\\$2'' .TP \\n()Cu +. el .TP 15 +.\} +.ie !'\\$3'' \{\ +.ta \\n()Au \\n()Bu +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !'\\$2'' \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +'\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !'\\$1'' .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !'\\$2'' .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +'\" # BS - start boxed text +'\" # ^y = starting y location +'\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +'\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +'\" # VS - start vertical sidebar +'\" # ^Y = starting y location +'\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !'\\$1'' .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +'\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +'\" # Special macro to handle page bottom: finish off current +'\" # box/sidebar if in box/sidebar mode, then invoked standard +'\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +'\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +'\" # DE - end display +.de DE +.fi +.RE +.sp +.. +'\" # SO - start of list of standard options +.de SO +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 4c 8c 12c +.ft B +.. +'\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\fBoptions\\fR manual entry for details on the standard options. +.. +'\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +'\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +'\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.TH table n 2.8 Tk "Tk Table Extension" +.HS table tk +.BS +.SH NAME +table \- Create and manipulate tables +.SH SYNOPSIS +\fBtable\fI \fIpathName \fR?\fIoptions\fR? +.SO +\-anchor \-background \-cursor +\-exportselection \-font \-foreground +\-highlightbackground \-highlightcolor \-highlightthickness +\-insertbackground \-insertborderwidth \-insertofftime +\-insertontime \-insertwidth \-invertselected +\-relief \-takefocus \-xscrollcommand +\-yscrollcommand +.SE + +.SH "WIDGET-SPECIFIC OPTIONS" +.OP \-autoclear autoClear AutoClear +A boolean value which specifies whether the first keypress in a cell will +delete whatever text was previously there. Defaults to 0. +.OP \-bordercursor borderCursor Cursor +Specifies the name of the cursor to show when over borders, a visual +indication that interactive resizing is allowed (it is thus affect by +the value of \-resizeborders). Defaults to \fIcrosshair\fR. +.OP "\-borderwidth or \-bd" borderWidth BorderWidth +Specifies a non-negative pixel value or list of values indicating the width +of the 3-D border to draw on interior table cells (if such a border is +being drawn; the \fBrelief\fR option typically determines this). If one +value is specified, a rectangle of this width will be drawn. If two values +are specified, then only the left and right edges of the cell will have +borders. If four values are specified, then the values correspond to the +{left right top bottom} edges. This can be overridden by the a tag's +borderwidth option. It can also be affected by the defined +\fB\-drawmode\fR for the table. Each value in the list must have one of +the forms acceptable to \fBTk_GetPixels\fR. +.OP "\-browsecommand or \-browsecmd" browseCommand BrowseCommand +Specifies a command which will be evaluated anytime the active cell changes. +It uses the %\-substition model described in COMMAND SUBSTITUTION below. +Any changes to the active cell while the command is running are ignored to +prevent recursion. +.OP \-cache cache Cache +A boolean value that specifies whether an internal cache of the table +contents should be kept. This greatly enhances speed performance when used +with \fB\-command\fR but uses extra memory. Can maintain state when both +\fB\-command\fR and \fB\-variable\fR are empty. The cache is automatically +flushed whenever the value of \fB\-cache\fR or \fB\-variable\fR changes, +otherwise you have to explicitly call \fBclear\fR on it. Defaults to off. +.OP \-colorigin colOrigin Origin +Specifies what column index to interpret as the leftmost column in the table. +This value is used for user indices in the table. Defaults to 0. +.OP \-cols cols Cols +Number of cols in the table. Defaults to 10. +.OP \-colseparator colSeparator Separator +Specifies a separator character that will be interpreted as the column +separator when cutting or pasting data in a table. By default, columns +are separated as elements of a tcl list. +.OP \-colstretchmode colStretchMode StretchMode +Specifies one of the following stretch modes for columns to fill extra +allocated window space: +.RS +.TP +\fBnone\fR +Columns will not stretch to fill the assigned window space. If the columns +are too narrow, there will be a blank space at the right of the table. This +is the default. +.TP +\fBunset\fR +Only columns that do not have a specific width set will be stretched. +.TP +\fBall\fR +All columns will be stretched by the same number of pixels to fill the +window space allocated to the table. This mode can interfere with +interactive border resizing which tries to force column width. +.TP +\fBlast\fR +The last column will be stretched +to fill the window space allocated to the table. +.TP +\fBfill\fR (only valid for \fB\-rowstretch\fR currently) +The table will get more or less columns according to the window +space allocated to the table. This mode has numerous quirks and +may disappear in the future. +.RE +.OP \-coltagcommand colTagCommand TagCommand +Provides the name of a procedure that will be evaluated by the widget to +determine the tag to be used for a given column. When displaying a cell, +the table widget will first check to see if a tag has been defined using the +\fBtag col\fR widget method. If no tag is found, it will evaluate the named +procedure passing the column number in question as the sole argument. The +procedure is expected to return the name of a tag to use, or a null string. +Errors occurring during the evaluation of the procedure, or the return of an +invalid tag name are silently ignored. +.OP \-colwidth colWidth ColWidth +Default column width, interpreted as characters in the default font when +the number is positive, or pixels if it is negative. Defaults to 10. +.OP \-command command Command +Specified a command to use as a procedural interface to cell values. +If \fB\-usecommand\fR is true, this command will be used instead of any +reference to the \fB\-variable\fR array. When retrieving cell values, +the return value of the command is used as the value for the cell. +It uses the %\-substition model described in COMMAND SUBSTITUTION below. +.OP \-drawmode drawMode DrawMode +Sets the table drawing mode to one of the following options: +.RS +.TP +\fBslow\fR +The table is drawn to an offscreen pixmap using the Tk bordering functions +(double-buffering). This means there will be no flashing, but this mode is +slow for larger tables. +.TP +\fBcompatible\fR +The table is drawn directly to the screen using the Tk border functions. +It is faster, but the screen may flash on update. This is the default. +.TP +\fBfast\fR +The table is drawn directly to the screen and the borders are done with +fast X calls, so they are always one pixel wide only. As a side effect, it +restricts \fB\-borderwidth\fR to a range of 0 or 1. This mode provides +best performance for large tables, but can flash on redraw and is not 100% +Tk compatible on the border mode. +.TP +\fBsingle\fR +The table is drawn to the screen as in fast mode, but only single pixel +lines are drawn (not square borders). +.RE +.OP \-ellipsis ellipsis Ellipsis +This specifies a string to display at the end of a line that would be +clipped by its cell, like ``...''. An ellipsis will be displayed only +on non-wrapping, non-multiline cells that would be clipped. The ellipsis +will display on the left for east anchored cells, otherwise it displays +on the right. +Defaults to "" (no ellipsis). +.OP \-flashmode flashMode FlashMode +A boolean value which specifies whether cells should flash when their value +changes. The table tag \fBflash\fR will be applied to these cells for the +duration specified by \fB\-flashtime\fR. Defaults to 0. +.OP \-flashtime flashTime FlashTime +The amount of time, in 1/4 second increments, for which a cell should flash +when its value has changed. \fB\-flashmode\fR must be on. Defaults to 2. +.OP \-height height Height +Specifies the desired height for the window, in rows. +If zero or less, then the desired height for the window is made just +large enough to hold all the rows in the table. The height can be +further limited by \fB\-maxheight\fR. +.OP \-invertselected invertSelected InvertSelected +Specifies whether the foreground and background of an item should simply +have their values swapped instead of merging the \fIsel\fR tag options +when the cell is selected. Defaults to 0 (merge \fIsel\fR tag). +.OP \-ipadx ipadX Pad +A pixel value specifying the internal offset X padding for text in a cell. +This value does not grow the size of the cell, it just causes the text to +be drawn further from the cell border. It only affects one side (depending +on anchor). Defaults to 0. See \fB\-padx\fR for an alternate padding +style. +.OP \-ipady ipadY Pad +A pixel value specifying the internal offset Y padding for text in a cell. +This value does not grow the size of the cell, it just causes the text to +be drawn further from the cell border. It only affects one side (depending +on anchor). Defaults to 0. See \fB\-pady\fR for an alternate padding +style. +.OP \-justify justify Justify +How to justify multi\-line text in a cell. +It must be one of \fBleft\fR, \fBright\fR, or \fBcenter\fR. +Defaults to left. +.OP \-maxheight maxHeight MaxHeight +The max height in pixels that the window will request. Defaults to 600. +.OP \-maxwidth maxWidth MaxWidth +The max width in pixels that the window will request. Defaults to 800. +.OP \-multiline multiline Multiline +Specifies the default setting for the multiline tag option. Defaults to 1. +.OP \-padx padX Pad +A pixel value specifying the offset X padding for a cell. This value +causes the default size of the cell to increase by two times the value (one +for each side), unless a specific pixel size is chosen for the cell with +the \fBwidth\fR command. This will force an empty area on the left and +right of each cell edge. This padding affects all types of data in the +cell. Defaults to 0. See \fB\-ipadx\fR for an alternate padding style. +.OP \-pady padY Pad +A pixel value specifying the offset Y padding for a cell. This value +causes the default size of the cell to increase by two times the value (one +for each side), unless a specific pixel size is chosen for the cell with +the \fBheight\fR command. This will force an empty area on the top and +bottom of each cell edge. This padding affects all types of data in the +cell. Defaults to 0. See \fB\-ipadx\fR for an alternate padding style. +.OP \-resizeborders resizeBorders ResizeBorders +Specifies what kind of interactive border resizing to allow, must be one of +row, col, both (default) or none. +.OP \-rowheight rowHeight RowHeight +Default row height, interpreted as lines in the default font when +the number is positive, or pixels if it is negative. Defaults to 1. +.OP \-roworigin rowOrigin Origin +Specifies what row index to interpret as the topmost row in the table. +This value is used for user indices in the table. Defaults to 0. +.OP \-rows rows Rows +Number of rows in the table. Defaults to 10. +.OP \-rowseparator rowSeparator Separator +Specifies a separator character that will be interpreted as the row +separator when cutting or pasting data in a table. By default, rows +are separated as tcl lists. +.OP \-rowstretchmode rowStretchMode StretchMode +Specifies the stretch modes for rows to fill extra +allocated window space. See \fB\-colstretchmode\fR for valid options. +.OP \-rowtagcommand rowTagCommand TagCommand +Provides the name of a procedure that can evaluated by the widget to +determine the tag to be used for a given row. The procedure must be +defined by the user to accept a single argument (the row number), and +return a tag name or null string. This operates in a similar manner as +\fB\-coltagcommand\fR, except that it applies to row tags. +.OP "\-selectioncommand or \-selcmd" selectionCommand SelectionCommand +Specifies a command to evaluate when the selection is retrieved from a +table via the selection mechanism (ie: evaluating ``\fBselection get\fR''). +The return value from this command will become the string passed on by the +selection mechanism. It uses the %\-substition model described in COMMAND +SUBSTITUTION below. If an error occurs, a Tcl background error is +generated and nothing is returned. +.OP \-selectmode selectMode SelectMode +Specifies one of several styles for manipulating the selection. The value +of the option may be arbitrary, but the default bindings expect it to be +either \fBsingle\fR, \fBbrowse\fR, \fBmultiple\fR, or \fBextended\fR; the +default value is \fBbrowse\fR. These styles are like those for the Tk +listbox, except expanded for 2 dimensions. +.OP \-selecttitle selectTitles SelectTitles +Specifies whether title cells should be allowed in the selection. +Defaults to 0 (disallowed). +.OP \-selecttype selectType SelectType +Specifies one of several types of selection for the table. The value of the +option may be one of \fBrow\fR, \fBcol\fR, \fBcell\fR, or \fBboth\fR +(meaning \fBrow && col\fR); the default value is \fBcell\fR. These types +define whether an entire row/col is affected when a cell's selection is +changed (set or clear). +.OP \-sparsearray sparseArray SparseArray +A boolean value that specifies whether an associated Tcl array should be +kept as a sparse array (1, the default) or as a full array (0). If true, +then cell values that are empty will be deleted from the array (taking +less memory). If false, then all values in the array will be maintained. +.OP \-state state State +Specifies one of two states for the entry: \fBnormal\fR or \fBdisabled\fR. +If the table is disabled then the value may not be changed using widget +commands and no insertion cursor will be displayed, even if the input focus +is in the widget. Also, all insert or delete methods will be ignored. +Defaults to \fBnormal\fR. +.OP \-titlecols titleCols TitleCols +Number of columns to use as a title area. Defaults to 0. +.OP \-titlerows titleRows TitleRows +Number of rows to use as a title area. Defaults to 0. +.OP \-usecommand useCommand UseCommand +A boolean value which specifies whether to use the \fBcommand\fR option. +This value sets itself to zero if \fBcommand\fR is used and returns an error. +Defaults to 1 (will use \fBcommand\fR if specified). +.OP \-validate validate Validate +A boolean specifying whether validation should occur for the active buffer. +Defaults to 0. +.OP "\-validatecommand or \-vcmd" validateCommand ValidateCommand +Specifies a command to execute when the active cell is edited. This command +is expected to return a Tcl boolean. If it returns true, then it is assumed +the new value is OK, otherwise the new value is rejected (the edition will +not take place). Errors in this command are handled in the background. It +uses the %\-substition model described in COMMAND SUBSTITUTION below. +.OP \-variable variable Variable +Global Tcl array variable to attach to the table's C array. It will be +created if it doesn't already exist or is a simple variable. Keys used by +the table in the array are of the form \fIrow\fR,\fIcol\fR for cells and +the special key \fIactive\fR which contains the value of the active cell +buffer. The Tcl array is managed as a sparse array (the table does not +require that all valid indices have values). No stored value for an index is +equivalent to the empty string, and clearing a cell will remove that index +from the Tcl array, unless the \fB\-sparsearray\fR options is set to 0. +.OP \-width width Width +Specifies the desired width for the window, in columns. +If zero or less, then the desired width for the window is made just +large enough to hold all the columns in the table. The width can be +further limited by \fB\-maxwidth\fR. +.OP \-wrap wrap Wrap +Specifies the default wrap value for tags. Defaults to 0. +.BE + +.SH DESCRIPTION +.PP +The \fBtable\fR command creates a 2\-dimensional grid of cells. The table +can use a Tcl array variable or Tcl command for data storage and retrieval, +as well as optionally cache data in memory for speed. One of these data +sources \fImust\fR be configured before any data is retained by the table. +The widget has an active cell, the contents of which can be edited (when +the state is normal). The widget supports a default style for the cells +and also multiple \fItags\fR, which can be used to change the style of a +row, column or cell (see TAGS for details). A cell \fIflash\fR can be set +up so that changed cells will change color for a specified amount of time +("blink"). Cells can have embedded images or windows, as described in +TAGS and "EMBEDDED WINDOWS" respectively. +.PP +One or more cells may be selected as described below. If a table is +exporting its selection (see \fB\-exportselection\fR option), then it will +observe the standard X11 protocols for handling the selection. See THE +SELECTION for details. +.PP +It is not necessary for all the cells to be displayed in the table window at +once; commands described below may be used to change the view in the window. +Tables allow scrolling in both directions using the standard +\fB\-xscrollcommand\fR and \fB\-yscrollcommand\fR options. They also support +scanning, as described below. +.PP +In order to obtain good performance, the table widget supports multiple +drawing modes, two of which are fully Tk compatible. + +.SH "INITIALIZATION" +.PP +When the \fBtable\fR command is loaded into an interpreter, a built-in +Tcl command, \fBtkTableInit\fR, is evaluated. This will search for the +appropriate table binding init file to load. The directories searched +are those in \fI$tcl_pkgPath\fR, both with Tktable(version) appended and +without, \fI$tk_library\fR and \fI[pwd]\fR (the current directory). You +can also define an \fI$env(TK_TABLE_LIBRARY)\fR to head this search list. +By default, the file searched for is called \fBtkTable.tcl\fR, but this +can be overridden by setting \fI$env(TK_TABLE_LIBRARY_FILE)\fR. +.PP +This entire init script can be overridden by providing your own +\fBtkTableInit\fR procedure before the library is loaded. Otherwise, the +aforementioned \fIenv(TK_TABLE_LIBRARY)\fR variable will be set with the +directory in which \fI$env(TK_TABLE_LIBRARY_FILE)\fR was found. + +.SH "INDICES" +.PP +Many of the widget commands for tables take one or more indices as arguments. +An index specifies a particular cell of the table, in any of +the following ways: +.TP 12 +\fInumber,number\fR +Specifies the cell as a numerical index of row,col which corresponds to the +index of the associated Tcl array, where \fB\-roworigin,\-colorigin\fR +corresponds to the first cell in the table (0,0 by default). The values +for row and column will be constrained to actual values in the table, +which means a valid cell is always found. +.TP 12 +\fBactive\fR +Indicates the cell that has the location cursor. +It is specified with the \fBactivate\fR widget command. +.TP 12 +\fBanchor\fR +Indicates the anchor point for the selection, which is set with the +\fBselection anchor\fR widget command. +.TP 12 +\fBbottomright\fR +Indicates the bottom\-rightmost cell visible in the table. +.TP 12 +\fBend\fR +Indicates the bottom right cell of the table. +.TP 12 +\fBorigin\fR +Indicates the top\-leftmost editable cell of the table, not necessarily +in the display. This takes into account the user specified origin and +title area. +.TP 12 +\fBtopleft\fR +Indicates the top\-leftmost editable cell visible in the table (this +excludes title cells). +.TP 12 +\fB@\fIx\fB,\fIy\fR +Indicates the cell that covers the point in the table window +specified by \fIx\fR and \fIy\fR (in pixel coordinates). If no +cell covers that point, then the closest cell to that +point is used. +.LP +In the widget command descriptions below, arguments named \fIindex\fR, +\fIfirst\fR, and \fIlast\fR always contain text indices in one of +the above forms. + +.SH TAGS +.PP +A tag is a textual string that is associated with zero or more rows, +columns or cells in a table. Tags may contain arbitrary characters, but it +is probably best to avoid using names which look like indices to reduce +coding confusion. A tag can apply to an entire row or column, or just a +single cell. There are several permanent tags in each table that can be +configured by the user and will determine the attributes for special cells: +.RS +.TP 10 +\fBactive\fR +This tag is given to the \fIactive\fR cell +.TP 10 +\fBflash\fR +If flash mode is on, this tag is given to any recently +edited cells. +.TP 10 +\fBsel\fR +This tag is given to any selected cells. +.TP 10 +\fBtitle\fR +This tag is given to any cells in the title rows and columns. This +tag has \fB\-state\fR \fIdisabled\fR by default. +.RE +.PP +Tags control the way cells are displayed on the screen. Where appropriate, +the default for displaying cells is determined by the options for the table +widget. However, display options may be associated with individual tags +using the ``\fIpathName \fBtag configure\fR'' widget command. If a cell, +row or column has been tagged, then the display options associated with the +tag override the default display style. The following options are +currently supported for tags: +.RS +.TP +\fB\-anchor\fR \fIanchor\fR +Anchor for item in the cell space. +.TP +\fB\-background\fR or \fB\-bg\fR \fIcolor\fR +Background color of the cell. +.TP +\fB\-borderwidth\fR or \fB\-bd\fR \fIpixelList\fR +Borderwidth of the cell, of the same format for the table, but may also +be empty to inherit the default table borderwidth value (the default). +.TP +\fB\-ellipsis\fR \fIstring\fR +String to display at the end of a line that would be clipped by its cell, +like ``...''. An ellipsis will be displayed only +on non-wrapping, non-multiline cells that would be clipped. The ellipsis +will display on the left for east anchored cells, otherwise it displays +on the right. +.TP +\fB\-font\fR \fIfontName\fR +Font for text in the cell. +.TP +\fB\-foreground\fR or \fB\-fg\fR \fIcolor\fR +Foreground color of the cell. +.TP +\fB\-justify\fR \fIjustify\fR +How to justify multi\-line text in a cell. +It must be one of \fBleft\fR, \fBright\fR, or \fBcenter\fR. +.TP +\fB\-image\fR \fIimageName\fR +An image to display in the cell instead of text. +.TP +\fB\-multiline\fR \fIboolean\fR +Whether to display text with newlines on multiple lines. +.TP +\fB\-relief\fR \fIrelief\fR +The relief for the cell. May be the empty string to cause this tag to +not disturb the value. +.TP +\fB\-showtext\fR \fIboolean\fR +Whether to show the text over an image. +.TP +\fB\-state\fR \fIstate\fR +The state of the cell, to allow for certain cells to be disabled. +This prevents the cell from being edited by the \fIinsert\fR or \fIdelete\fR +methods, but a direct \fIset\fR will not be prevented. +.TP +\fB\-wrap\fR \fIboolean\fR +Whether characters should wrap in a cell that is not wide enough. +.RE +.PP +A priority order is defined among tags based on creation order (first +created tag has highest default priority), and this order is used in +implementing some of the tag\-related functions described below. When a cell +is displayed, its properties are determined by the tags which are assigned +to it. The priority of a tag can be modified by the ``\fIpathName \fBtag +lower\fR'' and ``\fIpathName \fBtag raise\fR'' widget commands. +.PP +If a cell has several tags associated with it that define the same display +options (eg - a \fBtitle\fR cell with specific \fBrow\fR and \fBcell\fR +tags), then the options of the highest priority tag are used. If a +particular display option hasn't been specified for a particular tag, or if +it is specified as an empty string, then that option will not be used; the +next\-highest\-priority tag's option will be used instead. If no tag +specifies a particular display option, then the default style for the +widget will be used. +.PP +Images are used for display purposes only. Editing in that cell will still +be enabled and any querying of the cell will show the text value of the cell, +regardless of the value of \fB\-showtext\fR. + +.SH "EMBEDDED WINDOWS" +.PP +There may be any number of embedded windows in a table widget (one per +cell), and any widget may be used as an embedded window (subject to the +usual rules for geometry management, which require the table window to be +the parent of the embedded window or a descendant of its parent). The +embedded window's position on the screen will be updated as the table is +modified or scrolled, and it will be mapped and unmapped as it moves into +and out of the visible area of the table widget. Each embedded window +occupies one cell's worth of space in the table widget, and it is referred +to by the index of the cell in the table. Windows associated with the +table widget are destroyed when the table widget is destroyed. +.PP +Windows are used for display purposes only. A value still exists for that +cell, but will not be shown unless the window is deleted in some way. If +the window is destroyed or lost by the table widget to another geometry +manager, then any data associated with it is lost (the cell it occupied +will no longer appear in \fBwindow names\fR). +.PP +When an embedded window is added to a table widget with the window +configure widget command, several configuration options may be associated +with it. These options may be modified with later calls to the window +configure widget command. The following options are currently supported: +.RS +.TP +\fB\-create \fIscript\fR +NOT CURRENTLY SUPPORTED. Specifies a Tcl script that may be evaluated to +create the window for the annotation. If no \-window option has been +specified for this cell then this script will be evaluated when the +cell is about to be displayed on the screen. Script must create a +window for the cell and return the name of that window as its result. +If the cell's window should ever be deleted, the script will be evaluated +again the next time the cell is displayed. +.TP +\fB\-background\fR or \fB\-bg\fR \fIcolor\fR +Background color of the cell. If not +specified, it uses the table's default background. +.TP +\fB\-borderwidth\fR or \fB\-bd\fR \fIpixelList\fR +Borderwidth of the cell, of the same format for the table, but may also +be empty to inherit the default table borderwidth value (the default). +.TP +\fB\-padx \fIpixels\fR +As defined in the Tk options man page. +.TP +\fB\-pady \fIpixels\fR +As defined in the Tk options man page. +.TP +\fB\-relief \fIrelief\fR +The relief to use for the cell in which the window lies. If not +specified, it uses the table's default relief. +.TP +\fB\-sticky \fIsticky\fR +Stickiness of the window inside the cell, as defined by the \fBgrid\fR command. +.TP +\fB\-window \fIpathName\fR +Specifies the name of a window (widget) to display in the annotation. It +must exist before being specified here. When an empty string is specified, +if a window was displayed it will cease to be managed by the table widget. +.RE + +.SH "THE SELECTION" +.PP +Table selections are available as type STRING. By default, the value of +the selection will be the values of the selected cells in nested Tcl list +form where each row is a list and each column is an element of a row list. +You can change the way this value is interpreted by setting the +\fB\-rowseparator\fR and \fB\-colseparator\fR options. For example, +default Excel format would be to set \fB\-rowseparator\fR to '\\n' and +\fB\-colseparator\fR to '\\t'. Changing these values affects both how the +table sends out the selection and reads in pasted data, ensuring that the +table should always be able to cut and paste to itself. It is possible to +change how pastes are handled by editing the table library procedure +\fBtk_tablePasteHandler\fR. This might be necessary if +\fB\-selectioncommand\fR is set. + +.SH "ROW/COL SPANNING" +.PP +Individual cells can span multiple rows and/or columns. This is done +via the \fBspans\fR command (see below for exact arguments). Cells in +the title area that span are not permitted to span beyond the title area, +and will be constrained accordingly. If the title area shrinks during a +configure, sanity checking will occur to ensure the above. You may set +spans on regular cells that extend beyond the defined row/col area. These +spans will not be constrained, so that when the defined row/col area +expands, the span will expand with it. +.PP +When setting a span, checks are made as to whether the span would overlap +an already spanning or hidden cell. This is an error and it not allowed. +Spans can affect the overall speed of table drawing, although not +significantly. If spans are not used, then there is no performance loss. +.PP +Cells \fIhidden\fR by spanning cells still have valid data. This will +be seen during cut and paste operations that involve hidden cells, or +through direct access by a command like \fBget\fR or \fBset\fR. +.PP +The drawing properties of spanning cells apply to only the visual area +of the cell. For example, if a cell is center justified over 5 columns, +then when viewing any portion of those columns, it will appear centered +in the visible area. The non-visible column area will not be considered +in the centering calculations. + +.SH "COMMAND SUBSTITUTION" +.PP + +The various option based commands that the table supports all support the +familiar Tk %\-substitution model (see \fBbind\fR for more details). The +following %\-sequences are recognized and substituted by the table widget: +.TP 5 +\fB%c\fR +For \fBSelectionCommand\fR, it is the maximum number of columns in any +row in the selection. Otherwise it is the column of the triggered cell. +.TP 5 +\fB%C\fR +A convenience substitution for \fI%r\fR,\fI%c\fR. +.TP 5 +\fB%i\fR +For \fBSelectionCommand\fR, it is the total number of cells in the selection. +For \fBCommand\fR, it is 0 for a read (get) and 1 for a write (set). +Otherwise it is the current cursor position in the cell. +.TP 5 +\fB%r\fR +For \fBSelectionCommand\fR, it is the number of rows in the selection. +Otherwise it is the row of the triggered cell. +.TP 5 +\fB%s\fR +For \fBValidateCommand\fR, it is the current value of the cell being validated. +For \fBSelectionCommand\fR, it is the default value of the selection. +For \fBBrowseCommand\fR, it is the index of the last active cell. +For \fBCommand\fR, it is empty for reads (get) and the current value of the +cell for writes (set). +.TP 5 +\fB%S\fR +For \fBValidateCommand\fR, it is the potential new value of the cell +being validated. +For \fBBrowseCommand\fR, it is the index of the new active cell. +.TP 5 +\fB%W\fR +The pathname to the window for which the command was generated. +.LP + +.SH "WIDGET COMMAND" +.PP +The \fBtable\fR command creates a new Tcl command whose +name is \fIpathName\fR. This command may be used to invoke various +operations on the widget. It has the following general form: +.CS +\fIpathName option \fR?\fIarg arg ...\fR? +.CE +\fIOption\fR and the \fIarg\fRs +determine the exact behavior of the command. +.PP +The following commands are possible for \fBtable\fR widgets: +.TP +\fIpathName \fBactivate\fR \fIindex\fR +Sets the active cell to the one indicated by \fIindex\fR. +.TP +\fIpathName \fBbbox\fR \fIfirst\fR ?\fIlast\fR? +It returns the bounding box for the specified cell (range) as a 4\-tuple of +x, y, width and height in pixels. It clips the box to the visible portion, +if any, otherwise an empty string is returned. +.TP +\fIpathName \fBborder\fR \fIoption args\fR +This command is a voodoo hack to implement border sizing for tables. +This is normally called through bindings, with the following as valid +options: +.RS +.TP +\fIpathName \fBborder mark\fR \fIx y\fR ?\fIrow|col\fR? +Records \fIx\fR and \fIy\fR and the row and/or column border under that +point in the table window, if any; used in conjunction with later \fBborder +dragto\fR commands. Typically this command is associated with a mouse +button press in the widget. If \fIrow\fR or \fIcol\fR is not specified, it +returns a tuple of both border indices (an empty item means no border). +Otherwise, just the specified item is returned. +.TP +\fIpathName \fBborder dragto\fR \fIx y\fR +This command computes the difference between its \fIx\fR and \fIy\fR +arguments and the \fIx\fR and \fIy\fR arguments to the last \fBborder +mark\fR command for the widget. It then adjusts the previously marked +border by the difference. This command is typically associated with mouse +motion events in the widget, to produce the effect of interactive border +resizing. +.RE +.TP +\fIpathName \fBcget\fR \fIoption\fR +Returns the current value of the configuration option given +by \fIoption\fR. \fIOption\fR may have any of the values accepted +by the \fBtable\fR command. +.TP +\fIpathName \fBclear\fR \fIoption\fR ?\fIfirst\fR? ?\fIlast\fR? +This command is a convenience routine to clear certain state information +managed by the table. \fIfirst\fR and \fIlast\fR represent valid table +indices. If neither are specified, then the command operates on the +whole table. The following options are recognized: +.RS +.TP +\fIpathName \fBclear cache\fR ?\fIfirst\fR? ?\fIlast\fR? +Clears the specified section of the cache, if the table has been +keeping one. +.TP +\fIpathName \fBclear sizes\fR ?\fIfirst\fR? ?\fIlast\fR? +Clears the specified row and column areas of specific height/width +dimensions. When just one index is specified, for example \fB2,0\fR, +that is interpreted as row 2 \fBand\fR column 0. +.TP +\fIpathName \fBclear tags\fR ?\fIfirst\fR? ?\fIlast\fR? +Clears the specified area of tags (all row, column and cell tags). +.TP +\fIpathName \fBclear all\fR ?\fIfirst\fR? ?\fIlast\fR? +Performs all of the above clear functions on the specified area. +.RE +.TP +\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? +Query or modify the configuration options of the widget. +If no \fIoption\fR is specified, returns a list describing all of +the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for +information on the format of this list). If \fIoption\fR is specified +with no \fIvalue\fR, then the command returns a list describing the +one named option (this list will be identical to the corresponding +sublist of the value returned if no \fIoption\fR is specified). If +one or more \fIoption\-value\fR pairs are specified, then the command +modifies the given widget option(s) to have the given value(s); in +this case the command returns an empty string. +\fIOption\fR may have any of the values accepted by the \fBtable\fR +command. +.TP +\fIpathName \fBcurselection\fR ?\fIvalue\fR? +With no arguments, it returns the sorted indices of the currently selected +cells. Otherwise it sets all the selected cells to the given value. The +set has no effect if there is no associated Tcl array or the state is +disabled. +.TP +\fIpathName \fBcurvalue\fR ?\fIvalue\fR? +If no value is given, the value of the cell being edited (indexed by +\fBactive\fR) is returned, else it is set to the given value. +.TP +\fIpathName \fBdelete\fR \fIoption arg\fR ?\fIarg\fR? +This command is used to delete various things in a table. It has several +forms, depending on the \fIoption\fR: +.RS +.TP +\fIpathName \fBdelete active\fR \fIindex\fR ?\fIindex\fR? +Deletes text from the active cell. If only one index is given, it deletes +the character after that index, otherwise it deletes from the first index to +the second. \fIindex\fR can be a number, \fBinsert\fR or \fBend\fR. +.TP +\fIpathName \fBdelete cols\fR ?\fIswitches\fR? \fIindex\fR ?\fIcount\fR? +Deletes \fIcount\fR cols starting at (and including) col \fIindex\fR. The +\fIindex\fR will be constrained to the limits of the tables. If +\fIcount\fR is negative, it deletes cols to the left. Otherwise it deletes +cols to the right. \fIcount\fR defaults to 1 (meaning just the column +specified). At the moment, spans are +not adjusted with this action. Optional switches are: +.RS +.TP +\fB\-holddimensions\fR +Causes the table cols to be unaffected by the deletion (empty cols may +appear). By default the dimensions are adjusted by \fBcount\fR. +.TP +\fB\-holdselection\fR +Causes the selection to be maintained on the absolute cells values. +Otherwise, the selection will be cleared.. +.TP +\fB\-holdtags\fR +Causes the tags specified by the \fItag\fR method to not move along +with the data. Also prevents specific widths set by the \fIwidth\fR method +from being adjusted. By default, these tags are properly adjusted. +.TP +\fB\-holdwindows\fR +Causes the embedded windows created with the \fIwindow\fR method to not +move along with the data. By default, these windows are properly adjusted. +.TP +\fB\-keeptitles\fR +Prevents title area cells from being changed. Otherwise they are +treated just like regular cells and will move as specified. +.TP +\fB\-\-\fR +Signifies the end of the switches. +.RE +.TP +\fIpathName \fBdelete rows\fR ?\fIswitches\fR? \fIindex\fR ?\fIcount\fR? +Deletes \fBcount\fR rows starting at (and including) row \fBindex\fR. If +\fBcount\fR is negative, it deletes rows going up. Otherwise it deletes +rows going down. The selection will be cleared. The switches are the same +as those for column deletion. +.RE +.TP +\fIpathName \fBget\fR \fIfirst\fR ?\fIlast\fR? +Returns the value of the cells specified by the table indices \fIfirst\fR +and (optionally) \fIlast\fR in a list. +.TP +\fIpathName \fBheight\fR ?\fIrow\fR? ?\fIvalue row value ...\fR? +If no \fIrow\fR is specified, returns a list describing all rows for which +a height has been set. If \fBrow\fR is specified with no value, it prints +out the height of that row in characters (positive number) or pixels +(negative number). If one or more \fIrow\-value\fR pairs are specified, +then it sets each row to be that height in lines (positive number) or +pixels (negative number). If \fIvalue\fR is \fIdefault\fR, then the row +uses the default height, specified by \fB\-rowheight\fR. +.TP +\fIpathName \fBhidden\fR ?\fIindex\fR? ?\fIindex ...\fR? +When called without args, it returns all the \fIhidden\fR cells (those +cells covered by a spanning cell). If one index is specified, it returns +the spanning cell covering that index, if any. If multiple indices are +specified, it returns 1 if all indices are hidden cells, 0 otherwise. +.TP +\fIpathName \fBicursor\fR ?\fIarg\fR? +With no arguments, prints out the location of the insertion cursor in the +active cell. With one argument, sets the cursor to that point in the +string. 0 is before the first character, you can also use \fBinsert\fR or +\fBend\fR for the current insertion point or the end of the text. If +there is no active cell, or the cell or table is disabled, this will +return -1. +.TP +\fIpathName \fBindex\fR \fIindex\fR ?\fIrow|col\fR? +Returns the integer cell coordinate that corresponds to \fIindex\fR in the +form row,col. If \fBrow\fR or \fBcol\fR is specified, then only the row or +column index is returned. +.TP +\fIpathName \fBinsert\fR \fIoption arg arg\fR +This command is used to into various things into a table. It has several +forms, depending on the \fIoption\fR: +.RS +.TP +\fIpathName \fBinsert active\fR \fIindex value\fR +The \fIvalue\fR is a text string which is inserted at the \fIindex\fR +position of the active cell. The cursor is then positioned after the +new text. \fIindex\fR can be a number, \fBinsert\fR or \fBend\fR. +.TP +\fIpathName \fBinsert cols\fR ?\fIswitches\fR? \fIindex\fR ?\fIcount\fR? +Inserts \fBcount\fR cols starting at col \fBindex\fR. If \fBcount\fR is +negative, it inserts before the specified col. Otherwise it inserts after +the specified col. The selection will be cleared. The switches are the +same as those for column deletion. +.TP +\fIpathName \fBinsert rows\fR ?\fIswitches\fR? \fIindex\fR ?\fIcount\fR? +Inserts \fBcount\fR rows starting at row \fBindex\fR. If \fBcount\fR is +negative, it inserts before the specified row. Otherwise it inserts after +the specified row. The selection will be cleared. The switches are the +same as those for column deletion. +.RE +.TP +\fIpathName \fBreread\fR +Rereads the old contents of the cell back into the editing buffer. Useful +for a key binding when is pressed to abort the edit (a default +binding). +.TP +\fIpathName \fBscan\fR \fIoption args\fR +This command is used to implement scanning on tables. It has +two forms, depending on \fIoption\fR: +.RS +.TP +\fIpathName \fBscan mark\fR \fIx y\fR +Records \fIx\fR and \fIy\fR and the current view in the table +window; used in conjunction with later \fBscan dragto\fR commands. +Typically this command is associated with a mouse button press in +the widget. It returns an empty string. +.TP +\fIpathName \fBscan dragto\fR \fIx y\fR. +This command computes the difference between its \fIx\fR and \fIy\fR +arguments and the \fIx\fR and \fIy\fR arguments to the last \fBscan mark\fR +command for the widget. It then adjusts the view by 5 times the difference +in coordinates. This command is typically associated with mouse motion +events in the widget, to produce the effect of dragging the list at high +speed through the window. The return value is an empty string. +.RE +.TP +\fIpathName \fBsee\fR \fIindex\fR +Adjust the view in the table so that the cell given by \fIindex\fR is +positioned as the cell one off from top left (excluding title rows and +columns) if the cell is not currently visible on the screen. The actual +cell may be different to keep the screen full. +.TP +\fIpathName \fBselection\fR \fIoption arg\fR +This command is used to adjust the selection within a table. It +has several forms, depending on \fIoption\fR: +.RS +.TP +\fIpathName \fBselection anchor\fR \fIindex\fR +Sets the selection anchor to the cell given by \fIindex\fR. The selection +anchor is the end of the selection that is fixed while dragging out a +selection with the mouse. The index \fBanchor\fR may be used to refer to +the anchor cell. +.TP +\fIpathName \fBselection clear\fR \fIfirst \fR?\fIlast\fR? +If any of the cells between \fIfirst\fR and \fIlast\fR (inclusive) are +selected, they are deselected. The selection state is not changed for cells +outside this range. \fIfirst\fR may be specified as \fBall\fR to remove +the selection from all cells. +.TP +\fIpathName \fBselection includes\fR \fIindex\fR +Returns 1 if the cell indicated by \fIindex\fR is currently +selected, 0 if it isn't. +.TP +\fIpathName \fBselection set\fR \fIfirst\fR ?\fIlast\fR? +Selects all of the cells in the range between \fIfirst\fR and \fIlast\fR, +inclusive, without affecting the selection state of cells outside that +range. +.RE +.TP +\fIpathName \fBset\fR ?\fIrow|col\fR? \fIindex\fR ?\fIvalue\fR? ?\fIindex value ...\fR? +Sets the specified index to the associated value. Table validation will +not be triggered via this method. If \fBrow\fR or \fBcol\fR precedes the +list of index/value pairs, then the value is assumed to be a Tcl list whose +values will be split and set into the subsequent columns (if \fBrow\fR is +specified) or rows (for \fBcol\fR). For example, \fBset row 2,3 +{2,3 2,4 2,5}\fR will set 3 cells, from 2,3 to 2,5. The setting of cells +is silently bounded by the known table dimensions. +.TP +\fIpathName \fBspans\fR ?\fIindex\fR? ?\fIrows,cols index rows,cols ...\fR? +This command is used to manipulate row/col spans. When called with no +arguments, all known spans are returned as a list of tuples of the form +{index span}. When called with only the \fIindex\fR, the span for that +\fIindex\fR only is returned, if any. Otherwise an even number of +\fIindex rows,cols\fR pairs are used to set spans. A span starts at the +\fIindex\fR and continues for the specified number of rows and cols. +Negative spans are not supported. A span of 0,0 unsets any span on that +cell. See EXAMPLES for more info. +.TP +\fIpathName \fBtag\fR option ?\fIarg arg ...\fR? +This command is used to manipulate tags. The exact behavior of the command +depends on the \fIoption\fR argument that follows the \fBtag\fR argument. +\fIcget\fR, \fIcell\fR, and \fIrow|col\fR complain about unknown tag names. +The following forms of the command are currently supported: +.RS +.TP +\fIpathName \fBtag cell\fR \fItagName ?index ...?\fR +With no arguments, prints out the list of cells that use the \fItag\fR. +Otherwise it sets the specified cells to use the named tag, replacing any +tag that may have been set using this method before. If \fItagName\fR is +{}, the cells are reset to the default \fItag\fR. Tags added during +\-*tagcommand evaluation do not register here. If \fItagName\fR does +not exist, it will be created with the default options. +.TP +\fIpathName \fBtag cget\fR \fItagName option\fR +This command returns the current value of the option named \fIoption\fR +associated with the tag given by \fItagName\fR. \fIOption\fR may have any +of the values accepted by the \fBtag configure\fR widget command. +.TP +\fIpathName \fBtag col\fR \fItagName ?col ...?\fR +With no arguments, prints out the list of cols that use the \fItag\fR. +Otherwise it sets the specified columns to use the named tag, replacing any +tag that may have been set using this method before. If \fItagName\fR is +{}, the cols are reset to the default \fItag\fR. Tags added during +\-coltagcommand evaluation do not register here. If \fItagName\fR does +not exist, it will be created with the default options. +.TP +\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR? +This command is similar to the \fBconfigure\fR widget command except that +it modifies options associated with the tag given by \fItagName\fR instead +of modifying options for the overall table widget. If no \fIoption\fR is +specified, the command returns a list describing all of the available +options for \fItagName\fR (see \fBTk_ConfigureInfo\fR for information on +the format of this list). If \fIoption\fR is specified with no +\fIvalue\fR, then the command returns a list describing the one named +option (this list will be identical to the corresponding sublist of the +value returned if no \fIoption\fR is specified). If one or more +\fIoption\-value\fR pairs are specified, then the command modifies the +given option(s) to have the given value(s) in \fItagName\fR; in this case +the command returns an empty string. +See TAGS above for details on the options available for tags. +.TP +\fIpathName \fBtag delete\fR \fItagName\fR +Deletes a tag. No error if the tag does not exist. +.TP +\fIpathName \fBtag exists\fR \fItagName\fR +Returns 1 if the named tag exists, 0 otherwise. +.TP +\fIpathName \fBtag includes\fR \fItagName index\fR +Returns 1 if the specified index has the named tag, 0 otherwise. +.TP +\fIpathName \fBtag lower\fR \fItagName\fR ?\fIbelowThis\fR? +Lower the priority of the named tag. If \fIbelowThis\fR is not specified, +then the tag's priority is lowered to the bottom, otherwise it is lowered +to one below \fIbelowThis\fR. +.TP +\fIpathName \fBtag names\fR ?\fIpattern\fR? +If no pattern is specified, shows the names of all defined tags. +Otherwise the \fIpattern\fR is used as a glob pattern to show only +tags matching that pattern. Tag names are returned in priority order +(highest priority tag first). +.TP +\fIpathName \fBtag raise\fR \fItagName\fR ?\fIaboveThis\fR? +Raise the priority of the named tag. If \fIaboveThis\fR is not specified, +then the tag's priority is raised to the top, otherwise it is raised to +one above \fIaboveThis\fR. +.TP +\fIpathName \fBtag row\fR \fItagName\fR ?\fIrow ...\fR? +With no arguments, prints out the list of rows that use the \fItag\fR. +Otherwise it sets the specified rows to use the named tag, replacing any +tag that may have been set using this method before. If \fItagName\fR is +{}, the rows are reset to use the default tag. Tags added during +\-rowtagcommand evaluation do not register here. If \fItagName\fR does +not exist, it will be created with the default options. +.RE +.TP +\fIpathName \fBvalidate\fR \fIindex\fR +Explicitly validates the specified index based on the current +\fB\-validatecommand\fR and returns 0 or 1 based on whether the cell was +validated. +.TP +\fIpathName \fBwidth\fR ?\fIcol\fR? ?\fIvalue col value ...\fR? +If no \fIcol\fR is specified, returns a list describing all cols for which +a width has been set. If \fBcol\fR is specified with no value, it prints +out the width of that col in characters (positive number) or pixels +(negative number). If one or more \fIcol\-value\fR pairs are specified, +then it sets each col to be that width in characters (positive number) or +pixels (negative number). If \fIvalue\fR is \fIdefault\fR, then the col +uses the default width, specified by \fB\-colwidth\fR. +.TP +\fIpathName \fBwindow\fR option ?\fIarg arg ...\fR? +This command is used to manipulate embedded windows. The exact behavior of +the command depends on the \fIoption\fR argument that follows the +\fBwindow\fR argument. The following forms of the command are currently +supported: +.RS +.TP +\fIpathName \fBwindow cget\fR \fIindex option\fR +This command returns the current value of the option named \fIoption\fR +associated with the window given by \fIindex\fR. \fIOption\fR may have any +of the values accepted by the \fBwindow configure\fR widget command. +.TP +\fIpathName \fBwindow configure \fIindex\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR? +This command is similar to the \fBconfigure\fR widget command except that +it modifies options associated with the embedded window given by +\fIindex\fR instead of modifying options for the overall table widget. If +no \fIoption\fR is specified, the command returns a list describing all of +the available options for \fIindex\fR (see \fBTk_ConfigureInfo\fR for +information on the format of this list). If \fIoption\fR is specified with +no \fIvalue\fR, then the command returns a list describing the one named +option (this list will be identical to the corresponding sublist of the +value returned if no \fIoption\fR is specified). If one or more +\fIoption\-value\fR pairs are specified, then the command modifies the +given option(s) to have the given value(s) in \fIindex\fR; in this case +the command returns an empty string. +See EMBEDDED WINDOWS above for details on the options available for windows. +.TP +\fIpathName \fBwindow delete\fR \fIindex\fR ?\fIindex ...\fR? +Deletes an embedded window from the table. The associated window will +also be deleted. +.TP +\fIpathName \fBwindow move\fR \fIindexFrom indexTo\fR +Moves an embedded window from one cell to another. If a window already +exists in the target cell, it will be deleted. +.TP +\fIpathName \fBwindow names\fR ?\fIpattern\fR? +If no pattern is specified, shows the cells of all embedded windows. +Otherwise the \fIpattern\fR is used as a glob pattern to show only +cells matching that pattern. +.RE +.TP +\fIpathName \fBxview \fIargs\fR +This command is used to query and change the horizontal position of the +information in the widget's window. It can take any of the following +forms: +.RS +.TP +\fIpathName \fBxview\fR +Returns a list containing two elements. +Each element is a real fraction between 0 and 1; together they describe +the horizontal span that is visible in the window. +For example, if the first element is .2 and the second element is .6, +20% of the table's text is off\-screen to the left, the middle 40% is visible +in the window, and 40% of the text is off\-screen to the right. +These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR +option. +.TP +\fIpathName \fBxview\fR \fIindex\fR +Adjusts the view in the window so that the column given by +\fIindex\fR is displayed at the left edge of the window. +.TP +\fIpathName \fBxview moveto\fI fraction\fR +Adjusts the view in the window so that \fIfraction\fR of the +total width of the table text is off\-screen to the left. +\fIfraction\fR must be a fraction between 0 and 1. +.TP +\fIpathName \fBxview scroll \fInumber what\fR +This command shifts the view in the window left or right according to +\fInumber\fR and \fIwhat\fR. +\fINumber\fR must be an integer. +\fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation +of one of these. +If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by +\fInumber\fR cells on the display; if it is \fBpages\fR then the view +adjusts by \fInumber\fR screenfuls. +If \fInumber\fR is negative then cells farther to the left +become visible; if it is positive then cells farther to the right +become visible. +.RE +.TP +\fIpathName \fByview \fI?args\fR? +This command is used to query and change the vertical position of the +text in the widget's window. It can take any of the following forms: +.RS +.TP +\fIpathName \fByview\fR +Returns a list containing two elements, both of which are real fractions +between 0 and 1. The first element gives the position of the table element +at the top of the window, relative to the table as a whole (0.5 means it is +halfway through the table, for example). The second element gives the +position of the table element just after the last one in the window, +relative to the table as a whole. These are the same values passed to +scrollbars via the \fB\-yscrollcommand\fR option. +.TP +\fIpathName \fByview\fR \fIindex\fR +Adjusts the view in the window so that the row given by +\fIindex\fR is displayed at the top of the window. +.TP +\fIpathName \fByview moveto\fI fraction\fR +Adjusts the view in the window so that the element given by \fIfraction\fR +appears at the top of the window. +\fIFraction\fR is a fraction between 0 and 1; 0 indicates the first +element in the table, 0.33 indicates the element one\-third the +way through the table, and so on. +.TP +\fIpathName \fByview scroll \fInumber what\fR +This command adjusts the view in the window up or down according to +\fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. \fIWhat\fR +must be either \fBunits\fR or \fBpages\fR. If \fIwhat\fR is \fBunits\fR, +the view adjusts up or down by \fInumber\fR cells; if it is \fBpages\fR then +the view adjusts by \fInumber\fR screenfuls. If \fInumber\fR is negative +then earlier elements become visible; if it is positive then later elements +become visible. +.RE + +.SH "DEFAULT BINDINGS" +.PP +The initialization creates class bindings that give the +following default behaviour: +.IP [1] +Clicking Button\-1 in a cell activates that cell. Clicking +into an already active cell moves the insertion cursor to the +character nearest the mouse. +.IP [2] +Moving the mouse while Button\-1 is pressed will stroke out a selection area. +Exiting while Button\-1 is pressed causing scanning to occur on the table +along with selection. +.IP [3] +Moving the mouse while Button\-2 is pressed causes scanning to +occur without any selection. +.IP [4] +Home moves the table to have the origin in view. +.IP [5] +End moves the table to have the \fBend\fR cell in view. +.IP [6] +Control\-Home moves the table to the origin and activates that cell. +.IP [7] +Control\-End moves the table to the end and activates that cell. +.IP [8] +Shift\-Control\-Home extends the selection to the origin. +.IP [9] +Shift\-Control\-End extends the selection to the end. +.IP [10] +The left, right, up and down arrows move the active cell. +.IP [11] +Shift\- extends the selection in that direction. +.IP [12] +Control\-leftarrow and Control\-rightarrow move the insertion +cursor within the cell. +.IP [13] +Control\-slash selects all the cells. +.IP [14] +Control\-backslash clears selection from all the cells. +.IP [15] +Backspace deletes the character before the insertion cursor +in the active cell. +.IP [16] +Delete deletes the character after the insertion cursor +in the active cell. +.IP [17] +Escape rereads the value of the active cell from the specified data source, +discarding any edits that have may been performed on the cell. +.IP [18] +Control\-a moves the insertion cursor to the beginning of the active cell. +.IP [19] +Control\-e moves the insertion cursor to the end of the active cell. +.IP [20] +Control\-minus and Control\-equals decrease and increase the +width of the column with the active cell in it. +.IP [21] +Moving the mouse while Button\-3 (the right button on Windows) is pressed +while you are over a border will cause interactive resizing of that row +and/or column to occur, based on the value of \fB\-resizeborders\fR. +.PP +Some bindings may have slightly different behavior dependent on the +\fB\-selectionmode\fR of the widget. +.PP +If the widget is disabled using the \fB\-state\fR option, then its +view can still be adjusted and cells can still be selected, +but no insertion cursor will be displayed and no cell modifications will +take place. +.PP +The behavior of tables can be changed by defining new bindings for +individual widgets or by redefining the class bindings. The default +bindings are either compiled in or read from a file expected to +correspond to: "[lindex $tcl_pkgPath 0]/Tktable/tkTable.tcl". + +.SH "PERFORMANCE ISSUES" +.PP +The number of rows and columns or a table widget should not significantly +affect the speed of redraw. Recalculation and redraw of table parameters +and cells is restricted as much as possible. +.PP +The display cell with the insert cursor is redrawn each time the cursor +blinks, which causes a steady stream of graphics traffic. Set the +\fB\-insertofftime\fR option to 0 avoid this. The use of a \fB\-command\fR +with the table without a cache can cause significant slow\-down, as the +command is called once for each request of a cell value. + + +.SH EXAMPLES +.PP +Set the topleft title area to be one spanning cell. This overestimates +both row and column span by one, but the command does all the constraining +for us. +.CS +$table span [$table cget -roworigin],[$table cget -colorigin] [$table cget -titlerows],[$table cget -titlecols] +.CE +Force a table window refresh (useful for the slight chance that a bug +in the table is not causing proper refresh): +.CS +$table configure -padx [$table cget -padx] +.CE + +.SH KEYWORDS +table, widget, extension diff --git a/tktable/generic/tkAppInit.c b/tktable/generic/tkAppInit.c new file mode 100644 index 0000000..bc4fb61 --- /dev/null +++ b/tktable/generic/tkAppInit.c @@ -0,0 +1,132 @@ +/* + * tkAppInit.c -- + * + * Provides a default version of the Tcl_AppInit procedure for + * use in wish and similar Tk-based applications. + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tkAppInit.c 1.24 98/01/13 17:21:40 + */ + +#include "tk.h" +#include "locale.h" + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +extern int matherr(); +int *tclDummyMathPtr = (int *) matherr; + +EXTERN int Tktable_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#ifdef TK_TEST +EXTERN int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +EXTERN int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#endif /* TK_TEST */ + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tk_Main never returns here, so this procedure never + * returns either. + * + * Side effects: + * Whatever the application does. + * + *---------------------------------------------------------------------- + */ + +int +main(argc, argv) + int argc; /* Number of command-line arguments. */ + char **argv; /* Values of command-line arguments. */ +{ + Tk_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler warning. */ +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_AppInit(interp) + Tcl_Interp *interp; /* Interpreter for application. */ +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (Tk_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL); +#ifdef TK_TEST + if (Tcltest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, + (Tcl_PackageInitProc *) NULL); + if (Tktest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "Tktest", Tktest_Init, + (Tcl_PackageInitProc *) NULL); +#endif /* TK_TEST */ + + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + if (Tktable_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "Tktable", Tktable_Init, Tktable_SafeInit); + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + + Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); + return TCL_OK; +} diff --git a/tktable/generic/tkTable.c b/tktable/generic/tkTable.c new file mode 100644 index 0000000..9392b8f --- /dev/null +++ b/tktable/generic/tkTable.c @@ -0,0 +1,4090 @@ +/* + * tkTable.c -- + * + * This module implements table widgets for the Tk + * toolkit. An table displays a 2D array of strings + * and allows the strings to be edited. + * + * Based on Tk3 table widget written by Roland King + * + * Updates 1996 by: + * Jeffrey Hobbs jeff at hobbs org + * John Ellson ellson@lucent.com + * Peter Bruecker peter@bj-ig.de + * Tom Moore tmoore@spatial.ca + * Sebastian Wangnick wangnick@orthogon.de + * + * Copyright (c) 1997-2002 Jeffrey Hobbs + * + * See the file "license.txt" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tkTable.c,v 1.34 2008/11/14 23:43:35 hobbs Exp $ + */ + +#include "tkTable.h" + +#ifdef DEBUG +#include "dprint.h" +#endif + +static char ** StringifyObjects(int objc, Tcl_Obj *CONST objv[]); + +static int Tk_TableObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); + +static int TableWidgetObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static int TableConfigure(Tcl_Interp *interp, Table *tablePtr, + int objc, Tcl_Obj *CONST objv[], + int flags, int forceUpdate); +#ifdef HAVE_TCL84 +static void TableWorldChanged(ClientData instanceData); +#endif +static void TableDestroy(ClientData clientdata); +static void TableEventProc(ClientData clientData, XEvent *eventPtr); +static void TableCmdDeletedProc(ClientData clientData); + +static void TableRedrawHighlight(Table *tablePtr); +static void TableGetGc(Display *display, Drawable d, + TableTag *tagPtr, GC *tagGc); + +static void TableDisplay(ClientData clientdata); +static void TableFlashEvent(ClientData clientdata); +static char * TableVarProc(ClientData clientData, Tcl_Interp *interp, + char *name, char *index, int flags); +static void TableCursorEvent(ClientData clientData); +static int TableFetchSelection(ClientData clientData, + int offset, char *buffer, int maxBytes); +static Tk_RestrictAction TableRestrictProc(ClientData arg, XEvent *eventPtr); + +/* + * The following tables define the widget commands (and sub- + * commands) and map the indexes into the string tables into + * enumerated types used to dispatch the widget command. + */ + +static CONST84 char *selCmdNames[] = { + "anchor", "clear", "includes", "present", "set", (char *)NULL +}; +enum selCommand { + CMD_SEL_ANCHOR, CMD_SEL_CLEAR, CMD_SEL_INCLUDES, CMD_SEL_PRESENT, + CMD_SEL_SET +}; + +static CONST84 char *commandNames[] = { + "activate", "bbox", "border", "cget", "clear", "configure", + "curselection", "curvalue", "delete", "get", "height", + "hidden", "icursor", "index", "insert", +#ifdef POSTSCRIPT + "postscript", +#endif + "reread", "scan", "see", "selection", "set", + "spans", "tag", "validate", "version", "window", "width", + "xview", "yview", (char *)NULL +}; +enum command { + CMD_ACTIVATE, CMD_BBOX, CMD_BORDER, CMD_CGET, CMD_CLEAR, CMD_CONFIGURE, + CMD_CURSEL, CMD_CURVALUE, CMD_DELETE, CMD_GET, CMD_HEIGHT, + CMD_HIDDEN, CMD_ICURSOR, CMD_INDEX, CMD_INSERT, +#ifdef POSTSCRIPT + CMD_POSTSCRIPT, +#endif + CMD_REREAD, CMD_SCAN, CMD_SEE, CMD_SELECTION, CMD_SET, + CMD_SPANS, CMD_TAG, CMD_VALIDATE, CMD_VERSION, CMD_WINDOW, CMD_WIDTH, + CMD_XVIEW, CMD_YVIEW +}; + +/* -selecttype selection type options */ +static Cmd_Struct sel_vals[]= { + {"row", SEL_ROW}, + {"col", SEL_COL}, + {"both", SEL_BOTH}, + {"cell", SEL_CELL}, + {"", 0 } +}; + +/* -resizeborders options */ +static Cmd_Struct resize_vals[]= { + {"row", SEL_ROW}, /* allow rows to be dragged */ + {"col", SEL_COL}, /* allow cols to be dragged */ + {"both", SEL_ROW|SEL_COL}, /* allow either to be dragged */ + {"none", SEL_NONE}, /* allow nothing to be dragged */ + {"", 0 } +}; + +/* drawmode values */ +/* The display redraws with a pixmap using TK function calls */ +#define DRAW_MODE_SLOW (1<<0) +/* The redisplay is direct to the screen, but TK function calls are still + * used to give correct 3-d border appearance and thus remain compatible + * with other TK apps */ +#define DRAW_MODE_TK_COMPAT (1<<1) +/* the redisplay goes straight to the screen and the 3d borders are rendered + * with a single pixel wide line only. It cheats and uses the internal + * border structure to do the borders */ +#define DRAW_MODE_FAST (1<<2) +#define DRAW_MODE_SINGLE (1<<3) + +static Cmd_Struct drawmode_vals[] = { + {"fast", DRAW_MODE_FAST}, + {"compatible", DRAW_MODE_TK_COMPAT}, + {"slow", DRAW_MODE_SLOW}, + {"single", DRAW_MODE_SINGLE}, + {"", 0} +}; + +/* stretchmode values */ +#define STRETCH_MODE_NONE (1<<0) /* No additional pixels will be + added to rows or cols */ +#define STRETCH_MODE_UNSET (1<<1) /* All default rows or columns will + be stretched to fill the screen */ +#define STRETCH_MODE_ALL (1<<2) /* All rows/columns will be padded + to fill the window */ +#define STRETCH_MODE_LAST (1<<3) /* Stretch last elememt to fill + window */ +#define STRETCH_MODE_FILL (1<<4) /* More ROWS in Window */ + +static Cmd_Struct stretch_vals[] = { + {"none", STRETCH_MODE_NONE}, + {"unset", STRETCH_MODE_UNSET}, + {"all", STRETCH_MODE_ALL}, + {"last", STRETCH_MODE_LAST}, + {"fill", STRETCH_MODE_FILL}, + {"", 0} +}; + +static Cmd_Struct state_vals[]= { + {"normal", STATE_NORMAL}, + {"disabled", STATE_DISABLED}, + {"", 0 } +}; + +/* The widget configuration table */ +static Tk_CustomOption drawOpt = { Cmd_OptionSet, Cmd_OptionGet, + (ClientData)(&drawmode_vals) }; +static Tk_CustomOption resizeTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, + (ClientData)(&resize_vals) }; +static Tk_CustomOption stretchOpt = { Cmd_OptionSet, Cmd_OptionGet, + (ClientData)(&stretch_vals) }; +static Tk_CustomOption selTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, + (ClientData)(&sel_vals) }; +static Tk_CustomOption stateTypeOpt = { Cmd_OptionSet, Cmd_OptionGet, + (ClientData)(&state_vals) }; +static Tk_CustomOption bdOpt = { TableOptionBdSet, TableOptionBdGet, + (ClientData) BD_TABLE }; + +Tk_ConfigSpec tableSpecs[] = { + {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", + Tk_Offset(Table, defaultTag.anchor), 0}, + {TK_CONFIG_BOOLEAN, "-autoclear", "autoClear", "AutoClear", "0", + Tk_Offset(Table, autoClear), 0}, + {TK_CONFIG_BORDER, "-background", "background", "Background", NORMAL_BG, + Tk_Offset(Table, defaultTag.bg), 0}, + {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, + {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, + {TK_CONFIG_CURSOR, "-bordercursor", "borderCursor", "Cursor", "crosshair", + Tk_Offset(Table, bdcursor), TK_CONFIG_NULL_OK }, + {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "1", + Tk_Offset(Table, defaultTag), TK_CONFIG_NULL_OK, &bdOpt }, + {TK_CONFIG_STRING, "-browsecommand", "browseCommand", "BrowseCommand", "", + Tk_Offset(Table, browseCmd), TK_CONFIG_NULL_OK}, + {TK_CONFIG_SYNONYM, "-browsecmd", "browseCommand", (char *)NULL, + (char *)NULL, 0, TK_CONFIG_NULL_OK}, + {TK_CONFIG_BOOLEAN, "-cache", "cache", "Cache", "0", + Tk_Offset(Table, caching), 0}, + {TK_CONFIG_INT, "-colorigin", "colOrigin", "Origin", "0", + Tk_Offset(Table, colOffset), 0}, + {TK_CONFIG_INT, "-cols", "cols", "Cols", "10", + Tk_Offset(Table, cols), 0}, + {TK_CONFIG_STRING, "-colseparator", "colSeparator", "Separator", NULL, + Tk_Offset(Table, colSep), TK_CONFIG_NULL_OK }, + {TK_CONFIG_CUSTOM, "-colstretchmode", "colStretch", "StretchMode", "none", + Tk_Offset (Table, colStretch), 0 , &stretchOpt }, + {TK_CONFIG_STRING, "-coltagcommand", "colTagCommand", "TagCommand", NULL, + Tk_Offset(Table, colTagCmd), TK_CONFIG_NULL_OK }, + {TK_CONFIG_INT, "-colwidth", "colWidth", "ColWidth", "10", + Tk_Offset(Table, defColWidth), 0}, + {TK_CONFIG_STRING, "-command", "command", "Command", "", + Tk_Offset(Table, command), TK_CONFIG_NULL_OK}, + {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", "xterm", + Tk_Offset(Table, cursor), TK_CONFIG_NULL_OK }, + {TK_CONFIG_CUSTOM, "-drawmode", "drawMode", "DrawMode", "compatible", + Tk_Offset(Table, drawMode), 0, &drawOpt }, + {TK_CONFIG_STRING, "-ellipsis", "ellipsis", "Ellipsis", "", + Tk_Offset(Table, defaultTag.ellipsis), TK_CONFIG_NULL_OK}, + {TK_CONFIG_BOOLEAN, "-exportselection", "exportSelection", + "ExportSelection", "1", Tk_Offset(Table, exportSelection), 0}, + {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, + {TK_CONFIG_BOOLEAN, "-flashmode", "flashMode", "FlashMode", "0", + Tk_Offset(Table, flashMode), 0}, + {TK_CONFIG_INT, "-flashtime", "flashTime", "FlashTime", "2", + Tk_Offset(Table, flashTime), 0}, + {TK_CONFIG_FONT, "-font", "font", "Font", DEF_TABLE_FONT, + Tk_Offset(Table, defaultTag.tkfont), 0}, + {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", "black", + Tk_Offset(Table, defaultTag.fg), 0}, +#ifdef PROCS + {TK_CONFIG_BOOLEAN, "-hasprocs", "hasProcs", "hasProcs", "0", + Tk_Offset(Table, hasProcs), 0}, +#endif + {TK_CONFIG_INT, "-height", "height", "Height", "0", + Tk_Offset(Table, maxReqRows), 0}, + {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", + "HighlightBackground", NORMAL_BG, Tk_Offset(Table, highlightBgColorPtr), 0}, + {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", + HIGHLIGHT, Tk_Offset(Table, highlightColorPtr), 0}, + {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", + "HighlightThickness", "2", Tk_Offset(Table, highlightWidth), 0}, + {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground", + "Black", Tk_Offset(Table, insertBg), 0}, + {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", + "0", Tk_Offset(Table, insertBorderWidth), TK_CONFIG_COLOR_ONLY}, + {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", + "0", Tk_Offset(Table, insertBorderWidth), TK_CONFIG_MONO_ONLY}, + {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime", "300", + Tk_Offset(Table, insertOffTime), 0}, + {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime", "600", + Tk_Offset(Table, insertOnTime), 0}, + {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", "2", + Tk_Offset(Table, insertWidth), 0}, + {TK_CONFIG_BOOLEAN, "-invertselected", "invertSelected", "InvertSelected", + "0", Tk_Offset(Table, invertSelected), 0}, + {TK_CONFIG_PIXELS, "-ipadx", "ipadX", "Pad", "0", + Tk_Offset(Table, ipadX), 0}, + {TK_CONFIG_PIXELS, "-ipady", "ipadY", "Pad", "0", + Tk_Offset(Table, ipadY), 0}, + {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", "left", + Tk_Offset(Table, defaultTag.justify), 0 }, + {TK_CONFIG_PIXELS, "-maxheight", "maxHeight", "MaxHeight", "600", + Tk_Offset(Table, maxReqHeight), 0}, + {TK_CONFIG_PIXELS, "-maxwidth", "maxWidth", "MaxWidth", "800", + Tk_Offset(Table, maxReqWidth), 0}, + {TK_CONFIG_BOOLEAN, "-multiline", "multiline", "Multiline", "1", + Tk_Offset(Table, defaultTag.multiline), 0}, + {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", "0", Tk_Offset(Table, padX), 0}, + {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", "0", Tk_Offset(Table, padY), 0}, + {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", "sunken", + Tk_Offset(Table, defaultTag.relief), 0}, + {TK_CONFIG_CUSTOM, "-resizeborders", "resizeBorders", "ResizeBorders", + "both", Tk_Offset(Table, resize), 0, &resizeTypeOpt }, + {TK_CONFIG_INT, "-rowheight", "rowHeight", "RowHeight", "1", + Tk_Offset(Table, defRowHeight), 0}, + {TK_CONFIG_INT, "-roworigin", "rowOrigin", "Origin", "0", + Tk_Offset(Table, rowOffset), 0}, + {TK_CONFIG_INT, "-rows", "rows", "Rows", "10", Tk_Offset(Table, rows), 0}, + {TK_CONFIG_STRING, "-rowseparator", "rowSeparator", "Separator", NULL, + Tk_Offset(Table, rowSep), TK_CONFIG_NULL_OK }, + {TK_CONFIG_CUSTOM, "-rowstretchmode", "rowStretch", "StretchMode", "none", + Tk_Offset(Table, rowStretch), 0 , &stretchOpt }, + {TK_CONFIG_STRING, "-rowtagcommand", "rowTagCommand", "TagCommand", NULL, + Tk_Offset(Table, rowTagCmd), TK_CONFIG_NULL_OK }, + {TK_CONFIG_SYNONYM, "-selcmd", "selectionCommand", (char *)NULL, + (char *)NULL, 0, TK_CONFIG_NULL_OK}, + {TK_CONFIG_STRING, "-selectioncommand", "selectionCommand", + "SelectionCommand", NULL, Tk_Offset(Table, selCmd), TK_CONFIG_NULL_OK }, + {TK_CONFIG_STRING, "-selectmode", "selectMode", "SelectMode", "browse", + Tk_Offset(Table, selectMode), TK_CONFIG_NULL_OK }, + {TK_CONFIG_BOOLEAN, "-selecttitles", "selectTitles", "SelectTitles", "0", + Tk_Offset(Table, selectTitles), 0}, + {TK_CONFIG_CUSTOM, "-selecttype", "selectType", "SelectType", "cell", + Tk_Offset(Table, selectType), 0, &selTypeOpt }, +#ifdef PROCS + {TK_CONFIG_BOOLEAN, "-showprocs", "showProcs", "showProcs", "0", + Tk_Offset(Table, showProcs), 0}, +#endif + {TK_CONFIG_BOOLEAN, "-sparsearray", "sparseArray", "SparseArray", "1", + Tk_Offset(Table, sparse), 0}, + {TK_CONFIG_CUSTOM, "-state", "state", "State", "normal", + Tk_Offset(Table, state), 0, &stateTypeOpt}, + {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", (char *)NULL, + Tk_Offset(Table, takeFocus), TK_CONFIG_NULL_OK }, + {TK_CONFIG_INT, "-titlecols", "titleCols", "TitleCols", "0", + Tk_Offset(Table, titleCols), TK_CONFIG_NULL_OK }, +#ifdef TITLE_CURSOR + {TK_CONFIG_CURSOR, "-titlecursor", "titleCursor", "Cursor", "arrow", + Tk_Offset(Table, titleCursor), TK_CONFIG_NULL_OK }, +#endif + {TK_CONFIG_INT, "-titlerows", "titleRows", "TitleRows", "0", + Tk_Offset(Table, titleRows), TK_CONFIG_NULL_OK }, + {TK_CONFIG_BOOLEAN, "-usecommand", "useCommand", "UseCommand", "1", + Tk_Offset(Table, useCmd), 0}, + {TK_CONFIG_STRING, "-variable", "variable", "Variable", (char *)NULL, + Tk_Offset(Table, arrayVar), TK_CONFIG_NULL_OK }, + {TK_CONFIG_BOOLEAN, "-validate", "validate", "Validate", "0", + Tk_Offset(Table, validate), 0}, + {TK_CONFIG_STRING, "-validatecommand", "validateCommand", "ValidateCommand", + "", Tk_Offset(Table, valCmd), TK_CONFIG_NULL_OK}, + {TK_CONFIG_SYNONYM, "-vcmd", "validateCommand", (char *)NULL, + (char *)NULL, 0, TK_CONFIG_NULL_OK}, + {TK_CONFIG_INT, "-width", "width", "Width", "0", + Tk_Offset(Table, maxReqCols), 0}, + {TK_CONFIG_BOOLEAN, "-wrap", "wrap", "Wrap", "0", + Tk_Offset(Table, defaultTag.wrap), 0}, + {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", + NULL, Tk_Offset(Table, xScrollCmd), TK_CONFIG_NULL_OK }, + {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", + NULL, Tk_Offset(Table, yScrollCmd), TK_CONFIG_NULL_OK }, + {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, + (char *)NULL, 0, 0} +}; + +/* + * This specifies the configure options that will cause an update to + * occur, so we should have a quick lookup table for them. + * Keep this in sync with the above values. + */ + +static CONST84 char *updateOpts[] = { + "-anchor", "-background", "-bg", "-bd", + "-borderwidth", "-cache", "-command", "-colorigin", + "-cols", "-colstretchmode", "-coltagcommand", + "-drawmode", "-fg", "-font", "-foreground", + "-hasprocs", "-height", "-highlightbackground", + "-highlightcolor", "-highlightthickness", "-insertbackground", + "-insertborderwidth", "-insertwidth", "-invertselected", + "-ipadx", "-ipady", + "-maxheight", "-maxwidth", "-multiline", + "-padx", "-pady", "-relief", "-roworigin", + "-rows", "-rowstretchmode", "-rowtagcommand", + "-showprocs", "-state", "-titlecols", "-titlerows", + "-usecommand", "-variable", "-width", "-wrap", + "-xscrollcommand", "-yscrollcommand", (char *) NULL +}; + +#ifdef HAVE_TCL84 +/* + * The structure below defines widget class behavior by means of procedures + * that can be invoked from generic window code. + */ + +static Tk_ClassProcs tableClass = { + sizeof(Tk_ClassProcs), /* size */ + TableWorldChanged, /* worldChangedProc */ + NULL, /* createProc */ + NULL /* modalProc */ +}; +#endif + +#ifdef WIN32 +/* + * Some code from TkWinInt.h that we use to correct and speed up + * drawing of cells that need clipping in TableDisplay. + */ +typedef struct { + int type; + HWND handle; + void *winPtr; +} TkWinWindow; + +typedef struct { + int type; + HBITMAP handle; + Colormap colormap; + int depth; +} TkWinBitmap; + +typedef struct { + int type; + HDC hdc; +} TkWinDC; + +typedef union { + int type; + TkWinWindow window; + TkWinBitmap bitmap; + TkWinDC winDC; +} TkWinDrawable; +#endif + +/* + * END HEADER INFORMATION + */ + +/* + *--------------------------------------------------------------------------- + * + * StringifyObjects -- (from tclCmdAH.c) + * + * Helper function to bridge the gap between an object-based procedure + * and an older string-based procedure. + * + * Given an array of objects, allocate an array that consists of the + * string representations of those objects. + * + * Results: + * The return value is a pointer to the newly allocated array of + * strings. Elements 0 to (objc-1) of the string array point to the + * string representation of the corresponding element in the source + * object array; element objc of the string array is NULL. + * + * Side effects: + * Memory allocated. The caller must eventually free this memory + * by calling ckfree() on the return value. + * + int result; + char **argv; + argv = StringifyObjects(objc, objv); + result = StringBasedCmd(interp, objc, argv); + ckfree((char *) argv); + return result; + * + *--------------------------------------------------------------------------- + */ + +static char ** +StringifyObjects(objc, objv) + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + int i; + char **argv; + + argv = (char **) ckalloc((objc + 1) * sizeof(char *)); + for (i = 0; i < objc; i++) { + argv[i] = Tcl_GetString(objv[i]); + } + argv[i] = NULL; + return argv; +} + +/* + * As long as we wait for the Function in general + * + * This parses the "-class" option for the table. + */ +static int +Tk_ClassOptionObjCmd(Tk_Window tkwin, char *defaultclass, + int objc, Tcl_Obj *CONST objv[]) +{ + char *classname = defaultclass; + int offset = 0; + + if ((objc >= 4) && STREQ(Tcl_GetString(objv[2]),"-class")) { + classname = Tcl_GetString(objv[3]); + offset = 2; + } + Tk_SetClass(tkwin, classname); + return offset; +} + +/* + *-------------------------------------------------------------- + * + * Tk_TableObjCmd -- + * This procedure is invoked to process the "table" Tcl + * command. See the user documentation for details on what + * it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +static int +Tk_TableObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window associated with interpreter. */ + Tcl_Interp *interp; + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + register Table *tablePtr; + Tk_Window tkwin, mainWin = (Tk_Window) clientData; + int offset; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + return TCL_ERROR; + } + + tkwin = Tk_CreateWindowFromPath(interp, mainWin, Tcl_GetString(objv[1]), + (char *)NULL); + if (tkwin == NULL) { + return TCL_ERROR; + } + + tablePtr = (Table *) ckalloc(sizeof(Table)); + memset((VOID *) tablePtr, 0, sizeof(Table)); + + /* + * Set the structure elments that aren't 0/NULL by default, + * and that won't be set by the initial configure call. + */ + tablePtr->tkwin = tkwin; + tablePtr->display = Tk_Display(tkwin); + tablePtr->interp = interp; + tablePtr->widgetCmd = Tcl_CreateObjCommand(interp, + Tk_PathName(tablePtr->tkwin), TableWidgetObjCmd, + (ClientData) tablePtr, (Tcl_CmdDeleteProc *) TableCmdDeletedProc); + + tablePtr->anchorRow = -1; + tablePtr->anchorCol = -1; + tablePtr->activeRow = -1; + tablePtr->activeCol = -1; + tablePtr->oldTopRow = -1; + tablePtr->oldLeftCol = -1; + tablePtr->oldActRow = -1; + tablePtr->oldActCol = -1; + tablePtr->seen[0] = -1; + + tablePtr->dataSource = DATA_NONE; + tablePtr->activeBuf = ckalloc(1); + *(tablePtr->activeBuf) = '\0'; + + tablePtr->cursor = None; + tablePtr->bdcursor = None; + + tablePtr->defaultTag.justify = TK_JUSTIFY_LEFT; + tablePtr->defaultTag.state = STATE_UNKNOWN; + + /* misc tables */ + tablePtr->tagTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->tagTable, TCL_STRING_KEYS); + tablePtr->winTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->winTable, TCL_STRING_KEYS); + + /* internal value cache */ + tablePtr->cache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); + + /* style hash tables */ + tablePtr->colWidths = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->colWidths, TCL_ONE_WORD_KEYS); + tablePtr->rowHeights = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->rowHeights, TCL_ONE_WORD_KEYS); + + /* style hash tables */ + tablePtr->rowStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->rowStyles, TCL_ONE_WORD_KEYS); + tablePtr->colStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->colStyles, TCL_ONE_WORD_KEYS); + tablePtr->cellStyles = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->cellStyles, TCL_STRING_KEYS); + + /* special style hash tables */ + tablePtr->flashCells = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->flashCells, TCL_STRING_KEYS); + tablePtr->selCells = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); + + /* + * List of tags in priority order. 30 is a good default number to alloc. + */ + tablePtr->tagPrioMax = 30; + tablePtr->tagPrioNames = (char **) ckalloc( + sizeof(char *) * tablePtr->tagPrioMax); + tablePtr->tagPrios = (TableTag **) ckalloc( + sizeof(TableTag *) * tablePtr->tagPrioMax); + tablePtr->tagPrioSize = 0; + for (offset = 0; offset < tablePtr->tagPrioMax; offset++) { + tablePtr->tagPrioNames[offset] = (char *) NULL; + tablePtr->tagPrios[offset] = (TableTag *) NULL; + } + +#ifdef PROCS + tablePtr->inProc = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->inProc, TCL_STRING_KEYS); +#endif + + /* + * Handle class name and selection handlers + */ + offset = 2 + Tk_ClassOptionObjCmd(tkwin, "Table", objc, objv); +#ifdef HAVE_TCL84 + Tk_SetClassProcs(tkwin, &tableClass, (ClientData) tablePtr); +#endif + Tk_CreateEventHandler(tablePtr->tkwin, + PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask|VisibilityChangeMask, + TableEventProc, (ClientData) tablePtr); + Tk_CreateSelHandler(tablePtr->tkwin, XA_PRIMARY, XA_STRING, + TableFetchSelection, (ClientData) tablePtr, XA_STRING); + + if (TableConfigure(interp, tablePtr, objc - offset, objv + offset, + 0, 1 /* force update */) != TCL_OK) { + Tk_DestroyWindow(tkwin); + return TCL_ERROR; + } + TableInitTags(tablePtr); + + Tcl_SetObjResult(interp, + Tcl_NewStringObj(Tk_PathName(tablePtr->tkwin), -1)); + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * TableWidgetObjCmd -- + * This procedure is invoked to process the Tcl command + * that corresponds to a widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +static int +TableWidgetObjCmd(clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + register Table *tablePtr = (Table *) clientData; + int row, col, i, cmdIndex, result = TCL_OK; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + return TCL_ERROR; + } + + /* parse the first parameter */ + result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, + "option", 0, &cmdIndex); + if (result != TCL_OK) { + return result; + } + + Tcl_Preserve((ClientData) tablePtr); + switch ((enum command) cmdIndex) { + case CMD_ACTIVATE: + result = Table_ActivateCmd(clientData, interp, objc, objv); + break; + + case CMD_BBOX: + result = Table_BboxCmd(clientData, interp, objc, objv); + break; + + case CMD_BORDER: + result = Table_BorderCmd(clientData, interp, objc, objv); + break; + + case CMD_CGET: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option"); + result = TCL_ERROR; + } else { + result = Tk_ConfigureValue(interp, tablePtr->tkwin, tableSpecs, + (char *) tablePtr, Tcl_GetString(objv[2]), 0); + } + break; + + case CMD_CLEAR: + result = Table_ClearCmd(clientData, interp, objc, objv); + break; + + case CMD_CONFIGURE: + if (objc < 4) { + result = Tk_ConfigureInfo(interp, tablePtr->tkwin, tableSpecs, + (char *) tablePtr, (objc == 3) ? + Tcl_GetString(objv[2]) : (char *) NULL, 0); + } else { + result = TableConfigure(interp, tablePtr, objc - 2, objv + 2, + TK_CONFIG_ARGV_ONLY, 0); + } + break; + + case CMD_CURSEL: + result = Table_CurselectionCmd(clientData, interp, objc, objv); + break; + + case CMD_CURVALUE: + result = Table_CurvalueCmd(clientData, interp, objc, objv); + break; + + case CMD_DELETE: + case CMD_INSERT: + result = Table_EditCmd(clientData, interp, objc, objv); + break; + + case CMD_GET: + result = Table_GetCmd(clientData, interp, objc, objv); + break; + + case CMD_HEIGHT: + case CMD_WIDTH: + result = Table_AdjustCmd(clientData, interp, objc, objv); + break; + + case CMD_HIDDEN: + result = Table_HiddenCmd(clientData, interp, objc, objv); + break; + + case CMD_ICURSOR: + if (objc != 2 && objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "?cursorPos?"); + result = TCL_ERROR; + break; + } + if (!(tablePtr->flags & HAS_ACTIVE) || + (tablePtr->flags & ACTIVE_DISABLED) || + tablePtr->state == STATE_DISABLED) { + Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); + break; + } else if (objc == 3) { + if (TableGetIcursorObj(tablePtr, objv[2], NULL) != TCL_OK) { + result = TCL_ERROR; + break; + } + TableRefresh(tablePtr, tablePtr->activeRow, + tablePtr->activeCol, CELL); + } + Tcl_SetObjResult(interp, Tcl_NewIntObj(tablePtr->icursor)); + break; + + case CMD_INDEX: { + char *which = NULL; + + if (objc == 4) { + which = Tcl_GetString(objv[3]); + } + if ((objc < 3 || objc > 4) || + ((objc == 4) && (strcmp(which, "row") + && strcmp(which, "col")))) { + Tcl_WrongNumArgs(interp, 2, objv, " ?row|col?"); + result = TCL_ERROR; + } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) + != TCL_OK) { + result = TCL_ERROR; + } else if (objc == 3) { + char buf[INDEX_BUFSIZE]; + /* recreate the index, just in case it got bounded */ + TableMakeArrayIndex(row, col, buf); + Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1)); + } else { /* INDEX row|col */ + Tcl_SetObjResult(interp, + Tcl_NewIntObj((*which == 'r') ? row : col)); + } + break; + } + +#ifdef POSTSCRIPT + case CMD_POSTSCRIPT: + result = Table_PostscriptCmd(clientData, interp, objc, objv); + break; +#endif + + case CMD_REREAD: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, NULL); + result = TCL_ERROR; + } else if ((tablePtr->flags & HAS_ACTIVE) && + !(tablePtr->flags & ACTIVE_DISABLED) && + tablePtr->state != STATE_DISABLED) { + TableGetActiveBuf(tablePtr); + TableRefresh(tablePtr, tablePtr->activeRow, + tablePtr->activeCol, CELL|INV_FORCE); + } + break; + + case CMD_SCAN: + result = Table_ScanCmd(clientData, interp, objc, objv); + break; + + case CMD_SEE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index"); + result = TCL_ERROR; + } else if (TableGetIndexObj(tablePtr, objv[2], + &row, &col) == TCL_ERROR) { + result = TCL_ERROR; + } else { + /* Adjust from user to master coords */ + row -= tablePtr->rowOffset; + col -= tablePtr->colOffset; + if (!TableCellVCoords(tablePtr, row, col, &i, &i, &i, &i, 1)) { + tablePtr->topRow = row-1; + tablePtr->leftCol = col-1; + TableAdjustParams(tablePtr); + } + } + break; + + case CMD_SELECTION: + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + result = TCL_ERROR; + break; + } + if (Tcl_GetIndexFromObj(interp, objv[2], selCmdNames, + "selection option", 0, &cmdIndex) != TCL_OK) { + result = TCL_ERROR; + break; + } + switch ((enum selCommand) cmdIndex) { + case CMD_SEL_ANCHOR: + result = Table_SelAnchorCmd(clientData, interp, + objc, objv); + break; + case CMD_SEL_CLEAR: + result = Table_SelClearCmd(clientData, interp, objc, objv); + break; + case CMD_SEL_INCLUDES: + result = Table_SelIncludesCmd(clientData, interp, + objc, objv); + break; + case CMD_SEL_PRESENT: { + Tcl_HashSearch search; + int present = (Tcl_FirstHashEntry(tablePtr->selCells, + &search) != NULL); + + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(present)); + break; + } + case CMD_SEL_SET: + result = Table_SelSetCmd(clientData, interp, objc, objv); + break; + } + break; + + case CMD_SET: + result = Table_SetCmd(clientData, interp, objc, objv); + break; + + case CMD_SPANS: + result = Table_SpanCmd(clientData, interp, objc, objv); + break; + + case CMD_TAG: + result = Table_TagCmd(clientData, interp, objc, objv); + break; + + case CMD_VALIDATE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index"); + result = TCL_ERROR; + } else if (TableGetIndexObj(tablePtr, objv[2], + &row, &col) == TCL_ERROR) { + result = TCL_ERROR; + } else { + i = tablePtr->validate; + tablePtr->validate = 1; + result = TableValidateChange(tablePtr, row, col, (char *) NULL, + (char *) NULL, -1); + tablePtr->validate = i; + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result == TCL_OK)); + result = TCL_OK; + } + break; + + case CMD_VERSION: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, NULL); + result = TCL_ERROR; + } else { + Tcl_SetObjResult(interp, Tcl_NewStringObj(PACKAGE_VERSION, -1)); + } + break; + + case CMD_WINDOW: + result = Table_WindowCmd(clientData, interp, objc, objv); + break; + + case CMD_XVIEW: + case CMD_YVIEW: + result = Table_ViewCmd(clientData, interp, objc, objv); + break; + } + + Tcl_Release((ClientData) tablePtr); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * TableDestroy -- + * This procedure is invoked by Tcl_EventuallyFree + * to clean up the internal structure of a table at a safe time + * (when no-one is using it anymore). + * + * Results: + * None. + * + * Side effects: + * Everything associated with the table is freed up (hopefully). + * + *---------------------------------------------------------------------- + */ +static void +TableDestroy(ClientData clientdata) +{ + register Table *tablePtr = (Table *) clientdata; + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + + /* These may be repetitive from DestroyNotify, but it doesn't hurt */ + /* cancel any pending update or timer */ + if (tablePtr->flags & REDRAW_PENDING) { + Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); + tablePtr->flags &= ~REDRAW_PENDING; + } + Tcl_DeleteTimerHandler(tablePtr->cursorTimer); + Tcl_DeleteTimerHandler(tablePtr->flashTimer); + + /* delete the variable trace */ + if (tablePtr->arrayVar != NULL) { + Tcl_UntraceVar(tablePtr->interp, tablePtr->arrayVar, + TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, + (Tcl_VarTraceProc *)TableVarProc, (ClientData) tablePtr); + } + + /* free the int arrays */ + if (tablePtr->colPixels) ckfree((char *) tablePtr->colPixels); + if (tablePtr->rowPixels) ckfree((char *) tablePtr->rowPixels); + if (tablePtr->colStarts) ckfree((char *) tablePtr->colStarts); + if (tablePtr->rowStarts) ckfree((char *) tablePtr->rowStarts); + + /* delete cached active tag and string */ + if (tablePtr->activeTagPtr) ckfree((char *) tablePtr->activeTagPtr); + if (tablePtr->activeBuf != NULL) ckfree(tablePtr->activeBuf); + + /* + * Delete the various hash tables, make sure to clear the STRING_KEYS + * tables that allocate their strings: + * cache, spanTbl (spanAffTbl shares spanTbl info) + */ + Table_ClearHashTable(tablePtr->cache); + ckfree((char *) (tablePtr->cache)); + Tcl_DeleteHashTable(tablePtr->rowStyles); + ckfree((char *) (tablePtr->rowStyles)); + Tcl_DeleteHashTable(tablePtr->colStyles); + ckfree((char *) (tablePtr->colStyles)); + Tcl_DeleteHashTable(tablePtr->cellStyles); + ckfree((char *) (tablePtr->cellStyles)); + Tcl_DeleteHashTable(tablePtr->flashCells); + ckfree((char *) (tablePtr->flashCells)); + Tcl_DeleteHashTable(tablePtr->selCells); + ckfree((char *) (tablePtr->selCells)); + Tcl_DeleteHashTable(tablePtr->colWidths); + ckfree((char *) (tablePtr->colWidths)); + Tcl_DeleteHashTable(tablePtr->rowHeights); + ckfree((char *) (tablePtr->rowHeights)); +#ifdef PROCS + Tcl_DeleteHashTable(tablePtr->inProc); + ckfree((char *) (tablePtr->inProc)); +#endif + if (tablePtr->spanTbl) { + Table_ClearHashTable(tablePtr->spanTbl); + ckfree((char *) (tablePtr->spanTbl)); + Tcl_DeleteHashTable(tablePtr->spanAffTbl); + ckfree((char *) (tablePtr->spanAffTbl)); + } + + /* Now free up all the tag information */ + for (entryPtr = Tcl_FirstHashEntry(tablePtr->tagTable, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + TableCleanupTag(tablePtr, (TableTag *) Tcl_GetHashValue(entryPtr)); + ckfree((char *) Tcl_GetHashValue(entryPtr)); + } + /* free up the stuff in the default tag */ + TableCleanupTag(tablePtr, &(tablePtr->defaultTag)); + /* And delete the actual hash table */ + Tcl_DeleteHashTable(tablePtr->tagTable); + ckfree((char *) (tablePtr->tagTable)); + ckfree((char *) (tablePtr->tagPrios)); + ckfree((char *) (tablePtr->tagPrioNames)); + + /* Now free up all the embedded window info */ + for (entryPtr = Tcl_FirstHashEntry(tablePtr->winTable, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + EmbWinDelete(tablePtr, (TableEmbWindow *) Tcl_GetHashValue(entryPtr)); + } + /* And delete the actual hash table */ + Tcl_DeleteHashTable(tablePtr->winTable); + ckfree((char *) (tablePtr->winTable)); + + /* free the configuration options in the widget */ + Tk_FreeOptions(tableSpecs, (char *) tablePtr, tablePtr->display, 0); + + /* and free the widget memory at last! */ + ckfree((char *) (tablePtr)); +} + +/* + *---------------------------------------------------------------------- + * + * TableConfigure -- + * This procedure is called to process an objc/objv list, plus + * the Tk option database, in order to configure (or reconfigure) + * a table widget. + * + * Results: + * The return value is a standard Tcl result. If TCL_ERROR is + * returned, then interp result contains an error message. + * + * Side effects: + * Configuration information, such as colors, border width, etc. + * get set for tablePtr; old resources get freed, if there were any. + * Certain values might be constrained. + * + *---------------------------------------------------------------------- + */ +static int +TableConfigure(interp, tablePtr, objc, objv, flags, forceUpdate) + Tcl_Interp *interp; /* Used for error reporting. */ + register Table *tablePtr; /* Information about widget; may or may + * not already have values for some fields. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ + int flags; /* Flags to pass to Tk_ConfigureWidget. */ + int forceUpdate; /* Whether to force an update - required + * for initial configuration */ +{ + Tcl_HashSearch search; + int oldUse, oldCaching, oldExport, oldTitleRows, oldTitleCols; + int result = TCL_OK; + char *oldVar = NULL, **argv; + Tcl_DString error; + Tk_FontMetrics fm; + + oldExport = tablePtr->exportSelection; + oldCaching = tablePtr->caching; + oldUse = tablePtr->useCmd; + oldTitleRows = tablePtr->titleRows; + oldTitleCols = tablePtr->titleCols; + if (tablePtr->arrayVar != NULL) { + oldVar = ckalloc(strlen(tablePtr->arrayVar) + 1); + strcpy(oldVar, tablePtr->arrayVar); + } + + /* Do the configuration */ + argv = StringifyObjects(objc, objv); + result = Tk_ConfigureWidget(interp, tablePtr->tkwin, tableSpecs, + objc, (CONST84 char **) argv, (char *) tablePtr, flags); + ckfree((char *) argv); + if (result != TCL_OK) { + return TCL_ERROR; + } + + Tcl_DStringInit(&error); + + /* Any time we configure, reevaluate what our data source is */ + tablePtr->dataSource = DATA_NONE; + if (tablePtr->caching) { + tablePtr->dataSource |= DATA_CACHE; + } + if (tablePtr->command && tablePtr->useCmd) { + tablePtr->dataSource |= DATA_COMMAND; + } else if (tablePtr->arrayVar) { + tablePtr->dataSource |= DATA_ARRAY; + } + + /* Check to see if the array variable was changed */ + if (strcmp((tablePtr->arrayVar ? tablePtr->arrayVar : ""), + (oldVar ? oldVar : ""))) { + /* only do the following if arrayVar is our data source */ + if (tablePtr->dataSource & DATA_ARRAY) { + /* + * ensure that the cache will flush later + * so it gets the new values + */ + oldCaching = !(tablePtr->caching); + } + /* remove the trace on the old array variable if there was one */ + if (oldVar != NULL) + Tcl_UntraceVar(interp, oldVar, + TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, + (Tcl_VarTraceProc *)TableVarProc, (ClientData) tablePtr); + /* Check whether variable is an array and trace it if it is */ + if (tablePtr->arrayVar != NULL) { + /* does the variable exist as an array? */ + if (Tcl_SetVar2(interp, tablePtr->arrayVar, TEST_KEY, "", + TCL_GLOBAL_ONLY) == NULL) { + Tcl_DStringAppend(&error, "invalid variable value \"", -1); + Tcl_DStringAppend(&error, tablePtr->arrayVar, -1); + Tcl_DStringAppend(&error, "\": could not be made an array", + -1); + ckfree(tablePtr->arrayVar); + tablePtr->arrayVar = NULL; + tablePtr->dataSource &= ~DATA_ARRAY; + result = TCL_ERROR; + } else { + Tcl_UnsetVar2(interp, tablePtr->arrayVar, TEST_KEY, + TCL_GLOBAL_ONLY); + /* remove the effect of the evaluation */ + /* set a trace on the variable */ + Tcl_TraceVar(interp, tablePtr->arrayVar, + TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, + (Tcl_VarTraceProc *)TableVarProc, + (ClientData) tablePtr); + + /* only do the following if arrayVar is our data source */ + if (tablePtr->dataSource & DATA_ARRAY) { + /* get the current value of the selection */ + TableGetActiveBuf(tablePtr); + } + } + } + } + + /* Free oldVar if it was allocated */ + if (oldVar != NULL) ckfree(oldVar); + + if ((tablePtr->command && tablePtr->useCmd && !oldUse) || + (tablePtr->arrayVar && !(tablePtr->useCmd) && oldUse)) { + /* + * Our effective data source changed, so flush and + * retrieve new active buffer + */ + Table_ClearHashTable(tablePtr->cache); + Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); + TableGetActiveBuf(tablePtr); + forceUpdate = 1; + } else if (oldCaching != tablePtr->caching) { + /* + * Caching changed, so just clear the cache for safety + */ + Table_ClearHashTable(tablePtr->cache); + Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); + forceUpdate = 1; + } + + /* + * Set up the default column width and row height + */ + Tk_GetFontMetrics(tablePtr->defaultTag.tkfont, &fm); + tablePtr->charWidth = Tk_TextWidth(tablePtr->defaultTag.tkfont, "0", 1); + tablePtr->charHeight = fm.linespace + 2; + + if (tablePtr->insertWidth <= 0) { + tablePtr->insertWidth = 2; + } + if (tablePtr->insertBorderWidth > tablePtr->insertWidth/2) { + tablePtr->insertBorderWidth = tablePtr->insertWidth/2; + } + tablePtr->highlightWidth = MAX(0,tablePtr->highlightWidth); + + /* + * Ensure that certain values are within proper constraints + */ + tablePtr->rows = MAX(1, tablePtr->rows); + tablePtr->cols = MAX(1, tablePtr->cols); + tablePtr->padX = MAX(0, tablePtr->padX); + tablePtr->padY = MAX(0, tablePtr->padY); + tablePtr->ipadX = MAX(0, tablePtr->ipadX); + tablePtr->ipadY = MAX(0, tablePtr->ipadY); + tablePtr->maxReqCols = MAX(0, tablePtr->maxReqCols); + tablePtr->maxReqRows = MAX(0, tablePtr->maxReqRows); + CONSTRAIN(tablePtr->titleRows, 0, tablePtr->rows); + CONSTRAIN(tablePtr->titleCols, 0, tablePtr->cols); + + /* + * Handle change of default border style + * The default borderwidth must be >= 0. + */ + if (tablePtr->drawMode & (DRAW_MODE_SINGLE|DRAW_MODE_FAST)) { + /* + * When drawing fast or single, the border must be <= 1. + * We have to do this after the normal configuration + * to base the borders off the first value given. + */ + tablePtr->defaultTag.bd[0] = MIN(1, tablePtr->defaultTag.bd[0]); + tablePtr->defaultTag.borders = 1; + ckfree((char *) tablePtr->defaultTag.borderStr); + tablePtr->defaultTag.borderStr = (char *) ckalloc(2); + strcpy(tablePtr->defaultTag.borderStr, + tablePtr->defaultTag.bd[0] ? "1" : "0"); + } + + /* + * Claim the selection if we've suddenly started exporting it and + * there is a selection to export. + */ + if (tablePtr->exportSelection && !oldExport && + (Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL)) { + Tk_OwnSelection(tablePtr->tkwin, XA_PRIMARY, TableLostSelection, + (ClientData) tablePtr); + } + + if ((tablePtr->titleRows < oldTitleRows) || + (tablePtr->titleCols < oldTitleCols)) { + /* + * Prevent odd movement due to new possible topleft index + */ + if (tablePtr->titleRows < oldTitleRows) + tablePtr->topRow -= oldTitleRows - tablePtr->titleRows; + if (tablePtr->titleCols < oldTitleCols) + tablePtr->leftCol -= oldTitleCols - tablePtr->titleCols; + /* + * If our title area shrank, we need to check that the items + * within the new title area don't try to span outside it. + */ + TableSpanSanCheck(tablePtr); + } + + /* + * Only do the full reconfigure if absolutely necessary + */ + if (!forceUpdate) { + int i, dummy; + for (i = 0; i < objc-1; i += 2) { + if (Tcl_GetIndexFromObj(NULL, objv[i], updateOpts, "", 0, &dummy) + == TCL_OK) { + forceUpdate = 1; + break; + } + } + } + if (forceUpdate) { + /* + * Calculate the row and column starts + * Adjust the top left corner of the internal display + */ + TableAdjustParams(tablePtr); + /* reset the cursor */ + TableConfigCursor(tablePtr); + /* set up the background colour in the window */ + Tk_SetBackgroundFromBorder(tablePtr->tkwin, tablePtr->defaultTag.bg); + /* set the geometry and border */ + TableGeometryRequest(tablePtr); + Tk_SetInternalBorder(tablePtr->tkwin, tablePtr->highlightWidth); + /* invalidate the whole table */ + TableInvalidateAll(tablePtr, INV_HIGHLIGHT); + } + /* + * FIX this is goofy because the result could be munged by other + * functions. Could be improved. + */ + Tcl_ResetResult(interp); + if (result == TCL_ERROR) { + Tcl_AddErrorInfo(interp, "\t(configuring table widget)"); + Tcl_DStringResult(interp, &error); + } + Tcl_DStringFree(&error); + return result; +} +#ifdef HAVE_TCL84 +/* + *--------------------------------------------------------------------------- + * + * TableWorldChanged -- + * + * This procedure is called when the world has changed in some + * way and the widget needs to recompute all its graphics contexts + * and determine its new geometry. + * + * Results: + * None. + * + * Side effects: + * Entry will be relayed out and redisplayed. + * + *--------------------------------------------------------------------------- + */ + +static void +TableWorldChanged(instanceData) + ClientData instanceData; /* Information about widget. */ +{ + Table *tablePtr = (Table *) instanceData; + Tk_FontMetrics fm; + + /* + * Set up the default column width and row height + */ + Tk_GetFontMetrics(tablePtr->defaultTag.tkfont, &fm); + tablePtr->charWidth = Tk_TextWidth(tablePtr->defaultTag.tkfont, "0", 1); + tablePtr->charHeight = fm.linespace + 2; + + /* + * Recompute the window's geometry and arrange for it to be redisplayed. + */ + + TableAdjustParams(tablePtr); + TableGeometryRequest(tablePtr); + Tk_SetInternalBorder(tablePtr->tkwin, tablePtr->highlightWidth); + /* invalidate the whole table */ + TableInvalidateAll(tablePtr, INV_HIGHLIGHT); +} +#endif +/* + *-------------------------------------------------------------- + * + * TableEventProc -- + * This procedure is invoked by the Tk dispatcher for various + * events on tables. + * + * Results: + * None. + * + * Side effects: + * When the window gets deleted, internal structures get + * cleaned up. When it gets exposed, it is redisplayed. + * + *-------------------------------------------------------------- + */ +static void +TableEventProc(clientData, eventPtr) + ClientData clientData; /* Information about window. */ + XEvent *eventPtr; /* Information about event. */ +{ + Table *tablePtr = (Table *) clientData; + int row, col; + + switch (eventPtr->type) { + case MotionNotify: + if (!(tablePtr->resize & SEL_NONE) + && (tablePtr->bdcursor != None) && + TableAtBorder(tablePtr, eventPtr->xmotion.x, + eventPtr->xmotion.y, &row, &col) && + ((row>=0 && (tablePtr->resize & SEL_ROW)) || + (col>=0 && (tablePtr->resize & SEL_COL)))) { + /* + * The bordercursor is defined and we meet the criteria for + * being over a border. Set the cursor to border if not + * already done. + */ + if (!(tablePtr->flags & OVER_BORDER)) { + tablePtr->flags |= OVER_BORDER; + Tk_DefineCursor(tablePtr->tkwin, tablePtr->bdcursor); + } + } else if (tablePtr->flags & OVER_BORDER) { + tablePtr->flags &= ~OVER_BORDER; + if (tablePtr->cursor != None) { + Tk_DefineCursor(tablePtr->tkwin, tablePtr->cursor); + } else { + Tk_UndefineCursor(tablePtr->tkwin); + } +#ifdef TITLE_CURSOR + } else if (tablePtr->flags & (OVER_BORDER|OVER_TITLE)) { + Tk_Cursor cursor = tablePtr->cursor; + + //tablePtr->flags &= ~(OVER_BORDER|OVER_TITLE); + + if (tablePtr->titleCursor != None) { + TableWhatCell(tablePtr, eventPtr->xmotion.x, + eventPtr->xmotion.y, &row, &col); + if ((row < tablePtr->titleRows) || + (col < tablePtr->titleCols)) { + if (tablePtr->flags & OVER_TITLE) { + break; + } + tablePtr->flags |= OVER_TITLE; + cursor = tablePtr->titleCursor; + } + } + if (cursor != None) { + Tk_DefineCursor(tablePtr->tkwin, cursor); + } else { + Tk_UndefineCursor(tablePtr->tkwin); + } + } else if (tablePtr->titleCursor != None) { + Tk_Cursor cursor = tablePtr->cursor; + + TableWhatCell(tablePtr, eventPtr->xmotion.x, + eventPtr->xmotion.y, &row, &col); + if ((row < tablePtr->titleRows) || + (col < tablePtr->titleCols)) { + if (tablePtr->flags & OVER_TITLE) { + break; + } + tablePtr->flags |= OVER_TITLE; + cursor = tablePtr->titleCursor; + } +#endif + } + break; + + case Expose: + TableInvalidate(tablePtr, eventPtr->xexpose.x, eventPtr->xexpose.y, + eventPtr->xexpose.width, eventPtr->xexpose.height, + INV_HIGHLIGHT); + break; + + case DestroyNotify: + /* remove the command from the interpreter */ + if (tablePtr->tkwin != NULL) { + tablePtr->tkwin = NULL; + Tcl_DeleteCommandFromToken(tablePtr->interp, + tablePtr->widgetCmd); + } + + /* cancel any pending update or timer */ + if (tablePtr->flags & REDRAW_PENDING) { + Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); + tablePtr->flags &= ~REDRAW_PENDING; + } + Tcl_DeleteTimerHandler(tablePtr->cursorTimer); + Tcl_DeleteTimerHandler(tablePtr->flashTimer); + + Tcl_EventuallyFree((ClientData) tablePtr, + (Tcl_FreeProc *) TableDestroy); + break; + + case MapNotify: /* redraw table when remapped if it changed */ + if (tablePtr->flags & REDRAW_ON_MAP) { + tablePtr->flags &= ~REDRAW_ON_MAP; + Tcl_Preserve((ClientData) tablePtr); + TableAdjustParams(tablePtr); + TableInvalidateAll(tablePtr, INV_HIGHLIGHT); + Tcl_Release((ClientData) tablePtr); + } + break; + + case ConfigureNotify: + Tcl_Preserve((ClientData) tablePtr); + TableAdjustParams(tablePtr); + TableInvalidateAll(tablePtr, INV_HIGHLIGHT); + Tcl_Release((ClientData) tablePtr); + break; + + case FocusIn: + case FocusOut: + if (eventPtr->xfocus.detail != NotifyInferior) { + tablePtr->flags |= REDRAW_BORDER; + if (eventPtr->type == FocusOut) { + tablePtr->flags &= ~HAS_FOCUS; + } else { + tablePtr->flags |= HAS_FOCUS; + } + TableRedrawHighlight(tablePtr); + /* cancel the timer */ + TableConfigCursor(tablePtr); + } + break; + } +} + +/* + *---------------------------------------------------------------------- + * + * TableCmdDeletedProc -- + * + * This procedure is invoked when a widget command is deleted. If + * the widget isn't already in the process of being destroyed, + * this command destroys it. + * + * Results: + * None. + * + * Side effects: + * The widget is destroyed. + * + *---------------------------------------------------------------------- + */ +static void +TableCmdDeletedProc(ClientData clientData) +{ + Table *tablePtr = (Table *) clientData; + Tk_Window tkwin; + + /* + * This procedure could be invoked either because the window was + * destroyed and the command was then deleted (in which case tkwin + * is NULL) or because the command was deleted, and then this procedure + * destroys the widget. + */ + + if (tablePtr->tkwin != NULL) { + tkwin = tablePtr->tkwin; + tablePtr->tkwin = NULL; + Tk_DestroyWindow(tkwin); + } +} + +/* + *---------------------------------------------------------------------- + * + * TableRedrawHighlight -- + * Redraws just the highlight for the window + * + * Results: + * None. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ +static void +TableRedrawHighlight(Table *tablePtr) +{ + if ((tablePtr->flags & REDRAW_BORDER) && tablePtr->highlightWidth > 0) { + GC gc = Tk_GCForColor((tablePtr->flags & HAS_FOCUS) + ? tablePtr->highlightColorPtr : tablePtr->highlightBgColorPtr, + Tk_WindowId(tablePtr->tkwin)); + Tk_DrawFocusHighlight(tablePtr->tkwin, gc, tablePtr->highlightWidth, + Tk_WindowId(tablePtr->tkwin)); + } + tablePtr->flags &= ~REDRAW_BORDER; +} + +/* + *---------------------------------------------------------------------- + * + * TableRefresh -- + * Refreshes an area of the table based on the mode. + * row,col in real coords (0-based) + * + * Results: + * Will cause redraw for visible cells + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +TableRefresh(register Table *tablePtr, int row, int col, int mode) +{ + int x, y, w, h; + + if ((row < 0) || (col < 0)) { + /* + * Invalid coords passed in. This can happen when the "active" cell + * is refreshed, but doesn't really exist (row==-1 && col==-1). + */ + return; + } + if (mode & CELL) { + if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { + TableInvalidate(tablePtr, x, y, w, h, mode); + } + } else if (mode & ROW) { + /* get the position of the leftmost cell in the row */ + if ((mode & INV_FILL) && row < tablePtr->topRow) { + /* Invalidate whole table */ + TableInvalidateAll(tablePtr, mode); + } else if (TableCellVCoords(tablePtr, row, tablePtr->leftCol, + &x, &y, &w, &h, 0)) { + /* Invalidate from this row, maybe to end */ + TableInvalidate(tablePtr, 0, y, Tk_Width(tablePtr->tkwin), + (mode&INV_FILL)?Tk_Height(tablePtr->tkwin):h, mode); + } + } else if (mode & COL) { + /* get the position of the topmost cell on the column */ + if ((mode & INV_FILL) && col < tablePtr->leftCol) { + /* Invalidate whole table */ + TableInvalidateAll(tablePtr, mode); + } else if (TableCellVCoords(tablePtr, tablePtr->topRow, col, + &x, &y, &w, &h, 0)) { + /* Invalidate from this column, maybe to end */ + TableInvalidate(tablePtr, x, 0, + (mode&INV_FILL)?Tk_Width(tablePtr->tkwin):w, + Tk_Height(tablePtr->tkwin), mode); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TableGetGc -- + * Gets a GC corresponding to the tag structure passed. + * + * Results: + * Returns usable GC. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ +static void +TableGetGc(Display *display, Drawable d, TableTag *tagPtr, GC *tagGc) +{ + XGCValues gcValues; + gcValues.foreground = Tk_3DBorderColor(tagPtr->fg)->pixel; + gcValues.background = Tk_3DBorderColor(tagPtr->bg)->pixel; + gcValues.font = Tk_FontId(tagPtr->tkfont); + if (*tagGc == NULL) { + gcValues.graphics_exposures = False; + *tagGc = XCreateGC(display, d, + GCForeground|GCBackground|GCFont|GCGraphicsExposures, + &gcValues); + } else { + XChangeGC(display, *tagGc, GCForeground|GCBackground|GCFont, + &gcValues); + } +} + +#define TableFreeGc XFreeGC + +/* + *-------------------------------------------------------------- + * + * TableUndisplay -- + * This procedure removes the contents of a table window + * that have been moved offscreen. + * + * Results: + * Embedded windows can be unmapped. + * + * Side effects: + * Information disappears from the screen. + * + *-------------------------------------------------------------- + */ +static void +TableUndisplay(register Table *tablePtr) +{ + register int *seen = tablePtr->seen; + int row, col; + + /* We need to find out the true last cell, not considering spans */ + tablePtr->flags |= AVOID_SPANS; + TableGetLastCell(tablePtr, &row, &col); + tablePtr->flags &= ~AVOID_SPANS; + + if (seen[0] != -1) { + if (seen[0] < tablePtr->topRow) { + /* Remove now hidden rows */ + EmbWinUnmap(tablePtr, seen[0], MIN(seen[2],tablePtr->topRow-1), + seen[1], seen[3]); + /* Also account for the title area */ + EmbWinUnmap(tablePtr, seen[0], MIN(seen[2],tablePtr->topRow-1), + 0, tablePtr->titleCols-1); + } + if (seen[1] < tablePtr->leftCol) { + /* Remove now hidden cols */ + EmbWinUnmap(tablePtr, seen[0], seen[2], + seen[1], MAX(seen[3],tablePtr->leftCol-1)); + /* Also account for the title area */ + EmbWinUnmap(tablePtr, 0, tablePtr->titleRows-1, + seen[1], MAX(seen[3],tablePtr->leftCol-1)); + } + if (seen[2] > row) { + /* Remove now off-screen rows */ + EmbWinUnmap(tablePtr, MAX(seen[0],row+1), seen[2], + seen[1], seen[3]); + /* Also account for the title area */ + EmbWinUnmap(tablePtr, MAX(seen[0],row+1), seen[2], + 0, tablePtr->titleCols-1); + } + if (seen[3] > col) { + /* Remove now off-screen cols */ + EmbWinUnmap(tablePtr, seen[0], seen[2], + MAX(seen[1],col+1), seen[3]); + /* Also account for the title area */ + EmbWinUnmap(tablePtr, 0, tablePtr->titleRows-1, + MAX(seen[1],col+1), seen[3]); + } + } + seen[0] = tablePtr->topRow; + seen[1] = tablePtr->leftCol; + seen[2] = row; + seen[3] = col; +} + +/* + * Generally we should be able to use XSetClipRectangles on X11, but + * the addition of Xft drawing to Tk 8.5+ completely ignores the clip + * rectangles. Thus turn it off for all cases until clip rectangles + * are known to be respected. [Bug 1805350] + */ +#if 1 || defined(MAC_TCL) || defined(UNDER_CE) || (defined(WIN32) && defined(TCL_THREADS)) || defined(MAC_OSX_TK) +#define NO_XSETCLIP +#endif +/* + *-------------------------------------------------------------- + * + * TableDisplay -- + * This procedure redraws the contents of a table window. + * The conditional code in this function is due to these factors: + * o Lack of XSetClipRectangles on Macintosh + * o Use of alternative routine for Windows + * + * Results: + * None. + * + * Side effects: + * Information appears on the screen. + * + *-------------------------------------------------------------- + */ +static void +TableDisplay(ClientData clientdata) +{ + register Table *tablePtr = (Table *) clientdata; + Tk_Window tkwin = tablePtr->tkwin; + Display *display = tablePtr->display; + Drawable window; +#ifdef NO_XSETCLIP + Drawable clipWind; +#elif defined(WIN32) + TkWinDrawable *twdPtr; + HDC dc; + HRGN clipR; +#else + XRectangle clipRect; +#endif + int rowFrom, rowTo, colFrom, colTo, + invalidX, invalidY, invalidWidth, invalidHeight, + x, y, width, height, itemX, itemY, itemW, itemH, + row, col, urow, ucol, hrow=0, hcol=0, cx, cy, cw, ch, borders, bd[6], + numBytes, new, boundW, boundH, maxW, maxH, cellType, + originX, originY, activeCell, shouldInvert, ipadx, ipady, padx, pady; + GC tagGc = NULL, topGc, bottomGc; + char *string = NULL; + char buf[INDEX_BUFSIZE]; + TableTag *tagPtr = NULL, *titlePtr, *selPtr, *activePtr, *flashPtr, + *rowPtr, *colPtr; + Tcl_HashEntry *entryPtr; + static XPoint rect[3] = { {0, 0}, {0, 0}, {0, 0} }; + Tcl_HashTable *colTagsCache = NULL; + Tcl_HashTable *drawnCache = NULL; + Tk_TextLayout textLayout = NULL; + TableEmbWindow *ewPtr; + Tk_FontMetrics fm; + Tk_Font ellFont = NULL; + char *ellipsis = NULL; + int ellLen = 0, useEllLen = 0, ellEast = 0; + + tablePtr->flags &= ~REDRAW_PENDING; + if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) { + return; + } + + boundW = Tk_Width(tkwin) - tablePtr->highlightWidth; + boundH = Tk_Height(tkwin) - tablePtr->highlightWidth; + + /* Constrain drawable to not include highlight borders */ + invalidX = MAX(tablePtr->highlightWidth, tablePtr->invalidX); + invalidY = MAX(tablePtr->highlightWidth, tablePtr->invalidY); + invalidWidth = MIN(tablePtr->invalidWidth, MAX(1, boundW-invalidX)); + invalidHeight = MIN(tablePtr->invalidHeight, MAX(1, boundH-invalidY)); + + ipadx = tablePtr->ipadX; + ipady = tablePtr->ipadY; + padx = tablePtr->padX; + pady = tablePtr->padY; + +#ifndef WIN32 + /* + * if we are using the slow drawing mode with a pixmap + * create the pixmap and adjust x && y for offset in pixmap + * FIX: Ignore slow mode for Win32 as the fast ClipRgn trick + * below does not work for bitmaps. + */ + if (tablePtr->drawMode == DRAW_MODE_SLOW) { + window = Tk_GetPixmap(display, Tk_WindowId(tkwin), + invalidWidth, invalidHeight, Tk_Depth(tkwin)); + } else +#endif + window = Tk_WindowId(tkwin); +#ifdef NO_XSETCLIP + clipWind = Tk_GetPixmap(display, window, + invalidWidth, invalidHeight, Tk_Depth(tkwin)); +#endif + + /* set up the permanent tag styles */ + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "title"); + titlePtr = (TableTag *) Tcl_GetHashValue(entryPtr); + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "sel"); + selPtr = (TableTag *) Tcl_GetHashValue(entryPtr); + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "active"); + activePtr = (TableTag *) Tcl_GetHashValue(entryPtr); + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, "flash"); + flashPtr = (TableTag *) Tcl_GetHashValue(entryPtr); + + /* We need to find out the true cell span, not considering spans */ + tablePtr->flags |= AVOID_SPANS; + /* find out the cells represented by the invalid region */ + TableWhatCell(tablePtr, invalidX, invalidY, &rowFrom, &colFrom); + TableWhatCell(tablePtr, invalidX+invalidWidth-1, + invalidY+invalidHeight-1, &rowTo, &colTo); + tablePtr->flags &= ~AVOID_SPANS; + +#ifdef DEBUG + tcl_dprintf(tablePtr->interp, "%d,%d => %d,%d", + rowFrom+tablePtr->rowOffset, colFrom+tablePtr->colOffset, + rowTo+tablePtr->rowOffset, colTo+tablePtr->colOffset); +#endif + + /* + * Initialize colTagsCache hash table to cache column tag names. + */ + colTagsCache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(colTagsCache, TCL_ONE_WORD_KEYS); + /* + * Initialize drawnCache hash table to cache drawn cells. + * This is necessary to prevent spanning cells being drawn multiple times. + */ + drawnCache = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(drawnCache, TCL_STRING_KEYS); + + /* + * Create the tag here. This will actually create a JoinTag + * That will handle the priority management of merging for us. + * We only need one allocated, and we'll reset it for each cell. + */ + tagPtr = TableNewTag(tablePtr); + + /* Cycle through the cells and display them */ + for (row = rowFrom; row <= rowTo; row++) { + /* + * are we in the 'dead zone' between the + * title rows and the first displayed row + */ + if (row < tablePtr->topRow && row >= tablePtr->titleRows) { + row = tablePtr->topRow; + } + + /* Cache the row in user terms */ + urow = row+tablePtr->rowOffset; + + /* Get the row tag once for all iterations of col */ + rowPtr = FindRowColTag(tablePtr, urow, ROW); + + for (col = colFrom; col <= colTo; col++) { + activeCell = 0; + /* + * Adjust to first viewable column if we are in the 'dead zone' + * between the title cols and the first displayed column. + */ + if (col < tablePtr->leftCol && col >= tablePtr->titleCols) { + col = tablePtr->leftCol; + } + + /* + * Get the coordinates for the cell before possible rearrangement + * of row,col due to spanning cells + */ + cellType = TableCellCoords(tablePtr, row, col, + &x, &y, &width, &height); + if (cellType == CELL_HIDDEN) { + /* + * width,height holds the real start row,col of the span. + * Put the use cell ref into a buffer for the hash lookups. + */ + TableMakeArrayIndex(width, height, buf); + Tcl_CreateHashEntry(drawnCache, buf, &new); + if (!new) { + /* Not new in the entry, so it's already drawn */ + continue; + } + hrow = row; hcol = col; + row = width-tablePtr->rowOffset; + col = height-tablePtr->colOffset; + TableCellVCoords(tablePtr, row, col, + &x, &y, &width, &height, 0); + /* We have to adjust the coords back onto the visual display */ + urow = row+tablePtr->rowOffset; + rowPtr = FindRowColTag(tablePtr, urow, ROW); + } + + /* Constrain drawn size to the visual boundaries */ + if (width > boundW-x) { width = boundW-x; } + if (height > boundH-y) { height = boundH-y; } + + /* Cache the col in user terms */ + ucol = col+tablePtr->colOffset; + + /* put the use cell ref into a buffer for the hash lookups */ + TableMakeArrayIndex(urow, ucol, buf); + if (cellType != CELL_HIDDEN) { + Tcl_CreateHashEntry(drawnCache, buf, &new); + } + + /* + * Make sure we start with a clean tag (set to table defaults). + */ + TableResetTag(tablePtr, tagPtr); + + /* + * Check to see if we have an embedded window in this cell. + */ + entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf); + if (entryPtr != NULL) { + ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); + + if (ewPtr->tkwin != NULL) { + /* Display embedded window instead of text */ + + /* if active, make it disabled to avoid + * unnecessary editing */ + if ((tablePtr->flags & HAS_ACTIVE) + && row == tablePtr->activeRow + && col == tablePtr->activeCol) { + tablePtr->flags |= ACTIVE_DISABLED; + } + + /* + * The EmbWinDisplay function may modify values in + * tagPtr, so reference those after this call. + */ + EmbWinDisplay(tablePtr, window, ewPtr, tagPtr, + x, y, width, height); + +#ifndef WIN32 + if (tablePtr->drawMode == DRAW_MODE_SLOW) { + /* Correctly adjust x && y with the offset */ + x -= invalidX; + y -= invalidY; + } +#endif + + Tk_Fill3DRectangle(tkwin, window, tagPtr->bg, x, y, width, + height, 0, TK_RELIEF_FLAT); + + /* border width for cell should now be properly set */ + borders = TableGetTagBorders(tagPtr, &bd[0], &bd[1], + &bd[2], &bd[3]); + bd[4] = (bd[0] + bd[1])/2; + bd[5] = (bd[2] + bd[3])/2; + + goto DrawBorder; + } + } + + /* + * Don't draw what won't be seen. + * Embedded windows handle this in EmbWinDisplay. + */ + if ((width <= 0) || (height <= 0)) { continue; } + +#ifndef WIN32 + if (tablePtr->drawMode == DRAW_MODE_SLOW) { + /* Correctly adjust x && y with the offset */ + x -= invalidX; + y -= invalidY; + } +#endif + + shouldInvert = 0; + /* + * Get the combined tag structure for the cell. + * First clear out a new tag structure that we will build in + * then add tags as we realize they belong. + * + * Tags have their own priorities which TableMergeTag will + * take into account when merging tags. + */ + + /* + * Merge colPtr if it exists + * let's see if we have the value cached already + * if not, run the findColTag routine and cache the value + */ + entryPtr = Tcl_CreateHashEntry(colTagsCache, (char *)ucol, &new); + if (new) { + colPtr = FindRowColTag(tablePtr, ucol, COL); + Tcl_SetHashValue(entryPtr, colPtr); + } else { + colPtr = (TableTag *) Tcl_GetHashValue(entryPtr); + } + if (colPtr != (TableTag *) NULL) { + TableMergeTag(tablePtr, tagPtr, colPtr); + } + /* Merge rowPtr if it exists */ + if (rowPtr != (TableTag *) NULL) { + TableMergeTag(tablePtr, tagPtr, rowPtr); + } + /* Am I in the titles */ + if (row < tablePtr->titleRows || col < tablePtr->titleCols) { + TableMergeTag(tablePtr, tagPtr, titlePtr); + } + /* Does this have a cell tag */ + entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); + if (entryPtr != NULL) { + TableMergeTag(tablePtr, tagPtr, + (TableTag *) Tcl_GetHashValue(entryPtr)); + } + /* is this cell active? */ + if ((tablePtr->flags & HAS_ACTIVE) && + (tablePtr->state == STATE_NORMAL) && + row == tablePtr->activeRow && col == tablePtr->activeCol) { + if (tagPtr->state == STATE_DISABLED) { + tablePtr->flags |= ACTIVE_DISABLED; + } else { + TableMergeTag(tablePtr, tagPtr, activePtr); + activeCell = 1; + tablePtr->flags &= ~ACTIVE_DISABLED; + } + } + /* is this cell selected? */ + if (Tcl_FindHashEntry(tablePtr->selCells, buf) != NULL) { + if (tablePtr->invertSelected && !activeCell) { + shouldInvert = 1; + } else { + TableMergeTag(tablePtr, tagPtr, selPtr); + } + } + /* if flash mode is on, is this cell flashing? */ + if (tablePtr->flashMode && + Tcl_FindHashEntry(tablePtr->flashCells, buf) != NULL) { + TableMergeTag(tablePtr, tagPtr, flashPtr); + } + + if (shouldInvert) { + TableInvertTag(tagPtr); + } + + /* + * Borders for cell should now be properly set + */ + borders = TableGetTagBorders(tagPtr, &bd[0], &bd[1], + &bd[2], &bd[3]); + bd[4] = (bd[0] + bd[1])/2; + bd[5] = (bd[2] + bd[3])/2; + + /* + * First fill in a blank rectangle. + */ + Tk_Fill3DRectangle(tkwin, window, tagPtr->bg, + x, y, width, height, 0, TK_RELIEF_FLAT); + + /* + * Correct the dimensions to enforce padding constraints + */ + width -= bd[0] + bd[1] + (2 * padx); + height -= bd[2] + bd[3] + (2 * pady); + + /* + * Don't draw what won't be seen, based on border constraints. + */ + if ((width <= 0) || (height <= 0)) { + /* + * Re-Correct the dimensions before border drawing + */ + width += bd[0] + bd[1] + (2 * padx); + height += bd[2] + bd[3] + (2 * pady); + goto DrawBorder; + } + + /* + * If an image is in the tag, draw it + */ + if (tagPtr->image != NULL) { + Tk_SizeOfImage(tagPtr->image, &itemW, &itemH); + /* Handle anchoring of image in cell space */ + switch (tagPtr->anchor) { + case TK_ANCHOR_NW: + case TK_ANCHOR_W: + case TK_ANCHOR_SW: /* western position */ + originX = itemX = 0; + break; + case TK_ANCHOR_N: + case TK_ANCHOR_S: + case TK_ANCHOR_CENTER: /* centered position */ + itemX = MAX(0, (itemW - width) / 2); + originX = MAX(0, (width - itemW) / 2); + break; + default: /* eastern position */ + itemX = MAX(0, itemW - width); + originX = MAX(0, width - itemW); + } + switch (tagPtr->anchor) { + case TK_ANCHOR_N: + case TK_ANCHOR_NE: + case TK_ANCHOR_NW: /* northern position */ + originY = itemY = 0; + break; + case TK_ANCHOR_W: + case TK_ANCHOR_E: + case TK_ANCHOR_CENTER: /* centered position */ + itemY = MAX(0, (itemH - height) / 2); + originY = MAX(0, (height - itemH) / 2); + break; + default: /* southern position */ + itemY = MAX(0, itemH - height); + originY = MAX(0, height - itemH); + } + Tk_RedrawImage(tagPtr->image, itemX, itemY, + MIN(itemW, width-originX), MIN(itemH, height-originY), + window, x + originX + bd[0] + padx, + y + originY + bd[2] + pady); + /* + * If we don't want to display the text as well, then jump. + */ + if (tagPtr->showtext == 0) { + /* + * Re-Correct the dimensions before border drawing + */ + width += bd[0] + bd[1] + (2 * padx); + height += bd[2] + bd[3] + (2 * pady); + goto DrawBorder; + } + } + + /* + * Get the GC for this particular blend of tags. + * This creates the GC if it never existed, otherwise it + * modifies the one we have, so we only need the one + */ + TableGetGc(display, window, tagPtr, &tagGc); + + /* if this is the active cell, use the buffer */ + if (activeCell) { + string = tablePtr->activeBuf; + } else { + /* Is there a value in the cell? If so, draw it */ + string = TableGetCellValue(tablePtr, urow, ucol); + } + +#ifdef TCL_UTF_MAX + /* + * We have to use strlen here because otherwise it stops + * at the first \x00 unicode char it finds (!= '\0'), + * although there can be more to the string than that + */ + numBytes = Tcl_NumUtfChars(string, (int) strlen(string)); +#else + numBytes = strlen(string); +#endif + + /* If there is a string, show it */ + if (activeCell || numBytes) { + register int x0 = x + bd[0] + padx; + register int y0 = y + bd[2] + pady; + + /* get the dimensions of the string */ + textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, + string, numBytes, + (tagPtr->wrap > 0) ? width : 0, tagPtr->justify, + (tagPtr->multiline > 0) ? 0 : TK_IGNORE_NEWLINES, + &itemW, &itemH); + + /* + * Set the origin coordinates of the string to draw using + * the anchor. origin represents the (x,y) coordinate of + * the lower left corner of the text box, relative to the + * internal (inside the border) window + */ + + /* set the X origin first */ + switch (tagPtr->anchor) { + case TK_ANCHOR_NW: + case TK_ANCHOR_W: + case TK_ANCHOR_SW: /* western position */ + originX = ipadx; + break; + case TK_ANCHOR_N: + case TK_ANCHOR_S: + case TK_ANCHOR_CENTER: /* centered position */ + originX = (width - itemW) / 2; + break; + default: /* eastern position */ + originX = width - itemW - ipadx; + } + + /* then set the Y origin */ + switch (tagPtr->anchor) { + case TK_ANCHOR_N: + case TK_ANCHOR_NE: + case TK_ANCHOR_NW: /* northern position */ + originY = ipady; + break; + case TK_ANCHOR_W: + case TK_ANCHOR_E: + case TK_ANCHOR_CENTER: /* centered position */ + originY = (height - itemH) / 2; + break; + default: /* southern position */ + originY = height - itemH - ipady; + } + + /* + * If this is the active cell and we are editing, + * ensure that the cursor will be displayed + */ + if (activeCell) { + Tk_CharBbox(textLayout, tablePtr->icursor, + &cx, &cy, &cw, &ch); + /* we have to fudge with maxW because of odd width + * determination for newlines at the end of a line */ + maxW = width - tablePtr->insertWidth + - (cx + MIN(tablePtr->charWidth, cw)); + maxH = height - (cy + ch); + if (originX < bd[0] - cx) { + /* cursor off cell to the left */ + /* use western positioning to cet cursor at left + * with slight variation to show some text */ + originX = bd[0] - cx + + MIN(cx, width - tablePtr->insertWidth); + } else if (originX > maxW) { + /* cursor off cell to the right */ + /* use eastern positioning to cet cursor at right */ + originX = maxW; + } + if (originY < bd[2] - cy) { + /* cursor before top of cell */ + /* use northern positioning to cet cursor at top */ + originY = bd[2] - cy; + } else if (originY > maxH) { + /* cursor beyond bottom of cell */ + /* use southern positioning to cet cursor at bottom */ + originY = maxH; + } + tablePtr->activeTagPtr = tagPtr; + tablePtr->activeX = originX; + tablePtr->activeY = originY; + } + + /* + * Use a clip rectangle only if necessary as it means + * updating the GC in the server which slows everything down. + * We can't fudge the width or height, just in case the user + * wanted empty pad space. + */ + if ((originX < 0) || (originY < 0) || + (originX+itemW > width) || (originY+itemH > height)) { + if (!activeCell + && (tagPtr->ellipsis != NULL) + && (tagPtr->wrap <= 0) + && (tagPtr->multiline <= 0) + ) { + /* + * Check which side to draw ellipsis on + */ + switch (tagPtr->anchor) { + case TK_ANCHOR_NE: + case TK_ANCHOR_E: + case TK_ANCHOR_SE: /* eastern position */ + ellEast = 0; + break; + default: /* western position */ + ellEast = 1; + } + if ((ellipsis != tagPtr->ellipsis) + || (ellFont != tagPtr->tkfont)) { + /* + * Different ellipsis from last cached + */ + ellFont = tagPtr->tkfont; + ellipsis = tagPtr->ellipsis; + ellLen = Tk_TextWidth(ellFont, + ellipsis, (int) strlen(ellipsis)); + Tk_GetFontMetrics(tagPtr->tkfont, &fm); + } + useEllLen = MIN(ellLen, width); + } else { + ellEast = 0; + useEllLen = 0; + } + + /* + * The text wants to overflow the boundaries of the + * displayed cell, so we must clip in some way + */ +#ifdef NO_XSETCLIP + /* + * This code is basically for the Macintosh. + * Copy the the current contents of the cell into the + * clipped window area. This keeps any fg/bg and image + * data intact. + * x0 - x == pad area + */ + XCopyArea(display, window, clipWind, tagGc, x0, y0, + width, height, x0 - x, y0 - y); + /* + * Now draw into the cell space on the special window. + * Don't use x,y base offset for clipWind. + */ + Tk_DrawTextLayout(display, clipWind, tagGc, textLayout, + x0 - x + originX, y0 - y + originY, 0, -1); + + if (useEllLen) { + /* + * Recopy area the ellipse covers (not efficient) + */ + XCopyArea(display, window, clipWind, tagGc, + x0 + (ellEast ? width - useEllLen : 0), y0, + useEllLen, height, + x0 - x + (ellEast ? width - useEllLen : 0), + y0 - y); + Tk_DrawChars(display, clipWind, tagGc, ellFont, + ellipsis, (int) strlen(ellipsis), + x0 - x + (ellEast ? width - useEllLen : 0), + y0 - y + originY + fm.ascent); + } + /* + * Now copy back only the area that we want the + * text to be drawn on. + */ + XCopyArea(display, clipWind, window, tagGc, + x0 - x, y0 - y, width, height, x0, y0); +#elif defined(WIN32) + /* + * This is evil, evil evil! but the XCopyArea + * doesn't work in all cases - Michael Teske. + * The general structure follows the comments below. + */ + twdPtr = (TkWinDrawable *) window; + dc = GetDC(twdPtr->window.handle); + + clipR = CreateRectRgn(x0 + (ellEast ? 0 : useEllLen), y0, + x0 + width - (ellEast ? useEllLen : 0), y0 + height); + + SelectClipRgn(dc, clipR); + DeleteObject(clipR); + /* OffsetClipRgn(dc, 0, 0); */ + + Tk_DrawTextLayout(display, window, tagGc, textLayout, + x0 + originX, y0 + originY, 0, -1); + + if (useEllLen) { + clipR = CreateRectRgn(x0, y0, x0 + width, y0 + height); + SelectClipRgn(dc, clipR); + DeleteObject(clipR); + Tk_DrawChars(display, window, tagGc, ellFont, + ellipsis, (int) strlen(ellipsis), + x0 + (ellEast? width-useEllLen : 0), + y0 + originY + fm.ascent); + } + SelectClipRgn(dc, NULL); + ReleaseDC(twdPtr->window.handle, dc); +#else + /* + * Use an X clipping rectangle. The clipping is the + * rectangle just for the actual text space (to allow + * for empty padding space). + */ + clipRect.x = x0 + (ellEast ? 0 : useEllLen); + clipRect.y = y0; + clipRect.width = width - (ellEast ? useEllLen : 0); + clipRect.height = height; + XSetClipRectangles(display, tagGc, 0, 0, &clipRect, 1, + Unsorted); + Tk_DrawTextLayout(display, window, tagGc, textLayout, + x0 + originX, + y0 + originY, 0, -1); + if (useEllLen) { + clipRect.x = x0; + clipRect.width = width; + XSetClipRectangles(display, tagGc, 0, 0, &clipRect, 1, + Unsorted); + Tk_DrawChars(display, window, tagGc, ellFont, + ellipsis, (int) strlen(ellipsis), + x0 + (ellEast? width-useEllLen : 0), + y0 + originY + fm.ascent); + } + XSetClipMask(display, tagGc, None); +#endif + } else { + Tk_DrawTextLayout(display, window, tagGc, textLayout, + x0 + originX, y0 + originY, 0, -1); + } + + /* if this is the active cell draw the cursor if it's on. + * this ignores clip rectangles. */ + if (activeCell && (tablePtr->flags & CURSOR_ON) && + (originY + cy + bd[2] + pady < height) && + (originX + cx + bd[0] + padx - + (tablePtr->insertWidth / 2) >= 0)) { + /* make sure it will fit in the box */ + maxW = MAX(0, originY + cy + bd[2] + pady); + maxH = MIN(ch, height - maxW + bd[2] + pady); + Tk_Fill3DRectangle(tkwin, window, tablePtr->insertBg, + x0 + originX + cx - (tablePtr->insertWidth/2), + y + maxW, tablePtr->insertWidth, + maxH, 0, TK_RELIEF_FLAT); + } + } + + /* + * Re-Correct the dimensions before border drawing + */ + width += bd[0] + bd[1] + (2 * padx); + height += bd[2] + bd[3] + (2 * pady); + + DrawBorder: + /* Draw the 3d border on the pixmap correctly offset */ + if (tablePtr->drawMode == DRAW_MODE_SINGLE) { + topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, TK_3D_DARK_GC); + /* draw a line with single pixel width */ + rect[0].x = x; + rect[0].y = y + height - 1; + rect[1].y = -height + 1; + rect[2].x = width - 1; + XDrawLines(display, window, topGc, rect, 3, CoordModePrevious); + } else if (tablePtr->drawMode == DRAW_MODE_FAST) { + /* + * This depicts a full 1 pixel border. + * + * Choose the GCs to get the best approximation + * to the desired drawing style. + */ + switch(tagPtr->relief) { + case TK_RELIEF_FLAT: + topGc = bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, + TK_3D_FLAT_GC); + break; + case TK_RELIEF_RAISED: + case TK_RELIEF_RIDGE: + topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, + TK_3D_LIGHT_GC); + bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, + TK_3D_DARK_GC); + break; + default: /* TK_RELIEF_SUNKEN TK_RELIEF_GROOVE */ + bottomGc = Tk_3DBorderGC(tkwin, tagPtr->bg, + TK_3D_LIGHT_GC); + topGc = Tk_3DBorderGC(tkwin, tagPtr->bg, + TK_3D_DARK_GC); + break; + } + + /* draw a line with single pixel width */ + rect[0].x = x + width - 1; + rect[0].y = y; + rect[1].y = height - 1; + rect[2].x = -width + 1; + XDrawLines(display, window, bottomGc, rect, 3, + CoordModePrevious); + rect[0].x = x; + rect[0].y = y + height - 1; + rect[1].y = -height + 1; + rect[2].x = width - 1; + XDrawLines(display, window, topGc, rect, 3, + CoordModePrevious); + } else { + if (borders > 1) { + if (bd[0]) { + Tk_3DVerticalBevel(tkwin, window, tagPtr->bg, + x, y, bd[0], height, + 1 /* left side */, tagPtr->relief); + } + if (bd[1]) { + Tk_3DVerticalBevel(tkwin, window, tagPtr->bg, + x + width - bd[1], y, bd[1], height, + 0 /* right side */, tagPtr->relief); + } + if ((borders == 4) && bd[2]) { + Tk_3DHorizontalBevel(tkwin, window, tagPtr->bg, + x, y, width, bd[2], + 1, 1, 1 /* top */, tagPtr->relief); + } + if ((borders == 4) && bd[3]) { + Tk_3DHorizontalBevel(tkwin, window, tagPtr->bg, + x, y + height - bd[3], width, bd[3], + 0, 0, 0 /* bottom */, tagPtr->relief); + } + } else if (borders == 1) { + Tk_Draw3DRectangle(tkwin, window, tagPtr->bg, x, y, + width, height, bd[0], tagPtr->relief); + } + } + + /* clean up the necessaries */ + if (tagPtr == tablePtr->activeTagPtr) { + /* + * This means it was the activeCell with text displayed. + * We buffer the active tag for the 'activate' command. + */ + tablePtr->activeTagPtr = TableNewTag(NULL); + memcpy((VOID *) tablePtr->activeTagPtr, + (VOID *) tagPtr, sizeof(TableTag)); + } + if (textLayout) { + Tk_FreeTextLayout(textLayout); + textLayout = NULL; + } + if (cellType == CELL_HIDDEN) { + /* the last cell was a hidden one, + * rework row stuff back to normal */ + row = hrow; col = hcol; + urow = row+tablePtr->rowOffset; + rowPtr = FindRowColTag(tablePtr, urow, ROW); + } + } + } + ckfree((char *) tagPtr); +#ifdef NO_XSETCLIP + Tk_FreePixmap(display, clipWind); +#endif + + /* Take care of removing embedded windows that are no longer in view */ + TableUndisplay(tablePtr); + +#ifndef WIN32 + /* copy over and delete the pixmap if we are in slow mode */ + if (tablePtr->drawMode == DRAW_MODE_SLOW) { + /* Get a default valued GC */ + TableGetGc(display, window, &(tablePtr->defaultTag), &tagGc); + XCopyArea(display, window, Tk_WindowId(tkwin), tagGc, 0, 0, + (unsigned) invalidWidth, (unsigned) invalidHeight, + invalidX, invalidY); + Tk_FreePixmap(display, window); + window = Tk_WindowId(tkwin); + } +#endif + + /* + * If we are at the end of the table, clear the area after the last + * row/col. We discount spans here because we just need the coords + * for the area that would be the last physical cell. + */ + tablePtr->flags |= AVOID_SPANS; + TableCellCoords(tablePtr, tablePtr->rows-1, tablePtr->cols-1, + &x, &y, &width, &height); + tablePtr->flags &= ~AVOID_SPANS; + + /* This should occur before moving pixmap, but this simplifies things + * + * Could use Tk_Fill3DRectangle instead of XFillRectangle + * for best compatibility, and XClearArea could be used on Unix + * for best speed, so this is the compromise w/o #ifdef's + */ + if (x+width < invalidX+invalidWidth) { + XFillRectangle(display, window, + Tk_3DBorderGC(tkwin, tablePtr->defaultTag.bg, TK_3D_FLAT_GC), + x+width, invalidY, (unsigned) invalidX+invalidWidth-x-width, + (unsigned) invalidHeight); + } + + if (y+height < invalidY+invalidHeight) { + XFillRectangle(display, window, + Tk_3DBorderGC(tkwin, tablePtr->defaultTag.bg, TK_3D_FLAT_GC), + invalidX, y+height, (unsigned) invalidWidth, + (unsigned) invalidY+invalidHeight-y-height); + } + + if (tagGc != NULL) { + TableFreeGc(display, tagGc); + } + TableRedrawHighlight(tablePtr); + /* + * Free the hash table used to cache evaluations. + */ + Tcl_DeleteHashTable(colTagsCache); + ckfree((char *) (colTagsCache)); + Tcl_DeleteHashTable(drawnCache); + ckfree((char *) (drawnCache)); +} + +/* + *---------------------------------------------------------------------- + * + * TableInvalidate -- + * Invalidates a rectangle and adds it to the total invalid rectangle + * waiting to be redrawn. If the INV_FORCE flag bit is set, + * it does an update instantly else waits until Tk is idle. + * + * Results: + * Will schedule table (re)display. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ +void +TableInvalidate(Table * tablePtr, int x, int y, + int w, int h, int flags) +{ + Tk_Window tkwin = tablePtr->tkwin; + int hl = tablePtr->highlightWidth; + int height = Tk_Height(tkwin); + int width = Tk_Width(tkwin); + + /* + * Make sure that the window hasn't been destroyed already. + * Avoid allocating 0 sized pixmaps which would be fatal, + * and check if rectangle is even on the screen. + */ + if ((tkwin == NULL) + || (w <= 0) || (h <= 0) || (x > width) || (y > height)) { + return; + } + + /* If not even mapped, wait for the remap to redraw all */ + if (!Tk_IsMapped(tkwin)) { + tablePtr->flags |= REDRAW_ON_MAP; + return; + } + + /* + * If no pending updates exist, then replace the rectangle. + * Otherwise find the bounding rectangle. + */ + if ((flags & INV_HIGHLIGHT) && + (x < hl || y < hl || x+w >= width-hl || y+h >= height-hl)) { + tablePtr->flags |= REDRAW_BORDER; + } + + if (tablePtr->flags & REDRAW_PENDING) { + tablePtr->invalidWidth = MAX(x + w, + tablePtr->invalidX+tablePtr->invalidWidth); + tablePtr->invalidHeight = MAX(y + h, + tablePtr->invalidY+tablePtr->invalidHeight); + if (tablePtr->invalidX > x) tablePtr->invalidX = x; + if (tablePtr->invalidY > y) tablePtr->invalidY = y; + tablePtr->invalidWidth -= tablePtr->invalidX; + tablePtr->invalidHeight -= tablePtr->invalidY; + /* Do we want to force this update out? */ + if (flags & INV_FORCE) { + Tcl_CancelIdleCall(TableDisplay, (ClientData) tablePtr); + TableDisplay((ClientData) tablePtr); + } + } else { + tablePtr->invalidX = x; + tablePtr->invalidY = y; + tablePtr->invalidWidth = w; + tablePtr->invalidHeight = h; + if (flags & INV_FORCE) { + TableDisplay((ClientData) tablePtr); + } else { + tablePtr->flags |= REDRAW_PENDING; + Tcl_DoWhenIdle(TableDisplay, (ClientData) tablePtr); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TableFlashEvent -- + * Called when the flash timer goes off. + * + * Results: + * Decrements all the entries in the hash table and invalidates + * any cells that expire, deleting them from the table. If the + * table is now empty, stops the timer, else reenables it. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static void +TableFlashEvent(ClientData clientdata) +{ + Table *tablePtr = (Table *) clientdata; + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + int entries, count, row, col; + + entries = 0; + for (entryPtr = Tcl_FirstHashEntry(tablePtr->flashCells, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + count = (int) Tcl_GetHashValue(entryPtr); + if (--count <= 0) { + /* get the cell address and invalidate that region only */ + TableParseArrayIndex(&row, &col, + Tcl_GetHashKey(tablePtr->flashCells, entryPtr)); + + /* delete the entry from the table */ + Tcl_DeleteHashEntry(entryPtr); + + TableRefresh(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, CELL); + } else { + Tcl_SetHashValue(entryPtr, (ClientData) count); + entries++; + } + } + + /* do I need to restart the timer */ + if (entries && tablePtr->flashMode) { + tablePtr->flashTimer = Tcl_CreateTimerHandler(250, TableFlashEvent, + (ClientData) tablePtr); + } else { + tablePtr->flashTimer = 0; + } +} + +/* + *---------------------------------------------------------------------- + * + * TableAddFlash -- + * Adds a flash on cell row,col (real coords) with the default timeout + * if flashing is enabled and flashtime > 0. + * + * Results: + * Cell will flash. + * + * Side effects: + * Will start flash timer if it didn't exist. + * + *---------------------------------------------------------------------- + */ +void +TableAddFlash(Table *tablePtr, int row, int col) +{ + char buf[INDEX_BUFSIZE]; + int dummy; + Tcl_HashEntry *entryPtr; + + if (!tablePtr->flashMode || tablePtr->flashTime < 1) { + return; + } + + /* create the array index in user coords */ + TableMakeArrayIndex(row+tablePtr->rowOffset, col+tablePtr->colOffset, buf); + + /* add the flash to the hash table */ + entryPtr = Tcl_CreateHashEntry(tablePtr->flashCells, buf, &dummy); + Tcl_SetHashValue(entryPtr, tablePtr->flashTime); + + /* now set the timer if it's not already going and invalidate the area */ + if (tablePtr->flashTimer == NULL) { + tablePtr->flashTimer = Tcl_CreateTimerHandler(250, TableFlashEvent, + (ClientData) tablePtr); + } +} + +/* + *---------------------------------------------------------------------- + * + * TableSetActiveIndex -- + * Sets the "active" index of the associated array to the current + * value of the active buffer. + * + * Results: + * None. + * + * Side effects: + * Traces on the array can cause side effects. + * + *---------------------------------------------------------------------- + */ +void +TableSetActiveIndex(register Table *tablePtr) +{ + if (tablePtr->arrayVar) { + tablePtr->flags |= SET_ACTIVE; + Tcl_SetVar2(tablePtr->interp, tablePtr->arrayVar, "active", + tablePtr->activeBuf, TCL_GLOBAL_ONLY); + tablePtr->flags &= ~SET_ACTIVE; + } +} + +/* + *---------------------------------------------------------------------- + * + * TableGetActiveBuf -- + * Get the current selection into the buffer and mark it as unedited. + * Set the position to the end of the string. + * + * Results: + * None. + * + * Side effects: + * tablePtr->activeBuf will change. + * + *---------------------------------------------------------------------- + */ +void +TableGetActiveBuf(register Table *tablePtr) +{ + char *data = ""; + + if (tablePtr->flags & HAS_ACTIVE) { + data = TableGetCellValue(tablePtr, + tablePtr->activeRow+tablePtr->rowOffset, + tablePtr->activeCol+tablePtr->colOffset); + } + + if (STREQ(tablePtr->activeBuf, data)) { + /* this forced SetActiveIndex is necessary if we change array vars and + * they happen to have these cells equal, we won't properly set the + * active index for the new array var unless we do this here */ + TableSetActiveIndex(tablePtr); + return; + } + /* is the buffer long enough */ + tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, + strlen(data)+1); + strcpy(tablePtr->activeBuf, data); + TableGetIcursor(tablePtr, "end", (int *)0); + tablePtr->flags &= ~TEXT_CHANGED; + TableSetActiveIndex(tablePtr); +} + +/* + *---------------------------------------------------------------------- + * + * TableVarProc -- + * This is the trace procedure associated with the Tcl array. No + * validation will occur here because this only triggers when the + * array value is directly set, and we can't maintain the old value. + * + * Results: + * Invalidates changed cell. + * + * Side effects: + * Creates/Updates entry in the cache if we are caching. + * + *---------------------------------------------------------------------- + */ +static char * +TableVarProc(clientData, interp, name, index, flags) + ClientData clientData; /* Information about table. */ + Tcl_Interp *interp; /* Interpreter containing variable. */ + char *name; /* Not used. */ + char *index; /* Not used. */ + int flags; /* Information about what happened. */ +{ + Table *tablePtr = (Table *) clientData; + int row, col, update = 1; + + /* This is redundant, as the name should always == arrayVar */ + name = tablePtr->arrayVar; + + /* is this the whole var being destroyed or just one cell being deleted */ + if ((flags & TCL_TRACE_UNSETS) && index == NULL) { + /* if this isn't the interpreter being destroyed reinstate the trace */ + if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { + Tcl_SetVar2(interp, name, TEST_KEY, "", TCL_GLOBAL_ONLY); + Tcl_UnsetVar2(interp, name, TEST_KEY, TCL_GLOBAL_ONLY); + Tcl_ResetResult(interp); + + /* set a trace on the variable */ + Tcl_TraceVar(interp, name, + TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY, + (Tcl_VarTraceProc *)TableVarProc, (ClientData) tablePtr); + + /* only do the following if arrayVar is our data source */ + if (tablePtr->dataSource & DATA_ARRAY) { + /* clear the selection buffer */ + TableGetActiveBuf(tablePtr); + /* flush any cache */ + Table_ClearHashTable(tablePtr->cache); + Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); + /* and invalidate the table */ + TableInvalidateAll(tablePtr, 0); + } + } + return (char *)NULL; + } + /* only continue if arrayVar is our data source */ + if (!(tablePtr->dataSource & DATA_ARRAY)) { + return (char *)NULL; + } + /* get the cell address and invalidate that region only. + * Make sure that it is a valid cell address. */ + if (STREQ("active", index)) { + if (tablePtr->flags & SET_ACTIVE) { + /* If we are already setting the active cell, the update + * will occur in other code */ + update = 0; + } else { + /* modified TableGetActiveBuf */ + CONST char *data = ""; + + row = tablePtr->activeRow; + col = tablePtr->activeCol; + if (tablePtr->flags & HAS_ACTIVE) + data = Tcl_GetVar2(interp, name, index, TCL_GLOBAL_ONLY); + if (!data) data = ""; + + if (STREQ(tablePtr->activeBuf, data)) { + return (char *)NULL; + } + tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, + strlen(data)+1); + strcpy(tablePtr->activeBuf, data); + /* set cursor to the last char */ + TableGetIcursor(tablePtr, "end", (int *)0); + tablePtr->flags |= TEXT_CHANGED; + } + } else if (TableParseArrayIndex(&row, &col, index) == 2) { + char buf[INDEX_BUFSIZE]; + + /* Make sure it won't trigger on array(2,3extrastuff) */ + TableMakeArrayIndex(row, col, buf); + if (strcmp(buf, index)) { + return (char *)NULL; + } + if (tablePtr->caching) { + Tcl_HashEntry *entryPtr; + int new; + char *val, *data; + + entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); + if (!new) { + data = (char *) Tcl_GetHashValue(entryPtr); + if (data) { ckfree(data); } + } + data = (char *) Tcl_GetVar2(interp, name, index, TCL_GLOBAL_ONLY); + if (data && *data != '\0') { + val = (char *)ckalloc(strlen(data)+1); + strcpy(val, data); + } else { + val = NULL; + } + Tcl_SetHashValue(entryPtr, val); + } + /* convert index to real coords */ + row -= tablePtr->rowOffset; + col -= tablePtr->colOffset; + /* did the active cell just update */ + if (row == tablePtr->activeRow && col == tablePtr->activeCol) { + TableGetActiveBuf(tablePtr); + } + /* Flash the cell */ + TableAddFlash(tablePtr, row, col); + } else { + return (char *)NULL; + } + + if (update) { + TableRefresh(tablePtr, row, col, CELL); + } + + return (char *)NULL; +} + +/* + *---------------------------------------------------------------------- + * + * TableGeometryRequest -- + * This procedure is invoked to request a new geometry from Tk. + * + * Results: + * None. + * + * Side effects: + * Geometry information is updated and a new requested size is + * registered for the widget. Internal border info is also set. + * + *---------------------------------------------------------------------- + */ +void +TableGeometryRequest(tablePtr) + register Table *tablePtr; +{ + int x, y; + + /* Do the geometry request + * If -width #cols was not specified or it is greater than the real + * number of cols, use maxWidth as a lower bound, with the other lower + * bound being the upper bound of the window's user-set width and the + * value of -maxwidth set by the programmer + * Vice versa for rows/height + */ + x = MIN((tablePtr->maxReqCols==0 || tablePtr->maxReqCols > tablePtr->cols)? + tablePtr->maxWidth : tablePtr->colStarts[tablePtr->maxReqCols], + tablePtr->maxReqWidth) + 2*tablePtr->highlightWidth; + y = MIN((tablePtr->maxReqRows==0 || tablePtr->maxReqRows > tablePtr->rows)? + tablePtr->maxHeight : tablePtr->rowStarts[tablePtr->maxReqRows], + tablePtr->maxReqHeight) + 2*tablePtr->highlightWidth; + Tk_GeometryRequest(tablePtr->tkwin, x, y); +} + +/* + *---------------------------------------------------------------------- + * + * TableAdjustActive -- + * This procedure is called by AdjustParams and CMD_ACTIVATE to + * move the active cell. + * + * Results: + * Old and new active cell indices will be invalidated. + * + * Side effects: + * If the old active cell index was edited, it will be saved. + * The active buffer will be updated. + * + *---------------------------------------------------------------------- + */ +void +TableAdjustActive(tablePtr) + register Table *tablePtr; /* Widget record for table */ +{ + if (tablePtr->flags & HAS_ACTIVE) { + /* + * Make sure the active cell has a reasonable real index + */ + CONSTRAIN(tablePtr->activeRow, 0, tablePtr->rows-1); + CONSTRAIN(tablePtr->activeCol, 0, tablePtr->cols-1); + } + + /* + * Check the new value of active cell against the original, + * Only invalidate if it changed. + */ + if (tablePtr->oldActRow == tablePtr->activeRow && + tablePtr->oldActCol == tablePtr->activeCol) { + return; + } + + if (tablePtr->oldActRow >= 0 && tablePtr->oldActCol >= 0) { + /* + * Set the value of the old active cell to the active buffer + * SetCellValue will check if the value actually changed + */ + if (tablePtr->flags & TEXT_CHANGED) { + /* WARNING an outside trace will be triggered here and if it + * calls something that causes TableAdjustParams to be called + * again, we are in data consistency trouble */ + /* HACK - turn TEXT_CHANGED off now to possibly avoid the + * above data inconsistency problem. */ + tablePtr->flags &= ~TEXT_CHANGED; + TableSetCellValue(tablePtr, + tablePtr->oldActRow + tablePtr->rowOffset, + tablePtr->oldActCol + tablePtr->colOffset, + tablePtr->activeBuf); + } + /* + * Invalidate the old active cell + */ + TableRefresh(tablePtr, tablePtr->oldActRow, tablePtr->oldActCol, CELL); + } + + /* + * Store the new active cell value into the active buffer + */ + TableGetActiveBuf(tablePtr); + + /* + * Invalidate the new active cell + */ + TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); + + /* + * Cache the old active row/col for the next time this is called + */ + tablePtr->oldActRow = tablePtr->activeRow; + tablePtr->oldActCol = tablePtr->activeCol; +} + +/* + *---------------------------------------------------------------------- + * + * TableAdjustParams -- + * Calculate the row and column starts. Adjusts the topleft corner + * variable to keep it within the screen range, out of the titles + * and keep the screen full make sure the selected cell is in the + * visible area checks to see if the top left cell has changed at + * all and invalidates the table if it has. + * + * Results: + * None. + * + * Side Effects: + * Number of rows can change if -rowstretchmode == fill. + * topRow && leftCol can change to fit display. + * activeRow/Col can change to ensure it is a valid cell. + * + *---------------------------------------------------------------------- + */ +void +TableAdjustParams(register Table *tablePtr) +{ + int topRow, leftCol, row, col, total, i, value, x, y, width, height, + w, h, hl, px, py, recalc, bd[4], + diff, unpreset, lastUnpreset, pad, lastPad, numPixels, + defColWidth, defRowHeight; + Tcl_HashEntry *entryPtr; + + /* + * Cache some values for many upcoming calculations + */ + hl = tablePtr->highlightWidth; + w = Tk_Width(tablePtr->tkwin) - (2 * hl); + h = Tk_Height(tablePtr->tkwin) - (2 * hl); + TableGetTagBorders(&(tablePtr->defaultTag), + &bd[0], &bd[1], &bd[2], &bd[3]); + px = bd[0] + bd[1] + (2 * tablePtr->padX); + py = bd[2] + bd[3] + (2 * tablePtr->padY); + + /* + * Account for whether default dimensions are in chars (>0) or + * pixels (<=0). Border and Pad space is added in here for convenience. + * + * When a value in pixels is specified, we take that exact amount, + * not adding in padding. + */ + if (tablePtr->defColWidth > 0) { + defColWidth = tablePtr->charWidth * tablePtr->defColWidth + px; + } else { + defColWidth = -(tablePtr->defColWidth); + } + if (tablePtr->defRowHeight > 0) { + defRowHeight = tablePtr->charHeight * tablePtr->defRowHeight + py; + } else { + defRowHeight = -(tablePtr->defRowHeight); + } + + /* + * Set up the arrays to hold the col pixels and starts. + * ckrealloc was fixed in 8.2.1 to handle NULLs, so we can't rely on it. + */ + if (tablePtr->colPixels) ckfree((char *) tablePtr->colPixels); + tablePtr->colPixels = (int *) ckalloc(tablePtr->cols * sizeof(int)); + if (tablePtr->colStarts) ckfree((char *) tablePtr->colStarts); + tablePtr->colStarts = (int *) ckalloc((tablePtr->cols+1) * sizeof(int)); + + /* + * Get all the preset columns and set their widths + */ + lastUnpreset = 0; + numPixels = 0; + unpreset = 0; + for (i = 0; i < tablePtr->cols; i++) { + entryPtr = Tcl_FindHashEntry(tablePtr->colWidths, (char *) i); + if (entryPtr == NULL) { + tablePtr->colPixels[i] = -1; + unpreset++; + lastUnpreset = i; + } else { + value = (int) Tcl_GetHashValue(entryPtr); + if (value > 0) { + tablePtr->colPixels[i] = value * tablePtr->charWidth + px; + } else { + /* + * When a value in pixels is specified, we take that exact + * amount, not adding in pad or border values. + */ + tablePtr->colPixels[i] = -value; + } + numPixels += tablePtr->colPixels[i]; + } + } + + /* + * Work out how much to pad each col depending on the mode. + */ + diff = w - numPixels - (unpreset * defColWidth); + total = 0; + + /* + * Now do the padding and calculate the column starts. + * Diff lower than 0 means we can't see the entire set of columns, + * thus no special stretching will occur & we optimize the calculation. + */ + if (diff <= 0) { + for (i = 0; i < tablePtr->cols; i++) { + if (tablePtr->colPixels[i] == -1) { + tablePtr->colPixels[i] = defColWidth; + } + tablePtr->colStarts[i] = total; + total += tablePtr->colPixels[i]; + } + } else { + switch (tablePtr->colStretch) { + case STRETCH_MODE_NONE: + pad = 0; + lastPad = 0; + break; + case STRETCH_MODE_UNSET: + if (unpreset == 0) { + pad = 0; + lastPad = 0; + } else { + pad = diff / unpreset; + lastPad = diff - pad * (unpreset - 1); + } + break; + case STRETCH_MODE_LAST: + pad = 0; + lastPad = diff; + lastUnpreset = tablePtr->cols - 1; + break; + default: /* STRETCH_MODE_ALL, but also FILL for cols */ + pad = diff / tablePtr->cols; + /* force it to be applied to the last column too */ + lastUnpreset = tablePtr->cols - 1; + lastPad = diff - pad * lastUnpreset; + } + + for (i = 0; i < tablePtr->cols; i++) { + if (tablePtr->colPixels[i] == -1) { + tablePtr->colPixels[i] = defColWidth + + ((i == lastUnpreset) ? lastPad : pad); + } else if (tablePtr->colStretch == STRETCH_MODE_ALL) { + tablePtr->colPixels[i] += (i == lastUnpreset) ? lastPad : pad; + } + tablePtr->colStarts[i] = total; + total += tablePtr->colPixels[i]; + } + } + tablePtr->colStarts[i] = tablePtr->maxWidth = total; + + /* + * The 'do' loop is only necessary for rows because of FILL mode + */ + recalc = 0; + do { + /* Set up the arrays to hold the row pixels and starts */ + /* FIX - this can be moved outside 'do' if you check >row size */ + if (tablePtr->rowPixels) ckfree((char *) tablePtr->rowPixels); + tablePtr->rowPixels = (int *) ckalloc(tablePtr->rows * sizeof(int)); + + /* get all the preset rows and set their heights */ + lastUnpreset = 0; + numPixels = 0; + unpreset = 0; + for (i = 0; i < tablePtr->rows; i++) { + entryPtr = Tcl_FindHashEntry(tablePtr->rowHeights, (char *) i); + if (entryPtr == NULL) { + tablePtr->rowPixels[i] = -1; + unpreset++; + lastUnpreset = i; + } else { + value = (int) Tcl_GetHashValue(entryPtr); + if (value > 0) { + tablePtr->rowPixels[i] = value * tablePtr->charHeight + py; + } else { + /* + * When a value in pixels is specified, we take that exact + * amount, not adding in pad or border values. + */ + tablePtr->rowPixels[i] = -value; + } + numPixels += tablePtr->rowPixels[i]; + } + } + + /* work out how much to pad each row depending on the mode */ + diff = h - numPixels - (unpreset * defRowHeight); + switch(tablePtr->rowStretch) { + case STRETCH_MODE_NONE: + pad = 0; + lastPad = 0; + break; + case STRETCH_MODE_UNSET: + if (unpreset == 0) { + pad = 0; + lastPad = 0; + } else { + pad = MAX(0,diff) / unpreset; + lastPad = MAX(0,diff) - pad * (unpreset - 1); + } + break; + case STRETCH_MODE_LAST: + pad = 0; + lastPad = MAX(0,diff); + /* force it to be applied to the last column too */ + lastUnpreset = tablePtr->rows - 1; + break; + case STRETCH_MODE_FILL: + pad = 0; + lastPad = diff; + if (diff && !recalc) { + tablePtr->rows += (diff/defRowHeight); + if (diff < 0 && tablePtr->rows <= 0) { + tablePtr->rows = 1; + } + lastUnpreset = tablePtr->rows - 1; + recalc = 1; + continue; + } else { + lastUnpreset = tablePtr->rows - 1; + recalc = 0; + } + break; + default: /* STRETCH_MODE_ALL */ + pad = MAX(0,diff) / tablePtr->rows; + /* force it to be applied to the last column too */ + lastUnpreset = tablePtr->rows - 1; + lastPad = MAX(0,diff) - pad * lastUnpreset; + } + } while (recalc); + + if (tablePtr->rowStarts) ckfree((char *) tablePtr->rowStarts); + tablePtr->rowStarts = (int *) ckalloc((tablePtr->rows+1)*sizeof(int)); + /* + * Now do the padding and calculate the row starts + */ + total = 0; + for (i = 0; i < tablePtr->rows; i++) { + if (tablePtr->rowPixels[i] == -1) { + tablePtr->rowPixels[i] = defRowHeight + + ((i==lastUnpreset)?lastPad:pad); + } else if (tablePtr->rowStretch == STRETCH_MODE_ALL) { + tablePtr->rowPixels[i] += (i==lastUnpreset)?lastPad:pad; + } + /* calculate the start of each row */ + tablePtr->rowStarts[i] = total; + total += tablePtr->rowPixels[i]; + } + tablePtr->rowStarts[i] = tablePtr->maxHeight = total; + + /* + * Make sure the top row and col have reasonable real indices + */ + CONSTRAIN(tablePtr->topRow, tablePtr->titleRows, tablePtr->rows-1); + CONSTRAIN(tablePtr->leftCol, tablePtr->titleCols, tablePtr->cols-1); + + /* + * If we don't have the info, don't bother to fix up the other parameters + */ + if (Tk_WindowId(tablePtr->tkwin) == None) { + tablePtr->oldTopRow = tablePtr->oldLeftCol = -1; + return; + } + + topRow = tablePtr->topRow; + leftCol = tablePtr->leftCol; + w += hl; + h += hl; + /* + * If we use this value of topRow, will we fill the window? + * if not, decrease it until we will, or until it gets to titleRows + * make sure we don't cut off the bottom row + */ + for (; topRow > tablePtr->titleRows; topRow--) { + if ((tablePtr->maxHeight-(tablePtr->rowStarts[topRow-1] - + tablePtr->rowStarts[tablePtr->titleRows])) > h) { + break; + } + } + /* + * If we use this value of topCol, will we fill the window? + * if not, decrease it until we will, or until it gets to titleCols + * make sure we don't cut off the left column + */ + for (; leftCol > tablePtr->titleCols; leftCol--) { + if ((tablePtr->maxWidth-(tablePtr->colStarts[leftCol-1] - + tablePtr->colStarts[tablePtr->titleCols])) > w) { + break; + } + } + + tablePtr->topRow = topRow; + tablePtr->leftCol = leftCol; + + /* + * Now work out where the bottom right is for scrollbar update and to test + * for one last stretch. Avoid the confusion that spans could cause for + * determining the last cell dimensions. + */ + tablePtr->flags |= AVOID_SPANS; + TableGetLastCell(tablePtr, &row, &col); + TableCellVCoords(tablePtr, row, col, &x, &y, &width, &height, 0); + tablePtr->flags &= ~AVOID_SPANS; + + /* + * Do we have scrollbars, if so, calculate and call the TCL functions In + * order to get the scrollbar to be completely full when the whole screen + * is shown and there are titles, we have to arrange for the scrollbar + * range to be 0 -> rows-titleRows etc. This leads to the position + * setting methods, toprow and leftcol, being relative to the titles, not + * absolute row and column numbers. + */ + if (tablePtr->yScrollCmd != NULL || tablePtr->xScrollCmd != NULL) { + Tcl_Interp *interp = tablePtr->interp; + char buf[INDEX_BUFSIZE]; + double first, last; + + /* + * We must hold onto the interpreter because the data referred to at + * tablePtr might be freed as a result of the call to Tcl_VarEval. + */ + Tcl_Preserve((ClientData) interp); + + /* Do we have a Y-scrollbar and rows to scroll? */ + if (tablePtr->yScrollCmd != NULL) { + if (row < tablePtr->titleRows) { + first = 0; + last = 1; + } else { + diff = tablePtr->rowStarts[tablePtr->titleRows]; + last = (double) (tablePtr->rowStarts[tablePtr->rows]-diff); + if (last <= 0.0) { + first = 0; + last = 1; + } else { + first = (tablePtr->rowStarts[topRow]-diff) / last; + last = (height+tablePtr->rowStarts[row]-diff) / last; + } + } + sprintf(buf, " %g %g", first, last); + if (Tcl_VarEval(interp, tablePtr->yScrollCmd, + buf, (char *)NULL) != TCL_OK) { + Tcl_AddErrorInfo(interp, + "\n\t(vertical scrolling command executed by table)"); + Tcl_BackgroundError(interp); + } + } + /* Do we have a X-scrollbar and cols to scroll? */ + if (tablePtr->xScrollCmd != NULL) { + if (col < tablePtr->titleCols) { + first = 0; + last = 1; + } else { + diff = tablePtr->colStarts[tablePtr->titleCols]; + last = (double) (tablePtr->colStarts[tablePtr->cols]-diff); + if (last <= 0.0) { + first = 0; + last = 1; + } else { + first = (tablePtr->colStarts[leftCol]-diff) / last; + last = (width+tablePtr->colStarts[col]-diff) / last; + } + } + sprintf(buf, " %g %g", first, last); + if (Tcl_VarEval(interp, tablePtr->xScrollCmd, + buf, (char *)NULL) != TCL_OK) { + Tcl_AddErrorInfo(interp, + "\n\t(horizontal scrolling command executed by table)"); + Tcl_BackgroundError(interp); + } + } + + Tcl_Release((ClientData) interp); + } + + /* + * Adjust the last row/col to fill empty space if it is visible. + * Do this after setting the scrollbars to not upset its calculations. + */ + if (row == tablePtr->rows-1 && tablePtr->rowStretch != STRETCH_MODE_NONE) { + diff = h-(y+height); + if (diff > 0) { + tablePtr->rowPixels[tablePtr->rows-1] += diff; + tablePtr->rowStarts[tablePtr->rows] += diff; + } + } + if (col == tablePtr->cols-1 && tablePtr->colStretch != STRETCH_MODE_NONE) { + diff = w-(x+width); + if (diff > 0) { + tablePtr->colPixels[tablePtr->cols-1] += diff; + tablePtr->colStarts[tablePtr->cols] += diff; + } + } + + TableAdjustActive(tablePtr); + + /* + * now check the new value of topleft cell against the originals, + * If they changed, invalidate the area, else leave it alone + */ + if (tablePtr->topRow != tablePtr->oldTopRow || + tablePtr->leftCol != tablePtr->oldLeftCol) { + /* set the old top row/col for the next time this function is called */ + tablePtr->oldTopRow = tablePtr->topRow; + tablePtr->oldLeftCol = tablePtr->leftCol; + /* only the upper corner title cells wouldn't change */ + TableInvalidateAll(tablePtr, 0); + } +} + +/* + *---------------------------------------------------------------------- + * + * TableCursorEvent -- + * Toggle the cursor status. Equivalent to EntryBlinkProc. + * + * Results: + * None. + * + * Side effects: + * The cursor will be switched off/on. + * + *---------------------------------------------------------------------- + */ +static void +TableCursorEvent(ClientData clientData) +{ + register Table *tablePtr = (Table *) clientData; + + if (!(tablePtr->flags & HAS_FOCUS) || (tablePtr->insertOffTime == 0) + || (tablePtr->flags & ACTIVE_DISABLED) + || (tablePtr->state != STATE_NORMAL)) { + return; + } + + if (tablePtr->cursorTimer != NULL) { + Tcl_DeleteTimerHandler(tablePtr->cursorTimer); + } + + tablePtr->cursorTimer = + Tcl_CreateTimerHandler((tablePtr->flags & CURSOR_ON) ? + tablePtr->insertOffTime : tablePtr->insertOnTime, + TableCursorEvent, (ClientData) tablePtr); + + /* Toggle the cursor */ + tablePtr->flags ^= CURSOR_ON; + + /* invalidate the cell */ + TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); +} + +/* + *---------------------------------------------------------------------- + * + * TableConfigCursor -- + * Configures the timer depending on the state of the table. + * Equivalent to EntryFocusProc. + * + * Results: + * None. + * + * Side effects: + * The cursor will be switched off/on. + * + *---------------------------------------------------------------------- + */ +void +TableConfigCursor(register Table *tablePtr) +{ + /* + * To have a cursor, we have to have focus and allow edits + */ + if ((tablePtr->flags & HAS_FOCUS) && (tablePtr->state == STATE_NORMAL) && + !(tablePtr->flags & ACTIVE_DISABLED)) { + /* + * Turn the cursor ON + */ + if (!(tablePtr->flags & CURSOR_ON)) { + tablePtr->flags |= CURSOR_ON; + /* + * Only refresh when we toggled cursor + */ + TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, + CELL); + } + + /* set up the first timer */ + if (tablePtr->insertOffTime != 0) { + /* make sure nothing existed */ + Tcl_DeleteTimerHandler(tablePtr->cursorTimer); + tablePtr->cursorTimer = + Tcl_CreateTimerHandler(tablePtr->insertOnTime, + TableCursorEvent, (ClientData) tablePtr); + } + } else { + /* + * Turn the cursor OFF + */ + if ((tablePtr->flags & CURSOR_ON)) { + tablePtr->flags &= ~CURSOR_ON; + TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, + CELL); + } + + /* and disable the timer */ + if (tablePtr->cursorTimer != NULL) { + Tcl_DeleteTimerHandler(tablePtr->cursorTimer); + } + tablePtr->cursorTimer = NULL; + } + +} + +/* + *---------------------------------------------------------------------- + * + * TableFetchSelection -- + * This procedure is called back by Tk when the selection is + * requested by someone. It returns part or all of the selection + * in a buffer provided by the caller. + * + * Results: + * The return value is the number of non-NULL bytes stored + * at buffer. Buffer is filled (or partially filled) with a + * NULL-terminated string containing part or all of the selection, + * as given by offset and maxBytes. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static int +TableFetchSelection(clientData, offset, buffer, maxBytes) + ClientData clientData; /* Information about table widget. */ + int offset; /* Offset within selection of first + * character to be returned. */ + char *buffer; /* Location in which to place selection. */ + int maxBytes; /* Maximum number of bytes to place at buffer, + * not including terminating NULL. */ +{ + register Table *tablePtr = (Table *) clientData; + Tcl_Interp *interp = tablePtr->interp; + char *value, *data, *rowsep = tablePtr->rowSep, *colsep = tablePtr->colSep; + Tcl_DString selection; + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + int length, count, lastrow=0, needcs=0, r, c, listArgc, rslen=0, cslen=0; + int numcols, numrows; + CONST84 char **listArgv; + + /* if we are not exporting the selection || + * we have no data source, return */ + if (!tablePtr->exportSelection || + (tablePtr->dataSource == DATA_NONE)) { + return -1; + } + + /* First get a sorted list of the selected elements */ + Tcl_DStringInit(&selection); + for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + Tcl_DStringAppendElement(&selection, + Tcl_GetHashKey(tablePtr->selCells, entryPtr)); + } + value = TableCellSort(tablePtr, Tcl_DStringValue(&selection)); + Tcl_DStringFree(&selection); + + if (value == NULL || + Tcl_SplitList(interp, value, &listArgc, &listArgv) != TCL_OK) { + return -1; + } + Tcl_Free(value); + + Tcl_DStringInit(&selection); + rslen = (rowsep?(strlen(rowsep)):0); + cslen = (colsep?(strlen(colsep)):0); + numrows = numcols = 0; + for (count = 0; count < listArgc; count++) { + TableParseArrayIndex(&r, &c, listArgv[count]); + if (count) { + if (lastrow != r) { + lastrow = r; + needcs = 0; + if (rslen) { + Tcl_DStringAppend(&selection, rowsep, rslen); + } else { + Tcl_DStringEndSublist(&selection); + Tcl_DStringStartSublist(&selection); + } + ++numrows; + } else { + if (++needcs > numcols) + numcols = needcs; + } + } else { + lastrow = r; + needcs = 0; + if (!rslen) { + Tcl_DStringStartSublist(&selection); + } + } + data = TableGetCellValue(tablePtr, r, c); + if (cslen) { + if (needcs) { + Tcl_DStringAppend(&selection, colsep, cslen); + } + Tcl_DStringAppend(&selection, data, -1); + } else { + Tcl_DStringAppendElement(&selection, data); + } + } + if (!rslen && count) { + Tcl_DStringEndSublist(&selection); + } + Tcl_Free((char *) listArgv); + + if (tablePtr->selCmd != NULL) { + Tcl_DString script; + Tcl_DStringInit(&script); + ExpandPercents(tablePtr, tablePtr->selCmd, numrows+1, numcols+1, + Tcl_DStringValue(&selection), (char *)NULL, + listArgc, &script, CMD_ACTIVATE); + if (Tcl_GlobalEval(interp, Tcl_DStringValue(&script)) == TCL_ERROR) { + Tcl_AddErrorInfo(interp, + "\n (error in table selection command)"); + Tcl_BackgroundError(interp); + Tcl_DStringFree(&script); + Tcl_DStringFree(&selection); + return -1; + } else { + Tcl_DStringGetResult(interp, &selection); + } + Tcl_DStringFree(&script); + } + + length = Tcl_DStringLength(&selection); + + if (length == 0) + return -1; + + /* Copy the requested portion of the selection to the buffer. */ + count = length - offset; + if (count <= 0) { + count = 0; + } else { + if (count > maxBytes) { + count = maxBytes; + } + memcpy((VOID *) buffer, + (VOID *) (Tcl_DStringValue(&selection) + offset), + (size_t) count); + } + buffer[count] = '\0'; + Tcl_DStringFree(&selection); + return count; +} + +/* + *---------------------------------------------------------------------- + * + * TableLostSelection -- + * This procedure is called back by Tk when the selection is + * grabbed away from a table widget. + * + * Results: + * None. + * + * Side effects: + * The existing selection is unhighlighted, and the window is + * marked as not containing a selection. + * + *---------------------------------------------------------------------- + */ +void +TableLostSelection(clientData) + ClientData clientData; /* Information about table widget. */ +{ + register Table *tablePtr = (Table *) clientData; + + if (tablePtr->exportSelection) { + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + int row, col; + + /* Same as SEL CLEAR ALL */ + for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + TableParseArrayIndex(&row, &col, + Tcl_GetHashKey(tablePtr->selCells,entryPtr)); + Tcl_DeleteHashEntry(entryPtr); + TableRefresh(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, CELL); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TableRestrictProc -- + * A Tk_RestrictProc used by TableValidateChange to eliminate any + * extra key input events in the event queue that + * have a serial number no less than a given value. + * + * Results: + * Returns either TK_DISCARD_EVENT or TK_DEFER_EVENT. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static Tk_RestrictAction +TableRestrictProc(serial, eventPtr) + ClientData serial; + XEvent *eventPtr; +{ + if ((eventPtr->type == KeyRelease || eventPtr->type == KeyPress) && + ((eventPtr->xany.serial-(unsigned int)serial) > 0)) { + return TK_DEFER_EVENT; + } else { + return TK_PROCESS_EVENT; + } +} + +/* + *-------------------------------------------------------------- + * + * TableValidateChange -- + * This procedure is invoked when any character is added or + * removed from the table widget, or a set has triggered validation. + * + * Results: + * TCL_OK if the validatecommand accepts the new string, + * TCL_BREAK if the validatecommand rejects the new string, + * TCL_ERROR if any problems occured with validatecommand. + * + * Side effects: + * The insertion/deletion may be aborted, and the + * validatecommand might turn itself off (if an error + * or loop condition arises). + * + *-------------------------------------------------------------- + */ +int +TableValidateChange(tablePtr, r, c, old, new, index) + register Table *tablePtr; /* Table that needs validation. */ + int r, c; /* row,col index of cell in user coords */ + char *old; /* current value of cell */ + char *new; /* potential new value of cell */ + int index; /* index of insert/delete, -1 otherwise */ +{ + register Tcl_Interp *interp = tablePtr->interp; + int code, bool; + Tk_RestrictProc *rstrct; + ClientData cdata; + Tcl_DString script; + + if (tablePtr->valCmd == NULL || tablePtr->validate == 0) { + return TCL_OK; + } + + /* Magic code to make this bit of code UI synchronous in the face of + * possible new key events */ + XSync(tablePtr->display, False); + rstrct = Tk_RestrictEvents(TableRestrictProc, (ClientData) + NextRequest(tablePtr->display), &cdata); + + /* + * If we're already validating, then we're hitting a loop condition + * Return and set validate to 0 to disallow further validations + * and prevent current validation from finishing + */ + if (tablePtr->flags & VALIDATING) { + tablePtr->validate = 0; + return TCL_OK; + } + tablePtr->flags |= VALIDATING; + + /* Now form command string and run through the -validatecommand */ + Tcl_DStringInit(&script); + ExpandPercents(tablePtr, tablePtr->valCmd, r, c, old, new, index, &script, + CMD_VALIDATE); + code = Tcl_GlobalEval(tablePtr->interp, Tcl_DStringValue(&script)); + Tcl_DStringFree(&script); + + if (code != TCL_OK && code != TCL_RETURN) { + Tcl_AddErrorInfo(interp, + "\n\t(in validation command executed by table)"); + Tcl_BackgroundError(interp); + code = TCL_ERROR; + } else if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp), + &bool) != TCL_OK) { + Tcl_AddErrorInfo(interp, + "\n\tboolean not returned by validation command"); + Tcl_BackgroundError(interp); + code = TCL_ERROR; + } else { + code = (bool) ? TCL_OK : TCL_BREAK; + } + Tcl_SetObjResult(interp, Tcl_NewObj()); + + /* + * If ->validate has become VALIDATE_NONE during the validation, + * it means that a loop condition almost occured. Do not allow + * this validation result to finish. + */ + if (tablePtr->validate == 0) { + code = TCL_ERROR; + } + + /* If validate will return ERROR, then disallow further validations */ + if (code == TCL_ERROR) { + tablePtr->validate = 0; + } + + Tk_RestrictEvents(rstrct, cdata, &cdata); + tablePtr->flags &= ~VALIDATING; + + return code; +} + +/* + *-------------------------------------------------------------- + * + * ExpandPercents -- + * Given a command and an event, produce a new command + * by replacing % constructs in the original command + * with information from the X event. + * + * Results: + * The new expanded command is appended to the dynamic string + * given by dsPtr. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ +void +ExpandPercents(tablePtr, before, r, c, old, new, index, dsPtr, cmdType) + Table *tablePtr; /* Table that needs validation. */ + char *before; /* Command containing percent + * expressions to be replaced. */ + int r, c; /* row,col index of cell */ + char *old; /* current value of cell */ + char *new; /* potential new value of cell */ + int index; /* index of insert/delete */ + Tcl_DString *dsPtr; /* Dynamic string in which to append + * new command. */ + int cmdType; /* type of command to make %-subs for */ +{ + int length, spaceNeeded, cvtFlags; +#ifdef TCL_UTF_MAX + Tcl_UniChar ch; +#else + char ch; +#endif + char *string, buf[INDEX_BUFSIZE]; + + /* This returns the static value of the string as set in the array */ + if (old == NULL && cmdType == CMD_VALIDATE) { + old = TableGetCellValue(tablePtr, r, c); + } + + while (1) { + if (*before == '\0') { + break; + } + /* + * Find everything up to the next % character and append it + * to the result string. + */ + + string = before; +#ifdef TCL_UTF_MAX + /* No need to convert '%', as it is in ascii range */ + string = (char *) Tcl_UtfFindFirst(before, '%'); +#else + string = strchr(before, '%'); +#endif + if (string == (char *) NULL) { + Tcl_DStringAppend(dsPtr, before, -1); + break; + } else if (string != before) { + Tcl_DStringAppend(dsPtr, before, string-before); + before = string; + } + + /* + * There's a percent sequence here. Process it. + */ + + before++; /* skip over % */ + if (*before != '\0') { +#ifdef TCL_UTF_MAX + before += Tcl_UtfToUniChar(before, &ch); +#else + ch = before[0]; + before++; +#endif + } else { + ch = '%'; + } + switch (ch) { + case 'c': + sprintf(buf, "%d", c); + string = buf; + break; + case 'C': /* index of cell */ + TableMakeArrayIndex(r, c, buf); + string = buf; + break; + case 'r': + sprintf(buf, "%d", r); + string = buf; + break; + case 'i': /* index of cursor OR |number| of cells selected */ + sprintf(buf, "%d", index); + string = buf; + break; + case 's': /* Current cell value */ + string = old; + break; + case 'S': /* Potential new value of cell */ + string = (new?new:old); + break; + case 'W': /* widget name */ + string = Tk_PathName(tablePtr->tkwin); + break; + default: +#ifdef TCL_UTF_MAX + length = Tcl_UniCharToUtf(ch, buf); +#else + buf[0] = ch; + length = 1; +#endif + buf[length] = '\0'; + string = buf; + break; + } + + spaceNeeded = Tcl_ScanElement(string, &cvtFlags); + length = Tcl_DStringLength(dsPtr); + Tcl_DStringSetLength(dsPtr, length + spaceNeeded); + spaceNeeded = Tcl_ConvertElement(string, + Tcl_DStringValue(dsPtr) + length, + cvtFlags | TCL_DONT_USE_BRACES); + Tcl_DStringSetLength(dsPtr, length + spaceNeeded); + } + Tcl_DStringAppend(dsPtr, "", 1); +} + +/* Function to call on loading the Table module */ + +#ifdef BUILD_Tktable +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLEXPORT +#endif +#ifdef MAC_TCL +#pragma export on +#endif +EXTERN int +Tktable_Init(interp) + Tcl_Interp *interp; +{ + /* This defines the static chars tkTable(Safe)InitScript */ +#include "tkTableInitScript.h" + + if ( +#ifdef USE_TCL_STUBS + Tcl_InitStubs(interp, "8.0", 0) +#else + Tcl_PkgRequire(interp, "Tcl", "8.0", 0) +#endif + == NULL) { + return TCL_ERROR; + } + if ( +#ifdef USE_TK_STUBS + Tk_InitStubs(interp, "8.0", 0) +#else +# if (TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 0) + /* We require 8.0 exact because of the Unicode in 8.1+ */ + Tcl_PkgRequire(interp, "Tk", "8.0", 1) +# else + Tcl_PkgRequire(interp, "Tk", "8.0", 0) +# endif +#endif + == NULL) { + return TCL_ERROR; + } + if (Tcl_PkgProvide(interp, "Tktable", PACKAGE_VERSION) != TCL_OK) { + return TCL_ERROR; + } + Tcl_CreateObjCommand(interp, TBL_COMMAND, Tk_TableObjCmd, + (ClientData) Tk_MainWindow(interp), + (Tcl_CmdDeleteProc *) NULL); + + /* + * The init script can't make certain calls in a safe interpreter, + * so we always have to use the embedded runtime for it + */ + return Tcl_Eval(interp, Tcl_IsSafe(interp) ? + tkTableSafeInitScript : tkTableInitScript); +} + +EXTERN int +Tktable_SafeInit(interp) + Tcl_Interp *interp; +{ + return Tktable_Init(interp); +} +#ifdef MAC_TCL +#pragma export reset +#endif + +#ifdef WIN32 +/* + *---------------------------------------------------------------------- + * + * DllEntryPoint -- + * + * This wrapper function is used by Windows to invoke the + * initialization code for the DLL. If we are compiling + * with Visual C++, this routine will be renamed to DllMain. + * routine. + * + * Results: + * Returns TRUE; + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +BOOL APIENTRY +DllEntryPoint(hInst, reason, reserved) + HINSTANCE hInst; /* Library instance handle. */ + DWORD reason; /* Reason this function is being called. */ + LPVOID reserved; /* Not used. */ +{ + return TRUE; +} +#endif diff --git a/tktable/generic/tkTable.h b/tktable/generic/tkTable.h new file mode 100644 index 0000000..cfb83e7 --- /dev/null +++ b/tktable/generic/tkTable.h @@ -0,0 +1,658 @@ +/* + * tkTable.h -- + * + * This is the header file for the module that implements + * table widgets for the Tk toolkit. + * + * Copyright (c) 1997-2002 Jeffrey Hobbs + * + * See the file "license.txt" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tkTable.h,v 1.17 2004/07/20 20:46:21 hobbs Exp $ + */ + +#ifndef _TKTABLE_H_ +#define _TKTABLE_H_ + +#include +#include +#include +#include +#ifdef MAC_TCL +# include +#else +# include +#endif /* MAC_TCL */ + +#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 0) /* Tcl8.0 stuff */ +#define Tcl_GetString(objPtr) Tcl_GetStringFromObj(objPtr, (int *)NULL) +#endif + +#if (TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) +# define HAVE_TCL84 +#endif + +/* + * Tcl/Tk 8.4 introduced better CONST-ness in the APIs, but we use CONST84 in + * some cases for compatibility with earlier Tcl headers to prevent warnings. + */ +#ifndef CONST84 +# define CONST84 +#endif + +/* This EXTERN declaration is needed for Tcl < 8.0.3 */ +#ifndef EXTERN +# ifdef __cplusplus +# define EXTERN extern "C" +# else +# define EXTERN extern +# endif +#endif + +#ifdef TCL_STORAGE_CLASS +# undef TCL_STORAGE_CLASS +#endif +#ifdef BUILD_Tktable +# define TCL_STORAGE_CLASS DLLEXPORT +#else +# define TCL_STORAGE_CLASS DLLIMPORT +#endif + +#ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +# include +# undef WIN32_LEAN_AND_MEAN +/* VC++ has an entry point called DllMain instead of DllEntryPoint */ +# if defined(_MSC_VER) +# define DllEntryPoint DllMain +# endif +#endif + +#if defined(WIN32) || defined(MAC_TCL) || defined(MAC_OSX_TK) +/* XSync call defined in the internals for some reason */ +# ifndef XSync +# define XSync(display, bool) {display->request++;} +# endif +#endif /* defn of XSync */ + +#ifndef NORMAL_BG +# ifdef WIN32 +# define NORMAL_BG "SystemButtonFace" +# define ACTIVE_BG NORMAL_BG +# define SELECT_BG "SystemHighlight" +# define SELECT_FG "SystemHighlightText" +# define DISABLED "SystemDisabledText" +# define HIGHLIGHT "SystemWindowFrame" +# define DEF_TABLE_FONT "{MS Sans Serif} 8" +# elif defined(MAC_TCL) || defined(MAC_OSX_TK) +# define NORMAL_BG "systemWindowBody" +# define ACTIVE_BG "#ececec" +# define SELECT_BG "systemHighlight" +# define SELECT_FG "systemHighlightText" +# define DISABLED "#a3a3a3" +# define HIGHLIGHT "Black" +# define DEF_TABLE_FONT "Helvetica 12" +# else +# define NORMAL_BG "#d9d9d9" +# define ACTIVE_BG "#fcfcfc" +# define SELECT_BG "#c3c3c3" +# define SELECT_FG "Black" +# define DISABLED "#a3a3a3" +# define HIGHLIGHT "Black" +# define DEF_TABLE_FONT "Helvetica -12" +# endif +#endif /* NORMAL_BG */ + +#define MAX(A,B) (((A)>(B))?(A):(B)) +#define MIN(A,B) (((A)>(B))?(B):(A)) +#define BETWEEN(val,min,max) ( ((val)<(min)) ? (min) : \ + ( ((val)>(max)) ? (max) : (val) ) ) +#define CONSTRAIN(val,min,max) if ((val) < (min)) { (val) = (min); } \ + else if ((val) > (max)) { (val) = (max); } +#define STREQ(s1, s2) (strcmp((s1), (s2)) == 0) +#define ARSIZE(A) (sizeof(A)/sizeof(*A)) +#define INDEX_BUFSIZE 32 /* max size of buffer for indices */ +#define TEST_KEY "#TEST KEY#" /* index for testing array existence */ + +/* + * Assigned bits of "flags" fields of Table structures, and what those + * bits mean: + * + * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has + * already been queued to redisplay the table. + * REDRAW_BORDER: Non-zero means 3-D border must be redrawn + * around window during redisplay. Normally + * only text portion needs to be redrawn. + * CURSOR_ON: Non-zero means insert cursor is displayed at + * present. 0 means it isn't displayed. + * TEXT_CHANGED: Non-zero means the active cell text is being edited. + * HAS_FOCUS: Non-zero means this window has the input focus. + * HAS_ACTIVE: Non-zero means the active cell is set. + * HAS_ANCHOR: Non-zero means the anchor cell is set. + * BROWSE_CMD: Non-zero means we're evaluating the -browsecommand. + * VALIDATING: Non-zero means we are in a valCmd + * SET_ACTIVE: About to set the active array element internally + * ACTIVE_DISABLED: Non-zero means the active cell is -state disabled + * OVER_BORDER: Non-zero means we are over a table cell border + * REDRAW_ON_MAP: Forces a redraw on the unmap + * AVOID_SPANS: prevent cell spans from being used + * + * FIX - consider adding UPDATE_SCROLLBAR a la entry + */ +#define REDRAW_PENDING (1L<<0) +#define CURSOR_ON (1L<<1) +#define HAS_FOCUS (1L<<2) +#define TEXT_CHANGED (1L<<3) +#define HAS_ACTIVE (1L<<4) +#define HAS_ANCHOR (1L<<5) +#define BROWSE_CMD (1L<<6) +#define REDRAW_BORDER (1L<<7) +#define VALIDATING (1L<<8) +#define SET_ACTIVE (1L<<9) +#define ACTIVE_DISABLED (1L<<10) +#define OVER_BORDER (1L<<11) +#define REDRAW_ON_MAP (1L<<12) +#define AVOID_SPANS (1L<<13) + +/* Flags for TableInvalidate && TableRedraw */ +#define ROW (1L<<0) +#define COL (1L<<1) +#define CELL (1L<<2) + +#define CELL_BAD (1<<0) +#define CELL_OK (1<<1) +#define CELL_SPAN (1<<2) +#define CELL_HIDDEN (1<<3) +#define CELL_VIEWABLE (CELL_OK|CELL_SPAN) + +#define INV_FILL (1L<<3) /* use for Redraw when the affected + * row/col will affect neighbors */ +#define INV_FORCE (1L<<4) +#define INV_HIGHLIGHT (1L<<5) +#define INV_NO_ERR_MSG (1L<<5) /* Don't leave an error message */ + +/* These alter how the selection set/clear commands behave */ +#define SEL_ROW (1<<0) +#define SEL_COL (1<<1) +#define SEL_BOTH (1<<2) +#define SEL_CELL (1<<3) +#define SEL_NONE (1<<4) + +/* + * Definitions for tablePtr->dataSource, by bit + */ +#define DATA_NONE 0 +#define DATA_CACHE (1<<1) +#define DATA_ARRAY (1<<2) +#define DATA_COMMAND (1<<3) + +/* + * Definitions for configuring -borderwidth + */ +#define BD_TABLE 0 +#define BD_TABLE_TAG (1<<1) +#define BD_TABLE_WIN (1<<2) + +/* + * Possible state values for tags + */ +typedef enum { + STATE_UNUSED, STATE_UNKNOWN, STATE_HIDDEN, + STATE_NORMAL, STATE_DISABLED, STATE_ACTIVE, STATE_LAST +} TableState; + +/* + * Structure for use in parsing table commands/values. + * Accessor functions defined in tkTableUtil.c + */ +typedef struct { + char *name; /* name of the command/value */ + int value; /* >0 because 0 represents an error or proc */ +} Cmd_Struct; + +/* + * The tag structure + */ +typedef struct { + Tk_3DBorder bg; /* background color */ + Tk_3DBorder fg; /* foreground color */ + + char * borderStr; /* border style */ + int borders; /* number of borders specified (1, 2 or 4) */ + int bd[4]; /* cell border width */ + + int relief; /* relief type */ + Tk_Font tkfont; /* Information about text font, or NULL. */ + Tk_Anchor anchor; /* default anchor point */ + char * imageStr; /* name of image */ + Tk_Image image; /* actual pointer to image, if any */ + TableState state; /* state of the cell */ + Tk_Justify justify; /* justification of text in the cell */ + int multiline; /* wrapping style of multiline text */ + int wrap; /* wrapping style of multiline text */ + int showtext; /* whether to display text over image */ + char * ellipsis; /* ellipsis to display on clipped text */ +} TableTag; + +/* The widget structure for the table Widget */ + +typedef struct { + /* basic information about the window and the interpreter */ + Tk_Window tkwin; + Display *display; + Tcl_Interp *interp; + Tcl_Command widgetCmd; /* Token for entry's widget command. */ + + /* + * Configurable Options + */ + int autoClear; + char *selectMode; /* single, browse, multiple, or extended */ + int selectType; /* row, col, both, or cell */ + int selectTitles; /* whether to do automatic title selection */ + int rows, cols; /* number of rows and columns */ + int defRowHeight; /* default row height in chars (positive) + * or pixels (negative) */ + int defColWidth; /* default column width in chars (positive) + * or pixels (negative) */ + int maxReqCols; /* the requested # cols to display */ + int maxReqRows; /* the requested # rows to display */ + int maxReqWidth; /* the maximum requested width in pixels */ + int maxReqHeight; /* the maximum requested height in pixels */ + char *arrayVar; /* name of traced array variable */ + char *rowSep; /* separator string to place between + * rows when getting selection */ + char *colSep; /* separator string to place between + * cols when getting selection */ + TableTag defaultTag; /* the default tag colors/fonts etc */ + char *yScrollCmd; /* the y-scroll command */ + char *xScrollCmd; /* the x-scroll command */ + char *browseCmd; /* the command that is called when the + * active cell changes */ + int caching; /* whether to cache values of table */ + char *command; /* A command to eval when get/set occurs + * for table values */ + int useCmd; /* Signals whether to use command or the + * array variable, will be 0 if command errs */ + char *selCmd; /* the command that is called to when a + * [selection get] call occurs for a table */ + char *valCmd; /* Command prefix to use when invoking + * validate command. NULL means don't + * invoke commands. Malloc'ed. */ + int validate; /* Non-zero means try to validate */ + Tk_3DBorder insertBg; /* the cursor color */ + Tk_Cursor cursor; /* the regular mouse pointer */ + Tk_Cursor bdcursor; /* the mouse pointer when over borders */ +#ifdef TITLE_CURSOR + Tk_Cursor titleCursor; /* the mouse pointer when over titles */ +#endif + int exportSelection; /* Non-zero means tie internal table + * to X selection. */ + TableState state; /* Normal or disabled. Table is read-only + * when disabled. */ + int insertWidth; /* Total width of insert cursor. */ + int insertBorderWidth; /* Width of 3-D border around insert cursor. */ + int insertOnTime; /* Number of milliseconds cursor should spend + * in "on" state for each blink. */ + int insertOffTime; /* Number of milliseconds cursor should spend + * in "off" state for each blink. */ + int invertSelected; /* Whether to draw selected cells swapping + * foreground and background */ + int colStretch; /* The way to stretch columns if the window + * is too large */ + int rowStretch; /* The way to stretch rows if the window is + * too large */ + int colOffset; /* X index of leftmost col in the display */ + int rowOffset; /* Y index of topmost row in the display */ + int drawMode; /* The mode to use when redrawing */ + int flashMode; /* Specifies whether flashing is enabled */ + int flashTime; /* The number of ms to flash a cell for */ + int resize; /* -resizeborders option for interactive + * resizing of borders */ + int sparse; /* Whether to use "sparse" arrays by + * deleting empty array elements (default) */ + char *rowTagCmd, *colTagCmd;/* script to eval for getting row/tag cmd */ + int highlightWidth; /* Width in pixels of highlight to draw + * around widget when it has the focus. + * <= 0 means don't draw a highlight. */ + XColor *highlightBgColorPtr;/* Color for drawing traversal highlight + * area when highlight is off. */ + XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ + char *takeFocus; /* Used only in Tcl to check if this + * widget will accept focus */ + int padX, padY; /* Extra space around text (pixels to leave + * on each side). Ignored for bitmaps and + * images. */ + int ipadX, ipadY; /* Space to leave empty around cell borders. + * This differs from pad* in that it is always + * present for the cell (except windows). */ + + /* + * Cached Information + */ +#ifdef TITLE_CURSOR + Tk_Cursor *lastCursorPtr; /* pointer to last cursor defined. */ +#endif + int titleRows, titleCols; /* the number of rows|cols to use as a title */ + /* these are kept in real coords */ + int topRow, leftCol; /* The topleft cell to display excluding the + * fixed title rows. This is just the + * config request. The actual cell used may + * be different to keep the screen full */ + int anchorRow, anchorCol; /* the row,col of the anchor cell */ + int activeRow, activeCol; /* the row,col of the active cell */ + int oldTopRow, oldLeftCol; /* cached by TableAdjustParams */ + int oldActRow, oldActCol; /* cached by TableAdjustParams */ + int icursor; /* The index of the insertion cursor in the + * active cell */ + int flags; /* An or'ed combination of flags concerning + * redraw/cursor etc. */ + int dataSource; /* where our data comes from: + * DATA_{NONE,CACHE,ARRAY,COMMAND} */ + int maxWidth, maxHeight; /* max width|height required in pixels */ + int charWidth, charHeight; /* size of a character in the default font */ + int *colPixels, *rowPixels; /* Array of the pixel widths/heights */ + int *colStarts, *rowStarts; /* Array of start pixels for rows|columns */ + int scanMarkX, scanMarkY; /* Used by "scan" and "border" to mark */ + int scanMarkRow, scanMarkCol;/* necessary information for dragto */ + /* values in these are kept in user coords */ + Tcl_HashTable *cache; /* value cache */ + + /* + * colWidths and rowHeights are indexed from 0, so always adjust numbers + * by the appropriate *Offset factor + */ + Tcl_HashTable *colWidths; /* hash table of non default column widths */ + Tcl_HashTable *rowHeights; /* hash table of non default row heights */ + Tcl_HashTable *spanTbl; /* table for spans */ + Tcl_HashTable *spanAffTbl; /* table for cells affected by spans */ + Tcl_HashTable *tagTable; /* table for style tags */ + Tcl_HashTable *winTable; /* table for embedded windows */ + Tcl_HashTable *rowStyles; /* table for row styles */ + Tcl_HashTable *colStyles; /* table for col styles */ + Tcl_HashTable *cellStyles; /* table for cell styles */ + Tcl_HashTable *flashCells; /* table of flashing cells */ + Tcl_HashTable *selCells; /* table of selected cells */ + Tcl_TimerToken cursorTimer; /* timer token for the cursor blinking */ + Tcl_TimerToken flashTimer; /* timer token for the cell flashing */ + char *activeBuf; /* buffer where the selection is kept + * for editing the active cell */ + char **tagPrioNames; /* list of tag names in priority order */ + TableTag **tagPrios; /* list of tag pointers in priority order */ + TableTag *activeTagPtr; /* cache of active composite tag */ + int activeX, activeY; /* cache offset of active layout in cell */ + int tagPrioSize; /* size of tagPrios list */ + int tagPrioMax; /* max allocated size of tagPrios list */ + + /* The invalid rectangle if there is an update pending */ + int invalidX, invalidY, invalidWidth, invalidHeight; + int seen[4]; /* see TableUndisplay */ + +#ifdef POSTSCRIPT + /* Pointer to information used for generating Postscript for the canvas. + * NULL means no Postscript is currently being generated. */ + struct TkPostscriptInfo *psInfoPtr; +#endif + +#ifdef PROCS + Tcl_HashTable *inProc; /* cells where proc is being evaled */ + int showProcs; /* whether to show embedded proc (1) or + * its calculated value (0) */ + int hasProcs; /* whether table has embedded procs or not */ +#endif +} Table; + +/* + * HEADERS FOR EMBEDDED WINDOWS + */ + +/* + * A structure of the following type holds information for each window + * embedded in a table widget. + */ + +typedef struct TableEmbWindow { + Table *tablePtr; /* Information about the overall table + * widget. */ + Tk_Window tkwin; /* Window for this segment. NULL means that + * the window hasn't been created yet. */ + Tcl_HashEntry *hPtr; /* entry into winTable */ + char *create; /* Script to create window on-demand. + * NULL means no such script. + * Malloc-ed. */ + Tk_3DBorder bg; /* background color */ + + char *borderStr; /* border style */ + int borders; /* number of borders specified (1, 2 or 4) */ + int bd[4]; /* border width for cell around window */ + + int relief; /* relief type */ + int sticky; /* How to align window in space */ + int padX, padY; /* Padding to leave around each side + * of window, in pixels. */ + int displayed; /* Non-zero means that the window has been + * displayed on the screen recently. */ +} TableEmbWindow; + +extern Tk_ConfigSpec tableSpecs[]; + +extern void EmbWinDisplay(Table *tablePtr, Drawable window, + TableEmbWindow *ewPtr, TableTag *tagPtr, + int x, int y, int width, int height); +extern void EmbWinUnmap(register Table *tablePtr, + int rlo, int rhi, int clo, int chi); +extern void EmbWinDelete(register Table *tablePtr, TableEmbWindow *ewPtr); +extern int Table_WinMove(register Table *tablePtr, + char *CONST srcPtr, char *CONST destPtr, int flags); +extern int Table_WinDelete(register Table *tablePtr, char *CONST idxPtr); +extern int Table_WindowCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int TableValidateChange(Table *tablePtr, int r, + int c, char *oldVal, char *newVal, int idx); +extern void TableLostSelection(ClientData clientData); +extern void TableSetActiveIndex(register Table *tablePtr); + +/* + * HEADERS IN tkTableCmds.c + */ + +extern int Table_ActivateCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_AdjustCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_BboxCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_BorderCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_ClearCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_CurselectionCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_CurvalueCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_GetCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_ScanCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_SeeCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_SelAnchorCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_SelClearCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_SelIncludesCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_SelSetCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_ViewCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); + +/* + * HEADERS IN tkTableEdit.c + */ + +extern int Table_EditCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern void TableDeleteChars(register Table *tablePtr, + int idx, int count); +extern void TableInsertChars(register Table *tablePtr, + int idx, char *string); + +/* + * HEADERS IN tkTableTag.c + */ + +extern TableTag *TableNewTag(Table *tablePtr); +extern void TableResetTag(Table *tablePtr, TableTag *tagPtr); +extern void TableMergeTag(Table *tablePtr, TableTag *baseTag, + TableTag *addTag); +extern void TableInvertTag(TableTag *baseTag); +extern int TableGetTagBorders(TableTag *tagPtr, + int *left, int *right, int *top, int *bottom); +extern void TableInitTags(Table *tablePtr); +extern TableTag *FindRowColTag(Table *tablePtr, + int cell, int type); +extern void TableCleanupTag(Table *tablePtr, + TableTag *tagPtr); +extern int Table_TagCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); + +/* + * HEADERS IN tkTableUtil.c + */ + +extern void Table_ClearHashTable(Tcl_HashTable *hashTblPtr); +extern int TableOptionBdSet(ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + CONST84 char *value, char *widgRec, int offset); +extern char * TableOptionBdGet(ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, + Tcl_FreeProc **freeProcPtr); +extern int TableTagConfigureBd(Table *tablePtr, + TableTag *tagPtr, char *oldValue, int nullOK); +extern int Cmd_OptionSet(ClientData clientData, + Tcl_Interp *interp, + Tk_Window unused, CONST84 char *value, + char *widgRec, int offset); +extern char * Cmd_OptionGet(ClientData clientData, + Tk_Window unused, char *widgRec, + int offset, Tcl_FreeProc **freeProcPtr); + +/* + * HEADERS IN tkTableCell.c + */ + +extern int TableTrueCell(Table *tablePtr, int row, int col, + int *trow, int *tcol); +extern int TableCellCoords(Table *tablePtr, int row, + int col, int *rx, int *ry, int *rw, int *rh); +extern int TableCellVCoords(Table *tablePtr, int row, + int col, int *rx, int *ry, + int *rw, int *rh, int full); +extern void TableWhatCell(register Table *tablePtr, + int x, int y, int *row, int *col); +extern int TableAtBorder(Table *tablePtr, int x, int y, + int *row, int *col); +extern char * TableGetCellValue(Table *tablePtr, int r, int c); +extern int TableSetCellValue(Table *tablePtr, int r, int c, + char *value); +extern int TableMoveCellValue(Table *tablePtr, + int fromr, int fromc, char *frombuf, + int tor, int toc, char *tobuf, int outOfBounds); + +extern int TableGetIcursor(Table *tablePtr, char *arg, + int *posn); +#define TableGetIcursorObj(tablePtr, objPtr, posnPtr) \ + TableGetIcursor(tablePtr, Tcl_GetString(objPtr), posnPtr) +extern int TableGetIndex(register Table *tablePtr, + char *str, int *row_p, int *col_p); +#define TableGetIndexObj(tablePtr, objPtr, rowPtr, colPtr) \ + TableGetIndex(tablePtr, Tcl_GetString(objPtr), rowPtr, colPtr) +extern int Table_SetCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_HiddenCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern int Table_SpanCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern void TableSpanSanCheck(register Table *tablePtr); + +/* + * HEADERS IN TKTABLECELLSORT + */ +/* + * We keep the old CellSort true because it is used for grabbing + * the selection, so we really want them ordered + */ +extern char * TableCellSort(Table *tablePtr, char *str); +#ifdef NO_SORT_CELLS +# define TableCellSortObj(interp, objPtr) (objPtr) +#else +extern Tcl_Obj* TableCellSortObj(Tcl_Interp *interp, Tcl_Obj *listObjPtr); +#endif + +/* + * HEADERS IN TKTABLEPS + */ + +#ifdef POSTSCRIPT +extern int Table_PostscriptCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); +extern void Tcl_DStringAppendAllTCL_VARARGS(Tcl_DString *, arg1); +#endif + +/* + * HEADERS IN TKTABLE + */ + +EXTERN int Tktable_Init(Tcl_Interp *interp); +EXTERN int Tktable_SafeInit(Tcl_Interp *interp); + +extern void TableGetActiveBuf(register Table *tablePtr); +extern void ExpandPercents(Table *tablePtr, char *before, + int r, int c, char *oldVal, char *newVal, int idx, + Tcl_DString *dsPtr, int cmdType); +extern void TableInvalidate(Table *tablePtr, int x, int y, + int width, int height, int force); +extern void TableRefresh(register Table *tablePtr, + int arg1, int arg2, int mode); +extern void TableGeometryRequest(Table *tablePtr); +extern void TableAdjustActive(register Table *tablePtr); +extern void TableAdjustParams(register Table *tablePtr); +extern void TableConfigCursor(register Table *tablePtr); +extern void TableAddFlash(Table *tablePtr, int row, int col); + + +#define TableInvalidateAll(tablePtr, flags) \ + TableInvalidate((tablePtr), 0, 0, Tk_Width((tablePtr)->tkwin),\ + Tk_Height((tablePtr)->tkwin), (flags)) + + /* + * Turn row/col into an index into the table + */ +#define TableMakeArrayIndex(r, c, i) sprintf((i), "%d,%d", (r), (c)) + + /* + * Turn array index back into row/col + * return the number of args parsed (should be two) + */ +#define TableParseArrayIndex(r, c, i) sscanf((i), "%d,%d", (r), (c)) + + /* + * Macro for finding the last cell of the table + */ +#define TableGetLastCell(tablePtr, rowPtr, colPtr) \ + TableWhatCell((tablePtr),\ + Tk_Width((tablePtr)->tkwin)-(tablePtr)->highlightWidth-1,\ + Tk_Height((tablePtr)->tkwin)-(tablePtr)->highlightWidth-1,\ + (rowPtr), (colPtr)) + +/* + * end of header + * reset TCL_STORAGE_CLASS to DLLIMPORT. + */ +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLIMPORT + +#endif /* _TKTABLE_H_ */ + diff --git a/tktable/generic/tkTableCell.c b/tktable/generic/tkTableCell.c new file mode 100644 index 0000000..a98c335 --- /dev/null +++ b/tktable/generic/tkTableCell.c @@ -0,0 +1,1420 @@ +/* + * tkTableCell.c -- + * + * This module implements cell oriented functions for table + * widgets. + * + * Copyright (c) 1998-2000 Jeffrey Hobbs + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tkTableCell.c,v 1.12 2008/11/14 21:10:12 hobbs Exp $ + */ + +#include "tkTable.h" + +/* + *---------------------------------------------------------------------- + * + * TableTrueCell -- + * Takes a row,col pair in user coords and returns the true + * cell that it relates to, either dimension bounded, or a + * span cell if it was hidden. + * + * Results: + * The true row, col in user coords are placed in the pointers. + * If the value changed for some reasons, 0 is returned (it was not + * the /true/ cell). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +int +TableTrueCell(Table *tablePtr, int r, int c, int *row, int *col) +{ + *row = r; *col = c; + /* + * We check spans before constraints, because we don't want to + * constrain and then think we ended up in a span + */ + if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { + char buf[INDEX_BUFSIZE]; + Tcl_HashEntry *entryPtr; + + TableMakeArrayIndex(r, c, buf); + entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); + if ((entryPtr != NULL) && + ((char *)Tcl_GetHashValue(entryPtr) != NULL)) { + /* + * This cell is covered by another spanning cell. + * We need to return the coords for that spanning cell. + */ + TableParseArrayIndex(row, col, (char *)Tcl_GetHashValue(entryPtr)); + return 0; + } + } + *row = BETWEEN(r, tablePtr->rowOffset, + tablePtr->rows-1+tablePtr->rowOffset); + *col = BETWEEN(c, tablePtr->colOffset, + tablePtr->cols-1+tablePtr->colOffset); + return ((*row == r) && (*col == c)); +} + +/* + *---------------------------------------------------------------------- + * + * TableCellCoords -- + * Takes a row,col pair in real coords and finds it position + * on the virtual screen. + * + * Results: + * The virtual x, y, width, and height of the cell + * are placed in the pointers. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +int +TableCellCoords(Table *tablePtr, int row, int col, + int *x, int *y, int *w, int *h) +{ + register int hl = tablePtr->highlightWidth; + int result = CELL_OK; + + if (tablePtr->rows <= 0 || tablePtr->cols <= 0) { + *w = *h = *x = *y = 0; + return CELL_BAD; + } + /* + * Real coords required, always should be passed acceptable values, + * but this is a possible seg fault otherwise + */ + CONSTRAIN(row, 0, tablePtr->rows-1); + CONSTRAIN(col, 0, tablePtr->cols-1); + *w = tablePtr->colPixels[col]; + *h = tablePtr->rowPixels[row]; + /* + * Adjust for sizes of spanning cells + * and ensure that this cell isn't "hidden" + */ + if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { + char buf[INDEX_BUFSIZE]; + Tcl_HashEntry *entryPtr; + + TableMakeArrayIndex(row+tablePtr->rowOffset, + col+tablePtr->colOffset, buf); + entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); + if (entryPtr != NULL) { + int rs, cs; + char *cell; + + cell = (char *) Tcl_GetHashValue(entryPtr); + if (cell != NULL) { + /* This cell is covered by another spanning cell */ + /* We need to return the coords for that cell */ + TableParseArrayIndex(&rs, &cs, cell); + *w = rs; + *h = cs; + result = CELL_HIDDEN; + goto setxy; + } + /* Get the actual span values out of spanTbl */ + entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, buf); + cell = (char *) Tcl_GetHashValue(entryPtr); + TableParseArrayIndex(&rs, &cs, cell); + if (rs > 0) { + /* + * Make sure we don't overflow our space + */ + if (row < tablePtr->titleRows) { + rs = MIN(tablePtr->titleRows-1, row+rs); + } else { + rs = MIN(tablePtr->rows-1, row+rs); + } + *h = tablePtr->rowStarts[rs+1]-tablePtr->rowStarts[row]; + result = CELL_SPAN; + } else if (rs <= 0) { + /* currently negative spans are not supported */ + } + if (cs > 0) { + /* + * Make sure we don't overflow our space + */ + if (col < tablePtr->titleCols) { + cs = MIN(tablePtr->titleCols-1, col+cs); + } else { + cs = MIN(tablePtr->cols-1, col+cs); + } + *w = tablePtr->colStarts[cs+1]-tablePtr->colStarts[col]; + result = CELL_SPAN; + } else if (cs <= 0) { + /* currently negative spans are not supported */ + } + } + } +setxy: + *x = hl + tablePtr->colStarts[col]; + if (col >= tablePtr->titleCols) { + *x -= tablePtr->colStarts[tablePtr->leftCol] + - tablePtr->colStarts[tablePtr->titleCols]; + } + *y = hl + tablePtr->rowStarts[row]; + if (row >= tablePtr->titleRows) { + *y -= tablePtr->rowStarts[tablePtr->topRow] + - tablePtr->rowStarts[tablePtr->titleRows]; + } + return result; +} + +/* + *---------------------------------------------------------------------- + * + * TableCellVCoords -- + * Takes a row,col pair in real coords and finds it position + * on the actual screen. The full arg specifies whether + * only 100% visible cells should be considered visible. + * + * Results: + * The x, y, width, and height of the cell are placed in the pointers, + * depending upon visibility of the cell. + * Returns 0 for hidden and 1 for visible cells. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +int +TableCellVCoords(Table *tablePtr, int row, int col, + int *rx, int *ry, int *rw, int *rh, int full) +{ + int x, y, w, h, w0, h0, cellType, hl = tablePtr->highlightWidth; + + if (tablePtr->tkwin == NULL) return 0; + + /* + * Necessary to use separate vars in case dummies are passed in + */ + cellType = TableCellCoords(tablePtr, row, col, &x, &y, &w, &h); + *rx = x; *ry = y; *rw = w; *rh = h; + if (cellType == CELL_OK) { + if ((row < tablePtr->topRow && row >= tablePtr->titleRows) || + (col < tablePtr->leftCol && col >= tablePtr->titleCols)) { + /* + * A non-spanning cell hiding in "dead" space + * between title areas and visible cells + */ + return 0; + } + } else if (cellType == CELL_SPAN) { + /* + * we might need to treat full better is CELL_SPAN but primary + * cell is visible + */ + int topX = tablePtr->colStarts[tablePtr->titleCols]+hl; + int topY = tablePtr->rowStarts[tablePtr->titleRows]+hl; + if ((col < tablePtr->leftCol) && (col >= tablePtr->titleCols)) { + if (full || (x+w < topX)) { + return 0; + } else { + w -= topX-x; + x = topX; + } + } + if ((row < tablePtr->topRow) && (row >= tablePtr->titleRows)) { + if (full || (y+h < topY)) { + return 0; + } else { + h -= topY-y; + y = topY; + } + } + /* + * re-set these according to changed coords + */ + *rx = x; *ry = y; *rw = w; *rh = h; + } else { + /* + * If it is a hidden cell, then w,h is the row,col in user coords + * of the cell that spans over this one + */ + return 0; + } + /* + * At this point, we know it is on the screen, + * but not if we can see 100% of it (if we care) + */ + if (full) { + w0 = w; h0 = h; + } else { + /* + * if we don't care about seeing the whole thing, then + * make sure we at least see a pixel worth + */ + w0 = h0 = 1; + } + /* + * Is the cell visible? + */ + if ((x < hl) || (y < hl) || ((x+w0) > (Tk_Width(tablePtr->tkwin)-hl)) + || ((y+h0) > (Tk_Height(tablePtr->tkwin)-hl))) { + /* definitely off the screen */ + return 0; + } else { + /* if it was full, then w,h are already be properly constrained */ + if (!full) { + *rw = MIN(w, Tk_Width(tablePtr->tkwin)-hl-x); + *rh = MIN(h, Tk_Height(tablePtr->tkwin)-hl-y); + } + return 1; + } +} + +/* + *---------------------------------------------------------------------- + * + * TableWhatCell -- + * Takes a x,y screen coordinate and determines what cell contains. + * that point. This will return cells that are beyond the right/bottom + * edge of the viewable screen. + * + * Results: + * The row,col of the cell are placed in the pointers. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +TableWhatCell(register Table *tablePtr, int x, int y, int *row, int *col) +{ + int i; + x = MAX(0, x); y = MAX(0, y); + /* Adjust for table's global highlightthickness border */ + x -= tablePtr->highlightWidth; + y -= tablePtr->highlightWidth; + /* Adjust the x coord if not in the column titles to change display coords + * into internal coords */ + x += (x < tablePtr->colStarts[tablePtr->titleCols]) ? 0 : + tablePtr->colStarts[tablePtr->leftCol] - + tablePtr->colStarts[tablePtr->titleCols]; + y += (y < tablePtr->rowStarts[tablePtr->titleRows]) ? 0 : + tablePtr->rowStarts[tablePtr->topRow] - + tablePtr->rowStarts[tablePtr->titleRows]; + x = MIN(x, tablePtr->maxWidth-1); + y = MIN(y, tablePtr->maxHeight-1); + for (i = 1; x >= tablePtr->colStarts[i]; i++); + *col = i - 1; + for (i = 1; y >= tablePtr->rowStarts[i]; i++); + *row = i - 1; + if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS)) { + char buf[INDEX_BUFSIZE]; + Tcl_HashEntry *entryPtr; + + /* We now correct the returned cell if this was "hidden" */ + TableMakeArrayIndex(*row+tablePtr->rowOffset, + *col+tablePtr->colOffset, buf); + entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); + if ((entryPtr != NULL) && + /* We have to make sure this was not already hidden + * that's an error */ + ((char *)Tcl_GetHashValue(entryPtr) != NULL)) { + /* this is a "hidden" cell */ + TableParseArrayIndex(row, col, (char *)Tcl_GetHashValue(entryPtr)); + *row -= tablePtr->rowOffset; + *col -= tablePtr->colOffset; + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TableAtBorder -- + * Takes a x,y screen coordinate and determines if that point is + * over a border. + * + * Results: + * The left/top row,col corresponding to that point are placed in + * the pointers. The number of borders (+1 for row, +1 for col) + * hit is returned. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +int +TableAtBorder(Table * tablePtr, int x, int y, int *row, int *col) +{ + int i, brow, bcol, borders = 2, bd[6]; + + TableGetTagBorders(&(tablePtr->defaultTag), + &bd[0], &bd[1], &bd[2], &bd[3]); + bd[4] = (bd[0] + bd[1])/2; + bd[5] = (bd[2] + bd[3])/2; + + /* + * Constrain x && y appropriately, and adjust x if it is not in the + * column titles to change display coords into internal coords. + */ + x = MAX(0, x); y = MAX(0, y); + x -= tablePtr->highlightWidth; y -= tablePtr->highlightWidth; + x += (x < tablePtr->colStarts[tablePtr->titleCols]) ? 0 : + tablePtr->colStarts[tablePtr->leftCol] - + tablePtr->colStarts[tablePtr->titleCols]; + x = MIN(x, tablePtr->maxWidth - 1); + for (i = 1; (i <= tablePtr->cols) && + (x + (bd[0] + bd[1])) >= tablePtr->colStarts[i]; i++); + if (x > tablePtr->colStarts[--i] + bd[4]) { + borders--; + *col = -1; + bcol = (i < tablePtr->leftCol && i >= tablePtr->titleCols) ? + tablePtr->titleCols-1 : i-1; + } else { + bcol = *col = (i < tablePtr->leftCol && i >= tablePtr->titleCols) ? + tablePtr->titleCols-1 : i-1; + } + y += (y < tablePtr->rowStarts[tablePtr->titleRows]) ? 0 : + tablePtr->rowStarts[tablePtr->topRow] - + tablePtr->rowStarts[tablePtr->titleRows]; + y = MIN(y, tablePtr->maxHeight - 1); + for (i = 1; i <= tablePtr->rows && + (y + (bd[2] + bd[3])) >= tablePtr->rowStarts[i]; i++); + if (y > tablePtr->rowStarts[--i]+bd[5]) { + borders--; + *row = -1; + brow = (i < tablePtr->topRow && i >= tablePtr->titleRows) ? + tablePtr->titleRows-1 : i-1; + } else { + brow = *row = (i < tablePtr->topRow && i >= tablePtr->titleRows) ? + tablePtr->titleRows-1 : i-1; + } + /* + * We have to account for spanning cells, which may hide cells. + * In that case, we have to decrement our border count. + */ + if (tablePtr->spanAffTbl && !(tablePtr->flags & AVOID_SPANS) && borders) { + Tcl_HashEntry *entryPtr1, *entryPtr2 ; + char buf1[INDEX_BUFSIZE], buf2[INDEX_BUFSIZE]; + char *val; + + if (*row != -1) { + TableMakeArrayIndex(brow+tablePtr->rowOffset, + bcol+tablePtr->colOffset+1, buf1); + TableMakeArrayIndex(brow+tablePtr->rowOffset+1, + bcol+tablePtr->colOffset+1, buf2); + entryPtr1 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf1); + entryPtr2 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf2); + if (entryPtr1 != NULL && entryPtr2 != NULL) { + if ((val = (char *) Tcl_GetHashValue(entryPtr1)) != NULL) { + strcpy(buf1, val); + } + if ((val = (char *) Tcl_GetHashValue(entryPtr2)) != NULL) { + strcpy(buf2, val); + } + if (strcmp(buf1, buf2) == 0) { + borders--; + *row = -1; + } + } + } + if (*col != -1) { + TableMakeArrayIndex(brow+tablePtr->rowOffset+1, + bcol+tablePtr->colOffset, buf1); + TableMakeArrayIndex(brow+tablePtr->rowOffset+1, + bcol+tablePtr->colOffset+1, buf2); + entryPtr1 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf1); + entryPtr2 = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf2); + if (entryPtr1 != NULL && entryPtr2 != NULL) { + if ((val = (char *) Tcl_GetHashValue(entryPtr1)) != NULL) { + strcpy(buf1, val); + } + if ((val = (char *) Tcl_GetHashValue(entryPtr2)) != NULL) { + strcpy(buf2, val); + } + if (strcmp(buf1, buf2) == 0) { + borders--; + *col = -1; + } + } + } + } + return borders; +} + +/* + *---------------------------------------------------------------------- + * + * TableGetCellValue -- + * Takes a row,col pair in user coords and returns the value for + * that cell. This varies depending on what data source the + * user has selected. + * + * Results: + * The value of the cell is returned. The return value is VOLATILE + * (do not free). + * + * Side effects: + * The value will be cached if caching is turned on. + * + *---------------------------------------------------------------------- + */ +char * +TableGetCellValue(Table *tablePtr, int r, int c) +{ + register Tcl_Interp *interp = tablePtr->interp; + char *result = NULL; + char buf[INDEX_BUFSIZE]; + Tcl_HashEntry *entryPtr = NULL; + int new; + + TableMakeArrayIndex(r, c, buf); + + if (tablePtr->dataSource == DATA_CACHE) { + /* + * only cache as data source - just rely on cache + */ + entryPtr = Tcl_FindHashEntry(tablePtr->cache, buf); + if (entryPtr) { + result = (char *) Tcl_GetHashValue(entryPtr); + } + goto VALUE; + } + if (tablePtr->caching) { + /* + * If we are caching, let's see if we have the value cached. + * If so, use it, otherwise it will be cached after retrieving + * from the other data source. + */ + entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); + if (!new) { + result = (char *) Tcl_GetHashValue(entryPtr); + goto VALUE; + } + } + if (tablePtr->dataSource & DATA_COMMAND) { + Tcl_DString script; + Tcl_DStringInit(&script); + ExpandPercents(tablePtr, tablePtr->command, r, c, "", (char *)NULL, + 0, &script, 0); + if (Tcl_GlobalEval(interp, Tcl_DStringValue(&script)) == TCL_ERROR) { + tablePtr->useCmd = 0; + tablePtr->dataSource &= ~DATA_COMMAND; + if (tablePtr->arrayVar) + tablePtr->dataSource |= DATA_ARRAY; + Tcl_AddErrorInfo(interp, "\n\t(in -command evaled by table)"); + Tcl_AddErrorInfo(interp, Tcl_DStringValue(&script)); + Tcl_BackgroundError(interp); + TableInvalidateAll(tablePtr, 0); + } else { + result = (char *) Tcl_GetStringResult(interp); + } + Tcl_DStringFree(&script); + } + if (tablePtr->dataSource & DATA_ARRAY) { + result = (char *) Tcl_GetVar2(interp, tablePtr->arrayVar, buf, + TCL_GLOBAL_ONLY); + } + if (tablePtr->caching && entryPtr != NULL) { + /* + * If we are caching, make sure we cache the returned value + * + * entryPtr will have been set from above, but check to make sure + * someone didn't change caching during -command evaluation. + */ + char *val = NULL; + if (result) { + val = (char *)ckalloc(strlen(result)+1); + strcpy(val, result); + } + Tcl_SetHashValue(entryPtr, val); + } +VALUE: +#ifdef PROCS + if (result != NULL) { + /* Do we have procs, are we showing their value, is this a proc? */ + if (tablePtr->hasProcs && !tablePtr->showProcs && *result == '=' && + !(r-tablePtr->rowOffset == tablePtr->activeRow && + c-tablePtr->colOffset == tablePtr->activeCol)) { + Tcl_DString script; + /* provides a rough mutex on preventing proc loops */ + entryPtr = Tcl_CreateHashEntry(tablePtr->inProc, buf, &new); + if (!new) { + Tcl_SetHashValue(entryPtr, 1); + Tcl_AddErrorInfo(interp, "\n\t(loop hit in proc evaled by table)"); + return result; + } + Tcl_SetHashValue(entryPtr, 0); + Tcl_DStringInit(&script); + ExpandPercents(tablePtr, result+1, r, c, result+1, (char *)NULL, + 0, &script, 0); + if (Tcl_GlobalEval(interp, Tcl_DStringValue(&script)) != TCL_OK || + Tcl_GetHashValue(entryPtr) == 1) { + Tcl_AddErrorInfo(interp, "\n\tin proc evaled by table:\n"); + Tcl_AddErrorInfo(interp, Tcl_DStringValue(&script)); + Tcl_BackgroundError(interp); + } else { + result = Tcl_GetStringResult(interp); + } + /* + * XXX FIX: Can't free result that we still need. + * Use ref-counted objects instead. + */ + Tcl_FreeResult(interp); + Tcl_DStringFree(&script); + Tcl_DeleteHashEntry(entryPtr); + } + } +#endif + return (result?result:""); +} + +/* + *---------------------------------------------------------------------- + * + * TableSetCellValue -- + * Takes a row,col pair in user coords and saves the given value for + * that cell. This varies depending on what data source the + * user has selected. + * + * Results: + * Returns TCL_ERROR or TCL_OK, depending on whether an error + * occured during set (ie: during evaluation of -command). + * + * Side effects: + * If the value is NULL (empty string), it will be unset from + * an array rather than set to the empty string. + * + *---------------------------------------------------------------------- + */ +int +TableSetCellValue(Table *tablePtr, int r, int c, char *value) +{ + char buf[INDEX_BUFSIZE]; + int code = TCL_OK, flash = 0; + Tcl_Interp *interp = tablePtr->interp; + + TableMakeArrayIndex(r, c, buf); + + if (tablePtr->state == STATE_DISABLED) { + return TCL_OK; + } + if (tablePtr->dataSource & DATA_COMMAND) { + Tcl_DString script; + + Tcl_DStringInit(&script); + ExpandPercents(tablePtr, tablePtr->command, r, c, value, (char *)NULL, + 1, &script, 0); + if (Tcl_GlobalEval(interp, Tcl_DStringValue(&script)) == TCL_ERROR) { + /* An error resulted. Prevent further triggering of the command + * and set up the error message. */ + tablePtr->useCmd = 0; + tablePtr->dataSource &= ~DATA_COMMAND; + if (tablePtr->arrayVar) + tablePtr->dataSource |= DATA_ARRAY; + Tcl_AddErrorInfo(interp, "\n\t(in command executed by table)"); + Tcl_BackgroundError(interp); + code = TCL_ERROR; + } else { + flash = 1; + } + Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); + Tcl_DStringFree(&script); + } + if (tablePtr->dataSource & DATA_ARRAY) { + /* Warning: checking for \0 as the first char could invalidate + * allowing it as a valid first char, but only with incorrect utf-8 + */ + if ((value == NULL || *value == '\0') && tablePtr->sparse) { + Tcl_UnsetVar2(interp, tablePtr->arrayVar, buf, TCL_GLOBAL_ONLY); + value = NULL; + } else if (Tcl_SetVar2(interp, tablePtr->arrayVar, buf, value, + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { + code = TCL_ERROR; + } + } + if (code == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * This would be repetitive if we are using the array (which traces). + */ + if (tablePtr->caching && !(tablePtr->dataSource & DATA_ARRAY)) { + Tcl_HashEntry *entryPtr; + int new; + char *val = NULL; + + entryPtr = Tcl_CreateHashEntry(tablePtr->cache, buf, &new); + if (!new) { + val = (char *) Tcl_GetHashValue(entryPtr); + if (val) ckfree(val); + } + if (value) { + val = (char *)ckalloc(strlen(value)+1); + strcpy(val, value); + } + Tcl_SetHashValue(entryPtr, val); + flash = 1; + } + /* We do this conditionally because the var array already has + * it's own check to flash */ + if (flash && tablePtr->flashMode) { + r -= tablePtr->rowOffset; + c -= tablePtr->colOffset; + TableAddFlash(tablePtr, r, c); + TableRefresh(tablePtr, r, c, CELL); + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TableMoveCellValue -- + * To move cells faster on delete/insert line or col when cache is on + * and variable, command is off. + * To avoid another call to TableMakeArrayIndex(r, c, buf), + * we optionally provide the buffers. + * outOfBounds means we will just set the cell value to "" + * + * Results: + * Returns TCL_ERROR or TCL_OK, depending on whether an error + * occured during set (ie: during evaluation of -command). + * + * Side effects: + * If the value is NULL (empty string), it will be unset from + * an array rather than set to the empty string. + * + *---------------------------------------------------------------------- + */ +int +TableMoveCellValue(Table *tablePtr, int fromr, int fromc, char *frombuf, + int tor, int toc, char *tobuf, int outOfBounds) +{ + if (outOfBounds) { + return TableSetCellValue(tablePtr, tor, toc, ""); + } + + if (tablePtr->dataSource == DATA_CACHE) { + char *val; + char *result = NULL; + Tcl_HashEntry *entryPtr; + + /* + * Let's see if we have the from value cached. If so, copy + * that to the to cell. The to cell entry value will be + * deleted from the cache, and recreated only if from value + * was not NULL. + * We can be liberal removing our internal cached cells when + * DATA_CACHE is our only data source. + */ + entryPtr = Tcl_FindHashEntry(tablePtr->cache, frombuf); + if (entryPtr) { + result = (char *) Tcl_GetHashValue(entryPtr); + /* + * we set tho old value to NULL + */ + Tcl_DeleteHashEntry(entryPtr); + } + if (result) { + int new; + /* + * We enter here when there was a from value. + * set 'to' to the 'from' value without new mallocing. + */ + entryPtr = Tcl_CreateHashEntry(tablePtr->cache, tobuf, &new); + /* + * free old value + */ + if (!new) { + val = (char *) Tcl_GetHashValue(entryPtr); + if (val) ckfree(val); + } + Tcl_SetHashValue(entryPtr, result); + } else { + entryPtr = Tcl_FindHashEntry(tablePtr->cache, tobuf); + if (entryPtr) { + val = (char *) Tcl_GetHashValue(entryPtr); + if (val) ckfree(val); + Tcl_DeleteHashEntry(entryPtr); + } + } + return TCL_OK; + } + /* + * We have to do it the old way + */ + return TableSetCellValue(tablePtr, tor, toc, + TableGetCellValue(tablePtr, fromr, fromc)); + +} + +/* + *---------------------------------------------------------------------- + * + * TableGetIcursor -- + * Parses the argument as an index into the active cell string. + * Recognises 'end', 'insert' or an integer. Constrains it to the + * size of the buffer. This acts like a "SetIcursor" when *posn is NULL. + * + * Results: + * If (posn != NULL), then it gets the cursor position. + * + * Side effects: + * Can move cursor position. + * + *---------------------------------------------------------------------- + */ +int +TableGetIcursor(Table *tablePtr, char *arg, int *posn) +{ + int tmp, len; + + len = strlen(tablePtr->activeBuf); +#ifdef TCL_UTF_MAX + /* Need to base it off strlen to account for \x00 (Unicode null) */ + len = Tcl_NumUtfChars(tablePtr->activeBuf, len); +#endif + /* ensure icursor didn't get out of sync */ + if (tablePtr->icursor > len) tablePtr->icursor = len; + /* is this end */ + if (strcmp(arg, "end") == 0) { + tmp = len; + } else if (strcmp(arg, "insert") == 0) { + tmp = tablePtr->icursor; + } else { + if (Tcl_GetInt(tablePtr->interp, arg, &tmp) != TCL_OK) { + return TCL_ERROR; + } + CONSTRAIN(tmp, 0, len); + } + if (posn) { + *posn = tmp; + } else { + tablePtr->icursor = tmp; + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * TableGetIndex -- + * Parse an index into a table and return either its value + * or an error. + * + * Results: + * A standard Tcl result. If all went well, then *row,*col is + * filled in with the index corresponding to string. If an + * error occurs then an error message is left in interp result. + * The index returned is in user coords. + * + * Side effects: + * Sets row,col index to an appropriately constrained user index. + * + *-------------------------------------------------------------- + */ +int +TableGetIndex(tablePtr, str, row_p, col_p) + register Table *tablePtr; /* Table for which the index is being + * specified. */ + char *str; /* Symbolic specification of cell in table. */ + int *row_p; /* Where to store converted row. */ + int *col_p; /* Where to store converted col. */ +{ + int r, c, len = strlen(str); + char dummy; + + /* + * Note that all of these values will be adjusted by row/ColOffset + */ + if (str[0] == '@') { /* @x,y coordinate */ + int x, y; + + if (sscanf(str+1, "%d,%d%c", &x, &y, &dummy) != 2) { + /* Make sure it won't work for "2,3extrastuff" */ + goto IndexError; + } + TableWhatCell(tablePtr, x, y, &r, &c); + r += tablePtr->rowOffset; + c += tablePtr->colOffset; + } else if (*str == '-' || isdigit(str[0])) { + if (sscanf(str, "%d,%d%c", &r, &c, &dummy) != 2) { + /* Make sure it won't work for "2,3extrastuff" */ + goto IndexError; + } + /* ensure appropriate user index */ + CONSTRAIN(r, tablePtr->rowOffset, + tablePtr->rows-1+tablePtr->rowOffset); + CONSTRAIN(c, tablePtr->colOffset, + tablePtr->cols-1+tablePtr->colOffset); + } else if (len > 1 && strncmp(str, "active", len) == 0 ) { /* active */ + if (tablePtr->flags & HAS_ACTIVE) { + r = tablePtr->activeRow+tablePtr->rowOffset; + c = tablePtr->activeCol+tablePtr->colOffset; + } else { + Tcl_SetObjResult(tablePtr->interp, + Tcl_NewStringObj("no \"active\" cell in table", -1)); + return TCL_ERROR; + } + } else if (len > 1 && strncmp(str, "anchor", len) == 0) { /* anchor */ + if (tablePtr->flags & HAS_ANCHOR) { + r = tablePtr->anchorRow+tablePtr->rowOffset; + c = tablePtr->anchorCol+tablePtr->colOffset; + } else { + Tcl_SetObjResult(tablePtr->interp, + Tcl_NewStringObj("no \"anchor\" cell in table", -1)); + return TCL_ERROR; + } + } else if (strncmp(str, "end", len) == 0) { /* end */ + r = tablePtr->rows-1+tablePtr->rowOffset; + c = tablePtr->cols-1+tablePtr->colOffset; + } else if (strncmp(str, "origin", len) == 0) { /* origin */ + r = tablePtr->titleRows+tablePtr->rowOffset; + c = tablePtr->titleCols+tablePtr->colOffset; + } else if (strncmp(str, "topleft", len) == 0) { /* topleft */ + r = tablePtr->topRow+tablePtr->rowOffset; + c = tablePtr->leftCol+tablePtr->colOffset; + } else if (strncmp(str, "bottomright", len) == 0) { /* bottomright */ + /* + * FIX: Should this avoid spans, or consider them in the bottomright? + tablePtr->flags |= AVOID_SPANS; + tablePtr->flags &= ~AVOID_SPANS; + */ + TableGetLastCell(tablePtr, &r, &c); + r += tablePtr->rowOffset; + c += tablePtr->colOffset; + } else { + IndexError: + Tcl_AppendStringsToObj(Tcl_GetObjResult(tablePtr->interp), + "bad table index \"", str, "\": must be active, anchor, end, ", + "origin, topleft, bottomright, @x,y, or ,", + (char *)NULL); + return TCL_ERROR; + } + + /* Note: values are expected to be properly constrained + * as a user index by this point */ + if (row_p) *row_p = r; + if (col_p) *col_p = c; + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_SetCmd -- + * This procedure is invoked to process the set method + * that corresponds to a widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_SetCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *)clientData; + int row, col, len, i, j, max; + char *str; + + /* sets any number of tags/indices to a given value */ + if (objc < 3) { + CMD_SET_USAGE: + Tcl_WrongNumArgs(interp, 2, objv, + "?row|col? index ?value? ?index value ...?"); + return TCL_ERROR; + } + + /* make sure there is a data source to accept set */ + if (tablePtr->dataSource == DATA_NONE) { + return TCL_OK; + } + + str = Tcl_GetStringFromObj(objv[2], &len); + if (strncmp(str, "row", len) == 0 || strncmp(str, "col", len) == 0) { + Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); + /* set row index list ?index list ...? */ + if (objc < 4) { + goto CMD_SET_USAGE; + } else if (objc == 4) { + if (TableGetIndexObj(tablePtr, objv[3], + &row, &col) != TCL_OK) { + return TCL_ERROR; + } + if (*str == 'r') { + max = tablePtr->cols+tablePtr->colOffset; + for (i=col; irows+tablePtr->rowOffset; + for (i=row; istate == STATE_NORMAL) { + int listc; + Tcl_Obj **listv; + /* make sure there are an even number of index/list pairs */ + if (objc & 0) { + goto CMD_SET_USAGE; + } + for (i = 3; i < objc-1; i += 2) { + if ((TableGetIndexObj(tablePtr, objv[i], + &row, &col) != TCL_OK) || + (Tcl_ListObjGetElements(interp, objv[i+1], + &listc, &listv) != TCL_OK)) { + return TCL_ERROR; + } + if (*str == 'r') { + max = col+MIN(tablePtr->cols+tablePtr->colOffset-col, + listc); + for (j = col; j < max; j++) { + if (TableSetCellValue(tablePtr, row, j, + Tcl_GetString(listv[j-col])) + != TCL_OK) { + return TCL_ERROR; + } + if (row-tablePtr->rowOffset == tablePtr->activeRow && + j-tablePtr->colOffset == tablePtr->activeCol) { + TableGetActiveBuf(tablePtr); + } + TableRefresh(tablePtr, row-tablePtr->rowOffset, + j-tablePtr->colOffset, CELL); + } + } else { + max = row+MIN(tablePtr->rows+tablePtr->rowOffset-row, + listc); + for (j = row; j < max; j++) { + if (TableSetCellValue(tablePtr, j, col, + Tcl_GetString(listv[j-row])) + != TCL_OK) { + return TCL_ERROR; + } + if (j-tablePtr->rowOffset == tablePtr->activeRow && + col-tablePtr->colOffset == tablePtr->activeCol) { + TableGetActiveBuf(tablePtr); + } + TableRefresh(tablePtr, j-tablePtr->rowOffset, + col-tablePtr->colOffset, CELL); + } + } + } + } + } else if (objc == 3) { + /* set index */ + if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { + return TCL_ERROR; + } else { + /* + * Cannot use Tcl_GetObjResult here because TableGetCellValue + * can corrupt the resultPtr. + */ + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TableGetCellValue(tablePtr, row, col),-1)); + } + } else { + /* set index val ?index val ...? */ + /* make sure there are an even number of index/value pairs */ + if (objc & 1) { + goto CMD_SET_USAGE; + } + for (i = 2; i < objc-1; i += 2) { + if ((TableGetIndexObj(tablePtr, objv[i], &row, &col) != TCL_OK) || + (TableSetCellValue(tablePtr, row, col, + Tcl_GetString(objv[i+1])) != TCL_OK)) { + return TCL_ERROR; + } + row -= tablePtr->rowOffset; + col -= tablePtr->colOffset; + if (row == tablePtr->activeRow && col == tablePtr->activeCol) { + TableGetActiveBuf(tablePtr); + } + TableRefresh(tablePtr, row, col, CELL); + } + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_SpanSet -- + * Takes row,col in user coords and sets a span on the + * cell if possible + * + * Results: + * A standard Tcl result + * + * Side effects: + * The span can be constrained + * + *-------------------------------------------------------------- + */ +static int +Table_SpanSet(register Table *tablePtr, int urow, int ucol, int rs, int cs) +{ + Tcl_Interp *interp = tablePtr->interp; + int i, j, new, ors, ocs, result = TCL_OK; + int row, col; + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + char *dbuf, buf[INDEX_BUFSIZE], cell[INDEX_BUFSIZE], span[INDEX_BUFSIZE]; + + row = urow - tablePtr->rowOffset; + col = ucol - tablePtr->colOffset; + + TableMakeArrayIndex(urow, ucol, cell); + + if (tablePtr->spanTbl == NULL) { + tablePtr->spanTbl = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->spanTbl, TCL_STRING_KEYS); + tablePtr->spanAffTbl = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(tablePtr->spanAffTbl, TCL_STRING_KEYS); + } + + /* first check in the affected cells table */ + if ((entryPtr=Tcl_FindHashEntry(tablePtr->spanAffTbl, cell)) != NULL) { + /* We have to make sure this was not already hidden + * that's an error */ + if ((char *)Tcl_GetHashValue(entryPtr) != NULL) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "cannot set spanning on hidden cell ", + cell, (char *) NULL); + return TCL_ERROR; + } + } + /* do constraints on the spans + * title cells must not expand beyond the titles + * other cells can't expand negatively into title area + */ + if ((row < tablePtr->titleRows) && + (row + rs >= tablePtr->titleRows)) { + rs = tablePtr->titleRows - row - 1; + } + if ((col < tablePtr->titleCols) && + (col + cs >= tablePtr->titleCols)) { + cs = tablePtr->titleCols - col - 1; + } + rs = MAX(0, rs); + cs = MAX(0, cs); + + /* then work in the span cells table */ + if ((entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, cell)) != NULL) { + /* We have to readjust for what was there first */ + TableParseArrayIndex(&ors, &ocs, (char *)Tcl_GetHashValue(entryPtr)); + ckfree((char *) Tcl_GetHashValue(entryPtr)); + Tcl_DeleteHashEntry(entryPtr); + for (i = urow; i <= urow+ors; i++) { + for (j = ucol; j <= ucol+ocs; j++) { + TableMakeArrayIndex(i, j, buf); + entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); + if (entryPtr != NULL) { + Tcl_DeleteHashEntry(entryPtr); + } + TableRefresh(tablePtr, i-tablePtr->rowOffset, + j-tablePtr->colOffset, CELL); + } + } + } else { + ors = ocs = 0; + } + + /* calc to make sure that span is OK */ + for (i = urow; i <= urow+rs; i++) { + for (j = ucol; j <= ucol+cs; j++) { + TableMakeArrayIndex(i, j, buf); + entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, buf); + if (entryPtr != NULL) { + /* Something already spans here */ + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "cannot overlap already spanned cell ", + buf, (char *) NULL); + result = TCL_ERROR; + rs = ors; + cs = ocs; + break; + } + } + if (result == TCL_ERROR) + break; + } + + /* 0,0 span means set to unspanned again */ + if (rs == 0 && cs == 0) { + entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, cell); + if (entryPtr != NULL) { + ckfree((char *) Tcl_GetHashValue(entryPtr)); + Tcl_DeleteHashEntry(entryPtr); + } + entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, cell); + if (entryPtr != NULL) { + Tcl_DeleteHashEntry(entryPtr); + } + if (Tcl_FirstHashEntry(tablePtr->spanTbl, &search) == NULL) { + /* There are no more spans, so delete tables to improve + * performance of TableCellCoords */ + Tcl_DeleteHashTable(tablePtr->spanTbl); + ckfree((char *) (tablePtr->spanTbl)); + Tcl_DeleteHashTable(tablePtr->spanAffTbl); + ckfree((char *) (tablePtr->spanAffTbl)); + tablePtr->spanTbl = NULL; + tablePtr->spanAffTbl = NULL; + } + return result; + } + + /* Make sure there is no extra stuff */ + TableMakeArrayIndex(rs, cs, span); + + /* Set affected cell table to a NULL value */ + entryPtr = Tcl_CreateHashEntry(tablePtr->spanAffTbl, cell, &new); + Tcl_SetHashValue(entryPtr, (char *) NULL); + /* set the spanning cells table with span value */ + entryPtr = Tcl_CreateHashEntry(tablePtr->spanTbl, cell, &new); + dbuf = (char *)ckalloc(strlen(span)+1); + strcpy(dbuf, span); + Tcl_SetHashValue(entryPtr, dbuf); + dbuf = Tcl_GetHashKey(tablePtr->spanTbl, entryPtr); + /* Set other affected cells */ + EmbWinUnmap(tablePtr, row, row + rs, col, col + cs); + for (i = urow; i <= urow+rs; i++) { + for (j = ucol; j <= ucol+cs; j++) { + TableMakeArrayIndex(i, j, buf); + entryPtr = Tcl_CreateHashEntry(tablePtr->spanAffTbl, buf, &new); + if (!(i == urow && j == ucol)) { + Tcl_SetHashValue(entryPtr, (char *) dbuf); + } + } + } + TableRefresh(tablePtr, row, col, CELL); + return result; +} + +/* + *-------------------------------------------------------------- + * + * Table_SpanCmd -- + * This procedure is invoked to process the span method + * that corresponds to a widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_SpanCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int rs, cs, row, col, i; + Tcl_HashEntry *entryPtr; + + if (objc < 2 || (objc > 4 && (objc&1))) { + Tcl_WrongNumArgs(interp, 2, objv, + "?index? ?rows,cols index rows,cols ...?"); + return TCL_ERROR; + } + + if (objc == 2) { + if (tablePtr->spanTbl) { + Tcl_HashSearch search; + Tcl_Obj *objPtr, *resultPtr = Tcl_NewObj(); + + for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanTbl, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + objPtr = Tcl_NewStringObj(Tcl_GetHashKey(tablePtr->spanTbl, + entryPtr), -1); + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + objPtr = Tcl_NewStringObj((char *) Tcl_GetHashValue(entryPtr), + -1); + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + Tcl_SetObjResult(interp, resultPtr); + } + return TCL_OK; + } else if (objc == 3) { + if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { + return TCL_ERROR; + } + /* Just return the spanning values of the one cell */ + if (tablePtr->spanTbl && + (entryPtr = Tcl_FindHashEntry(tablePtr->spanTbl, + Tcl_GetString(objv[2]))) != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj((char *)Tcl_GetHashValue(entryPtr), -1)); + } + return TCL_OK; + } else { + for (i = 2; i < objc-1; i += 2) { + if (TableGetIndexObj(tablePtr, objv[i], &row, &col) == TCL_ERROR || + (TableParseArrayIndex(&rs, &cs, + Tcl_GetString(objv[i+1])) != 2) || + Table_SpanSet(tablePtr, row, col, rs, cs) == TCL_ERROR) { + return TCL_ERROR; + } + } + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_HiddenCmd -- + * This procedure is invoked to process the hidden method + * that corresponds to a widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_HiddenCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int i, row, col; + Tcl_HashEntry *entryPtr; + char *span; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 2, objv, "?index? ?index ...?"); + return TCL_ERROR; + } + if (tablePtr->spanTbl == NULL) { + /* Avoid the whole thing if we have no spans */ + if (objc > 3) { + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); + } + return TCL_OK; + } + if (objc == 2) { + /* return all "hidden" cells */ + Tcl_HashSearch search; + Tcl_Obj *objPtr = Tcl_NewObj(); + + for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanAffTbl, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + if ((span = (char *) Tcl_GetHashValue(entryPtr)) == NULL) { + /* this is actually a spanning cell */ + continue; + } + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewStringObj(Tcl_GetHashKey(tablePtr->spanAffTbl, + entryPtr), -1)); + } + Tcl_SetObjResult(interp, TableCellSortObj(interp, objPtr)); + return TCL_OK; + } + if (objc == 3) { + if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { + return TCL_ERROR; + } + /* Just return the spanning values of the one cell */ + entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, + Tcl_GetString(objv[2])); + if (entryPtr != NULL && + (span = (char *)Tcl_GetHashValue(entryPtr)) != NULL) { + /* this is a hidden cell */ + Tcl_SetObjResult(interp, Tcl_NewStringObj(span, -1)); + } + return TCL_OK; + } + for (i = 2; i < objc; i++) { + if (TableGetIndexObj(tablePtr, objv[i], &row, &col) == TCL_ERROR) { + return TCL_ERROR; + } + entryPtr = Tcl_FindHashEntry(tablePtr->spanAffTbl, + Tcl_GetString(objv[i])); + if (entryPtr != NULL && + (char *)Tcl_GetHashValue(entryPtr) != NULL) { + /* this is a hidden cell */ + continue; + } + /* We only reach here if it doesn't satisfy "hidden" criteria */ + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0)); + return TCL_OK; + } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1)); + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * TableSpanSanCheck -- + * This procedure is invoked by TableConfigure to make sure + * that spans are kept sane according to the docs. + * See the user documentation for details on what it does. + * + * Results: + * void. + * + * Side effects: + * Spans in title areas can be reconstrained. + * + *-------------------------------------------------------------- + */ +void +TableSpanSanCheck(register Table *tablePtr) +{ + int rs, cs, row, col, reset; + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + + if (tablePtr->spanTbl == NULL) { + return; + } + + for (entryPtr = Tcl_FirstHashEntry(tablePtr->spanTbl, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + reset = 0; + TableParseArrayIndex(&row, &col, + Tcl_GetHashKey(tablePtr->spanTbl, entryPtr)); + TableParseArrayIndex(&rs, &cs, + (char *) Tcl_GetHashValue(entryPtr)); + if ((row-tablePtr->rowOffset < tablePtr->titleRows) && + (row-tablePtr->rowOffset+rs >= tablePtr->titleRows)) { + rs = tablePtr->titleRows-(row-tablePtr->rowOffset)-1; + reset = 1; + } + if ((col-tablePtr->colOffset < tablePtr->titleCols) && + (col-tablePtr->colOffset+cs >= tablePtr->titleCols)) { + cs = tablePtr->titleCols-(col-tablePtr->colOffset)-1; + reset = 1; + } + if (reset) { + Table_SpanSet(tablePtr, row, col, rs, cs); + } + } +} diff --git a/tktable/generic/tkTableCellSort.c b/tktable/generic/tkTableCellSort.c new file mode 100644 index 0000000..b2a7837 --- /dev/null +++ b/tktable/generic/tkTableCellSort.c @@ -0,0 +1,400 @@ +/* + * tkTableCell.c -- + * + * This module implements cell sort functions for table + * widgets. The MergeSort algorithm and other aux sorting + * functions were taken from tclCmdIL.c lsort command: + + * tclCmdIL.c -- + * + * This file contains the top-level command routines for most of + * the Tcl built-in commands whose names begin with the letters + * I through L. It contains only commands in the generic core + * (i.e. those that don't depend much upon UNIX facilities). + * + * Copyright (c) 1987-1993 The Regents of the University of California. + * Copyright (c) 1993-1997 Lucent Technologies. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-1999 by Scriptics Corporation. + + * + * Copyright (c) 1998-2002 Jeffrey Hobbs + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + */ + +#include "tkTable.h" + +#ifndef UCHAR +#define UCHAR(c) ((unsigned char) (c)) +#endif + +/* + * During execution of the "lsort" command, structures of the following + * type are used to arrange the objects being sorted into a collection + * of linked lists. + */ + +typedef struct SortElement { + Tcl_Obj *objPtr; /* Object being sorted. */ + struct SortElement *nextPtr; /* Next element in the list, or + * NULL for end of list. */ +} SortElement; + +static int TableSortCompareProc _ANSI_ARGS_((CONST VOID *first, + CONST VOID *second)); +static SortElement * MergeSort _ANSI_ARGS_((SortElement *headPt)); +static SortElement * MergeLists _ANSI_ARGS_((SortElement *leftPtr, + SortElement *rightPtr)); +static int DictionaryCompare _ANSI_ARGS_((char *left, + char *right)); + +/* + *---------------------------------------------------------------------- + * + * TableSortCompareProc -- + * This procedure is invoked by qsort to determine the proper + * ordering between two elements. + * + * Results: + * < 0 means first is "smaller" than "second", > 0 means "first" + * is larger than "second", and 0 means they should be treated + * as equal. + * + * Side effects: + * None, unless a user-defined comparison command does something + * weird. + * + *---------------------------------------------------------------------- + */ +static int +TableSortCompareProc(first, second) + CONST VOID *first, *second; /* Elements to be compared. */ +{ + char *str1 = *((char **) first); + char *str2 = *((char **) second); + + return DictionaryCompare(str1, str2); +} + +/* + *---------------------------------------------------------------------- + * + * TableCellSort -- + * Sort a list of table cell elements (of form row,col) + * + * Results: + * Returns the sorted list of elements. Because Tcl_Merge allocs + * the space for result, it must later be Tcl_Free'd by caller. + * + * Side effects: + * Behaviour undefined for ill-formed input list of elements. + * + *---------------------------------------------------------------------- + */ +char * +TableCellSort(Table *tablePtr, char *str) +{ + int listArgc; + CONST84 char **listArgv; + char *result; + + if (Tcl_SplitList(tablePtr->interp, str, &listArgc, &listArgv) != TCL_OK) { + return str; + } + /* Thread safety: qsort is reportedly not thread-safe... */ + qsort((VOID *) listArgv, (size_t) listArgc, sizeof (char *), + TableSortCompareProc); + result = Tcl_Merge(listArgc, listArgv); + ckfree((char *) listArgv); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * DictionaryCompare - Not the Unicode version + * + * This function compares two strings as if they were being used in + * an index or card catalog. The case of alphabetic characters is + * ignored, except to break ties. Thus "B" comes before "b" but + * after "a". Also, integers embedded in the strings compare in + * numerical order. In other words, "x10y" comes after "x9y", not + * before it as it would when using strcmp(). + * + * Results: + * A negative result means that the first element comes before the + * second, and a positive result means that the second element + * should come first. A result of zero means the two elements + * are equal and it doesn't matter which comes first. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +DictionaryCompare(left, right) + char *left, *right; /* The strings to compare */ +{ + int diff, zeros; + int secondaryDiff = 0; + + while (1) { + if (isdigit(UCHAR(*right)) && isdigit(UCHAR(*left))) { + /* + * There are decimal numbers embedded in the two + * strings. Compare them as numbers, rather than + * strings. If one number has more leading zeros than + * the other, the number with more leading zeros sorts + * later, but only as a secondary choice. + */ + + zeros = 0; + while ((*right == '0') && (isdigit(UCHAR(right[1])))) { + right++; + zeros--; + } + while ((*left == '0') && (isdigit(UCHAR(left[1])))) { + left++; + zeros++; + } + if (secondaryDiff == 0) { + secondaryDiff = zeros; + } + + /* + * The code below compares the numbers in the two + * strings without ever converting them to integers. It + * does this by first comparing the lengths of the + * numbers and then comparing the digit values. + */ + + diff = 0; + while (1) { + if (diff == 0) { + diff = UCHAR(*left) - UCHAR(*right); + } + right++; + left++; + if (!isdigit(UCHAR(*right))) { + if (isdigit(UCHAR(*left))) { + return 1; + } else { + /* + * The two numbers have the same length. See + * if their values are different. + */ + + if (diff != 0) { + return diff; + } + break; + } + } else if (!isdigit(UCHAR(*left))) { + return -1; + } + } + continue; + } + diff = UCHAR(*left) - UCHAR(*right); + if (diff) { + if (isupper(UCHAR(*left)) && islower(UCHAR(*right))) { + diff = UCHAR(tolower(*left)) - UCHAR(*right); + if (diff) { + return diff; + } else if (secondaryDiff == 0) { + secondaryDiff = -1; + } + } else if (isupper(UCHAR(*right)) && islower(UCHAR(*left))) { + diff = UCHAR(*left) - UCHAR(tolower(UCHAR(*right))); + if (diff) { + return diff; + } else if (secondaryDiff == 0) { + secondaryDiff = 1; + } + } else { + return diff; + } + } + if (*left == 0) { + break; + } + left++; + right++; + } + if (diff == 0) { + diff = secondaryDiff; + } + return diff; +} + +/* + *---------------------------------------------------------------------- + * + * MergeLists - + * + * This procedure combines two sorted lists of SortElement structures + * into a single sorted list. + * + * Results: + * The unified list of SortElement structures. + * + * Side effects: + * None, unless a user-defined comparison command does something + * weird. + * + *---------------------------------------------------------------------- + */ + +static SortElement * +MergeLists(leftPtr, rightPtr) + SortElement *leftPtr; /* First list to be merged; may be + * NULL. */ + SortElement *rightPtr; /* Second list to be merged; may be + * NULL. */ +{ + SortElement *headPtr; + SortElement *tailPtr; + + if (leftPtr == NULL) { + return rightPtr; + } + if (rightPtr == NULL) { + return leftPtr; + } + if (DictionaryCompare(Tcl_GetString(leftPtr->objPtr), + Tcl_GetString(rightPtr->objPtr)) > 0) { + tailPtr = rightPtr; + rightPtr = rightPtr->nextPtr; + } else { + tailPtr = leftPtr; + leftPtr = leftPtr->nextPtr; + } + headPtr = tailPtr; + while ((leftPtr != NULL) && (rightPtr != NULL)) { + if (DictionaryCompare(Tcl_GetString(leftPtr->objPtr), + Tcl_GetString(rightPtr->objPtr)) > 0) { + tailPtr->nextPtr = rightPtr; + tailPtr = rightPtr; + rightPtr = rightPtr->nextPtr; + } else { + tailPtr->nextPtr = leftPtr; + tailPtr = leftPtr; + leftPtr = leftPtr->nextPtr; + } + } + if (leftPtr != NULL) { + tailPtr->nextPtr = leftPtr; + } else { + tailPtr->nextPtr = rightPtr; + } + return headPtr; +} + +/* + *---------------------------------------------------------------------- + * + * MergeSort - + * + * This procedure sorts a linked list of SortElement structures + * use the merge-sort algorithm. + * + * Results: + * A pointer to the head of the list after sorting is returned. + * + * Side effects: + * None, unless a user-defined comparison command does something + * weird. + * + *---------------------------------------------------------------------- + */ + +static SortElement * +MergeSort(headPtr) + SortElement *headPtr; /* First element on the list */ +{ + /* + * The subList array below holds pointers to temporary lists built + * during the merge sort. Element i of the array holds a list of + * length 2**i. + */ + +# define NUM_LISTS 30 + SortElement *subList[NUM_LISTS]; + SortElement *elementPtr; + int i; + + for(i = 0; i < NUM_LISTS; i++){ + subList[i] = NULL; + } + while (headPtr != NULL) { + elementPtr = headPtr; + headPtr = headPtr->nextPtr; + elementPtr->nextPtr = 0; + for (i = 0; (i < NUM_LISTS) && (subList[i] != NULL); i++){ + elementPtr = MergeLists(subList[i], elementPtr); + subList[i] = NULL; + } + if (i >= NUM_LISTS) { + i = NUM_LISTS-1; + } + subList[i] = elementPtr; + } + elementPtr = NULL; + for (i = 0; i < NUM_LISTS; i++){ + elementPtr = MergeLists(subList[i], elementPtr); + } + return elementPtr; +} + +#ifndef NO_SORT_CELLS +/* + *---------------------------------------------------------------------- + * + * TableCellSortObj -- + * Sorts a list of table cell elements (of form row,col) in place + * + * Results: + * Sorts list of elements in place. + * + * Side effects: + * Behaviour undefined for ill-formed input list of elements. + * + *---------------------------------------------------------------------- + */ +Tcl_Obj * +TableCellSortObj(Tcl_Interp *interp, Tcl_Obj *listObjPtr) +{ + int length, i; + Tcl_Obj *sortedObjPtr, **listObjPtrs; + SortElement *elementArray; + SortElement *elementPtr; + + if (Tcl_ListObjGetElements(interp, listObjPtr, + &length, &listObjPtrs) != TCL_OK) { + return NULL; + } + if (length <= 0) { + return listObjPtr; + } + + elementArray = (SortElement *) ckalloc(length * sizeof(SortElement)); + for (i=0; i < length; i++){ + elementArray[i].objPtr = listObjPtrs[i]; + elementArray[i].nextPtr = &elementArray[i+1]; + } + elementArray[length-1].nextPtr = NULL; + elementPtr = MergeSort(elementArray); + sortedObjPtr = Tcl_NewObj(); + for (; elementPtr != NULL; elementPtr = elementPtr->nextPtr){ + Tcl_ListObjAppendElement(NULL, sortedObjPtr, elementPtr->objPtr); + } + ckfree((char*) elementArray); + + return sortedObjPtr; +} +#endif diff --git a/tktable/generic/tkTableCmds.c b/tktable/generic/tkTableCmds.c new file mode 100644 index 0000000..3668b01 --- /dev/null +++ b/tktable/generic/tkTableCmds.c @@ -0,0 +1,1306 @@ +/* + * tkTableCmds.c -- + * + * This module implements general commands of a table widget, + * based on the major/minor command structure. + * + * Copyright (c) 1998-2002 Jeffrey Hobbs + * + * See the file "license.txt" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + */ + +#include "tkTable.h" + +/* + *-------------------------------------------------------------- + * + * Table_ActivateCmd -- + * This procedure is invoked to process the activate method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_ActivateCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int result = TCL_OK; + int row, col, templen; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index"); + return TCL_ERROR; + } else if (Tcl_GetStringFromObj(objv[2], &templen), templen == 0) { + /* + * Test implementation to clear active cell (becroft) + */ + tablePtr->flags &= ~HAS_ACTIVE; + tablePtr->flags |= ACTIVE_DISABLED; + tablePtr->activeRow = -1; + tablePtr->activeCol = -1; + TableAdjustActive(tablePtr); + TableConfigCursor(tablePtr); + } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) != TCL_OK) { + return TCL_ERROR; + } else { + int x, y, w, dummy; + char buf1[INDEX_BUFSIZE], buf2[INDEX_BUFSIZE]; + + /* convert to valid active index in real coords */ + row -= tablePtr->rowOffset; + col -= tablePtr->colOffset; + /* we do this regardless, to avoid cell commit problems */ + if ((tablePtr->flags & HAS_ACTIVE) && + (tablePtr->flags & TEXT_CHANGED)) { + tablePtr->flags &= ~TEXT_CHANGED; + TableSetCellValue(tablePtr, + tablePtr->activeRow+tablePtr->rowOffset, + tablePtr->activeCol+tablePtr->colOffset, + tablePtr->activeBuf); + } + if (row != tablePtr->activeRow || col != tablePtr->activeCol) { + if (tablePtr->flags & HAS_ACTIVE) { + TableMakeArrayIndex(tablePtr->activeRow+tablePtr->rowOffset, + tablePtr->activeCol+tablePtr->colOffset, + buf1); + } else { + buf1[0] = '\0'; + } + tablePtr->flags |= HAS_ACTIVE; + tablePtr->flags &= ~ACTIVE_DISABLED; + tablePtr->activeRow = row; + tablePtr->activeCol = col; + if (tablePtr->activeTagPtr != NULL) { + ckfree((char *) (tablePtr->activeTagPtr)); + tablePtr->activeTagPtr = NULL; + } + TableAdjustActive(tablePtr); + TableConfigCursor(tablePtr); + if (!(tablePtr->flags & BROWSE_CMD) && + tablePtr->browseCmd != NULL) { + Tcl_DString script; + tablePtr->flags |= BROWSE_CMD; + row = tablePtr->activeRow+tablePtr->rowOffset; + col = tablePtr->activeCol+tablePtr->colOffset; + TableMakeArrayIndex(row, col, buf2); + Tcl_DStringInit(&script); + ExpandPercents(tablePtr, tablePtr->browseCmd, row, col, + buf1, buf2, tablePtr->icursor, &script, 0); + result = Tcl_GlobalEval(interp, Tcl_DStringValue(&script)); + if (result == TCL_OK || result == TCL_RETURN) { + Tcl_ResetResult(interp); + } + Tcl_DStringFree(&script); + tablePtr->flags &= ~BROWSE_CMD; + } + } else { + char *p = Tcl_GetString(objv[2]); + + if ((tablePtr->activeTagPtr != NULL) && *p == '@' && + !(tablePtr->flags & ACTIVE_DISABLED) && + TableCellVCoords(tablePtr, row, col, &x, &y, &w, &dummy, 0)) { + /* we are clicking into the same cell + * If it was activated with @x,y indexing, + * find the closest char */ + Tk_TextLayout textLayout; + TableTag *tagPtr = tablePtr->activeTagPtr; + + /* no error checking because GetIndex did it for us */ + p++; + x = strtol(p, &p, 0) - x - tablePtr->activeX; + p++; + y = strtol(p, &p, 0) - y - tablePtr->activeY; + + textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, + tablePtr->activeBuf, -1, + (tagPtr->wrap) ? w : 0, + tagPtr->justify, 0, &dummy, &dummy); + + tablePtr->icursor = Tk_PointToChar(textLayout, x, y); + Tk_FreeTextLayout(textLayout); + TableRefresh(tablePtr, row, col, CELL|INV_FORCE); + } + } + tablePtr->flags |= HAS_ACTIVE; + } + return result; +} + +/* + *-------------------------------------------------------------- + * + * Table_AdjustCmd -- + * This procedure is invoked to process the width/height method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_AdjustCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + Tcl_HashTable *hashTablePtr; + int i, widthType, dummy, value, posn, offset; + char buf1[INDEX_BUFSIZE]; + + widthType = (*(Tcl_GetString(objv[1])) == 'w'); + /* changes the width/height of certain selected columns */ + if (objc != 3 && (objc & 1)) { + Tcl_WrongNumArgs(interp, 2, objv, widthType ? + "?col? ?width col width ...?" : + "?row? ?height row height ...?"); + return TCL_ERROR; + } + if (widthType) { + hashTablePtr = tablePtr->colWidths; + offset = tablePtr->colOffset; + } else { + hashTablePtr = tablePtr->rowHeights; + offset = tablePtr->rowOffset; + } + + if (objc == 2) { + /* print out all the preset column widths or row heights */ + entryPtr = Tcl_FirstHashEntry(hashTablePtr, &search); + while (entryPtr != NULL) { + posn = ((int) Tcl_GetHashKey(hashTablePtr, entryPtr)) + offset; + value = (int) Tcl_GetHashValue(entryPtr); + sprintf(buf1, "%d %d", posn, value); + /* OBJECTIFY */ + Tcl_AppendElement(interp, buf1); + entryPtr = Tcl_NextHashEntry(&search); + } + } else if (objc == 3) { + /* get the width/height of a particular row/col */ + if (Tcl_GetIntFromObj(interp, objv[2], &posn) != TCL_OK) { + return TCL_ERROR; + } + /* no range check is done, why bother? */ + posn -= offset; + entryPtr = Tcl_FindHashEntry(hashTablePtr, (char *) posn); + if (entryPtr != NULL) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), + (int) Tcl_GetHashValue(entryPtr)); + } else { + Tcl_SetIntObj(Tcl_GetObjResult(interp), widthType ? + tablePtr->defColWidth : tablePtr->defRowHeight); + } + } else { + for (i=2; i 4) { + Tcl_WrongNumArgs(interp, 2, objv, "first ?last?"); + return TCL_ERROR; + } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR || + (objc == 4 && + TableGetIndexObj(tablePtr, objv[3], &x, &y) == TCL_ERROR)) { + return TCL_ERROR; + } + + resultPtr = Tcl_GetObjResult(interp); + if (objc == 3) { + row -= tablePtr->rowOffset; col -= tablePtr->colOffset; + if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { + Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(x)); + Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(y)); + Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(w)); + Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(h)); + } + return TCL_OK; + } else { + int r1, c1, r2, c2, minX = 99999, minY = 99999, maxX = 0, maxY = 0; + + row -= tablePtr->rowOffset; col -= tablePtr->colOffset; + x -= tablePtr->rowOffset; y -= tablePtr->colOffset; + r1 = MIN(row,x); r2 = MAX(row,x); + c1 = MIN(col,y); c2 = MAX(col,y); + key = 0; + for (row = r1; row <= r2; row++) { + for (col = c1; col <= c2; col++) { + if (TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0)) { + /* Get max bounding box */ + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x+w > maxX) maxX = x+w; + if (y+h > maxY) maxY = y+h; + key++; + } + } + } + if (key) { + Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(minX)); + Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(minY)); + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewIntObj(maxX-minX)); + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewIntObj(maxY-minY)); + } + } + return TCL_OK; +} + +static CONST84 char *bdCmdNames[] = { + "mark", "dragto", (char *)NULL +}; +enum bdCmd { + BD_MARK, BD_DRAGTO +}; + +/* + *-------------------------------------------------------------- + * + * Table_BorderCmd -- + * This procedure is invoked to process the bbox method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_BorderCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + Tcl_HashEntry *entryPtr; + int x, y, w, h, row, col, key, dummy, value, cmdIndex; + char *rc = NULL; + Tcl_Obj *objPtr, *resultPtr; + + if (objc < 5 || objc > 6) { + Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?row|col?"); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[2], bdCmdNames, + "option", 0, &cmdIndex) != TCL_OK || + Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK || + Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) { + return TCL_ERROR; + } + if (objc == 6) { + rc = Tcl_GetStringFromObj(objv[5], &w); + if ((w < 1) || (strncmp(rc, "row", w) && strncmp(rc, "col", w))) { + Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?row|col?"); + return TCL_ERROR; + } + } + + resultPtr = Tcl_GetObjResult(interp); + switch ((enum bdCmd) cmdIndex) { + case BD_MARK: + /* Use x && y to determine if we are over a border */ + value = TableAtBorder(tablePtr, x, y, &row, &col); + /* Cache the row && col for use in DRAGTO */ + tablePtr->scanMarkRow = row; + tablePtr->scanMarkCol = col; + if (!value) { + return TCL_OK; + } + TableCellCoords(tablePtr, row, col, &x, &y, &dummy, &dummy); + tablePtr->scanMarkX = x; + tablePtr->scanMarkY = y; + if (objc == 5 || *rc == 'r') { + if (row < 0) { + objPtr = Tcl_NewStringObj("", 0); + } else { + objPtr = Tcl_NewIntObj(row+tablePtr->rowOffset); + } + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + if (objc == 5 || *rc == 'c') { + if (col < 0) { + objPtr = Tcl_NewStringObj("", 0); + } else { + objPtr = Tcl_NewIntObj(col+tablePtr->colOffset); + } + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + return TCL_OK; /* BORDER MARK */ + + case BD_DRAGTO: + /* check to see if we want to resize any borders */ + if (tablePtr->resize == SEL_NONE) { return TCL_OK; } + row = tablePtr->scanMarkRow; + col = tablePtr->scanMarkCol; + TableCellCoords(tablePtr, row, col, &w, &h, &dummy, &dummy); + key = 0; + if (row >= 0 && (tablePtr->resize & SEL_ROW)) { + /* row border was active, move it */ + value = y-h; + if (value < -1) value = -1; + if (value != tablePtr->scanMarkY) { + entryPtr = Tcl_CreateHashEntry(tablePtr->rowHeights, + (char *) row, &dummy); + /* -value means rowHeight will be interp'd as pixels, not + lines */ + Tcl_SetHashValue(entryPtr, (ClientData) MIN(0,-value)); + tablePtr->scanMarkY = value; + key++; + } + } + if (col >= 0 && (tablePtr->resize & SEL_COL)) { + /* col border was active, move it */ + value = x-w; + if (value < -1) value = -1; + if (value != tablePtr->scanMarkX) { + entryPtr = Tcl_CreateHashEntry(tablePtr->colWidths, + (char *) col, &dummy); + /* -value means colWidth will be interp'd as pixels, not + chars */ + Tcl_SetHashValue(entryPtr, (ClientData) MIN(0,-value)); + tablePtr->scanMarkX = value; + key++; + } + } + /* Only if something changed do we want to update */ + if (key) { + TableAdjustParams(tablePtr); + /* Only rerequest geometry if the basis is the #rows &| #cols */ + if (tablePtr->maxReqCols || tablePtr->maxReqRows) + TableGeometryRequest(tablePtr); + TableInvalidateAll(tablePtr, 0); + } + return TCL_OK; /* BORDER DRAGTO */ + } + return TCL_OK; +} + +/* clear subcommands */ +static CONST84 char *clearNames[] = { + "all", "cache", "sizes", "tags", (char *)NULL +}; +enum clearCommand { + CLEAR_ALL, CLEAR_CACHE, CLEAR_SIZES, CLEAR_TAGS +}; + +/* + *-------------------------------------------------------------- + * + * Table_ClearCmd -- + * This procedure is invoked to process the clear method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * Cached info can be lost. Returns valid Tcl result. + * + * Side effects: + * Can cause redraw. + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_ClearCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int cmdIndex, redraw = 0; + + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 2, objv, "option ?first? ?last?"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj(interp, objv[2], clearNames, + "clear option", 0, &cmdIndex) != TCL_OK) { + return TCL_ERROR; + } + + if (objc == 3) { + if (cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) { + Tcl_DeleteHashTable(tablePtr->rowStyles); + Tcl_DeleteHashTable(tablePtr->colStyles); + Tcl_DeleteHashTable(tablePtr->cellStyles); + Tcl_DeleteHashTable(tablePtr->flashCells); + Tcl_DeleteHashTable(tablePtr->selCells); + + /* style hash tables */ + Tcl_InitHashTable(tablePtr->rowStyles, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(tablePtr->colStyles, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(tablePtr->cellStyles, TCL_STRING_KEYS); + + /* special style hash tables */ + Tcl_InitHashTable(tablePtr->flashCells, TCL_STRING_KEYS); + Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); + } + + if (cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) { + Tcl_DeleteHashTable(tablePtr->colWidths); + Tcl_DeleteHashTable(tablePtr->rowHeights); + + /* style hash tables */ + Tcl_InitHashTable(tablePtr->colWidths, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(tablePtr->rowHeights, TCL_ONE_WORD_KEYS); + } + + if (cmdIndex == CLEAR_CACHE || cmdIndex == CLEAR_ALL) { + Table_ClearHashTable(tablePtr->cache); + Tcl_InitHashTable(tablePtr->cache, TCL_STRING_KEYS); + /* If we were caching and we have no other data source, + * invalidate all the cells */ + if (tablePtr->dataSource == DATA_CACHE) { + TableGetActiveBuf(tablePtr); + } + } + redraw = 1; + } else { + int row, col, r1, r2, c1, c2; + Tcl_HashEntry *entryPtr; + char buf[INDEX_BUFSIZE], *value; + + if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK || + ((objc == 5) && + TableGetIndexObj(tablePtr, objv[4], &r2, &c2) != TCL_OK)) { + return TCL_ERROR; + } + if (objc == 4) { + r1 = r2 = row; + c1 = c2 = col; + } else { + r1 = MIN(row,r2); r2 = MAX(row,r2); + c1 = MIN(col,c2); c2 = MAX(col,c2); + } + for (row = r1; row <= r2; row++) { + /* Note that *Styles entries are user based (no offset) + * while size entries are 0-based (real) */ + if ((cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) && + (entryPtr = Tcl_FindHashEntry(tablePtr->rowStyles, + (char *) row))) { + Tcl_DeleteHashEntry(entryPtr); + redraw = 1; + } + + if ((cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) && + (entryPtr = Tcl_FindHashEntry(tablePtr->rowHeights, + (char *) row-tablePtr->rowOffset))) { + Tcl_DeleteHashEntry(entryPtr); + redraw = 1; + } + + for (col = c1; col <= c2; col++) { + TableMakeArrayIndex(row, col, buf); + + if (cmdIndex == CLEAR_TAGS || cmdIndex == CLEAR_ALL) { + if ((row == r1) && + (entryPtr = Tcl_FindHashEntry(tablePtr->colStyles, + (char *) col))) { + Tcl_DeleteHashEntry(entryPtr); + redraw = 1; + } + if ((entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, + buf))) { + Tcl_DeleteHashEntry(entryPtr); + redraw = 1; + } + if ((entryPtr = Tcl_FindHashEntry(tablePtr->flashCells, + buf))) { + Tcl_DeleteHashEntry(entryPtr); + redraw = 1; + } + if ((entryPtr = Tcl_FindHashEntry(tablePtr->selCells, + buf))) { + Tcl_DeleteHashEntry(entryPtr); + redraw = 1; + } + } + + if ((cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) && + row == r1 && + (entryPtr = Tcl_FindHashEntry(tablePtr->colWidths, (char *) + col-tablePtr->colOffset))) { + Tcl_DeleteHashEntry(entryPtr); + redraw = 1; + } + + if ((cmdIndex == CLEAR_CACHE || cmdIndex == CLEAR_ALL) && + (entryPtr = Tcl_FindHashEntry(tablePtr->cache, buf))) { + value = (char *) Tcl_GetHashValue(entryPtr); + if (value) { ckfree(value); } + Tcl_DeleteHashEntry(entryPtr); + /* if the cache is our data source, + * we need to invalidate the cells changed */ + if ((tablePtr->dataSource == DATA_CACHE) && + (row-tablePtr->rowOffset == tablePtr->activeRow && + col-tablePtr->colOffset == tablePtr->activeCol)) + TableGetActiveBuf(tablePtr); + redraw = 1; + } + } + } + } + /* This could be more sensitive about what it updates, + * but that can actually be a lot more costly in some cases */ + if (redraw) { + if (cmdIndex == CLEAR_SIZES || cmdIndex == CLEAR_ALL) { + TableAdjustParams(tablePtr); + /* rerequest geometry */ + TableGeometryRequest(tablePtr); + } + TableInvalidateAll(tablePtr, 0); + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_CurselectionCmd -- + * This procedure is invoked to process the bbox method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_CurselectionCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + char *value = NULL; + int row, col; + + if (objc > 3) { + Tcl_WrongNumArgs(interp, 2, objv, "?value?"); + return TCL_ERROR; + } + if (objc == 3) { + /* make sure there is a data source to accept a set value */ + if ((tablePtr->state == STATE_DISABLED) || + (tablePtr->dataSource == DATA_NONE)) { + return TCL_OK; + } + value = Tcl_GetString(objv[2]); + for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + TableParseArrayIndex(&row, &col, + Tcl_GetHashKey(tablePtr->selCells, entryPtr)); + TableSetCellValue(tablePtr, row, col, value); + row -= tablePtr->rowOffset; + col -= tablePtr->colOffset; + if (row == tablePtr->activeRow && col == tablePtr->activeCol) { + TableGetActiveBuf(tablePtr); + } + TableRefresh(tablePtr, row, col, CELL); + } + } else { + Tcl_Obj *objPtr = Tcl_NewObj(); + + for (entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + value = Tcl_GetHashKey(tablePtr->selCells, entryPtr); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewStringObj(value, -1)); + } + Tcl_SetObjResult(interp, TableCellSortObj(interp, objPtr)); + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_CurvalueCmd -- + * This procedure is invoked to process the curvalue method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_CurvalueCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + + if (objc > 3) { + Tcl_WrongNumArgs(interp, 2, objv, "??"); + return TCL_ERROR; + } else if (!(tablePtr->flags & HAS_ACTIVE)) { + return TCL_OK; + } + + if (objc == 3) { + char *value; + int len; + + value = Tcl_GetStringFromObj(objv[2], &len); + if (STREQ(value, tablePtr->activeBuf)) { + Tcl_SetObjResult(interp, objv[2]); + return TCL_OK; + } + /* validate potential new active buffer contents + * only accept if validation returns acceptance. */ + if (tablePtr->validate && + TableValidateChange(tablePtr, + tablePtr->activeRow+tablePtr->rowOffset, + tablePtr->activeCol+tablePtr->colOffset, + tablePtr->activeBuf, + value, tablePtr->icursor) != TCL_OK) { + return TCL_OK; + } + tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, len+1); + strcpy(tablePtr->activeBuf, value); + /* mark the text as changed */ + tablePtr->flags |= TEXT_CHANGED; + TableSetActiveIndex(tablePtr); + /* check for possible adjustment of icursor */ + TableGetIcursor(tablePtr, "insert", (int *)0); + TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); + } + + Tcl_SetObjResult(interp, Tcl_NewStringObj(tablePtr->activeBuf, -1)); + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_GetCmd -- + * This procedure is invoked to process the bbox method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_GetCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int result = TCL_OK; + int r1, c1, r2, c2, row, col; + + if (objc < 3 || objc > 4) { + Tcl_WrongNumArgs(interp, 2, objv, "first ?last?"); + result = TCL_ERROR; + } else if (TableGetIndexObj(tablePtr, objv[2], &row, &col) == TCL_ERROR) { + result = TCL_ERROR; + } else if (objc == 3) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj(TableGetCellValue(tablePtr, row, col), -1)); + } else if (TableGetIndexObj(tablePtr, objv[3], &r2, &c2) == TCL_ERROR) { + result = TCL_ERROR; + } else { + Tcl_Obj *objPtr = Tcl_NewObj(); + + r1 = MIN(row,r2); r2 = MAX(row,r2); + c1 = MIN(col,c2); c2 = MAX(col,c2); + for ( row = r1; row <= r2; row++ ) { + for ( col = c1; col <= c2; col++ ) { + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewStringObj(TableGetCellValue(tablePtr, + row, col), -1)); + } + } + Tcl_SetObjResult(interp, objPtr); + } + return result; +} + +/* + *-------------------------------------------------------------- + * + * Table_ScanCmd -- + * This procedure is invoked to process the scan method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_ScanCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int x, y, row, col, cmdIndex; + + if (objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y"); + return TCL_ERROR; + } else if (Tcl_GetIndexFromObj(interp, objv[2], bdCmdNames, + "option", 0, &cmdIndex) != TCL_OK || + Tcl_GetIntFromObj(interp, objv[3], &x) == TCL_ERROR || + Tcl_GetIntFromObj(interp, objv[4], &y) == TCL_ERROR) { + return TCL_ERROR; + } + switch ((enum bdCmd) cmdIndex) { + case BD_MARK: + TableWhatCell(tablePtr, x, y, &row, &col); + tablePtr->scanMarkRow = row-tablePtr->topRow; + tablePtr->scanMarkCol = col-tablePtr->leftCol; + tablePtr->scanMarkX = x; + tablePtr->scanMarkY = y; + break; + + case BD_DRAGTO: { + int oldTop = tablePtr->topRow, oldLeft = tablePtr->leftCol; + y += (5*(y-tablePtr->scanMarkY)); + x += (5*(x-tablePtr->scanMarkX)); + + TableWhatCell(tablePtr, x, y, &row, &col); + + /* maintain appropriate real index */ + tablePtr->topRow = BETWEEN(row-tablePtr->scanMarkRow, + tablePtr->titleRows, tablePtr->rows-1); + tablePtr->leftCol = BETWEEN(col-tablePtr->scanMarkCol, + tablePtr->titleCols, tablePtr->cols-1); + + /* Adjust the table if new top left */ + if (oldTop != tablePtr->topRow || oldLeft != tablePtr->leftCol) { + TableAdjustParams(tablePtr); + } + break; + } + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_SelAnchorCmd -- + * This procedure is invoked to process the selection anchor method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_SelAnchorCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int row, col; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 3, objv, "index"); + return TCL_ERROR; + } else if (TableGetIndexObj(tablePtr, objv[3], &row, &col) != TCL_OK) { + return TCL_ERROR; + } + tablePtr->flags |= HAS_ANCHOR; + /* maintain appropriate real index */ + if (tablePtr->selectTitles) { + tablePtr->anchorRow = BETWEEN(row-tablePtr->rowOffset, + 0, tablePtr->rows-1); + tablePtr->anchorCol = BETWEEN(col-tablePtr->colOffset, + 0, tablePtr->cols-1); + } else { + tablePtr->anchorRow = BETWEEN(row-tablePtr->rowOffset, + tablePtr->titleRows, tablePtr->rows-1); + tablePtr->anchorCol = BETWEEN(col-tablePtr->colOffset, + tablePtr->titleCols, tablePtr->cols-1); + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_SelClearCmd -- + * This procedure is invoked to process the selection clear method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_SelClearCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int result = TCL_OK; + char buf1[INDEX_BUFSIZE]; + int row, col, key, clo=0,chi=0,r1,c1,r2,c2; + Tcl_HashEntry *entryPtr; + + if (objc < 4 || objc > 5) { + Tcl_WrongNumArgs(interp, 3, objv, "all| ??"); + return TCL_ERROR; + } + if (STREQ(Tcl_GetString(objv[3]), "all")) { + Tcl_HashSearch search; + for(entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + TableParseArrayIndex(&row, &col, + Tcl_GetHashKey(tablePtr->selCells,entryPtr)); + Tcl_DeleteHashEntry(entryPtr); + TableRefresh(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, CELL); + } + return TCL_OK; + } + if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR || + (objc==5 && + TableGetIndexObj(tablePtr, objv[4], &r2, &c2) == TCL_ERROR)) { + return TCL_ERROR; + } + key = 0; + if (objc == 4) { + r1 = r2 = row; + c1 = c2 = col; + } else { + r1 = MIN(row,r2); r2 = MAX(row,r2); + c1 = MIN(col,c2); c2 = MAX(col,c2); + } + switch (tablePtr->selectType) { + case SEL_BOTH: + clo = c1; chi = c2; + c1 = tablePtr->colOffset; + c2 = tablePtr->cols-1+c1; + key = 1; + goto CLEAR_CELLS; + CLEAR_BOTH: + key = 0; + c1 = clo; c2 = chi; + case SEL_COL: + r1 = tablePtr->rowOffset; + r2 = tablePtr->rows-1+r1; + break; + case SEL_ROW: + c1 = tablePtr->colOffset; + c2 = tablePtr->cols-1+c1; + break; + } + /* row/col are in user index coords */ +CLEAR_CELLS: + for ( row = r1; row <= r2; row++ ) { + for ( col = c1; col <= c2; col++ ) { + TableMakeArrayIndex(row, col, buf1); + entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf1); + if (entryPtr != NULL) { + Tcl_DeleteHashEntry(entryPtr); + TableRefresh(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, CELL); + } + } + } + if (key) goto CLEAR_BOTH; + return result; +} + +/* + *-------------------------------------------------------------- + * + * Table_SelIncludesCmd -- + * This procedure is invoked to process the selection includes method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_SelIncludesCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int row, col; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 3, objv, "index"); + return TCL_ERROR; + } else if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR) { + return TCL_ERROR; + } else { + char buf[INDEX_BUFSIZE]; + TableMakeArrayIndex(row, col, buf); + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), + (Tcl_FindHashEntry(tablePtr->selCells, buf)!=NULL)); + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_SelSetCmd -- + * This procedure is invoked to process the selection set method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_SelSetCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int row, col, dummy, key; + char buf1[INDEX_BUFSIZE]; + Tcl_HashSearch search; + Tcl_HashEntry *entryPtr; + + int clo=0, chi=0, r1, c1, r2, c2, firstRow, firstCol, lastRow, lastCol; + if (objc < 4 || objc > 5) { + Tcl_WrongNumArgs(interp, 3, objv, "first ?last?"); + return TCL_ERROR; + } + if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR || + (objc==5 && + TableGetIndexObj(tablePtr, objv[4], &r2, &c2) == TCL_ERROR)) { + return TCL_ERROR; + } + key = 0; + lastRow = tablePtr->rows-1+tablePtr->rowOffset; + lastCol = tablePtr->cols-1+tablePtr->colOffset; + if (tablePtr->selectTitles) { + firstRow = tablePtr->rowOffset; + firstCol = tablePtr->colOffset; + } else { + firstRow = tablePtr->titleRows+tablePtr->rowOffset; + firstCol = tablePtr->titleCols+tablePtr->colOffset; + } + /* maintain appropriate user index */ + CONSTRAIN(row, firstRow, lastRow); + CONSTRAIN(col, firstCol, lastCol); + if (objc == 4) { + r1 = r2 = row; + c1 = c2 = col; + } else { + CONSTRAIN(r2, firstRow, lastRow); + CONSTRAIN(c2, firstCol, lastCol); + r1 = MIN(row,r2); r2 = MAX(row,r2); + c1 = MIN(col,c2); c2 = MAX(col,c2); + } + switch (tablePtr->selectType) { + case SEL_BOTH: + if (firstCol > lastCol) c2--; /* No selectable columns in table */ + if (firstRow > lastRow) r2--; /* No selectable rows in table */ + clo = c1; chi = c2; + c1 = firstCol; + c2 = lastCol; + key = 1; + goto SET_CELLS; + SET_BOTH: + key = 0; + c1 = clo; c2 = chi; + case SEL_COL: + r1 = firstRow; + r2 = lastRow; + if (firstCol > lastCol) c2--; /* No selectable columns in table */ + break; + case SEL_ROW: + c1 = firstCol; + c2 = lastCol; + if (firstRow>lastRow) r2--; /* No selectable rows in table */ + break; + } +SET_CELLS: + entryPtr = Tcl_FirstHashEntry(tablePtr->selCells, &search); + for ( row = r1; row <= r2; row++ ) { + for ( col = c1; col <= c2; col++ ) { + TableMakeArrayIndex(row, col, buf1); + if (Tcl_FindHashEntry(tablePtr->selCells, buf1) == NULL) { + Tcl_CreateHashEntry(tablePtr->selCells, buf1, &dummy); + TableRefresh(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, CELL); + } + } + } + if (key) goto SET_BOTH; + + /* Adjust the table for top left, selection on screen etc */ + TableAdjustParams(tablePtr); + + /* If the table was previously empty and we want to export the + * selection, we should grab it now */ + if (entryPtr == NULL && tablePtr->exportSelection) { + Tk_OwnSelection(tablePtr->tkwin, XA_PRIMARY, TableLostSelection, + (ClientData) tablePtr); + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_ViewCmd -- + * This procedure is invoked to process the x|yview method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_ViewCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int row, col, value; + char *xy; + + /* Check xview or yview */ + if (objc > 5) { + Tcl_WrongNumArgs(interp, 2, objv, "?args?"); + return TCL_ERROR; + } + xy = Tcl_GetString(objv[1]); + + if (objc == 2) { + Tcl_Obj *resultPtr; + int diff, x, y, w, h; + double first, last; + + resultPtr = Tcl_GetObjResult(interp); + TableGetLastCell(tablePtr, &row, &col); + TableCellVCoords(tablePtr, row, col, &x, &y, &w, &h, 0); + if (*xy == 'y') { + if (row < tablePtr->titleRows) { + first = 0; + last = 1; + } else { + diff = tablePtr->rowStarts[tablePtr->titleRows]; + last = (double) (tablePtr->rowStarts[tablePtr->rows]-diff); + first = (tablePtr->rowStarts[tablePtr->topRow]-diff) / last; + last = (h+tablePtr->rowStarts[row]-diff) / last; + } + } else { + if (col < tablePtr->titleCols) { + first = 0; + last = 1; + } else { + diff = tablePtr->colStarts[tablePtr->titleCols]; + last = (double) (tablePtr->colStarts[tablePtr->cols]-diff); + first = (tablePtr->colStarts[tablePtr->leftCol]-diff) / last; + last = (w+tablePtr->colStarts[col]-diff) / last; + } + } + Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewDoubleObj(first)); + Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewDoubleObj(last)); + } else { + /* cache old topleft to see if it changes */ + int oldTop = tablePtr->topRow, oldLeft = tablePtr->leftCol; + + if (objc == 3) { + if (Tcl_GetIntFromObj(interp, objv[2], &value) != TCL_OK) { + return TCL_ERROR; + } + if (*xy == 'y') { + tablePtr->topRow = value + tablePtr->titleRows; + } else { + tablePtr->leftCol = value + tablePtr->titleCols; + } + } else { + int result; + double frac; +#if (TK_MINOR_VERSION > 0) /* 8.1+ */ + result = Tk_GetScrollInfoObj(interp, objc, objv, &frac, &value); +#else + int i; + char **argv = (char **) ckalloc((objc + 1) * sizeof(char *)); + for (i = 0; i < objc; i++) { + argv[i] = Tcl_GetString(objv[i]); + } + argv[i] = NULL; + result = Tk_GetScrollInfo(interp, objc, argv, &frac, &value); + ckfree ((char *) argv); +#endif + switch (result) { + case TK_SCROLL_ERROR: + return TCL_ERROR; + case TK_SCROLL_MOVETO: + if (frac < 0) frac = 0; + if (*xy == 'y') { + tablePtr->topRow = (int)(frac*tablePtr->rows) + +tablePtr->titleRows; + } else { + tablePtr->leftCol = (int)(frac*tablePtr->cols) + +tablePtr->titleCols; + } + break; + case TK_SCROLL_PAGES: + TableGetLastCell(tablePtr, &row, &col); + if (*xy == 'y') { + tablePtr->topRow += value * (row-tablePtr->topRow+1); + } else { + tablePtr->leftCol += value * (col-tablePtr->leftCol+1); + } + break; + case TK_SCROLL_UNITS: + if (*xy == 'y') { + tablePtr->topRow += value; + } else { + tablePtr->leftCol += value; + } + break; + } + } + /* maintain appropriate real index */ + CONSTRAIN(tablePtr->topRow, tablePtr->titleRows, tablePtr->rows-1); + CONSTRAIN(tablePtr->leftCol, tablePtr->titleCols, tablePtr->cols-1); + /* Do the table adjustment if topRow || leftCol changed */ + if (oldTop != tablePtr->topRow || oldLeft != tablePtr->leftCol) { + TableAdjustParams(tablePtr); + } + } + + return TCL_OK; +} + +#if 0 +/* + *-------------------------------------------------------------- + * + * Table_Cmd -- + * This procedure is invoked to process the CMD method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_Cmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int result = TCL_OK; + + return result; +} +#endif diff --git a/tktable/generic/tkTableEdit.c b/tktable/generic/tkTableEdit.c new file mode 100644 index 0000000..b3ba6de --- /dev/null +++ b/tktable/generic/tkTableEdit.c @@ -0,0 +1,723 @@ +/* + * tkTableEdit.c -- + * + * This module implements editing functions of a table widget. + * + * Copyright (c) 1998-2000 Jeffrey Hobbs + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tkTableEdit.c,v 1.7 2002/10/16 07:30:56 hobbs Exp $ + */ + +#include "tkTable.h" + +static void TableModifyRC _ANSI_ARGS_((register Table *tablePtr, + int doRows, int movetag, + Tcl_HashTable *tagTblPtr, Tcl_HashTable *dimTblPtr, + int offset, int from, int to, int lo, int hi, + int outOfBounds)); + +/* insert/delete subcommands */ +static CONST84 char *modCmdNames[] = { + "active", "cols", "rows", (char *)NULL +}; +enum modCmd { + MOD_ACTIVE, MOD_COLS, MOD_ROWS +}; + +/* insert/delete row/col switches */ +static CONST84 char *rcCmdNames[] = { + "-keeptitles", "-holddimensions", "-holdselection", + "-holdtags", "-holdwindows", "--", + (char *) NULL +}; +enum rcCmd { + OPT_TITLES, OPT_DIMS, OPT_SEL, + OPT_TAGS, OPT_WINS, OPT_LAST +}; + +#define HOLD_TITLES 1<<0 +#define HOLD_DIMS 1<<1 +#define HOLD_TAGS 1<<2 +#define HOLD_WINS 1<<3 +#define HOLD_SEL 1<<4 + + +/* + *-------------------------------------------------------------- + * + * Table_EditCmd -- + * This procedure is invoked to process the insert/delete method + * that corresponds to a table widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_EditCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *) clientData; + int doInsert, cmdIndex, first, last; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, + "option ?switches? arg ?arg?"); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[2], modCmdNames, + "option", 0, &cmdIndex) != TCL_OK) { + return TCL_ERROR; + } + + doInsert = (*(Tcl_GetString(objv[1])) == 'i'); + switch ((enum modCmd) cmdIndex) { + case MOD_ACTIVE: + if (doInsert) { + /* INSERT */ + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "index string"); + return TCL_ERROR; + } + if (TableGetIcursorObj(tablePtr, objv[3], &first) != TCL_OK) { + return TCL_ERROR; + } else if ((tablePtr->flags & HAS_ACTIVE) && + !(tablePtr->flags & ACTIVE_DISABLED) && + tablePtr->state == STATE_NORMAL) { + TableInsertChars(tablePtr, first, Tcl_GetString(objv[4])); + } + } else { + /* DELETE */ + if (objc > 5) { + Tcl_WrongNumArgs(interp, 3, objv, "first ?last?"); + return TCL_ERROR; + } + if (TableGetIcursorObj(tablePtr, objv[3], &first) != TCL_OK) { + return TCL_ERROR; + } + if (objc == 4) { + last = first+1; + } else if (TableGetIcursorObj(tablePtr, objv[4], + &last) != TCL_OK) { + return TCL_ERROR; + } + if ((last >= first) && (tablePtr->flags & HAS_ACTIVE) && + !(tablePtr->flags & ACTIVE_DISABLED) && + tablePtr->state == STATE_NORMAL) { + TableDeleteChars(tablePtr, first, last-first); + } + } + break; /* EDIT ACTIVE */ + + case MOD_COLS: + case MOD_ROWS: { + /* + * ROW/COL INSERTION/DELETION + * FIX: This doesn't handle spans + */ + int i, lo, hi, argsLeft, offset, minkeyoff, doRows; + int maxrow, maxcol, maxkey, minkey, flags, count, *dimPtr; + Tcl_HashTable *tagTblPtr, *dimTblPtr; + Tcl_HashSearch search; + + doRows = (cmdIndex == MOD_ROWS); + flags = 0; + for (i = 3; i < objc; i++) { + if (*(Tcl_GetString(objv[i])) != '-') { + break; + } + if (Tcl_GetIndexFromObj(interp, objv[i], rcCmdNames, + "switch", 0, &cmdIndex) != TCL_OK) { + return TCL_ERROR; + } + if (cmdIndex == OPT_LAST) { + i++; + break; + } + switch (cmdIndex) { + case OPT_TITLES: + flags |= HOLD_TITLES; + break; + case OPT_DIMS: + flags |= HOLD_DIMS; + break; + case OPT_SEL: + flags |= HOLD_SEL; + break; + case OPT_TAGS: + flags |= HOLD_TAGS; + break; + case OPT_WINS: + flags |= HOLD_WINS; + break; + } + } + argsLeft = objc - i; + if (argsLeft < 1 || argsLeft > 2) { + Tcl_WrongNumArgs(interp, 3, objv, "?switches? index ?count?"); + return TCL_ERROR; + } + + count = 1; + maxcol = tablePtr->cols-1+tablePtr->colOffset; + maxrow = tablePtr->rows-1+tablePtr->rowOffset; + if (strcmp(Tcl_GetString(objv[i]), "end") == 0) { + /* allow "end" to be specified as an index */ + first = (doRows) ? maxrow : maxcol; + } else if (Tcl_GetIntFromObj(interp, objv[i], &first) != TCL_OK) { + return TCL_ERROR; + } + if (argsLeft == 2 && + Tcl_GetIntFromObj(interp, objv[++i], &count) != TCL_OK) { + return TCL_ERROR; + } + if (count == 0 || (tablePtr->state == STATE_DISABLED)) { + return TCL_OK; + } + + if (doRows) { + maxkey = maxrow; + minkey = tablePtr->rowOffset; + minkeyoff = tablePtr->rowOffset+tablePtr->titleRows; + offset = tablePtr->rowOffset; + tagTblPtr = tablePtr->rowStyles; + dimTblPtr = tablePtr->rowHeights; + dimPtr = &(tablePtr->rows); + lo = tablePtr->colOffset + + ((flags & HOLD_TITLES) ? tablePtr->titleCols : 0); + hi = maxcol; + } else { + maxkey = maxcol; + minkey = tablePtr->colOffset; + minkeyoff = tablePtr->colOffset+tablePtr->titleCols; + offset = tablePtr->colOffset; + tagTblPtr = tablePtr->colStyles; + dimTblPtr = tablePtr->colWidths; + dimPtr = &(tablePtr->cols); + lo = tablePtr->rowOffset + + ((flags & HOLD_TITLES) ? tablePtr->titleRows : 0); + hi = maxrow; + } + + /* constrain the starting index */ + if (first > maxkey) { + first = maxkey; + } else if (first < minkey) { + first = minkey; + } + if (doInsert) { + /* +count means insert after index, + * -count means insert before index */ + if (count < 0) { + count = -count; + } else { + first++; + } + if ((flags & HOLD_TITLES) && (first < minkeyoff)) { + count -= minkeyoff-first; + if (count <= 0) { + return TCL_OK; + } + first = minkeyoff; + } + if (!(flags & HOLD_DIMS)) { + maxkey += count; + *dimPtr += count; + } + /* + * We need to call TableAdjustParams before TableModifyRC to + * ensure that side effect code like var traces that might get + * called will access the correct new dimensions. + */ + if (*dimPtr < 1) { + *dimPtr = 1; + } + TableAdjustParams(tablePtr); + for (i = maxkey; i >= first; i--) { + /* move row/col style && width/height here */ + TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, + offset, i, i-count, lo, hi, ((i-count) < first)); + } + if (!(flags & HOLD_WINS)) { + /* + * This may be a little severe, but it does unmap the + * windows that need to be unmapped, and those that should + * stay do remap correctly. [Bug #551325] + */ + if (doRows) { + EmbWinUnmap(tablePtr, + first - tablePtr->rowOffset, + maxkey - tablePtr->rowOffset, + lo - tablePtr->colOffset, + hi - tablePtr->colOffset); + } else { + EmbWinUnmap(tablePtr, + lo - tablePtr->rowOffset, + hi - tablePtr->rowOffset, + first - tablePtr->colOffset, + maxkey - tablePtr->colOffset); + } + } + } else { + /* (index = i && count = 1) == (index = i && count = -1) */ + if (count < 0) { + /* if the count is negative, make sure that the col count will + * delete no greater than the original index */ + if (first+count < minkey) { + if (first-minkey < abs(count)) { + /* + * In this case, the user is asking to delete more rows + * than exist before the minkey, so we have to shrink + * the count down to the existing rows up to index. + */ + count = first-minkey; + } else { + count += first-minkey; + } + first = minkey; + } else { + first += count; + count = -count; + } + } + if ((flags & HOLD_TITLES) && (first <= minkeyoff)) { + count -= minkeyoff-first; + if (count <= 0) { + return TCL_OK; + } + first = minkeyoff; + } + if (count > maxkey-first+1) { + count = maxkey-first+1; + } + if (!(flags & HOLD_DIMS)) { + *dimPtr -= count; + } + /* + * We need to call TableAdjustParams before TableModifyRC to + * ensure that side effect code like var traces that might get + * called will access the correct new dimensions. + */ + if (*dimPtr < 1) { + *dimPtr = 1; + } + TableAdjustParams(tablePtr); + for (i = first; i <= maxkey; i++) { + TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, + offset, i, i+count, lo, hi, ((i+count) > maxkey)); + } + } + if (!(flags & HOLD_SEL) && + Tcl_FirstHashEntry(tablePtr->selCells, &search) != NULL) { + /* clear selection - forceful, but effective */ + Tcl_DeleteHashTable(tablePtr->selCells); + Tcl_InitHashTable(tablePtr->selCells, TCL_STRING_KEYS); + } + + /* + * Make sure that the modified dimension is actually legal + * after removing all that stuff. + */ + if (*dimPtr < 1) { + *dimPtr = 1; + TableAdjustParams(tablePtr); + } + + /* change the geometry */ + TableGeometryRequest(tablePtr); + /* FIX: + * This has to handle when the previous rows/cols resize because + * of the *stretchmode. InvalidateAll does that, but could be + * more efficient. + */ + TableInvalidateAll(tablePtr, 0); + break; + } + + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TableDeleteChars -- + * Remove one or more characters from an table widget. + * + * Results: + * None. + * + * Side effects: + * Memory gets freed, the table gets modified and (eventually) + * redisplayed. + * + *---------------------------------------------------------------------- + */ +void +TableDeleteChars(tablePtr, index, count) + register Table *tablePtr; /* Table widget to modify. */ + int index; /* Index of first character to delete. */ + int count; /* How many characters to delete. */ +{ +#ifdef TCL_UTF_MAX + int byteIndex, byteCount, newByteCount, numBytes, numChars; + char *new, *string; + + string = tablePtr->activeBuf; + numBytes = strlen(string); + numChars = Tcl_NumUtfChars(string, numBytes); + if ((index + count) > numChars) { + count = numChars - index; + } + if (count <= 0) { + return; + } + + byteIndex = Tcl_UtfAtIndex(string, index) - string; + byteCount = Tcl_UtfAtIndex(string + byteIndex, count) + - (string + byteIndex); + + newByteCount = numBytes + 1 - byteCount; + new = (char *) ckalloc((unsigned) newByteCount); + memcpy(new, string, (size_t) byteIndex); + strcpy(new + byteIndex, string + byteIndex + byteCount); +#else + int oldlen; + char *new; + + /* this gets the length of the string, as well as ensuring that + * the cursor isn't beyond the end char */ + TableGetIcursor(tablePtr, "end", &oldlen); + + if ((index+count) > oldlen) + count = oldlen-index; + if (count <= 0) + return; + + new = (char *) ckalloc((unsigned)(oldlen-count+1)); + strncpy(new, tablePtr->activeBuf, (size_t) index); + strcpy(new+index, tablePtr->activeBuf+index+count); + /* make sure this string is null terminated */ + new[oldlen-count] = '\0'; +#endif + /* This prevents deletes on BREAK or validation error. */ + if (tablePtr->validate && + TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, + tablePtr->activeCol+tablePtr->colOffset, + tablePtr->activeBuf, new, index) != TCL_OK) { + ckfree(new); + return; + } + + ckfree(tablePtr->activeBuf); + tablePtr->activeBuf = new; + + /* mark the text as changed */ + tablePtr->flags |= TEXT_CHANGED; + + if (tablePtr->icursor >= index) { + if (tablePtr->icursor >= (index+count)) { + tablePtr->icursor -= count; + } else { + tablePtr->icursor = index; + } + } + + TableSetActiveIndex(tablePtr); + + TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); +} + +/* + *---------------------------------------------------------------------- + * + * TableInsertChars -- + * Add new characters to the active cell of a table widget. + * + * Results: + * None. + * + * Side effects: + * New information gets added to tablePtr; it will be redisplayed + * soon, but not necessarily immediately. + * + *---------------------------------------------------------------------- + */ +void +TableInsertChars(tablePtr, index, value) + register Table *tablePtr; /* Table that is to get the new elements. */ + int index; /* Add the new elements before this element. */ + char *value; /* New characters to add (NULL-terminated + * string). */ +{ +#ifdef TCL_UTF_MAX + int oldlen, byteIndex, byteCount; + char *new, *string; + + byteCount = strlen(value); + if (byteCount == 0) { + return; + } + + /* Is this an autoclear and this is the first update */ + /* Note that this clears without validating */ + if (tablePtr->autoClear && !(tablePtr->flags & TEXT_CHANGED)) { + /* set the buffer to be empty */ + tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, 1); + tablePtr->activeBuf[0] = '\0'; + /* the insert position now has to be 0 */ + index = 0; + tablePtr->icursor = 0; + } + + string = tablePtr->activeBuf; + byteIndex = Tcl_UtfAtIndex(string, index) - string; + + oldlen = strlen(string); + new = (char *) ckalloc((unsigned)(oldlen + byteCount + 1)); + memcpy(new, string, (size_t) byteIndex); + strcpy(new + byteIndex, value); + strcpy(new + byteIndex + byteCount, string + byteIndex); + + /* validate potential new active buffer */ + /* This prevents inserts on either BREAK or validation error. */ + if (tablePtr->validate && + TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, + tablePtr->activeCol+tablePtr->colOffset, + tablePtr->activeBuf, new, byteIndex) != TCL_OK) { + ckfree(new); + return; + } + + /* + * The following construction is used because inserting improperly + * formed UTF-8 sequences between other improperly formed UTF-8 + * sequences could result in actually forming valid UTF-8 sequences; + * the number of characters added may not be Tcl_NumUtfChars(string, -1), + * because of context. The actual number of characters added is how + * many characters were are in the string now minus the number that + * used to be there. + */ + + if (tablePtr->icursor >= index) { + tablePtr->icursor += Tcl_NumUtfChars(new, oldlen+byteCount) + - Tcl_NumUtfChars(tablePtr->activeBuf, oldlen); + } + + ckfree(string); + tablePtr->activeBuf = new; + +#else + int oldlen, newlen; + char *new; + + newlen = strlen(value); + if (newlen == 0) return; + + /* Is this an autoclear and this is the first update */ + /* Note that this clears without validating */ + if (tablePtr->autoClear && !(tablePtr->flags & TEXT_CHANGED)) { + /* set the buffer to be empty */ + tablePtr->activeBuf = (char *)ckrealloc(tablePtr->activeBuf, 1); + tablePtr->activeBuf[0] = '\0'; + /* the insert position now has to be 0 */ + index = 0; + } + oldlen = strlen(tablePtr->activeBuf); + /* get the buffer to at least the right length */ + new = (char *) ckalloc((unsigned)(oldlen+newlen+1)); + strncpy(new, tablePtr->activeBuf, (size_t) index); + strcpy(new+index, value); + strcpy(new+index+newlen, (tablePtr->activeBuf)+index); + /* make sure this string is null terminated */ + new[oldlen+newlen] = '\0'; + + /* validate potential new active buffer */ + /* This prevents inserts on either BREAK or validation error. */ + if (tablePtr->validate && + TableValidateChange(tablePtr, tablePtr->activeRow+tablePtr->rowOffset, + tablePtr->activeCol+tablePtr->colOffset, + tablePtr->activeBuf, new, index) != TCL_OK) { + ckfree(new); + return; + } + ckfree(tablePtr->activeBuf); + tablePtr->activeBuf = new; + + if (tablePtr->icursor >= index) { + tablePtr->icursor += newlen; + } +#endif + + /* mark the text as changed */ + tablePtr->flags |= TEXT_CHANGED; + + TableSetActiveIndex(tablePtr); + + TableRefresh(tablePtr, tablePtr->activeRow, tablePtr->activeCol, CELL); +} + +/* + *---------------------------------------------------------------------- + * + * TableModifyRC -- + * Helper function that does the core work of moving rows/cols + * and associated tags. + * + * Results: + * None. + * + * Side effects: + * Moves cell data and possibly tag data + * + *---------------------------------------------------------------------- + */ +static void +TableModifyRC(tablePtr, doRows, flags, tagTblPtr, dimTblPtr, + offset, from, to, lo, hi, outOfBounds) + Table *tablePtr; /* Information about text widget. */ + int doRows; /* rows (1) or cols (0) */ + int flags; /* flags indicating what to move */ + Tcl_HashTable *tagTblPtr, *dimTblPtr; /* Pointers to the row/col tags + * and width/height tags */ + int offset; /* appropriate offset */ + int from, to; /* the from and to row/col */ + int lo, hi; /* the lo and hi col/row */ + int outOfBounds; /* the boundary check for shifting items */ +{ + int j, new; + char buf[INDEX_BUFSIZE], buf1[INDEX_BUFSIZE]; + Tcl_HashEntry *entryPtr, *newPtr; + TableEmbWindow *ewPtr; + + /* + * move row/col style && width/height here + * If -holdtags is specified, we don't move the user-set widths/heights + * of the absolute rows/columns, otherwise we enter here to move the + * dimensions appropriately + */ + if (!(flags & HOLD_TAGS)) { + entryPtr = Tcl_FindHashEntry(tagTblPtr, (char *)from); + if (entryPtr != NULL) { + Tcl_DeleteHashEntry(entryPtr); + } + entryPtr = Tcl_FindHashEntry(dimTblPtr, (char *)from-offset); + if (entryPtr != NULL) { + Tcl_DeleteHashEntry(entryPtr); + } + if (!outOfBounds) { + entryPtr = Tcl_FindHashEntry(tagTblPtr, (char *)to); + if (entryPtr != NULL) { + newPtr = Tcl_CreateHashEntry(tagTblPtr, (char *)from, &new); + Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); + Tcl_DeleteHashEntry(entryPtr); + } + entryPtr = Tcl_FindHashEntry(dimTblPtr, (char *)to-offset); + if (entryPtr != NULL) { + newPtr = Tcl_CreateHashEntry(dimTblPtr, (char *)from-offset, + &new); + Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); + Tcl_DeleteHashEntry(entryPtr); + } + } + } + for (j = lo; j <= hi; j++) { + if (doRows /* rows */) { + TableMakeArrayIndex(from, j, buf); + TableMakeArrayIndex(to, j, buf1); + TableMoveCellValue(tablePtr, to, j, buf1, from, j, buf, + outOfBounds); + } else { + TableMakeArrayIndex(j, from, buf); + TableMakeArrayIndex(j, to, buf1); + TableMoveCellValue(tablePtr, j, to, buf1, j, from, buf, + outOfBounds); + } + /* + * If -holdselection is specified, we leave the selected cells in the + * absolute cell values, otherwise we enter here to move the + * selection appropriately + */ + if (!(flags & HOLD_SEL)) { + entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf); + if (entryPtr != NULL) { + Tcl_DeleteHashEntry(entryPtr); + } + if (!outOfBounds) { + entryPtr = Tcl_FindHashEntry(tablePtr->selCells, buf1); + if (entryPtr != NULL) { + Tcl_CreateHashEntry(tablePtr->selCells, buf, &new); + Tcl_DeleteHashEntry(entryPtr); + } + } + } + /* + * If -holdtags is specified, we leave the tags in the + * absolute cell values, otherwise we enter here to move the + * tags appropriately + */ + if (!(flags & HOLD_TAGS)) { + entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); + if (entryPtr != NULL) { + Tcl_DeleteHashEntry(entryPtr); + } + if (!outOfBounds) { + entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf1); + if (entryPtr != NULL) { + newPtr = Tcl_CreateHashEntry(tablePtr->cellStyles, buf, + &new); + Tcl_SetHashValue(newPtr, Tcl_GetHashValue(entryPtr)); + Tcl_DeleteHashEntry(entryPtr); + } + } + } + /* + * If -holdwindows is specified, we leave the windows in the + * absolute cell values, otherwise we enter here to move the + * windows appropriately + */ + if (!(flags & HOLD_WINS)) { + /* + * Delete whatever window might be in our destination + */ + Table_WinDelete(tablePtr, buf); + if (!outOfBounds) { + /* + * buf1 is where the window is + * buf is where we want it to be + * + * This is an adaptation of Table_WinMove, which we can't + * use because we are intermediately fiddling with boundaries + */ + entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf1); + if (entryPtr != NULL) { + /* + * If there was a window in our source, + * get the window pointer to move it + */ + ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); + /* and free the old hash table entry */ + Tcl_DeleteHashEntry(entryPtr); + + entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, + &new); + /* + * We needn't check if a window was in buf, since the + * Table_WinDelete above should guarantee that no window + * is there. Just set the new entry's value. + */ + Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); + ewPtr->hPtr = entryPtr; + } + } + } + } +} diff --git a/tktable/generic/tkTableInitScript.h b/tktable/generic/tkTableInitScript.h new file mode 100644 index 0000000..a61d19b --- /dev/null +++ b/tktable/generic/tkTableInitScript.h @@ -0,0 +1,90 @@ +/* + * tkTableInitScript.h -- + * + * This file contains common init script for tkTable + * + * Copyright (c) 1998 Jeffrey Hobbs + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +/* + * The following string is the startup script executed when the table is + * loaded. It looks on disk in several different directories for a script + * "TBL_RUNTIME" (as defined in Makefile) that is compatible with this + * version of tkTable. The sourced script has all key bindings defined. + */ + +static char tkTableInitScript[] = "if {[info proc tkTableInit]==\"\"} {\n\ + proc tkTableInit {} {\n\ + global tk_library tcl_pkgPath errorInfo env\n\ + rename tkTableInit {}\n\ + set errors {}\n\ + if {![info exists env(TK_TABLE_LIBRARY_FILE)]} {\n\ + set env(TK_TABLE_LIBRARY_FILE) " TBL_RUNTIME "\n\ + }\n\ + if {[info exists env(TK_TABLE_LIBRARY)]} {\n\ + lappend dirs $env(TK_TABLE_LIBRARY)\n\ + }\n\ + lappend dirs " TBL_RUNTIME_DIR "\n\ + if {[info exists tcl_pkgPath]} {\n\ + foreach i $tcl_pkgPath {\n\ + lappend dirs [file join $i Tktable" PACKAGE_VERSION "] \\\n\ + [file join $i Tktable] $i\n\ + }\n\ + }\n\ + lappend dirs $tk_library [pwd]\n\ + foreach i $dirs {\n\ + set try [file join $i $env(TK_TABLE_LIBRARY_FILE)]\n\ + if {[file exists $try]} {\n\ + if {![catch {uplevel #0 [list source $try]} msg]} {\n\ + set env(TK_TABLE_LIBRARY) $i\n\ + return\n\ + } else {\n\ + append errors \"$try: $msg\n$errorInfo\n\"\n\ + }\n\ + }\n\ + }\n" +#ifdef NO_EMBEDDED_RUNTIME +" set msg \"Can't find a $env(TK_TABLE_LIBRARY_FILE) in the following directories: \n\"\n\ + append msg \" $dirs\n\n$errors\n\n\"\n\ + append msg \"This probably means that TkTable wasn't installed properly.\"\n\ + return -code error $msg\n" +#else +" set env(TK_TABLE_LIBRARY) EMBEDDED_RUNTIME\n" +# ifdef MAC_TCL +" source -rsrc tkTable" +# else +" uplevel #0 {" +# include "tkTable.tcl.h" +" }" +# endif +#endif +" }\n\ +}\n\ +tkTableInit"; + +/* + * The init script can't make certain calls in a safe interpreter, + * so we always have to use the embedded runtime for it + */ +static char tkTableSafeInitScript[] = "if {[info proc tkTableInit]==\"\"} {\n\ + proc tkTableInit {} {\n\ + set env(TK_TABLE_LIBRARY) EMBEDDED_RUNTIME\n" +#ifdef NO_EMBEDDED_RUNTIME +" append msg \"tkTable requires embedded runtime to be compiled for\"\n\ + append msg \" use in safe interpreters\"\n\ + return -code error $msg\n" +#endif +# ifdef MAC_TCL +" source -rsrc tkTable" +# else +" uplevel #0 {" +# include "tkTable.tcl.h" +" }" +# endif +" }\n\ +}\n\ +tkTableInit"; + diff --git a/tktable/generic/tkTablePs.c b/tktable/generic/tkTablePs.c new file mode 100644 index 0000000..018f079 --- /dev/null +++ b/tktable/generic/tkTablePs.c @@ -0,0 +1,1299 @@ +/* + * tkTablePs.c -- + * + * This module implements postscript output for table widgets. + * Based off of Tk8.1a2 tkCanvPs.c. + * + * Copyright (c) 1991-1994 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * changes 1998 Copyright (c) 1998 Jeffrey Hobbs + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + */ + +#include "tkTable.h" + +/* This is for Tcl_DStringAppendAll */ +#if defined(__STDC__) || defined(HAS_STDARG) +#include +#else +#include +#endif + +#ifndef TCL_INTEGER_SPACE +/* This appears in 8.1 */ +#define TCL_INTEGER_SPACE 24 +#endif + +/* + * One of the following structures is created to keep track of Postscript + * output being generated. It consists mostly of information provided on + * the widget command line. + */ + +typedef struct TkPostscriptInfo { + int x, y, width, height; /* Area to print, in table pixel + * coordinates. */ + int x2, y2; /* x+width and y+height. */ + char *pageXString; /* String value of "-pagex" option or NULL. */ + char *pageYString; /* String value of "-pagey" option or NULL. */ + double pageX, pageY; /* Postscript coordinates (in points) + * corresponding to pageXString and + * pageYString. Don't forget that y-values + * grow upwards for Postscript! */ + char *pageWidthString; /* Printed width of output. */ + char *pageHeightString; /* Printed height of output. */ + double scale; /* Scale factor for conversion: each pixel + * maps into this many points. */ + Tk_Anchor pageAnchor; /* How to anchor bbox on Postscript page. */ + int rotate; /* Non-zero means output should be rotated + * on page (landscape mode). */ + char *fontVar; /* If non-NULL, gives name of global variable + * containing font mapping information. + * Malloc'ed. */ + char *colorVar; /* If non-NULL, give name of global variable + * containing color mapping information. + * Malloc'ed. */ + char *colorMode; /* Mode for handling colors: "monochrome", + * "gray", or "color". Malloc'ed. */ + int colorLevel; /* Numeric value corresponding to colorMode: + * 0 for mono, 1 for gray, 2 for color. */ + char *fileName; /* Name of file in which to write Postscript; + * NULL means return Postscript info as + * result. Malloc'ed. */ + char *channelName; /* If -channel is specified, the name of + * the channel to use. */ + Tcl_Channel chan; /* Open channel corresponding to fileName. */ + Tcl_HashTable fontTable; /* Hash table containing names of all font + * families used in output. The hash table + * values are not used. */ + char *first, *last; /* table indices to start and end at */ +} TkPostscriptInfo; + +/* + * The table below provides a template that's used to process arguments + * to the table "postscript" command and fill in TkPostscriptInfo + * structures. + */ + +static Tk_ConfigSpec configSpecs[] = { + {TK_CONFIG_STRING, "-colormap", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, colorVar), 0}, + {TK_CONFIG_STRING, "-colormode", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, colorMode), 0}, + {TK_CONFIG_STRING, "-file", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, fileName), 0}, + {TK_CONFIG_STRING, "-channel", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, channelName), 0}, + {TK_CONFIG_STRING, "-first", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, first), 0}, + {TK_CONFIG_STRING, "-fontmap", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, fontVar), 0}, + {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, height), 0}, + {TK_CONFIG_STRING, "-last", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, last), 0}, + {TK_CONFIG_ANCHOR, "-pageanchor", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, pageAnchor), 0}, + {TK_CONFIG_STRING, "-pageheight", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, pageHeightString), 0}, + {TK_CONFIG_STRING, "-pagewidth", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, pageWidthString), 0}, + {TK_CONFIG_STRING, "-pagex", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, pageXString), 0}, + {TK_CONFIG_STRING, "-pagey", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, pageYString), 0}, + {TK_CONFIG_BOOLEAN, "-rotate", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, rotate), 0}, + {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, width), 0}, + {TK_CONFIG_PIXELS, "-x", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, x), 0}, + {TK_CONFIG_PIXELS, "-y", (char *) NULL, (char *) NULL, "", + Tk_Offset(TkPostscriptInfo, y), 0}, + {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, 0} +}; + +/* + * The prolog data. Generated by str2c from prolog.ps + * This was split in small chunks by str2c because + * some C compiler have limitations on the size of static strings. + * (str2c is a small tcl script in tcl's tool directory (source release)) + */ +/* + * This is a stripped down version of that found in tkCanvPs.c of Tk8.1a2. + * Comments, and stuff pertaining to stipples and other unused entities + * have been removed + */ +static CONST char * CONST prolog[]= { + /* Start of part 1 */ + "%%BeginProlog\n\ +50 dict begin\n\ +\n\ +% This is standard prolog for Postscript generated by Tk's table widget.\n\ +% Based of standard prolog for Tk's canvas widget.\n\ +\n\ +% INITIALIZING VARIABLES\n\ +\n\ +/baseline 0 def\n\ +/height 0 def\n\ +/justify 0 def\n\ +/cellHeight 0 def\n\ +/cellWidth 0 def\n\ +/spacing 0 def\n\ +/strings 0 def\n\ +/xoffset 0 def\n\ +/yoffset 0 def\n\ +/x 0 def\n\ +/y 0 def\n\ +\n\ +% Define the array ISOLatin1Encoding, if it isn't already present.\n\ +\n\ +systemdict /ISOLatin1Encoding known not {\n\ + /ISOLatin1Encoding [\n\ + /space /space /space /space /space /space /space /space\n\ + /space /space /space /space /space /space /space /space\n\ + /space /space /space /space /space /space /space /space\n\ + /space /space /space /space /space /space /space /space\n\ + /space /exclam /quotedbl /numbersign /dollar /percent /ampersand\n\ + /quoteright\n\ + /parenleft /parenright /asterisk /plus /comma /minus /period /slash\n\ + /zero /one /two /three /four /five /six /seven\n\ + /eight /nine /colon /semicolon /less /equal /greater /question\n\ + /at /A /B /C /D /E /F /G\n\ + /H /I /J /K /L /M /N /O\n\ + /P /Q /R /S /T /U /V /W\n\ + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ + /quoteleft /a /b /c /d /e /f /g\n\ + /h /i /j /k /l /m /n /o\n\ + /p /q /r /s /t /u /v /w\n\ + /x /y /z /braceleft /bar /braceright /asciitilde /space\n\ + /space /space /space /space /space /space /space /space\n\ + /space /space /space /space /space /space /space /space\n\ + /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent\n\ + /dieresis /space /ring /cedilla /space /hungarumlaut /ogonek /caron\n\ + /space /exclamdown /cent /sterling /currency /yen /brokenbar /section\n\ + /dieresis /copyright /ordfem", + + "inine /guillemotleft /logicalnot /hyphen\n\ + /registered /macron\n\ + /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph\n\ + /periodcentered\n\ + /cedillar /onesuperior /ordmasculine /guillemotright /onequarter\n\ + /onehalf /threequarters /questiondown\n\ + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n\ + /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex\n\ + /Idieresis\n\ + /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply\n\ + /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n\ + /germandbls\n\ + /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n\ + /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex\n\ + /idieresis\n\ + /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide\n\ + /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn\n\ + /ydieresis\n\ + ] def\n\ +} if\n", + + "\n\ +% font ISOEncode font\n\ +% This procedure changes the encoding of a font from the default\n\ +% Postscript encoding to ISOLatin1. It's typically invoked just\n\ +% before invoking \"setfont\". The body of this procedure comes from\n\ +% Section 5.6.1 of the Postscript book.\n\ +\n\ +/ISOEncode {\n\ + dup length dict begin\n\ + {1 index /FID ne {def} {pop pop} ifelse} forall\n\ + /Encoding ISOLatin1Encoding def\n\ + currentdict\n\ + end\n\ +\n\ + % I'm not sure why it's necessary to use \"definefont\" on this new\n\ + % font, but it seems to be important; just use the name \"Temporary\"\n\ + % for the font.\n\ +\n\ + /Temporary exch definefont\n\ +} bind def\n\ +\n\ +% -- AdjustColor --\n\ +% Given a color value already set for output by the caller, adjusts\n\ +% that value to a grayscale or mono value if requested by the CL variable.\n\ +\n\ +/AdjustColor {\n\ + setrgbcolor\n\ + CL 2 lt {\n\ + currentgray\n\ + CL 0 eq {\n\ + .5 lt {0} {1} ifelse\n\ + } if\n\ + setgray\n\ + } if\n\ +} bind def\n\ +\n\ +% pointSize fontName SetFont\n\ +% The ISOEncode shouldn't be done to Symbol fonts...\n\ +/SetFont {\n\ + findfont exch scalefont ISOEncode setfont\n\ +} def\n\ +\n", + + "% x y strings spacing xoffset yoffset justify ... DrawText --\n\ +% This procedure does all of the real work of drawing text. The\n\ +% color and font must already have been set by the caller, and the\n\ +% following arguments must be on the stack:\n\ +%\n\ +% x, y - Coordinates at which to draw text.\n\ +% strings - An array of strings, one for each line of the text item,\n\ +% in order from top to bottom.\n\ +% spacing - Spacing between lines.\n\ +% xoffset - Horizontal offset for text bbox relative to x and y: 0 for\n\ +% nw/w/sw anchor, -0.5 for n/center/s, and -1.0 for ne/e/se.\n\ +% yoffset - Vertical offset for text bbox relative to x and y: 0 for\n\ +% nw/n/ne anchor, +0.5 for w/center/e, and +1.0 for sw/s/se.\n\ +% justify - 0 for left justification, 0.5 for center, 1 for right justify.\n\ +% cellWidth - width for this cell\n\ +% cellHeight - height for this cell\n\ +%\n\ +% Also, when this procedure is invoked, the color and font must already\n\ +% have been set for the text.\n\ +\n", + + "/DrawCellText {\n\ + /cellHeight exch def\n\ + /cellWidth exch def\n\ + /justify exch def\n\ + /yoffset exch def\n\ + /xoffset exch def\n\ + /spacing exch def\n\ + /strings exch def\n\ + /y exch def\n\ + /x exch def\n\ +\n\ + % Compute the baseline offset and the actual font height.\n\ +\n\ + 0 0 moveto (TXygqPZ) false charpath\n\ + pathbbox dup /baseline exch def\n\ + exch pop exch sub /height exch def pop\n\ + newpath\n\ +\n\ + % Translate coordinates first so that the origin is at the upper-left\n\ + % corner of the text's bounding box. Remember that x and y for\n\ + % positioning are still on the stack.\n\ +\n\ + col0 x sub row0 y sub translate\n\ + cellWidth xoffset mul\n\ + strings length 1 sub spacing mul height add yoffset mul translate\n\ +\n\ + % Now use the baseline and justification information to translate so\n\ + % that the origin is at the baseline and positioning point for the\n\ + % first line of text.\n\ +\n\ + justify cellWidth mul baseline neg translate\n\ +\n\ + % Iterate over each of the lines to output it. For each line,\n\ + % compute its width again so it can be properly justified, then\n\ + % display it.\n\ +\n\ + strings {\n\ + dup stringwidth pop\n\ + justify neg mul 0 moveto\n\ + show\n\ + 0 spacing neg translate\n\ + } forall\n\ +} bind def\n\ +\n", + + "%\n\ +% x, y - Coordinates at which to draw text.\n\ +% strings - An array of strings, one for each line of the text item,\n\ +% in order from top to bottom.\n\ +% spacing - Spacing between lines.\n\ +% xoffset - Horizontal offset for text bbox relative to x and y: 0 for\n\ +% nw/w/sw anchor, -0.5 for n/center/s, and -1.0 for ne/e/se.\n\ +% yoffset - Vertical offset for text bbox relative to x and y: 0 for\n\ +% nw/n/ne anchor, +0.5 for w/center/e, and +1.0 for sw/s/se.\n\ +% justify - 0 for left justification, 0.5 for center, 1 for right justify.\n\ +% cellWidth - width for this cell\n\ +% cellHeight - height for this cell\n\ +%\n\ +% Also, when this procedure is invoked, the color and font must already\n\ +% have been set for the text.\n\ +\n\ +/DrawCellTextOld {\n\ + /cellHeight exch def\n\ + /cellWidth exch def\n\ + /justify exch def\n\ + /yoffset exch def\n\ + /xoffset exch def\n\ + /spacing exch def\n\ + /strings exch def\n\ +\n\ + % Compute the baseline offset and the actual font height.\n\ +\n\ + 0 0 moveto (TXygqPZ) false charpath\n\ + pathbbox dup /baseline exch def\n\ + exch pop exch sub /height exch def pop\n\ + newpath\n\ +\n\ + % Translate coordinates first so that the origin is at the upper-left\n\ + % corner of the text's bounding box. Remember that x and y for\n\ + % positioning are still on the stack.\n\ +\n\ + translate\n\ + cellWidth xoffset mul\n\ + strings length 1 sub spacing mul height add yoffset mul translate\n\ +\n\ + % Now use the baseline and justification information to translate so\n\ + % that the origin is at the baseline and positioning point for the\n\ + % first line of text.\n\ +\n\ + justify cellWidth mul baseline neg translate\n\ +\n\ + % Iterate over each of the lines to output it. For each line,\n\ + % compute its width again so it can be properly justified, then\n\ + % display it.\n\ +\n\ + strings {\n\ + dup stringwidth pop\n\ + justify neg mul 0 moveto\n\ + show\n\ + 0 spacing neg translate\n\ + } forall\n\ +} bind def\n\ +\n\ +%%EndProlog\n\ +", + /* End of part 5 */ + + NULL /* End of data marker */ +}; + +/* + * Forward declarations for procedures defined later in this file: + */ + +static int GetPostscriptPoints _ANSI_ARGS_((Tcl_Interp *interp, + char *string, double *doublePtr)); +int Tk_TablePsFont _ANSI_ARGS_((Tcl_Interp *interp, + Table *tablePtr, Tk_Font tkfont)); +int Tk_TablePsColor _ANSI_ARGS_((Tcl_Interp *interp, + Table *tablePtr, XColor *colorPtr)); +static int TextToPostscript _ANSI_ARGS_((Tcl_Interp *interp, + Table *tablePtr, TableTag *tagPtr, int tagX, int tagY, + int width, int height, int row, int col, + Tk_TextLayout textLayout)); + +/* + * Tcl could really use some more convenience routines... + * This is just Tcl_DStringAppend for multiple lines, including + * the full text of each line + */ +void +Tcl_DStringAppendAll TCL_VARARGS_DEF(Tcl_DString *, arg1) +{ + va_list argList; + Tcl_DString *dstringPtr; + char *string; + + dstringPtr = TCL_VARARGS_START(Tcl_DString *, arg1, argList); + while ((string = va_arg(argList, char *)) != NULL) { + Tcl_DStringAppend(dstringPtr, string, -1); + } + va_end(argList); +} + +/* + *-------------------------------------------------------------- + * + * Table_PostscriptCmd -- + * + * This procedure is invoked to process the "postscript" options + * of the widget command for table widgets. See the user + * documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ + + /* ARGSUSED */ +int +Table_PostscriptCmd(clientData, interp, objc, objv) + ClientData clientData; /* Information about table widget. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of argument objects. */ + Tcl_Obj *CONST objv[]; +{ +#ifdef _WIN32 + /* + * At the moment, it just doesn't like this code... + */ + return TCL_OK; +#else + register Table *tablePtr = (Table *) clientData; + TkPostscriptInfo psInfo, *oldInfoPtr; + int result; + int row, col, firstRow, firstCol, lastRow, lastCol; + /* dimensions of first and last cell to output */ + int x0, y0, w0, h0, xn, yn, wn, hn; + int x, y, w, h, i; +#define STRING_LENGTH 400 + char string[STRING_LENGTH+1], *p, **argv; + size_t length; + int deltaX = 0, deltaY = 0; /* Offset of lower-left corner of area to + * be marked up, measured in table units + * from the positioning point on the page + * (reflects anchor position). Initial + * values needed only to stop compiler + * warnings. */ + Tcl_HashSearch search; + Tcl_HashEntry *hPtr; + CONST char * CONST *chunk; + Tk_TextLayout textLayout = NULL; + char *value; + int rowHeight, total, *colWidths, iW, iH; + TableTag *tagPtr, *colPtr, *rowPtr, *titlePtr; + Tcl_DString postscript, buffer; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 2, objv, "?option value ...?"); + return TCL_ERROR; + } + + /* + *---------------------------------------------------------------- + * Initialize the data structure describing Postscript generation, + * then process all the arguments to fill the data structure in. + *---------------------------------------------------------------- + */ + + Tcl_DStringInit(&postscript); + Tcl_DStringInit(&buffer); + oldInfoPtr = tablePtr->psInfoPtr; + tablePtr->psInfoPtr = &psInfo; + /* This is where in the window that we start printing from */ + psInfo.x = 0; + psInfo.y = 0; + psInfo.width = -1; + psInfo.height = -1; + psInfo.pageXString = NULL; + psInfo.pageYString = NULL; + psInfo.pageX = 72*4.25; + psInfo.pageY = 72*5.5; + psInfo.pageWidthString = NULL; + psInfo.pageHeightString = NULL; + psInfo.scale = 1.0; + psInfo.pageAnchor = TK_ANCHOR_CENTER; + psInfo.rotate = 0; + psInfo.fontVar = NULL; + psInfo.colorVar = NULL; + psInfo.colorMode = NULL; + psInfo.colorLevel = 0; + psInfo.fileName = NULL; + psInfo.channelName = NULL; + psInfo.chan = NULL; + psInfo.first = NULL; + psInfo.last = NULL; + Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS); + + /* + * The magic StringifyObjects + */ + argv = (char **) ckalloc((objc + 1) * sizeof(char *)); + for (i = 0; i < objc; i++) + argv[i] = Tcl_GetString(objv[i]); + argv[i] = NULL; + + result = Tk_ConfigureWidget(interp, tablePtr->tkwin, configSpecs, + objc-2, argv+2, (char *) &psInfo, + TK_CONFIG_ARGV_ONLY); + if (result != TCL_OK) { + goto cleanup; + } + + if (psInfo.first == NULL) { + firstRow = 0; + firstCol = 0; + } else if (TableGetIndex(tablePtr, psInfo.first, &firstRow, &firstCol) + != TCL_OK) { + result = TCL_ERROR; + goto cleanup; + } + if (psInfo.last == NULL) { + lastRow = tablePtr->rows-1; + lastCol = tablePtr->cols-1; + } else if (TableGetIndex(tablePtr, psInfo.last, &lastRow, &lastCol) + != TCL_OK) { + result = TCL_ERROR; + goto cleanup; + } + + if (psInfo.fileName != NULL) { + /* Check that -file and -channel are not both specified. */ + if (psInfo.channelName != NULL) { + Tcl_AppendResult(interp, "can't specify both -file", + " and -channel", (char *) NULL); + result = TCL_ERROR; + goto cleanup; + } + + /* + * Check that we are not in a safe interpreter. If we are, disallow + * the -file specification. + */ + if (Tcl_IsSafe(interp)) { + Tcl_AppendResult(interp, "can't specify -file in a", + " safe interpreter", (char *) NULL); + result = TCL_ERROR; + goto cleanup; + } + + p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer); + if (p == NULL) { + result = TCL_ERROR; + goto cleanup; + } + psInfo.chan = Tcl_OpenFileChannel(interp, p, "w", 0666); + Tcl_DStringFree(&buffer); + Tcl_DStringInit(&buffer); + if (psInfo.chan == NULL) { + result = TCL_ERROR; + goto cleanup; + } + } + + if (psInfo.channelName != NULL) { + int mode; + /* + * Check that the channel is found in this interpreter and that it + * is open for writing. + */ + psInfo.chan = Tcl_GetChannel(interp, psInfo.channelName, &mode); + if (psInfo.chan == (Tcl_Channel) NULL) { + result = TCL_ERROR; + goto cleanup; + } + if ((mode & TCL_WRITABLE) == 0) { + Tcl_AppendResult(interp, "channel \"", psInfo.channelName, + "\" wasn't opened for writing", (char *) NULL); + result = TCL_ERROR; + goto cleanup; + } + } + + if (psInfo.colorMode == NULL) { + psInfo.colorLevel = 2; + } else { + length = strlen(psInfo.colorMode); + if (strncmp(psInfo.colorMode, "monochrome", length) == 0) { + psInfo.colorLevel = 0; + } else if (strncmp(psInfo.colorMode, "gray", length) == 0) { + psInfo.colorLevel = 1; + } else if (strncmp(psInfo.colorMode, "color", length) == 0) { + psInfo.colorLevel = 2; + } else { + Tcl_AppendResult(interp, "bad color mode \"", psInfo.colorMode, + "\": must be monochrome, gray or color", (char *) NULL); + goto cleanup; + } + } + + TableCellCoords(tablePtr, firstRow, firstCol, &x0, &y0, &w0, &h0); + TableCellCoords(tablePtr, lastRow, lastCol, &xn, &yn, &wn, &hn); + psInfo.x = x0; + psInfo.y = y0; + if (psInfo.width == -1) { + psInfo.width = xn+wn; + } + if (psInfo.height == -1) { + psInfo.height = yn+hn; + } + psInfo.x2 = psInfo.x + psInfo.width; + psInfo.y2 = psInfo.y + psInfo.height; + + if (psInfo.pageXString != NULL) { + if (GetPostscriptPoints(interp, psInfo.pageXString, + &psInfo.pageX) != TCL_OK) { + goto cleanup; + } + } + if (psInfo.pageYString != NULL) { + if (GetPostscriptPoints(interp, psInfo.pageYString, + &psInfo.pageY) != TCL_OK) { + goto cleanup; + } + } + if (psInfo.pageWidthString != NULL) { + if (GetPostscriptPoints(interp, psInfo.pageWidthString, + &psInfo.scale) != TCL_OK) { + goto cleanup; + } + psInfo.scale /= psInfo.width; + } else if (psInfo.pageHeightString != NULL) { + if (GetPostscriptPoints(interp, psInfo.pageHeightString, + &psInfo.scale) != TCL_OK) { + goto cleanup; + } + psInfo.scale /= psInfo.height; + } else { + psInfo.scale = (72.0/25.4)*WidthMMOfScreen(Tk_Screen(tablePtr->tkwin)) + / WidthOfScreen(Tk_Screen(tablePtr->tkwin)); + } + switch (psInfo.pageAnchor) { + case TK_ANCHOR_NW: + case TK_ANCHOR_W: + case TK_ANCHOR_SW: + deltaX = 0; + break; + case TK_ANCHOR_N: + case TK_ANCHOR_CENTER: + case TK_ANCHOR_S: + deltaX = -psInfo.width/2; + break; + case TK_ANCHOR_NE: + case TK_ANCHOR_E: + case TK_ANCHOR_SE: + deltaX = -psInfo.width; + break; + } + switch (psInfo.pageAnchor) { + case TK_ANCHOR_NW: + case TK_ANCHOR_N: + case TK_ANCHOR_NE: + deltaY = - psInfo.height; + break; + case TK_ANCHOR_W: + case TK_ANCHOR_CENTER: + case TK_ANCHOR_E: + deltaY = -psInfo.height/2; + break; + case TK_ANCHOR_SW: + case TK_ANCHOR_S: + case TK_ANCHOR_SE: + deltaY = 0; + break; + } + + /* + *-------------------------------------------------------- + * Make a PREPASS over all of the tags + * to collect information about all the fonts in use, so that + * we can output font information in the proper form required + * by the Document Structuring Conventions. + *-------------------------------------------------------- + */ + + Tk_TablePsFont(interp, tablePtr, tablePtr->defaultTag.tkfont); + Tcl_ResetResult(interp); + for (hPtr = Tcl_FirstHashEntry(tablePtr->tagTable, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + tagPtr = (TableTag *) Tcl_GetHashValue(hPtr); + if (tagPtr->tkfont != NULL) { + Tk_TablePsFont(interp, tablePtr, tagPtr->tkfont); + } + } + Tcl_ResetResult(interp); + + /* + *-------------------------------------------------------- + * Generate the header and prolog for the Postscript. + *-------------------------------------------------------- + */ + + sprintf(string, " %d,%d => %d,%d\n", firstRow, firstCol, lastRow, lastCol); + Tcl_DStringAppendAll(&postscript, + "%!PS-Adobe-3.0 EPSF-3.0\n", + "%%Creator: Tk Table Widget ", TBL_VERSION, "\n", + "%%Title: Window ", + Tk_PathName(tablePtr->tkwin), string, + "%%BoundingBox: ", + (char *) NULL); + if (!psInfo.rotate) { + sprintf(string, "%d %d %d %d\n", + (int) (psInfo.pageX + psInfo.scale*deltaX), + (int) (psInfo.pageY + psInfo.scale*deltaY), + (int) (psInfo.pageX + psInfo.scale*(deltaX + psInfo.width) + + 1.0), + (int) (psInfo.pageY + psInfo.scale*(deltaY + psInfo.height) + + 1.0)); + } else { + sprintf(string, "%d %d %d %d\n", + (int) (psInfo.pageX - psInfo.scale*(deltaY + psInfo.height)), + (int) (psInfo.pageY + psInfo.scale*deltaX), + (int) (psInfo.pageX - psInfo.scale*deltaY + 1.0), + (int) (psInfo.pageY + psInfo.scale*(deltaX + psInfo.width) + + 1.0)); + } + Tcl_DStringAppendAll(&postscript, string, + "%%Pages: 1\n%%DocumentData: Clean7Bit\n", + "%%Orientation: ", + psInfo.rotate?"Landscape\n":"Portrait\n", + (char *) NULL); + p = "%%DocumentNeededResources: font "; + for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + sprintf(string, "%s%s\n", p, Tcl_GetHashKey(&psInfo.fontTable, hPtr)); + Tcl_DStringAppend(&postscript, string, -1); + p = "%%+ font "; + } + Tcl_DStringAppend(&postscript, "%%EndComments\n\n", -1); + + /* + * Insert the prolog + */ + for (chunk=prolog; *chunk; chunk++) { + Tcl_DStringAppend(&postscript, *chunk, -1); + } + + if (psInfo.chan != NULL) { + Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); + Tcl_DStringFree(&postscript); + Tcl_DStringInit(&postscript); + } + + /* + * Document setup: set the color level and include fonts. + * This is where we start using &postscript + */ + + sprintf(string, "/CL %d def\n", psInfo.colorLevel); + Tcl_DStringAppendAll(&postscript, "%%BeginSetup\n", string, (char *) NULL); + for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + sprintf(string, "%s%s\n", "%%IncludeResource: font ", + Tcl_GetHashKey(&psInfo.fontTable, hPtr)); + Tcl_DStringAppend(&postscript, string, -1); + } + Tcl_DStringAppend(&postscript, "%%EndSetup\n\n", -1); + + /* + * Page setup: move to page positioning point, rotate if + * needed, set scale factor, offset for proper anchor position, + * and set clip region. + */ + + sprintf(string, "%.1f %.1f translate\n", + psInfo.pageX, psInfo.pageY); + Tcl_DStringAppendAll(&postscript, "%%Page: 1 1\nsave\n", + string, psInfo.rotate?"90 rotate\n":"", + (char *) NULL); + sprintf(string, "%.4g %.4g scale\n%d %d translate\n", + psInfo.scale, psInfo.scale, deltaX - psInfo.x, deltaY); + Tcl_DStringAppend(&postscript, string, -1); + sprintf(string, "%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g", + psInfo.x, (double) psInfo.y2-psInfo.y, + psInfo.x2,(double) psInfo.y2-psInfo.y, + psInfo.x2, 0.0, psInfo.x, 0.0); + Tcl_DStringAppend(&postscript, string, -1); + Tcl_DStringAppend(&postscript, " lineto closepath clip newpath\n", -1); + if (psInfo.chan != NULL) { + Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); + Tcl_DStringFree(&postscript); + Tcl_DStringInit(&postscript); + } + + /* + * Go through each cell, calculating full desired height + */ + result = TCL_OK; + + hPtr = Tcl_FindHashEntry(tablePtr->tagTable, "title"); + titlePtr = (TableTag *) Tcl_GetHashValue(hPtr); + + total = 0; + colWidths = (int *) ckalloc((lastCol-firstCol) * sizeof(int)); + for (col = 0; col <= lastCol-firstCol; col++) colWidths[col] = 0; + Tcl_DStringAppend(&buffer, "gsave\n", -1); + for (row = firstRow; row <= lastRow; row++) { + rowHeight = 0; + rowPtr = FindRowColTag(tablePtr, row+tablePtr->rowOffset, ROW); + for (col = firstCol; col <= lastCol; col++) { + /* get the coordinates for the cell */ + TableCellCoords(tablePtr, row, col, &x, &y, &w, &h); + if ((x >= psInfo.x2) || (x+w < psInfo.x) || + (y >= psInfo.y2) || (y+h < psInfo.y)) { + continue; + } + + if (row == tablePtr->activeRow && col == tablePtr->activeCol) { + value = tablePtr->activeBuf; + } else { + value = TableGetCellValue(tablePtr, row+tablePtr->rowOffset, + col+tablePtr->colOffset); + } + if (!strlen(value)) { + continue; + } + + /* Create the tag here */ + tagPtr = TableNewTag(); + /* First, merge in the default tag */ + TableMergeTag(tagPtr, &(tablePtr->defaultTag)); + + colPtr = FindRowColTag(tablePtr, col+tablePtr->colOffset, COL); + if (colPtr != (TableTag *) NULL) TableMergeTag(tagPtr, colPtr); + if (rowPtr != (TableTag *) NULL) TableMergeTag(tagPtr, rowPtr); + /* Am I in the titles */ + if (row < tablePtr->topRow || col < tablePtr->leftCol) { + TableMergeTag(tagPtr, titlePtr); + } + /* Does this have a cell tag */ + TableMakeArrayIndex(row+tablePtr->rowOffset, + col+tablePtr->colOffset, string); + hPtr = Tcl_FindHashEntry(tablePtr->cellStyles, string); + if (hPtr != NULL) { + TableMergeTag(tagPtr, (TableTag *) Tcl_GetHashValue(hPtr)); + } + + /* + * the use of -1 instead of Tcl_NumUtfChars means we don't + * pass NULLs to postscript + */ + textLayout = Tk_ComputeTextLayout(tagPtr->tkfont, value, -1, + (tagPtr->wrap>0) ? w : 0, + tagPtr->justify, + (tagPtr->multiline>0) ? 0 : + TK_IGNORE_NEWLINES, &iW, &iH); + + rowHeight = MAX(rowHeight, iH); + colWidths[col-firstCol] = MAX(colWidths[col-firstCol], iW); + + result = TextToPostscript(interp, tablePtr, tagPtr, + x, y, iW, iH, row, col, textLayout); + Tk_FreeTextLayout(textLayout); + if (result != TCL_OK) { + char msg[64 + TCL_INTEGER_SPACE]; + + sprintf(msg, "\n (generating Postscript for cell %s)", + string); + Tcl_AddErrorInfo(interp, msg); + goto cleanup; + } + Tcl_DStringAppend(&buffer, Tcl_GetStringResult(interp), -1); + } + sprintf(string, "/row%d %d def\n", + row, tablePtr->psInfoPtr->y2 - total); + Tcl_DStringAppend(&postscript, string, -1); + total += rowHeight + 2*tablePtr->defaultTag.bd; + } + Tcl_DStringAppend(&buffer, "grestore\n", -1); + sprintf(string, "/row%d %d def\n", row, tablePtr->psInfoPtr->y2 - total); + Tcl_DStringAppend(&postscript, string, -1); + + total = tablePtr->defaultTag.bd; + for (col = firstCol; col <= lastCol; col++) { + sprintf(string, "/col%d %d def\n", col, total); + Tcl_DStringAppend(&postscript, string, -1); + total += colWidths[col-firstCol] + 2*tablePtr->defaultTag.bd; + } + sprintf(string, "/col%d %d def\n", col, total); + Tcl_DStringAppend(&postscript, string, -1); + + Tcl_DStringAppend(&postscript, Tcl_DStringValue(&buffer), -1); + + /* + * Output to channel at the end of it all + * This should more incremental, but that can't be avoided in order + * to post-define width/height of the cols/rows + */ + if (psInfo.chan != NULL) { + Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); + Tcl_DStringFree(&postscript); + Tcl_DStringInit(&postscript); + } + + /* + *--------------------------------------------------------------------- + * Output page-end information, such as commands to print the page + * and document trailer stuff. + *--------------------------------------------------------------------- + */ + + Tcl_DStringAppend(&postscript, + "restore showpage\n\n%%Trailer\nend\n%%EOF\n", -1); + if (psInfo.chan != NULL) { + Tcl_Write(psInfo.chan, Tcl_DStringValue(&postscript), -1); + Tcl_DStringFree(&postscript); + Tcl_DStringInit(&postscript); + } + + /* + * Clean up psInfo to release malloc'ed stuff. + */ + +cleanup: + ckfree((char *) argv); + Tcl_DStringResult(interp, &postscript); + Tcl_DStringFree(&postscript); + Tcl_DStringFree(&buffer); + if (psInfo.first != NULL) { + ckfree(psInfo.first); + } + if (psInfo.last != NULL) { + ckfree(psInfo.last); + } + if (psInfo.pageXString != NULL) { + ckfree(psInfo.pageXString); + } + if (psInfo.pageYString != NULL) { + ckfree(psInfo.pageYString); + } + if (psInfo.pageWidthString != NULL) { + ckfree(psInfo.pageWidthString); + } + if (psInfo.pageHeightString != NULL) { + ckfree(psInfo.pageHeightString); + } + if (psInfo.fontVar != NULL) { + ckfree(psInfo.fontVar); + } + if (psInfo.colorVar != NULL) { + ckfree(psInfo.colorVar); + } + if (psInfo.colorMode != NULL) { + ckfree(psInfo.colorMode); + } + if (psInfo.fileName != NULL) { + ckfree(psInfo.fileName); + } + if ((psInfo.chan != NULL) && (psInfo.channelName == NULL)) { + Tcl_Close(interp, psInfo.chan); + } + if (psInfo.channelName != NULL) { + ckfree(psInfo.channelName); + } + Tcl_DeleteHashTable(&psInfo.fontTable); + tablePtr->psInfoPtr = oldInfoPtr; + return result; +#endif +} + +/* + *-------------------------------------------------------------- + * + * Tk_TablePsColor -- + * + * This procedure is called by individual table items when + * they want to set a color value for output. Given information + * about an X color, this procedure will generate Postscript + * commands to set up an appropriate color in Postscript. + * + * Results: + * Returns a standard Tcl return value. If an error occurs + * then an error message will be left in the interp's result. + * If no error occurs, then additional Postscript will be + * appended to the interp's result. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +int +Tk_TablePsColor(interp, tablePtr, colorPtr) + Tcl_Interp *interp; /* Interpreter for returning Postscript + * or error message. */ + Table *tablePtr; /* Information about table. */ + XColor *colorPtr; /* Information about color. */ +{ + TkPostscriptInfo *psInfoPtr = tablePtr->psInfoPtr; + int tmp; + double red, green, blue; + char string[200]; + + /* + * If there is a color map defined, then look up the color's name + * in the map and use the Postscript commands found there, if there + * are any. + */ + + if (psInfoPtr->colorVar != NULL) { + char *cmdString; + + cmdString = Tcl_GetVar2(interp, psInfoPtr->colorVar, + Tk_NameOfColor(colorPtr), 0); + if (cmdString != NULL) { + Tcl_AppendResult(interp, cmdString, "\n", (char *) NULL); + return TCL_OK; + } + } + + /* + * No color map entry for this color. Grab the color's intensities + * and output Postscript commands for them. Special note: X uses + * a range of 0-65535 for intensities, but most displays only use + * a range of 0-255, which maps to (0, 256, 512, ... 65280) in the + * X scale. This means that there's no way to get perfect white, + * since the highest intensity is only 65280 out of 65535. To + * work around this problem, rescale the X intensity to a 0-255 + * scale and use that as the basis for the Postscript colors. This + * scheme still won't work if the display only uses 4 bits per color, + * but most diplays use at least 8 bits. + */ + + tmp = colorPtr->red; + red = ((double) (tmp >> 8))/255.0; + tmp = colorPtr->green; + green = ((double) (tmp >> 8))/255.0; + tmp = colorPtr->blue; + blue = ((double) (tmp >> 8))/255.0; + sprintf(string, "%.3f %.3f %.3f AdjustColor\n", + red, green, blue); + Tcl_AppendResult(interp, string, (char *) NULL); + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Tk_TablePsFont -- + * + * This procedure is called by individual table items when + * they want to output text. Given information about an X + * font, this procedure will generate Postscript commands + * to set up an appropriate font in Postscript. + * + * Results: + * Returns a standard Tcl return value. If an error occurs + * then an error message will be left in the interp's result. + * If no error occurs, then additional Postscript will be + * appended to the interp's result. + * + * Side effects: + * The Postscript font name is entered into psInfoPtr->fontTable + * if it wasn't already there. + * + *-------------------------------------------------------------- + */ + +int +Tk_TablePsFont(interp, tablePtr, tkfont) + Tcl_Interp *interp; /* Interpreter for returning Postscript + * or error message. */ + Table *tablePtr; /* Information about table. */ + Tk_Font tkfont; /* Information about font in which text + * is to be printed. */ +{ + TkPostscriptInfo *psInfoPtr = tablePtr->psInfoPtr; + char *end; + char pointString[TCL_INTEGER_SPACE]; + Tcl_DString ds; + int i, points; + + /* + * First, look up the font's name in the font map, if there is one. + * If there is an entry for this font, it consists of a list + * containing font name and size. Use this information. + */ + + Tcl_DStringInit(&ds); + + if (psInfoPtr->fontVar != NULL) { + char *list, **argv; + int objc; + double size; + char *name; + + name = Tk_NameOfFont(tkfont); + list = Tcl_GetVar2(interp, psInfoPtr->fontVar, name, 0); + if (list != NULL) { + if (Tcl_SplitList(interp, list, &objc, &argv) != TCL_OK) { + badMapEntry: + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "bad font map entry for \"", name, + "\": \"", list, "\"", (char *) NULL); + return TCL_ERROR; + } + if (objc != 2) { + goto badMapEntry; + } + size = strtod(argv[1], &end); + if ((size <= 0) || (*end != 0)) { + goto badMapEntry; + } + + Tcl_DStringAppend(&ds, argv[0], -1); + points = (int) size; + + ckfree((char *) argv); + goto findfont; + } + } + + points = Tk_PostscriptFontName(tkfont, &ds); + +findfont: + sprintf(pointString, "%d", points); + Tcl_AppendResult(interp, pointString, " /", Tcl_DStringValue(&ds), + " SetFont\n", (char *) NULL); + Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i); + Tcl_DStringFree(&ds); + + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * GetPostscriptPoints -- + * + * Given a string, returns the number of Postscript points + * corresponding to that string. + * + * Results: + * The return value is a standard Tcl return result. If + * TCL_OK is returned, then everything went well and the + * screen distance is stored at *doublePtr; otherwise + * TCL_ERROR is returned and an error message is left in + * the interp's result. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +static int +GetPostscriptPoints(interp, string, doublePtr) + Tcl_Interp *interp; /* Use this for error reporting. */ + char *string; /* String describing a screen distance. */ + double *doublePtr; /* Place to store converted result. */ +{ + char *end; + double d; + + d = strtod(string, &end); + if (end == string) { + error: + Tcl_AppendResult(interp, "bad distance \"", string, + "\"", (char *) NULL); + return TCL_ERROR; + } +#define UCHAR(c) ((unsigned char) (c)) + while ((*end != '\0') && isspace(UCHAR(*end))) { + end++; + } + switch (*end) { + case 'c': + d *= 72.0/2.54; + end++; + break; + case 'i': + d *= 72.0; + end++; + break; + case 'm': + d *= 72.0/25.4; + end++; + break; + case 0: + break; + case 'p': + end++; + break; + default: + goto error; + } + while ((*end != '\0') && isspace(UCHAR(*end))) { + end++; + } + if (*end != 0) { + goto error; + } + *doublePtr = d; + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * TextToPostscript -- + * + * This procedure is called to generate Postscript for + * text items. + * + * Results: + * The return value is a standard Tcl result. If an error + * occurs in generating Postscript then an error message is + * left in the interp's result, replacing whatever used + * to be there. If no error occurs, then Postscript for the + * item is appended to the result. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +static int +TextToPostscript(interp, tablePtr, tagPtr, tagX, tagY, width, height, + row, col, textLayout) + Tcl_Interp *interp; /* Leave Postscript or error message here. */ + Table *tablePtr; /* Information about overall canvas. */ + TableTag *tagPtr; /* */ + int tagX, tagY; /* */ + int width, height; /* */ + int row, col; /* */ + Tk_TextLayout textLayout; /* */ +{ + int x, y; + Tk_FontMetrics fm; + char *justify; + char buffer[500]; + Tk_3DBorder fg = tagPtr->fg; + + if (fg == NULL) { + fg = tablePtr->defaultTag.fg; + } + + if (Tk_TablePsFont(interp, tablePtr, tagPtr->tkfont) != TCL_OK) { + return TCL_ERROR; + } + if (Tk_TablePsColor(interp, tablePtr, Tk_3DBorderColor(fg)) != TCL_OK) { + return TCL_ERROR; + } + + sprintf(buffer, "%% %.15g %.15g [\n", (tagX+width)/2.0, + tablePtr->psInfoPtr->y2 - ((tagY+height)/2.0)); + Tcl_AppendResult(interp, buffer, (char *) NULL); + sprintf(buffer, "col%d row%d [\n", col, row); + Tcl_AppendResult(interp, buffer, (char *) NULL); + + Tk_TextLayoutToPostscript(interp, textLayout); + + x = 0; y = 0; justify = NULL; /* lint. */ + switch (tagPtr->anchor) { + case TK_ANCHOR_NW: x = 0; y = 0; break; + case TK_ANCHOR_N: x = 1; y = 0; break; + case TK_ANCHOR_NE: x = 2; y = 0; break; + case TK_ANCHOR_E: x = 2; y = 1; break; + case TK_ANCHOR_SE: x = 2; y = 2; break; + case TK_ANCHOR_S: x = 1; y = 2; break; + case TK_ANCHOR_SW: x = 0; y = 2; break; + case TK_ANCHOR_W: x = 0; y = 1; break; + case TK_ANCHOR_CENTER: x = 1; y = 1; break; + } + switch (tagPtr->justify) { + case TK_JUSTIFY_RIGHT: justify = "1"; break; + case TK_JUSTIFY_CENTER: justify = "0.5";break; + case TK_JUSTIFY_LEFT: justify = "0"; + } + + Tk_GetFontMetrics(tagPtr->tkfont, &fm); + sprintf(buffer, "] %d %g %g %s %d %d DrawCellText\n", + fm.linespace, (x / -2.0), (y / 2.0), justify, + width, height); + Tcl_AppendResult(interp, buffer, (char *) NULL); + + return TCL_OK; +} diff --git a/tktable/generic/tkTableTag.c b/tktable/generic/tkTableTag.c new file mode 100644 index 0000000..028984a --- /dev/null +++ b/tktable/generic/tkTableTag.c @@ -0,0 +1,1354 @@ +/* + * tkTableTag.c -- + * + * This module implements tags for table widgets. + * + * Copyright (c) 1998-2002 Jeffrey Hobbs + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tkTableTag.c,v 1.15 2008/11/14 22:46:57 hobbs Exp $ + */ + +#include "tkTable.h" + +static TableTag *TableTagGetEntry _ANSI_ARGS_((Table *tablePtr, char *name, + int objc, CONST char **argv)); +static unsigned int TableTagGetPriority _ANSI_ARGS_((Table *tablePtr, + TableTag *tagPtr)); +static void TableImageProc _ANSI_ARGS_((ClientData clientData, int x, + int y, int width, int height, int imageWidth, int imageHeight)); +static int TableOptionReliefSet _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + CONST84 char *value, char *widgRec, int offset)); +static char * TableOptionReliefGet _ANSI_ARGS_((ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, + Tcl_FreeProc **freeProcPtr)); + +static CONST84 char *tagCmdNames[] = { + "celltag", "cget", "coltag", "configure", "delete", "exists", + "includes", "lower", "names", "raise", "rowtag", (char *) NULL +}; + +enum tagCmd { + TAG_CELLTAG, TAG_CGET, TAG_COLTAG, TAG_CONFIGURE, TAG_DELETE, TAG_EXISTS, + TAG_INCLUDES, TAG_LOWER, TAG_NAMES, TAG_RAISE, TAG_ROWTAG +}; + +static Cmd_Struct tagState_vals[]= { + {"unknown", STATE_UNKNOWN}, + {"normal", STATE_NORMAL}, + {"disabled", STATE_DISABLED}, + {"", 0 } +}; + +static Tk_CustomOption tagStateOpt = +{ Cmd_OptionSet, Cmd_OptionGet, (ClientData) (&tagState_vals) }; +static Tk_CustomOption tagBdOpt = +{ TableOptionBdSet, TableOptionBdGet, (ClientData) BD_TABLE_TAG }; +static Tk_CustomOption tagReliefOpt = +{ TableOptionReliefSet, TableOptionReliefGet, (ClientData) NULL }; + +/* + * The default specification for configuring tags + * Done like this to make the command line parsing easy + */ + +static Tk_ConfigSpec tagConfig[] = { + {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", + Tk_Offset(TableTag, anchor), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_BORDER, "-background", "background", "Background", NULL, + Tk_Offset(TableTag, bg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, + {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, + {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "", + 0 /* no offset */, + TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagBdOpt }, + {TK_CONFIG_STRING, "-ellipsis", "ellipsis", "Ellipsis", "", + Tk_Offset(TableTag, ellipsis), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", NULL, + Tk_Offset(TableTag, fg), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, + {TK_CONFIG_FONT, "-font", "font", "Font", NULL, + Tk_Offset(TableTag, tkfont), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_STRING, "-image", "image", "Image", NULL, + Tk_Offset(TableTag, imageStr), + TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", "left", + Tk_Offset(TableTag, justify), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_INT, "-multiline", "multiline", "Multiline", "-1", + Tk_Offset(TableTag, multiline), TK_CONFIG_DONT_SET_DEFAULT }, + {TK_CONFIG_CUSTOM, "-relief", "relief", "Relief", "flat", + Tk_Offset(TableTag, relief), TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, + &tagReliefOpt }, + {TK_CONFIG_INT, "-showtext", "showText", "ShowText", "-1", + Tk_Offset(TableTag, showtext), TK_CONFIG_DONT_SET_DEFAULT }, + {TK_CONFIG_CUSTOM, "-state", "state", "State", "unknown", + Tk_Offset(TableTag, state), TK_CONFIG_DONT_SET_DEFAULT, &tagStateOpt }, + {TK_CONFIG_INT, "-wrap", "wrap", "Wrap", "-1", + Tk_Offset(TableTag, wrap), TK_CONFIG_DONT_SET_DEFAULT }, + {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} +}; + +/* + * The join tag structure is used to create a combined tag, so it + * keeps priority info. + */ +typedef struct { + TableTag tag; /* must be first */ + unsigned int magic; + unsigned int pbg, pfg, pborders, prelief, ptkfont, panchor, pimage; + unsigned int pstate, pjustify, pmultiline, pwrap, pshowtext, pellipsis; +} TableJoinTag; + +/* + *---------------------------------------------------------------------- + * + * TableImageProc -- + * Called when an image associated with a tag is changed. + * + * Results: + * None. + * + * Side effects: + * Invalidates the whole table. + * This should only invalidate affected cells, but that info + * is not managed... + * + *---------------------------------------------------------------------- + */ +static void +TableImageProc(ClientData clientData, int x, int y, int width, int height, + int imageWidth, int imageHeight) +{ + TableInvalidateAll((Table *)clientData, 0); +} + +/* + *---------------------------------------------------------------------- + * + * TableNewTag -- + * ckallocs space for a new tag structure and inits the structure. + * + * Results: + * Returns a pointer to the new structure. Must be freed later. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +TableTag * +TableNewTag(Table *tablePtr) +{ + TableTag *tagPtr; + + /* + * If tablePtr is NULL, make a regular tag, otherwise make a join tag. + */ + if (tablePtr == NULL) { + tagPtr = (TableTag *) ckalloc(sizeof(TableTag)); + memset((VOID *) tagPtr, 0, sizeof(TableTag)); + + /* + * Set the values that aren't 0/NULL by default + */ + tagPtr->anchor = (Tk_Anchor)-1; + tagPtr->justify = (Tk_Justify)-1; + tagPtr->multiline = -1; + tagPtr->relief = -1; + tagPtr->showtext = -1; + tagPtr->state = STATE_UNKNOWN; + tagPtr->wrap = -1; + } else { + TableJoinTag *jtagPtr = (TableJoinTag *) ckalloc(sizeof(TableJoinTag)); + memset((VOID *) jtagPtr, 0, sizeof(TableJoinTag)); + tagPtr = (TableTag *) jtagPtr; + + tagPtr->anchor = (Tk_Anchor)-1; + tagPtr->justify = (Tk_Justify)-1; + tagPtr->multiline = -1; + tagPtr->relief = -1; + tagPtr->showtext = -1; + tagPtr->state = STATE_UNKNOWN; + tagPtr->wrap = -1; + jtagPtr->magic = 0x99ABCDEF; + jtagPtr->pbg = -1; + jtagPtr->pfg = -1; + jtagPtr->pborders = -1; + jtagPtr->prelief = -1; + jtagPtr->ptkfont = -1; + jtagPtr->panchor = -1; + jtagPtr->pimage = -1; + jtagPtr->pstate = -1; + jtagPtr->pjustify = -1; + jtagPtr->pmultiline = -1; + jtagPtr->pwrap = -1; + jtagPtr->pshowtext = -1; + jtagPtr->pellipsis = -1; + } + + return (TableTag *) tagPtr; +} + +/* + *---------------------------------------------------------------------- + * + * TableResetTag -- + * This routine resets a given tag to the table defaults. + * + * Results: + * Tag will have values changed. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +TableResetTag(Table *tablePtr, TableTag *tagPtr) +{ + TableJoinTag *jtagPtr = (TableJoinTag *) tagPtr; + + if (jtagPtr->magic != 0x99ABCDEF) { + panic("bad mojo in TableResetTag"); + } + + memset((VOID *) jtagPtr, 0, sizeof(TableJoinTag)); + + tagPtr->anchor = (Tk_Anchor)-1; + tagPtr->justify = (Tk_Justify)-1; + tagPtr->multiline = -1; + tagPtr->relief = -1; + tagPtr->showtext = -1; + tagPtr->state = STATE_UNKNOWN; + tagPtr->wrap = -1; + jtagPtr->magic = 0x99ABCDEF; + jtagPtr->pbg = -1; + jtagPtr->pfg = -1; + jtagPtr->pborders = -1; + jtagPtr->prelief = -1; + jtagPtr->ptkfont = -1; + jtagPtr->panchor = -1; + jtagPtr->pimage = -1; + jtagPtr->pstate = -1; + jtagPtr->pjustify = -1; + jtagPtr->pmultiline = -1; + jtagPtr->pwrap = -1; + jtagPtr->pshowtext = -1; + jtagPtr->pellipsis = -1; + + /* + * Merge in the default tag. + */ + memcpy((VOID *) jtagPtr, (VOID *) &(tablePtr->defaultTag), + sizeof(TableTag)); +} + +/* + *---------------------------------------------------------------------- + * + * TableMergeTag -- + * This routine merges two tags by adding any fields from the addTag + * that are set to the baseTag. + * + * Results: + * baseTag will inherit all set characteristics of addTag + * (addTag thus has the priority). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +TableMergeTag(Table *tablePtr, TableTag *baseTag, TableTag *addTag) +{ + TableJoinTag *jtagPtr = (TableJoinTag *) baseTag; + unsigned int prio; + + if (jtagPtr->magic != 0x99ABCDEF) { + panic("bad mojo in TableMergeTag"); + } + +#ifndef NO_TAG_PRIORITIES + /* + * Find priority for the tag to merge + */ + prio = TableTagGetPriority(tablePtr, addTag); + + if ((addTag->anchor != -1) && (prio < jtagPtr->panchor)) { + baseTag->anchor = addTag->anchor; + jtagPtr->panchor = prio; + } + if ((addTag->bg != NULL) && (prio < jtagPtr->pbg)) { + baseTag->bg = addTag->bg; + jtagPtr->pbg = prio; + } + if ((addTag->fg != NULL) && (prio < jtagPtr->pfg)) { + baseTag->fg = addTag->fg; + jtagPtr->pfg = prio; + } + if ((addTag->ellipsis != NULL) && (prio < jtagPtr->pellipsis)) { + baseTag->ellipsis = addTag->ellipsis; + jtagPtr->pellipsis = prio; + } + if ((addTag->tkfont != NULL) && (prio < jtagPtr->ptkfont)) { + baseTag->tkfont = addTag->tkfont; + jtagPtr->ptkfont = prio; + } + if ((addTag->imageStr != NULL) && (prio < jtagPtr->pimage)) { + baseTag->imageStr = addTag->imageStr; + baseTag->image = addTag->image; + jtagPtr->pimage = prio; + } + if ((addTag->multiline >= 0) && (prio < jtagPtr->pmultiline)) { + baseTag->multiline = addTag->multiline; + jtagPtr->pmultiline = prio; + } + if ((addTag->relief != -1) && (prio < jtagPtr->prelief)) { + baseTag->relief = addTag->relief; + jtagPtr->prelief = prio; + } + if ((addTag->showtext >= 0) && (prio < jtagPtr->pshowtext)) { + baseTag->showtext = addTag->showtext; + jtagPtr->pshowtext = prio; + } + if ((addTag->state != STATE_UNKNOWN) && (prio < jtagPtr->pstate)) { + baseTag->state = addTag->state; + jtagPtr->pstate = prio; + } + if ((addTag->justify != -1) && (prio < jtagPtr->pjustify)) { + baseTag->justify = addTag->justify; + jtagPtr->pjustify = prio; + } + if ((addTag->wrap >= 0) && (prio < jtagPtr->pwrap)) { + baseTag->wrap = addTag->wrap; + jtagPtr->pwrap = prio; + } + if ((addTag->borders) && (prio < jtagPtr->pborders)) { + baseTag->borderStr = addTag->borderStr; + baseTag->borders = addTag->borders; + baseTag->bd[0] = addTag->bd[0]; + baseTag->bd[1] = addTag->bd[1]; + baseTag->bd[2] = addTag->bd[2]; + baseTag->bd[3] = addTag->bd[3]; + jtagPtr->pborders = prio; + } +#else + if (addTag->anchor != -1) baseTag->anchor = addTag->anchor; + if (addTag->bg != NULL) baseTag->bg = addTag->bg; + if (addTag->fg != NULL) baseTag->fg = addTag->fg; + if (addTag->ellipsis != NULL) baseTag->ellipsis = addTag->ellipsis; + if (addTag->tkfont != NULL) baseTag->tkfont = addTag->tkfont; + if (addTag->imageStr != NULL) { + baseTag->imageStr = addTag->imageStr; + baseTag->image = addTag->image; + } + if (addTag->multiline >= 0) baseTag->multiline = addTag->multiline; + if (addTag->relief != -1) baseTag->relief = addTag->relief; + if (addTag->showtext >= 0) baseTag->showtext = addTag->showtext; + if (addTag->state != STATE_UNKNOWN) baseTag->state = addTag->state; + if (addTag->justify != -1) baseTag->justify = addTag->justify; + if (addTag->wrap >= 0) baseTag->wrap = addTag->wrap; + if (addTag->borders) { + baseTag->borderStr = addTag->borderStr; + baseTag->borders = addTag->borders; + baseTag->bd[0] = addTag->bd[0]; + baseTag->bd[1] = addTag->bd[1]; + baseTag->bd[2] = addTag->bd[2]; + baseTag->bd[3] = addTag->bd[3]; + } +#endif +} + +/* + *---------------------------------------------------------------------- + * + * TableInvertTag -- + * This routine swaps background and foreground for the selected tag. + * + * Results: + * Inverts fg and bg of tag. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +TableInvertTag(TableTag *baseTag) +{ + Tk_3DBorder tmpBg; + + tmpBg = baseTag->fg; + baseTag->fg = baseTag->bg; + baseTag->bg = tmpBg; +} + +/* + *---------------------------------------------------------------------- + * + * TableGetTagBorders -- + * This routine gets the border values based on a tag. + * + * Results: + * It returns the values in the int*'s (if not NULL), and the + * total number of defined borders as a result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +int +TableGetTagBorders(TableTag *tagPtr, + int *left, int *right, int *top, int *bottom) +{ + switch (tagPtr->borders) { + case 0: + if (left) { *left = 0; } + if (right) { *right = 0; } + if (top) { *top = 0; } + if (bottom) { *bottom = 0; } + break; + case 1: + if (left) { *left = tagPtr->bd[0]; } + if (right) { *right = tagPtr->bd[0]; } + if (top) { *top = tagPtr->bd[0]; } + if (bottom) { *bottom = tagPtr->bd[0]; } + break; + case 2: + if (left) { *left = tagPtr->bd[0]; } + if (right) { *right = tagPtr->bd[1]; } + if (top) { *top = 0; } + if (bottom) { *bottom = 0; } + break; + case 4: + if (left) { *left = tagPtr->bd[0]; } + if (right) { *right = tagPtr->bd[1]; } + if (top) { *top = tagPtr->bd[2]; } + if (bottom) { *bottom = tagPtr->bd[3]; } + break; + default: + panic("invalid border value '%d'\n", tagPtr->borders); + break; + } + return tagPtr->borders; +} + +/* + *---------------------------------------------------------------------- + * + * TableTagGetEntry -- + * Takes a name and optional args and creates a tag entry in the + * table's tag table. + * + * Results: + * A new tag entry will be created and returned. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static TableTag * +TableTagGetEntry(Table *tablePtr, char *name, int objc, CONST char **argv) +{ + Tcl_HashEntry *entryPtr; + TableTag *tagPtr = NULL; + int new; + + entryPtr = Tcl_CreateHashEntry(tablePtr->tagTable, name, &new); + if (new) { + tagPtr = TableNewTag(NULL); + Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); + if (tablePtr->tagPrioSize >= tablePtr->tagPrioMax) { + int i; + /* + * Increase the priority list size in blocks of 10 + */ + tablePtr->tagPrioMax += 10; + tablePtr->tagPrioNames = (char **) ckrealloc( + (char *) tablePtr->tagPrioNames, + sizeof(TableTag *) * tablePtr->tagPrioMax); + tablePtr->tagPrios = (TableTag **) ckrealloc( + (char *) tablePtr->tagPrios, + sizeof(TableTag *) * tablePtr->tagPrioMax); + for (i = tablePtr->tagPrioSize; i < tablePtr->tagPrioMax; i++) { + tablePtr->tagPrioNames[i] = (char *) NULL; + tablePtr->tagPrios[i] = (TableTag *) NULL; + } + } + tablePtr->tagPrioNames[tablePtr->tagPrioSize] = + (char *) Tcl_GetHashKey(tablePtr->tagTable, entryPtr); + tablePtr->tagPrios[tablePtr->tagPrioSize] = tagPtr; + tablePtr->tagPrioSize++; + } else { + tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); + } + if (objc) { + Tk_ConfigureWidget(tablePtr->interp, tablePtr->tkwin, tagConfig, + objc, (CONST84 char **) argv, (char *)tagPtr, + TK_CONFIG_ARGV_ONLY); + } + return tagPtr; +} + +/* + *---------------------------------------------------------------------- + * + * TableTagGetPriority -- + * Get the priority value for a tag. + * + * Results: + * returns the priority. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static unsigned int +TableTagGetPriority(Table *tablePtr, TableTag *tagPtr) +{ + unsigned int prio = 0; + while (tagPtr != tablePtr->tagPrios[prio]) { prio++; } + return prio; +} + +/* + *---------------------------------------------------------------------- + * + * TableInitTags -- + * Creates the static table tags. + * + * Results: + * active, sel, title and flash are created as tags. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +TableInitTags(Table *tablePtr) +{ + static CONST char *activeArgs[] = {"-bg", ACTIVE_BG, "-relief", "flat" }; + static CONST char *selArgs[] = {"-bg", SELECT_BG, "-fg", SELECT_FG, + "-relief", "sunken" }; + static CONST char *titleArgs[] = {"-bg", DISABLED, "-fg", "white", + "-relief", "flat", + "-state", "disabled" }; + static CONST char *flashArgs[] = {"-bg", "red" }; + /* + * The order of creation is important to priority. + */ + TableTagGetEntry(tablePtr, "flash", ARSIZE(flashArgs), flashArgs); + TableTagGetEntry(tablePtr, "active", ARSIZE(activeArgs), activeArgs); + TableTagGetEntry(tablePtr, "sel", ARSIZE(selArgs), selArgs); + TableTagGetEntry(tablePtr, "title", ARSIZE(titleArgs), titleArgs); +} + +/* + *---------------------------------------------------------------------- + * + * FindRowColTag -- + * Finds a row/col tag based on the row/col styles and tagCommand. + * + * Results: + * Returns tag associated with row/col cell, if any. + * + * Side effects: + * Possible side effects from eval of tagCommand. + * IMPORTANT: This plays with the interp result object, + * so use of resultPtr in prior command may be invalid after + * calling this function. + * + *---------------------------------------------------------------------- + */ +TableTag * +FindRowColTag(Table *tablePtr, int cell, int mode) +{ + Tcl_HashEntry *entryPtr; + TableTag *tagPtr = NULL; + + entryPtr = Tcl_FindHashEntry((mode == ROW) ? tablePtr->rowStyles + : tablePtr->colStyles, (char *) cell); + if (entryPtr == NULL) { + char *cmd = (mode == ROW) ? tablePtr->rowTagCmd : tablePtr->colTagCmd; + if (cmd) { + register Tcl_Interp *interp = tablePtr->interp; + char buf[INDEX_BUFSIZE]; + /* + * Since no specific row/col tag exists, eval the given command + * with row/col appended + */ + sprintf(buf, " %d", cell); + Tcl_Preserve((ClientData) interp); + if (Tcl_VarEval(interp, cmd, buf, (char *)NULL) == TCL_OK) { + CONST char *name = Tcl_GetStringResult(interp); + if (name && *name) { + /* + * If a result was returned, check to see if it is + * a valid tag. + */ + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, name); + } + } + Tcl_Release((ClientData) interp); + Tcl_ResetResult(interp); + } + } + if (entryPtr != NULL) { + /* + * This can be either the one in row|colStyles, + * or that returned by eval'ing the row|colTagCmd + */ + tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); + } + return tagPtr; +} + +/* + *---------------------------------------------------------------------- + * + * TableCleanupTag -- + * Releases the resources used by a tag before it is freed up. + * + * Results: + * None. + * + * Side effects: + * The tag is no longer valid. + * + *---------------------------------------------------------------------- + */ +void +TableCleanupTag(Table *tablePtr, TableTag *tagPtr) +{ + /* + * Free resources that the optionSpec doesn't specifically know about + */ + if (tagPtr->image) { + Tk_FreeImage(tagPtr->image); + } + + Tk_FreeOptions(tagConfig, (char *) tagPtr, tablePtr->display, 0); +} + +/* + *-------------------------------------------------------------- + * + * Table_TagCmd -- + * This procedure is invoked to process the tag method + * that corresponds to a widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_TagCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *)clientData; + int result = TCL_OK, cmdIndex, i, newEntry, value, len; + int row, col, tagPrio, refresh = 0; + TableTag *tagPtr, *tag2Ptr; + Tcl_HashEntry *entryPtr, *scanPtr; + Tcl_HashTable *hashTblPtr; + Tcl_HashSearch search; + Tk_Image image; + Tcl_Obj *objPtr, *resultPtr; + char buf[INDEX_BUFSIZE], *keybuf, *tagname; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + return TCL_ERROR; + } + + result = Tcl_GetIndexFromObj(interp, objv[2], tagCmdNames, + "tag option", 0, &cmdIndex); + if (result != TCL_OK) { + return result; + } + /* + * Before using this object, make sure there aren't any calls that + * could have changed the interp result, thus freeing the object. + */ + resultPtr = Tcl_GetObjResult(interp); + + switch ((enum tagCmd) cmdIndex) { + case TAG_CELLTAG: /* add named tag to a (group of) cell(s) */ + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "tag ?arg arg ...?"); + return TCL_ERROR; + } + tagname = Tcl_GetStringFromObj(objv[3], &len); + if (len == 0) { + /* + * An empty string was specified, so just delete the tag. + */ + tagPtr = NULL; + } else { + /* + * Get the pointer to the tag structure. If it doesn't + * exist, it will be created. + */ + tagPtr = TableTagGetEntry(tablePtr, tagname, 0, NULL); + } + + if (objc == 4) { + /* + * The user just wants the cells with this tag returned. + * Handle specially tags named: active, flash, sel, title + */ + + if ((tablePtr->flags & HAS_ACTIVE) && + STREQ(tagname, "active")) { + TableMakeArrayIndex( + tablePtr->activeRow+tablePtr->rowOffset, + tablePtr->activeCol+tablePtr->colOffset, buf); + Tcl_SetStringObj(resultPtr, buf, -1); + } else if ((tablePtr->flashMode && STREQ(tagname, "flash")) + || STREQ(tagname, "sel")) { + hashTblPtr = (*tagname == 's') ? + tablePtr->selCells : tablePtr->flashCells; + for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); + scanPtr != NULL; + scanPtr = Tcl_NextHashEntry(&search)) { + keybuf = (char *) Tcl_GetHashKey(hashTblPtr, scanPtr); + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewStringObj(keybuf, -1)); + } + } else if (STREQ(tagname, "title") && + (tablePtr->titleRows || tablePtr->titleCols)) { + for (row = tablePtr->rowOffset; + row < tablePtr->rowOffset+tablePtr->rows; row++) { + for (col = tablePtr->colOffset; + col < tablePtr->colOffset+tablePtr->titleCols; + col++) { + TableMakeArrayIndex(row, col, buf); + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewStringObj(buf, -1)); + } + } + for (row = tablePtr->rowOffset; + row < tablePtr->rowOffset+tablePtr->titleRows; + row++) { + for (col = tablePtr->colOffset+tablePtr->titleCols; + col < tablePtr->colOffset+tablePtr->cols; col++) { + TableMakeArrayIndex(row, col, buf); + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewStringObj(buf, -1)); + } + } + } else { + /* + * Check this tag pointer amongst all tagged cells + */ + for (scanPtr = Tcl_FirstHashEntry(tablePtr->cellStyles, + &search); + scanPtr != NULL; + scanPtr = Tcl_NextHashEntry(&search)) { + if ((TableTag *) Tcl_GetHashValue(scanPtr) == tagPtr) { + keybuf = (char *) Tcl_GetHashKey( + tablePtr->cellStyles, scanPtr); + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewStringObj(keybuf, -1)); + } + } + } + return TCL_OK; + } + + /* + * Loop through the arguments and fill in the hash table + */ + for (i = 4; i < objc; i++) { + /* + * Try and parse the index + */ + if (TableGetIndexObj(tablePtr, objv[i], &row, &col) + != TCL_OK) { + return TCL_ERROR; + } + /* + * Get the hash key ready + */ + TableMakeArrayIndex(row, col, buf); + + if (tagPtr == NULL) { + /* + * This is a deletion + */ + entryPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); + if (entryPtr != NULL) { + Tcl_DeleteHashEntry(entryPtr); + refresh = 1; + } + } else { + /* + * Add a key to the hash table and set it to point to the + * Tag structure if it wasn't the same as an existing one + */ + entryPtr = Tcl_CreateHashEntry(tablePtr->cellStyles, + buf, &newEntry); + if (newEntry || (tagPtr != + (TableTag *) Tcl_GetHashValue(entryPtr))) { + Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); + refresh = 1; + } + } + /* + * Now invalidate this cell for redraw + */ + if (refresh) { + TableRefresh(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, CELL); + } + } + return TCL_OK; + + case TAG_COLTAG: + case TAG_ROWTAG: { /* tag a row or a column */ + int forRows = (cmdIndex == TAG_ROWTAG); + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "tag ?arg arg ..?"); + return TCL_ERROR; + } + tagname = Tcl_GetStringFromObj(objv[3], &len); + if (len == 0) { + /* + * Empty string, so we want to delete this element + */ + tagPtr = NULL; + } else { + /* + * Get the pointer to the tag structure. If it doesn't + * exist, it will be created. + */ + tagPtr = TableTagGetEntry(tablePtr, tagname, 0, NULL); + } + + /* + * Choose the correct hash table based on args + */ + hashTblPtr = forRows ? tablePtr->rowStyles : tablePtr->colStyles; + + if (objc == 4) { + /* the user just wants the tagged cells to be returned */ + /* Special handling for tags: active, flash, sel, title */ + + if ((tablePtr->flags & HAS_ACTIVE) && + strcmp(tagname, "active") == 0) { + Tcl_SetIntObj(resultPtr, + (forRows ? + tablePtr->activeRow+tablePtr->rowOffset : + tablePtr->activeCol+tablePtr->colOffset)); + } else if ((tablePtr->flashMode && STREQ(tagname, "flash")) + || STREQ(tagname, "sel")) { + Tcl_HashTable *cacheTblPtr; + + cacheTblPtr = (Tcl_HashTable *) + ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(cacheTblPtr, TCL_ONE_WORD_KEYS); + + hashTblPtr = (*tagname == 's') ? + tablePtr->selCells : tablePtr->flashCells; + for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); + scanPtr != NULL; + scanPtr = Tcl_NextHashEntry(&search)) { + TableParseArrayIndex(&row, &col, + Tcl_GetHashKey(hashTblPtr, scanPtr)); + value = forRows ? row : col; + entryPtr = Tcl_CreateHashEntry(cacheTblPtr, + (char *)value, &newEntry); + if (newEntry) { + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewIntObj(value)); + } + } + + Tcl_DeleteHashTable(cacheTblPtr); + ckfree((char *) (cacheTblPtr)); + } else if (STREQ(tagname, "title") && + (forRows?tablePtr->titleRows:tablePtr->titleCols)) { + if (forRows) { + for (row = tablePtr->rowOffset; + row < tablePtr->rowOffset+tablePtr->titleRows; + row++) { + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewIntObj(row)); + } + } else { + for (col = tablePtr->colOffset; + col < tablePtr->colOffset+tablePtr->titleCols; + col++) { + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewIntObj(col)); + } + } + } else { + for (scanPtr = Tcl_FirstHashEntry(hashTblPtr, &search); + scanPtr != NULL; + scanPtr = Tcl_NextHashEntry(&search)) { + /* is this the tag pointer on this row */ + if ((TableTag *) Tcl_GetHashValue(scanPtr) == tagPtr) { + objPtr = Tcl_NewIntObj( + (int) Tcl_GetHashKey(hashTblPtr, scanPtr)); + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + } + } + return TCL_OK; + } + + /* + * Loop through the arguments and fill in the hash table + */ + for (i = 4; i < objc; i++) { + /* + * Try and parse the index + */ + if (Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK) { + return TCL_ERROR; + } + if (tagPtr == NULL) { + /* + * This is a deletion + */ + entryPtr = Tcl_FindHashEntry(hashTblPtr, (char *)value); + if (entryPtr != NULL) { + Tcl_DeleteHashEntry(entryPtr); + refresh = 1; + } + } else { + /* + * Add a key to the hash table and set it to point to the + * Tag structure if it wasn't the same as an existing one + */ + entryPtr = Tcl_CreateHashEntry(hashTblPtr, + (char *) value, &newEntry); + if (newEntry || (tagPtr != + (TableTag *) Tcl_GetHashValue(entryPtr))) { + Tcl_SetHashValue(entryPtr, (ClientData) tagPtr); + refresh = 1; + } + } + /* and invalidate the row or column affected */ + if (refresh) { + if (cmdIndex == TAG_ROWTAG) { + TableRefresh(tablePtr, value-tablePtr->rowOffset, 0, + ROW); + } else { + TableRefresh(tablePtr, 0, value-tablePtr->colOffset, + COL); + } + } + } + return TCL_OK; /* COLTAG && ROWTAG */ + } + + case TAG_CGET: + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName option"); + return TCL_ERROR; + } + tagname = Tcl_GetString(objv[3]); + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); + if (entryPtr == NULL) { + goto invalidtag; + } else { + tagPtr = (TableTag *) Tcl_GetHashValue (entryPtr); + result = Tk_ConfigureValue(interp, tablePtr->tkwin, tagConfig, + (char *) tagPtr, Tcl_GetString(objv[4]), 0); + } + return result; /* CGET */ + + case TAG_CONFIGURE: + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName ?arg arg ...?"); + return TCL_ERROR; + } + + /* + * Get the pointer to the tag structure. If it doesn't + * exist, it will be created. + */ + tagPtr = TableTagGetEntry(tablePtr, Tcl_GetString(objv[3]), + 0, NULL); + + /* + * If there were less than 6 args, we return the configuration + * (for all or just one option), even for new tags + */ + if (objc < 6) { + result = Tk_ConfigureInfo(interp, tablePtr->tkwin, tagConfig, + (char *) tagPtr, (objc == 5) ? + Tcl_GetString(objv[4]) : NULL, 0); + } else { + CONST84 char **argv; + + /* Stringify */ + argv = (CONST84 char **) ckalloc((objc + 1) * sizeof(char *)); + for (i = 0; i < objc; i++) + argv[i] = Tcl_GetString(objv[i]); + argv[objc] = NULL; + + result = Tk_ConfigureWidget(interp, tablePtr->tkwin, + tagConfig, objc-4, argv+4, (char *) tagPtr, + TK_CONFIG_ARGV_ONLY); + ckfree((char *) argv); + if (result == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Handle change of image name + */ + if (tagPtr->imageStr) { + image = Tk_GetImage(interp, tablePtr->tkwin, + tagPtr->imageStr, + TableImageProc, (ClientData)tablePtr); + if (image == NULL) { + result = TCL_ERROR; + } + } else { + image = NULL; + } + if (tagPtr->image) { + Tk_FreeImage(tagPtr->image); + } + tagPtr->image = image; + + /* + * We reconfigured, so invalidate the table to redraw + */ + TableInvalidateAll(tablePtr, 0); + } + return result; + + case TAG_DELETE: + /* delete a tag */ + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?"); + return TCL_ERROR; + } + /* run through the remaining arguments */ + for (i = 3; i < objc; i++) { + tagname = Tcl_GetString(objv[i]); + /* cannot delete the title tag */ + if (STREQ(tagname, "title") || + STREQ(tagname, "sel") || + STREQ(tagname, "flash") || + STREQ(tagname, "active")) { + Tcl_AppendStringsToObj(resultPtr, "cannot delete ", + tagname, " tag", (char *) NULL); + return TCL_ERROR; + } + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); + if (entryPtr != NULL) { + /* get the tag pointer */ + tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); + + /* delete all references to this tag in rows */ + scanPtr = Tcl_FirstHashEntry(tablePtr->rowStyles, &search); + for (; scanPtr != NULL; + scanPtr = Tcl_NextHashEntry(&search)) { + if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { + Tcl_DeleteHashEntry(scanPtr); + refresh = 1; + } + } + + /* delete all references to this tag in cols */ + scanPtr = Tcl_FirstHashEntry(tablePtr->colStyles, &search); + for (; scanPtr != NULL; + scanPtr = Tcl_NextHashEntry(&search)) { + if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { + Tcl_DeleteHashEntry(scanPtr); + refresh = 1; + } + } + + /* delete all references to this tag in cells */ + scanPtr = Tcl_FirstHashEntry(tablePtr->cellStyles, + &search); + for (; scanPtr != NULL; + scanPtr = Tcl_NextHashEntry(&search)) { + if ((TableTag *)Tcl_GetHashValue(scanPtr) == tagPtr) { + Tcl_DeleteHashEntry(scanPtr); + refresh = 1; + } + } + + /* + * Remove the tag from the prio list and collapse + * the rest of the tags. We could check for shrinking + * the prio list as well. + */ + for (i = 0; i < tablePtr->tagPrioSize; i++) { + if (tablePtr->tagPrios[i] == tagPtr) break; + } + for ( ; i < tablePtr->tagPrioSize; i++) { + tablePtr->tagPrioNames[i] = + tablePtr->tagPrioNames[i+1]; + tablePtr->tagPrios[i] = tablePtr->tagPrios[i+1]; + } + tablePtr->tagPrioSize--; + + /* Release the tag structure */ + TableCleanupTag(tablePtr, tagPtr); + ckfree((char *) tagPtr); + + /* And free the hash table entry */ + Tcl_DeleteHashEntry(entryPtr); + } + } + /* since we deleted a tag, redraw the screen */ + if (refresh) { + TableInvalidateAll(tablePtr, 0); + } + return result; + + case TAG_EXISTS: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName"); + return TCL_ERROR; + } + Tcl_SetBooleanObj(resultPtr, + (Tcl_FindHashEntry(tablePtr->tagTable, + Tcl_GetString(objv[3])) != NULL)); + return TCL_OK; + + case TAG_INCLUDES: + /* does a tag contain a index ? */ + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "tag index"); + return TCL_ERROR; + } + tagname = Tcl_GetString(objv[3]); + /* check to see if the tag actually exists */ + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); + if (entryPtr == NULL) { + /* Unknown tag, just return 0 */ + Tcl_SetBooleanObj(resultPtr, 0); + return TCL_OK; + } + /* parse index */ + if (TableGetIndexObj(tablePtr, objv[4], &row, &col) != TCL_OK) { + return TCL_ERROR; + } + /* create hash key */ + TableMakeArrayIndex(row, col, buf); + + if (STREQ(tagname, "active")) { + result = (tablePtr->activeRow+tablePtr->rowOffset==row && + tablePtr->activeCol+tablePtr->colOffset==col); + } else if (STREQ(tagname, "flash")) { + result = (tablePtr->flashMode && + (Tcl_FindHashEntry(tablePtr->flashCells, buf) + != NULL)); + } else if (STREQ(tagname, "sel")) { + result = (Tcl_FindHashEntry(tablePtr->selCells, buf) != NULL); + } else if (STREQ(tagname, "title")) { + result = (row < tablePtr->titleRows+tablePtr->rowOffset || + col < tablePtr->titleCols+tablePtr->colOffset); + } else { + /* get the pointer to the tag structure */ + tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); + scanPtr = Tcl_FindHashEntry(tablePtr->cellStyles, buf); + /* + * Look to see if there is a cell, row, or col tag + * for this cell + */ + result = ((scanPtr && + (tagPtr == (TableTag *) Tcl_GetHashValue(scanPtr))) || + (tagPtr == FindRowColTag(tablePtr, row, ROW)) || + (tagPtr == FindRowColTag(tablePtr, col, COL))); + } + /* + * Because we may call FindRowColTag above, we can't use + * the resultPtr, but this is almost equivalent, and is SAFE + */ + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result)); + return TCL_OK; + + case TAG_NAMES: + /* + * Print out the tag names in priority order + */ + if (objc < 3 || objc > 4) { + Tcl_WrongNumArgs(interp, 3, objv, "?pattern?"); + return TCL_ERROR; + } + tagname = (objc == 4) ? Tcl_GetString(objv[3]) : NULL; + for (i = 0; i < tablePtr->tagPrioSize; i++) { + keybuf = tablePtr->tagPrioNames[i]; + if (objc == 3 || Tcl_StringMatch(keybuf, tagname)) { + objPtr = Tcl_NewStringObj(keybuf, -1); + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + } + return TCL_OK; + + case TAG_LOWER: + case TAG_RAISE: + /* + * Change priority of the named tag + */ + if (objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, (cmdIndex == TAG_LOWER) ? + "tagName ?belowThis?" : "tagName ?aboveThis?"); + return TCL_ERROR; + } + tagname = Tcl_GetString(objv[3]); + /* check to see if the tag actually exists */ + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); + if (entryPtr == NULL) { + goto invalidtag; + } + tagPtr = (TableTag *) Tcl_GetHashValue(entryPtr); + tagPrio = TableTagGetPriority(tablePtr, tagPtr); + keybuf = tablePtr->tagPrioNames[tagPrio]; + /* + * In the RAISE case, the priority is one higher (-1) because + * we want the named tag to move above the other in priority. + */ + if (objc == 5) { + tagname = Tcl_GetString(objv[4]); + entryPtr = Tcl_FindHashEntry(tablePtr->tagTable, tagname); + if (entryPtr == NULL) { + goto invalidtag; + } + tag2Ptr = (TableTag *) Tcl_GetHashValue(entryPtr); + if (cmdIndex == TAG_LOWER) { + value = TableTagGetPriority(tablePtr, tag2Ptr); + } else { + value = TableTagGetPriority(tablePtr, tag2Ptr) - 1; + } + } else { + if (cmdIndex == TAG_LOWER) { + /* + * Lower this tag's priority to the bottom. + */ + value = tablePtr->tagPrioSize - 1; + } else { + /* + * Raise this tag's priority to the top. + */ + value = -1; + } + } + if (value < tagPrio) { + /* + * Move tag up in priority. + */ + for (i = tagPrio; i > value; i--) { + tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i-1]; + tablePtr->tagPrios[i] = tablePtr->tagPrios[i-1]; + } + i++; + tablePtr->tagPrioNames[i] = keybuf; + tablePtr->tagPrios[i] = tagPtr; + refresh = 1; + } else if (value > tagPrio) { + /* + * Move tag down in priority. + */ + for (i = tagPrio; i < value; i++) { + tablePtr->tagPrioNames[i] = tablePtr->tagPrioNames[i+1]; + tablePtr->tagPrios[i] = tablePtr->tagPrios[i+1]; + } + tablePtr->tagPrioNames[i] = keybuf; + tablePtr->tagPrios[i] = tagPtr; + refresh = 1; + } + /* since we deleted a tag, redraw the screen */ + if (refresh) { + TableInvalidateAll(tablePtr, 0); + } + return TCL_OK; + + } + return TCL_OK; + + invalidtag: + /* + * When jumping here, ensure the invalid 'tagname' is set already. + */ + Tcl_AppendStringsToObj(resultPtr, "invalid tag name \"", + tagname, "\"", (char *) NULL); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * TableOptionReliefSet -- + * + * This routine configures the borderwidth value for a tag. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * It may adjust the tag struct values of relief[0..4] and borders. + * + *---------------------------------------------------------------------- + */ + +static int +TableOptionReliefSet(clientData, interp, tkwin, value, widgRec, offset) + ClientData clientData; /* Type of struct being set. */ + Tcl_Interp *interp; /* Used for reporting errors. */ + Tk_Window tkwin; /* Window containing table widget. */ + CONST84 char *value; /* Value of option. */ + char *widgRec; /* Pointer to record for item. */ + int offset; /* Offset into item. */ +{ + TableTag *tagPtr = (TableTag *) widgRec; + + if (*value == '\0') { + tagPtr->relief = -1; + } else { + return Tk_GetRelief(interp, value, &(tagPtr->relief)); + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TableOptionReliefGet -- + * + * Results: + * Value of the tag's -relief option. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static char * +TableOptionReliefGet(clientData, tkwin, widgRec, offset, freeProcPtr) + ClientData clientData; /* Type of struct being set. */ + Tk_Window tkwin; /* Window containing canvas widget. */ + char *widgRec; /* Pointer to record for item. */ + int offset; /* Offset into item. */ + Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with + * information about how to reclaim + * storage for return string. */ +{ + return (char *) Tk_NameOfRelief(((TableTag *) widgRec)->relief); +} diff --git a/tktable/generic/tkTableUtil.c b/tktable/generic/tkTableUtil.c new file mode 100644 index 0000000..5e5e9d0 --- /dev/null +++ b/tktable/generic/tkTableUtil.c @@ -0,0 +1,372 @@ +/* + * tkTableUtil.c -- + * + * This module contains utility functions for table widgets. + * + * Copyright (c) 2000-2002 Jeffrey Hobbs + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tkTableUtil.c,v 1.4 2002/10/16 07:31:48 hobbs Exp $ + */ + +#include "tkTable.h" + +static char * Cmd_GetName _ANSI_ARGS_((const Cmd_Struct *cmds, int val)); +static int Cmd_GetValue _ANSI_ARGS_((const Cmd_Struct *cmds, + const char *arg)); +static void Cmd_GetError _ANSI_ARGS_((Tcl_Interp *interp, + const Cmd_Struct *cmds, const char *arg)); + +/* + *-------------------------------------------------------------- + * + * Table_ClearHashTable -- + * This procedure is invoked to clear a STRING_KEY hash table, + * freeing the string entries and then deleting the hash table. + * The hash table cannot be used after calling this, except to + * be freed or reinitialized. + * + * Results: + * Cached info will be lost. + * + * Side effects: + * Can cause redraw. + * See the user documentation. + * + *-------------------------------------------------------------- + */ +void +Table_ClearHashTable(Tcl_HashTable *hashTblPtr) +{ + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + char *value; + + for (entryPtr = Tcl_FirstHashEntry(hashTblPtr, &search); + entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { + value = (char *) Tcl_GetHashValue(entryPtr); + if (value != NULL) ckfree(value); + } + + Tcl_DeleteHashTable(hashTblPtr); +} + +/* + *---------------------------------------------------------------------- + * + * TableOptionBdSet -- + * + * This routine configures the borderwidth value for a tag. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * It may adjust the tag struct values of bd[0..4] and borders. + * + *---------------------------------------------------------------------- + */ + +int +TableOptionBdSet(clientData, interp, tkwin, value, widgRec, offset) + ClientData clientData; /* Type of struct being set. */ + Tcl_Interp *interp; /* Used for reporting errors. */ + Tk_Window tkwin; /* Window containing table widget. */ + CONST84 char *value; /* Value of option. */ + char *widgRec; /* Pointer to record for item. */ + int offset; /* Offset into item. */ +{ + char **borderStr; + int *bordersPtr, *bdPtr; + int type = (int) clientData; + int result = TCL_OK; + int argc; + CONST84 char **argv; + + if ((type == BD_TABLE) && (value[0] == '\0')) { + /* + * NULL strings aren't allowed for the table global -bd + */ + Tcl_AppendResult(interp, "borderwidth value may not be empty", + (char *) NULL); + return TCL_ERROR; + } + + if ((type == BD_TABLE) || (type == BD_TABLE_TAG)) { + TableTag *tagPtr = (TableTag *) (widgRec + offset); + borderStr = &(tagPtr->borderStr); + bordersPtr = &(tagPtr->borders); + bdPtr = tagPtr->bd; + } else if (type == BD_TABLE_WIN) { + TableEmbWindow *tagPtr = (TableEmbWindow *) widgRec; + borderStr = &(tagPtr->borderStr); + bordersPtr = &(tagPtr->borders); + bdPtr = tagPtr->bd; + } else { + panic("invalid type given to TableOptionBdSet\n"); + return TCL_ERROR; /* lint */ + } + + result = Tcl_SplitList(interp, value, &argc, &argv); + if (result == TCL_OK) { + int i, bd[4]; + + if (((type == BD_TABLE) && (argc == 0)) || (argc == 3) || (argc > 4)) { + Tcl_AppendResult(interp, + "1, 2 or 4 values must be specified for borderwidth", + (char *) NULL); + result = TCL_ERROR; + } else { + /* + * We use the shadow bd array first, in case we have an error + * parsing arguments half way through. + */ + for (i = 0; i < argc; i++) { + if (Tk_GetPixels(interp, tkwin, argv[i], &(bd[i])) != TCL_OK) { + result = TCL_ERROR; + break; + } + } + /* + * If everything is OK, store the parsed and given values for + * easy retrieval. + */ + if (result == TCL_OK) { + for (i = 0; i < argc; i++) { + bdPtr[i] = MAX(0, bd[i]); + } + if (*borderStr) { + ckfree(*borderStr); + } + if (value) { + *borderStr = (char *) ckalloc(strlen(value) + 1); + strcpy(*borderStr, value); + } else { + *borderStr = NULL; + } + *bordersPtr = argc; + } + } + ckfree ((char *) argv); + } + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * TableOptionBdGet -- + * + * Results: + * Value of the -bd option. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +char * +TableOptionBdGet(clientData, tkwin, widgRec, offset, freeProcPtr) + ClientData clientData; /* Type of struct being set. */ + Tk_Window tkwin; /* Window containing canvas widget. */ + char *widgRec; /* Pointer to record for item. */ + int offset; /* Offset into item. */ + Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with + * information about how to reclaim + * storage for return string. */ +{ + register int type = (int) clientData; + + if (type == BD_TABLE) { + return ((TableTag *) (widgRec + offset))->borderStr; + } else if (type == BD_TABLE_TAG) { + return ((TableTag *) widgRec)->borderStr; + } else if (type == BD_TABLE_WIN) { + return ((TableEmbWindow *) widgRec)->borderStr; + } else { + panic("invalid type given to TableOptionBdSet\n"); + return NULL; /* lint */ + } +} + +/* + *---------------------------------------------------------------------- + * + * TableTagConfigureBd -- + * This routine configures the border values based on a tag. + * The previous value of the bd string (oldValue) is assumed to + * be a valid value for this tag. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * It may adjust the value used by -bd. + * + *---------------------------------------------------------------------- + */ + +int +TableTagConfigureBd(Table *tablePtr, TableTag *tagPtr, + char *oldValue, int nullOK) +{ + int i, argc, result = TCL_OK; + CONST84 char **argv; + + /* + * First check to see if the value really changed. + */ + if (strcmp(tagPtr->borderStr ? tagPtr->borderStr : "", + oldValue ? oldValue : "") == 0) { + return TCL_OK; + } + + tagPtr->borders = 0; + if (!nullOK && ((tagPtr->borderStr == NULL) + || (*(tagPtr->borderStr) == '\0'))) { + /* + * NULL strings aren't allowed for this tag + */ + result = TCL_ERROR; + } else if (tagPtr->borderStr) { + result = Tcl_SplitList(tablePtr->interp, tagPtr->borderStr, + &argc, &argv); + if (result == TCL_OK) { + if ((!nullOK && (argc == 0)) || (argc == 3) || (argc > 4)) { + Tcl_SetResult(tablePtr->interp, + "1, 2 or 4 values must be specified to -borderwidth", + TCL_STATIC); + result = TCL_ERROR; + } else { + for (i = 0; i < argc; i++) { + if (Tk_GetPixels(tablePtr->interp, tablePtr->tkwin, + argv[i], &(tagPtr->bd[i])) != TCL_OK) { + result = TCL_ERROR; + break; + } + tagPtr->bd[i] = MAX(0, tagPtr->bd[i]); + } + tagPtr->borders = argc; + } + ckfree ((char *) argv); + } + } + + if (result != TCL_OK) { + if (tagPtr->borderStr) { + ckfree ((char *) tagPtr->borderStr); + } + if (oldValue != NULL) { + size_t length = strlen(oldValue) + 1; + /* + * We are making the assumption that oldValue is correct. + * We have to reparse in case the bad new value had a couple + * of correct args before failing on a bad pixel value. + */ + Tcl_SplitList(tablePtr->interp, oldValue, &argc, &argv); + for (i = 0; i < argc; i++) { + Tk_GetPixels(tablePtr->interp, tablePtr->tkwin, + argv[i], &(tagPtr->bd[i])); + } + ckfree ((char *) argv); + tagPtr->borders = argc; + tagPtr->borderStr = (char *) ckalloc(length); + memcpy(tagPtr->borderStr, oldValue, length); + } else { + tagPtr->borders = 0; + tagPtr->borderStr = (char *) NULL; + } + } + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * Cmd_OptionSet -- + * + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +Cmd_OptionSet(ClientData clientData, Tcl_Interp *interp, + Tk_Window unused, CONST84 char *value, char *widgRec, int offset) +{ + Cmd_Struct *p = (Cmd_Struct *)clientData; + int mode = Cmd_GetValue(p,value); + if (!mode) { + Cmd_GetError(interp,p,value); + return TCL_ERROR; + } + *((int*)(widgRec+offset)) = mode; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * Cmd_OptionGet -- + * + * + * Results: + * Value of the option. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +char * +Cmd_OptionGet(ClientData clientData, Tk_Window unused, + char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) +{ + Cmd_Struct *p = (Cmd_Struct *)clientData; + int mode = *((int*)(widgRec+offset)); + return Cmd_GetName(p,mode); +} + +/* + * simple Cmd_Struct lookup functions + */ + +char * +Cmd_GetName(const Cmd_Struct *cmds, int val) +{ + for(;cmds->name && cmds->name[0];cmds++) { + if (cmds->value==val) return cmds->name; + } + return NULL; +} + +int +Cmd_GetValue(const Cmd_Struct *cmds, const char *arg) +{ + unsigned int len = strlen(arg); + for(;cmds->name && cmds->name[0];cmds++) { + if (!strncmp(cmds->name, arg, len)) return cmds->value; + } + return 0; +} + +void +Cmd_GetError(Tcl_Interp *interp, const Cmd_Struct *cmds, const char *arg) +{ + int i; + Tcl_AppendResult(interp, "bad option \"", arg, "\" must be ", (char *) 0); + for(i=0;cmds->name && cmds->name[0];cmds++,i++) { + Tcl_AppendResult(interp, (i?", ":""), cmds->name, (char *) 0); + } +} diff --git a/tktable/generic/tkTableWin.c b/tktable/generic/tkTableWin.c new file mode 100644 index 0000000..86e1c0c --- /dev/null +++ b/tktable/generic/tkTableWin.c @@ -0,0 +1,955 @@ +/* + * tkTableWin.c -- + * + * This module implements embedded windows for table widgets. + * Much of this code is adapted from tkGrid.c and tkTextWind.c. + * + * Copyright (c) 1998-2002 Jeffrey Hobbs + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tkTableWin.c,v 1.6 2004/06/11 00:24:44 hobbs Exp $ + */ + +#include "tkTable.h" + +static int StickyParseProc _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + CONST84 char *value, char *widgRec, int offset)); +static char * StickyPrintProc _ANSI_ARGS_((ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, + Tcl_FreeProc **freeProcPtr)); + +static void EmbWinLostSlaveProc _ANSI_ARGS_((ClientData clientData, + Tk_Window tkwin)); +static void EmbWinRequestProc _ANSI_ARGS_((ClientData clientData, + Tk_Window tkwin)); + +static void EmbWinCleanup _ANSI_ARGS_((Table *tablePtr, + TableEmbWindow *ewPtr)); +static int EmbWinConfigure _ANSI_ARGS_((Table *tablePtr, + TableEmbWindow *ewPtr, + int objc, Tcl_Obj *CONST objv[])); +static void EmbWinStructureProc _ANSI_ARGS_((ClientData clientData, + XEvent *eventPtr)); +static void EmbWinUnmapNow _ANSI_ARGS_((Tk_Window ewTkwin, + Tk_Window tkwin)); + +static Tk_GeomMgr tableGeomType = { + "table", /* name */ + EmbWinRequestProc, /* requestProc */ + EmbWinLostSlaveProc, /* lostSlaveProc */ +}; + +/* windows subcommands */ +static CONST84 char *winCmdNames[] = { + "cget", "configure", "delete", "move", "names", (char *) NULL +}; +enum winCommand { + WIN_CGET, WIN_CONFIGURE, WIN_DELETE, WIN_MOVE, WIN_NAMES +}; + +/* Flag values for "sticky"ness The 16 combinations subsume the packer's + * notion of anchor and fill. + * + * STICK_NORTH This window sticks to the top of its cavity. + * STICK_EAST This window sticks to the right edge of its cavity. + * STICK_SOUTH This window sticks to the bottom of its cavity. + * STICK_WEST This window sticks to the left edge of its cavity. + */ + +#define STICK_NORTH (1<<0) +#define STICK_EAST (1<<1) +#define STICK_SOUTH (1<<2) +#define STICK_WEST (1<<3) + +/* + * The default specification for configuring embedded windows + * Done like this to make the command line parsing easy + */ + +static Tk_CustomOption stickyOption = { StickyParseProc, StickyPrintProc, + (ClientData) NULL }; +static Tk_CustomOption tagBdOpt = { TableOptionBdSet, TableOptionBdGet, + (ClientData) BD_TABLE_WIN }; + +static Tk_ConfigSpec winConfigSpecs[] = { + {TK_CONFIG_BORDER, "-background", "background", "Background", NULL, + Tk_Offset(TableEmbWindow, bg), + TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, + {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, + {TK_CONFIG_CUSTOM, "-borderwidth", "borderWidth", "BorderWidth", "", + 0 /* no offset */, + TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK, &tagBdOpt }, + {TK_CONFIG_STRING, "-create", (char *)NULL, (char *)NULL, (char *)NULL, + Tk_Offset(TableEmbWindow, create), + TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_PIXELS, "-padx", (char *)NULL, (char *)NULL, (char *)NULL, + Tk_Offset(TableEmbWindow, padX), TK_CONFIG_DONT_SET_DEFAULT }, + {TK_CONFIG_PIXELS, "-pady", (char *)NULL, (char *)NULL, (char *)NULL, + Tk_Offset(TableEmbWindow, padY), TK_CONFIG_DONT_SET_DEFAULT }, + {TK_CONFIG_CUSTOM, "-sticky", (char *)NULL, (char *)NULL, (char *)NULL, + Tk_Offset(TableEmbWindow, sticky), TK_CONFIG_DONT_SET_DEFAULT, + &stickyOption}, + {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", NULL, + Tk_Offset(TableEmbWindow, relief), 0 }, + {TK_CONFIG_WINDOW, "-window", (char *)NULL, (char *)NULL, (char *)NULL, + Tk_Offset(TableEmbWindow, tkwin), + TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK }, + {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, + (char *)NULL, 0, 0 } +}; + +/* + *---------------------------------------------------------------------- + * + * StickyPrintProc -- + * Converts the internal boolean combination of "sticky" bits onto + * a TCL string element containing zero or more of n, s, e, or w. + * + * Results: + * A string is placed into the "result" pointer. + * + * Side effects: + * none. + * + *---------------------------------------------------------------------- + */ +static char * +StickyPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) + ClientData clientData; /* Ignored. */ + Tk_Window tkwin; /* Window for text widget. */ + char *widgRec; /* Pointer to TkTextEmbWindow + * structure. */ + int offset; /* Ignored. */ + Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with + * information about how to reclaim + * storage for return string. */ +{ + int flags = ((TableEmbWindow *) widgRec)->sticky; + int count = 0; + char *result = (char *) ckalloc(5*sizeof(char)); + + if (flags&STICK_NORTH) result[count++] = 'n'; + if (flags&STICK_EAST) result[count++] = 'e'; + if (flags&STICK_SOUTH) result[count++] = 's'; + if (flags&STICK_WEST) result[count++] = 'w'; + + *freeProcPtr = TCL_DYNAMIC; + result[count] = '\0'; + return result; +} + +/* + *---------------------------------------------------------------------- + * + * StringParseProc -- + * Converts an ascii string representing a widgets stickyness + * into the boolean result. + * + * Results: + * The boolean combination of the "sticky" bits is retuned. If an + * error occurs, such as an invalid character, -1 is returned instead. + * + * Side effects: + * none + * + *---------------------------------------------------------------------- + */ +static int +StickyParseProc(clientData, interp, tkwin, value, widgRec, offset) + ClientData clientData; /* Not used.*/ + Tcl_Interp *interp; /* Used for reporting errors. */ + Tk_Window tkwin; /* Window for text widget. */ + CONST84 char *value; /* Value of option. */ + char *widgRec; /* Pointer to TkTextEmbWindow + * structure. */ + int offset; /* Offset into item (ignored). */ +{ + register TableEmbWindow *ewPtr = (TableEmbWindow *) widgRec; + int sticky = 0; + char c; + + while ((c = *value++) != '\0') { + switch (c) { + case 'n': case 'N': sticky |= STICK_NORTH; break; + case 'e': case 'E': sticky |= STICK_EAST; break; + case 's': case 'S': sticky |= STICK_SOUTH; break; + case 'w': case 'W': sticky |= STICK_WEST; break; + case ' ': case ',': case '\t': case '\r': case '\n': break; + default: + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "bad sticky value \"", --value, + "\": must contain n, s, e or w", + (char *) NULL); + return TCL_ERROR; + } + } + ewPtr->sticky = sticky; + return TCL_OK; +} + +/* + * ckallocs space for a new embedded window structure and clears the structure + * returns the pointer to the new structure + */ +static TableEmbWindow * +TableNewEmbWindow(Table *tablePtr) +{ + TableEmbWindow *ewPtr = (TableEmbWindow *) ckalloc(sizeof(TableEmbWindow)); + memset((VOID *) ewPtr, 0, sizeof(TableEmbWindow)); + + /* + * Set the values that aren't 0/NULL by default + */ + ewPtr->tablePtr = tablePtr; + ewPtr->relief = -1; + ewPtr->padX = -1; + ewPtr->padY = -1; + + return ewPtr; +} + +/* + *---------------------------------------------------------------------- + * + * EmbWinCleanup -- + * Releases resources used by an embedded window before it is freed up. + * + * Results: + * Window will no longer be valid. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static void +EmbWinCleanup(Table *tablePtr, TableEmbWindow *ewPtr) +{ + Tk_FreeOptions(winConfigSpecs, (char *) ewPtr, tablePtr->display, 0); +} + +/* + *-------------------------------------------------------------- + * + * EmbWinDisplay -- + * + * This procedure is invoked by TableDisplay for + * mapping windows into cells. + * + * Results: + * Displays or moves window on table screen. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ +void +EmbWinDisplay(Table *tablePtr, Drawable window, TableEmbWindow *ewPtr, + TableTag *tagPtr, int x, int y, int width, int height) +{ + Tk_Window tkwin = tablePtr->tkwin; + Tk_Window ewTkwin = ewPtr->tkwin; + int diffx=0; /* Cavity width - slave width. */ + int diffy=0; /* Cavity hight - slave height. */ + int sticky = ewPtr->sticky; + int padx, pady; + + if (ewPtr->bg) tagPtr->bg = ewPtr->bg; + if (ewPtr->relief != -1) tagPtr->relief = ewPtr->relief; + if (ewPtr->borders) { + tagPtr->borderStr = ewPtr->borderStr; + tagPtr->borders = ewPtr->borders; + tagPtr->bd[0] = ewPtr->bd[0]; + tagPtr->bd[1] = ewPtr->bd[1]; + tagPtr->bd[2] = ewPtr->bd[2]; + tagPtr->bd[3] = ewPtr->bd[3]; + } + + padx = (ewPtr->padX < 0) ? tablePtr->padX : ewPtr->padX; + pady = (ewPtr->padY < 0) ? tablePtr->padY : ewPtr->padY; + + x += padx; + width -= padx*2; + y += pady; + height -= pady*2; + + if (width > Tk_ReqWidth(ewPtr->tkwin)) { + diffx = width - Tk_ReqWidth(ewPtr->tkwin); + width = Tk_ReqWidth(ewPtr->tkwin); + } + if (height > Tk_ReqHeight(ewPtr->tkwin)) { + diffy = height - Tk_ReqHeight(ewPtr->tkwin); + height = Tk_ReqHeight(ewPtr->tkwin); + } + if (sticky&STICK_EAST && sticky&STICK_WEST) { + width += diffx; + } + if (sticky&STICK_NORTH && sticky&STICK_SOUTH) { + height += diffy; + } + if (!(sticky&STICK_WEST)) { + x += (sticky&STICK_EAST) ? diffx : diffx/2; + } + if (!(sticky&STICK_NORTH)) { + y += (sticky&STICK_SOUTH) ? diffy : diffy/2; + } + + /* + * If we fall below a specific minimum width/height requirement, + * we just unmap the window + */ + if (width < 2 || height < 2) { + if (ewPtr->displayed) { + EmbWinUnmapNow(ewTkwin, tkwin); + } + return; + } + + if (tkwin == Tk_Parent(ewTkwin)) { + if ((x != Tk_X(ewTkwin)) || (y != Tk_Y(ewTkwin)) + || (width != Tk_Width(ewTkwin)) + || (height != Tk_Height(ewTkwin))) { + Tk_MoveResizeWindow(ewTkwin, x, y, width, height); + } + Tk_MapWindow(ewTkwin); + } else { + Tk_MaintainGeometry(ewTkwin, tkwin, x, y, width, height); + } + ewPtr->displayed = 1; +} + +/* + *-------------------------------------------------------------- + * + * EmbWinUnmapNow -- + * Handles unmapping the window depending on parent. + * tkwin should be tablePtr->tkwin. + * ewTkwin should be ewPtr->tkwin. + * + * Results: + * Removes the window. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ +static void +EmbWinUnmapNow(Tk_Window ewTkwin, Tk_Window tkwin) +{ + if (tkwin != Tk_Parent(ewTkwin)) { + Tk_UnmaintainGeometry(ewTkwin, tkwin); + } + Tk_UnmapWindow(ewTkwin); +} + +/* + *-------------------------------------------------------------- + * + * EmbWinUnmap -- + * This procedure is invoked by TableAdjustParams for + * unmapping windows managed moved offscreen. + * rlo, ... should be in real coords. + * + * Results: + * None. + * + * Side effects: + * Unmaps embedded windows. + * + *-------------------------------------------------------------- + */ +void +EmbWinUnmap(Table *tablePtr, int rlo, int rhi, int clo, int chi) +{ + register TableEmbWindow *ewPtr; + Tcl_HashEntry *entryPtr; + int row, col, trow, tcol; + char buf[INDEX_BUFSIZE]; + + /* + * Transform numbers from real to user user coords + */ + rlo += tablePtr->rowOffset; + rhi += tablePtr->rowOffset; + clo += tablePtr->colOffset; + chi += tablePtr->colOffset; + for (row = rlo; row <= rhi; row++) { + for (col = clo; col <= chi; col++) { + TableTrueCell(tablePtr, row, col, &trow, &tcol); + TableMakeArrayIndex(trow, tcol, buf); + entryPtr = Tcl_FindHashEntry(tablePtr->winTable, buf); + if (entryPtr != NULL) { + ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); + if (ewPtr->displayed) { + ewPtr->displayed = 0; + if (ewPtr->tkwin != NULL && tablePtr->tkwin != NULL) { + EmbWinUnmapNow(ewPtr->tkwin, tablePtr->tkwin); + } + } + } + } + } +} + +/* + *-------------------------------------------------------------- + * + * EmbWinRequestProc -- + * This procedure is invoked by Tk_GeometryRequest for + * windows managed by the Table. + * + * Results: + * None. + * + * Side effects: + * Arranges for tkwin, and all its managed siblings, to + * be re-arranged at the next idle point. + * + *-------------------------------------------------------------- + */ +static void +EmbWinRequestProc(clientData, tkwin) + ClientData clientData; /* Table's information about + * window that got new preferred + * geometry. */ + Tk_Window tkwin; /* Other Tk-related information + * about the window. */ +{ + register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; + + /* + * Resize depends on the sticky + */ + if (ewPtr->displayed && ewPtr->hPtr != NULL) { + Table *tablePtr = ewPtr->tablePtr; + int row, col, x, y, width, height; + + TableParseArrayIndex(&row, &col, + Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr)); + if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, &x, &y, &width, &height, + 0)) { + TableInvalidate(tablePtr, x, y, width, height, 0); + } + } +} + +static void +EmbWinRemove(TableEmbWindow *ewPtr) +{ + Table *tablePtr = ewPtr->tablePtr; + + if (ewPtr->tkwin != NULL) { + Tk_DeleteEventHandler(ewPtr->tkwin, StructureNotifyMask, + EmbWinStructureProc, (ClientData) ewPtr); + ewPtr->tkwin = NULL; + } + ewPtr->displayed = 0; + if (tablePtr->tkwin != NULL) { + int row, col, x, y, width, height; + + TableParseArrayIndex(&row, &col, + Tcl_GetHashKey(tablePtr->winTable, ewPtr->hPtr)); + /* this will cause windows removed from the table to actually + * cause the associated embdedded window hash data to be removed */ + Tcl_DeleteHashEntry(ewPtr->hPtr); + if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, &x, &y, &width, &height, + 0)) + TableInvalidate(tablePtr, x, y, width, height, 1); + } + /* this will cause windows removed from the table to actually + * cause the associated embdedded window hash data to be removed */ + EmbWinCleanup(tablePtr, ewPtr); + ckfree((char *) ewPtr); +} + +/* + *-------------------------------------------------------------- + * + * EmbWinLostSlaveProc -- + * This procedure is invoked by Tk whenever some other geometry + * claims control over a slave that used to be managed by us. + * + * Results: + * None. + * + * Side effects: + * Forgets all table-related information about the slave. + * + *-------------------------------------------------------------- + */ + +static void +EmbWinLostSlaveProc(clientData, tkwin) + ClientData clientData; /* Table structure for slave window that + * was stolen away. */ + Tk_Window tkwin; /* Tk's handle for the slave window. */ +{ + register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; + +#if 0 + Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr); +#endif + EmbWinUnmapNow(tkwin, ewPtr->tablePtr->tkwin); + EmbWinRemove(ewPtr); +} + +/* + *-------------------------------------------------------------- + * + * EmbWinStructureProc -- + * This procedure is invoked by the Tk event loop whenever + * StructureNotify events occur for a window that's embedded + * in a table widget. This procedure's only purpose is to + * clean up when windows are deleted. + * + * Results: + * None. + * + * Side effects: + * The window is disassociated from the window segment, and + * the portion of the table is redisplayed. + * + *-------------------------------------------------------------- + */ +static void +EmbWinStructureProc(clientData, eventPtr) + ClientData clientData; /* Pointer to record describing window item. */ + XEvent *eventPtr; /* Describes what just happened. */ +{ + register TableEmbWindow *ewPtr = (TableEmbWindow *) clientData; + + if (eventPtr->type != DestroyNotify) { + return; + } + + EmbWinRemove(ewPtr); +} + +/* + *-------------------------------------------------------------- + * + * EmbWinDelete -- + * This procedure is invoked by ... whenever + * an embedded window is being deleted. + * + * Results: + * None. + * + * Side effects: + * The embedded window is deleted, if it exists, and any resources + * associated with it are released. + * + *-------------------------------------------------------------- + */ +void +EmbWinDelete(register Table *tablePtr, TableEmbWindow *ewPtr) +{ + Tcl_HashEntry *entryPtr = ewPtr->hPtr; + + if (ewPtr->tkwin != NULL) { + Tk_Window tkwin = ewPtr->tkwin; + /* + * Delete the event handler for the window before destroying + * the window, so that EmbWinStructureProc doesn't get called + * (we'll already do everything that it would have done, and + * it will just get confused). + */ + + ewPtr->tkwin = NULL; + Tk_DeleteEventHandler(tkwin, StructureNotifyMask, + EmbWinStructureProc, (ClientData) ewPtr); + Tk_DestroyWindow(tkwin); + } + if (tablePtr->tkwin != NULL && entryPtr != NULL) { + int row, col, x, y, width, height; + TableParseArrayIndex(&row, &col, + Tcl_GetHashKey(tablePtr->winTable, entryPtr)); + Tcl_DeleteHashEntry(entryPtr); + + if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, + &x, &y, &width, &height, 0)) + TableInvalidate(tablePtr, x, y, width, height, 0); + } +#if 0 + Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr); +#endif + EmbWinCleanup(tablePtr, ewPtr); + ckfree((char *) ewPtr); +} + +/* + *-------------------------------------------------------------- + * + * EmbWinConfigure -- + * This procedure is called to handle configuration options + * for an embedded window. + * + * Results: + * The return value is a standard Tcl result. If TCL_ERROR is + * returned, then the interp's result contains an error message.. + * + * Side effects: + * Configuration information for the embedded window changes, + * such as alignment, stretching, or name of the embedded + * window. + * + *-------------------------------------------------------------- + */ +static int +EmbWinConfigure(tablePtr, ewPtr, objc, objv) + Table *tablePtr; /* Information about table widget that + * contains embedded window. */ + TableEmbWindow *ewPtr; /* Embedded window to be configured. */ + int objc; /* Number of objs in objv. */ + Tcl_Obj *CONST objv[]; /* Obj type options. */ +{ + Tcl_Interp *interp = tablePtr->interp; + Tk_Window oldWindow; + int i, result; + CONST84 char **argv; + + oldWindow = ewPtr->tkwin; + + /* Stringify */ + argv = (CONST84 char **) ckalloc((objc + 1) * sizeof(char *)); + for (i = 0; i < objc; i++) + argv[i] = Tcl_GetString(objv[i]); + argv[i] = NULL; + result = Tk_ConfigureWidget(interp, tablePtr->tkwin, + winConfigSpecs, objc, argv, (char *) ewPtr, + TK_CONFIG_ARGV_ONLY); + ckfree((char *) argv); + if (result != TCL_OK) { + return TCL_ERROR; + } + + if (oldWindow != ewPtr->tkwin) { + ewPtr->displayed = 0; + if (oldWindow != NULL) { + Tk_DeleteEventHandler(oldWindow, StructureNotifyMask, + EmbWinStructureProc, (ClientData) ewPtr); + Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL, + (ClientData) NULL); + EmbWinUnmapNow(oldWindow, tablePtr->tkwin); + } + if (ewPtr->tkwin != NULL) { + Tk_Window ancestor, parent; + + /* + * Make sure that the table is either the parent of the + * embedded window or a descendant of that parent. Also, + * don't allow a top-level window to be managed inside + * a table. + */ + + parent = Tk_Parent(ewPtr->tkwin); + for (ancestor = tablePtr->tkwin; ; + ancestor = Tk_Parent(ancestor)) { + if (ancestor == parent) { + break; + } + if (Tk_IsTopLevel(ancestor)) { + badMaster: + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "can't embed ", + Tk_PathName(ewPtr->tkwin), " in ", + Tk_PathName(tablePtr->tkwin), + (char *)NULL); + ewPtr->tkwin = NULL; + return TCL_ERROR; + } + } + if (Tk_IsTopLevel(ewPtr->tkwin) || + (ewPtr->tkwin == tablePtr->tkwin)) { + goto badMaster; + } + + /* + * Take over geometry management for the window, plus create + * an event handler to find out when it is deleted. + */ + + Tk_ManageGeometry(ewPtr->tkwin, &tableGeomType, (ClientData)ewPtr); + Tk_CreateEventHandler(ewPtr->tkwin, StructureNotifyMask, + EmbWinStructureProc, (ClientData) ewPtr); + } + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_WinMove -- + * This procedure is invoked by ... whenever + * an embedded window is being moved. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * If an embedded window is in the dest cell, it is deleted. + * + *-------------------------------------------------------------- + */ +int +Table_WinMove(register Table *tablePtr, char *CONST srcPtr, + char *CONST destPtr, int flags) +{ + int srow, scol, row, col, new; + Tcl_HashEntry *entryPtr; + TableEmbWindow *ewPtr; + + if (TableGetIndex(tablePtr, srcPtr, &srow, &scol) != TCL_OK || + TableGetIndex(tablePtr, destPtr, &row, &col) != TCL_OK) { + return TCL_ERROR; + } + entryPtr = Tcl_FindHashEntry(tablePtr->winTable, srcPtr); + if (entryPtr == NULL) { + if (flags & INV_NO_ERR_MSG) { + return TCL_OK; + } else { + Tcl_AppendStringsToObj(Tcl_GetObjResult(tablePtr->interp), + "no window at index \"", srcPtr, "\"", (char *) NULL); + return TCL_ERROR; + } + } + /* avoid moving it to the same location */ + if (srow == row && scol == col) { + return TCL_OK; + } + /* get the window pointer */ + ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); + /* and free the old hash table entry */ + Tcl_DeleteHashEntry(entryPtr); + + entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, destPtr, &new); + if (!new) { + /* window already there - just delete it */ + TableEmbWindow *ewPtrDel; + ewPtrDel = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); + /* This prevents the deletion of it's own entry, since we need it */ + ewPtrDel->hPtr = NULL; + EmbWinDelete(tablePtr, ewPtrDel); + } + /* set the new entry's value */ + Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); + ewPtr->hPtr = entryPtr; + + if (flags & INV_FORCE) { + int x, y, w, h; + /* Invalidate old cell */ + if (TableCellVCoords(tablePtr, srow-tablePtr->rowOffset, + scol-tablePtr->colOffset, &x, &y, &w, &h, 0)) { + TableInvalidate(tablePtr, x, y, w, h, 0); + } + /* Invalidate new cell */ + if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, &x, &y, &w, &h, 0)) { + TableInvalidate(tablePtr, x, y, w, h, 0); + } + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_WinDelete -- + * This procedure is invoked by ... whenever + * an embedded window is being delete. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Window info will be deleted. + * + *-------------------------------------------------------------- + */ +int +Table_WinDelete(register Table *tablePtr, char *CONST idxPtr) +{ + Tcl_HashEntry *entryPtr; + + entryPtr = Tcl_FindHashEntry(tablePtr->winTable, idxPtr); + if (entryPtr != NULL) { + /* get the window pointer & clean up data associated with it */ + EmbWinDelete(tablePtr, (TableEmbWindow *) Tcl_GetHashValue(entryPtr)); + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Table_WindowCmd -- + * This procedure is invoked to process the window method + * that corresponds to a widget managed by this module. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +Table_WindowCmd(ClientData clientData, register Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + register Table *tablePtr = (Table *)clientData; + int result = TCL_OK, cmdIndex, row, col, x, y, width, height, i, new; + TableEmbWindow *ewPtr; + Tcl_HashEntry *entryPtr; + Tcl_HashSearch search; + char buf[INDEX_BUFSIZE], *keybuf, *winname; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + return TCL_ERROR; + } + + /* parse the next argument */ + if (Tcl_GetIndexFromObj(interp, objv[2], winCmdNames, + "option", 0, &cmdIndex) != TCL_OK) { + return TCL_ERROR; + } + switch ((enum winCommand) cmdIndex) { + case WIN_CGET: + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "index option"); + return TCL_ERROR; + } + entryPtr = Tcl_FindHashEntry(tablePtr->winTable, + Tcl_GetString(objv[3])); + if (entryPtr == NULL) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "no window at index \"", + Tcl_GetString(objv[3]), "\"", (char *)NULL); + return TCL_ERROR; + } else { + ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); + result = Tk_ConfigureValue(interp, tablePtr->tkwin, winConfigSpecs, + (char *) ewPtr, + Tcl_GetString(objv[4]), 0); + } + return result; /* CGET */ + + case WIN_CONFIGURE: + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "index ?arg arg ...?"); + return TCL_ERROR; + } + if (TableGetIndexObj(tablePtr, objv[3], &row, &col) == TCL_ERROR) { + return TCL_ERROR; + } + TableMakeArrayIndex(row, col, buf); + entryPtr = Tcl_CreateHashEntry(tablePtr->winTable, buf, &new); + + if (new) { + /* create the structure */ + ewPtr = TableNewEmbWindow(tablePtr); + + /* insert it into the table */ + Tcl_SetHashValue(entryPtr, (ClientData) ewPtr); + ewPtr->hPtr = entryPtr; + + /* configure the window structure */ + result = EmbWinConfigure(tablePtr, ewPtr, objc-4, objv+4); + if (result == TCL_ERROR) { + /* release the structure */ + EmbWinCleanup(tablePtr, ewPtr); + ckfree((char *) ewPtr); + + /* and free the hash table entry */ + Tcl_DeleteHashEntry(entryPtr); + } + } else { + /* window exists, do a reconfig if we have enough args */ + /* get the window pointer from the table */ + ewPtr = (TableEmbWindow *) Tcl_GetHashValue(entryPtr); + + /* 5 args means that there are values to replace */ + if (objc > 5) { + /* and do a reconfigure */ + result = EmbWinConfigure(tablePtr, ewPtr, objc-4, objv+4); + } + } + if (result == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * If there were less than 6 args, we need + * to do a printout of the config, even for new windows + */ + if (objc < 6) { + result = Tk_ConfigureInfo(interp, tablePtr->tkwin, winConfigSpecs, + (char *) ewPtr, (objc == 5)? + Tcl_GetString(objv[4]) : NULL, 0); + } else { + /* Otherwise we reconfigured so invalidate + * the table for a redraw */ + if (TableCellVCoords(tablePtr, row-tablePtr->rowOffset, + col-tablePtr->colOffset, + &x, &y, &width, &height, 0)) { + TableInvalidate(tablePtr, x, y, width, height, 1); + } + } + return result; /* CONFIGURE */ + + case WIN_DELETE: + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "index ?index ...?"); + return TCL_ERROR; + } + for (i = 3; i < objc; i++) { + Table_WinDelete(tablePtr, Tcl_GetString(objv[i])); + } + break; + + case WIN_MOVE: + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "srcIndex destIndex"); + return TCL_ERROR; + } + result = Table_WinMove(tablePtr, Tcl_GetString(objv[3]), + Tcl_GetString(objv[4]), INV_FORCE); + break; + + case WIN_NAMES: { + Tcl_Obj *objPtr = Tcl_NewObj(); + + /* just print out the window names */ + if (objc < 3 || objc > 4) { + Tcl_WrongNumArgs(interp, 3, objv, "?pattern?"); + return TCL_ERROR; + } + winname = (objc == 4) ? Tcl_GetString(objv[3]) : NULL; + entryPtr = Tcl_FirstHashEntry(tablePtr->winTable, &search); + while (entryPtr != NULL) { + keybuf = Tcl_GetHashKey(tablePtr->winTable, entryPtr); + if (objc == 3 || Tcl_StringMatch(keybuf, winname)) { + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewStringObj(keybuf, -1)); + } + entryPtr = Tcl_NextHashEntry(&search); + } + Tcl_SetObjResult(interp, TableCellSortObj(interp, objPtr)); + break; + } + } + return TCL_OK; +} diff --git a/tktable/generic/version.h b/tktable/generic/version.h new file mode 100644 index 0000000..91d1bbe --- /dev/null +++ b/tktable/generic/version.h @@ -0,0 +1,8 @@ +#if 0 +TBL_MAJOR_VERSION = 2 +TBL_MINOR_VERSION = 10 +PACKAGE_VERSION = $(TBL_MAJOR_VERSION).$(TBL_MINOR_VERSION) +#endif +#define TBL_MAJOR_VERSION 2 +#define TBL_MINOR_VERSION 10 +#define PACKAGE_VERSION "2.10" diff --git a/tktable/library/tkTable.tcl b/tktable/library/tkTable.tcl new file mode 100644 index 0000000..53a2e7f --- /dev/null +++ b/tktable/library/tkTable.tcl @@ -0,0 +1,825 @@ +# table.tcl -- +# +# Version align with tkTable 2.7, jeff at hobbs org +# This file defines the default bindings for Tk table widgets +# and provides procedures that help in implementing those bindings. +# +# RCS: @(#) $Id: tkTable.tcl,v 1.14 2005/07/12 23:26:28 hobbs Exp $ + +#-------------------------------------------------------------------------- +# ::tk::table::Priv elements used in this file: +# +# x && y - Coords in widget +# afterId - Token returned by "after" for autoscanning. +# tablePrev - The last element to be selected or deselected +# during a selection operation. +# mouseMoved - Boolean to indicate whether mouse moved while +# the button was pressed. +# borderInfo - Boolean to know if the user clicked on a border +# borderB1 - Boolean that set whether B1 can be used for the +# interactiving resizing +#-------------------------------------------------------------------------- + +namespace eval ::tk::table { + # Ensure that a namespace is created for us + variable Priv + array set Priv [list x 0 y 0 afterId {} mouseMoved 0 \ + borderInfo {} borderB1 1] +} + +# ::tk::table::ClipboardKeysyms -- +# This procedure is invoked to identify the keys that correspond to +# the "copy", "cut", and "paste" functions for the clipboard. +# +# Arguments: +# copy - Name of the key (keysym name plus modifiers, if any, +# such as "Meta-y") used for the copy operation. +# cut - Name of the key used for the cut operation. +# paste - Name of the key used for the paste operation. + +proc ::tk::table::ClipboardKeysyms {copy cut paste} { + bind Table <$copy> {tk_tableCopy %W} + bind Table <$cut> {tk_tableCut %W} + bind Table <$paste> {tk_tablePaste %W} +} +::tk::table::ClipboardKeysyms + +## +## Interactive cell resizing, affected by -resizeborders option +## +bind Table <3> { + ## You might want to check for cell returned if you want to + ## restrict the resizing of certain cells + %W border mark %x %y +} +bind Table { %W border dragto %x %y } + +## Button events + +bind Table <1> { ::tk::table::Button1 %W %x %y } +bind Table { ::tk::table::B1Motion %W %x %y } + +bind Table { + if {$::tk::table::Priv(borderInfo) == "" && [winfo exists %W]} { + ::tk::table::CancelRepeat + %W activate @%x,%y + } +} +bind Table { + # empty +} + +bind Table {::tk::table::BeginExtend %W [%W index @%x,%y]} +bind Table {::tk::table::BeginToggle %W [%W index @%x,%y]} +bind Table {::tk::table::CancelRepeat} +bind Table { + if {$::tk::table::Priv(borderInfo) == ""} { + array set ::tk::table::Priv {x %x y %y} + ::tk::table::AutoScan %W + } +} +bind Table <2> { + %W scan mark %x %y + array set ::tk::table::Priv {x %x y %y} + set ::tk::table::Priv(mouseMoved) 0 +} +bind Table { + if {(%x != $::tk::table::Priv(x)) || (%y != $::tk::table::Priv(y))} { + set ::tk::table::Priv(mouseMoved) 1 + } + if {$::tk::table::Priv(mouseMoved)} { %W scan dragto %x %y } +} +bind Table { + if {!$::tk::table::Priv(mouseMoved)} { tk_tablePaste %W [%W index @%x,%y] } +} + +## Key events + +# This forces a cell commit if an active cell exists +bind Table <> { + catch {%W activate active} +} +# Remove this if you don't want cell commit to occur on every Leave for +# the table (via mouse) or FocusOut (loss of focus by table). +event add <> + +bind Table {::tk::table::ExtendSelect %W -1 0} +bind Table {::tk::table::ExtendSelect %W 1 0} +bind Table {::tk::table::ExtendSelect %W 0 -1} +bind Table {::tk::table::ExtendSelect %W 0 1} +bind Table {%W yview scroll -1 pages; %W activate topleft} +bind Table {%W yview scroll 1 pages; %W activate topleft} +bind Table {%W xview scroll -1 pages} +bind Table {%W xview scroll 1 pages} +bind Table {%W see origin} +bind Table {%W see end} +bind Table { + %W selection clear all + %W activate origin + %W selection set active + %W see active +} +bind Table { + %W selection clear all + %W activate end + %W selection set active + %W see active +} +bind Table {::tk::table::DataExtend %W origin} +bind Table {::tk::table::DataExtend %W end} +bind Table