diff options
Diffstat (limited to 'win')
-rwxr-xr-x | win/buildall.vc.bat | 214 | ||||
-rwxr-xr-x | win/configure | 40 | ||||
-rw-r--r-- | win/configure.in | 2 | ||||
-rw-r--r-- | win/makefile.bc | 1074 | ||||
-rw-r--r-- | win/makefile.vc | 2063 | ||||
-rw-r--r-- | win/mkd.bat | 24 | ||||
-rw-r--r-- | win/nmakehlp.c | 6 | ||||
-rw-r--r-- | win/rc/lamp.bmp | bin | 2102 -> 2102 bytes | |||
-rw-r--r-- | win/rc/tk_base.rc | 12 | ||||
-rw-r--r-- | win/rc/wish.ico | bin | 46878 -> 43646 bytes | |||
-rw-r--r-- | win/rc/wish.rc | 2 | ||||
-rw-r--r-- | win/rmd.bat | 40 | ||||
-rw-r--r-- | win/rules.vc | 1432 | ||||
-rw-r--r-- | win/tcl.m4 | 33 | ||||
-rw-r--r-- | win/tkConfig.sh.in | 2 | ||||
-rw-r--r-- | win/tkWin.h | 10 | ||||
-rw-r--r-- | win/tkWinButton.c | 34 | ||||
-rw-r--r-- | win/tkWinClipboard.c | 36 | ||||
-rw-r--r-- | win/tkWinColor.c | 14 | ||||
-rw-r--r-- | win/tkWinDefault.h | 1 | ||||
-rw-r--r-- | win/tkWinDialog.c | 1424 | ||||
-rw-r--r-- | win/tkWinEmbed.c | 11 | ||||
-rw-r--r-- | win/tkWinFont.c | 5 | ||||
-rw-r--r-- | win/tkWinInit.c | 51 | ||||
-rw-r--r-- | win/tkWinInt.h | 10 | ||||
-rw-r--r-- | win/tkWinPort.h | 9 | ||||
-rw-r--r-- | win/tkWinScrlbr.c | 4 | ||||
-rw-r--r-- | win/tkWinSend.c | 55 | ||||
-rw-r--r-- | win/tkWinTest.c | 151 | ||||
-rw-r--r-- | win/tkWinWm.c | 8 | ||||
-rw-r--r-- | win/winMain.c | 2 | ||||
-rw-r--r-- | win/wish.exe.manifest.in | 2 |
32 files changed, 3998 insertions, 2773 deletions
diff --git a/win/buildall.vc.bat b/win/buildall.vc.bat index 162490e..8f6803b 100755 --- a/win/buildall.vc.bat +++ b/win/buildall.vc.bat @@ -1,107 +1,107 @@ -@echo off - -:: This is an example batchfile for building everything. Please -:: edit this (or make your own) for your needs and wants using -:: the instructions for calling makefile.vc found in makefile.vc - -set SYMBOLS= - -:OPTIONS -if "%1" == "/?" goto help -if /i "%1" == "/help" goto help -if %1.==symbols. goto SYMBOLS -if %1.==debug. goto SYMBOLS -goto OPTIONS_DONE - -:SYMBOLS - set SYMBOLS=symbols - shift - goto OPTIONS - -:OPTIONS_DONE - -:: reset errorlevel -cd > nul - -:: You might have installed your developer studio to add itself to the -:: path or have already run vcvars32.bat. Testing these envars proves -:: cl.exe and friends are in your path. -:: -if defined VCINSTALLDIR (goto :startBuilding) -if defined MSDEVDIR (goto :startBuilding) -if defined MSVCDIR (goto :startBuilding) -if defined MSSDK (goto :startBuilding) -if defined WINDOWSSDKDIR (goto :startBuilding) - -:: We need to run the development environment batch script that comes -:: with developer studio (v4,5,6,7,etc...) All have it. This path -:: might not be correct. You should call it yourself prior to running -:: this batchfile. -:: -call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat" -if errorlevel 1 (goto no_vcvars) - -:startBuilding - -echo. -echo Sit back and have a cup of coffee while this grinds through ;) -echo You asked for *everything*, remember? -echo. -title Building Tk, please wait... - - -:: makefile.vc uses this for its default anyways, but show its use here -:: just to be explicit and convey understanding to the user. Setting -:: the INSTALLDIR envar prior to running this batchfile affects all builds. -:: -if "%INSTALLDIR%" == "" set INSTALLDIR=C:\Program Files\Tcl - - -:: Where is the Tcl source directory? -:: You can set the TCLDIR environment variable to your Tcl HEAD checkout -if "%TCLDIR%" == "" set TCLDIR=..\..\tcl - -:: Build the normal stuff along with the help file. -:: -set OPTS=none -if not %SYMBOLS%.==. set OPTS=symbols -nmake -nologo -f makefile.vc release htmlhelp OPTS=%OPTS% %1 -if errorlevel 1 goto error - -:: Build the static core and shell. -:: -set OPTS=static,msvcrt -if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt -nmake -nologo -f makefile.vc shell OPTS=%OPTS% %1 -if errorlevel 1 goto error - -set OPTS= -set SYMBOLS= -goto end - -:error -echo *** BOOM! *** -goto end - -:no_vcvars -echo vcvars32.bat was not run prior to this batchfile, nor are the MS tools in your path. -goto out - -:help -title buildall.vc.bat help message -echo usage: -echo %0 : builds Tk for all build types (do this first) -echo %0 install : installs all the release builds (do this second) -echo %0 symbols : builds Tk for all debugging build types -echo %0 symbols install : install all the debug builds. -echo. -goto out - -:end -title Building Tk, please wait... DONE! -echo DONE! -goto out - -:out -pause -title Command Prompt +@echo off
+
+:: This is an example batchfile for building everything. Please
+:: edit this (or make your own) for your needs and wants using
+:: the instructions for calling makefile.vc found in makefile.vc
+
+set SYMBOLS=
+
+:OPTIONS
+if "%1" == "/?" goto help
+if /i "%1" == "/help" goto help
+if %1.==symbols. goto SYMBOLS
+if %1.==debug. goto SYMBOLS
+goto OPTIONS_DONE
+
+:SYMBOLS
+ set SYMBOLS=symbols
+ shift
+ goto OPTIONS
+
+:OPTIONS_DONE
+
+:: reset errorlevel
+cd > nul
+
+:: You might have installed your developer studio to add itself to the
+:: path or have already run vcvars32.bat. Testing these envars proves
+:: cl.exe and friends are in your path.
+::
+if defined VCINSTALLDIR (goto :startBuilding)
+if defined MSDEVDIR (goto :startBuilding)
+if defined MSVCDIR (goto :startBuilding)
+if defined MSSDK (goto :startBuilding)
+if defined WINDOWSSDKDIR (goto :startBuilding)
+
+:: We need to run the development environment batch script that comes
+:: with developer studio (v4,5,6,7,etc...) All have it. This path
+:: might not be correct. You should call it yourself prior to running
+:: this batchfile.
+::
+call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat"
+if errorlevel 1 (goto no_vcvars)
+
+:startBuilding
+
+echo.
+echo Sit back and have a cup of coffee while this grinds through ;)
+echo You asked for *everything*, remember?
+echo.
+title Building Tk, please wait...
+
+
+:: makefile.vc uses this for its default anyways, but show its use here
+:: just to be explicit and convey understanding to the user. Setting
+:: the INSTALLDIR envar prior to running this batchfile affects all builds.
+::
+if "%INSTALLDIR%" == "" set INSTALLDIR=C:\Program Files\Tcl
+
+
+:: Where is the Tcl source directory?
+:: You can set the TCLDIR environment variable to your Tcl HEAD checkout
+if "%TCLDIR%" == "" set TCLDIR=..\..\tcl
+
+:: Build the normal stuff along with the help file.
+::
+set OPTS=none
+if not %SYMBOLS%.==. set OPTS=symbols
+nmake -nologo -f makefile.vc release htmlhelp OPTS=%OPTS% %1
+if errorlevel 1 goto error
+
+:: Build the static core and shell.
+::
+set OPTS=static,msvcrt
+if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt
+nmake -nologo -f makefile.vc shell OPTS=%OPTS% %1
+if errorlevel 1 goto error
+
+set OPTS=
+set SYMBOLS=
+goto end
+
+:error
+echo *** BOOM! ***
+goto end
+
+:no_vcvars
+echo vcvars32.bat was not run prior to this batchfile, nor are the MS tools in your path.
+goto out
+
+:help
+title buildall.vc.bat help message
+echo usage:
+echo %0 : builds Tk for all build types (do this first)
+echo %0 install : installs all the release builds (do this second)
+echo %0 symbols : builds Tk for all debugging build types
+echo %0 symbols install : install all the debug builds.
+echo.
+goto out
+
+:end
+title Building Tk, please wait... DONE!
+echo DONE!
+goto out
+
+:out
+pause
+title Command Prompt
diff --git a/win/configure b/win/configure index 299be69..18efa23 100755 --- a/win/configure +++ b/win/configure @@ -1312,7 +1312,7 @@ SHELL=/bin/sh TK_VERSION=8.6 TK_MAJOR_VERSION=8 TK_MINOR_VERSION=6 -TK_PATCH_LEVEL=".1" +TK_PATCH_LEVEL=".4" VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION #------------------------------------------------------------------------ @@ -3449,7 +3449,7 @@ do 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" + ac_cv_prog_CYGPATH="cygpath -m" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -3736,7 +3736,7 @@ echo $ECHO_N "checking compiler flags... $ECHO_C" >&6 if test "${GCC}" = "yes" ; then SHLIB_LD="" SHLIB_LD_LIBS='${LIBS}' - LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -lws2_32" + LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -lws2_32" # mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32" STLIB_LD='${AR} cr' @@ -3906,6 +3906,13 @@ echo "${ECHO_T}using shared flags" >&6 # Add SHLIB_LD_LIBS to the Make rule, not here. LIBRARIES="\${SHARED_LIBRARIES}" EXESUFFIX="\${DBGX}.exe" + case "x`echo \${VisualStudioVersion}`" in + x1[4-9]*) + lflags="${lflags} -nodefaultlib:libucrt.lib" + ;; + *) + ;; + esac fi MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\$@" # DLLSUFFIX is separate because it is the building block for @@ -3934,18 +3941,23 @@ echo "${ECHO_T}using shared flags" >&6 ;; 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 + { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK" >&5 +echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK" >&2;} fi + echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 +echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 fi - LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib" + LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib" + + case "x`echo \${VisualStudioVersion}`" in + x1[4-9]*) + LIBS="$LIBS ucrt.lib" + ;; + *) + ;; + esac + if test "$do64bit" != "no" ; then # The space-based-path will work for the Makefile, but will # not work if AC_TRY_COMPILE is called. TEA has the @@ -4020,7 +4032,7 @@ fi CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d" # Do not use -O2 for Win64 - this has proved buggy in code gen. CFLAGS_OPTIMIZE="-nologo -O1 ${runtime}" - lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" + lflags="${lflags} -nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" # Avoid 'unresolved external symbol __security_cookie' errors. # c.f. http://support.microsoft.com/?id=894573 @@ -4032,7 +4044,7 @@ fi CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d" # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy) CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}" - lflags="-nologo" + lflags="${lflags} -nologo" LINKBIN="link" fi diff --git a/win/configure.in b/win/configure.in index 50efa8d..709b97f 100644 --- a/win/configure.in +++ b/win/configure.in @@ -14,7 +14,7 @@ SHELL=/bin/sh TK_VERSION=8.6 TK_MAJOR_VERSION=8 TK_MINOR_VERSION=6 -TK_PATCH_LEVEL=".1" +TK_PATCH_LEVEL=".4" VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION #------------------------------------------------------------------------ diff --git a/win/makefile.bc b/win/makefile.bc index 934599c..d98dfd7 100644 --- a/win/makefile.bc +++ b/win/makefile.bc @@ -1,537 +1,537 @@ -# -# Makefile for Borland C++ 5.5 (or C++ Builder 5), adapted from the makefile -# for Visual C++ that came with tk 8.3.3 -# -# Some "not so obvious" details in this makefile are preceded by a comment -# "maintenance hint", which tries to explain what's going on. Better to -# leave those in place. -# Helmut Giese, July 2002 -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# Copyright (c) 1995-1997 Sun Microsystems, Inc. -# Copyright (c) 1998-2000 Ajuba Solutions. - -# Does not depend on the presence of any environment variables in -# order to compile tcl; all needed information is derived from -# location of the compiler directories. - -# -# Project directories -# -# ROOT = top of source tree -# -# TMPDIR = location where .obj files should be stored during build -# -# TOOLS32 = location of Borland development tools. -# -# TCLDIR = location of top of Tcl source hierarchy -# - -ROOT = .. -TCLDIR = ..\..\tcl8.4 -INSTALLDIR = D:\tmp\tcl - -# If you have C++ Builder 5 or the free Borland C++ 5.5 compiler -# adapt the following paths as appropriate for your system -TOOLS32 = d:\cbld5 -TOOLS32_rc = d:\cbld5 -#TOOLS32 = c:\bc55 -#TOOLS32_rc = c:\bc55 - -cc32 = "$(TOOLS32)\bin\bcc32.exe" -link32 = "$(TOOLS32)\bin\ilink32.exe" -lib32 = "$(TOOLS32)\bin\tlib.exe" -rc32 = "$(TOOLS32_rc)\bin\brcc32.exe" -include32 = -I"$(TOOLS32)\include;$(TOOLS32)\include\mfc" -libpath32 = -L"$(TOOLS32)\lib" - -# Uncomment the following line to compile with thread support -#THREADDEFINES = -DTCL_THREADS=1 - -# Allow definition of NDEBUG via command line -# Set NODEBUG to 0 to compile with symbols -!if !defined(NODEBUG) -NODEBUG = 1 -!endif - -# uncomment the following two lines to compile with TCL_MEM_DEBUG -#DEBUGDEFINES =-DTCL_MEM_DEBUG - -###################################################################### -# Do not modify below this line -###################################################################### - -TCLNAMEPREFIX = tcl -TKNAMEPREFIX = tk -WISHNAMEPREFIX = wish -VERSION = 84 -DOTVERSION = 8.4 - -TCLSTUBPREFIX = $(TCLNAMEPREFIX)stub -TKSTUBPREFIX = $(TKNAMEPREFIX)stub - - -BINROOT = . -!IF "$(NODEBUG)" == "1" -TMPDIRNAME = Release -DBGX = -!ELSE -TMPDIRNAME = Debug -DBGX = -#DBGX = d -!ENDIF -TMPDIR = $(BINROOT)\$(TMPDIRNAME) -OUTDIRNAME = $(TMPDIRNAME) -OUTDIR = $(TMPDIR) - -TCLLIB = $(TCLNAMEPREFIX)$(VERSION)$(DBGX).lib -TCLPLUGINLIB = $(TCLNAMEPREFIX)$(VERSION)p.lib -TCLSTUBLIB = $(TCLSTUBPREFIX)$(VERSION)$(DBGX).lib -TKDLLNAME = $(TKNAMEPREFIX)$(VERSION)$(DBGX).dll -TKDLL = $(OUTDIR)\$(TKDLLNAME) -TKLIB = $(OUTDIR)\$(TKNAMEPREFIX)$(VERSION)$(DBGX).lib -TKSTUBLIBNAME = $(TKSTUBPREFIX)$(VERSION)$(DBGX).lib -TKSTUBLIB = $(OUTDIR)\$(TKSTUBLIBNAME) -TKPLUGINDLLNAME = $(TKNAMEPREFIX)$(VERSION)p$(DBG).dll -TKPLUGINDLL = $(OUTDIR)\$(TKPLUGINDLLNAME) -TKPLUGINLIB = $(OUTDIR)\$(TKNAMEPREFIX)$(VERSION)p$(DBGX).lib - -WISH = $(OUTDIR)\$(WISHNAMEPREFIX)$(VERSION)$(DBGX).exe -WISHC = $(OUTDIR)\$(WISHNAMEPREFIX)c$(VERSION)$(DBGX).exe -WISHP = $(OUTDIR)\$(WISHNAMEPREFIX)p$(VERSION)$(DBGX).exe -TKTEST = $(OUTDIR)\$(TKNAMEPREFIX)test.exe -CAT32 = $(TMPDIR)\cat32.exe - -BIN_INSTALL_DIR = $(INSTALLDIR)\bin -INCLUDE_INSTALL_DIR = $(INSTALLDIR)\include -LIB_INSTALL_DIR = $(INSTALLDIR)\lib -SCRIPT_INSTALL_DIR = $(LIB_INSTALL_DIR)\tk$(DOTVERSION) - -WISHOBJS = \ - $(TMPDIR)\winMain.obj - -TKTESTOBJS = \ - $(TMPDIR)\tkTest.obj \ - $(TMPDIR)\tkSquare.obj \ - $(TMPDIR)\testMain.obj \ - $(TMPDIR)\tkOldTest.obj \ - $(TMPDIR)\tkWinTest.obj \ - $(TCLLIBDIR)\tclThreadTest.obj - -XLIBOBJS = \ - $(TMPDIR)\xcolors.obj \ - $(TMPDIR)\xdraw.obj \ - $(TMPDIR)\xgc.obj \ - $(TMPDIR)\ximage.obj \ - $(TMPDIR)\xutil.obj - -TKOBJS = \ - $(TMPDIR)\tkConsole.obj \ - $(TMPDIR)\tkUnixMenubu.obj \ - $(TMPDIR)\tkUnixScale.obj \ - $(XLIBOBJS) \ - $(TMPDIR)\tkWin3d.obj \ - $(TMPDIR)\tkWin32Dll.obj \ - $(TMPDIR)\tkWinButton.obj \ - $(TMPDIR)\tkWinClipboard.obj \ - $(TMPDIR)\tkWinColor.obj \ - $(TMPDIR)\tkWinConfig.obj \ - $(TMPDIR)\tkWinCursor.obj \ - $(TMPDIR)\tkWinDialog.obj \ - $(TMPDIR)\tkWinDraw.obj \ - $(TMPDIR)\tkWinEmbed.obj \ - $(TMPDIR)\tkWinFont.obj \ - $(TMPDIR)\tkWinImage.obj \ - $(TMPDIR)\tkWinInit.obj \ - $(TMPDIR)\tkWinKey.obj \ - $(TMPDIR)\tkWinMenu.obj \ - $(TMPDIR)\tkWinPixmap.obj \ - $(TMPDIR)\tkWinPointer.obj \ - $(TMPDIR)\tkWinRegion.obj \ - $(TMPDIR)\tkWinScrlbr.obj \ - $(TMPDIR)\tkWinSend.obj \ - $(TMPDIR)\tkWinWindow.obj \ - $(TMPDIR)\tkWinWm.obj \ - $(TMPDIR)\tkWinX.obj \ - $(TMPDIR)\stubs.obj \ - $(TMPDIR)\tk3d.obj \ - $(TMPDIR)\tkArgv.obj \ - $(TMPDIR)\tkAtom.obj \ - $(TMPDIR)\tkBind.obj \ - $(TMPDIR)\tkBitmap.obj \ - $(TMPDIR)\tkBusy.obj \ - $(TMPDIR)\tkButton.obj \ - $(TMPDIR)\tkCanvArc.obj \ - $(TMPDIR)\tkCanvBmap.obj \ - $(TMPDIR)\tkCanvImg.obj \ - $(TMPDIR)\tkCanvLine.obj \ - $(TMPDIR)\tkCanvPoly.obj \ - $(TMPDIR)\tkCanvPs.obj \ - $(TMPDIR)\tkCanvText.obj \ - $(TMPDIR)\tkCanvUtil.obj \ - $(TMPDIR)\tkCanvWind.obj \ - $(TMPDIR)\tkCanvas.obj \ - $(TMPDIR)\tkClipboard.obj \ - $(TMPDIR)\tkCmds.obj \ - $(TMPDIR)\tkColor.obj \ - $(TMPDIR)\tkConfig.obj \ - $(TMPDIR)\tkCursor.obj \ - $(TMPDIR)\tkEntry.obj \ - $(TMPDIR)\tkError.obj \ - $(TMPDIR)\tkEvent.obj \ - $(TMPDIR)\tkFileFilter.obj \ - $(TMPDIR)\tkFocus.obj \ - $(TMPDIR)\tkFont.obj \ - $(TMPDIR)\tkFrame.obj \ - $(TMPDIR)\tkGC.obj \ - $(TMPDIR)\tkGeometry.obj \ - $(TMPDIR)\tkGet.obj \ - $(TMPDIR)\tkGrab.obj \ - $(TMPDIR)\tkGrid.obj \ - $(TMPDIR)\tkImage.obj \ - $(TMPDIR)\tkImgBmap.obj \ - $(TMPDIR)\tkImgGIF.obj \ - $(TMPDIR)\tkImgPPM.obj \ - $(TMPDIR)\tkImgPhoto.obj \ - $(TMPDIR)\tkImgPhInstance.obj \ - $(TMPDIR)\tkImgUtil.obj \ - $(TMPDIR)\tkListbox.obj \ - $(TMPDIR)\tkMacWinMenu.obj \ - $(TMPDIR)\tkMain.obj \ - $(TMPDIR)\tkMenu.obj \ - $(TMPDIR)\tkMenubutton.obj \ - $(TMPDIR)\tkMenuDraw.obj \ - $(TMPDIR)\tkMessage.obj \ - $(TMP_DIR)\tkPanedWindow.obj \ - $(TMPDIR)\tkObj.obj \ - $(TMPDIR)\tkOldConfig.obj \ - $(TMPDIR)\tkOption.obj \ - $(TMPDIR)\tkPack.obj \ - $(TMPDIR)\tkPlace.obj \ - $(TMPDIR)\tkPointer.obj \ - $(TMPDIR)\tkRectOval.obj \ - $(TMPDIR)\tkScale.obj \ - $(TMPDIR)\tkScrollbar.obj \ - $(TMPDIR)\tkSelect.obj \ - $(TMPDIR)\tkText.obj \ - $(TMPDIR)\tkTextBTree.obj \ - $(TMPDIR)\tkTextDisp.obj \ - $(TMPDIR)\tkTextImage.obj \ - $(TMPDIR)\tkTextIndex.obj \ - $(TMPDIR)\tkTextMark.obj \ - $(TMPDIR)\tkTextTag.obj \ - $(TMPDIR)\tkTextWind.obj \ - $(TMPDIR)\tkTrig.obj \ - $(TMPDIR)\tkUtil.obj \ - $(TMPDIR)\tkVisual.obj \ - $(TMPDIR)\tkStubInit.obj \ - $(TMPDIR)\tkWindow.obj - -# Maintenance hint: Please have multiple members of TKSTUBOBJS be separated -# by exactly one ' ' (see below the rule for making TKSTUBLIB) -TKSTUBOBJS = $(TMPDIR)\tkStubLib.obj - -WINDIR = $(ROOT)\win -GENERICDIR = $(ROOT)\generic -XLIBDIR = $(ROOT)\xlib -BITMAPDIR = $(ROOT)\bitmaps -TCLLIBDIR = $(TCLDIR)\win\$(OUTDIRNAME) -RCDIR = $(WINDIR)\rc - -TK_INCLUDES = -I$(WINDIR) -I$(GENERICDIR) -I$(BITMAPDIR) -I$(XLIBDIR) \ - -I$(TCLDIR)\generic -I$(TCLDIR)\win - -TK_DEFINES = -D_WIN32 $(DEBUGDEFINES) $(THREADDEFINES) SUPPORT_CONFIG_EMBEDDED - -###################################################################### -# Compile flags -###################################################################### - -!IF "$(NODEBUG)" == "1" -# these macros cause maximum optimization and no symbols -cdebug = -v- -vi- -O2 -D_DEBUG -!ELSE -# these macros enable debugging -cdebug = -k -Od -r- -v -vi- -y -!ENDIF - -SYSDEFINES = _MT;NO_STRICT;_NO_VCL - -# declarations common to all compiler options -cbase = -3 -a4 -c -g0 -tWM -Ve -Vx -X- -WARNINGS = -w-rch -w-pch -w-par -w-dup -w-pro -w-dpu - -ccons = -tWC - -CFLAGS = $(cdebug) $(cbase) $(WARNINGS) -D$(SYSDEFINES) - -CON_CFLAGS = $(CFLAGS) $(TK_DEFINES) $(include32) $(ccons) -WISH_CFLAGS = $(CFLAGS) $(include32) $(TK_INCLUDES) $(TK_DEFINES) -TK_CFLAGS = $(CFLAGS) $(include32) $(TK_INCLUDES) $(TK_DEFINES) \ - -DUSE_TCL_STUBS - -###################################################################### -# Link flags -###################################################################### - -!IF "$(NODEBUG)" == "1" -ldebug = -!ELSE -ldebug = -v -!ENDIF - -# declarations common to all linker options -LNFLAGS = -D"" -Gn -I$(TMPDIR) -x $(ldebug) $(libpath32) -# -Gi: create lib file (is -Gl in doc) -# -aa: Windows app, -ap: Windows console app -LNFLAGS_DLL = -ap -Gi -Tpd -LNFLAGS_CONS = -ap -Tpe -LNFLAGS_GUI = -aa -Tpe - -LNLIBS = import32 cw32mt - - -###################################################################### -# Project specific targets -###################################################################### - -all: setup $(WISH) $(CAT32) -install: install-binaries install-libraries -plugin: setup $(TKPLUGINDLL) $(WISHP) -tktest: setup $(TKTEST) $(CAT32) - -# Maintenance hint: We want to set environment variables before calling tktest. -# If we do this in the form of normal commands, they will not persist up to -# the call of tktest. Therfore we put all commands wanted into a batch file. -# The normal way of using 'echo >x.bat' and 'echo >>x.bat' does not work here -# because we cannot write '... > tktest.txt' this way. Hence this advanced -# form of loop hopping: -# - Have MAKE produce a temporary file with the content we want. -# - Use it as input to the COPY command to produce a batch file. -# - Run the batch file and be happy. -# -test: setup $(TKTEST) $(TKLIB) $(CAT32) - copy &&! - set TCL_LIBRARY=$(TCLDIR)/library - set PATH=$(TCLDIR)\win\$(TMPDIRNAME);$(PATH) - $(TKTEST) $(ROOT)/tests/all.tcl > tktest.txt -! _test.bat - _test.bat -# del _test.bat - -runtest: setup $(TKTEST) $(TKLIB) $(CAT32) - echo set TCL_LIBRARY=$(TCLDIR)/library > _test2.bat - echo set PATH=$(TCLDIR)\win\$(TMPDIRNAME);$(PATH) >> _test2.bat - echo $(TKTEST) >> _test2.bat - _test2.bat -# del _test2.bat - -console-wish : all $(WISHC) - -stubs: - $(TCLDIR)\win\$(TMPDIRNAME)\tclsh$(VERSION)$(DBGX) \ - $(TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \ - $(GENERICDIR)\tk.decls $(GENERICDIR)\tkInt.decls - -setup: - @mkd $(TMPDIR) - @mkd $(OUTDIR) - -install-binaries: - @mkd "$(BIN_INSTALL_DIR)" - copy $(TKDLL) "$(BIN_INSTALL_DIR)" - copy $(WISH) "$(BIN_INSTALL_DIR)" - @mkd "$(LIB_INSTALL_DIR)" - copy $(TKLIB) "$(LIB_INSTALL_DIR)" - -install-libraries: - @mkd "$(INCLUDE_INSTALL_DIR)" - @mkd "$(INCLUDE_INSTALL_DIR)\X11" - copy "$(GENERICDIR)\tk.h" "$(INCLUDE_INSTALL_DIR)" - copy "$(GENERICDIR)\tkDecls.h" "$(INCLUDE_INSTALL_DIR)" - copy "$(GENERICDIR)\tkPlatDecls.h" "$(INCLUDE_INSTALL_DIR)" - copy "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)" - xcopy "$(XLIBDIR)\X11\*.h" "$(INCLUDE_INSTALL_DIR)\X11" - @mkd "$(SCRIPT_INSTALL_DIR)" - @mkd "$(SCRIPT_INSTALL_DIR)\images" - @mkd "$(SCRIPT_INSTALL_DIR)\demos" - @mkd "$(SCRIPT_INSTALL_DIR)\demos\images" - @mkd "$(SCRIPT_INSTALL_DIR)\msgs" - xcopy "$(ROOT)\library" "$(SCRIPT_INSTALL_DIR)" - xcopy "$(ROOT)\library\images" "$(SCRIPT_INSTALL_DIR)\images" - xcopy "$(ROOT)\library\demos" "$(SCRIPT_INSTALL_DIR)\demos" - xcopy "$(ROOT)\library\demos\images" "$(SCRIPT_INSTALL_DIR)\demos\images" - xcopy "$(ROOT)\library\msgs" "$(SCRIPT_INSTALL_DIR)\msgs" - -$(TKLIB): $(TKDLL) $(TKSTUBLIB) - -# Maintenance hint: The macro puts a '+-' before the first member of -# TKSTUBOBJS, than replaces any ' ' with ' +-' - together putting '+-' in -# front of any member of TKSTUBOBJS (provided, they are separated in their -# defintion by just one space). -# -# The first time you *make* this target, you will get a warning -# tkStubLib not found in library -# This is (probably) because of the '-' option, telling TLIB to remove -# 'tkStubLib' when it does not yet exist. Forcing a re-make when it already -# exists avoids this warning. -# -$(TKSTUBLIB): $(TKSTUBOBJS) - $(lib32) $@ +-$(TKSTUBOBJS: = +-) - -# $(lib32) $@ @&&! -#+-$(TKSTUBOBJS: = &^ -#+-) -#! - -$(TKDLL): $(TKOBJS) $(TMPDIR)\tk.res - $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 @&&! - $(TKOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLSTUBLIB),, $(TMPDIR)\tk.res -! - -$(TKPLUGINLIB): $(TKPLUGINDLL) - -#$(TKPLUGINDLL): $(TKOBJS) $(TMPDIR)\tk.res -# $(link32) $(ldebug) $(dlllflags) \ -# -out:$@ $(TMPDIR)\tk.res $(TCLLIBDIR)\$(TCLPLUGINLIB) \ -# $(guilibsdll) @<< -# $(TKOBJS) -#<< - -$(WISH): $(WISHOBJS) $(TKLIB) $(TMPDIR)\wish.res - $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_GUI) $(TOOLS32)\lib\c0x32 @&&! - $(WISHOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB),, $(TMPDIR)\wish.res -! - -$(WISHC): $(WISHOBJS) $(TKLIB) $(TMPDIR)\wish.res - $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 @&&! - $(WISHOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB),, $(TMPDIR)\wish.res -! - -$(WISHP): $(WISHOBJS) $(TKPLUGINLIB) $(TMPDIR)\wish.res - $(link32) $(ldebug) $(guilflags) $(TMPDIR)\wish.res -out:$@ \ - $(guilibsdll) $(TCLLIBDIR)\$(TCLPLUGINLIB) \ - $(TKPLUGINLIB) $(WISHOBJS) - -$(TKTEST): $(TKTESTOBJS) $(TKLIB) $(TMPDIR)\wish.res - $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_GUI) $(TOOLS32)\lib\c0x32 @&&! - $(TKTESTOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB),, $(TMPDIR)\wish.res -! -# $(link32) $(ldebug) $(guilflags) $(TMPDIR)\wish.res -out:$@ \ -# $(guilibsdll) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB) $(TKTESTOBJS) - -#$(CAT32): $(TCLDIR)\win\cat.c -# $(cc32) $(CON_CFLAGS) -o$(TMPDIR)\cat.obj $? -# $(link32) $(conlflags) -out:$@ -stack:16384 $(TMPDIR)\cat.obj $(conlibs) - -$(CAT32): $(TCLDIR)\win\cat.c - $(cc32) $(CONS_CFLAGS) -o$(TMPDIR)\cat.obj $? - $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 \ - $(TMPDIR)\cat.obj, $@, -x, $(LNLIBS),, - -# -# Regenerate the stubs files. -# - -genstubs: - tclsh$(VERSION) $(TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \ - $(GENERICDIR)\tk.decls $(GENERICDIR)\tkInt.decls - -# -# Special case object file targets -# - -$(TMPDIR)\testMain.obj: $(WINDIR)\winMain.c - $(cc32) $(WISH_CFLAGS) -DTK_TEST -o$@ $? - -$(TMPDIR)\tkTest.obj: $(GENERICDIR)\tkTest.c - $(cc32) $(WISH_CFLAGS) -o$@ $? - -$(TMPDIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c - $(cc32) $(WISH_CFLAGS) -o$@ $? - -$(TMPDIR)\tkWinTest.obj: $(WINDIR)\tkWinTest.c - $(cc32) $(WISH_CFLAGS) -o$@ $? - -$(TMPDIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c - $(cc32) $(WISH_CFLAGS) -o$@ $? - -$(TMPDIR)\winMain.obj: $(WINDIR)\winMain.c - $(cc32) $(WISH_CFLAGS) -o$@ $? - -$(TMPDIR)\tkStubLib.obj : $(GENERICDIR)\tkStubLib.c - $(cc32) $(TK_CFLAGS) -DSTATIC_BUILD -o$@ $? - -# -# Implicit rules -# - -{$(XLIBDIR)}.c{$(TMPDIR)}.obj: - $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $< - -{$(GENERICDIR)}.c{$(TMPDIR)}.obj: - $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $< - -{$(WINDIR)}.c{$(TMPDIR)}.obj: - $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $< - -{$(ROOT)\unix}.c{$(TMPDIR)}.obj: - $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $< - -{$(RCDIR)}.rc{$(TMPDIR)}.res: - $(rc32) -I"$(GENERICDIR)" -I"$(TOOLS32)\include" -I"$(TCLDIR)\generic" \ - -D$(USERDEFINES);$(SYSDEFINES) -fo$@ $< - -clean: - -@del $(OUTDIR)\*.exp - -@del $(OUTDIR)\*.lib - -@del $(OUTDIR)\*.dll - -@del $(OUTDIR)\*.exe - -@del $(OUTDIR)\*.pdb - -@del $(TMPDIR)\*.pch - -@del $(TMPDIR)\*.obj - -@del $(TMPDIR)\*.res - -@del $(TMPDIR)\*.exe - -@rmd $(OUTDIR) - -@rmd $(TMPDIR) - -# dependencies - -$(TMPDIR)\tk.res: \ - $(RCDIR)\buttons.bmp \ - $(RCDIR)\cursor*.cur \ - $(RCDIR)\tk.ico - -$(GENERICDIR)/default.h: $(WINDIR)/tkWinDefault.h -$(GENERICDIR)/tkButton.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkCanvas.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkEntry.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkFrame.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkListbox.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkMenu.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkMenubutton.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkMessage.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkScale.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkScrollbar.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkText.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkTextIndex.c: $(GENERICDIR)/default.h -$(GENERICDIR)/tkTextTag.c: $(GENERICDIR)/default.h - -$(GENERICDIR)/tkText.c: $(GENERICDIR)/tkText.h -$(GENERICDIR)/tkTextBTree.c: $(GENERICDIR)/tkText.h -$(GENERICDIR)/tkTextDisp.c: $(GENERICDIR)/tkText.h -$(GENERICDIR)/tkTextDisp.c: $(GENERICDIR)/tkText.h -$(GENERICDIR)/tkTextImage.c: $(GENERICDIR)/tkText.h -$(GENERICDIR)/tkTextIndex.c: $(GENERICDIR)/tkText.h -$(GENERICDIR)/tkTextMark.c: $(GENERICDIR)/tkText.h -$(GENERICDIR)/tkTextTag.c: $(GENERICDIR)/tkText.h -$(GENERICDIR)/tkTextWind.c: $(GENERICDIR)/tkText.h - -$(GENERICDIR)/tkMacWinMenu.c: $(GENERICDIR)/tkMenu.h -$(GENERICDIR)/tkMenu.c: $(GENERICDIR)/tkMenu.h -$(GENERICDIR)/tkMenuDraw.c: $(GENERICDIR)/tkMenu.h -$(WINDIR)/tkWinMenu.c: $(GENERICDIR)/tkMenu.h - - +#
+# Makefile for Borland C++ 5.5 (or C++ Builder 5), adapted from the makefile
+# for Visual C++ that came with tk 8.3.3
+#
+# Some "not so obvious" details in this makefile are preceded by a comment
+# "maintenance hint", which tries to explain what's going on. Better to
+# leave those in place.
+# Helmut Giese, July 2002
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 1995-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+
+# Does not depend on the presence of any environment variables in
+# order to compile tcl; all needed information is derived from
+# location of the compiler directories.
+
+#
+# Project directories
+#
+# ROOT = top of source tree
+#
+# TMPDIR = location where .obj files should be stored during build
+#
+# TOOLS32 = location of Borland development tools.
+#
+# TCLDIR = location of top of Tcl source hierarchy
+#
+
+ROOT = ..
+TCLDIR = ..\..\tcl8.4
+INSTALLDIR = D:\tmp\tcl
+
+# If you have C++ Builder 5 or the free Borland C++ 5.5 compiler
+# adapt the following paths as appropriate for your system
+TOOLS32 = d:\cbld5
+TOOLS32_rc = d:\cbld5
+#TOOLS32 = c:\bc55
+#TOOLS32_rc = c:\bc55
+
+cc32 = "$(TOOLS32)\bin\bcc32.exe"
+link32 = "$(TOOLS32)\bin\ilink32.exe"
+lib32 = "$(TOOLS32)\bin\tlib.exe"
+rc32 = "$(TOOLS32_rc)\bin\brcc32.exe"
+include32 = -I"$(TOOLS32)\include;$(TOOLS32)\include\mfc"
+libpath32 = -L"$(TOOLS32)\lib"
+
+# Uncomment the following line to compile with thread support
+#THREADDEFINES = -DTCL_THREADS=1
+
+# Allow definition of NDEBUG via command line
+# Set NODEBUG to 0 to compile with symbols
+!if !defined(NODEBUG)
+NODEBUG = 1
+!endif
+
+# uncomment the following two lines to compile with TCL_MEM_DEBUG
+#DEBUGDEFINES =-DTCL_MEM_DEBUG
+
+######################################################################
+# Do not modify below this line
+######################################################################
+
+TCLNAMEPREFIX = tcl
+TKNAMEPREFIX = tk
+WISHNAMEPREFIX = wish
+VERSION = 84
+DOTVERSION = 8.4
+
+TCLSTUBPREFIX = $(TCLNAMEPREFIX)stub
+TKSTUBPREFIX = $(TKNAMEPREFIX)stub
+
+
+BINROOT = .
+!IF "$(NODEBUG)" == "1"
+TMPDIRNAME = Release
+DBGX =
+!ELSE
+TMPDIRNAME = Debug
+DBGX =
+#DBGX = d
+!ENDIF
+TMPDIR = $(BINROOT)\$(TMPDIRNAME)
+OUTDIRNAME = $(TMPDIRNAME)
+OUTDIR = $(TMPDIR)
+
+TCLLIB = $(TCLNAMEPREFIX)$(VERSION)$(DBGX).lib
+TCLPLUGINLIB = $(TCLNAMEPREFIX)$(VERSION)p.lib
+TCLSTUBLIB = $(TCLSTUBPREFIX)$(VERSION)$(DBGX).lib
+TKDLLNAME = $(TKNAMEPREFIX)$(VERSION)$(DBGX).dll
+TKDLL = $(OUTDIR)\$(TKDLLNAME)
+TKLIB = $(OUTDIR)\$(TKNAMEPREFIX)$(VERSION)$(DBGX).lib
+TKSTUBLIBNAME = $(TKSTUBPREFIX)$(VERSION)$(DBGX).lib
+TKSTUBLIB = $(OUTDIR)\$(TKSTUBLIBNAME)
+TKPLUGINDLLNAME = $(TKNAMEPREFIX)$(VERSION)p$(DBG).dll
+TKPLUGINDLL = $(OUTDIR)\$(TKPLUGINDLLNAME)
+TKPLUGINLIB = $(OUTDIR)\$(TKNAMEPREFIX)$(VERSION)p$(DBGX).lib
+
+WISH = $(OUTDIR)\$(WISHNAMEPREFIX)$(VERSION)$(DBGX).exe
+WISHC = $(OUTDIR)\$(WISHNAMEPREFIX)c$(VERSION)$(DBGX).exe
+WISHP = $(OUTDIR)\$(WISHNAMEPREFIX)p$(VERSION)$(DBGX).exe
+TKTEST = $(OUTDIR)\$(TKNAMEPREFIX)test.exe
+CAT32 = $(TMPDIR)\cat32.exe
+
+BIN_INSTALL_DIR = $(INSTALLDIR)\bin
+INCLUDE_INSTALL_DIR = $(INSTALLDIR)\include
+LIB_INSTALL_DIR = $(INSTALLDIR)\lib
+SCRIPT_INSTALL_DIR = $(LIB_INSTALL_DIR)\tk$(DOTVERSION)
+
+WISHOBJS = \
+ $(TMPDIR)\winMain.obj
+
+TKTESTOBJS = \
+ $(TMPDIR)\tkTest.obj \
+ $(TMPDIR)\tkSquare.obj \
+ $(TMPDIR)\testMain.obj \
+ $(TMPDIR)\tkOldTest.obj \
+ $(TMPDIR)\tkWinTest.obj \
+ $(TCLLIBDIR)\tclThreadTest.obj
+
+XLIBOBJS = \
+ $(TMPDIR)\xcolors.obj \
+ $(TMPDIR)\xdraw.obj \
+ $(TMPDIR)\xgc.obj \
+ $(TMPDIR)\ximage.obj \
+ $(TMPDIR)\xutil.obj
+
+TKOBJS = \
+ $(TMPDIR)\tkConsole.obj \
+ $(TMPDIR)\tkUnixMenubu.obj \
+ $(TMPDIR)\tkUnixScale.obj \
+ $(XLIBOBJS) \
+ $(TMPDIR)\tkWin3d.obj \
+ $(TMPDIR)\tkWin32Dll.obj \
+ $(TMPDIR)\tkWinButton.obj \
+ $(TMPDIR)\tkWinClipboard.obj \
+ $(TMPDIR)\tkWinColor.obj \
+ $(TMPDIR)\tkWinConfig.obj \
+ $(TMPDIR)\tkWinCursor.obj \
+ $(TMPDIR)\tkWinDialog.obj \
+ $(TMPDIR)\tkWinDraw.obj \
+ $(TMPDIR)\tkWinEmbed.obj \
+ $(TMPDIR)\tkWinFont.obj \
+ $(TMPDIR)\tkWinImage.obj \
+ $(TMPDIR)\tkWinInit.obj \
+ $(TMPDIR)\tkWinKey.obj \
+ $(TMPDIR)\tkWinMenu.obj \
+ $(TMPDIR)\tkWinPixmap.obj \
+ $(TMPDIR)\tkWinPointer.obj \
+ $(TMPDIR)\tkWinRegion.obj \
+ $(TMPDIR)\tkWinScrlbr.obj \
+ $(TMPDIR)\tkWinSend.obj \
+ $(TMPDIR)\tkWinWindow.obj \
+ $(TMPDIR)\tkWinWm.obj \
+ $(TMPDIR)\tkWinX.obj \
+ $(TMPDIR)\stubs.obj \
+ $(TMPDIR)\tk3d.obj \
+ $(TMPDIR)\tkArgv.obj \
+ $(TMPDIR)\tkAtom.obj \
+ $(TMPDIR)\tkBind.obj \
+ $(TMPDIR)\tkBitmap.obj \
+ $(TMPDIR)\tkBusy.obj \
+ $(TMPDIR)\tkButton.obj \
+ $(TMPDIR)\tkCanvArc.obj \
+ $(TMPDIR)\tkCanvBmap.obj \
+ $(TMPDIR)\tkCanvImg.obj \
+ $(TMPDIR)\tkCanvLine.obj \
+ $(TMPDIR)\tkCanvPoly.obj \
+ $(TMPDIR)\tkCanvPs.obj \
+ $(TMPDIR)\tkCanvText.obj \
+ $(TMPDIR)\tkCanvUtil.obj \
+ $(TMPDIR)\tkCanvWind.obj \
+ $(TMPDIR)\tkCanvas.obj \
+ $(TMPDIR)\tkClipboard.obj \
+ $(TMPDIR)\tkCmds.obj \
+ $(TMPDIR)\tkColor.obj \
+ $(TMPDIR)\tkConfig.obj \
+ $(TMPDIR)\tkCursor.obj \
+ $(TMPDIR)\tkEntry.obj \
+ $(TMPDIR)\tkError.obj \
+ $(TMPDIR)\tkEvent.obj \
+ $(TMPDIR)\tkFileFilter.obj \
+ $(TMPDIR)\tkFocus.obj \
+ $(TMPDIR)\tkFont.obj \
+ $(TMPDIR)\tkFrame.obj \
+ $(TMPDIR)\tkGC.obj \
+ $(TMPDIR)\tkGeometry.obj \
+ $(TMPDIR)\tkGet.obj \
+ $(TMPDIR)\tkGrab.obj \
+ $(TMPDIR)\tkGrid.obj \
+ $(TMPDIR)\tkImage.obj \
+ $(TMPDIR)\tkImgBmap.obj \
+ $(TMPDIR)\tkImgGIF.obj \
+ $(TMPDIR)\tkImgPPM.obj \
+ $(TMPDIR)\tkImgPhoto.obj \
+ $(TMPDIR)\tkImgPhInstance.obj \
+ $(TMPDIR)\tkImgUtil.obj \
+ $(TMPDIR)\tkListbox.obj \
+ $(TMPDIR)\tkMacWinMenu.obj \
+ $(TMPDIR)\tkMain.obj \
+ $(TMPDIR)\tkMenu.obj \
+ $(TMPDIR)\tkMenubutton.obj \
+ $(TMPDIR)\tkMenuDraw.obj \
+ $(TMPDIR)\tkMessage.obj \
+ $(TMP_DIR)\tkPanedWindow.obj \
+ $(TMPDIR)\tkObj.obj \
+ $(TMPDIR)\tkOldConfig.obj \
+ $(TMPDIR)\tkOption.obj \
+ $(TMPDIR)\tkPack.obj \
+ $(TMPDIR)\tkPlace.obj \
+ $(TMPDIR)\tkPointer.obj \
+ $(TMPDIR)\tkRectOval.obj \
+ $(TMPDIR)\tkScale.obj \
+ $(TMPDIR)\tkScrollbar.obj \
+ $(TMPDIR)\tkSelect.obj \
+ $(TMPDIR)\tkText.obj \
+ $(TMPDIR)\tkTextBTree.obj \
+ $(TMPDIR)\tkTextDisp.obj \
+ $(TMPDIR)\tkTextImage.obj \
+ $(TMPDIR)\tkTextIndex.obj \
+ $(TMPDIR)\tkTextMark.obj \
+ $(TMPDIR)\tkTextTag.obj \
+ $(TMPDIR)\tkTextWind.obj \
+ $(TMPDIR)\tkTrig.obj \
+ $(TMPDIR)\tkUtil.obj \
+ $(TMPDIR)\tkVisual.obj \
+ $(TMPDIR)\tkStubInit.obj \
+ $(TMPDIR)\tkWindow.obj
+
+# Maintenance hint: Please have multiple members of TKSTUBOBJS be separated
+# by exactly one ' ' (see below the rule for making TKSTUBLIB)
+TKSTUBOBJS = $(TMPDIR)\tkStubLib.obj
+
+WINDIR = $(ROOT)\win
+GENERICDIR = $(ROOT)\generic
+XLIBDIR = $(ROOT)\xlib
+BITMAPDIR = $(ROOT)\bitmaps
+TCLLIBDIR = $(TCLDIR)\win\$(OUTDIRNAME)
+RCDIR = $(WINDIR)\rc
+
+TK_INCLUDES = -I$(WINDIR) -I$(GENERICDIR) -I$(BITMAPDIR) -I$(XLIBDIR) \
+ -I$(TCLDIR)\generic -I$(TCLDIR)\win
+
+TK_DEFINES = -D_WIN32 $(DEBUGDEFINES) $(THREADDEFINES) SUPPORT_CONFIG_EMBEDDED
+
+######################################################################
+# Compile flags
+######################################################################
+
+!IF "$(NODEBUG)" == "1"
+# these macros cause maximum optimization and no symbols
+cdebug = -v- -vi- -O2 -D_DEBUG
+!ELSE
+# these macros enable debugging
+cdebug = -k -Od -r- -v -vi- -y
+!ENDIF
+
+SYSDEFINES = _MT;NO_STRICT;_NO_VCL
+
+# declarations common to all compiler options
+cbase = -3 -a4 -c -g0 -tWM -Ve -Vx -X-
+WARNINGS = -w-rch -w-pch -w-par -w-dup -w-pro -w-dpu
+
+ccons = -tWC
+
+CFLAGS = $(cdebug) $(cbase) $(WARNINGS) -D$(SYSDEFINES)
+
+CON_CFLAGS = $(CFLAGS) $(TK_DEFINES) $(include32) $(ccons)
+WISH_CFLAGS = $(CFLAGS) $(include32) $(TK_INCLUDES) $(TK_DEFINES)
+TK_CFLAGS = $(CFLAGS) $(include32) $(TK_INCLUDES) $(TK_DEFINES) \
+ -DUSE_TCL_STUBS
+
+######################################################################
+# Link flags
+######################################################################
+
+!IF "$(NODEBUG)" == "1"
+ldebug =
+!ELSE
+ldebug = -v
+!ENDIF
+
+# declarations common to all linker options
+LNFLAGS = -D"" -Gn -I$(TMPDIR) -x $(ldebug) $(libpath32)
+# -Gi: create lib file (is -Gl in doc)
+# -aa: Windows app, -ap: Windows console app
+LNFLAGS_DLL = -ap -Gi -Tpd
+LNFLAGS_CONS = -ap -Tpe
+LNFLAGS_GUI = -aa -Tpe
+
+LNLIBS = import32 cw32mt
+
+
+######################################################################
+# Project specific targets
+######################################################################
+
+all: setup $(WISH) $(CAT32)
+install: install-binaries install-libraries
+plugin: setup $(TKPLUGINDLL) $(WISHP)
+tktest: setup $(TKTEST) $(CAT32)
+
+# Maintenance hint: We want to set environment variables before calling tktest.
+# If we do this in the form of normal commands, they will not persist up to
+# the call of tktest. Therfore we put all commands wanted into a batch file.
+# The normal way of using 'echo >x.bat' and 'echo >>x.bat' does not work here
+# because we cannot write '... > tktest.txt' this way. Hence this advanced
+# form of loop hopping:
+# - Have MAKE produce a temporary file with the content we want.
+# - Use it as input to the COPY command to produce a batch file.
+# - Run the batch file and be happy.
+#
+test: setup $(TKTEST) $(TKLIB) $(CAT32)
+ copy &&!
+ set TCL_LIBRARY=$(TCLDIR)/library
+ set PATH=$(TCLDIR)\win\$(TMPDIRNAME);$(PATH)
+ $(TKTEST) $(ROOT)/tests/all.tcl > tktest.txt
+! _test.bat
+ _test.bat
+# del _test.bat
+
+runtest: setup $(TKTEST) $(TKLIB) $(CAT32)
+ echo set TCL_LIBRARY=$(TCLDIR)/library > _test2.bat
+ echo set PATH=$(TCLDIR)\win\$(TMPDIRNAME);$(PATH) >> _test2.bat
+ echo $(TKTEST) >> _test2.bat
+ _test2.bat
+# del _test2.bat
+
+console-wish : all $(WISHC)
+
+stubs:
+ $(TCLDIR)\win\$(TMPDIRNAME)\tclsh$(VERSION)$(DBGX) \
+ $(TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
+ $(GENERICDIR)\tk.decls $(GENERICDIR)\tkInt.decls
+
+setup:
+ @mkd $(TMPDIR)
+ @mkd $(OUTDIR)
+
+install-binaries:
+ @mkd "$(BIN_INSTALL_DIR)"
+ copy $(TKDLL) "$(BIN_INSTALL_DIR)"
+ copy $(WISH) "$(BIN_INSTALL_DIR)"
+ @mkd "$(LIB_INSTALL_DIR)"
+ copy $(TKLIB) "$(LIB_INSTALL_DIR)"
+
+install-libraries:
+ @mkd "$(INCLUDE_INSTALL_DIR)"
+ @mkd "$(INCLUDE_INSTALL_DIR)\X11"
+ copy "$(GENERICDIR)\tk.h" "$(INCLUDE_INSTALL_DIR)"
+ copy "$(GENERICDIR)\tkDecls.h" "$(INCLUDE_INSTALL_DIR)"
+ copy "$(GENERICDIR)\tkPlatDecls.h" "$(INCLUDE_INSTALL_DIR)"
+ copy "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)"
+ xcopy "$(XLIBDIR)\X11\*.h" "$(INCLUDE_INSTALL_DIR)\X11"
+ @mkd "$(SCRIPT_INSTALL_DIR)"
+ @mkd "$(SCRIPT_INSTALL_DIR)\images"
+ @mkd "$(SCRIPT_INSTALL_DIR)\demos"
+ @mkd "$(SCRIPT_INSTALL_DIR)\demos\images"
+ @mkd "$(SCRIPT_INSTALL_DIR)\msgs"
+ xcopy "$(ROOT)\library" "$(SCRIPT_INSTALL_DIR)"
+ xcopy "$(ROOT)\library\images" "$(SCRIPT_INSTALL_DIR)\images"
+ xcopy "$(ROOT)\library\demos" "$(SCRIPT_INSTALL_DIR)\demos"
+ xcopy "$(ROOT)\library\demos\images" "$(SCRIPT_INSTALL_DIR)\demos\images"
+ xcopy "$(ROOT)\library\msgs" "$(SCRIPT_INSTALL_DIR)\msgs"
+
+$(TKLIB): $(TKDLL) $(TKSTUBLIB)
+
+# Maintenance hint: The macro puts a '+-' before the first member of
+# TKSTUBOBJS, than replaces any ' ' with ' +-' - together putting '+-' in
+# front of any member of TKSTUBOBJS (provided, they are separated in their
+# defintion by just one space).
+#
+# The first time you *make* this target, you will get a warning
+# tkStubLib not found in library
+# This is (probably) because of the '-' option, telling TLIB to remove
+# 'tkStubLib' when it does not yet exist. Forcing a re-make when it already
+# exists avoids this warning.
+#
+$(TKSTUBLIB): $(TKSTUBOBJS)
+ $(lib32) $@ +-$(TKSTUBOBJS: = +-)
+
+# $(lib32) $@ @&&!
+#+-$(TKSTUBOBJS: = &^
+#+-)
+#!
+
+$(TKDLL): $(TKOBJS) $(TMPDIR)\tk.res
+ $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 @&&!
+ $(TKOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLSTUBLIB),, $(TMPDIR)\tk.res
+!
+
+$(TKPLUGINLIB): $(TKPLUGINDLL)
+
+#$(TKPLUGINDLL): $(TKOBJS) $(TMPDIR)\tk.res
+# $(link32) $(ldebug) $(dlllflags) \
+# -out:$@ $(TMPDIR)\tk.res $(TCLLIBDIR)\$(TCLPLUGINLIB) \
+# $(guilibsdll) @<<
+# $(TKOBJS)
+#<<
+
+$(WISH): $(WISHOBJS) $(TKLIB) $(TMPDIR)\wish.res
+ $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_GUI) $(TOOLS32)\lib\c0x32 @&&!
+ $(WISHOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB),, $(TMPDIR)\wish.res
+!
+
+$(WISHC): $(WISHOBJS) $(TKLIB) $(TMPDIR)\wish.res
+ $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 @&&!
+ $(WISHOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB),, $(TMPDIR)\wish.res
+!
+
+$(WISHP): $(WISHOBJS) $(TKPLUGINLIB) $(TMPDIR)\wish.res
+ $(link32) $(ldebug) $(guilflags) $(TMPDIR)\wish.res -out:$@ \
+ $(guilibsdll) $(TCLLIBDIR)\$(TCLPLUGINLIB) \
+ $(TKPLUGINLIB) $(WISHOBJS)
+
+$(TKTEST): $(TKTESTOBJS) $(TKLIB) $(TMPDIR)\wish.res
+ $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_GUI) $(TOOLS32)\lib\c0x32 @&&!
+ $(TKTESTOBJS), $@, -x, $(LNLIBS) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB),, $(TMPDIR)\wish.res
+!
+# $(link32) $(ldebug) $(guilflags) $(TMPDIR)\wish.res -out:$@ \
+# $(guilibsdll) $(TCLLIBDIR)\$(TCLLIB) $(TKLIB) $(TKTESTOBJS)
+
+#$(CAT32): $(TCLDIR)\win\cat.c
+# $(cc32) $(CON_CFLAGS) -o$(TMPDIR)\cat.obj $?
+# $(link32) $(conlflags) -out:$@ -stack:16384 $(TMPDIR)\cat.obj $(conlibs)
+
+$(CAT32): $(TCLDIR)\win\cat.c
+ $(cc32) $(CONS_CFLAGS) -o$(TMPDIR)\cat.obj $?
+ $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 \
+ $(TMPDIR)\cat.obj, $@, -x, $(LNLIBS),,
+
+#
+# Regenerate the stubs files.
+#
+
+genstubs:
+ tclsh$(VERSION) $(TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
+ $(GENERICDIR)\tk.decls $(GENERICDIR)\tkInt.decls
+
+#
+# Special case object file targets
+#
+
+$(TMPDIR)\testMain.obj: $(WINDIR)\winMain.c
+ $(cc32) $(WISH_CFLAGS) -DTK_TEST -o$@ $?
+
+$(TMPDIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
+ $(cc32) $(WISH_CFLAGS) -o$@ $?
+
+$(TMPDIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
+ $(cc32) $(WISH_CFLAGS) -o$@ $?
+
+$(TMPDIR)\tkWinTest.obj: $(WINDIR)\tkWinTest.c
+ $(cc32) $(WISH_CFLAGS) -o$@ $?
+
+$(TMPDIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
+ $(cc32) $(WISH_CFLAGS) -o$@ $?
+
+$(TMPDIR)\winMain.obj: $(WINDIR)\winMain.c
+ $(cc32) $(WISH_CFLAGS) -o$@ $?
+
+$(TMPDIR)\tkStubLib.obj : $(GENERICDIR)\tkStubLib.c
+ $(cc32) $(TK_CFLAGS) -DSTATIC_BUILD -o$@ $?
+
+#
+# Implicit rules
+#
+
+{$(XLIBDIR)}.c{$(TMPDIR)}.obj:
+ $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $<
+
+{$(GENERICDIR)}.c{$(TMPDIR)}.obj:
+ $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $<
+
+{$(WINDIR)}.c{$(TMPDIR)}.obj:
+ $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $<
+
+{$(ROOT)\unix}.c{$(TMPDIR)}.obj:
+ $(cc32) -DDLL_BUILD -DBUILD_tk $(TK_CFLAGS) -o$@ $<
+
+{$(RCDIR)}.rc{$(TMPDIR)}.res:
+ $(rc32) -I"$(GENERICDIR)" -I"$(TOOLS32)\include" -I"$(TCLDIR)\generic" \
+ -D$(USERDEFINES);$(SYSDEFINES) -fo$@ $<
+
+clean:
+ -@del $(OUTDIR)\*.exp
+ -@del $(OUTDIR)\*.lib
+ -@del $(OUTDIR)\*.dll
+ -@del $(OUTDIR)\*.exe
+ -@del $(OUTDIR)\*.pdb
+ -@del $(TMPDIR)\*.pch
+ -@del $(TMPDIR)\*.obj
+ -@del $(TMPDIR)\*.res
+ -@del $(TMPDIR)\*.exe
+ -@rmd $(OUTDIR)
+ -@rmd $(TMPDIR)
+
+# dependencies
+
+$(TMPDIR)\tk.res: \
+ $(RCDIR)\buttons.bmp \
+ $(RCDIR)\cursor*.cur \
+ $(RCDIR)\tk.ico
+
+$(GENERICDIR)/default.h: $(WINDIR)/tkWinDefault.h
+$(GENERICDIR)/tkButton.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkCanvas.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkEntry.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkFrame.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkListbox.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkMenu.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkMenubutton.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkMessage.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkScale.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkScrollbar.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkText.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkTextIndex.c: $(GENERICDIR)/default.h
+$(GENERICDIR)/tkTextTag.c: $(GENERICDIR)/default.h
+
+$(GENERICDIR)/tkText.c: $(GENERICDIR)/tkText.h
+$(GENERICDIR)/tkTextBTree.c: $(GENERICDIR)/tkText.h
+$(GENERICDIR)/tkTextDisp.c: $(GENERICDIR)/tkText.h
+$(GENERICDIR)/tkTextDisp.c: $(GENERICDIR)/tkText.h
+$(GENERICDIR)/tkTextImage.c: $(GENERICDIR)/tkText.h
+$(GENERICDIR)/tkTextIndex.c: $(GENERICDIR)/tkText.h
+$(GENERICDIR)/tkTextMark.c: $(GENERICDIR)/tkText.h
+$(GENERICDIR)/tkTextTag.c: $(GENERICDIR)/tkText.h
+$(GENERICDIR)/tkTextWind.c: $(GENERICDIR)/tkText.h
+
+$(GENERICDIR)/tkMacWinMenu.c: $(GENERICDIR)/tkMenu.h
+$(GENERICDIR)/tkMenu.c: $(GENERICDIR)/tkMenu.h
+$(GENERICDIR)/tkMenuDraw.c: $(GENERICDIR)/tkMenu.h
+$(WINDIR)/tkWinMenu.c: $(GENERICDIR)/tkMenu.h
+
+
diff --git a/win/makefile.vc b/win/makefile.vc index 6be320e..ae43eb6 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -1,1027 +1,1036 @@ -#------------------------------------------------------------- -*- makefile -*- -# makefile.vc -- -# -# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+) -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# Copyright (c) 1995-1996 Sun Microsystems, Inc. -# Copyright (c) 1998-2000 Ajuba Solutions. -# Copyright (c) 2001-2005 ActiveState Corporation. -# Copyright (c) 2001-2004 David Gravereaux. -# Copyright (c) 2003-2008 Pat Thoyts. -#------------------------------------------------------------------------------ - -# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or -# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir) -!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR) -MSG = ^ -You need to run vcvars32.bat from Developer Studio or setenv.bat from the^ -Platform SDK first to setup the environment. Jump to this line to read^ -the build instructions. -!error $(MSG) -!endif - -#------------------------------------------------------------------------------ -# HOW TO USE this makefile: -# -# 1) It is now necessary to have MSVCDir, MSDevDir or MSSDK set in the -# environment. This is used as a check to see if vcvars32.bat had been -# run prior to running nmake or during the installation of Microsoft -# Visual C++, MSVCDir had been set globally and the PATH adjusted. -# Either way is valid. -# -# You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin -# directory to setup the proper environment, if needed, for your -# current setup. This is a needed bootstrap requirement and allows the -# swapping of different environments to be easier. -# -# 2) To use the Platform SDK (not expressly needed), run setenv.bat after -# vcvars32.bat according to the instructions for it. This can also -# turn on the 64-bit compiler, if your SDK has it. -# -# 3) Targets are: -# release -- Builds the core, the shell. (default) -# dlls -- Just builds the windows extensions. -# shell -- Just builds the shell and the core. -# core -- Only builds the core [tkXX.(dll|lib)]. -# all -- Builds everything. -# test -- Builds and runs the test suite. -# tktest -- Just builds the binaries for the test suite. -# install -- Installs the built binaries and libraries to $(INSTALLDIR) -# as the root of the install tree. -# cwish -- Builds a console version of wish. -# tidy/clean/hose -- varying levels of cleaning. -# genstubs -- Rebuilds the Stubs table and support files (dev only). -# depend -- Generates an accurate set of source dependancies for this -# makefile. Helpful to avoid problems when the sources are -# refreshed and you rebuild, but can "overbuild" when common -# headers like tkInt.h just get small changes. -# htmlhelp -- Builds a Windows .chm help file for Tcl and Tk from the -# troff manual pages found in $(ROOT)\doc. You need to -# have installed the HTML Help Compiler package from Microsoft -# to produce the .chm file. -# winhelp -- Builds the windows .hlp file for Tcl from the troff man -# files found in $(ROOT)\doc. -# -# 4) Macros usable on the commandline: -# TCLDIR=<path> -# Sets the location for where to find the Tcl headers and -# libraries. The install point is assumed when not specified. -# Tk does need the source directory, though. Tk comes very close -# to not needing the sources, but does, in fact, require them. -# -# INSTALLDIR=<path> -# Sets where to install Tcl from the built binaries. -# C:\Progra~1\Tcl is assumed when not specified. -# -# OPTS=loimpact,msvcrt,nothreads,noxp,pdbs,profile,square,static,staticpkg,symbols,unchecked,none -# Sets special options for the core. The default is for none. -# Any combination of the above may be used (comma separated). -# 'none' will over-ride everything to nothing. -# -# loimpact = Adds a flag for how NT treats the heap to keep memory -# in use, low. This is said to impact alloc performance. -# msvcrt = Affects the static option only to switch it from -# using libcmt(d) as the C runtime [by default] to -# msvcrt(d). This is useful for static embedding -# support. -# nothreads= Turns off full multithreading support. -# noxp = If you do not have the uxtheme.h header then you -# cannot include support for XP themeing. -# square = Include the demo square widget. -# static = Builds a static library of the core instead of a -# dll. The shell will be static (and large), as well. -# staticpkg= Affects the static option only to switch wishXX.exe -# to have the dde and reg extension linked inside it. -# pdbs = Build detached symbols for release builds. -# profile = Adds profiling hooks. Map file is assumed. -# thrdalloc = Use the thread allocator (shared global free pool) -# This is the default on threaded builds. -# tclalloc = Use the old non-thread allocator -# symbols = Debug build. Links to the debug C runtime, disables -# optimizations and creates pdb symbols files. -# unchecked = Allows a symbols build to not use the debug -# enabled runtime (msvcrt.dll not msvcrtd.dll -# or libcmt.lib not libcmtd.lib). -# -# STATS=compdbg,memdbg,none -# Sets optional memory and bytecode compiler debugging code added -# to the core. The default is for none. Any combination of the -# above may be used (comma separated). 'none' will over-ride -# everything to nothing. -# -# compdbg = Enables byte compilation logging. -# memdbg = Enables the debugging memory allocator. -# -# CHECKS=64bit,fullwarn,nodep,none -# Sets special macros for checking compatability. -# -# 64bit = Enable 64bit portability warnings (if available) -# fullwarn = Builds with full compiler and link warnings enabled. -# Very verbose. -# nodep = Turns off compatability macros to ensure the core -# isn't being built with deprecated functions. -# -# MACHINE=(ALPHA|AMD64|IA64|IX86) -# Set the machine type used for the compiler, linker, and -# resource compiler. This hook is needed to tell the tools -# when alternate platforms are requested. IX86 is the default -# when not specified. If the CPU environment variable has been -# set (ie: recent Platform SDK) then MACHINE is set from CPU. -# -# TMP_DIR=<path> -# OUT_DIR=<path> -# Hooks to allow the intermediate and output directories to be -# changed. $(OUT_DIR) is assumed to be -# $(BINROOT)\(Release|Debug) based on if symbols are requested. -# $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default. -# -# TESTPAT=<file> -# Reads the tests requested to be run from this file. -# -# 5) Examples: -# -# Basic syntax of calling nmake looks like this: -# nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]] -# -# Standard (no frills) -# c:\tk_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat -# Setting environment for using Microsoft Visual C++ tools. -# c:\tk_src\win\>nmake -f makefile.vc release -# c:\tk_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl -# -# Building for Win64 -# c:\tk_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat -# Setting environment for using Microsoft Visual C++ tools. -# c:\tk_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL -# Targeting Windows pre64 RETAIL -# c:\tk_src\win\>nmake -f makefile.vc MACHINE=IA64 -# -#------------------------------------------------------------------------------ -#============================================================================== -############################################################################### - - -# //==================================================================\\ -# >>[ -> Do not modify below this line. <- ]<< -# >>[ Please, use the commandline macros to modify how Tcl is built. ]<< -# >>[ If you need more features, send us a patch for more macros. ]<< -# \\==================================================================// - - -############################################################################### -#============================================================================== -#------------------------------------------------------------------------------ - -!if !exist("makefile.vc") -MSG = ^ -You must run this makefile only from the directory it is in.^ -Please `cd` to its location first. -!error $(MSG) -!endif - -PROJECT = tk -!include "rules.vc" - -!if $(TCLINSTALL) -!message *** Warning: Tk requires the source distribution of Tcl to build from, -!message *** at this time, sorry. Please set the TCLDIR macro to point to the -!message *** Tcl sources. -!endif - -# Extra makefile options processing... -!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"] -HAVE_UXTHEME_H = 1 -TTK_SQUARE_WIDGET = 0 -!else -!if [nmakehlp -f $(OPTS) "noxp"] -!message *** Exclude support for XP theme -HAVE_UXTHEME_H = 0 -!else -HAVE_UXTHEME_H = 1 -!endif -!if [nmakehlp -f "$(OPTS)" "square"] -!message *** Include ttk square demo widget -TTK_SQUARE_WIDGET = 1 -!else -TTK_SQUARE_WIDGET = 0 -!endif -!endif - -STUBPREFIX = $(PROJECT)stub -WISHNAMEPREFIX = wish - -BINROOT = $(MAKEDIR) # originally . -ROOT = $(MAKEDIR)\.. # originally .. - -TK_LIBRARY = $(ROOT)\library - -TKIMPLIB = "$(OUT_DIR)\$(PROJECT)$(TK_VERSION)$(SUFX).lib" -TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT) -TKLIB = "$(OUT_DIR)\$(TKLIBNAME)" - -TKSTUBLIBNAME = $(STUBPREFIX)$(TK_VERSION).lib -TKSTUBLIB = "$(OUT_DIR)\$(TKSTUBLIBNAME)" - -WISH = "$(OUT_DIR)\$(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe" -WISHC = "$(OUT_DIR)\$(WISHNAMEPREFIX)c$(TK_VERSION)$(SUFX).exe" - -TKTEST = "$(OUT_DIR)\$(PROJECT)test.exe" -CAT32 = "$(OUT_DIR)\cat32.exe" - -LIB_INSTALL_DIR = $(_INSTALLDIR)\lib -BIN_INSTALL_DIR = $(_INSTALLDIR)\bin -DOC_INSTALL_DIR = $(_INSTALLDIR)\doc -SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_DOTVERSION) -INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include - -WISHOBJS = \ - $(TMP_DIR)\winMain.obj \ -!if $(TCL_USE_STATIC_PACKAGES) - $(TCLDDELIB) \ - $(TCLREGLIB) \ -!endif - $(TMP_DIR)\wish.res - -TKTESTOBJS = \ - $(TMP_DIR)\testMain.obj \ - $(TMP_DIR)\tkSquare.obj \ - $(TMP_DIR)\tkTest.obj \ - $(TMP_DIR)\tkOldTest.obj \ - $(TMP_DIR)\tkWinTest.obj - -XLIBOBJS = \ - $(TMP_DIR)\xcolors.obj \ - $(TMP_DIR)\xdraw.obj \ - $(TMP_DIR)\xgc.obj \ - $(TMP_DIR)\ximage.obj \ - $(TMP_DIR)\xutil.obj - -TKOBJS = \ - $(TMP_DIR)\tkConsole.obj \ - $(TMP_DIR)\tkUnixMenubu.obj \ - $(TMP_DIR)\tkUnixScale.obj \ - $(XLIBOBJS) \ - $(TMP_DIR)\tkWin3d.obj \ - $(TMP_DIR)\tkWin32Dll.obj \ - $(TMP_DIR)\tkWinButton.obj \ - $(TMP_DIR)\tkWinClipboard.obj \ - $(TMP_DIR)\tkWinColor.obj \ - $(TMP_DIR)\tkWinConfig.obj \ - $(TMP_DIR)\tkWinCursor.obj \ - $(TMP_DIR)\tkWinDialog.obj \ - $(TMP_DIR)\tkWinDraw.obj \ - $(TMP_DIR)\tkWinEmbed.obj \ - $(TMP_DIR)\tkWinFont.obj \ - $(TMP_DIR)\tkWinImage.obj \ - $(TMP_DIR)\tkWinInit.obj \ - $(TMP_DIR)\tkWinKey.obj \ - $(TMP_DIR)\tkWinMenu.obj \ - $(TMP_DIR)\tkWinPixmap.obj \ - $(TMP_DIR)\tkWinPointer.obj \ - $(TMP_DIR)\tkWinRegion.obj \ - $(TMP_DIR)\tkWinScrlbr.obj \ - $(TMP_DIR)\tkWinSend.obj \ - $(TMP_DIR)\tkWinSendCom.obj \ - $(TMP_DIR)\tkWinWindow.obj \ - $(TMP_DIR)\tkWinWm.obj \ - $(TMP_DIR)\tkWinX.obj \ - $(TMP_DIR)\stubs.obj \ - $(TMP_DIR)\tk3d.obj \ - $(TMP_DIR)\tkArgv.obj \ - $(TMP_DIR)\tkAtom.obj \ - $(TMP_DIR)\tkBind.obj \ - $(TMP_DIR)\tkBitmap.obj \ - $(TMP_DIR)\tkBusy.obj \ - $(TMP_DIR)\tkButton.obj \ - $(TMP_DIR)\tkCanvArc.obj \ - $(TMP_DIR)\tkCanvBmap.obj \ - $(TMP_DIR)\tkCanvImg.obj \ - $(TMP_DIR)\tkCanvLine.obj \ - $(TMP_DIR)\tkCanvPoly.obj \ - $(TMP_DIR)\tkCanvPs.obj \ - $(TMP_DIR)\tkCanvText.obj \ - $(TMP_DIR)\tkCanvUtil.obj \ - $(TMP_DIR)\tkCanvWind.obj \ - $(TMP_DIR)\tkCanvas.obj \ - $(TMP_DIR)\tkClipboard.obj \ - $(TMP_DIR)\tkCmds.obj \ - $(TMP_DIR)\tkColor.obj \ - $(TMP_DIR)\tkConfig.obj \ - $(TMP_DIR)\tkCursor.obj \ - $(TMP_DIR)\tkEntry.obj \ - $(TMP_DIR)\tkError.obj \ - $(TMP_DIR)\tkEvent.obj \ - $(TMP_DIR)\tkFileFilter.obj \ - $(TMP_DIR)\tkFocus.obj \ - $(TMP_DIR)\tkFont.obj \ - $(TMP_DIR)\tkFrame.obj \ - $(TMP_DIR)\tkGC.obj \ - $(TMP_DIR)\tkGeometry.obj \ - $(TMP_DIR)\tkGet.obj \ - $(TMP_DIR)\tkGrab.obj \ - $(TMP_DIR)\tkGrid.obj \ - $(TMP_DIR)\tkImage.obj \ - $(TMP_DIR)\tkImgBmap.obj \ - $(TMP_DIR)\tkImgGIF.obj \ - $(TMP_DIR)\tkImgPNG.obj \ - $(TMP_DIR)\tkImgPPM.obj \ - $(TMP_DIR)\tkImgPhoto.obj \ - $(TMP_DIR)\tkImgPhInstance.obj \ - $(TMP_DIR)\tkImgUtil.obj \ - $(TMP_DIR)\tkListbox.obj \ - $(TMP_DIR)\tkMacWinMenu.obj \ - $(TMP_DIR)\tkMain.obj \ - $(TMP_DIR)\tkMain2.obj \ - $(TMP_DIR)\tkMenu.obj \ - $(TMP_DIR)\tkMenubutton.obj \ - $(TMP_DIR)\tkMenuDraw.obj \ - $(TMP_DIR)\tkMessage.obj \ - $(TMP_DIR)\tkPanedWindow.obj \ - $(TMP_DIR)\tkObj.obj \ - $(TMP_DIR)\tkOldConfig.obj \ - $(TMP_DIR)\tkOption.obj \ - $(TMP_DIR)\tkPack.obj \ - $(TMP_DIR)\tkPlace.obj \ - $(TMP_DIR)\tkPointer.obj \ - $(TMP_DIR)\tkRectOval.obj \ - $(TMP_DIR)\tkScale.obj \ - $(TMP_DIR)\tkScrollbar.obj \ - $(TMP_DIR)\tkSelect.obj \ - $(TMP_DIR)\tkStyle.obj \ - $(TMP_DIR)\tkText.obj \ - $(TMP_DIR)\tkTextBTree.obj \ - $(TMP_DIR)\tkTextDisp.obj \ - $(TMP_DIR)\tkTextImage.obj \ - $(TMP_DIR)\tkTextIndex.obj \ - $(TMP_DIR)\tkTextMark.obj \ - $(TMP_DIR)\tkTextTag.obj \ - $(TMP_DIR)\tkTextWind.obj \ - $(TMP_DIR)\tkTrig.obj \ - $(TMP_DIR)\tkUndo.obj \ - $(TMP_DIR)\tkUtil.obj \ - $(TMP_DIR)\tkVisual.obj \ - $(TMP_DIR)\tkStubInit.obj \ - $(TMP_DIR)\tkWindow.obj \ - $(TTK_OBJS) \ -!if !$(STATIC_BUILD) - $(TMP_DIR)\tk.res -!endif - -TTK_OBJS = \ - $(TMP_DIR)\ttkWinMonitor.obj \ - $(TMP_DIR)\ttkWinTheme.obj \ - $(TMP_DIR)\ttkWinXPTheme.obj \ - $(TMP_DIR)\ttkBlink.obj \ - $(TMP_DIR)\ttkButton.obj \ - $(TMP_DIR)\ttkCache.obj \ - $(TMP_DIR)\ttkClamTheme.obj \ - $(TMP_DIR)\ttkClassicTheme.obj \ - $(TMP_DIR)\ttkDefaultTheme.obj \ - $(TMP_DIR)\ttkElements.obj \ - $(TMP_DIR)\ttkEntry.obj \ - $(TMP_DIR)\ttkFrame.obj \ - $(TMP_DIR)\ttkImage.obj \ - $(TMP_DIR)\ttkInit.obj \ - $(TMP_DIR)\ttkLabel.obj \ - $(TMP_DIR)\ttkLayout.obj \ - $(TMP_DIR)\ttkManager.obj \ - $(TMP_DIR)\ttkNotebook.obj \ - $(TMP_DIR)\ttkPanedwindow.obj \ - $(TMP_DIR)\ttkProgress.obj \ - $(TMP_DIR)\ttkScale.obj \ - $(TMP_DIR)\ttkScrollbar.obj \ - $(TMP_DIR)\ttkScroll.obj \ - $(TMP_DIR)\ttkSeparator.obj \ - $(TMP_DIR)\ttkSquare.obj \ - $(TMP_DIR)\ttkState.obj \ - $(TMP_DIR)\ttkTagSet.obj \ - $(TMP_DIR)\ttkTheme.obj \ - $(TMP_DIR)\ttkTrace.obj \ - $(TMP_DIR)\ttkTrack.obj \ - $(TMP_DIR)\ttkTreeview.obj \ - $(TMP_DIR)\ttkWidget.obj \ - $(TMP_DIR)\ttkStubInit.obj - -TKSTUBOBJS = \ - $(TMP_DIR)\tkStubLib.obj \ - $(TMP_DIR)\ttkStubLib.obj - - -WINDIR = $(ROOT)\win -GENERICDIR = $(ROOT)\generic -XLIBDIR = $(ROOT)\xlib -TTKDIR = $(ROOT)\generic\ttk -BITMAPDIR = $(ROOT)\bitmaps -DOCDIR = $(ROOT)\doc -RCDIR = $(WINDIR)\rc - -TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(BITMAPDIR)" -I"$(XLIBDIR)" \ - $(TCL_INCLUDES) - -CONFIG_DEFS =-DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 \ - -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 \ - -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 \ - -DSUPPORT_CONFIG_EMBEDDED \ -!if $(HAVE_UXTHEME_H) - -DHAVE_UXTHEME_H=1 \ -!endif -!if $(TTK_SQUARE_WIDGET) - -DTTK_SQUARE_WIDGET=1 \ -!endif - -TK_DEFINES =-DBUILD_ttk $(OPTDEFINES) $(CONFIG_DEFS) -Dinline=__inline - -#--------------------------------------------------------------------- -# Compile flags -#--------------------------------------------------------------------- - -!if !$(DEBUG) -!if $(OPTIMIZING) -### This cranks the optimization level to maximize speed -### We can't use -O2 because sometimes it causes problems. -cdebug = $(OPTIMIZATIONS) -!else -cdebug = -!endif -!if $(SYMBOLS) -cdebug = $(cdebug) -Zi -!endif -!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" -### Warnings are too many, can't support warnings into errors. -cdebug = -Zi -Od $(DEBUGFLAGS) -!else -cdebug = -Zi -WX $(DEBUGFLAGS) -!endif - -### Declarations common to all compiler options -cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE -cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\ - -!if $(MSVCRT) -!if $(DEBUG) && !$(UNCHECKED) -crt = -MDd -!else -crt = -MD -!endif -!else -!if $(DEBUG) && !$(UNCHECKED) -crt = -MTd -!else -crt = -MT -!endif -!endif - -BASE_CFLAGS = $(cdebug) $(cflags) $(crt) $(TK_INCLUDES) -TK_CFLAGS = $(BASE_CFLAGS) $(TK_DEFINES) -DUSE_TCL_STUBS -CON_CFLAGS = $(cdebug) $(cflags) $(crt) -DCONSOLE -WISH_CFLAGS = $(BASE_CFLAGS) $(TK_DEFINES) -STUB_CFLAGS = $(cflags) $(cdebug) $(TK_DEFINES) - -#--------------------------------------------------------------------- -# Link flags -#--------------------------------------------------------------------- - -!if $(DEBUG) -ldebug = -debug -debugtype:cv -!else -ldebug = -release -opt:ref -opt:icf,3 -!if $(SYMBOLS) -ldebug = $(ldebug) -debug -debugtype:cv -!endif -!endif - -### Declarations common to all linker options -lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug) - -!if $(PROFILE) -lflags = $(lflags) -profile -!endif - -!if $(ALIGN98_HACK) && !$(STATIC_BUILD) -### Align sections for PE size savings. -lflags = $(lflags) -opt:nowin98 -!else if !$(ALIGN98_HACK) && $(STATIC_BUILD) -### Align sections for speed in loading by choosing the virtual page size. -lflags = $(lflags) -align:4096 -!endif - -!if $(LOIMPACT) -lflags = $(lflags) -ws:aggressive -!endif - -dlllflags = $(lflags) -dll -conlflags = $(lflags) -subsystem:console -guilflags = $(lflags) -subsystem:windows - -tcllibs = $(TCLSTUBLIB) $(TCLIMPLIB) - -baselibs = netapi32.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib -# Avoid 'unresolved external symbol __security_cookie' errors. -# c.f. http://support.microsoft.com/?id=894573 -!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" -!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500 -baselibs = $(baselibs) bufferoverflowU.lib -!endif -!endif -guilibs = $(baselibs) gdi32.lib - - -#--------------------------------------------------------------------- -# TkTest flags -#--------------------------------------------------------------------- - -!if "$(TESTPAT)" != "" -TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT) -!endif - - -#--------------------------------------------------------------------- -# Project specific targets -#--------------------------------------------------------------------- - -release: setup $(TKSTUBLIB) $(WISH) -all: release $(CAT32) -core: setup $(TKSTUBLIB) $(TKLIB) -cwish: $(WISHC) -install: install-binaries install-libraries install-docs -tktest: setup $(TKTEST) $(CAT32) - - -test: test-classic test-ttk - -test-classic: setup $(TKTEST) $(TKLIB) $(CAT32) - @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) - @set TK_LIBRARY=$(TK_LIBRARY:\=/) - @set TCLLIBPATH= -!if $(TCLINSTALL) - @set PATH=$(_TCLDIR)\bin;$(PATH) -!else - @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) -!endif - $(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) | $(CAT32) - -test-ttk: setup $(TKTEST) $(TKLIB) $(CAT32) - @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) - @set TK_LIBRARY=$(TK_LIBRARY:\=/) - @set TCLLIBPATH= -!if $(TCLINSTALL) - @set PATH=$(_TCLDIR)\bin;$(PATH) -!else - @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) -!endif - $(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32) - -runtest: setup $(TKTEST) $(TKLIB) $(CAT32) - @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) - @set TK_LIBRARY=$(TK_LIBRARY:\=/) - @set TCLLIBPATH= -!if $(TCLINSTALL) - @set PATH=$(_TCLDIR)\bin;$(PATH) -!else - @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) -!endif - $(DEBUGGER) $(TKTEST) - -rundemo: setup $(TKTEST) $(TKLIB) $(CAT32) - @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) - @set TK_LIBRARY=$(TK_LIBRARY:\=/) - @set TCLLIBPATH= -!if $(TCLINSTALL) - @set PATH=$(_TCLDIR)\bin;$(PATH) -!else - @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) -!endif - $(TKTEST) $(ROOT:\=/)\library\demos\widget - -shell: setup $(WISH) - @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) - @set TK_LIBRARY=$(TK_LIBRARY:\=/) - @set TCLLIBPATH= -!if $(TCLINSTALL) - @set PATH=$(_TCLDIR)\bin;$(PATH) -!else - @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) -!endif - $(DEBUGGER) $(WISH) << - console show -<< - -dbgshell: setup $(WISH) - @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) - @set TK_LIBRARY=$(TK_LIBRARY:\=/) - @set TCLLIBPATH= -!if $(TCLINSTALL) - @set PATH=$(_TCLDIR)\bin;$(PATH) -!else - @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) -!endif - windbg $(WISH) - -setup: - @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) - @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) - -!if !$(STATIC_BUILD) -$(TKIMPLIB): $(TKLIB) -!endif - -$(TKLIB): $(TKOBJS) -!if $(STATIC_BUILD) - $(lib32) -nologo -out:$@ @<< -$** -<< -!else - $(link32) $(dlllflags) -base:@$(COFFBASE),tk -out:$@ $(guilibs) \ - $(TCLSTUBLIB) @<< -$** -<< - $(_VC_MANIFEST_EMBED_DLL) - -@del $*.exp -!endif - - -$(TKSTUBLIB): $(TKSTUBOBJS) - $(lib32) -nologo -nodefaultlib -out:$@ $** - - -$(WISH): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB) - $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(tcllibs) $** - $(_VC_MANIFEST_EMBED_EXE) - - -$(WISHC): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB) - $(link32) $(conlflags) -stack:2300000 -out:$@ $(guilibs) $(tcllibs) $** - $(_VC_MANIFEST_EMBED_EXE) - - -$(TKTEST): $(TKTESTOBJS) $(TKSTUBLIB) $(TKIMPLIB) - $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(tcllibs) $** - $(_VC_MANIFEST_EMBED_EXE) - - -$(CAT32): $(_TCLDIR)\win\cat.c - $(cc32) $(CON_CFLAGS) -Fo$(TMP_DIR)\ $? - $(link32) $(conlflags) -out:$@ -stack:16384 $(TMP_DIR)\cat.obj $(baselibs) - $(_VC_MANIFEST_EMBED_EXE) - -#--------------------------------------------------------------------- -# Regenerate the stubs files. [Development use only] -#--------------------------------------------------------------------- - -genstubs: -!if !exist($(TCLSH)) - @echo Build tclsh first! -!else - set TCL_LIBRARY=$(TCL_LIBRARY) - $(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \ - $(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls -!endif - - -#--------------------------------------------------------------------- -# Build the Windows HTML help file. -#--------------------------------------------------------------------- - -# NOTE: you can define HHC on the command-line to override this -!ifndef HHC -HHC=""%ProgramFiles%\HTML Help Workshop\hhc.exe"" -!endif -HTMLDIR=$(ROOT)\html -HTMLBASE=TclTk$(VERSION) -HHPFILE=$(HTMLDIR)\$(HTMLBASE).hhp -CHMFILE=$(HTMLDIR)\$(HTMLBASE).chm - -htmlhelp: chmsetup $(CHMFILE) - -$(CHMFILE): $(DOCDIR)\* - @$(TCLSH) $(TCLTOOLSDIR)\tcltk-man2html.tcl - @echo Compiling HTML help project - @$(HHC) <<$(HHPFILE) >NUL -[OPTIONS] -Compatibility=1.1 or later -Compiled file=$(HTMLBASE).chm -Display compile progress=no -Error log file=$(HTMLBASE).log -Language=0x409 English (United States) -Title=Tcl/Tk $(DOT_VERSION) Help -[FILES] -contents.htm -docs.css -Keywords -TclCmd -TclLib -TkCmd -TkLib -UserCmd -<< - -chmsetup: - @if not exist $(HTMLDIR)\nul mkdir $(HTMLDIR) - -#------------------------------------------------------------------------- -# Build the old-style Windows .hlp file -#------------------------------------------------------------------------- - -HLPBASE = $(PROJECT)$(TK_VERSION) -HELPFILE = $(OUT_DIR)\$(HLPBASE).hlp -HELPCNT = $(OUT_DIR)\$(HLPBASE).cnt -DOCTMP_DIR = $(OUT_DIR)\$(PROJECT)_docs -HELPRTF = $(DOCTMP_DIR)\$(PROJECT).rtf -MAN2HELP = $(DOCTMP_DIR)\man2help.tcl -MAN2HELP2 = $(DOCTMP_DIR)\man2help2.tcl -INDEX = $(DOCTMP_DIR)\index.tcl -BMP = $(DOCTMP_DIR)\lamp.bmp -BMP_NOPATH = lamp.bmp -MAN2TCL = $(DOCTMP_DIR)\man2tcl.exe - -winhelp: docsetup $(HELPFILE) - -docsetup: - @if not exist $(DOCTMP_DIR)\nul mkdir $(DOCTMP_DIR) - -$(MAN2HELP) $(MAN2HELP2) $(INDEX): $(TCLTOOLSDIR)\$$(@F) - $(CPY) $(TCLTOOLSDIR)\$(@F) $(@D) - -$(BMP): - $(CPY) $(WINDIR)\rc\$(@F) $(@D) - -$(HELPFILE): $(HELPRTF) $(BMP) - cd $(DOCTMP_DIR) - start /wait hcrtf.exe -x <<$(PROJECT).hpj -[OPTIONS] -COMPRESS=12 Hall Zeck -LCID=0x409 0x0 0x0 ; English (United States) -TITLE=Tk Reference Manual -BMROOT=. -CNT=$(@B).cnt -HLP=$(@B).hlp - -[FILES] -$(PROJECT).rtf - -[WINDOWS] -main="Tcl/Tk Reference Manual",,27648,(r15263976),(r4227327) - -[CONFIG] -BrowseButtons() -CreateButton(1, "Web", ExecFile("http://www.tcl.tk")) -CreateButton(2, "SF", ExecFile("http://sf.net/projects/tcl")) -CreateButton(3, "Wiki", ExecFile("http://wiki.tcl.tk")) -CreateButton(4, "FAQ", ExecFile("http://www.purl.org/NET/Tcl-FAQ/")) -<< - cd $(MAKEDIR) - @$(CPY) "$(DOCTMP_DIR)\$(@B).hlp" "$(OUT_DIR)" - @$(CPY) "$(DOCTMP_DIR)\$(@B).cnt" "$(OUT_DIR)" - -$(MAN2TCL): $(TCLTOOLSDIR)\$$(@B).c - $(cc32) $(TK_CFLAGS) -Fo$(@D)\ $(TCLTOOLSDIR)\$(@B).c - $(link32) $(conlflags) -out:$@ -stack:16384 $(@D)\man2tcl.obj - $(_VC_MANIFEST_EMBED_EXE) - -$(HELPRTF): $(MAN2TCL) $(MAN2HELP) $(MAN2HELP2) $(INDEX) - $(TCLSH) $(MAN2HELP) -bitmap $(BMP_NOPATH) $(PROJECT) $(TK_VERSION) $(DOCDIR:\=/) - -install-docs: -!if exist($(HELPFILE)) - $(CPY) "$(HELPFILE)" "$(DOC_INSTALL_DIR)\" - $(CPY) "$(HELPCNT)" "$(DOC_INSTALL_DIR)\" - $(TCLSH) << -puts "Installing $(PROJECT)'s helpfile contents into Tcl's ..." -set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(TK_VERSION).cnt" r] -while {![eof $$f]} { - if {[regexp {:Include $(PROJECT)([0-9]{2}).cnt} [gets $$f] dummy ver]} { - if {$$ver == $(TK_VERSION)} { - puts "Already installed." - exit - } else { - # do something here logical to remove (or replace) it. - puts "$$ver != $(TK_VERSION), unfinished code path, die, die!" - exit 1 - } - } -} -close $$f -set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(TK_VERSION).cnt" a] -puts $$f {:Include $(HLPBASE).cnt} -close $$f -<< - start /wait winhlp32 -g $(DOC_INSTALL_DIR)\tcl$(TK_VERSION).hlp -!endif - -#--------------------------------------------------------------------- -# Special case object file targets -#--------------------------------------------------------------------- - -$(TMP_DIR)\testMain.obj: $(WINDIR)\winMain.c - $(cc32) $(WISH_CFLAGS) -DTK_TEST \ - -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ - -Fo$@ $? - -$(TMP_DIR)\tkTest.obj: $(GENERICDIR)\tkTest.c - $(cc32) $(WISH_CFLAGS) -Fo$@ $? - -$(TMP_DIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c - $(cc32) $(WISH_CFLAGS) -Fo$@ $? - -$(TMP_DIR)\tkWinTest.obj: $(WINDIR)\tkWinTest.c - $(cc32) $(WISH_CFLAGS) -Fo$@ $? - -$(TMP_DIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c - $(cc32) $(WISH_CFLAGS) -Fo$@ $? - -$(TMP_DIR)\winMain.obj: $(WINDIR)\winMain.c - $(cc32) $(WISH_CFLAGS) \ - -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ - -Fo$@ $? - -$(TMP_DIR)\tkMain2.obj: $(GENERICDIR)\tkMain.c - $(cc32) -DBUILD_tk $(TK_CFLAGS) -DTK_ASCII_MAIN -Fo$@ $? - -# The following objects are part of the stub library and should not -# be built as DLL objects but none of the symbols should be exported -# and no reference made to a C runtime. - -$(TMP_DIR)\tkStubLib.obj : $(GENERICDIR)\tkStubLib.c - $(cc32) $(STUB_CFLAGS) $(TK_INCLUDES) -Zl -DSTATIC_BUILD -Fo$@ $? - - -$(TMP_DIR)\wish.exe.manifest: $(WINDIR)\wish.exe.manifest.in - @nmakehlp -s << $** >$@ -@MACHINE@ $(MACHINE:IX86=X86) -@TK_WIN_VERSION@ $(TK_DOTVERSION).0.0 -<< - -#--------------------------------------------------------------------- -# Generate the source dependencies. Having dependency rules will -# improve incremental build accuracy without having to resort to a -# full rebuild just because some non-global header file like -# tclCompile.h was changed. These rules aren't needed when building -# from scratch. -#--------------------------------------------------------------------- - -depend: -!if !exist($(TCLSH)) - @echo Build tclsh first! -!else - set TCL_LIBRARY=$(TCL_LIBRARY) - $(TCLSH) $(TCLTOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \ - -passthru:"-DBUILD_tk $(TK_INCLUDES)" $(GENERICDIR),$$(GENERICDIR) \ - $(WINDIR),$$(WINDIR) $(TTKDIR),$$(TTKDIR) $(XLIBDIR),$$(XLIBDIR) \ - $(BITMAPDIR),$$(BITMAPDIR) @<< -$(TKOBJS) -<< -!endif - -#--------------------------------------------------------------------- -# Dependency rules -#--------------------------------------------------------------------- - -$(TMP_DIR)\tk.res: \ - $(RCDIR)\buttons.bmp \ - $(RCDIR)\cursor*.cur \ - $(RCDIR)\tk.ico - -!if exist("$(OUT_DIR)\depend.mk") -!include "$(OUT_DIR)\depend.mk" -!message *** Dependency rules in use. -!else -!message *** Dependency rules are not being used. -!endif - -### add a spacer in the output -!message - -#--------------------------------------------------------------------- -# Implicit rules -#--------------------------------------------------------------------- - -{$(XLIBDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(GENERICDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(TTKDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(WINDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(ROOT)\unix}.c{$(TMP_DIR)}.obj:: - $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(RCDIR)}.rc{$(TMP_DIR)}.res: - $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" $(TCL_INCLUDES) \ - -d DEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \ - -d TCL_THREADS=$(TCL_THREADS) \ - -d STATIC_BUILD=$(STATIC_BUILD) \ - $< - -$(TMP_DIR)\tk.res: $(TMP_DIR)\wish.exe.manifest -$(TMP_DIR)\wish.res: $(TMP_DIR)\wish.exe.manifest - -.SUFFIXES: -.SUFFIXES:.c .rc - - -#--------------------------------------------------------------------- -# Installation. -#--------------------------------------------------------------------- - -install-binaries: - @echo installing binaries - @$(CPY) "$(WISH)" "$(BIN_INSTALL_DIR)\" -!if $(TKLIB) != $(TKIMPLIB) - @$(CPY) "$(TKLIB)" "$(BIN_INSTALL_DIR)\" -!endif - @$(CPY) "$(TKIMPLIB)" "$(LIB_INSTALL_DIR)\" - @$(CPY) "$(TKSTUBLIB)" "$(LIB_INSTALL_DIR)\" -!if !$(STATIC_BUILD) - @echo creating package index - @type << > $(OUT_DIR)\pkgIndex.tcl -if {[catch {package present Tcl $(TCL_PATCH_LEVEL)}]} { return } -if {($$::tcl_platform(platform) eq "unix") && ([info exists ::env(DISPLAY)] - || ([info exists ::argv] && ("-display" in $$::argv)))} { - package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin libtk$(TK_DOTVERSION).dll] Tk] -} else { - package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin $(TKLIBNAME)] Tk] -} -<< - @$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)\" -!endif - -#" - -install-libraries: - @echo installing Tk headers - @$(CPY) "$(GENERICDIR)\tk.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tkDecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tkPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(XLIBDIR)\X11\*.h" "$(INCLUDE_INSTALL_DIR)\X11\" - @echo installing script library - @$(CPY) "$(ROOT)\library\*" "$(SCRIPT_INSTALL_DIR)\" - @echo installing theme library - @$(CPY) "$(ROOT)\library\ttk\*" "$(SCRIPT_INSTALL_DIR)\ttk\" - @echo installing demos - @$(CPY) "$(ROOT)\library\demos\*" "$(SCRIPT_INSTALL_DIR)\demos\" - @$(CPY) "$(ROOT)\library\demos\images\*" "$(SCRIPT_INSTALL_DIR)\demos\images\" - @echo installing images - @$(CPY) "$(ROOT)\library\images\*" "$(SCRIPT_INSTALL_DIR)\images\" - @echo installing language files - @$(CPY) "$(ROOT)\library\msgs\*" "$(SCRIPT_INSTALL_DIR)\msgs\" - -#" - -#--------------------------------------------------------------------- -# Clean up -#--------------------------------------------------------------------- - -tidy: -!if $(TKLIB) != $(TKIMPLIB) - @echo Removing $(TKLIB) ... - @if exist $(TKLIB) del $(TKLIB) -!endif - @echo Removing $(TKIMPLIB) ... - @if exist $(TKIMPLIB) del $(TKIMPLIB) - @echo Removing $(WISH) ... - @if exist $(WISH) del $(WISH) - @echo Removing $(TKTEST) ... - @if exist $(TKTEST) del $(TKTEST) - @echo Removing $(TKSTUBLIB) ... - @if exist $(TKSTUBLIB) del $(TKSTUBLIB) - -clean: - @echo Cleaning $(TMP_DIR)\* ... - @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR) - @echo Cleaning $(WINDIR)\nmakehlp.obj ... - @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj - @echo Cleaning $(WINDIR)\nmakehlp.exe ... - @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe - @echo Cleaning $(WINDIR)\_junk.pch ... - @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch - @echo Cleaning $(WINDIR)\vercl.x ... - @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x - @echo Cleaning $(WINDIR)\vercl.i ... - @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i - @echo Cleaning $(WINDIR)\versions.vc ... - @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc - -realclean: hose - -hose: - @echo Hosing $(OUT_DIR)\* ... - @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR) +#------------------------------------------------------------- -*- makefile -*-
+# makefile.vc --
+#
+# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+# Copyright (c) 2001-2005 ActiveState Corporation.
+# Copyright (c) 2001-2004 David Gravereaux.
+# Copyright (c) 2003-2008 Pat Thoyts.
+#------------------------------------------------------------------------------
+
+# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
+# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
+MSG = ^
+You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
+Platform SDK first to setup the environment. Jump to this line to read^
+the build instructions.
+!error $(MSG)
+!endif
+
+#------------------------------------------------------------------------------
+# HOW TO USE this makefile:
+#
+# 1) It is now necessary to have MSVCDir, MSDevDir or MSSDK set in the
+# environment. This is used as a check to see if vcvars32.bat had been
+# run prior to running nmake or during the installation of Microsoft
+# Visual C++, MSVCDir had been set globally and the PATH adjusted.
+# Either way is valid.
+#
+# You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
+# directory to setup the proper environment, if needed, for your
+# current setup. This is a needed bootstrap requirement and allows the
+# swapping of different environments to be easier.
+#
+# 2) To use the Platform SDK (not expressly needed), run setenv.bat after
+# vcvars32.bat according to the instructions for it. This can also
+# turn on the 64-bit compiler, if your SDK has it.
+#
+# 3) Targets are:
+# release -- Builds the core, the shell and the dlls. (default)
+# dlls -- Just builds the windows extensions.
+# shell -- Just builds the shell and the core.
+# core -- Only builds the core [tkXX.(dll|lib)].
+# all -- Builds everything.
+# test -- Builds and runs the test suite.
+# tktest -- Just builds the binaries for the test suite.
+# install -- Installs the built binaries and libraries to $(INSTALLDIR)
+# as the root of the install tree.
+# cwish -- Builds a console version of wish.
+# tidy/clean/hose -- varying levels of cleaning.
+# genstubs -- Rebuilds the Stubs table and support files (dev only).
+# depend -- Generates an accurate set of source dependancies for this
+# makefile. Helpful to avoid problems when the sources are
+# refreshed and you rebuild, but can "overbuild" when common
+# headers like tkInt.h just get small changes.
+# htmlhelp -- Builds a Windows .chm help file for Tcl and Tk from the
+# troff manual pages found in $(ROOT)\doc. You need to
+# have installed the HTML Help Compiler package from Microsoft
+# to produce the .chm file.
+# winhelp -- Builds the windows .hlp file for Tcl from the troff man
+# files found in $(ROOT)\doc.
+#
+# 4) Macros usable on the commandline:
+# TCLDIR=<path>
+# Sets the location for where to find the Tcl headers and
+# libraries. The install point is assumed when not specified.
+# Tk does need the source directory, though. Tk comes very close
+# to not needing the sources, but does, in fact, require them.
+#
+# INSTALLDIR=<path>
+# Sets where to install Tcl from the built binaries.
+# C:\Progra~1\Tcl is assumed when not specified.
+#
+# OPTS=loimpact,msvcrt,nothreads,noxp,pdbs,profile,square,static,staticpkg,symbols,unchecked,none
+# Sets special options for the core. The default is for none.
+# Any combination of the above may be used (comma separated).
+# 'none' will over-ride everything to nothing.
+#
+# loimpact = Adds a flag for how NT treats the heap to keep memory
+# in use, low. This is said to impact alloc performance.
+# msvcrt = Affects the static option only to switch it from
+# using libcmt(d) as the C runtime [by default] to
+# msvcrt(d). This is useful for static embedding
+# support.
+# nothreads= Turns off full multithreading support.
+# noxp = If you do not have the uxtheme.h header then you
+# cannot include support for XP themeing.
+# square = Include the demo square widget.
+# static = Builds a static library of the core instead of a
+# dll. The shell will be static (and large), as well.
+# staticpkg= Affects the static option only to switch wishXX.exe
+# to have the dde and reg extension linked inside it.
+# pdbs = Build detached symbols for release builds.
+# profile = Adds profiling hooks. Map file is assumed.
+# thrdalloc = Use the thread allocator (shared global free pool)
+# This is the default on threaded builds.
+# tclalloc = Use the old non-thread allocator
+# symbols = Debug build. Links to the debug C runtime, disables
+# optimizations and creates pdb symbols files.
+# unchecked = Allows a symbols build to not use the debug
+# enabled runtime (msvcrt.dll not msvcrtd.dll
+# or libcmt.lib not libcmtd.lib).
+#
+# STATS=compdbg,memdbg,none
+# Sets optional memory and bytecode compiler debugging code added
+# to the core. The default is for none. Any combination of the
+# above may be used (comma separated). 'none' will over-ride
+# everything to nothing.
+#
+# compdbg = Enables byte compilation logging.
+# memdbg = Enables the debugging memory allocator.
+#
+# CHECKS=64bit,fullwarn,nodep,none
+# Sets special macros for checking compatability.
+#
+# 64bit = Enable 64bit portability warnings (if available)
+# fullwarn = Builds with full compiler and link warnings enabled.
+# Very verbose.
+# nodep = Turns off compatability macros to ensure the core
+# isn't being built with deprecated functions.
+#
+# MACHINE=(ALPHA|AMD64|IA64|IX86)
+# Set the machine type used for the compiler, linker, and
+# resource compiler. This hook is needed to tell the tools
+# when alternate platforms are requested. IX86 is the default
+# when not specified. If the CPU environment variable has been
+# set (ie: recent Platform SDK) then MACHINE is set from CPU.
+#
+# TMP_DIR=<path>
+# OUT_DIR=<path>
+# Hooks to allow the intermediate and output directories to be
+# changed. $(OUT_DIR) is assumed to be
+# $(BINROOT)\(Release|Debug) based on if symbols are requested.
+# $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
+#
+# TESTPAT=<file>
+# Reads the tests requested to be run from this file.
+#
+# 5) Examples:
+#
+# Basic syntax of calling nmake looks like this:
+# nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
+#
+# Standard (no frills)
+# c:\tk_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+# Setting environment for using Microsoft Visual C++ tools.
+# c:\tk_src\win\>nmake -f makefile.vc release
+# c:\tk_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
+#
+# Building for Win64
+# c:\tk_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+# Setting environment for using Microsoft Visual C++ tools.
+# c:\tk_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
+# Targeting Windows pre64 RETAIL
+# c:\tk_src\win\>nmake -f makefile.vc MACHINE=IA64
+#
+#------------------------------------------------------------------------------
+#==============================================================================
+###############################################################################
+
+
+# //==================================================================\\
+# >>[ -> Do not modify below this line. <- ]<<
+# >>[ Please, use the commandline macros to modify how Tcl is built. ]<<
+# >>[ If you need more features, send us a patch for more macros. ]<<
+# \\==================================================================//
+
+
+###############################################################################
+#==============================================================================
+#------------------------------------------------------------------------------
+
+!if !exist("makefile.vc")
+MSG = ^
+You must run this makefile only from the directory it is in.^
+Please `cd` to its location first.
+!error $(MSG)
+!endif
+
+PROJECT = tk
+!include "rules.vc"
+
+!if $(TCLINSTALL)
+!message *** Warning: Tk requires the source distribution of Tcl to build from,
+!message *** at this time, sorry. Please set the TCLDIR macro to point to the
+!message *** Tcl sources.
+!endif
+
+# Extra makefile options processing...
+!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
+HAVE_UXTHEME_H = 1
+TTK_SQUARE_WIDGET = 0
+!else
+!if [nmakehlp -f $(OPTS) "noxp"]
+!message *** Exclude support for XP theme
+HAVE_UXTHEME_H = 0
+!else
+HAVE_UXTHEME_H = 1
+!endif
+!if [nmakehlp -f "$(OPTS)" "square"]
+!message *** Include ttk square demo widget
+TTK_SQUARE_WIDGET = 1
+!else
+TTK_SQUARE_WIDGET = 0
+!endif
+!endif
+
+STUBPREFIX = $(PROJECT)stub
+WISHNAMEPREFIX = wish
+
+BINROOT = $(MAKEDIR) # originally .
+ROOT = $(MAKEDIR)\.. # originally ..
+
+TK_LIBRARY = $(ROOT)\library
+
+TKIMPLIB = "$(OUT_DIR)\$(PROJECT)$(TK_VERSION)$(SUFX).lib"
+TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
+TKLIB = "$(OUT_DIR)\$(TKLIBNAME)"
+
+TKSTUBLIBNAME = $(STUBPREFIX)$(TK_VERSION).lib
+TKSTUBLIB = "$(OUT_DIR)\$(TKSTUBLIBNAME)"
+
+WISH = "$(OUT_DIR)\$(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe"
+WISHC = "$(OUT_DIR)\$(WISHNAMEPREFIX)c$(TK_VERSION)$(SUFX).exe"
+
+TKTEST = "$(OUT_DIR)\$(PROJECT)test.exe"
+CAT32 = "$(OUT_DIR)\cat32.exe"
+
+LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
+BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
+DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_DOTVERSION)
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
+
+WISHOBJS = \
+ $(TMP_DIR)\winMain.obj \
+!if $(TCL_USE_STATIC_PACKAGES)
+ $(TCLDDELIB) \
+ $(TCLREGLIB) \
+!endif
+ $(TMP_DIR)\wish.res
+
+TKTESTOBJS = \
+ $(TMP_DIR)\testMain.obj \
+ $(TMP_DIR)\tkSquare.obj \
+ $(TMP_DIR)\tkTest.obj \
+ $(TMP_DIR)\tkOldTest.obj \
+ $(TMP_DIR)\tkWinTest.obj
+
+XLIBOBJS = \
+ $(TMP_DIR)\xcolors.obj \
+ $(TMP_DIR)\xdraw.obj \
+ $(TMP_DIR)\xgc.obj \
+ $(TMP_DIR)\ximage.obj \
+ $(TMP_DIR)\xutil.obj
+
+TKOBJS = \
+ $(TMP_DIR)\tkConsole.obj \
+ $(TMP_DIR)\tkUnixMenubu.obj \
+ $(TMP_DIR)\tkUnixScale.obj \
+ $(XLIBOBJS) \
+ $(TMP_DIR)\tkWin3d.obj \
+ $(TMP_DIR)\tkWin32Dll.obj \
+ $(TMP_DIR)\tkWinButton.obj \
+ $(TMP_DIR)\tkWinClipboard.obj \
+ $(TMP_DIR)\tkWinColor.obj \
+ $(TMP_DIR)\tkWinConfig.obj \
+ $(TMP_DIR)\tkWinCursor.obj \
+ $(TMP_DIR)\tkWinDialog.obj \
+ $(TMP_DIR)\tkWinDraw.obj \
+ $(TMP_DIR)\tkWinEmbed.obj \
+ $(TMP_DIR)\tkWinFont.obj \
+ $(TMP_DIR)\tkWinImage.obj \
+ $(TMP_DIR)\tkWinInit.obj \
+ $(TMP_DIR)\tkWinKey.obj \
+ $(TMP_DIR)\tkWinMenu.obj \
+ $(TMP_DIR)\tkWinPixmap.obj \
+ $(TMP_DIR)\tkWinPointer.obj \
+ $(TMP_DIR)\tkWinRegion.obj \
+ $(TMP_DIR)\tkWinScrlbr.obj \
+ $(TMP_DIR)\tkWinSend.obj \
+ $(TMP_DIR)\tkWinSendCom.obj \
+ $(TMP_DIR)\tkWinWindow.obj \
+ $(TMP_DIR)\tkWinWm.obj \
+ $(TMP_DIR)\tkWinX.obj \
+ $(TMP_DIR)\stubs.obj \
+ $(TMP_DIR)\tk3d.obj \
+ $(TMP_DIR)\tkArgv.obj \
+ $(TMP_DIR)\tkAtom.obj \
+ $(TMP_DIR)\tkBind.obj \
+ $(TMP_DIR)\tkBitmap.obj \
+ $(TMP_DIR)\tkBusy.obj \
+ $(TMP_DIR)\tkButton.obj \
+ $(TMP_DIR)\tkCanvArc.obj \
+ $(TMP_DIR)\tkCanvBmap.obj \
+ $(TMP_DIR)\tkCanvImg.obj \
+ $(TMP_DIR)\tkCanvLine.obj \
+ $(TMP_DIR)\tkCanvPoly.obj \
+ $(TMP_DIR)\tkCanvPs.obj \
+ $(TMP_DIR)\tkCanvText.obj \
+ $(TMP_DIR)\tkCanvUtil.obj \
+ $(TMP_DIR)\tkCanvWind.obj \
+ $(TMP_DIR)\tkCanvas.obj \
+ $(TMP_DIR)\tkClipboard.obj \
+ $(TMP_DIR)\tkCmds.obj \
+ $(TMP_DIR)\tkColor.obj \
+ $(TMP_DIR)\tkConfig.obj \
+ $(TMP_DIR)\tkCursor.obj \
+ $(TMP_DIR)\tkEntry.obj \
+ $(TMP_DIR)\tkError.obj \
+ $(TMP_DIR)\tkEvent.obj \
+ $(TMP_DIR)\tkFileFilter.obj \
+ $(TMP_DIR)\tkFocus.obj \
+ $(TMP_DIR)\tkFont.obj \
+ $(TMP_DIR)\tkFrame.obj \
+ $(TMP_DIR)\tkGC.obj \
+ $(TMP_DIR)\tkGeometry.obj \
+ $(TMP_DIR)\tkGet.obj \
+ $(TMP_DIR)\tkGrab.obj \
+ $(TMP_DIR)\tkGrid.obj \
+ $(TMP_DIR)\tkImage.obj \
+ $(TMP_DIR)\tkImgBmap.obj \
+ $(TMP_DIR)\tkImgGIF.obj \
+ $(TMP_DIR)\tkImgPNG.obj \
+ $(TMP_DIR)\tkImgPPM.obj \
+ $(TMP_DIR)\tkImgPhoto.obj \
+ $(TMP_DIR)\tkImgPhInstance.obj \
+ $(TMP_DIR)\tkImgUtil.obj \
+ $(TMP_DIR)\tkListbox.obj \
+ $(TMP_DIR)\tkMacWinMenu.obj \
+ $(TMP_DIR)\tkMain.obj \
+ $(TMP_DIR)\tkMain2.obj \
+ $(TMP_DIR)\tkMenu.obj \
+ $(TMP_DIR)\tkMenubutton.obj \
+ $(TMP_DIR)\tkMenuDraw.obj \
+ $(TMP_DIR)\tkMessage.obj \
+ $(TMP_DIR)\tkPanedWindow.obj \
+ $(TMP_DIR)\tkObj.obj \
+ $(TMP_DIR)\tkOldConfig.obj \
+ $(TMP_DIR)\tkOption.obj \
+ $(TMP_DIR)\tkPack.obj \
+ $(TMP_DIR)\tkPlace.obj \
+ $(TMP_DIR)\tkPointer.obj \
+ $(TMP_DIR)\tkRectOval.obj \
+ $(TMP_DIR)\tkScale.obj \
+ $(TMP_DIR)\tkScrollbar.obj \
+ $(TMP_DIR)\tkSelect.obj \
+ $(TMP_DIR)\tkStyle.obj \
+ $(TMP_DIR)\tkText.obj \
+ $(TMP_DIR)\tkTextBTree.obj \
+ $(TMP_DIR)\tkTextDisp.obj \
+ $(TMP_DIR)\tkTextImage.obj \
+ $(TMP_DIR)\tkTextIndex.obj \
+ $(TMP_DIR)\tkTextMark.obj \
+ $(TMP_DIR)\tkTextTag.obj \
+ $(TMP_DIR)\tkTextWind.obj \
+ $(TMP_DIR)\tkTrig.obj \
+ $(TMP_DIR)\tkUndo.obj \
+ $(TMP_DIR)\tkUtil.obj \
+ $(TMP_DIR)\tkVisual.obj \
+ $(TMP_DIR)\tkStubInit.obj \
+ $(TMP_DIR)\tkWindow.obj \
+ $(TTK_OBJS) \
+!if !$(STATIC_BUILD)
+ $(TMP_DIR)\tk.res
+!endif
+
+TTK_OBJS = \
+ $(TMP_DIR)\ttkWinMonitor.obj \
+ $(TMP_DIR)\ttkWinTheme.obj \
+ $(TMP_DIR)\ttkWinXPTheme.obj \
+ $(TMP_DIR)\ttkBlink.obj \
+ $(TMP_DIR)\ttkButton.obj \
+ $(TMP_DIR)\ttkCache.obj \
+ $(TMP_DIR)\ttkClamTheme.obj \
+ $(TMP_DIR)\ttkClassicTheme.obj \
+ $(TMP_DIR)\ttkDefaultTheme.obj \
+ $(TMP_DIR)\ttkElements.obj \
+ $(TMP_DIR)\ttkEntry.obj \
+ $(TMP_DIR)\ttkFrame.obj \
+ $(TMP_DIR)\ttkImage.obj \
+ $(TMP_DIR)\ttkInit.obj \
+ $(TMP_DIR)\ttkLabel.obj \
+ $(TMP_DIR)\ttkLayout.obj \
+ $(TMP_DIR)\ttkManager.obj \
+ $(TMP_DIR)\ttkNotebook.obj \
+ $(TMP_DIR)\ttkPanedwindow.obj \
+ $(TMP_DIR)\ttkProgress.obj \
+ $(TMP_DIR)\ttkScale.obj \
+ $(TMP_DIR)\ttkScrollbar.obj \
+ $(TMP_DIR)\ttkScroll.obj \
+ $(TMP_DIR)\ttkSeparator.obj \
+ $(TMP_DIR)\ttkSquare.obj \
+ $(TMP_DIR)\ttkState.obj \
+ $(TMP_DIR)\ttkTagSet.obj \
+ $(TMP_DIR)\ttkTheme.obj \
+ $(TMP_DIR)\ttkTrace.obj \
+ $(TMP_DIR)\ttkTrack.obj \
+ $(TMP_DIR)\ttkTreeview.obj \
+ $(TMP_DIR)\ttkWidget.obj \
+ $(TMP_DIR)\ttkStubInit.obj
+
+TKSTUBOBJS = \
+ $(TMP_DIR)\tkStubLib.obj \
+ $(TMP_DIR)\ttkStubLib.obj
+
+
+WINDIR = $(ROOT)\win
+GENERICDIR = $(ROOT)\generic
+XLIBDIR = $(ROOT)\xlib
+TTKDIR = $(ROOT)\generic\ttk
+BITMAPDIR = $(ROOT)\bitmaps
+DOCDIR = $(ROOT)\doc
+RCDIR = $(WINDIR)\rc
+
+TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(BITMAPDIR)" -I"$(XLIBDIR)" \
+ $(TCL_INCLUDES)
+
+CONFIG_DEFS =-DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 \
+ -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 \
+ -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 \
+ -DSUPPORT_CONFIG_EMBEDDED \
+!if $(HAVE_UXTHEME_H)
+ -DHAVE_UXTHEME_H=1 \
+!endif
+!if $(TTK_SQUARE_WIDGET)
+ -DTTK_SQUARE_WIDGET=1 \
+!endif
+
+TK_DEFINES =-DBUILD_ttk $(OPTDEFINES) $(CONFIG_DEFS) -Dinline=__inline
+
+#---------------------------------------------------------------------
+# Compile flags
+#---------------------------------------------------------------------
+
+!if !$(DEBUG)
+!if $(OPTIMIZING)
+### This cranks the optimization level to maximize speed
+### We can't use -O2 because sometimes it causes problems.
+cdebug = $(OPTIMIZATIONS)
+!else
+cdebug =
+!endif
+!if $(SYMBOLS)
+cdebug = $(cdebug) -Zi
+!endif
+!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+### Warnings are too many, can't support warnings into errors.
+cdebug = -Zi -Od $(DEBUGFLAGS)
+!else
+cdebug = -Zi -WX $(DEBUGFLAGS)
+!endif
+
+### Declarations common to all compiler options
+cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
+cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
+
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+BASE_CFLAGS = $(cdebug) $(cflags) $(crt) $(TK_INCLUDES)
+TK_CFLAGS = $(BASE_CFLAGS) $(TK_DEFINES) -DUSE_TCL_STUBS
+CON_CFLAGS = $(cdebug) $(cflags) $(crt) -DCONSOLE
+WISH_CFLAGS = $(BASE_CFLAGS) $(TK_DEFINES)
+STUB_CFLAGS = $(cflags) $(cdebug) $(TK_DEFINES)
+
+
+#---------------------------------------------------------------------
+# Link flags
+#---------------------------------------------------------------------
+
+!if $(DEBUG)
+ldebug = -debug -debugtype:cv
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!if $(SYMBOLS)
+ldebug = $(ldebug) -debug -debugtype:cv
+!endif
+!endif
+
+### Declarations common to all linker options
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(PROFILE)
+lflags = $(lflags) -profile
+!endif
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+lflags = $(lflags) -nodefaultlib:libucrt.lib
+!endif
+
+!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
+### Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
+### Align sections for speed in loading by choosing the virtual page size.
+lflags = $(lflags) -align:4096
+!endif
+
+!if $(LOIMPACT)
+lflags = $(lflags) -ws:aggressive
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+
+tcllibs = $(TCLSTUBLIB) $(TCLIMPLIB)
+
+baselibs = netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
+baselibs = $(baselibs) bufferoverflowU.lib
+!endif
+!endif
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+baselibs = $(baselibs) ucrt.lib
+!endif
+
+guilibs = $(baselibs) gdi32.lib
+
+
+#---------------------------------------------------------------------
+# TkTest flags
+#---------------------------------------------------------------------
+
+!if "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!endif
+
+
+#---------------------------------------------------------------------
+# Project specific targets
+#---------------------------------------------------------------------
+
+release: setup $(TKSTUBLIB) $(WISH)
+all: release $(CAT32)
+core: setup $(TKSTUBLIB) $(TKLIB)
+cwish: $(WISHC)
+install: install-binaries install-libraries install-docs
+tktest: setup $(TKTEST) $(CAT32)
+
+
+test: test-classic test-ttk
+
+test-classic: setup $(TKTEST) $(TKLIB) $(CAT32)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+ $(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) | $(CAT32)
+
+test-ttk: setup $(TKTEST) $(TKLIB) $(CAT32)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+ $(DEBUGGER) $(TKTEST) "$(ROOT:\=/)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32)
+
+runtest: setup $(TKTEST) $(TKLIB) $(CAT32)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+ $(DEBUGGER) $(TKTEST)
+
+rundemo: setup $(TKTEST) $(TKLIB) $(CAT32)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+ $(TKTEST) $(ROOT:\=/)\library\demos\widget
+
+shell: setup $(WISH)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+ $(DEBUGGER) $(WISH) <<
+ console show
+<<
+
+dbgshell: setup $(WISH)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+ windbg $(WISH)
+
+setup:
+ @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+ @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+!if !$(STATIC_BUILD)
+$(TKIMPLIB): $(TKLIB)
+!endif
+
+$(TKLIB): $(TKOBJS)
+!if $(STATIC_BUILD)
+ $(lib32) -nologo -out:$@ @<<
+$**
+<<
+!else
+ $(link32) $(dlllflags) -base:@$(COFFBASE),tk -out:$@ $(guilibs) \
+ $(TCLSTUBLIB) @<<
+$**
+<<
+ $(_VC_MANIFEST_EMBED_DLL)
+ -@del $*.exp
+!endif
+
+
+$(TKSTUBLIB): $(TKSTUBOBJS)
+ $(lib32) -nologo -nodefaultlib -out:$@ $**
+
+
+$(WISH): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB)
+ $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(tcllibs) $**
+ $(_VC_MANIFEST_EMBED_EXE)
+
+
+$(WISHC): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB)
+ $(link32) $(conlflags) -stack:2300000 -out:$@ $(guilibs) $(tcllibs) $**
+ $(_VC_MANIFEST_EMBED_EXE)
+
+
+$(TKTEST): $(TKTESTOBJS) $(TKSTUBLIB) $(TKIMPLIB)
+ $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(tcllibs) $**
+ $(_VC_MANIFEST_EMBED_EXE)
+
+
+$(CAT32): $(_TCLDIR)\win\cat.c
+ $(cc32) $(CON_CFLAGS) -Fo$(TMP_DIR)\ $?
+ $(link32) $(conlflags) -out:$@ -stack:16384 $(TMP_DIR)\cat.obj $(baselibs)
+ $(_VC_MANIFEST_EMBED_EXE)
+
+#---------------------------------------------------------------------
+# Regenerate the stubs files. [Development use only]
+#---------------------------------------------------------------------
+
+genstubs:
+!if !exist($(TCLSH))
+ @echo Build tclsh first!
+!else
+ set TCL_LIBRARY=$(TCL_LIBRARY)
+ $(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
+ $(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls
+!endif
+
+
+#---------------------------------------------------------------------
+# Build the Windows HTML help file.
+#---------------------------------------------------------------------
+
+# NOTE: you can define HHC on the command-line to override this
+!ifndef HHC
+HHC=""%ProgramFiles%\HTML Help Workshop\hhc.exe""
+!endif
+HTMLDIR=$(ROOT)\html
+HTMLBASE=TclTk$(VERSION)
+HHPFILE=$(HTMLDIR)\$(HTMLBASE).hhp
+CHMFILE=$(HTMLDIR)\$(HTMLBASE).chm
+
+htmlhelp: chmsetup $(CHMFILE)
+
+$(CHMFILE): $(DOCDIR)\*
+ @$(TCLSH) $(TCLTOOLSDIR)\tcltk-man2html.tcl
+ @echo Compiling HTML help project
+ @$(HHC) <<$(HHPFILE) >NUL
+[OPTIONS]
+Compatibility=1.1 or later
+Compiled file=$(HTMLBASE).chm
+Display compile progress=no
+Error log file=$(HTMLBASE).log
+Language=0x409 English (United States)
+Title=Tcl/Tk $(DOT_VERSION) Help
+[FILES]
+contents.htm
+docs.css
+Keywords
+TclCmd
+TclLib
+TkCmd
+TkLib
+UserCmd
+<<
+
+chmsetup:
+ @if not exist $(HTMLDIR)\nul mkdir $(HTMLDIR)
+
+#-------------------------------------------------------------------------
+# Build the old-style Windows .hlp file
+#-------------------------------------------------------------------------
+
+HLPBASE = $(PROJECT)$(TK_VERSION)
+HELPFILE = $(OUT_DIR)\$(HLPBASE).hlp
+HELPCNT = $(OUT_DIR)\$(HLPBASE).cnt
+DOCTMP_DIR = $(OUT_DIR)\$(PROJECT)_docs
+HELPRTF = $(DOCTMP_DIR)\$(PROJECT).rtf
+MAN2HELP = $(DOCTMP_DIR)\man2help.tcl
+MAN2HELP2 = $(DOCTMP_DIR)\man2help2.tcl
+INDEX = $(DOCTMP_DIR)\index.tcl
+BMP = $(DOCTMP_DIR)\lamp.bmp
+BMP_NOPATH = lamp.bmp
+MAN2TCL = $(DOCTMP_DIR)\man2tcl.exe
+
+winhelp: docsetup $(HELPFILE)
+
+docsetup:
+ @if not exist $(DOCTMP_DIR)\nul mkdir $(DOCTMP_DIR)
+
+$(MAN2HELP) $(MAN2HELP2) $(INDEX): $(TCLTOOLSDIR)\$$(@F)
+ $(CPY) $(TCLTOOLSDIR)\$(@F) $(@D)
+
+$(BMP):
+ $(CPY) $(WINDIR)\rc\$(@F) $(@D)
+
+$(HELPFILE): $(HELPRTF) $(BMP)
+ cd $(DOCTMP_DIR)
+ start /wait hcrtf.exe -x <<$(PROJECT).hpj
+[OPTIONS]
+COMPRESS=12 Hall Zeck
+LCID=0x409 0x0 0x0 ; English (United States)
+TITLE=Tk Reference Manual
+BMROOT=.
+CNT=$(@B).cnt
+HLP=$(@B).hlp
+
+[FILES]
+$(PROJECT).rtf
+
+[WINDOWS]
+main="Tcl/Tk Reference Manual",,27648,(r15263976),(r4227327)
+
+[CONFIG]
+BrowseButtons()
+CreateButton(1, "Web", ExecFile("http://www.tcl.tk"))
+CreateButton(2, "SF", ExecFile("http://sf.net/projects/tcl"))
+CreateButton(3, "Wiki", ExecFile("http://wiki.tcl.tk"))
+CreateButton(4, "FAQ", ExecFile("http://www.purl.org/NET/Tcl-FAQ/"))
+<<
+ cd $(MAKEDIR)
+ @$(CPY) "$(DOCTMP_DIR)\$(@B).hlp" "$(OUT_DIR)"
+ @$(CPY) "$(DOCTMP_DIR)\$(@B).cnt" "$(OUT_DIR)"
+
+$(MAN2TCL): $(TCLTOOLSDIR)\$$(@B).c
+ $(cc32) $(TK_CFLAGS) -Fo$(@D)\ $(TCLTOOLSDIR)\$(@B).c
+ $(link32) $(conlflags) -out:$@ -stack:16384 $(@D)\man2tcl.obj
+ $(_VC_MANIFEST_EMBED_EXE)
+
+$(HELPRTF): $(MAN2TCL) $(MAN2HELP) $(MAN2HELP2) $(INDEX)
+ $(TCLSH) $(MAN2HELP) -bitmap $(BMP_NOPATH) $(PROJECT) $(TK_VERSION) $(DOCDIR:\=/)
+
+install-docs:
+!if exist($(HELPFILE))
+ $(CPY) "$(HELPFILE)" "$(DOC_INSTALL_DIR)\"
+ $(CPY) "$(HELPCNT)" "$(DOC_INSTALL_DIR)\"
+ $(TCLSH) <<
+puts "Installing $(PROJECT)'s helpfile contents into Tcl's ..."
+set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(TK_VERSION).cnt" r]
+while {![eof $$f]} {
+ if {[regexp {:Include $(PROJECT)([0-9]{2}).cnt} [gets $$f] dummy ver]} {
+ if {$$ver == $(TK_VERSION)} {
+ puts "Already installed."
+ exit
+ } else {
+ # do something here logical to remove (or replace) it.
+ puts "$$ver != $(TK_VERSION), unfinished code path, die, die!"
+ exit 1
+ }
+ }
+}
+close $$f
+set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(TK_VERSION).cnt" a]
+puts $$f {:Include $(HLPBASE).cnt}
+close $$f
+<<
+ start /wait winhlp32 -g $(DOC_INSTALL_DIR)\tcl$(TK_VERSION).hlp
+!endif
+
+#---------------------------------------------------------------------
+# Special case object file targets
+#---------------------------------------------------------------------
+
+$(TMP_DIR)\testMain.obj: $(WINDIR)\winMain.c
+ $(cc32) $(WISH_CFLAGS) -DTK_TEST \
+ -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
+ -Fo$@ $?
+
+$(TMP_DIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
+ $(cc32) $(WISH_CFLAGS) -Fo$@ $?
+
+$(TMP_DIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
+ $(cc32) $(WISH_CFLAGS) -Fo$@ $?
+
+$(TMP_DIR)\tkWinTest.obj: $(WINDIR)\tkWinTest.c
+ $(cc32) $(WISH_CFLAGS) -Fo$@ $?
+
+$(TMP_DIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
+ $(cc32) $(WISH_CFLAGS) -Fo$@ $?
+
+$(TMP_DIR)\winMain.obj: $(WINDIR)\winMain.c
+ $(cc32) $(WISH_CFLAGS) \
+ -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
+ -Fo$@ $?
+
+$(TMP_DIR)\tkMain2.obj: $(GENERICDIR)\tkMain.c
+ $(cc32) -DBUILD_tk $(TK_CFLAGS) -DTK_ASCII_MAIN -Fo$@ $?
+
+# The following objects are part of the stub library and should not
+# be built as DLL objects but none of the symbols should be exported
+# and no reference made to a C runtime.
+
+$(TMP_DIR)\tkStubLib.obj : $(GENERICDIR)\tkStubLib.c
+ $(cc32) $(STUB_CFLAGS) $(TK_INCLUDES) -Zl -DSTATIC_BUILD -Fo$@ $?
+
+
+$(TMP_DIR)\wish.exe.manifest: $(WINDIR)\wish.exe.manifest.in
+ @nmakehlp -s << $** >$@
+@MACHINE@ $(MACHINE:IX86=X86)
+@TK_WIN_VERSION@ $(TK_DOTVERSION).0.0
+<<
+
+#---------------------------------------------------------------------
+# Generate the source dependencies. Having dependency rules will
+# improve incremental build accuracy without having to resort to a
+# full rebuild just because some non-global header file like
+# tclCompile.h was changed. These rules aren't needed when building
+# from scratch.
+#---------------------------------------------------------------------
+
+depend:
+!if !exist($(TCLSH))
+ @echo Build tclsh first!
+!else
+ set TCL_LIBRARY=$(TCL_LIBRARY)
+ $(TCLSH) $(TCLTOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \
+ -passthru:"-DBUILD_tk $(TK_INCLUDES)" $(GENERICDIR),$$(GENERICDIR) \
+ $(WINDIR),$$(WINDIR) $(TTKDIR),$$(TTKDIR) $(XLIBDIR),$$(XLIBDIR) \
+ $(BITMAPDIR),$$(BITMAPDIR) @<<
+$(TKOBJS)
+<<
+!endif
+
+#---------------------------------------------------------------------
+# Dependency rules
+#---------------------------------------------------------------------
+
+$(TMP_DIR)\tk.res: \
+ $(RCDIR)\buttons.bmp \
+ $(RCDIR)\cursor*.cur \
+ $(RCDIR)\tk.ico
+
+!if exist("$(OUT_DIR)\depend.mk")
+!include "$(OUT_DIR)\depend.mk"
+!message *** Dependency rules in use.
+!else
+!message *** Dependency rules are not being used.
+!endif
+
+### add a spacer in the output
+!message
+
+#---------------------------------------------------------------------
+# Implicit rules
+#---------------------------------------------------------------------
+
+{$(XLIBDIR)}.c{$(TMP_DIR)}.obj::
+ $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+ $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(TTKDIR)}.c{$(TMP_DIR)}.obj::
+ $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+ $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(ROOT)\unix}.c{$(TMP_DIR)}.obj::
+ $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(RCDIR)}.rc{$(TMP_DIR)}.res:
+ $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" $(TCL_INCLUDES) \
+ -d DEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
+ -d TCL_THREADS=$(TCL_THREADS) \
+ -d STATIC_BUILD=$(STATIC_BUILD) \
+ $<
+
+$(TMP_DIR)\tk.res: $(TMP_DIR)\wish.exe.manifest
+$(TMP_DIR)\wish.res: $(TMP_DIR)\wish.exe.manifest
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+
+#---------------------------------------------------------------------
+# Installation.
+#---------------------------------------------------------------------
+
+install-binaries:
+ @echo installing binaries
+ @$(CPY) "$(WISH)" "$(BIN_INSTALL_DIR)\"
+!if $(TKLIB) != $(TKIMPLIB)
+ @$(CPY) "$(TKLIB)" "$(BIN_INSTALL_DIR)\"
+!endif
+ @$(CPY) "$(TKIMPLIB)" "$(LIB_INSTALL_DIR)\"
+ @$(CPY) "$(TKSTUBLIB)" "$(LIB_INSTALL_DIR)\"
+!if !$(STATIC_BUILD)
+ @echo creating package index
+ @type << > $(OUT_DIR)\pkgIndex.tcl
+if {[catch {package present Tcl $(TCL_PATCH_LEVEL)}]} { return }
+if {($$::tcl_platform(platform) eq "unix") && ([info exists ::env(DISPLAY)]
+ || ([info exists ::argv] && ("-display" in $$::argv)))} {
+ package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin libtk$(TK_DOTVERSION).dll] Tk]
+} else {
+ package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin $(TKLIBNAME)] Tk]
+}
+<<
+ @$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)\"
+!endif
+
+#"
+
+install-libraries:
+ @echo installing Tk headers
+ @$(CPY) "$(GENERICDIR)\tk.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(GENERICDIR)\tkDecls.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(GENERICDIR)\tkPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(XLIBDIR)\X11\*.h" "$(INCLUDE_INSTALL_DIR)\X11\"
+ @echo installing script library
+ @$(CPY) "$(ROOT)\library\*" "$(SCRIPT_INSTALL_DIR)\"
+ @echo installing theme library
+ @$(CPY) "$(ROOT)\library\ttk\*" "$(SCRIPT_INSTALL_DIR)\ttk\"
+ @echo installing demos
+ @$(CPY) "$(ROOT)\library\demos\*" "$(SCRIPT_INSTALL_DIR)\demos\"
+ @$(CPY) "$(ROOT)\library\demos\images\*" "$(SCRIPT_INSTALL_DIR)\demos\images\"
+ @echo installing images
+ @$(CPY) "$(ROOT)\library\images\*" "$(SCRIPT_INSTALL_DIR)\images\"
+ @echo installing language files
+ @$(CPY) "$(ROOT)\library\msgs\*" "$(SCRIPT_INSTALL_DIR)\msgs\"
+
+#"
+
+#---------------------------------------------------------------------
+# Clean up
+#---------------------------------------------------------------------
+
+tidy:
+!if $(TKLIB) != $(TKIMPLIB)
+ @echo Removing $(TKLIB) ...
+ @if exist $(TKLIB) del $(TKLIB)
+!endif
+ @echo Removing $(TKIMPLIB) ...
+ @if exist $(TKIMPLIB) del $(TKIMPLIB)
+ @echo Removing $(WISH) ...
+ @if exist $(WISH) del $(WISH)
+ @echo Removing $(TKTEST) ...
+ @if exist $(TKTEST) del $(TKTEST)
+ @echo Removing $(TKSTUBLIB) ...
+ @if exist $(TKSTUBLIB) del $(TKSTUBLIB)
+
+clean:
+ @echo Cleaning $(TMP_DIR)\* ...
+ @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+ @echo Cleaning $(WINDIR)\nmakehlp.obj ...
+ @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+ @echo Cleaning $(WINDIR)\nmakehlp.exe ...
+ @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+ @echo Cleaning $(WINDIR)\_junk.pch ...
+ @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+ @echo Cleaning $(WINDIR)\vercl.x ...
+ @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+ @echo Cleaning $(WINDIR)\vercl.i ...
+ @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+ @echo Cleaning $(WINDIR)\versions.vc ...
+ @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+
+realclean: hose
+
+hose:
+ @echo Hosing $(OUT_DIR)\* ...
+ @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
diff --git a/win/mkd.bat b/win/mkd.bat index f741daf..1bd5ccb 100644 --- a/win/mkd.bat +++ b/win/mkd.bat @@ -1,12 +1,12 @@ -@echo off - -if exist %1\nul goto end - -md %1 -if errorlevel 1 goto end - -echo Created directory %1 - -:end - - +@echo off
+
+if exist %1\nul goto end
+
+md %1
+if errorlevel 1 goto end
+
+echo Created directory %1
+
+:end
+
+
diff --git a/win/nmakehlp.c b/win/nmakehlp.c index b1a1517..84cf75c 100644 --- a/win/nmakehlp.c +++ b/win/nmakehlp.c @@ -606,8 +606,8 @@ SubstituteFile( sp = fopen(substitutions, "rt"); if (sp != NULL) { while (fgets(szBuffer, cbBuffer, sp) != NULL) { - char *ks, *ke, *vs, *ve; - ks = szBuffer; + unsigned char *ks, *ke, *vs, *ve; + ks = (unsigned char*)szBuffer; while (ks && *ks && isspace(*ks)) ++ks; ke = ks; while (ke && *ke && !isspace(*ke)) ++ke; @@ -616,7 +616,7 @@ SubstituteFile( ve = vs; while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve; *ke = 0, *ve = 0; - list_insert(&substPtr, ks, vs); + list_insert(&substPtr, (char*)ks, (char*)vs); } fclose(sp); } diff --git a/win/rc/lamp.bmp b/win/rc/lamp.bmp Binary files differindex 834c0f9..1e2f9d4 100644 --- a/win/rc/lamp.bmp +++ b/win/rc/lamp.bmp diff --git a/win/rc/tk_base.rc b/win/rc/tk_base.rc index 3e065c9..e6ab016 100644 --- a/win/rc/tk_base.rc +++ b/win/rc/tk_base.rc @@ -26,12 +26,12 @@ FONT 8, "Helv" BEGIN LTEXT "Directory &name:",-1,8,6,118,9 EDITTEXT edt10,8,26,144,12, WS_TABSTOP | ES_AUTOHSCROLL - LISTBOX lst2,8,40,144,64,LBS_SORT | LBS_OWNERDRAWFIXED | - LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | + LISTBOX lst2,8,40,144,64,LBS_SORT | LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP LTEXT "Dri&ves:",stc4,8,106,92,9 - COMBOBOX cmb2,8,115,144,68,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | - CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | + COMBOBOX cmb2,8,115,144,68,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | + CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK",1,160,6,50,14,WS_GROUP PUSHBUTTON "Cancel",2,160,24,50,14,WS_GROUP @@ -42,8 +42,8 @@ BEGIN LTEXT "a",stc3,9,143,114,15 EDITTEXT edt1,7,158,135,20,NOT WS_TABSTOP LISTBOX lst1,8,205,134,42,LBS_NOINTEGRALHEIGHT - COMBOBOX cmb1,8,253,135,21,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | - CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | + COMBOBOX cmb1,8,253,135,21,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | + CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL END diff --git a/win/rc/wish.ico b/win/rc/wish.ico Binary files differindex 05cad66..5801fb8 100644 --- a/win/rc/wish.ico +++ b/win/rc/wish.ico diff --git a/win/rc/wish.rc b/win/rc/wish.rc index 5cc2fa4..53e02fa 100644 --- a/win/rc/wish.rc +++ b/win/rc/wish.rc @@ -63,7 +63,7 @@ END // // Icon -// +// // The icon whose name or resource ID is lexigraphically first, is used // as the application's icon. // diff --git a/win/rmd.bat b/win/rmd.bat index d260936..820b76f 100644 --- a/win/rmd.bat +++ b/win/rmd.bat @@ -1,20 +1,20 @@ -@echo off - -if not exist %1\nul goto end - -echo Removing directory %1 - -if "%OS%" == "Windows_NT" goto winnt - -deltree /y %1 -if errorlevel 1 goto end -goto success - -:winnt -rmdir /s /q %1 -if errorlevel 1 goto end - -:success -echo Deleted directory %1 - -:end +@echo off
+
+if not exist %1\nul goto end
+
+echo Removing directory %1
+
+if "%OS%" == "Windows_NT" goto winnt
+
+deltree /y %1
+if errorlevel 1 goto end
+goto success
+
+:winnt
+rmdir /s /q %1
+if errorlevel 1 goto end
+
+:success
+echo Deleted directory %1
+
+:end
diff --git a/win/rules.vc b/win/rules.vc index adc3165..0d8cd6b 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -1,716 +1,716 @@ -#------------------------------------------------------------------------------ -# rules.vc -- -# -# Microsoft Visual C++ makefile include for decoding the commandline -# macros. This file does not need editing to build Tcl. -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# Copyright (c) 2001-2003 David Gravereaux. -# Copyright (c) 2003-2008 Patrick Thoyts -#------------------------------------------------------------------------------ - -!ifndef _RULES_VC -_RULES_VC = 1 - -cc32 = $(CC) # built-in default. -link32 = link -lib32 = lib -rc32 = $(RC) # built-in default. - -!ifndef INSTALLDIR -### Assume the normal default. -_INSTALLDIR = C:\Program Files\Tcl -!else -### Fix the path separators. -_INSTALLDIR = $(INSTALLDIR:/=\) -!endif - -#---------------------------------------------------------- -# Set the proper copy method to avoid overwrite questions -# to the user when copying files and selecting the right -# "delete all" method. -#---------------------------------------------------------- - -!if "$(OS)" == "Windows_NT" -RMDIR = rmdir /S /Q -ERRNULL = 2>NUL -!if ![ver | find "4.0" > nul] -CPY = echo y | xcopy /i >NUL -COPY = copy >NUL -!else -CPY = xcopy /i /y >NUL -COPY = copy /y >NUL -!endif -!else # "$(OS)" != "Windows_NT" -CPY = xcopy /i >_JUNK.OUT # On Win98 NUL does not work here. -COPY = copy >_JUNK.OUT # On Win98 NUL does not work here. -RMDIR = deltree /Y -NULL = \NUL # Used in testing directory existence -ERRNULL = >NUL # Win9x shell cannot redirect stderr -!endif -MKDIR = mkdir - -#------------------------------------------------------------------------------ -# Determine the host and target architectures and compiler version. -#------------------------------------------------------------------------------ - -_HASH=^# -_VC_MANIFEST_EMBED_EXE= -_VC_MANIFEST_EMBED_DLL= -VCVER=0 -!if ![echo VCVERSION=_MSC_VER > vercl.x] \ - && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \ - && ![echo ARCH=IX86 >> vercl.x] \ - && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \ - && ![echo ARCH=AMD64 >> vercl.x] \ - && ![echo $(_HASH)endif >> vercl.x] \ - && ![cl -nologo -TC -P vercl.x $(ERRNULL)] -!include vercl.i -!if ![echo VCVER= ^\> vercl.vc] \ - && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc] -!include vercl.vc -!endif -!endif -!if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc] -!endif - -!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86] -NATIVE_ARCH=IX86 -!else -NATIVE_ARCH=AMD64 -!endif - -# Since MSVC8 we must deal with manifest resources. -!if $(VCVERSION) >= 1400 -_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1 -_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2 -!endif - -!ifndef MACHINE -MACHINE=$(ARCH) -!endif - -!ifndef CFG_ENCODING -CFG_ENCODING = \"cp1252\" -!endif - -!message =============================================================================== - -#---------------------------------------------------------- -# build the helper app we need to overcome nmake's limiting -# environment. -#---------------------------------------------------------- - -!if !exist(nmakehlp.exe) -!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul] -!endif -!endif - -#---------------------------------------------------------- -# Test for compiler features -#---------------------------------------------------------- - -### test for optimizations -!if [nmakehlp -c -Ot] -!message *** Compiler has 'Optimizations' -OPTIMIZING = 1 -!else -!message *** Compiler does not have 'Optimizations' -OPTIMIZING = 0 -!endif - -OPTIMIZATIONS = - -!if [nmakehlp -c -Ot] -OPTIMIZATIONS = $(OPTIMIZATIONS) -Ot -!endif - -!if [nmakehlp -c -Oi] -OPTIMIZATIONS = $(OPTIMIZATIONS) -Oi -!endif - -!if [nmakehlp -c -Op] -OPTIMIZATIONS = $(OPTIMIZATIONS) -Op -!endif - -!if [nmakehlp -c -fp:strict] -OPTIMIZATIONS = $(OPTIMIZATIONS) -fp:strict -!endif - -!if [nmakehlp -c -Gs] -OPTIMIZATIONS = $(OPTIMIZATIONS) -Gs -!endif - -!if [nmakehlp -c -GS] -OPTIMIZATIONS = $(OPTIMIZATIONS) -GS -!endif - -!if [nmakehlp -c -GL] -OPTIMIZATIONS = $(OPTIMIZATIONS) -GL -!endif - -DEBUGFLAGS = - -!if [nmakehlp -c -RTC1] -DEBUGFLAGS = $(DEBUGFLAGS) -RTC1 -!elseif [nmakehlp -c -GZ] -DEBUGFLAGS = $(DEBUGFLAGS) -GZ -!endif - -COMPILERFLAGS =-W3 -DUNICODE -D_UNICODE - -# In v13 -GL and -YX are incompatible. -!if [nmakehlp -c -YX] -!if ![nmakehlp -c -GL] -OPTIMIZATIONS = $(OPTIMIZATIONS) -YX -!endif -!endif - -!if "$(MACHINE)" == "IX86" -### test for pentium errata -!if [nmakehlp -c -QI0f] -!message *** Compiler has 'Pentium 0x0f fix' -COMPILERFLAGS = $(COMPILERFLAGS) -QI0f -!else -!message *** Compiler does not have 'Pentium 0x0f fix' -!endif -!endif - -!if "$(MACHINE)" == "IA64" -### test for Itanium errata -!if [nmakehlp -c -QIA64_Bx] -!message *** Compiler has 'B-stepping errata workarounds' -COMPILERFLAGS = $(COMPILERFLAGS) -QIA64_Bx -!else -!message *** Compiler does not have 'B-stepping errata workarounds' -!endif -!endif - -!if "$(MACHINE)" == "IX86" -### test for -align:4096, when align:512 will do. -!if [nmakehlp -l -opt:nowin98] -!message *** Linker has 'Win98 alignment problem' -ALIGN98_HACK = 1 -!else -!message *** Linker does not have 'Win98 alignment problem' -ALIGN98_HACK = 0 -!endif -!else -ALIGN98_HACK = 0 -!endif - -LINKERFLAGS = - -!if [nmakehlp -l -ltcg] -LINKERFLAGS =-ltcg -!endif - -#---------------------------------------------------------- -# Decode the options requested. -#---------------------------------------------------------- - -!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"] -STATIC_BUILD = 0 -TCL_THREADS = 1 -DEBUG = 0 -SYMBOLS = 0 -PROFILE = 0 -PGO = 0 -MSVCRT = 1 -LOIMPACT = 0 -TCL_USE_STATIC_PACKAGES = 0 -USE_THREAD_ALLOC = 1 -UNCHECKED = 0 -!else -!if [nmakehlp -f $(OPTS) "static"] -!message *** Doing static -STATIC_BUILD = 1 -!else -STATIC_BUILD = 0 -!endif -!if [nmakehlp -f $(OPTS) "msvcrt"] -!message *** Doing msvcrt -MSVCRT = 1 -!else -!if !$(STATIC_BUILD) -MSVCRT = 1 -!else -MSVCRT = 0 -!endif -!endif -!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD) -!message *** Doing staticpkg -TCL_USE_STATIC_PACKAGES = 1 -!else -TCL_USE_STATIC_PACKAGES = 0 -!endif -!if [nmakehlp -f $(OPTS) "nothreads"] -!message *** Compile explicitly for non-threaded tcl -TCL_THREADS = 0 -USE_THREAD_ALLOC= 0 -!else -TCL_THREADS = 1 -USE_THREAD_ALLOC= 1 -!endif -!if [nmakehlp -f $(OPTS) "symbols"] -!message *** Doing symbols -DEBUG = 1 -!else -DEBUG = 0 -!endif -!if [nmakehlp -f $(OPTS) "pdbs"] -!message *** Doing pdbs -SYMBOLS = 1 -!else -SYMBOLS = 0 -!endif -!if [nmakehlp -f $(OPTS) "profile"] -!message *** Doing profile -PROFILE = 1 -!else -PROFILE = 0 -!endif -!if [nmakehlp -f $(OPTS) "pgi"] -!message *** Doing profile guided optimization instrumentation -PGO = 1 -!elseif [nmakehlp -f $(OPTS) "pgo"] -!message *** Doing profile guided optimization -PGO = 2 -!else -PGO = 0 -!endif -!if [nmakehlp -f $(OPTS) "loimpact"] -!message *** Doing loimpact -LOIMPACT = 1 -!else -LOIMPACT = 0 -!endif -!if [nmakehlp -f $(OPTS) "thrdalloc"] -!message *** Doing thrdalloc -USE_THREAD_ALLOC = 1 -!endif -!if [nmakehlp -f $(OPTS) "tclalloc"] -!message *** Doing tclalloc -USE_THREAD_ALLOC = 0 -!endif -!if [nmakehlp -f $(OPTS) "unchecked"] -!message *** Doing unchecked -UNCHECKED = 1 -!else -UNCHECKED = 0 -!endif -!endif - -#---------------------------------------------------------- -# Figure-out how to name our intermediate and output directories. -# We wouldn't want different builds to use the same .obj files -# by accident. -#---------------------------------------------------------- - -#---------------------------------------- -# Naming convention: -# t = full thread support. -# s = static library (as opposed to an -# import library) -# g = linked to the debug enabled C -# run-time. -# x = special static build when it -# links to the dynamic C run-time. -#---------------------------------------- -SUFX = tsgx - -!if $(DEBUG) -BUILDDIRTOP = Debug -!else -BUILDDIRTOP = Release -!endif - -!if "$(MACHINE)" != "IX86" -BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE) -!endif -!if $(VCVER) > 6 -BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER) -!endif - -!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED) -SUFX = $(SUFX:g=) -!endif - -TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX - -!if !$(STATIC_BUILD) -TMP_DIRFULL = $(TMP_DIRFULL:Static=) -SUFX = $(SUFX:s=) -EXT = dll -TMP_DIRFULL = $(TMP_DIRFULL:X=) -SUFX = $(SUFX:x=) -!else -TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=) -EXT = lib -!if !$(MSVCRT) -TMP_DIRFULL = $(TMP_DIRFULL:X=) -SUFX = $(SUFX:x=) -!endif -!endif - -!if !$(TCL_THREADS) -TMP_DIRFULL = $(TMP_DIRFULL:Threaded=) -SUFX = $(SUFX:t=) -!endif - -!ifndef TMP_DIR -TMP_DIR = $(TMP_DIRFULL) -!ifndef OUT_DIR -OUT_DIR = .\$(BUILDDIRTOP) -!endif -!else -!ifndef OUT_DIR -OUT_DIR = $(TMP_DIR) -!endif -!endif - - -#---------------------------------------------------------- -# Decode the statistics requested. -#---------------------------------------------------------- - -!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"] -TCL_MEM_DEBUG = 0 -TCL_COMPILE_DEBUG = 0 -!else -!if [nmakehlp -f $(STATS) "memdbg"] -!message *** Doing memdbg -TCL_MEM_DEBUG = 1 -!else -TCL_MEM_DEBUG = 0 -!endif -!if [nmakehlp -f $(STATS) "compdbg"] -!message *** Doing compdbg -TCL_COMPILE_DEBUG = 1 -!else -TCL_COMPILE_DEBUG = 0 -!endif -!endif - - -#---------------------------------------------------------- -# Decode the checks requested. -#---------------------------------------------------------- - -!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"] -TCL_NO_DEPRECATED = 0 -WARNINGS = -W3 -!else -!if [nmakehlp -f $(CHECKS) "nodep"] -!message *** Doing nodep check -TCL_NO_DEPRECATED = 1 -!else -TCL_NO_DEPRECATED = 0 -!endif -!if [nmakehlp -f $(CHECKS) "fullwarn"] -!message *** Doing full warnings check -WARNINGS = -W4 -!if [nmakehlp -l -warn:3] -LINKERFLAGS = $(LINKERFLAGS) -warn:3 -!endif -!else -WARNINGS = -W3 -!endif -!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64] -!message *** Doing 64bit portability warnings -WARNINGS = $(WARNINGS) -Wp64 -!endif -!endif - -!if $(PGO) > 1 -!if [nmakehlp -l -ltcg:pgoptimize] -LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize -!else -MSG=^ -This compiler does not support profile guided optimization. -!error $(MSG) -!endif -!elseif $(PGO) > 0 -!if [nmakehlp -l -ltcg:pginstrument] -LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument -!else -MSG=^ -This compiler does not support profile guided optimization. -!error $(MSG) -!endif -!endif - -#---------------------------------------------------------- -# Set our defines now armed with our options. -#---------------------------------------------------------- - -OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS - -!if $(TCL_MEM_DEBUG) -OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG -!endif -!if $(TCL_COMPILE_DEBUG) -OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS -!endif -!if $(TCL_THREADS) -OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1 -!if $(USE_THREAD_ALLOC) -OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1 -!endif -!endif -!if $(STATIC_BUILD) -OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD -!endif -!if $(TCL_NO_DEPRECATED) -OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED -!endif - -!if !$(DEBUG) -OPTDEFINES = $(OPTDEFINES) -DNDEBUG -!if $(OPTIMIZING) -OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED -!endif -!endif -!if $(PROFILE) -OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED -!endif -!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" -OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT -!endif -!if $(VCVERSION) < 1300 -OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64 -!endif - -#---------------------------------------------------------- -# Locate the Tcl headers to build against -#---------------------------------------------------------- - -!if "$(PROJECT)" == "tcl" - -_TCL_H = ..\generic\tcl.h - -!else - -# If INSTALLDIR set to tcl root dir then reset to the lib dir. -!if exist("$(_INSTALLDIR)\include\tcl.h") -_INSTALLDIR=$(_INSTALLDIR)\lib -!endif - -!if !defined(TCLDIR) -!if exist("$(_INSTALLDIR)\..\include\tcl.h") -TCLINSTALL = 1 -_TCLDIR = $(_INSTALLDIR)\.. -_TCL_H = $(_INSTALLDIR)\..\include\tcl.h -TCLDIR = $(_INSTALLDIR)\.. -!else -MSG=^ -Failed to find tcl.h. Set the TCLDIR macro. -!error $(MSG) -!endif -!else -_TCLDIR = $(TCLDIR:/=\) -!if exist("$(_TCLDIR)\include\tcl.h") -TCLINSTALL = 1 -_TCL_H = $(_TCLDIR)\include\tcl.h -!elseif exist("$(_TCLDIR)\generic\tcl.h") -TCLINSTALL = 0 -_TCL_H = $(_TCLDIR)\generic\tcl.h -!else -MSG =^ -Failed to find tcl.h. The TCLDIR macro does not appear correct. -!error $(MSG) -!endif -!endif -!endif - -#-------------------------------------------------------------- -# Extract various version numbers from tcl headers -# The generated file is then included in the makefile. -#-------------------------------------------------------------- - -!if [echo REM = This file is generated from rules.vc > versions.vc] -!endif -!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \ - && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc] -!endif -!if [echo TCL_MINOR_VERSION = \>> versions.vc] \ - && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc] -!endif -!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \ - && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc] -!endif - -# If building the tcl core then we need additional package versions -!if "$(PROJECT)" == "tcl" -!if [echo PKG_HTTP_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc] -!endif -!if [echo PKG_TCLTEST_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc] -!endif -!if [echo PKG_MSGCAT_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc] -!endif -!if [echo PKG_PLATFORM_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc] -!endif -!if [echo PKG_SHELL_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc] -!endif -!if [echo PKG_DDE_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\dde\pkgIndex.tcl "dde " >> versions.vc] -!endif -!if [echo PKG_REG_VER =\>> versions.vc] \ - && [nmakehlp -V ..\library\reg\pkgIndex.tcl registry >> versions.vc] -!endif -!endif - -!include versions.vc - -#-------------------------------------------------------------- -# Setup tcl version dependent stuff headers -#-------------------------------------------------------------- - -!if "$(PROJECT)" != "tcl" - -TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION) - -!if $(TCLINSTALL) -TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe" -!if !exist($(TCLSH)) -TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:x=).exe" -!endif -TCLSTUBLIB = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib" -TCLIMPLIB = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib" -!if !exist($(TCLIMPLIB)) -TCLIMPLIB = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:x=).lib" -!endif -TCL_LIBRARY = $(_TCLDIR)\lib -TCLREGLIB = "$(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib" -TCLDDELIB = "$(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib" -COFFBASE = \must\have\tcl\sources\to\build\this\target -TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target -TCL_INCLUDES = -I"$(_TCLDIR)\include" -!else -TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe" -!if !exist($(TCLSH)) -TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:x=).exe" -!endif -TCLSTUBLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib" -TCLIMPLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib" -!if !exist($(TCLIMPLIB)) -TCLIMPLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:x=).lib" -!endif -TCL_LIBRARY = $(_TCLDIR)\library -TCLREGLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib" -TCLDDELIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib" -COFFBASE = "$(_TCLDIR)\win\coffbase.txt" -TCLTOOLSDIR = $(_TCLDIR)\tools -TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win" -!endif - -!endif - -#------------------------------------------------------------------------- -# Locate the Tk headers to build against -#------------------------------------------------------------------------- - -!if "$(PROJECT)" == "tk" -_TK_H = ..\generic\tk.h -_INSTALLDIR = $(_INSTALLDIR)\.. -!endif - -!ifdef PROJECT_REQUIRES_TK -!if !defined(TKDIR) -!if exist("$(_INSTALLDIR)\..\include\tk.h") -TKINSTALL = 1 -_TKDIR = $(_INSTALLDIR)\.. -_TK_H = $(_TKDIR)\include\tk.h -TKDIR = $(_TKDIR) -!elseif exist("$(_TCLDIR)\include\tk.h") -TKINSTALL = 1 -_TKDIR = $(_TCLDIR) -_TK_H = $(_TKDIR)\include\tk.h -TKDIR = $(_TKDIR) -!endif -!else -_TKDIR = $(TKDIR:/=\) -!if exist("$(_TKDIR)\include\tk.h") -TKINSTALL = 1 -_TK_H = $(_TKDIR)\include\tk.h -!elseif exist("$(_TKDIR)\generic\tk.h") -TKINSTALL = 0 -_TK_H = $(_TKDIR)\generic\tk.h -!else -MSG =^ -Failed to find tk.h. The TKDIR macro does not appear correct. -!error $(MSG) -!endif -!endif -!endif - -#------------------------------------------------------------------------- -# Extract Tk version numbers -#------------------------------------------------------------------------- - -!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk" - -!if [echo TK_MAJOR_VERSION = \>> versions.vc] \ - && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc] -!endif -!if [echo TK_MINOR_VERSION = \>> versions.vc] \ - && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc] -!endif -!if [echo TK_PATCH_LEVEL = \>> versions.vc] \ - && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc] -!endif - -!include versions.vc - -TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION) -TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION) - -!if "$(PROJECT)" != "tk" -!if $(TKINSTALL) -WISH = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe" -!if !exist($(WISH)) -WISH = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX:x=).exe" -!endif -TKSTUBLIB = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib" -TKIMPLIB = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib" -!if !exist($(TKIMPLIB)) -TKIMPLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX:x=).lib" -!endif -TK_INCLUDES = -I"$(_TKDIR)\include" -!else -WISH = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe" -!if !exist($(WISH)) -WISH = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX:x=).exe" -!endif -TKSTUBLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib" -TKIMPLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib" -!if !exist($(TKIMPLIB)) -TKIMPLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX:x=).lib" -!endif -TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib" -!endif -!endif - -!endif - -#---------------------------------------------------------- -# Display stats being used. -#---------------------------------------------------------- - -!message *** Intermediate directory will be '$(TMP_DIR)' -!message *** Output directory will be '$(OUT_DIR)' -!message *** Suffix for binaries will be '$(SUFX)' -!message *** Optional defines are '$(OPTDEFINES)' -!message *** Compiler version $(VCVER). Target machine is $(MACHINE) -!message *** Host architecture is $(NATIVE_ARCH) -!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)' -!message *** Link options '$(LINKERFLAGS)' - -!endif +#------------------------------------------------------------------------------
+# rules.vc --
+#
+# Microsoft Visual C++ makefile include for decoding the commandline
+# macros. This file does not need editing to build Tcl.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 2001-2003 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+cc32 = $(CC) # built-in default.
+link32 = link
+lib32 = lib
+rc32 = $(RC) # built-in default.
+
+!ifndef INSTALLDIR
+### Assume the normal default.
+_INSTALLDIR = C:\Program Files\Tcl
+!else
+### Fix the path separators.
+_INSTALLDIR = $(INSTALLDIR:/=\)
+!endif
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+!if "$(OS)" == "Windows_NT"
+RMDIR = rmdir /S /Q
+ERRNULL = 2>NUL
+!if ![ver | find "4.0" > nul]
+CPY = echo y | xcopy /i >NUL
+COPY = copy >NUL
+!else
+CPY = xcopy /i /y >NUL
+COPY = copy /y >NUL
+!endif
+!else # "$(OS)" != "Windows_NT"
+CPY = xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
+COPY = copy >_JUNK.OUT # On Win98 NUL does not work here.
+RMDIR = deltree /Y
+NULL = \NUL # Used in testing directory existence
+ERRNULL = >NUL # Win9x shell cannot redirect stderr
+!endif
+MKDIR = mkdir
+
+#------------------------------------------------------------------------------
+# Determine the host and target architectures and compiler version.
+#------------------------------------------------------------------------------
+
+_HASH=^#
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+ && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
+ && ![echo ARCH=IX86 >> vercl.x] \
+ && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
+ && ![echo ARCH=AMD64 >> vercl.x] \
+ && ![echo $(_HASH)endif >> vercl.x] \
+ && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
+!include vercl.i
+!if ![echo VCVER= ^\> vercl.vc] \
+ && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
+!include vercl.vc
+!endif
+!endif
+!if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc]
+!endif
+
+!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
+NATIVE_ARCH=IX86
+!else
+NATIVE_ARCH=AMD64
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+!ifndef MACHINE
+MACHINE=$(ARCH)
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING = \"cp1252\"
+!endif
+
+!message ===============================================================================
+
+#----------------------------------------------------------
+# build the helper app we need to overcome nmake's limiting
+# environment.
+#----------------------------------------------------------
+
+!if !exist(nmakehlp.exe)
+!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
+!endif
+!endif
+
+#----------------------------------------------------------
+# Test for compiler features
+#----------------------------------------------------------
+
+### test for optimizations
+!if [nmakehlp -c -Ot]
+!message *** Compiler has 'Optimizations'
+OPTIMIZING = 1
+!else
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING = 0
+!endif
+
+OPTIMIZATIONS =
+
+!if [nmakehlp -c -Ot]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -Ot
+!endif
+
+!if [nmakehlp -c -Oi]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -Oi
+!endif
+
+!if [nmakehlp -c -Op]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -Op
+!endif
+
+!if [nmakehlp -c -fp:strict]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -fp:strict
+!endif
+
+!if [nmakehlp -c -Gs]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -Gs
+!endif
+
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
+!endif
+
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
+!endif
+
+DEBUGFLAGS =
+
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS = $(DEBUGFLAGS) -GZ
+!endif
+
+COMPILERFLAGS =-W3 -DUNICODE -D_UNICODE
+
+# In v13 -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+!if ![nmakehlp -c -GL]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
+!endif
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+COMPILERFLAGS = $(COMPILERFLAGS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+!if "$(MACHINE)" == "IA64"
+### test for Itanium errata
+!if [nmakehlp -c -QIA64_Bx]
+!message *** Compiler has 'B-stepping errata workarounds'
+COMPILERFLAGS = $(COMPILERFLAGS) -QIA64_Bx
+!else
+!message *** Compiler does not have 'B-stepping errata workarounds'
+!endif
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for -align:4096, when align:512 will do.
+!if [nmakehlp -l -opt:nowin98]
+!message *** Linker has 'Win98 alignment problem'
+ALIGN98_HACK = 1
+!else
+!message *** Linker does not have 'Win98 alignment problem'
+ALIGN98_HACK = 0
+!endif
+!else
+ALIGN98_HACK = 0
+!endif
+
+LINKERFLAGS =
+
+!if [nmakehlp -l -ltcg]
+LINKERFLAGS =-ltcg
+!endif
+
+#----------------------------------------------------------
+# Decode the options requested.
+#----------------------------------------------------------
+
+!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
+STATIC_BUILD = 0
+TCL_THREADS = 1
+DEBUG = 0
+SYMBOLS = 0
+PROFILE = 0
+PGO = 0
+MSVCRT = 1
+LOIMPACT = 0
+TCL_USE_STATIC_PACKAGES = 0
+USE_THREAD_ALLOC = 1
+UNCHECKED = 0
+!else
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD = 1
+!else
+STATIC_BUILD = 0
+!endif
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT = 1
+!else
+!if !$(STATIC_BUILD)
+MSVCRT = 1
+!else
+MSVCRT = 0
+!endif
+!endif
+!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES = 1
+!else
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS = 0
+USE_THREAD_ALLOC= 0
+!else
+TCL_THREADS = 1
+USE_THREAD_ALLOC= 1
+!endif
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG = 1
+!else
+DEBUG = 0
+!endif
+!if [nmakehlp -f $(OPTS) "pdbs"]
+!message *** Doing pdbs
+SYMBOLS = 1
+!else
+SYMBOLS = 0
+!endif
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE = 1
+!else
+PROFILE = 0
+!endif
+!if [nmakehlp -f $(OPTS) "pgi"]
+!message *** Doing profile guided optimization instrumentation
+PGO = 1
+!elseif [nmakehlp -f $(OPTS) "pgo"]
+!message *** Doing profile guided optimization
+PGO = 2
+!else
+PGO = 0
+!endif
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Doing loimpact
+LOIMPACT = 1
+!else
+LOIMPACT = 0
+!endif
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!endif
+!if [nmakehlp -f $(OPTS) "tclalloc"]
+!message *** Doing tclalloc
+USE_THREAD_ALLOC = 0
+!endif
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+!endif
+
+#----------------------------------------------------------
+# Figure-out how to name our intermediate and output directories.
+# We wouldn't want different builds to use the same .obj files
+# by accident.
+#----------------------------------------------------------
+
+#----------------------------------------
+# Naming convention:
+# t = full thread support.
+# s = static library (as opposed to an
+# import library)
+# g = linked to the debug enabled C
+# run-time.
+# x = special static build when it
+# links to the dynamic C run-time.
+#----------------------------------------
+SUFX = tsgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX = $(SUFX:s=)
+EXT = dll
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR = $(TMP_DIR)
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Decode the statistics requested.
+#----------------------------------------------------------
+
+!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]
+TCL_MEM_DEBUG = 0
+TCL_COMPILE_DEBUG = 0
+!else
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG = 1
+!else
+TCL_MEM_DEBUG = 0
+!endif
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG = 1
+!else
+TCL_COMPILE_DEBUG = 0
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Decode the checks requested.
+#----------------------------------------------------------
+
+!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
+TCL_NO_DEPRECATED = 0
+WARNINGS = -W3
+!else
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED = 1
+!else
+TCL_NO_DEPRECATED = 0
+!endif
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS = -W4
+!if [nmakehlp -l -warn:3]
+LINKERFLAGS = $(LINKERFLAGS) -warn:3
+!endif
+!else
+WARNINGS = -W3
+!endif
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS = $(WARNINGS) -Wp64
+!endif
+!endif
+
+!if $(PGO) > 1
+!if [nmakehlp -l -ltcg:pgoptimize]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!elseif $(PGO) > 0
+!if [nmakehlp -l -ltcg:pginstrument]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!endif
+
+#----------------------------------------------------------
+# Set our defines now armed with our options.
+#----------------------------------------------------------
+
+OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if !$(DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DNDEBUG
+!if $(OPTIMIZING)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!endif
+!if $(PROFILE)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+!if $(VCVERSION) < 1300
+OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
+!endif
+
+#----------------------------------------------------------
+# Locate the Tcl headers to build against
+#----------------------------------------------------------
+
+!if "$(PROJECT)" == "tcl"
+
+_TCL_H = ..\generic\tcl.h
+
+!else
+
+# If INSTALLDIR set to tcl root dir then reset to the lib dir.
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+!if !defined(TCLDIR)
+!if exist("$(_INSTALLDIR)\..\include\tcl.h")
+TCLINSTALL = 1
+_TCLDIR = $(_INSTALLDIR)\..
+_TCL_H = $(_INSTALLDIR)\..\include\tcl.h
+TCLDIR = $(_INSTALLDIR)\..
+!else
+MSG=^
+Failed to find tcl.h. Set the TCLDIR macro.
+!error $(MSG)
+!endif
+!else
+_TCLDIR = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h")
+TCLINSTALL = 1
+_TCL_H = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h")
+TCLINSTALL = 0
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!else
+MSG =^
+Failed to find tcl.h. The TCLDIR macro does not appear correct.
+!error $(MSG)
+!endif
+!endif
+!endif
+
+#--------------------------------------------------------------
+# Extract various version numbers from tcl headers
+# The generated file is then included in the makefile.
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
+
+# If building the tcl core then we need additional package versions
+!if "$(PROJECT)" == "tcl"
+!if [echo PKG_HTTP_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc]
+!endif
+!if [echo PKG_TCLTEST_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc]
+!endif
+!if [echo PKG_MSGCAT_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc]
+!endif
+!if [echo PKG_PLATFORM_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc]
+!endif
+!if [echo PKG_SHELL_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc]
+!endif
+!if [echo PKG_DDE_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\dde\pkgIndex.tcl "dde " >> versions.vc]
+!endif
+!if [echo PKG_REG_VER =\>> versions.vc] \
+ && [nmakehlp -V ..\library\reg\pkgIndex.tcl registry >> versions.vc]
+!endif
+!endif
+
+!include versions.vc
+
+#--------------------------------------------------------------
+# Setup tcl version dependent stuff headers
+#--------------------------------------------------------------
+
+!if "$(PROJECT)" != "tcl"
+
+TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+
+!if $(TCLINSTALL)
+TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH))
+TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:x=).exe"
+!endif
+TCLSTUBLIB = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
+TCLIMPLIB = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
+!if !exist($(TCLIMPLIB))
+TCLIMPLIB = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:x=).lib"
+!endif
+TCL_LIBRARY = $(_TCLDIR)\lib
+TCLREGLIB = "$(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib"
+TCLDDELIB = "$(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib"
+COFFBASE = \must\have\tcl\sources\to\build\this\target
+TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES = -I"$(_TCLDIR)\include"
+!else
+TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH))
+TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:x=).exe"
+!endif
+TCLSTUBLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
+TCLIMPLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
+!if !exist($(TCLIMPLIB))
+TCLIMPLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:x=).lib"
+!endif
+TCL_LIBRARY = $(_TCLDIR)\library
+TCLREGLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib"
+TCLDDELIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib"
+COFFBASE = "$(_TCLDIR)\win\coffbase.txt"
+TCLTOOLSDIR = $(_TCLDIR)\tools
+TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+!endif
+
+!endif
+
+#-------------------------------------------------------------------------
+# Locate the Tk headers to build against
+#-------------------------------------------------------------------------
+
+!if "$(PROJECT)" == "tk"
+_TK_H = ..\generic\tk.h
+_INSTALLDIR = $(_INSTALLDIR)\..
+!endif
+
+!ifdef PROJECT_REQUIRES_TK
+!if !defined(TKDIR)
+!if exist("$(_INSTALLDIR)\..\include\tk.h")
+TKINSTALL = 1
+_TKDIR = $(_INSTALLDIR)\..
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+!elseif exist("$(_TCLDIR)\include\tk.h")
+TKINSTALL = 1
+_TKDIR = $(_TCLDIR)
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+!endif
+!else
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL = 1
+_TK_H = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL = 0
+_TK_H = $(_TKDIR)\generic\tk.h
+!else
+MSG =^
+Failed to find tk.h. The TKDIR macro does not appear correct.
+!error $(MSG)
+!endif
+!endif
+!endif
+
+#-------------------------------------------------------------------------
+# Extract Tk version numbers
+#-------------------------------------------------------------------------
+
+!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk"
+
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+
+!include versions.vc
+
+TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+
+!if "$(PROJECT)" != "tk"
+!if $(TKINSTALL)
+WISH = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
+!if !exist($(WISH))
+WISH = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX:x=).exe"
+!endif
+TKSTUBLIB = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
+TKIMPLIB = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
+!if !exist($(TKIMPLIB))
+TKIMPLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX:x=).lib"
+!endif
+TK_INCLUDES = -I"$(_TKDIR)\include"
+!else
+WISH = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(WISH))
+WISH = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX:x=).exe"
+!endif
+TKSTUBLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
+TKIMPLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
+!if !exist($(TKIMPLIB))
+TKIMPLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX:x=).lib"
+!endif
+TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!endif
+!endif
+
+!endif
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Optional defines are '$(OPTDEFINES)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Host architecture is $(NATIVE_ARCH)
+!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
+!message *** Link options '$(LINKERFLAGS)'
+
+!endif
@@ -559,7 +559,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ EXTRA_CFLAGS="" AC_DEFINE(MODULE_SCOPE, [extern], [No need to mark inidividual symbols as hidden]) - AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo) + AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) SHLIB_SUFFIX=".dll" @@ -673,7 +673,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ if test "${GCC}" = "yes" ; then SHLIB_LD="" SHLIB_LD_LIBS='${LIBS}' - LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -lws2_32" + LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -lws2_32" # mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32" STLIB_LD='${AR} cr' @@ -791,6 +791,13 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ # Add SHLIB_LD_LIBS to the Make rule, not here. LIBRARIES="\${SHARED_LIBRARIES}" EXESUFFIX="\${DBGX}.exe" + case "x`echo \${VisualStudioVersion}`" in + x1[[4-9]]*) + lflags="${lflags} -nodefaultlib:libucrt.lib" + ;; + *) + ;; + esac fi MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\[$]@" # DLLSUFFIX is separate because it is the building block for @@ -819,15 +826,21 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ ;; esac if test ! -d "${PATH64}" ; then - AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode]) - AC_MSG_WARN([Ensure latest Platform SDK is installed]) - do64bit="no" - else - AC_MSG_RESULT([ Using 64-bit $MACHINE mode]) + AC_MSG_WARN([Could not find 64-bit $MACHINE SDK]) fi + AC_MSG_RESULT([ Using 64-bit $MACHINE mode]) fi - LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib" + LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib" + + case "x`echo \${VisualStudioVersion}`" in + x1[[4-9]]*) + LIBS="$LIBS ucrt.lib" + ;; + *) + ;; + esac + if test "$do64bit" != "no" ; then # The space-based-path will work for the Makefile, but will # not work if AC_TRY_COMPILE is called. TEA has the @@ -842,7 +855,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d" # Do not use -O2 for Win64 - this has proved buggy in code gen. CFLAGS_OPTIMIZE="-nologo -O1 ${runtime}" - lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" + lflags="${lflags} -nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" # Avoid 'unresolved external symbol __security_cookie' errors. # c.f. http://support.microsoft.com/?id=894573 @@ -854,7 +867,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d" # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy) CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}" - lflags="-nologo" + lflags="${lflags} -nologo" LINKBIN="link" fi diff --git a/win/tkConfig.sh.in b/win/tkConfig.sh.in index 7816b15..c511312 100644 --- a/win/tkConfig.sh.in +++ b/win/tkConfig.sh.in @@ -1,5 +1,5 @@ # tkConfig.sh -- -# +# # This shell script (for sh) is generated automatically by Tk's # configure script. It will create shell variables for most of # the configuration options discovered by the configure script. diff --git a/win/tkWin.h b/win/tkWin.h index adb943b..4d278d7 100644 --- a/win/tkWin.h +++ b/win/tkWin.h @@ -16,7 +16,7 @@ /* * We must specify the lower version we intend to support. In particular * the SystemParametersInfo API doesn't like to receive structures that - * are larger than it expects which affects the font assignements. + * are larger than it expects which affects the font assignments. * * WINVER = 0x0500 means Windows 2000 and above */ @@ -38,9 +38,9 @@ /* * The following messages are used to communicate between a Tk toplevel - * and its container window. A Tk container may not be able to provide - * service to all of the following requests at the moment. But an embedded - * Tk window will send out these requests to support external Tk container + * and its container window. A Tk container may not be able to provide + * service to all of the following requests at the moment. But an embedded + * Tk window will send out these requests to support external Tk container * application. */ @@ -61,7 +61,7 @@ /* * The following are sub-messages (wParam) for TK_INFO. An embedded window may - * send a TK_INFO message with one of the sub-messages to query a container + * send a TK_INFO message with one of the sub-messages to query a container * for verification and availability */ #define TK_CONTAINER_VERIFY 0x01 diff --git a/win/tkWinButton.c b/win/tkWinButton.c index ca6d48e..e46bcb3 100644 --- a/win/tkWinButton.c +++ b/win/tkWinButton.c @@ -1265,21 +1265,29 @@ ButtonProc( return 0; } case BN_CLICKED: { - int code; - Tcl_Interp *interp = butPtr->info.interp; - - if (butPtr->info.state != STATE_DISABLED) { - Tcl_Preserve((ClientData)interp); - code = TkInvokeButton((TkButton*)butPtr); - if (code != TCL_OK && code != TCL_CONTINUE - && code != TCL_BREAK) { - Tcl_AddErrorInfo(interp, "\n (button invoke)"); - Tcl_BackgroundException(interp, code); + /* + * OOPS: chromium fires WM_NULL regularly to ping if plugin is still + * alive. When using an external window (i.e. via the tcl plugin), this + * causes all buttons to fire once a second, so we need to make sure + * that we are not dealing with the chromium life check. + */ + if (wParam != 0 || lParam != 0) { + int code; + Tcl_Interp *interp = butPtr->info.interp; + + if (butPtr->info.state != STATE_DISABLED) { + Tcl_Preserve((ClientData)interp); + code = TkInvokeButton((TkButton*)butPtr); + if (code != TCL_OK && code != TCL_CONTINUE + && code != TCL_BREAK) { + Tcl_AddErrorInfo(interp, "\n (button invoke)"); + Tcl_BackgroundException(interp, code); + } + Tcl_Release((ClientData)interp); } - Tcl_Release((ClientData)interp); + Tcl_ServiceAll(); + return 0; } - Tcl_ServiceAll(); - return 0; } default: diff --git a/win/tkWinClipboard.c b/win/tkWinClipboard.c index 2501688..200883f 100644 --- a/win/tkWinClipboard.c +++ b/win/tkWinClipboard.c @@ -12,6 +12,7 @@ #include "tkWinInt.h" #include "tkSelect.h" +#include <shlobj.h> /* for DROPFILES */ static void UpdateClipboard(HWND hwnd); @@ -52,7 +53,7 @@ TkSelGetSelection( Tcl_DString ds; HGLOBAL handle; Tcl_Encoding encoding; - int result, locale; + int result, locale, noBackslash = 0; if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD")) || (target != XA_STRING) @@ -132,7 +133,37 @@ TkSelGetSelection( if (encoding) { Tcl_FreeEncoding(encoding); } + } else if (IsClipboardFormatAvailable(CF_HDROP)) { + DROPFILES *drop; + handle = GetClipboardData(CF_HDROP); + if (!handle) { + CloseClipboard(); + goto error; + } + Tcl_DStringInit(&ds); + drop = (DROPFILES *) GlobalLock(handle); + if (drop->fWide) { + WCHAR *fname = (WCHAR *) ((char *) drop + drop->pFiles); + Tcl_DString dsTmp; + int count = 0, len; + + while (*fname != 0) { + if (count) { + Tcl_DStringAppend(&ds, "\n", 1); + } + len = Tcl_UniCharLen((Tcl_UniChar *) fname); + Tcl_DStringInit(&dsTmp); + Tcl_UniCharToUtfDString((Tcl_UniChar *) fname, len, &dsTmp); + Tcl_DStringAppend(&ds, Tcl_DStringValue(&dsTmp), + Tcl_DStringLength(&dsTmp)); + Tcl_DStringFree(&dsTmp); + fname += len + 1; + count++; + } + noBackslash = (count > 0); + } + GlobalUnlock(handle); } else { CloseClipboard(); goto error; @@ -146,6 +177,9 @@ TkSelGetSelection( while (*data) { if (data[0] == '\r' && data[1] == '\n') { data++; + } else if (noBackslash && data[0] == '\\') { + data++; + *destPtr++ = '/'; } else { *destPtr++ = *data++; } diff --git a/win/tkWinColor.c b/win/tkWinColor.c index 5eaeeb3..ba9815c 100644 --- a/win/tkWinColor.c +++ b/win/tkWinColor.c @@ -316,7 +316,8 @@ XAllocColor( if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) { unsigned long sizePalette = GetDeviceCaps(dc, SIZEPALETTE); UINT newPixel, closePixel; - int new, refCount; + int new; + size_t refCount; Tcl_HashEntry *entryPtr; UINT index; @@ -361,9 +362,9 @@ XAllocColor( if (new) { refCount = 1; } else { - refCount = (PTR2INT(Tcl_GetHashValue(entryPtr))) + 1; + refCount = (size_t)Tcl_GetHashValue(entryPtr) + 1; } - Tcl_SetHashValue(entryPtr, INT2PTR(refCount)); + Tcl_SetHashValue(entryPtr, (void *)refCount); } else { /* * Determine what color will actually be used on non-colormap systems. @@ -407,7 +408,8 @@ XFreeColors( { TkWinColormap *cmap = (TkWinColormap *) colormap; COLORREF cref; - UINT count, index, refCount; + UINT count, index; + size_t refCount; int i; PALETTEENTRY entry, *entries; Tcl_HashEntry *entryPtr; @@ -427,7 +429,7 @@ XFreeColors( if (!entryPtr) { Tcl_Panic("Tried to free a color that isn't allocated"); } - refCount = PTR2INT(Tcl_GetHashValue(entryPtr)) - 1; + refCount = (size_t)Tcl_GetHashValue(entryPtr) - 1; if (refCount == 0) { cref = pixels[i] & 0x00ffffff; index = GetNearestPaletteIndex(cmap->palette, cref); @@ -444,7 +446,7 @@ XFreeColors( } Tcl_DeleteHashEntry(entryPtr); } else { - Tcl_SetHashValue(entryPtr, INT2PTR(refCount)); + Tcl_SetHashValue(entryPtr, (size_t)refCount); } } } diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h index 6d1a0c9..29fe4ee 100644 --- a/win/tkWinDefault.h +++ b/win/tkWinDefault.h @@ -371,6 +371,7 @@ #define DEF_PANEDWINDOW_HEIGHT "" #define DEF_PANEDWINDOW_OPAQUERESIZE "1" #define DEF_PANEDWINDOW_ORIENT "horizontal" +#define DEF_PANEDWINDOW_PROXYBORDER "2" #define DEF_PANEDWINDOW_RELIEF "flat" #define DEF_PANEDWINDOW_SASHCURSOR "" #define DEF_PANEDWINDOW_SASHPAD "0" diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index baebfc9..d7f63fb 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -14,18 +14,19 @@ #include "tkFont.h" #include <commdlg.h> /* includes common dialog functionality */ -#ifdef _MSC_VER -# pragma comment (lib, "comdlg32.lib") -#endif #include <dlgs.h> /* includes common dialog template defines */ #include <cderr.h> /* includes the common dialog error codes */ #include <shlobj.h> /* includes SHBrowseForFolder */ + #ifdef _MSC_VER # pragma comment (lib, "shell32.lib") +# pragma comment (lib, "comdlg32.lib") +# pragma comment (lib, "uuid.lib") #endif /* These needed for compilation with VC++ 5.2 */ +/* XXX - remove these since need at least VC 6 */ #ifndef BIF_EDITBOX #define BIF_EDITBOX 0x10 #endif @@ -34,6 +35,7 @@ #define BIF_VALIDATE 0x0020 #endif +/* This "new" dialog style is now actually the "old" dialog style post-Vista */ #ifndef BIF_NEWDIALOGSTYLE #define BIF_NEWDIALOGSTYLE 0x0040 #endif @@ -57,6 +59,10 @@ typedef struct ThreadSpecificData { HHOOK hMsgBoxHook; /* Hook proc for tk_messageBox and the */ HICON hSmallIcon; /* icons used by a parent to be used in */ HICON hBigIcon; /* the message box */ + int newFileDialogsState; +#define FDLG_STATE_INIT 0 /* Uninitialized */ +#define FDLG_STATE_USE_NEW 1 /* Use the new dialogs */ +#define FDLG_STATE_USE_OLD 2 /* Use the old dialogs */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -159,6 +165,408 @@ typedef struct OFNData { } OFNData; /* + * The following structure is used to gather options used by various + * file dialogs + */ +typedef struct OFNOpts { + Tk_Window tkwin; /* Owner window for dialog */ + Tcl_Obj *extObj; /* Default extension */ + Tcl_Obj *titleObj; /* Title for dialog */ + Tcl_Obj *filterObj; /* File type filter list */ + Tcl_Obj *typeVariableObj; /* Variable in which to store type selected */ + Tcl_Obj *initialTypeObj; /* Initial value of above, or NULL */ + Tcl_DString utfDirString; /* Initial dir */ + int multi; /* Multiple selection enabled */ + int confirmOverwrite; /* Confirm before overwriting */ + int mustExist; /* Used only for */ + int forceXPStyle; /* XXX - Force XP style even on newer systems */ + TCHAR file[TK_MULTI_MAX_PATH]; /* File name + XXX - fixed size because it was so + historically. Why not malloc'ed ? + XXX - also, TCHAR should really be WCHAR + because TkWinGetUnicodeEncoding is always + UCS2. + */ +} OFNOpts; + +/* Define the operation for which option parsing is to be done. */ +enum OFNOper { + OFN_FILE_SAVE, /* tk_getOpenFile */ + OFN_FILE_OPEN, /* tk_getSaveFile */ + OFN_DIR_CHOOSE /* tk_chooseDirectory */ +}; + + +/* + * The following definitions are required when using older versions of + * Visual C++ (like 6.0) and possibly MingW. Those headers do not contain + * required definitions for interfaces new to Vista that we need for + * the new file dialogs. Duplicating definitions is OK because they + * should forever remain unchanged. + * + * XXX - is there a better/easier way to use new data definitions with + * older compilers? Should we prefix definitions with Tcl_ instead + * of using the same names as in the SDK? + */ +#ifndef __IShellItem_INTERFACE_DEFINED__ +# define __IShellItem_INTERFACE_DEFINED__ +#ifdef __MSVCRT__ +typedef struct IShellItem IShellItem; + +typedef enum __MIDL_IShellItem_0001 { + SIGDN_NORMALDISPLAY = 0,SIGDN_PARENTRELATIVEPARSING = 0x80018001,SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8001c001, + SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000,SIGDN_PARENTRELATIVEEDITING = 0x80031001,SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000, + SIGDN_FILESYSPATH = 0x80058000,SIGDN_URL = 0x80068000 +} SIGDN; + +typedef DWORD SICHINTF; + +typedef struct IShellItemVtbl +{ + BEGIN_INTERFACE + + HRESULT (STDMETHODCALLTYPE *QueryInterface)(IShellItem *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(IShellItem *); + ULONG (STDMETHODCALLTYPE *Release)(IShellItem *); + HRESULT (STDMETHODCALLTYPE *BindToHandler)(IShellItem *, IBindCtx *, REFGUID, REFIID, void **); + HRESULT (STDMETHODCALLTYPE *GetParent)(IShellItem *, IShellItem **); + HRESULT (STDMETHODCALLTYPE *GetDisplayName)(IShellItem *, SIGDN, LPOLESTR *); + HRESULT (STDMETHODCALLTYPE *GetAttributes)(IShellItem *, SFGAOF, SFGAOF *); + HRESULT (STDMETHODCALLTYPE *Compare)(IShellItem *, IShellItem *, SICHINTF, int *); + + END_INTERFACE +} IShellItemVtbl; +struct IShellItem { + CONST_VTBL struct IShellItemVtbl *lpVtbl; +}; +#endif +#endif + +#ifndef __IShellItemArray_INTERFACE_DEFINED__ +#define __IShellItemArray_INTERFACE_DEFINED__ + +typedef enum SIATTRIBFLAGS { + SIATTRIBFLAGS_AND = 0x1, + SIATTRIBFLAGS_OR = 0x2, + SIATTRIBFLAGS_APPCOMPAT = 0x3, + SIATTRIBFLAGS_MASK = 0x3, + SIATTRIBFLAGS_ALLITEMS = 0x4000 +} SIATTRIBFLAGS; +#ifdef __MSVCRT__ +typedef ULONG SFGAOF; +#endif /* __MSVCRT__ */ +typedef struct IShellItemArray IShellItemArray; +typedef struct IShellItemArrayVtbl +{ + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IShellItemArray *, REFIID riid,void **ppvObject); + ULONG ( STDMETHODCALLTYPE *AddRef )(IShellItemArray *); + ULONG ( STDMETHODCALLTYPE *Release )(IShellItemArray *); + HRESULT ( STDMETHODCALLTYPE *BindToHandler )(IShellItemArray *, + IBindCtx *, REFGUID, REFIID, void **); + /* flags is actually is enum GETPROPERTYSTOREFLAGS */ + HRESULT ( STDMETHODCALLTYPE *GetPropertyStore )( + IShellItemArray *, int, REFIID, void **); + /* keyType actually REFPROPERTYKEY */ + HRESULT ( STDMETHODCALLTYPE *GetPropertyDescriptionList )( + IShellItemArray *, void *, REFIID, void **); + HRESULT ( STDMETHODCALLTYPE *GetAttributes )(IShellItemArray *, + SIATTRIBFLAGS, SFGAOF, SFGAOF *); + HRESULT ( STDMETHODCALLTYPE *GetCount )( + IShellItemArray *, DWORD *); + HRESULT ( STDMETHODCALLTYPE *GetItemAt )( + IShellItemArray *, DWORD, IShellItem **); + /* ppenumShellItems actually (IEnumShellItems **) */ + HRESULT ( STDMETHODCALLTYPE *EnumItems )( + IShellItemArray *, void **); + + END_INTERFACE +} IShellItemArrayVtbl; + +struct IShellItemArray { + CONST_VTBL struct IShellItemArrayVtbl *lpVtbl; +}; + +#endif /* __IShellItemArray_INTERFACE_DEFINED__ */ + +/* + * Older compilers do not define these CLSIDs so we do so here under + * a slightly different name so as to not clash with the definitions + * in new compilers + */ +static const CLSID ClsidFileOpenDialog = { + 0xDC1C5A9C, 0xE88A, 0X4DDE, {0xA5, 0xA1, 0x60, 0xF8, 0x2A, 0x20, 0xAE, 0xF7} +}; +static const CLSID ClsidFileSaveDialog = { + 0xC0B4E2F3, 0xBA21, 0x4773, {0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B} +}; +static const IID IIDIFileOpenDialog = { + 0xD57C7288, 0xD4AD, 0x4768, {0xBE, 0x02, 0x9D, 0x96, 0x95, 0x32, 0xD9, 0x60} +}; +static const IID IIDIFileSaveDialog = { + 0x84BCCD23, 0x5FDE, 0x4CDB, {0xAE, 0xA4, 0xAF, 0x64, 0xB8, 0x3D, 0x78, 0xAB} +}; +static const IID IIDIShellItem = { + 0x43826D1E, 0xE718, 0x42EE, {0xBC, 0x55, 0xA1, 0xE2, 0x61, 0xC3, 0x7B, 0xFE} +}; + +#ifdef __IFileDialog_INTERFACE_DEFINED__ +# define TCLCOMDLG_FILTERSPEC COMDLG_FILTERSPEC +#else + +/* Forward declarations for structs that are referenced but not used */ +typedef struct IPropertyStore IPropertyStore; +typedef struct IPropertyDescriptionList IPropertyDescriptionList; +typedef struct IFileOperationProgressSink IFileOperationProgressSink; +typedef enum FDAP { + FDAP_BOTTOM = 0, + FDAP_TOP = 1 +} FDAP; + +typedef struct { + LPCWSTR pszName; + LPCWSTR pszSpec; +} TCLCOMDLG_FILTERSPEC; + +enum _FILEOPENDIALOGOPTIONS { + FOS_OVERWRITEPROMPT = 0x2, + FOS_STRICTFILETYPES = 0x4, + FOS_NOCHANGEDIR = 0x8, + FOS_PICKFOLDERS = 0x20, + FOS_FORCEFILESYSTEM = 0x40, + FOS_ALLNONSTORAGEITEMS = 0x80, + FOS_NOVALIDATE = 0x100, + FOS_ALLOWMULTISELECT = 0x200, + FOS_PATHMUSTEXIST = 0x800, + FOS_FILEMUSTEXIST = 0x1000, + FOS_CREATEPROMPT = 0x2000, + FOS_SHAREAWARE = 0x4000, + FOS_NOREADONLYRETURN = 0x8000, + FOS_NOTESTFILECREATE = 0x10000, + FOS_HIDEMRUPLACES = 0x20000, + FOS_HIDEPINNEDPLACES = 0x40000, + FOS_NODEREFERENCELINKS = 0x100000, + FOS_DONTADDTORECENT = 0x2000000, + FOS_FORCESHOWHIDDEN = 0x10000000, + FOS_DEFAULTNOMINIMODE = 0x20000000, + FOS_FORCEPREVIEWPANEON = 0x40000000 +} ; +typedef DWORD FILEOPENDIALOGOPTIONS; + +typedef struct IFileDialog IFileDialog; +typedef struct IFileDialogVtbl +{ + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFileDialog *, REFIID, void **); + ULONG ( STDMETHODCALLTYPE *AddRef )( IFileDialog *); + ULONG ( STDMETHODCALLTYPE *Release )( IFileDialog *); + HRESULT ( STDMETHODCALLTYPE *Show )( IFileDialog *, HWND); + HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( IFileDialog *, + UINT, const TCLCOMDLG_FILTERSPEC *); + HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )(IFileDialog *, UINT); + HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )(IFileDialog *, UINT *); + /* XXX - Actually pfde is IFileDialogEvents* but we do not use + this call and do not want to define IFileDialogEvents as that + pulls in a whole bunch of other stuff. */ + HRESULT ( STDMETHODCALLTYPE *Advise )( + IFileDialog *, void *, DWORD *); + HRESULT ( STDMETHODCALLTYPE *Unadvise )(IFileDialog *, DWORD); + HRESULT ( STDMETHODCALLTYPE *SetOptions )( + IFileDialog *, FILEOPENDIALOGOPTIONS); + HRESULT ( STDMETHODCALLTYPE *GetOptions )( + IFileDialog *, FILEOPENDIALOGOPTIONS *); + HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )( + IFileDialog *, IShellItem *); + HRESULT ( STDMETHODCALLTYPE *SetFolder )( + IFileDialog *, IShellItem *); + HRESULT ( STDMETHODCALLTYPE *GetFolder )( + IFileDialog *, IShellItem **); + HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )( + IFileDialog *, IShellItem **); + HRESULT ( STDMETHODCALLTYPE *SetFileName )( + IFileDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *GetFileName )( + IFileDialog *, LPWSTR *); + HRESULT ( STDMETHODCALLTYPE *SetTitle )( + IFileDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )( + IFileDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )( + IFileDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *GetResult )( + IFileDialog *, IShellItem **); + HRESULT ( STDMETHODCALLTYPE *AddPlace )( + IFileDialog *, IShellItem *, FDAP); + HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )( + IFileDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *Close )( IFileDialog *, HRESULT); + HRESULT ( STDMETHODCALLTYPE *SetClientGuid )( + IFileDialog *, REFGUID); + HRESULT ( STDMETHODCALLTYPE *ClearClientData )( IFileDialog *); + /* pFilter actually IShellItemFilter. But deprecated in Win7 AND we do + not use it anyways. So define as void* */ + HRESULT ( STDMETHODCALLTYPE *SetFilter )( + IFileDialog *, void *); + + END_INTERFACE +} IFileDialogVtbl; + +struct IFileDialog { + CONST_VTBL struct IFileDialogVtbl *lpVtbl; +}; + + +typedef struct IFileSaveDialog IFileSaveDialog; +typedef struct IFileSaveDialogVtbl { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFileSaveDialog *, REFIID, void **); + ULONG ( STDMETHODCALLTYPE *AddRef )( IFileSaveDialog *); + ULONG ( STDMETHODCALLTYPE *Release )( IFileSaveDialog *); + HRESULT ( STDMETHODCALLTYPE *Show )( + IFileSaveDialog *, HWND); + HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( IFileSaveDialog * this, + UINT, const TCLCOMDLG_FILTERSPEC *); + HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )( + IFileSaveDialog *, UINT); + HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )( + IFileSaveDialog *, UINT *); + /* Actually pfde is IFileSaveDialogEvents* */ + HRESULT ( STDMETHODCALLTYPE *Advise )( + IFileSaveDialog *, void *, DWORD *); + HRESULT ( STDMETHODCALLTYPE *Unadvise )( IFileSaveDialog *, DWORD); + HRESULT ( STDMETHODCALLTYPE *SetOptions )( + IFileSaveDialog *, FILEOPENDIALOGOPTIONS); + HRESULT ( STDMETHODCALLTYPE *GetOptions )( + IFileSaveDialog *, FILEOPENDIALOGOPTIONS *); + HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )( + IFileSaveDialog *, IShellItem *); + HRESULT ( STDMETHODCALLTYPE *SetFolder )( + IFileSaveDialog *, IShellItem *); + HRESULT ( STDMETHODCALLTYPE *GetFolder )( + IFileSaveDialog *, IShellItem **); + HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )( + IFileSaveDialog *, IShellItem **); + HRESULT ( STDMETHODCALLTYPE *SetFileName )( + IFileSaveDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *GetFileName )( + IFileSaveDialog *, LPWSTR *); + HRESULT ( STDMETHODCALLTYPE *SetTitle )( + IFileSaveDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )( + IFileSaveDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )( + IFileSaveDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *GetResult )( + IFileSaveDialog *, IShellItem **); + HRESULT ( STDMETHODCALLTYPE *AddPlace )( + IFileSaveDialog *, IShellItem *, FDAP); + HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )( + IFileSaveDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *Close )( IFileSaveDialog *, HRESULT); + HRESULT ( STDMETHODCALLTYPE *SetClientGuid )( + IFileSaveDialog *, REFGUID); + HRESULT ( STDMETHODCALLTYPE *ClearClientData )( IFileSaveDialog *); + /* pFilter Actually IShellItemFilter* */ + HRESULT ( STDMETHODCALLTYPE *SetFilter )( + IFileSaveDialog *, void *); + HRESULT ( STDMETHODCALLTYPE *SetSaveAsItem )( + IFileSaveDialog *, IShellItem *); + HRESULT ( STDMETHODCALLTYPE *SetProperties )( + IFileSaveDialog *, IPropertyStore *); + HRESULT ( STDMETHODCALLTYPE *SetCollectedProperties )( + IFileSaveDialog *, IPropertyDescriptionList *, BOOL); + HRESULT ( STDMETHODCALLTYPE *GetProperties )( + IFileSaveDialog *, IPropertyStore **); + HRESULT ( STDMETHODCALLTYPE *ApplyProperties )( + IFileSaveDialog *, IShellItem *, IPropertyStore *, + HWND, IFileOperationProgressSink *); + + END_INTERFACE + +} IFileSaveDialogVtbl; + +struct IFileSaveDialog { + CONST_VTBL struct IFileSaveDialogVtbl *lpVtbl; +}; + +typedef struct IFileOpenDialog IFileOpenDialog; +typedef struct IFileOpenDialogVtbl { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFileOpenDialog *, REFIID, void **); + ULONG ( STDMETHODCALLTYPE *AddRef )( IFileOpenDialog *); + ULONG ( STDMETHODCALLTYPE *Release )( IFileOpenDialog *); + HRESULT ( STDMETHODCALLTYPE *Show )( IFileOpenDialog *, HWND); + HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( IFileOpenDialog *, + UINT, const TCLCOMDLG_FILTERSPEC *); + HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )( + IFileOpenDialog *, UINT); + HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )( + IFileOpenDialog *, UINT *); + /* Actually pfde is IFileDialogEvents* */ + HRESULT ( STDMETHODCALLTYPE *Advise )( + IFileOpenDialog *, void *, DWORD *); + HRESULT ( STDMETHODCALLTYPE *Unadvise )( IFileOpenDialog *, DWORD); + HRESULT ( STDMETHODCALLTYPE *SetOptions )( + IFileOpenDialog *, FILEOPENDIALOGOPTIONS); + HRESULT ( STDMETHODCALLTYPE *GetOptions )( + IFileOpenDialog *, FILEOPENDIALOGOPTIONS *); + HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )( + IFileOpenDialog *, IShellItem *); + HRESULT ( STDMETHODCALLTYPE *SetFolder )( + IFileOpenDialog *, IShellItem *); + HRESULT ( STDMETHODCALLTYPE *GetFolder )( + IFileOpenDialog *, IShellItem **); + HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )( + IFileOpenDialog *, IShellItem **); + HRESULT ( STDMETHODCALLTYPE *SetFileName )( + IFileOpenDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *GetFileName )( + IFileOpenDialog *, LPWSTR *); + HRESULT ( STDMETHODCALLTYPE *SetTitle )( + IFileOpenDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )( + IFileOpenDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )( + IFileOpenDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *GetResult )( + IFileOpenDialog *, IShellItem **); + HRESULT ( STDMETHODCALLTYPE *AddPlace )( + IFileOpenDialog *, IShellItem *, FDAP); + HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )( + IFileOpenDialog *, LPCWSTR); + HRESULT ( STDMETHODCALLTYPE *Close )( IFileOpenDialog *, HRESULT); + HRESULT ( STDMETHODCALLTYPE *SetClientGuid )( + IFileOpenDialog *, REFGUID); + HRESULT ( STDMETHODCALLTYPE *ClearClientData )( + IFileOpenDialog *); + HRESULT ( STDMETHODCALLTYPE *SetFilter )( + IFileOpenDialog *, + /* pFilter is actually IShellItemFilter */ + void *); + HRESULT ( STDMETHODCALLTYPE *GetResults )( + IFileOpenDialog *, IShellItemArray **); + HRESULT ( STDMETHODCALLTYPE *GetSelectedItems )( + IFileOpenDialog *, IShellItemArray **); + + END_INTERFACE +} IFileOpenDialogVtbl; + +struct IFileOpenDialog +{ + CONST_VTBL struct IFileOpenDialogVtbl *lpVtbl; +}; + +#endif /* __IFileDialog_INTERFACE_DEFINED__ */ + +/* * Definitions of functions used only in this file. */ @@ -166,9 +574,21 @@ static UINT APIENTRY ChooseDirectoryValidateProc(HWND hdlg, UINT uMsg, LPARAM wParam, LPARAM lParam); static UINT CALLBACK ColorDlgHookProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +static void CleanupOFNOptions(OFNOpts *optsPtr); +static int ParseOFNOptions(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[], enum OFNOper oper, OFNOpts *optsPtr); +static int GetFileNameXP(Tcl_Interp *interp, OFNOpts *optsPtr, + enum OFNOper oper); +static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, + enum OFNOper oper); static int GetFileName(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[], int isOpen); + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[], enum OFNOper oper); +static int MakeFilterVista(Tcl_Interp *interp, OFNOpts *optsPtr, + DWORD *countPtr, TCLCOMDLG_FILTERSPEC **dlgFilterPtrPtr, + DWORD *defaultFilterIndexPtr); +static void FreeFilterVista(DWORD count, TCLCOMDLG_FILTERSPEC *dlgFilterPtr); static int MakeFilter(Tcl_Interp *interp, Tcl_Obj *valuePtr, Tcl_DString *dsPtr, Tcl_Obj *initialPtr, int *indexPtr); @@ -178,6 +598,66 @@ static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam); static void SetTkDialog(ClientData clientData); static const char *ConvertExternalFilename(TCHAR *filename, Tcl_DString *dsPtr); +static void LoadShellProcs(void); + + +/* Definitions of dynamically loaded Win32 calls */ +typedef HRESULT (STDAPICALLTYPE SHCreateItemFromParsingNameProc)( + PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv); +struct ShellProcPointers { + SHCreateItemFromParsingNameProc *SHCreateItemFromParsingName; +} ShellProcs; + + +/* + *------------------------------------------------------------------------- + * + * LoadShellProcs -- + * + * Some shell functions are not available on older versions of + * Windows. This function dynamically loads them and stores pointers + * to them in ShellProcs. Any function that is not available has + * the corresponding pointer set to NULL. + * + * Note this call never fails. Unavailability of a function is not + * a reason for failure. Caller should check whether a particular + * function pointer is NULL or not. Once loaded a function stays + * forever loaded. + * + * XXX - we load the function pointers into global memory. This implies + * there is a potential (however small) for race conditions between + * threads. However, Tk is in any case meant to be loaded in exactly + * one thread so this should not be an issue and saves us from + * unnecessary bookkeeping. + * + * Return value: + * None. + * + * Side effects: + * ShellProcs is populated. + *------------------------------------------------------------------------- + */ +static void LoadShellProcs() +{ + static HMODULE shell32_handle = NULL; + + if (shell32_handle != NULL) + return; /* We have already been through here. */ + + /* + * XXX - Note we never call FreeLibrary. There is no point because + * shell32.dll is loaded at startup anyways and stays for the duration + * of the process so why bother with keeping track of when to unload + */ + shell32_handle = LoadLibrary(TEXT("shell32.dll")); + if (shell32_handle == NULL) /* Should never happen but check anyways. */ + return; + + ShellProcs.SHCreateItemFromParsingName = + (SHCreateItemFromParsingNameProc*) GetProcAddress(shell32_handle, + "SHCreateItemFromParsingName"); +} + /* *------------------------------------------------------------------------- @@ -487,7 +967,7 @@ Tk_GetOpenFileObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - return GetFileName(clientData, interp, objc, objv, 1); + return GetFileName(clientData, interp, objc, objv, OFN_FILE_OPEN); } /* @@ -514,51 +994,61 @@ Tk_GetSaveFileObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - return GetFileName(clientData, interp, objc, objv, 0); + return GetFileName(clientData, interp, objc, objv, OFN_FILE_SAVE); } /* *---------------------------------------------------------------------- * - * GetFileName -- + * CleanupOFNOptions -- * - * Calls GetOpenFileName() or GetSaveFileName(). + * Cleans up any storage allocated by ParseOFNOptions * * Results: - * See user documentation. + * None. * * Side effects: - * See user documentation. + * Releases resources held by *optsPtr + *---------------------------------------------------------------------- + */ +static void CleanupOFNOptions(OFNOpts *optsPtr) +{ + Tcl_DStringFree(&optsPtr->utfDirString); +} + + + +/* + *---------------------------------------------------------------------- * + * ParseOFNOptions -- + * + * Option parsing for tk_get{Open,Save}File + * + * Results: + * TCL_OK on success, TCL_ERROR otherwise + * + * Side effects: + * Returns option values in *optsPtr. Note these may include string + * pointers into objv[] *---------------------------------------------------------------------- */ static int -GetFileName( +ParseOFNOptions( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[], /* Argument objects. */ - int open) /* 1 to call GetOpenFileName(), 0 to call - * GetSaveFileName(). */ + enum OFNOper oper, /* 1 for Open, 0 for Save */ + OFNOpts *optsPtr) /* Output, uninitialized on entry */ { - OPENFILENAME ofn; - TCHAR file[TK_MULTI_MAX_PATH]; - OFNData ofnData; - int cdlgerr; - int filterIndex = 0, result = TCL_ERROR, winCode, oldMode, i, multi = 0; - int confirmOverwrite = 1; - const char *extension = NULL, *title = NULL; - Tk_Window tkwin = clientData; - HWND hWnd; - Tcl_Obj *filterObj = NULL, *initialTypeObj = NULL, *typeVariableObj = NULL; - Tcl_DString utfFilterString, utfDirString, ds; - Tcl_DString extString, filterString, dirString, titleString; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + int i; + Tcl_DString ds; enum options { FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE, FILE_PARENT, - FILE_TITLE, FILE_TYPEVARIABLE, FILE_MULTIPLE, FILE_CONFIRMOW + FILE_TITLE, FILE_TYPEVARIABLE, FILE_MULTIPLE, FILE_CONFIRMOW, + FILE_MUSTEXIST, }; struct Options { const char *name; @@ -586,115 +1076,528 @@ GetFileName( {"-typevariable", FILE_TYPEVARIABLE}, {NULL, FILE_DEFAULT/*ignored*/ } }; - const struct Options *const options = open ? openOptions : saveOptions; + static const struct Options dirOptions[] = { + {"-initialdir", FILE_INITDIR}, + {"-mustexist", FILE_MUSTEXIST}, + {"-parent", FILE_PARENT}, + {"-title", FILE_TITLE}, + {NULL, FILE_DEFAULT/*ignored*/ } + }; - file[0] = '\0'; - ZeroMemory(&ofnData, sizeof(OFNData)); - Tcl_DStringInit(&utfFilterString); - Tcl_DStringInit(&utfDirString); + const struct Options *options = NULL; - /* - * Parse the arguments. - */ + switch (oper) { + case OFN_FILE_SAVE: options = saveOptions; break; + case OFN_DIR_CHOOSE: options = dirOptions; break; + case OFN_FILE_OPEN: options = openOptions; break; + } + + ZeroMemory(optsPtr, sizeof(*optsPtr)); + // optsPtr->forceXPStyle = 1; + optsPtr->tkwin = clientData; + optsPtr->confirmOverwrite = 1; /* By default we ask for confirmation */ + Tcl_DStringInit(&optsPtr->utfDirString); + optsPtr->file[0] = 0; for (i = 1; i < objc; i += 2) { int index; const char *string; - Tcl_Obj *valuePtr = objv[i + 1]; + Tcl_Obj *valuePtr; if (Tcl_GetIndexFromObjStruct(interp, objv[i], options, sizeof(struct Options), "option", 0, &index) != TCL_OK) { - goto end; + /* + * XXX -xpstyle is explicitly checked for as it is undocumented + * and we do not want it to show in option error messages. + */ + if (strcmp(Tcl_GetString(objv[i]), "-xpstyle")) + goto error_return; + if (i + 1 == objc) { + Tcl_SetResult(interp, "value for \"-xpstyle\" missing", TCL_STATIC); + Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL); + goto error_return; + } + if (Tcl_GetBooleanFromObj(interp, objv[i+1], + &optsPtr->forceXPStyle) != TCL_OK) + goto error_return; + + continue; + } else if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", options[index].name)); - Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL); - goto end; + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", options[index].name)); + Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL); + goto error_return; } + valuePtr = objv[i + 1]; string = Tcl_GetString(valuePtr); switch (options[index].value) { case FILE_DEFAULT: - if (string[0] == '.') { - string++; - } - extension = string; + optsPtr->extObj = valuePtr; break; case FILE_TYPES: - filterObj = valuePtr; + optsPtr->filterObj = valuePtr; break; case FILE_INITDIR: - Tcl_DStringFree(&utfDirString); + Tcl_DStringFree(&optsPtr->utfDirString); if (Tcl_TranslateFileName(interp, string, - &utfDirString) == NULL) { - goto end; - } + &optsPtr->utfDirString) == NULL) + goto error_return; break; case FILE_INITFILE: - if (Tcl_TranslateFileName(interp, string, &ds) == NULL) { - goto end; - } + if (Tcl_TranslateFileName(interp, string, &ds) == NULL) + goto error_return; Tcl_UtfToExternal(NULL, TkWinGetUnicodeEncoding(), - Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), 0, NULL, - (char *) file, sizeof(file), NULL, NULL, NULL); + Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), 0, NULL, + (char *) &optsPtr->file[0], sizeof(optsPtr->file), + NULL, NULL, NULL); Tcl_DStringFree(&ds); break; case FILE_PARENT: - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { - goto end; - } + optsPtr->tkwin = Tk_NameToWindow(interp, string, clientData); + if (optsPtr->tkwin == NULL) + goto error_return; break; case FILE_TITLE: - title = string; + optsPtr->titleObj = valuePtr; break; case FILE_TYPEVARIABLE: - typeVariableObj = valuePtr; - initialTypeObj = Tcl_ObjGetVar2(interp, typeVariableObj, NULL, - TCL_GLOBAL_ONLY); + optsPtr->typeVariableObj = valuePtr; + optsPtr->initialTypeObj = Tcl_ObjGetVar2(interp, valuePtr, + NULL, TCL_GLOBAL_ONLY); break; case FILE_MULTIPLE: - if (Tcl_GetBooleanFromObj(interp, valuePtr, &multi) != TCL_OK) { - return TCL_ERROR; - } + if (Tcl_GetBooleanFromObj(interp, valuePtr, + &optsPtr->multi) != TCL_OK) + goto error_return; break; case FILE_CONFIRMOW: if (Tcl_GetBooleanFromObj(interp, valuePtr, - &confirmOverwrite) != TCL_OK) { - return TCL_ERROR; - } + &optsPtr->confirmOverwrite) != TCL_OK) + goto error_return; break; + case FILE_MUSTEXIST: + if (Tcl_GetBooleanFromObj(interp, valuePtr, + &optsPtr->mustExist) != TCL_OK) + goto error_return; + break; } } - if (MakeFilter(interp, filterObj, &utfFilterString, initialTypeObj, - &filterIndex) != TCL_OK) { + return TCL_OK; + +error_return: /* interp should already hold error */ + /* On error, we need to clean up anything we might have allocated */ + CleanupOFNOptions(optsPtr); + return TCL_ERROR; + +} + + +/* + *---------------------------------------------------------------------- + * VistaFileDialogsAvailable + * + * Checks whether the new (Vista) file dialogs can be used on + * the system. + * + * Returns: + * 1 if new dialogs are available, 0 otherwise + * + * Side effects: + * Loads required procedures dynamically if available. + * If new dialogs are available, COM is also initialized. + *---------------------------------------------------------------------- + */ +static int VistaFileDialogsAvailable() +{ + HRESULT hr; + IFileDialog *fdlgPtr = NULL; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + if (tsdPtr->newFileDialogsState == FDLG_STATE_INIT) { + tsdPtr->newFileDialogsState = FDLG_STATE_USE_OLD; + LoadShellProcs(); + if (ShellProcs.SHCreateItemFromParsingName != NULL) { + hr = CoInitialize(0); + /* XXX - need we schedule CoUninitialize at thread shutdown ? */ + + /* Ensure all COM interfaces we use are available */ + if (SUCCEEDED(hr)) { + hr = CoCreateInstance(&ClsidFileOpenDialog, NULL, + CLSCTX_INPROC_SERVER, &IIDIFileOpenDialog, (void **) &fdlgPtr); + if (SUCCEEDED(hr)) { + fdlgPtr->lpVtbl->Release(fdlgPtr); + hr = CoCreateInstance(&ClsidFileSaveDialog, NULL, + CLSCTX_INPROC_SERVER, &IIDIFileSaveDialog, + (void **) &fdlgPtr); + if (SUCCEEDED(hr)) { + fdlgPtr->lpVtbl->Release(fdlgPtr); + + /* Looks like we have all we need */ + tsdPtr->newFileDialogsState = FDLG_STATE_USE_NEW; + } + } + } + } + } + + return (tsdPtr->newFileDialogsState == FDLG_STATE_USE_NEW); +} + +/* + *---------------------------------------------------------------------- + * + * GetFileNameVista -- + * + * Displays the new file dialogs on Vista and later. + * This function must generally not be called unless the + * tsdPtr->newFileDialogsState is FDLG_STATE_USE_NEW but if + * it is, it will just pass the call to the older GetFileNameXP + * + * Results: + * TCL_OK - dialog was successfully displayed, results returned in interp + * TCL_ERROR - error return + * + * Side effects: + * Dialogs is displayed + *---------------------------------------------------------------------- + */ +static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, + enum OFNOper oper) +{ + HRESULT hr; + HWND hWnd; + DWORD flags, nfilters, defaultFilterIndex; + TCLCOMDLG_FILTERSPEC *filterPtr = NULL; + IFileDialog *fdlgIf = NULL; + IShellItem *dirIf = NULL; + LPWSTR wstr; + Tcl_Obj *resultObj = NULL; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + int oldMode; + + if (tsdPtr->newFileDialogsState != FDLG_STATE_USE_NEW) { + /* XXX - should be an assert but Tcl does not seem to have one? */ + Tcl_SetResult(interp, "Internal error: GetFileNameVista: IFileDialog API not available", TCL_STATIC); + return TCL_ERROR; + } + + /* + * At this point new interfaces are supposed to be available. + * fdlgIf is actually a IFileOpenDialog or IFileSaveDialog + * both of which inherit from IFileDialog. We use the common + * IFileDialog interface for the most part, casting only for + * type-specific calls. + */ + Tk_MakeWindowExist(optsPtr->tkwin); + hWnd = Tk_GetHWND(Tk_WindowId(optsPtr->tkwin)); + + /* + * The only validation we need to do w.r.t caller supplied data + * is the filter specification so do that before creating + */ + if (MakeFilterVista(interp, optsPtr, &nfilters, &filterPtr, + &defaultFilterIndex) != TCL_OK) + return TCL_ERROR; + + /* + * Beyond this point, do not just return on error as there will be + * resources that need to be released/freed. + */ + + if (oper == OFN_FILE_OPEN || oper == OFN_DIR_CHOOSE) + hr = CoCreateInstance(&ClsidFileOpenDialog, NULL, + CLSCTX_INPROC_SERVER, &IIDIFileOpenDialog, (void **) &fdlgIf); + else + hr = CoCreateInstance(&ClsidFileSaveDialog, NULL, + CLSCTX_INPROC_SERVER, &IIDIFileSaveDialog, (void **) &fdlgIf); + + if (FAILED(hr)) + goto vamoose; + + /* + * Get current settings first because we want to preserve existing + * settings like whether to show hidden files etc. based on the + * user's existing preference + */ + hr = fdlgIf->lpVtbl->GetOptions(fdlgIf, &flags); + if (FAILED(hr)) + goto vamoose; + + if (filterPtr) { + /* + * Causes -filetypes {{All *}} -defaultextension ext to return + * foo.ext.ext when foo is typed into the entry box + * flags |= FOS_STRICTFILETYPES; + */ + hr = fdlgIf->lpVtbl->SetFileTypes(fdlgIf, nfilters, filterPtr); + if (FAILED(hr)) + goto vamoose; + hr = fdlgIf->lpVtbl->SetFileTypeIndex(fdlgIf, defaultFilterIndex); + if (FAILED(hr)) + goto vamoose; + } + + /* Flags are equivalent to those we used in the older API */ + + /* + * Following flags must be set irrespective of original setting + * XXX - should FOS_NOVALIDATE be there ? Note FOS_NOVALIDATE has different + * semantics than OFN_NOVALIDATE in the old API. + */ + flags |= + FOS_FORCEFILESYSTEM | /* Only want files, not other shell items */ + FOS_NOVALIDATE | /* Don't check for access denied etc. */ + FOS_PATHMUSTEXIST; /* The *directory* path must exist */ + + + if (oper == OFN_DIR_CHOOSE) { + flags |= FOS_PICKFOLDERS; + if (optsPtr->mustExist) + flags |= FOS_FILEMUSTEXIST; /* XXX - check working */ + } else + flags &= ~ FOS_PICKFOLDERS; + + if (optsPtr->multi) + flags |= FOS_ALLOWMULTISELECT; + else + flags &= ~FOS_ALLOWMULTISELECT; + + if (optsPtr->confirmOverwrite) + flags |= FOS_OVERWRITEPROMPT; + else + flags &= ~FOS_OVERWRITEPROMPT; + + hr = fdlgIf->lpVtbl->SetOptions(fdlgIf, flags); + if (FAILED(hr)) + goto vamoose; + + if (optsPtr->extObj != NULL) { + wstr = Tcl_GetUnicode(optsPtr->extObj); + if (wstr[0] == L'.') + ++wstr; + hr = fdlgIf->lpVtbl->SetDefaultExtension(fdlgIf, wstr); + if (FAILED(hr)) + goto vamoose; + } + + if (optsPtr->titleObj != NULL) { + hr = fdlgIf->lpVtbl->SetTitle(fdlgIf, + Tcl_GetUnicode(optsPtr->titleObj)); + if (FAILED(hr)) + goto vamoose; + } + + if (optsPtr->file[0]) { + hr = fdlgIf->lpVtbl->SetFileName(fdlgIf, optsPtr->file); + if (FAILED(hr)) + goto vamoose; + } + + if (Tcl_DStringValue(&optsPtr->utfDirString)[0] != '\0') { + Tcl_Obj *normPath, *iniDirPath; + iniDirPath = Tcl_NewStringObj(Tcl_DStringValue(&optsPtr->utfDirString), -1); + Tcl_IncrRefCount(iniDirPath); + normPath = Tcl_FSGetNormalizedPath(interp, iniDirPath); + /* XXX - Note on failures do not raise error, simply ignore ini dir */ + if (normPath) { + const WCHAR *nativePath; + Tcl_IncrRefCount(normPath); + nativePath = Tcl_FSGetNativePath(normPath); /* Points INTO normPath*/ + if (nativePath) { + hr = ShellProcs.SHCreateItemFromParsingName( + nativePath, NULL, + &IIDIShellItem, (void **) &dirIf); + if (SUCCEEDED(hr)) { + /* Note we use SetFolder, not SetDefaultFolder - see MSDN */ + fdlgIf->lpVtbl->SetFolder(fdlgIf, dirIf); /* Ignore errors */ + } + } + Tcl_DecrRefCount(normPath); /* ALSO INVALIDATES nativePath !! */ + } + Tcl_DecrRefCount(iniDirPath); + } + + oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); + hr = fdlgIf->lpVtbl->Show(fdlgIf, hWnd); + Tcl_SetServiceMode(oldMode); + + /* + * Ensure that hWnd is enabled, because it can happen that we have updated + * the wrapper of the parent, which causes us to leave this child disabled + * (Windows loses sync). + */ + + if (hWnd) + EnableWindow(hWnd, 1); + + /* + * Clear interp result since it might have been set during the modal loop. + * http://core.tcl.tk/tk/tktview/4a0451f5291b3c9168cc560747dae9264e1d2ef6 + */ + Tcl_ResetResult(interp); + + if (SUCCEEDED(hr)) { + if ((oper == OFN_FILE_OPEN) && optsPtr->multi) { + IShellItemArray *multiIf; + DWORD dw, count; + IFileOpenDialog *fodIf = (IFileOpenDialog *) fdlgIf; + hr = fodIf->lpVtbl->GetResults(fodIf, &multiIf); + if (SUCCEEDED(hr)) { + Tcl_Obj *multiObj; + hr = multiIf->lpVtbl->GetCount(multiIf, &count); + multiObj = Tcl_NewListObj(count, NULL); + if (SUCCEEDED(hr)) { + IShellItem *itemIf; + for (dw = 0; dw < count; ++dw) { + hr = multiIf->lpVtbl->GetItemAt(multiIf, dw, &itemIf); + if (FAILED(hr)) + break; + hr = itemIf->lpVtbl->GetDisplayName(itemIf, + SIGDN_FILESYSPATH, &wstr); + if (SUCCEEDED(hr)) { + Tcl_DString fnds; + ConvertExternalFilename(wstr, &fnds); + CoTaskMemFree(wstr); + Tcl_ListObjAppendElement( + interp, multiObj, + Tcl_NewStringObj(Tcl_DStringValue(&fnds), + Tcl_DStringLength(&fnds))); + } + itemIf->lpVtbl->Release(itemIf); + if (FAILED(hr)) + break; + } + } + multiIf->lpVtbl->Release(multiIf); + if (SUCCEEDED(hr)) + resultObj = multiObj; + else + Tcl_DecrRefCount(multiObj); + } + } else { + IShellItem *resultIf; + hr = fdlgIf->lpVtbl->GetResult(fdlgIf, &resultIf); + if (SUCCEEDED(hr)) { + hr = resultIf->lpVtbl->GetDisplayName(resultIf, SIGDN_FILESYSPATH, + &wstr); + if (SUCCEEDED(hr)) { + Tcl_DString fnds; + ConvertExternalFilename(wstr, &fnds); + resultObj = Tcl_NewStringObj(Tcl_DStringValue(&fnds), + Tcl_DStringLength(&fnds)); + CoTaskMemFree(wstr); + } + resultIf->lpVtbl->Release(resultIf); + } + } + if (SUCCEEDED(hr)) { + if (filterPtr && optsPtr->typeVariableObj) { + UINT ftix; + hr = fdlgIf->lpVtbl->GetFileTypeIndex(fdlgIf, &ftix); + if (SUCCEEDED(hr)) { + /* Note ftix is a 1-based index */ + if (ftix > 0 && ftix <= nfilters) { + Tcl_ObjSetVar2(interp, optsPtr->typeVariableObj, NULL, + Tcl_NewUnicodeObj(filterPtr[ftix-1].pszName, -1), + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); + } + } + } + } + } else { + if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) + hr = 0; /* User cancelled, return empty string */ + } + +vamoose: /* (hr != 0) => error */ + if (dirIf) + dirIf->lpVtbl->Release(dirIf); + if (fdlgIf) + fdlgIf->lpVtbl->Release(fdlgIf); + + if (filterPtr) + FreeFilterVista(nfilters, filterPtr); + + if (hr == 0) { + if (resultObj) /* May be NULL if user cancelled */ + Tcl_SetObjResult(interp, resultObj); + return TCL_OK; + } else { + if (resultObj) + Tcl_DecrRefCount(resultObj); + Tcl_SetObjResult(interp, TkWin32ErrorObj(hr)); + return TCL_ERROR; + } +} + + +/* + *---------------------------------------------------------------------- + * + * GetFileNameXP -- + * + * Displays the old pre-Vista file dialogs. + * + * Results: + * TCL_OK - if dialog was successfully displayed + * TCL_ERROR - error return + * + * Side effects: + * See user documentation. + *---------------------------------------------------------------------- + */ +static int GetFileNameXP(Tcl_Interp *interp, OFNOpts *optsPtr, enum OFNOper oper) +{ + OPENFILENAME ofn; + OFNData ofnData; + int cdlgerr; + int filterIndex = 0, result = TCL_ERROR, winCode, oldMode; + HWND hWnd; + Tcl_DString utfFilterString, ds; + Tcl_DString extString, filterString, dirString, titleString; + const char *str; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + ZeroMemory(&ofnData, sizeof(OFNData)); + Tcl_DStringInit(&utfFilterString); + Tcl_DStringInit(&dirString); /* XXX - original code was missing this + leaving dirString uninitialized for + the unlikely code path where cwd failed */ + + if (MakeFilter(interp, optsPtr->filterObj, &utfFilterString, + optsPtr->initialTypeObj, &filterIndex) != TCL_OK) { goto end; } - Tk_MakeWindowExist(tkwin); - hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); + Tk_MakeWindowExist(optsPtr->tkwin); + hWnd = Tk_GetHWND(Tk_WindowId(optsPtr->tkwin)); ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.hInstance = TkWinGetHInstance(ofn.hwndOwner); - ofn.lpstrFile = file; + ofn.lpstrFile = optsPtr->file; ofn.nMaxFile = TK_MULTI_MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR - | OFN_EXPLORER | OFN_ENABLEHOOK| OFN_ENABLESIZING; + | OFN_EXPLORER| OFN_ENABLEHOOK| OFN_ENABLESIZING; ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProc; ofn.lCustData = (LPARAM) &ofnData; - if (open != 0) { + if (oper != OFN_FILE_SAVE) { ofn.Flags |= OFN_FILEMUSTEXIST; - } else if (confirmOverwrite) { + } else if (optsPtr->confirmOverwrite) { ofn.Flags |= OFN_OVERWRITEPROMPT; } if (tsdPtr->debugFlag != 0) { ofnData.interp = interp; } - if (multi != 0) { + if (optsPtr->multi != 0) { ofn.Flags |= OFN_ALLOWMULTISELECT; /* @@ -706,8 +1609,11 @@ GetFileName( ofnData.dynFileBuffer = ckalloc(512 * sizeof(TCHAR)); } - if (extension != NULL) { - Tcl_WinUtfToTChar(extension, -1, &extString); + if (optsPtr->extObj != NULL) { + str = Tcl_GetString(optsPtr->extObj); + if (str[0] == '.') + ++str; + Tcl_WinUtfToTChar(str, -1, &extString); ofn.lpstrDefExt = (TCHAR *) Tcl_DStringValue(&extString); } @@ -716,9 +1622,9 @@ GetFileName( ofn.lpstrFilter = (TCHAR *) Tcl_DStringValue(&filterString); ofn.nFilterIndex = filterIndex; - if (Tcl_DStringValue(&utfDirString)[0] != '\0') { - Tcl_WinUtfToTChar(Tcl_DStringValue(&utfDirString), - Tcl_DStringLength(&utfDirString), &dirString); + if (Tcl_DStringValue(&optsPtr->utfDirString)[0] != '\0') { + Tcl_WinUtfToTChar(Tcl_DStringValue(&optsPtr->utfDirString), + Tcl_DStringLength(&optsPtr->utfDirString), &dirString); } else { /* * NT 5.0 changed the meaning of lpstrInitialDir, so we have to ensure @@ -727,10 +1633,10 @@ GetFileName( Tcl_DString cwd; - Tcl_DStringFree(&utfDirString); - if ((Tcl_GetCwd(interp, &utfDirString) == NULL) || + Tcl_DStringFree(&optsPtr->utfDirString); + if ((Tcl_GetCwd(interp, &optsPtr->utfDirString) == NULL) || (Tcl_TranslateFileName(interp, - Tcl_DStringValue(&utfDirString), &cwd) == NULL)) { + Tcl_DStringValue(&optsPtr->utfDirString), &cwd) == NULL)) { Tcl_ResetResult(interp); } else { Tcl_WinUtfToTChar(Tcl_DStringValue(&cwd), @@ -740,8 +1646,8 @@ GetFileName( } ofn.lpstrInitialDir = (TCHAR *) Tcl_DStringValue(&dirString); - if (title != NULL) { - Tcl_WinUtfToTChar(title, -1, &titleString); + if (optsPtr->titleObj != NULL) { + Tcl_WinUtfToTChar(Tcl_GetString(optsPtr->titleObj), -1, &titleString); ofn.lpstrTitle = (TCHAR *) Tcl_DStringValue(&titleString); } @@ -750,7 +1656,7 @@ GetFileName( */ oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - if (open != 0) { + if (oper != OFN_FILE_SAVE) { winCode = GetOpenFileName(&ofn); } else { winCode = GetSaveFileName(&ofn); @@ -859,22 +1765,37 @@ GetFileName( Tcl_DStringFree(&ds); } result = TCL_OK; - if ((ofn.nFilterIndex > 0) && gotFilename && typeVariableObj - && filterObj) { + if ((ofn.nFilterIndex > 0) && gotFilename && optsPtr->typeVariableObj + && optsPtr->filterObj) { int listObjc, count; Tcl_Obj **listObjv = NULL; Tcl_Obj **typeInfo = NULL; - if (Tcl_ListObjGetElements(interp, filterObj, + if (Tcl_ListObjGetElements(interp, optsPtr->filterObj, &listObjc, &listObjv) != TCL_OK) { result = TCL_ERROR; } else if (Tcl_ListObjGetElements(interp, listObjv[ofn.nFilterIndex - 1], &count, &typeInfo) != TCL_OK) { result = TCL_ERROR; - } else if (Tcl_ObjSetVar2(interp, typeVariableObj, NULL, - typeInfo[0], TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - result = TCL_ERROR; + } else { + /* + * BUGFIX for d43a10ce2fed950e00890049f3c273f2cdd12583 + * The original code was broken because it passed typeinfo[0] + * directly into Tcl_ObjSetVar2. In the case of typeInfo[0] + * pointing into a list which is also referenced by + * typeVariableObj, TOSV2 shimmers the object into + * variable intrep which loses the list representation. + * This invalidates typeInfo[0] which is freed but + * nevertheless stored as the value of the variable. + */ + Tcl_Obj *selFilterObj = typeInfo[0]; + Tcl_IncrRefCount(selFilterObj); + if (Tcl_ObjSetVar2(interp, optsPtr->typeVariableObj, NULL, + selFilterObj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { + result = TCL_ERROR; + } + Tcl_DecrRefCount(selFilterObj); } } } else if (cdlgerr == FNERR_INVALIDFILENAME) { @@ -892,6 +1813,8 @@ GetFileName( Tcl_DStringFree(&titleString); } if (ofn.lpstrInitialDir != NULL) { + /* XXX - huh? lpstrInitialDir is set from Tcl_DStringValue which + can never return NULL */ Tcl_DStringFree(&dirString); } Tcl_DStringFree(&filterString); @@ -899,8 +1822,7 @@ GetFileName( Tcl_DStringFree(&extString); } - end: - Tcl_DStringFree(&utfDirString); +end: Tcl_DStringFree(&utfFilterString); if (ofnData.dynFileBuffer != NULL) { ckfree(ofnData.dynFileBuffer); @@ -909,6 +1831,49 @@ GetFileName( return result; } + + +/* + *---------------------------------------------------------------------- + * + * GetFileName -- + * + * Calls GetOpenFileName() or GetSaveFileName(). + * + * Results: + * See user documentation. + * + * Side effects: + * See user documentation. + * + *---------------------------------------------------------------------- + */ + +static int +GetFileName( + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[], /* Argument objects. */ + enum OFNOper oper) /* 1 to call GetOpenFileName(), 0 to call + * GetSaveFileName(). */ +{ + OFNOpts ofnOpts; + int result; + + result = ParseOFNOptions(clientData, interp, objc, objv, oper, &ofnOpts); + if (result != TCL_OK) + return result; + + if (VistaFileDialogsAvailable() && ! ofnOpts.forceXPStyle) + result = GetFileNameVista(interp, &ofnOpts, oper); + else + result = GetFileNameXP(interp, &ofnOpts, oper); + + CleanupOFNOptions(&ofnOpts); + return result; +} + /* *------------------------------------------------------------------------- @@ -973,8 +1938,8 @@ OFNHookProc( buffer = ofnData->dynFileBuffer; hdlg = GetParent(hdlg); - selsize = SendMessage(hdlg, CDM_GETSPEC, 0, 0); - dirsize = SendMessage(hdlg, CDM_GETFOLDERPATH, 0, 0); + selsize = (int) SendMessage(hdlg, CDM_GETSPEC, 0, 0); + dirsize = (int) SendMessage(hdlg, CDM_GETFOLDERPATH, 0, 0); buffersize = (selsize + dirsize + 1); /* @@ -1232,6 +2197,145 @@ MakeFilter( /* *---------------------------------------------------------------------- * + * FreeFilterVista + * + * Frees storage previously allocated by MakeFilterVista. + * count is the number of elements in dlgFilterPtr[] + */ +static void FreeFilterVista(DWORD count, TCLCOMDLG_FILTERSPEC *dlgFilterPtr) +{ + if (dlgFilterPtr != NULL) { + DWORD dw; + for (dw = 0; dw < count; ++dw) { + if (dlgFilterPtr[dw].pszName != NULL) + ckfree(dlgFilterPtr[dw].pszName); + if (dlgFilterPtr[dw].pszSpec != NULL) + ckfree(dlgFilterPtr[dw].pszSpec); + } + ckfree(dlgFilterPtr); + } +} + +/* + *---------------------------------------------------------------------- + * + * MakeFilterVista -- + * + * Returns file type filters in a format required + * by the Vista file dialogs. + * + * Results: + * A standard TCL return value. + * + * Side effects: + * Various values are returned through the parameters as + * described in the comments below. + *---------------------------------------------------------------------- + */ +static int MakeFilterVista( + Tcl_Interp *interp, /* Current interpreter. */ + OFNOpts *optsPtr, /* Caller specified options */ + DWORD *countPtr, /* Will hold number of filters */ + TCLCOMDLG_FILTERSPEC **dlgFilterPtrPtr, /* Will hold pointer to filter array. + Set to NULL if no filters specified. + Must be freed by calling + FreeFilterVista */ + DWORD *initialIndexPtr) /* Will hold index of default type */ +{ + TCLCOMDLG_FILTERSPEC *dlgFilterPtr; + const char *initial = NULL; + FileFilterList flist; + FileFilter *filterPtr; + DWORD initialIndex = 0; + Tcl_DString ds, patterns; + int i; + + if (optsPtr->filterObj == NULL) { + *dlgFilterPtrPtr = NULL; + *countPtr = 0; + return TCL_OK; + } + + if (optsPtr->initialTypeObj) + initial = Tcl_GetString(optsPtr->initialTypeObj); + + TkInitFileFilters(&flist); + if (TkGetFileFilters(interp, &flist, optsPtr->filterObj, 1) != TCL_OK) + return TCL_ERROR; + + if (flist.filters == NULL) { + *dlgFilterPtrPtr = NULL; + *countPtr = 0; + return TCL_OK; + } + + Tcl_DStringInit(&ds); + Tcl_DStringInit(&patterns); + dlgFilterPtr = ckalloc(flist.numFilters * sizeof(*dlgFilterPtr)); + + for (i = 0, filterPtr = flist.filters; + filterPtr; + filterPtr = filterPtr->next, ++i) { + const char *sep; + FileFilterClause *clausePtr; + int nbytes; + + /* Check if this entry should be shown as the default */ + if (initial && strcmp(initial, filterPtr->name) == 0) + initialIndex = i+1; /* Windows filter indices are 1-based */ + + /* First stash away the text description of the pattern */ + Tcl_WinUtfToTChar(filterPtr->name, -1, &ds); + nbytes = Tcl_DStringLength(&ds); /* # bytes, not Unicode chars */ + nbytes += sizeof(WCHAR); /* Terminating \0 */ + dlgFilterPtr[i].pszName = ckalloc(nbytes); + memmove((void *) dlgFilterPtr[i].pszName, Tcl_DStringValue(&ds), nbytes); + Tcl_DStringFree(&ds); + + /* + * Loop through and join patterns with a ";" Each "clause" + * corresponds to a single textual description (called typename) + * in the tk_getOpenFile docs. Each such typename may occur + * multiple times and all these form a single filter entry + * with one clause per occurence. Further each clause may specify + * multiple patterns. Hence the nested loop here. + */ + sep = ""; + for (clausePtr=filterPtr->clauses ; clausePtr; + clausePtr=clausePtr->next) { + GlobPattern *globPtr; + for (globPtr = clausePtr->patterns; globPtr; + globPtr = globPtr->next) { + Tcl_DStringAppend(&patterns, sep, -1); + Tcl_DStringAppend(&patterns, globPtr->pattern, -1); + sep = ";"; + } + } + + /* Again we need a Unicode form of the string */ + Tcl_WinUtfToTChar(Tcl_DStringValue(&patterns), -1, &ds); + nbytes = Tcl_DStringLength(&ds); /* # bytes, not Unicode chars */ + nbytes += sizeof(WCHAR); /* Terminating \0 */ + dlgFilterPtr[i].pszSpec = ckalloc(nbytes); + memmove((void *)dlgFilterPtr[i].pszSpec, Tcl_DStringValue(&ds), nbytes); + Tcl_DStringFree(&ds); + Tcl_DStringFree(&patterns); + } + + if (initialIndex == 0) + initialIndex = 1; /* If no default, show first entry */ + *initialIndexPtr = initialIndex; + *dlgFilterPtrPtr = dlgFilterPtr; + *countPtr = flist.numFilters; + + TkFreeFileFilters(&flist); + return TCL_OK; +} + + +/* + *---------------------------------------------------------------------- + * * Tk_ChooseDirectoryObjCmd -- * * This function implements the "tk_chooseDirectory" dialog box for the @@ -1307,102 +2411,60 @@ Tk_ChooseDirectoryObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { TCHAR path[MAX_PATH]; - int oldMode, result = TCL_ERROR, i; + int oldMode, result; LPCITEMIDLIST pidl; /* Returned by browser */ BROWSEINFO bInfo; /* Used by browser */ ChooseDir cdCBData; /* Structure to pass back and forth */ LPMALLOC pMalloc; /* Used by shell */ - Tk_Window tkwin = clientData; HWND hWnd; - const char *utfTitle = NULL;/* Title for window */ TCHAR saveDir[MAX_PATH]; Tcl_DString titleString; /* Title */ - Tcl_DString initDirString; /* Initial directory */ Tcl_DString tempString; /* temporary */ Tcl_Obj *objPtr; - static const char *const optionStrings[] = { - "-initialdir", "-mustexist", "-parent", "-title", NULL - }; - enum options { - DIR_INITIAL, DIR_EXIST, DIR_PARENT, FILE_TITLE - }; + OFNOpts ofnOpts; + const char *utfDir; + + result = ParseOFNOptions(clientData, interp, objc, objv, + OFN_DIR_CHOOSE, &ofnOpts); + if (result != TCL_OK) + return result; + + /* Use new dialogs if available */ + if (VistaFileDialogsAvailable() && ! ofnOpts.forceXPStyle) { + result = GetFileNameVista(interp, &ofnOpts, OFN_DIR_CHOOSE); + CleanupOFNOptions(&ofnOpts); + return result; + } - /* - * Initialize - */ + /* Older dialogs */ path[0] = '\0'; ZeroMemory(&cdCBData, sizeof(ChooseDir)); cdCBData.interp = interp; + cdCBData.mustExist = ofnOpts.mustExist; - /* - * Process the command line options - */ - - for (i = 1; i < objc; i += 2) { - int index; - const char *string; + utfDir = Tcl_DStringValue(&ofnOpts.utfDirString); + if (utfDir[0] != '\0') { const TCHAR *uniStr; - Tcl_Obj *optionPtr, *valuePtr; - optionPtr = objv[i]; - valuePtr = objv[i + 1]; + Tcl_WinUtfToTChar(Tcl_DStringValue(&ofnOpts.utfDirString), -1, + &tempString); + uniStr = (TCHAR *) Tcl_DStringValue(&tempString); - if (Tcl_GetIndexFromObjStruct(interp, optionPtr, optionStrings, - sizeof(char *), "option", 0, &index) != TCL_OK) { - goto cleanup; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(optionPtr))); - Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "VALUE", NULL); - goto cleanup; - } + /* Convert possible relative path to full path to keep dialog happy. */ - string = Tcl_GetString(valuePtr); - switch ((enum options) index) { - case DIR_INITIAL: - if (Tcl_TranslateFileName(interp,string,&initDirString) == NULL) { - goto cleanup; - } - Tcl_WinUtfToTChar(Tcl_DStringValue(&initDirString), -1, - &tempString); - uniStr = (TCHAR *) Tcl_DStringValue(&tempString); - - /* - * Convert possible relative path to full path to keep dialog - * happy. - */ - - GetFullPathName(uniStr, MAX_PATH, saveDir, NULL); - _tcsncpy(cdCBData.initDir, saveDir, MAX_PATH); - Tcl_DStringFree(&initDirString); - Tcl_DStringFree(&tempString); - break; - case DIR_EXIST: - if (Tcl_GetBooleanFromObj(interp, valuePtr, - &cdCBData.mustExist) != TCL_OK) { - goto cleanup; - } - break; - case DIR_PARENT: - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { - goto cleanup; - } - break; - case FILE_TITLE: - utfTitle = string; - break; - } + GetFullPathName(uniStr, MAX_PATH, saveDir, NULL); + _tcsncpy(cdCBData.initDir, saveDir, MAX_PATH); } + /* XXX - rest of this (original) code has no error checks at all. */ + /* * Get ready to call the browser */ - Tk_MakeWindowExist(tkwin); - hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); + Tk_MakeWindowExist(ofnOpts.tkwin); + hWnd = Tk_GetHWND(Tk_WindowId(ofnOpts.tkwin)); /* * Setup the parameters used by SHBrowseForFolder @@ -1416,8 +2478,8 @@ Tk_ChooseDirectoryObjCmd( } bInfo.lParam = (LPARAM) &cdCBData; - if (utfTitle != NULL) { - Tcl_WinUtfToTChar(utfTitle, -1, &titleString); + if (ofnOpts.titleObj != NULL) { + Tcl_WinUtfToTChar(Tcl_GetString(ofnOpts.titleObj), -1, &titleString); bInfo.lpszTitle = (LPTSTR) Tcl_DStringValue(&titleString); } else { bInfo.lpszTitle = TEXT("Please choose a directory, then select OK."); @@ -1455,6 +2517,10 @@ Tk_ChooseDirectoryObjCmd( oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); GetCurrentDirectory(MAX_PATH, saveDir); if (SHGetMalloc(&pMalloc) == NOERROR) { + /* + * XXX - MSDN says CoInitialize must have been called before + * SHBrowseForFolder can be used but don't see that called anywhere. + */ pidl = SHBrowseForFolder(&bInfo); /* @@ -1506,14 +2572,8 @@ Tk_ChooseDirectoryObjCmd( Tcl_DStringFree(&ds); } - result = TCL_OK; - - if (utfTitle != NULL) { - Tcl_DStringFree(&titleString); - } - - cleanup: - return result; + CleanupOFNOptions(&ofnOpts); + return TCL_OK; } /* diff --git a/win/tkWinEmbed.c b/win/tkWinEmbed.c index a908a1f..8bfd295 100644 --- a/win/tkWinEmbed.c +++ b/win/tkWinEmbed.c @@ -101,8 +101,8 @@ int TkpTestembedCmd( ClientData clientData, Tcl_Interp *interp, - int argc, - const char **argv) + int objc, + Tcl_Obj *const objv[]) { return TCL_OK; } @@ -257,10 +257,13 @@ TkpUseWindow( return TCL_OK; } - if (Tcl_GetInt(interp, string, &id) != TCL_OK) { + if ( +#ifdef _WIN64 + (sscanf(string, "0x%p", &hwnd) != 1) && +#endif + Tcl_GetInt(interp, string, (int *) &hwnd) != TCL_OK) { return TCL_ERROR; } - hwnd = (HWND) INT2PTR(id); if ((HWND)winPtr->privatePtr == hwnd) { return TCL_OK; } diff --git a/win/tkWinFont.c b/win/tkWinFont.c index 86f63ac..9172b00 100644 --- a/win/tkWinFont.c +++ b/win/tkWinFont.c @@ -33,7 +33,7 @@ typedef struct FontFamily { struct FontFamily *nextPtr; /* Next in list of all known font families. */ - int refCount; /* How many SubFonts are referring to this + size_t refCount; /* How many SubFonts are referring to this * FontFamily. When the refCount drops to * zero, this FontFamily may be freed. */ /* @@ -1869,8 +1869,7 @@ FreeFontFamily( if (familyPtr == NULL) { return; } - familyPtr->refCount--; - if (familyPtr->refCount > 0) { + if (familyPtr->refCount-- > 1) { return; } for (i = 0; i < FONTMAP_PAGES; i++) { diff --git a/win/tkWinInit.c b/win/tkWinInit.c index 4a327a2..b1b2d6b 100644 --- a/win/tkWinInit.c +++ b/win/tkWinInit.c @@ -159,6 +159,57 @@ TkpDisplayWarning( } /* + * ---------------------------------------------------------------------- + * + * Win32ErrorObj -- + * + * Returns a string object containing text from a COM or Win32 error code + * + * Results: + * A Tcl_Obj containing the Win32 error message. + * + * Side effects: + * Removed the error message from the COM threads error object. + * + * ---------------------------------------------------------------------- + */ + +Tcl_Obj* +TkWin32ErrorObj( + HRESULT hrError) +{ + LPTSTR lpBuffer = NULL, p = NULL; + TCHAR sBuffer[30]; + Tcl_Obj* errPtr = NULL; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)hrError, + LANG_NEUTRAL, (LPTSTR)&lpBuffer, 0, NULL); + + if (lpBuffer == NULL) { + lpBuffer = sBuffer; + wsprintf(sBuffer, TEXT("Error Code: %08lX"), hrError); + } + + if ((p = _tcsrchr(lpBuffer, TEXT('\r'))) != NULL) { + *p = TEXT('\0'); + } + +#ifdef _UNICODE + errPtr = Tcl_NewUnicodeObj(lpBuffer, (int)wcslen(lpBuffer)); +#else + errPtr = Tcl_NewStringObj(lpBuffer, (int)strlen(lpBuffer)); +#endif /* _UNICODE */ + + if (lpBuffer != sBuffer) { + LocalFree((HLOCAL)lpBuffer); + } + + return errPtr; +} + + +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/win/tkWinInt.h b/win/tkWinInt.h index 580e58f..0e2c844 100644 --- a/win/tkWinInt.h +++ b/win/tkWinInt.h @@ -201,9 +201,15 @@ MODULE_SCOPE void TkpWinToplevelDetachWindow(TkWindow *winPtr); MODULE_SCOPE int TkpWmGetState(TkWindow *winPtr); /* + * Common routines used in Windows implementation + */ +MODULE_SCOPE Tcl_Obj * TkWin32ErrorObj(HRESULT hrError); + + +/* * The following functions are not present in old versions of Windows - * API headers but are used in the Tk source to ensure 64bit - * compatability. + * API headers but are used in the Tk source to ensure 64bit + * compatibility. */ #ifndef GetClassLongPtr diff --git a/win/tkWinPort.h b/win/tkWinPort.h index 95cad78..965dbc5 100644 --- a/win/tkWinPort.h +++ b/win/tkWinPort.h @@ -87,6 +87,13 @@ #define REDO_KEYSYM_LOOKUP /* + * See ticket [916c1095438eae56]: GetVersionExW triggers warnings + */ +#if defined(_MSC_VER) +# pragma warning(disable:4996) +#endif + +/* * The following macro checks to see whether there is buffered * input data available for a stdio FILE. */ @@ -105,7 +112,7 @@ | ((p)->green & 0xff00) | (((p)->blue << 8) & 0xff0000)) | 0x20000000) /* - * These calls implement native bitmaps which are not currently + * These calls implement native bitmaps which are not currently * supported under Windows. The macros eliminate the calls. */ diff --git a/win/tkWinScrlbr.c b/win/tkWinScrlbr.c index a280626..1b3717e 100644 --- a/win/tkWinScrlbr.c +++ b/win/tkWinScrlbr.c @@ -217,10 +217,10 @@ CreateProc( if (scrollPtr->info.vertical) { style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS - | SBS_VERT | SBS_RIGHTALIGN; + | SBS_VERT; } else { style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS - | SBS_HORZ | SBS_BOTTOMALIGN; + | SBS_HORZ; } scrollPtr->hwnd = CreateWindow(TEXT("SCROLLBAR"), NULL, style, diff --git a/win/tkWinSend.c b/win/tkWinSend.c index 7fde655..6c4731a 100644 --- a/win/tkWinSend.c +++ b/win/tkWinSend.c @@ -77,7 +77,6 @@ static int FindInterpreterObject(Tcl_Interp *interp, static int Send(LPDISPATCH pdispInterp, Tcl_Interp *interp, int async, ClientData clientData, int objc, Tcl_Obj *const objv[]); -static Tcl_Obj * Win32ErrorObj(HRESULT hrError); static void SendTrace(const char *format, ...); static Tcl_EventProc SendEventProc; @@ -281,7 +280,7 @@ TkGetInterpNames( if (objList != NULL) { Tcl_DecrRefCount(objList); } - Tcl_SetObjResult(interp, Win32ErrorObj(hr)); + Tcl_SetObjResult(interp, TkWin32ErrorObj(hr)); result = TCL_ERROR; } @@ -451,7 +450,7 @@ FindInterpreterObject( pROT->lpVtbl->Release(pROT); } if (FAILED(hr) && result == TCL_OK) { - Tcl_SetObjResult(interp, Win32ErrorObj(hr)); + Tcl_SetObjResult(interp, TkWin32ErrorObj(hr)); result = TCL_ERROR; } return result; @@ -809,56 +808,6 @@ Send( /* * ---------------------------------------------------------------------- * - * Win32ErrorObj -- - * - * Returns a string object containing text from a COM or Win32 error code - * - * Results: - * A Tcl_Obj containing the Win32 error message. - * - * Side effects: - * Removed the error message from the COM threads error object. - * - * ---------------------------------------------------------------------- - */ - -static Tcl_Obj* -Win32ErrorObj( - HRESULT hrError) -{ - LPTSTR lpBuffer = NULL, p = NULL; - TCHAR sBuffer[30]; - Tcl_Obj* errPtr = NULL; - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)hrError, - LANG_NEUTRAL, (LPTSTR)&lpBuffer, 0, NULL); - - if (lpBuffer == NULL) { - lpBuffer = sBuffer; - wsprintf(sBuffer, TEXT("Error Code: %08lX"), hrError); - } - - if ((p = _tcsrchr(lpBuffer, TEXT('\r'))) != NULL) { - *p = TEXT('\0'); - } - -#ifdef _UNICODE - errPtr = Tcl_NewUnicodeObj(lpBuffer, (int)wcslen(lpBuffer)); -#else - errPtr = Tcl_NewStringObj(lpBuffer, (int)strlen(lpBuffer)); -#endif /* _UNICODE */ - - if (lpBuffer != sBuffer) { - LocalFree((HLOCAL)lpBuffer); - } - - return errPtr; -} - -/* - * ---------------------------------------------------------------------- - * * TkWinSend_SetExcepInfo -- * * Convert the error information from a Tcl interpreter into a COM diff --git a/win/tkWinTest.c b/win/tkWinTest.c index 6036995..d824ee4 100644 --- a/win/tkWinTest.c +++ b/win/tkWinTest.c @@ -27,8 +27,9 @@ HWND tkWinCurrentDialog; static int TestclipboardObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static int TestwineventCmd(ClientData clientData, - Tcl_Interp *interp, int argc, const char **argv); +static int TestwineventObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); static int TestfindwindowObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -67,7 +68,7 @@ TkplatformtestInit( Tcl_CreateObjCommand(interp, "testclipboard", TestclipboardObjCmd, (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateCommand(interp, "testwinevent", TestwineventCmd, + Tcl_CreateObjCommand(interp, "testwinevent", TestwineventObjCmd, (ClientData) Tk_MainWindow(interp), NULL); Tcl_CreateObjCommand(interp, "testfindwindow", TestfindwindowObjCmd, (ClientData) Tk_MainWindow(interp), NULL); @@ -78,6 +79,42 @@ TkplatformtestInit( return TCL_OK; } +struct TestFindControlState { + int id; + HWND control; +}; + +/* Callback for window enumeration - used for TestFindControl */ +BOOL CALLBACK TestFindControlCallback( + HWND hwnd, + LPARAM lParam +) +{ + struct TestFindControlState *fcsPtr = (struct TestFindControlState *)lParam; + fcsPtr->control = GetDlgItem(hwnd, fcsPtr->id); + /* If we have found the control, return FALSE to stop the enumeration */ + return fcsPtr->control == NULL ? TRUE : FALSE; +} + +/* + * Finds the descendent control window with the specified ID and returns + * its HWND. + */ +HWND TestFindControl(HWND root, int id) +{ + struct TestFindControlState fcs; + + fcs.control = GetDlgItem(root, id); + if (fcs.control == NULL) { + /* Control is not a direct child. Look in descendents */ + fcs.id = id; + fcs.control = NULL; + EnumChildWindows(root, TestFindControlCallback, (LPARAM) &fcs); + } + return fcs.control; +} + + /* *---------------------------------------------------------------------- * @@ -220,7 +257,7 @@ TestclipboardObjCmd( /* *---------------------------------------------------------------------- * - * TestwineventCmd -- + * TestwineventObjCmd -- * * This function implements the testwinevent command. It provides a way * to send messages to windows dialogs. @@ -235,19 +272,21 @@ TestclipboardObjCmd( */ static int -TestwineventCmd( +TestwineventObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { HWND hwnd = 0; HWND child = 0; + HWND control; int id; char *rest; UINT message; WPARAM wParam; LPARAM lParam; + LRESULT result; static const TkStateMap messageMap[] = { {WM_LBUTTONDOWN, "WM_LBUTTONDOWN"}, {WM_LBUTTONUP, "WM_LBUTTONUP"}, @@ -258,33 +297,23 @@ TestwineventCmd( {-1, NULL} }; - if ((argc == 3) && (strcmp(argv[1], "debug") == 0)) { + if ((objc == 3) && (strcmp(Tcl_GetString(objv[1]), "debug") == 0)) { int b; - if (Tcl_GetBoolean(interp, argv[2], &b) != TCL_OK) { + if (Tcl_GetBoolean(interp, Tcl_GetString(objv[2]), &b) != TCL_OK) { return TCL_ERROR; } TkWinDialogDebug(b); return TCL_OK; } - if (argc < 4) { + if (objc < 4) { return TCL_ERROR; } -#if 0 - TkpScanWindowId(interp, argv[1], &id); - if ( -#ifdef _WIN64 - (sscanf(string, "0x%p", &number) != 1) && -#endif /* _WIN64 */ - Tcl_GetInt(interp, string, (int *)&number) != TCL_OK) { - return TCL_ERROR; - } -#endif - hwnd = INT2PTR(strtol(argv[1], &rest, 0)); - if (rest == argv[1]) { - hwnd = FindWindowA(NULL, argv[1]); + hwnd = INT2PTR(strtol(Tcl_GetString(objv[1]), &rest, 0)); + if (rest == Tcl_GetString(objv[1])) { + hwnd = FindWindowA(NULL, Tcl_GetString(objv[1])); if (hwnd == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("no such window", -1)); return TCL_ERROR; @@ -292,14 +321,14 @@ TestwineventCmd( } UpdateWindow(hwnd); - id = strtol(argv[2], &rest, 0); - if (rest == argv[2]) { + id = strtol(Tcl_GetString(objv[2]), &rest, 0); + if (rest == Tcl_GetString(objv[2])) { char buf[256]; child = GetWindow(hwnd, GW_CHILD); while (child != NULL) { SendMessageA(child, WM_GETTEXT, (WPARAM) sizeof(buf), (LPARAM) buf); - if (strcasecmp(buf, argv[2]) == 0) { + if (strcasecmp(buf, Tcl_GetString(objv[2])) == 0) { id = GetDlgCtrlID(child); break; } @@ -307,19 +336,20 @@ TestwineventCmd( } if (child == NULL) { Tcl_AppendResult(interp, "could not find a control matching \"", - argv[2], "\"", NULL); + Tcl_GetString(objv[2]), "\"", NULL); return TCL_ERROR; } } - message = TkFindStateNum(NULL, NULL, messageMap, argv[3]); + + message = TkFindStateNum(NULL, NULL, messageMap, Tcl_GetString(objv[3])); wParam = 0; lParam = 0; - if (argc > 4) { - wParam = strtol(argv[4], NULL, 0); + if (objc > 4) { + wParam = strtol(Tcl_GetString(objv[4]), NULL, 0); } - if (argc > 5) { - lParam = strtol(argv[5], NULL, 0); + if (objc > 5) { + lParam = strtol(Tcl_GetString(objv[5]), NULL, 0); } switch (message) { @@ -327,7 +357,19 @@ TestwineventCmd( Tcl_DString ds; char buf[256]; +#if 0 GetDlgItemTextA(hwnd, id, buf, 256); +#else + control = TestFindControl(hwnd, id); + if (control == NULL) { + Tcl_SetObjResult(interp, + Tcl_ObjPrintf("Could not find control with id %d", id)); + return TCL_ERROR; + } + buf[0] = 0; + SendMessageA(control, WM_GETTEXT, (WPARAM)sizeof(buf), + (LPARAM) buf); +#endif Tcl_ExternalToUtfDString(NULL, buf, -1, &ds); Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL); Tcl_DStringFree(&ds); @@ -335,21 +377,27 @@ TestwineventCmd( } case WM_SETTEXT: { Tcl_DString ds; - BOOL result; - Tcl_UtfToExternalDString(NULL, argv[4], -1, &ds); - result = SetDlgItemTextA(hwnd, id, Tcl_DStringValue(&ds)); + control = TestFindControl(hwnd, id); + if (control == NULL) { + Tcl_SetObjResult(interp, + Tcl_ObjPrintf("Could not find control with id %d", id)); + return TCL_ERROR; + } + Tcl_UtfToExternalDString(NULL, Tcl_GetString(objv[4]), -1, &ds); + result = SendMessageA(control, WM_SETTEXT, 0, + (LPARAM) Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); if (result == 0) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to send text to dialog: ", -1)); - AppendSystemError(interp, GetLastError()); - return TCL_ERROR; + Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to send text to dialog: ", -1)); + AppendSystemError(interp, GetLastError()); + return TCL_ERROR; } break; } case WM_COMMAND: { char buf[TCL_INTEGER_SPACE]; - if (argc < 5) { + if (objc < 5) { wParam = MAKEWPARAM(id, 0); lParam = (LPARAM)child; } @@ -391,6 +439,7 @@ TestfindwindowObjCmd( Tcl_DString titleString, classString; HWND hwnd = NULL; int r = TCL_OK; + DWORD myPid; Tcl_DStringInit(&classString); Tcl_DStringInit(&titleString); @@ -404,8 +453,30 @@ TestfindwindowObjCmd( if (objc == 3) { class = Tcl_WinUtfToTChar(Tcl_GetString(objv[2]), -1, &classString); } - + if (title[0] == 0) + title = NULL; +#if 0 hwnd = FindWindow(class, title); +#else + /* We want find a window the belongs to us and not some other process */ + hwnd = NULL; + myPid = GetCurrentProcessId(); + while (1) { + DWORD pid, tid; + hwnd = FindWindowEx(NULL, hwnd, class, title); + if (hwnd == NULL) + break; + tid = GetWindowThreadProcessId(hwnd, &pid); + if (tid == 0) { + /* Window has gone */ + hwnd = NULL; + break; + } + if (pid == myPid) + break; /* Found it */ + } + +#endif if (hwnd == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to find window: ", -1)); diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 017cba9..768ee69 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -148,7 +148,7 @@ typedef struct { */ typedef struct WinIconInstance { - int refCount; /* Number of instances that share this data + size_t refCount; /* Number of instances that share this data * structure. */ BlockOfIconImagesPtr iconBlock; /* Pointer to icon resource data for image */ @@ -1421,9 +1421,7 @@ static void DecrIconRefCount( WinIconPtr titlebaricon) { - titlebaricon->refCount--; - - if (titlebaricon->refCount <= 0) { + if (titlebaricon->refCount-- <= 1) { if (titlebaricon->iconBlock != NULL) { FreeIconBlock(titlebaricon->iconBlock); } @@ -5730,7 +5728,7 @@ WmWaitVisibilityOrMapProc( * This function is invoked by a widget when it wishes to set a grid * coordinate system that controls the size of a top-level window. It * provides a C interface equivalent to the "wm grid" command and is - * usually asscoiated with the -setgrid option. + * usually associated with the -setgrid option. * * Results: * None. diff --git a/win/winMain.c b/win/winMain.c index 36dbea9..62bcbd8 100644 --- a/win/winMain.c +++ b/win/winMain.c @@ -224,7 +224,7 @@ Tcl_AppInit( */ /* - * Call Tcl_CreateCommand for application-specific commands, if they + * Call Tcl_CreateObjCommand for application-specific commands, if they * weren't already created by the init procedures called above. */ diff --git a/win/wish.exe.manifest.in b/win/wish.exe.manifest.in index 7db42e3..4829471 100644 --- a/win/wish.exe.manifest.in +++ b/win/wish.exe.manifest.in @@ -20,6 +20,8 @@ </trustInfo> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> + <!-- Windows 10 --> + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- Windows 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!-- Windows 8 --> |