diff options
Diffstat (limited to 'tk8.6/win')
137 files changed, 0 insertions, 50161 deletions
diff --git a/tk8.6/win/Makefile.in b/tk8.6/win/Makefile.in deleted file mode 100644 index 7e48213..0000000 --- a/tk8.6/win/Makefile.in +++ /dev/null @@ -1,748 +0,0 @@ -# This file is a Makefile for Tk. If it has the name "Makefile.in" -# then it is a template for a Makefile; to generate the actual Makefile, -# run "./configure", which is a configuration script generated by the -# "autoconf" program (constructs like "@foo@" will get replaced in the -# actual Makefile. - -TCLVERSION = @TCL_VERSION@ -TCLPATCHL = @TCL_PATCH_LEVEL@ -VERSION = @TK_VERSION@ -PATCH_LEVEL = @TK_PATCH_LEVEL@ - -#---------------------------------------------------------------- -# Things you can change to personalize the Makefile for your own -# site (you can make these changes in either Makefile.in or -# Makefile, but changes to Makefile will get lost if you re-run -# the configuration script). -#---------------------------------------------------------------- - -# Default top-level directories in which to install architecture- -# specific files (exec_prefix) and machine-independent files such -# as scripts (prefix). The values specified here may be overridden -# at configure-time with the --exec-prefix and --prefix options -# to the "configure" script. - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -libdir = @libdir@ -includedir = @includedir@ -datarootdir = @datarootdir@ -mandir = @mandir@ - -# The following definition can be set to non-null for special systems -# like AFS with replication. It allows the pathnames used for installation -# to be different than those used for actually reference files at -# run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix -# when installing files. -INSTALL_ROOT = - -# Directory from which applications will reference the library of Tk -# scripts (note: you can set the TK_LIBRARY environment variable at -# run-time to override this value): -TK_LIBRARY = $(prefix)/lib/tk$(VERSION) - -# Path to use at runtime to refer to LIB_INSTALL_DIR: -LIB_RUNTIME_DIR = $(libdir) - -# Directory in which to install the program wish: -BIN_INSTALL_DIR = $(INSTALL_ROOT)$(bindir) - -# Directory in which to install the .a or .so binary for the Tk library: -LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir) - -# Path name to use when installing library scripts: -SCRIPT_INSTALL_DIR = $(INSTALL_ROOT)$(TK_LIBRARY) - -# Directory in which to install the include file tk.h: -INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir) - -# Directory in which to (optionally) install the private tk headers: -PRIVATE_INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir) - -# Top-level directory for manual entries: -MAN_INSTALL_DIR = $(INSTALL_ROOT)$(mandir) - -# Directory in which to install manual entry for wish: -MAN1_INSTALL_DIR = $(MAN_INSTALL_DIR)/man1 - -# Directory in which to install manual entries for Tk's C library -# procedures: -MAN3_INSTALL_DIR = $(MAN_INSTALL_DIR)/man3 - -# Directory in which to install manual entries for the built-in -# Tk commands: -MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann - -# Libraries built with optimization switches have this additional extension -TK_DBGX = @TK_DBGX@ - -# Directory in which to install the pkgIndex.tcl file for loadable Tk -PKG_INSTALL_DIR = $(LIB_INSTALL_DIR)/tk$(VERSION)$(TK_DBGX) - -# Package index file for loadable Tk -PKG_INDEX = $(PKG_INSTALL_DIR)/pkgIndex.tcl - -# The directory containing the Tcl source and header files. -TCL_SRC_DIR = @TCL_SRC_DIR@ - -# The directory containing the Tcl library archive file appropriate -# for this version of Tk: -TCL_BIN_DIR = @TCL_BIN_DIR@ - -# The directory containing the Tcl sources and headers appropriate -# for this version of Tk ("srcdir" will be replaced or has already -# been replaced by the configure script): -TCL_GENERIC_DIR = @TCL_SRC_DIR@/generic - -# The directory containing the platform specific Tcl sources and headers -# appropriate for this version of Tk: -TCL_PLATFORM_DIR = @TCL_SRC_DIR@/win - -TCL_TOOL_DIR = @TCL_SRC_DIR@/tools - -# Converts a POSIX path to a Windows native path. -CYGPATH = @CYGPATH@ - -# The name of the Tcl library. -TCL_LIB_FILE = "$(shell $(CYGPATH) '@TCL_BIN_DIR@/@TCL_LIB_FILE@')" -TCL_STUB_LIB_FILE = "$(shell $(CYGPATH) '@TCL_BIN_DIR@/@TCL_STUB_LIB_FILE@')" - -SRC_DIR = @srcdir@ -ROOT_DIR = $(SRC_DIR)/.. -WIN_DIR = $(SRC_DIR) -UNIX_DIR = $(SRC_DIR)/../unix -GENERIC_DIR = $(SRC_DIR)/../generic -TTK_DIR = $(GENERIC_DIR)/ttk -BITMAP_DIR = $(ROOT_DIR)/bitmaps -XLIB_DIR = $(ROOT_DIR)/xlib -RC_DIR = $(WIN_DIR)/rc - -ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)' | sed 's!\\!/!g') -WIN_DIR_NATIVE = $(shell $(CYGPATH) '$(WIN_DIR)' | sed 's!\\!/!g') -GENERIC_DIR_NATIVE = $(shell $(CYGPATH) '$(GENERIC_DIR)' | sed 's!\\!/!g') -BITMAP_DIR_NATIVE = $(ROOT_DIR_NATIVE)/bitmaps -XLIB_DIR_NATIVE = $(ROOT_DIR_NATIVE)/xlib -RC_DIR_NATIVE = $(WIN_DIR_NATIVE)/rc -TCL_GENERIC_NATIVE = $(shell $(CYGPATH) '$(TCL_GENERIC_DIR)' | sed 's!\\!/!g') -TCL_PLATFORM_NATIVE = $(shell $(CYGPATH) '$(TCL_PLATFORM_DIR)' | sed 's!\\!/!g') -TCL_SRC_DIR_NATIVE = $(shell $(CYGPATH) '$(TCL_SRC_DIR)' | sed 's!\\!/!g') - -DLLSUFFIX = @DLLSUFFIX@ -LIBSUFFIX = @LIBSUFFIX@ -EXESUFFIX = @EXESUFFIX@ - -TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ -TK_LIB_FILE = @TK_LIB_FILE@ -TK_DLL_FILE = @TK_DLL_FILE@ -TEST_DLL_FILE = tktest$(VER)${DLLSUFFIX} -TEST_LIB_FILE = @LIBPREFIX@tktest$(VER)${LIBSUFFIX} - -SHARED_LIBRARIES = $(TK_DLL_FILE) $(TK_STUB_LIB_FILE) -STATIC_LIBRARIES = $(TK_LIB_FILE) - -WISH = wish$(VER)${EXESUFFIX} -TKTEST = tktest${EXEEXT} -CAT32 = cat32$(EXEEXT) -MAN2TCL = man2tcl$(EXEEXT) - -@SET_MAKE@ - -# Setting the VPATH variable to a list of paths will cause the -# makefile to look into these paths when resolving .c to .obj -# dependencies. - -VPATH = $(GENERIC_DIR):$(TTK_DIR):$(WIN_DIR):$(UNIX_DIR):$(XLIB_DIR):$(RC_DIR) - -# warning flags -CFLAGS_WARNING = @CFLAGS_WARNING@ - -# The default switches for optimization or debugging -CFLAGS_DEBUG = @CFLAGS_DEBUG@ -CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@ - -# The default switches for optimization or debugging -LDFLAGS_DEBUG = @LDFLAGS_DEBUG@ -LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@ - -# To change the compiler switches, for example to change from optimization to -# debugging symbols, change the following line: -#CFLAGS = $(CFLAGS_DEBUG) -#CFLAGS = $(CFLAGS_OPTIMIZE) -#CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE) -CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DUNICODE -D_UNICODE -D_ATL_XP_TARGETING - -# Special compiler flags to use when building man2tcl on Windows. -MAN2TCLFLAGS = @MAN2TCLFLAGS@ - -AR = @AR@ -RANLIB = @RANLIB@ -CC = @CC@ -RC = @RC@ -RES = @RES@ -TK_RES = @TK_RES@ -AC_FLAGS = @EXTRA_CFLAGS@ @DEFS@ @TCL_DEFS@ -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ @LDFLAGS_DEFAULT@ -LDFLAGS_CONSOLE = @LDFLAGS_CONSOLE@ -LDFLAGS_WINDOW = @LDFLAGS_WINDOW@ -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -STLIB_LD = @STLIB_LD@ -SHLIB_LD = @SHLIB_LD@ -SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ -SHLIB_CFLAGS = @SHLIB_CFLAGS@ -SHLIB_SUFFIX = @SHLIB_SUFFIX@ -VER = @TK_MAJOR_VERSION@@TK_MINOR_VERSION@ -DOTVER = @TK_MAJOR_VERSION@.@TK_MINOR_VERSION@ -LIBS = $(TCL_STUB_LIB_FILE) @LIBS@ @LIBS_GUI@ -RMDIR = rm -rf -MKDIR = mkdir -p -SHELL = @SHELL@ -RM = rm -f -COPY = cp - -BUILD_TCLSH = @BUILD_TCLSH@ - -# Tk does not used deprecated Tcl constructs so it should -# compile fine with -DTCL_NO_DEPRECATED. To remove its own -# set of deprecated code uncomment the second line. -NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED -#NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED - -# TCL_EXE is the name of a tclsh executable that is available *BEFORE* -# running make for the first time. Certain build targets (make genstubs) -# need it to be available on the PATH. This executable should *NOT* be -# required just to do a normal build although it can be required to run -# make dist. -TCL_EXE = @TCLSH_PROG@ - -CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \ --I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \ --I"${XLIB_DIR_NATIVE}" -I"${BITMAP_DIR_NATIVE}" \ --I"${TCL_GENERIC_NATIVE}" -I"${TCL_PLATFORM_NATIVE}" \ -${AC_FLAGS} $(NO_DEPRECATED_FLAGS) -DUSE_TCL_STUBS - -CC_OBJNAME = @CC_OBJNAME@ -CC_EXENAME = @CC_EXENAME@ - -# Tk used to let the configure script choose which program to use -# for installing, but there are just too many different versions of -# "install" around; better to use the install-sh script that comes -# with the distribution, which is slower but guaranteed to work. - -INSTALL = cp -INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} - -WISH_OBJS = \ - winMain.$(OBJEXT) - -TKTEST_OBJS = \ - tkSquare.$(OBJEXT) \ - tkTest.$(OBJEXT) \ - tkOldTest.$(OBJEXT) \ - tkWinTest.$(OBJEXT) - -XLIB_OBJS = \ - xcolors.$(OBJEXT) \ - xdraw.$(OBJEXT) \ - xgc.$(OBJEXT) \ - ximage.$(OBJEXT) \ - xutil.$(OBJEXT) - -TK_OBJS = \ - tkConsole.$(OBJEXT) \ - tkUnixMenubu.$(OBJEXT) \ - tkUnixScale.$(OBJEXT) \ - $(XLIB_OBJS) \ - tkWin3d.$(OBJEXT) \ - tkWin32Dll.$(OBJEXT) \ - tkWinButton.$(OBJEXT) \ - tkWinClipboard.$(OBJEXT) \ - tkWinColor.$(OBJEXT) \ - tkWinConfig.$(OBJEXT) \ - tkWinCursor.$(OBJEXT) \ - tkWinDialog.$(OBJEXT) \ - tkWinDraw.$(OBJEXT) \ - tkWinEmbed.$(OBJEXT) \ - tkWinFont.$(OBJEXT) \ - tkWinImage.$(OBJEXT) \ - tkWinInit.$(OBJEXT) \ - tkWinKey.$(OBJEXT) \ - tkWinMenu.$(OBJEXT) \ - tkWinPixmap.$(OBJEXT) \ - tkWinPointer.$(OBJEXT) \ - tkWinRegion.$(OBJEXT) \ - tkWinScrlbr.$(OBJEXT) \ - tkWinSend.$(OBJEXT) \ - tkWinSendCom.$(OBJEXT) \ - tkWinWindow.$(OBJEXT) \ - tkWinWm.$(OBJEXT) \ - tkWinX.$(OBJEXT) \ - stubs.$(OBJEXT) \ - tk3d.$(OBJEXT) \ - tkArgv.$(OBJEXT) \ - tkAtom.$(OBJEXT) \ - tkBind.$(OBJEXT) \ - tkBitmap.$(OBJEXT) \ - tkBusy.$(OBJEXT) \ - tkButton.$(OBJEXT) \ - tkCanvArc.$(OBJEXT) \ - tkCanvBmap.$(OBJEXT) \ - tkCanvImg.$(OBJEXT) \ - tkCanvLine.$(OBJEXT) \ - tkCanvPoly.$(OBJEXT) \ - tkCanvPs.$(OBJEXT) \ - tkCanvText.$(OBJEXT) \ - tkCanvUtil.$(OBJEXT) \ - tkCanvWind.$(OBJEXT) \ - tkCanvas.$(OBJEXT) \ - tkClipboard.$(OBJEXT) \ - tkCmds.$(OBJEXT) \ - tkColor.$(OBJEXT) \ - tkConfig.$(OBJEXT) \ - tkCursor.$(OBJEXT) \ - tkEntry.$(OBJEXT) \ - tkError.$(OBJEXT) \ - tkEvent.$(OBJEXT) \ - tkFileFilter.$(OBJEXT) \ - tkFocus.$(OBJEXT) \ - tkFont.$(OBJEXT) \ - tkFrame.$(OBJEXT) \ - tkGC.$(OBJEXT) \ - tkGeometry.$(OBJEXT) \ - tkGet.$(OBJEXT) \ - tkGrab.$(OBJEXT) \ - tkGrid.$(OBJEXT) \ - tkImage.$(OBJEXT) \ - tkImgBmap.$(OBJEXT) \ - tkImgGIF.$(OBJEXT) \ - tkImgPNG.$(OBJEXT) \ - tkImgPPM.$(OBJEXT) \ - tkImgPhoto.$(OBJEXT) \ - tkImgPhInstance.$(OBJEXT) \ - tkImgUtil.$(OBJEXT) \ - tkListbox.$(OBJEXT) \ - tkMacWinMenu.$(OBJEXT) \ - tkMain.$(OBJEXT) \ - tkMain2.$(OBJEXT) \ - tkMenu.$(OBJEXT) \ - tkMenubutton.$(OBJEXT) \ - tkMenuDraw.$(OBJEXT) \ - tkMessage.$(OBJEXT) \ - tkPanedWindow.$(OBJEXT) \ - tkObj.$(OBJEXT) \ - tkOldConfig.$(OBJEXT) \ - tkOption.$(OBJEXT) \ - tkPack.$(OBJEXT) \ - tkPlace.$(OBJEXT) \ - tkPointer.$(OBJEXT) \ - tkRectOval.$(OBJEXT) \ - tkScale.$(OBJEXT) \ - tkScrollbar.$(OBJEXT) \ - tkSelect.$(OBJEXT) \ - tkStyle.$(OBJEXT) \ - tkText.$(OBJEXT) \ - tkTextBTree.$(OBJEXT) \ - tkTextDisp.$(OBJEXT) \ - tkTextImage.$(OBJEXT) \ - tkTextIndex.$(OBJEXT) \ - tkTextMark.$(OBJEXT) \ - tkTextTag.$(OBJEXT) \ - tkTextWind.$(OBJEXT) \ - tkTrig.$(OBJEXT) \ - tkUndo.$(OBJEXT) \ - tkUtil.$(OBJEXT) \ - tkVisual.$(OBJEXT) \ - tkStubInit.$(OBJEXT) \ - tkWindow.$(OBJEXT) \ - $(TTK_OBJS) - -TTK_OBJS = \ - ttkWinMonitor.$(OBJEXT) \ - ttkWinTheme.$(OBJEXT) \ - ttkWinXPTheme.$(OBJEXT) \ - ttkBlink.$(OBJEXT) \ - ttkButton.$(OBJEXT) \ - ttkCache.$(OBJEXT) \ - ttkClamTheme.$(OBJEXT) \ - ttkClassicTheme.$(OBJEXT) \ - ttkDefaultTheme.$(OBJEXT) \ - ttkElements.$(OBJEXT) \ - ttkEntry.$(OBJEXT) \ - ttkFrame.$(OBJEXT) \ - ttkImage.$(OBJEXT) \ - ttkInit.$(OBJEXT) \ - ttkLabel.$(OBJEXT) \ - ttkLayout.$(OBJEXT) \ - ttkManager.$(OBJEXT) \ - ttkNotebook.$(OBJEXT) \ - ttkPanedwindow.$(OBJEXT) \ - ttkProgress.$(OBJEXT) \ - ttkScale.$(OBJEXT) \ - ttkScrollbar.$(OBJEXT) \ - ttkScroll.$(OBJEXT) \ - ttkSeparator.$(OBJEXT) \ - ttkSquare.$(OBJEXT) \ - ttkState.$(OBJEXT) \ - ttkTagSet.$(OBJEXT) \ - ttkTheme.$(OBJEXT) \ - ttkTrace.$(OBJEXT) \ - ttkTrack.$(OBJEXT) \ - ttkTreeview.$(OBJEXT) \ - ttkWidget.$(OBJEXT) \ - ttkStubInit.$(OBJEXT) - -STUB_OBJS = \ - tkStubLib.$(OBJEXT) \ - ttkStubLib.$(OBJEXT) - -TCL_DOCS = "$(TCL_SRC_DIR_NATIVE)/doc/*.[13n]" -TK_DOCS = "$(ROOT_DIR_NATIVE)/doc/*.[13n]" -CORE_DOCS = $(TCL_DOCS) $(TK_DOCS) - -DEMOPROGS = browse hello ixset rmt rolodex square tcolor timer widget - -SHELL_ENV = \ - @TCL_LIBRARY="$(TCL_SRC_DIR_NATIVE)/library"; export TCL_LIBRARY; \ - TK_LIBRARY="$(ROOT_DIR_NATIVE)/library"; export TK_LIBRARY; \ - PATH="$(TCL_BIN_DIR):$(PATH)"; export PATH; - -# Main targets. The default target -- all -- builds the binaries, -# performs any post processing on libraries or documents. - -all: binaries libraries doc - -binaries: @LIBRARIES@ $(WISH) - -libraries: - -$(ROOT_DIR)/doc/man.macros: - $(INSTALL_DATA) "$(TCL_SRC_DIR)/doc/man.macros" "$(ROOT_DIR)/doc/man.macros" - -doc: $(ROOT_DIR)/doc/man.macros - -winhelp: $(TCL_SRC_DIR)/tools/man2help.tcl $(MAN2TCL) - $(TCL_EXE) "$(TCL_SRC_DIR_NATIVE)/tools/man2help.tcl" tcl "$(VER)" $(CORE_DOCS) - $(COPY) "$(TCL_BIN_DIR)/tcl.hpj" ./ - hcw /c /e tcl.hpj - $(COPY) ./tcl$(VER).cnt ./TCL$(VER).HLP "$(TCL_SRC_DIR_NATIVE)/tools/" - -$(MAN2TCL): $(TCL_SRC_DIR)/tools/man2tcl.c - $(CC) $(CFLAGS_OPTIMIZE) $(MAN2TCLFLAGS) -o $(MAN2TCL) "$(TCL_SRC_DIR_NATIVE)/tools/man2tcl.c" - -# Specifying TESTFLAGS on the command line is the standard way to pass -# args to tcltest, ie: -# % make test TESTFLAGS="-verbose bps -file fileName.test" - -test: test-classic test-ttk - -test-classic: binaries $(TKTEST) $(TEST_DLL_FILE) $(CAT32) - $(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/all.tcl" \ - $(TESTFLAGS) | ./$(CAT32) - -test-ttk: binaries $(TKTEST) $(TEST_DLL_FILE) $(CAT32) - $(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/ttk/all.tcl" \ - $(TESTFLAGS) | ./$(CAT32) - -runtest: binaries $(TKTEST) $(TEST_DLL_FILE) - $(SHELL_ENV) ./$(TKTEST) $(TESTFLAGS) $(SCRIPT) - -# This target can be used to run wish from the build directory -# via `make shell` or `make shell SCRIPT=foo.tcl` -shell: binaries - $(SHELL_ENV) ./$(WISH) $(SCRIPT) - -demo: $(WISH) - $(SHELL_ENV) ./$(WISH) $(ROOT_DIR)/library/demos/widget - -# This target can be used to run wish inside either gdb or insight -gdb: binaries - @echo "set env TCL_LIBRARY=$(TCL_SRC_DIR_NATIVE)/library" > gdb.run - @echo "set env TK_LIBRARY=$(ROOT_DIR_NATIVE)/library" >> gdb.run - PATH="$(TCL_BIN_DIR):$(PATH)"; export PATH; \ - gdb ./$(WISH) --command=gdb.run - @$(RM) gdb.run - -install: all install-binaries install-libraries install-doc install-demos - -install-binaries: binaries - @for i in $(LIB_INSTALL_DIR) $(BIN_INSTALL_DIR) $(PKG_INSTALL_DIR); \ - do \ - if [ ! -d $$i ] ; then \ - echo "Making directory $$i"; \ - $(MKDIR) $$i; \ - chmod 755 $$i; \ - else true; \ - fi; \ - done; - @for i in $(TK_DLL_FILE) $(WISH); \ - do \ - if [ -f $$i ]; then \ - echo "Installing $$i to $(BIN_INSTALL_DIR)/"; \ - $(COPY) $$i "$(BIN_INSTALL_DIR)"; \ - fi; \ - done - @echo "Creating package index $(PKG_INDEX)"; - @$(RM) $(PKG_INDEX); - @(\ - echo "if {[catch {package present Tcl 8.6.0}]} return";\ - echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\ - echo " || ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\ - echo " package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin libtk$(VERSION).dll]] Tk]";\ - echo "} else {";\ - echo " package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin $(TK_DLL_FILE)]] Tk]";\ - echo "}";\ - ) > $(PKG_INDEX); - @for i in tkConfig.sh $(TK_LIB_FILE) $(TK_STUB_LIB_FILE); \ - do \ - if [ -f $$i ]; then \ - echo "Installing $$i to $(LIB_INSTALL_DIR)/"; \ - $(COPY) $$i "$(LIB_INSTALL_DIR)"; \ - fi; \ - done - -install-libraries: libraries - @for i in $(INSTALL_ROOT)$(prefix)/lib \ - $(INCLUDE_INSTALL_DIR) $(INCLUDE_INSTALL_DIR)/X11 \ - $(SCRIPT_INSTALL_DIR) $(SCRIPT_INSTALL_DIR)/images \ - $(SCRIPT_INSTALL_DIR)/msgs $(SCRIPT_INSTALL_DIR)/ttk; \ - do \ - if [ ! -d $$i ] ; then \ - echo "Making directory $$i"; \ - $(MKDIR) $$i; \ - chmod 755 $$i; \ - else true; \ - fi; \ - done; - @echo "Installing header files to $(INCLUDE_INSTALL_DIR)/"; - @for i in $(GENERIC_DIR)/tk.h $(GENERIC_DIR)/tkPlatDecls.h \ - $(GENERIC_DIR)/tkIntXlibDecls.h $(GENERIC_DIR)/tkDecls.h ; \ - do \ - $(INSTALL_DATA) $$i $(INCLUDE_INSTALL_DIR); \ - done; - @for i in $(XLIB_DIR)/X11/*.h; \ - do \ - $(INSTALL_DATA) $$i $(INCLUDE_INSTALL_DIR)/X11; \ - done; - @echo "Installing library files to $(SCRIPT_INSTALL_DIR)"; - @for i in $(ROOT_DIR)/library/*.tcl $(ROOT_DIR)/library/tclIndex \ - $(UNIX_DIR)/tkAppInit.c; \ - do \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR); \ - done; - @echo "Installing library ttk directory"; - @for i in $(ROOT_DIR)/library/ttk/*.tcl; \ - do \ - if [ -f $$i ] ; then \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR)/ttk; \ - fi; \ - done; - @echo "Installing library images directory"; - @for i in $(ROOT_DIR)/library/images/*; \ - do \ - if [ -f $$i ] ; then \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR)/images; \ - fi; \ - done; - @echo "Installing translation directory"; - @for i in $(ROOT_DIR)/library/msgs/*.msg; \ - do \ - if [ -f $$i ] ; then \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR)/msgs; \ - fi; \ - done; - -install-demos: - @for i in $(INSTALL_ROOT)$(prefix)/lib $(SCRIPT_INSTALL_DIR) \ - $(SCRIPT_INSTALL_DIR)/demos \ - $(SCRIPT_INSTALL_DIR)/demos/images ; \ - do \ - if [ ! -d $$i ] ; then \ - echo "Making directory $$i"; \ - $(MKDIR) $$i; \ - chmod 755 $$i; \ - else true; \ - fi; \ - done; - @echo "Installing demos to $(SCRIPT_INSTALL_DIR)/demos/"; - @for i in $(ROOT_DIR)/library/demos/*; \ - do \ - if [ -f $$i ] ; then \ - sed -e '3 s|exec wish|exec wish$(VER)|' \ - $$i > $(SCRIPT_INSTALL_DIR)/demos/`basename $$i`; \ - fi; \ - done; - @for i in $(DEMOPROGS); \ - do \ - if test $$i = "square"; then \ - rm -f $(SCRIPT_INSTALL_DIR)/demos/$$i; \ - else \ - chmod 755 $(SCRIPT_INSTALL_DIR)/demos/$$i; \ - fi; \ - done; - @echo "Installing demo images"; - @for i in $(ROOT_DIR)/library/demos/images/*; \ - do \ - if [ -f $$i ] ; then \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR)/demos/images; \ - fi; \ - done; - -install-doc: doc - -# Optional target to install private headers -install-private-headers: libraries - @for i in $(PRIVATE_INCLUDE_INSTALL_DIR); \ - do \ - if [ ! -d $$i ] ; then \ - echo "Making directory $$i"; \ - $(MKDIR) $$i; \ - chmod 755 $$i; \ - else true; \ - fi; \ - done; - @echo "Installing private header files to $(PRIVATE_INCLUDE_INSTALL_DIR)/"; - @for i in $(GENERIC_DIR)/tkInt.h $(GENERIC_DIR)/tkIntDecls.h \ - $(GENERIC_DIR)/tkIntPlatDecls.h $(GENERIC_DIR)/tkPort.h \ - $(WIN_DIR)/tkWinPort.h $(WIN_DIR)/tkWinInt.h $(WIN_DIR)/tkWin.h; \ - do \ - $(INSTALL_DATA) $$i $(PRIVATE_INCLUDE_INSTALL_DIR); \ - done; - -$(WISH): $(WISH_OBJS) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES) - $(CC) $(CFLAGS) $(WISH_OBJS) $(TK_LIB_FILE) \ - $(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \ - wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW) - @VC_MANIFEST_EMBED_EXE@ - -tktest: $(TKTEST) - -$(TKTEST): testMain.$(OBJEXT) $(TEST_DLL_FILE) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES) - $(CC) $(CFLAGS) testMain.$(OBJEXT) $(TEST_LIB_FILE) $(TK_LIB_FILE) \ - $(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \ - wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW) - @VC_MANIFEST_EMBED_EXE@ - -${TEST_DLL_FILE}: ${TKTEST_OBJS} ${TK_STUB_LIB_FILE} - @MAKE_DLL@ ${TKTEST_OBJS} $(TK_STUB_LIB_FILE) $(SHLIB_LD_LIBS) - -# Msys make requires this next rule for some reason. -$(TCL_SRC_DIR)/win/cat.c: - -cat32.${OBJEXT}: $(TCL_SRC_DIR)/win/cat.c - $(CC) -c $(CC_SWITCHES) "$(TCL_SRC_DIR)/win/cat.c" $(CC_OBJNAME) - -$(CAT32): cat32.${OBJEXT} - $(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE) - -# The following targets are configured by autoconf to generate either -# a shared library or static library - -${TK_STUB_LIB_FILE}: ${STUB_OBJS} - @$(RM) ${TK_STUB_LIB_FILE} - @MAKE_STUB_LIB@ ${STUB_OBJS} - @POST_MAKE_LIB@ - -${TK_DLL_FILE}: ${TK_OBJS} $(TK_RES) - @$(RM) ${TK_DLL_FILE} - @MAKE_DLL@ ${TK_OBJS} $(TK_RES) $(SHLIB_LD_LIBS) - @VC_MANIFEST_EMBED_DLL@ - -${TK_LIB_FILE}: ${TK_OBJS} - @$(RM) ${TK_LIB_FILE} - @MAKE_LIB@ ${TK_OBJS} - @POST_MAKE_LIB@ - -# Special case object file targets - -winMain.$(OBJEXT): winMain.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -testMain.$(OBJEXT): winMain.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ -DTK_TEST $(CC_OBJNAME) - -tkTest.$(OBJEXT): tkTest.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -tkOldTest.$(OBJEXT): tkOldTest.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -tkWinTest.$(OBJEXT): tkWinTest.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -tkSquare.$(OBJEXT): tkSquare.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -tkMain2.$(OBJEXT): tkMain.c - $(CC) -c $(CC_SWITCHES) -DBUILD_tk -DTK_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) - -# Extra dependency info -tkConsole.$(OBJEXT): configure Makefile -tkMain.$(OBJEXT): configure Makefile -tkWindow.$(OBJEXT): configure Makefile - -# Add the object extension to the implicit rules. By default .obj is not -# automatically added. - -.SUFFIXES: .${OBJEXT} -.SUFFIXES: .$(RES) -.SUFFIXES: .rc - -# Implicit rule for all object files that will end up in the Tk library - -%.$(OBJEXT): %.c - $(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME) - -.rc.$(RES): - $(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(TCL_GENERIC_NATIVE)" @RC_INCLUDE@ "$(RC_DIR_NATIVE)" @DEPARG@ - -depend: - -cleanhelp: - $(RM) *.hlp *.cnt *.hpj *.GID *.rtf man2tcl${EXEEXT} - -clean: cleanhelp - $(RM) *.lib *.a *.exp *.dll *.res *.${OBJEXT} *~ \#* TAGS a.out - $(RM) $(WISH) $(TKTEST) $(CAT32) - $(RM) *.pch *.ilk *.pdb - -distclean: clean - $(RM) Makefile config.status config.cache config.log tkConfig.sh \ - wish.exe.manifest - -Makefile: $(SRC_DIR)/Makefile.in - ./config.status - -# -# Regenerate the stubs files. -# - -$(GENERIC_DIR)/tkStubInit.c: $(GENERIC_DIR)/tk.decls \ - $(GENERIC_DIR)/tkInt.decls - @echo "Warning: tkStubInit.c may be out of date." - @echo "Developers may want to run \"make genstubs\" to regenerate." - @echo "This warning can be safely ignored, do not report as a bug!" - -genstubs: - $(TCL_EXE) "$(TCL_TOOL_DIR)/genStubs.tcl" \ - "$(GENERIC_DIR_NATIVE)" \ - "$(GENERIC_DIR_NATIVE)/tk.decls" \ - "$(GENERIC_DIR_NATIVE)/tkInt.decls" - $(TCL_EXE) "$(TTK_DIR)/ttkGenStubs.tcl" \ - "$(TTK_DIR)" \ - "$(TTK_DIR)/ttk.decls" - -# -# The list of all the targets that do not correspond to real files. This stops -# 'make' from getting confused when someone makes an error in a rule. -# - -.PHONY: all binaries libraries doc tkLibObjs objs tktest-real test test-classic -.PHONY: test-ttk testlang runtest shell demo gdb install install-strip -.PHONY: install-binaries install-libraries install-demos install-doc -.PHONY: install-private-headers clean distclean depend genstubs checkstubs -.PHONY: checkuchar checkexports rpm dist alldist allpatch html html-tcl html-tk - -# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/tk8.6/win/README b/tk8.6/win/README deleted file mode 100644 index 8670446..0000000 --- a/tk8.6/win/README +++ /dev/null @@ -1,21 +0,0 @@ -Tk 8.6 for Windows - -Originally by Scott Stanton while at Sun Microsystems Labs - -This is the directory where you configure and compile the Windows -version of Tk. This directory also contains source files for Tk -that are specific to Microsoft Windows. The rest of this file -contains information specific to the Windows version of Tk. - -Please see the README and win/README files that come with the -associated Tcl release for an extensive set of pointers to -documentation. You will need to obtain and compile the -Tcl release before using the Tk source distrition. - -If you install the Tk sources next to the Tcl sources, then -the Tk Makefiles (e.g., makefile.vc for VC++) will properly -locate the necessary Tcl files. Otherwise you may need to -edit makefile.vc and adjust the path to Tcl accordingly. - -Information about compiling for windows is maintained at: - http://www.tcl.tk/doc/howto/compile.html diff --git a/tk8.6/win/aclocal.m4 b/tk8.6/win/aclocal.m4 deleted file mode 100644 index bc7540d..0000000 --- a/tk8.6/win/aclocal.m4 +++ /dev/null @@ -1 +0,0 @@ -builtin(include,tcl.m4) diff --git a/tk8.6/win/buildall.vc.bat b/tk8.6/win/buildall.vc.bat deleted file mode 100755 index 8f6803b..0000000 --- a/tk8.6/win/buildall.vc.bat +++ /dev/null @@ -1,107 +0,0 @@ -@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/tk8.6/win/configure b/tk8.6/win/configure deleted file mode 100755 index 15d509e..0000000 --- a/tk8.6/win/configure +++ /dev/null @@ -1,6176 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59. -# -# Copyright (C) 2003 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi -DUALCASE=1; export DUALCASE # for MKS sh - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -exec 6>&1 - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_config_libobj_dir=. -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} - -# Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= - -ac_unique_file="../generic/tk.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include <stdio.h> -#if HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif -#if HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#if STDC_HEADERS -# include <stdlib.h> -# include <stddef.h> -#else -# if HAVE_STDLIB_H -# include <stdlib.h> -# endif -#endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H -# include <memory.h> -# endif -# include <string.h> -#endif -#if HAVE_STRINGS_H -# include <strings.h> -#endif -#if HAVE_INTTYPES_H -# include <inttypes.h> -#else -# if HAVE_STDINT_H -# include <stdint.h> -# endif -#endif -#if HAVE_UNISTD_H -# include <unistd.h> -#endif" - -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_DEFS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING MAN2TCLFLAGS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE BUILD_TCLSH TCLSH_PROG TK_WIN_VERSION MACHINE TK_VERSION TK_MAJOR_VERSION TK_MINOR_VERSION TK_PATCH_LEVEL TK_DBGX TK_LIB_FILE TK_DLL_FILE TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_BUILD_STUB_LIB_SPEC TK_SRC_DIR TK_BIN_DIR TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_DBGX CFG_TK_SHARED_LIB_SUFFIX CFG_TK_UNSHARED_LIB_SUFFIX CFG_TK_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW TK_RES STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TK_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TK_LIB_FLAG TK_LIB_SPEC TK_BUILD_LIB_SPEC TK_STUB_LIB_SPEC TK_STUB_LIB_PATH TK_BUILD_STUB_LIB_PATH TK_CC_SEARCH_FLAGS TK_LD_SEARCH_FLAGS RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS' -ac_subst_files='' - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -ac_prev= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_option in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "enable_$ac_feature='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "with_$ac_package='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } - fi -fi -(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || - { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 - { (exit 1); exit 1; }; } -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS -ac_env_CPP_set=${CPP+set} -ac_env_CPP_value=$CPP -ac_cv_env_CPP_set=${CPP+set} -ac_cv_env_CPP_value=$CPP - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -_ACEOF - - cat <<_ACEOF -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] -_ACEOF - - cat <<\_ACEOF -_ACEOF -fi - -if test -n "$ac_init_help"; then - - cat <<\_ACEOF - -Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-threads build with threads (default: on) - --enable-shared build and link with shared libraries (default: on) - --enable-64bit enable 64bit support (where applicable) - --enable-wince enable Win/CE support (where applicable) - --enable-symbols build with debugging symbols (default: off) - --enable-embedded-manifest - embed manifest if possible (default: yes) - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-tcl directory containing tcl configuration - (tclConfig.sh) - --with-celib=DIR use Windows/CE support library from DIR - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a - nonstandard directory <lib dir> - CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have - headers in a nonstandard directory <include dir> - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -_ACEOF -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - ac_popdir=`pwd` - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd $ac_popdir - done -fi - -test -n "$ac_init_help" && exit 0 -if $ac_init_version; then - cat <<\_ACEOF - -Copyright (C) 2003 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit 0 -fi -exec 5>config.log -cat >&5 <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was - - $ $0 $@ - -_ACEOF -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_sep= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - # Get rid of the leading space. - ac_sep=" " - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -{ - (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) - sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; - *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------- ## -## Output files. ## -## ------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - sed "/^$/d" confdefs.h | sort - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status - ' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - - - - - - -# The following define is needed when building with Cygwin since newer -# versions of autoconf incorrectly set SHELL to /bin/bash instead of -# /bin/sh. The bash shell seems to suffer from some strange failures. -SHELL=/bin/sh - -TK_VERSION=8.6 -TK_MAJOR_VERSION=8 -TK_MINOR_VERSION=6 -TK_PATCH_LEVEL=".8" -VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION - -#------------------------------------------------------------------------ -# Handle the --prefix=... option -#------------------------------------------------------------------------ - -if test "${prefix}" = "NONE"; then - prefix=/usr/local -fi -if test "${exec_prefix}" = "NONE"; then - exec_prefix=$prefix -fi -# libdir must be a fully qualified path (not ${exec_prefix}/lib) -eval libdir="$libdir" - -#------------------------------------------------------------------------ -# Standard compiler checks -#------------------------------------------------------------------------ - -# If the user did not set CFLAGS, set it now to keep -# the AC_PROG_CC macro from adding "-g -O2". -if test "${CFLAGS+set}" != "set" ; then - CFLAGS="" -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CC" && break -done - - CC=$ac_ct_CC -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5 - (eval $ac_compiler --version </dev/null >&5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5 - (eval $ac_compiler -v </dev/null >&5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5 - (eval $ac_compiler -V </dev/null >&5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -# b.out is created by i960 compilers. -for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; - conftest.$ac_ext ) - # This is the source file. - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext - break;; - * ) - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 - -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_cc_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_stdc=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std1 is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std1. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX 10.20 and later -Ae -# HP-UX older versions -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_stdc=$ac_arg -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext -done -rm -f conftest.$ac_ext conftest.$ac_objext -CC=$ac_save_CC - -fi - -case "x$ac_cv_prog_cc_stdc" in - x|xno) - echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6 ;; - *) - echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 - CC="$CC $ac_cv_prog_cc_stdc" ;; -esac - -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include <stdlib.h> -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -echo "$as_me:$LINENO: checking for inline" >&5 -echo $ECHO_N "checking for inline... $ECHO_C" >&6 -if test "${ac_cv_c_inline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif - -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_inline=$ac_kw; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 -echo "${ECHO_T}$ac_cv_c_inline" >&6 - - -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif -_ACEOF - ;; -esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6 -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6 -if test "${ac_cv_prog_egrep+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' - fi -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 -echo "${ECHO_T}$ac_cv_prog_egrep" >&6 - EGREP=$ac_cv_prog_egrep - - -echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_stdc=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <string.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <stdlib.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <ctype.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - exit(2); - exit (0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6 -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="${ac_tool_prefix}ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - echo "$as_me:$LINENO: result: $AR" >&5 -echo "${ECHO_T}$AR" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_AR"; then - ac_ct_AR=$AR - # Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 -echo "${ECHO_T}$ac_ct_AR" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - AR=$ac_ct_AR -else - AR="$ac_cv_prog_AR" -fi - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - RANLIB=$ac_ct_RANLIB -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. -set dummy ${ac_tool_prefix}windres; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RC"; then - ac_cv_prog_RC="$RC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RC="${ac_tool_prefix}windres" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -RC=$ac_cv_prog_RC -if test -n "$RC"; then - echo "$as_me:$LINENO: result: $RC" >&5 -echo "${ECHO_T}$RC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_RC"; then - ac_ct_RC=$RC - # Extract the first word of "windres", so it can be a program name with args. -set dummy windres; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RC"; then - ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RC="windres" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_RC=$ac_cv_prog_ac_ct_RC -if test -n "$ac_ct_RC"; then - echo "$as_me:$LINENO: result: $ac_ct_RC" >&5 -echo "${ECHO_T}$ac_ct_RC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - RC=$ac_ct_RC -else - RC="$ac_cv_prog_RC" -fi - - -#-------------------------------------------------------------------- -# Checks to see if the make program sets the $MAKE variable. -#-------------------------------------------------------------------- - -echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` -if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.make <<\_ACEOF -all: - @echo 'ac_maketemp="$(MAKE)"' -_ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` -if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes -else - eval ac_cv_prog_make_${ac_make}_set=no -fi -rm -f conftest.make -fi -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - SET_MAKE= -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - SET_MAKE="MAKE=${MAKE-make}" -fi - - -#-------------------------------------------------------------------- -# Determines the correct binary file extension (.o, .obj, .exe etc.) -#-------------------------------------------------------------------- - - - - -#-------------------------------------------------------------------- -# Check whether --enable-threads or --disable-threads was given. -#-------------------------------------------------------------------- - - - echo "$as_me:$LINENO: checking for building with threads" >&5 -echo $ECHO_N "checking for building with threads... $ECHO_C" >&6 - # Check whether --enable-threads or --disable-threads was given. -if test "${enable_threads+set}" = set; then - enableval="$enable_threads" - tcl_ok=$enableval -else - tcl_ok=yes -fi; - - if test "$tcl_ok" = "yes"; then - echo "$as_me:$LINENO: result: yes (default)" >&5 -echo "${ECHO_T}yes (default)" >&6 - TCL_THREADS=1 - cat >>confdefs.h <<\_ACEOF -#define TCL_THREADS 1 -_ACEOF - - # USE_THREAD_ALLOC tells us to try the special thread-based - # allocator that significantly reduces lock contention - cat >>confdefs.h <<\_ACEOF -#define USE_THREAD_ALLOC 1 -_ACEOF - - else - TCL_THREADS=0 - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - fi - - - -#-------------------------------------------------------------------- -# The statements below define a collection of symbols related to -# building libtk as a shared library instead of a static library. -#-------------------------------------------------------------------- - - - echo "$as_me:$LINENO: checking how to build libraries" >&5 -echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6 - # Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - tcl_ok=$enableval -else - tcl_ok=yes -fi; - - if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - tcl_ok=$enableval - else - tcl_ok=yes - fi - - if test "$tcl_ok" = "yes" ; then - echo "$as_me:$LINENO: result: shared" >&5 -echo "${ECHO_T}shared" >&6 - SHARED_BUILD=1 - else - echo "$as_me:$LINENO: result: static" >&5 -echo "${ECHO_T}static" >&6 - SHARED_BUILD=0 - -cat >>confdefs.h <<\_ACEOF -#define STATIC_BUILD 1 -_ACEOF - - fi - - -#-------------------------------------------------------------------- -# Locate and source the tclConfig.sh file. -#-------------------------------------------------------------------- - - - # - # Ok, lets find the tcl configuration - # First, look for one uninstalled. - # the alternative search directory is invoked by --with-tcl - # - - if test x"${no_tcl}" = x ; then - # we reset no_tcl in case something fails here - no_tcl=true - -# Check whether --with-tcl or --without-tcl was given. -if test "${with_tcl+set}" = set; then - withval="$with_tcl" - with_tclconfig="${withval}" -fi; - echo "$as_me:$LINENO: checking for Tcl configuration" >&5 -echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6 - if test "${ac_cv_c_tclconfig+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - - # First check to see if --with-tcl was specified. - if test x"${with_tclconfig}" != x ; then - case "${with_tclconfig}" in - */tclConfig.sh ) - if test -f "${with_tclconfig}"; then - { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5 -echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;} - with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" - fi ;; - esac - if test -f "${with_tclconfig}/tclConfig.sh" ; then - ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" - else - { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 -echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} - { (exit 1); exit 1; }; } - fi - fi - - # then check for a private Tcl installation - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ../tcl \ - `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ - ../../tcl \ - `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ - ../../../tcl \ - `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do - if test -f "$i/win/tclConfig.sh" ; then - ac_cv_c_tclconfig="`(cd $i/win; pwd)`" - break - fi - done - fi - - # check in a few common install locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in `ls -d ${libdir} 2>/dev/null` \ - `ls -d ${exec_prefix}/lib 2>/dev/null` \ - `ls -d ${prefix}/lib 2>/dev/null` \ - `ls -d /cygdrive/c/Tcl/lib 2>/dev/null` \ - `ls -d /cygdrive/c/Progra~1/Tcl/lib 2>/dev/null` \ - `ls -d /c/Tcl/lib 2>/dev/null` \ - `ls -d /c/Progra~1/Tcl/lib 2>/dev/null` \ - `ls -d C:/Tcl/lib 2>/dev/null` \ - `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ - ; do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig="`(cd $i; pwd)`" - break - fi - done - fi - - # check in a few other private locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ${srcdir}/../tcl \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do - if test -f "$i/win/tclConfig.sh" ; then - ac_cv_c_tclconfig="`(cd $i/win; pwd)`" - break - fi - done - fi - -fi - - - if test x"${ac_cv_c_tclconfig}" = x ; then - TCL_BIN_DIR="# no Tcl configs found" - { { echo "$as_me:$LINENO: error: Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" >&5 -echo "$as_me: error: Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" >&2;} - { (exit 1); exit 1; }; } - else - no_tcl= - TCL_BIN_DIR="${ac_cv_c_tclconfig}" - echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5 -echo "${ECHO_T}found ${TCL_BIN_DIR}/tclConfig.sh" >&6 - fi - fi - - - echo "$as_me:$LINENO: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5 -echo $ECHO_N "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... $ECHO_C" >&6 - - if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then - echo "$as_me:$LINENO: result: loading" >&5 -echo "${ECHO_T}loading" >&6 - . "${TCL_BIN_DIR}/tclConfig.sh" - else - echo "$as_me:$LINENO: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5 -echo "${ECHO_T}could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6 - fi - - # - # If the TCL_BIN_DIR is the build directory (not the install directory), - # then set the common variable name to the value of the build variables. - # For example, the variable TCL_LIB_SPEC will be set to the value - # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC - # instead of TCL_BUILD_LIB_SPEC since it will work with both an - # installed and uninstalled version of Tcl. - # - - if test -f $TCL_BIN_DIR/Makefile ; then - TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} - TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} - TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} - fi - - # - # eval is required to do the TCL_DBGX substitution - # - - eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" - eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" - eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" - - eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" - eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" - eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" - - - - - - - - - - - - - - - - -if test "${TCL_MAJOR_VERSION}" != "${TK_MAJOR_VERSION}"; then - { { echo "$as_me:$LINENO: error: ${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}. -Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}. -Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}." >&5 -echo "$as_me: error: ${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}. -Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}. -Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}." >&2;} - { (exit 1); exit 1; }; } -fi -if test "${TCL_MINOR_VERSION}" -lt "${TK_MINOR_VERSION}"; then - { { echo "$as_me:$LINENO: error: ${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}. -Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}. -Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}." >&5 -echo "$as_me: error: ${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}. -Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}. -Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}." >&2;} - { (exit 1); exit 1; }; } -fi - -#-------------------------------------------------------------------- -# The statements below define a collection of compile flags. This -# macro depends on the value of SHARED_BUILD, and should be called -# after SC_ENABLE_SHARED checks the configure switches. -#-------------------------------------------------------------------- - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_Header=no" -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - - - # Step 0: Enable 64 bit support? - - echo "$as_me:$LINENO: checking if 64bit support is requested" >&5 -echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6 - # Check whether --enable-64bit or --disable-64bit was given. -if test "${enable_64bit+set}" = set; then - enableval="$enable_64bit" - do64bit=$enableval -else - do64bit=no -fi; - echo "$as_me:$LINENO: result: $do64bit" >&5 -echo "${ECHO_T}$do64bit" >&6 - - # Cross-compiling options for Windows/CE builds - - echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5 -echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6 - # Check whether --enable-wince or --disable-wince was given. -if test "${enable_wince+set}" = set; then - enableval="$enable_wince" - doWince=$enableval -else - doWince=no -fi; - echo "$as_me:$LINENO: result: $doWince" >&5 -echo "${ECHO_T}$doWince" >&6 - - echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5 -echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6 - -# Check whether --with-celib or --without-celib was given. -if test "${with_celib+set}" = set; then - withval="$with_celib" - CELIB_DIR=$withval -else - CELIB_DIR=NO_CELIB -fi; - echo "$as_me:$LINENO: result: $CELIB_DIR" >&5 -echo "${ECHO_T}$CELIB_DIR" >&6 - - # Set some defaults (may get changed below) - EXTRA_CFLAGS="" - -cat >>confdefs.h <<\_ACEOF -#define MODULE_SCOPE extern -_ACEOF - - - # Extract the first word of "cygpath", so it can be a program name with args. -set dummy cygpath; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CYGPATH+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CYGPATH"; then - ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CYGPATH="cygpath -m" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo" -fi -fi -CYGPATH=$ac_cv_prog_CYGPATH -if test -n "$CYGPATH"; then - echo "$as_me:$LINENO: result: $CYGPATH" >&5 -echo "${ECHO_T}$CYGPATH" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - - SHLIB_SUFFIX=".dll" - - # MACHINE is IX86 for LINK, but this is used by the manifest, - # which requires x86|amd64|ia64. - MACHINE="X86" - - if test "$GCC" = "yes"; then - - echo "$as_me:$LINENO: checking for cross-compile version of gcc" >&5 -echo $ECHO_N "checking for cross-compile version of gcc... $ECHO_C" >&6 -if test "${ac_cv_cross+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - #ifndef _WIN32 - #error cross-compiler - #endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_cross=no -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_cross=yes -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $ac_cv_cross" >&5 -echo "${ECHO_T}$ac_cv_cross" >&6 - - if test "$ac_cv_cross" = "yes"; then - case "$do64bit" in - amd64|x64|yes) - CC="x86_64-w64-mingw32-gcc" - LD="x86_64-w64-mingw32-ld" - AR="x86_64-w64-mingw32-ar" - RANLIB="x86_64-w64-mingw32-ranlib" - RC="x86_64-w64-mingw32-windres" - ;; - *) - CC="i686-w64-mingw32-gcc" - LD="i686-w64-mingw32-ld" - AR="i686-w64-mingw32-ar" - RANLIB="i686-w64-mingw32-ranlib" - RC="i686-w64-mingw32-windres" - ;; - esac - fi - fi - - # Check for a bug in gcc's windres that causes the - # compile to fail when a Windows native path is - # passed into windres. The mingw toolchain requires - # Windows native paths while Cygwin should work - # with both. Avoid the bug by passing a POSIX - # path when using the Cygwin toolchain. - - if test "$GCC" = "yes" && test "$CYGPATH" != "echo" ; then - conftest=/tmp/conftest.rc - echo "STRINGTABLE BEGIN" > $conftest - echo "101 \"name\"" >> $conftest - echo "END" >> $conftest - - echo "$as_me:$LINENO: checking for Windows native path bug in windres" >&5 -echo $ECHO_N "checking for Windows native path bug in windres... $ECHO_C" >&6 - cyg_conftest=`$CYGPATH $conftest` - if { ac_try='$RC -o conftest.res.o $cyg_conftest' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } ; then - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - else - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - CYGPATH=echo - fi - conftest= - cyg_conftest= - fi - - if test "$CYGPATH" = "echo"; then - DEPARG='"$<"' - else - DEPARG='"$(shell $(CYGPATH) $<)"' - fi - - # set various compiler flags depending on whether we are using gcc or cl - - if test "${GCC}" = "yes" ; then - extra_cflags="-pipe" - extra_ldflags="-pipe -static-libgcc" - echo "$as_me:$LINENO: checking for mingw32 version of gcc" >&5 -echo $ECHO_N "checking for mingw32 version of gcc... $ECHO_C" >&6 -if test "${ac_cv_win32+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - #ifdef _WIN32 - #error win32 - #endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_win32=no -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_win32=yes -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $ac_cv_win32" >&5 -echo "${ECHO_T}$ac_cv_win32" >&6 - if test "$ac_cv_win32" != "yes"; then - { { echo "$as_me:$LINENO: error: ${CC} cannot produce win32 executables." >&5 -echo "$as_me: error: ${CC} cannot produce win32 executables." >&2;} - { (exit 1); exit 1; }; } - fi - - hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain" - echo "$as_me:$LINENO: checking for working -municode linker flag" >&5 -echo $ECHO_N "checking for working -municode linker flag... $ECHO_C" >&6 -if test "${ac_cv_municode+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - #include <windows.h> - int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;} - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_municode=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_municode=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $ac_cv_municode" >&5 -echo "${ECHO_T}$ac_cv_municode" >&6 - CFLAGS=$hold_cflags - if test "$ac_cv_municode" = "yes" ; then - extra_ldflags="$extra_ldflags -municode" - else - extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS" - fi - fi - - echo "$as_me:$LINENO: checking compiler flags" >&5 -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 -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' - RC_OUT=-o - RC_TYPE= - RC_INCLUDE=--include - RC_DEFINE=--define - RES=res.o - MAKE_LIB="\${STLIB_LD} \$@" - MAKE_STUB_LIB="\${STLIB_LD} \$@" - POST_MAKE_LIB="\${RANLIB} \$@" - MAKE_EXE="\${CC} -o \$@" - LIBPREFIX="lib" - - if test "${SHARED_BUILD}" = "0" ; then - # static - echo "$as_me:$LINENO: result: using static flags" >&5 -echo "${ECHO_T}using static flags" >&6 - runtime= - LIBRARIES="\${STATIC_LIBRARIES}" - EXESUFFIX="s\${DBGX}.exe" - else - # dynamic - echo "$as_me:$LINENO: result: using shared flags" >&5 -echo "${ECHO_T}using shared flags" >&6 - - # ad-hoc check to see if CC supports -shared. - if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then - { { echo "$as_me:$LINENO: error: ${CC} does not support the -shared option. - You will need to upgrade to a newer version of the toolchain." >&5 -echo "$as_me: error: ${CC} does not support the -shared option. - You will need to upgrade to a newer version of the toolchain." >&2;} - { (exit 1); exit 1; }; } - fi - - runtime= - # Add SHLIB_LD_LIBS to the Make rule, not here. - - EXESUFFIX="\${DBGX}.exe" - LIBRARIES="\${SHARED_LIBRARIES}" - fi - # Link with gcc since ld does not link to default libs like - # -luser32 and -lmsvcrt by default. - SHLIB_LD='${CC} -shared' - SHLIB_LD_LIBS='${LIBS}' - MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \$@ ${extra_ldflags} \ - -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\$@)" - # DLLSUFFIX is separate because it is the building block for - # users of tclConfig.sh that may build shared or static. - DLLSUFFIX="\${DBGX}.dll" - LIBSUFFIX="\${DBGX}.a" - LIBFLAGSUFFIX="\${DBGX}" - SHLIB_SUFFIX=.dll - - EXTRA_CFLAGS="${extra_cflags}" - - CFLAGS_DEBUG=-g - CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" - CFLAGS_WARNING="-Wall -Wdeclaration-after-statement" - LDFLAGS_DEBUG= - LDFLAGS_OPTIMIZE= - - # Specify the CC output file names based on the target name - CC_OBJNAME="-o \$@" - CC_EXENAME="-o \$@" - - # Specify linker flags depending on the type of app being - # built -- Console vs. Window. - # - # ORIGINAL COMMENT: - # We need to pass -e _WinMain@16 so that ld will use - # WinMain() instead of main() as the entry point. We can't - # use autoconf to check for this case since it would need - # to run an executable and that does not work when - # cross compiling. Remove this -e workaround once we - # require a gcc that does not have this bug. - # - # MK NOTE: Tk should use a different mechanism. This causes - # interesting problems, such as wish dying at startup. - #LDFLAGS_WINDOW="-mwindows -e _WinMain@16 ${extra_ldflags}" - LDFLAGS_CONSOLE="-mconsole ${extra_ldflags}" - LDFLAGS_WINDOW="-mwindows ${extra_ldflags}" - - case "$do64bit" in - amd64|x64|yes) - MACHINE="AMD64" ; # assume AMD64 as default 64-bit build - echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 -echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 - ;; - ia64) - MACHINE="IA64" - echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 -echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 - ;; - *) - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - #ifndef _WIN64 - #error 32-bit - #endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_win_64bit=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_win_64bit=no - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - if test "$tcl_win_64bit" = "yes" ; then - do64bit=amd64 - MACHINE="AMD64" - echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 -echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 - fi - ;; - esac - else - if test "${SHARED_BUILD}" = "0" ; then - # static - echo "$as_me:$LINENO: result: using static flags" >&5 -echo "${ECHO_T}using static flags" >&6 - runtime=-MT - LIBRARIES="\${STATIC_LIBRARIES}" - EXESUFFIX="s\${DBGX}.exe" - else - # dynamic - echo "$as_me:$LINENO: result: using shared flags" >&5 -echo "${ECHO_T}using shared flags" >&6 - runtime=-MD - # 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 - # users of tclConfig.sh that may build shared or static. - DLLSUFFIX="\${DBGX}.dll" - LIBSUFFIX="\${DBGX}.lib" - LIBFLAGSUFFIX="\${DBGX}" - - # This is a 2-stage check to make sure we have the 64-bit SDK - # We have to know where the SDK is installed. - # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs - if test "$do64bit" != "no" ; then - if test "x${MSSDK}x" = "xx" ; then - MSSDK="C:/Progra~1/Microsoft Platform SDK" - fi - MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` - PATH64="" - case "$do64bit" in - amd64|x64|yes) - MACHINE="AMD64" ; # assume AMD64 as default 64-bit build - PATH64="${MSSDK}/Bin/Win64/x86/AMD64" - ;; - ia64) - MACHINE="IA64" - PATH64="${MSSDK}/Bin/Win64" - ;; - esac - if test ! -d "${PATH64}" ; then - { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK" >&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 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 - # TEA_PATH_NOSPACE to avoid this issue. - # Check if _WIN64 is already recognized, and if so we don't - # need to modify CC. - echo "$as_me:$LINENO: checking whether _WIN64 is declared" >&5 -echo $ECHO_N "checking whether _WIN64 is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl__WIN64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -#ifndef _WIN64 - char *p = (char *) _WIN64; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl__WIN64=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_have_decl__WIN64=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl__WIN64" >&5 -echo "${ECHO_T}$ac_cv_have_decl__WIN64" >&6 -if test $ac_cv_have_decl__WIN64 = yes; then - : -else - CC="\"${PATH64}/cl.exe\" -I\"${MSSDK}/Include\" \ - -I\"${MSSDK}/Include/crt\" \ - -I\"${MSSDK}/Include/crt/sys\"" -fi - - RC="\"${MSSDK}/bin/rc.exe\"" - 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="${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 - LIBS="$LIBS bufferoverflowU.lib" - else - RC="rc" - # -Od - no optimization - # -WX - warnings as errors - 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="${lflags} -nologo" - LINKBIN="link" - fi - - if test "$doWince" != "no" ; then - # Set defaults for common evc4/PPC2003 setup - # Currently Tcl requires 300+, possibly 420+ for sockets - CEVERSION=420; # could be 211 300 301 400 420 ... - TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... - ARCH=ARM; # could be ARM MIPS X86EM ... - PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" - if test "$doWince" != "yes"; then - # If !yes then the user specified something - # Reset ARCH to allow user to skip specifying it - ARCH= - eval `echo $doWince | awk -F "," '{ \ - if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \ - if ($1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ - if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \ - if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \ - if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \ - }'` - if test "x${ARCH}" = "x" ; then - ARCH=$TARGETCPU; - fi - fi - OSVERSION=WCE$CEVERSION; - if test "x${WCEROOT}" = "x" ; then - WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" - if test ! -d "${WCEROOT}" ; then - WCEROOT="C:/Program Files/Microsoft eMbedded Tools" - fi - fi - if test "x${SDKROOT}" = "x" ; then - SDKROOT="C:/Program Files/Windows CE Tools" - if test ! -d "${SDKROOT}" ; then - SDKROOT="C:/Windows CE Tools" - fi - fi - # The space-based-path will work for the Makefile, but will - # not work if AC_TRY_COMPILE is called. - WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` - SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` - CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` - if test ! -d "${CELIB_DIR}/inc"; then - { { echo "$as_me:$LINENO: error: Invalid celib directory \"${CELIB_DIR}\"" >&5 -echo "$as_me: error: Invalid celib directory \"${CELIB_DIR}\"" >&2;} - { (exit 1); exit 1; }; } - fi - if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"\ - -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then - { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5 -echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;} - { (exit 1); exit 1; }; } - else - CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" - if test -d "${CEINCLUDE}/${TARGETCPU}" ; then - CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" - fi - CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" - fi - fi - - if test "$doWince" != "no" ; then - CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" - if test "${TARGETCPU}" = "X86"; then - CC="${CEBINROOT}/cl.exe" - else - CC="${CEBINROOT}/cl${ARCH}.exe" - fi - CC="\"${CC}\" -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" - RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" - arch=`echo ${ARCH} | awk '{print tolower($0)}'` - defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _DLL _WINDOWS" - for i in $defs ; do - cat >>confdefs.h <<_ACEOF -#define $i 1 -_ACEOF - - done -# if test "${ARCH}" = "X86EM"; then -# AC_DEFINE_UNQUOTED(_WIN32_WCE_EMULATION) -# fi - cat >>confdefs.h <<_ACEOF -#define _WIN32_WCE $CEVERSION -_ACEOF - - cat >>confdefs.h <<_ACEOF -#define UNDER_CE $CEVERSION -_ACEOF - - CFLAGS_DEBUG="-nologo -Zi -Od" - CFLAGS_OPTIMIZE="-nologo -O2" - lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` - lflags="-nodefaultlib -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" - LINKBIN="\"${CEBINROOT}/link.exe\"" - - if test "${CEVERSION}" -lt 400 ; then - LIBS="coredll.lib corelibc.lib winsock.lib" - else - LIBS="coredll.lib corelibc.lib ws2.lib" - fi - # celib currently stuck at wce300 status - #LIBS="$LIBS \${CELIB_DIR}/wince-${ARCH}-pocket-${OSVERSION}-release/celib.lib" - LIBS="$LIBS \"\${CELIB_DIR}/wince-${ARCH}-pocket-wce300-release/celib.lib\"" - LIBS_GUI="commctrl.lib commdlg.lib" - else - LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib" - fi - - SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}" - SHLIB_LD_LIBS='${LIBS}' - # link -lib only works when -lib is the first arg - STLIB_LD="${LINKBIN} -lib ${lflags}" - RC_OUT=-fo - RC_TYPE=-r - RC_INCLUDE=-i - RC_DEFINE=-d - RES=res - MAKE_LIB="\${STLIB_LD} -out:\$@" - MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\$@" - POST_MAKE_LIB= - MAKE_EXE="\${CC} -Fe\$@" - LIBPREFIX="" - - CFLAGS_DEBUG="${CFLAGS_DEBUG} -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE" - CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE" - - EXTRA_CFLAGS="" - CFLAGS_WARNING="-W3" - LDFLAGS_DEBUG="-debug" - LDFLAGS_OPTIMIZE="-release" - - # Specify the CC output file names based on the target name - CC_OBJNAME="-Fo\$@" - CC_EXENAME="-Fe\"\$(shell \$(CYGPATH) '\$@')\"" - - # Specify linker flags depending on the type of app being - # built -- Console vs. Window. - if test "$doWince" != "no" -a "${TARGETCPU}" != "X86"; then - LDFLAGS_CONSOLE="-link ${lflags}" - LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} - else - LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" - LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" - fi - fi - - if test "$do64bit" != "no" ; then - cat >>confdefs.h <<\_ACEOF -#define TCL_CFG_DO64BIT 1 -_ACEOF - - fi - - if test "${GCC}" = "yes" ; then - echo "$as_me:$LINENO: checking for SEH support in compiler" >&5 -echo $ECHO_N "checking for SEH support in compiler... $ECHO_C" >&6 -if test "${tcl_cv_seh+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - tcl_cv_seh=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #undef WIN32_LEAN_AND_MEAN - - int main(int argc, char** argv) { - int a, b = 0; - __try { - a = 666 / b; - } - __except (EXCEPTION_EXECUTE_HANDLER) { - return 0; - } - return 1; - } - -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_seh=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -tcl_cv_seh=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - -fi -echo "$as_me:$LINENO: result: $tcl_cv_seh" >&5 -echo "${ECHO_T}$tcl_cv_seh" >&6 - if test "$tcl_cv_seh" = "no" ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_NO_SEH 1 -_ACEOF - - fi - - # - # Check to see if the excpt.h include file provided contains the - # definition for EXCEPTION_DISPOSITION; if not, which is the case - # with Cygwin's version as of 2002-04-10, define it to be int, - # sufficient for getting the current code to work. - # - echo "$as_me:$LINENO: checking for EXCEPTION_DISPOSITION support in include files" >&5 -echo $ECHO_N "checking for EXCEPTION_DISPOSITION support in include files... $ECHO_C" >&6 -if test "${tcl_cv_eh_disposition+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -# define WIN32_LEAN_AND_MEAN -# include <windows.h> -# undef WIN32_LEAN_AND_MEAN - -int -main () -{ - - EXCEPTION_DISPOSITION x; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_eh_disposition=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_eh_disposition=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_eh_disposition" >&5 -echo "${ECHO_T}$tcl_cv_eh_disposition" >&6 - if test "$tcl_cv_eh_disposition" = "no" ; then - -cat >>confdefs.h <<\_ACEOF -#define EXCEPTION_DISPOSITION int -_ACEOF - - fi - - # Check to see if winnt.h defines CHAR, SHORT, and LONG - # even if VOID has already been #defined. The win32api - # used by mingw and cygwin is known to do this. - - echo "$as_me:$LINENO: checking for winnt.h that ignores VOID define" >&5 -echo $ECHO_N "checking for winnt.h that ignores VOID define... $ECHO_C" >&6 -if test "${tcl_cv_winnt_ignore_void+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - #define VOID void - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #undef WIN32_LEAN_AND_MEAN - -int -main () -{ - - CHAR c; - SHORT s; - LONG l; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_winnt_ignore_void=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_winnt_ignore_void=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_winnt_ignore_void" >&5 -echo "${ECHO_T}$tcl_cv_winnt_ignore_void" >&6 - if test "$tcl_cv_winnt_ignore_void" = "yes" ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_WINNT_IGNORE_VOID 1 -_ACEOF - - fi - - # See if the compiler supports casting to a union type. - # This is used to stop gcc from printing a compiler - # warning when initializing a union member. - - echo "$as_me:$LINENO: checking for cast to union support" >&5 -echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6 -if test "${tcl_cv_cast_to_union+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - union foo { int i; double d; }; - union foo f = (union foo) (int) 0; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_cast_to_union=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cast_to_union=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5 -echo "${ECHO_T}$tcl_cv_cast_to_union" >&6 - if test "$tcl_cv_cast_to_union" = "yes"; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_CAST_TO_UNION 1 -_ACEOF - - fi - fi - - # DL_LIBS is empty, but then we match the Unix version - - - - - - -#-------------------------------------------------------------------- -# man2tcl needs this so that it can use errno.h -#-------------------------------------------------------------------- - -if test "${ac_cv_header_errno_h+set}" = set; then - echo "$as_me:$LINENO: checking for errno.h" >&5 -echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 -if test "${ac_cv_header_errno_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 -echo "${ECHO_T}$ac_cv_header_errno_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking errno.h usability" >&5 -echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <errno.h> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking errno.h presence" >&5 -echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <errno.h> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: errno.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: errno.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for errno.h" >&5 -echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 -if test "${ac_cv_header_errno_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_errno_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 -echo "${ECHO_T}$ac_cv_header_errno_h" >&6 - -fi -if test $ac_cv_header_errno_h = yes; then - : -else - MAN2TCLFLAGS="-DNO_ERRNO_H" -fi - - - - -#------------------------------------------- -# Check for _strtoi64 -#------------------------------------------- - -echo "$as_me:$LINENO: checking availability of _strtoi64" >&5 -echo $ECHO_N "checking availability of _strtoi64... $ECHO_C" >&6 -if test "${tcl_cv_strtoi64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <stdlib.h> -int -main () -{ -_strtoi64(0,0,0) - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_strtoi64=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_strtoi64=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_strtoi64" >&5 -echo "${ECHO_T}$tcl_cv_strtoi64" >&6 -if test $tcl_cv_strtoi64 = no; then - -cat >>confdefs.h <<\_ACEOF -#define NO_STRTOI64 1 -_ACEOF - -fi - -#-------------------------------------------------------------------- -# Windows XP theme engine header for Ttk -#-------------------------------------------------------------------- - -echo "$as_me:$LINENO: checking for uxtheme.h" >&5 -echo $ECHO_N "checking for uxtheme.h... $ECHO_C" >&6 -if test "${ac_cv_header_uxtheme_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <windows.h> - -#include <uxtheme.h> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_uxtheme_h=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_uxtheme_h=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_header_uxtheme_h" >&5 -echo "${ECHO_T}$ac_cv_header_uxtheme_h" >&6 -if test $ac_cv_header_uxtheme_h = yes; then - cat >>confdefs.h <<\_ACEOF -#define HAVE_UXTHEME_H 1 -_ACEOF - -else - { echo "$as_me:$LINENO: xpnative theme will be unavailable" >&5 -echo "$as_me: xpnative theme will be unavailable" >&6;} -fi - - -echo "$as_me:$LINENO: checking for vssym32.h" >&5 -echo $ECHO_N "checking for vssym32.h... $ECHO_C" >&6 -if test "${ac_cv_header_vssym32_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <windows.h> -#include <uxtheme.h> - -#include <vssym32.h> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_vssym32_h=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_vssym32_h=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_header_vssym32_h" >&5 -echo "${ECHO_T}$ac_cv_header_vssym32_h" >&6 -if test $ac_cv_header_vssym32_h = yes; then - cat >>confdefs.h <<\_ACEOF -#define HAVE_VSSYM32_H 1 -_ACEOF - -fi - - - -#-------------------------------------------------------------------- -# Set the default compiler switches based on the --enable-symbols -# option. This macro depends on C flags, and should be called -# after SC_CONFIG_CFLAGS macro is called. -#-------------------------------------------------------------------- - - - echo "$as_me:$LINENO: checking for build with symbols" >&5 -echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6 - # Check whether --enable-symbols or --disable-symbols was given. -if test "${enable_symbols+set}" = set; then - enableval="$enable_symbols" - tcl_ok=$enableval -else - tcl_ok=no -fi; -# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT. - if test "$tcl_ok" = "no"; then - CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)' - LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)' - DBGX="" - -cat >>confdefs.h <<\_ACEOF -#define NDEBUG 1 -_ACEOF - - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - - cat >>confdefs.h <<\_ACEOF -#define TCL_CFG_OPTIMIZED 1 -_ACEOF - - else - CFLAGS_DEFAULT='$(CFLAGS_DEBUG)' - LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)' - DBGX=g - if test "$tcl_ok" = "yes"; then - echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 -echo "${ECHO_T}yes (standard debugging)" >&6 - fi - fi - - - - if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then - -cat >>confdefs.h <<\_ACEOF -#define TCL_MEM_DEBUG 1 -_ACEOF - - fi - - if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then - -cat >>confdefs.h <<\_ACEOF -#define TCL_COMPILE_DEBUG 1 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define TCL_COMPILE_STATS 1 -_ACEOF - - fi - - if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then - if test "$tcl_ok" = "all"; then - echo "$as_me:$LINENO: result: enabled symbols mem compile debugging" >&5 -echo "${ECHO_T}enabled symbols mem compile debugging" >&6 - else - echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 -echo "${ECHO_T}enabled $tcl_ok debugging" >&6 - fi - fi - - -TK_DBGX=${DBGX} - -#-------------------------------------------------------------------- -# Embed the manifest if we can determine how -#-------------------------------------------------------------------- - - - echo "$as_me:$LINENO: checking whether to embed manifest" >&5 -echo $ECHO_N "checking whether to embed manifest... $ECHO_C" >&6 - # Check whether --enable-embedded-manifest or --disable-embedded-manifest was given. -if test "${enable_embedded_manifest+set}" = set; then - enableval="$enable_embedded_manifest" - embed_ok=$enableval -else - embed_ok=yes -fi; - - VC_MANIFEST_EMBED_DLL= - VC_MANIFEST_EMBED_EXE= - result=no - if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \ - -a "$GCC" != "yes" ; then - # Add the magic to embed the manifest into the dll/exe - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#if defined(_MSC_VER) && _MSC_VER >= 1400 -print("manifest needed") -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "manifest needed" >/dev/null 2>&1; then - - # Could do a CHECK_PROG for mt, but should always be with MSVC8+ - # Could add 'if test -f' check, but manifest should be created - # in this compiler case - # Add in a manifest argument that may be specified - # XXX Needs improvement so that the test for existence accounts - # XXX for a provided (known) manifest - VC_MANIFEST_EMBED_DLL="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest wish.exe.manifest -outputresource:\$@\;2 ; fi" - VC_MANIFEST_EMBED_EXE="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest wish.exe.manifest -outputresource:\$@\;1 ; fi" - result=yes - if test "xwish.exe.manifest" != x ; then - result="yes (wish.exe.manifest)" - fi - -fi -rm -f conftest* - - fi - echo "$as_me:$LINENO: result: $result" >&5 -echo "${ECHO_T}$result" >&6 - - - - - - echo "$as_me:$LINENO: checking for tclsh in Tcl build directory" >&5 -echo $ECHO_N "checking for tclsh in Tcl build directory... $ECHO_C" >&6 - BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT} - echo "$as_me:$LINENO: result: $BUILD_TCLSH" >&5 -echo "${ECHO_T}$BUILD_TCLSH" >&6 - - - - echo "$as_me:$LINENO: checking for tclsh" >&5 -echo $ECHO_N "checking for tclsh... $ECHO_C" >&6 - - if test "${ac_cv_path_tclsh+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/tclsh[8-9]*.exe 2> /dev/null` \ - `ls -r $dir/tclsh* 2> /dev/null` ; do - if test x"$ac_cv_path_tclsh" = x ; then - if test -f "$j" ; then - ac_cv_path_tclsh=$j - break - fi - fi - done - done - -fi - - - if test -f "$ac_cv_path_tclsh" ; then - TCLSH_PROG="$ac_cv_path_tclsh" - echo "$as_me:$LINENO: result: $TCLSH_PROG" >&5 -echo "${ECHO_T}$TCLSH_PROG" >&6 - else - # It is not an error if an installed version of Tcl can't be located. - TCLSH_PROG="" - echo "$as_me:$LINENO: result: No tclsh found on PATH" >&5 -echo "${ECHO_T}No tclsh found on PATH" >&6 - fi - - - -#------------------------------------------------------------------------ -# tkConfig.sh refers to this by a different name -#------------------------------------------------------------------------ - -TK_SHARED_BUILD=${SHARED_BUILD} - -#-------------------------------------------------------------------- -# Perform final evaluations of variables with possible substitutions. -#-------------------------------------------------------------------- - -TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}" -TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}" -TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}" - -eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\"" - -eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}" -eval "TK_LIB_FILE=${LIBPREFIX}tk$VER${LIBSUFFIX}" - -eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${VER}${LIBSUFFIX}" -# FIXME: All of this var junk needs to be done in tcl.m4 !!!! -# I left out the other vars that also need to get defined here. -# we also need to double check about spaces in path names -eval "TK_LIB_FLAG=\"-ltk${VER}${LIBFLAGSUFFIX}\"" -TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}" -TK_BUILD_LIB_SPEC="-L`pwd` ${TK_LIB_FLAG}" - -eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\"" -TK_BUILD_STUB_LIB_SPEC="-L`pwd` ${TK_STUB_LIB_FLAG}" - -TK_STUB_LIB_SPEC="-L${libdir} ${TK_STUB_LIB_FLAG}" -TK_STUB_LIB_PATH="${libdir}/${TK_STUB_LIB_FILE}" -TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}" - -eval "DLLSUFFIX=${DLLSUFFIX}" -eval "LIBPREFIX=${LIBPREFIX}" -eval "LIBSUFFIX=${LIBSUFFIX}" -eval "EXESUFFIX=${EXESUFFIX}" - -CFG_TK_SHARED_LIB_SUFFIX=${TK_SHARED_LIB_SUFFIX} -CFG_TK_UNSHARED_LIB_SUFFIX=${TK_UNSHARED_LIB_SUFFIX} -CFG_TK_EXPORT_FILE_SUFFIX=${TK_EXPORT_FILE_SUFFIX} - -#-------------------------------------------------------------------- -# Adjust the defines for how the resources are built depending -# on symbols and static vs. shared. -#-------------------------------------------------------------------- - -if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then - if test "${DBGX}" = "d"; then - RC_DEFINES="${RC_DEFINE} STATIC_BUILD ${RC_DEFINE} DEBUG" - else - RC_DEFINES="${RC_DEFINE} STATIC_BUILD" - fi - TK_RES="" -else - if test "${DBGX}" = "d"; then - RC_DEFINES="${RC_DEFINE} DEBUG" - else - RC_DEFINES="" - fi - TK_RES='tk.$(RES)' -fi - -# The wish.exe.manifest requires these -# TK_WIN_VERSION is the 4 dotted pair Windows version format which needs -# the release level, and must account for interim release versioning -case "$TK_PATCH_LEVEL" in - *a*) TK_RELEASE_LEVEL=0 ;; - *b*) TK_RELEASE_LEVEL=1 ;; - *) TK_RELEASE_LEVEL=2 ;; -esac -TK_WIN_VERSION="$TK_VERSION.$TK_RELEASE_LEVEL.`echo $TK_PATCH_LEVEL | tr -d ab.`" - -# X86|AMD64|IA64 for manifest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# win/tcl.m4 doesn't set (LDFLAGS) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# undefined at this point for win - - - - - - - - - - - - ac_config_files="$ac_config_files Makefile tkConfig.sh wish.exe.manifest" -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -{ - (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} | - sed ' - t clear - : clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" - cat confcache >$cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then we branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -cat >confdef2opt.sed <<\_ACEOF -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g -t quote -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g -t quote -d -: quote -s,[ `~#$^&*(){}\\|;'"<>?],\\&,g -s,\[,\\&,g -s,\],\\&,g -s,\$,$$,g -p -_ACEOF -# We use echo to avoid assuming a particular line-breaking character. -# The extra dot is to prevent the shell from consuming trailing -# line-breaks from the sub-command output. A line-break within -# single-quotes doesn't work because, if this script is created in a -# platform that uses two characters for line-breaks (e.g., DOS), tr -# would break. -ac_LF_and_DOT=`echo; echo .` -DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` -rm -f confdef2opt.sed - - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_i=`echo "$ac_i" | - sed 's/\$U\././;s/\.o$//;s/\.obj$//'` - # 2. Add them. - ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi -DUALCASE=1; export DUALCASE # for MKS sh - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - -exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - -This file was extended by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 -_ACEOF - -# Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi - -cat >>$CONFIG_STATUS <<\_ACEOF - -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Report bugs to <bug-autoconf@gnu.org>." -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.59, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2003 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` - ac_shift=: - ;; - -*) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; - esac - - case $ac_option in - # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -if \$ac_cs_recheck; then - echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -fi - -_ACEOF - - - - - -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_config_target in $ac_config_targets -do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "tkConfig.sh" ) CONFIG_FILES="$CONFIG_FILES tkConfig.sh" ;; - "wish.exe.manifest" ) CONFIG_FILES="$CONFIG_FILES wish.exe.manifest" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF - -# -# CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@CPP@,$CPP,;t t -s,@EGREP@,$EGREP,;t t -s,@AR@,$AR,;t t -s,@ac_ct_AR@,$ac_ct_AR,;t t -s,@RANLIB@,$RANLIB,;t t -s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t -s,@RC@,$RC,;t t -s,@ac_ct_RC@,$ac_ct_RC,;t t -s,@SET_MAKE@,$SET_MAKE,;t t -s,@TCL_THREADS@,$TCL_THREADS,;t t -s,@TCL_VERSION@,$TCL_VERSION,;t t -s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t -s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t -s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t -s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t -s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t -s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t -s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t -s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t -s,@TCL_DEFS@,$TCL_DEFS,;t t -s,@CYGPATH@,$CYGPATH,;t t -s,@CELIB_DIR@,$CELIB_DIR,;t t -s,@DL_LIBS@,$DL_LIBS,;t t -s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t -s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t -s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t -s,@MAN2TCLFLAGS@,$MAN2TCLFLAGS,;t t -s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t -s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t -s,@VC_MANIFEST_EMBED_DLL@,$VC_MANIFEST_EMBED_DLL,;t t -s,@VC_MANIFEST_EMBED_EXE@,$VC_MANIFEST_EMBED_EXE,;t t -s,@BUILD_TCLSH@,$BUILD_TCLSH,;t t -s,@TCLSH_PROG@,$TCLSH_PROG,;t t -s,@TK_WIN_VERSION@,$TK_WIN_VERSION,;t t -s,@MACHINE@,$MACHINE,;t t -s,@TK_VERSION@,$TK_VERSION,;t t -s,@TK_MAJOR_VERSION@,$TK_MAJOR_VERSION,;t t -s,@TK_MINOR_VERSION@,$TK_MINOR_VERSION,;t t -s,@TK_PATCH_LEVEL@,$TK_PATCH_LEVEL,;t t -s,@TK_DBGX@,$TK_DBGX,;t t -s,@TK_LIB_FILE@,$TK_LIB_FILE,;t t -s,@TK_DLL_FILE@,$TK_DLL_FILE,;t t -s,@TK_STUB_LIB_FILE@,$TK_STUB_LIB_FILE,;t t -s,@TK_STUB_LIB_FLAG@,$TK_STUB_LIB_FLAG,;t t -s,@TK_BUILD_STUB_LIB_SPEC@,$TK_BUILD_STUB_LIB_SPEC,;t t -s,@TK_SRC_DIR@,$TK_SRC_DIR,;t t -s,@TK_BIN_DIR@,$TK_BIN_DIR,;t t -s,@TCL_MAJOR_VERSION@,$TCL_MAJOR_VERSION,;t t -s,@TCL_MINOR_VERSION@,$TCL_MINOR_VERSION,;t t -s,@TCL_PATCH_LEVEL@,$TCL_PATCH_LEVEL,;t t -s,@TCL_DBGX@,$TCL_DBGX,;t t -s,@CFG_TK_SHARED_LIB_SUFFIX@,$CFG_TK_SHARED_LIB_SUFFIX,;t t -s,@CFG_TK_UNSHARED_LIB_SUFFIX@,$CFG_TK_UNSHARED_LIB_SUFFIX,;t t -s,@CFG_TK_EXPORT_FILE_SUFFIX@,$CFG_TK_EXPORT_FILE_SUFFIX,;t t -s,@EXTRA_CFLAGS@,$EXTRA_CFLAGS,;t t -s,@DEPARG@,$DEPARG,;t t -s,@CC_OBJNAME@,$CC_OBJNAME,;t t -s,@CC_EXENAME@,$CC_EXENAME,;t t -s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t -s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t -s,@LDFLAGS_CONSOLE@,$LDFLAGS_CONSOLE,;t t -s,@LDFLAGS_WINDOW@,$LDFLAGS_WINDOW,;t t -s,@TK_RES@,$TK_RES,;t t -s,@STLIB_LD@,$STLIB_LD,;t t -s,@SHLIB_LD@,$SHLIB_LD,;t t -s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t -s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t -s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t -s,@TK_SHARED_BUILD@,$TK_SHARED_BUILD,;t t -s,@LIBS_GUI@,$LIBS_GUI,;t t -s,@DLLSUFFIX@,$DLLSUFFIX,;t t -s,@LIBPREFIX@,$LIBPREFIX,;t t -s,@LIBSUFFIX@,$LIBSUFFIX,;t t -s,@EXESUFFIX@,$EXESUFFIX,;t t -s,@LIBRARIES@,$LIBRARIES,;t t -s,@MAKE_LIB@,$MAKE_LIB,;t t -s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t -s,@POST_MAKE_LIB@,$POST_MAKE_LIB,;t t -s,@MAKE_DLL@,$MAKE_DLL,;t t -s,@MAKE_EXE@,$MAKE_EXE,;t t -s,@TK_LIB_FLAG@,$TK_LIB_FLAG,;t t -s,@TK_LIB_SPEC@,$TK_LIB_SPEC,;t t -s,@TK_BUILD_LIB_SPEC@,$TK_BUILD_LIB_SPEC,;t t -s,@TK_STUB_LIB_SPEC@,$TK_STUB_LIB_SPEC,;t t -s,@TK_STUB_LIB_PATH@,$TK_STUB_LIB_PATH,;t t -s,@TK_BUILD_STUB_LIB_PATH@,$TK_BUILD_STUB_LIB_PATH,;t t -s,@TK_CC_SEARCH_FLAGS@,$TK_CC_SEARCH_FLAGS,;t t -s,@TK_LD_SEARCH_FLAGS@,$TK_LD_SEARCH_FLAGS,;t t -s,@RC_OUT@,$RC_OUT,;t t -s,@RC_TYPE@,$RC_TYPE,;t t -s,@RC_INCLUDE@,$RC_INCLUDE,;t t -s,@RC_DEFINE@,$RC_DEFINE,;t t -s,@RC_DEFINES@,$RC_DEFINES,;t t -s,@RES@,$RES,;t t -s,@LIBOBJS@,$LIBOBJS,;t t -s,@LTLIBOBJS@,$LTLIBOBJS,;t t -CEOF - -_ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - - diff --git a/tk8.6/win/configure.in b/tk8.6/win/configure.in deleted file mode 100644 index 5ec7c35..0000000 --- a/tk8.6/win/configure.in +++ /dev/null @@ -1,314 +0,0 @@ -#! /bin/bash -norc -# This file is an input file used by the GNU "autoconf" program to -# generate the file "configure", which is run during Tk installation -# to configure the system for the local environment. - -AC_INIT(../generic/tk.h) -AC_PREREQ(2.59) - -# The following define is needed when building with Cygwin since newer -# versions of autoconf incorrectly set SHELL to /bin/bash instead of -# /bin/sh. The bash shell seems to suffer from some strange failures. -SHELL=/bin/sh - -TK_VERSION=8.6 -TK_MAJOR_VERSION=8 -TK_MINOR_VERSION=6 -TK_PATCH_LEVEL=".8" -VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION - -#------------------------------------------------------------------------ -# Handle the --prefix=... option -#------------------------------------------------------------------------ - -if test "${prefix}" = "NONE"; then - prefix=/usr/local -fi -if test "${exec_prefix}" = "NONE"; then - exec_prefix=$prefix -fi -# libdir must be a fully qualified path (not ${exec_prefix}/lib) -eval libdir="$libdir" - -#------------------------------------------------------------------------ -# Standard compiler checks -#------------------------------------------------------------------------ - -# If the user did not set CFLAGS, set it now to keep -# the AC_PROG_CC macro from adding "-g -O2". -if test "${CFLAGS+set}" != "set" ; then - CFLAGS="" -fi - -AC_PROG_CC -AC_C_INLINE -AC_HEADER_STDC - -AC_CHECK_TOOL(AR, ar) -AC_CHECK_TOOL(RANLIB, ranlib) -AC_CHECK_TOOL(RC, windres) - -#-------------------------------------------------------------------- -# Checks to see if the make program sets the $MAKE variable. -#-------------------------------------------------------------------- - -AC_PROG_MAKE_SET - -#-------------------------------------------------------------------- -# Determines the correct binary file extension (.o, .obj, .exe etc.) -#-------------------------------------------------------------------- - -AC_OBJEXT -AC_EXEEXT - -#-------------------------------------------------------------------- -# Check whether --enable-threads or --disable-threads was given. -#-------------------------------------------------------------------- - -SC_ENABLE_THREADS - -#-------------------------------------------------------------------- -# The statements below define a collection of symbols related to -# building libtk as a shared library instead of a static library. -#-------------------------------------------------------------------- - -SC_ENABLE_SHARED - -#-------------------------------------------------------------------- -# Locate and source the tclConfig.sh file. -#-------------------------------------------------------------------- - -SC_PATH_TCLCONFIG($TK_PATCH_LEVEL) -SC_LOAD_TCLCONFIG - -if test "${TCL_MAJOR_VERSION}" != "${TK_MAJOR_VERSION}"; then - AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}. -Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}. -Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}.]) -fi -if test "${TCL_MINOR_VERSION}" -lt "${TK_MINOR_VERSION}"; then - AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}. -Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}. -Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}.]) -fi - -#-------------------------------------------------------------------- -# The statements below define a collection of compile flags. This -# macro depends on the value of SHARED_BUILD, and should be called -# after SC_ENABLE_SHARED checks the configure switches. -#-------------------------------------------------------------------- - -SC_CONFIG_CFLAGS - -#-------------------------------------------------------------------- -# man2tcl needs this so that it can use errno.h -#-------------------------------------------------------------------- - -AC_CHECK_HEADER(errno.h, , MAN2TCLFLAGS="-DNO_ERRNO_H") -AC_SUBST(MAN2TCLFLAGS) - -#------------------------------------------- -# Check for _strtoi64 -#------------------------------------------- - -AC_CACHE_CHECK([availability of _strtoi64], tcl_cv_strtoi64, [ - AC_TRY_LINK([#include <stdlib.h>], - [_strtoi64(0,0,0)], - tcl_cv_strtoi64=yes, tcl_cv_strtoi64=no)]) -if test $tcl_cv_strtoi64 = no; then - AC_DEFINE(NO_STRTOI64, 1, [Is _strtoi64 function available?]) -fi - -#-------------------------------------------------------------------- -# Windows XP theme engine header for Ttk -#-------------------------------------------------------------------- - -AC_CHECK_HEADER([uxtheme.h], [AC_DEFINE(HAVE_UXTHEME_H)], - [AC_MSG_NOTICE([xpnative theme will be unavailable])], - [#include <windows.h>]) -AC_CHECK_HEADER([vssym32.h], [AC_DEFINE(HAVE_VSSYM32_H)], [], - [#include <windows.h> -#include <uxtheme.h>]) - -#-------------------------------------------------------------------- -# Set the default compiler switches based on the --enable-symbols -# option. This macro depends on C flags, and should be called -# after SC_CONFIG_CFLAGS macro is called. -#-------------------------------------------------------------------- - -SC_ENABLE_SYMBOLS - -TK_DBGX=${DBGX} - -#-------------------------------------------------------------------- -# Embed the manifest if we can determine how -#-------------------------------------------------------------------- - -SC_EMBED_MANIFEST(wish.exe.manifest) - -SC_BUILD_TCLSH -SC_PROG_TCLSH - -#------------------------------------------------------------------------ -# tkConfig.sh refers to this by a different name -#------------------------------------------------------------------------ - -TK_SHARED_BUILD=${SHARED_BUILD} - -#-------------------------------------------------------------------- -# Perform final evaluations of variables with possible substitutions. -#-------------------------------------------------------------------- - -TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}" -TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}" -TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}" - -eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\"" - -eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}" -eval "TK_LIB_FILE=${LIBPREFIX}tk$VER${LIBSUFFIX}" - -eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${VER}${LIBSUFFIX}" -# FIXME: All of this var junk needs to be done in tcl.m4 !!!! -# I left out the other vars that also need to get defined here. -# we also need to double check about spaces in path names -eval "TK_LIB_FLAG=\"-ltk${VER}${LIBFLAGSUFFIX}\"" -TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}" -TK_BUILD_LIB_SPEC="-L`pwd` ${TK_LIB_FLAG}" - -eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\"" -TK_BUILD_STUB_LIB_SPEC="-L`pwd` ${TK_STUB_LIB_FLAG}" - -TK_STUB_LIB_SPEC="-L${libdir} ${TK_STUB_LIB_FLAG}" -TK_STUB_LIB_PATH="${libdir}/${TK_STUB_LIB_FILE}" -TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}" - -eval "DLLSUFFIX=${DLLSUFFIX}" -eval "LIBPREFIX=${LIBPREFIX}" -eval "LIBSUFFIX=${LIBSUFFIX}" -eval "EXESUFFIX=${EXESUFFIX}" - -CFG_TK_SHARED_LIB_SUFFIX=${TK_SHARED_LIB_SUFFIX} -CFG_TK_UNSHARED_LIB_SUFFIX=${TK_UNSHARED_LIB_SUFFIX} -CFG_TK_EXPORT_FILE_SUFFIX=${TK_EXPORT_FILE_SUFFIX} - -#-------------------------------------------------------------------- -# Adjust the defines for how the resources are built depending -# on symbols and static vs. shared. -#-------------------------------------------------------------------- - -if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then - if test "${DBGX}" = "d"; then - RC_DEFINES="${RC_DEFINE} STATIC_BUILD ${RC_DEFINE} DEBUG" - else - RC_DEFINES="${RC_DEFINE} STATIC_BUILD" - fi - TK_RES="" -else - if test "${DBGX}" = "d"; then - RC_DEFINES="${RC_DEFINE} DEBUG" - else - RC_DEFINES="" - fi - TK_RES='tk.$(RES)' -fi - -# The wish.exe.manifest requires these -# TK_WIN_VERSION is the 4 dotted pair Windows version format which needs -# the release level, and must account for interim release versioning -case "$TK_PATCH_LEVEL" in - *a*) TK_RELEASE_LEVEL=0 ;; - *b*) TK_RELEASE_LEVEL=1 ;; - *) TK_RELEASE_LEVEL=2 ;; -esac -TK_WIN_VERSION="$TK_VERSION.$TK_RELEASE_LEVEL.`echo $TK_PATCH_LEVEL | tr -d ab.`" -AC_SUBST(TK_WIN_VERSION) -# X86|AMD64|IA64 for manifest -AC_SUBST(MACHINE) - -AC_SUBST(TK_VERSION) -AC_SUBST(TK_MAJOR_VERSION) -AC_SUBST(TK_MINOR_VERSION) -AC_SUBST(TK_PATCH_LEVEL) -AC_SUBST(TK_DBGX) -AC_SUBST(TK_LIB_FILE) -AC_SUBST(TK_DLL_FILE) -AC_SUBST(TK_STUB_LIB_FILE) -AC_SUBST(TK_STUB_LIB_FLAG) -AC_SUBST(TK_BUILD_STUB_LIB_SPEC) -AC_SUBST(TK_SRC_DIR) -AC_SUBST(TK_BIN_DIR) - -AC_SUBST(TCL_VERSION) -AC_SUBST(TCL_MAJOR_VERSION) -AC_SUBST(TCL_MINOR_VERSION) -AC_SUBST(TCL_PATCH_LEVEL) - -AC_SUBST(TCL_SRC_DIR) -AC_SUBST(TCL_BIN_DIR) -AC_SUBST(TCL_DBGX) -AC_SUBST(CFG_TK_SHARED_LIB_SUFFIX) -AC_SUBST(CFG_TK_UNSHARED_LIB_SUFFIX) -AC_SUBST(CFG_TK_EXPORT_FILE_SUFFIX) - -AC_SUBST(CFLAGS_DEFAULT) -AC_SUBST(EXTRA_CFLAGS) -AC_SUBST(CYGPATH) -AC_SUBST(DEPARG) -AC_SUBST(CC_OBJNAME) -AC_SUBST(CC_EXENAME) - -# win/tcl.m4 doesn't set (LDFLAGS) -AC_SUBST(LDFLAGS_DEFAULT) -AC_SUBST(LDFLAGS_DEBUG) -AC_SUBST(LDFLAGS_OPTIMIZE) -AC_SUBST(LDFLAGS_CONSOLE) -AC_SUBST(LDFLAGS_WINDOW) -AC_SUBST(AR) -AC_SUBST(RANLIB) -AC_SUBST(TK_RES) - -AC_SUBST(STLIB_LD) -AC_SUBST(SHLIB_LD) -AC_SUBST(SHLIB_LD_LIBS) -AC_SUBST(SHLIB_CFLAGS) -AC_SUBST(SHLIB_SUFFIX) -AC_SUBST(TK_SHARED_BUILD) - -AC_SUBST(LIBS) -AC_SUBST(LIBS_GUI) -AC_SUBST(DLLSUFFIX) -AC_SUBST(LIBPREFIX) -AC_SUBST(LIBSUFFIX) -AC_SUBST(EXESUFFIX) -AC_SUBST(LIBRARIES) -AC_SUBST(MAKE_LIB) -AC_SUBST(MAKE_STUB_LIB) -AC_SUBST(POST_MAKE_LIB) -AC_SUBST(MAKE_DLL) -AC_SUBST(MAKE_EXE) - -AC_SUBST(TK_LIB_FLAG) -AC_SUBST(TK_LIB_SPEC) -AC_SUBST(TK_BUILD_LIB_SPEC) -AC_SUBST(TK_STUB_LIB_SPEC) -AC_SUBST(TK_STUB_LIB_PATH) -AC_SUBST(TK_BUILD_STUB_LIB_PATH) - -# undefined at this point for win -AC_SUBST(TK_CC_SEARCH_FLAGS) -AC_SUBST(TK_LD_SEARCH_FLAGS) - -AC_SUBST(RC) -AC_SUBST(RC_OUT) -AC_SUBST(RC_TYPE) -AC_SUBST(RC_INCLUDE) -AC_SUBST(RC_DEFINE) -AC_SUBST(RC_DEFINES) -AC_SUBST(RES) - -AC_OUTPUT(Makefile tkConfig.sh wish.exe.manifest) - -dnl Local Variables: -dnl mode: autoconf; -dnl End: diff --git a/tk8.6/win/license.terms b/tk8.6/win/license.terms deleted file mode 100644 index 0126435..0000000 --- a/tk8.6/win/license.terms +++ /dev/null @@ -1,40 +0,0 @@ -This software is copyrighted by the Regents of the University of -California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState -Corporation, Apple Inc. and other parties. The following terms apply to -all files associated with the software unless explicitly disclaimed in -individual files. - -The authors hereby grant permission to use, copy, modify, distribute, -and license this software and its documentation for any purpose, provided -that existing copyright notices are retained in all copies and that this -notice is included verbatim in any distributions. No written agreement, -license, or royalty fee is required for any of the authorized uses. -Modifications to this software may be copyrighted by their authors -and need not follow the licensing terms described here, provided that -the new terms are clearly indicated on the first page of each file where -they apply. - -IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY -FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY -DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE -IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE -NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -MODIFICATIONS. - -GOVERNMENT USE: If you are acquiring this software on behalf of the -U.S. government, the Government shall have only "Restricted Rights" -in the software and related documentation as defined in the Federal -Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you -are acquiring the software on behalf of the Department of Defense, the -software shall be classified as "Commercial Computer Software" and the -Government shall have only "Restricted Rights" as defined in Clause -252.227-7013 (b) (3) of DFARs. Notwithstanding the foregoing, the -authors grant the U.S. Government and others acting in its behalf -permission to use and distribute the software in accordance with the -terms specified in this license. diff --git a/tk8.6/win/makefile.vc b/tk8.6/win/makefile.vc deleted file mode 100644 index 04c9757..0000000 --- a/tk8.6/win/makefile.vc +++ /dev/null @@ -1,698 +0,0 @@ -#------------------------------------------------------------- -*- 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.
-# Copyright (c) 2017 Ashok P. Nadkarni
-#------------------------------------------------------------------------------
-
-# General usage:
-# nmake [-nologo] -f makefile.vc [TARGET|MACRODEF [TARGET|MACRODEF] [...]]
-#
-# For MACRODEF, see TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md)
-# or examine Sections 6-8 in rules.vc. This makefile has the following
-# values for the OPTS macro in addition to the ones described there.
-# noxp = If you do not have the uxtheme.h header then you
-# cannot include support for XP themeing.
-# square = Include the demo square widget.
-#
-# Possible values for TARGET 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.
-#
-# The steps to setup a Visual C++ environment depend on which
-# version of Visual Studio and/or the Windows SDK you are building
-# against and are not described here. The simplest method is generally
-# to start a command shell using one of the short cuts installed by
-# Visual Studio/Windows SDK for the appropriate target architecture.
-#
-# NOTE: For older (Visual C++ 6 or the 2003 SDK), 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.
-#
-# Examples:
-# Assumign Tcl sources lie in ../../tcl
-# c:\tcl_src\win\>nmake -f makefile.vc release
-# If Tcl sources are not in ../../tcl, use the TCLDIR macro to specify dir
-# c:\tcl_src\win\>nmake -f makefile.vc release TCLDIR=c:\src\tcl
-# Run the test suite
-# c:\tcl_src\win\>nmake -f makefile.vc test
-# Install Tk in location specified by INSTALLDIR macro
-# c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
-# Build release with PDF files
-# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=pdbs
-# Build debug version
-# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=symbols
-#
-###############################################################################
-
-# The PROJECT macro is used by rules.vc for generating appropriate
-# macros and rules.
-PROJECT = tk
-
-# Default target to build if no target is specified. If unspecified, the
-# rules.vc file will set up "all" as the target.
-DEFAULT_BUILD_TARGET = release
-
-# We have a custom resource file
-RCFILE = tk.rc
-
-# The rules.vc file does much of the hard work in terms of defining
-# the build configuration, macros, output directories etc.
-!include "rules-ext.vc"
-
-# TCLINSTALL is set to 1 by rules.vc to indicate we are building against
-# an installed Tcl and 0 if building against Tcl source. Tk needs the latter.
-!message TCLINSTALL=$(TCLINSTALL)
-!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 for non-standard OPTS values ...
-!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
-
-WISHC = "$(OUT_DIR)\$(WISHNAMEPREFIX)c$(VERSION)$(SUFX).exe"
-
-TKTEST = "$(OUT_DIR)\$(PROJECT)test.exe"
-CAT32 = "$(OUT_DIR)\cat32.exe"
-
-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
-
-### The following paths CANNOT have spaces in them as they appear on
-### the left side of implicit rules.
-XLIBDIR = $(ROOT)\xlib
-TTKDIR = $(ROOT)\generic\ttk
-BITMAPDIR = $(ROOT)\bitmaps
-
-# Additional include and C macro definitions for the implicit rules
-# defined in rules.vc
-PRJ_INCLUDES = -I"$(BITMAPDIR)" -I"$(XLIBDIR)"
-
-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
-
-PRJ_DEFINES = -DBUILD_ttk $(CONFIG_DEFS) -Dinline=__inline -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
-
-# Additional Link libraries needed beyond those in rules.vc
-PRJ_LIBS = netapi32.lib gdi32.lib user32.lib userenv.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)
-
-setup: default-setup
-
-test: test-classic test-ttk
-
-test-classic: setup $(TKTEST) $(TKLIB) $(CAT32)
- @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
- @set TK_LIBRARY=$(LIBDIR:\=/)
- @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=$(LIBDIR:\=/)
- @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=$(LIBDIR:\=/)
- @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=$(LIBDIR:\=/)
- @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=$(LIBDIR:\=/)
- @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=$(LIBDIR:\=/)
- @set TCLLIBPATH=
-!if $(TCLINSTALL)
- @set PATH=$(_TCLDIR)\bin;$(PATH)
-!else
- @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
-!endif
- windbg $(WISH)
-
-!if $(STATIC_BUILD)
-
-$(TKLIB): $(TKOBJS)
- $(LIBCMD) @<<
-$**
-<<
-
-!else
-
-$(TKLIB): $(TKOBJS)
- $(DLLCMD) @<<
-$**
-<<
- $(_VC_MANIFEST_EMBED_DLL)
- @if exist $*.exp del $*.exp
-
-$(TKIMPLIB): $(TKLIB)
-
-!endif # $(STATIC_BUILD)
-
-$(TKSTUBLIB): $(TKSTUBOBJS)
- $(LIBCMD) -nodefaultlib $**
-
-
-$(WISH): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB)
- $(GUIEXECMD) -stack:2300000 $**
- $(_VC_MANIFEST_EMBED_EXE)
-
-
-$(WISHC): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB)
- $(CONEXECMD) -stack:2300000 $**
- $(_VC_MANIFEST_EMBED_EXE)
-
-
-$(TKTEST): $(TKTESTOBJS) $(TKSTUBLIB) $(TKIMPLIB)
- $(GUIEXECMD) -stack:2300000 $**
- $(_VC_MANIFEST_EMBED_EXE)
-
-
-$(CAT32): $(_TCLDIR)\win\cat.c
- $(cc32) $(cflags) $(crt) -D_CRT_NONSTDC_NO_DEPRECATE -DCONSOLE -Fo$(TMP_DIR)\ $?
- $(CONEXECMD) -DCONSOLE -stack:16384 $(TMP_DIR)\cat.obj
- $(_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.
-#---------------------------------------------------------------------
-
-!if defined(PROCESSOR_ARCHITECTURE) && "$(PROCESSOR_ARCHITECTURE)" == "AMD64"
-HHC="%ProgramFiles(x86)%\HTML Help Workshop\hhc.exe"
-!else
-HHC="%ProgramFiles%\HTML Help Workshop\hhc.exe"
-!endif
-HTMLDIR=$(ROOT)\html
-HTMLBASE=TclTk$(TCL_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 $(TCL_DOTVERSION) Help
-[FILES]
-contents.htm
-docs.css
-Keywords
-TclCmd
-TclLib
-TkCmd
-TkLib
-UserCmd
-<<
-
-chmsetup:
- @if not exist $(HTMLDIR)\nul mkdir $(HTMLDIR)
-
-install-docs:
-!if exist("$(CHMFILE)")
- @echo Installing compiled HTML help
- @$(CPY) "$(CHMFILE)" "$(DOC_INSTALL_DIR)\"
-!endif
-# "emacs font-lock highlighting fix
-
-#---------------------------------------------------------------------
-# Special case object file targets
-#---------------------------------------------------------------------
-
-$(TMP_DIR)\testMain.obj: $(WINDIR)\winMain.c
- $(cc32) $(appcflags_nostubs) -DTK_TEST \
- -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
- -Fo$@ $?
-
-$(TMP_DIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
- $(cc32) $(appcflags_nostubs) -Fo$@ $?
-
-$(TMP_DIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
- $(cc32) $(appcflags_nostubs) -Fo$@ $?
-
-$(TMP_DIR)\tkWinTest.obj: $(WINDIR)\tkWinTest.c
- $(cc32) $(appcflags_nostubs) -Fo$@ $?
-
-$(TMP_DIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
- $(cc32) $(appcflags_nostubs) -Fo$@ $?
-
-$(TMP_DIR)\winMain.obj: $(WINDIR)\winMain.c
- $(cc32) $(appcflags_nostubs) \
- -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
- -Fo$@ $?
-
-$(TMP_DIR)\tkMain2.obj: $(GENERICDIR)\tkMain.c
- $(cc32) $(pkgcflags) -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) $(stubscflags) -Fo$@ $?
-
-
-$(TMP_DIR)\wish.exe.manifest: $(WINDIR)\wish.exe.manifest.in
- @nmakehlp -s << $** >$@
-@MACHINE@ $(MACHINE:IX86=X86)
-@TK_WIN_VERSION@ $(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::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(TTKDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(ROOT)\unix}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-$(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 8.6.0}]} { 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$(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) "$(LIBDIR)\*" "$(SCRIPT_INSTALL_DIR)\"
- @echo installing theme library
- @$(CPY) "$(LIBDIR)\ttk\*" "$(SCRIPT_INSTALL_DIR)\ttk\"
- @echo installing images
- @$(CPY) "$(LIBDIR)\images\*" "$(SCRIPT_INSTALL_DIR)\images\"
- @echo installing language files
- @$(CPY) "$(LIBDIR)\msgs\*" "$(SCRIPT_INSTALL_DIR)\msgs\"
- @echo installing demos
- @$(CPY) "$(DEMODIR)\*" "$(DEMO_INSTALL_DIR)\"
- @$(CPY) "$(DEMODIR)\images\*" "$(DEMO_INSTALL_DIR)\images\"
-
-#"
-
-#---------------------------------------------------------------------
-# Clean up
-#---------------------------------------------------------------------
-
-clean: default-clean
-realclean: hose
-hose: default-hose
-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)
-
diff --git a/tk8.6/win/mkd.bat b/tk8.6/win/mkd.bat deleted file mode 100644 index 1bd5ccb..0000000 --- a/tk8.6/win/mkd.bat +++ /dev/null @@ -1,12 +0,0 @@ -@echo off
-
-if exist %1\nul goto end
-
-md %1
-if errorlevel 1 goto end
-
-echo Created directory %1
-
-:end
-
-
diff --git a/tk8.6/win/nmakehlp.c b/tk8.6/win/nmakehlp.c deleted file mode 100644 index 025bb99..0000000 --- a/tk8.6/win/nmakehlp.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * nmakehlp.c -- - * - * This is used to fix limitations within nmake and the environment. - * - * Copyright (c) 2002 by David Gravereaux. - * Copyright (c) 2006 by Pat Thoyts - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - * ---------------------------------------------------------------------------- - */ - -#define _CRT_SECURE_NO_DEPRECATE -#include <windows.h> -#define NO_SHLWAPI_GDI -#define NO_SHLWAPI_STREAM -#define NO_SHLWAPI_REG -#include <shlwapi.h> -#pragma comment (lib, "user32.lib") -#pragma comment (lib, "kernel32.lib") -#pragma comment (lib, "shlwapi.lib") -#include <stdio.h> -#include <math.h> - -/* - * This library is required for x64 builds with _some_ versions of MSVC - */ -#if defined(_M_IA64) || defined(_M_AMD64) -#if _MSC_VER >= 1400 && _MSC_VER < 1500 -#pragma comment(lib, "bufferoverflowU") -#endif -#endif - -/* ISO hack for dumb VC++ */ -#ifdef _MSC_VER -#define snprintf _snprintf -#endif - - -/* protos */ - -static int CheckForCompilerFeature(const char *option); -static int CheckForLinkerFeature(const char **options, int count); -static int IsIn(const char *string, const char *substring); -static int SubstituteFile(const char *substs, const char *filename); -static int QualifyPath(const char *path); -static int LocateDependency(const char *keyfile); -static const char *GetVersionFromFile(const char *filename, const char *match, int numdots); -static DWORD WINAPI ReadFromPipe(LPVOID args); - -/* globals */ - -#define CHUNK 25 -#define STATICBUFFERSIZE 1000 -typedef struct { - HANDLE pipe; - char buffer[STATICBUFFERSIZE]; -} pipeinfo; - -pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'}; -pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'}; - -/* - * exitcodes: 0 == no, 1 == yes, 2 == error - */ - -int -main( - int argc, - char *argv[]) -{ - char msg[300]; - DWORD dwWritten; - int chars; - char *s; - - /* - * Make sure children (cl.exe and link.exe) are kept quiet. - */ - - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); - - /* - * Make sure the compiler and linker aren't effected by the outside world. - */ - - SetEnvironmentVariable("CL", ""); - SetEnvironmentVariable("LINK", ""); - - if (argc > 1 && *argv[1] == '-') { - switch (*(argv[1]+1)) { - case 'c': - if (argc != 3) { - chars = snprintf(msg, sizeof(msg) - 1, - "usage: %s -c <compiler option>\n" - "Tests for whether cl.exe supports an option\n" - "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, - &dwWritten, NULL); - return 2; - } - return CheckForCompilerFeature(argv[2]); - case 'l': - if (argc < 3) { - chars = snprintf(msg, sizeof(msg) - 1, - "usage: %s -l <linker option> ?<mandatory option> ...?\n" - "Tests for whether link.exe supports an option\n" - "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, - &dwWritten, NULL); - return 2; - } - return CheckForLinkerFeature(&argv[2], argc-2); - case 'f': - if (argc == 2) { - chars = snprintf(msg, sizeof(msg) - 1, - "usage: %s -f <string> <substring>\n" - "Find a substring within another\n" - "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, - &dwWritten, NULL); - return 2; - } else if (argc == 3) { - /* - * If the string is blank, there is no match. - */ - - return 0; - } else { - return IsIn(argv[2], argv[3]); - } - case 's': - if (argc == 2) { - chars = snprintf(msg, sizeof(msg) - 1, - "usage: %s -s <substitutions file> <file>\n" - "Perform a set of string map type substutitions on a file\n" - "exitcodes: 0\n", - argv[0]); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, - &dwWritten, NULL); - return 2; - } - return SubstituteFile(argv[2], argv[3]); - case 'V': - if (argc != 4) { - chars = snprintf(msg, sizeof(msg) - 1, - "usage: %s -V filename matchstring\n" - "Extract a version from a file:\n" - "eg: pkgIndex.tcl \"package ifneeded http\"", - argv[0]); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, - &dwWritten, NULL); - return 0; - } - s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0'); - if (s && *s) { - printf("%s\n", s); - return 0; - } else - return 1; /* Version not found. Return non-0 exit code */ - - case 'Q': - if (argc != 3) { - chars = snprintf(msg, sizeof(msg) - 1, - "usage: %s -Q path\n" - "Emit the fully qualified path\n" - "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, - &dwWritten, NULL); - return 2; - } - return QualifyPath(argv[2]); - - case 'L': - if (argc != 3) { - chars = snprintf(msg, sizeof(msg) - 1, - "usage: %s -L keypath\n" - "Emit the fully qualified path of directory containing keypath\n" - "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, - &dwWritten, NULL); - return 2; - } - return LocateDependency(argv[2]); - } - } - chars = snprintf(msg, sizeof(msg) - 1, - "usage: %s -c|-f|-l|-Q|-s|-V ...\n" - "This is a little helper app to equalize shell differences between WinNT and\n" - "Win9x and get nmake.exe to accomplish its job.\n", - argv[0]); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL); - return 2; -} - -static int -CheckForCompilerFeature( - const char *option) -{ - STARTUPINFO si; - PROCESS_INFORMATION pi; - SECURITY_ATTRIBUTES sa; - DWORD threadID; - char msg[300]; - BOOL ok; - HANDLE hProcess, h, pipeThreads[2]; - char cmdline[100]; - - hProcess = GetCurrentProcess(); - - ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); - ZeroMemory(&si, sizeof(STARTUPINFO)); - si.cb = sizeof(STARTUPINFO); - si.dwFlags = STARTF_USESTDHANDLES; - si.hStdInput = INVALID_HANDLE_VALUE; - - ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = FALSE; - - /* - * Create a non-inheritible pipe. - */ - - CreatePipe(&Out.pipe, &h, &sa, 0); - - /* - * Dupe the write side, make it inheritible, and close the original. - */ - - DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE, - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); - - /* - * Same as above, but for the error side. - */ - - CreatePipe(&Err.pipe, &h, &sa, 0); - DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE, - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); - - /* - * Base command line. - */ - - lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch "); - - /* - * Append our option for testing - */ - - lstrcat(cmdline, option); - - /* - * Filename to compile, which exists, but is nothing and empty. - */ - - lstrcat(cmdline, " .\\nul"); - - ok = CreateProcess( - NULL, /* Module name. */ - cmdline, /* Command line. */ - NULL, /* Process handle not inheritable. */ - NULL, /* Thread handle not inheritable. */ - TRUE, /* yes, inherit handles. */ - DETACHED_PROCESS, /* No console for you. */ - NULL, /* Use parent's environment block. */ - NULL, /* Use parent's starting directory. */ - &si, /* Pointer to STARTUPINFO structure. */ - &pi); /* Pointer to PROCESS_INFORMATION structure. */ - - if (!ok) { - DWORD err = GetLastError(); - int chars = snprintf(msg, sizeof(msg) - 1, - "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err); - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| - FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars], - (300-chars), 0); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL); - return 2; - } - - /* - * Close our references to the write handles that have now been inherited. - */ - - CloseHandle(si.hStdOutput); - CloseHandle(si.hStdError); - - WaitForInputIdle(pi.hProcess, 5000); - CloseHandle(pi.hThread); - - /* - * Start the pipe reader threads. - */ - - pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID); - pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID); - - /* - * Block waiting for the process to end. - */ - - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hProcess); - - /* - * Wait for our pipe to get done reading, should it be a little slow. - */ - - WaitForMultipleObjects(2, pipeThreads, TRUE, 500); - CloseHandle(pipeThreads[0]); - CloseHandle(pipeThreads[1]); - - /* - * Look for the commandline warning code in both streams. - * - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002. - */ - - return !(strstr(Out.buffer, "D4002") != NULL - || strstr(Err.buffer, "D4002") != NULL - || strstr(Out.buffer, "D9002") != NULL - || strstr(Err.buffer, "D9002") != NULL - || strstr(Out.buffer, "D2021") != NULL - || strstr(Err.buffer, "D2021") != NULL); -} - -static int -CheckForLinkerFeature( - const char **options, - int count) -{ - STARTUPINFO si; - PROCESS_INFORMATION pi; - SECURITY_ATTRIBUTES sa; - DWORD threadID; - char msg[300]; - BOOL ok; - HANDLE hProcess, h, pipeThreads[2]; - int i; - char cmdline[255]; - - hProcess = GetCurrentProcess(); - - ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); - ZeroMemory(&si, sizeof(STARTUPINFO)); - si.cb = sizeof(STARTUPINFO); - si.dwFlags = STARTF_USESTDHANDLES; - si.hStdInput = INVALID_HANDLE_VALUE; - - ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - /* - * Create a non-inheritible pipe. - */ - - CreatePipe(&Out.pipe, &h, &sa, 0); - - /* - * Dupe the write side, make it inheritible, and close the original. - */ - - DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE, - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); - - /* - * Same as above, but for the error side. - */ - - CreatePipe(&Err.pipe, &h, &sa, 0); - DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE, - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); - - /* - * Base command line. - */ - - lstrcpy(cmdline, "link.exe -nologo "); - - /* - * Append our option for testing. - */ - - for (i = 0; i < count; i++) { - lstrcat(cmdline, " \""); - lstrcat(cmdline, options[i]); - lstrcat(cmdline, "\""); - } - - ok = CreateProcess( - NULL, /* Module name. */ - cmdline, /* Command line. */ - NULL, /* Process handle not inheritable. */ - NULL, /* Thread handle not inheritable. */ - TRUE, /* yes, inherit handles. */ - DETACHED_PROCESS, /* No console for you. */ - NULL, /* Use parent's environment block. */ - NULL, /* Use parent's starting directory. */ - &si, /* Pointer to STARTUPINFO structure. */ - &pi); /* Pointer to PROCESS_INFORMATION structure. */ - - if (!ok) { - DWORD err = GetLastError(); - int chars = snprintf(msg, sizeof(msg) - 1, - "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err); - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| - FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars], - (300-chars), 0); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL); - return 2; - } - - /* - * Close our references to the write handles that have now been inherited. - */ - - CloseHandle(si.hStdOutput); - CloseHandle(si.hStdError); - - WaitForInputIdle(pi.hProcess, 5000); - CloseHandle(pi.hThread); - - /* - * Start the pipe reader threads. - */ - - pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID); - pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID); - - /* - * Block waiting for the process to end. - */ - - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hProcess); - - /* - * Wait for our pipe to get done reading, should it be a little slow. - */ - - WaitForMultipleObjects(2, pipeThreads, TRUE, 500); - CloseHandle(pipeThreads[0]); - CloseHandle(pipeThreads[1]); - - /* - * Look for the commandline warning code in the stderr stream. - */ - - return !(strstr(Out.buffer, "LNK1117") != NULL || - strstr(Err.buffer, "LNK1117") != NULL || - strstr(Out.buffer, "LNK4044") != NULL || - strstr(Err.buffer, "LNK4044") != NULL || - strstr(Out.buffer, "LNK4224") != NULL || - strstr(Err.buffer, "LNK4224") != NULL); -} - -static DWORD WINAPI -ReadFromPipe( - LPVOID args) -{ - pipeinfo *pi = (pipeinfo *) args; - char *lastBuf = pi->buffer; - DWORD dwRead; - BOOL ok; - - again: - if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) { - CloseHandle(pi->pipe); - return (DWORD)-1; - } - ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L); - if (!ok || dwRead == 0) { - CloseHandle(pi->pipe); - return 0; - } - lastBuf += dwRead; - goto again; - - return 0; /* makes the compiler happy */ -} - -static int -IsIn( - const char *string, - const char *substring) -{ - return (strstr(string, substring) != NULL); -} - -/* - * GetVersionFromFile -- - * Looks for a match string in a file and then returns the version - * following the match where a version is anything acceptable to - * package provide or package ifneeded. - */ - -static const char * -GetVersionFromFile( - const char *filename, - const char *match, - int numdots) -{ - size_t cbBuffer = 100; - static char szBuffer[100]; - char *szResult = NULL; - FILE *fp = fopen(filename, "rt"); - - if (fp != NULL) { - /* - * Read data until we see our match string. - */ - - while (fgets(szBuffer, cbBuffer, fp) != NULL) { - LPSTR p, q; - - p = strstr(szBuffer, match); - if (p != NULL) { - /* - * Skip to first digit after the match. - */ - - p += strlen(match); - while (*p && !isdigit(*p)) { - ++p; - } - - /* - * Find ending whitespace. - */ - - q = p; - while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q) - && (!strchr("ab", q[-1])) || --numdots))) { - ++q; - } - - memcpy(szBuffer, p, q - p); - szBuffer[q-p] = 0; - szResult = szBuffer; - break; - } - } - fclose(fp); - } - return szResult; -} - -/* - * List helpers for the SubstituteFile function - */ - -typedef struct list_item_t { - struct list_item_t *nextPtr; - char * key; - char * value; -} list_item_t; - -/* insert a list item into the list (list may be null) */ -static list_item_t * -list_insert(list_item_t **listPtrPtr, const char *key, const char *value) -{ - list_item_t *itemPtr = malloc(sizeof(list_item_t)); - if (itemPtr) { - itemPtr->key = strdup(key); - itemPtr->value = strdup(value); - itemPtr->nextPtr = NULL; - - while(*listPtrPtr) { - listPtrPtr = &(*listPtrPtr)->nextPtr; - } - *listPtrPtr = itemPtr; - } - return itemPtr; -} - -static void -list_free(list_item_t **listPtrPtr) -{ - list_item_t *tmpPtr, *listPtr = *listPtrPtr; - while (listPtr) { - tmpPtr = listPtr; - listPtr = listPtr->nextPtr; - free(tmpPtr->key); - free(tmpPtr->value); - free(tmpPtr); - } -} - -/* - * SubstituteFile -- - * As windows doesn't provide anything useful like sed and it's unreliable - * to use the tclsh you are building against (consider x-platform builds - - * eg compiling AMD64 target from IX86) we provide a simple substitution - * option here to handle autoconf style substitutions. - * The substitution file is whitespace and line delimited. The file should - * consist of lines matching the regular expression: - * \s*\S+\s+\S*$ - * - * Usage is something like: - * nmakehlp -S << $** > $@ - * @PACKAGE_NAME@ $(PACKAGE_NAME) - * @PACKAGE_VERSION@ $(PACKAGE_VERSION) - * << - */ - -static int -SubstituteFile( - const char *substitutions, - const char *filename) -{ - size_t cbBuffer = 1024; - static char szBuffer[1024], szCopy[1024]; - char *szResult = NULL; - list_item_t *substPtr = NULL; - FILE *fp, *sp; - - fp = fopen(filename, "rt"); - if (fp != NULL) { - - /* - * Build a list of substutitions from the first filename - */ - - sp = fopen(substitutions, "rt"); - if (sp != NULL) { - while (fgets(szBuffer, cbBuffer, sp) != NULL) { - unsigned char *ks, *ke, *vs, *ve; - ks = (unsigned char*)szBuffer; - while (ks && *ks && isspace(*ks)) ++ks; - ke = ks; - while (ke && *ke && !isspace(*ke)) ++ke; - vs = ke; - while (vs && *vs && isspace(*vs)) ++vs; - ve = vs; - while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve; - *ke = 0, *ve = 0; - list_insert(&substPtr, (char*)ks, (char*)vs); - } - fclose(sp); - } - - /* debug: dump the list */ -#ifdef _DEBUG - { - int n = 0; - list_item_t *p = NULL; - for (p = substPtr; p != NULL; p = p->nextPtr, ++n) { - fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value); - } - } -#endif - - /* - * Run the substitutions over each line of the input - */ - - while (fgets(szBuffer, cbBuffer, fp) != NULL) { - list_item_t *p = NULL; - for (p = substPtr; p != NULL; p = p->nextPtr) { - char *m = strstr(szBuffer, p->key); - if (m) { - char *cp, *op, *sp; - cp = szCopy; - op = szBuffer; - while (op != m) *cp++ = *op++; - sp = p->value; - while (sp && *sp) *cp++ = *sp++; - op += strlen(p->key); - while (*op) *cp++ = *op++; - *cp = 0; - memcpy(szBuffer, szCopy, sizeof(szCopy)); - } - } - printf(szBuffer); - } - - list_free(&substPtr); - } - fclose(fp); - return 0; -} - -/* - * QualifyPath -- - * - * This composes the current working directory with a provided path - * and returns the fully qualified and normalized path. - * Mostly needed to setup paths for testing. - */ - -static int -QualifyPath( - const char *szPath) -{ - char szCwd[MAX_PATH + 1]; - char szTmp[MAX_PATH + 1]; - char *p; - GetCurrentDirectory(MAX_PATH, szCwd); - while ((p = strchr(szPath, '/')) && *p) - *p = '\\'; - PathCombine(szTmp, szCwd, szPath); - PathCanonicalize(szCwd, szTmp); - printf("%s\n", szCwd); - return 0; -} - -/* - * Implements LocateDependency for a single directory. See that command - * for an explanation. - * Returns 0 if found after printing the directory. - * Returns 1 if not found but no errors. - * Returns 2 on any kind of error - * Basically, these are used as exit codes for the process. - */ -static int LocateDependencyHelper(const char *dir, const char *keypath) -{ - HANDLE hSearch; - char path[MAX_PATH+1]; - int dirlen, keylen, ret; - WIN32_FIND_DATA finfo; - - if (dir == NULL || keypath == NULL) - return 2; /* Have no real error reporting mechanism into nmake */ - dirlen = strlen(dir); - if ((dirlen + 3) > sizeof(path)) - return 2; - strncpy(path, dir, dirlen); - strncpy(path+dirlen, "\\*", 3); /* Including terminating \0 */ - keylen = strlen(keypath); - -#if 0 /* This function is not available in Visual C++ 6 */ - /* - * Use numerics 0 -> FindExInfoStandard, - * 1 -> FindExSearchLimitToDirectories, - * as these are not defined in Visual C++ 6 - */ - hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0); -#else - hSearch = FindFirstFile(path, &finfo); -#endif - if (hSearch == INVALID_HANDLE_VALUE) - return 1; /* Not found */ - - /* Loop through all subdirs checking if the keypath is under there */ - ret = 1; /* Assume not found */ - do { - int sublen; - /* - * We need to check it is a directory despite the - * FindExSearchLimitToDirectories in the above call. See SDK docs - */ - if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) - continue; - sublen = strlen(finfo.cFileName); - if ((dirlen+1+sublen+1+keylen+1) > sizeof(path)) - continue; /* Path does not fit, assume not matched */ - strncpy(path+dirlen+1, finfo.cFileName, sublen); - path[dirlen+1+sublen] = '\\'; - strncpy(path+dirlen+1+sublen+1, keypath, keylen+1); - if (PathFileExists(path)) { - /* Found a match, print to stdout */ - path[dirlen+1+sublen] = '\0'; - QualifyPath(path); - ret = 0; - break; - } - } while (FindNextFile(hSearch, &finfo)); - FindClose(hSearch); - return ret; -} - -/* - * LocateDependency -- - * - * Locates a dependency for a package. - * keypath - a relative path within the package directory - * that is used to confirm it is the correct directory. - * The search path for the package directory is currently only - * the parent and grandparent of the current working directory. - * If found, the command prints - * name_DIRPATH=<full path of located directory> - * and returns 0. If not found, does not print anything and returns 1. - */ -static int LocateDependency(const char *keypath) -{ - int i, ret; - static char *paths[] = {"..", "..\\..", "..\\..\\.."}; - - for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) { - ret = LocateDependencyHelper(paths[i], keypath); - if (ret == 0) - return ret; - } - return ret; -} - - -/* - * Local variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * indent-tabs-mode: t - * tab-width: 8 - * End: - */ diff --git a/tk8.6/win/rc/buttons.bmp b/tk8.6/win/rc/buttons.bmp Binary files differdeleted file mode 100644 index f37a4c9..0000000 --- a/tk8.6/win/rc/buttons.bmp +++ /dev/null diff --git a/tk8.6/win/rc/cursor00.cur b/tk8.6/win/rc/cursor00.cur Binary files differdeleted file mode 100644 index 0c58bfe..0000000 --- a/tk8.6/win/rc/cursor00.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor02.cur b/tk8.6/win/rc/cursor02.cur Binary files differdeleted file mode 100644 index 46f0f11..0000000 --- a/tk8.6/win/rc/cursor02.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor04.cur b/tk8.6/win/rc/cursor04.cur Binary files differdeleted file mode 100644 index 1b3028d..0000000 --- a/tk8.6/win/rc/cursor04.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor06.cur b/tk8.6/win/rc/cursor06.cur Binary files differdeleted file mode 100644 index bb06edf..0000000 --- a/tk8.6/win/rc/cursor06.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor08.cur b/tk8.6/win/rc/cursor08.cur Binary files differdeleted file mode 100644 index d9f15f7..0000000 --- a/tk8.6/win/rc/cursor08.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor0a.cur b/tk8.6/win/rc/cursor0a.cur Binary files differdeleted file mode 100644 index 6bffda5..0000000 --- a/tk8.6/win/rc/cursor0a.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor0c.cur b/tk8.6/win/rc/cursor0c.cur Binary files differdeleted file mode 100644 index a991da6..0000000 --- a/tk8.6/win/rc/cursor0c.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor0e.cur b/tk8.6/win/rc/cursor0e.cur Binary files differdeleted file mode 100644 index 6e0434d..0000000 --- a/tk8.6/win/rc/cursor0e.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor10.cur b/tk8.6/win/rc/cursor10.cur Binary files differdeleted file mode 100644 index c4f7809..0000000 --- a/tk8.6/win/rc/cursor10.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor12.cur b/tk8.6/win/rc/cursor12.cur Binary files differdeleted file mode 100644 index 0d0d667..0000000 --- a/tk8.6/win/rc/cursor12.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor14.cur b/tk8.6/win/rc/cursor14.cur Binary files differdeleted file mode 100644 index c7de122..0000000 --- a/tk8.6/win/rc/cursor14.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor16.cur b/tk8.6/win/rc/cursor16.cur Binary files differdeleted file mode 100644 index cfc08f2..0000000 --- a/tk8.6/win/rc/cursor16.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor18.cur b/tk8.6/win/rc/cursor18.cur Binary files differdeleted file mode 100644 index 95ed2ee..0000000 --- a/tk8.6/win/rc/cursor18.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor1a.cur b/tk8.6/win/rc/cursor1a.cur Binary files differdeleted file mode 100644 index ea51361..0000000 --- a/tk8.6/win/rc/cursor1a.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor1c.cur b/tk8.6/win/rc/cursor1c.cur Binary files differdeleted file mode 100644 index 6f10bfb..0000000 --- a/tk8.6/win/rc/cursor1c.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor1e.cur b/tk8.6/win/rc/cursor1e.cur Binary files differdeleted file mode 100644 index 3272db1..0000000 --- a/tk8.6/win/rc/cursor1e.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor20.cur b/tk8.6/win/rc/cursor20.cur Binary files differdeleted file mode 100644 index 48080be..0000000 --- a/tk8.6/win/rc/cursor20.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor22.cur b/tk8.6/win/rc/cursor22.cur Binary files differdeleted file mode 100644 index 2f8e912..0000000 --- a/tk8.6/win/rc/cursor22.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor24.cur b/tk8.6/win/rc/cursor24.cur Binary files differdeleted file mode 100644 index 87ba5b4..0000000 --- a/tk8.6/win/rc/cursor24.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor26.cur b/tk8.6/win/rc/cursor26.cur Binary files differdeleted file mode 100644 index 0b2dbd2..0000000 --- a/tk8.6/win/rc/cursor26.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor28.cur b/tk8.6/win/rc/cursor28.cur Binary files differdeleted file mode 100644 index 30550f9..0000000 --- a/tk8.6/win/rc/cursor28.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor2a.cur b/tk8.6/win/rc/cursor2a.cur Binary files differdeleted file mode 100644 index 5e75f16..0000000 --- a/tk8.6/win/rc/cursor2a.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor2c.cur b/tk8.6/win/rc/cursor2c.cur Binary files differdeleted file mode 100644 index 7be3494..0000000 --- a/tk8.6/win/rc/cursor2c.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor2e.cur b/tk8.6/win/rc/cursor2e.cur Binary files differdeleted file mode 100644 index 7a0bc69..0000000 --- a/tk8.6/win/rc/cursor2e.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor30.cur b/tk8.6/win/rc/cursor30.cur Binary files differdeleted file mode 100644 index 70ef4fd..0000000 --- a/tk8.6/win/rc/cursor30.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor32.cur b/tk8.6/win/rc/cursor32.cur Binary files differdeleted file mode 100644 index 93b5c47..0000000 --- a/tk8.6/win/rc/cursor32.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor34.cur b/tk8.6/win/rc/cursor34.cur Binary files differdeleted file mode 100644 index 0fad3f1..0000000 --- a/tk8.6/win/rc/cursor34.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor36.cur b/tk8.6/win/rc/cursor36.cur Binary files differdeleted file mode 100644 index fc8d4f6..0000000 --- a/tk8.6/win/rc/cursor36.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor38.cur b/tk8.6/win/rc/cursor38.cur Binary files differdeleted file mode 100644 index 4447d7d..0000000 --- a/tk8.6/win/rc/cursor38.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor3a.cur b/tk8.6/win/rc/cursor3a.cur Binary files differdeleted file mode 100644 index e3eda81..0000000 --- a/tk8.6/win/rc/cursor3a.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor3c.cur b/tk8.6/win/rc/cursor3c.cur Binary files differdeleted file mode 100644 index 6a3111d..0000000 --- a/tk8.6/win/rc/cursor3c.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor3e.cur b/tk8.6/win/rc/cursor3e.cur Binary files differdeleted file mode 100644 index fa6fe5b..0000000 --- a/tk8.6/win/rc/cursor3e.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor40.cur b/tk8.6/win/rc/cursor40.cur Binary files differdeleted file mode 100644 index f07bf4f..0000000 --- a/tk8.6/win/rc/cursor40.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor42.cur b/tk8.6/win/rc/cursor42.cur Binary files differdeleted file mode 100644 index 387d5f0..0000000 --- a/tk8.6/win/rc/cursor42.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor44.cur b/tk8.6/win/rc/cursor44.cur Binary files differdeleted file mode 100644 index 190320c..0000000 --- a/tk8.6/win/rc/cursor44.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor46.cur b/tk8.6/win/rc/cursor46.cur Binary files differdeleted file mode 100644 index 4f969d1..0000000 --- a/tk8.6/win/rc/cursor46.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor48.cur b/tk8.6/win/rc/cursor48.cur Binary files differdeleted file mode 100644 index 97e499a..0000000 --- a/tk8.6/win/rc/cursor48.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor4a.cur b/tk8.6/win/rc/cursor4a.cur Binary files differdeleted file mode 100644 index 30febfa..0000000 --- a/tk8.6/win/rc/cursor4a.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor4c.cur b/tk8.6/win/rc/cursor4c.cur Binary files differdeleted file mode 100644 index 3512a51..0000000 --- a/tk8.6/win/rc/cursor4c.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor4e.cur b/tk8.6/win/rc/cursor4e.cur Binary files differdeleted file mode 100644 index 28992c4..0000000 --- a/tk8.6/win/rc/cursor4e.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor50.cur b/tk8.6/win/rc/cursor50.cur Binary files differdeleted file mode 100644 index 7352420..0000000 --- a/tk8.6/win/rc/cursor50.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor52.cur b/tk8.6/win/rc/cursor52.cur Binary files differdeleted file mode 100644 index 435f99f..0000000 --- a/tk8.6/win/rc/cursor52.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor54.cur b/tk8.6/win/rc/cursor54.cur Binary files differdeleted file mode 100644 index 54eb4f2..0000000 --- a/tk8.6/win/rc/cursor54.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor56.cur b/tk8.6/win/rc/cursor56.cur Binary files differdeleted file mode 100644 index c808bd4..0000000 --- a/tk8.6/win/rc/cursor56.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor58.cur b/tk8.6/win/rc/cursor58.cur Binary files differdeleted file mode 100644 index 98b6a2f..0000000 --- a/tk8.6/win/rc/cursor58.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor5a.cur b/tk8.6/win/rc/cursor5a.cur Binary files differdeleted file mode 100644 index b00070e..0000000 --- a/tk8.6/win/rc/cursor5a.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor5c.cur b/tk8.6/win/rc/cursor5c.cur Binary files differdeleted file mode 100644 index a407b55..0000000 --- a/tk8.6/win/rc/cursor5c.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor5e.cur b/tk8.6/win/rc/cursor5e.cur Binary files differdeleted file mode 100644 index ab3449f..0000000 --- a/tk8.6/win/rc/cursor5e.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor60.cur b/tk8.6/win/rc/cursor60.cur Binary files differdeleted file mode 100644 index dc61469..0000000 --- a/tk8.6/win/rc/cursor60.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor62.cur b/tk8.6/win/rc/cursor62.cur Binary files differdeleted file mode 100644 index ff7c009..0000000 --- a/tk8.6/win/rc/cursor62.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor64.cur b/tk8.6/win/rc/cursor64.cur Binary files differdeleted file mode 100644 index a6bdd0e..0000000 --- a/tk8.6/win/rc/cursor64.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor66.cur b/tk8.6/win/rc/cursor66.cur Binary files differdeleted file mode 100644 index 269f772..0000000 --- a/tk8.6/win/rc/cursor66.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor68.cur b/tk8.6/win/rc/cursor68.cur Binary files differdeleted file mode 100644 index 27cfaf0..0000000 --- a/tk8.6/win/rc/cursor68.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor6a.cur b/tk8.6/win/rc/cursor6a.cur Binary files differdeleted file mode 100644 index 20f138e..0000000 --- a/tk8.6/win/rc/cursor6a.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor6c.cur b/tk8.6/win/rc/cursor6c.cur Binary files differdeleted file mode 100644 index d8fb0f1..0000000 --- a/tk8.6/win/rc/cursor6c.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor6e.cur b/tk8.6/win/rc/cursor6e.cur Binary files differdeleted file mode 100644 index 3a9b6b0..0000000 --- a/tk8.6/win/rc/cursor6e.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor70.cur b/tk8.6/win/rc/cursor70.cur Binary files differdeleted file mode 100644 index e2d7673..0000000 --- a/tk8.6/win/rc/cursor70.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor72.cur b/tk8.6/win/rc/cursor72.cur Binary files differdeleted file mode 100644 index 471bcf0..0000000 --- a/tk8.6/win/rc/cursor72.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor74.cur b/tk8.6/win/rc/cursor74.cur Binary files differdeleted file mode 100644 index 176d2b0..0000000 --- a/tk8.6/win/rc/cursor74.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor76.cur b/tk8.6/win/rc/cursor76.cur Binary files differdeleted file mode 100644 index 34f402a..0000000 --- a/tk8.6/win/rc/cursor76.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor78.cur b/tk8.6/win/rc/cursor78.cur Binary files differdeleted file mode 100644 index 70e25dd..0000000 --- a/tk8.6/win/rc/cursor78.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor7a.cur b/tk8.6/win/rc/cursor7a.cur Binary files differdeleted file mode 100644 index 5ea95c4..0000000 --- a/tk8.6/win/rc/cursor7a.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor7c.cur b/tk8.6/win/rc/cursor7c.cur Binary files differdeleted file mode 100644 index 38036ab..0000000 --- a/tk8.6/win/rc/cursor7c.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor7e.cur b/tk8.6/win/rc/cursor7e.cur Binary files differdeleted file mode 100644 index 4b24e50..0000000 --- a/tk8.6/win/rc/cursor7e.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor80.cur b/tk8.6/win/rc/cursor80.cur Binary files differdeleted file mode 100644 index a3955a5..0000000 --- a/tk8.6/win/rc/cursor80.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor82.cur b/tk8.6/win/rc/cursor82.cur Binary files differdeleted file mode 100644 index 984cfba..0000000 --- a/tk8.6/win/rc/cursor82.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor84.cur b/tk8.6/win/rc/cursor84.cur Binary files differdeleted file mode 100644 index cd6807e..0000000 --- a/tk8.6/win/rc/cursor84.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor86.cur b/tk8.6/win/rc/cursor86.cur Binary files differdeleted file mode 100644 index 52cb5c3..0000000 --- a/tk8.6/win/rc/cursor86.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor88.cur b/tk8.6/win/rc/cursor88.cur Binary files differdeleted file mode 100644 index fdba0d6..0000000 --- a/tk8.6/win/rc/cursor88.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor8a.cur b/tk8.6/win/rc/cursor8a.cur Binary files differdeleted file mode 100644 index 369e71f..0000000 --- a/tk8.6/win/rc/cursor8a.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor8c.cur b/tk8.6/win/rc/cursor8c.cur Binary files differdeleted file mode 100644 index 811a0c3..0000000 --- a/tk8.6/win/rc/cursor8c.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor8e.cur b/tk8.6/win/rc/cursor8e.cur Binary files differdeleted file mode 100644 index a500a38..0000000 --- a/tk8.6/win/rc/cursor8e.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor90.cur b/tk8.6/win/rc/cursor90.cur Binary files differdeleted file mode 100644 index 3c655d5..0000000 --- a/tk8.6/win/rc/cursor90.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor92.cur b/tk8.6/win/rc/cursor92.cur Binary files differdeleted file mode 100644 index 4364b5d..0000000 --- a/tk8.6/win/rc/cursor92.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor94.cur b/tk8.6/win/rc/cursor94.cur Binary files differdeleted file mode 100644 index 16e6b61..0000000 --- a/tk8.6/win/rc/cursor94.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor96.cur b/tk8.6/win/rc/cursor96.cur Binary files differdeleted file mode 100644 index cecaea3..0000000 --- a/tk8.6/win/rc/cursor96.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor98.cur b/tk8.6/win/rc/cursor98.cur Binary files differdeleted file mode 100644 index 5cab68e..0000000 --- a/tk8.6/win/rc/cursor98.cur +++ /dev/null diff --git a/tk8.6/win/rc/cursor9a.cur b/tk8.6/win/rc/cursor9a.cur Binary files differdeleted file mode 100644 index 048f06b..0000000 --- a/tk8.6/win/rc/cursor9a.cur +++ /dev/null diff --git a/tk8.6/win/rc/lamp.bmp b/tk8.6/win/rc/lamp.bmp Binary files differdeleted file mode 100644 index 1e2f9d4..0000000 --- a/tk8.6/win/rc/lamp.bmp +++ /dev/null diff --git a/tk8.6/win/rc/tk.ico b/tk8.6/win/rc/tk.ico Binary files differdeleted file mode 100644 index e254318..0000000 --- a/tk8.6/win/rc/tk.ico +++ /dev/null diff --git a/tk8.6/win/rc/tk.rc b/tk8.6/win/rc/tk.rc deleted file mode 100644 index 6a74be3..0000000 --- a/tk8.6/win/rc/tk.rc +++ /dev/null @@ -1,74 +0,0 @@ -// -// Version Resource Script -// - -#include <windows.h> -#include <tk.h> - -// -// build-up the name suffix that defines the type of build this is. -// -#if TCL_THREADS -#define SUFFIX_THREADS "t" -#else -#define SUFFIX_THREADS "" -#endif - -#if DEBUG && !UNCHECKED -#define SUFFIX_DEBUG "g" -#else -#define SUFFIX_DEBUG "" -#endif - -#define SUFFIX SUFFIX_THREADS SUFFIX_DEBUG - - -VS_VERSION_INFO VERSIONINFO - FILEVERSION TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL - PRODUCTVERSION TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL - FILEFLAGSMASK 0x3fL -#ifdef DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "FileDescription", "Tk DLL\0" - VALUE "OriginalFilename", "tk" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".dll\0" - VALUE "CompanyName", "ActiveState Corporation\0" - VALUE "FileVersion", TK_PATCH_LEVEL - VALUE "LegalCopyright", "Copyright \251 2001 by ActiveState Corporation, et al\0" - VALUE "ProductName", "Tk " TK_VERSION " for Windows\0" - VALUE "ProductVersion", TK_PATCH_LEVEL - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -// -// Include the base resources. -// - -#include "tk_base.rc" - -// -// This enables themed scrollbars in XP by trying to use comctl32 v6. -// - -#ifndef RT_MANIFEST -#define RT_MANIFEST 24 -#endif -#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID -#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 -#endif -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "wish.exe.manifest" diff --git a/tk8.6/win/rc/tk_base.rc b/tk8.6/win/rc/tk_base.rc deleted file mode 100644 index e6ab016..0000000 --- a/tk8.6/win/rc/tk_base.rc +++ /dev/null @@ -1,140 +0,0 @@ -// -// Base resources needed by Tk whether it's a DLL or a static library. -// - -#include <windows.h> - -// -// Tk Icon -// -// The BASE_NO_TK_ICON symbol can be defined to avoid -// creating an icon named "tk" in this resource file. -// The user can then create another icon named tk in -// another resource file and link both resource files. -// Tk will then use the custom icon instead of tk.ico. - -#ifndef BASE_NO_TK_ICON -tk ICON DISCARDABLE "tk.ico" -#endif - -#include <dlgs.h> - -FILEOPENORD DIALOG DISCARDABLE 36, 24, 218, 138 -STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Choose Directory" -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 | - 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 | - WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "OK",1,160,6,50,14,WS_GROUP - PUSHBUTTON "Cancel",2,160,24,50,14,WS_GROUP - PUSHBUTTON "&Help",psh15,160,42,50,14,WS_GROUP - CHECKBOX "&Read only",chx1,160,66,50,12,WS_GROUP - PUSHBUTTON "Net&work...",psh14,160,115,50,14,WS_GROUP - - 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 | - WS_VSCROLL - -END - - -// -// Bitmaps -// - -buttons BITMAP DISCARDABLE "buttons.bmp" - -// -// Cursors -// - -X_cursor CURSOR DISCARDABLE "cursor00.cur" -arrow CURSOR DISCARDABLE "cursor02.cur" -based_arrow_down CURSOR DISCARDABLE "cursor04.cur" -based_arrow_up CURSOR DISCARDABLE "cursor06.cur" -boat CURSOR DISCARDABLE "cursor08.cur" -bogosity CURSOR DISCARDABLE "cursor0a.cur" -bottom_left_corner CURSOR DISCARDABLE "cursor0c.cur" -bottom_right_corner CURSOR DISCARDABLE "cursor0e.cur" -bottom_side CURSOR DISCARDABLE "cursor10.cur" -bottom_tee CURSOR DISCARDABLE "cursor12.cur" -box_spiral CURSOR DISCARDABLE "cursor14.cur" -center_ptr CURSOR DISCARDABLE "cursor16.cur" -circle CURSOR DISCARDABLE "cursor18.cur" -clock CURSOR DISCARDABLE "cursor1a.cur" -coffee_mug CURSOR DISCARDABLE "cursor1c.cur" -cross CURSOR DISCARDABLE "cursor1e.cur" -cross_reverse CURSOR DISCARDABLE "cursor20.cur" -crosshair CURSOR DISCARDABLE "cursor22.cur" -diamond_cross CURSOR DISCARDABLE "cursor24.cur" -dot CURSOR DISCARDABLE "cursor26.cur" -dotbox CURSOR DISCARDABLE "cursor28.cur" -double_arrow CURSOR DISCARDABLE "cursor2a.cur" -draft_large CURSOR DISCARDABLE "cursor2c.cur" -draft_small CURSOR DISCARDABLE "cursor2e.cur" -draped_box CURSOR DISCARDABLE "cursor30.cur" -exchange CURSOR DISCARDABLE "cursor32.cur" -fleur CURSOR DISCARDABLE "cursor34.cur" -gobbler CURSOR DISCARDABLE "cursor36.cur" -gumby CURSOR DISCARDABLE "cursor38.cur" -hand1 CURSOR DISCARDABLE "cursor3a.cur" -hand2 CURSOR DISCARDABLE "cursor3c.cur" -heart CURSOR DISCARDABLE "cursor3e.cur" -icon CURSOR DISCARDABLE "cursor40.cur" -iron_cross CURSOR DISCARDABLE "cursor42.cur" -left_ptr CURSOR DISCARDABLE "cursor44.cur" -left_side CURSOR DISCARDABLE "cursor46.cur" -left_tee CURSOR DISCARDABLE "cursor48.cur" -leftbutton CURSOR DISCARDABLE "cursor4a.cur" -ll_angle CURSOR DISCARDABLE "cursor4c.cur" -lr_angle CURSOR DISCARDABLE "cursor4e.cur" -man CURSOR DISCARDABLE "cursor50.cur" -middlebutton CURSOR DISCARDABLE "cursor52.cur" -mouse CURSOR DISCARDABLE "cursor54.cur" -pencil CURSOR DISCARDABLE "cursor56.cur" -pirate CURSOR DISCARDABLE "cursor58.cur" -plus CURSOR DISCARDABLE "cursor5a.cur" -question_arrow CURSOR DISCARDABLE "cursor5c.cur" -right_ptr CURSOR DISCARDABLE "cursor5e.cur" -right_side CURSOR DISCARDABLE "cursor60.cur" -right_tee CURSOR DISCARDABLE "cursor62.cur" -rightbutton CURSOR DISCARDABLE "cursor64.cur" -rtl_logo CURSOR DISCARDABLE "cursor66.cur" -sailboat CURSOR DISCARDABLE "cursor68.cur" -sb_down_arrow CURSOR DISCARDABLE "cursor6a.cur" -sb_h_double_arrow CURSOR DISCARDABLE "cursor6c.cur" -sb_left_arrow CURSOR DISCARDABLE "cursor6e.cur" -sb_right_arrow CURSOR DISCARDABLE "cursor70.cur" -sb_up_arrow CURSOR DISCARDABLE "cursor72.cur" -sb_v_double_arrow CURSOR DISCARDABLE "cursor74.cur" -shuttle CURSOR DISCARDABLE "cursor76.cur" -sizing CURSOR DISCARDABLE "cursor78.cur" -spider CURSOR DISCARDABLE "cursor7a.cur" -spraycan CURSOR DISCARDABLE "cursor7c.cur" -star CURSOR DISCARDABLE "cursor7e.cur" -target CURSOR DISCARDABLE "cursor80.cur" -tcross CURSOR DISCARDABLE "cursor82.cur" -top_left_arrow CURSOR DISCARDABLE "cursor84.cur" -top_left_corner CURSOR DISCARDABLE "cursor86.cur" -top_right_corner CURSOR DISCARDABLE "cursor88.cur" -top_side CURSOR DISCARDABLE "cursor8a.cur" -top_tee CURSOR DISCARDABLE "cursor8c.cur" -trek CURSOR DISCARDABLE "cursor8e.cur" -ul_angle CURSOR DISCARDABLE "cursor90.cur" -umbrella CURSOR DISCARDABLE "cursor92.cur" -ur_angle CURSOR DISCARDABLE "cursor94.cur" -watch CURSOR DISCARDABLE "cursor96.cur" -xterm CURSOR DISCARDABLE "cursor98.cur" -none CURSOR DISCARDABLE "cursor9a.cur" - diff --git a/tk8.6/win/rc/wish.ico b/tk8.6/win/rc/wish.ico Binary files differdeleted file mode 100644 index 5801fb8..0000000 --- a/tk8.6/win/rc/wish.ico +++ /dev/null diff --git a/tk8.6/win/rc/wish.rc b/tk8.6/win/rc/wish.rc deleted file mode 100644 index 53e02fa..0000000 --- a/tk8.6/win/rc/wish.rc +++ /dev/null @@ -1,87 +0,0 @@ -// -// Version Resource Script -// - -#include <windows.h> -#include <tk.h> - -// -// build-up the name suffix that defines the type of build this is. -// -#if TCL_THREADS -#define SUFFIX_THREADS "t" -#else -#define SUFFIX_THREADS "" -#endif - -#if STATIC_BUILD -#define SUFFIX_STATIC "s" -#else -#define SUFFIX_STATIC "" -#endif - -#if DEBUG && !UNCHECKED -#define SUFFIX_DEBUG "g" -#else -#define SUFFIX_DEBUG "" -#endif - -#define SUFFIX SUFFIX_THREADS SUFFIX_STATIC SUFFIX_DEBUG - - -VS_VERSION_INFO VERSIONINFO - FILEVERSION TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL - PRODUCTVERSION TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL - FILEFLAGSMASK 0x3fL -#ifdef DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "FileDescription", "Wish Application\0" - VALUE "OriginalFilename", "wish" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".exe\0" - VALUE "CompanyName", "ActiveState Corporation\0" - VALUE "FileVersion", TK_PATCH_LEVEL - VALUE "LegalCopyright", "Copyright \251 2000 by ActiveState Corporation, et al\0" - VALUE "ProductName", "Tk " TK_VERSION " for Windows\0" - VALUE "ProductVersion", TK_PATCH_LEVEL - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -// -// Icon -// -// The icon whose name or resource ID is lexigraphically first, is used -// as the application's icon. -// - -app ICON DISCARDABLE "wish.ico" - -#if STATIC_BUILD -#include "tk_base.rc" -#endif - -// -// This enables themed scrollbars in XP by trying to use comctl32 v6. -// - -#ifndef RT_MANIFEST -#define RT_MANIFEST 24 -#endif -#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID -#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 -#endif -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "wish.exe.manifest" diff --git a/tk8.6/win/rmd.bat b/tk8.6/win/rmd.bat deleted file mode 100644 index 820b76f..0000000 --- a/tk8.6/win/rmd.bat +++ /dev/null @@ -1,20 +0,0 @@ -@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/tk8.6/win/rules-ext.vc b/tk8.6/win/rules-ext.vc deleted file mode 100644 index ab86876..0000000 --- a/tk8.6/win/rules-ext.vc +++ /dev/null @@ -1,118 +0,0 @@ -# This file should only be included in makefiles for Tcl extensions, -# NOT in the makefile for Tcl itself. - -!ifndef _RULES_EXT_VC - -# We need to run from the directory the parent makefile is located in. -# nmake does not tell us what makefile was used to invoke it so parent -# makefile has to set the MAKEFILEVC macro or we just make a guess and -# warn if we think that is not the case. -!if "$(MAKEFILEVC)" == "" - -!if exist("$(PROJECT).vc") -MAKEFILEVC = $(PROJECT).vc -!elseif exist("makefile.vc") -MAKEFILEVC = makefile.vc -!endif -!endif # "$(MAKEFILEVC)" == "" - -!if !exist("$(MAKEFILEVC)") -MSG = ^ -You must run nmake from the directory containing the project makefile.^ -If you are doing that and getting this message, set the MAKEFILEVC^ -macro to the name of the project makefile. -!message WARNING: $(MSG) -!endif - -!if "$(PROJECT)" == "tcl" -!error The rules-ext.vc file is not intended for Tcl itself. -!endif - -# We extract version numbers using the nmakehlp program. For now use -# the local copy of nmakehlp. Once we locate Tcl, we will use that -# one if it is newer. -!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul] -!endif - -# First locate the Tcl directory that we are working with. -!ifdef TCLDIR - -_RULESDIR = $(TCLDIR:/=\) - -!else - -# If an installation path is specified, that is also the Tcl directory. -# Also Tk never builds against an installed Tcl, it needs Tcl sources -!if defined(INSTALLDIR) && "$(PROJECT)" != "tk" -_RULESDIR=$(INSTALLDIR:/=\) -!else -# Locate Tcl sources -!if [echo _RULESDIR = \> nmakehlp.out] \ - || [nmakehlp -L generic\tcl.h >> nmakehlp.out] -_RULESDIR = ..\..\tcl -!else -!include nmakehlp.out -!endif - -!endif # defined(INSTALLDIR).... - -!endif # ifndef TCLDIR - -# Now look for the targets.vc file under the Tcl root. Note we check this -# file and not rules.vc because the latter also exists on older systems. -!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl -_RULESDIR = $(_RULESDIR)\lib\nmake -!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources -_RULESDIR = $(_RULESDIR)\win -!else -# If we have not located Tcl's targets file, most likely we are compiling -# against an older version of Tcl and so must use our own support files. -_RULESDIR = . -!endif - -!if "$(_RULESDIR)" != "." -# Potentially using Tcl's support files. If this extension has its own -# nmake support files, need to compare the versions and pick newer. - -!if exist("rules.vc") # The extension has its own copy - -!if [echo TCL_RULES_MAJOR = \> versions.vc] \ - && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc] -!endif -!if [echo TCL_RULES_MINOR = \>> versions.vc] \ - && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc] -!endif - -!if [echo OUR_RULES_MAJOR = \>> versions.vc] \ - && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc] -!endif -!if [echo OUR_RULES_MINOR = \>> versions.vc] \ - && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc] -!endif -!include versions.vc -# We have a newer version of the support files, use them -!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR)) -_RULESDIR = . -!endif - -!endif # if exist("rules.vc") - -!endif # if $(_RULESDIR) != "." - -# Let rules.vc know what copy of nmakehlp.c to use. -NMAKEHLPC = $(_RULESDIR)\nmakehlp.c - -# Get rid of our internal defines before calling rules.vc -!undef TCL_RULES_MAJOR -!undef TCL_RULES_MINOR -!undef OUR_RULES_MAJOR -!undef OUR_RULES_MINOR - -!if exist("$(_RULESDIR)\rules.vc") -!message *** Using $(_RULESDIR)\rules.vc -!include "$(_RULESDIR)\rules.vc" -!else -!error *** Could not locate rules.vc in $(_RULESDIR) -!endif - -!endif # _RULES_EXT_VC
\ No newline at end of file diff --git a/tk8.6/win/rules.vc b/tk8.6/win/rules.vc deleted file mode 100644 index 7fc51c1..0000000 --- a/tk8.6/win/rules.vc +++ /dev/null @@ -1,1723 +0,0 @@ -#------------------------------------------------------------- -*- makefile -*-
-# rules.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file does all the hard work in terms of parsing build options,
-# compiler switches, defining common targets and macros. The Tcl makefile
-# directly includes this. Extensions include it via "rules-ext.vc".
-#
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# 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
-# Copyright (c) 2017 Ashok P. Nadkarni
-#------------------------------------------------------------------------------
-
-!ifndef _RULES_VC
-_RULES_VC = 1
-
-# The following macros define the version of the rules.vc nmake build system
-# For modifications that are not backward-compatible, you *must* change
-# the major version.
-RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 0
-
-# The PROJECT macro must be defined by parent makefile.
-!if "$(PROJECT)" == ""
-!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
-!endif
-
-!if "$(PRJ_PACKAGE_TCLNAME)" == ""
-PRJ_PACKAGE_TCLNAME = $(PROJECT)
-!endif
-
-# Also special case Tcl and Tk to save some typing later
-DOING_TCL = 0
-DOING_TK = 0
-!if "$(PROJECT)" == "tcl"
-DOING_TCL = 1
-!elseif "$(PROJECT)" == "tk"
-DOING_TK = 1
-!endif
-
-!ifndef NEED_TK
-# Backwards compatibility
-!ifdef PROJECT_REQUIRES_TK
-NEED_TK = $(PROJECT_REQUIRES_TK)
-!else
-NEED_TK = 0
-!endif
-!endif
-
-!ifndef NEED_TCL_SOURCE
-NEED_TCL_SOURCE = 0
-!endif
-
-!ifdef NEED_TK_SOURCE
-!if $(NEED_TK_SOURCE)
-NEED_TK = 1
-!endif
-!else
-NEED_TK_SOURCE = 0
-!endif
-
-################################################################
-# Nmake is a pretty weak environment in syntax and capabilities
-# so this file is necessarily verbose. It's broken down into
-# the following parts.
-#
-# 0. Sanity check that compiler environment is set up and initialize
-# any built-in settings from the parent makefile
-# 1. First define the external tools used for compiling, copying etc.
-# as this is independent of everything else.
-# 2. Figure out our build structure in terms of the directory, whether
-# we are building Tcl or an extension, etc.
-# 3. Determine the compiler and linker versions
-# 4. Build the nmakehlp helper application
-# 5. Determine the supported compiler options and features
-# 6. Parse the OPTS macro value for user-specified build configuration
-# 7. Parse the STATS macro value for statistics instrumentation
-# 8. Parse the CHECKS macro for additional compilation checks
-# 9. Extract Tcl, and possibly Tk, version numbers from the headers
-# 10. Based on this selected configuration, construct the output
-# directory and file paths
-# 11. Construct the paths where the package is to be installed
-# 12. Set up the actual options passed to compiler and linker based
-# on the information gathered above.
-# 13. Define some standard build targets and implicit rules. These may
-# be optionally disabled by the parent makefile.
-# 14. (For extensions only.) Compare the configuration of the target
-# Tcl and the extensions and warn against discrepancies.
-#
-# One final note about the macro names used. They are as they are
-# for historical reasons. We would like legacy extensions to
-# continue to work with this make include file so be wary of
-# changing them for consistency or clarity.
-
-# 0. Sanity check compiler environment
-
-# 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 = ^
-Visual C++ compiler environment not initialized.
-!error $(MSG)
-!endif
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-
-################################################################
-# 1. Define external programs being used
-
-#----------------------------------------------------------
-# Set the proper copy method to avoid overwrite questions
-# to the user when copying files and selecting the right
-# "delete all" method.
-#----------------------------------------------------------
-
-RMDIR = rmdir /S /Q
-CPY = xcopy /i /y >NUL
-CPYDIR = xcopy /e /i /y >NUL
-COPY = copy /y >NUL
-MKDIR = mkdir
-
-######################################################################
-# 2. Figure out our build environment in terms of what we're building.
-#
-# (a) Tcl itself
-# (b) Tk
-# (c) a Tcl extension using libraries/includes from an *installed* Tcl
-# (d) a Tcl extension using libraries/includes from Tcl source directory
-#
-# This last is needed because some extensions still need
-# some Tcl interfaces that are not publicly exposed.
-#
-# The fragment will set the following macros:
-# ROOT - root of this module sources
-# COMPATDIR - source directory that holds compatibility sources
-# DOCDIR - source directory containing documentation files
-# GENERICDIR - platform-independent source directory
-# WINDIR - Windows-specific source directory
-# TESTDIR - directory containing test files
-# TOOLSDIR - directory containing build tools
-# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
-# when building Tcl itself.
-# _INSTALLDIR - native form of the installation path. For Tcl
-# this will be the root of the Tcl installation. For extensions
-# this will be the lib directory under the root.
-# TCLINSTALL - set to 1 if _TCLDIR refers to
-# headers and libraries from an installed Tcl, and 0 if built against
-# Tcl sources. Not set when building Tcl itself. Yes, not very well
-# named.
-# _TCL_H - native path to the tcl.h file
-#
-# If Tk is involved, also sets the following
-# _TKDIR - native form Tk installation OR Tk source. Not set if building
-# Tk itself.
-# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
-# _TK_H - native path to the tk.h file
-
-# Root directory for sources and assumed subdirectories
-ROOT = $(MAKEDIR)\..
-# The following paths CANNOT have spaces in them as they appear on the
-# left side of implicit rules.
-!ifndef COMPATDIR
-COMPATDIR = $(ROOT)\compat
-!endif
-!ifndef DOCDIR
-DOCDIR = $(ROOT)\doc
-!endif
-!ifndef GENERICDIR
-GENERICDIR = $(ROOT)\generic
-!endif
-!ifndef TOOLSDIR
-TOOLSDIR = $(ROOT)\tools
-!endif
-!ifndef TESTDIR
-TESTDIR = $(ROOT)\tests
-!endif
-!ifndef LIBDIR
-!if exist("$(ROOT)\library")
-LIBDIR = $(ROOT)\library
-!else
-LIBDIR = $(ROOT)\lib
-!endif
-!endif
-!ifndef DEMODIR
-!if exist("$(LIBDIR)\demos")
-DEMODIR = $(LIBDIR)\demos
-!else
-DEMODIR = $(ROOT)\demos
-!endif
-!endif # ifndef DEMODIR
-# Do NOT enclose WINDIR in a !ifndef because Windows always defines
-# WINDIR env var to point to c:\windows!
-# TBD - This is a potentially dangerous conflict, rename WINDIR to
-# something else
-WINDIR = $(ROOT)\win
-
-!ifndef RCDIR
-!if exist("$(WINDIR)\rc")
-RCDIR = $(WINDIR)\rc
-!else
-RCDIR = $(WINDIR)
-!endif
-!endif
-RCDIR = $(RCDIR:/=\)
-
-# The target directory where the built packages and binaries will be installed.
-# INSTALLDIR is the (optional) path specified by the user.
-# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
-!ifdef INSTALLDIR
-### Fix the path separators.
-_INSTALLDIR = $(INSTALLDIR:/=\)
-!else
-### Assume the normal default.
-_INSTALLDIR = $(HOMEDRIVE)\Tcl
-!endif
-
-!if $(DOING_TCL)
-
-# BEGIN Case 2(a) - Building Tcl itself
-
-# Only need to define _TCL_H
-_TCL_H = ..\generic\tcl.h
-
-# END Case 2(a) - Building Tcl itself
-
-!elseif $(DOING_TK)
-
-# BEGIN Case 2(b) - Building Tk
-
-TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
-!if "$(TCLDIR)" == ""
-!if [echo TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-!endif # TCLDIR == ""
-
-_TCLDIR = $(TCLDIR:/=\)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!if !exist("$(_TCL_H)")
-!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
-!endif
-
-_TK_H = ..\generic\tk.h
-
-# END Case 2(b) - Building Tk
-
-!else
-
-# BEGIN Case 2(c) or (d) - Building an extension other than Tk
-
-# If command line has specified Tcl location through TCLDIR, use it
-# else default to the INSTALLDIR setting
-!if "$(TCLDIR)" != ""
-
-_TCLDIR = $(TCLDIR:/=\)
-!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
-TCLINSTALL = 1
-_TCL_H = $(_TCLDIR)\include\tcl.h
-!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
-TCLINSTALL = 0
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!endif
-
-!else # # Case 2(c) for extensions with TCLDIR undefined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
-
-TCLINSTALL = 1
-TCLDIR = $(_INSTALLDIR)\..
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TCLDIR = $(_INSTALLDIR)\..
-_TCL_H = $(_TCLDIR)\include\tcl.h
-
-!else # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!if [echo _TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-TCLINSTALL = 0
-TCLDIR = $(_TCLDIR)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-
-!endif # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!endif # TCLDIR
-
-!ifndef _TCL_H
-MSG =^
-Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
-!error $(MSG)
-!endif
-
-# Now do the same to locate Tk headers and libs if project requires Tk
-!if $(NEED_TK)
-
-!if "$(TKDIR)" != ""
-
-_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
-!endif
-
-!else # TKDIR not defined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-TKINSTALL = 1
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TKDIR = $(_INSTALLDIR)\..
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
-
-!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!if [echo _TKDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tk.h >> nmakehlp.out]
-!error *** Could not locate Tk source directory.
-!endif
-!include nmakehlp.out
-TKINSTALL = 0
-TKDIR = $(_TKDIR)
-_TK_H = $(_TKDIR)\generic\tk.h
-
-!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!endif # TKDIR
-
-!ifndef _TK_H
-MSG =^
-Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
-!error $(MSG)
-!endif
-
-!endif # NEED_TK
-
-!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tcl.^
-*** Please set the TCLDIR macro to point to the Tcl sources.
-!error $(MSG)
-!endif
-
-!if $(NEED_TK_SOURCE)
-!if $(TKINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tk.^
-*** Please set the TKDIR macro to point to the Tk sources.
-!error $(MSG)
-!endif
-!endif
-
-
-# If INSTALLDIR set to tcl installation root dir then reset to the
-# lib dir for installing extensions
-!if exist("$(_INSTALLDIR)\include\tcl.h")
-_INSTALLDIR=$(_INSTALLDIR)\lib
-!endif
-
-# END Case 2(c) or (d) - Building an extension
-!endif # if $(DOING_TCL)
-
-################################################################
-# 3. Determine compiler version and architecture
-# In this section, we figure out the compiler version and the
-# architecture for which we are building. This sets the
-# following macros:
-# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
-# This is also printed by the compiler in dotted form 19.10 etc.
-# VCVER - the "marketing version", for example Visual C++ 6 for internal
-# compiler version 1200. This is kept only for legacy reasons as it
-# does not make sense for recent Microsoft compilers. Only used for
-# output directory names.
-# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
-# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
-# MACHINE - same as $(ARCH) - legacy
-# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
-# CFG_ENCODING - set to an character encoding.
-# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
-# see where it is used
-
-cc32 = $(CC) # built-in default.
-link32 = link
-lib32 = lib
-rc32 = $(RC) # built-in default.
-
-#----------------------------------------------------------------
-# Figure out the compiler architecture and version by writing
-# the C macros to a file, preprocessing them with the C
-# preprocessor and reading back the created file
-
-_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] \
- && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
-!include vercl.i
-!if $(VCVERSION) < 1900
-!if ![echo VCVER= ^\> vercl.vc] \
- && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
-!include vercl.vc
-!endif
-!else
-# The simple calculation above does not apply to new Visual Studio releases
-# Keep the compiler version in its native form.
-VCVER = $(VCVERSION)
-!endif
-!endif
-
-!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
-!endif
-
-#----------------------------------------------------------------
-# The MACHINE macro is used by legacy makefiles so set it as well
-!ifdef MACHINE
-!if "$(MACHINE)" == "x86"
-!undef MACHINE
-MACHINE = IX86
-!elseif "$(MACHINE)" == "x64"
-!undef MACHINE
-MACHINE = AMD64
-!endif
-!if "$(MACHINE)" != "$(ARCH)"
-!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
-!endif
-!else
-MACHINE=$(ARCH)
-!endif
-
-#------------------------------------------------------------
-# Figure out the *host* architecture by reading the registry
-
-!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 CFG_ENCODING
-CFG_ENCODING = \"cp1252\"
-!endif
-
-################################################################
-# 4. Build the nmakehlp program
-# This is a helper app we need to overcome nmake's limiting
-# environment. We will call out to it to get various bits of
-# information about supported compiler options etc.
-#
-# Tcl itself will always use the nmakehlp.c program which is
-# in its own source. This is the "master" copy and kept updated.
-#
-# Extensions built against an installed Tcl will use the installed
-# copy of Tcl's nmakehlp.c if there is one and their own version
-# otherwise. In the latter case, they would also be using their own
-# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
-# or rules.vc.
-#
-# Extensions built against Tcl sources will use the one from the Tcl source.
-#
-# When building an extension using a sufficiently new version of Tcl,
-# rules-ext.vc will define NMAKEHLPC appropriately to point to the
-# copy of nmakehlp.c to be used.
-
-!ifndef NMAKEHLPC
-# Default to the one in the current directory (the extension's own nmakehlp.c)
-NMAKEHLPC = nmakehlp.c
-
-!if !$(DOING_TCL)
-!if $(TCLINSTALL)
-!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
-!endif
-!else # ! $(TCLINSTALL)
-!if exist("$(_TCLDIR)\win\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
-!endif
-!endif # $(TCLINSTALL)
-!endif # !$(DOING_TCL)
-
-!endif # NMAKEHLPC
-
-# We always build nmakehlp even if it exists since we do not know
-# what source it was built from.
-!message *** Using $(NMAKEHLPC)
-!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
-!endif
-
-################################################################
-# 5. Test for compiler features
-# Visual C++ compiler options have changed over the years. Check
-# which options are supported by the compiler in use.
-#
-# The following macros are set:
-# OPTIMIZATIONS - the compiler flags to be used for optimized builds
-# DEBUGFLAGS - the compiler flags to be used for debug builds
-# LINKERFLAGS - Flags passed to the linker
-#
-# Note that these are the compiler settings *available*, not those
-# that will be *used*. The latter depends on the OPTS macro settings
-# which we have not yet parsed.
-#
-# Also note that some of the flags in OPTIMIZATIONS are not really
-# related to optimization. They are placed there only for legacy reasons
-# as some extensions expect them to be included in that macro.
-
-# -Op improves float consistency. Note only needed for older compilers
-# Newer compilers do not need or support this option.
-!if [nmakehlp -c -Op]
-FPOPTS = -Op
-!endif
-
-# Strict floating point semantics - present in newer compilers in lieu of -Op
-!if [nmakehlp -c -fp:strict]
-FPOPTS = $(FPOPTS) -fp:strict
-!endif
-
-!if "$(MACHINE)" == "IX86"
-### test for pentium errata
-!if [nmakehlp -c -QI0f]
-!message *** Compiler has 'Pentium 0x0f fix'
-FPOPTS = $(FPOPTS) -QI0f
-!else
-!message *** Compiler does not have 'Pentium 0x0f fix'
-!endif
-!endif
-
-### test for optimizations
-# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
-# documentation. Note we do NOT want /Gs as that inserts a _chkstk
-# stack probe at *every* function entry, not just those with more than
-# a page of stack allocation resulting in a performance hit. However,
-# /O2 documentation is misleading as its stack probes are simply the
-# default page size locals allocation probes and not what is implied
-# by an explicit /Gs option.
-
-OPTIMIZATIONS = $(FPOPTS)
-
-!if [nmakehlp -c -O2]
-!message *** Compiler has 'Optimizations'
-OPTIMIZING = 1
-OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
-!else
-# Legacy, really. All modern compilers support this
-!message *** Compiler does not have 'Optimizations'
-OPTIMIZING = 0
-!endif
-
-# Checks for buffer overflows in local arrays
-!if [nmakehlp -c -GS]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
-!endif
-
-# Link time optimization. Note that this option (potentially) makes
-# generated libraries only usable by the specific VC++ version that
-# created it. Requires /LTCG linker option
-!if [nmakehlp -c -GL]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
-CC_GL_OPT_ENABLED = 1
-!else
-# In newer compilers -GL and -YX are incompatible.
-!if [nmakehlp -c -YX]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
-!endif
-!endif # [nmakehlp -c -GL]
-
-DEBUGFLAGS = $(FPOPTS)
-
-# Run time error checks. Not available or valid in a release, non-debug build
-# RTC is for modern compilers, -GZ is legacy
-!if [nmakehlp -c -RTC1]
-DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
-!elseif [nmakehlp -c -GZ]
-DEBUGFLAGS = $(DEBUGFLAGS) -GZ
-!endif
-
-#----------------------------------------------------------------
-# Linker flags
-
-# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
-# if the linker supports a specific option. Without these flags link will
-# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
-# They are not passed through to the actual application / extension
-# link rules.
-!ifndef LINKER_TESTFLAGS
-LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
-!endif
-
-LINKERFLAGS =
-
-# If compiler has enabled link time optimization, linker must too with -ltcg
-!ifdef CC_GL_OPT_ENABLED
-!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -ltcg
-!endif
-!endif
-
-########################################################################
-# 6. Parse the OPTS macro to work out the requested build configuration.
-# Based on this, we will construct the actual switches to be passed to the
-# compiler and linker using the macros defined in the previous section.
-# The following macros are defined by this section based on OPTS
-# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
-# 1 -> build as a static library and shell
-# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
-# DEBUG - 1 -> debug build, 0 -> release builds
-# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
-# PROFILE - 1 -> generate profiling info, 0 -> no profiling
-# PGO - 1 -> profile based optimization, 0 -> no
-# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
-# 0 -> link to static C runtime for static Tcl build.
-# Does not impact shared Tcl builds (STATIC_BUILD == 0)
-# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
-# in the Tcl shell. 0 -> keep them as shared libraries
-# Does not impact shared Tcl builds.
-# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
-# 0 -> Use the non-thread allocator.
-# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
-# C runtime, 0 -> use the debug C runtime.
-# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
-# CONFIG_CHECK - 1 -> check current build configuration against Tcl
-# configuration (ignored for Tcl itself)
-# Further, LINKERFLAGS are modified based on above.
-
-# Default values for all the above
-STATIC_BUILD = 0
-TCL_THREADS = 1
-DEBUG = 0
-SYMBOLS = 0
-PROFILE = 0
-PGO = 0
-MSVCRT = 1
-TCL_USE_STATIC_PACKAGES = 0
-USE_THREAD_ALLOC = 1
-UNCHECKED = 0
-CONFIG_CHECK = 1
-!if $(DOING_TCL)
-USE_STUBS = 0
-!else
-USE_STUBS = 1
-!endif
-
-# If OPTS is not empty AND does not contain "none" which turns off all OPTS
-# set the above macros based on OPTS content
-!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
-
-# OPTS are specified, parse them
-
-!if [nmakehlp -f $(OPTS) "static"]
-!message *** Doing static
-STATIC_BUILD = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "nostubs"]
-!message *** Not using stubs
-USE_STUBS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nomsvcrt"]
-!message *** Doing nomsvcrt
-MSVCRT = 0
-!else
-!if [nmakehlp -f $(OPTS) "msvcrt"]
-!message *** Doing msvcrt
-MSVCRT = 1
-!else
-!if !$(STATIC_BUILD)
-MSVCRT = 1
-!else
-MSVCRT = 0
-!endif
-!endif
-!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
-
-!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 *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
-!endif
-
-# TBD - should get rid of this option
-!if [nmakehlp -f $(OPTS) "thrdalloc"]
-!message *** Doing thrdalloc
-USE_THREAD_ALLOC = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "tclalloc"]
-USE_THREAD_ALLOC = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "unchecked"]
-!message *** Doing unchecked
-UNCHECKED = 1
-!else
-UNCHECKED = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "noconfigcheck"]
-CONFIG_CHECK = 1
-!else
-CONFIG_CHECK = 0
-!endif
-
-!endif # "$(OPTS)" != "" && ... parsing of OPTS
-
-# Set linker flags based on above
-
-!if $(PGO) > 1
-!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
-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 $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!endif
-
-################################################################
-# 7. Parse the STATS macro to configure code instrumentation
-# The following macros are set by this section:
-# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
-# 0 -> disables
-# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
-# 0 -> disables
-
-# Default both are off
-TCL_MEM_DEBUG = 0
-TCL_COMPILE_DEBUG = 0
-
-!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
-
-!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
-
-####################################################################
-# 8. Parse the CHECKS macro to configure additional compiler checks
-# The following macros are set by this section:
-# WARNINGS - compiler switches that control the warnings level
-# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
-# 0 -> enable deprecated functions
-
-# Defaults - Permit deprecated functions and warning level 3
-TCL_NO_DEPRECATED = 0
-WARNINGS = -W3
-
-!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
-
-!if [nmakehlp -f $(CHECKS) "nodep"]
-!message *** Doing nodep check
-TCL_NO_DEPRECATED = 1
-!endif
-
-!if [nmakehlp -f $(CHECKS) "fullwarn"]
-!message *** Doing full warnings check
-WARNINGS = -W4
-!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -warn:3
-!endif
-!endif
-
-!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
-!message *** Doing 64bit portability warnings
-WARNINGS = $(WARNINGS) -Wp64
-!endif
-
-!endif
-
-################################################################
-# 9. Extract various version numbers
-# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
-# respectively. For extensions, versions are extracted from the
-# configure.in or configure.ac from the TEA configuration if it
-# exists, and unset otherwise.
-# Sets the following macros:
-# TCL_MAJOR_VERSION
-# TCL_MINOR_VERSION
-# TCL_PATCH_LEVEL
-# TCL_VERSION
-# TK_MAJOR_VERSION
-# TK_MINOR_VERSION
-# TK_PATCH_LEVEL
-# TK_VERSION
-# DOTVERSION - set as (for example) 2.5
-# VERSION - set as (for example 25)
-#--------------------------------------------------------------
-
-!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 defined(_TK_H)
-!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
-!endif # _TK_H
-
-!include versions.vc
-
-TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
-TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!if defined(_TK_H)
-TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
-TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-
-# Set DOTVERSION and VERSION
-!if $(DOING_TCL)
-
-DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-VERSION = $(TCL_VERSION)
-
-!elseif $(DOING_TK)
-
-DOTVERSION = $(TK_DOTVERSION)
-VERSION = $(TK_VERSION)
-
-!else # Doing a non-Tk extension
-
-# If parent makefile has not defined DOTVERSION, try to get it from TEA
-# first from a configure.in file, and then from configure.ac
-!ifndef DOTVERSION
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
-!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
-!endif
-!endif
-!include versions.vc
-!endif # DOTVERSION
-VERSION = $(DOTVERSION:.=)
-
-!endif # $(DOING_TCL) ... etc.
-
-################################################################
-# 10. Construct output directory and file paths
-# Figure-out how to name our intermediate and output directories.
-# In order to avoid inadvertent mixing of object files built using
-# different compilers, build configurations etc.,
-#
-# Naming convention (suffixes):
-# 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.
-#
-# The following macros are set in this section:
-# SUFX - the suffix to use for binaries based on above naming convention
-# BUILDDIRTOP - the toplevel default output directory
-# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
-# TMP_DIR - directory where object files are created
-# OUT_DIR - directory where output executables are created
-# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
-# parent makefile (or command line). The default values are
-# based on BUILDDIRTOP.
-# STUBPREFIX - name of the stubs library for this project
-# PRJIMPLIB - output path of the generated project import library
-# PRJLIBNAME - name of generated project library
-# PRJLIB - output path of generated project library
-# PRJSTUBLIBNAME - name of the generated project stubs library
-# PRJSTUBLIB - output path of the generated project stubs library
-# RESFILE - output resource file (only if not static build)
-
-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
-
-# Relative paths -> absolute
-!if [echo OUT_DIR = \> nmakehlp.out] \
- || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
-!endif
-!if [echo TMP_DIR = \>> nmakehlp.out] \
- || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
-!endif
-!include nmakehlp.out
-
-# The name of the stubs library for the project being built
-STUBPREFIX = $(PROJECT)stub
-
-# Set up paths to various Tcl executables and libraries needed by extensions
-!if $(DOING_TCL)
-
-TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
-TCLSH = $(OUT_DIR)\$(TCLSHNAME)
-TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
-
-TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist("$(TCLSH)") && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\lib
-TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
-TCL_INCLUDES = -I"$(_TCLDIR)\include"
-
-!else # Building against Tcl sources
-
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\library
-TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = $(_TCLDIR)\tools
-TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
-
-!endif # TCLINSTALL
-
-tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
-
-!endif # $(DOING_TCL)
-
-# We need a tclsh that will run on the host machine as part of the build.
-# IX86 runs on all architectures.
-!ifndef TCLSH_NATIVE
-!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
-TCLSH_NATIVE = $(TCLSH)
-!else
-!error You must explicitly set TCLSH_NATIVE for cross-compilation
-!endif
-!endif
-
-# Do the same for Tk and Tk extensions that require the Tk libraries
-!if $(DOING_TK) || $(NEED_TK)
-WISHNAMEPREFIX = wish
-WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
-TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
-TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
-TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
-
-!if $(DOING_TK)
-WISH = $(OUT_DIR)\$(WISHNAME)
-TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
-TKLIB = $(OUT_DIR)\$(TKLIBNAME)
-TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # effectively NEED_TK
-
-!if $(TKINSTALL) # Building against installed Tk
-WISH = $(_TKDIR)\bin\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\include"
-!else # Building against Tk sources
-WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
-!endif # TKINSTALL
-tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
-
-!endif # $(DOING_TK)
-!endif # $(DOING_TK) || $(NEED_TK)
-
-# Various output paths
-PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
-
-PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
-
-# If extension parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
-!ifdef RCFILE
-RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
-!else
-RESFILE = $(TMP_DIR)\$(PROJECT).res
-!endif
-!endif
-
-###################################################################
-# 11. Construct the paths for the installation directories
-# The following macros get defined in this section:
-# LIB_INSTALL_DIR - where libraries should be installed
-# BIN_INSTALL_DIR - where the executables should be installed
-# DOC_INSTALL_DIR - where documentation should be installed
-# SCRIPT_INSTALL_DIR - where scripts should be installed
-# INCLUDE_INSTALL_DIR - where C include files should be installed
-# DEMO_INSTALL_DIR - where demos should be installed
-# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
-
-!if $(DOING_TCL) || $(DOING_TK)
-LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
-BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
-DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
-!if $(DOING_TCL)
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!else # DOING_TK
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
-
-!else # extension other than Tk
-
-PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
-LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
-
-!endif
-
-###################################################################
-# 12. Set up actual options to be passed to the compiler and linker
-# Now we have all the information we need, set up the actual flags and
-# options that we will pass to the compiler and linker. The main
-# makefile should use these in combination with whatever other flags
-# and switches are specific to it.
-# The following macros are defined, names are for historical compatibility:
-# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
-# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
-# crt - Compiler switch that selects the appropriate C runtime
-# cdebug - Compiler switches related to debug AND optimizations
-# cwarn - Compiler switches that set warning levels
-# cflags - complete compiler switches (subsumes cdebug and cwarn)
-# ldebug - Linker switches controlling debug information and optimization
-# lflags - complete linker switches (subsumes ldebug) except subsystem type
-# dlllflags - complete linker switches to build DLLs (subsumes lflags)
-# conlflags - complete linker switches for console program (subsumes lflags)
-# guilflags - complete linker switches for GUI program (subsumes lflags)
-# baselibs - minimum Windows libraries required. Parent makefile can
-# define PRJ_LIBS before including rules.rc if additional libs are needed
-
-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 $(USE_STUBS)
-# Note we do not define USE_TCL_STUBS even when building tk since some
-# test targets in tk do not use stubs
-!if ! $(DOING_TCL)
-USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
-!if $(NEED_TK)
-USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
-!endif
-!endif
-!endif # USE_STUBS
-
-!if !$(DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DNDEBUG
-!if $(OPTIMIZING)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
-!endif
-!endif
-!if $(PROFILE)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
-!endif
-!if "$(MACHINE)" == "AMD64"
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
-!endif
-!if $(VCVERSION) < 1300
-OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
-!endif
-
-# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
-COMPILERFLAGS = /D_ATL_XP_TARGETING
-
-# Following is primarily for the benefit of extensions. Tcl 8.5 builds
-# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
-# an extension, it is advisable (but not mandated) to use the same Windows
-# API as the Tcl build. This is accordingly defaulted below. A particular
-# extension can override this by pre-definining USE_WIDECHAR_API.
-!ifndef USE_WIDECHAR_API
-!if $(TCL_VERSION) > 85
-USE_WIDECHAR_API = 1
-!else
-USE_WIDECHAR_API = 0
-!endif
-!endif
-
-!if $(USE_WIDECHAR_API)
-COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
-!endif
-
-# Like the TEA system only set this non empty for non-Tk extensions
-# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
-# so we pass both
-!if !$(DOING_TCL) && !$(DOING_TK)
-PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
- -DMODULE_SCOPE=extern
-!endif
-
-# crt picks the C run time based on selected OPTS
-!if $(MSVCRT)
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MDd
-!else
-crt = -MD
-!endif
-!else
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MTd
-!else
-crt = -MT
-!endif
-!endif
-
-# cdebug includes compiler options for debugging as well as optimization.
-!if $(DEBUG)
-
-# In debugging mode, optimizations need to be disabled
-cdebug = -Zi -Od $(DEBUGFLAGS)
-
-!else
-
-cdebug = $(OPTIMIZATIONS)
-!if $(SYMBOLS)
-cdebug = $(cdebug) -Zi
-!endif
-
-!endif # $(DEBUG)
-
-# cwarn includes default warning levels.
-cwarn = $(WARNINGS)
-
-!if "$(MACHINE)" == "AMD64"
-# Disable pointer<->int warnings related to cast between different sizes
-# There are a gadzillion of these due to use of ClientData and
-# clutter up compiler
-# output increasing chance of a real warning getting lost. So disable them.
-# Eventually some day, Tcl will be 64-bit clean.
-cwarn = $(cwarn) -wd4311 -wd4312
-!endif
-
-### Common compiler options that are architecture specific
-!if "$(MACHINE)" == "ARM"
-carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
-!else
-carch =
-!endif
-
-!if $(DEBUG)
-# Turn warnings into errors
-cwarn = $(cwarn) -WX
-!endif
-
-INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
-!if !$(DOING_TCL) && !$(DOING_TK)
-INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
-!endif
-
-# These flags are defined roughly in the order of the pre-reform
-# rules.vc/makefile.vc to help visually compare that the pre- and
-# post-reform build logs
-
-# cflags contains generic flags used for building practically all object files
-cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
-
-# appcflags contains $(cflags) and flags for building the application
-# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
-# flags used for building shared object files The two differ in the
-# BUILD_$(PROJECT) macro which should be defined only for the shared
-# library *implementation* and not for its caller interface
-
-appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
-appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
-pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-
-# stubscflags contains $(cflags) plus flags used for building a stubs
-# library for the package. Note: -DSTATIC_BUILD is defined in
-# $(OPTDEFINES) only if the OPTS configuration indicates a static
-# library. However the stubs library is ALWAYS static hence included
-# here irrespective of the OPTS setting.
-#
-# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
-# without stating why. Tcl itself compiled stubs libs with this flag.
-# so we do not remove it from cflags. -GL may prevent extensions
-# compiled with one VC version to fail to link against stubs library
-# compiled with another VC version. Check for this and fix accordingly.
-stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
-
-# 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
-
-# Note: Profiling is currently only possible with the Visual Studio Enterprise
-!if $(PROFILE)
-ldebug= $(ldebug) -profile
-!endif
-
-### Declarations common to all linker versions
-lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-lflags = $(lflags) -nodefaultlib:libucrt.lib
-!endif
-
-# Old linkers (Visual C++ 6 in particular) will link for fast loading
-# on Win98. Since we do not support Win98 any more, we specify nowin98
-# as recommended for NT and later. However, this is only required by
-# IX86 on older compilers and only needed if we are not doing a static build.
-
-!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
-!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
-# Align sections for PE size savings.
-lflags = $(lflags) -opt:nowin98
-!endif
-!endif
-
-dlllflags = $(lflags) -dll
-conlflags = $(lflags) -subsystem:console
-guilflags = $(lflags) -subsystem:windows
-
-# Libraries that are required for every image.
-# Extensions should define any additional libraries with $(PRJ_LIBS)
-winlibs = kernel32.lib advapi32.lib
-
-!if $(NEED_TK)
-winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
-!endif
-
-# Avoid 'unresolved external symbol __security_cookie' errors.
-# c.f. http://support.microsoft.com/?id=894573
-!if "$(MACHINE)" == "AMD64"
-!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
-winlibs = $(winlibs) bufferoverflowU.lib
-!endif
-!endif
-
-baselibs = $(winlibs) $(PRJ_LIBS)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-baselibs = $(baselibs) ucrt.lib
-!endif
-
-################################################################
-# 13. Define standard commands, common make targets and implicit rules
-
-CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
-CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
-CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
-
-LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
-DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-
-CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
- $(TCL_INCLUDES) \
- -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
- -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
- -DDOTVERSION=\"$(DOTVERSION)\" \
- -DVERSION=\"$(VERSION)\" \
- -DSUFX=\"$(SUFX)\" \
- -DPROJECT=\"$(PROJECT)\" \
- -DPRJLIBNAME=\"$(PRJLIBNAME)\"
-
-!ifndef DEFAULT_BUILD_TARGET
-DEFAULT_BUILD_TARGET = $(PROJECT)
-!endif
-
-default-target: $(DEFAULT_BUILD_TARGET)
-
-default-pkgindex:
- @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
- [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
-
-default-pkgindex-tea:
- @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
-@PACKAGE_VERSION@ $(DOTVERSION)
-@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
-@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-
-default-install: default-install-binaries default-install-libraries
-
-default-install-binaries: $(PRJLIB)
- @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
- @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
- @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
- @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
- @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
-
-default-install-stubs:
- @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-docs-html:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-docs-n:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-demos:
- @echo Installing demos to '$(DEMO_INSTALL_DIR)'
- @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
- @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
-
-default-clean:
- @echo Cleaning $(TMP_DIR)\* ...
- @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
- @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
- @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
- @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
- @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
- @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
- @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
- @echo Cleaning $(WINDIR)\_junk.pch ...
- @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
- @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
- @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
- @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
- @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
- @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
- @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
-
-default-hose: default-clean
- @echo Hosing $(OUT_DIR)\* ...
- @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
-
-# Only for backward compatibility
-default-distclean: default-hose
-
-default-setup:
- @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
- @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
-
-!if "$(TESTPAT)" != ""
-TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
-!endif
-
-default-test: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
-
-default-shell: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- $(DEBUGGER) $(TCLSH)
-
-# Generation of Windows version resource
-!ifdef RCFILE
-
-# Note: don't use $** in below rule because there may be other dependencies
-# and only the "master" rc must be passed to the resource compiler
-$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
- $(RESCMD) $(RCDIR)\$(PROJECT).rc
-
-!else
-
-# If parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
-
-$(TMP_DIR)\$(PROJECT).rc:
- @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
-#include <winver.h>
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION COMMAVERSION
- PRODUCTVERSION COMMAVERSION
- FILEFLAGSMASK 0x3fL
-#ifdef DEBUG
- FILEFLAGS VS_FF_DEBUG
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "FileDescription", "Tcl extension " PROJECT
- VALUE "OriginalFilename", PRJLIBNAME
- VALUE "FileVersion", DOTVERSION
- VALUE "ProductName", "Package " PROJECT " for Tcl"
- VALUE "ProductVersion", DOTVERSION
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-<<
-
-!endif # ifdef RCFILE
-
-!ifndef DISABLE_IMPLICIT_RULES
-DISABLE_IMPLICIT_RULES = 0
-!endif
-
-!if !$(DISABLE_IMPLICIT_RULES)
-# Implicit rule definitions - only for building library objects. For stubs and
-# main application, the master makefile should define explicit rules.
-
-{$(ROOT)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(WINDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(RCDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(WINDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-.SUFFIXES:
-.SUFFIXES:.c .rc
-
-!endif
-
-################################################################
-# 14. Sanity check selected options against Tcl build options
-# When building an extension, certain configuration options should
-# match the ones used when Tcl was built. Here we check and
-# warn on a mismatch.
-!if ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
-TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
-!endif
-!else # ! $(TCLINSTALL) - building against Tcl source
-!if exist("$(OUT_DIR)\tcl.nmake")
-TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
-!endif
-!endif # TCLINSTALL
-
-!if $(CONFIG_CHECK)
-!ifdef TCLNMAKECONFIG
-!include $(TCLNMAKECONFIG)
-
-!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
-!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
-!endif
-!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
-!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
-!endif
-!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
-!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
-!endif
-!endif
-
-!endif # TCLNMAKECONFIG
-
-!endif # ! $(DOING_TCL)
-
-
-#----------------------------------------------------------
-# Display stats being used.
-#----------------------------------------------------------
-
-!if !$(DOING_TCL)
-!message *** Building against Tcl at '$(_TCLDIR)'
-!endif
-!if !$(DOING_TK) && $(NEED_TK)
-!message *** Building against Tk at '$(_TKDIR)'
-!endif
-!message *** Intermediate directory will be '$(TMP_DIR)'
-!message *** Output directory will be '$(OUT_DIR)'
-!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
-!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
-
-!endif # ifdef _RULES_VC
diff --git a/tk8.6/win/stubs.c b/tk8.6/win/stubs.c deleted file mode 100644 index 1cf23ef..0000000 --- a/tk8.6/win/stubs.c +++ /dev/null @@ -1,474 +0,0 @@ -#include "tk.h" - -/* - * Undocumented Xlib internal function - */ - -int -_XInitImageFuncPtrs( - XImage *image) -{ - return Success; -} - -/* - * From Xutil.h - */ - -void -XSetWMClientMachine( - Display *display, - Window w, - XTextProperty *text_prop) -{ -} - -Status -XStringListToTextProperty( - char **list, - int count, - XTextProperty *text_prop_return) -{ - return (Status) 0; -} - -/* - * From Xlib.h - */ - -int -XChangeProperty( - Display *display, - Window w, - Atom property, - Atom type, - int format, - int mode, - _Xconst unsigned char *data, - int nelements) -{ - return Success; -} - -Cursor -XCreateGlyphCursor( - Display *display, - Font source_font, - Font mask_font, - unsigned int source_char, - unsigned int mask_char, - XColor _Xconst *foreground_color, - XColor _Xconst *background_color) -{ - return 1; -} - -XIC -XCreateIC(XIM xim, ...) -{ - return NULL; -} - -Cursor -XCreatePixmapCursor( - Display *display, - Pixmap source, - Pixmap mask, - XColor *foreground_color, - XColor *background_color, - unsigned int x, - unsigned int y) -{ - return (Cursor) NULL; -} - -int -XDeleteProperty( - Display *display, - Window w, - Atom property) -{ - return Success; -} - -void -XDestroyIC( - XIC ic) -{ -} - -Bool -XFilterEvent( - XEvent *event, - Window window) -{ - return 0; -} - -int -XForceScreenSaver( - Display *display, - int mode) -{ - return Success; -} - -int -XFreeCursor( - Display *display, - Cursor cursor) -{ - return Success; -} - -GContext -XGContextFromGC( - GC gc) -{ - return (GContext) NULL; -} - -char * -XGetAtomName( - Display *display, - Atom atom) -{ - return NULL; -} - -int -XGetWindowAttributes( - Display *display, - Window w, - XWindowAttributes *window_attributes_return) -{ - return Success; -} - -Status -XGetWMColormapWindows( - Display *display, - Window w, - Window **windows_return, - int *count_return) -{ - return (Status) 0; -} - -int -XIconifyWindow( - Display *display, - Window w, - int screen_number) -{ - return Success; -} - -XHostAddress * -XListHosts( - Display *display, - int *nhosts_return, - Bool *state_return) -{ - return NULL; -} - -int -XLookupColor( - Display *display, - Colormap colormap, - _Xconst char *color_name, - XColor *exact_def_return, - XColor *screen_def_return) -{ - return Success; -} - -int -XNextEvent( - Display *display, - XEvent *event_return) -{ - return Success; -} - -int -XPutBackEvent( - Display *display, - XEvent *event) -{ - return Success; -} - -int -XQueryColors( - Display *display, - Colormap colormap, - XColor *defs_in_out, - int ncolors) -{ - return Success; -} - -int -XQueryTree( - Display *display, - Window w, - Window *root_return, - Window *parent_return, - Window **children_return, - unsigned int *nchildren_return) -{ - return Success; -} - -int -XRefreshKeyboardMapping( - XMappingEvent *event_map) -{ - return Success; -} - -Window -XRootWindow( - Display *display, - int screen_number) -{ - return (Window) NULL; -} - -int -XSelectInput( - Display *display, - Window w, - long event_mask) -{ - return Success; -} - -int -XSendEvent( - Display *display, - Window w, - Bool propagate, - long event_mask, - XEvent *event_send) -{ - return Success; -} - -int -XSetCommand( - Display *display, - Window w, - char **argv, - int argc) -{ - return Success; -} - -XErrorHandler -XSetErrorHandler( - XErrorHandler handler) -{ - return NULL; -} - -int -XSetIconName( - Display *display, - Window w, - _Xconst char *icon_name) -{ - return Success; -} - -int -XSetWindowBackground( - Display *display, - Window w, - unsigned long background_pixel) -{ - return Success; -} - -int -XSetWindowBackgroundPixmap( - Display *display, - Window w, - Pixmap background_pixmap) -{ - return Success; -} - -int -XSetWindowBorder( - Display *display, - Window w, - unsigned long border_pixel) -{ - return Success; -} - -int -XSetWindowBorderPixmap( - Display *display, - Window w, - Pixmap border_pixmap) -{ - return Success; -} - -int -XSetWindowBorderWidth( - Display *display, - Window w, - unsigned int width) -{ - return Success; -} - -int -XSetWindowColormap( - Display *display, - Window w, - Colormap colormap) -{ - return Success; -} - -Bool -XTranslateCoordinates( - Display *display, - Window src_w, - Window dest_w, - int src_x, - int src_y, - int *dest_x_return, - int *dest_y_return, - Window *child_return) -{ - return 0; -} - -int -XWindowEvent( - Display *display, - Window w, - long event_mask, - XEvent *event_return) -{ - return Success; -} - -int -XWithdrawWindow( - Display *display, - Window w, - int screen_number) -{ - return Success; -} - -int -XmbLookupString( - XIC ic, - XKeyPressedEvent *event, - char *buffer_return, - int bytes_buffer, - KeySym *keysym_return, - Status *status_return) -{ - return Success; -} - -int -XGetWindowProperty( - Display *display, - Window w, - Atom property, - long long_offset, - long long_length, - Bool delete, - Atom req_type, - Atom *actual_type_return, - int *actual_format_return, - unsigned long *nitems_return, - unsigned long *bytes_after_return, - unsigned char **prop_return) -{ - *actual_type_return = None; - *actual_format_return = 0; - *nitems_return = 0; - *bytes_after_return = 0; - *prop_return = NULL; - return BadValue; -} - -/* - * The following functions were implemented as macros under Windows. - */ - -int -XFlush( - Display *display) -{ - return 0; -} - -int -XGrabServer( - Display *display) -{ - return 0; -} - -int -XUngrabServer( - Display *display) -{ - return 0; -} - -int -XFree( - void *data) -{ - if ((data) != NULL) { - ckfree(data); - } - return 0; -} - -int -XNoOp( - Display *display) -{ - display->request++; - return 0; -} - -XAfterFunction -XSynchronize( - Display *display, - Bool bool) -{ - display->request++; - return NULL; -} - -int -XSync( - Display *display, - Bool bool) -{ - display->request++; - return 0; -} - -VisualID -XVisualIDFromVisual( - Visual *visual) -{ - return visual->visualid; -} diff --git a/tk8.6/win/targets.vc b/tk8.6/win/targets.vc deleted file mode 100644 index 312022d..0000000 --- a/tk8.6/win/targets.vc +++ /dev/null @@ -1,98 +0,0 @@ -#------------------------------------------------------------- -*- makefile -*- -# targets.vc -- -# -# Part of the nmake based build system for Tcl and its extensions. -# This file defines some standard targets for the convenience of extensions -# and can be optionally included by the extension makefile. -# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs. - -$(PROJECT): setup pkgindex $(PRJLIB) - -!ifdef PRJ_STUBOBJS -$(PROJECT): $(PRJSTUBLIB) -$(PRJSTUBLIB): $(PRJ_STUBOBJS) - $(LIBCMD) $** - -$(PRJ_STUBOBJS): - $(CCSTUBSCMD) %s -!endif # PRJ_STUBOBJS - -!ifdef PRJ_MANIFEST -$(PROJECT): $(PRJLIB).manifest -$(PRJLIB).manifest: $(PRJ_MANIFEST) - @nmakehlp -s << $** >$@ -@MACHINE@ $(MACHINE:IX86=X86) -<< -!endif - -!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk" -$(PRJLIB): $(PRJ_OBJS) $(RESFILE) -!if $(STATIC_BUILD) - $(LIBCMD) $** -!else - $(DLLCMD) $** - $(_VC_MANIFEST_EMBED_DLL) -!endif - -@del $*.exp -!endif - -!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != "" -$(PRJ_OBJS): $(PRJ_HEADERS) -!endif - -# If parent makefile has defined stub objects, add their installation -# to the default install -!if "$(PRJ_STUBOBJS)" != "" -default-install: default-install-stubs -!endif - -# Unlike the other default targets, these cannot be in rules.vc because -# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC -# that the parent makefile will not define until after including rules-ext.vc -!if "$(PRJ_HEADERS_PUBLIC)" != "" -default-install: default-install-headers -default-install-headers: - @echo Installing headers to '$(INCLUDE_INSTALL_DIR)' - @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)" -!endif - -!if "$(DISABLE_STANDARD_TARGETS)" == "" -DISABLE_STANDARD_TARGETS = 0 -!endif - -!if "$(DISABLE_TARGET_setup)" == "" -DISABLE_TARGET_setup = 0 -!endif -!if "$(DISABLE_TARGET_install)" == "" -DISABLE_TARGET_install = 0 -!endif -!if "$(DISABLE_TARGET_clean)" == "" -DISABLE_TARGET_clean = 0 -!endif -!if "$(DISABLE_TARGET_test)" == "" -DISABLE_TARGET_test = 0 -!endif -!if "$(DISABLE_TARGET_shell)" == "" -DISABLE_TARGET_shell = 0 -!endif - -!if !$(DISABLE_STANDARD_TARGETS) -!if !$(DISABLE_TARGET_setup) -setup: default-setup -!endif -!if !$(DISABLE_TARGET_install) -install: default-install -!endif -!if !$(DISABLE_TARGET_clean) -clean: default-clean -realclean: hose -hose: default-hose -distclean: realclean default-distclean -!endif -!if !$(DISABLE_TARGET_test) -test: default-test -!endif -!if !$(DISABLE_TARGET_shell) -shell: default-shell -!endif -!endif # DISABLE_STANDARD_TARGETS diff --git a/tk8.6/win/tcl.m4 b/tk8.6/win/tcl.m4 deleted file mode 100644 index 84f0dff..0000000 --- a/tk8.6/win/tcl.m4 +++ /dev/null @@ -1,1299 +0,0 @@ -#------------------------------------------------------------------------ -# SC_PATH_TCLCONFIG -- -# -# Locate the tclConfig.sh file and perform a sanity check on -# the Tcl compile flags -# -# Arguments: -# none -# -# Results: -# -# Adds the following arguments to configure: -# --with-tcl=... -# -# Defines the following vars: -# TCL_BIN_DIR Full path to the directory containing -# the tclConfig.sh file -#------------------------------------------------------------------------ - -AC_DEFUN([SC_PATH_TCLCONFIG], [ - # - # Ok, lets find the tcl configuration - # First, look for one uninstalled. - # the alternative search directory is invoked by --with-tcl - # - - if test x"${no_tcl}" = x ; then - # we reset no_tcl in case something fails here - no_tcl=true - AC_ARG_WITH(tcl, - AC_HELP_STRING([--with-tcl], - [directory containing tcl configuration (tclConfig.sh)]), - with_tclconfig="${withval}") - AC_MSG_CHECKING([for Tcl configuration]) - AC_CACHE_VAL(ac_cv_c_tclconfig,[ - - # First check to see if --with-tcl was specified. - if test x"${with_tclconfig}" != x ; then - case "${with_tclconfig}" in - */tclConfig.sh ) - if test -f "${with_tclconfig}"; then - AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself]) - with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" - fi ;; - esac - if test -f "${with_tclconfig}/tclConfig.sh" ; then - ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" - else - AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) - fi - fi - - # then check for a private Tcl installation - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ../tcl \ - `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ - ../../tcl \ - `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ - ../../../tcl \ - `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do - if test -f "$i/win/tclConfig.sh" ; then - ac_cv_c_tclconfig="`(cd $i/win; pwd)`" - break - fi - done - fi - - # check in a few common install locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in `ls -d ${libdir} 2>/dev/null` \ - `ls -d ${exec_prefix}/lib 2>/dev/null` \ - `ls -d ${prefix}/lib 2>/dev/null` \ - `ls -d /cygdrive/c/Tcl/lib 2>/dev/null` \ - `ls -d /cygdrive/c/Progra~1/Tcl/lib 2>/dev/null` \ - `ls -d /c/Tcl/lib 2>/dev/null` \ - `ls -d /c/Progra~1/Tcl/lib 2>/dev/null` \ - `ls -d C:/Tcl/lib 2>/dev/null` \ - `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ - ; do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig="`(cd $i; pwd)`" - break - fi - done - fi - - # check in a few other private locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ${srcdir}/../tcl \ - `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do - if test -f "$i/win/tclConfig.sh" ; then - ac_cv_c_tclconfig="`(cd $i/win; pwd)`" - break - fi - done - fi - ]) - - if test x"${ac_cv_c_tclconfig}" = x ; then - TCL_BIN_DIR="# no Tcl configs found" - AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh]) - else - no_tcl= - TCL_BIN_DIR="${ac_cv_c_tclconfig}" - AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh]) - fi - fi -]) - -#------------------------------------------------------------------------ -# SC_PATH_TKCONFIG -- -# -# Locate the tkConfig.sh file -# -# Arguments: -# none -# -# Results: -# -# Adds the following arguments to configure: -# --with-tk=... -# -# Defines the following vars: -# TK_BIN_DIR Full path to the directory containing -# the tkConfig.sh file -#------------------------------------------------------------------------ - -AC_DEFUN([SC_PATH_TKCONFIG], [ - # - # Ok, lets find the tk configuration - # First, look for one uninstalled. - # the alternative search directory is invoked by --with-tk - # - - if test x"${no_tk}" = x ; then - # we reset no_tk in case something fails here - no_tk=true - AC_ARG_WITH(tk, - AC_HELP_STRING([--with-tk], - [directory containing tk configuration (tkConfig.sh)]), - with_tkconfig="${withval}") - AC_MSG_CHECKING([for Tk configuration]) - AC_CACHE_VAL(ac_cv_c_tkconfig,[ - - # First check to see if --with-tkconfig was specified. - if test x"${with_tkconfig}" != x ; then - case "${with_tkconfig}" in - */tkConfig.sh ) - if test -f "${with_tkconfig}"; then - AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself]) - with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`" - fi ;; - esac - if test -f "${with_tkconfig}/tkConfig.sh" ; then - ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`" - else - AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) - fi - fi - - # then check for a private Tk library - if test x"${ac_cv_c_tkconfig}" = x ; then - for i in \ - ../tk \ - `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \ - ../../tk \ - `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \ - ../../../tk \ - `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do - if test -f "$i/win/tkConfig.sh" ; then - ac_cv_c_tkconfig="`(cd $i/win; pwd)`" - break - fi - done - fi - - # check in a few common install locations - if test x"${ac_cv_c_tkconfig}" = x ; then - for i in `ls -d ${libdir} 2>/dev/null` \ - `ls -d ${exec_prefix}/lib 2>/dev/null` \ - `ls -d ${prefix}/lib 2>/dev/null` \ - `ls -d /cygdrive/c/Tcl/lib 2>/dev/null` \ - `ls -d /cygdrive/c/Progra~1/Tcl/lib 2>/dev/null` \ - `ls -d /c/Tcl/lib 2>/dev/null` \ - `ls -d /c/Progra~1/Tcl/lib 2>/dev/null` \ - `ls -d C:/Tcl/lib 2>/dev/null` \ - `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ - ; do - if test -f "$i/tkConfig.sh" ; then - ac_cv_c_tkconfig="`(cd $i; pwd)`" - break - fi - done - fi - - # check in a few other private locations - if test x"${ac_cv_c_tkconfig}" = x ; then - for i in \ - ${srcdir}/../tk \ - `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do - if test -f "$i/win/tkConfig.sh" ; then - ac_cv_c_tkconfig="`(cd $i/win; pwd)`" - break - fi - done - fi - ]) - - if test x"${ac_cv_c_tkconfig}" = x ; then - TK_BIN_DIR="# no Tk configs found" - AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh]) - else - no_tk= - TK_BIN_DIR="${ac_cv_c_tkconfig}" - AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh]) - fi - fi -]) - -#------------------------------------------------------------------------ -# SC_LOAD_TCLCONFIG -- -# -# Load the tclConfig.sh file. -# -# Arguments: -# -# Requires the following vars to be set: -# TCL_BIN_DIR -# -# Results: -# -# Substitutes the following vars: -# TCL_BIN_DIR -# TCL_SRC_DIR -# TCL_LIB_FILE -# -#------------------------------------------------------------------------ - -AC_DEFUN([SC_LOAD_TCLCONFIG], [ - AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh]) - - if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then - AC_MSG_RESULT([loading]) - . "${TCL_BIN_DIR}/tclConfig.sh" - else - AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh]) - fi - - # - # If the TCL_BIN_DIR is the build directory (not the install directory), - # then set the common variable name to the value of the build variables. - # For example, the variable TCL_LIB_SPEC will be set to the value - # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC - # instead of TCL_BUILD_LIB_SPEC since it will work with both an - # installed and uninstalled version of Tcl. - # - - if test -f $TCL_BIN_DIR/Makefile ; then - TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} - TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} - TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} - fi - - # - # eval is required to do the TCL_DBGX substitution - # - - eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" - eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" - eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" - - eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" - eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" - eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" - - AC_SUBST(TCL_VERSION) - AC_SUBST(TCL_BIN_DIR) - AC_SUBST(TCL_SRC_DIR) - - AC_SUBST(TCL_LIB_FILE) - AC_SUBST(TCL_LIB_FLAG) - AC_SUBST(TCL_LIB_SPEC) - - AC_SUBST(TCL_STUB_LIB_FILE) - AC_SUBST(TCL_STUB_LIB_FLAG) - AC_SUBST(TCL_STUB_LIB_SPEC) - - AC_SUBST(TCL_DEFS) -]) - -#------------------------------------------------------------------------ -# SC_LOAD_TKCONFIG -- -# -# Load the tkConfig.sh file -# -# Arguments: -# -# Requires the following vars to be set: -# TK_BIN_DIR -# -# Results: -# -# Sets the following vars that should be in tkConfig.sh: -# TK_BIN_DIR -#------------------------------------------------------------------------ - -AC_DEFUN([SC_LOAD_TKCONFIG], [ - AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh]) - - if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then - AC_MSG_RESULT([loading]) - . "${TK_BIN_DIR}/tkConfig.sh" - else - AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh]) - fi - - - AC_SUBST(TK_BIN_DIR) - AC_SUBST(TK_SRC_DIR) - AC_SUBST(TK_LIB_FILE) -]) - -#------------------------------------------------------------------------ -# SC_ENABLE_SHARED -- -# -# Allows the building of shared libraries -# -# Arguments: -# none -# -# Results: -# -# Adds the following arguments to configure: -# --enable-shared=yes|no -# -# Defines the following vars: -# STATIC_BUILD Used for building import/export libraries -# on Windows. -# -# Sets the following vars: -# SHARED_BUILD Value of 1 or 0 -#------------------------------------------------------------------------ - -AC_DEFUN([SC_ENABLE_SHARED], [ - AC_MSG_CHECKING([how to build libraries]) - AC_ARG_ENABLE(shared, - [ --enable-shared build and link with shared libraries (default: on)], - [tcl_ok=$enableval], [tcl_ok=yes]) - - if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - tcl_ok=$enableval - else - tcl_ok=yes - fi - - if test "$tcl_ok" = "yes" ; then - AC_MSG_RESULT([shared]) - SHARED_BUILD=1 - else - AC_MSG_RESULT([static]) - SHARED_BUILD=0 - AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?]) - fi -]) - -#------------------------------------------------------------------------ -# SC_ENABLE_THREADS -- -# -# Specify if thread support should be enabled -# -# Arguments: -# none -# -# Results: -# -# Adds the following arguments to configure: -# --enable-threads=yes|no -# -# Defines the following vars: -# TCL_THREADS -#------------------------------------------------------------------------ - -AC_DEFUN([SC_ENABLE_THREADS], [ - AC_MSG_CHECKING(for building with threads) - AC_ARG_ENABLE(threads, [ --enable-threads build with threads (default: on)], - [tcl_ok=$enableval], [tcl_ok=yes]) - - if test "$tcl_ok" = "yes"; then - AC_MSG_RESULT([yes (default)]) - TCL_THREADS=1 - AC_DEFINE(TCL_THREADS) - # USE_THREAD_ALLOC tells us to try the special thread-based - # allocator that significantly reduces lock contention - AC_DEFINE(USE_THREAD_ALLOC) - else - TCL_THREADS=0 - AC_MSG_RESULT(no) - fi - AC_SUBST(TCL_THREADS) -]) - -#------------------------------------------------------------------------ -# SC_ENABLE_SYMBOLS -- -# -# Specify if debugging symbols should be used. -# Memory (TCL_MEM_DEBUG) and compile (TCL_COMPILE_DEBUG) debugging -# can also be enabled. -# -# Arguments: -# none -# -# Requires the following vars to be set in the Makefile: -# CFLAGS_DEBUG -# CFLAGS_OPTIMIZE -# -# Results: -# -# Adds the following arguments to configure: -# --enable-symbols -# -# Defines the following vars: -# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true -# Sets to $(CFLAGS_OPTIMIZE) if false -# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true -# Sets to $(LDFLAGS_OPTIMIZE) if false -# DBGX Debug library extension -# -#------------------------------------------------------------------------ - -AC_DEFUN([SC_ENABLE_SYMBOLS], [ - AC_MSG_CHECKING([for build with symbols]) - AC_ARG_ENABLE(symbols, [ --enable-symbols build with debugging symbols (default: off)], [tcl_ok=$enableval], [tcl_ok=no]) -# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT. - if test "$tcl_ok" = "no"; then - CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)' - LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)' - DBGX="" - AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?]) - AC_MSG_RESULT([no]) - - AC_DEFINE(TCL_CFG_OPTIMIZED) - else - CFLAGS_DEFAULT='$(CFLAGS_DEBUG)' - LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)' - DBGX=g - if test "$tcl_ok" = "yes"; then - AC_MSG_RESULT([yes (standard debugging)]) - fi - fi - AC_SUBST(CFLAGS_DEFAULT) - AC_SUBST(LDFLAGS_DEFAULT) - - if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then - AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?]) - fi - - if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then - AC_DEFINE(TCL_COMPILE_DEBUG, 1, [Is bytecode debugging enabled?]) - AC_DEFINE(TCL_COMPILE_STATS, 1, [Are bytecode statistics enabled?]) - fi - - if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then - if test "$tcl_ok" = "all"; then - AC_MSG_RESULT([enabled symbols mem compile debugging]) - else - AC_MSG_RESULT([enabled $tcl_ok debugging]) - fi - fi -]) - -#-------------------------------------------------------------------- -# SC_CONFIG_CFLAGS -# -# Try to determine the proper flags to pass to the compiler -# for building shared libraries and other such nonsense. -# -# NOTE: The backslashes in quotes below are substituted twice -# due to the fact that they are in a macro and then inlined -# in the final configure script. -# -# Arguments: -# none -# -# Results: -# -# Can the following vars: -# EXTRA_CFLAGS -# CFLAGS_DEBUG -# CFLAGS_OPTIMIZE -# CFLAGS_WARNING -# LDFLAGS_DEBUG -# LDFLAGS_OPTIMIZE -# LDFLAGS_CONSOLE -# LDFLAGS_WINDOW -# CC_OBJNAME -# CC_EXENAME -# CYGPATH -# STLIB_LD -# SHLIB_LD -# SHLIB_LD_LIBS -# LIBS -# AR -# RC -# RES -# -# MAKE_LIB -# MAKE_STUB_LIB -# MAKE_EXE -# MAKE_DLL -# -# LIBSUFFIX -# LIBFLAGSUFFIX -# LIBPREFIX -# LIBRARIES -# EXESUFFIX -# DLLSUFFIX -# -#-------------------------------------------------------------------- - -AC_DEFUN([SC_CONFIG_CFLAGS], [ - - # Step 0: Enable 64 bit support? - - AC_MSG_CHECKING([if 64bit support is requested]) - AC_ARG_ENABLE(64bit,[ --enable-64bit enable 64bit support (where applicable)], [do64bit=$enableval], [do64bit=no]) - AC_MSG_RESULT($do64bit) - - # Cross-compiling options for Windows/CE builds - - AC_MSG_CHECKING([if Windows/CE build is requested]) - AC_ARG_ENABLE(wince,[ --enable-wince enable Win/CE support (where applicable)], [doWince=$enableval], [doWince=no]) - AC_MSG_RESULT($doWince) - - AC_MSG_CHECKING([for Windows/CE celib directory]) - AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], - CELIB_DIR=$withval, CELIB_DIR=NO_CELIB) - AC_MSG_RESULT([$CELIB_DIR]) - - # Set some defaults (may get changed below) - EXTRA_CFLAGS="" - AC_DEFINE(MODULE_SCOPE, [extern], [No need to mark inidividual symbols as hidden]) - - AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) - - SHLIB_SUFFIX=".dll" - - # MACHINE is IX86 for LINK, but this is used by the manifest, - # which requires x86|amd64|ia64. - MACHINE="X86" - - if test "$GCC" = "yes"; then - - AC_CACHE_CHECK(for cross-compile version of gcc, - ac_cv_cross, - AC_TRY_COMPILE([ - #ifndef _WIN32 - #error cross-compiler - #endif - ], [], - ac_cv_cross=no, - ac_cv_cross=yes) - ) - - if test "$ac_cv_cross" = "yes"; then - case "$do64bit" in - amd64|x64|yes) - CC="x86_64-w64-mingw32-gcc" - LD="x86_64-w64-mingw32-ld" - AR="x86_64-w64-mingw32-ar" - RANLIB="x86_64-w64-mingw32-ranlib" - RC="x86_64-w64-mingw32-windres" - ;; - *) - CC="i686-w64-mingw32-gcc" - LD="i686-w64-mingw32-ld" - AR="i686-w64-mingw32-ar" - RANLIB="i686-w64-mingw32-ranlib" - RC="i686-w64-mingw32-windres" - ;; - esac - fi - fi - - # Check for a bug in gcc's windres that causes the - # compile to fail when a Windows native path is - # passed into windres. The mingw toolchain requires - # Windows native paths while Cygwin should work - # with both. Avoid the bug by passing a POSIX - # path when using the Cygwin toolchain. - - if test "$GCC" = "yes" && test "$CYGPATH" != "echo" ; then - conftest=/tmp/conftest.rc - echo "STRINGTABLE BEGIN" > $conftest - echo "101 \"name\"" >> $conftest - echo "END" >> $conftest - - AC_MSG_CHECKING([for Windows native path bug in windres]) - cyg_conftest=`$CYGPATH $conftest` - if AC_TRY_COMMAND($RC -o conftest.res.o $cyg_conftest) ; then - AC_MSG_RESULT([no]) - else - AC_MSG_RESULT([yes]) - CYGPATH=echo - fi - conftest= - cyg_conftest= - fi - - if test "$CYGPATH" = "echo"; then - DEPARG='"$<"' - else - DEPARG='"$(shell $(CYGPATH) $<)"' - fi - - # set various compiler flags depending on whether we are using gcc or cl - - if test "${GCC}" = "yes" ; then - extra_cflags="-pipe" - extra_ldflags="-pipe -static-libgcc" - AC_CACHE_CHECK(for mingw32 version of gcc, - ac_cv_win32, - AC_TRY_COMPILE([ - #ifdef _WIN32 - #error win32 - #endif - ], [], - ac_cv_win32=no, - ac_cv_win32=yes) - ) - if test "$ac_cv_win32" != "yes"; then - AC_MSG_ERROR([${CC} cannot produce win32 executables.]) - fi - - hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain" - AC_CACHE_CHECK(for working -municode linker flag, - ac_cv_municode, - AC_TRY_LINK([ - #include <windows.h> - int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;} - ], - [], - ac_cv_municode=yes, - ac_cv_municode=no) - ) - CFLAGS=$hold_cflags - if test "$ac_cv_municode" = "yes" ; then - extra_ldflags="$extra_ldflags -municode" - else - extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS" - fi - fi - - AC_MSG_CHECKING([compiler flags]) - if test "${GCC}" = "yes" ; then - SHLIB_LD="" - SHLIB_LD_LIBS='${LIBS}' - 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' - RC_OUT=-o - RC_TYPE= - RC_INCLUDE=--include - RC_DEFINE=--define - RES=res.o - MAKE_LIB="\${STLIB_LD} \[$]@" - MAKE_STUB_LIB="\${STLIB_LD} \[$]@" - POST_MAKE_LIB="\${RANLIB} \[$]@" - MAKE_EXE="\${CC} -o \[$]@" - LIBPREFIX="lib" - - if test "${SHARED_BUILD}" = "0" ; then - # static - AC_MSG_RESULT([using static flags]) - runtime= - LIBRARIES="\${STATIC_LIBRARIES}" - EXESUFFIX="s\${DBGX}.exe" - else - # dynamic - AC_MSG_RESULT([using shared flags]) - - # ad-hoc check to see if CC supports -shared. - if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then - AC_MSG_ERROR([${CC} does not support the -shared option. - You will need to upgrade to a newer version of the toolchain.]) - fi - - runtime= - # Add SHLIB_LD_LIBS to the Make rule, not here. - - EXESUFFIX="\${DBGX}.exe" - LIBRARIES="\${SHARED_LIBRARIES}" - fi - # Link with gcc since ld does not link to default libs like - # -luser32 and -lmsvcrt by default. - SHLIB_LD='${CC} -shared' - SHLIB_LD_LIBS='${LIBS}' - MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \[$]@ ${extra_ldflags} \ - -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\[$]@)" - # DLLSUFFIX is separate because it is the building block for - # users of tclConfig.sh that may build shared or static. - DLLSUFFIX="\${DBGX}.dll" - LIBSUFFIX="\${DBGX}.a" - LIBFLAGSUFFIX="\${DBGX}" - SHLIB_SUFFIX=.dll - - EXTRA_CFLAGS="${extra_cflags}" - - CFLAGS_DEBUG=-g - CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" - CFLAGS_WARNING="-Wall -Wdeclaration-after-statement" - LDFLAGS_DEBUG= - LDFLAGS_OPTIMIZE= - - # Specify the CC output file names based on the target name - CC_OBJNAME="-o \[$]@" - CC_EXENAME="-o \[$]@" - - # Specify linker flags depending on the type of app being - # built -- Console vs. Window. - # - # ORIGINAL COMMENT: - # We need to pass -e _WinMain@16 so that ld will use - # WinMain() instead of main() as the entry point. We can't - # use autoconf to check for this case since it would need - # to run an executable and that does not work when - # cross compiling. Remove this -e workaround once we - # require a gcc that does not have this bug. - # - # MK NOTE: Tk should use a different mechanism. This causes - # interesting problems, such as wish dying at startup. - #LDFLAGS_WINDOW="-mwindows -e _WinMain@16 ${extra_ldflags}" - LDFLAGS_CONSOLE="-mconsole ${extra_ldflags}" - LDFLAGS_WINDOW="-mwindows ${extra_ldflags}" - - case "$do64bit" in - amd64|x64|yes) - MACHINE="AMD64" ; # assume AMD64 as default 64-bit build - AC_MSG_RESULT([ Using 64-bit $MACHINE mode]) - ;; - ia64) - MACHINE="IA64" - AC_MSG_RESULT([ Using 64-bit $MACHINE mode]) - ;; - *) - AC_TRY_COMPILE([ - #ifndef _WIN64 - #error 32-bit - #endif - ], [], - tcl_win_64bit=yes, - tcl_win_64bit=no - ) - if test "$tcl_win_64bit" = "yes" ; then - do64bit=amd64 - MACHINE="AMD64" - AC_MSG_RESULT([ Using 64-bit $MACHINE mode]) - fi - ;; - esac - else - if test "${SHARED_BUILD}" = "0" ; then - # static - AC_MSG_RESULT([using static flags]) - runtime=-MT - LIBRARIES="\${STATIC_LIBRARIES}" - EXESUFFIX="s\${DBGX}.exe" - else - # dynamic - AC_MSG_RESULT([using shared flags]) - runtime=-MD - # 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 - # users of tclConfig.sh that may build shared or static. - DLLSUFFIX="\${DBGX}.dll" - LIBSUFFIX="\${DBGX}.lib" - LIBFLAGSUFFIX="\${DBGX}" - - # This is a 2-stage check to make sure we have the 64-bit SDK - # We have to know where the SDK is installed. - # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs - if test "$do64bit" != "no" ; then - if test "x${MSSDK}x" = "xx" ; then - MSSDK="C:/Progra~1/Microsoft Platform SDK" - fi - MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` - PATH64="" - case "$do64bit" in - amd64|x64|yes) - MACHINE="AMD64" ; # assume AMD64 as default 64-bit build - PATH64="${MSSDK}/Bin/Win64/x86/AMD64" - ;; - ia64) - MACHINE="IA64" - PATH64="${MSSDK}/Bin/Win64" - ;; - esac - if test ! -d "${PATH64}" ; then - 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 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 - # TEA_PATH_NOSPACE to avoid this issue. - # Check if _WIN64 is already recognized, and if so we don't - # need to modify CC. - AC_CHECK_DECL([_WIN64], [], - [CC="\"${PATH64}/cl.exe\" -I\"${MSSDK}/Include\" \ - -I\"${MSSDK}/Include/crt\" \ - -I\"${MSSDK}/Include/crt/sys\""]) - RC="\"${MSSDK}/bin/rc.exe\"" - 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="${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 - LIBS="$LIBS bufferoverflowU.lib" - else - RC="rc" - # -Od - no optimization - # -WX - warnings as errors - 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="${lflags} -nologo" - LINKBIN="link" - fi - - if test "$doWince" != "no" ; then - # Set defaults for common evc4/PPC2003 setup - # Currently Tcl requires 300+, possibly 420+ for sockets - CEVERSION=420; # could be 211 300 301 400 420 ... - TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... - ARCH=ARM; # could be ARM MIPS X86EM ... - PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" - if test "$doWince" != "yes"; then - # If !yes then the user specified something - # Reset ARCH to allow user to skip specifying it - ARCH= - eval `echo $doWince | awk -F "," '{ \ - if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \ - if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ - if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \ - if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \ - if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \ - }'` - if test "x${ARCH}" = "x" ; then - ARCH=$TARGETCPU; - fi - fi - OSVERSION=WCE$CEVERSION; - if test "x${WCEROOT}" = "x" ; then - WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" - if test ! -d "${WCEROOT}" ; then - WCEROOT="C:/Program Files/Microsoft eMbedded Tools" - fi - fi - if test "x${SDKROOT}" = "x" ; then - SDKROOT="C:/Program Files/Windows CE Tools" - if test ! -d "${SDKROOT}" ; then - SDKROOT="C:/Windows CE Tools" - fi - fi - # The space-based-path will work for the Makefile, but will - # not work if AC_TRY_COMPILE is called. - WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` - SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` - CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` - if test ! -d "${CELIB_DIR}/inc"; then - AC_MSG_ERROR([Invalid celib directory "${CELIB_DIR}"]) - fi - if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"\ - -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then - AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]]) - else - CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" - if test -d "${CEINCLUDE}/${TARGETCPU}" ; then - CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" - fi - CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" - fi - fi - - if test "$doWince" != "no" ; then - CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" - if test "${TARGETCPU}" = "X86"; then - CC="${CEBINROOT}/cl.exe" - else - CC="${CEBINROOT}/cl${ARCH}.exe" - fi - CC="\"${CC}\" -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" - RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" - arch=`echo ${ARCH} | awk '{print tolower([$]0)}'` - defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _DLL _WINDOWS" - for i in $defs ; do - AC_DEFINE_UNQUOTED($i) - done -# if test "${ARCH}" = "X86EM"; then -# AC_DEFINE_UNQUOTED(_WIN32_WCE_EMULATION) -# fi - AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION) - AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION) - CFLAGS_DEBUG="-nologo -Zi -Od" - CFLAGS_OPTIMIZE="-nologo -O2" - lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` - lflags="-nodefaultlib -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" - LINKBIN="\"${CEBINROOT}/link.exe\"" - AC_SUBST(CELIB_DIR) - if test "${CEVERSION}" -lt 400 ; then - LIBS="coredll.lib corelibc.lib winsock.lib" - else - LIBS="coredll.lib corelibc.lib ws2.lib" - fi - # celib currently stuck at wce300 status - #LIBS="$LIBS \${CELIB_DIR}/wince-${ARCH}-pocket-${OSVERSION}-release/celib.lib" - LIBS="$LIBS \"\${CELIB_DIR}/wince-${ARCH}-pocket-wce300-release/celib.lib\"" - LIBS_GUI="commctrl.lib commdlg.lib" - else - LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib" - fi - - SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}" - SHLIB_LD_LIBS='${LIBS}' - # link -lib only works when -lib is the first arg - STLIB_LD="${LINKBIN} -lib ${lflags}" - RC_OUT=-fo - RC_TYPE=-r - RC_INCLUDE=-i - RC_DEFINE=-d - RES=res - MAKE_LIB="\${STLIB_LD} -out:\[$]@" - MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\[$]@" - POST_MAKE_LIB= - MAKE_EXE="\${CC} -Fe\[$]@" - LIBPREFIX="" - - CFLAGS_DEBUG="${CFLAGS_DEBUG} -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE" - CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE" - - EXTRA_CFLAGS="" - CFLAGS_WARNING="-W3" - LDFLAGS_DEBUG="-debug" - LDFLAGS_OPTIMIZE="-release" - - # Specify the CC output file names based on the target name - CC_OBJNAME="-Fo\[$]@" - CC_EXENAME="-Fe\"\$(shell \$(CYGPATH) '\[$]@')\"" - - # Specify linker flags depending on the type of app being - # built -- Console vs. Window. - if test "$doWince" != "no" -a "${TARGETCPU}" != "X86"; then - LDFLAGS_CONSOLE="-link ${lflags}" - LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} - else - LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" - LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" - fi - fi - - if test "$do64bit" != "no" ; then - AC_DEFINE(TCL_CFG_DO64BIT) - fi - - if test "${GCC}" = "yes" ; then - AC_CACHE_CHECK(for SEH support in compiler, - tcl_cv_seh, - AC_TRY_RUN([ - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #undef WIN32_LEAN_AND_MEAN - - int main(int argc, char** argv) { - int a, b = 0; - __try { - a = 666 / b; - } - __except (EXCEPTION_EXECUTE_HANDLER) { - return 0; - } - return 1; - } - ], - tcl_cv_seh=yes, - tcl_cv_seh=no, - tcl_cv_seh=no) - ) - if test "$tcl_cv_seh" = "no" ; then - AC_DEFINE(HAVE_NO_SEH, 1, - [Defined when mingw does not support SEH]) - fi - - # - # Check to see if the excpt.h include file provided contains the - # definition for EXCEPTION_DISPOSITION; if not, which is the case - # with Cygwin's version as of 2002-04-10, define it to be int, - # sufficient for getting the current code to work. - # - AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files, - tcl_cv_eh_disposition, - AC_TRY_COMPILE([ -# define WIN32_LEAN_AND_MEAN -# include <windows.h> -# undef WIN32_LEAN_AND_MEAN - ],[ - EXCEPTION_DISPOSITION x; - ], - tcl_cv_eh_disposition=yes, - tcl_cv_eh_disposition=no) - ) - if test "$tcl_cv_eh_disposition" = "no" ; then - AC_DEFINE(EXCEPTION_DISPOSITION, int, - [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION]) - fi - - # Check to see if winnt.h defines CHAR, SHORT, and LONG - # even if VOID has already been #defined. The win32api - # used by mingw and cygwin is known to do this. - - AC_CACHE_CHECK(for winnt.h that ignores VOID define, - tcl_cv_winnt_ignore_void, - AC_TRY_COMPILE([ - #define VOID void - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #undef WIN32_LEAN_AND_MEAN - ], [ - CHAR c; - SHORT s; - LONG l; - ], - tcl_cv_winnt_ignore_void=yes, - tcl_cv_winnt_ignore_void=no) - ) - if test "$tcl_cv_winnt_ignore_void" = "yes" ; then - AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1, - [Defined when cygwin/mingw ignores VOID define in winnt.h]) - fi - - # See if the compiler supports casting to a union type. - # This is used to stop gcc from printing a compiler - # warning when initializing a union member. - - AC_CACHE_CHECK(for cast to union support, - tcl_cv_cast_to_union, - AC_TRY_COMPILE([], - [ - union foo { int i; double d; }; - union foo f = (union foo) (int) 0; - ], - tcl_cv_cast_to_union=yes, - tcl_cv_cast_to_union=no) - ) - if test "$tcl_cv_cast_to_union" = "yes"; then - AC_DEFINE(HAVE_CAST_TO_UNION, 1, - [Defined when compiler supports casting to union type.]) - fi - fi - - # DL_LIBS is empty, but then we match the Unix version - AC_SUBST(DL_LIBS) - AC_SUBST(CFLAGS_DEBUG) - AC_SUBST(CFLAGS_OPTIMIZE) - AC_SUBST(CFLAGS_WARNING) -]) - -#------------------------------------------------------------------------ -# SC_WITH_TCL -- -# -# Location of the Tcl build directory. -# -# Arguments: -# none -# -# Results: -# -# Adds the following arguments to configure: -# --with-tcl=... -# -# Defines the following vars: -# TCL_BIN_DIR Full path to the tcl build dir. -#------------------------------------------------------------------------ - -AC_DEFUN([SC_WITH_TCL], [ - if test -d ../../tcl8.6$1/win; then - TCL_BIN_DEFAULT=../../tcl8.6$1/win - else - TCL_BIN_DEFAULT=../../tcl8.6/win - fi - - AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.6 binaries from DIR], - TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DEFAULT; pwd`) - if test ! -d $TCL_BIN_DIR; then - AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist) - fi - if test ! -f $TCL_BIN_DIR/Makefile; then - AC_MSG_ERROR(There is no Makefile in $TCL_BIN_DIR: perhaps you did not specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?) - else - echo "building against Tcl binaries in: $TCL_BIN_DIR" - fi - AC_SUBST(TCL_BIN_DIR) -]) - -#------------------------------------------------------------------------ -# SC_PROG_TCLSH -# Locate a tclsh shell installed on the system path. This macro -# will only find a Tcl shell that already exists on the system. -# It will not find a Tcl shell in the Tcl build directory or -# a Tcl shell that has been installed from the Tcl build directory. -# If a Tcl shell can't be located on the PATH, then TCLSH_PROG will -# be set to "". Extensions should take care not to create Makefile -# rules that are run by default and depend on TCLSH_PROG. An -# extension can't assume that an executable Tcl shell exists at -# build time. -# -# Arguments -# none -# -# Results -# Subst's the following values: -# TCLSH_PROG -#------------------------------------------------------------------------ - -AC_DEFUN([SC_PROG_TCLSH], [ - AC_MSG_CHECKING([for tclsh]) - - AC_CACHE_VAL(ac_cv_path_tclsh, [ - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/tclsh[[8-9]]*.exe 2> /dev/null` \ - `ls -r $dir/tclsh* 2> /dev/null` ; do - if test x"$ac_cv_path_tclsh" = x ; then - if test -f "$j" ; then - ac_cv_path_tclsh=$j - break - fi - fi - done - done - ]) - - if test -f "$ac_cv_path_tclsh" ; then - TCLSH_PROG="$ac_cv_path_tclsh" - AC_MSG_RESULT($TCLSH_PROG) - else - # It is not an error if an installed version of Tcl can't be located. - TCLSH_PROG="" - AC_MSG_RESULT([No tclsh found on PATH]) - fi - AC_SUBST(TCLSH_PROG) -]) - -#------------------------------------------------------------------------ -# SC_BUILD_TCLSH -# Determine the fully qualified path name of the tclsh executable -# in the Tcl build directory. This macro will correctly determine -# the name of the tclsh executable even if tclsh has not yet -# been built in the build directory. The build tclsh must be used -# when running tests from an extension build directory. It is not -# correct to use the TCLSH_PROG in cases like this. -# -# Arguments -# none -# -# Results -# Subst's the following values: -# BUILD_TCLSH -#------------------------------------------------------------------------ - -AC_DEFUN([SC_BUILD_TCLSH], [ - AC_MSG_CHECKING([for tclsh in Tcl build directory]) - BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT} - AC_MSG_RESULT($BUILD_TCLSH) - AC_SUBST(BUILD_TCLSH) -]) - -#-------------------------------------------------------------------- -# SC_TCL_CFG_ENCODING TIP #59 -# -# Declare the encoding to use for embedded configuration information. -# -# Arguments: -# None. -# -# Results: -# Might append to the following vars: -# DEFS (implicit) -# -# Will define the following vars: -# TCL_CFGVAL_ENCODING -# -#-------------------------------------------------------------------- - -AC_DEFUN([SC_TCL_CFG_ENCODING], [ - AC_ARG_WITH(encoding, [ --with-encoding encoding for configuration values], with_tcencoding=${withval}) - - if test x"${with_tcencoding}" != x ; then - AC_DEFINE_UNQUOTED(TCL_CFGVAL_ENCODING,"${with_tcencoding}") - else - # Default encoding on windows is not "iso8859-1" - AC_DEFINE(TCL_CFGVAL_ENCODING,"cp1252") - fi -]) - -#-------------------------------------------------------------------- -# SC_EMBED_MANIFEST -# -# Figure out if we can embed the manifest where necessary -# -# Arguments: -# An optional manifest to merge into DLL/EXE. -# -# Results: -# Will define the following vars: -# VC_MANIFEST_EMBED_DLL -# VC_MANIFEST_EMBED_EXE -# -#-------------------------------------------------------------------- - -AC_DEFUN([SC_EMBED_MANIFEST], [ - AC_MSG_CHECKING(whether to embed manifest) - AC_ARG_ENABLE(embedded-manifest, - AC_HELP_STRING([--enable-embedded-manifest], - [embed manifest if possible (default: yes)]), - [embed_ok=$enableval], [embed_ok=yes]) - - VC_MANIFEST_EMBED_DLL= - VC_MANIFEST_EMBED_EXE= - result=no - if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \ - -a "$GCC" != "yes" ; then - # Add the magic to embed the manifest into the dll/exe - AC_EGREP_CPP([manifest needed], [ -#if defined(_MSC_VER) && _MSC_VER >= 1400 -print("manifest needed") -#endif - ], [ - # Could do a CHECK_PROG for mt, but should always be with MSVC8+ - # Could add 'if test -f' check, but manifest should be created - # in this compiler case - # Add in a manifest argument that may be specified - # XXX Needs improvement so that the test for existence accounts - # XXX for a provided (known) manifest - VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest $1 -outputresource:\[$]@\;2 ; fi" - VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest $1 -outputresource:\[$]@\;1 ; fi" - result=yes - if test "x$1" != x ; then - result="yes ($1)" - fi - ]) - fi - AC_MSG_RESULT([$result]) - AC_SUBST(VC_MANIFEST_EMBED_DLL) - AC_SUBST(VC_MANIFEST_EMBED_EXE) -]) diff --git a/tk8.6/win/tkConfig.sh.in b/tk8.6/win/tkConfig.sh.in deleted file mode 100644 index c511312..0000000 --- a/tk8.6/win/tkConfig.sh.in +++ /dev/null @@ -1,87 +0,0 @@ -# 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. -# This script is intended to be included by the configure scripts -# for Tk extensions so that they don't have to figure this all -# out for themselves. This file does not duplicate information -# already provided by tclConfig.sh, so you may need to use that -# file in addition to this one. -# -# The information in this file is specific to a single platform. - -TK_DLL_FILE="@TK_DLL_FILE@" - -# Tk's version number. -TK_VERSION='@TK_VERSION@' -TK_MAJOR_VERSION='@TK_MAJOR_VERSION@' -TK_MINOR_VERSION='@TK_MINOR_VERSION@' -TK_PATCH_LEVEL='@TK_PATCH_LEVEL@' - -# -D flags for use with the C compiler. -TK_DEFS='@DEFS@' - -# Flag, 1: we built a shared lib, 0 we didn't -TK_SHARED_BUILD=@TK_SHARED_BUILD@ - -# This indicates if Tk was build with debugging symbols -TK_DBGX=@TK_DBGX@ - -# The name of the Tk library (may be either a .a file or a shared library): -TK_LIB_FILE='@TK_LIB_FILE@' - -# Additional libraries to use when linking Tk. -TK_LIBS='@LIBS@ @LIBS_GUI@' - -# Top-level directory in which Tcl's platform-independent files are -# installed. -TK_PREFIX='@prefix@' - -# Top-level directory in which Tcl's platform-specific files (e.g. -# executables) are installed. -TK_EXEC_PREFIX='@exec_prefix@' - -# -l flag to pass to the linker to pick up the Tcl library -TK_LIB_FLAG='@TK_LIB_FLAG@' - -# String to pass to linker to pick up the Tk library from its -# build directory. -TK_BUILD_LIB_SPEC='@TK_BUILD_LIB_SPEC@' - -# String to pass to linker to pick up the Tk library from its -# installed directory. -TK_LIB_SPEC='@TK_LIB_SPEC@' - -# Location of the top-level source directory from which Tk was built. -# This is the directory that contains a README file as well as -# subdirectories such as generic, unix, etc. If Tk was compiled in a -# different place than the directory containing the source files, this -# points to the location of the sources, not the location where Tk was -# compiled. -TK_SRC_DIR='@TK_SRC_DIR@' - -# Needed if you want to make a 'fat' shared library library -# containing tk objects or link a different wish. -TK_CC_SEARCH_FLAGS='@TK_CC_SEARCH_FLAGS@' -TK_LD_SEARCH_FLAGS='@TK_LD_SEARCH_FLAGS@' - -# The name of the Tk stub library (.a): -TK_STUB_LIB_FILE='@TK_STUB_LIB_FILE@' - -# -l flag to pass to the linker to pick up the Tk stub library -TK_STUB_LIB_FLAG='@TK_STUB_LIB_FLAG@' - -# String to pass to linker to pick up the Tk stub library from its -# build directory. -TK_BUILD_STUB_LIB_SPEC='@TK_BUILD_STUB_LIB_SPEC@' - -# String to pass to linker to pick up the Tk stub library from its -# installed directory. -TK_STUB_LIB_SPEC='@TK_STUB_LIB_SPEC@' - -# Path to the Tk stub library in the build directory. -TK_BUILD_STUB_LIB_PATH='@TK_BUILD_STUB_LIB_PATH@' - -# Path to the Tk stub library in the install directory. -TK_STUB_LIB_PATH='@TK_STUB_LIB_PATH@' diff --git a/tk8.6/win/tkWin.h b/tk8.6/win/tkWin.h deleted file mode 100644 index 4d278d7..0000000 --- a/tk8.6/win/tkWin.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * tkWin.h -- - * - * Declarations of public types and interfaces that are only - * available under Windows. - * - * Copyright (c) 1996-1997 by Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#ifndef _TKWIN -#define _TKWIN - -/* - * 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 assignments. - * - * WINVER = 0x0500 means Windows 2000 and above - */ - -#ifndef WINVER -#define WINVER 0x0500 -#endif -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 -#endif - -#ifndef _TK -#include <tk.h> -#endif - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN - -/* - * 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 - * application. - */ - -#define TK_CLAIMFOCUS (WM_USER) /* an embedded window requests to focus */ -#define TK_GEOMETRYREQ (WM_USER+1) /* an embedded window requests to change size */ -#define TK_ATTACHWINDOW (WM_USER+2) /* an embedded window requests to attach */ -#define TK_DETACHWINDOW (WM_USER+3) /* an embedded window requests to detach */ -#define TK_MOVEWINDOW (WM_USER+4) /* an embedded window requests to move */ -#define TK_RAISEWINDOW (WM_USER+5) /* an embedded window requests to raise */ -#define TK_ICONIFY (WM_USER+6) /* an embedded window requests to iconify */ -#define TK_DEICONIFY (WM_USER+7) /* an embedded window requests to deiconify */ -#define TK_WITHDRAW (WM_USER+8) /* an embedded window requests to withdraw */ -#define TK_GETFRAMEWID (WM_USER+9) /* an embedded window requests a frame window id */ -#define TK_OVERRIDEREDIRECT (WM_USER+10) /* an embedded window requests to overrideredirect */ -#define TK_SETMENU (WM_USER+11) /* an embedded window requests to setup menu */ -#define TK_STATE (WM_USER+12) /* an embedded window sets/gets state */ -#define TK_INFO (WM_USER+13) /* an embedded window requests a container's info */ - -/* - * 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 - * for verification and availability - */ -#define TK_CONTAINER_VERIFY 0x01 -#define TK_CONTAINER_ISAVAILABLE 0x02 - - -/* - *-------------------------------------------------------------- - * - * Exported procedures defined for the Windows platform only. - * - *-------------------------------------------------------------- - */ - -#include "tkPlatDecls.h" - -#endif /* _TKWIN */ diff --git a/tk8.6/win/tkWin32Dll.c b/tk8.6/win/tkWin32Dll.c deleted file mode 100644 index 3c3d83a..0000000 --- a/tk8.6/win/tkWin32Dll.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * tkWin32Dll.c -- - * - * This file contains a stub dll entry point. - * - * Copyright (c) 1995 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" -#ifndef STATIC_BUILD - -#ifdef HAVE_NO_SEH - -/* - * Unlike Borland and Microsoft, we don't register exception handlers by - * pushing registration records onto the runtime stack. Instead, we register - * them by creating an TCLEXCEPTION_REGISTRATION within the activation record. - */ - -typedef struct TCLEXCEPTION_REGISTRATION { - struct TCLEXCEPTION_REGISTRATION *link; - EXCEPTION_DISPOSITION (*handler)( - struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*); - void *ebp; - void *esp; - int status; -} TCLEXCEPTION_REGISTRATION; - -/* - * Need to add noinline flag to DllMain declaration so that gcc -O3 does not - * inline asm code into DllEntryPoint and cause a compile time error because - * of redefined local labels. - */ - -BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, - LPVOID reserved) __attribute__ ((noinline)); - -#else /* !HAVE_NO_SEH */ - -/* - * The following declaration is for the VC++ DLL entry point. - */ - -BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, - LPVOID reserved); -#endif /* HAVE_NO_SEH */ - -/* - *---------------------------------------------------------------------- - * - * DllEntryPoint -- - * - * This wrapper function is used by Borland to invoke the initialization - * code for Tk. It simply calls the DllMain routine. - * - * Results: - * See DllMain. - * - * Side effects: - * See DllMain. - * - *---------------------------------------------------------------------- - */ - -BOOL APIENTRY -DllEntryPoint( - HINSTANCE hInst, /* Library instance handle. */ - DWORD reason, /* Reason this function is being called. */ - LPVOID reserved) /* Not used. */ -{ - return DllMain(hInst, reason, reserved); -} - -/* - *---------------------------------------------------------------------- - * - * DllMain -- - * - * DLL entry point. It is only necessary to specify our dll here so that - * resources are found correctly. Otherwise Tk will initialize and clean - * up after itself through other methods, in order to be consistent - * whether the build is static or dynamic. - * - * Results: - * Always TRUE. - * - * Side effects: - * This might call some synchronization functions, but MSDN documentation - * states: "Waiting on synchronization objects in DllMain can cause a - * deadlock." - * - *---------------------------------------------------------------------- - */ - -BOOL APIENTRY -DllMain( - HINSTANCE hInstance, - DWORD reason, - LPVOID reserved) -{ -#ifdef HAVE_NO_SEH - TCLEXCEPTION_REGISTRATION registration; -#endif - - /* - * If we are attaching to the DLL from a new process, tell Tk about the - * hInstance to use. - */ - - switch (reason) { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hInstance); - TkWinSetHINSTANCE(hInstance); - break; - - case DLL_PROCESS_DETACH: - /* - * Protect the call to TkFinalize in an SEH block. We can't be - * guarenteed Tk is always being unloaded from a stable condition. - */ - -#ifdef HAVE_NO_SEH -# ifdef __WIN64 - __asm__ __volatile__ ( - - /* - * Construct an TCLEXCEPTION_REGISTRATION to protect the call to - * TkFinalize - */ - - "leaq %[registration], %%rdx" "\n\t" - "movq %%gs:0, %%rax" "\n\t" - "movq %%rax, 0x0(%%rdx)" "\n\t" /* link */ - "leaq 1f, %%rax" "\n\t" - "movq %%rax, 0x8(%%rdx)" "\n\t" /* handler */ - "movq %%rbp, 0x10(%%rdx)" "\n\t" /* rbp */ - "movq %%rsp, 0x18(%%rdx)" "\n\t" /* rsp */ - "movl %[error], 0x20(%%rdx)" "\n\t" /* status */ - - /* - * Link the TCLEXCEPTION_REGISTRATION on the chain - */ - - "movq %%rdx, %%gs:0" "\n\t" - - /* - * Call TkFinalize - */ - - "movq $0x0, 0x0(%%esp)" "\n\t" - "call TkFinalize" "\n\t" - - /* - * Come here on a normal exit. Recover the TCLEXCEPTION_REGISTRATION - * and store a TCL_OK status - */ - - "movq %%gs:0, %%rdx" "\n\t" - "movl %[ok], %%eax" "\n\t" - "movl %%eax, 0x20(%%rdx)" "\n\t" - "jmp 2f" "\n" - - /* - * Come here on an exception. Get the TCLEXCEPTION_REGISTRATION that - * we previously put on the chain. - */ - - "1:" "\t" - "movq %%gs:0, %%rdx" "\n\t" - "movq 0x10(%%rdx), %%rdx" "\n\t" - - /* - * Come here however we exited. Restore context from the - * TCLEXCEPTION_REGISTRATION in case the stack is unbalanced. - */ - - "2:" "\t" - "movq 0x18(%%rdx), %%rsp" "\n\t" - "movq 0x10(%%rdx), %%rbp" "\n\t" - "movq 0x0(%%rdx), %%rax" "\n\t" - "movq %%rax, %%gs:0" "\n\t" - - : - /* No outputs */ - : - [registration] "m" (registration), - [ok] "i" (TCL_OK), - [error] "i" (TCL_ERROR) - : - "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "memory" - ); - -# else - __asm__ __volatile__ ( - - /* - * Construct an TCLEXCEPTION_REGISTRATION to protect the call to - * TkFinalize - */ - - "leal %[registration], %%edx" "\n\t" - "movl %%fs:0, %%eax" "\n\t" - "movl %%eax, 0x0(%%edx)" "\n\t" /* link */ - "leal 1f, %%eax" "\n\t" - "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */ - "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */ - "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */ - "movl %[error], 0x10(%%edx)" "\n\t" /* status */ - - /* - * Link the TCLEXCEPTION_REGISTRATION on the chain - */ - - "movl %%edx, %%fs:0" "\n\t" - - /* - * Call TkFinalize - */ - - "movl $0x0, 0x0(%%esp)" "\n\t" - "call _TkFinalize" "\n\t" - - /* - * Come here on a normal exit. Recover the TCLEXCEPTION_REGISTRATION - * and store a TCL_OK status - */ - - "movl %%fs:0, %%edx" "\n\t" - "movl %[ok], %%eax" "\n\t" - "movl %%eax, 0x10(%%edx)" "\n\t" - "jmp 2f" "\n" - - /* - * Come here on an exception. Get the TCLEXCEPTION_REGISTRATION that - * we previously put on the chain. - */ - - "1:" "\t" - "movl %%fs:0, %%edx" "\n\t" - "movl 0x8(%%edx), %%edx" "\n" - - - /* - * Come here however we exited. Restore context from the - * TCLEXCEPTION_REGISTRATION in case the stack is unbalanced. - */ - - "2:" "\t" - "movl 0xc(%%edx), %%esp" "\n\t" - "movl 0x8(%%edx), %%ebp" "\n\t" - "movl 0x0(%%edx), %%eax" "\n\t" - "movl %%eax, %%fs:0" "\n\t" - - : - /* No outputs */ - : - [registration] "m" (registration), - [ok] "i" (TCL_OK), - [error] "i" (TCL_ERROR) - : - "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory" - ); - -# endif -#else /* HAVE_NO_SEH */ - __try { - /* - * Run and remove our exit handlers, if they haven't already been - * run. Just in case we are being unloaded prior to Tcl (it can - * happen), we won't leave any dangling pointers hanging around - * for when Tcl gets unloaded later. - */ - - TkFinalize(NULL); - } __except (EXCEPTION_EXECUTE_HANDLER) { - /* empty handler body. */ - } -#endif - - break; - } - return TRUE; -} - -#endif /* !STATIC_BUILD */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWin3d.c b/tk8.6/win/tkWin3d.c deleted file mode 100644 index d3c443d..0000000 --- a/tk8.6/win/tkWin3d.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * tkWin3d.c -- - * - * This file contains the platform specific routines for drawing 3D - * borders in the Windows 95 style. - * - * Copyright (c) 1996 by Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" -#include "tk3d.h" - -/* - * This structure is used to keep track of the extra colors used by Windows 3D - * borders. - */ - -typedef struct { - TkBorder info; - XColor *light2ColorPtr; /* System3dLight */ - XColor *dark2ColorPtr; /* System3dDarkShadow */ -} WinBorder; - -/* - *---------------------------------------------------------------------- - * - * TkpGetBorder -- - * - * This function allocates a new TkBorder structure. - * - * Results: - * Returns a newly allocated TkBorder. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TkBorder * -TkpGetBorder(void) -{ - WinBorder *borderPtr = ckalloc(sizeof(WinBorder)); - - borderPtr->light2ColorPtr = NULL; - borderPtr->dark2ColorPtr = NULL; - return (TkBorder *) borderPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TkpFreeBorder -- - * - * This function frees any colors allocated by the platform specific part - * of this module. - * - * Results: - * None. - * - * Side effects: - * May deallocate some colors. - * - *---------------------------------------------------------------------- - */ - -void -TkpFreeBorder( - TkBorder *borderPtr) -{ - WinBorder *winBorderPtr = (WinBorder *) borderPtr; - if (winBorderPtr->light2ColorPtr) { - Tk_FreeColor(winBorderPtr->light2ColorPtr); - } - if (winBorderPtr->dark2ColorPtr) { - Tk_FreeColor(winBorderPtr->dark2ColorPtr); - } -} - -/* - *-------------------------------------------------------------- - * - * Tk_3DVerticalBevel -- - * - * This procedure draws a vertical bevel along one side of an object. The - * bevel is always rectangular in shape: - * ||| - * ||| - * ||| - * ||| - * ||| - * ||| - * An appropriate shadow color is chosen for the bevel based on the - * leftBevel and relief arguments. Normally this procedure is called - * first, then Tk_3DHorizontalBevel is called next to draw neat corners. - * - * Results: - * None. - * - * Side effects: - * Graphics are drawn in drawable. - * - *-------------------------------------------------------------- - */ - -void -Tk_3DVerticalBevel( - Tk_Window tkwin, /* Window for which border was allocated. */ - Drawable drawable, /* X window or pixmap in which to draw. */ - Tk_3DBorder border, /* Token for border to draw. */ - int x, int y, int width, int height, - /* Area of vertical bevel. */ - int leftBevel, /* Non-zero means this bevel forms the left - * side of the object; 0 means it forms the - * right side. */ - int relief) /* Kind of bevel to draw. For example, - * TK_RELIEF_RAISED means interior of object - * should appear higher than exterior. */ -{ - TkBorder *borderPtr = (TkBorder *) border; - int left, right; - Display *display = Tk_Display(tkwin); - TkWinDCState state; - HDC dc = TkWinGetDrawableDC(display, drawable, &state); - int half; - - if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) { - TkpGetShadows(borderPtr, tkwin); - } - - switch (relief) { - case TK_RELIEF_RAISED: - left = (leftBevel) - ? borderPtr->lightGC->foreground - : borderPtr->darkGC->foreground; - right = (leftBevel) - ? ((WinBorder *)borderPtr)->light2ColorPtr->pixel - : ((WinBorder *)borderPtr)->dark2ColorPtr->pixel; - break; - case TK_RELIEF_SUNKEN: - left = (leftBevel) - ? borderPtr->darkGC->foreground - : ((WinBorder *)borderPtr)->light2ColorPtr->pixel; - right = (leftBevel) - ? ((WinBorder *)borderPtr)->dark2ColorPtr->pixel - : borderPtr->lightGC->foreground; - break; - case TK_RELIEF_RIDGE: - left = borderPtr->lightGC->foreground; - right = borderPtr->darkGC->foreground; - break; - case TK_RELIEF_GROOVE: - left = borderPtr->darkGC->foreground; - right = borderPtr->lightGC->foreground; - break; - case TK_RELIEF_FLAT: - left = right = borderPtr->bgGC->foreground; - break; - case TK_RELIEF_SOLID: - default: - left = right = RGB(0,0,0); - break; - } - half = width/2; - if (leftBevel && (width & 1)) { - half++; - } - TkWinFillRect(dc, x, y, half, height, left); - TkWinFillRect(dc, x+half, y, width-half, height, right); - TkWinReleaseDrawableDC(drawable, dc, &state); -} - -/* - *-------------------------------------------------------------- - * - * Tk_3DHorizontalBevel -- - * - * This procedure draws a horizontal bevel along one side of an object. - * The bevel has mitered corners (depending on leftIn and rightIn - * arguments). - * - * Results: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------- - */ - -void -Tk_3DHorizontalBevel( - Tk_Window tkwin, /* Window for which border was allocated. */ - Drawable drawable, /* X window or pixmap in which to draw. */ - Tk_3DBorder border, /* Token for border to draw. */ - int x, int y, int width, int height, - /* Bounding box of area of bevel. Height gives - * width of border. */ - int leftIn, int rightIn, /* Describes whether the left and right edges - * of the bevel angle in or out as they go - * down. For example, if "leftIn" is true, the - * left side of the bevel looks like this: - * ___________ - * __________ - * _________ - * ________ - */ - int topBevel, /* Non-zero means this bevel forms the top - * side of the object; 0 means it forms the - * bottom side. */ - int relief) /* Kind of bevel to draw. For example, - * TK_RELIEF_RAISED means interior of object - * should appear higher than exterior. */ -{ - TkBorder *borderPtr = (TkBorder *) border; - Display *display = Tk_Display(tkwin); - int bottom, halfway, x1, x2, x1Delta, x2Delta; - TkWinDCState state; - HDC dc = TkWinGetDrawableDC(display, drawable, &state); - int topColor, bottomColor; - - if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) { - TkpGetShadows(borderPtr, tkwin); - } - - /* - * Compute a GC for the top half of the bevel and a GC for the bottom half - * (they're the same in many cases). - */ - - switch (relief) { - case TK_RELIEF_RAISED: - topColor = (topBevel) - ? borderPtr->lightGC->foreground - : borderPtr->darkGC->foreground; - bottomColor = (topBevel) - ? ((WinBorder *)borderPtr)->light2ColorPtr->pixel - : ((WinBorder *)borderPtr)->dark2ColorPtr->pixel; - break; - case TK_RELIEF_SUNKEN: - topColor = (topBevel) - ? borderPtr->darkGC->foreground - : ((WinBorder *)borderPtr)->light2ColorPtr->pixel; - bottomColor = (topBevel) - ? ((WinBorder *)borderPtr)->dark2ColorPtr->pixel - : borderPtr->lightGC->foreground; - break; - case TK_RELIEF_RIDGE: - topColor = borderPtr->lightGC->foreground; - bottomColor = borderPtr->darkGC->foreground; - break; - case TK_RELIEF_GROOVE: - topColor = borderPtr->darkGC->foreground; - bottomColor = borderPtr->lightGC->foreground; - break; - case TK_RELIEF_FLAT: - topColor = bottomColor = borderPtr->bgGC->foreground; - break; - case TK_RELIEF_SOLID: - default: - topColor = bottomColor = RGB(0,0,0); - } - - /* - * Compute various other geometry-related stuff. - */ - - if (leftIn) { - x1 = x+1; - } else { - x1 = x+height-1; - } - x2 = x+width; - if (rightIn) { - x2--; - } else { - x2 -= height; - } - x1Delta = (leftIn) ? 1 : -1; - x2Delta = (rightIn) ? -1 : 1; - halfway = y + height/2; - if (topBevel && (height & 1)) { - halfway++; - } - bottom = y + height; - - /* - * Draw one line for each y-coordinate covered by the bevel. - */ - - for ( ; y < bottom; y++) { - /* - * In some weird cases (such as large border widths for skinny - * rectangles) x1 can be >= x2. Don't draw the lines in these cases. - */ - - if (x1 < x2) { - TkWinFillRect(dc, x1, y, x2-x1, 1, - (y < halfway) ? topColor : bottomColor); - } - x1 += x1Delta; - x2 += x2Delta; - } - TkWinReleaseDrawableDC(drawable, dc, &state); -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetShadows -- - * - * This procedure computes the shadow colors for a 3-D border and fills - * in the corresponding fields of the Border structure. It's called - * lazily, so that the colors aren't allocated until something is - * actually drawn with them. That way, if a border is only used for flat - * backgrounds the shadow colors will never be allocated. - * - * Results: - * None. - * - * Side effects: - * The lightGC and darkGC fields in borderPtr get filled in, if they - * weren't already. - * - *---------------------------------------------------------------------- - */ - -void -TkpGetShadows( - TkBorder *borderPtr, /* Information about border. */ - Tk_Window tkwin) /* Window where border will be used for - * drawing. */ -{ - XColor lightColor, darkColor; - int tmp1, tmp2; - int r, g, b; - XGCValues gcValues; - - if (borderPtr->lightGC != None) { - return; - } - - /* - * Handle the special case of the default system colors. - */ - - if ((TkWinIndexOfColor(borderPtr->bgColorPtr) == COLOR_3DFACE) - || (TkWinIndexOfColor(borderPtr->bgColorPtr) == COLOR_WINDOW)) { - borderPtr->darkColorPtr = Tk_GetColor(NULL, tkwin, - Tk_GetUid("SystemButtonShadow")); - gcValues.foreground = borderPtr->darkColorPtr->pixel; - borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues); - borderPtr->lightColorPtr = Tk_GetColor(NULL, tkwin, - Tk_GetUid("SystemButtonHighlight")); - gcValues.foreground = borderPtr->lightColorPtr->pixel; - borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues); - ((WinBorder*)borderPtr)->dark2ColorPtr = Tk_GetColor(NULL, tkwin, - Tk_GetUid("System3dDarkShadow")); - ((WinBorder*)borderPtr)->light2ColorPtr = Tk_GetColor(NULL, tkwin, - Tk_GetUid("System3dLight")); - return; - } - darkColor.red = 0; - darkColor.green = 0; - darkColor.blue = 0; - ((WinBorder*)borderPtr)->dark2ColorPtr = Tk_GetColorByValue(tkwin, - &darkColor); - lightColor = *(borderPtr->bgColorPtr); - ((WinBorder*)borderPtr)->light2ColorPtr = Tk_GetColorByValue(tkwin, - &lightColor); - - /* - * First, handle the case of a color display with lots of colors. The - * shadow colors get computed using whichever formula results in the - * greatest change in color: - * 1. Lighter shadow is half-way to white, darker shadow is half way to - * dark. - * 2. Lighter shadow is 40% brighter than background, darker shadow is 40% - * darker than background. - */ - - if (Tk_Depth(tkwin) >= 6) { - /* - * This is a color display with lots of colors. For the dark shadow, - * cut 40% from each of the background color components. But if the - * background is already very dark, make the dark color a little - * lighter than the background by increasing each color component - * 1/4th of the way to MAX_INTENSITY. - * - * For the light shadow, boost each component by 40% or half-way to - * white, whichever is greater (the first approach works better for - * unsaturated colors, the second for saturated ones). But if the - * background is already very bright, instead choose a slightly darker - * color for the light shadow by reducing each color component by 10%. - * - * Compute the colors using integers, not using lightColor.red etc.: - * these are shorts and may have problems with integer overflow. - */ - - /* - * Compute the dark shadow color - */ - - r = (int) borderPtr->bgColorPtr->red; - g = (int) borderPtr->bgColorPtr->green; - b = (int) borderPtr->bgColorPtr->blue; - - if (r*0.5*r + g*1.0*g + b*0.28*b < MAX_INTENSITY*0.05*MAX_INTENSITY) { - darkColor.red = (MAX_INTENSITY + 3*r)/4; - darkColor.green = (MAX_INTENSITY + 3*g)/4; - darkColor.blue = (MAX_INTENSITY + 3*b)/4; - } else { - darkColor.red = (60 * r)/100; - darkColor.green = (60 * g)/100; - darkColor.blue = (60 * b)/100; - } - - /* - * Allocate the dark shadow color and its GC - */ - - borderPtr->darkColorPtr = Tk_GetColorByValue(tkwin, &darkColor); - gcValues.foreground = borderPtr->darkColorPtr->pixel; - borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues); - - /* - * Compute the light shadow color - */ - - if (g > MAX_INTENSITY*0.95) { - lightColor.red = (90 * r)/100; - lightColor.green = (90 * g)/100; - lightColor.blue = (90 * b)/100; - } else { - tmp1 = (14 * r)/10; - if (tmp1 > MAX_INTENSITY) { - tmp1 = MAX_INTENSITY; - } - tmp2 = (MAX_INTENSITY + r)/2; - lightColor.red = (tmp1 > tmp2) ? tmp1 : tmp2; - tmp1 = (14 * g)/10; - if (tmp1 > MAX_INTENSITY) { - tmp1 = MAX_INTENSITY; - } - tmp2 = (MAX_INTENSITY + g)/2; - lightColor.green = (tmp1 > tmp2) ? tmp1 : tmp2; - tmp1 = (14 * b)/10; - if (tmp1 > MAX_INTENSITY) { - tmp1 = MAX_INTENSITY; - } - tmp2 = (MAX_INTENSITY + b)/2; - lightColor.blue = (tmp1 > tmp2) ? tmp1 : tmp2; - } - - /* - * Allocate the light shadow color and its GC - */ - - borderPtr->lightColorPtr = Tk_GetColorByValue(tkwin, &lightColor); - gcValues.foreground = borderPtr->lightColorPtr->pixel; - borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues); - return; - } - - if (borderPtr->shadow == None) { - borderPtr->shadow = Tk_GetBitmap((Tcl_Interp *) NULL, tkwin, - Tk_GetUid("gray50")); - if (borderPtr->shadow == None) { - Tcl_Panic("TkpGetShadows couldn't allocate bitmap for border"); - } - } - if (borderPtr->visual->map_entries > 2) { - /* - * This isn't a monochrome display, but the colormap either ran out of - * entries or didn't have very many to begin with. Generate the light - * shadows with a white stipple and the dark shadows with a black - * stipple. - */ - - gcValues.foreground = borderPtr->bgColorPtr->pixel; - gcValues.background = BlackPixelOfScreen(borderPtr->screen); - gcValues.stipple = borderPtr->shadow; - gcValues.fill_style = FillOpaqueStippled; - borderPtr->darkGC = Tk_GetGC(tkwin, - GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues); - gcValues.foreground = WhitePixelOfScreen(borderPtr->screen); - gcValues.background = borderPtr->bgColorPtr->pixel; - borderPtr->lightGC = Tk_GetGC(tkwin, - GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues); - return; - } - - /* - * This is just a measly monochrome display, hardly even worth its - * existence on this earth. Make one shadow a 50% stipple and the other - * the opposite of the background. - */ - - gcValues.foreground = WhitePixelOfScreen(borderPtr->screen); - gcValues.background = BlackPixelOfScreen(borderPtr->screen); - gcValues.stipple = borderPtr->shadow; - gcValues.fill_style = FillOpaqueStippled; - borderPtr->lightGC = Tk_GetGC(tkwin, - GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues); - if (borderPtr->bgColorPtr->pixel - == WhitePixelOfScreen(borderPtr->screen)) { - gcValues.foreground = BlackPixelOfScreen(borderPtr->screen); - borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues); - } else { - borderPtr->darkGC = borderPtr->lightGC; - borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWinGetBorderPixels -- - * - * This routine returns the 5 COLORREFs used to draw a given 3d border. - * - * Results: - * Returns the colors in the specified array. - * - * Side effects: - * May cause the remaining colors to be allocated. - * - *---------------------------------------------------------------------- - */ - -COLORREF -TkWinGetBorderPixels( - Tk_Window tkwin, - Tk_3DBorder border, - int which) /* One of TK_3D_FLAT_GC, TK_3D_LIGHT_GC, - * TK_3D_DARK_GC, TK_3D_LIGHT2, TK_3D_DARK2 */ -{ - WinBorder *borderPtr = (WinBorder *) border; - - if (borderPtr->info.lightGC == None) { - TkpGetShadows(&borderPtr->info, tkwin); - } - switch (which) { - case TK_3D_FLAT_GC: - return borderPtr->info.bgColorPtr->pixel; - case TK_3D_LIGHT_GC: - if (borderPtr->info.lightColorPtr == NULL) { - return WhitePixelOfScreen(borderPtr->info.screen); - } - return borderPtr->info.lightColorPtr->pixel; - case TK_3D_DARK_GC: - if (borderPtr->info.darkColorPtr == NULL) { - return BlackPixelOfScreen(borderPtr->info.screen); - } - return borderPtr->info.darkColorPtr->pixel; - case TK_3D_LIGHT2: - return borderPtr->light2ColorPtr->pixel; - case TK_3D_DARK2: - return borderPtr->dark2ColorPtr->pixel; - } - return 0; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinButton.c b/tk8.6/win/tkWinButton.c deleted file mode 100644 index e46bcb3..0000000 --- a/tk8.6/win/tkWinButton.c +++ /dev/null @@ -1,1307 +0,0 @@ -/* - * tkWinButton.c -- - * - * This file implements the Windows specific portion of the button - * widgets. - * - * Copyright (c) 1996-1998 by Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#define OEMRESOURCE -#include "tkWinInt.h" -#include "tkButton.h" - -/* - * These macros define the base style flags for the different button types. - */ - -#define LABEL_STYLE (BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS) -#define PUSH_STYLE (LABEL_STYLE | BS_PUSHBUTTON) -#define CHECK_STYLE (LABEL_STYLE | BS_CHECKBOX) -#define RADIO_STYLE (LABEL_STYLE | BS_RADIOBUTTON) - -/* - * Declaration of Windows specific button structure. - */ - -typedef struct WinButton { - TkButton info; /* Generic button info. */ - WNDPROC oldProc; /* Old window procedure. */ - HWND hwnd; /* Current window handle. */ - Pixmap pixmap; /* Bitmap for rendering the button. */ - DWORD style; /* Window style flags. */ -} WinButton; - -/* - * The following macro reverses the order of RGB bytes to convert between - * RGBQUAD and COLORREF values. - */ - -#define FlipColor(rgb) (RGB(GetBValue(rgb),GetGValue(rgb),GetRValue(rgb))) - -/* - * The following enumeration defines the meaning of the palette entries in the - * "buttons" image used to draw checkbox and radiobutton indicators. - */ - -enum { - PAL_CHECK = 0, - PAL_TOP_OUTER = 1, - PAL_BOTTOM_OUTER = 2, - PAL_BOTTOM_INNER = 3, - PAL_INTERIOR = 4, - PAL_TOP_INNER = 5, - PAL_BACKGROUND = 6 -}; - -/* - * Cached information about the boxes bitmap, and the default border width for - * a button in string form for use in Tk_OptionSpec for the various button - * widget classes. - */ - -typedef struct ThreadSpecificData { - BITMAPINFOHEADER *boxesPtr; /* Information about the bitmap. */ - DWORD *boxesPalette; /* Pointer to color palette. */ - LPSTR boxesBits; /* Pointer to bitmap data. */ - DWORD boxHeight; /* Height of each sub-image. */ - DWORD boxWidth; /* Width of each sub-image. */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -/* - * Declarations for functions defined in this file. - */ - -static LRESULT CALLBACK ButtonProc(HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam); -static Window CreateProc(Tk_Window tkwin, Window parent, - ClientData instanceData); -static void InitBoxes(void); - -/* - * The class procedure table for the button widgets. - */ - -const Tk_ClassProcs tkpButtonProcs = { - sizeof(Tk_ClassProcs), /* size */ - TkButtonWorldChanged, /* worldChangedProc */ - CreateProc, /* createProc */ - NULL /* modalProc */ -}; - - -/* - *---------------------------------------------------------------------- - * - * InitBoxes -- - * - * This function load the Tk 3d button bitmap. "buttons" is a 16 color - * bitmap that is laid out such that the top row contains the 4 checkbox - * images, and the bottom row contains the radio button images. Note that - * the bitmap is stored in bottom-up format. Also, the first seven - * palette entries are used to identify the different parts of the - * bitmaps so we can do the appropriate color mappings based on the - * current button colors. - * - * Results: - * None. - * - * Side effects: - * Loads the "buttons" resource. - * - *---------------------------------------------------------------------- - */ - -static void -InitBoxes(void) -{ - /* - * For DLLs like Tk, the HINSTANCE is the same as the HMODULE. - */ - - HMODULE module = (HINSTANCE) Tk_GetHINSTANCE(); - HRSRC hrsrc; - HGLOBAL hblk; - LPBITMAPINFOHEADER newBitmap; - DWORD size; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - hrsrc = FindResource(module, TEXT("buttons"), RT_BITMAP); - if (hrsrc == NULL) { - Tcl_Panic("FindResource() failed for buttons bitmap resource, " - "resources in tk_base.rc must be linked into Tk dll or static executable"); - } else { - hblk = LoadResource(module, hrsrc); - tsdPtr->boxesPtr = (LPBITMAPINFOHEADER)LockResource(hblk); - } - - /* - * Copy the DIBitmap into writable memory. - */ - - if (tsdPtr->boxesPtr != NULL && !(tsdPtr->boxesPtr->biWidth % 4) - && !(tsdPtr->boxesPtr->biHeight % 2)) { - size = tsdPtr->boxesPtr->biSize + (1 << tsdPtr->boxesPtr->biBitCount) - * sizeof(RGBQUAD) + tsdPtr->boxesPtr->biSizeImage; - newBitmap = ckalloc(size); - memcpy(newBitmap, tsdPtr->boxesPtr, size); - tsdPtr->boxesPtr = newBitmap; - tsdPtr->boxWidth = tsdPtr->boxesPtr->biWidth / 4; - tsdPtr->boxHeight = tsdPtr->boxesPtr->biHeight / 2; - tsdPtr->boxesPalette = (DWORD*) (((LPSTR) tsdPtr->boxesPtr) - + tsdPtr->boxesPtr->biSize); - tsdPtr->boxesBits = ((LPSTR) tsdPtr->boxesPalette) - + ((1 << tsdPtr->boxesPtr->biBitCount) * sizeof(RGBQUAD)); - } else { - tsdPtr->boxesPtr = NULL; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpButtonSetDefaults -- - * - * This procedure is invoked before option tables are created for - * buttons. It modifies some of the default values to match the current - * values defined for this platform. - * - * Results: - * Some of the default values in *specPtr are modified. - * - * Side effects: - * Updates some of. - * - *---------------------------------------------------------------------- - */ - -void -TkpButtonSetDefaults() -{ - int width = GetSystemMetrics(SM_CXEDGE); - if (width > 0) { - sprintf(tkDefButtonBorderWidth, "%d", width); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpCreateButton -- - * - * Allocate a new TkButton structure. - * - * Results: - * Returns a newly allocated TkButton structure. - * - * Side effects: - * Registers an event handler for the widget. - * - *---------------------------------------------------------------------- - */ - -TkButton * -TkpCreateButton( - Tk_Window tkwin) -{ - WinButton *butPtr; - - butPtr = ckalloc(sizeof(WinButton)); - butPtr->hwnd = NULL; - return (TkButton *) butPtr; -} - -/* - *---------------------------------------------------------------------- - * - * CreateProc -- - * - * This function creates a new Button control, subclasses the instance, - * and generates a new Window object. - * - * Results: - * Returns the newly allocated Window object, or None on failure. - * - * Side effects: - * Causes a new Button control to come into existence. - * - *---------------------------------------------------------------------- - */ - -static Window -CreateProc( - Tk_Window tkwin, /* Token for window. */ - Window parentWin, /* Parent of new window. */ - ClientData instanceData) /* Button instance data. */ -{ - Window window; - HWND parent; - const TCHAR *class; - WinButton *butPtr = (WinButton *)instanceData; - - parent = Tk_GetHWND(parentWin); - if (butPtr->info.type == TYPE_LABEL) { - class = TEXT("STATIC"); - butPtr->style = SS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; - } else { - class = TEXT("BUTTON"); - butPtr->style = BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; - } - butPtr->hwnd = CreateWindow(class, NULL, butPtr->style, - Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), - parent, NULL, Tk_GetHINSTANCE(), NULL); - SetWindowPos(butPtr->hwnd, HWND_TOP, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - butPtr->oldProc = (WNDPROC)SetWindowLongPtr(butPtr->hwnd, GWLP_WNDPROC, - (LONG_PTR) ButtonProc); - - window = Tk_AttachHWND(tkwin, butPtr->hwnd); - return window; -} - -/* - *---------------------------------------------------------------------- - * - * TkpDestroyButton -- - * - * Free data structures associated with the button control. - * - * Results: - * None. - * - * Side effects: - * Restores the default control state. - * - *---------------------------------------------------------------------- - */ - -void -TkpDestroyButton( - TkButton *butPtr) -{ - WinButton *winButPtr = (WinButton *)butPtr; - HWND hwnd = winButPtr->hwnd; - - if (hwnd) { - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) winButPtr->oldProc); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpDisplayButton -- - * - * This procedure is invoked to display a button widget. It is normally - * invoked as an idle handler. - * - * Results: - * None. - * - * Side effects: - * Information appears on the screen. The REDRAW_PENDING flag is cleared. - * - *---------------------------------------------------------------------- - */ - -void -TkpDisplayButton( - ClientData clientData) /* Information about widget. */ -{ - TkWinDCState state; - HDC dc; - register TkButton *butPtr = (TkButton *) clientData; - GC gc; - Tk_3DBorder border; - Pixmap pixmap; - int x = 0; /* Initialization only needed to stop compiler - * warning. */ - int y, relief; - register Tk_Window tkwin = butPtr->tkwin; - int width = 0, height = 0, haveImage = 0, haveText = 0, drawRing = 0; - RECT rect; - int defaultWidth; /* Width of default ring. */ - int offset; /* 0 means this is a label widget. 1 means it - * is a flavor of button, so we offset the - * text to make the button appear to move up - * and down as the relief changes. */ - int textXOffset = 0, textYOffset = 0; - /* Text offsets for use with compound buttons - * and focus ring. */ - int imageWidth, imageHeight; - int imageXOffset = 0, imageYOffset = 0; - /* Image information that will be used to - * restrict disabled pixmap as well. */ - DWORD *boxesPalette; - - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - boxesPalette= tsdPtr->boxesPalette; - butPtr->flags &= ~REDRAW_PENDING; - if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { - return; - } - - border = butPtr->normalBorder; - if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) { - gc = butPtr->disabledGC; - } else if ((butPtr->state == STATE_ACTIVE) - && !Tk_StrictMotif(butPtr->tkwin)) { - gc = butPtr->activeTextGC; - border = butPtr->activeBorder; - } else { - gc = butPtr->normalTextGC; - } - if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE) - && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) { - border = butPtr->selectBorder; - } - - /* - * Override the relief specified for the button if this is a checkbutton - * or radiobutton and there's no indicator. The new relief is as follows: - * If the button is select --> "sunken" - * If relief==overrelief --> relief - * Otherwise --> overrelief - * - * The effect we are trying to achieve is as follows: - * - * value mouse-over? --> relief - * ------- ------------ -------- - * off no flat - * off yes raised - * on no sunken - * on yes sunken - * - * This is accomplished by configuring the checkbutton or radiobutton like - * this: - * - * -indicatoron 0 -overrelief raised -offrelief flat - * - * Bindings (see library/button.tcl) will copy the -overrelief into - * -relief on mouseover. Hence, we can tell if we are in mouse-over by - * comparing relief against overRelief. This is an aweful kludge, but it - * gives use the desired behavior while keeping the code backwards - * compatible. - */ - - relief = butPtr->relief; - if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) { - if (butPtr->flags & SELECTED) { - relief = TK_RELIEF_SUNKEN; - } else if (butPtr->overRelief != relief) { - relief = butPtr->offRelief; - } - } - - /* - * Compute width of default ring and offset for pushed buttons. - */ - - if (butPtr->type == TYPE_BUTTON) { - defaultWidth = ((butPtr->defaultState == DEFAULT_ACTIVE) - ? butPtr->highlightWidth : 0); - offset = 1; - } else { - defaultWidth = 0; - if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) { - offset = 1; - } else { - offset = 0; - } - } - - /* - * In order to avoid screen flashes, this procedure redraws the button in - * a pixmap, then copies the pixmap to the screen in a single operation. - * This means that there's no point in time where the on-sreen image has - * been cleared. - */ - - pixmap = Tk_GetPixmap(butPtr->display, Tk_WindowId(tkwin), - Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); - Tk_Fill3DRectangle(tkwin, pixmap, border, 0, 0, Tk_Width(tkwin), - Tk_Height(tkwin), 0, TK_RELIEF_FLAT); - - /* - * Display image or bitmap or text for button. - */ - - if (butPtr->image != None) { - Tk_SizeOfImage(butPtr->image, &width, &height); - haveImage = 1; - } else if (butPtr->bitmap != None) { - Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); - haveImage = 1; - } - imageWidth = width; - imageHeight = height; - - haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0); - - if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) { - int fullWidth = 0, fullHeight = 0; - - switch ((enum compound) butPtr->compound) { - case COMPOUND_TOP: - case COMPOUND_BOTTOM: - /* - * Image is above or below text. - */ - - if (butPtr->compound == COMPOUND_TOP) { - textYOffset = height + butPtr->padY; - } else { - imageYOffset = butPtr->textHeight + butPtr->padY; - } - fullHeight = height + butPtr->textHeight + butPtr->padY; - fullWidth = (width > butPtr->textWidth ? width : - butPtr->textWidth); - textXOffset = (fullWidth - butPtr->textWidth)/2; - imageXOffset = (fullWidth - width)/2; - break; - - case COMPOUND_LEFT: - case COMPOUND_RIGHT: - /* - * Image is left or right of text. - */ - - if (butPtr->compound == COMPOUND_LEFT) { - textXOffset = width + butPtr->padX; - } else { - imageXOffset = butPtr->textWidth + butPtr->padX; - } - fullWidth = butPtr->textWidth + butPtr->padX + width; - fullHeight = (height > butPtr->textHeight ? height : - butPtr->textHeight); - textYOffset = (fullHeight - butPtr->textHeight)/2; - imageYOffset = (fullHeight - height)/2; - break; - - case COMPOUND_CENTER: - /* - * Image and text are superimposed. - */ - - fullWidth = (width > butPtr->textWidth ? width : - butPtr->textWidth); - fullHeight = (height > butPtr->textHeight ? height : - butPtr->textHeight); - textXOffset = (fullWidth - butPtr->textWidth)/2; - imageXOffset = (fullWidth - width)/2; - textYOffset = (fullHeight - butPtr->textHeight)/2; - imageYOffset = (fullHeight - height)/2; - break; - case COMPOUND_NONE: - break; - } - TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY, - butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y); - x += butPtr->indicatorSpace; - - if (relief == TK_RELIEF_SUNKEN) { - x += offset; - y += offset; - } - imageXOffset += x; - imageYOffset += y; - if (butPtr->image != NULL) { - if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) { - Tk_RedrawImage(butPtr->selectImage, 0, 0, - width, height, pixmap, imageXOffset, imageYOffset); - } else if ((butPtr->tristateImage != NULL) - && (butPtr->flags & TRISTATED)) { - Tk_RedrawImage(butPtr->tristateImage, 0, 0, - width, height, pixmap, imageXOffset, imageYOffset); - } else { - Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, - imageXOffset, imageYOffset); - } - } else { - XSetClipOrigin(butPtr->display, gc, imageXOffset, imageYOffset); - XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, - 0, 0, (unsigned int) width, (unsigned int) height, - imageXOffset, imageYOffset, 1); - XSetClipOrigin(butPtr->display, gc, 0, 0); - } - if ((butPtr->state == STATE_DISABLED) && - (butPtr->disabledFg != NULL)) { - COLORREF oldFgColor = gc->foreground; - - if (gc->background == GetSysColor(COLOR_BTNFACE)) { - gc->foreground = GetSysColor(COLOR_3DHILIGHT); - Tk_DrawTextLayout(butPtr->display, pixmap, gc, - butPtr->textLayout, x + textXOffset + 1, - y + textYOffset + 1, 0, -1); - Tk_UnderlineTextLayout(butPtr->display, pixmap, gc, - butPtr->textLayout, x + textXOffset + 1, - y + textYOffset + 1, - butPtr->underline); - gc->foreground = oldFgColor; - } - } - - Tk_DrawTextLayout(butPtr->display, pixmap, gc, - butPtr->textLayout, x + textXOffset, y + textYOffset, 0, -1); - Tk_UnderlineTextLayout(butPtr->display, pixmap, gc, - butPtr->textLayout, x + textXOffset, y + textYOffset, - butPtr->underline); - height = fullHeight; - drawRing = 1; - } else { - if (haveImage) { - TkComputeAnchor(butPtr->anchor, tkwin, 0, 0, - butPtr->indicatorSpace + width, height, &x, &y); - x += butPtr->indicatorSpace; - - if (relief == TK_RELIEF_SUNKEN) { - x += offset; - y += offset; - } - imageXOffset += x; - imageYOffset += y; - if (butPtr->image != NULL) { - if ((butPtr->selectImage != NULL) && - (butPtr->flags & SELECTED)) { - Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, - pixmap, imageXOffset, imageYOffset); - } else if ((butPtr->tristateImage != NULL) && - (butPtr->flags & TRISTATED)) { - Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, - pixmap, imageXOffset, imageYOffset); - } else { - Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, - imageXOffset, imageYOffset); - } - } else { - XSetClipOrigin(butPtr->display, gc, x, y); - XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0, - (unsigned int) width, (unsigned int) height, x, y, 1); - XSetClipOrigin(butPtr->display, gc, 0, 0); - } - } else { - TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY, - butPtr->indicatorSpace + butPtr->textWidth, - butPtr->textHeight, &x, &y); - - x += butPtr->indicatorSpace; - - if (relief == TK_RELIEF_SUNKEN) { - x += offset; - y += offset; - } - if ((butPtr->state == STATE_DISABLED) && - (butPtr->disabledFg != NULL)) { - COLORREF oldFgColor = gc->foreground; - if (gc->background == GetSysColor(COLOR_BTNFACE)) { - gc->foreground = GetSysColor(COLOR_3DHILIGHT); - Tk_DrawTextLayout(butPtr->display, pixmap, gc, - butPtr->textLayout, - x + 1, y + 1, 0, -1); - Tk_UnderlineTextLayout(butPtr->display, pixmap, gc, - butPtr->textLayout, x + 1, y + 1, butPtr->underline); - gc->foreground = oldFgColor; - } - } - Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout, - x, y, 0, -1); - Tk_UnderlineTextLayout(butPtr->display, pixmap, gc, - butPtr->textLayout, x, y, butPtr->underline); - - height = butPtr->textHeight; - drawRing = 1; - } - } - - /* - * Draw the focus ring. If this is a push button then we need to put it - * around the inner edge of the border, otherwise we put it around the - * text. The text offsets are only non-zero when this is a compound - * button. - */ - - if (drawRing && butPtr->flags & GOT_FOCUS && butPtr->type != TYPE_LABEL) { - dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state); - if (butPtr->type == TYPE_BUTTON || !butPtr->indicatorOn) { - rect.top = butPtr->borderWidth + 1 + defaultWidth; - rect.left = rect.top; - rect.right = Tk_Width(tkwin) - rect.left; - rect.bottom = Tk_Height(tkwin) - rect.top; - } else { - rect.top = y-1 + textYOffset; - rect.left = x-1 + textXOffset; - rect.right = x+butPtr->textWidth + 1 + textXOffset; - rect.bottom = y+butPtr->textHeight + 2 + textYOffset; - } - SetTextColor(dc, gc->foreground); - SetBkColor(dc, gc->background); - DrawFocusRect(dc, &rect); - TkWinReleaseDrawableDC(pixmap, dc, &state); - } - - y += height/2; - - /* - * Draw the indicator for check buttons and radio buttons. At this point x - * and y refer to the top-left corner of the text or image or bitmap. - */ - - if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn - && tsdPtr->boxesPtr) { - int xSrc, ySrc; - - x -= butPtr->indicatorSpace; - y -= butPtr->indicatorDiameter / 2; - - xSrc = (butPtr->flags & (SELECTED|TRISTATED)) ? tsdPtr->boxWidth : 0; - if (butPtr->state == STATE_ACTIVE) { - xSrc += tsdPtr->boxWidth*2; - } - ySrc = (butPtr->type == TYPE_RADIO_BUTTON) ? 0 : tsdPtr->boxHeight; - - /* - * Update the palette in the boxes bitmap to reflect the current - * button colors. Note that this code relies on the layout of the - * bitmap's palette. Also, all of the colors used to draw the bitmap - * must be in the palette that is selected into the DC of the - * offscreen pixmap. This requires that the static colors be placed - * into the palette. - */ - - if ((butPtr->state == STATE_DISABLED) - && (butPtr->disabledFg == NULL)) { - boxesPalette[PAL_CHECK] = FlipColor(TkWinGetBorderPixels(tkwin, - border, TK_3D_DARK_GC)); - } else { - boxesPalette[PAL_CHECK] = FlipColor(gc->foreground); - } - boxesPalette[PAL_TOP_OUTER] = FlipColor(TkWinGetBorderPixels(tkwin, - border, TK_3D_DARK_GC)); - boxesPalette[PAL_TOP_INNER] = FlipColor(TkWinGetBorderPixels(tkwin, - border, TK_3D_DARK2)); - boxesPalette[PAL_BOTTOM_INNER] = FlipColor(TkWinGetBorderPixels(tkwin, - border, TK_3D_LIGHT2)); - boxesPalette[PAL_BOTTOM_OUTER] = FlipColor(TkWinGetBorderPixels(tkwin, - border, TK_3D_LIGHT_GC)); - if ((butPtr->state == STATE_DISABLED) || (butPtr->flags & TRISTATED)) { - boxesPalette[PAL_INTERIOR] = FlipColor(TkWinGetBorderPixels(tkwin, - border, TK_3D_LIGHT2)); - } else if (butPtr->selectBorder != NULL) { - boxesPalette[PAL_INTERIOR] = FlipColor(TkWinGetBorderPixels(tkwin, - butPtr->selectBorder, TK_3D_FLAT_GC)); - } else { - boxesPalette[PAL_INTERIOR] = FlipColor(GetSysColor(COLOR_WINDOW)); - } - boxesPalette[PAL_BACKGROUND] = FlipColor(TkWinGetBorderPixels(tkwin, - border, TK_3D_FLAT_GC)); - - dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state); - StretchDIBits(dc, x, y, (int)tsdPtr->boxWidth, (int)tsdPtr->boxHeight, - xSrc, ySrc, (int)tsdPtr->boxWidth, (int)tsdPtr->boxHeight, - tsdPtr->boxesBits, (LPBITMAPINFO) tsdPtr->boxesPtr, - DIB_RGB_COLORS, SRCCOPY); - TkWinReleaseDrawableDC(pixmap, dc, &state); - } - - /* - * If the button is disabled with a stipple rather than a special - * foreground color, generate the stippled effect. If the widget is - * selected and we use a different background color when selected, must - * temporarily modify the GC so the stippling is the right color. - */ - - if ((butPtr->state == STATE_DISABLED) - && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) { - if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn - && (butPtr->selectBorder != NULL)) { - XSetForeground(butPtr->display, butPtr->stippleGC, - Tk_3DBorderColor(butPtr->selectBorder)->pixel); - } - - /* - * Stipple the whole button if no disabledFg was specified, otherwise - * restrict stippling only to displayed image - */ - - if (butPtr->disabledFg == NULL) { - XFillRectangle(butPtr->display, pixmap, butPtr->stippleGC, 0, 0, - (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin)); - } else { - XFillRectangle(butPtr->display, pixmap, butPtr->stippleGC, - imageXOffset, imageYOffset, - (unsigned) imageWidth, (unsigned) imageHeight); - } - if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn - && (butPtr->selectBorder != NULL)) { - XSetForeground(butPtr->display, butPtr->stippleGC, - Tk_3DBorderColor(butPtr->normalBorder)->pixel); - } - } - - /* - * Draw the border and traversal highlight last. This way, if the button's - * contents overflow they'll be covered up by the border. - */ - - if (relief != TK_RELIEF_FLAT) { - Tk_Draw3DRectangle(tkwin, pixmap, border, - defaultWidth, defaultWidth, - Tk_Width(tkwin) - 2*defaultWidth, - Tk_Height(tkwin) - 2*defaultWidth, - butPtr->borderWidth, relief); - } - if (defaultWidth != 0) { - dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state); - TkWinFillRect(dc, 0, 0, Tk_Width(tkwin), defaultWidth, - (int) butPtr->highlightColorPtr->pixel); - TkWinFillRect(dc, 0, 0, defaultWidth, Tk_Height(tkwin), - (int) butPtr->highlightColorPtr->pixel); - TkWinFillRect(dc, 0, Tk_Height(tkwin) - defaultWidth, - Tk_Width(tkwin), defaultWidth, - (int) butPtr->highlightColorPtr->pixel); - TkWinFillRect(dc, Tk_Width(tkwin) - defaultWidth, 0, - defaultWidth, Tk_Height(tkwin), - (int) butPtr->highlightColorPtr->pixel); - TkWinReleaseDrawableDC(pixmap, dc, &state); - } - - if (butPtr->flags & GOT_FOCUS) { - Tk_SetCaretPos(tkwin, x, y, 0 /* not used */); - } - - /* - * Copy the information from the off-screen pixmap onto the screen, then - * delete the pixmap. - */ - - XCopyArea(butPtr->display, pixmap, Tk_WindowId(tkwin), - butPtr->copyGC, 0, 0, (unsigned) Tk_Width(tkwin), - (unsigned) Tk_Height(tkwin), 0, 0); - Tk_FreePixmap(butPtr->display, pixmap); -} - -/* - *---------------------------------------------------------------------- - * - * TkpComputeButtonGeometry -- - * - * After changes in a button's text or bitmap, this procedure recomputes - * the button's geometry and passes this information along to the - * geometry manager for the window. - * - * Results: - * None. - * - * Side effects: - * The button's window may change size. - * - *---------------------------------------------------------------------- - */ - -void -TkpComputeButtonGeometry( - register TkButton *butPtr) /* Button whose geometry may have changed. */ -{ - int txtWidth, txtHeight; /* Width and height of text */ - int imgWidth, imgHeight; /* Width and height of image */ - int width = 0, height = 0; /* Width and height of button */ - int haveImage, haveText; - int avgWidth; - int minWidth; - /* Vertical and horizontal dialog units size in pixels. */ - double vDLU, hDLU; - Tk_FontMetrics fm; - - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (butPtr->highlightWidth < 0) { - butPtr->highlightWidth = 0; - } - butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth; - butPtr->indicatorSpace = 0; - - if (!tsdPtr->boxesPtr) { - InitBoxes(); - } - - /* - * Figure out image metrics. - */ - - if (butPtr->image != NULL) { - Tk_SizeOfImage(butPtr->image, &imgWidth, &imgHeight); - haveImage = 1; - } else if (butPtr->bitmap != None) { - Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, - &imgWidth, &imgHeight); - haveImage = 1; - } else { - imgWidth = 0; - imgHeight = 0; - haveImage = 0; - } - - /* - * Figure out font metrics (even if we don't have text because we need - * DLUs (based on font, not text) for some spacing calculations below). - */ - - Tk_FreeTextLayout(butPtr->textLayout); - butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont, - Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength, - butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight); - - txtWidth = butPtr->textWidth; - txtHeight = butPtr->textHeight; - haveText = (*(Tcl_GetString(butPtr->textPtr)) != '\0'); - avgWidth = (Tk_TextWidth(butPtr->tkfont, - "abcdefghijklmnopqurstuvwzyABCDEFGHIJKLMNOPQURSTUVWZY", - 52) + 26) / 52; - Tk_GetFontMetrics(butPtr->tkfont, &fm); - - /* - * Compute dialog units for layout calculations. - */ - - hDLU = avgWidth / 4.0; - vDLU = fm.linespace / 8.0; - - /* - * First, let's try to compute button size "by the book" (See "Microsoft - * Windows User Experience" (ISBN 0-7356-0566-1), Chapter 14 - Visual - * Design, Section 4 - Layout (page 448)). - * - * Note, that Tk "buttons" are Microsoft "Command buttons", Tk - * "checkbuttons" are Microsoft "check boxes", Tk "radiobuttons" are - * Microsoft "option buttons", and Tk "labels" are Microsoft "text - * labels". - */ - - /* - * Set width and height by button type; See User Experience table, p449. - * These are text-based measurements, even if the text is "". If there is - * an image, height will get set again later. - */ - - switch (butPtr->type) { - case TYPE_BUTTON: - /* - * First compute the minimum width of the button in characters. MWUE - * says that the button should be 50 DLUs. We allow 6 DLUs padding - * left and right. (There is no rule but this is consistent with the - * fact that button text is 8 DLUs high and buttons are 14 DLUs high.) - * - * The width is specified in characters. A character is, by - * definition, 4 DLUs wide. 11 char * 4 DLU is 44 DLU + 6 DLU padding - * = 50 DLU. Therefore, width = -11 -> MWUE compliant buttons. - */ - - if (butPtr->width < 0) { - minWidth = -(butPtr->width); /* Min width in chars */ - width = avgWidth * minWidth; /* Allow for characters */ - width += (int)(0.5 + (6 * hDLU)); /* Add for padding */ - } - - /* - * If shrink-wrapping was requested (width = 0) or if the text is - * wider than the default button width, adjust the button width up to - * suit. - */ - - if (butPtr->width == 0 - || (txtWidth + (int)(0.5 + (6 * hDLU)) > width)) { - width = txtWidth + (int)(0.5 + (6 * hDLU)); - } - - /* - * The User Experience says 14 DLUs. Since text is, by definition, 8 - * DLU/line, this allows for multi-line text while working perfectly - * for single-line text. - */ - - height = txtHeight + (int)(0.5 + (6 * vDLU)); - - /* - * The above includes 6 DLUs of padding which should include defaults - * of 1 pixel of highlightwidth, 2 pixels of borderwidth, 1 pixel of - * padding and 1 pixel of extra inset on each side. Those will be - * added later so reduce width and height now to compensate. - */ - - width -= 10; - height -= 10; - - if (!haveImage) { - /* - * Extra inset for the focus ring. - */ - - butPtr->inset += 1; - } - break; - - case TYPE_LABEL: - /* - * The User Experience says, "as wide as needed". - */ - - width = txtWidth; - - /* - * The User Experience says, "8 (DLUs) per line of text". Since text - * is, by definition, 8 DLU/line, this allows for multi-line text - * while working perfectly for single-line text. - */ - - if (txtHeight) { - height = txtHeight; - } else { - /* - * If there's no text, we want the height to be one linespace. - */ - height = fm.linespace; - } - break; - - case TYPE_RADIO_BUTTON: - case TYPE_CHECK_BUTTON: { - /* - * See note for TYPE_LABEL. - */ - - width = txtWidth; - - /* - * The User Experience says 10 DLUs. (Is that one DLU above and below - * for the focus ring?) See note above about multi-line text and 8 - * DLU/line. - */ - - height = txtHeight + (int)(0.5 + (2.0 * vDLU)); - - /* - * The above includes 2 DLUs of padding which should include defaults - * of 1 pixel of highlightwidth, 0 pixels of borderwidth, and 1 pixel - * of padding on each side. Those will be added later so reduce height - * now to compensate. - */ - - height -= 4; - - /* - * Extra inset for the focus ring. - */ - butPtr->inset += 1; - break; - } - }/* switch */ - - /* - * At this point, the width and height are correct for a Tk text button, - * excluding padding and inset, but we have to allow for compound buttons. - * The image may be above, below, left, or right of the text. - */ - - /* - * If the button is compound (i.e., it shows both an image and text), the - * new geometry is a combination of the image and text geometry. We only - * honor the compound bit if the button has both text and an image, - * because otherwise it is not really a compound button. - */ - - if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) { - switch ((enum compound) butPtr->compound) { - case COMPOUND_TOP: - case COMPOUND_BOTTOM: - /* - * Image is above or below text. - */ - - if (imgWidth > width) { - width = imgWidth; - } - height += imgHeight + butPtr->padY; - break; - - case COMPOUND_LEFT: - case COMPOUND_RIGHT: - - /* - * Image is left or right of text. - * - * Only increase width of button if image doesn't fit in slack - * space of default button width - */ - - if ((imgWidth + txtWidth + butPtr->padX) > width) { - width = imgWidth + txtWidth + butPtr->padX; - } - - if (imgHeight > height) { - height = imgHeight; - } - break; - - case COMPOUND_CENTER: - /* - * Image and text are superimposed. - */ - - if (imgWidth > width) { - width = imgWidth; - } - if (imgHeight > height) { - height = imgHeight; - } - break; - case COMPOUND_NONE: - break; - } /* switch */ - - /* - * Fix up for minimum width. - */ - - if (butPtr->width < 0) { - /* - * minWidth in pixels (because there's an image. - */ - - minWidth = -(butPtr->width); - if (width < minWidth) { - width = minWidth; - } - } else if (butPtr->width > 0) { - width = butPtr->width; - } - - if (butPtr->height > 0) { - height = butPtr->height; - } - - width += 2*butPtr->padX; - height += 2*butPtr->padY; - } else if (haveImage) { - if (butPtr->width > 0) { - width = butPtr->width; - } else { - width = imgWidth; - } - if (butPtr->height > 0) { - height = butPtr->height; - } else { - height = imgHeight; - } - } else { - /* - * No image. May or may not be text. May or may not be compound. - */ - - /* - * butPtr->width is in characters. We need to allow for that many - * characters on the face, not in the over-all button width - */ - - if (butPtr->width > 0) { - width = butPtr->width * avgWidth; - } - - /* - * butPtr->height is in lines of text. We need to allow for that many - * lines on the face, not in the over-all button height. - */ - - if (butPtr->height > 0) { - height = butPtr->height * fm.linespace; - - /* - * Make the same adjustments as above to get same height for e.g. - * a one line text with -height 0 or 1. [Bug #565485] - */ - - switch (butPtr->type) { - case TYPE_BUTTON: { - height += (int)(0.5 + (6 * vDLU)) - 10; - break; - } - case TYPE_RADIO_BUTTON: - case TYPE_CHECK_BUTTON: { - height += (int)(0.5 + (2.0 * vDLU)) - 4; - break; - } - } - } - - width += 2 * butPtr->padX; - height += 2 * butPtr->padY; - } - - /* - * Fix up width and height for indicator sizing and spacing. - */ - - if (butPtr->type == TYPE_RADIO_BUTTON - || butPtr->type == TYPE_CHECK_BUTTON) { - if (butPtr->indicatorOn) { - butPtr->indicatorDiameter = tsdPtr->boxHeight; - - /* - * Make sure we can see the whole indicator, even if the text or - * image is very small. - */ - - if (height < butPtr->indicatorDiameter) { - height = butPtr->indicatorDiameter; - } - - /* - * There is no rule for space between the indicator and the text - * (the two are atomic on 'Windows) but the User Experience page - * 451 says leave 3 hDLUs between "text labels and their - * associated controls". - */ - - butPtr->indicatorSpace = butPtr->indicatorDiameter + - (int)(0.5 + (3.0 * hDLU)); - width += butPtr->indicatorSpace; - } - } - - /* - * Inset is always added to the size. - */ - - width += 2 * butPtr->inset; - height += 2 * butPtr->inset; - - Tk_GeometryRequest(butPtr->tkwin, width, height); - Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset); -} - -/* - *---------------------------------------------------------------------- - * - * ButtonProc -- - * - * This function is call by Windows whenever an event occurs on a button - * control created by Tk. - * - * Results: - * Standard Windows return value. - * - * Side effects: - * May generate events. - * - *---------------------------------------------------------------------- - */ - -static LRESULT CALLBACK -ButtonProc( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - LRESULT result; - WinButton *butPtr; - Tk_Window tkwin = Tk_HWNDToWindow(hwnd); - - if (tkwin == NULL) { - Tcl_Panic("ButtonProc called on an invalid HWND"); - } - butPtr = (WinButton *)((TkWindow*)tkwin)->instanceData; - - switch(message) { - case WM_ERASEBKGND: - return 0; - - case BM_GETCHECK: - if (((butPtr->info.type == TYPE_CHECK_BUTTON) - || (butPtr->info.type == TYPE_RADIO_BUTTON)) - && butPtr->info.indicatorOn) { - return (butPtr->info.flags & SELECTED) - ? BST_CHECKED : BST_UNCHECKED; - } - return 0; - - case BM_GETSTATE: { - DWORD state = 0; - - if (((butPtr->info.type == TYPE_CHECK_BUTTON) - || (butPtr->info.type == TYPE_RADIO_BUTTON)) - && butPtr->info.indicatorOn) { - state = (butPtr->info.flags & SELECTED) - ? BST_CHECKED : BST_UNCHECKED; - } - if (butPtr->info.flags & GOT_FOCUS) { - state |= BST_FOCUS; - } - return state; - } - case WM_ENABLE: - break; - - case WM_PAINT: { - PAINTSTRUCT ps; - BeginPaint(hwnd, &ps); - EndPaint(hwnd, &ps); - TkpDisplayButton((ClientData)butPtr); - - /* - * Special note: must cancel any existing idle handler for - * TkpDisplayButton; it's no longer needed, and TkpDisplayButton - * cleared the REDRAW_PENDING flag. - */ - - Tcl_CancelIdleCall(TkpDisplayButton, (ClientData)butPtr); - return 0; - } - case BN_CLICKED: { - /* - * 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_ServiceAll(); - return 0; - } - } - - default: - if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) { - return result; - } - } - return DefWindowProc(hwnd, message, wParam, lParam); -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinClipboard.c b/tk8.6/win/tkWinClipboard.c deleted file mode 100644 index 03c0cde..0000000 --- a/tk8.6/win/tkWinClipboard.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * tkWinClipboard.c -- - * - * This file contains functions for managing the clipboard. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-2000 by Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" -#include "tkSelect.h" -#include <shlobj.h> /* for DROPFILES */ - -static void UpdateClipboard(HWND hwnd); - -/* - *---------------------------------------------------------------------- - * - * TkSelGetSelection -- - * - * Retrieve the specified selection from another process. For now, only - * fetching XA_STRING from CLIPBOARD is supported. Eventually other types - * should be allowed. - * - * Results: - * The return value is a standard Tcl return value. If an error occurs - * (such as no selection exists) then an error message is left in the - * interp's result. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkSelGetSelection( - Tcl_Interp *interp, /* Interpreter to use for reporting errors. */ - Tk_Window tkwin, /* Window on whose behalf to retrieve the - * selection (determines display from which to - * retrieve). */ - Atom selection, /* Selection to retrieve. */ - Atom target, /* Desired form in which selection is to be - * returned. */ - Tk_GetSelProc *proc, /* Procedure to call to process the selection, - * once it has been retrieved. */ - ClientData clientData) /* Arbitrary value to pass to proc. */ -{ - char *data, *destPtr; - Tcl_DString ds; - HGLOBAL handle; - Tcl_Encoding encoding; - int result, locale, noBackslash = 0; - - if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD")) - || (target != XA_STRING) - || !OpenClipboard(NULL)) { - goto error; - } - - /* - * Attempt to get the data in Unicode form if available as this is less - * work that CF_TEXT. - */ - - result = TCL_ERROR; - if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { - handle = GetClipboardData(CF_UNICODETEXT); - if (!handle) { - CloseClipboard(); - goto error; - } - data = GlobalLock(handle); - Tcl_DStringInit(&ds); - Tcl_UniCharToUtfDString((Tcl_UniChar *)data, - Tcl_UniCharLen((Tcl_UniChar *)data), &ds); - GlobalUnlock(handle); - } else if (IsClipboardFormatAvailable(CF_TEXT)) { - /* - * Determine the encoding to use to convert this text. - */ - - if (IsClipboardFormatAvailable(CF_LOCALE)) { - handle = GetClipboardData(CF_LOCALE); - if (!handle) { - CloseClipboard(); - goto error; - } - - /* - * Get the locale identifier, determine the proper code page to - * use, and find the corresponding encoding. - */ - - Tcl_DStringInit(&ds); - Tcl_DStringAppend(&ds, "cp######", -1); - data = GlobalLock(handle); - - /* - * Even though the documentation claims that GetLocaleInfo expects - * an LCID, on Windows 9x it really seems to expect a LanguageID. - */ - - locale = LANGIDFROMLCID(*((int*)data)); - GetLocaleInfoA(locale, LOCALE_IDEFAULTANSICODEPAGE, - Tcl_DStringValue(&ds)+2, Tcl_DStringLength(&ds)-2); - GlobalUnlock(handle); - - encoding = Tcl_GetEncoding(NULL, Tcl_DStringValue(&ds)); - Tcl_DStringFree(&ds); - } else { - encoding = NULL; - } - - /* - * Fetch the text and convert it to UTF. - */ - - handle = GetClipboardData(CF_TEXT); - if (!handle) { - if (encoding) { - Tcl_FreeEncoding(encoding); - } - CloseClipboard(); - goto error; - } - data = GlobalLock(handle); - Tcl_ExternalToUtfDString(encoding, data, -1, &ds); - GlobalUnlock(handle); - 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; - } - - /* - * Translate CR/LF to LF. - */ - - data = destPtr = Tcl_DStringValue(&ds); - while (*data) { - if (data[0] == '\r' && data[1] == '\n') { - data++; - } else if (noBackslash && data[0] == '\\') { - data++; - *destPtr++ = '/'; - } else { - *destPtr++ = *data++; - } - } - *destPtr = '\0'; - - /* - * Pass the data off to the selection procedure. - */ - - result = proc(clientData, interp, Tcl_DStringValue(&ds)); - Tcl_DStringFree(&ds); - CloseClipboard(); - return result; - - error: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "%s selection doesn't exist or form \"%s\" not defined", - Tk_GetAtomName(tkwin, selection), Tk_GetAtomName(tkwin, target))); - Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL); - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * TkSetSelectionOwner -- - * - * This function claims ownership of the specified selection. If the - * selection is CLIPBOARD, then we empty the system clipboard. - * - * Results: - * None. - * - * Side effects: - * Empties the system clipboard, and claims ownership. - * - *---------------------------------------------------------------------- - */ - -int -XSetSelectionOwner( - Display *display, - Atom selection, - Window owner, - Time time) -{ - HWND hwnd = owner ? TkWinGetHWND(owner) : NULL; - Tk_Window tkwin; - - /* - * This is a gross hack because the Tk_InternAtom interface is broken. It - * expects a Tk_Window, even though it only needs a Tk_Display. - */ - - tkwin = (Tk_Window) TkGetMainInfoList()->winPtr; - - if (selection == Tk_InternAtom(tkwin, "CLIPBOARD")) { - /* - * Only claim and empty the clipboard if we aren't already the owner - * of the clipboard. - */ - - if (GetClipboardOwner() != hwnd) { - UpdateClipboard(hwnd); - } - } - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinClipboardRender -- - * - * This function supplies the contents of the clipboard in response to a - * WM_RENDERFORMAT message. - * - * Results: - * None. - * - * Side effects: - * Sets the contents of the clipboard. - * - *---------------------------------------------------------------------- - */ - -void -TkWinClipboardRender( - TkDisplay *dispPtr, - UINT format) -{ - TkClipboardTarget *targetPtr; - TkClipboardBuffer *cbPtr; - HGLOBAL handle; - char *buffer, *p, *rawText, *endPtr; - int length; - Tcl_DString ds; - - for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL; - targetPtr = targetPtr->nextPtr) { - if (targetPtr->type == XA_STRING) { - break; - } - } - - /* - * Count the number of newlines so we can add space for them in the - * resulting string. - */ - - length = 0; - if (targetPtr != NULL) { - for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL; - cbPtr = cbPtr->nextPtr) { - length += cbPtr->length; - for (p = cbPtr->buffer, endPtr = p + cbPtr->length; - p < endPtr; p++) { - if (*p == '\n') { - length++; - } - } - } - } - - /* - * Copy the data and change EOL characters. - */ - - buffer = rawText = ckalloc(length + 1); - if (targetPtr != NULL) { - for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL; - cbPtr = cbPtr->nextPtr) { - for (p = cbPtr->buffer, endPtr = p + cbPtr->length; - p < endPtr; p++) { - if (*p == '\n') { - *buffer++ = '\r'; - } - *buffer++ = *p; - } - } - } - *buffer = '\0'; - - /* - * Depending on the platform, turn the data into Unicode or the system - * encoding before placing it on the clipboard. - */ - -#ifdef UNICODE - Tcl_DStringInit(&ds); - Tcl_WinUtfToTChar(rawText, -1, &ds); - ckfree(rawText); - handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, - (unsigned) Tcl_DStringLength(&ds) + 2); - if (!handle) { - Tcl_DStringFree(&ds); - return; - } - buffer = GlobalLock(handle); - memcpy(buffer, Tcl_DStringValue(&ds), - (unsigned) Tcl_DStringLength(&ds) + 2); - GlobalUnlock(handle); - Tcl_DStringFree(&ds); - SetClipboardData(CF_UNICODETEXT, handle); -#else - Tcl_UtfToExternalDString(NULL, rawText, -1, &ds); - ckfree(rawText); - handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, - (unsigned) Tcl_DStringLength(&ds) + 1); - if (!handle) { - Tcl_DStringFree(&ds); - return; - } - buffer = GlobalLock(handle); - memcpy(buffer, Tcl_DStringValue(&ds), - (unsigned) Tcl_DStringLength(&ds) + 1); - GlobalUnlock(handle); - Tcl_DStringFree(&ds); - SetClipboardData(CF_TEXT, handle); -#endif -} - -/* - *---------------------------------------------------------------------- - * - * TkSelUpdateClipboard -- - * - * This function is called to force the clipboard to be updated after new - * data is added. - * - * Results: - * None. - * - * Side effects: - * Clears the current contents of the clipboard. - * - *---------------------------------------------------------------------- - */ - -void -TkSelUpdateClipboard( - TkWindow *winPtr, - TkClipboardTarget *targetPtr) -{ - HWND hwnd = TkWinGetHWND(winPtr->window); - UpdateClipboard(hwnd); -} - -/* - *---------------------------------------------------------------------- - * - * UpdateClipboard -- - * - * Take ownership of the clipboard, clear it, and indicate to the system - * the supported formats. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateClipboard( - HWND hwnd) -{ - TkWinUpdatingClipboard(TRUE); - OpenClipboard(hwnd); - EmptyClipboard(); - - SetClipboardData(CF_UNICODETEXT, NULL); - CloseClipboard(); - TkWinUpdatingClipboard(FALSE); -} - -/* - *-------------------------------------------------------------- - * - * TkSelEventProc -- - * - * This procedure is invoked whenever a selection-related event occurs. - * - * Results: - * None. - * - * Side effects: - * Lots: depends on the type of event. - * - *-------------------------------------------------------------- - */ - -void -TkSelEventProc( - Tk_Window tkwin, /* Window for which event was targeted. */ - register XEvent *eventPtr) /* X event: either SelectionClear, - * SelectionRequest, or SelectionNotify. */ -{ - if (eventPtr->type == SelectionClear) { - TkSelClearSelection(tkwin, eventPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkSelPropProc -- - * - * This procedure is invoked when property-change events occur on windows - * not known to the toolkit. This is a stub function under Windows. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkSelPropProc( - register XEvent *eventPtr) /* X PropertyChange event. */ -{ -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinColor.c b/tk8.6/win/tkWinColor.c deleted file mode 100644 index ba9815c..0000000 --- a/tk8.6/win/tkWinColor.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * tkWinColor.c -- - * - * Functions to map color names to system color values. - * - * Copyright (c) 1995 Sun Microsystems, Inc. - * Copyright (c) 1994 Software Research Associates, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" -#include "tkColor.h" - -/* - * The following structure is used to keep track of each color that is - * allocated by this module. - */ - -typedef struct WinColor { - TkColor info; /* Generic color information. */ - int index; /* Index for GetSysColor(), -1 if color is not - * a "live" system color. */ -} WinColor; - -/* - * The sysColors array contains the names and index values for the Windows - * indirect system color names. In use, all of the names will have the string - * "System" prepended, but we omit it in the table to save space. - */ - -typedef struct { - const char *name; - int index; -} SystemColorEntry; - -static const SystemColorEntry sysColors[] = { - {"3dDarkShadow", COLOR_3DDKSHADOW}, - {"3dLight", COLOR_3DLIGHT}, - {"ActiveBorder", COLOR_ACTIVEBORDER}, - {"ActiveCaption", COLOR_ACTIVECAPTION}, - {"AppWorkspace", COLOR_APPWORKSPACE}, - {"Background", COLOR_BACKGROUND}, - {"ButtonFace", COLOR_BTNFACE}, - {"ButtonHighlight", COLOR_BTNHIGHLIGHT}, - {"ButtonShadow", COLOR_BTNSHADOW}, - {"ButtonText", COLOR_BTNTEXT}, - {"CaptionText", COLOR_CAPTIONTEXT}, - {"DisabledText", COLOR_GRAYTEXT}, - {"GrayText", COLOR_GRAYTEXT}, - {"Highlight", COLOR_HIGHLIGHT}, - {"HighlightText", COLOR_HIGHLIGHTTEXT}, - {"InactiveBorder", COLOR_INACTIVEBORDER}, - {"InactiveCaption", COLOR_INACTIVECAPTION}, - {"InactiveCaptionText", COLOR_INACTIVECAPTIONTEXT}, - {"InfoBackground", COLOR_INFOBK}, - {"InfoText", COLOR_INFOTEXT}, - {"Menu", COLOR_MENU}, - {"MenuText", COLOR_MENUTEXT}, - {"Scrollbar", COLOR_SCROLLBAR}, - {"Window", COLOR_WINDOW}, - {"WindowFrame", COLOR_WINDOWFRAME}, - {"WindowText", COLOR_WINDOWTEXT} -}; - -/* - * Forward declarations for functions defined later in this file. - */ - -static int FindSystemColor(const char *name, XColor *colorPtr, - int *indexPtr); - -/* - *---------------------------------------------------------------------- - * - * FindSystemColor -- - * - * This routine finds the color entry that corresponds to the specified - * color. - * - * Results: - * Returns non-zero on success. The RGB values of the XColor will be - * initialized to the proper values on success. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -FindSystemColor( - const char *name, /* Color name. */ - XColor *colorPtr, /* Where to store results. */ - int *indexPtr) /* Out parameter to store color index. */ -{ - int l, u, r, i; - int index; - - /* - * Perform a binary search on the sorted array of colors. - */ - - l = 0; - u = (sizeof(sysColors) / sizeof(sysColors[0])) - 1; - while (l <= u) { - i = (l + u) / 2; - r = strcasecmp(name, sysColors[i].name); - if (r == 0) { - break; - } else if (r < 0) { - u = i-1; - } else { - l = i+1; - } - } - if (l > u) { - return 0; - } - - *indexPtr = index = sysColors[i].index; - colorPtr->pixel = GetSysColor(index); - - /* - * x257 is (value<<8 + value) to get the properly bit shifted and padded - * value. [Bug: 4919] - */ - - colorPtr->red = GetRValue(colorPtr->pixel) * 257; - colorPtr->green = GetGValue(colorPtr->pixel) * 257; - colorPtr->blue = GetBValue(colorPtr->pixel) * 257; - colorPtr->flags = DoRed|DoGreen|DoBlue; - colorPtr->pad = 0; - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetColor -- - * - * Allocate a new TkColor for the color with the given name. - * - * Results: - * Returns a newly allocated TkColor, or NULL on failure. - * - * Side effects: - * May invalidate the colormap cache associated with tkwin upon - * allocating a new colormap entry. Allocates a new TkColor structure. - * - *---------------------------------------------------------------------- - */ - -TkColor * -TkpGetColor( - Tk_Window tkwin, /* Window in which color will be used. */ - Tk_Uid name) /* Name of color to allocated (in form - * suitable for passing to XParseColor). */ -{ - WinColor *winColPtr; - XColor color; - int index = -1; /* -1 indicates that this is not an indirect - * system color. */ - - /* - * Check to see if it is a system color or an X color string. If the color - * is found, allocate a new WinColor and store the XColor and the system - * color index. - */ - - if (((strncasecmp(name, "system", 6) == 0) - && FindSystemColor(name+6, &color, &index)) - || TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name, - &color)) { - winColPtr = ckalloc(sizeof(WinColor)); - winColPtr->info.color = color; - winColPtr->index = index; - - XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin), - &winColPtr->info.color); - return (TkColor *) winColPtr; - } - return (TkColor *) NULL; -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetColorByValue -- - * - * Given a desired set of red-green-blue intensities for a color, locate - * a pixel value to use to draw that color in a given window. - * - * Results: - * The return value is a pointer to an TkColor structure that indicates - * the closest red, blue, and green intensities available to those - * specified in colorPtr, and also specifies a pixel value to use to draw - * in that color. - * - * Side effects: - * May invalidate the colormap cache for the specified window. Allocates - * a new TkColor structure. - * - *---------------------------------------------------------------------- - */ - -TkColor * -TkpGetColorByValue( - Tk_Window tkwin, /* Window in which color will be used. */ - XColor *colorPtr) /* Red, green, and blue fields indicate - * desired color. */ -{ - WinColor *tkColPtr = ckalloc(sizeof(WinColor)); - - tkColPtr->info.color.red = colorPtr->red; - tkColPtr->info.color.green = colorPtr->green; - tkColPtr->info.color.blue = colorPtr->blue; - tkColPtr->info.color.pixel = 0; - tkColPtr->index = -1; - XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin), &tkColPtr->info.color); - return (TkColor *) tkColPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TkpFreeColor -- - * - * Release the specified color back to the system. - * - * Results: - * None - * - * Side effects: - * Invalidates the colormap cache for the colormap associated with the - * given color. - * - *---------------------------------------------------------------------- - */ - -void -TkpFreeColor( - TkColor *tkColPtr) /* Color to be released. Must have been - * allocated by TkpGetColor or - * TkpGetColorByValue. */ -{ - Screen *screen = tkColPtr->screen; - - XFreeColors(DisplayOfScreen(screen), tkColPtr->colormap, - &tkColPtr->color.pixel, 1, 0L); -} - -/* - *---------------------------------------------------------------------- - * - * TkWinIndexOfColor -- - * - * Given a color, return the system color index that was used to create - * the color. - * - * Results: - * If the color was allocated using a system indirect color name, then - * the corresponding GetSysColor() index is returned. Otherwise, -1 is - * returned. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkWinIndexOfColor( - XColor *colorPtr) -{ - register WinColor *winColPtr = (WinColor *) colorPtr; - if (winColPtr->info.magic == COLOR_MAGIC) { - return winColPtr->index; - } - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * XAllocColor -- - * - * Find the closest available color to the specified XColor. - * - * Results: - * Updates the color argument and returns 1 on success. Otherwise returns - * 0. - * - * Side effects: - * Allocates a new color in the palette. - * - *---------------------------------------------------------------------- - */ - -int -XAllocColor( - Display *display, - Colormap colormap, - XColor *color) -{ - TkWinColormap *cmap = (TkWinColormap *) colormap; - PALETTEENTRY entry, closeEntry; - HDC dc = GetDC(NULL); - - entry.peRed = (color->red) >> 8; - entry.peGreen = (color->green) >> 8; - entry.peBlue = (color->blue) >> 8; - entry.peFlags = 0; - - if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) { - unsigned long sizePalette = GetDeviceCaps(dc, SIZEPALETTE); - UINT newPixel, closePixel; - int new; - size_t refCount; - Tcl_HashEntry *entryPtr; - UINT index; - - /* - * Find the nearest existing palette entry. - */ - - newPixel = RGB(entry.peRed, entry.peGreen, entry.peBlue); - index = GetNearestPaletteIndex(cmap->palette, newPixel); - GetPaletteEntries(cmap->palette, index, 1, &closeEntry); - closePixel = RGB(closeEntry.peRed, closeEntry.peGreen, - closeEntry.peBlue); - - /* - * If this is not a duplicate, allocate a new entry. Note that we may - * get values for index that are above the current size of the - * palette. This happens because we don't shrink the size of the - * palette object when we deallocate colors so there may be stale - * values that match in the upper slots. We should ignore those values - * and just put the new color in as if the colors had not matched. - */ - - if ((index >= cmap->size) || (newPixel != closePixel)) { - if (cmap->size == sizePalette) { - color->red = closeEntry.peRed * 257; - color->green = closeEntry.peGreen * 257; - color->blue = closeEntry.peBlue * 257; - entry = closeEntry; - if (index >= cmap->size) { - OutputDebugStringA("XAllocColor: Colormap is bigger than we thought"); - } - } else { - cmap->size++; - ResizePalette(cmap->palette, cmap->size); - SetPaletteEntries(cmap->palette, cmap->size - 1, 1, &entry); - } - } - - color->pixel = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue); - entryPtr = Tcl_CreateHashEntry(&cmap->refCounts, - INT2PTR(color->pixel), &new); - if (new) { - refCount = 1; - } else { - refCount = (size_t)Tcl_GetHashValue(entryPtr) + 1; - } - Tcl_SetHashValue(entryPtr, (void *)refCount); - } else { - /* - * Determine what color will actually be used on non-colormap systems. - */ - - color->pixel = GetNearestColor(dc, - RGB(entry.peRed, entry.peGreen, entry.peBlue)); - color->red = GetRValue(color->pixel) * 257; - color->green = GetGValue(color->pixel) * 257; - color->blue = GetBValue(color->pixel) * 257; - } - - ReleaseDC(NULL, dc); - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * XFreeColors -- - * - * Deallocate a block of colors. - * - * Results: - * None. - * - * Side effects: - * Removes entries for the current palette and compacts the remaining - * set. - * - *---------------------------------------------------------------------- - */ - -int -XFreeColors( - Display *display, - Colormap colormap, - unsigned long *pixels, - int npixels, - unsigned long planes) -{ - TkWinColormap *cmap = (TkWinColormap *) colormap; - COLORREF cref; - UINT count, index; - size_t refCount; - int i; - PALETTEENTRY entry, *entries; - Tcl_HashEntry *entryPtr; - HDC dc = GetDC(NULL); - - /* - * We don't have to do anything for non-palette devices. - */ - - if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) { - /* - * This is really slow for large values of npixels. - */ - - for (i = 0; i < npixels; i++) { - entryPtr = Tcl_FindHashEntry(&cmap->refCounts, INT2PTR(pixels[i])); - if (!entryPtr) { - Tcl_Panic("Tried to free a color that isn't allocated"); - } - refCount = (size_t)Tcl_GetHashValue(entryPtr) - 1; - if (refCount == 0) { - cref = pixels[i] & 0x00ffffff; - index = GetNearestPaletteIndex(cmap->palette, cref); - GetPaletteEntries(cmap->palette, index, 1, &entry); - if (cref == RGB(entry.peRed, entry.peGreen, entry.peBlue)) { - count = cmap->size - index; - entries = ckalloc(sizeof(PALETTEENTRY) * count); - GetPaletteEntries(cmap->palette, index+1, count, entries); - SetPaletteEntries(cmap->palette, index, count, entries); - ckfree(entries); - cmap->size--; - } else { - Tcl_Panic("Tried to free a color that isn't allocated"); - } - Tcl_DeleteHashEntry(entryPtr); - } else { - Tcl_SetHashValue(entryPtr, (size_t)refCount); - } - } - } - ReleaseDC(NULL, dc); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XCreateColormap -- - * - * Allocate a new colormap. - * - * Results: - * Returns a newly allocated colormap. - * - * Side effects: - * Allocates an empty palette and color list. - * - *---------------------------------------------------------------------- - */ - -Colormap -XCreateColormap( - Display *display, - Window w, - Visual *visual, - int alloc) -{ - char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)]; - LOGPALETTE *logPalettePtr; - PALETTEENTRY *entryPtr; - TkWinColormap *cmap; - Tcl_HashEntry *hashPtr; - int new; - UINT i; - HPALETTE sysPal; - - /* - * Allocate a starting palette with all of the reserved colors. - */ - - logPalettePtr = (LOGPALETTE *) logPalBuf; - logPalettePtr->palVersion = 0x300; - sysPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); - logPalettePtr->palNumEntries = GetPaletteEntries(sysPal, 0, 256, - logPalettePtr->palPalEntry); - - cmap = ckalloc(sizeof(TkWinColormap)); - cmap->size = logPalettePtr->palNumEntries; - cmap->stale = 0; - cmap->palette = CreatePalette(logPalettePtr); - - /* - * Add hash entries for each of the static colors. - */ - - Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS); - for (i = 0; i < logPalettePtr->palNumEntries; i++) { - entryPtr = logPalettePtr->palPalEntry + i; - hashPtr = Tcl_CreateHashEntry(&cmap->refCounts, INT2PTR(PALETTERGB( - entryPtr->peRed, entryPtr->peGreen, entryPtr->peBlue)), &new); - Tcl_SetHashValue(hashPtr, INT2PTR(1)); - } - - return (Colormap)cmap; -} - -/* - *---------------------------------------------------------------------- - * - * XFreeColormap -- - * - * Frees the resources associated with the given colormap. - * - * Results: - * None. - * - * Side effects: - * Deletes the palette associated with the colormap. Note that the - * palette must not be selected into a device context when this occurs. - * - *---------------------------------------------------------------------- - */ - -int -XFreeColormap( - Display *display, - Colormap colormap) -{ - TkWinColormap *cmap = (TkWinColormap *) colormap; - - if (!DeleteObject(cmap->palette)) { - Tcl_Panic("Unable to free colormap, palette is still selected"); - } - Tcl_DeleteHashTable(&cmap->refCounts); - ckfree(cmap); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinSelectPalette -- - * - * This function sets up the specified device context with a given - * palette. If the palette is stale, it realizes it in the background - * unless the palette is the current global palette. - * - * Results: - * Returns the previous palette selected into the device context. - * - * Side effects: - * May change the system palette. - * - *---------------------------------------------------------------------- - */ - -HPALETTE -TkWinSelectPalette( - HDC dc, - Colormap colormap) -{ - TkWinColormap *cmap = (TkWinColormap *) colormap; - HPALETTE oldPalette; - - oldPalette = SelectPalette(dc, cmap->palette, - (cmap->palette == TkWinGetSystemPalette()) ? FALSE : TRUE); - RealizePalette(dc); - return oldPalette; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinConfig.c b/tk8.6/win/tkWinConfig.c deleted file mode 100644 index aeb9405..0000000 --- a/tk8.6/win/tkWinConfig.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * tkWinConfig.c -- - * - * This module implements the Windows system defaults for the - * configuration package. - * - * Copyright (c) 1997 by Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - - -/* - *---------------------------------------------------------------------- - * - * TkpGetSystemDefault -- - * - * Given a dbName and className for a configuration option, return a - * string representation of the option. - * - * Results: - * Returns a Tk_Uid that is the string identifier that identifies this - * option. Returns NULL if there are no system defaults that match this - * pair. - * - * Side effects: - * None, once the package is initialized. - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj * -TkpGetSystemDefault( - Tk_Window tkwin, /* A window to use. */ - const char *dbName, /* The option database name. */ - const char *className) /* The name of the option class. */ -{ - Tcl_Obj *valueObjPtr; - Tk_Uid classUid; - - if (tkwin == NULL) { - return NULL; - } - - valueObjPtr = NULL; - classUid = Tk_Class(tkwin); - - if (strcmp(classUid, "Menu") == 0) { - valueObjPtr = TkWinGetMenuSystemDefault(tkwin, dbName, className); - } - - return valueObjPtr; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinCursor.c b/tk8.6/win/tkWinCursor.c deleted file mode 100644 index 622ba4d..0000000 --- a/tk8.6/win/tkWinCursor.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * tkWinCursor.c -- - * - * This file contains Win32 specific cursor related routines. - * - * Copyright (c) 1995 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - -/* - * The following data structure contains the system specific data necessary to - * control Windows cursors. - */ - -typedef struct { - TkCursor info; /* Generic cursor info used by tkCursor.c */ - HCURSOR winCursor; /* Win32 cursor handle. */ - int system; /* 1 if cursor is a system cursor, else 0. */ -} TkWinCursor; - -/* - * The HAND cursor is only present when WINVER >= 0x0500. If this is not - * available at runtime, it will default to the unix-style cursor. - */ - -#ifndef IDC_HAND -#define IDC_HAND MAKEINTRESOURCE(32649) -#endif -#ifndef IDC_HELP -#define IDC_HELP MAKEINTRESOURCE(32651) -#endif - -/* - * The table below is used to map from the name of a predefined cursor to its - * resource identifier. - */ - -static struct CursorName { - const char *name; - LPCTSTR id; -} cursorNames[] = { - {"starting", IDC_APPSTARTING}, - {"arrow", IDC_ARROW}, - {"ibeam", IDC_IBEAM}, - {"icon", IDC_ICON}, - {"no", IDC_NO}, - {"size", IDC_SIZEALL}, - {"size_ne_sw", IDC_SIZENESW}, - {"size_ns", IDC_SIZENS}, - {"size_nw_se", IDC_SIZENWSE}, - {"size_we", IDC_SIZEWE}, - {"uparrow", IDC_UPARROW}, - {"wait", IDC_WAIT}, - {"crosshair", IDC_CROSS}, - {"fleur", IDC_SIZEALL}, - {"sb_v_double_arrow", IDC_SIZENS}, - {"sb_h_double_arrow", IDC_SIZEWE}, - {"center_ptr", IDC_UPARROW}, - {"watch", IDC_WAIT}, - {"xterm", IDC_IBEAM}, - {"hand2", IDC_HAND}, - {"question_arrow", IDC_HELP}, - {NULL, 0} -}; - -/* - * The default cursor is used whenever no other cursor has been specified. - */ - -#define TK_DEFAULT_CURSOR IDC_ARROW - -/* - *---------------------------------------------------------------------- - * - * TkGetCursorByName -- - * - * Retrieve a system cursor by name. - * - * Results: - * Returns a new cursor, or NULL on errors. - * - * Side effects: - * Allocates a new cursor. - * - *---------------------------------------------------------------------- - */ - -TkCursor * -TkGetCursorByName( - Tcl_Interp *interp, /* Interpreter to use for error reporting. */ - Tk_Window tkwin, /* Window in which cursor will be used. */ - Tk_Uid string) /* Description of cursor. See manual entry for - * details on legal syntax. */ -{ - struct CursorName *namePtr; - TkWinCursor *cursorPtr; - int argc; - const char **argv = NULL; - - /* - * All cursor names are valid lists of one element (for - * Unix-compatability), even unadorned system cursor names. - */ - - if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) { - return NULL; - } - if (argc == 0) { - goto badCursorSpec; - } - - cursorPtr = ckalloc(sizeof(TkWinCursor)); - cursorPtr->info.cursor = (Tk_Cursor) cursorPtr; - cursorPtr->winCursor = NULL; - cursorPtr->system = 0; - - if (argv[0][0] == '@') { - /* - * Check for system cursor of type @<filename>, where only the name is - * allowed. This accepts any of: - * -cursor @/winnt/cursors/globe.ani - * -cursor @C:/Winnt/cursors/E_arrow.cur - * -cursor {@C:/Program\ Files/Cursors/bart.ani} - * -cursor {{@C:/Program Files/Cursors/bart.ani}} - * -cursor [list @[file join "C:/Program Files" Cursors bart.ani]] - */ - - if (Tcl_IsSafe(interp)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "can't get cursor from a file in a safe interpreter",-1)); - Tcl_SetErrorCode(interp, "TK", "SAFE", "CURSOR_FILE", NULL); - ckfree(argv); - ckfree(cursorPtr); - return NULL; - } - cursorPtr->winCursor = LoadCursorFromFileA(&(argv[0][1])); - } else { - /* - * Check for the cursor in the system cursor set. - */ - - for (namePtr = cursorNames; namePtr->name != NULL; namePtr++) { - if (strcmp(namePtr->name, argv[0]) == 0) { - cursorPtr->winCursor = LoadCursor(NULL, namePtr->id); - break; - } - } - - if (cursorPtr->winCursor == NULL) { - /* - * Hmm, it is not in the system cursor set. Check to see if it is - * one of our application resources. - */ - - cursorPtr->winCursor = LoadCursorA(Tk_GetHINSTANCE(), argv[0]); - } else { - cursorPtr->system = 1; - } - } - - if (cursorPtr->winCursor == NULL) { - ckfree(cursorPtr); - badCursorSpec: - ckfree(argv); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad cursor spec \"%s\"", string)); - Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", NULL); - return NULL; - } - ckfree(argv); - return (TkCursor *) cursorPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TkCreateCursorFromData -- - * - * Creates a cursor from the source and mask bits. - * - * Results: - * Returns a new cursor, or NULL on errors. - * - * Side effects: - * Allocates a new cursor. - * - *---------------------------------------------------------------------- - */ - -TkCursor * -TkCreateCursorFromData( - Tk_Window tkwin, /* Window in which cursor will be used. */ - const char *source, /* Bitmap data for cursor shape. */ - const char *mask, /* Bitmap data for cursor mask. */ - int width, int height, /* Dimensions of cursor. */ - int xHot, int yHot, /* Location of hot-spot in cursor. */ - XColor fgColor, /* Foreground color for cursor. */ - XColor bgColor) /* Background color for cursor. */ -{ - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * TkpFreeCursor -- - * - * This procedure is called to release a cursor allocated by - * TkGetCursorByName. - * - * Results: - * None. - * - * Side effects: - * The cursor data structure is deallocated. - * - *---------------------------------------------------------------------- - */ - -void -TkpFreeCursor( - TkCursor *cursorPtr) -{ - /* TkWinCursor *winCursorPtr = (TkWinCursor *) cursorPtr; */ -} - -/* - *---------------------------------------------------------------------- - * - * TkpSetCursor -- - * - * Set the global cursor. If the cursor is None, then use the default Tk - * cursor. - * - * Results: - * None. - * - * Side effects: - * Changes the mouse cursor. - * - *---------------------------------------------------------------------- - */ - -void -TkpSetCursor( - TkpCursor cursor) -{ - HCURSOR hcursor; - TkWinCursor *winCursor = (TkWinCursor *) cursor; - - if (winCursor == NULL || winCursor->winCursor == NULL) { - hcursor = LoadCursor(NULL, TK_DEFAULT_CURSOR); - } else { - hcursor = winCursor->winCursor; - } - - if (hcursor != NULL) { - SetCursor(hcursor); - } -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinDefault.h b/tk8.6/win/tkWinDefault.h deleted file mode 100644 index f389075..0000000 --- a/tk8.6/win/tkWinDefault.h +++ /dev/null @@ -1,536 +0,0 @@ -/* - * tkWinDefault.h -- - * - * This file defines the defaults for all options for all of - * the Tk widgets. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#ifndef _TKWINDEFAULT -#define _TKWINDEFAULT - -/* - * The definitions below provide symbolic names for the default colors. - * NORMAL_BG - Normal background color. - * ACTIVE_BG - Background color when widget is active. - * SELECT_BG - Background color for selected text. - * TROUGH - Background color for troughs in scales and scrollbars. - * INDICATOR - Color for indicator when button is selected. - * DISABLED - Foreground color when widget is disabled. - */ - -#define BLACK "Black" -#define WHITE "White" - -#define NORMAL_BG "SystemButtonFace" -#define NORMAL_FG "SystemButtonText" -#define ACTIVE_BG NORMAL_BG -#define TEXT_FG "SystemWindowText" -#define SELECT_BG "SystemHighlight" -#define SELECT_FG "SystemHighlightText" -#define TROUGH "SystemScrollbar" -#define INDICATOR "SystemWindow" -#define DISABLED "SystemDisabledText" -#define MENU_BG "SystemMenu" -#define MENU_FG "SystemMenuText" -#define HIGHLIGHT "SystemWindowFrame" - -/* - * Defaults for labels, buttons, checkbuttons, and radiobuttons: - */ - -#define DEF_BUTTON_ANCHOR "center" -#define DEF_BUTTON_ACTIVE_BG_COLOR NORMAL_BG -#define DEF_BUTTON_ACTIVE_BG_MONO BLACK -#define DEF_BUTTON_ACTIVE_FG_COLOR NORMAL_FG -#define DEF_CHKRAD_ACTIVE_FG_COLOR TEXT_FG -#define DEF_BUTTON_ACTIVE_FG_MONO WHITE -#define DEF_BUTTON_BG_COLOR NORMAL_BG -#define DEF_BUTTON_BG_MONO WHITE -#define DEF_BUTTON_BITMAP "" -#define DEF_BUTTON_BORDER_WIDTH "2" -#define DEF_BUTTON_CURSOR "" -#define DEF_BUTTON_COMMAND "" -#define DEF_BUTTON_COMPOUND "none" -#define DEF_BUTTON_DEFAULT "disabled" -#define DEF_BUTTON_DISABLED_FG_COLOR DISABLED -#define DEF_BUTTON_DISABLED_FG_MONO "" -#define DEF_BUTTON_FG NORMAL_FG -#define DEF_CHKRAD_FG TEXT_FG -#define DEF_BUTTON_FONT "TkDefaultFont" -#define DEF_BUTTON_HEIGHT "0" -#define DEF_BUTTON_HIGHLIGHT_BG_COLOR DEF_BUTTON_BG_COLOR -#define DEF_BUTTON_HIGHLIGHT_BG_MONO DEF_BUTTON_BG_MONO -#define DEF_BUTTON_HIGHLIGHT HIGHLIGHT -#define DEF_LABEL_HIGHLIGHT_WIDTH "0" -#define DEF_BUTTON_HIGHLIGHT_WIDTH "1" -#define DEF_BUTTON_IMAGE ((char *) NULL) -#define DEF_BUTTON_INDICATOR "1" -#define DEF_BUTTON_JUSTIFY "center" -#define DEF_BUTTON_OFF_VALUE "0" -#define DEF_BUTTON_ON_VALUE "1" -#define DEF_BUTTON_OVER_RELIEF "" -#define DEF_BUTTON_PADX "1" -#define DEF_LABCHKRAD_PADX "1" -#define DEF_BUTTON_PADY "1" -#define DEF_LABCHKRAD_PADY "1" -#define DEF_BUTTON_RELIEF "raised" -#define DEF_LABCHKRAD_RELIEF "flat" -#define DEF_BUTTON_REPEAT_DELAY "0" -#define DEF_BUTTON_REPEAT_INTERVAL "0" -#define DEF_BUTTON_SELECT_COLOR INDICATOR -#define DEF_BUTTON_SELECT_MONO BLACK -#define DEF_BUTTON_SELECT_IMAGE ((char *) NULL) -#define DEF_BUTTON_STATE "normal" -#define DEF_LABEL_TAKE_FOCUS "0" -#define DEF_BUTTON_TAKE_FOCUS ((char *) NULL) -#define DEF_BUTTON_TEXT "" -#define DEF_BUTTON_TEXT_VARIABLE "" -#define DEF_BUTTON_TRISTATE_VALUE "" -#define DEF_BUTTON_UNDERLINE "-1" -#define DEF_BUTTON_VALUE "" -#define DEF_BUTTON_WIDTH "0" -#define DEF_BUTTON_WRAP_LENGTH "0" -#define DEF_RADIOBUTTON_VARIABLE "selectedButton" -#define DEF_CHECKBUTTON_VARIABLE "" - -/* - * Defaults for canvases: - */ - -#define DEF_CANVAS_BG_COLOR NORMAL_BG -#define DEF_CANVAS_BG_MONO WHITE -#define DEF_CANVAS_BORDER_WIDTH "0" -#define DEF_CANVAS_CLOSE_ENOUGH "1" -#define DEF_CANVAS_CONFINE "1" -#define DEF_CANVAS_CURSOR "" -#define DEF_CANVAS_HEIGHT "7c" -#define DEF_CANVAS_HIGHLIGHT_BG NORMAL_BG -#define DEF_CANVAS_HIGHLIGHT HIGHLIGHT -#define DEF_CANVAS_HIGHLIGHT_WIDTH "2" -#define DEF_CANVAS_INSERT_BG NORMAL_FG -#define DEF_CANVAS_INSERT_BD_COLOR "0" -#define DEF_CANVAS_INSERT_BD_MONO "0" -#define DEF_CANVAS_INSERT_OFF_TIME "300" -#define DEF_CANVAS_INSERT_ON_TIME "600" -#define DEF_CANVAS_INSERT_WIDTH "2" -#define DEF_CANVAS_RELIEF "flat" -#define DEF_CANVAS_SCROLL_REGION "" -#define DEF_CANVAS_SELECT_COLOR SELECT_BG -#define DEF_CANVAS_SELECT_MONO BLACK -#define DEF_CANVAS_SELECT_BD_COLOR "1" -#define DEF_CANVAS_SELECT_BD_MONO "0" -#define DEF_CANVAS_SELECT_FG_COLOR SELECT_FG -#define DEF_CANVAS_SELECT_FG_MONO WHITE -#define DEF_CANVAS_TAKE_FOCUS ((char *) NULL) -#define DEF_CANVAS_WIDTH "10c" -#define DEF_CANVAS_X_SCROLL_CMD "" -#define DEF_CANVAS_X_SCROLL_INCREMENT "0" -#define DEF_CANVAS_Y_SCROLL_CMD "" -#define DEF_CANVAS_Y_SCROLL_INCREMENT "0" - -/* - * Defaults for entries: - */ - -#define DEF_ENTRY_BG_COLOR "SystemWindow" -#define DEF_ENTRY_BG_MONO WHITE -#define DEF_ENTRY_BORDER_WIDTH "1" -#define DEF_ENTRY_CURSOR "xterm" -#define DEF_ENTRY_DISABLED_BG_COLOR "SystemButtonFace" -#define DEF_ENTRY_DISABLED_BG_MONO WHITE -#define DEF_ENTRY_DISABLED_FG DISABLED -#define DEF_ENTRY_EXPORT_SELECTION "1" -#define DEF_ENTRY_FONT "TkTextFont" -#define DEF_ENTRY_FG TEXT_FG -#define DEF_ENTRY_HIGHLIGHT_BG NORMAL_BG -#define DEF_ENTRY_HIGHLIGHT HIGHLIGHT -#define DEF_ENTRY_HIGHLIGHT_WIDTH "0" -#define DEF_ENTRY_INSERT_BG TEXT_FG -#define DEF_ENTRY_INSERT_BD_COLOR "0" -#define DEF_ENTRY_INSERT_BD_MONO "0" -#define DEF_ENTRY_INSERT_OFF_TIME "300" -#define DEF_ENTRY_INSERT_ON_TIME "600" -#define DEF_ENTRY_INSERT_WIDTH "2" -#define DEF_ENTRY_JUSTIFY "left" -#define DEF_ENTRY_READONLY_BG_COLOR "SystemButtonFace" -#define DEF_ENTRY_READONLY_BG_MONO WHITE -#define DEF_ENTRY_RELIEF "sunken" -#define DEF_ENTRY_SCROLL_COMMAND "" -#define DEF_ENTRY_SELECT_COLOR SELECT_BG -#define DEF_ENTRY_SELECT_MONO BLACK -#define DEF_ENTRY_SELECT_BD_COLOR "0" -#define DEF_ENTRY_SELECT_BD_MONO "0" -#define DEF_ENTRY_SELECT_FG_COLOR SELECT_FG -#define DEF_ENTRY_SELECT_FG_MONO WHITE -#define DEF_ENTRY_SHOW ((char *) NULL) -#define DEF_ENTRY_STATE "normal" -#define DEF_ENTRY_TAKE_FOCUS ((char *) NULL) -#define DEF_ENTRY_TEXT_VARIABLE "" -#define DEF_ENTRY_WIDTH "20" - -/* - * Defaults for frames: - */ - -#define DEF_FRAME_BG_COLOR NORMAL_BG -#define DEF_FRAME_BG_MONO WHITE -#define DEF_FRAME_BORDER_WIDTH "0" -#define DEF_FRAME_CLASS "Frame" -#define DEF_FRAME_COLORMAP "" -#define DEF_FRAME_CONTAINER "0" -#define DEF_FRAME_CURSOR "" -#define DEF_FRAME_HEIGHT "0" -#define DEF_FRAME_HIGHLIGHT_BG NORMAL_BG -#define DEF_FRAME_HIGHLIGHT HIGHLIGHT -#define DEF_FRAME_HIGHLIGHT_WIDTH "0" -#define DEF_FRAME_PADX "0" -#define DEF_FRAME_PADY "0" -#define DEF_FRAME_RELIEF "flat" -#define DEF_FRAME_TAKE_FOCUS "0" -#define DEF_FRAME_VISUAL "" -#define DEF_FRAME_WIDTH "0" - -/* - * Defaults for labelframes: - */ - -#define DEF_LABELFRAME_BORDER_WIDTH "2" -#define DEF_LABELFRAME_CLASS "Labelframe" -#define DEF_LABELFRAME_RELIEF "groove" -#define DEF_LABELFRAME_FG NORMAL_FG -#define DEF_LABELFRAME_FONT "TkDefaultFont" -#define DEF_LABELFRAME_TEXT "" -#define DEF_LABELFRAME_LABELANCHOR "nw" - -/* - * Defaults for listboxes: - */ - -#define DEF_LISTBOX_ACTIVE_STYLE "underline" -#define DEF_LISTBOX_BG_COLOR "SystemWindow" -#define DEF_LISTBOX_BG_MONO WHITE -#define DEF_LISTBOX_BORDER_WIDTH "1" -#define DEF_LISTBOX_CURSOR "" -#define DEF_LISTBOX_DISABLED_FG DISABLED -#define DEF_LISTBOX_EXPORT_SELECTION "1" -#define DEF_LISTBOX_FONT "TkDefaultFont" -#define DEF_LISTBOX_FG NORMAL_FG -#define DEF_LISTBOX_HEIGHT "10" -#define DEF_LISTBOX_HIGHLIGHT_BG NORMAL_BG -#define DEF_LISTBOX_HIGHLIGHT HIGHLIGHT -#define DEF_LISTBOX_HIGHLIGHT_WIDTH "1" -#define DEF_LISTBOX_JUSTIFY "left" -#define DEF_LISTBOX_RELIEF "sunken" -#define DEF_LISTBOX_SCROLL_COMMAND "" -#define DEF_LISTBOX_LIST_VARIABLE "" -#define DEF_LISTBOX_SELECT_COLOR SELECT_BG -#define DEF_LISTBOX_SELECT_MONO BLACK -#define DEF_LISTBOX_SELECT_BD "0" -#define DEF_LISTBOX_SELECT_FG_COLOR SELECT_FG -#define DEF_LISTBOX_SELECT_FG_MONO WHITE -#define DEF_LISTBOX_SELECT_MODE "browse" -#define DEF_LISTBOX_SET_GRID "0" -#define DEF_LISTBOX_STATE "normal" -#define DEF_LISTBOX_TAKE_FOCUS ((char *) NULL) -#define DEF_LISTBOX_WIDTH "20" - -/* - * Defaults for individual entries of menus: - */ - -#define DEF_MENU_ENTRY_ACTIVE_BG ((char *) NULL) -#define DEF_MENU_ENTRY_ACTIVE_FG ((char *) NULL) -#define DEF_MENU_ENTRY_ACCELERATOR ((char *) NULL) -#define DEF_MENU_ENTRY_BG ((char *) NULL) -#define DEF_MENU_ENTRY_BITMAP None -#define DEF_MENU_ENTRY_COLUMN_BREAK "0" -#define DEF_MENU_ENTRY_COMMAND ((char *) NULL) -#define DEF_MENU_ENTRY_COMPOUND "none" -#define DEF_MENU_ENTRY_FG ((char *) NULL) -#define DEF_MENU_ENTRY_FONT ((char *) NULL) -#define DEF_MENU_ENTRY_HIDE_MARGIN "0" -#define DEF_MENU_ENTRY_IMAGE ((char *) NULL) -#define DEF_MENU_ENTRY_INDICATOR "1" -#define DEF_MENU_ENTRY_LABEL ((char *) NULL) -#define DEF_MENU_ENTRY_MENU ((char *) NULL) -#define DEF_MENU_ENTRY_OFF_VALUE "0" -#define DEF_MENU_ENTRY_ON_VALUE "1" -#define DEF_MENU_ENTRY_SELECT_IMAGE ((char *) NULL) -#define DEF_MENU_ENTRY_STATE "normal" -#define DEF_MENU_ENTRY_VALUE ((char *) NULL) -#define DEF_MENU_ENTRY_CHECK_VARIABLE ((char *) NULL) -#define DEF_MENU_ENTRY_RADIO_VARIABLE "selectedButton" -#define DEF_MENU_ENTRY_SELECT ((char *) NULL) -#define DEF_MENU_ENTRY_UNDERLINE "-1" - -/* - * Defaults for menus overall: - */ - -#define DEF_MENU_ACTIVE_BG_COLOR SELECT_BG -#define DEF_MENU_ACTIVE_BG_MONO BLACK -#define DEF_MENU_ACTIVE_BORDER_WIDTH "0" -#define DEF_MENU_ACTIVE_FG_COLOR SELECT_FG -#define DEF_MENU_ACTIVE_FG_MONO WHITE -#define DEF_MENU_BG_COLOR MENU_BG -#define DEF_MENU_BG_MONO WHITE -#define DEF_MENU_BORDER_WIDTH "0" -#define DEF_MENU_CURSOR "arrow" -#define DEF_MENU_DISABLED_FG_COLOR DISABLED -#define DEF_MENU_DISABLED_FG_MONO "" -#define DEF_MENU_FONT "TkMenuFont" -#define DEF_MENU_FG MENU_FG -#define DEF_MENU_POST_COMMAND "" -#define DEF_MENU_RELIEF "flat" -#define DEF_MENU_SELECT_COLOR MENU_FG -#define DEF_MENU_SELECT_MONO BLACK -#define DEF_MENU_TAKE_FOCUS "0" -#define DEF_MENU_TEAROFF "1" -#define DEF_MENU_TEAROFF_CMD ((char *) NULL) -#define DEF_MENU_TITLE "" -#define DEF_MENU_TYPE "normal" - -/* - * Defaults for menubuttons: - */ - -#define DEF_MENUBUTTON_ANCHOR "center" -#define DEF_MENUBUTTON_ACTIVE_BG_COLOR ACTIVE_BG -#define DEF_MENUBUTTON_ACTIVE_BG_MONO BLACK -#define DEF_MENUBUTTON_ACTIVE_FG_COLOR NORMAL_FG -#define DEF_MENUBUTTON_ACTIVE_FG_MONO WHITE -#define DEF_MENUBUTTON_BG_COLOR NORMAL_BG -#define DEF_MENUBUTTON_BG_MONO WHITE -#define DEF_MENUBUTTON_BITMAP "" -#define DEF_MENUBUTTON_BORDER_WIDTH "1" -#define DEF_MENUBUTTON_CURSOR "" -#define DEF_MENUBUTTON_DIRECTION "below" -#define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED -#define DEF_MENUBUTTON_DISABLED_FG_MONO "" -#define DEF_MENUBUTTON_FONT "TkDefaultFont" -#define DEF_MENUBUTTON_FG NORMAL_FG -#define DEF_MENUBUTTON_HEIGHT "0" -#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR -#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO DEF_MENUBUTTON_BG_MONO -#define DEF_MENUBUTTON_HIGHLIGHT HIGHLIGHT -#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH "0" -#define DEF_MENUBUTTON_IMAGE ((char *) NULL) -#define DEF_MENUBUTTON_INDICATOR "0" -#define DEF_MENUBUTTON_JUSTIFY "center" -#define DEF_MENUBUTTON_MENU "" -#define DEF_MENUBUTTON_PADX "4p" -#define DEF_MENUBUTTON_PADY "3p" -#define DEF_MENUBUTTON_RELIEF "flat" -#define DEF_MENUBUTTON_STATE "normal" -#define DEF_MENUBUTTON_TAKE_FOCUS "0" -#define DEF_MENUBUTTON_TEXT "" -#define DEF_MENUBUTTON_TEXT_VARIABLE "" -#define DEF_MENUBUTTON_UNDERLINE "-1" -#define DEF_MENUBUTTON_WIDTH "0" -#define DEF_MENUBUTTON_WRAP_LENGTH "0" - -/* - * Defaults for messages: - */ - -#define DEF_MESSAGE_ANCHOR "center" -#define DEF_MESSAGE_ASPECT "150" -#define DEF_MESSAGE_BG_COLOR NORMAL_BG -#define DEF_MESSAGE_BG_MONO WHITE -#define DEF_MESSAGE_BORDER_WIDTH "1" -#define DEF_MESSAGE_CURSOR "" -#define DEF_MESSAGE_FG NORMAL_FG -#define DEF_MESSAGE_FONT "TkDefaultFont" -#define DEF_MESSAGE_HIGHLIGHT_BG NORMAL_BG -#define DEF_MESSAGE_HIGHLIGHT HIGHLIGHT -#define DEF_MESSAGE_HIGHLIGHT_WIDTH "0" -#define DEF_MESSAGE_JUSTIFY "left" -#define DEF_MESSAGE_PADX "-1" -#define DEF_MESSAGE_PADY "-1" -#define DEF_MESSAGE_RELIEF "flat" -#define DEF_MESSAGE_TAKE_FOCUS "0" -#define DEF_MESSAGE_TEXT "" -#define DEF_MESSAGE_TEXT_VARIABLE "" -#define DEF_MESSAGE_WIDTH "0" - -/* - * Defaults for panedwindows - */ - -#define DEF_PANEDWINDOW_BG_COLOR NORMAL_BG -#define DEF_PANEDWINDOW_BG_MONO WHITE -#define DEF_PANEDWINDOW_BORDERWIDTH "1" -#define DEF_PANEDWINDOW_CURSOR "" -#define DEF_PANEDWINDOW_HANDLEPAD "8" -#define DEF_PANEDWINDOW_HANDLESIZE "8" -#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" -#define DEF_PANEDWINDOW_SASHRELIEF "flat" -#define DEF_PANEDWINDOW_SASHWIDTH "3" -#define DEF_PANEDWINDOW_SHOWHANDLE "0" -#define DEF_PANEDWINDOW_WIDTH "" - -/* - * Defaults for panedwindow panes - */ - -#define DEF_PANEDWINDOW_PANE_AFTER "" -#define DEF_PANEDWINDOW_PANE_BEFORE "" -#define DEF_PANEDWINDOW_PANE_HEIGHT "" -#define DEF_PANEDWINDOW_PANE_MINSIZE "0" -#define DEF_PANEDWINDOW_PANE_PADX "0" -#define DEF_PANEDWINDOW_PANE_PADY "0" -#define DEF_PANEDWINDOW_PANE_STICKY "nsew" -#define DEF_PANEDWINDOW_PANE_WIDTH "" -#define DEF_PANEDWINDOW_PANE_HIDE "0" -#define DEF_PANEDWINDOW_PANE_STRETCH "last" - -/* - * Defaults for scales: - */ - -#define DEF_SCALE_ACTIVE_BG_COLOR ACTIVE_BG -#define DEF_SCALE_ACTIVE_BG_MONO BLACK -#define DEF_SCALE_BG_COLOR NORMAL_BG -#define DEF_SCALE_BG_MONO WHITE -#define DEF_SCALE_BIG_INCREMENT "0" -#define DEF_SCALE_BORDER_WIDTH "1" -#define DEF_SCALE_COMMAND "" -#define DEF_SCALE_CURSOR "" -#define DEF_SCALE_DIGITS "0" -#define DEF_SCALE_FONT "TkDefaultFont" -#define DEF_SCALE_FG_COLOR NORMAL_FG -#define DEF_SCALE_FG_MONO BLACK -#define DEF_SCALE_FROM "0" -#define DEF_SCALE_HIGHLIGHT_BG_COLOR DEF_SCALE_BG_COLOR -#define DEF_SCALE_HIGHLIGHT_BG_MONO DEF_SCALE_BG_MONO -#define DEF_SCALE_HIGHLIGHT HIGHLIGHT -#define DEF_SCALE_HIGHLIGHT_WIDTH "2" -#define DEF_SCALE_LABEL "" -#define DEF_SCALE_LENGTH "100" -#define DEF_SCALE_ORIENT "vertical" -#define DEF_SCALE_RELIEF "flat" -#define DEF_SCALE_REPEAT_DELAY "300" -#define DEF_SCALE_REPEAT_INTERVAL "100" -#define DEF_SCALE_RESOLUTION "1" -#define DEF_SCALE_TROUGH_COLOR TROUGH -#define DEF_SCALE_TROUGH_MONO WHITE -#define DEF_SCALE_SHOW_VALUE "1" -#define DEF_SCALE_SLIDER_LENGTH "30" -#define DEF_SCALE_SLIDER_RELIEF "raised" -#define DEF_SCALE_STATE "normal" -#define DEF_SCALE_TAKE_FOCUS ((char *) NULL) -#define DEF_SCALE_TICK_INTERVAL "0" -#define DEF_SCALE_TO "100" -#define DEF_SCALE_VARIABLE "" -#define DEF_SCALE_WIDTH "15" - -/* - * Defaults for scrollbars: - */ - -#define DEF_SCROLLBAR_ACTIVE_BG_COLOR ACTIVE_BG -#define DEF_SCROLLBAR_ACTIVE_BG_MONO BLACK -#define DEF_SCROLLBAR_ACTIVE_RELIEF "raised" -#define DEF_SCROLLBAR_BG_COLOR NORMAL_BG -#define DEF_SCROLLBAR_BG_MONO WHITE -#define DEF_SCROLLBAR_BORDER_WIDTH "0" -#define DEF_SCROLLBAR_COMMAND "" -#define DEF_SCROLLBAR_CURSOR "" -#define DEF_SCROLLBAR_EL_BORDER_WIDTH "-1" -#define DEF_SCROLLBAR_HIGHLIGHT_BG NORMAL_BG -#define DEF_SCROLLBAR_HIGHLIGHT HIGHLIGHT -#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH "0" -#define DEF_SCROLLBAR_JUMP "0" -#define DEF_SCROLLBAR_ORIENT "vertical" -#define DEF_SCROLLBAR_RELIEF "sunken" -#define DEF_SCROLLBAR_REPEAT_DELAY "300" -#define DEF_SCROLLBAR_REPEAT_INTERVAL "100" -#define DEF_SCROLLBAR_TAKE_FOCUS ((char *) NULL) -#define DEF_SCROLLBAR_TROUGH_COLOR TROUGH -#define DEF_SCROLLBAR_TROUGH_MONO WHITE -#define DEF_SCROLLBAR_WIDTH "10" - -/* - * Defaults for texts: - */ - -#define DEF_TEXT_AUTO_SEPARATORS "1" -#define DEF_TEXT_BG_COLOR "SystemWindow" -#define DEF_TEXT_BG_MONO WHITE -#define DEF_TEXT_BLOCK_CURSOR "0" -#define DEF_TEXT_BORDER_WIDTH "1" -#define DEF_TEXT_CURSOR "xterm" -#define DEF_TEXT_FG TEXT_FG -#define DEF_TEXT_EXPORT_SELECTION "1" -#define DEF_TEXT_FONT "TkFixedFont" -#define DEF_TEXT_HEIGHT "24" -#define DEF_TEXT_HIGHLIGHT_BG NORMAL_BG -#define DEF_TEXT_HIGHLIGHT HIGHLIGHT -#define DEF_TEXT_HIGHLIGHT_WIDTH "0" -#define DEF_TEXT_INSERT_BG TEXT_FG -#define DEF_TEXT_INSERT_BD_COLOR "0" -#define DEF_TEXT_INSERT_BD_MONO "0" -#define DEF_TEXT_INSERT_OFF_TIME "300" -#define DEF_TEXT_INSERT_ON_TIME "600" -#define DEF_TEXT_INSERT_UNFOCUSSED "none" -#define DEF_TEXT_INSERT_WIDTH "2" -#define DEF_TEXT_MAX_UNDO "0" -#define DEF_TEXT_PADX "1" -#define DEF_TEXT_PADY "1" -#define DEF_TEXT_RELIEF "sunken" -#define DEF_TEXT_INACTIVE_SELECT_COLOR NULL -#define DEF_TEXT_SELECT_COLOR SELECT_BG -#define DEF_TEXT_SELECT_MONO BLACK -#define DEF_TEXT_SELECT_BD_COLOR "0" -#define DEF_TEXT_SELECT_BD_MONO "0" -#define DEF_TEXT_SELECT_FG_COLOR SELECT_FG -#define DEF_TEXT_SELECT_FG_MONO WHITE -#define DEF_TEXT_SELECT_RELIEF "flat" -#define DEF_TEXT_SET_GRID "0" -#define DEF_TEXT_SPACING1 "0" -#define DEF_TEXT_SPACING2 "0" -#define DEF_TEXT_SPACING3 "0" -#define DEF_TEXT_STATE "normal" -#define DEF_TEXT_TABS "" -#define DEF_TEXT_TABSTYLE "tabular" -#define DEF_TEXT_TAKE_FOCUS ((char *) NULL) -#define DEF_TEXT_UNDO "0" -#define DEF_TEXT_WIDTH "80" -#define DEF_TEXT_WRAP "char" -#define DEF_TEXT_XSCROLL_COMMAND "" -#define DEF_TEXT_YSCROLL_COMMAND "" - -/* - * Defaults for canvas text: - */ - -#define DEF_CANVTEXT_FONT "TkDefaultFont" - -/* - * Defaults for toplevels (most of the defaults for frames also apply - * to toplevels): - */ - -#define DEF_TOPLEVEL_CLASS "Toplevel" -#define DEF_TOPLEVEL_MENU "" -#define DEF_TOPLEVEL_SCREEN "" -#define DEF_TOPLEVEL_USE "" - -/* - * Defaults for busy windows: - */ - -#define DEF_BUSY_CURSOR "wait" - -#endif /* _TKWINDEFAULT */ diff --git a/tk8.6/win/tkWinDialog.c b/tk8.6/win/tkWinDialog.c deleted file mode 100644 index f97d813..0000000 --- a/tk8.6/win/tkWinDialog.c +++ /dev/null @@ -1,3623 +0,0 @@ -/* - * tkWinDialog.c -- - * - * Contains the Windows implementation of the common dialog boxes. - * - * Copyright (c) 1996-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" -#include "tkFileFilter.h" -#include "tkFont.h" - -#include <commdlg.h> /* includes common dialog functionality */ -#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 - -#ifndef BIF_VALIDATE -#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 - -#ifndef BFFM_VALIDATEFAILED -#ifdef UNICODE -#define BFFM_VALIDATEFAILED 4 -#else -#define BFFM_VALIDATEFAILED 3 -#endif -#endif /* BFFM_VALIDATEFAILED */ - -typedef struct ThreadSpecificData { - int debugFlag; /* Flags whether we should output debugging - * information while displaying a builtin - * dialog. */ - Tcl_Interp *debugInterp; /* Interpreter to used for debugging. */ - UINT WM_LBSELCHANGED; /* Holds a registered windows event used for - * communicating between the Directory Chooser - * dialog and its hook proc. */ - 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; - -/* - * The following structures are used by Tk_MessageBoxCmd() to parse arguments - * and return results. - */ - -static const TkStateMap iconMap[] = { - {MB_ICONERROR, "error"}, - {MB_ICONINFORMATION, "info"}, - {MB_ICONQUESTION, "question"}, - {MB_ICONWARNING, "warning"}, - {-1, NULL} -}; - -static const TkStateMap typeMap[] = { - {MB_ABORTRETRYIGNORE, "abortretryignore"}, - {MB_OK, "ok"}, - {MB_OKCANCEL, "okcancel"}, - {MB_RETRYCANCEL, "retrycancel"}, - {MB_YESNO, "yesno"}, - {MB_YESNOCANCEL, "yesnocancel"}, - {-1, NULL} -}; - -static const TkStateMap buttonMap[] = { - {IDABORT, "abort"}, - {IDRETRY, "retry"}, - {IDIGNORE, "ignore"}, - {IDOK, "ok"}, - {IDCANCEL, "cancel"}, - {IDNO, "no"}, - {IDYES, "yes"}, - {-1, NULL} -}; - -static const int buttonFlagMap[] = { - MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON3, MB_DEFBUTTON4 -}; - -static const struct {int type; int btnIds[3];} allowedTypes[] = { - {MB_ABORTRETRYIGNORE, {IDABORT, IDRETRY, IDIGNORE}}, - {MB_OK, {IDOK, -1, -1 }}, - {MB_OKCANCEL, {IDOK, IDCANCEL, -1 }}, - {MB_RETRYCANCEL, {IDRETRY, IDCANCEL, -1 }}, - {MB_YESNO, {IDYES, IDNO, -1 }}, - {MB_YESNOCANCEL, {IDYES, IDNO, IDCANCEL}} -}; - -#define NUM_TYPES (sizeof(allowedTypes) / sizeof(allowedTypes[0])) - -/* - * Abstract trivial differences between Win32 and Win64. - */ - -#define TkWinGetHInstance(from) \ - ((HINSTANCE) GetWindowLongPtr((from), GWLP_HINSTANCE)) -#define TkWinGetUserData(from) \ - GetWindowLongPtr((from), GWLP_USERDATA) -#define TkWinSetUserData(to,what) \ - SetWindowLongPtr((to), GWLP_USERDATA, (LPARAM)(what)) - -/* - * The value of TK_MULTI_MAX_PATH dictates how many files can be retrieved - * with tk_get*File -multiple 1. It must be allocated on the stack, so make it - * large enough but not too large. - hobbs - * - * The data is stored as <dir>\0<file1>\0<file2>\0...<fileN>\0\0. Since - * MAX_PATH == 260 on Win2K/NT, *40 is ~10Kbytes. - */ - -#define TK_MULTI_MAX_PATH (MAX_PATH*40) - -/* - * The following structure is used to pass information between the directory - * chooser function, Tk_ChooseDirectoryObjCmd(), and its dialog hook proc. - */ - -typedef struct { - TCHAR initDir[MAX_PATH]; /* Initial folder to use */ - TCHAR retDir[MAX_PATH]; /* Returned folder to use */ - Tcl_Interp *interp; - int mustExist; /* True if file must exist to return from - * callback */ -} ChooseDir; - -/* - * The following structure is used to pass information between GetFileName - * function and OFN dialog hook procedures. [Bug 2896501, Patch 2898255] - */ - -typedef struct OFNData { - Tcl_Interp *interp; /* Interp, used only if debug is turned on, - * for setting the "tk_dialog" variable. */ - int dynFileBufferSize; /* Dynamic filename buffer size, stored to - * avoid shrinking and expanding the buffer - * when selection changes */ - TCHAR *dynFileBuffer; /* Dynamic filename buffer */ -} 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. - */ - -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[], 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); -static UINT APIENTRY OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam, - LPARAM lParam); -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. */ - - shell32_handle = GetModuleHandle(TEXT("shell32.dll")); - if (shell32_handle == NULL) /* Should never happen but check anyways. */ - return; - - ShellProcs.SHCreateItemFromParsingName = - (SHCreateItemFromParsingNameProc*) GetProcAddress(shell32_handle, - "SHCreateItemFromParsingName"); -} - - -/* - *------------------------------------------------------------------------- - * - * EatSpuriousMessageBugFix -- - * - * In the file open/save dialog, double clicking on a list item causes - * the dialog box to close, but an unwanted WM_LBUTTONUP message is sent - * to the window underneath. If the window underneath happens to be a - * windows control (eg a button) then it will be activated by accident. - * - * This problem does not occur in dialog boxes, because windows must do - * some special processing to solve the problem. (separate message - * processing functions are used to cope with keyboard navigation of - * controls.) - * - * Here is one solution. After returning, we flush all mouse events - * for 1/4 second. In 8.6.5 and earlier, the code used to - * poll the message queue consuming WM_LBUTTONUP messages. - * On seeing a WM_LBUTTONDOWN message, it would exit early, since the user - * must be doing something new. However this early exit does not work - * on Vista and later because the Windows sends both BUTTONDOWN and - * BUTTONUP after the DBLCLICK instead of just BUTTONUP as on XP. - * Rather than try and figure out version specific sequences, we - * ignore all mouse events in that interval. - * - * This fix only works for the current application, so the problem will - * still occur if the open dialog happens to be over another applications - * button. However this is a fairly rare occurrance. - * - * Results: - * None. - * - * Side effects: - * Consumes unwanted mouse related messages. - * - *------------------------------------------------------------------------- - */ - -static void -EatSpuriousMessageBugFix(void) -{ - MSG msg; - DWORD nTime = GetTickCount() + 250; - - while (GetTickCount() < nTime) { - PeekMessage(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE); - } -} - -/* - *------------------------------------------------------------------------- - * - * TkWinDialogDebug -- - * - * Function to turn on/off debugging support for common dialogs under - * windows. The variable "tk_debug" is set to the identifier of the - * dialog window when the modal dialog window pops up and it is safe to - * send messages to the dialog. - * - * Results: - * None. - * - * Side effects: - * This variable only makes sense if just one dialog is up at a time. - * - *------------------------------------------------------------------------- - */ - -void -TkWinDialogDebug( - int debug) -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - tsdPtr->debugFlag = debug; -} - -/* - *------------------------------------------------------------------------- - * - * Tk_ChooseColorObjCmd -- - * - * This function implements the color dialog box for the Windows - * platform. See the user documentation for details on what it does. - * - * Results: - * See user documentation. - * - * Side effects: - * A dialog window is created the first time this function is called. - * This window is not destroyed and will be reused the next time the - * application invokes the "tk_chooseColor" command. - * - *------------------------------------------------------------------------- - */ - -int -Tk_ChooseColorObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_Window tkwin = clientData, parent; - HWND hWnd; - int i, oldMode, winCode, result; - CHOOSECOLOR chooseColor; - static int inited = 0; - static COLORREF dwCustColors[16]; - static long oldColor; /* the color selected last time */ - static const char *const optionStrings[] = { - "-initialcolor", "-parent", "-title", NULL - }; - enum options { - COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE - }; - - result = TCL_OK; - if (inited == 0) { - /* - * dwCustColors stores the custom color which the user can modify. We - * store these colors in a static array so that the next time the - * color dialog pops up, the same set of custom colors remain in the - * dialog. - */ - - for (i = 0; i < 16; i++) { - dwCustColors[i] = RGB(255-i * 10, i, i * 10); - } - oldColor = RGB(0xa0, 0xa0, 0xa0); - inited = 1; - } - - parent = tkwin; - chooseColor.lStructSize = sizeof(CHOOSECOLOR); - chooseColor.hwndOwner = NULL; - chooseColor.hInstance = NULL; - chooseColor.rgbResult = oldColor; - chooseColor.lpCustColors = dwCustColors; - chooseColor.Flags = CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK; - chooseColor.lCustData = (LPARAM) NULL; - chooseColor.lpfnHook = (LPOFNHOOKPROC) ColorDlgHookProc; - chooseColor.lpTemplateName = (LPTSTR) interp; - - for (i = 1; i < objc; i += 2) { - int index; - const char *string; - Tcl_Obj *optionPtr, *valuePtr; - - optionPtr = objv[i]; - valuePtr = objv[i + 1]; - - if (Tcl_GetIndexFromObjStruct(interp, optionPtr, optionStrings, - sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { - return TCL_ERROR; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(optionPtr))); - Tcl_SetErrorCode(interp, "TK", "COLORDIALOG", "VALUE", NULL); - return TCL_ERROR; - } - - string = Tcl_GetString(valuePtr); - switch ((enum options) index) { - case COLOR_INITIAL: { - XColor *colorPtr; - - colorPtr = Tk_GetColor(interp, tkwin, string); - if (colorPtr == NULL) { - return TCL_ERROR; - } - chooseColor.rgbResult = RGB(colorPtr->red / 0x100, - colorPtr->green / 0x100, colorPtr->blue / 0x100); - break; - } - case COLOR_PARENT: - parent = Tk_NameToWindow(interp, string, tkwin); - if (parent == NULL) { - return TCL_ERROR; - } - break; - case COLOR_TITLE: - chooseColor.lCustData = (LPARAM) string; - break; - } - } - - Tk_MakeWindowExist(parent); - chooseColor.hwndOwner = NULL; - hWnd = Tk_GetHWND(Tk_WindowId(parent)); - chooseColor.hwndOwner = hWnd; - - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - winCode = ChooseColor(&chooseColor); - (void) 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). - */ - - EnableWindow(hWnd, 1); - - /* - * Clear the interp result since anything may have happened during the - * modal loop. - */ - - Tcl_ResetResult(interp); - - /* - * 3. Process the result of the dialog - */ - - if (winCode) { - /* - * User has selected a color - */ - - Tcl_SetObjResult(interp, Tcl_ObjPrintf("#%02x%02x%02x", - GetRValue(chooseColor.rgbResult), - GetGValue(chooseColor.rgbResult), - GetBValue(chooseColor.rgbResult))); - oldColor = chooseColor.rgbResult; - result = TCL_OK; - } - - return result; -} - -/* - *------------------------------------------------------------------------- - * - * ColorDlgHookProc -- - * - * Provides special handling of messages for the Color common dialog box. - * Used to set the title when the dialog first appears. - * - * Results: - * The return value is 0 if the default dialog box function should handle - * the message, non-zero otherwise. - * - * Side effects: - * Changes the title of the dialog window. - * - *---------------------------------------------------------------------- - */ - -static UINT CALLBACK -ColorDlgHookProc( - HWND hDlg, /* Handle to the color dialog. */ - UINT uMsg, /* Type of message. */ - WPARAM wParam, /* First message parameter. */ - LPARAM lParam) /* Second message parameter. */ -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - const char *title; - CHOOSECOLOR *ccPtr; - - if (WM_INITDIALOG == uMsg) { - - /* - * Set the title string of the dialog. - */ - - ccPtr = (CHOOSECOLOR *) lParam; - title = (const char *) ccPtr->lCustData; - - if ((title != NULL) && (title[0] != '\0')) { - Tcl_DString ds; - - SetWindowText(hDlg, Tcl_WinUtfToTChar(title,-1,&ds)); - Tcl_DStringFree(&ds); - } - if (tsdPtr->debugFlag) { - tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName; - Tcl_DoWhenIdle(SetTkDialog, hDlg); - } - return TRUE; - } - return FALSE; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetOpenFileCmd -- - * - * This function implements the "open file" dialog box for the Windows - * platform. See the user documentation for details on what it does. - * - * Results: - * See user documentation. - * - * Side effects: - * A dialog window is created the first this function is called. - * - *---------------------------------------------------------------------- - */ - -int -Tk_GetOpenFileObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - return GetFileName(clientData, interp, objc, objv, OFN_FILE_OPEN); -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetSaveFileCmd -- - * - * Same as Tk_GetOpenFileCmd but opens a "save file" dialog box - * instead - * - * Results: - * Same as Tk_GetOpenFileCmd. - * - * Side effects: - * Same as Tk_GetOpenFileCmd. - * - *---------------------------------------------------------------------- - */ - -int -Tk_GetSaveFileObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - return GetFileName(clientData, interp, objc, objv, OFN_FILE_SAVE); -} - -/* - *---------------------------------------------------------------------- - * - * CleanupOFNOptions -- - * - * Cleans up any storage allocated by ParseOFNOptions - * - * Results: - * None. - * - * Side effects: - * 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 -ParseOFNOptions( - 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 for Open, 0 for Save */ - OFNOpts *optsPtr) /* Output, uninitialized on entry */ -{ - 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_MUSTEXIST, - }; - struct Options { - const char *name; - enum options value; - }; - static const struct Options saveOptions[] = { - {"-confirmoverwrite", FILE_CONFIRMOW}, - {"-defaultextension", FILE_DEFAULT}, - {"-filetypes", FILE_TYPES}, - {"-initialdir", FILE_INITDIR}, - {"-initialfile", FILE_INITFILE}, - {"-parent", FILE_PARENT}, - {"-title", FILE_TITLE}, - {"-typevariable", FILE_TYPEVARIABLE}, - {NULL, FILE_DEFAULT/*ignored*/ } - }; - static const struct Options openOptions[] = { - {"-defaultextension", FILE_DEFAULT}, - {"-filetypes", FILE_TYPES}, - {"-initialdir", FILE_INITDIR}, - {"-initialfile", FILE_INITFILE}, - {"-multiple", FILE_MULTIPLE}, - {"-parent", FILE_PARENT}, - {"-title", FILE_TITLE}, - {"-typevariable", FILE_TYPEVARIABLE}, - {NULL, FILE_DEFAULT/*ignored*/ } - }; - static const struct Options dirOptions[] = { - {"-initialdir", FILE_INITDIR}, - {"-mustexist", FILE_MUSTEXIST}, - {"-parent", FILE_PARENT}, - {"-title", FILE_TITLE}, - {NULL, FILE_DEFAULT/*ignored*/ } - }; - - const struct Options *options = NULL; - - 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; - - if (Tcl_GetIndexFromObjStruct(interp, objv[i], options, - sizeof(struct Options), "option", 0, &index) != TCL_OK) { - /* - * 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_SetObjResult(interp, Tcl_NewStringObj("value for \"-xpstyle\" missing", -1)); - 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 error_return; - } - - valuePtr = objv[i + 1]; - string = Tcl_GetString(valuePtr); - switch (options[index].value) { - case FILE_DEFAULT: - optsPtr->extObj = valuePtr; - break; - case FILE_TYPES: - optsPtr->filterObj = valuePtr; - break; - case FILE_INITDIR: - Tcl_DStringFree(&optsPtr->utfDirString); - if (Tcl_TranslateFileName(interp, string, - &optsPtr->utfDirString) == NULL) - goto error_return; - break; - case FILE_INITFILE: - if (Tcl_TranslateFileName(interp, string, &ds) == NULL) - goto error_return; - Tcl_UtfToExternal(NULL, TkWinGetUnicodeEncoding(), - 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: - optsPtr->tkwin = Tk_NameToWindow(interp, string, clientData); - if (optsPtr->tkwin == NULL) - goto error_return; - break; - case FILE_TITLE: - optsPtr->titleObj = valuePtr; - break; - case FILE_TYPEVARIABLE: - optsPtr->typeVariableObj = valuePtr; - optsPtr->initialTypeObj = Tcl_ObjGetVar2(interp, valuePtr, - NULL, TCL_GLOBAL_ONLY); - break; - case FILE_MULTIPLE: - if (Tcl_GetBooleanFromObj(interp, valuePtr, - &optsPtr->multi) != TCL_OK) - goto error_return; - break; - case FILE_CONFIRMOW: - if (Tcl_GetBooleanFromObj(interp, valuePtr, - &optsPtr->confirmOverwrite) != TCL_OK) - goto error_return; - break; - case FILE_MUSTEXIST: - if (Tcl_GetBooleanFromObj(interp, valuePtr, - &optsPtr->mustExist) != TCL_OK) - goto error_return; - break; - } - } - - 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) { - Tcl_Panic("Internal error: GetFileNameVista: IFileDialog API not available"); - 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) { - Tcl_DString ds; - const char *src; - - src = Tcl_GetString(optsPtr->extObj); - wstr = (LPWSTR) Tcl_WinUtfToTChar(src, optsPtr->extObj->length, &ds); - if (wstr[0] == L'.') - ++wstr; - hr = fdlgIf->lpVtbl->SetDefaultExtension(fdlgIf, wstr); - Tcl_DStringFree(&ds); - if (FAILED(hr)) - goto vamoose; - } - - if (optsPtr->titleObj != NULL) { - Tcl_DString ds; - const char *src; - - src = Tcl_GetString(optsPtr->titleObj); - wstr = (LPWSTR) Tcl_WinUtfToTChar(src, optsPtr->titleObj->length, &ds); - hr = fdlgIf->lpVtbl->SetTitle(fdlgIf, wstr); - Tcl_DStringFree(&ds); - 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); - EatSpuriousMessageBugFix(); - - /* - * 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))); - Tcl_DStringFree(&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); - Tcl_DStringFree(&fnds); - } - 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_DString ftds; - Tcl_Obj *ftobj; - - Tcl_WinTCharToUtf(filterPtr[ftix-1].pszName, -1, &ftds); - ftobj = Tcl_NewStringObj(Tcl_DStringValue(&ftds), - Tcl_DStringLength(&ftds)); - Tcl_ObjSetVar2(interp, optsPtr->typeVariableObj, NULL, - ftobj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); - Tcl_DStringFree(&ftds); - } - } - } - } - } 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(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 = optsPtr->file; - ofn.nMaxFile = TK_MULTI_MAX_PATH; - ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR - | OFN_EXPLORER| OFN_ENABLEHOOK| OFN_ENABLESIZING; - ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProc; - ofn.lCustData = (LPARAM) &ofnData; - - if (oper != OFN_FILE_SAVE) { - ofn.Flags |= OFN_FILEMUSTEXIST; - } else if (optsPtr->confirmOverwrite) { - ofn.Flags |= OFN_OVERWRITEPROMPT; - } - if (tsdPtr->debugFlag != 0) { - ofnData.interp = interp; - } - if (optsPtr->multi != 0) { - ofn.Flags |= OFN_ALLOWMULTISELECT; - - /* - * Starting buffer size. The buffer will be expanded by the OFN dialog - * procedure when necessary - */ - - ofnData.dynFileBufferSize = 512; - ofnData.dynFileBuffer = ckalloc(512 * sizeof(TCHAR)); - } - - if (optsPtr->extObj != NULL) { - str = Tcl_GetString(optsPtr->extObj); - if (str[0] == '.') - ++str; - Tcl_WinUtfToTChar(str, -1, &extString); - ofn.lpstrDefExt = (TCHAR *) Tcl_DStringValue(&extString); - } - - Tcl_WinUtfToTChar(Tcl_DStringValue(&utfFilterString), - Tcl_DStringLength(&utfFilterString), &filterString); - ofn.lpstrFilter = (TCHAR *) Tcl_DStringValue(&filterString); - ofn.nFilterIndex = filterIndex; - - 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 - * that we set the [pwd] if the user didn't specify anything else. - */ - - Tcl_DString cwd; - - Tcl_DStringFree(&optsPtr->utfDirString); - if ((Tcl_GetCwd(interp, &optsPtr->utfDirString) == NULL) || - (Tcl_TranslateFileName(interp, - Tcl_DStringValue(&optsPtr->utfDirString), &cwd) == NULL)) { - Tcl_ResetResult(interp); - } else { - Tcl_WinUtfToTChar(Tcl_DStringValue(&cwd), - Tcl_DStringLength(&cwd), &dirString); - } - Tcl_DStringFree(&cwd); - } - ofn.lpstrInitialDir = (TCHAR *) Tcl_DStringValue(&dirString); - - if (optsPtr->titleObj != NULL) { - Tcl_WinUtfToTChar(Tcl_GetString(optsPtr->titleObj), -1, &titleString); - ofn.lpstrTitle = (TCHAR *) Tcl_DStringValue(&titleString); - } - - /* - * Popup the dialog. - */ - - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - if (oper != OFN_FILE_SAVE) { - winCode = GetOpenFileName(&ofn); - } else { - winCode = GetSaveFileName(&ofn); - } - Tcl_SetServiceMode(oldMode); - EatSpuriousMessageBugFix(); - - /* - * 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). - */ - - EnableWindow(hWnd, 1); - - /* - * Clear the interp result since anything may have happened during the - * modal loop. - */ - - Tcl_ResetResult(interp); - - /* - * Process the results. - * - * Use the CommDlgExtendedError() function to retrieve the error code. - * This function can return one of about two dozen codes; most of these - * indicate some sort of gross system failure (insufficient memory, bad - * window handles, etc.). Most of the error codes will be ignored; as we - * find we want more specific error messages for particular errors, we can - * extend the code as needed. - */ - - cdlgerr = CommDlgExtendedError(); - - /* - * We now allow FNERR_BUFFERTOOSMALL when multiselection is enabled. The - * filename buffer has been dynamically allocated by the OFN dialog - * procedure to accomodate all selected files. - */ - - if ((winCode != 0) - || ((cdlgerr == FNERR_BUFFERTOOSMALL) - && (ofn.Flags & OFN_ALLOWMULTISELECT))) { - int gotFilename = 0; /* Flag for tracking whether we have any - * filename at all. For details, see - * http://stackoverflow.com/q/9227859/301832 - */ - - if (ofn.Flags & OFN_ALLOWMULTISELECT) { - /* - * The result in dynFileBuffer contains many items, separated by - * NUL characters. It is terminated with two nulls in a row. The - * first element is the directory path. - */ - - TCHAR *files = ofnData.dynFileBuffer; - Tcl_Obj *returnList = Tcl_NewObj(); - int count = 0; - - /* - * Get directory. - */ - - ConvertExternalFilename(files, &ds); - - while (*files != '\0') { - while (*files != '\0') { - files++; - } - files++; - if (*files != '\0') { - Tcl_Obj *fullnameObj; - Tcl_DString filenameBuf; - - count++; - ConvertExternalFilename(files, &filenameBuf); - - fullnameObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds)); - Tcl_AppendToObj(fullnameObj, "/", -1); - Tcl_AppendToObj(fullnameObj, Tcl_DStringValue(&filenameBuf), - Tcl_DStringLength(&filenameBuf)); - gotFilename = 1; - Tcl_DStringFree(&filenameBuf); - Tcl_ListObjAppendElement(NULL, returnList, fullnameObj); - } - } - - if (count == 0) { - /* - * Only one file was returned. - */ - - Tcl_ListObjAppendElement(NULL, returnList, - Tcl_NewStringObj(Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds))); - gotFilename |= (Tcl_DStringLength(&ds) > 0); - } - Tcl_SetObjResult(interp, returnList); - Tcl_DStringFree(&ds); - } else { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - ConvertExternalFilename(ofn.lpstrFile, &ds), -1)); - gotFilename = (Tcl_DStringLength(&ds) > 0); - Tcl_DStringFree(&ds); - } - result = TCL_OK; - if ((ofn.nFilterIndex > 0) && gotFilename && optsPtr->typeVariableObj - && optsPtr->filterObj) { - int listObjc, count; - Tcl_Obj **listObjv = NULL; - Tcl_Obj **typeInfo = NULL; - - 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 { - /* - * 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) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "invalid filename \"%s\"", - ConvertExternalFilename(ofn.lpstrFile, &ds))); - Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "INVALID_FILENAME", - NULL); - Tcl_DStringFree(&ds); - } else { - result = TCL_OK; - } - - if (ofn.lpstrTitle != NULL) { - 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); - if (ofn.lpstrDefExt != NULL) { - Tcl_DStringFree(&extString); - } - -end: - Tcl_DStringFree(&utfFilterString); - if (ofnData.dynFileBuffer != NULL) { - ckfree(ofnData.dynFileBuffer); - ofnData.dynFileBuffer = NULL; - } - - 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; -} - - -/* - *------------------------------------------------------------------------- - * - * OFNHookProc -- - * - * Dialog box hook function. This is used to sets the "tk_dialog" - * variable for test/debugging when the dialog is ready to receive - * messages. When multiple file selection is enabled this function - * is used to process the list of names. - * - * Results: - * Returns 0 to allow default processing of messages to occur. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static UINT APIENTRY -OFNHookProc( - HWND hdlg, /* Handle to child dialog window. */ - UINT uMsg, /* Message identifier */ - WPARAM wParam, /* Message parameter */ - LPARAM lParam) /* Message parameter */ -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - OPENFILENAME *ofnPtr; - OFNData *ofnData; - - if (uMsg == WM_INITDIALOG) { - TkWinSetUserData(hdlg, lParam); - } else if (uMsg == WM_NOTIFY) { - OFNOTIFY *notifyPtr = (OFNOTIFY *) lParam; - - /* - * This is weird... or not. The CDN_FILEOK is NOT sent when the - * selection exceeds declared buffer size (the nMaxFile member of the - * OPENFILENAME struct passed to GetOpenFileName function). So, we - * have to rely on the most recent CDN_SELCHANGE then. Unfortunately - * this means, that gathering the selected filenames happens twice - * when they fit into the declared buffer. Luckily, it's not frequent - * operation so it should not incur any noticeable delay. See [Bug - * 2987995] - */ - - if (notifyPtr->hdr.code == CDN_FILEOK || - notifyPtr->hdr.code == CDN_SELCHANGE) { - int dirsize, selsize; - TCHAR *buffer; - int buffersize; - - /* - * Change of selection. Unscramble the unholy mess that's in the - * selection buffer, resizing it if necessary. - */ - - ofnPtr = notifyPtr->lpOFN; - ofnData = (OFNData *) ofnPtr->lCustData; - buffer = ofnData->dynFileBuffer; - hdlg = GetParent(hdlg); - - selsize = (int) SendMessage(hdlg, CDM_GETSPEC, 0, 0); - dirsize = (int) SendMessage(hdlg, CDM_GETFOLDERPATH, 0, 0); - buffersize = (selsize + dirsize + 1); - - /* - * Just empty the buffer if dirsize indicates an error. [Bug - * 3071836] - */ - - if ((selsize > 1) && (dirsize > 0)) { - if (ofnData->dynFileBufferSize < buffersize) { - buffer = ckrealloc(buffer, buffersize * sizeof(TCHAR)); - ofnData->dynFileBufferSize = buffersize; - ofnData->dynFileBuffer = buffer; - } - - SendMessage(hdlg, CDM_GETFOLDERPATH, dirsize, (LPARAM) buffer); - buffer += dirsize; - - SendMessage(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer); - - /* - * If there are multiple files, delete the quotes and change - * every second quote to NULL terminator - */ - - if (buffer[0] == '"') { - BOOL findquote = TRUE; - TCHAR *tmp = buffer; - - while (*buffer != '\0') { - if (findquote) { - if (*buffer == '"') { - findquote = FALSE; - } - buffer++; - } else { - if (*buffer == '"') { - findquote = TRUE; - *buffer = '\0'; - } - *tmp++ = *buffer++; - } - } - *tmp = '\0'; /* Second NULL terminator. */ - } else { - - /* - * Replace directory terminating NULL with a with a backslash, - * but only if not an absolute path. - */ - - Tcl_DString tmpfile; - ConvertExternalFilename(buffer, &tmpfile); - if (TCL_PATH_ABSOLUTE == - Tcl_GetPathType(Tcl_DStringValue(&tmpfile))) { - /* re-get the full path to the start of the buffer */ - buffer = (TCHAR *) ofnData->dynFileBuffer; - SendMessage(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer); - } else { - *(buffer-1) = '\\'; - } - buffer[selsize] = '\0'; /* Second NULL terminator. */ - Tcl_DStringFree(&tmpfile); - } - } else { - /* - * Nothing is selected, so just empty the string. - */ - - if (buffer != NULL) { - *buffer = '\0'; - } - } - } - } else if (uMsg == WM_WINDOWPOSCHANGED) { - /* - * This message is delivered at the right time to enable Tk to set the - * debug information. Unhooks itself so it won't set the debug - * information every time it gets a WM_WINDOWPOSCHANGED message. - */ - - ofnPtr = (OPENFILENAME *) TkWinGetUserData(hdlg); - if (ofnPtr != NULL) { - ofnData = (OFNData *) ofnPtr->lCustData; - if (ofnData->interp != NULL) { - hdlg = GetParent(hdlg); - tsdPtr->debugInterp = ofnData->interp; - Tcl_DoWhenIdle(SetTkDialog, hdlg); - } - TkWinSetUserData(hdlg, NULL); - } - } - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * MakeFilter -- - * - * Allocate a buffer to store the filters in a format understood by - * Windows. - * - * Results: - * A standard TCL return value. - * - * Side effects: - * ofnPtr->lpstrFilter is modified. - * - *---------------------------------------------------------------------- - */ - -static int -MakeFilter( - Tcl_Interp *interp, /* Current interpreter. */ - Tcl_Obj *valuePtr, /* Value of the -filetypes option */ - Tcl_DString *dsPtr, /* Filled with windows filter string. */ - Tcl_Obj *initialPtr, /* Initial type name */ - int *indexPtr) /* Index of initial type in filter string */ -{ - char *filterStr; - char *p; - const char *initial = NULL; - int pass; - int ix = 0; /* index counter */ - FileFilterList flist; - FileFilter *filterPtr; - - if (initialPtr) { - initial = Tcl_GetString(initialPtr); - } - TkInitFileFilters(&flist); - if (TkGetFileFilters(interp, &flist, valuePtr, 1) != TCL_OK) { - return TCL_ERROR; - } - - if (flist.filters == NULL) { - /* - * Use "All Files (*.*) as the default filter if none is specified - */ - const char *defaultFilter = "All Files (*.*)"; - - p = filterStr = ckalloc(30); - - strcpy(p, defaultFilter); - p+= strlen(defaultFilter); - - *p++ = '\0'; - *p++ = '*'; - *p++ = '.'; - *p++ = '*'; - *p++ = '\0'; - *p++ = '\0'; - *p = '\0'; - - } else { - size_t len; - - if (valuePtr == NULL) { - len = 0; - } else { - (void) Tcl_GetString(valuePtr); - len = valuePtr->length; - } - - /* - * We format the filetype into a string understood by Windows: {"Text - * Documents" {.doc .txt} {TEXT}} becomes "Text Documents - * (*.doc,*.txt)\0*.doc;*.txt\0" - * - * See the Windows OPENFILENAME manual page for details on the filter - * string format. - */ - - /* - * Since we may only add asterisks (*) to the filter, we need at most - * twice the size of the string to format the filter - */ - - filterStr = ckalloc(len * 3); - - for (filterPtr = flist.filters, p = filterStr; filterPtr; - filterPtr = filterPtr->next) { - const char *sep; - FileFilterClause *clausePtr; - - /* - * Check initial index for match, set *indexPtr. Filter index is 1 - * based so increment first - */ - - ix++; - if (indexPtr && initial - && (strcmp(initial, filterPtr->name) == 0)) { - *indexPtr = ix; - } - - /* - * First, put in the name of the file type. - */ - - strcpy(p, filterPtr->name); - p+= strlen(filterPtr->name); - *p++ = ' '; - *p++ = '('; - - for (pass = 1; pass <= 2; pass++) { - /* - * In the first pass, we format the extensions in the name - * field. In the second pass, we format the extensions in the - * filter pattern field - */ - - sep = ""; - for (clausePtr=filterPtr->clauses;clausePtr; - clausePtr=clausePtr->next) { - GlobPattern *globPtr; - - for (globPtr = clausePtr->patterns; globPtr; - globPtr = globPtr->next) { - strcpy(p, sep); - p += strlen(sep); - strcpy(p, globPtr->pattern); - p += strlen(globPtr->pattern); - - if (pass == 1) { - sep = ","; - } else { - sep = ";"; - } - } - } - if (pass == 1) { - *p ++ = ')'; - } - *p++ = '\0'; - } - } - - /* - * Windows requires the filter string to be ended by two NULL - * characters. - */ - - *p++ = '\0'; - *p = '\0'; - } - - Tcl_DStringAppend(dsPtr, filterStr, (int) (p - filterStr)); - ckfree(filterStr); - - TkFreeFileFilters(&flist); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * 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 - * Windows platform. See the user documentation for details on what it - * does. Uses the newer SHBrowseForFolder explorer type interface. - * - * Results: - * See user documentation. - * - * Side effects: - * A modal dialog window is created. Tcl_SetServiceMode() is called to - * allow background events to be processed - * - *---------------------------------------------------------------------- - * - * The function tk_chooseDirectory pops up a dialog box for the user to select - * a directory. The following option-value pairs are possible as command line - * arguments: - * - * -initialdir dirname - * - * Specifies that the directories in directory should be displayed when the - * dialog pops up. If this parameter is not specified, then the directories in - * the current working directory are displayed. If the parameter specifies a - * relative path, the return value will convert the relative path to an - * absolute path. This option may not always work on the Macintosh. This is - * not a bug. Rather, the General Controls control panel on the Mac allows the - * end user to override the application default directory. - * - * -parent window - * - * Makes window the logical parent of the dialog. The dialog is displayed on - * top of its parent window. - * - * -title titleString - * - * Specifies a string to display as the title of the dialog box. If this - * option is not specified, then a default title will be displayed. - * - * -mustexist boolean - * - * Specifies whether the user may specify non-existant directories. If this - * parameter is true, then the user may only select directories that already - * exist. The default value is false. - * - * New Behaviour: - * - * - If mustexist = 0 and a user entered folder does not exist, a prompt will - * pop-up asking if the user wants another chance to change it. The old - * dialog just returned the bogus entry. On mustexist = 1, the entries MUST - * exist before exiting the box with OK. - * - * Bugs: - * - * - If valid abs directory name is entered into the entry box and Enter - * pressed, the box will close returning the name. This is inconsistent when - * entering relative names or names with forward slashes, which are - * invalidated then corrected in the callback. After correction, the box is - * held open to allow further modification by the user. - * - * - Not sure how to implement localization of message prompts. - * - * - -title is really -message. - * - *---------------------------------------------------------------------- - */ - -int -Tk_ChooseDirectoryObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - TCHAR path[MAX_PATH]; - 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 */ - HWND hWnd; - TCHAR saveDir[MAX_PATH]; - Tcl_DString titleString; /* Title */ - Tcl_DString tempString; /* temporary */ - Tcl_Obj *objPtr; - 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; - } - - /* Older dialogs */ - - path[0] = '\0'; - ZeroMemory(&cdCBData, sizeof(ChooseDir)); - cdCBData.interp = interp; - cdCBData.mustExist = ofnOpts.mustExist; - - utfDir = Tcl_DStringValue(&ofnOpts.utfDirString); - if (utfDir[0] != '\0') { - const TCHAR *uniStr; - - Tcl_WinUtfToTChar(Tcl_DStringValue(&ofnOpts.utfDirString), -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); - } - - /* XXX - rest of this (original) code has no error checks at all. */ - - /* - * Get ready to call the browser - */ - - Tk_MakeWindowExist(ofnOpts.tkwin); - hWnd = Tk_GetHWND(Tk_WindowId(ofnOpts.tkwin)); - - /* - * Setup the parameters used by SHBrowseForFolder - */ - - bInfo.hwndOwner = hWnd; - bInfo.pszDisplayName = path; - bInfo.pidlRoot = NULL; - if (_tcslen(cdCBData.initDir) == 0) { - GetCurrentDirectory(MAX_PATH, cdCBData.initDir); - } - bInfo.lParam = (LPARAM) &cdCBData; - - 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."); - } - - /* - * Set flags to add edit box, status text line and use the new ui. Allow - * override with magic variable (ignore errors in retrieval). See - * http://msdn.microsoft.com/en-us/library/bb773205(VS.85).aspx for - * possible flag values. - */ - - bInfo.ulFlags = BIF_EDITBOX | BIF_STATUSTEXT | BIF_RETURNFSANCESTORS - | BIF_VALIDATE | BIF_NEWDIALOGSTYLE; - objPtr = Tcl_GetVar2Ex(interp, "::tk::winChooseDirFlags", NULL, - TCL_GLOBAL_ONLY); - if (objPtr != NULL) { - int flags; - Tcl_GetIntFromObj(NULL, objPtr, &flags); - bInfo.ulFlags = flags; - } - - /* - * Callback to handle events - */ - - bInfo.lpfn = (BFFCALLBACK) ChooseDirectoryValidateProc; - - /* - * Display dialog in background and process result. We look to give the - * user a chance to change their mind on an invalid folder if mustexist is - * 0. - */ - - 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); - - /* - * This is a fix for Windows 2000, which seems to modify the folder - * name buffer even when the dialog is canceled (in this case the - * buffer contains garbage). See [Bug #3002230] - */ - - path[0] = '\0'; - - /* - * Null for cancel button or invalid dir, otherwise valid. - */ - - if (pidl != NULL) { - if (!SHGetPathFromIDList(pidl, path)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "error: not a file system folder", -1)); - Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "PSEUDO", NULL); - } - pMalloc->lpVtbl->Free(pMalloc, (void *) pidl); - } else if (_tcslen(cdCBData.retDir) > 0) { - _tcscpy(path, cdCBData.retDir); - } - pMalloc->lpVtbl->Release(pMalloc); - } - SetCurrentDirectory(saveDir); - 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). - */ - - EnableWindow(hWnd, 1); - - /* - * Change the pathname to the Tcl "normalized" pathname, where back - * slashes are used instead of forward slashes - */ - - Tcl_ResetResult(interp); - if (*path) { - Tcl_DString ds; - - Tcl_SetObjResult(interp, Tcl_NewStringObj( - ConvertExternalFilename(path, &ds), -1)); - Tcl_DStringFree(&ds); - } - - CleanupOFNOptions(&ofnOpts); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * ChooseDirectoryValidateProc -- - * - * Hook function called by the explorer ChooseDirectory dialog when - * events occur. It is used to validate the text entry the user may have - * entered. - * - * Results: - * Returns 0 to allow default processing of message, or 1 to tell default - * dialog function not to close. - * - *---------------------------------------------------------------------- - */ - -static UINT APIENTRY -ChooseDirectoryValidateProc( - HWND hwnd, - UINT message, - LPARAM lParam, - LPARAM lpData) -{ - TCHAR selDir[MAX_PATH]; - ChooseDir *chooseDirSharedData = (ChooseDir *) lpData; - Tcl_DString tempString; - Tcl_DString initDirString; - TCHAR string[MAX_PATH]; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (tsdPtr->debugFlag) { - tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp; - Tcl_DoWhenIdle(SetTkDialog, hwnd); - } - chooseDirSharedData->retDir[0] = '\0'; - switch (message) { - case BFFM_VALIDATEFAILED: - /* - * First save and check to see if it is a valid path name, if so then - * make that path the one shown in the window. Otherwise, it failed - * the check and should be treated as such. Use - * Set/GetCurrentDirectory which allows relative path names and names - * with forward slashes. Use Tcl_TranslateFileName to make sure names - * like ~ are converted correctly. - */ - - Tcl_WinTCharToUtf((TCHAR *) lParam, -1, &initDirString); - if (Tcl_TranslateFileName(chooseDirSharedData->interp, - Tcl_DStringValue(&initDirString), &tempString) == NULL) { - /* - * Should we expose the error (in the interp result) to the user - * at this point? - */ - - chooseDirSharedData->retDir[0] = '\0'; - return 1; - } - Tcl_DStringFree(&initDirString); - Tcl_WinUtfToTChar(Tcl_DStringValue(&tempString), -1, &initDirString); - Tcl_DStringFree(&tempString); - _tcsncpy(string, (TCHAR *) Tcl_DStringValue(&initDirString), - MAX_PATH); - Tcl_DStringFree(&initDirString); - - if (SetCurrentDirectory(string) == 0) { - - /* - * Get the full path name to the user entry, at this point it does - * not exist so see if it is supposed to. Otherwise just return - * it. - */ - - GetFullPathName(string, MAX_PATH, - chooseDirSharedData->retDir, NULL); - if (chooseDirSharedData->mustExist) { - /* - * User HAS to select a valid directory. - */ - - wsprintf(selDir, TEXT("Directory '%s' does not exist,\n") - TEXT("please select or enter an existing directory."), - chooseDirSharedData->retDir); - MessageBox(NULL, selDir, NULL, MB_ICONEXCLAMATION|MB_OK); - chooseDirSharedData->retDir[0] = '\0'; - return 1; - } - } else { - /* - * Changed to new folder OK, return immediatly with the current - * directory in utfRetDir. - */ - - GetCurrentDirectory(MAX_PATH, chooseDirSharedData->retDir); - return 0; - } - return 0; - - case BFFM_SELCHANGED: - /* - * Set the status window to the currently selected path and enable the - * OK button if a file system folder, otherwise disable the OK button - * for things like server names. Perhaps a new switch - * -enablenonfolders can be used to allow non folders to be selected. - * - * Not called when user changes edit box directly. - */ - - if (SHGetPathFromIDList((LPITEMIDLIST) lParam, selDir)) { - SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM) selDir); - // enable the OK button - SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1); - } else { - // disable the OK button - SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0); - } - UpdateWindow(hwnd); - return 1; - - case BFFM_INITIALIZED: { - /* - * Directory browser intializing - tell it where to start from, user - * specified parameter. - */ - - TCHAR *initDir = chooseDirSharedData->initDir; - - SetCurrentDirectory(initDir); - - if (*initDir == '\\') { - /* - * BFFM_SETSELECTION only understands UNC paths as pidls, so - * convert path to pidl using IShellFolder interface. - */ - - LPMALLOC pMalloc; - LPSHELLFOLDER psfFolder; - - if (SUCCEEDED(SHGetMalloc(&pMalloc))) { - if (SUCCEEDED(SHGetDesktopFolder(&psfFolder))) { - LPITEMIDLIST pidlMain; - ULONG ulCount, ulAttr; - - if (SUCCEEDED(psfFolder->lpVtbl->ParseDisplayName( - psfFolder, hwnd, NULL, (TCHAR *) - initDir, &ulCount,&pidlMain,&ulAttr)) - && (pidlMain != NULL)) { - SendMessage(hwnd, BFFM_SETSELECTION, FALSE, - (LPARAM) pidlMain); - pMalloc->lpVtbl->Free(pMalloc, pidlMain); - } - psfFolder->lpVtbl->Release(psfFolder); - } - pMalloc->lpVtbl->Release(pMalloc); - } - } else { - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM) initDir); - } - SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1); - break; - } - - } - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_MessageBoxObjCmd -- - * - * This function implements the MessageBox window for the Windows - * platform. See the user documentation for details on what it does. - * - * Results: - * See user documentation. - * - * Side effects: - * None. The MessageBox window will be destroy before this function - * returns. - * - *---------------------------------------------------------------------- - */ - -int -Tk_MessageBoxObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_Window tkwin = clientData, parent; - HWND hWnd; - Tcl_Obj *messageObj, *titleObj, *detailObj, *tmpObj; - int defaultBtn, icon, type; - int i, oldMode, winCode; - UINT flags; - static const char *const optionStrings[] = { - "-default", "-detail", "-icon", "-message", - "-parent", "-title", "-type", NULL - }; - enum options { - MSG_DEFAULT, MSG_DETAIL, MSG_ICON, MSG_MESSAGE, - MSG_PARENT, MSG_TITLE, MSG_TYPE - }; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - Tcl_DString titleBuf, tmpBuf; - const WCHAR *titlePtr, *tmpPtr; - const char *src; - - defaultBtn = -1; - detailObj = NULL; - icon = MB_ICONINFORMATION; - messageObj = NULL; - parent = tkwin; - titleObj = NULL; - type = MB_OK; - - for (i = 1; i < objc; i += 2) { - int index; - Tcl_Obj *optionPtr, *valuePtr; - - optionPtr = objv[i]; - valuePtr = objv[i + 1]; - - if (Tcl_GetIndexFromObjStruct(interp, optionPtr, optionStrings, - sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { - return TCL_ERROR; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(optionPtr))); - Tcl_SetErrorCode(interp, "TK", "MSGBOX", "VALUE", NULL); - return TCL_ERROR; - } - - switch ((enum options) index) { - case MSG_DEFAULT: - defaultBtn = TkFindStateNumObj(interp, optionPtr, buttonMap, - valuePtr); - if (defaultBtn < 0) { - return TCL_ERROR; - } - break; - - case MSG_DETAIL: - detailObj = valuePtr; - break; - - case MSG_ICON: - icon = TkFindStateNumObj(interp, optionPtr, iconMap, valuePtr); - if (icon < 0) { - return TCL_ERROR; - } - break; - - case MSG_MESSAGE: - messageObj = valuePtr; - break; - - case MSG_PARENT: - parent = Tk_NameToWindow(interp, Tcl_GetString(valuePtr), tkwin); - if (parent == NULL) { - return TCL_ERROR; - } - break; - - case MSG_TITLE: - titleObj = valuePtr; - break; - - case MSG_TYPE: - type = TkFindStateNumObj(interp, optionPtr, typeMap, valuePtr); - if (type < 0) { - return TCL_ERROR; - } - break; - } - } - - while (!Tk_IsTopLevel(parent)) { - parent = Tk_Parent(parent); - } - Tk_MakeWindowExist(parent); - hWnd = Tk_GetHWND(Tk_WindowId(parent)); - - flags = 0; - if (defaultBtn >= 0) { - int defaultBtnIdx = -1; - - for (i = 0; i < (int) NUM_TYPES; i++) { - if (type == allowedTypes[i].type) { - int j; - - for (j = 0; j < 3; j++) { - if (allowedTypes[i].btnIds[j] == defaultBtn) { - defaultBtnIdx = j; - break; - } - } - if (defaultBtnIdx < 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "invalid default button \"%s\"", - TkFindStateString(buttonMap, defaultBtn))); - Tcl_SetErrorCode(interp, "TK", "MSGBOX", "DEFAULT", NULL); - return TCL_ERROR; - } - break; - } - } - flags = buttonFlagMap[defaultBtnIdx]; - } - - flags |= icon | type | MB_TASKMODAL | MB_SETFOREGROUND; - - tmpObj = messageObj ? Tcl_DuplicateObj(messageObj) - : Tcl_NewUnicodeObj(NULL, 0); - Tcl_IncrRefCount(tmpObj); - if (detailObj) { - const Tcl_UniChar twoNL[] = { '\n', '\n' }; - - Tcl_AppendUnicodeToObj(tmpObj, twoNL, 2); - Tcl_AppendObjToObj(tmpObj, detailObj); - } - - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - - /* - * MessageBoxW exists for all platforms. Use it to allow unicode error - * message to be displayed correctly where possible by the OS. - * - * In order to have the parent window icon reflected in a MessageBox, we - * have to create a hook that will trigger when the MessageBox is being - * created. - */ - - tsdPtr->hSmallIcon = TkWinGetIcon(parent, ICON_SMALL); - tsdPtr->hBigIcon = TkWinGetIcon(parent, ICON_BIG); - tsdPtr->hMsgBoxHook = SetWindowsHookEx(WH_CBT, MsgBoxCBTProc, NULL, - GetCurrentThreadId()); - src = Tcl_GetString(tmpObj); - tmpPtr = Tcl_WinUtfToTChar(src, tmpObj->length, &tmpBuf); - if (titleObj != NULL) { - src = Tcl_GetString(titleObj); - titlePtr = Tcl_WinUtfToTChar(src, titleObj->length, &titleBuf); - } else { - titlePtr = L""; - Tcl_DStringInit(&titleBuf); - } - winCode = MessageBox(hWnd, tmpPtr, titlePtr, flags); - Tcl_DStringFree(&titleBuf); - Tcl_DStringFree(&tmpBuf); - UnhookWindowsHookEx(tsdPtr->hMsgBoxHook); - (void) 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). - */ - - EnableWindow(hWnd, 1); - - Tcl_DecrRefCount(tmpObj); - Tcl_SetObjResult(interp, Tcl_NewStringObj( - TkFindStateString(buttonMap, winCode), -1)); - return TCL_OK; -} - -static LRESULT CALLBACK -MsgBoxCBTProc( - int nCode, - WPARAM wParam, - LPARAM lParam) -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (nCode == HCBT_CREATEWND) { - /* - * Window owned by our task is being created. Since the hook is - * installed just before the MessageBox call and removed after the - * MessageBox call, the window being created is either the message box - * or one of its controls. Check that the class is WC_DIALOG to ensure - * that it's the one we want. - */ - - LPCBT_CREATEWND lpcbtcreate = (LPCBT_CREATEWND) lParam; - - if (WC_DIALOG == lpcbtcreate->lpcs->lpszClass) { - HWND hwnd = (HWND) wParam; - - SendMessage(hwnd, WM_SETICON, ICON_SMALL, - (LPARAM) tsdPtr->hSmallIcon); - SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) tsdPtr->hBigIcon); - } - } - - /* - * Call the next hook proc, if there is one - */ - - return CallNextHookEx(tsdPtr->hMsgBoxHook, nCode, wParam, lParam); -} - -/* - * ---------------------------------------------------------------------- - * - * SetTkDialog -- - * - * Records the HWND for a native dialog in the 'tk_dialog' variable so - * that the test-suite can operate on the correct dialog window. Use of - * this is enabled when a test program calls TkWinDialogDebug by calling - * the test command 'tkwinevent debug 1'. - * - * ---------------------------------------------------------------------- - */ - -static void -SetTkDialog( - ClientData clientData) -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - char buf[32]; - - sprintf(buf, "0x%p", (HWND) clientData); - Tcl_SetVar2(tsdPtr->debugInterp, "tk_dialog", NULL, buf, TCL_GLOBAL_ONLY); -} - -/* - * Factored out a common pattern in use in this file. - */ - -static const char * -ConvertExternalFilename( - TCHAR *filename, - Tcl_DString *dsPtr) -{ - char *p; - - Tcl_WinTCharToUtf(filename, -1, dsPtr); - for (p = Tcl_DStringValue(dsPtr); *p != '\0'; p++) { - /* - * Change the pathname to the Tcl "normalized" pathname, where back - * slashes are used instead of forward slashes - */ - - if (*p == '\\') { - *p = '/'; - } - } - return Tcl_DStringValue(dsPtr); -} - -/* - * ---------------------------------------------------------------------- - * - * GetFontObj -- - * - * Convert a windows LOGFONT into a Tk font description. - * - * Result: - * A list containing a Tk font description. - * - * ---------------------------------------------------------------------- - */ - -static Tcl_Obj * -GetFontObj( - HDC hdc, - LOGFONT *plf) -{ - Tcl_DString ds; - Tcl_Obj *resObj; - int pt = 0; - - resObj = Tcl_NewListObj(0, NULL); - Tcl_WinTCharToUtf(plf->lfFaceName, -1, &ds); - Tcl_ListObjAppendElement(NULL, resObj, - Tcl_NewStringObj(Tcl_DStringValue(&ds), -1)); - Tcl_DStringFree(&ds); - pt = -MulDiv(plf->lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY)); - Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewIntObj(pt)); - if (plf->lfWeight >= 700) { - Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj("bold", -1)); - } - if (plf->lfItalic) { - Tcl_ListObjAppendElement(NULL, resObj, - Tcl_NewStringObj("italic", -1)); - } - if (plf->lfUnderline) { - Tcl_ListObjAppendElement(NULL, resObj, - Tcl_NewStringObj("underline", -1)); - } - if (plf->lfStrikeOut) { - Tcl_ListObjAppendElement(NULL, resObj, - Tcl_NewStringObj("overstrike", -1)); - } - return resObj; -} - -static void -ApplyLogfont( - Tcl_Interp *interp, - Tcl_Obj *cmdObj, - HDC hdc, - LOGFONT *logfontPtr) -{ - int objc; - Tcl_Obj **objv, **tmpv; - - Tcl_ListObjGetElements(NULL, cmdObj, &objc, &objv); - tmpv = ckalloc(sizeof(Tcl_Obj *) * (objc + 2)); - memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc); - tmpv[objc] = GetFontObj(hdc, logfontPtr); - TkBackgroundEvalObjv(interp, objc+1, tmpv, TCL_EVAL_GLOBAL); - ckfree(tmpv); -} - -/* - * ---------------------------------------------------------------------- - * - * HookProc -- - * - * Font selection hook. If the user selects Apply on the dialog, we call - * the applyProc script with the currently selected font as arguments. - * - * ---------------------------------------------------------------------- - */ - -typedef struct HookData { - Tcl_Interp *interp; - Tcl_Obj *titleObj; - Tcl_Obj *cmdObj; - Tcl_Obj *parentObj; - Tcl_Obj *fontObj; - HWND hwnd; - Tk_Window parent; -} HookData; - -static UINT_PTR CALLBACK -HookProc( - HWND hwndDlg, - UINT msg, - WPARAM wParam, - LPARAM lParam) -{ - CHOOSEFONT *pcf = (CHOOSEFONT *) lParam; - HWND hwndCtrl; - static HookData *phd = NULL; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (WM_INITDIALOG == msg && lParam != 0) { - phd = (HookData *) pcf->lCustData; - phd->hwnd = hwndDlg; - if (tsdPtr->debugFlag) { - tsdPtr->debugInterp = phd->interp; - Tcl_DoWhenIdle(SetTkDialog, hwndDlg); - } - if (phd->titleObj != NULL) { - Tcl_DString title; - - Tcl_WinUtfToTChar(Tcl_GetString(phd->titleObj), -1, &title); - if (Tcl_DStringLength(&title) > 0) { - SetWindowText(hwndDlg, (LPCTSTR) Tcl_DStringValue(&title)); - } - Tcl_DStringFree(&title); - } - - /* - * Disable the colour combobox (0x473) and its label (0x443). - */ - - hwndCtrl = GetDlgItem(hwndDlg, 0x443); - if (IsWindow(hwndCtrl)) { - EnableWindow(hwndCtrl, FALSE); - } - hwndCtrl = GetDlgItem(hwndDlg, 0x473); - if (IsWindow(hwndCtrl)) { - EnableWindow(hwndCtrl, FALSE); - } - TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL); - return 1; /* we handled the message */ - } - - if (WM_DESTROY == msg) { - phd->hwnd = NULL; - TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL); - return 0; - } - - /* - * Handle apply button by calling the provided command script as a - * background evaluation (ie: errors dont come back here). - */ - - if (WM_COMMAND == msg && LOWORD(wParam) == 1026) { - LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0}}; - HDC hdc = GetDC(hwndDlg); - - SendMessage(hwndDlg, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM) &lf); - if (phd && phd->cmdObj) { - ApplyLogfont(phd->interp, phd->cmdObj, hdc, &lf); - } - if (phd && phd->parent) { - TkSendVirtualEvent(phd->parent, "TkFontchooserFontChanged", NULL); - } - return 1; - } - return 0; /* pass on for default processing */ -} - -/* - * Helper for the FontchooserConfigure command to return the current value of - * any of the options (which may be NULL in the structure) - */ - -enum FontchooserOption { - FontchooserParent, FontchooserTitle, FontchooserFont, FontchooserCmd, - FontchooserVisible -}; - -static Tcl_Obj * -FontchooserCget( - HookData *hdPtr, - int optionIndex) -{ - Tcl_Obj *resObj = NULL; - - switch(optionIndex) { - case FontchooserParent: - if (hdPtr->parentObj) { - resObj = hdPtr->parentObj; - } else { - resObj = Tcl_NewStringObj(".", 1); - } - break; - case FontchooserTitle: - if (hdPtr->titleObj) { - resObj = hdPtr->titleObj; - } else { - resObj = Tcl_NewStringObj("", 0); - } - break; - case FontchooserFont: - if (hdPtr->fontObj) { - resObj = hdPtr->fontObj; - } else { - resObj = Tcl_NewStringObj("", 0); - } - break; - case FontchooserCmd: - if (hdPtr->cmdObj) { - resObj = hdPtr->cmdObj; - } else { - resObj = Tcl_NewStringObj("", 0); - } - break; - case FontchooserVisible: - resObj = Tcl_NewBooleanObj(hdPtr->hwnd && IsWindow(hdPtr->hwnd)); - break; - default: - resObj = Tcl_NewStringObj("", 0); - } - return resObj; -} - -/* - * ---------------------------------------------------------------------- - * - * FontchooserConfigureCmd -- - * - * Implementation of the 'tk fontchooser configure' ensemble command. See - * the user documentation for what it does. - * - * Results: - * See the user documentation. - * - * Side effects: - * Per-interp data structure may be modified - * - * ---------------------------------------------------------------------- - */ - -static int -FontchooserConfigureCmd( - ClientData clientData, /* Main window */ - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - Tk_Window tkwin = clientData; - HookData *hdPtr = NULL; - int i, r = TCL_OK; - static const char *const optionStrings[] = { - "-parent", "-title", "-font", "-command", "-visible", NULL - }; - - hdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser", NULL); - - /* - * With no arguments we return all the options in a dict. - */ - - if (objc == 1) { - Tcl_Obj *keyObj, *valueObj; - Tcl_Obj *dictObj = Tcl_NewDictObj(); - - for (i = 0; r == TCL_OK && optionStrings[i] != NULL; ++i) { - keyObj = Tcl_NewStringObj(optionStrings[i], -1); - valueObj = FontchooserCget(hdPtr, i); - r = Tcl_DictObjPut(interp, dictObj, keyObj, valueObj); - } - if (r == TCL_OK) { - Tcl_SetObjResult(interp, dictObj); - } - return r; - } - - for (i = 1; i < objc; i += 2) { - int optionIndex; - - if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings, - sizeof(char *), "option", 0, &optionIndex) != TCL_OK) { - return TCL_ERROR; - } - if (objc == 2) { - /* - * If one option and no arg - return the current value. - */ - - Tcl_SetObjResult(interp, FontchooserCget(hdPtr, optionIndex)); - return TCL_OK; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "VALUE", NULL); - return TCL_ERROR; - } - switch (optionIndex) { - case FontchooserVisible: { - static const char *msg = "cannot change read-only option " - "\"-visible\": use the show or hide command"; - - Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1)); - Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "READONLY", NULL); - return TCL_ERROR; - } - case FontchooserParent: { - Tk_Window parent = Tk_NameToWindow(interp, - Tcl_GetString(objv[i+1]), tkwin); - - if (parent == None) { - return TCL_ERROR; - } - if (hdPtr->parentObj) { - Tcl_DecrRefCount(hdPtr->parentObj); - } - hdPtr->parentObj = objv[i+1]; - if (Tcl_IsShared(hdPtr->parentObj)) { - hdPtr->parentObj = Tcl_DuplicateObj(hdPtr->parentObj); - } - Tcl_IncrRefCount(hdPtr->parentObj); - break; - } - case FontchooserTitle: - if (hdPtr->titleObj) { - Tcl_DecrRefCount(hdPtr->titleObj); - } - hdPtr->titleObj = objv[i+1]; - if (Tcl_IsShared(hdPtr->titleObj)) { - hdPtr->titleObj = Tcl_DuplicateObj(hdPtr->titleObj); - } - Tcl_IncrRefCount(hdPtr->titleObj); - break; - case FontchooserFont: - if (hdPtr->fontObj) { - Tcl_DecrRefCount(hdPtr->fontObj); - } - (void)Tcl_GetString(objv[i+1]); - if (objv[i+1]->length) { - hdPtr->fontObj = objv[i+1]; - if (Tcl_IsShared(hdPtr->fontObj)) { - hdPtr->fontObj = Tcl_DuplicateObj(hdPtr->fontObj); - } - Tcl_IncrRefCount(hdPtr->fontObj); - } else { - hdPtr->fontObj = NULL; - } - break; - case FontchooserCmd: - if (hdPtr->cmdObj) { - Tcl_DecrRefCount(hdPtr->cmdObj); - } - (void)Tcl_GetString(objv[i+1]); - if (objv[i+1]->length) { - hdPtr->cmdObj = objv[i+1]; - if (Tcl_IsShared(hdPtr->cmdObj)) { - hdPtr->cmdObj = Tcl_DuplicateObj(hdPtr->cmdObj); - } - Tcl_IncrRefCount(hdPtr->cmdObj); - } else { - hdPtr->cmdObj = NULL; - } - break; - } - } - return TCL_OK; -} - -/* - * ---------------------------------------------------------------------- - * - * FontchooserShowCmd -- - * - * Implements the 'tk fontchooser show' ensemble command. The per-interp - * configuration data for the dialog is held in an interp associated - * structure. - * - * Calls the Win32 FontChooser API which provides a modal dialog. See - * HookProc where we make a few changes to the dialog and set some - * additional state. - * - * ---------------------------------------------------------------------- - */ - -static int -FontchooserShowCmd( - ClientData clientData, /* Main window */ - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - Tcl_DString ds; - Tk_Window tkwin = clientData, parent; - CHOOSEFONT cf; - LOGFONT lf; - HDC hdc; - HookData *hdPtr; - int r = TCL_OK, oldMode = 0; - - hdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser", NULL); - - parent = tkwin; - if (hdPtr->parentObj) { - parent = Tk_NameToWindow(interp, Tcl_GetString(hdPtr->parentObj), - tkwin); - if (parent == None) { - return TCL_ERROR; - } - } - - Tk_MakeWindowExist(parent); - - ZeroMemory(&cf, sizeof(CHOOSEFONT)); - ZeroMemory(&lf, sizeof(LOGFONT)); - lf.lfCharSet = DEFAULT_CHARSET; - cf.lStructSize = sizeof(CHOOSEFONT); - cf.hwndOwner = Tk_GetHWND(Tk_WindowId(parent)); - cf.lpLogFont = &lf; - cf.nFontType = SCREEN_FONTTYPE; - cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_ENABLEHOOK; - cf.rgbColors = RGB(0,0,0); - cf.lpfnHook = HookProc; - cf.lCustData = (INT_PTR) hdPtr; - hdPtr->interp = interp; - hdPtr->parent = parent; - hdc = GetDC(cf.hwndOwner); - - if (hdPtr->fontObj != NULL) { - TkFont *fontPtr; - Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, hdPtr->fontObj); - - if (f == NULL) { - return TCL_ERROR; - } - fontPtr = (TkFont *) f; - cf.Flags |= CF_INITTOLOGFONTSTRUCT; - Tcl_WinUtfToTChar(fontPtr->fa.family, -1, &ds); - _tcsncpy(lf.lfFaceName, (TCHAR *)Tcl_DStringValue(&ds), - LF_FACESIZE-1); - Tcl_DStringFree(&ds); - lf.lfFaceName[LF_FACESIZE-1] = 0; - lf.lfHeight = -MulDiv((int)(TkFontGetPoints(tkwin, fontPtr->fa.size) + 0.5), - GetDeviceCaps(hdc, LOGPIXELSY), 72); - if (fontPtr->fa.weight == TK_FW_BOLD) { - lf.lfWeight = FW_BOLD; - } - if (fontPtr->fa.slant != TK_FS_ROMAN) { - lf.lfItalic = TRUE; - } - if (fontPtr->fa.underline) { - lf.lfUnderline = TRUE; - } - if (fontPtr->fa.overstrike) { - lf.lfStrikeOut = TRUE; - } - Tk_FreeFont(f); - } - - if (TCL_OK == r && hdPtr->cmdObj != NULL) { - int len = 0; - - r = Tcl_ListObjLength(interp, hdPtr->cmdObj, &len); - if (len > 0) { - cf.Flags |= CF_APPLY; - } - } - - if (TCL_OK == r) { - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - if (ChooseFont(&cf)) { - if (hdPtr->cmdObj) { - ApplyLogfont(hdPtr->interp, hdPtr->cmdObj, hdc, &lf); - } - if (hdPtr->parent) { - TkSendVirtualEvent(hdPtr->parent, "TkFontchooserFontChanged", NULL); - } - } - Tcl_SetServiceMode(oldMode); - EnableWindow(cf.hwndOwner, 1); - } - - ReleaseDC(cf.hwndOwner, hdc); - return r; -} - -/* - * ---------------------------------------------------------------------- - * - * FontchooserHideCmd -- - * - * Implementation of the 'tk fontchooser hide' ensemble. See the user - * documentation for details. - * As the Win32 FontChooser function is always modal all we do here is - * destroy the dialog - * - * ---------------------------------------------------------------------- - */ - -static int -FontchooserHideCmd( - ClientData clientData, /* Main window */ - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - HookData *hdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser", NULL); - - if (hdPtr->hwnd && IsWindow(hdPtr->hwnd)) { - EndDialog(hdPtr->hwnd, 0); - } - return TCL_OK; -} - -/* - * ---------------------------------------------------------------------- - * - * DeleteHookData -- - * - * Clean up the font chooser configuration data when the interp is - * destroyed. - * - * ---------------------------------------------------------------------- - */ - -static void -DeleteHookData(ClientData clientData, Tcl_Interp *interp) -{ - HookData *hdPtr = clientData; - - if (hdPtr->parentObj) { - Tcl_DecrRefCount(hdPtr->parentObj); - } - if (hdPtr->fontObj) { - Tcl_DecrRefCount(hdPtr->fontObj); - } - if (hdPtr->titleObj) { - Tcl_DecrRefCount(hdPtr->titleObj); - } - if (hdPtr->cmdObj) { - Tcl_DecrRefCount(hdPtr->cmdObj); - } - ckfree(hdPtr); -} - -/* - * ---------------------------------------------------------------------- - * - * TkInitFontchooser -- - * - * Associate the font chooser configuration data with the Tcl - * interpreter. There is one font chooser per interp. - * - * ---------------------------------------------------------------------- - */ - -MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[]; -const TkEnsemble tkFontchooserEnsemble[] = { - { "configure", FontchooserConfigureCmd, NULL }, - { "show", FontchooserShowCmd, NULL }, - { "hide", FontchooserHideCmd, NULL }, - { NULL, NULL, NULL } -}; - -int -TkInitFontchooser(Tcl_Interp *interp, ClientData clientData) -{ - HookData *hdPtr = ckalloc(sizeof(HookData)); - - memset(hdPtr, 0, sizeof(HookData)); - Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteHookData, hdPtr); - return TCL_OK; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinDraw.c b/tk8.6/win/tkWinDraw.c deleted file mode 100644 index e13a5e5..0000000 --- a/tk8.6/win/tkWinDraw.c +++ /dev/null @@ -1,1523 +0,0 @@ -/* - * tkWinDraw.c -- - * - * This file contains the Xlib emulation functions pertaining to actually - * drawing objects on a window. - * - * Copyright (c) 1995 Sun Microsystems, Inc. - * Copyright (c) 1994 Software Research Associates, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - -/* - * These macros convert between X's bizarre angle units to radians. - */ - -#define XAngleToRadians(a) ((double)(a) / 64 * PI / 180); - -/* - * Translation table between X gc functions and Win32 raster op modes. - */ - -const int tkpWinRopModes[] = { - R2_BLACK, /* GXclear */ - R2_MASKPEN, /* GXand */ - R2_MASKPENNOT, /* GXandReverse */ - R2_COPYPEN, /* GXcopy */ - R2_MASKNOTPEN, /* GXandInverted */ - R2_NOT, /* GXnoop */ - R2_XORPEN, /* GXxor */ - R2_MERGEPEN, /* GXor */ - R2_NOTMERGEPEN, /* GXnor */ - R2_NOTXORPEN, /* GXequiv */ - R2_NOT, /* GXinvert */ - R2_MERGEPENNOT, /* GXorReverse */ - R2_NOTCOPYPEN, /* GXcopyInverted */ - R2_MERGENOTPEN, /* GXorInverted */ - R2_NOTMASKPEN, /* GXnand */ - R2_WHITE /* GXset */ -}; - -/* - * Translation table between X gc functions and Win32 BitBlt op modes. Some of - * the operations defined in X don't have names, so we have to construct new - * opcodes for those functions. This is arcane and probably not all that - * useful, but at least it's accurate. - */ - -#define NOTSRCAND (DWORD)0x00220326 /* dest = (NOT source) AND dest */ -#define NOTSRCINVERT (DWORD)0x00990066 /* dest = (NOT source) XOR dest */ -#define SRCORREVERSE (DWORD)0x00DD0228 /* dest = source OR (NOT dest) */ -#define SRCNAND (DWORD)0x007700E6 /* dest = NOT (source AND dest) */ - -const int tkpWinBltModes[] = { - BLACKNESS, /* GXclear */ - SRCAND, /* GXand */ - SRCERASE, /* GXandReverse */ - SRCCOPY, /* GXcopy */ - NOTSRCAND, /* GXandInverted */ - PATCOPY, /* GXnoop */ - SRCINVERT, /* GXxor */ - SRCPAINT, /* GXor */ - NOTSRCERASE, /* GXnor */ - NOTSRCINVERT, /* GXequiv */ - DSTINVERT, /* GXinvert */ - SRCORREVERSE, /* GXorReverse */ - NOTSRCCOPY, /* GXcopyInverted */ - MERGEPAINT, /* GXorInverted */ - SRCNAND, /* GXnand */ - WHITENESS /* GXset */ -}; - -/* - * The following raster op uses the source bitmap as a mask for the pattern. - * This is used to draw in a foreground color but leave the background color - * transparent. - */ - -#define MASKPAT 0x00E20746 /* dest = (src & pat) | (!src & dst) */ - -/* - * The following two raster ops are used to copy the foreground and background - * bits of a source pattern as defined by a stipple used as the pattern. - */ - -#define COPYFG 0x00CA0749 /* dest = (pat & src) | (!pat & dst) */ -#define COPYBG 0x00AC0744 /* dest = (!pat & src) | (pat & dst) */ - -/* - * Macros used later in the file. - */ -#ifndef MIN -# define MIN(a,b) ((a>b) ? b : a) -# define MAX(a,b) ((a<b) ? b : a) -#endif - -/* - * The followng typedef is used to pass Windows GDI drawing functions. - */ - -typedef BOOL (CALLBACK *WinDrawFunc)(HDC dc, const POINT *points, int npoints); - -typedef struct ThreadSpecificData { - POINT *winPoints; /* Array of points that is reused. */ - int nWinPoints; /* Current size of point array. */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -/* - * Forward declarations for functions defined in this file: - */ - -static POINT * ConvertPoints(XPoint *points, int npoints, int mode, - RECT *bbox); -static int DrawOrFillArc(Display *display, Drawable d, GC gc, - int x, int y, unsigned int width, - unsigned int height, int start, int extent, - int fill); -static void RenderObject(HDC dc, GC gc, XPoint* points, - int npoints, int mode, HPEN pen, WinDrawFunc func); -static HPEN SetUpGraphicsPort(GC gc); - -/* - *---------------------------------------------------------------------- - * - * TkWinGetDrawableDC -- - * - * Retrieve the DC from a drawable. - * - * Results: - * Returns the window DC for windows. Returns a new memory DC for - * pixmaps. - * - * Side effects: - * Sets up the palette for the device context, and saves the old device - * context state in the passed in TkWinDCState structure. - * - *---------------------------------------------------------------------- - */ - -HDC -TkWinGetDrawableDC( - Display *display, - Drawable d, - TkWinDCState *state) -{ - HDC dc; - TkWinDrawable *twdPtr = (TkWinDrawable *)d; - Colormap cmap; - - if (twdPtr->type == TWD_WINDOW) { - TkWindow *winPtr = twdPtr->window.winPtr; - - dc = GetDC(twdPtr->window.handle); - if (winPtr == NULL) { - cmap = DefaultColormap(display, DefaultScreen(display)); - } else { - cmap = winPtr->atts.colormap; - } - } else if (twdPtr->type == TWD_WINDC) { - dc = twdPtr->winDC.hdc; - cmap = DefaultColormap(display, DefaultScreen(display)); - } else { - dc = CreateCompatibleDC(NULL); - SelectObject(dc, twdPtr->bitmap.handle); - cmap = twdPtr->bitmap.colormap; - } - state->palette = TkWinSelectPalette(dc, cmap); - state->bkmode = GetBkMode(dc); - return dc; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinReleaseDrawableDC -- - * - * Frees the resources associated with a drawable's DC. - * - * Results: - * None. - * - * Side effects: - * Restores the old bitmap handle to the memory DC for pixmaps. - * - *---------------------------------------------------------------------- - */ - -void -TkWinReleaseDrawableDC( - Drawable d, - HDC dc, - TkWinDCState *state) -{ - TkWinDrawable *twdPtr = (TkWinDrawable *)d; - - SetBkMode(dc, state->bkmode); - SelectPalette(dc, state->palette, TRUE); - RealizePalette(dc); - if (twdPtr->type == TWD_WINDOW) { - ReleaseDC(TkWinGetHWND(d), dc); - } else if (twdPtr->type == TWD_BITMAP) { - DeleteDC(dc); - } -} - -/* - *---------------------------------------------------------------------- - * - * ConvertPoints -- - * - * Convert an array of X points to an array of Win32 points. - * - * Results: - * Returns the converted array of POINTs. - * - * Side effects: - * Allocates a block of memory in thread local storage that should not be - * freed. - * - *---------------------------------------------------------------------- - */ - -static POINT * -ConvertPoints( - XPoint *points, - int npoints, - int mode, /* CoordModeOrigin or CoordModePrevious. */ - RECT *bbox) /* Bounding box of points. */ -{ - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - int i; - - /* - * To avoid paying the cost of a malloc on every drawing routine, we reuse - * the last array if it is large enough. - */ - - if (npoints > tsdPtr->nWinPoints) { - if (tsdPtr->winPoints != NULL) { - ckfree(tsdPtr->winPoints); - } - tsdPtr->winPoints = ckalloc(sizeof(POINT) * npoints); - if (tsdPtr->winPoints == NULL) { - tsdPtr->nWinPoints = -1; - return NULL; - } - tsdPtr->nWinPoints = npoints; - } - - bbox->left = bbox->right = points[0].x; - bbox->top = bbox->bottom = points[0].y; - - if (mode == CoordModeOrigin) { - for (i = 0; i < npoints; i++) { - tsdPtr->winPoints[i].x = points[i].x; - tsdPtr->winPoints[i].y = points[i].y; - bbox->left = MIN(bbox->left, tsdPtr->winPoints[i].x); - bbox->right = MAX(bbox->right, tsdPtr->winPoints[i].x); - bbox->top = MIN(bbox->top, tsdPtr->winPoints[i].y); - bbox->bottom = MAX(bbox->bottom, tsdPtr->winPoints[i].y); - } - } else { - tsdPtr->winPoints[0].x = points[0].x; - tsdPtr->winPoints[0].y = points[0].y; - for (i = 1; i < npoints; i++) { - tsdPtr->winPoints[i].x = tsdPtr->winPoints[i-1].x + points[i].x; - tsdPtr->winPoints[i].y = tsdPtr->winPoints[i-1].y + points[i].y; - bbox->left = MIN(bbox->left, tsdPtr->winPoints[i].x); - bbox->right = MAX(bbox->right, tsdPtr->winPoints[i].x); - bbox->top = MIN(bbox->top, tsdPtr->winPoints[i].y); - bbox->bottom = MAX(bbox->bottom, tsdPtr->winPoints[i].y); - } - } - return tsdPtr->winPoints; -} - -/* - *---------------------------------------------------------------------- - * - * XCopyArea -- - * - * Copies data from one drawable to another using block transfer - * routines. - * - * Results: - * None. - * - * Side effects: - * Data is moved from a window or bitmap to a second window or bitmap. - * - *---------------------------------------------------------------------- - */ - -int -XCopyArea( - Display *display, - Drawable src, - Drawable dest, - GC gc, - int src_x, int src_y, - unsigned int width, unsigned int height, - int dest_x, int dest_y) -{ - HDC srcDC, destDC; - TkWinDCState srcState, destState; - TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; - - srcDC = TkWinGetDrawableDC(display, src, &srcState); - - if (src != dest) { - destDC = TkWinGetDrawableDC(display, dest, &destState); - } else { - destDC = srcDC; - } - - if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { - SelectClipRgn(destDC, (HRGN) clipPtr->value.region); - OffsetClipRgn(destDC, gc->clip_x_origin, gc->clip_y_origin); - } - - BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, srcDC, - src_x, src_y, (DWORD) tkpWinBltModes[gc->function]); - - SelectClipRgn(destDC, NULL); - - if (src != dest) { - TkWinReleaseDrawableDC(dest, destDC, &destState); - } - TkWinReleaseDrawableDC(src, srcDC, &srcState); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XCopyPlane -- - * - * Copies a bitmap from a source drawable to a destination drawable. The - * plane argument specifies which bit plane of the source contains the - * bitmap. Note that this implementation ignores the gc->function. - * - * Results: - * None. - * - * Side effects: - * Changes the destination drawable. - * - *---------------------------------------------------------------------- - */ - -int -XCopyPlane( - Display *display, - Drawable src, - Drawable dest, - GC gc, - int src_x, int src_y, - unsigned int width, unsigned int height, - int dest_x, int dest_y, - unsigned long plane) -{ - HDC srcDC, destDC; - TkWinDCState srcState, destState; - HBRUSH bgBrush, fgBrush, oldBrush; - TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; - - display->request++; - - if (plane != 1) { - Tcl_Panic("Unexpected plane specified for XCopyPlane"); - } - - srcDC = TkWinGetDrawableDC(display, src, &srcState); - - if (src != dest) { - destDC = TkWinGetDrawableDC(display, dest, &destState); - } else { - destDC = srcDC; - } - - if (clipPtr == NULL || clipPtr->type == TKP_CLIP_REGION) { - /* - * Case 1: opaque bitmaps. Windows handles the conversion from one bit - * to multiple bits by setting 0 to the foreground color, and 1 to the - * background color (seems backwards, but there you are). - */ - - if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { - SelectClipRgn(destDC, (HRGN) clipPtr->value.region); - OffsetClipRgn(destDC, gc->clip_x_origin, gc->clip_y_origin); - } - - SetBkMode(destDC, OPAQUE); - SetBkColor(destDC, gc->foreground); - SetTextColor(destDC, gc->background); - BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, srcDC, - src_x, src_y, SRCCOPY); - - SelectClipRgn(destDC, NULL); - } else if (clipPtr->type == TKP_CLIP_PIXMAP) { - if (clipPtr->value.pixmap == src) { - - /* - * Case 2: transparent bitmaps are handled by setting the - * destination to the foreground color whenever the source pixel - * is set. - */ - - fgBrush = CreateSolidBrush(gc->foreground); - oldBrush = SelectObject(destDC, fgBrush); - SetBkColor(destDC, RGB(255,255,255)); - SetTextColor(destDC, RGB(0,0,0)); - BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, srcDC, - src_x, src_y, MASKPAT); - SelectObject(destDC, oldBrush); - DeleteObject(fgBrush); - } else { - - /* - * Case 3: two arbitrary bitmaps. Copy the source rectangle into a - * color pixmap. Use the result as a brush when copying the clip - * mask into the destination. - */ - - HDC memDC, maskDC; - HBITMAP bitmap; - TkWinDCState maskState; - - fgBrush = CreateSolidBrush(gc->foreground); - bgBrush = CreateSolidBrush(gc->background); - maskDC = TkWinGetDrawableDC(display, clipPtr->value.pixmap, - &maskState); - memDC = CreateCompatibleDC(destDC); - bitmap = CreateBitmap((int) width, (int) height, 1, 1, NULL); - SelectObject(memDC, bitmap); - - /* - * Set foreground bits. We create a new bitmap containing (source - * AND mask), then use it to set the foreground color into the - * destination. - */ - - BitBlt(memDC, 0, 0, (int) width, (int) height, srcDC, src_x, src_y, - SRCCOPY); - BitBlt(memDC, 0, 0, (int) width, (int) height, maskDC, - dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin, - SRCAND); - oldBrush = SelectObject(destDC, fgBrush); - BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, memDC, - 0, 0, MASKPAT); - - /* - * Set background bits. Same as foreground, except we use ((NOT - * source) AND mask) and the background brush. - */ - - BitBlt(memDC, 0, 0, (int) width, (int) height, srcDC, src_x, src_y, - NOTSRCCOPY); - BitBlt(memDC, 0, 0, (int) width, (int) height, maskDC, - dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin, - SRCAND); - SelectObject(destDC, bgBrush); - BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, memDC, - 0, 0, MASKPAT); - - TkWinReleaseDrawableDC(clipPtr->value.pixmap, maskDC, &maskState); - SelectObject(destDC, oldBrush); - DeleteDC(memDC); - DeleteObject(bitmap); - DeleteObject(fgBrush); - DeleteObject(bgBrush); - } - } - if (src != dest) { - TkWinReleaseDrawableDC(dest, destDC, &destState); - } - TkWinReleaseDrawableDC(src, srcDC, &srcState); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * TkPutImage, XPutImage -- - * - * Copies a subimage from an in-memory image to a rectangle of of the - * specified drawable. - * - * Results: - * None. - * - * Side effects: - * Draws the image on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -int -TkPutImage( - unsigned long *colors, /* Array of pixel values used by this image. - * May be NULL. */ - int ncolors, /* Number of colors used, or 0. */ - Display *display, - Drawable d, /* Destination drawable. */ - GC gc, - XImage *image, /* Source image. */ - int src_x, int src_y, /* Offset of subimage. */ - int dest_x, int dest_y, /* Position of subimage origin in drawable. */ - unsigned int width, unsigned int height) - /* Dimensions of subimage. */ -{ - HDC dc, dcMem; - TkWinDCState state; - BITMAPINFO *infoPtr; - HBITMAP bitmap; - char *data; - - display->request++; - - dc = TkWinGetDrawableDC(display, d, &state); - SetROP2(dc, tkpWinRopModes[gc->function]); - dcMem = CreateCompatibleDC(dc); - - if (image->bits_per_pixel == 1) { - /* - * If the image isn't in the right format, we have to copy it into a - * new buffer in MSBFirst and word-aligned format. - */ - - if ((image->bitmap_bit_order != MSBFirst) - || (image->bitmap_pad != sizeof(WORD))) { - data = TkAlignImageData(image, sizeof(WORD), MSBFirst); - bitmap = CreateBitmap(image->width, image->height, 1, 1, data); - ckfree(data); - } else { - bitmap = CreateBitmap(image->width, image->height, 1, 1, - image->data); - } - SetTextColor(dc, gc->foreground); - SetBkColor(dc, gc->background); - } else { - int i, usePalette; - - /* - * Do not use a palette for TrueColor images. - */ - - usePalette = (image->bits_per_pixel < 16); - - if (usePalette) { - infoPtr = ckalloc(sizeof(BITMAPINFOHEADER) - + sizeof(RGBQUAD)*ncolors); - } else { - infoPtr = ckalloc(sizeof(BITMAPINFOHEADER)); - } - - infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - infoPtr->bmiHeader.biWidth = image->width; - infoPtr->bmiHeader.biHeight = -image->height; /* Top-down order */ - infoPtr->bmiHeader.biPlanes = 1; - infoPtr->bmiHeader.biBitCount = image->bits_per_pixel; - infoPtr->bmiHeader.biCompression = BI_RGB; - infoPtr->bmiHeader.biSizeImage = 0; - infoPtr->bmiHeader.biXPelsPerMeter = 0; - infoPtr->bmiHeader.biYPelsPerMeter = 0; - infoPtr->bmiHeader.biClrImportant = 0; - - if (usePalette) { - infoPtr->bmiHeader.biClrUsed = ncolors; - for (i = 0; i < ncolors; i++) { - infoPtr->bmiColors[i].rgbBlue = GetBValue(colors[i]); - infoPtr->bmiColors[i].rgbGreen = GetGValue(colors[i]); - infoPtr->bmiColors[i].rgbRed = GetRValue(colors[i]); - infoPtr->bmiColors[i].rgbReserved = 0; - } - } else { - infoPtr->bmiHeader.biClrUsed = 0; - } - bitmap = CreateDIBitmap(dc, &infoPtr->bmiHeader, CBM_INIT, - image->data, infoPtr, DIB_RGB_COLORS); - ckfree(infoPtr); - } - if (!bitmap) { - Tcl_Panic("Fail to allocate bitmap"); - DeleteDC(dcMem); - TkWinReleaseDrawableDC(d, dc, &state); - return BadValue; - } - bitmap = SelectObject(dcMem, bitmap); - BitBlt(dc, dest_x, dest_y, (int) width, (int) height, dcMem, src_x, src_y, - SRCCOPY); - DeleteObject(SelectObject(dcMem, bitmap)); - DeleteDC(dcMem); - TkWinReleaseDrawableDC(d, dc, &state); - return Success; -} - -int -XPutImage( - Display *display, - Drawable d, /* Destination drawable. */ - GC gc, - XImage *image, /* Source image. */ - int src_x, int src_y, /* Offset of subimage. */ - int dest_x, int dest_y, /* Position of subimage origin in drawable. */ - unsigned int width, unsigned int height) - /* Dimensions of subimage. */ -{ - return TkPutImage(NULL, 0, display, d, gc, image, - src_x, src_y, dest_x, dest_y, width, height); -} - -/* - *---------------------------------------------------------------------- - * - * XFillRectangles -- - * - * Fill multiple rectangular areas in the given drawable. - * - * Results: - * None. - * - * Side effects: - * Draws onto the specified drawable. - * - *---------------------------------------------------------------------- - */ - -int -XFillRectangles( - Display *display, - Drawable d, - GC gc, - XRectangle *rectangles, - int nrectangles) -{ - HDC dc; - RECT rect; - TkWinDCState state; - HBRUSH brush, oldBrush; - - if (d == None) { - return BadDrawable; - } - - dc = TkWinGetDrawableDC(display, d, &state); - SetROP2(dc, tkpWinRopModes[gc->function]); - brush = CreateSolidBrush(gc->foreground); - - if ((gc->fill_style == FillStippled - || gc->fill_style == FillOpaqueStippled) - && gc->stipple != None) { - TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; - HBRUSH stipple; - HBITMAP oldBitmap, bitmap; - HDC dcMem; - HBRUSH bgBrush = CreateSolidBrush(gc->background); - - if (twdPtr->type != TWD_BITMAP) { - Tcl_Panic("unexpected drawable type in stipple"); - } - - /* - * Select stipple pattern into destination dc. - */ - - stipple = CreatePatternBrush(twdPtr->bitmap.handle); - SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL); - oldBrush = SelectObject(dc, stipple); - dcMem = CreateCompatibleDC(dc); - - /* - * For each rectangle, create a drawing surface which is the size of - * the rectangle and fill it with the background color. Then merge the - * result with the stipple pattern. - */ - - while (nrectangles-- > 0) { - bitmap = CreateCompatibleBitmap(dc, rectangles[0].width, - rectangles[0].height); - oldBitmap = SelectObject(dcMem, bitmap); - rect.left = 0; - rect.top = 0; - rect.right = rectangles[0].width; - rect.bottom = rectangles[0].height; - FillRect(dcMem, &rect, brush); - BitBlt(dc, rectangles[0].x, rectangles[0].y, rectangles[0].width, - rectangles[0].height, dcMem, 0, 0, COPYFG); - if (gc->fill_style == FillOpaqueStippled) { - FillRect(dcMem, &rect, bgBrush); - BitBlt(dc, rectangles[0].x, rectangles[0].y, - rectangles[0].width, rectangles[0].height, dcMem, - 0, 0, COPYBG); - } - SelectObject(dcMem, oldBitmap); - DeleteObject(bitmap); - ++rectangles; - } - - DeleteDC(dcMem); - SelectObject(dc, oldBrush); - DeleteObject(stipple); - DeleteObject(bgBrush); - } else { - if (gc->function == GXcopy) { - while (nrectangles-- > 0) { - rect.left = rectangles[0].x; - rect.right = rect.left + rectangles[0].width; - rect.top = rectangles[0].y; - rect.bottom = rect.top + rectangles[0].height; - FillRect(dc, &rect, brush); - ++rectangles; - } - } else { - HPEN newPen = CreatePen(PS_NULL, 0, gc->foreground); - HPEN oldPen = SelectObject(dc, newPen); - oldBrush = SelectObject(dc, brush); - - while (nrectangles-- > 0) { - Rectangle(dc, rectangles[0].x, rectangles[0].y, - rectangles[0].x + rectangles[0].width + 1, - rectangles[0].y + rectangles[0].height + 1); - ++rectangles; - } - - SelectObject(dc, oldBrush); - SelectObject(dc, oldPen); - DeleteObject(newPen); - } - } - DeleteObject(brush); - TkWinReleaseDrawableDC(d, dc, &state); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * MakeAndStrokePath -- - * - * This function draws a shape using a list of points, a stipple pattern, - * and the specified drawing function. It does it through creation of a - * so-called 'path' (see GDI documentation on MSDN). - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -static void -MakeAndStrokePath( - HDC dc, - POINT *winPoints, - int npoints, - WinDrawFunc func) /* Name of the Windows GDI drawing function: - this is either Polyline or Polygon. */ -{ - BeginPath(dc); - func(dc, winPoints, npoints); - /* - * In the case of closed polylines, the first and last points - * are the same. We want miter or bevel join be rendered also - * at this point, this needs telling the Windows GDI that the - * path is closed. - */ - if (func == Polyline) { - if ((winPoints[0].x == winPoints[npoints-1].x) && - (winPoints[0].y == winPoints[npoints-1].y)) { - CloseFigure(dc); - } - EndPath(dc); - StrokePath(dc); - } else { - EndPath(dc); - StrokeAndFillPath(dc); - } -} - -/* - *---------------------------------------------------------------------- - * - * RenderObject -- - * - * This function draws a shape using a list of points, a stipple pattern, - * and the specified drawing function. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -RenderObject( - HDC dc, - GC gc, - XPoint *points, - int npoints, - int mode, - HPEN pen, - WinDrawFunc func) -{ - RECT rect = {0,0,0,0}; - HPEN oldPen; - HBRUSH oldBrush; - POINT *winPoints = ConvertPoints(points, npoints, mode, &rect); - - if ((gc->fill_style == FillStippled - || gc->fill_style == FillOpaqueStippled) - && gc->stipple != None) { - - TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; - HDC dcMem; - LONG width, height; - HBITMAP oldBitmap; - int i; - HBRUSH oldMemBrush; - - if (twdPtr->type != TWD_BITMAP) { - Tcl_Panic("unexpected drawable type in stipple"); - } - - /* - * Grow the bounding box enough to account for line width. - */ - - rect.left -= gc->line_width; - rect.top -= gc->line_width; - rect.right += gc->line_width; - rect.bottom += gc->line_width; - - width = rect.right - rect.left; - height = rect.bottom - rect.top; - - /* - * Select stipple pattern into destination dc. - */ - - SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL); - oldBrush = SelectObject(dc, CreatePatternBrush(twdPtr->bitmap.handle)); - - /* - * Create temporary drawing surface containing a copy of the - * destination equal in size to the bounding box of the object. - */ - - dcMem = CreateCompatibleDC(dc); - oldBitmap = SelectObject(dcMem, CreateCompatibleBitmap(dc, width, - height)); - oldPen = SelectObject(dcMem, pen); - BitBlt(dcMem, 0, 0, width, height, dc, rect.left, rect.top, SRCCOPY); - - /* - * Translate the object for rendering in the temporary drawing - * surface. - */ - - for (i = 0; i < npoints; i++) { - winPoints[i].x -= rect.left; - winPoints[i].y -= rect.top; - } - - /* - * Draw the object in the foreground color and copy it to the - * destination wherever the pattern is set. - */ - - SetPolyFillMode(dcMem, (gc->fill_rule == EvenOddRule) ? ALTERNATE - : WINDING); - oldMemBrush = SelectObject(dcMem, CreateSolidBrush(gc->foreground)); - MakeAndStrokePath(dcMem, winPoints, npoints, func); - BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, COPYFG); - - /* - * If we are rendering an opaque stipple, then draw the polygon in the - * background color and copy it to the destination wherever the - * pattern is clear. - */ - - if (gc->fill_style == FillOpaqueStippled) { - DeleteObject(SelectObject(dcMem, - CreateSolidBrush(gc->background))); - MakeAndStrokePath(dcMem, winPoints, npoints, func); - BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, - COPYBG); - } - - SelectObject(dcMem, oldPen); - DeleteObject(SelectObject(dcMem, oldMemBrush)); - DeleteObject(SelectObject(dcMem, oldBitmap)); - DeleteDC(dcMem); - } else { - oldPen = SelectObject(dc, pen); - oldBrush = SelectObject(dc, CreateSolidBrush(gc->foreground)); - SetROP2(dc, tkpWinRopModes[gc->function]); - - SetPolyFillMode(dc, (gc->fill_rule == EvenOddRule) ? ALTERNATE - : WINDING); - MakeAndStrokePath(dc, winPoints, npoints, func); - SelectObject(dc, oldPen); - } - DeleteObject(SelectObject(dc, oldBrush)); -} - -/* - *---------------------------------------------------------------------- - * - * XDrawLines -- - * - * Draw connected lines. - * - * Results: - * None. - * - * Side effects: - * Renders a series of connected lines. - * - *---------------------------------------------------------------------- - */ - -int -XDrawLines( - Display *display, - Drawable d, - GC gc, - XPoint *points, - int npoints, - int mode) -{ - HPEN pen; - TkWinDCState state; - HDC dc; - - if (d == None) { - return BadDrawable; - } - - dc = TkWinGetDrawableDC(display, d, &state); - - pen = SetUpGraphicsPort(gc); - SetBkMode(dc, TRANSPARENT); - RenderObject(dc, gc, points, npoints, mode, pen, Polyline); - DeleteObject(pen); - - TkWinReleaseDrawableDC(d, dc, &state); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XFillPolygon -- - * - * Draws a filled polygon. - * - * Results: - * None. - * - * Side effects: - * Draws a filled polygon on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -int -XFillPolygon( - Display *display, - Drawable d, - GC gc, - XPoint *points, - int npoints, - int shape, - int mode) -{ - HPEN pen; - TkWinDCState state; - HDC dc; - - if (d == None) { - return BadDrawable; - } - - dc = TkWinGetDrawableDC(display, d, &state); - - pen = GetStockObject(NULL_PEN); - RenderObject(dc, gc, points, npoints, mode, pen, Polygon); - - TkWinReleaseDrawableDC(d, dc, &state); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XDrawRectangle, XDrawRectangles -- - * - * Draws a rectangle. - * - * Results: - * None. - * - * Side effects: - * Draws a rectangle on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -int -XDrawRectangle( - Display *display, - Drawable d, - GC gc, - int x, int y, - unsigned int width, unsigned int height) -{ - HPEN pen, oldPen; - TkWinDCState state; - HBRUSH oldBrush; - HDC dc; - - if (d == None) { - return BadDrawable; - } - - dc = TkWinGetDrawableDC(display, d, &state); - - pen = SetUpGraphicsPort(gc); - SetBkMode(dc, TRANSPARENT); - oldPen = SelectObject(dc, pen); - oldBrush = SelectObject(dc, GetStockObject(NULL_BRUSH)); - SetROP2(dc, tkpWinRopModes[gc->function]); - - Rectangle(dc, x, y, (int) x+width+1, (int) y+height+1); - - DeleteObject(SelectObject(dc, oldPen)); - SelectObject(dc, oldBrush); - TkWinReleaseDrawableDC(d, dc, &state); - return Success; -} - -int -XDrawRectangles( - Display *display, - Drawable d, - GC gc, - XRectangle rects[], - int nrects) -{ - int ret = Success; - - while (nrects-- > 0) { - ret = XDrawRectangle(display, d, gc, rects[0].x, rects[0].y, - rects[0].width, rects[0].height); - if (ret != Success) { - break; - } - ++rects; - } - return ret; -} - -/* - *---------------------------------------------------------------------- - * - * XDrawArc, XDrawArcs -- - * - * Draw an arc. - * - * Results: - * None. - * - * Side effects: - * Draws an arc on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -int -XDrawArc( - Display *display, - Drawable d, - GC gc, - int x, int y, - unsigned int width, unsigned int height, - int start, int extent) -{ - display->request++; - - return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 0); -} - -int -XDrawArcs( - Display *display, - Drawable d, - GC gc, - XArc *arcs, - int narcs) -{ - int ret = Success; - - display->request++; - - while (narcs-- > 0) { - ret = DrawOrFillArc(display, d, gc, arcs[0].x, arcs[0].y, - arcs[0].width, arcs[0].height, - arcs[0].angle1, arcs[0].angle2, 0); - if (ret != Success) { - break; - } - ++arcs; - } - return ret; -} - -/* - *---------------------------------------------------------------------- - * - * XFillArc, XFillArcs -- - * - * Draw a filled arc. - * - * Results: - * None. - * - * Side effects: - * Draws a filled arc on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -int -XFillArc( - Display *display, - Drawable d, - GC gc, - int x, int y, - unsigned int width, unsigned int height, - int start, int extent) -{ - display->request++; - - return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 1); -} - -int -XFillArcs( - Display *display, - Drawable d, - GC gc, - XArc *arcs, - int narcs) -{ - int ret = Success; - - display->request++; - - while (narcs-- > 0) { - ret = DrawOrFillArc(display, d, gc, arcs[0].x, arcs[0].y, - arcs[0].width, arcs[0].height, - arcs[0].angle1, arcs[0].angle2, 1); - if (ret != Success) { - break; - } - ++arcs; - } - return ret; -} - -/* - *---------------------------------------------------------------------- - * - * DrawOrFillArc -- - * - * This function handles the rendering of drawn or filled arcs and - * chords. - * - * Results: - * None. - * - * Side effects: - * Renders the requested arc. - * - *---------------------------------------------------------------------- - */ - -static int -DrawOrFillArc( - Display *display, - Drawable d, - GC gc, - int x, int y, /* left top */ - unsigned int width, unsigned int height, - int start, /* start: three-o'clock (deg*64) */ - int extent, /* extent: relative (deg*64) */ - int fill) /* ==0 draw, !=0 fill */ -{ - HDC dc; - HBRUSH brush, oldBrush; - HPEN pen, oldPen; - TkWinDCState state; - int clockwise = (extent < 0); /* non-zero if clockwise */ - int xstart, ystart, xend, yend; - double radian_start, radian_end, xr, yr; - - if (d == None) { - return BadDrawable; - } - - dc = TkWinGetDrawableDC(display, d, &state); - - SetROP2(dc, tkpWinRopModes[gc->function]); - - /* - * Compute the absolute starting and ending angles in normalized radians. - * Swap the start and end if drawing clockwise. - */ - - start = start % (64*360); - if (start < 0) { - start += (64*360); - } - extent = (start+extent) % (64*360); - if (extent < 0) { - extent += (64*360); - } - if (clockwise) { - int tmp = start; - start = extent; - extent = tmp; - } - radian_start = XAngleToRadians(start); - radian_end = XAngleToRadians(extent); - - /* - * Now compute points on the radial lines that define the starting and - * ending angles. Be sure to take into account that the y-coordinate - * system is inverted. - */ - - xr = x + width / 2.0; - yr = y + height / 2.0; - xstart = (int)((xr + cos(radian_start)*width/2.0) + 0.5); - ystart = (int)((yr + sin(-radian_start)*height/2.0) + 0.5); - xend = (int)((xr + cos(radian_end)*width/2.0) + 0.5); - yend = (int)((yr + sin(-radian_end)*height/2.0) + 0.5); - - /* - * Now draw a filled or open figure. Note that we have to increase the - * size of the bounding box by one to account for the difference in pixel - * definitions between X and Windows. - */ - - pen = SetUpGraphicsPort(gc); - oldPen = SelectObject(dc, pen); - if (!fill) { - /* - * Note that this call will leave a gap of one pixel at the end of the - * arc for thin arcs. We can't use ArcTo because it's only supported - * under Windows NT. - */ - - SetBkMode(dc, TRANSPARENT); - Arc(dc, x, y, (int) (x+width+1), (int) (y+height+1), xstart, ystart, - xend, yend); - } else { - brush = CreateSolidBrush(gc->foreground); - oldBrush = SelectObject(dc, brush); - if (gc->arc_mode == ArcChord) { - Chord(dc, x, y, (int) (x+width+1), (int) (y+height+1), - xstart, ystart, xend, yend); - } else if (gc->arc_mode == ArcPieSlice) { - Pie(dc, x, y, (int) (x+width+1), (int) (y+height+1), - xstart, ystart, xend, yend); - } - DeleteObject(SelectObject(dc, oldBrush)); - } - DeleteObject(SelectObject(dc, oldPen)); - TkWinReleaseDrawableDC(d, dc, &state); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * SetUpGraphicsPort -- - * - * Set up the graphics port from the given GC. - * - * Results: - * None. - * - * Side effects: - * The current port is adjusted. - * - *---------------------------------------------------------------------- - */ - -static HPEN -SetUpGraphicsPort( - GC gc) -{ - DWORD style; - - if (gc->line_style == LineOnOffDash) { - unsigned char *p = (unsigned char *) &(gc->dashes); - /* pointer to the dash-list */ - - /* - * Below is a simple translation of serveral dash patterns to valid - * windows pen types. Far from complete, but I don't know how to do it - * better. Any ideas: <mailto:j.nijtmans@chello.nl> - */ - - if (p[1] && p[2]) { - if (!p[3] || p[4]) { - style = PS_DASHDOTDOT; /* -.. */ - } else { - style = PS_DASHDOT; /* -. */ - } - } else { - if (p[0] > (4 * gc->line_width)) { - style = PS_DASH; /* - */ - } else { - style = PS_DOT; /* . */ - } - } - } else { - style = PS_SOLID; - } - if (gc->line_width < 2) { - return CreatePen((int) style, gc->line_width, gc->foreground); - } else { - LOGBRUSH lb; - - lb.lbStyle = BS_SOLID; - lb.lbColor = gc->foreground; - lb.lbHatch = 0; - - style |= PS_GEOMETRIC; - switch (gc->cap_style) { - case CapNotLast: - case CapButt: - style |= PS_ENDCAP_FLAT; - break; - case CapRound: - style |= PS_ENDCAP_ROUND; - break; - default: - style |= PS_ENDCAP_SQUARE; - break; - } - switch (gc->join_style) { - case JoinMiter: - style |= PS_JOIN_MITER; - break; - case JoinRound: - style |= PS_JOIN_ROUND; - break; - default: - style |= PS_JOIN_BEVEL; - break; - } - return ExtCreatePen(style, (DWORD) gc->line_width, &lb, 0, NULL); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkScrollWindow -- - * - * Scroll a rectangle of the specified window and accumulate a damage - * region. - * - * Results: - * Returns 0 if the scroll genereated no additional damage. Otherwise, - * sets the region that needs to be repainted after scrolling and returns - * 1. - * - * Side effects: - * Scrolls the bits in the window. - * - *---------------------------------------------------------------------- - */ - -int -TkScrollWindow( - Tk_Window tkwin, /* The window to be scrolled. */ - GC gc, /* GC for window to be scrolled. */ - int x, int y, int width, int height, - /* Position rectangle to be scrolled. */ - int dx, int dy, /* Distance rectangle should be moved. */ - TkRegion damageRgn) /* Region to accumulate damage in. */ -{ - HWND hwnd = TkWinGetHWND(Tk_WindowId(tkwin)); - RECT scrollRect; - - scrollRect.left = x; - scrollRect.top = y; - scrollRect.right = x + width; - scrollRect.bottom = y + height; - return (ScrollWindowEx(hwnd, dx, dy, &scrollRect, NULL, (HRGN) damageRgn, - NULL, 0) == NULLREGION) ? 0 : 1; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinFillRect -- - * - * This routine fills a rectangle with the foreground color from the - * specified GC ignoring all other GC values. This is the fastest way to - * fill a drawable with a solid color. - * - * Results: - * None. - * - * Side effects: - * Modifies the contents of the DC drawing surface. - * - *---------------------------------------------------------------------- - */ - -void -TkWinFillRect( - HDC dc, - int x, int y, int width, int height, - int pixel) -{ - RECT rect; - COLORREF oldColor; - - rect.left = x; - rect.top = y; - rect.right = x + width; - rect.bottom = y + height; - oldColor = SetBkColor(dc, (COLORREF)pixel); - SetBkMode(dc, OPAQUE); - ExtTextOut(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); - SetBkColor(dc, oldColor); -} - -/* - *---------------------------------------------------------------------- - * - * TkpDrawHighlightBorder -- - * - * This function draws a rectangular ring around the outside of a widget - * to indicate that it has received the input focus. - * - * On Windows, we just draw the simple inset ring. On other sytems, e.g. - * the Mac, the focus ring is a little more complicated, so we need this - * abstraction. - * - * Results: - * None. - * - * Side effects: - * A rectangle "width" pixels wide is drawn in "drawable", corresponding - * to the outer area of "tkwin". - * - *---------------------------------------------------------------------- - */ - -void -TkpDrawHighlightBorder( - Tk_Window tkwin, - GC fgGC, - GC bgGC, - int highlightWidth, - Drawable drawable) -{ - TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0); -} - -/* - *---------------------------------------------------------------------- - * - * TkpDrawFrame -- - * - * This function draws the rectangular frame area. - * - * Results: - * None. - * - * Side effects: - * Draws inside the tkwin area. - * - *---------------------------------------------------------------------- - */ - -void -TkpDrawFrame( - Tk_Window tkwin, - Tk_3DBorder border, - int highlightWidth, - int borderWidth, - int relief) -{ - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, highlightWidth, - highlightWidth, Tk_Width(tkwin) - 2 * highlightWidth, - Tk_Height(tkwin) - 2 * highlightWidth, borderWidth, relief); -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinEmbed.c b/tk8.6/win/tkWinEmbed.c deleted file mode 100644 index 8bfd295..0000000 --- a/tk8.6/win/tkWinEmbed.c +++ /dev/null @@ -1,1118 +0,0 @@ -/* - * tkWinEmbed.c -- - * - * This file contains platform specific procedures for Windows platforms - * to provide basic operations needed for application embedding (where - * one application can use as its main window an internal window from - * another application). - * - * Copyright (c) 1996-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - -/* - * One of the following structures exists for each container in this - * application. It keeps track of the container window and its associated - * embedded window. - */ - -typedef struct Container { - HWND parentHWnd; /* Windows HWND to the parent window */ - TkWindow *parentPtr; /* Tk's information about the container or - * NULL if the container isn't in this - * process. */ - HWND embeddedHWnd; /* Windows HWND to the embedded window. */ - TkWindow *embeddedPtr; /* Tk's information about the embedded window, - * or NULL if the embedded application isn't - * in this process. */ - HWND embeddedMenuHWnd; /* Tk's embedded menu window handler. */ - struct Container *nextPtr; /* Next in list of all containers in this - * process. */ -} Container; - -typedef struct ThreadSpecificData { - Container *firstContainerPtr; - /* First in list of all containers managed by - * this process. */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -static void ContainerEventProc(ClientData clientData, - XEvent *eventPtr); -static void EmbedGeometryRequest(Container *containerPtr, - int width, int height); -static void EmbedWindowDeleted(TkWindow *winPtr); -static void Tk_MapEmbeddedWindow(TkWindow* winPtr); -HWND Tk_GetEmbeddedHWnd(TkWindow* winPtr); - -/* - *---------------------------------------------------------------------- - * - * TkWinCleanupContainerList -- - * - * Finalizes the list of containers. - * - * Results: - * None. - * - * Side effects: - * Releases memory occupied by containers of embedded windows. - * - *---------------------------------------------------------------------- - */ - -void -TkWinCleanupContainerList(void) -{ - Container *nextPtr; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - for (; tsdPtr->firstContainerPtr != NULL; - tsdPtr->firstContainerPtr = nextPtr) { - nextPtr = tsdPtr->firstContainerPtr->nextPtr; - ckfree(tsdPtr->firstContainerPtr); - } - tsdPtr->firstContainerPtr = NULL; -} - -/* - *---------------------------------------------------------------------- - * - * TkpTestembedCmd -- - * - * Test command for the embedding facility. - * - * Results: - * Always returns TCL_OK. - * - * Side effects: - * Currently it does not do anything. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -int -TkpTestembedCmd( - ClientData clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_DetachEmbeddedWindow -- - * - * This function detaches an embedded window - * - * Results: - * No return value. Detach the embedded window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static -void -Tk_DetachEmbeddedWindow( - TkWindow *winPtr, /* an embedded window */ - BOOL detachFlag) /* a flag of truely detaching */ -{ - TkpWinToplevelDetachWindow(winPtr); - if(detachFlag) { - TkpWinToplevelOverrideRedirect(winPtr, 0); - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_MapEmbeddedWindow -- - * - * This function is required for mapping an embedded window during idle. - * The input winPtr must be preserved using Tcl_Preserve before call this - * function and will be released by this function. - * - * Results: - * No return value. Map the embedded window if it is not dead. - * - * Side effects: - * The embedded window may change its state as the container's. - * - *---------------------------------------------------------------------- - */ - -static -void Tk_MapEmbeddedWindow( - TkWindow *winPtr) /* Top-level window that's about to be - * mapped. */ -{ - if(!(winPtr->flags & TK_ALREADY_DEAD)) { - HWND hwnd = (HWND)winPtr->privatePtr; - int state = SendMessage(hwnd, TK_STATE, -1, -1) - 1; - - if (state < 0 || state > 3) { - state = NormalState; - } - - while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) { - /* empty body */ - } - - TkpWmSetState(winPtr, state); - TkWmMapWindow(winPtr); - } - Tcl_Release((ClientData)winPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TkpUseWindow -- - * - * This procedure causes a Tk window to use a given Windows handle for a - * window as its underlying window, rather than a new Windows window - * being created automatically. It is invoked by an embedded application - * to specify the window in which the application is embedded. - * - * This procedure uses a simple attachment protocol by sending TK_INFO - * messages to the window to use with two sub messages: - * - * TK_CONTAINER_VERIFY - if a window handles this message, it should - * return either a (long)hwnd for a container or a -(long)hwnd - * for a non-container. - * - * TK_CONTAINER_ISAVAILABLE - a container window should return either - * a TRUE (non-zero) if it is available for use or a FALSE (zero) - * othersize. - * - * The TK_INFO messages are required in order to verify if the window to - * use is a valid container. Without an id verification, an invalid - * window attachment may cause unexpected crashes/panics (bug 1096074). - * Additional sub messages may be definded/used in future for other - * needs. - * - * We do not enforce the above protocol for the reason of backward - * compatibility. If the window to use is unable to handle TK_INFO - * messages (e.g., legacy Tk container applications before 8.5), a dialog - * box with a warning message pops up and the user is asked to confirm if - * the attachment should proceed. However, we may have to enforce it in - * future. - * - * Results: - * The return value is normally TCL_OK. If an error occurred (such as if - * the argument does not identify a legal Windows window handle or it is - * already in use or a cancel button is pressed by a user in confirming - * the use window as a Tk container) the return value is TCL_ERROR and an - * error message is left in the the interp's result if interp is not - * NULL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkpUseWindow( - Tcl_Interp *interp, /* If not NULL, used for error reporting if - * string is bogus. */ - Tk_Window tkwin, /* Tk window that does not yet have an - * associated X window. */ - const char *string) /* String identifying an X window to use for - * tkwin; must be an integer value. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - int id; - HWND hwnd; -/* - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); -*/ - -/* - if (winPtr->window != None) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "can't modify container after widget is created", -1)); - Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL); - return TCL_ERROR; - } -*/ - - if (strcmp(string, "") == 0) { - if (winPtr->flags & TK_EMBEDDED) { - Tk_DetachEmbeddedWindow(winPtr, TRUE); - } - return TCL_OK; - } - - if ( -#ifdef _WIN64 - (sscanf(string, "0x%p", &hwnd) != 1) && -#endif - Tcl_GetInt(interp, string, (int *) &hwnd) != TCL_OK) { - return TCL_ERROR; - } - if ((HWND)winPtr->privatePtr == hwnd) { - return TCL_OK; - } - - /* - * Check if the window is a valid handle. If it is invalid, return - * TCL_ERROR and potentially leave an error message in the interp's - * result. - */ - - if (!IsWindow(hwnd)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" doesn't exist", string)); - Tcl_SetErrorCode(interp, "TK", "EMBED", "EXIST", NULL); - } - return TCL_ERROR; - } - - id = SendMessage(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0); - if (id == PTR2INT(hwnd)) { - if (!SendMessage(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "The container is already in use", -1)); - Tcl_SetErrorCode(interp, "TK", "EMBED", "IN_USE", NULL); - return TCL_ERROR; - } - } else if (id == -PTR2INT(hwnd)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "the window to use is not a Tk container", -1)); - Tcl_SetErrorCode(interp, "TK", "EMBED", "CONTAINER", NULL); - return TCL_ERROR; - } else { - /* - * Proceed if the user decide to do so because it can be a legacy - * container application. However we may have to return a TCL_ERROR in - * order to avoid bug 1096074 in future. - */ - - char msg[256]; - - sprintf(msg, "Unable to get information of window \"%.80s\". Attach to this\nwindow may have unpredictable results if it is not a valid container.\n\nPress Ok to proceed or Cancel to abort attaching.", string); - if (IDCANCEL == MessageBoxA(hwnd, msg, "Tk Warning", - MB_OKCANCEL | MB_ICONWARNING)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "Operation has been canceled", -1)); - Tcl_SetErrorCode(interp, "TK", "EMBED", "CANCEL", NULL); - return TCL_ERROR; - } - } - - Tk_DetachEmbeddedWindow(winPtr, FALSE); - - /* - * Store the parent window in the platform private data slot so - * TkWmMapWindow can use it when creating the wrapper window. - */ - - winPtr->privatePtr = (struct TkWindowPrivate*) hwnd; - winPtr->flags |= TK_EMBEDDED; - winPtr->flags &= ~(TK_MAPPED); - - /* - * Preserve the winPtr and create an idle handler to map the embedded - * window. - */ - - Tcl_Preserve((ClientData) winPtr); - Tcl_DoWhenIdle((Tcl_IdleProc*) Tk_MapEmbeddedWindow, (ClientData) winPtr); - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkpMakeContainer -- - * - * This procedure is called to indicate that a particular window will be - * a container for an embedded application. This changes certain aspects - * of the window's behavior, such as whether it will receive events - * anymore. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkpMakeContainer( - Tk_Window tkwin) -{ - TkWindow *winPtr = (TkWindow *) tkwin; - Container *containerPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - /* - * Register the window as a container so that, for example, we can find - * out later if the embedded app. is in the same process. - */ - - Tk_MakeWindowExist(tkwin); - containerPtr = ckalloc(sizeof(Container)); - containerPtr->parentPtr = winPtr; - containerPtr->parentHWnd = Tk_GetHWND(Tk_WindowId(tkwin)); - containerPtr->embeddedHWnd = NULL; - containerPtr->embeddedPtr = NULL; - containerPtr->embeddedMenuHWnd = NULL; - containerPtr->nextPtr = tsdPtr->firstContainerPtr; - tsdPtr->firstContainerPtr = containerPtr; - winPtr->flags |= TK_CONTAINER; - - /* - * Unlike in tkUnixEmbed.c, we don't make any requests for events in the - * embedded window here. Now we just allow the embedding of another TK - * application into TK windows. When the embedded window makes a request, - * that will be done by sending to the container window a WM_USER message, - * which will be intercepted by TkWinContainerProc. - * - * We need to get structure events of the container itself, though. - */ - - Tk_CreateEventHandler(tkwin, StructureNotifyMask, - ContainerEventProc, (ClientData) containerPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TkWinEmbeddedEventProc -- - * - * This procedure is invoked by the Tk event dispatcher when various - * useful events are received for the *children* of a container window. - * It forwards relevant information, such as geometry requests, from the - * events into the container's application. - * - * Results: - * None. - * - * Side effects: - * Depends on the event. For example, when ConfigureRequest events occur, - * geometry information gets set for the container window. - * - *---------------------------------------------------------------------- - */ - -LRESULT -TkWinEmbeddedEventProc( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - int result = 1; - Container *containerPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - /* - * Find the Container structure associated with the parent window. - */ - - for (containerPtr = tsdPtr->firstContainerPtr; - containerPtr && containerPtr->parentHWnd != hwnd; - containerPtr = containerPtr->nextPtr) { - /* empty loop body */ - } - - if (containerPtr) { - TkWindow *topwinPtr = NULL; - if(Tk_IsTopLevel(containerPtr->parentPtr)) { - topwinPtr = containerPtr->parentPtr; - } - switch (message) { - case TK_INFO: - /* - * An embedded window may send this message for container - * verification and availability before attach. - * - * wParam - a sub message - * - * TK_CONTAINER_ISAVAILABLE - if the container is available - * for use? - * result = 1 for yes and 0 for no; - * - * TK_CONTAINER_VERIFY - request the container to verify its - * identification - * result = (long)hwnd if this window is a container - * -(long)hwnd otherwise - * - * lParam - N/A - */ - - switch(wParam) { - case TK_CONTAINER_ISAVAILABLE: - result = containerPtr->embeddedHWnd == NULL? 1:0; - break; - case TK_CONTAINER_VERIFY: - result = PTR2INT(containerPtr->parentHWnd); - break; - default: - result = 0; - } - break; - - case TK_ATTACHWINDOW: - /* - * An embedded window (either from this application or from - * another application) is trying to attach to this container. We - * attach it only if this container is not yet containing any - * window. - * - * wParam - a handle of an embedded window - * lParam - N/A - * - * An embedded window may send this message with a wParam of NULL - * to test if a window is able to provide embedding service. The - * container returns its window handle for accepting the - * attachment and identifying itself or a zero for being already - * in use. - * - * Return value: - * 0 - the container is unable to be used. - * hwnd - the container is ready to be used. - */ - if (containerPtr->embeddedHWnd == NULL) { - if (wParam) { - TkWindow *winPtr = (TkWindow *) - Tk_HWNDToWindow((HWND) wParam); - if (winPtr) { - winPtr->flags |= TK_BOTH_HALVES; - containerPtr->embeddedPtr = winPtr; - containerPtr->parentPtr->flags |= TK_BOTH_HALVES; - } - containerPtr->embeddedHWnd = (HWND)wParam; - } - result = PTR2INT(containerPtr->parentHWnd); - } else { - result = 0; - } - break; - - case TK_DETACHWINDOW: - /* - * An embedded window notifies the container that it is detached. - * The container should clearn the related variables and redraw - * its window. - * - * wParam - N/A - * lParam - N/A - * - * Return value: - * 0 - the message is not processed. - * others - the message is processed. - */ - - containerPtr->embeddedMenuHWnd = NULL; - containerPtr->embeddedHWnd = NULL; - containerPtr->parentPtr->flags &= ~TK_BOTH_HALVES; - if (topwinPtr) { - TkWinSetMenu((Tk_Window) topwinPtr, 0); - } - InvalidateRect(hwnd, NULL, TRUE); - break; - - case TK_GEOMETRYREQ: - /* - * An embedded window requests a window size change. - * - * wParam - window width - * lParam - window height - * - * Return value: - * 0 - the message is not processed. - * others - the message is processed. - */ - - EmbedGeometryRequest(containerPtr, (int)wParam, lParam); - break; - - case TK_RAISEWINDOW: - /* - * An embedded window requests to change its Z-order. - * - * wParam - a window handle as a z-order stack reference - * lParam - a flag of above-below: 0 - above; 1 or others: - below - * - * Return value: - * 0 - the message is not processed. - * others - the message is processed. - */ - - TkWinSetWindowPos(GetParent(containerPtr->parentHWnd), - (HWND)wParam, (int)lParam); - break; - - case TK_GETFRAMEWID: - /* - * An embedded window requests to get the frame window's id. - * - * wParam - N/A - * lParam - N/A - * - * Return vlaue: - * - * A handle of the frame window. If it is not availble, a zero is - * returned. - */ - if (topwinPtr) { - result = PTR2INT(GetParent(containerPtr->parentHWnd)); - } else { - topwinPtr = containerPtr->parentPtr; - while (!(topwinPtr->flags & TK_TOP_HIERARCHY)) { - topwinPtr = topwinPtr->parentPtr; - } - if (topwinPtr && topwinPtr->window) { - result = PTR2INT(GetParent(Tk_GetHWND(topwinPtr->window))); - } else { - result = 0; - } - } - break; - - case TK_CLAIMFOCUS: - /* - * An embedded window requests a focus. - * - * wParam - a flag of forcing focus - * lParam - N/A - * - * Return value: - * 0 - the message is not processed - * 1 - the message is processed - */ - - if (!SetFocus(containerPtr->embeddedHWnd) && wParam) { - /* - * forcing focus TBD - */ - } - break; - - case TK_WITHDRAW: - /* - * An embedded window requests withdraw. - * - * wParam - N/A - * lParam - N/A - * - * Return value - * 0 - the message is not processed - * 1 - the message is processed - */ - - if (topwinPtr) { - TkpWinToplevelWithDraw(topwinPtr); - } else { - result = 0; - } - break; - - case TK_ICONIFY: - /* - * An embedded window requests iconification. - * - * wParam - N/A - * lParam - N/A - * - * Return value - * 0 - the message is not processed - * 1 - the message is processed - */ - - if (topwinPtr) { - TkpWinToplevelIconify(topwinPtr); - } else { - result = 0; - } - break; - - case TK_DEICONIFY: - /* - * An embedded window requests deiconification. - * - * wParam - N/A - * lParam - N/A - * - * Return value - * 0 - the message is not processed - * 1 - the message is processed - */ - if (topwinPtr) { - TkpWinToplevelDeiconify(topwinPtr); - } else { - result = 0; - } - break; - - case TK_MOVEWINDOW: - /* - * An embedded window requests to move position if both wParam and - * lParam are greater or equal to 0. - * wParam - x value of the frame's upper left - * lParam - y value of the frame's upper left - * - * Otherwise an embedded window requests the current position - * - * Return value: an encoded window position in a 32bit long, i.e, - * ((x << 16) & 0xffff0000) | (y & 0xffff) - * - * Only a toplevel container may move the embedded. - */ - - result = TkpWinToplevelMove(containerPtr->parentPtr, - wParam, lParam); - break; - - case TK_OVERRIDEREDIRECT: - /* - * An embedded window request overrideredirect. - * - * wParam - * 0 - add a frame if there is no one - * 1 - remove the frame if there is a one - * < 0 - query the current overrideredirect value - * - * lParam - N/A - * - * Return value: - * 1 + the current value of overrideredirect if the container is a - * toplevel. Otherwise 0. - */ - if (topwinPtr) { - result = 1 + TkpWinToplevelOverrideRedirect(topwinPtr, wParam); - } else { - result = 0; - } - break; - - case TK_SETMENU: - /* - * An embedded requests to set a menu. - * - * wParam - a menu handle - * lParam - a menu window handle - * - * Return value: - * 1 - the message is processed - * 0 - the message is not processed - */ - if (topwinPtr) { - containerPtr->embeddedMenuHWnd = (HWND)lParam; - TkWinSetMenu((Tk_Window)topwinPtr, (HMENU)wParam); - } else { - result = 0; - } - break; - - case TK_STATE: - /* - * An embedded window request set/get state services. - * - * wParam - service directive - * 0 - 3 for setting state - * 0 - withdrawn state - * 1 - normal state - * 2 - zoom state - * 3 - icon state - * others for gettting state - * - * lParam - N/A - * - * Return value - * 1 + the current state or 0 if the container is not a toplevel - */ - - if (topwinPtr) { - if (wParam <= 3) { - TkpWmSetState(topwinPtr, wParam); - } - result = 1+TkpWmGetState(topwinPtr); - } else { - result = 0; - } - break; - - /* - * Return 0 since the current Tk container implementation is - * unable to provide following services. - */ - default: - result = 0; - break; - } - } else { - if ((message == TK_INFO) && (wParam == TK_CONTAINER_VERIFY)) { - /* - * Reply the message sender: this is not a Tk container - */ - - return -PTR2INT(hwnd); - } else { - result = 0; - } - } - - return result; -} - -/* - *---------------------------------------------------------------------- - * - * EmbedGeometryRequest -- - * - * This procedure is invoked when an embedded application requests a - * particular size. It processes the request (which may or may not - * actually resize the window) and reflects the results back to the - * embedded application. - * - * Results: - * None. - * - * Side effects: - * If we deny the child's size change request, a Configure event is - * synthesized to let the child know that the size is the same as it used - * to be. Events get processed while we're waiting for the geometry - * managers to do their thing. - * - *---------------------------------------------------------------------- - */ - -void -EmbedGeometryRequest( - Container *containerPtr, /* Information about the container window. */ - int width, int height) /* Size that the child has requested. */ -{ - TkWindow *winPtr = containerPtr->parentPtr; - - /* - * Forward the requested size into our geometry management hierarchy via - * the container window. We need to send a Configure event back to the - * embedded application even if we decide not to resize the window; to - * make this happen, process all idle event handlers synchronously here - * (so that the geometry managers have had a chance to do whatever they - * want to do), and if the window's size didn't change then generate a - * configure event. - */ - - Tk_GeometryRequest((Tk_Window)winPtr, width, height); - - if (containerPtr->embeddedHWnd != NULL) { - while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) { - /* Empty loop body. */ - } - - SetWindowPos(containerPtr->embeddedHWnd, NULL, 0, 0, - winPtr->changes.width, winPtr->changes.height, SWP_NOZORDER); - } -} - -/* - *---------------------------------------------------------------------- - * - * ContainerEventProc -- - * - * This procedure is invoked by the Tk event dispatcher when various - * useful events are received for the container window. - * - * Results: - * None. - * - * Side effects: - * Depends on the event. For example, when ConfigureRequest events occur, - * geometry information gets set for the container window. - * - *---------------------------------------------------------------------- - */ - -static void -ContainerEventProc( - ClientData clientData, /* Token for container window. */ - XEvent *eventPtr) /* ResizeRequest event. */ -{ - Container *containerPtr = (Container *)clientData; - Tk_Window tkwin = (Tk_Window)containerPtr->parentPtr; - - if (eventPtr->type == ConfigureNotify) { - /* - * Resize the embedded window, if there is any. - */ - - if (containerPtr->embeddedHWnd) { - SetWindowPos(containerPtr->embeddedHWnd, NULL, 0, 0, - Tk_Width(tkwin), Tk_Height(tkwin), SWP_NOZORDER); - } - } else if (eventPtr->type == DestroyNotify) { - /* - * The container is gone, remove it from the list. - */ - - EmbedWindowDeleted(containerPtr->parentPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetOtherWindow -- - * - * If both the container and embedded window are in the same process, - * this procedure will return either one, given the other. - * - * Results: - * If winPtr is a container, the return value is the token for the - * embedded window, and vice versa. If the "other" window isn't in this - * process, NULL is returned. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TkWindow * -TkpGetOtherWindow( - TkWindow *winPtr) /* Tk's structure for a container or embedded - * window. */ -{ - Container *containerPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL; - containerPtr = containerPtr->nextPtr) { - if (containerPtr->embeddedPtr == winPtr) { - return containerPtr->parentPtr; - } else if (containerPtr->parentPtr == winPtr) { - return containerPtr->embeddedPtr; - } - } - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetEmbeddedHWnd -- - * - * This function returns the embedded window id. - * - * Results: - * If winPtr is a container, the return value is the HWND for the - * embedded window. Otherwise it returns NULL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -HWND -Tk_GetEmbeddedHWnd( - TkWindow *winPtr) -{ - Container *containerPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL; - containerPtr = containerPtr->nextPtr) { - if (containerPtr->parentPtr == winPtr) { - return containerPtr->embeddedHWnd; - } - } - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetEmbeddedMenuHWND -- - * - * This function returns the embedded menu window id. - * - * Results: - * If winPtr is a container, the return value is the HWND for the - * embedded menu window. Otherwise it returns NULL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -HWND -Tk_GetEmbeddedMenuHWND( - Tk_Window tkwin) -{ - TkWindow *winPtr = (TkWindow*)tkwin; - Container *containerPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL; - containerPtr = containerPtr->nextPtr) { - if (containerPtr->parentPtr == winPtr) { - return containerPtr->embeddedMenuHWnd; - } - } - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * TkpClaimFocus -- - * - * This procedure is invoked when someone asks or the input focus to be - * put on a window in an embedded application, but the application - * doesn't currently have the focus. It requests the input focus from the - * container application. - * - * Results: - * None. - * - * Side effects: - * The input focus may change. - * - *---------------------------------------------------------------------- - */ - -void -TkpClaimFocus( - TkWindow *topLevelPtr, /* Top-level window containing desired focus - * window; should be embedded. */ - int force) /* One means that the container should claim - * the focus if it doesn't currently have - * it. */ -{ - HWND hwnd = GetParent(Tk_GetHWND(topLevelPtr->window)); - SendMessage(hwnd, TK_CLAIMFOCUS, (WPARAM) force, 0); -} - -/* - *---------------------------------------------------------------------- - * - * TkpRedirectKeyEvent -- - * - * This procedure is invoked when a key press or release event arrives - * for an application that does not believe it owns the input focus. - * This can happen because of embedding; for example, X can send an event - * to an embedded application when the real focus window is in the - * container application and is an ancestor of the container. This - * procedure's job is to forward the event back to the application where - * it really belongs. - * - * Results: - * None. - * - * Side effects: - * The event may get sent to a different application. - * - *---------------------------------------------------------------------- - */ - -void -TkpRedirectKeyEvent( - TkWindow *winPtr, /* Window to which the event was originally - * reported. */ - XEvent *eventPtr) /* X event to redirect (should be KeyPress or - * KeyRelease). */ -{ - /* not implemented */ -} - -/* - *---------------------------------------------------------------------- - * - * EmbedWindowDeleted -- - * - * This procedure is invoked when a window involved in embedding (as - * either the container or the embedded application) is destroyed. It - * cleans up the Container structure for the window. - * - * Results: - * None. - * - * Side effects: - * A Container structure may be freed. - * - *---------------------------------------------------------------------- - */ - -static void -EmbedWindowDeleted( - TkWindow *winPtr) /* Tk's information about window that was - * deleted. */ -{ - Container *containerPtr, *prevPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - /* - * Find the Container structure for this window work. Delete the - * information about the embedded application and free the container's - * record. The main container may be null. [Bug #476176] - */ - - prevPtr = NULL; - containerPtr = tsdPtr->firstContainerPtr; - if (containerPtr == NULL) return; - while (1) { - if (containerPtr->embeddedPtr == winPtr) { - containerPtr->embeddedHWnd = NULL; - containerPtr->embeddedPtr = NULL; - break; - } - if (containerPtr->parentPtr == winPtr) { - SendMessage(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0); - containerPtr->parentPtr = NULL; - containerPtr->embeddedPtr = NULL; - break; - } - prevPtr = containerPtr; - containerPtr = containerPtr->nextPtr; - if (containerPtr == NULL) { - return; - } - } - if ((containerPtr->embeddedPtr == NULL) - && (containerPtr->parentPtr == NULL)) { - if (prevPtr == NULL) { - tsdPtr->firstContainerPtr = containerPtr->nextPtr; - } else { - prevPtr->nextPtr = containerPtr->nextPtr; - } - ckfree(containerPtr); - } -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinFont.c b/tk8.6/win/tkWinFont.c deleted file mode 100644 index d67ea66..0000000 --- a/tk8.6/win/tkWinFont.c +++ /dev/null @@ -1,2908 +0,0 @@ -/* - * tkWinFont.c -- - * - * Contains the Windows implementation of the platform-independant font - * package interface. - * - * Copyright (c) 1994 Software Research Associates, Inc. - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-1999 by Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" -#include "tkFont.h" - -/* - * The following structure represents a font family. It is assumed that all - * screen fonts constructed from the same "font family" share certain - * properties; all screen fonts with the same "font family" point to a shared - * instance of this structure. The most important shared property is the - * character existence metrics, used to determine if a screen font can display - * a given Unicode character. - * - * Under Windows, a "font family" is uniquely identified by its face name. - */ - -#define FONTMAP_SHIFT 10 - -#define FONTMAP_PAGES (1 << (sizeof(Tcl_UniChar)*8 - FONTMAP_SHIFT)) -#define FONTMAP_BITSPERPAGE (1 << FONTMAP_SHIFT) - -typedef struct FontFamily { - struct FontFamily *nextPtr; /* Next in list of all known font families. */ - size_t refCount; /* How many SubFonts are referring to this - * FontFamily. When the refCount drops to - * zero, this FontFamily may be freed. */ - /* - * Key. - */ - - Tk_Uid faceName; /* Face name key for this FontFamily. */ - - /* - * Derived properties. - */ - - Tcl_Encoding encoding; /* Encoding for this font family. */ - int isSymbolFont; /* Non-zero if this is a symbol font. */ - int isWideFont; /* 1 if this is a double-byte font, 0 - * otherwise. */ - BOOL (WINAPI *textOutProc)(HDC hdc, int x, int y, TCHAR *str, int len); - /* The procedure to use to draw text after it - * has been converted from UTF-8 to the - * encoding of this font. */ - BOOL (WINAPI *getTextExtentPoint32Proc)(HDC, TCHAR *, int, LPSIZE); - /* The procedure to use to measure text after - * it has been converted from UTF-8 to the - * encoding of this font. */ - - char *fontMap[FONTMAP_PAGES]; - /* Two-level sparse table used to determine - * quickly if the specified character exists. - * As characters are encountered, more pages - * in this table are dynamically added. The - * contents of each page is a bitmask - * consisting of FONTMAP_BITSPERPAGE bits, - * representing whether this font can be used - * to display the given character at the - * corresponding bit position. The high bits - * of the character are used to pick which - * page of the table is used. */ - - /* - * Cached Truetype font info. - */ - - int segCount; /* The length of the following arrays. */ - USHORT *startCount; /* Truetype information about the font, */ - USHORT *endCount; /* indicating which characters this font can - * display (malloced). The format of this - * information is (relatively) compact, but - * would take longer to search than indexing - * into the fontMap[][] table. */ -} FontFamily; - -/* - * The following structure encapsulates an individual screen font. A font - * object is made up of however many SubFonts are necessary to display a - * stream of multilingual characters. - */ - -typedef struct SubFont { - char **fontMap; /* Pointer to font map from the FontFamily, - * cached here to save a dereference. */ - HFONT hFont0; /* The specific screen font that will be used - * when displaying/measuring chars belonging - * to the FontFamily. */ - FontFamily *familyPtr; /* The FontFamily for this SubFont. */ - HFONT hFontAngled; - double angle; -} SubFont; - -/* - * The following structure represents Windows' implementation of a font - * object. - */ - -#define SUBFONT_SPACE 3 -#define BASE_CHARS 128 - -typedef struct WinFont { - TkFont font; /* Stuff used by generic font package. Must be - * first in structure. */ - SubFont staticSubFonts[SUBFONT_SPACE]; - /* Builtin space for a limited number of - * SubFonts. */ - int numSubFonts; /* Length of following array. */ - SubFont *subFontArray; /* Array of SubFonts that have been loaded in - * order to draw/measure all the characters - * encountered by this font so far. All fonts - * start off with one SubFont initialized by - * AllocFont() from the original set of font - * attributes. Usually points to - * staticSubFonts, but may point to malloced - * space if there are lots of SubFonts. */ - HWND hwnd; /* Toplevel window of application that owns - * this font, used for getting HDC for - * offscreen measurements. */ - int pixelSize; /* Original pixel size used when font was - * constructed. */ - int widths[BASE_CHARS]; /* Widths of first 128 chars in the base font, - * for handling common case. The base font is - * always used to draw characters between - * 0x0000 and 0x007f. */ -} WinFont; - -/* - * The following structure is passed as the LPARAM when calling the font - * enumeration procedure to determine if a font can support the given - * character. - */ - -typedef struct CanUse { - HDC hdc; - WinFont *fontPtr; - Tcl_DString *nameTriedPtr; - int ch; - SubFont *subFontPtr; - SubFont **subFontPtrPtr; -} CanUse; - -/* - * The following structure is used to map between the Tcl strings that - * represent the system fonts and the numbers used by Windows. - */ - -static const TkStateMap systemMap[] = { - {ANSI_FIXED_FONT, "ansifixed"}, - {ANSI_FIXED_FONT, "fixed"}, - {ANSI_VAR_FONT, "ansi"}, - {DEVICE_DEFAULT_FONT, "device"}, - {DEFAULT_GUI_FONT, "defaultgui"}, - {OEM_FIXED_FONT, "oemfixed"}, - {SYSTEM_FIXED_FONT, "systemfixed"}, - {SYSTEM_FONT, "system"}, - {-1, NULL} -}; - -typedef struct ThreadSpecificData { - FontFamily *fontFamilyList; /* The list of font families that are - * currently loaded. As screen fonts are - * loaded, this list grows to hold information - * about what characters exist in each font - * family. */ - Tcl_HashTable uidTable; -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -/* - * Information cached about the system at startup time. - */ - -static Tcl_Encoding systemEncoding; - -/* - * Procedures used only in this file. - */ - -static FontFamily * AllocFontFamily(HDC hdc, HFONT hFont, int base); -static SubFont * CanUseFallback(HDC hdc, WinFont *fontPtr, - const char *fallbackName, int ch, - SubFont **subFontPtrPtr); -static SubFont * CanUseFallbackWithAliases(HDC hdc, WinFont *fontPtr, - const char *faceName, int ch, - Tcl_DString *nameTriedPtr, - SubFont **subFontPtrPtr); -static int FamilyExists(HDC hdc, const char *faceName); -static const char * FamilyOrAliasExists(HDC hdc, const char *faceName); -static SubFont * FindSubFontForChar(WinFont *fontPtr, int ch, - SubFont **subFontPtrPtr); -static void FontMapInsert(SubFont *subFontPtr, int ch); -static void FontMapLoadPage(SubFont *subFontPtr, int row); -static int FontMapLookup(SubFont *subFontPtr, int ch); -static void FreeFontFamily(FontFamily *familyPtr); -static HFONT GetScreenFont(const TkFontAttributes *faPtr, - const char *faceName, int pixelSize, - double angle); -static void InitFont(Tk_Window tkwin, HFONT hFont, - int overstrike, WinFont *tkFontPtr); -static inline void InitSubFont(HDC hdc, HFONT hFont, int base, - SubFont *subFontPtr); -static int CreateNamedSystemLogFont(Tcl_Interp *interp, - Tk_Window tkwin, const char* name, - LOGFONT* logFontPtr); -static int CreateNamedSystemFont(Tcl_Interp *interp, - Tk_Window tkwin, const char* name, HFONT hFont); -static int LoadFontRanges(HDC hdc, HFONT hFont, - USHORT **startCount, USHORT **endCount, - int *symbolPtr); -static void MultiFontTextOut(HDC hdc, WinFont *fontPtr, - const char *source, int numBytes, int x, int y, - double angle); -static void ReleaseFont(WinFont *fontPtr); -static inline void ReleaseSubFont(SubFont *subFontPtr); -static int SeenName(const char *name, Tcl_DString *dsPtr); -static inline HFONT SelectFont(HDC hdc, WinFont *fontPtr, - SubFont *subFontPtr, double angle); -static inline void SwapLong(PULONG p); -static inline void SwapShort(USHORT *p); -static int CALLBACK WinFontCanUseProc(ENUMLOGFONT *lfPtr, - NEWTEXTMETRIC *tmPtr, int fontType, - LPARAM lParam); -static int CALLBACK WinFontExistProc(ENUMLOGFONT *lfPtr, - NEWTEXTMETRIC *tmPtr, int fontType, - LPARAM lParam); -static int CALLBACK WinFontFamilyEnumProc(ENUMLOGFONT *lfPtr, - NEWTEXTMETRIC *tmPtr, int fontType, - LPARAM lParam); - -/* - *------------------------------------------------------------------------- - * - * TkpFontPkgInit -- - * - * This procedure is called when an application is created. It - * initializes all the structures that are used by the platform-dependent - * code on a per application basis. - * - * Results: - * None. - * - * Side effects: - * - * None. - * - *------------------------------------------------------------------------- - */ - -void -TkpFontPkgInit( - TkMainInfo *mainPtr) /* The application being created. */ -{ - systemEncoding = TkWinGetUnicodeEncoding(); - TkWinSetupSystemFonts(mainPtr); -} - -/* - *--------------------------------------------------------------------------- - * - * TkpGetNativeFont -- - * - * Map a platform-specific native font name to a TkFont. - * - * Results: - * The return value is a pointer to a TkFont that represents the native - * font. If a native font by the given name could not be found, the - * return value is NULL. - * - * Every call to this procedure returns a new TkFont structure, even if - * the name has already been seen before. The caller should call - * TkpDeleteFont() when the font is no longer needed. - * - * The caller is responsible for initializing the memory associated with - * the generic TkFont when this function returns and releasing the - * contents of the generic TkFont before calling TkpDeleteFont(). - * - * Side effects: - * Memory allocated. - * - *--------------------------------------------------------------------------- - */ - -TkFont * -TkpGetNativeFont( - Tk_Window tkwin, /* For display where font will be used. */ - const char *name) /* Platform-specific font name. */ -{ - int object; - WinFont *fontPtr; - - object = TkFindStateNum(NULL, NULL, systemMap, name); - if (object < 0) { - return NULL; - } - - tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr; - fontPtr = ckalloc(sizeof(WinFont)); - InitFont(tkwin, GetStockObject(object), 0, fontPtr); - - return (TkFont *) fontPtr; -} - -/* - *--------------------------------------------------------------------------- - * - * CreateNamedSystemFont -- - * - * This function registers a Windows logical font description with the Tk - * named font mechanism. - * - * Side effects: - * A new named font is added to the Tk font registry. - * - *--------------------------------------------------------------------------- - */ - -static int -CreateNamedSystemLogFont( - Tcl_Interp *interp, - Tk_Window tkwin, - const char* name, - LOGFONT* logFontPtr) -{ - HFONT hFont; - int r; - - hFont = CreateFontIndirect(logFontPtr); - r = CreateNamedSystemFont(interp, tkwin, name, hFont); - DeleteObject((HGDIOBJ)hFont); - return r; -} - -/* - *--------------------------------------------------------------------------- - * - * CreateNamedSystemFont -- - * - * This function registers a Windows font with the Tk named font - * mechanism. - * - * Side effects: - * A new named font is added to the Tk font registry. - * - *--------------------------------------------------------------------------- - */ - -static int -CreateNamedSystemFont( - Tcl_Interp *interp, - Tk_Window tkwin, - const char* name, - HFONT hFont) -{ - WinFont winfont; - int r; - - TkDeleteNamedFont(NULL, tkwin, name); - InitFont(tkwin, hFont, 0, &winfont); - r = TkCreateNamedFont(interp, tkwin, name, &winfont.font.fa); - TkpDeleteFont((TkFont *)&winfont); - return r; -} - -/* - *--------------------------------------------------------------------------- - * - * TkWinSystemFonts -- - * - * Create some platform specific named fonts that to give access to the - * system fonts. These are all defined for the Windows desktop - * parameters. - * - *--------------------------------------------------------------------------- - */ - -void -TkWinSetupSystemFonts( - TkMainInfo *mainPtr) -{ - Tcl_Interp *interp; - Tk_Window tkwin; - const TkStateMap *mapPtr; - NONCLIENTMETRICS ncMetrics; - ICONMETRICS iconMetrics; - HFONT hFont; - - interp = (Tcl_Interp *) mainPtr->interp; - tkwin = (Tk_Window) mainPtr->winPtr; - - /* force this for now */ - if (((TkWindow *) tkwin)->mainPtr == NULL) { - ((TkWindow *) tkwin)->mainPtr = mainPtr; - } - - /* - * If this API call fails then we will fallback to setting these named - * fonts from script in ttk/fonts.tcl. So far I've only seen it fail when - * WINVER has been defined for a higher platform than we are running on. - * (i.e. WINVER=0x0600 and running on XP). - */ - - ZeroMemory(&ncMetrics, sizeof(ncMetrics)); - ncMetrics.cbSize = sizeof(ncMetrics); - if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, - sizeof(ncMetrics), &ncMetrics, 0)) { - CreateNamedSystemLogFont(interp, tkwin, "TkDefaultFont", - &ncMetrics.lfMessageFont); - CreateNamedSystemLogFont(interp, tkwin, "TkHeadingFont", - &ncMetrics.lfMessageFont); - CreateNamedSystemLogFont(interp, tkwin, "TkTextFont", - &ncMetrics.lfMessageFont); - CreateNamedSystemLogFont(interp, tkwin, "TkMenuFont", - &ncMetrics.lfMenuFont); - CreateNamedSystemLogFont(interp, tkwin, "TkTooltipFont", - &ncMetrics.lfStatusFont); - CreateNamedSystemLogFont(interp, tkwin, "TkCaptionFont", - &ncMetrics.lfCaptionFont); - CreateNamedSystemLogFont(interp, tkwin, "TkSmallCaptionFont", - &ncMetrics.lfSmCaptionFont); - } - - iconMetrics.cbSize = sizeof(iconMetrics); - if (SystemParametersInfo(SPI_GETICONMETRICS, sizeof(iconMetrics), - &iconMetrics, 0)) { - CreateNamedSystemLogFont(interp, tkwin, "TkIconFont", - &iconMetrics.lfFont); - } - - /* - * Identify an available fixed font. Equivalent to ANSI_FIXED_FONT but - * more reliable on Russian Windows. - */ - - { - LOGFONT lfFixed = { - 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, - 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, TEXT("") - }; - long pointSize, dpi; - HDC hdc = GetDC(NULL); - dpi = GetDeviceCaps(hdc, LOGPIXELSY); - pointSize = -MulDiv(ncMetrics.lfMessageFont.lfHeight, 72, dpi); - lfFixed.lfHeight = -MulDiv(pointSize+1, dpi, 72); - ReleaseDC(NULL, hdc); - CreateNamedSystemLogFont(interp, tkwin, "TkFixedFont", &lfFixed); - } - - /* - * Setup the remaining standard Tk font names as named fonts. - */ - - for (mapPtr = systemMap; mapPtr->strKey != NULL; mapPtr++) { - hFont = (HFONT) GetStockObject(mapPtr->numKey); - CreateNamedSystemFont(interp, tkwin, mapPtr->strKey, hFont); - } -} - -/* - *--------------------------------------------------------------------------- - * - * TkpGetFontFromAttributes -- - * - * Given a desired set of attributes for a font, find a font with the - * closest matching attributes. - * - * Results: - * The return value is a pointer to a TkFont that represents the font - * with the desired attributes. If a font with the desired attributes - * could not be constructed, some other font will be substituted - * automatically. NULL is never returned. - * - * Every call to this procedure returns a new TkFont structure, even if - * the specified attributes have already been seen before. The caller - * should call TkpDeleteFont() to free the platform- specific data when - * the font is no longer needed. - * - * The caller is responsible for initializing the memory associated with - * the generic TkFont when this function returns and releasing the - * contents of the generic TkFont before calling TkpDeleteFont(). - * - * Side effects: - * Memory allocated. - * - *--------------------------------------------------------------------------- - */ - -TkFont * -TkpGetFontFromAttributes( - TkFont *tkFontPtr, /* If non-NULL, store the information in this - * existing TkFont structure, rather than - * allocating a new structure to hold the - * font; the existing contents of the font - * will be released. If NULL, a new TkFont - * structure is allocated. */ - Tk_Window tkwin, /* For display where font will be used. */ - const TkFontAttributes *faPtr) - /* Set of attributes to match. */ -{ - int i, j; - HDC hdc; - HWND hwnd; - HFONT hFont; - Window window; - WinFont *fontPtr; - const char *const *const *fontFallbacks; - Tk_Uid faceName, fallback, actualName; - - tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr; - window = Tk_WindowId(tkwin); - hwnd = (window == None) ? NULL : TkWinGetHWND(window); - hdc = GetDC(hwnd); - - /* - * Algorithm to get the closest font name to the one requested. - * - * try fontname - * try all aliases for fontname - * foreach fallback for fontname - * try the fallback - * try all aliases for the fallback - */ - - faceName = faPtr->family; - if (faceName != NULL) { - actualName = FamilyOrAliasExists(hdc, faceName); - if (actualName != NULL) { - faceName = actualName; - goto found; - } - fontFallbacks = TkFontGetFallbacks(); - for (i = 0; fontFallbacks[i] != NULL; i++) { - for (j = 0; (fallback = fontFallbacks[i][j]) != NULL; j++) { - if (strcasecmp(faceName, fallback) == 0) { - break; - } - } - if (fallback != NULL) { - for (j = 0; (fallback = fontFallbacks[i][j]) != NULL; j++) { - actualName = FamilyOrAliasExists(hdc, fallback); - if (actualName != NULL) { - faceName = actualName; - goto found; - } - } - } - } - } - - found: - ReleaseDC(hwnd, hdc); - - hFont = GetScreenFont(faPtr, faceName, - (int)(TkFontGetPixels(tkwin, faPtr->size) + 0.5), 0.0); - if (tkFontPtr == NULL) { - fontPtr = ckalloc(sizeof(WinFont)); - } else { - fontPtr = (WinFont *) tkFontPtr; - ReleaseFont(fontPtr); - } - InitFont(tkwin, hFont, faPtr->overstrike, fontPtr); - - return (TkFont *) fontPtr; -} - -/* - *--------------------------------------------------------------------------- - * - * TkpDeleteFont -- - * - * Called to release a font allocated by TkpGetNativeFont() or - * TkpGetFontFromAttributes(). The caller should have already released - * the fields of the TkFont that are used exclusively by the generic - * TkFont code. - * - * Results: - * None. - * - * Side effects: - * TkFont is deallocated. - * - *--------------------------------------------------------------------------- - */ - -void -TkpDeleteFont( - TkFont *tkFontPtr) /* Token of font to be deleted. */ -{ - WinFont *fontPtr; - - fontPtr = (WinFont *) tkFontPtr; - ReleaseFont(fontPtr); -} - -/* - *--------------------------------------------------------------------------- - * - * TkpGetFontFamilies, WinFontFamilyEnumProc -- - * - * Return information about the font families that are available on the - * display of the given window. - * - * Results: - * Modifies interp's result object to hold a list of all the available - * font families. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -void -TkpGetFontFamilies( - Tcl_Interp *interp, /* Interp to hold result. */ - Tk_Window tkwin) /* For display to query. */ -{ - HDC hdc; - HWND hwnd; - Window window; - Tcl_Obj *resultObj; - - window = Tk_WindowId(tkwin); - hwnd = (window == None) ? NULL : TkWinGetHWND(window); - hdc = GetDC(hwnd); - resultObj = Tcl_NewObj(); - - /* - * On any version NT, there may fonts with international names. Use the - * NT-only Unicode version of EnumFontFamilies to get the font names. If - * we used the ANSI version on a non-internationalized version of NT, we - * would get font names with '?' replacing all the international - * characters. - * - * On a non-internationalized verson of 95, fonts with international names - * are not allowed, so the ANSI version of EnumFontFamilies will work. On - * an internationalized version of 95, there may be fonts with - * international names; the ANSI version will work, fetching the name in - * the system code page. Can't use the Unicode version of EnumFontFamilies - * because it only exists under NT. - */ - - EnumFontFamilies(hdc, NULL, (FONTENUMPROC) WinFontFamilyEnumProc, - (LPARAM) resultObj); - ReleaseDC(hwnd, hdc); - Tcl_SetObjResult(interp, resultObj); -} - -static int CALLBACK -WinFontFamilyEnumProc( - ENUMLOGFONT *lfPtr, /* Logical-font data. */ - NEWTEXTMETRIC *tmPtr, /* Physical-font data (not used). */ - int fontType, /* Type of font (not used). */ - LPARAM lParam) /* Result object to hold result. */ -{ - char *faceName = (char *) lfPtr->elfLogFont.lfFaceName; - Tcl_Obj *resultObj = (Tcl_Obj *) lParam; - Tcl_DString faceString; - - Tcl_ExternalToUtfDString(systemEncoding, faceName, -1, &faceString); - Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( - Tcl_DStringValue(&faceString), Tcl_DStringLength(&faceString))); - Tcl_DStringFree(&faceString); - return 1; -} - -/* - *------------------------------------------------------------------------- - * - * TkpGetSubFonts -- - * - * A function used by the testing package for querying the actual screen - * fonts that make up a font object. - * - * Results: - * Modifies interp's result object to hold a list containing the names of - * the screen fonts that make up the given font object. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -void -TkpGetSubFonts( - Tcl_Interp *interp, /* Interp to hold result. */ - Tk_Font tkfont) /* Font object to query. */ -{ - int i; - WinFont *fontPtr; - FontFamily *familyPtr; - Tcl_Obj *resultPtr, *strPtr; - - resultPtr = Tcl_NewObj(); - fontPtr = (WinFont *) tkfont; - for (i = 0; i < fontPtr->numSubFonts; i++) { - familyPtr = fontPtr->subFontArray[i].familyPtr; - strPtr = Tcl_NewStringObj(familyPtr->faceName, -1); - Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); - } - Tcl_SetObjResult(interp, resultPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetFontAttrsForChar -- - * - * Retrieve the font attributes of the actual font used to render a given - * character. - * - * Results: - * None. - * - * Side effects: - * The font attributes are stored in *faPtr. - * - *---------------------------------------------------------------------- - */ - -void -TkpGetFontAttrsForChar( - Tk_Window tkwin, /* Window on the font's display */ - Tk_Font tkfont, /* Font to query */ - int c, /* Character of interest */ - TkFontAttributes *faPtr) /* Output: Font attributes */ -{ - WinFont *fontPtr = (WinFont *) tkfont; - /* Structure describing the logical font */ - HDC hdc = GetDC(fontPtr->hwnd); - /* GDI device context */ - SubFont *lastSubFontPtr = &fontPtr->subFontArray[0]; - /* Pointer to subfont array in case - * FindSubFontForChar needs to fix up the - * memory allocation */ - SubFont *thisSubFontPtr = - FindSubFontForChar(fontPtr, c, &lastSubFontPtr); - /* Pointer to the subfont to use for the given - * character */ - FontFamily *familyPtr = thisSubFontPtr->familyPtr; - HFONT oldfont; /* Saved font from the device context */ - TEXTMETRIC tm; /* Font metrics of the selected subfont */ - - /* - * Get the font attributes. - */ - - oldfont = SelectObject(hdc, thisSubFontPtr->hFont0); - GetTextMetrics(hdc, &tm); - SelectObject(hdc, oldfont); - ReleaseDC(fontPtr->hwnd, hdc); - faPtr->family = familyPtr->faceName; - faPtr->size = TkFontGetPoints(tkwin, - (double)(tm.tmInternalLeading - tm.tmHeight)); - faPtr->weight = (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL; - faPtr->slant = tm.tmItalic ? TK_FS_ITALIC : TK_FS_ROMAN; - faPtr->underline = (tm.tmUnderlined != 0); - faPtr->overstrike = fontPtr->font.fa.overstrike; -} - -/* - *--------------------------------------------------------------------------- - * - * Tk_MeasureChars -- - * - * Determine the number of bytes from the string that will fit in the - * given horizontal span. The measurement is done under the assumption - * that Tk_DrawChars() will be used to actually display the characters. - * - * Results: - * The return value is the number of bytes from source that fit into the - * span that extends from 0 to maxLength. *lengthPtr is filled with the - * x-coordinate of the right edge of the last character that did fit. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -int -Tk_MeasureChars( - Tk_Font tkfont, /* Font in which characters will be drawn. */ - const char *source, /* UTF-8 string to be displayed. Need not be - * '\0' terminated. */ - int numBytes, /* Maximum number of bytes to consider from - * source string. */ - int maxLength, /* If >= 0, maxLength specifies the longest - * permissible line length in pixels; don't - * consider any character that would cross - * this x-position. If < 0, then line length - * is unbounded and the flags argument is - * ignored. */ - int flags, /* Various flag bits OR-ed together: - * TK_PARTIAL_OK means include the last char - * which only partially fits on this line. - * TK_WHOLE_WORDS means stop on a word - * boundary, if possible. TK_AT_LEAST_ONE - * means return at least one character (or at - * least the first partial word in case - * TK_WHOLE_WORDS is also set) even if no - * characters (words) fit. */ - int *lengthPtr) /* Filled with x-location just after the - * terminating character. */ -{ - HDC hdc; - HFONT oldFont; - WinFont *fontPtr; - int curX, moretomeasure; - int ch; - SIZE size; - FontFamily *familyPtr; - Tcl_DString runString; - SubFont *thisSubFontPtr, *lastSubFontPtr; - const char *p, *end, *next = NULL, *start; - - if (numBytes == 0) { - *lengthPtr = 0; - return 0; - } - - fontPtr = (WinFont *) tkfont; - - hdc = GetDC(fontPtr->hwnd); - lastSubFontPtr = &fontPtr->subFontArray[0]; - oldFont = SelectObject(hdc, lastSubFontPtr->hFont0); - - /* - * A three step process: - * 1. Find a contiguous range of characters that can all be represented by - * a single screen font. - * 2. Convert those chars to the encoding of that font. - * 3. Measure converted chars. - */ - - moretomeasure = 0; - curX = 0; - start = source; - end = start + numBytes; - for (p = start; p < end; ) { - next = p + TkUtfToUniChar(p, &ch); - thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); - if (thisSubFontPtr != lastSubFontPtr) { - familyPtr = lastSubFontPtr->familyPtr; - Tcl_UtfToExternalDString(familyPtr->encoding, start, - (int) (p - start), &runString); - size.cx = 0; - familyPtr->getTextExtentPoint32Proc(hdc, - (TCHAR *)Tcl_DStringValue(&runString), - Tcl_DStringLength(&runString) >> familyPtr->isWideFont, - &size); - Tcl_DStringFree(&runString); - if (maxLength >= 0 && (curX+size.cx) > maxLength) { - moretomeasure = 1; - break; - } - curX += size.cx; - lastSubFontPtr = thisSubFontPtr; - start = p; - - SelectObject(hdc, lastSubFontPtr->hFont0); - } - p = next; - } - - if (!moretomeasure) { - /* - * We get here if the previous loop was just finished normally, - * without a break. Just measure the last run and that's it. - */ - - familyPtr = lastSubFontPtr->familyPtr; - Tcl_UtfToExternalDString(familyPtr->encoding, start, - (int) (p - start), &runString); - size.cx = 0; - familyPtr->getTextExtentPoint32Proc(hdc, (TCHAR *) Tcl_DStringValue(&runString), - Tcl_DStringLength(&runString) >> familyPtr->isWideFont, - &size); - Tcl_DStringFree(&runString); - if (maxLength >= 0 && (curX+size.cx) > maxLength) { - moretomeasure = 1; - } else { - curX += size.cx; - p = end; - } - } - - if (moretomeasure) { - /* - * We get here if the measurement of the last run was over the - * maxLength limit. We need to restart this run and do it char by - * char, but always in context with the previous text to account for - * kerning (especially italics). - */ - - char buf[16]; - int dstWrote; - int lastSize = 0; - - familyPtr = lastSubFontPtr->familyPtr; - Tcl_DStringInit(&runString); - for (p = start; p < end; ) { - next = p + TkUtfToUniChar(p, &ch); - Tcl_UtfToExternal(NULL, familyPtr->encoding, p, - (int) (next - p), 0, NULL, buf, sizeof(buf), NULL, - &dstWrote, NULL); - Tcl_DStringAppend(&runString,buf,dstWrote); - size.cx = 0; - familyPtr->getTextExtentPoint32Proc(hdc, - (TCHAR *) Tcl_DStringValue(&runString), - Tcl_DStringLength(&runString) >> familyPtr->isWideFont, - &size); - if ((curX+size.cx) > maxLength) { - break; - } - lastSize = size.cx; - p = next; - } - Tcl_DStringFree(&runString); - - /* - * "p" points to the first character that doesn't fit in the desired - * span. Look at the flags to figure out whether to include this next - * character. - */ - - if ((p < end) && (((flags & TK_PARTIAL_OK) && (curX != maxLength)) - || ((p==source) && (flags&TK_AT_LEAST_ONE) && (curX==0)))) { - /* - * Include the first character that didn't quite fit in the - * desired span. The width returned will include the width of that - * extra character. - */ - - p = next; - curX += size.cx; - } else { - curX += lastSize; - } - } - - SelectObject(hdc, oldFont); - ReleaseDC(fontPtr->hwnd, hdc); - - if ((flags & TK_WHOLE_WORDS) && (p < end)) { - /* - * Scan the string for the last word break and than repeat the whole - * procedure without the maxLength limit or any flags. - */ - - const char *lastWordBreak = NULL; - int ch2; - - end = p; - p = source; - ch = ' '; - while (p < end) { - next = p + TkUtfToUniChar(p, &ch2); - if ((ch != ' ') && (ch2 == ' ')) { - lastWordBreak = p; - } - p = next; - ch = ch2; - } - - if (lastWordBreak != NULL) { - return Tk_MeasureChars(tkfont, source, lastWordBreak-source, - -1, 0, lengthPtr); - } - if (flags & TK_AT_LEAST_ONE) { - p = end; - } else { - p = source; - curX = 0; - } - } - - *lengthPtr = curX; - return p - source; -} - -/* - *--------------------------------------------------------------------------- - * - * TkpMeasureCharsInContext -- - * - * Determine the number of bytes from the string that will fit in the - * given horizontal span. The measurement is done under the assumption - * that TkpDrawCharsInContext() will be used to actually display the - * characters. - * - * This one is almost the same as Tk_MeasureChars(), but with access to - * all the characters on the line for context. On Windows this context - * isn't consulted, so we just call Tk_MeasureChars(). - * - * Results: - * The return value is the number of bytes from source that fit into the - * span that extends from 0 to maxLength. *lengthPtr is filled with the - * x-coordinate of the right edge of the last character that did fit. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -int -TkpMeasureCharsInContext( - Tk_Font tkfont, /* Font in which characters will be drawn. */ - const char *source, /* UTF-8 string to be displayed. Need not be - * '\0' terminated. */ - int numBytes, /* Maximum number of bytes to consider from - * source string in all. */ - int rangeStart, /* Index of first byte to measure. */ - int rangeLength, /* Length of range to measure in bytes. */ - int maxLength, /* If >= 0, maxLength specifies the longest - * permissible line length; don't consider any - * character that would cross this x-position. - * If < 0, then line length is unbounded and - * the flags argument is ignored. */ - int flags, /* Various flag bits OR-ed together: - * TK_PARTIAL_OK means include the last char - * which only partially fit on this line. - * TK_WHOLE_WORDS means stop on a word - * boundary, if possible. TK_AT_LEAST_ONE - * means return at least one character even if - * no characters fit. TK_ISOLATE_END means - * that the last character should not be - * considered in context with the rest of the - * string (used for breaking lines). */ - int *lengthPtr) /* Filled with x-location just after the - * terminating character. */ -{ - (void) numBytes; /*unused*/ - return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength, - maxLength, flags, lengthPtr); -} - -/* - *--------------------------------------------------------------------------- - * - * Tk_DrawChars -- - * - * Draw a string of characters on the screen. - * - * Results: - * None. - * - * Side effects: - * Information gets drawn on the screen. - * - *--------------------------------------------------------------------------- - */ - -void -Tk_DrawChars( - Display *display, /* Display on which to draw. */ - Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context for drawing characters. */ - Tk_Font tkfont, /* Font in which characters will be drawn; - * must be the same as font used in GC. */ - const char *source, /* UTF-8 string to be displayed. Need not be - * '\0' terminated. All Tk meta-characters - * (tabs, control characters, and newlines) - * should be stripped out of the string that - * is passed to this function. If they are not - * stripped out, they will be displayed as - * regular printing characters. */ - int numBytes, /* Number of bytes in string. */ - int x, int y) /* Coordinates at which to place origin of - * string when drawing. */ -{ - HDC dc; - WinFont *fontPtr; - TkWinDCState state; - - fontPtr = (WinFont *) gc->font; - display->request++; - - if (drawable == None) { - return; - } - - dc = TkWinGetDrawableDC(display, drawable, &state); - - SetROP2(dc, tkpWinRopModes[gc->function]); - - if ((gc->clip_mask != None) && - ((TkpClipMask *) gc->clip_mask)->type == TKP_CLIP_REGION) { - SelectClipRgn(dc, (HRGN)((TkpClipMask *)gc->clip_mask)->value.region); - } - - if ((gc->fill_style == FillStippled - || gc->fill_style == FillOpaqueStippled) - && gc->stipple != None) { - TkWinDrawable *twdPtr = (TkWinDrawable *) gc->stipple; - HBRUSH oldBrush, stipple; - HBITMAP oldBitmap, bitmap; - HDC dcMem; - TEXTMETRIC tm; - SIZE size; - - if (twdPtr->type != TWD_BITMAP) { - Tcl_Panic("unexpected drawable type in stipple"); - } - - /* - * Select stipple pattern into destination dc. - */ - - dcMem = CreateCompatibleDC(dc); - - stipple = CreatePatternBrush(twdPtr->bitmap.handle); - SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL); - oldBrush = SelectObject(dc, stipple); - - SetTextAlign(dcMem, TA_LEFT | TA_BASELINE); - SetTextColor(dcMem, gc->foreground); - SetBkMode(dcMem, TRANSPARENT); - SetBkColor(dcMem, RGB(0, 0, 0)); - - /* - * Compute the bounding box and create a compatible bitmap. - */ - - GetTextExtentPointA(dcMem, source, numBytes, &size); - GetTextMetrics(dcMem, &tm); - size.cx -= tm.tmOverhang; - bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy); - oldBitmap = SelectObject(dcMem, bitmap); - - /* - * The following code is tricky because fonts are rendered in multiple - * colors. First we draw onto a black background and copy the white - * bits. Then we draw onto a white background and copy the black bits. - * Both the foreground and background bits of the font are ANDed with - * the stipple pattern as they are copied. - */ - - PatBlt(dcMem, 0, 0, size.cx, size.cy, BLACKNESS); - MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0); - BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem, - 0, 0, 0xEA02E9); - PatBlt(dcMem, 0, 0, size.cx, size.cy, WHITENESS); - MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0); - BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem, - 0, 0, 0x8A0E06); - - /* - * Destroy the temporary bitmap and restore the device context. - */ - - SelectObject(dcMem, oldBitmap); - DeleteObject(bitmap); - DeleteDC(dcMem); - SelectObject(dc, oldBrush); - DeleteObject(stipple); - } else if (gc->function == GXcopy) { - SetTextAlign(dc, TA_LEFT | TA_BASELINE); - SetTextColor(dc, gc->foreground); - SetBkMode(dc, TRANSPARENT); - MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0); - } else { - HBITMAP oldBitmap, bitmap; - HDC dcMem; - TEXTMETRIC tm; - SIZE size; - - dcMem = CreateCompatibleDC(dc); - - SetTextAlign(dcMem, TA_LEFT | TA_BASELINE); - SetTextColor(dcMem, gc->foreground); - SetBkMode(dcMem, TRANSPARENT); - SetBkColor(dcMem, RGB(0, 0, 0)); - - /* - * Compute the bounding box and create a compatible bitmap. - */ - - GetTextExtentPointA(dcMem, source, numBytes, &size); - GetTextMetrics(dcMem, &tm); - size.cx -= tm.tmOverhang; - bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy); - oldBitmap = SelectObject(dcMem, bitmap); - - MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent, - 0.0); - BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem, - 0, 0, (DWORD) tkpWinBltModes[gc->function]); - - /* - * Destroy the temporary bitmap and restore the device context. - */ - - SelectObject(dcMem, oldBitmap); - DeleteObject(bitmap); - DeleteDC(dcMem); - } - TkWinReleaseDrawableDC(drawable, dc, &state); -} - -void -TkDrawAngledChars( - Display *display, /* Display on which to draw. */ - Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context for drawing characters. */ - Tk_Font tkfont, /* Font in which characters will be drawn; - * must be the same as font used in GC. */ - const char *source, /* UTF-8 string to be displayed. Need not be - * '\0' terminated. All Tk meta-characters - * (tabs, control characters, and newlines) - * should be stripped out of the string that - * is passed to this function. If they are not - * stripped out, they will be displayed as - * regular printing characters. */ - int numBytes, /* Number of bytes in string. */ - double x, double y, /* Coordinates at which to place origin of - * string when drawing. */ - double angle) -{ - HDC dc; - WinFont *fontPtr; - TkWinDCState state; - - fontPtr = (WinFont *) gc->font; - display->request++; - - if (drawable == None) { - return; - } - - dc = TkWinGetDrawableDC(display, drawable, &state); - - SetROP2(dc, tkpWinRopModes[gc->function]); - - if ((gc->clip_mask != None) && - ((TkpClipMask *) gc->clip_mask)->type == TKP_CLIP_REGION) { - SelectClipRgn(dc, (HRGN)((TkpClipMask *)gc->clip_mask)->value.region); - } - - if ((gc->fill_style == FillStippled - || gc->fill_style == FillOpaqueStippled) - && gc->stipple != None) { - TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; - HBRUSH oldBrush, stipple; - HBITMAP oldBitmap, bitmap; - HDC dcMem; - TEXTMETRIC tm; - SIZE size; - - if (twdPtr->type != TWD_BITMAP) { - Tcl_Panic("unexpected drawable type in stipple"); - } - - /* - * Select stipple pattern into destination dc. - */ - - dcMem = CreateCompatibleDC(dc); - - stipple = CreatePatternBrush(twdPtr->bitmap.handle); - SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL); - oldBrush = SelectObject(dc, stipple); - - SetTextAlign(dcMem, TA_LEFT | TA_BASELINE); - SetTextColor(dcMem, gc->foreground); - SetBkMode(dcMem, TRANSPARENT); - SetBkColor(dcMem, RGB(0, 0, 0)); - - /* - * Compute the bounding box and create a compatible bitmap. - */ - - GetTextExtentPointA(dcMem, source, numBytes, &size); - GetTextMetrics(dcMem, &tm); - size.cx -= tm.tmOverhang; - bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy); - oldBitmap = SelectObject(dcMem, bitmap); - - /* - * The following code is tricky because fonts are rendered in multiple - * colors. First we draw onto a black background and copy the white - * bits. Then we draw onto a white background and copy the black bits. - * Both the foreground and background bits of the font are ANDed with - * the stipple pattern as they are copied. - */ - - PatBlt(dcMem, 0, 0, size.cx, size.cy, BLACKNESS); - MultiFontTextOut(dc, fontPtr, source, numBytes, (int)x, (int)y, angle); - BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem, - 0, 0, 0xEA02E9); - PatBlt(dcMem, 0, 0, size.cx, size.cy, WHITENESS); - MultiFontTextOut(dc, fontPtr, source, numBytes, (int)x, (int)y, angle); - BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem, - 0, 0, 0x8A0E06); - - /* - * Destroy the temporary bitmap and restore the device context. - */ - - SelectObject(dcMem, oldBitmap); - DeleteObject(bitmap); - DeleteDC(dcMem); - SelectObject(dc, oldBrush); - DeleteObject(stipple); - } else if (gc->function == GXcopy) { - SetTextAlign(dc, TA_LEFT | TA_BASELINE); - SetTextColor(dc, gc->foreground); - SetBkMode(dc, TRANSPARENT); - MultiFontTextOut(dc, fontPtr, source, numBytes, (int)x, (int)y, angle); - } else { - HBITMAP oldBitmap, bitmap; - HDC dcMem; - TEXTMETRIC tm; - SIZE size; - - dcMem = CreateCompatibleDC(dc); - - SetTextAlign(dcMem, TA_LEFT | TA_BASELINE); - SetTextColor(dcMem, gc->foreground); - SetBkMode(dcMem, TRANSPARENT); - SetBkColor(dcMem, RGB(0, 0, 0)); - - /* - * Compute the bounding box and create a compatible bitmap. - */ - - GetTextExtentPointA(dcMem, source, numBytes, &size); - GetTextMetrics(dcMem, &tm); - size.cx -= tm.tmOverhang; - bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy); - oldBitmap = SelectObject(dcMem, bitmap); - - MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent, - angle); - BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem, - 0, 0, (DWORD) tkpWinBltModes[gc->function]); - - /* - * Destroy the temporary bitmap and restore the device context. - */ - - SelectObject(dcMem, oldBitmap); - DeleteObject(bitmap); - DeleteDC(dcMem); - } - TkWinReleaseDrawableDC(drawable, dc, &state); -} - -/* - *--------------------------------------------------------------------------- - * - * TkpDrawCharsInContext -- - * - * Draw a string of characters on the screen like Tk_DrawChars(), but - * with access to all the characters on the line for context. On Windows - * this context isn't consulted, so we just call Tk_DrawChars(). - * - * Results: - * None. - * - * Side effects: - * Information gets drawn on the screen. - * - *--------------------------------------------------------------------------- - */ - -void -TkpDrawCharsInContext( - Display *display, /* Display on which to draw. */ - Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context for drawing characters. */ - Tk_Font tkfont, /* Font in which characters will be drawn; - * must be the same as font used in GC. */ - const char *source, /* UTF-8 string to be displayed. Need not be - * '\0' terminated. All Tk meta-characters - * (tabs, control characters, and newlines) - * should be stripped out of the string that - * is passed to this function. If they are not - * stripped out, they will be displayed as - * regular printing characters. */ - int numBytes, /* Number of bytes in string. */ - int rangeStart, /* Index of first byte to draw. */ - int rangeLength, /* Length of range to draw in bytes. */ - int x, int y) /* Coordinates at which to place origin of the - * whole (not just the range) string when - * drawing. */ -{ - int widthUntilStart; - - (void) numBytes; /*unused*/ - - Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart); - Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart, - rangeLength, x+widthUntilStart, y); -} - -/* - *------------------------------------------------------------------------- - * - * MultiFontTextOut -- - * - * Helper function for Tk_DrawChars. Draws characters, using the various - * screen fonts in fontPtr to draw multilingual characters. Note: No - * bidirectional support. - * - * Results: - * None. - * - * Side effects: - * Information gets drawn on the screen. Contents of fontPtr may be - * modified if more subfonts were loaded in order to draw all the - * multilingual characters in the given string. - * - *------------------------------------------------------------------------- - */ - -static void -MultiFontTextOut( - HDC hdc, /* HDC to draw into. */ - WinFont *fontPtr, /* Contains set of fonts to use when drawing - * following string. */ - const char *source, /* Potentially multilingual UTF-8 string. */ - int numBytes, /* Length of string in bytes. */ - int x, int y, /* Coordinates at which to place origin of - * string when drawing. */ - double angle) -{ - int ch; - SIZE size; - HFONT oldFont; - FontFamily *familyPtr; - Tcl_DString runString; - const char *p, *end, *next; - SubFont *lastSubFontPtr, *thisSubFontPtr; - TEXTMETRIC tm; - - lastSubFontPtr = &fontPtr->subFontArray[0]; - oldFont = SelectFont(hdc, fontPtr, lastSubFontPtr, angle); - GetTextMetrics(hdc, &tm); - - end = source + numBytes; - for (p = source; p < end; ) { - next = p + TkUtfToUniChar(p, &ch); - thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); - - /* - * The drawing API has a limit of 32767 pixels in one go. - * To avoid spending time on a rare case we do not measure each char, - * instead we limit to drawing chunks of 200 bytes since that works - * well in practice. - */ - - if ((thisSubFontPtr != lastSubFontPtr) || (p-source > 200)) { - if (p > source) { - familyPtr = lastSubFontPtr->familyPtr; - Tcl_UtfToExternalDString(familyPtr->encoding, source, - (int) (p - source), &runString); - familyPtr->textOutProc(hdc, x-(tm.tmOverhang/2), y, - (TCHAR *)Tcl_DStringValue(&runString), - Tcl_DStringLength(&runString)>>familyPtr->isWideFont); - familyPtr->getTextExtentPoint32Proc(hdc, - (TCHAR *)Tcl_DStringValue(&runString), - Tcl_DStringLength(&runString) >> familyPtr->isWideFont, - &size); - x += size.cx; - Tcl_DStringFree(&runString); - } - lastSubFontPtr = thisSubFontPtr; - source = p; - SelectFont(hdc, fontPtr, lastSubFontPtr, angle); - GetTextMetrics(hdc, &tm); - } - p = next; - } - if (p > source) { - familyPtr = lastSubFontPtr->familyPtr; - Tcl_UtfToExternalDString(familyPtr->encoding, source, - (int) (p - source), &runString); - familyPtr->textOutProc(hdc, x-(tm.tmOverhang/2), y, - (TCHAR *)Tcl_DStringValue(&runString), - Tcl_DStringLength(&runString) >> familyPtr->isWideFont); - Tcl_DStringFree(&runString); - } - SelectObject(hdc, oldFont); -} - -static inline HFONT -SelectFont( - HDC hdc, - WinFont *fontPtr, - SubFont *subFontPtr, - double angle) -{ - if (angle == 0.0) { - return SelectObject(hdc, subFontPtr->hFont0); - } else if (angle == subFontPtr->angle) { - return SelectObject(hdc, subFontPtr->hFontAngled); - } else { - if (subFontPtr->hFontAngled) { - DeleteObject(subFontPtr->hFontAngled); - } - subFontPtr->hFontAngled = GetScreenFont(&fontPtr->font.fa, - subFontPtr->familyPtr->faceName, fontPtr->pixelSize, angle); - if (subFontPtr->hFontAngled == NULL) { - return SelectObject(hdc, subFontPtr->hFont0); - } - subFontPtr->angle = angle; - return SelectObject(hdc, subFontPtr->hFontAngled); - } -} - -/* - *--------------------------------------------------------------------------- - * - * InitFont -- - * - * Helper for TkpGetNativeFont() and TkpGetFontFromAttributes(). - * Initializes the memory for a new WinFont that wraps the - * platform-specific data. - * - * The caller is responsible for initializing the fields of the WinFont - * that are used exclusively by the generic TkFont code, and for - * releasing those fields before calling TkpDeleteFont(). - * - * Results: - * Fills the WinFont structure. - * - * Side effects: - * Memory allocated. - * - *--------------------------------------------------------------------------- - */ - -static void -InitFont( - Tk_Window tkwin, /* Main window of interp in which font will be - * used, for getting HDC. */ - HFONT hFont, /* Windows token for font. */ - int overstrike, /* The overstrike attribute of logfont used to - * allocate this font. For some reason, the - * TEXTMETRICs may contain incorrect info in - * the tmStruckOut field. */ - WinFont *fontPtr) /* Filled with information constructed from - * the above arguments. */ -{ - HDC hdc; - HWND hwnd; - HFONT oldFont; - TEXTMETRIC tm; - Window window; - TkFontMetrics *fmPtr; - Tcl_Encoding encoding; - Tcl_DString faceString; - TkFontAttributes *faPtr; - TCHAR buf[LF_FACESIZE]; - - window = Tk_WindowId(tkwin); - hwnd = (window == None) ? NULL : TkWinGetHWND(window); - hdc = GetDC(hwnd); - oldFont = SelectObject(hdc, hFont); - - GetTextMetrics(hdc, &tm); - - /* - * On any version NT, there may fonts with international names. Use the - * NT-only Unicode version of GetTextFace to get the font's name. If we - * used the ANSI version on a non-internationalized version of NT, we - * would get a font name with '?' replacing all the international - * characters. - * - * On a non-internationalized verson of 95, fonts with international names - * are not allowed, so the ANSI version of GetTextFace will work. On an - * internationalized version of 95, there may be fonts with international - * names; the ANSI version will work, fetching the name in the - * international system code page. Can't use the Unicode version of - * GetTextFace because it only exists under NT. - */ - - GetTextFace(hdc, LF_FACESIZE, buf); - Tcl_ExternalToUtfDString(systemEncoding, (char *) buf, -1, &faceString); - - fontPtr->font.fid = (Font) fontPtr; - fontPtr->hwnd = hwnd; - fontPtr->pixelSize = tm.tmHeight - tm.tmInternalLeading; - - faPtr = &fontPtr->font.fa; - faPtr->family = Tk_GetUid(Tcl_DStringValue(&faceString)); - - faPtr->size = - TkFontGetPoints(tkwin, (double)-(fontPtr->pixelSize)); - faPtr->weight = - (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL; - faPtr->slant = (tm.tmItalic != 0) ? TK_FS_ITALIC : TK_FS_ROMAN; - faPtr->underline = (tm.tmUnderlined != 0) ? 1 : 0; - faPtr->overstrike = overstrike; - - fmPtr = &fontPtr->font.fm; - fmPtr->ascent = tm.tmAscent; - fmPtr->descent = tm.tmDescent; - fmPtr->maxWidth = tm.tmMaxCharWidth; - fmPtr->fixed = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); - - fontPtr->numSubFonts = 1; - fontPtr->subFontArray = fontPtr->staticSubFonts; - InitSubFont(hdc, hFont, 1, &fontPtr->subFontArray[0]); - - encoding = fontPtr->subFontArray[0].familyPtr->encoding; - if (encoding == TkWinGetUnicodeEncoding()) { - GetCharWidth(hdc, 0, BASE_CHARS - 1, fontPtr->widths); - } else { - GetCharWidthA(hdc, 0, BASE_CHARS - 1, fontPtr->widths); - } - Tcl_DStringFree(&faceString); - - SelectObject(hdc, oldFont); - ReleaseDC(hwnd, hdc); -} - -/* - *------------------------------------------------------------------------- - * - * ReleaseFont -- - * - * Called to release the windows-specific contents of a TkFont. The - * caller is responsible for freeing the memory used by the font itself. - * - * Results: - * None. - * - * Side effects: - * Memory is freed. - * - *--------------------------------------------------------------------------- - */ - -static void -ReleaseFont( - WinFont *fontPtr) /* The font to delete. */ -{ - int i; - - for (i = 0; i < fontPtr->numSubFonts; i++) { - ReleaseSubFont(&fontPtr->subFontArray[i]); - } - if (fontPtr->subFontArray != fontPtr->staticSubFonts) { - ckfree(fontPtr->subFontArray); - } -} - -/* - *------------------------------------------------------------------------- - * - * InitSubFont -- - * - * Wrap a screen font and load the FontFamily that represents it. Used to - * prepare a SubFont so that characters can be mapped from UTF-8 to the - * charset of the font. - * - * Results: - * The subFontPtr is filled with information about the font. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static inline void -InitSubFont( - HDC hdc, /* HDC in which font can be selected. */ - HFONT hFont, /* The screen font. */ - int base, /* Non-zero if this SubFont is being used as - * the base font for a font object. */ - SubFont *subFontPtr) /* Filled with SubFont constructed from above - * attributes. */ -{ - subFontPtr->hFont0 = hFont; - subFontPtr->familyPtr = AllocFontFamily(hdc, hFont, base); - subFontPtr->fontMap = subFontPtr->familyPtr->fontMap; - subFontPtr->hFontAngled = NULL; - subFontPtr->angle = 0.0; -} - -/* - *------------------------------------------------------------------------- - * - * ReleaseSubFont -- - * - * Called to release the contents of a SubFont. The caller is responsible - * for freeing the memory used by the SubFont itself. - * - * Results: - * None. - * - * Side effects: - * Memory and resources are freed. - * - *--------------------------------------------------------------------------- - */ - -static inline void -ReleaseSubFont( - SubFont *subFontPtr) /* The SubFont to delete. */ -{ - DeleteObject(subFontPtr->hFont0); - if (subFontPtr->hFontAngled) { - DeleteObject(subFontPtr->hFontAngled); - } - FreeFontFamily(subFontPtr->familyPtr); -} - -/* - *------------------------------------------------------------------------- - * - * AllocFontFamily -- - * - * Find the FontFamily structure associated with the given font name. The - * information should be stored by the caller in a SubFont and used when - * determining if that SubFont supports a character. - * - * Cannot use the string name used to construct the font as the key, - * because the capitalization may not be canonical. Therefore use the - * face name actually retrieved from the font metrics as the key. - * - * Results: - * A pointer to a FontFamily. The reference count in the FontFamily is - * automatically incremented. When the SubFont is released, the reference - * count is decremented. When no SubFont is using this FontFamily, it may - * be deleted. - * - * Side effects: - * A new FontFamily structure will be allocated if this font family has - * not been seen. TrueType character existence metrics are loaded into - * the FontFamily structure. - * - *------------------------------------------------------------------------- - */ - -static FontFamily * -AllocFontFamily( - HDC hdc, /* HDC in which font can be selected. */ - HFONT hFont, /* Screen font whose FontFamily is to be - * returned. */ - int base) /* Non-zero if this font family is to be used - * in the base font of a font object. */ -{ - Tk_Uid faceName; - FontFamily *familyPtr; - Tcl_DString faceString; - Tcl_Encoding encoding; - TCHAR buf[LF_FACESIZE]; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - hFont = SelectObject(hdc, hFont); - GetTextFace(hdc, LF_FACESIZE, buf); - Tcl_ExternalToUtfDString(systemEncoding, (char *) buf, -1, &faceString); - faceName = Tk_GetUid(Tcl_DStringValue(&faceString)); - Tcl_DStringFree(&faceString); - hFont = SelectObject(hdc, hFont); - - familyPtr = tsdPtr->fontFamilyList; - for ( ; familyPtr != NULL; familyPtr = familyPtr->nextPtr) { - if (familyPtr->faceName == faceName) { - familyPtr->refCount++; - return familyPtr; - } - } - - familyPtr = ckalloc(sizeof(FontFamily)); - memset(familyPtr, 0, sizeof(FontFamily)); - familyPtr->nextPtr = tsdPtr->fontFamilyList; - tsdPtr->fontFamilyList = familyPtr; - - /* - * Set key for this FontFamily. - */ - - familyPtr->faceName = faceName; - - /* - * An initial refCount of 2 means that FontFamily information will persist - * even when the SubFont that loaded the FontFamily is released. Change it - * to 1 to cause FontFamilies to be unloaded when not in use. - */ - - familyPtr->refCount = 2; - - familyPtr->segCount = LoadFontRanges(hdc, hFont, &familyPtr->startCount, - &familyPtr->endCount, &familyPtr->isSymbolFont); - - encoding = NULL; - if (familyPtr->isSymbolFont != 0) { - /* - * Symbol fonts are handled specially. For instance, Unicode 0393 - * (GREEK CAPITAL GAMMA) must be mapped to Symbol character 0047 - * (GREEK CAPITAL GAMMA), because the Symbol font doesn't have a GREEK - * CAPITAL GAMMA at location 0393. If Tk interpreted the Symbol font - * using the Unicode encoding, it would decide that the Symbol font - * has no GREEK CAPITAL GAMMA, because the Symbol encoding (of course) - * reports that character 0393 doesn't exist. - * - * With non-symbol Windows fonts, such as Times New Roman, if the font - * has a GREEK CAPITAL GAMMA, it will be found in the correct Unicode - * location (0393); the GREEK CAPITAL GAMMA will not be off hiding at - * some other location. - */ - - encoding = Tcl_GetEncoding(NULL, faceName); - } - - if (encoding == NULL) { - encoding = Tcl_GetEncoding(NULL, "unicode"); - familyPtr->textOutProc = - (BOOL (WINAPI *)(HDC, int, int, TCHAR *, int)) TextOutW; - familyPtr->getTextExtentPoint32Proc = - (BOOL (WINAPI *)(HDC, TCHAR *, int, LPSIZE)) GetTextExtentPoint32W; - familyPtr->isWideFont = 1; - } else { - familyPtr->textOutProc = - (BOOL (WINAPI *)(HDC, int, int, TCHAR *, int)) TextOutA; - familyPtr->getTextExtentPoint32Proc = - (BOOL (WINAPI *)(HDC, TCHAR *, int, LPSIZE)) GetTextExtentPoint32A; - familyPtr->isWideFont = 0; - } - - familyPtr->encoding = encoding; - - return familyPtr; -} - -/* - *------------------------------------------------------------------------- - * - * FreeFontFamily -- - * - * Called to free a FontFamily when the SubFont is finished using it. - * Frees the contents of the FontFamily and the memory used by the - * FontFamily itself. - * - * Results: - * None. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static void -FreeFontFamily( - FontFamily *familyPtr) /* The FontFamily to delete. */ -{ - int i; - FontFamily **familyPtrPtr; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (familyPtr == NULL) { - return; - } - if (familyPtr->refCount-- > 1) { - return; - } - for (i = 0; i < FONTMAP_PAGES; i++) { - if (familyPtr->fontMap[i] != NULL) { - ckfree(familyPtr->fontMap[i]); - } - } - if (familyPtr->startCount != NULL) { - ckfree(familyPtr->startCount); - } - if (familyPtr->endCount != NULL) { - ckfree(familyPtr->endCount); - } - if (familyPtr->encoding != TkWinGetUnicodeEncoding()) { - Tcl_FreeEncoding(familyPtr->encoding); - } - - /* - * Delete from list. - */ - - for (familyPtrPtr = &tsdPtr->fontFamilyList; ; ) { - if (*familyPtrPtr == familyPtr) { - *familyPtrPtr = familyPtr->nextPtr; - break; - } - familyPtrPtr = &(*familyPtrPtr)->nextPtr; - } - - ckfree(familyPtr); -} - -/* - *------------------------------------------------------------------------- - * - * FindSubFontForChar -- - * - * Determine which screen font is necessary to use to display the given - * character. If the font object does not have a screen font that can - * display the character, another screen font may be loaded into the font - * object, following a set of preferred fallback rules. - * - * Results: - * The return value is the SubFont to use to display the given character. - * - * Side effects: - * The contents of fontPtr are modified to cache the results of the - * lookup and remember any SubFonts that were dynamically loaded. - * - *------------------------------------------------------------------------- - */ - -static SubFont * -FindSubFontForChar( - WinFont *fontPtr, /* The font object with which the character - * will be displayed. */ - int ch, /* The Unicode character to be displayed. */ - SubFont **subFontPtrPtr) /* Pointer to var to be fixed up if we - * reallocate the subfont table. */ -{ - HDC hdc; - int i, j, k; - CanUse canUse; - const char *const *aliases; - const char *const *anyFallbacks; - const char *const *const *fontFallbacks; - const char *fallbackName; - SubFont *subFontPtr; - Tcl_DString ds; - - - if ((ch < BASE_CHARS) || (ch >= 0x10000)) { - return &fontPtr->subFontArray[0]; - } - - for (i = 0; i < fontPtr->numSubFonts; i++) { - if (FontMapLookup(&fontPtr->subFontArray[i], ch)) { - return &fontPtr->subFontArray[i]; - } - } - - /* - * Keep track of all face names that we check, so we don't check some name - * multiple times if it can be reached by multiple paths. - */ - - Tcl_DStringInit(&ds); - hdc = GetDC(fontPtr->hwnd); - - aliases = TkFontGetAliasList(fontPtr->font.fa.family); - - fontFallbacks = TkFontGetFallbacks(); - for (i = 0; fontFallbacks[i] != NULL; i++) { - for (j = 0; fontFallbacks[i][j] != NULL; j++) { - fallbackName = fontFallbacks[i][j]; - if (strcasecmp(fallbackName, fontPtr->font.fa.family) == 0) { - /* - * If the base font has a fallback... - */ - - goto tryfallbacks; - } else if (aliases != NULL) { - /* - * Or if an alias for the base font has a fallback... - */ - - for (k = 0; aliases[k] != NULL; k++) { - if (strcasecmp(aliases[k], fallbackName) == 0) { - goto tryfallbacks; - } - } - } - } - continue; - - /* - * ...then see if we can use one of the fallbacks, or an alias for one - * of the fallbacks. - */ - - tryfallbacks: - for (j = 0; fontFallbacks[i][j] != NULL; j++) { - fallbackName = fontFallbacks[i][j]; - subFontPtr = CanUseFallbackWithAliases(hdc, fontPtr, fallbackName, - ch, &ds, subFontPtrPtr); - if (subFontPtr != NULL) { - goto end; - } - } - } - - /* - * See if we can use something from the global fallback list. - */ - - anyFallbacks = TkFontGetGlobalClass(); - for (i = 0; anyFallbacks[i] != NULL; i++) { - fallbackName = anyFallbacks[i]; - subFontPtr = CanUseFallbackWithAliases(hdc, fontPtr, fallbackName, - ch, &ds, subFontPtrPtr); - if (subFontPtr != NULL) { - goto end; - } - } - - /* - * Try all face names available in the whole system until we find one that - * can be used. - */ - - canUse.hdc = hdc; - canUse.fontPtr = fontPtr; - canUse.nameTriedPtr = &ds; - canUse.ch = ch; - canUse.subFontPtr = NULL; - canUse.subFontPtrPtr = subFontPtrPtr; - EnumFontFamilies(hdc, NULL, (FONTENUMPROC) WinFontCanUseProc, - (LPARAM) &canUse); - subFontPtr = canUse.subFontPtr; - - end: - Tcl_DStringFree(&ds); - - if (subFontPtr == NULL) { - /* - * No font can display this character. We will use the base font and - * have it display the "unknown" character. - */ - - subFontPtr = &fontPtr->subFontArray[0]; - FontMapInsert(subFontPtr, ch); - } - ReleaseDC(fontPtr->hwnd, hdc); - return subFontPtr; -} - -static int CALLBACK -WinFontCanUseProc( - ENUMLOGFONT *lfPtr, /* Logical-font data. */ - NEWTEXTMETRIC *tmPtr, /* Physical-font data (not used). */ - int fontType, /* Type of font (not used). */ - LPARAM lParam) /* Result object to hold result. */ -{ - int ch; - HDC hdc; - WinFont *fontPtr; - CanUse *canUsePtr; - char *fallbackName; - SubFont *subFontPtr; - Tcl_DString faceString; - Tcl_DString *nameTriedPtr; - - canUsePtr = (CanUse *) lParam; - ch = canUsePtr->ch; - hdc = canUsePtr->hdc; - fontPtr = canUsePtr->fontPtr; - nameTriedPtr = canUsePtr->nameTriedPtr; - - fallbackName = (char *) lfPtr->elfLogFont.lfFaceName; - Tcl_ExternalToUtfDString(systemEncoding, fallbackName, -1, &faceString); - fallbackName = Tcl_DStringValue(&faceString); - - if (SeenName(fallbackName, nameTriedPtr) == 0) { - subFontPtr = CanUseFallback(hdc, fontPtr, fallbackName, ch, - canUsePtr->subFontPtrPtr); - if (subFontPtr != NULL) { - canUsePtr->subFontPtr = subFontPtr; - Tcl_DStringFree(&faceString); - return 0; - } - } - Tcl_DStringFree(&faceString); - return 1; -} - -/* - *------------------------------------------------------------------------- - * - * FontMapLookup -- - * - * See if the screen font can display the given character. - * - * Results: - * The return value is 0 if the screen font cannot display the character, - * non-zero otherwise. - * - * Side effects: - * New pages are added to the font mapping cache whenever the character - * belongs to a page that hasn't been seen before. When a page is loaded, - * information about all the characters on that page is stored, not just - * for the single character in question. - * - *------------------------------------------------------------------------- - */ - -static int -FontMapLookup( - SubFont *subFontPtr, /* Contains font mapping cache to be queried - * and possibly updated. */ - int ch) /* Character to be tested. */ -{ - int row, bitOffset; - - row = ch >> FONTMAP_SHIFT; - if (subFontPtr->fontMap[row] == NULL) { - FontMapLoadPage(subFontPtr, row); - } - bitOffset = ch & (FONTMAP_BITSPERPAGE - 1); - return (subFontPtr->fontMap[row][bitOffset >> 3] >> (bitOffset & 7)) & 1; -} - -/* - *------------------------------------------------------------------------- - * - * FontMapInsert -- - * - * Tell the font mapping cache that the given screen font should be used - * to display the specified character. This is called when no font on the - * system can be be found that can display that character; we lie to the - * font and tell it that it can display the character, otherwise we would - * end up re-searching the entire fallback hierarchy every time that - * character was seen. - * - * Results: - * None. - * - * Side effects: - * New pages are added to the font mapping cache whenever the character - * belongs to a page that hasn't been seen before. When a page is loaded, - * information about all the characters on that page is stored, not just - * for the single character in question. - * - *------------------------------------------------------------------------- - */ - -static void -FontMapInsert( - SubFont *subFontPtr, /* Contains font mapping cache to be - * updated. */ - int ch) /* Character to be added to cache. */ -{ - int row, bitOffset; - - row = ch >> FONTMAP_SHIFT; - if (subFontPtr->fontMap[row] == NULL) { - FontMapLoadPage(subFontPtr, row); - } - bitOffset = ch & (FONTMAP_BITSPERPAGE - 1); - subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7); -} - -/* - *------------------------------------------------------------------------- - * - * FontMapLoadPage -- - * - * Load information about all the characters on a given page. This - * information consists of one bit per character that indicates whether - * the associated HFONT can (1) or cannot (0) display the characters on - * the page. - * - * Results: - * None. - * - * Side effects: - * Mempry allocated. - * - *------------------------------------------------------------------------- - */ - -static void -FontMapLoadPage( - SubFont *subFontPtr, /* Contains font mapping cache to be - * updated. */ - int row) /* Index of the page to be loaded into the - * cache. */ -{ - FontFamily *familyPtr; - Tcl_Encoding encoding; - char src[XMaxTransChars], buf[16]; - USHORT *startCount, *endCount; - int i, j, bitOffset, end, segCount; - - subFontPtr->fontMap[row] = ckalloc(FONTMAP_BITSPERPAGE / 8); - memset(subFontPtr->fontMap[row], 0, FONTMAP_BITSPERPAGE / 8); - - familyPtr = subFontPtr->familyPtr; - encoding = familyPtr->encoding; - - if (familyPtr->encoding == TkWinGetUnicodeEncoding()) { - /* - * Font is Unicode. Few fonts are going to have all characters, so - * examine the TrueType character existence metrics to determine what - * characters actually exist in this font. - */ - - segCount = familyPtr->segCount; - startCount = familyPtr->startCount; - endCount = familyPtr->endCount; - - j = 0; - end = (row + 1) << FONTMAP_SHIFT; - for (i = row << FONTMAP_SHIFT; i < end; i++) { - for ( ; j < segCount; j++) { - if (endCount[j] >= i) { - if (startCount[j] <= i) { - bitOffset = i & (FONTMAP_BITSPERPAGE - 1); - subFontPtr->fontMap[row][bitOffset >> 3] |= - 1 << (bitOffset & 7); - } - break; - } - } - } - } else if (familyPtr->isSymbolFont) { - /* - * Assume that a symbol font with a known encoding has all the - * characters that its encoding claims it supports. - * - * The test for "encoding == unicodeEncoding" must occur before this - * case, to catch all symbol fonts (such as {Comic Sans MS} or - * Wingdings) for which we don't have encoding information; those - * symbol fonts are treated as if they were in the Unicode encoding - * and their symbolic character existence metrics are treated as if - * they were Unicode character existence metrics. This way, although - * we don't know the proper Unicode -> symbol font mapping, we can - * install the symbol font as the base font and access its glyphs. - */ - - end = (row + 1) << FONTMAP_SHIFT; - for (i = row << FONTMAP_SHIFT; i < end; i++) { - if (Tcl_UtfToExternal(NULL, encoding, src, - Tcl_UniCharToUtf(i, src), TCL_ENCODING_STOPONERROR, NULL, - buf, sizeof(buf), NULL, NULL, NULL) != TCL_OK) { - continue; - } - bitOffset = i & (FONTMAP_BITSPERPAGE - 1); - subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7); - } - } -} - -/* - *--------------------------------------------------------------------------- - * - * CanUseFallbackWithAliases -- - * - * Helper function for FindSubFontForChar. Determine if the specified - * face name (or an alias of the specified face name) can be used to - * construct a screen font that can display the given character. - * - * Results: - * See CanUseFallback(). - * - * Side effects: - * If the name and/or one of its aliases was rejected, the rejected - * string is recorded in nameTriedPtr so that it won't be tried again. - * - *--------------------------------------------------------------------------- - */ - -static SubFont * -CanUseFallbackWithAliases( - HDC hdc, /* HDC in which font can be selected. */ - WinFont *fontPtr, /* The font object that will own the new - * screen font. */ - const char *faceName, /* Desired face name for new screen font. */ - int ch, /* The Unicode character that the new screen - * font must be able to display. */ - Tcl_DString *nameTriedPtr, /* Records face names that have already been - * tried. It is possible for the same face - * name to be queried multiple times when - * trying to find a suitable screen font. */ - SubFont **subFontPtrPtr) /* Variable to fixup if we reallocate the - * array of subfonts. */ -{ - int i; - const char *const *aliases; - SubFont *subFontPtr; - - if (SeenName(faceName, nameTriedPtr) == 0) { - subFontPtr = CanUseFallback(hdc, fontPtr, faceName, ch, subFontPtrPtr); - if (subFontPtr != NULL) { - return subFontPtr; - } - } - aliases = TkFontGetAliasList(faceName); - if (aliases != NULL) { - for (i = 0; aliases[i] != NULL; i++) { - if (SeenName(aliases[i], nameTriedPtr) == 0) { - subFontPtr = CanUseFallback(hdc, fontPtr, aliases[i], ch, - subFontPtrPtr); - if (subFontPtr != NULL) { - return subFontPtr; - } - } - } - } - return NULL; -} - -/* - *--------------------------------------------------------------------------- - * - * SeenName -- - * - * Used to determine we have already tried and rejected the given face - * name when looking for a screen font that can support some Unicode - * character. - * - * Results: - * The return value is 0 if this face name has not already been seen, - * non-zero otherwise. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -static int -SeenName( - const char *name, /* The name to check. */ - Tcl_DString *dsPtr) /* Contains names that have already been - * seen. */ -{ - const char *seen, *end; - - seen = Tcl_DStringValue(dsPtr); - end = seen + Tcl_DStringLength(dsPtr); - while (seen < end) { - if (strcasecmp(seen, name) == 0) { - return 1; - } - seen += strlen(seen) + 1; - } - Tcl_DStringAppend(dsPtr, name, (int) (strlen(name) + 1)); - return 0; -} - -/* - *------------------------------------------------------------------------- - * - * CanUseFallback -- - * - * If the specified screen font has not already been loaded into the font - * object, determine if it can display the given character. - * - * Results: - * The return value is a pointer to a newly allocated SubFont, owned by - * the font object. This SubFont can be used to display the given - * character. The SubFont represents the screen font with the base set of - * font attributes from the font object, but using the specified font - * name. NULL is returned if the font object already holds a reference to - * the specified physical font or if the specified physical font cannot - * display the given character. - * - * Side effects: - * The font object's subFontArray is updated to contain a reference to - * the newly allocated SubFont. - * - *------------------------------------------------------------------------- - */ - -static SubFont * -CanUseFallback( - HDC hdc, /* HDC in which font can be selected. */ - WinFont *fontPtr, /* The font object that will own the new - * screen font. */ - const char *faceName, /* Desired face name for new screen font. */ - int ch, /* The Unicode character that the new screen - * font must be able to display. */ - SubFont **subFontPtrPtr) /* Variable to fix-up if we realloc the array - * of subfonts. */ -{ - int i; - HFONT hFont; - SubFont subFont; - - if (FamilyExists(hdc, faceName) == 0) { - return NULL; - } - - /* - * Skip all fonts we've already used. - */ - - for (i = 0; i < fontPtr->numSubFonts; i++) { - if (faceName == fontPtr->subFontArray[i].familyPtr->faceName) { - return NULL; - } - } - - /* - * Load this font and see if it has the desired character. - */ - - hFont = GetScreenFont(&fontPtr->font.fa, faceName, fontPtr->pixelSize, - 0.0); - InitSubFont(hdc, hFont, 0, &subFont); - if (((ch < 256) && (subFont.familyPtr->isSymbolFont)) - || (FontMapLookup(&subFont, ch) == 0)) { - /* - * Don't use a symbol font as a fallback font for characters below - * 256. - */ - - ReleaseSubFont(&subFont); - return NULL; - } - - if (fontPtr->numSubFonts >= SUBFONT_SPACE) { - SubFont *newPtr; - - newPtr = ckalloc(sizeof(SubFont) * (fontPtr->numSubFonts + 1)); - memcpy(newPtr, fontPtr->subFontArray, - fontPtr->numSubFonts * sizeof(SubFont)); - if (fontPtr->subFontArray != fontPtr->staticSubFonts) { - ckfree(fontPtr->subFontArray); - } - - /* - * Fix up the variable pointed to by subFontPtrPtr so it still points - * into the live array. [Bug 618872] - */ - - *subFontPtrPtr = newPtr + (*subFontPtrPtr - fontPtr->subFontArray); - fontPtr->subFontArray = newPtr; - } - fontPtr->subFontArray[fontPtr->numSubFonts] = subFont; - fontPtr->numSubFonts++; - return &fontPtr->subFontArray[fontPtr->numSubFonts - 1]; -} - -/* - *--------------------------------------------------------------------------- - * - * GetScreenFont -- - * - * Given the name and other attributes, construct an HFONT. This is where - * all the alias and fallback substitution bottoms out. - * - * Results: - * The screen font that corresponds to the attributes. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -static HFONT -GetScreenFont( - const TkFontAttributes *faPtr, - /* Desired font attributes for new HFONT. */ - const char *faceName, /* Overrides font family specified in font - * attributes. */ - int pixelSize, /* Overrides size specified in font - * attributes. */ - double angle) /* What is the desired orientation of the - * font. */ -{ - Tcl_DString ds; - HFONT hFont; - LOGFONT lf; - - memset(&lf, 0, sizeof(lf)); - lf.lfHeight = -pixelSize; - lf.lfWidth = 0; - lf.lfEscapement = ROUND16(angle * 10); - lf.lfOrientation = ROUND16(angle * 10); - lf.lfWeight = (faPtr->weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD; - lf.lfItalic = faPtr->slant; - lf.lfUnderline = faPtr->underline; - lf.lfStrikeOut = faPtr->overstrike; - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfOutPrecision = OUT_TT_PRECIS; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; - lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; - - Tcl_UtfToExternalDString(systemEncoding, faceName, -1, &ds); - _tcsncpy(lf.lfFaceName, (TCHAR *)Tcl_DStringValue(&ds), LF_FACESIZE-1); - Tcl_DStringFree(&ds); - lf.lfFaceName[LF_FACESIZE-1] = 0; - hFont = CreateFontIndirect(&lf); - return hFont; -} - -/* - *------------------------------------------------------------------------- - * - * FamilyExists, FamilyOrAliasExists, WinFontExistsProc -- - * - * Determines if any physical screen font exists on the system with the - * given family name. If the family exists, then it should be possible to - * construct some physical screen font with that family name. - * - * Results: - * The return value is 0 if the specified font family does not exist, - * non-zero otherwise. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -FamilyExists( - HDC hdc, /* HDC in which font family will be used. */ - const char *faceName) /* Font family to query. */ -{ - int result; - Tcl_DString faceString; - - /* - * Just immediately rule out the following fonts, because they look so - * ugly on windows. The caller's fallback mechanism will cause the - * corresponding appropriate TrueType fonts to be selected. - */ - - if (strcasecmp(faceName, "Courier") == 0) { - return 0; - } - if (strcasecmp(faceName, "Times") == 0) { - return 0; - } - if (strcasecmp(faceName, "Helvetica") == 0) { - return 0; - } - - Tcl_UtfToExternalDString(systemEncoding, faceName, -1, &faceString); - - /* - * If the family exists, WinFontExistProc() will be called and - * EnumFontFamilies() will return whatever WinFontExistProc() returns. If - * the family doesn't exist, EnumFontFamilies() will just return a - * non-zero value. - */ - - result = EnumFontFamilies(hdc, (TCHAR*) Tcl_DStringValue(&faceString), - (FONTENUMPROC) WinFontExistProc, 0); - Tcl_DStringFree(&faceString); - return (result == 0); -} - -static const char * -FamilyOrAliasExists( - HDC hdc, - const char *faceName) -{ - const char *const *aliases; - int i; - - if (FamilyExists(hdc, faceName) != 0) { - return faceName; - } - aliases = TkFontGetAliasList(faceName); - if (aliases != NULL) { - for (i = 0; aliases[i] != NULL; i++) { - if (FamilyExists(hdc, aliases[i]) != 0) { - return aliases[i]; - } - } - } - return NULL; -} - -static int CALLBACK -WinFontExistProc( - ENUMLOGFONT *lfPtr, /* Logical-font data. */ - NEWTEXTMETRIC *tmPtr, /* Physical-font data (not used). */ - int fontType, /* Type of font (not used). */ - LPARAM lParam) /* EnumFontData to hold result. */ -{ - return 0; -} - -/* - * The following data structures are used when querying a TrueType font file - * to determine which characters the font supports. - */ - -#pragma pack(1) /* Structures are byte aligned in file. */ - -#define CMAPHEX 0x636d6170 /* Key for character map resource. */ - -typedef struct CMAPTABLE { - USHORT version; /* Table version number (0). */ - USHORT numTables; /* Number of encoding tables following. */ -} CMAPTABLE; - -typedef struct ENCODINGTABLE { - USHORT platform; /* Platform for which data is targeted. 3 - * means data is for Windows. */ - USHORT encoding; /* How characters in font are encoded. 1 means - * that the following subtable is keyed based - * on Unicode. */ - ULONG offset; /* Byte offset from beginning of CMAPTABLE to - * the subtable for this encoding. */ -} ENCODINGTABLE; - -typedef struct ANYTABLE { - USHORT format; /* Format number. */ - USHORT length; /* The actual length in bytes of this - * subtable. */ - USHORT version; /* Version number (starts at 0). */ -} ANYTABLE; - -typedef struct BYTETABLE { - USHORT format; /* Format number is set to 0. */ - USHORT length; /* The actual length in bytes of this - * subtable. */ - USHORT version; /* Version number (starts at 0). */ - BYTE glyphIdArray[256]; /* Array that maps up to 256 single-byte char - * codes to glyph indices. */ -} BYTETABLE; - -typedef struct SUBHEADER { - USHORT firstCode; /* First valid low byte for subHeader. */ - USHORT entryCount; /* Number valid low bytes for subHeader. */ - SHORT idDelta; /* Constant adder to get base glyph index. */ - USHORT idRangeOffset; /* Byte offset from here to appropriate - * glyphIndexArray. */ -} SUBHEADER; - -typedef struct HIBYTETABLE { - USHORT format; /* Format number is set to 2. */ - USHORT length; /* The actual length in bytes of this - * subtable. */ - USHORT version; /* Version number (starts at 0). */ - USHORT subHeaderKeys[256]; /* Maps high bytes to subHeaders: value is - * subHeader index * 8. */ -#if 0 - SUBHEADER subHeaders[]; /* Variable-length array of SUBHEADERs. */ - USHORT glyphIndexArray[]; /* Variable-length array containing subarrays - * used for mapping the low byte of 2-byte - * characters. */ -#endif -} HIBYTETABLE; - -typedef struct SEGMENTTABLE { - USHORT format; /* Format number is set to 4. */ - USHORT length; /* The actual length in bytes of this - * subtable. */ - USHORT version; /* Version number (starts at 0). */ - USHORT segCountX2; /* 2 x segCount. */ - USHORT searchRange; /* 2 x (2**floor(log2(segCount))). */ - USHORT entrySelector; /* log2(searchRange/2). */ - USHORT rangeShift; /* 2 x segCount - searchRange. */ -#if 0 - USHORT endCount[segCount] /* End characterCode for each segment. */ - USHORT reservedPad; /* Set to 0. */ - USHORT startCount[segCount];/* Start character code for each segment. */ - USHORT idDelta[segCount]; /* Delta for all character in segment. */ - USHORT idRangeOffset[segCount]; /* Offsets into glyphIdArray or 0. */ - USHORT glyphIdArray[] /* Glyph index array. */ -#endif -} SEGMENTTABLE; - -typedef struct TRIMMEDTABLE { - USHORT format; /* Format number is set to 6. */ - USHORT length; /* The actual length in bytes of this - * subtable. */ - USHORT version; /* Version number (starts at 0). */ - USHORT firstCode; /* First character code of subrange. */ - USHORT entryCount; /* Number of character codes in subrange. */ -#if 0 - USHORT glyphIdArray[]; /* Array of glyph index values for - * character codes in the range. */ -#endif -} TRIMMEDTABLE; - -typedef union SUBTABLE { - ANYTABLE any; - BYTETABLE byte; - HIBYTETABLE hiByte; - SEGMENTTABLE segment; - TRIMMEDTABLE trimmed; -} SUBTABLE; - -#pragma pack() - -/* - *------------------------------------------------------------------------- - * - * LoadFontRanges -- - * - * Given an HFONT, get the information about the characters that this - * font can display. - * - * Results: - * If the font has no Unicode character information, the return value is - * 0 and *startCountPtr and *endCountPtr are filled with NULL. Otherwise, - * *startCountPtr and *endCountPtr are set to pointers to arrays of - * TrueType character existence information and the return value is the - * length of the arrays (the two arrays are always the same length as - * each other). - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -LoadFontRanges( - HDC hdc, /* HDC into which font can be selected. */ - HFONT hFont, /* HFONT to query. */ - USHORT **startCountPtr, /* Filled with malloced pointer to character - * range information. */ - USHORT **endCountPtr, /* Filled with malloced pointer to character - * range information. */ - int *symbolPtr) - { - int n, i, swapped, offset, cbData, segCount; - DWORD cmapKey; - USHORT *startCount, *endCount; - CMAPTABLE cmapTable; - ENCODINGTABLE encTable; - SUBTABLE subTable; - char *s; - - segCount = 0; - startCount = NULL; - endCount = NULL; - *symbolPtr = 0; - - hFont = SelectObject(hdc, hFont); - - i = 0; - s = (char *) &i; - *s = '\1'; - swapped = 0; - - if (i == 1) { - swapped = 1; - } - - cmapKey = CMAPHEX; - if (swapped) { - SwapLong(&cmapKey); - } - - n = GetFontData(hdc, cmapKey, 0, &cmapTable, sizeof(cmapTable)); - if (n != (int) GDI_ERROR) { - if (swapped) { - SwapShort(&cmapTable.numTables); - } - for (i = 0; i < cmapTable.numTables; i++) { - offset = sizeof(cmapTable) + i * sizeof(encTable); - GetFontData(hdc, cmapKey, (DWORD) offset, &encTable, - sizeof(encTable)); - if (swapped) { - SwapShort(&encTable.platform); - SwapShort(&encTable.encoding); - SwapLong(&encTable.offset); - } - if (encTable.platform != 3) { - /* - * Not Microsoft encoding. - */ - - continue; - } - if (encTable.encoding == 0) { - *symbolPtr = 1; - } else if (encTable.encoding != 1) { - continue; - } - - GetFontData(hdc, cmapKey, (DWORD) encTable.offset, &subTable, - sizeof(subTable)); - if (swapped) { - SwapShort(&subTable.any.format); - } - if (subTable.any.format == 4) { - if (swapped) { - SwapShort(&subTable.segment.segCountX2); - } - segCount = subTable.segment.segCountX2 / 2; - cbData = segCount * sizeof(USHORT); - - startCount = ckalloc(cbData); - endCount = ckalloc(cbData); - - offset = encTable.offset + sizeof(subTable.segment); - GetFontData(hdc, cmapKey, (DWORD) offset, endCount, cbData); - offset += cbData + sizeof(USHORT); - GetFontData(hdc, cmapKey, (DWORD) offset, startCount, cbData); - if (swapped) { - for (i = 0; i < segCount; i++) { - SwapShort(&endCount[i]); - SwapShort(&startCount[i]); - } - } - if (*symbolPtr != 0) { - /* - * Empirically determined: When a symbol font is loaded, - * the character existence metrics obtained from the - * system are mildly wrong. If the real range of the - * symbol font is from 0020 to 00FE, then the metrics are - * reported as F020 to F0FE. When we load a symbol font, - * we must fix the character existence metrics. - * - * Symbol fonts should only use the symbol encoding for - * 8-bit characters [note Bug: 2406] - */ - - for (i = 0; i < segCount; i++) { - if (((startCount[i] & 0xff00) == 0xf000) - && ((endCount[i] & 0xff00) == 0xf000)) { - startCount[i] &= 0xff; - endCount[i] &= 0xff; - } - } - } - } - } - } else if (GetTextCharset(hdc) == ANSI_CHARSET) { - /* - * Bitmap font. We should also support ranges for the other *_CHARSET - * values. - */ - - segCount = 1; - cbData = segCount * sizeof(USHORT); - startCount = ckalloc(cbData); - endCount = ckalloc(cbData); - startCount[0] = 0x0000; - endCount[0] = 0x00ff; - } - SelectObject(hdc, hFont); - - *startCountPtr = startCount; - *endCountPtr = endCount; - return segCount; -} - -/* - *------------------------------------------------------------------------- - * - * SwapShort, SwapLong -- - * - * Helper functions to convert the data loaded from TrueType font files - * to Intel byte ordering. - * - * Results: - * Bytes of input value are swapped and stored back in argument. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static inline void -SwapShort( - PUSHORT p) -{ - *p = (SHORT)(HIBYTE(*p) + (LOBYTE(*p) << 8)); -} - -static inline void -SwapLong( - PULONG p) -{ - ULONG temp; - - temp = (LONG) ((BYTE) *p); - temp <<= 8; - *p >>=8; - - temp += (LONG) ((BYTE) *p); - temp <<= 8; - *p >>=8; - - temp += (LONG) ((BYTE) *p); - temp <<= 8; - *p >>=8; - - temp += (LONG) ((BYTE) *p); - *p = temp; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinImage.c b/tk8.6/win/tkWinImage.c deleted file mode 100644 index d61b84a..0000000 --- a/tk8.6/win/tkWinImage.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * tkWinImage.c -- - * - * This file contains routines for manipulation full-color images. - * - * Copyright (c) 1995 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - -static int DestroyImage(XImage* data); -static unsigned long ImageGetPixel(XImage *image, int x, int y); -static int PutPixel(XImage *image, int x, int y, - unsigned long pixel); - -/* - *---------------------------------------------------------------------- - * - * DestroyImage -- - * - * This is a trivial wrapper around ckfree to make it possible to pass - * ckfree as a pointer. - * - * Results: - * None. - * - * Side effects: - * Deallocates the image. - * - *---------------------------------------------------------------------- - */ - -static int -DestroyImage( - XImage *imagePtr) /* Image to free. */ -{ - if (imagePtr) { - if (imagePtr->data) { - ckfree(imagePtr->data); - } - ckfree(imagePtr); - } - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * ImageGetPixel -- - * - * Get a single pixel from an image. - * - * Results: - * Returns the 32 bit pixel value. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static unsigned long -ImageGetPixel( - XImage *image, - int x, int y) -{ - unsigned long pixel = 0; - unsigned char *srcPtr = (unsigned char *) &(image->data[(y * image->bytes_per_line) - + ((x * image->bits_per_pixel) / NBBY)]); - - switch (image->bits_per_pixel) { - case 32: - case 24: - pixel = RGB(srcPtr[2], srcPtr[1], srcPtr[0]); - break; - case 16: - pixel = RGB(((((WORD*)srcPtr)[0]) >> 7) & 0xf8, - ((((WORD*)srcPtr)[0]) >> 2) & 0xf8, - ((((WORD*)srcPtr)[0]) << 3) & 0xf8); - break; - case 8: - pixel = srcPtr[0]; - break; - case 4: - pixel = ((x%2) ? (*srcPtr) : ((*srcPtr) >> 4)) & 0x0f; - break; - case 1: - pixel = ((*srcPtr) & (0x80 >> (x%8))) ? 1 : 0; - break; - } - return pixel; -} - -/* - *---------------------------------------------------------------------- - * - * PutPixel -- - * - * Set a single pixel in an image. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -PutPixel( - XImage *image, - int x, int y, - unsigned long pixel) -{ - unsigned char *destPtr = (unsigned char *) &(image->data[(y * image->bytes_per_line) - + ((x * image->bits_per_pixel) / NBBY)]); - - switch (image->bits_per_pixel) { - case 32: - /* - * Pixel is DWORD: 0x00BBGGRR - */ - - destPtr[3] = 0; - case 24: - /* - * Pixel is triplet: 0xBBGGRR. - */ - - destPtr[0] = (unsigned char) GetBValue(pixel); - destPtr[1] = (unsigned char) GetGValue(pixel); - destPtr[2] = (unsigned char) GetRValue(pixel); - break; - case 16: - /* - * Pixel is WORD: 5-5-5 (R-G-B) - */ - - (*(WORD*)destPtr) = ((GetRValue(pixel) & 0xf8) << 7) - | ((GetGValue(pixel) & 0xf8) <<2) - | ((GetBValue(pixel) & 0xf8) >> 3); - break; - case 8: - /* - * Pixel is 8-bit index into color table. - */ - - (*destPtr) = (unsigned char) pixel; - break; - case 4: - /* - * Pixel is 4-bit index in MSBFirst order. - */ - - if (x%2) { - (*destPtr) = (unsigned char) (((*destPtr) & 0xf0) - | (pixel & 0x0f)); - } else { - (*destPtr) = (unsigned char) (((*destPtr) & 0x0f) - | ((pixel << 4) & 0xf0)); - } - break; - case 1: { - /* - * Pixel is bit in MSBFirst order. - */ - - int mask = (0x80 >> (x%8)); - - if (pixel) { - (*destPtr) |= mask; - } else { - (*destPtr) &= ~mask; - } - break; - } - } - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * XCreateImage -- - * - * Allocates storage for a new XImage. - * - * Results: - * Returns a newly allocated XImage. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -XImage * -XCreateImage( - Display *display, - Visual *visual, - unsigned int depth, - int format, - int offset, - char *data, - unsigned int width, - unsigned int height, - int bitmap_pad, - int bytes_per_line) -{ - XImage* imagePtr = ckalloc(sizeof(XImage)); - imagePtr->width = width; - imagePtr->height = height; - imagePtr->xoffset = offset; - imagePtr->format = format; - imagePtr->data = data; - imagePtr->byte_order = LSBFirst; - imagePtr->bitmap_unit = 8; - imagePtr->bitmap_bit_order = LSBFirst; - imagePtr->bitmap_pad = bitmap_pad; - imagePtr->bits_per_pixel = depth; - imagePtr->depth = depth; - - /* - * Under Windows, bitmap_pad must be on an LONG data-type boundary. - */ - -#define LONGBITS (sizeof(LONG) * 8) - - bitmap_pad = (bitmap_pad + LONGBITS - 1) / LONGBITS * LONGBITS; - - /* - * Round to the nearest bitmap_pad boundary. - */ - - if (bytes_per_line) { - imagePtr->bytes_per_line = bytes_per_line; - } else { - imagePtr->bytes_per_line = (((depth * width) - + (bitmap_pad - 1)) >> 3) & ~((bitmap_pad >> 3) - 1); - } - - imagePtr->red_mask = 0; - imagePtr->green_mask = 0; - imagePtr->blue_mask = 0; - - imagePtr->f.put_pixel = PutPixel; - imagePtr->f.get_pixel = ImageGetPixel; - imagePtr->f.destroy_image = DestroyImage; - imagePtr->f.create_image = NULL; - imagePtr->f.sub_image = NULL; - imagePtr->f.add_pixel = NULL; - - return imagePtr; -} - -/* - *---------------------------------------------------------------------- - * - * XGetImageZPixmap -- - * - * This function copies data from a pixmap or window into an XImage. This - * handles the ZPixmap case only. - * - * Results: - * Returns a newly allocated image containing the data from the given - * rectangle of the given drawable. - * - * Side effects: - * None. - * - * This procedure is adapted from the XGetImage implementation in TkNT. That - * code is Copyright (c) 1994 Software Research Associates, Inc. - * - *---------------------------------------------------------------------- - */ - -static XImage * -XGetImageZPixmap( - Display *display, - Drawable d, - int x, int y, - unsigned int width, unsigned int height, - unsigned long plane_mask, - int format) -{ - TkWinDrawable *twdPtr = (TkWinDrawable *)d; - XImage *ret_image; - HDC hdc, hdcMem; - HBITMAP hbmp, hbmpPrev; - BITMAPINFO *bmInfo = NULL; - HPALETTE hPal, hPalPrev1 = 0, hPalPrev2 = 0; - int size; - unsigned int n; - unsigned int depth; - unsigned char *data; - TkWinDCState state; - BOOL ret; - - if (format != ZPixmap) { - TkpDisplayWarning("Only ZPixmap types are implemented", - "XGetImageZPixmap Failure"); - return NULL; - } - - hdc = TkWinGetDrawableDC(display, d, &state); - - /* - * Need to do a Blt operation to copy into a new bitmap. - */ - - hbmp = CreateCompatibleBitmap(hdc, (int) width, (int) height); - hdcMem = CreateCompatibleDC(hdc); - hbmpPrev = SelectObject(hdcMem, hbmp); - hPal = state.palette; - if (hPal) { - hPalPrev1 = SelectPalette(hdcMem, hPal, FALSE); - n = RealizePalette(hdcMem); - if (n > 0) { - UpdateColors(hdcMem); - } - hPalPrev2 = SelectPalette(hdc, hPal, FALSE); - n = RealizePalette(hdc); - if (n > 0) { - UpdateColors(hdc); - } - } - - ret = BitBlt(hdcMem, 0, 0, (int) width, (int) height, hdc, x, y, SRCCOPY); - if (hPal) { - SelectPalette(hdc, hPalPrev2, FALSE); - } - SelectObject(hdcMem, hbmpPrev); - TkWinReleaseDrawableDC(d, hdc, &state); - if (ret == FALSE) { - ret_image = NULL; - goto cleanup; - } - if (twdPtr->type == TWD_WINDOW) { - depth = Tk_Depth((Tk_Window) twdPtr->window.winPtr); - } else { - depth = twdPtr->bitmap.depth; - } - - size = sizeof(BITMAPINFO); - if (depth <= 8) { - size += sizeof(unsigned short) * (1 << depth); - } - bmInfo = ckalloc(size); - - bmInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmInfo->bmiHeader.biWidth = width; - bmInfo->bmiHeader.biHeight = -(int) height; - bmInfo->bmiHeader.biPlanes = 1; - bmInfo->bmiHeader.biBitCount = depth; - bmInfo->bmiHeader.biCompression = BI_RGB; - bmInfo->bmiHeader.biSizeImage = 0; - bmInfo->bmiHeader.biXPelsPerMeter = 0; - bmInfo->bmiHeader.biYPelsPerMeter = 0; - bmInfo->bmiHeader.biClrUsed = 0; - bmInfo->bmiHeader.biClrImportant = 0; - - if (depth == 1) { - unsigned char *p, *pend; - - GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS); - data = ckalloc(bmInfo->bmiHeader.biSizeImage); - if (!data) { - /* printf("Failed to allocate data area for XImage.\n"); */ - ret_image = NULL; - goto cleanup; - } - ret_image = XCreateImage(display, NULL, depth, ZPixmap, 0, (char *) data, - width, height, 32, (int) ((width + 31) >> 3) & ~1); - if (ret_image == NULL) { - ckfree(data); - goto cleanup; - } - - /* - * Get the BITMAP info into the Image. - */ - - if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo, - DIB_PAL_COLORS) == 0) { - ckfree(ret_image->data); - ckfree(ret_image); - ret_image = NULL; - goto cleanup; - } - p = data; - pend = data + bmInfo->bmiHeader.biSizeImage; - while (p < pend) { - *p = ~*p; - p++; - } - } else if (depth == 8) { - unsigned short *palette; - unsigned int i; - unsigned char *p; - - GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS); - data = ckalloc(bmInfo->bmiHeader.biSizeImage); - if (!data) { - /* printf("Failed to allocate data area for XImage.\n"); */ - ret_image = NULL; - goto cleanup; - } - ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, (char *) data, - width, height, 8, (int) width); - if (ret_image == NULL) { - ckfree(data); - goto cleanup; - } - - /* - * Get the BITMAP info into the Image. - */ - - if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo, - DIB_PAL_COLORS) == 0) { - ckfree(ret_image->data); - ckfree(ret_image); - ret_image = NULL; - goto cleanup; - } - p = data; - palette = (unsigned short *) bmInfo->bmiColors; - for (i = 0; i < bmInfo->bmiHeader.biSizeImage; i++, p++) { - *p = (unsigned char) palette[*p]; - } - } else if (depth == 16) { - GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS); - data = ckalloc(bmInfo->bmiHeader.biSizeImage); - if (!data) { - /* printf("Failed to allocate data area for XImage.\n"); */ - ret_image = NULL; - goto cleanup; - } - ret_image = XCreateImage(display, NULL, 16, ZPixmap, 0, (char *) data, - width, height, 16, 0 /* will be calc'ed from bitmap_pad */); - if (ret_image == NULL) { - ckfree(data); - goto cleanup; - } - - /* - * Get the BITMAP info directly into the Image. - */ - - if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo, - DIB_RGB_COLORS) == 0) { - ckfree(ret_image->data); - ckfree(ret_image); - ret_image = NULL; - goto cleanup; - } - } else { - GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS); - data = ckalloc(width * height * 4); - if (!data) { - /* printf("Failed to allocate data area for XImage.\n"); */ - ret_image = NULL; - goto cleanup; - } - ret_image = XCreateImage(display, NULL, 32, ZPixmap, 0, (char *) data, - width, height, 0, (int) width * 4); - if (ret_image == NULL) { - ckfree(data); - goto cleanup; - } - - if (depth <= 24) { - /* - * This used to handle 16 and 24 bpp, but now just handles 24. It - * can likely be optimized for that. -- hobbs - */ - - unsigned char *smallBitData, *smallBitBase, *bigBitData; - unsigned int byte_width, h, w; - - byte_width = ((width * 3 + 3) & ~(unsigned)3); - smallBitBase = ckalloc(byte_width * height); - if (!smallBitBase) { - ckfree(ret_image->data); - ckfree(ret_image); - ret_image = NULL; - goto cleanup; - } - smallBitData = smallBitBase; - - /* - * Get the BITMAP info into the Image. - */ - - if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo, - DIB_RGB_COLORS) == 0) { - ckfree(ret_image->data); - ckfree(ret_image); - ckfree(smallBitBase); - ret_image = NULL; - goto cleanup; - } - - /* - * Copy the 24 Bit Pixmap to a 32-Bit one. - */ - - for (h = 0; h < height; h++) { - bigBitData = (unsigned char *) ret_image->data + h * ret_image->bytes_per_line; - smallBitData = smallBitBase + h * byte_width; - - for (w = 0; w < width; w++) { - *bigBitData++ = ((*smallBitData++)); - *bigBitData++ = ((*smallBitData++)); - *bigBitData++ = ((*smallBitData++)); - *bigBitData++ = 0; - } - } - - /* - * Free the Device contexts, and the Bitmap. - */ - - ckfree(smallBitBase); - } else { - /* - * Get the BITMAP info directly into the Image. - */ - - if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo, - DIB_RGB_COLORS) == 0) { - ckfree(ret_image->data); - ckfree(ret_image); - ret_image = NULL; - goto cleanup; - } - } - } - - cleanup: - if (bmInfo) { - ckfree(bmInfo); - } - if (hPal) { - SelectPalette(hdcMem, hPalPrev1, FALSE); - } - DeleteDC(hdcMem); - DeleteObject(hbmp); - - return ret_image; -} - -/* - *---------------------------------------------------------------------- - * - * XGetImage -- - * - * This function copies data from a pixmap or window into an XImage. - * - * Results: - * Returns a newly allocated image containing the data from the given - * rectangle of the given drawable. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -XImage * -XGetImage( - Display* display, - Drawable d, - int x, int y, - unsigned int width, unsigned int height, - unsigned long plane_mask, - int format) -{ - TkWinDrawable *twdPtr = (TkWinDrawable *)d; - XImage *imagePtr; - HDC dc; - - display->request++; - - if (twdPtr == NULL) { - /* - * Avoid unmapped windows or bad drawables - */ - - return NULL; - } - - if (twdPtr->type != TWD_BITMAP) { - /* - * This handles TWD_WINDOW or TWD_WINDC, always creating a 32bit - * image. If the window being copied isn't visible (unmapped or - * obscured), we quietly stop copying (no user error). The user will - * see black where the widget should be. This branch is likely - * followed in favor of XGetImageZPixmap as postscript printed widgets - * require RGB data. - */ - - TkWinDCState state; - unsigned int xx, yy, size; - COLORREF pixel; - - dc = TkWinGetDrawableDC(display, d, &state); - - imagePtr = XCreateImage(display, NULL, 32, format, 0, NULL, - width, height, 32, 0); - size = imagePtr->bytes_per_line * imagePtr->height; - imagePtr->data = ckalloc(size); - ZeroMemory(imagePtr->data, size); - - for (yy = 0; yy < height; yy++) { - for (xx = 0; xx < width; xx++) { - pixel = GetPixel(dc, x+(int)xx, y+(int)yy); - if (pixel == CLR_INVALID) { - break; - } - PutPixel(imagePtr, (int) xx, (int) yy, pixel); - } - } - - TkWinReleaseDrawableDC(d, dc, &state); - } else if (format == ZPixmap) { - /* - * This actually handles most TWD_WINDOW requests, but it varies from - * the above in that it really does a screen capture of an area, which - * is consistent with the Unix behavior, but does not appear to handle - * all bit depths correctly. -- hobbs - */ - - imagePtr = XGetImageZPixmap(display, d, x, y, - width, height, plane_mask, format); - } else { - const char *errMsg = NULL; - char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)]; - BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf; - - if (twdPtr->bitmap.handle == NULL) { - errMsg = "XGetImage: not implemented for empty bitmap handles"; - } else if (format != XYPixmap) { - errMsg = "XGetImage: not implemented for format != XYPixmap"; - } else if (plane_mask != 1) { - errMsg = "XGetImage: not implemented for plane_mask != 1"; - } - if (errMsg != NULL) { - /* - * Do a soft warning for the unsupported XGetImage types. - */ - - TkpDisplayWarning(errMsg, "XGetImage Failure"); - return NULL; - } - - imagePtr = XCreateImage(display, NULL, 1, XYBitmap, 0, NULL, - width, height, 32, 0); - imagePtr->data = ckalloc(imagePtr->bytes_per_line * imagePtr->height); - - dc = GetDC(NULL); - - GetDIBits(dc, twdPtr->bitmap.handle, 0, height, NULL, - infoPtr, DIB_RGB_COLORS); - - infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - infoPtr->bmiHeader.biWidth = width; - infoPtr->bmiHeader.biHeight = -(LONG)height; - infoPtr->bmiHeader.biPlanes = 1; - infoPtr->bmiHeader.biBitCount = 1; - infoPtr->bmiHeader.biCompression = BI_RGB; - infoPtr->bmiHeader.biSizeImage = 0; - infoPtr->bmiHeader.biXPelsPerMeter = 0; - infoPtr->bmiHeader.biYPelsPerMeter = 0; - infoPtr->bmiHeader.biClrUsed = 0; - infoPtr->bmiHeader.biClrImportant = 0; - - GetDIBits(dc, twdPtr->bitmap.handle, 0, height, imagePtr->data, - infoPtr, DIB_RGB_COLORS); - ReleaseDC(NULL, dc); - } - - return imagePtr; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinInit.c b/tk8.6/win/tkWinInit.c deleted file mode 100644 index 4c18399..0000000 --- a/tk8.6/win/tkWinInit.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * tkWinInit.c -- - * - * This file contains Windows-specific interpreter initialization - * functions. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - - -/* - *---------------------------------------------------------------------- - * - * TkpInit -- - * - * Performs Windows-specific interpreter initialization related to the - * tk_library variable. - * - * Results: - * A standard Tcl completion code (TCL_OK or TCL_ERROR). Also leaves - * information in the interp's result. - * - * Side effects: - * Sets "tk_library" Tcl variable, runs "tk.tcl" script. - * - *---------------------------------------------------------------------- - */ - -int -TkpInit( - Tcl_Interp *interp) -{ - /* - * This is necessary for static initialization, and is ok otherwise - * because TkWinXInit flips a static bit to do its work just once. - */ - - TkWinXInit(Tk_GetHINSTANCE()); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetAppName -- - * - * Retrieves the name of the current application from a platform specific - * location. For Windows, the application name is the root of the tail of - * the path contained in the tcl variable argv0. - * - * Results: - * Returns the application name in the given Tcl_DString. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkpGetAppName( - Tcl_Interp *interp, - Tcl_DString *namePtr) /* A previously initialized Tcl_DString. */ -{ - int argc, namelength; - const char **argv = NULL, *name, *p; - - name = Tcl_GetVar2(interp, "argv0", NULL, TCL_GLOBAL_ONLY); - namelength = -1; - if (name != NULL) { - Tcl_SplitPath(name, &argc, &argv); - if (argc > 0) { - name = argv[argc-1]; - p = strrchr(name, '.'); - if (p != NULL) { - namelength = p - name; - } - } else { - name = NULL; - } - } - if ((name == NULL) || (*name == 0)) { - name = "tk"; - namelength = -1; - } - Tcl_DStringAppend(namePtr, name, namelength); - if (argv != NULL) { - ckfree(argv); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpDisplayWarning -- - * - * This routines is called from Tk_Main to display warning messages that - * occur during startup. - * - * Results: - * None. - * - * Side effects: - * Displays a message box. - * - *---------------------------------------------------------------------- - */ - -void -TkpDisplayWarning( - const char *msg, /* Message to be displayed. */ - const char *title) /* Title of warning. */ -{ -#define TK_MAX_WARN_LEN 1024 - WCHAR titleString[TK_MAX_WARN_LEN]; - WCHAR *msgString; /* points to titleString, just after title, leaving space for ": " */ - int len; /* size of title, including terminating NULL */ - - /* If running on Cygwin and we have a stderr channel, use it. */ -#if !defined(STATIC_BUILD) - if (tclStubsPtr->reserved9) { - Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR); - if (errChannel) { - Tcl_WriteChars(errChannel, title, -1); - Tcl_WriteChars(errChannel, ": ", 2); - Tcl_WriteChars(errChannel, msg, -1); - Tcl_WriteChars(errChannel, "\n", 1); - return; - } - } -#endif /* !STATIC_BUILD */ - - len = MultiByteToWideChar(CP_UTF8, 0, title, -1, titleString, TK_MAX_WARN_LEN); - msgString = &titleString[len + 1]; - titleString[TK_MAX_WARN_LEN - 1] = L'\0'; - MultiByteToWideChar(CP_UTF8, 0, msg, -1, msgString, (TK_MAX_WARN_LEN - 1) - len); - /* - * Truncate MessageBox string if it is too long to not overflow the screen - * and cause possible oversized window error. - */ - if (titleString[TK_MAX_WARN_LEN - 1] != L'\0') { - memcpy(titleString + (TK_MAX_WARN_LEN - 5), L" ...", 5 * sizeof(WCHAR)); - } - if (IsDebuggerPresent()) { - titleString[len - 1] = L':'; - titleString[len] = L' '; - OutputDebugStringW(titleString); - } else { - titleString[len - 1] = L'\0'; - MessageBoxW(NULL, msgString, titleString, - MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL - | MB_SETFOREGROUND | MB_TOPMOST); - } -} - -/* - * ---------------------------------------------------------------------- - * - * 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; -#ifdef _UNICODE - Tcl_DString ds; -#endif - - 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 - Tcl_WinTCharToUtf(lpBuffer, (int)wcslen(lpBuffer) * sizeof (WCHAR), &ds); - errPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); - Tcl_DStringFree(&ds); -#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 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinInt.h b/tk8.6/win/tkWinInt.h deleted file mode 100644 index 0e2c844..0000000 --- a/tk8.6/win/tkWinInt.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * tkWinInt.h -- - * - * This file contains declarations that are shared among the - * Windows-specific parts of Tk, but aren't used by the rest of Tk. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-2000 by Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#ifndef _TKWININT -#define _TKWININT - -#ifndef _TKINT -#include "tkInt.h" -#endif - -/* - * Include platform specific public interfaces. - */ - -#ifndef _TKWIN -#include "tkWin.h" -#endif - -/* - * Define constants missing from older Win32 SDK header files. - */ - -#ifndef WS_EX_TOOLWINDOW -#define WS_EX_TOOLWINDOW 0x00000080L -#endif -#ifndef SPI_SETKEYBOARDCUES -#define SPI_SETKEYBOARDCUES 0x100B -#endif - -/* - * The TkWinDCState is used to save the state of a device context so that it - * can be restored later. - */ - -typedef struct TkWinDCState { - HPALETTE palette; - int bkmode; -} TkWinDCState; - -/* - * The TkWinDrawable is the internal implementation of an X Drawable (either a - * Window or a Pixmap). The following constants define the valid Drawable - * types. - */ - -#define TWD_BITMAP 1 -#define TWD_WINDOW 2 -#define TWD_WINDC 3 - -typedef struct { - int type; - HWND handle; - TkWindow *winPtr; -} TkWinWindow; - -typedef struct { - int type; - HBITMAP handle; - Colormap colormap; - int depth; -} TkWinBitmap; - -typedef struct { - int type; - HDC hdc; -}TkWinDC; - -typedef union { - int type; - TkWinWindow window; - TkWinBitmap bitmap; - TkWinDC winDC; -} TkWinDrawable; - -/* - * The following macros are used to retrieve internal values from a Drawable. - */ - -#define TkWinGetHWND(w) (((TkWinDrawable *) w)->window.handle) -#define TkWinGetWinPtr(w) (((TkWinDrawable *) w)->window.winPtr) -#define TkWinGetHBITMAP(w) (((TkWinDrawable *) w)->bitmap.handle) -#define TkWinGetColormap(w) (((TkWinDrawable *) w)->bitmap.colormap) -#define TkWinGetHDC(w) (((TkWinDrawable *) w)->winDC.hdc) - -/* - * The following structure is used to encapsulate palette information. - */ - -typedef struct { - HPALETTE palette; /* Palette handle used when drawing. */ - UINT size; /* Number of entries in the palette. */ - int stale; /* 1 if palette needs to be realized, - * otherwise 0. If the palette is stale, then - * an idle handler is scheduled to realize the - * palette. */ - Tcl_HashTable refCounts; /* Hash table of palette entry reference - * counts indexed by pixel value. */ -} TkWinColormap; - -/* - * The following macro retrieves the Win32 palette from a colormap. - */ - -#define TkWinGetPalette(colormap) (((TkWinColormap *) colormap)->palette) - -/* - * The following macros define the class names for Tk Window types. - */ - -#define TK_WIN_TOPLEVEL_CLASS_NAME TEXT("TkTopLevel") -#define TK_WIN_CHILD_CLASS_NAME TEXT("TkChild") - -/* - * The following variable is a translation table between X gc functions and - * Win32 raster and BitBlt op modes. - */ - -MODULE_SCOPE const int tkpWinRopModes[]; -MODULE_SCOPE const int tkpWinBltModes[]; - -/* - * The following defines are used with TkWinGetBorderPixels to get the extra 2 - * border colors from a Tk_3DBorder. - */ - -#define TK_3D_LIGHT2 TK_3D_DARK_GC+1 -#define TK_3D_DARK2 TK_3D_DARK_GC+2 - -/* - * Internal functions used by more than one source file. - */ - -#include "tkIntPlatDecls.h" - -/* - * Special proc needed as tsd accessor function between - * tkWinX.c:GenerateXEvent and tkWinClipboard.c:UpdateClipboard - */ - -MODULE_SCOPE void TkWinUpdatingClipboard(int mode); - -/* - * Used by tkWinDialog.c to associate the right icon with tk_messageBox - */ - -MODULE_SCOPE HICON TkWinGetIcon(Tk_Window tkw, DWORD iconsize); - -/* - * Used by tkWinX.c on for certain system display change messages and cleanup - * up containers - */ - -MODULE_SCOPE void TkWinDisplayChanged(Display *display); -MODULE_SCOPE void TkWinCleanupContainerList(void); - -/* - * Used by tkWinWm.c for embedded menu handling. May become public. - */ - -MODULE_SCOPE HWND Tk_GetMenuHWND(Tk_Window tkwin); -MODULE_SCOPE HWND Tk_GetEmbeddedMenuHWND(Tk_Window tkwin); - -/* - * The following allows us to cache these encoding for multiple functions. - */ - - -MODULE_SCOPE Tcl_Encoding TkWinGetKeyInputEncoding(void); -MODULE_SCOPE Tcl_Encoding TkWinGetUnicodeEncoding(void); -MODULE_SCOPE void TkWinSetupSystemFonts(TkMainInfo *mainPtr); - -/* - * Values returned by TkWinGetPlatformTheme. - */ - -#define TK_THEME_WIN_CLASSIC 1 -#define TK_THEME_WIN_XP 2 - -/* - * The following is implemented in tkWinWm and used by tkWinEmbed.c - */ - -MODULE_SCOPE void TkpWinToplevelWithDraw(TkWindow *winPtr); -MODULE_SCOPE void TkpWinToplevelIconify(TkWindow *winPtr); -MODULE_SCOPE void TkpWinToplevelDeiconify(TkWindow *winPtr); -MODULE_SCOPE long TkpWinToplevelIsControlledByWm(TkWindow *winPtr); -MODULE_SCOPE long TkpWinToplevelMove(TkWindow *winPtr, int x, int y); -MODULE_SCOPE long TkpWinToplevelOverrideRedirect(TkWindow *winPtr, - int reqValue); -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 - * compatibility. - */ - -#ifndef GetClassLongPtr -# define GetClassLongPtrA GetClassLongA -# define GetClassLongPtrW GetClassLongW -# define SetClassLongPtrA SetClassLongA -# define SetClassLongPtrW SetClassLongW -# ifdef UNICODE -# define GetClassLongPtr GetClassLongPtrW -# define SetClassLongPtr SetClassLongPtrW -# else -# define GetClassLongPtr GetClassLongPtrA -# define SetClassLongPtr SetClassLongPtrA -# endif /* !UNICODE */ -#endif /* !GetClassLongPtr */ -#ifndef GCLP_HICON -# define GCLP_HICON GCL_HICON -#endif /* !GCLP_HICON */ -#ifndef GCLP_HICONSM -# define GCLP_HICONSM (-34) -#endif /* !GCLP_HICONSM */ - -#ifndef GetWindowLongPtr -# define GetWindowLongPtrA GetWindowLongA -# define GetWindowLongPtrW GetWindowLongW -# define SetWindowLongPtrA SetWindowLongA -# define SetWindowLongPtrW SetWindowLongW -# ifdef UNICODE -# define GetWindowLongPtr GetWindowLongPtrW -# define SetWindowLongPtr SetWindowLongPtrW -# else -# define GetWindowLongPtr GetWindowLongPtrW -# define SetWindowLongPtr SetWindowLongPtrW -# endif /* !UNICODE */ -#endif /* !GetWindowLongPtr */ -#ifndef GWLP_WNDPROC -#define GWLP_WNDPROC GWL_WNDPROC -#define GWLP_HINSTANCE GWL_HINSTANCE -#define GWLP_HWNDPARENT GWL_HWNDPARENT -#define GWLP_USERDATA GWL_USERDATA -#define GWLP_ID GWL_ID -#endif /* !GWLP_WNDPROC */ - -#endif /* _TKWININT */ diff --git a/tk8.6/win/tkWinKey.c b/tk8.6/win/tkWinKey.c deleted file mode 100644 index 357a804..0000000 --- a/tk8.6/win/tkWinKey.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - * tkWinKey.c -- - * - * This file contains X emulation routines for keyboard related - * functions. - * - * Copyright (c) 1995 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - -/* - * The keymap table holds mappings of Windows keycodes to X keysyms. If - * Windows ever comes along and changes the value of their keycodes, this will - * break all kinds of things. However, this table lookup is much faster than - * the alternative, in which we walked a list of keycodes looking for a match. - * Since this lookup is performed for every Windows keypress event, it seems - * like a worthwhile improvement to use the table. - */ - -#define MAX_KEYCODE 179 /* VK_MEDIA_PLAY_PAUSE is the last entry in our table below */ -/* cf. https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx */ - -static const KeySym keymap[] = { - NoSymbol, NoSymbol, NoSymbol, XK_Cancel, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, XK_BackSpace, XK_Tab, - NoSymbol, NoSymbol, XK_Clear, XK_Return, NoSymbol, - NoSymbol, XK_Shift_L, XK_Control_L, XK_Alt_L, XK_Pause, - XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, XK_Escape, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, XK_space, XK_Prior, XK_Next, - XK_End, XK_Home, XK_Left, XK_Up, XK_Right, - XK_Down, XK_Select, XK_Print, XK_Execute, NoSymbol, - XK_Insert, XK_Delete, XK_Help, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, XK_Win_L, XK_Win_R, XK_App, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, XK_F1, XK_F2, XK_F3, - XK_F4, XK_F5, XK_F6, XK_F7, XK_F8, - XK_F9, XK_F10, XK_F11, XK_F12, XK_F13, - XK_F14, XK_F15, XK_F16, XK_F17, XK_F18, - XK_F19, XK_F20, XK_F21, XK_F22, XK_F23, - XK_F24, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, XK_Num_Lock, - XK_Scroll_Lock, NoSymbol, NoSymbol, NoSymbol, NoSymbol, - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*150 0x96*/ - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*155 0x9b*/ - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*160 0xa0*/ - NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*165 0xa5*/ - NoSymbol, NoSymbol, NoSymbol, XK_XF86AudioMute, XK_XF86AudioLowerVolume, /*170 0xaa*/ - XK_XF86AudioRaiseVolume, XK_XF86AudioNext, XK_XF86AudioPrev, XK_XF86AudioStop, XK_XF86AudioPlay /*175 0xaf*/ -}; - -/* - * Prototypes for local functions defined in this file: - */ - -static KeySym KeycodeToKeysym(unsigned int keycode, - int state, int noascii); - -/* - *---------------------------------------------------------------------- - * - * TkpGetString -- - * - * Retrieve the UTF string equivalent for the given keyboard event. - * - * Results: - * Returns the UTF string. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -const char * -TkpGetString( - TkWindow *winPtr, /* Window where event occurred: needed to get - * input context. */ - XEvent *eventPtr, /* X keyboard event. */ - Tcl_DString *dsPtr) /* Uninitialized or empty string to hold - * result. */ -{ - XKeyEvent *keyEv = &eventPtr->xkey; - char buf[6]; - int len; - - Tcl_DStringInit(dsPtr); - if (keyEv->send_event == -1) { - if (keyEv->nbytes > 0) { - Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(), - keyEv->trans_chars, keyEv->nbytes, dsPtr); - } - } else if (keyEv->send_event == -3) { - - /* - * Special case for WM_UNICHAR and win2000 multi-lingal IME input - */ - - len = TkUniCharToUtf(keyEv->keycode, buf); - Tcl_DStringAppend(dsPtr, buf, len); - } else { - /* - * This is an event generated from generic code. It has no nchars or - * trans_chars members. - */ - - KeySym keysym = KeycodeToKeysym(keyEv->keycode, keyEv->state, 0); - - if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256)) - || (keysym == XK_Return) || (keysym == XK_Tab)) { - len = Tcl_UniCharToUtf((Tcl_UniChar) (keysym & 255), buf); - Tcl_DStringAppend(dsPtr, buf, len); - } - } - return Tcl_DStringValue(dsPtr); -} - -/* - *---------------------------------------------------------------------- - * - * XKeycodeToKeysym -- - * - * Translate from a system-dependent keycode to a system-independent - * keysym. - * - * Results: - * Returns the translated keysym, or NoSymbol on failure. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -KeySym -XKeycodeToKeysym( - Display *display, - unsigned int keycode, - int index) -{ - int state = 0; - - if (index & 0x01) { - state |= ShiftMask; - } - return KeycodeToKeysym(keycode, state, 0); -} - -/* - *---------------------------------------------------------------------- - * - * KeycodeToKeysym -- - * - * Translate from a system-dependent keycode to a system-independent - * keysym. - * - * Results: - * Returns the translated keysym, or NoSymbol on failure. - * - * Side effects: - * It may affect the internal state of the keyboard, such as remembered - * dead key or lock indicator lamps. - * - *---------------------------------------------------------------------- - */ - -static KeySym -KeycodeToKeysym( - unsigned int keycode, - int state, - int noascii) -{ - BYTE keys[256]; - int result, deadkey, shift; - TCHAR buf[4]; - unsigned int scancode = MapVirtualKey(keycode, 0); - - /* - * Do not run keycodes of lock keys through ToUnicode(). One of ToUnicode()'s - * side effects is to handle the lights on the keyboard, and we don't want - * to mess that up. - */ - - if (noascii || keycode == VK_CAPITAL || keycode == VK_SCROLL || - keycode == VK_NUMLOCK) { - goto skipToUnicode; - } - - /* - * Use MapVirtualKey() to detect some dead keys. - */ - - if (MapVirtualKey(keycode, 2) > 0x7fffUL) { - return XK_Multi_key; - } - - /* - * Set up a keyboard with correct modifiers - */ - - memset(keys, 0, 256); - if (state & ShiftMask) { - keys[VK_SHIFT] = 0x80; - } - if (state & ControlMask) { - keys[VK_CONTROL] = 0x80; - } - if (state & Mod2Mask) { - keys[VK_MENU] = 0x80; - } - - /* - * Make sure all lock button info is correct so we don't mess up the - * lights. - */ - - if (state & LockMask) { - keys[VK_CAPITAL] = 1; - } - if (state & Mod3Mask) { - keys[VK_SCROLL] = 1; - } - if (state & Mod1Mask) { - keys[VK_NUMLOCK] = 1; - } - - result = ToUnicode(keycode, scancode, keys, buf, 4, 0); - - if (result < 0) { - /* - * Win95/98: This was a dead char, which is now remembered by the - * keyboard. Call ToUnicode() again to forget it. - * WinNT: This was a dead char, overwriting any previously remembered - * key. Calling ToUnicode() again does not affect anything. - */ - - ToUnicode(keycode, scancode, keys, buf, 4, 0); - return XK_Multi_key; - } - - if (result == 2) { - /* - * This was a dead char, and there were one previously remembered by - * the keyboard. Call ToUnicode() again with proper parameters to - * restore it. - * - * Get information about the old char - */ - - deadkey = VkKeyScan(buf[0]); - shift = deadkey >> 8; - deadkey &= 255; - scancode = MapVirtualKey(deadkey, 0); - - /* - * Set up a keyboard with proper modifier keys - */ - - memset(keys, 0, 256); - if (shift & 1) { - keys[VK_SHIFT] = 0x80; - } - if (shift & 2) { - keys[VK_CONTROL] = 0x80; - } - if (shift & 4) { - keys[VK_MENU] = 0x80; - } - ToUnicode(deadkey, scancode, keys, buf, 4, 0); - return XK_Multi_key; - } - - /* - * Keycode mapped to a valid Unicode character. Since the keysyms for - * alphanumeric characters map onto Unicode, we just return it. - * - * We treat 0x7F as a special case mostly for backwards compatibility. In - * versions of Tk<=8.2, Control-Backspace returned "XK_BackSpace" as the X - * Keysym. This was due to the fact that we did not initialize the keys - * array properly when we passed it to ToUnicode, above. We had previously - * not been setting the state bit for the Control key. When we fixed that, - * we found that Control-Backspace on Windows is interpreted as ASCII-127 - * (0x7F), which corresponds to the Delete key. - * - * Upon discovering this, we realized we had two choices: return XK_Delete - * or return XK_BackSpace. If we returned XK_Delete, that could be - * considered "more correct" (although the correctness would be dependent - * on whether you believe that ToUnicode is doing the right thing in that - * case); however, this would break backwards compatibility, and worse, it - * would limit application programmers; they would effectively be unable - * to bind to <Control-Backspace> on Windows. We therefore chose instead - * to return XK_BackSpace (handled here by letting the code "fall-through" - * to the return statement below, which works because the keycode for this - * event is VK_BACKSPACE, and the keymap table maps that keycode to - * XK_BackSpace). - */ - - if (result == 1 && buf[0] >= 0x20 && buf[0] != 0x7F) { - return (KeySym) buf[0]; - } - - /* - * Keycode is a non-alphanumeric key, so we have to do the lookup. - */ - - skipToUnicode: - if (keycode > MAX_KEYCODE) { - return NoSymbol; - } - switch (keycode) { - /* - * Windows only gives us an undifferentiated VK_CONTROL code (for - * example) when either Control key is pressed. To distinguish between - * left and right, we use the Extended flag. Indeed, the right Control - * and Alt (aka Menu) keys are such extended keys (which their left - * counterparts are not). - * Regarding the shift case, Windows does not set the Extended flag for - * the neither the left nor the right shift key. As a consequence another - * way to distinguish between the two keys is to query the state of one - * of the two to determine which was actually pressed. So if the keycode - * indicates Shift, do this extra test. If the right-side key was - * pressed, return the appropriate keycode. Otherwise, we fall through - * and rely on the keymap table to hold the correct keysym value. - * Note: this little trick only works for KeyPress, not for KeyRelease, - * for reasons stated in bug [2945130] - */ - - case VK_CONTROL: - if (state & EXTENDED_MASK) { - return XK_Control_R; - } - break; - case VK_SHIFT: - if (GetKeyState(VK_RSHIFT) & 0x80) { - return XK_Shift_R; - } - break; - case VK_MENU: - if (state & EXTENDED_MASK) { - return XK_Alt_R; - } - break; - } - return keymap[keycode]; -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetKeySym -- - * - * Given an X KeyPress or KeyRelease event, map the keycode in the event - * into a KeySym. - * - * Results: - * The return value is the KeySym corresponding to eventPtr, or NoSymbol - * if no matching Keysym could be found. - * - * Side effects: - * In the first call for a given display, keycode-to-KeySym maps get - * loaded. - * - *---------------------------------------------------------------------- - */ - -KeySym -TkpGetKeySym( - TkDisplay *dispPtr, /* Display in which to map keycode. */ - XEvent *eventPtr) /* Description of X event. */ -{ - KeySym sym; - int state = eventPtr->xkey.state; - - /* - * Refresh the mapping information if it's stale - */ - - if (dispPtr->bindInfoStale) { - TkpInitKeymapInfo(dispPtr); - } - - sym = KeycodeToKeysym(eventPtr->xkey.keycode, state, 0); - - /* - * Special handling: if this is a ctrl-alt or shifted key, and there is no - * keysym defined, try without the modifiers. - */ - - if ((sym == NoSymbol) && ((state & ControlMask) || (state & Mod2Mask))) { - state &= ~(ControlMask | Mod2Mask); - sym = KeycodeToKeysym(eventPtr->xkey.keycode, state, 0); - } - if ((sym == NoSymbol) && (state & ShiftMask)) { - state &= ~ShiftMask; - sym = KeycodeToKeysym(eventPtr->xkey.keycode, state, 0); - } - return sym; -} - -/* - *-------------------------------------------------------------- - * - * TkpInitKeymapInfo -- - * - * This function is invoked to scan keymap information to recompute stuff - * that's important for binding, such as the modifier key (if any) that - * corresponds to "mode switch". - * - * Results: - * None. - * - * Side effects: - * Keymap-related information in dispPtr is updated. - * - *-------------------------------------------------------------- - */ - -void -TkpInitKeymapInfo( - TkDisplay *dispPtr) /* Display for which to recompute keymap - * information. */ -{ - XModifierKeymap *modMapPtr; - KeyCode *codePtr; - KeySym keysym; - int count, i, j, max, arraySize; -#define KEYCODE_ARRAY_SIZE 20 - - dispPtr->bindInfoStale = 0; - modMapPtr = XGetModifierMapping(dispPtr->display); - - /* - * Check the keycodes associated with the Lock modifier. If any of them is - * associated with the XK_Shift_Lock modifier, then Lock has to be - * interpreted as Shift Lock, not Caps Lock. - */ - - dispPtr->lockUsage = LU_IGNORE; - codePtr = modMapPtr->modifiermap + modMapPtr->max_keypermod*LockMapIndex; - for (count = modMapPtr->max_keypermod; count > 0; count--, codePtr++) { - if (*codePtr == 0) { - continue; - } - keysym = KeycodeToKeysym(*codePtr, 0, 1); - if (keysym == XK_Shift_Lock) { - dispPtr->lockUsage = LU_SHIFT; - break; - } - if (keysym == XK_Caps_Lock) { - dispPtr->lockUsage = LU_CAPS; - break; - } - } - - /* - * Look through the keycodes associated with modifiers to see if the the - * "mode switch", "meta", or "alt" keysyms are associated with any - * modifiers. If so, remember their modifier mask bits. - */ - - dispPtr->modeModMask = 0; - dispPtr->metaModMask = 0; - dispPtr->altModMask = 0; - codePtr = modMapPtr->modifiermap; - max = 8*modMapPtr->max_keypermod; - for (i = 0; i < max; i++, codePtr++) { - if (*codePtr == 0) { - continue; - } - keysym = KeycodeToKeysym(*codePtr, 0, 1); - if (keysym == XK_Mode_switch) { - dispPtr->modeModMask |= ShiftMask << (i/modMapPtr->max_keypermod); - } - if ((keysym == XK_Meta_L) || (keysym == XK_Meta_R)) { - dispPtr->metaModMask |= ShiftMask << (i/modMapPtr->max_keypermod); - } - if ((keysym == XK_Alt_L) || (keysym == XK_Alt_R)) { - dispPtr->altModMask |= ShiftMask << (i/modMapPtr->max_keypermod); - } - } - - /* - * Create an array of the keycodes for all modifier keys. - */ - - if (dispPtr->modKeyCodes != NULL) { - ckfree(dispPtr->modKeyCodes); - } - dispPtr->numModKeyCodes = 0; - arraySize = KEYCODE_ARRAY_SIZE; - dispPtr->modKeyCodes = ckalloc(KEYCODE_ARRAY_SIZE * sizeof(KeyCode)); - for (i = 0, codePtr = modMapPtr->modifiermap; i < max; i++, codePtr++) { - if (*codePtr == 0) { - continue; - } - - /* - * Make sure that the keycode isn't already in the array. - */ - - for (j = 0; j < dispPtr->numModKeyCodes; j++) { - if (dispPtr->modKeyCodes[j] == *codePtr) { - goto nextModCode; - } - } - if (dispPtr->numModKeyCodes >= arraySize) { - KeyCode *new; - - /* - * Ran out of space in the array; grow it. - */ - - arraySize *= 2; - new = ckalloc(arraySize * sizeof(KeyCode)); - memcpy(new, dispPtr->modKeyCodes, - dispPtr->numModKeyCodes * sizeof(KeyCode)); - ckfree(dispPtr->modKeyCodes); - dispPtr->modKeyCodes = new; - } - dispPtr->modKeyCodes[dispPtr->numModKeyCodes] = *codePtr; - dispPtr->numModKeyCodes++; - nextModCode: continue; - } - XFreeModifiermap(modMapPtr); -} - -/* - * When mapping from a keysym to a keycode, need information about the - * modifier state that should be used so that when they call XKeycodeToKeysym - * taking into account the xkey.state, they will get back the original keysym. - */ - -void -TkpSetKeycodeAndState( - Tk_Window tkwin, - KeySym keySym, - XEvent *eventPtr) -{ - int i; - SHORT result; - int shift; - - eventPtr->xkey.keycode = 0; - if (keySym == NoSymbol) { - return; - } - - /* - * We check our private map first for a virtual keycode, as VkKeyScan will - * return values that don't map to X for the "extended" Syms. This may be - * due to just casting problems below, but this works. - */ - - for (i = 0; i <= MAX_KEYCODE; i++) { - if (keymap[i] == keySym) { - eventPtr->xkey.keycode = i; - return; - } - } - if (keySym >= 0x20) { - result = VkKeyScan((TCHAR) keySym); - if (result != -1) { - shift = result >> 8; - if (shift & 1) - eventPtr->xkey.state |= ShiftMask; - if (shift & 2) - eventPtr->xkey.state |= ControlMask; - if (shift & 4) - eventPtr->xkey.state |= Mod2Mask; - eventPtr->xkey.keycode = (KeyCode) (result & 0xff); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * XKeysymToKeycode -- - * - * Translate a keysym back into a keycode. - * - * Results: - * Returns the keycode that would generate the specified keysym. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -KeyCode -XKeysymToKeycode( - Display *display, - KeySym keysym) -{ - int i; - SHORT result; - - /* - * We check our private map first for a virtual keycode, as VkKeyScan will - * return values that don't map to X for the "extended" Syms. This may be - * due to just casting problems below, but this works. - */ - - if (keysym == NoSymbol) { - return 0; - } - for (i = 0; i <= MAX_KEYCODE; i++) { - if (keymap[i] == keysym) { - return ((KeyCode) i); - } - } - if (keysym >= 0x20) { - result = VkKeyScan((TCHAR) keysym); - if (result != -1) { - return (KeyCode) (result & 0xff); - } - } - - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * XGetModifierMapping -- - * - * Fetch the current keycodes used as modifiers. - * - * Results: - * Returns a new modifier map. - * - * Side effects: - * Allocates a new modifier map data structure. - * - *---------------------------------------------------------------------- - */ - -XModifierKeymap * -XGetModifierMapping( - Display *display) -{ - XModifierKeymap *map = ckalloc(sizeof(XModifierKeymap)); - - map->max_keypermod = 1; - map->modifiermap = ckalloc(sizeof(KeyCode) * 8); - map->modifiermap[ShiftMapIndex] = VK_SHIFT; - map->modifiermap[LockMapIndex] = VK_CAPITAL; - map->modifiermap[ControlMapIndex] = VK_CONTROL; - map->modifiermap[Mod1MapIndex] = VK_NUMLOCK; - map->modifiermap[Mod2MapIndex] = VK_MENU; - map->modifiermap[Mod3MapIndex] = VK_SCROLL; - map->modifiermap[Mod4MapIndex] = 0; - map->modifiermap[Mod5MapIndex] = 0; - return map; -} - -/* - *---------------------------------------------------------------------- - * - * XFreeModifiermap -- - * - * Deallocate a modifier map that was created by XGetModifierMapping. - * - * Results: - * None. - * - * Side effects: - * Frees the datastructure referenced by modmap. - * - *---------------------------------------------------------------------- - */ - -int -XFreeModifiermap( - XModifierKeymap *modmap) -{ - ckfree(modmap->modifiermap); - ckfree(modmap); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XStringToKeysym -- - * - * Translate a keysym name to the matching keysym. - * - * Results: - * Returns the keysym. Since this is already handled by Tk's - * StringToKeysym function, we just return NoSymbol. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -KeySym -XStringToKeysym( - _Xconst char *string) -{ - return NoSymbol; -} - -/* - *---------------------------------------------------------------------- - * - * XKeysymToString -- - * - * Convert a keysym to character form. - * - * Results: - * Returns NULL, since Tk will have handled this already. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -char * -XKeysymToString( - KeySym keysym) -{ - return NULL; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinMenu.c b/tk8.6/win/tkWinMenu.c deleted file mode 100644 index 5dc8f8a..0000000 --- a/tk8.6/win/tkWinMenu.c +++ /dev/null @@ -1,3396 +0,0 @@ -/* - * tkWinMenu.c -- - * - * This module implements the Windows platform-specific features of - * menus. - * - * Copyright (c) 1996-1998 by Sun Microsystems, Inc. - * Copyright (c) 1998-1999 by Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#define OEMRESOURCE -#include "tkWinInt.h" -#include "tkMenu.h" - -/* - * The class of the window for popup menus. - */ - -#define MENU_CLASS_NAME TEXT("MenuWindowClass") -#define EMBEDDED_MENU_CLASS_NAME TEXT("EmbeddedMenuWindowClass") - -/* - * Used to align a windows bitmap inside a rectangle - */ - -#define ALIGN_BITMAP_LEFT 0x00000001 -#define ALIGN_BITMAP_RIGHT 0x00000002 -#define ALIGN_BITMAP_TOP 0x00000004 -#define ALIGN_BITMAP_BOTTOM 0x00000008 - - -/* - * Platform-specific menu flags: - * - * MENU_SYSTEM_MENU Non-zero means that the Windows menu handle was - * retrieved with GetSystemMenu and needs to be disposed - * of specially. - * MENU_RECONFIGURE_PENDING - * Non-zero means that an idle handler has been set up to - * reconfigure the Windows menu handle for this menu. - */ - -#define MENU_SYSTEM_MENU MENU_PLATFORM_FLAG1 -#define MENU_RECONFIGURE_PENDING MENU_PLATFORM_FLAG2 - -/* - * ODS_NOACCEL flag forbids drawing accelerator cues (i.e. underlining labels) - * on Windows 2000 and above. The ODS_NOACCEL define is missing from mingw32 - * headers and undefined for _WIN32_WINNT < 0x0500 in Microsoft SDK. We might - * check for _WIN32_WINNT here, but I think it's not needed, as checking for - * this flag does no harm on even on NT: reserved bits should be zero, and in - * fact they are. - */ - -#ifndef ODS_NOACCEL -#define ODS_NOACCEL 0x100 -#endif -#ifndef SPI_GETKEYBOARDCUES -#define SPI_GETKEYBOARDCUES 0x100A -#endif -#ifndef WM_UPDATEUISTATE -#define WM_UPDATEUISTATE 0x0128 -#endif -#ifndef UIS_SET -#define UIS_SET 1 -#endif -#ifndef UIS_CLEAR -#define UIS_CLEAR 2 -#endif -#ifndef UISF_HIDEACCEL -#define UISF_HIDEACCEL 2 -#endif - -#ifndef WM_UNINITMENUPOPUP -#define WM_UNINITMENUPOPUP 0x0125 -#endif - -static int indicatorDimensions[2]; - /* The dimensions of the indicator space in a - * menu entry. Calculated at init time to save - * time. */ - -static BOOL showMenuAccelerators; - -typedef struct ThreadSpecificData { - int inPostMenu; /* We cannot be re-entrant like X Windows. */ - WORD lastCommandID; /* The last command ID we allocated. */ - HWND menuHWND; /* A window to service popup-menu messages - * in. */ - HWND embeddedMenuHWND; /* A window to service embedded menu - * messages */ - int oldServiceMode; /* Used while processing a menu; we need to - * set the event mode specially when we enter - * the menu processing modal loop and reset it - * when menus go away. */ - TkMenu *modalMenuPtr; /* The menu we are processing inside the modal - * loop. We need this to reset all of the - * active items when menus go away since - * Windows does not see fit to give this to us - * when it sends its WM_MENUSELECT. */ - Tcl_HashTable commandTable; /* A map of command ids to menu entries */ - Tcl_HashTable winMenuTable; /* Need this to map HMENUs back to menuPtrs */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -/* - * The following are default menu value strings. - */ - -static int defaultBorderWidth; /* The windows default border width. */ -static Tcl_DString menuFontDString; - /* A buffer to store the default menu font - * string. */ -/* - * Forward declarations for functions defined later in this file: - */ - -static void DrawMenuEntryAccelerator(TkMenu *menuPtr, - TkMenuEntry *mePtr, Drawable d, GC gc, - Tk_Font tkfont, const Tk_FontMetrics *fmPtr, - Tk_3DBorder activeBorder, int x, int y, - int width, int height); -static void DrawMenuEntryArrow(TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, Tk_3DBorder activeBorder, - int x,int y, int width, int height, int drawArrow); -static void DrawMenuEntryBackground(TkMenu *menuPtr, - TkMenuEntry *mePtr, Drawable d, - Tk_3DBorder activeBorder, Tk_3DBorder bgBorder, - int x, int y, int width, int heigth); -static void DrawMenuEntryIndicator(TkMenu *menuPtr, - TkMenuEntry *mePtr, Drawable d, GC gc, - GC indicatorGC, Tk_Font tkfont, - const Tk_FontMetrics *fmPtr, int x, int y, - int width, int height); -static void DrawMenuEntryLabel(TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, Tk_Font tkfont, - const Tk_FontMetrics *fmPtr, int x, int y, - int width, int height, int underline); -static void DrawMenuSeparator(TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, Tk_Font tkfont, - const Tk_FontMetrics *fmPtr, - int x, int y, int width, int height); -static void DrawTearoffEntry(TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, Tk_Font tkfont, - const Tk_FontMetrics *fmPtr, int x, int y, - int width, int height); -static void DrawMenuUnderline(TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, Tk_Font tkfont, - const Tk_FontMetrics *fmPtr, int x, int y, - int width, int height); -static void DrawWindowsSystemBitmap(Display *display, - Drawable drawable, GC gc, const RECT *rectPtr, - int bitmapID, int alignFlags); -static void FreeID(WORD commandID); -static char * GetEntryText(TkMenu *menuPtr, TkMenuEntry *mePtr); -static void GetMenuAccelGeometry(TkMenu *menuPtr, - TkMenuEntry *mePtr, Tk_Font tkfont, - const Tk_FontMetrics *fmPtr, int *widthPtr, - int *heightPtr); -static void GetMenuLabelGeometry(TkMenuEntry *mePtr, - Tk_Font tkfont, const Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr); -static void GetMenuIndicatorGeometry(TkMenu *menuPtr, - TkMenuEntry *mePtr, Tk_Font tkfont, - const Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr); -static void GetMenuSeparatorGeometry(TkMenu *menuPtr, - TkMenuEntry *mePtr, Tk_Font tkfont, - const Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr); -static void GetTearoffEntryGeometry(TkMenu *menuPtr, - TkMenuEntry *mePtr, Tk_Font tkfont, - const Tk_FontMetrics *fmPtr, int *widthPtr, - int *heightPtr); -static int GetNewID(TkMenuEntry *mePtr, WORD *menuIDPtr); -static int TkWinMenuKeyObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static void MenuSelectEvent(TkMenu *menuPtr); -static void ReconfigureWindowsMenu(ClientData clientData); -static void RecursivelyClearActiveMenu(TkMenu *menuPtr); -static void SetDefaults(int firstTime); -static LRESULT CALLBACK TkWinMenuProc(HWND hwnd, UINT message, WPARAM wParam, - LPARAM lParam); -static LRESULT CALLBACK TkWinEmbeddedMenuProc(HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam); - -static inline void -ScheduleMenuReconfigure( - TkMenu *menuPtr) -{ - if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { - menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureWindowsMenu, menuPtr); - } -} - -static inline void -CallPendingReconfigureImmediately( - TkMenu *menuPtr) -{ - if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { - Tcl_CancelIdleCall(ReconfigureWindowsMenu, menuPtr); - ReconfigureWindowsMenu(menuPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * GetNewID -- - * - * Allocates a new menu id and marks it in use. - * - * Results: - * Returns TCL_OK if succesful; TCL_ERROR if there are no more ids of the - * appropriate type to allocate. menuIDPtr contains the new id if - * succesful. - * - * Side effects: - * An entry is created for the menu in the command hash table, and the - * hash entry is stored in the appropriate field in the menu data - * structure. - * - *---------------------------------------------------------------------- - */ - -static int -GetNewID( - TkMenuEntry *mePtr, /* The menu we are working with. */ - WORD *menuIDPtr) /* The resulting id. */ -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - WORD curID = tsdPtr->lastCommandID; - - while (1) { - Tcl_HashEntry *commandEntryPtr; - int new; - - /* - * Try the next ID number, taking care to wrap rather than stray - * into the system menu IDs. [Bug 3235256] - */ - if (++curID >= 0xF000) { - curID = 1; - } - - /* Return error when we've checked all IDs without success. */ - if (curID == tsdPtr->lastCommandID) { - return TCL_ERROR; - } - - commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable, - INT2PTR(curID), &new); - if (new) { - Tcl_SetHashValue(commandEntryPtr, mePtr); - *menuIDPtr = curID; - tsdPtr->lastCommandID = curID; - return TCL_OK; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * FreeID -- - * - * Marks the itemID as free. - * - * Results: - * None. - * - * Side effects: - * The hash table entry for the ID is cleared. - * - *---------------------------------------------------------------------- - */ - -static void -FreeID( - WORD commandID) -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - /* - * If the menuHWND is NULL, this table has been finalized already. - */ - - if (tsdPtr->menuHWND != NULL) { - Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable, - INT2PTR(commandID)); - - if (entryPtr != NULL) { - Tcl_DeleteHashEntry(entryPtr); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpNewMenu -- - * - * Gets a new blank menu. Only the platform specific options are filled - * in. - * - * Results: - * Standard TCL error. - * - * Side effects: - * Allocates a Windows menu handle and places it in the platformData - * field of the menuPtr. - * - *---------------------------------------------------------------------- - */ - -int -TkpNewMenu( - TkMenu *menuPtr) /* The common structure we are making the - * platform structure for. */ -{ - HMENU winMenuHdl; - Tcl_HashEntry *hashEntryPtr; - int newEntry; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - winMenuHdl = CreatePopupMenu(); - if (winMenuHdl == NULL) { - Tcl_SetObjResult(menuPtr->interp, Tcl_NewStringObj( - "No more menus can be allocated.", -1)); - Tcl_SetErrorCode(menuPtr->interp, "TK", "MENU", "SYSTEM_RESOURCES", NULL); - return TCL_ERROR; - } - - /* - * We hash all of the HMENU's so that we can get their menu ptrs back when - * dispatch messages. - */ - - hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, - (char *) winMenuHdl, &newEntry); - Tcl_SetHashValue(hashEntryPtr, menuPtr); - - menuPtr->platformData = (TkMenuPlatformData) winMenuHdl; - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkpDestroyMenu -- - * - * Destroys platform-specific menu structures. - * - * Results: - * None. - * - * Side effects: - * All platform-specific allocations are freed up. - * - *---------------------------------------------------------------------- - */ - -void -TkpDestroyMenu( - TkMenu *menuPtr) /* The common menu structure */ -{ - HMENU winMenuHdl = (HMENU) menuPtr->platformData; - const char *searchName; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { - Tcl_CancelIdleCall(ReconfigureWindowsMenu, menuPtr); - } - - if (winMenuHdl == NULL) { - return; - } - - if (menuPtr->menuFlags & MENU_SYSTEM_MENU) { - TkMenuEntry *searchEntryPtr; - Tcl_HashTable *tablePtr = TkGetMenuHashTable(menuPtr->interp); - char *menuName = Tcl_GetHashKey(tablePtr, - menuPtr->menuRefPtr->hashEntryPtr); - - /* - * Search for the menu in the menubar, if it is present, get the - * wrapper window associated with the toplevel and reset its - * system menu to the default menu. - */ - - for (searchEntryPtr = menuPtr->menuRefPtr->parentEntryPtr; - searchEntryPtr != NULL; - searchEntryPtr = searchEntryPtr->nextCascadePtr) { - searchName = Tcl_GetString(searchEntryPtr->namePtr); - if (strcmp(searchName, menuName) == 0) { - Tk_Window parentTopLevelPtr = searchEntryPtr - ->menuPtr->parentTopLevelPtr; - - if (parentTopLevelPtr != NULL) { - GetSystemMenu( - TkWinGetWrapperWindow(parentTopLevelPtr), TRUE); - } - break; - } - } - } else { - /* - * Remove the menu from the menu hash table, then destroy the handle. - * If the menuHWND is NULL, this table has been finalized already. - */ - - if (tsdPtr->menuHWND != NULL) { - Tcl_HashEntry *hashEntryPtr = - Tcl_FindHashEntry(&tsdPtr->winMenuTable, (char *) winMenuHdl); - - if (hashEntryPtr != NULL) { - Tcl_DeleteHashEntry(hashEntryPtr); - } - } - DestroyMenu(winMenuHdl); - } - menuPtr->platformData = NULL; - - if (menuPtr == tsdPtr->modalMenuPtr) { - tsdPtr->modalMenuPtr = NULL; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpDestroyMenuEntry -- - * - * Cleans up platform-specific menu entry items. - * - * Results: - * None - * - * Side effects: - * All platform-specific allocations are freed up. - * - *---------------------------------------------------------------------- - */ - -void -TkpDestroyMenuEntry( - TkMenuEntry *mePtr) /* The entry to destroy */ -{ - TkMenu *menuPtr = mePtr->menuPtr; - HMENU winMenuHdl = (HMENU) menuPtr->platformData; - - if (NULL != winMenuHdl) { - ScheduleMenuReconfigure(menuPtr); - } - FreeID((WORD) PTR2INT(mePtr->platformEntryData)); - mePtr->platformEntryData = NULL; -} - -/* - *---------------------------------------------------------------------- - * - * GetEntryText -- - * - * Given a menu entry, gives back the text that should go in it. - * Separators should be done by the caller, as they have to be handled - * specially. Allocates the memory with alloc. The caller should free the - * memory. - * - * Results: - * itemText points to the new text for the item. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static char * -GetEntryText( - TkMenu *menuPtr, /* The menu considered. */ - TkMenuEntry *mePtr) /* A pointer to the menu entry. */ -{ - char *itemText; - - if (mePtr->type == TEAROFF_ENTRY) { - itemText = ckalloc(sizeof("(Tear-off)")); - strcpy(itemText, "(Tear-off)"); - } else if (mePtr->imagePtr != NULL) { - itemText = ckalloc(sizeof("(Image)")); - strcpy(itemText, "(Image)"); - } else if (mePtr->bitmapPtr != NULL) { - itemText = ckalloc(sizeof("(Pixmap)")); - strcpy(itemText, "(Pixmap)"); - } else if (mePtr->labelPtr == NULL || mePtr->labelLength == 0) { - itemText = ckalloc(sizeof("( )")); - strcpy(itemText, "( )"); - } else { - int i; - const char *label = (mePtr->labelPtr == NULL) ? "" - : Tcl_GetString(mePtr->labelPtr); - const char *accel = ((menuPtr->menuType == MENUBAR) || (mePtr->accelPtr == NULL)) ? "" - : Tcl_GetString(mePtr->accelPtr); - const char *p, *next; - Tcl_DString itemString; - - /* - * We have to construct the string with an ampersand preceeding the - * underline character, and a tab seperating the text and the accel - * text. We have to be careful with ampersands in the string. - */ - - Tcl_DStringInit(&itemString); - - for (p = label, i = 0; *p != '\0'; i++, p = next) { - if (i == mePtr->underline) { - Tcl_DStringAppend(&itemString, "&", 1); - } - if (*p == '&') { - Tcl_DStringAppend(&itemString, "&", 1); - } - next = Tcl_UtfNext(p); - Tcl_DStringAppend(&itemString, p, (int) (next - p)); - } - if (mePtr->accelLength > 0) { - Tcl_DStringAppend(&itemString, "\t", 1); - for (p = accel, i = 0; *p != '\0'; i++, p = next) { - if (*p == '&') { - Tcl_DStringAppend(&itemString, "&", 1); - } - next = Tcl_UtfNext(p); - Tcl_DStringAppend(&itemString, p, (int) (next - p)); - } - } - - itemText = ckalloc(Tcl_DStringLength(&itemString) + 1); - strcpy(itemText, Tcl_DStringValue(&itemString)); - Tcl_DStringFree(&itemString); - } - return itemText; -} - -/* - *---------------------------------------------------------------------- - * - * ReconfigureWindowsMenu -- - * - * Tears down and rebuilds the platform-specific part of this menu. - * - * Results: - * None. - * - * Side effects: - * Configuration information get set for mePtr; old resources get freed, - * if any need it. - * - *---------------------------------------------------------------------- - */ - -static void -ReconfigureWindowsMenu( - ClientData clientData) /* The menu we are rebuilding */ -{ - TkMenu *menuPtr = clientData; - TkMenuEntry *mePtr; - HMENU winMenuHdl = (HMENU) menuPtr->platformData; - char *itemText = NULL; - const TCHAR *lpNewItem; - UINT flags; - UINT itemID; - int i, count, systemMenu = 0, base; - Tcl_DString translatedText; - - if (NULL == winMenuHdl) { - return; - } - - /* - * Reconstruct the entire menu. Takes care of nasty system menu and index - * problem. - */ - - base = (menuPtr->menuFlags & MENU_SYSTEM_MENU) ? 7 : 0; - count = GetMenuItemCount(winMenuHdl); - for (i = base; i < count; i++) { - RemoveMenu(winMenuHdl, base, MF_BYPOSITION); - } - - count = menuPtr->numEntries; - for (i = 0; i < count; i++) { - mePtr = menuPtr->entries[i]; - lpNewItem = NULL; - flags = MF_BYPOSITION; - itemID = 0; - Tcl_DStringInit(&translatedText); - - if ((menuPtr->menuType == MENUBAR) && (mePtr->type == TEAROFF_ENTRY)) { - continue; - } - - itemText = GetEntryText(menuPtr, mePtr); - if ((menuPtr->menuType == MENUBAR) - || (menuPtr->menuFlags & MENU_SYSTEM_MENU)) { - Tcl_WinUtfToTChar(itemText, -1, &translatedText); - lpNewItem = (const TCHAR *) Tcl_DStringValue(&translatedText); - flags |= MF_STRING; - } else { - lpNewItem = (LPCTSTR) mePtr; - flags |= MF_OWNERDRAW; - } - - /* - * Set enabling and disabling correctly. - */ - - if (mePtr->state == ENTRY_DISABLED) { - flags |= MF_DISABLED | MF_GRAYED; - } - - /* - * Set the check mark for check entries and radio entries. - */ - - if (((mePtr->type == CHECK_BUTTON_ENTRY) - || (mePtr->type == RADIO_BUTTON_ENTRY)) - && (mePtr->entryFlags & ENTRY_SELECTED)) { - flags |= MF_CHECKED; - } - - /* - * Set the SEPARATOR bit for separator entries. This bit is not used - * by our internal drawing functions, but it is used by the system - * when drawing the system menu (we do not draw the system menu - * ourselves). If this bit is not set, separator entries on the system - * menu will not be drawn correctly. - */ - - if (mePtr->type == SEPARATOR_ENTRY) { - flags |= MF_SEPARATOR; - } - - if (mePtr->columnBreak) { - flags |= MF_MENUBREAK; - } - - itemID = PTR2INT(mePtr->platformEntryData); - if ((mePtr->type == CASCADE_ENTRY) - && (mePtr->childMenuRefPtr != NULL) - && (mePtr->childMenuRefPtr->menuPtr != NULL)) { - HMENU childMenuHdl = (HMENU) mePtr->childMenuRefPtr->menuPtr - ->platformData; - if (childMenuHdl != NULL) { - /* - * Win32 draws the popup arrow in the wrong color for a - * disabled cascade menu, so do it by hand. Given it is - * disabled, there's no need for it to be connected to its - * child. - */ - - if (mePtr->state != ENTRY_DISABLED) { - flags |= MF_POPUP; - /* - * If the MF_POPUP flag is set, then the id is interpreted - * as the handle of a submenu. - */ - itemID = PTR2INT(childMenuHdl); - } - } - if ((menuPtr->menuType == MENUBAR) - && !(mePtr->childMenuRefPtr->menuPtr->menuFlags - & MENU_SYSTEM_MENU)) { - Tcl_DString ds; - TkMenuReferences *menuRefPtr; - TkMenu *systemMenuPtr = mePtr->childMenuRefPtr->menuPtr; - - Tcl_DStringInit(&ds); - Tcl_DStringAppend(&ds, - Tk_PathName(menuPtr->masterMenuPtr->tkwin), -1); - Tcl_DStringAppend(&ds, ".system", 7); - - menuRefPtr = TkFindMenuReferences(menuPtr->interp, - Tcl_DStringValue(&ds)); - - Tcl_DStringFree(&ds); - - if ((menuRefPtr != NULL) - && (menuRefPtr->menuPtr != NULL) - && (menuPtr->parentTopLevelPtr != NULL) - && (systemMenuPtr->masterMenuPtr - == menuRefPtr->menuPtr)) { - HMENU systemMenuHdl = (HMENU) systemMenuPtr->platformData; - HWND wrapper = TkWinGetWrapperWindow(menuPtr - ->parentTopLevelPtr); - - if (wrapper != NULL) { - DestroyMenu(systemMenuHdl); - systemMenuHdl = GetSystemMenu(wrapper, FALSE); - systemMenuPtr->menuFlags |= MENU_SYSTEM_MENU; - systemMenuPtr->platformData = - (TkMenuPlatformData) systemMenuHdl; - ScheduleMenuReconfigure(systemMenuPtr); - } - } - } - if (mePtr->childMenuRefPtr->menuPtr->menuFlags - & MENU_SYSTEM_MENU) { - systemMenu++; - } - } - if (!systemMenu) { - InsertMenu(winMenuHdl, 0xFFFFFFFF, flags, itemID, lpNewItem); - } - Tcl_DStringFree(&translatedText); - if (itemText != NULL) { - ckfree(itemText); - itemText = NULL; - } - } - - - if ((menuPtr->menuType == MENUBAR) - && (menuPtr->parentTopLevelPtr != NULL)) { - HANDLE bar = TkWinGetWrapperWindow(menuPtr->parentTopLevelPtr); - - if (bar) { - DrawMenuBar(bar); - } - } - - menuPtr->menuFlags &= ~(MENU_RECONFIGURE_PENDING); -} - -/* - *---------------------------------------------------------------------- - * - * TkpPostMenu -- - * - * Posts a menu on the screen - * - * Results: - * None. - * - * Side effects: - * The menu is posted and handled. - * - *---------------------------------------------------------------------- - */ - -int -TkpPostMenu( - Tcl_Interp *interp, - TkMenu *menuPtr, - int x, int y) -{ - HMENU winMenuHdl = (HMENU) menuPtr->platformData; - int result, flags; - RECT noGoawayRect; - POINT point; - Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin); - int oldServiceMode = Tcl_GetServiceMode(); - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - tsdPtr->inPostMenu++; - - CallPendingReconfigureImmediately(menuPtr); - - result = TkPreprocessMenu(menuPtr); - if (result != TCL_OK) { - tsdPtr->inPostMenu--; - return result; - } - - /* - * The post commands could have deleted the menu, which means - * we are dead and should go away. - */ - - if (menuPtr->tkwin == NULL) { - tsdPtr->inPostMenu--; - return TCL_OK; - } - - if (NULL == parentWindow) { - noGoawayRect.top = y - 50; - noGoawayRect.bottom = y + 50; - noGoawayRect.left = x - 50; - noGoawayRect.right = x + 50; - } else { - int left, top; - Tk_GetRootCoords(parentWindow, &left, &top); - noGoawayRect.left = left; - noGoawayRect.top = top; - noGoawayRect.bottom = noGoawayRect.top + Tk_Height(parentWindow); - noGoawayRect.right = noGoawayRect.left + Tk_Width(parentWindow); - } - - Tcl_SetServiceMode(TCL_SERVICE_NONE); - - /* - * Make an assumption here. If the right button is down, - * then we want to track it. Otherwise, track the left mouse button. - */ - - flags = TPM_LEFTALIGN; - if (GetSystemMetrics(SM_SWAPBUTTON)) { - if (GetAsyncKeyState(VK_LBUTTON) < 0) { - flags |= TPM_RIGHTBUTTON; - } else { - flags |= TPM_LEFTBUTTON; - } - } else { - if (GetAsyncKeyState(VK_RBUTTON) < 0) { - flags |= TPM_RIGHTBUTTON; - } else { - flags |= TPM_LEFTBUTTON; - } - } - - TrackPopupMenu(winMenuHdl, flags, x, y, 0, - tsdPtr->menuHWND, &noGoawayRect); - Tcl_SetServiceMode(oldServiceMode); - - GetCursorPos(&point); - Tk_PointerEvent(NULL, point.x, point.y); - - if (tsdPtr->inPostMenu) { - tsdPtr->inPostMenu = 0; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkpMenuNewEntry -- - * - * Adds a pointer to a new menu entry structure with the platform- - * specific fields filled in. - * - * Results: - * Standard TCL error. - * - * Side effects: - * A new command ID is allocated and stored in the platformEntryData - * field of mePtr. - * - *---------------------------------------------------------------------- - */ - -int -TkpMenuNewEntry( - TkMenuEntry *mePtr) -{ - WORD commandID; - TkMenu *menuPtr = mePtr->menuPtr; - - if (GetNewID(mePtr, &commandID) != TCL_OK) { - return TCL_ERROR; - } - ScheduleMenuReconfigure(menuPtr); - mePtr->platformEntryData = (TkMenuPlatformEntryData) INT2PTR(commandID); - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinMenuProc -- - * - * The window proc for the dummy window we put popups in. This allows - * is to post a popup whether or not we know what the parent window - * is. - * - * Results: - * Returns whatever is appropriate for the message in question. - * - * Side effects: - * Normal side-effect for windows messages. - * - *---------------------------------------------------------------------- - */ - -static LRESULT CALLBACK -TkWinMenuProc( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - LRESULT lResult; - - if (!TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &lResult)) { - lResult = DefWindowProc(hwnd, message, wParam, lParam); - } - return lResult; -} - -/* - *---------------------------------------------------------------------- - * - * UpdateEmbeddedMenu -- - * - * This function is used as work-around for updating the pull-down window - * of an embedded menu which may show as a blank popup window. - * - * Results: - * Invalidate the client area of the embedded pull-down menu and - * redraw it. - * - * Side effects: - * Redraw the embedded menu window. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateEmbeddedMenu( - ClientData clientData) -{ - RECT rc; - HWND hMenuWnd = (HWND)clientData; - - GetClientRect(hMenuWnd, &rc); - InvalidateRect(hMenuWnd, &rc, FALSE); - UpdateWindow(hMenuWnd); -} - -/* - *---------------------------------------------------------------------- - * - * TkWinEmbeddedMenuProc -- - * - * This window proc is for the embedded menu windows. It provides - * message services to an embedded menu in a different process. - * - * Results: - * Returns 1 if the message has been handled or 0 otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static LRESULT CALLBACK -TkWinEmbeddedMenuProc( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - static int nIdles = 0; - LRESULT lResult = 1; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - switch(message) { - case WM_ENTERIDLE: - if ((wParam == MSGF_MENU) && (nIdles < 1) - && (hwnd == tsdPtr->embeddedMenuHWND)) { - Tcl_CreateTimerHandler(200, UpdateEmbeddedMenu, - (ClientData) lParam); - nIdles++; - } - break; - - case WM_INITMENUPOPUP: - nIdles = 0; - break; - - case WM_SETTINGCHANGE: - if (wParam == SPI_SETNONCLIENTMETRICS - || wParam == SPI_SETKEYBOARDCUES) { - SetDefaults(0); - } - break; - - case WM_INITMENU: - case WM_SYSCOMMAND: - case WM_COMMAND: - case WM_MENUCHAR: - case WM_MEASUREITEM: - case WM_DRAWITEM: - case WM_MENUSELECT: - lResult = TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, - &lResult); - if (lResult || (GetCapture() != hwnd)) { - break; - } - - default: - lResult = DefWindowProc(hwnd, message, wParam, lParam); - break; - } - return lResult; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinHandleMenuEvent -- - * - * Filters out menu messages from messages passed to a top-level. Will - * respond appropriately to WM_COMMAND, WM_MENUSELECT, WM_MEASUREITEM, - * WM_DRAWITEM - * - * Result: - * Returns 1 if this handled the message; 0 if it did not. - * - * Side effects: - * All of the parameters may be modified so that the caller can think it - * is getting a different message. plResult points to the result that - * should be returned to windows from this message. - * - *---------------------------------------------------------------------- - */ - -int -TkWinHandleMenuEvent( - HWND *phwnd, - UINT *pMessage, - WPARAM *pwParam, - LPARAM *plParam, - LRESULT *plResult) -{ - Tcl_HashEntry *hashEntryPtr; - int returnResult = 0; - TkMenu *menuPtr; - TkMenuEntry *mePtr; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - switch (*pMessage) { - case WM_UNINITMENUPOPUP: - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) *pwParam); - if (hashEntryPtr != NULL) { - menuPtr = Tcl_GetHashValue(hashEntryPtr); - if ((menuPtr->menuRefPtr != NULL) - && (menuPtr->menuRefPtr->parentEntryPtr != NULL)) { - TkPostSubmenu(menuPtr->interp, - menuPtr->menuRefPtr->parentEntryPtr->menuPtr, NULL); - } - } - break; - - case WM_INITMENU: - TkMenuInit(); - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) *pwParam); - if (hashEntryPtr != NULL) { - tsdPtr->oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - menuPtr = Tcl_GetHashValue(hashEntryPtr); - tsdPtr->modalMenuPtr = menuPtr; - CallPendingReconfigureImmediately(menuPtr); - RecursivelyClearActiveMenu(menuPtr); - if (!tsdPtr->inPostMenu) { - Tcl_Interp *interp = menuPtr->interp; - int code; - - Tcl_Preserve(interp); - code = TkPreprocessMenu(menuPtr); - if ((code != TCL_OK) && (code != TCL_CONTINUE) - && (code != TCL_BREAK)) { - Tcl_AddErrorInfo(interp, "\n (menu preprocess)"); - Tcl_BackgroundException(interp, code); - } - Tcl_Release(interp); - } - TkActivateMenuEntry(menuPtr, -1); - *plResult = 0; - returnResult = 1; - } else { - tsdPtr->modalMenuPtr = NULL; - } - break; - - case WM_SYSCOMMAND: - case WM_COMMAND: - TkMenuInit(); - if (HIWORD(*pwParam) != 0) { - break; - } - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable, - INT2PTR(LOWORD(*pwParam))); - if (hashEntryPtr == NULL) { - break; - } - mePtr = Tcl_GetHashValue(hashEntryPtr); - if (mePtr != NULL) { - TkMenuReferences *menuRefPtr; - TkMenuEntry *parentEntryPtr; - Tcl_Interp *interp; - int code; - - /* - * We have to set the parent of this menu to be active if this is - * a submenu so that tearoffs will get the correct title. - */ - - menuPtr = mePtr->menuPtr; - menuRefPtr = TkFindMenuReferences(menuPtr->interp, - Tk_PathName(menuPtr->tkwin)); - if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) { - for (parentEntryPtr = menuRefPtr->parentEntryPtr ; ; - parentEntryPtr = parentEntryPtr->nextCascadePtr) { - const char *name = Tcl_GetString(parentEntryPtr->namePtr); - - if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) { - break; - } - } - if (parentEntryPtr->menuPtr->entries[parentEntryPtr->index] - ->state != ENTRY_DISABLED) { - TkActivateMenuEntry(parentEntryPtr->menuPtr, - parentEntryPtr->index); - } - } - - interp = menuPtr->interp; - Tcl_Preserve(interp); - code = TkInvokeMenu(interp, menuPtr, mePtr->index); - if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) { - Tcl_AddErrorInfo(interp, "\n (menu invoke)"); - Tcl_BackgroundException(interp, code); - } - Tcl_Release(interp); - *plResult = 0; - returnResult = 1; - } - break; - - case WM_MENUCHAR: { - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) *plParam); - if (hashEntryPtr != NULL) { - int i, len, underline; - Tcl_Obj *labelPtr; - Tcl_UniChar *wlabel, menuChar; - - *plResult = 0; - menuPtr = Tcl_GetHashValue(hashEntryPtr); - /* - * Assume we have something directly convertable to Tcl_UniChar. - * True at least for wide systems. - */ - menuChar = Tcl_UniCharToUpper((Tcl_UniChar) LOWORD(*pwParam)); - - for (i = 0; i < menuPtr->numEntries; i++) { - underline = menuPtr->entries[i]->underline; - labelPtr = menuPtr->entries[i]->labelPtr; - if ((underline >= 0) && (labelPtr != NULL)) { - /* - * Ensure we don't exceed the label length, then check - */ - wlabel = Tcl_GetUnicodeFromObj(labelPtr, &len); - if ((underline < len) && (menuChar == - Tcl_UniCharToUpper(wlabel[underline]))) { - *plResult = (2 << 16) | i; - returnResult = 1; - break; - } - } - } - } - break; - } - - case WM_MEASUREITEM: { - LPMEASUREITEMSTRUCT itemPtr = (LPMEASUREITEMSTRUCT) *plParam; - - if (itemPtr != NULL && tsdPtr->modalMenuPtr != NULL) { - mePtr = (TkMenuEntry *) itemPtr->itemData; - menuPtr = mePtr->menuPtr; - - TkRecomputeMenu(menuPtr); - itemPtr->itemHeight = mePtr->height; - itemPtr->itemWidth = mePtr->width; - if (mePtr->hideMargin) { - itemPtr->itemWidth += 2 - indicatorDimensions[1]; - } else { - int activeBorderWidth; - - Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, &activeBorderWidth); - itemPtr->itemWidth += 2 * activeBorderWidth; - } - *plResult = 1; - returnResult = 1; - } - break; - } - - case WM_DRAWITEM: { - TkWinDrawable *twdPtr; - LPDRAWITEMSTRUCT itemPtr = (LPDRAWITEMSTRUCT) *plParam; - Tk_FontMetrics fontMetrics; - int drawingParameters = 0; - - if (itemPtr != NULL && tsdPtr->modalMenuPtr != NULL) { - Tk_Font tkfont; - - if (itemPtr->itemState & ODS_NOACCEL && !showMenuAccelerators) { - drawingParameters |= DRAW_MENU_ENTRY_NOUNDERLINE; - } - mePtr = (TkMenuEntry *) itemPtr->itemData; - menuPtr = mePtr->menuPtr; - twdPtr = ckalloc(sizeof(TkWinDrawable)); - twdPtr->type = TWD_WINDC; - twdPtr->winDC.hdc = itemPtr->hDC; - - if (mePtr->state != ENTRY_DISABLED) { - if (itemPtr->itemState & ODS_SELECTED) { - TkActivateMenuEntry(menuPtr, mePtr->index); - } else { - TkActivateMenuEntry(menuPtr, -1); - } - } else { - /* - * On windows, menu entries should highlight even if they are - * disabled. (I know this seems dumb, but it is the way native - * windows menus works so we ought to mimic it.) The - * ENTRY_PLATFORM_FLAG1 flag will indicate that the entry - * should be highlighted even though it is disabled. - */ - - if (itemPtr->itemState & ODS_SELECTED) { - mePtr->entryFlags |= ENTRY_PLATFORM_FLAG1; - } else { - mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1; - } - - /* - * Also, set the DRAW_MENU_ENTRY_ARROW flag for a disabled - * cascade menu since we need to draw the arrow ourselves. - */ - - if (mePtr->type == CASCADE_ENTRY) { - drawingParameters |= DRAW_MENU_ENTRY_ARROW; - } - } - - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - Tk_GetFontMetrics(tkfont, &fontMetrics); - TkpDrawMenuEntry(mePtr, (Drawable) twdPtr, tkfont, &fontMetrics, - itemPtr->rcItem.left, itemPtr->rcItem.top, - itemPtr->rcItem.right - itemPtr->rcItem.left, - itemPtr->rcItem.bottom - itemPtr->rcItem.top, - 0, drawingParameters); - - ckfree(twdPtr); - } - *plResult = 1; - returnResult = 1; - break; - } - - case WM_MENUSELECT: { - UINT flags = HIWORD(*pwParam); - - TkMenuInit(); - - if ((flags == 0xFFFF) && (*plParam == 0)) { - if (tsdPtr->modalMenuPtr != NULL) { - Tcl_SetServiceMode(tsdPtr->oldServiceMode); - RecursivelyClearActiveMenu(tsdPtr->modalMenuPtr); - } - } else { - menuPtr = NULL; - if (*plParam != 0) { - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) *plParam); - if (hashEntryPtr != NULL) { - menuPtr = Tcl_GetHashValue(hashEntryPtr); - } - } - - if (menuPtr != NULL) { - long entryIndex = LOWORD(*pwParam); - - if ((menuPtr->menuType == MENUBAR) && menuPtr->tearoff) { - /* - * Windows passes the entry index starting at 0 for - * the first menu entry. However this entry #0 is the - * tearoff entry for Tk (the menu has -tearoff 1), - * which is ignored for MENUBAR menues on Windows. - */ - - entryIndex++; - } - mePtr = NULL; - if (flags != 0xFFFF) { - if ((flags&MF_POPUP) && (entryIndex<menuPtr->numEntries)) { - mePtr = menuPtr->entries[entryIndex]; - } else { - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable, - INT2PTR(entryIndex)); - if (hashEntryPtr != NULL) { - mePtr = Tcl_GetHashValue(hashEntryPtr); - } - } - } - - if ((mePtr == NULL) || (mePtr->state == ENTRY_DISABLED)) { - TkActivateMenuEntry(menuPtr, -1); - } else { - if (mePtr->index >= menuPtr->numEntries) { - Tcl_Panic("Trying to activate an entry which doesn't exist"); - } - TkActivateMenuEntry(menuPtr, mePtr->index); - } - MenuSelectEvent(menuPtr); - Tcl_ServiceAll(); - *plResult = 0; - returnResult = 1; - } - } - break; - } - } - return returnResult; -} - -/* - *---------------------------------------------------------------------- - * - * RecursivelyClearActiveMenu -- - * - * Recursively clears the active entry in the menu's cascade hierarchy. - * - * Results: - * None. - * - * Side effects: - * Generates <<MenuSelect>> virtual events. - * - *---------------------------------------------------------------------- - */ - -void -RecursivelyClearActiveMenu( - TkMenu *menuPtr) /* The menu to reset. */ -{ - int i; - TkMenuEntry *mePtr; - - TkActivateMenuEntry(menuPtr, -1); - MenuSelectEvent(menuPtr); - for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - if (mePtr->state == ENTRY_ACTIVE) { - mePtr->state = ENTRY_NORMAL; - } - mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1; - if (mePtr->type == CASCADE_ENTRY) { - if ((mePtr->childMenuRefPtr != NULL) - && (mePtr->childMenuRefPtr->menuPtr != NULL)) { - RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpSetWindowMenuBar -- - * - * Associates a given menu with a window. - * - * Results: - * None. - * - * Side effects: - * On Windows and UNIX, associates the platform menu with the - * platform window. - * - *---------------------------------------------------------------------- - */ - -void -TkpSetWindowMenuBar( - Tk_Window tkwin, /* The window we are putting the menubar - * into.*/ - TkMenu *menuPtr) /* The menu we are inserting */ -{ - HMENU winMenuHdl; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (menuPtr != NULL) { - Tcl_HashEntry *hashEntryPtr; - int newEntry; - - winMenuHdl = (HMENU) menuPtr->platformData; - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) winMenuHdl); - Tcl_DeleteHashEntry(hashEntryPtr); - DestroyMenu(winMenuHdl); - winMenuHdl = CreateMenu(); - hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, - (char *) winMenuHdl, &newEntry); - Tcl_SetHashValue(hashEntryPtr, menuPtr); - menuPtr->platformData = (TkMenuPlatformData) winMenuHdl; - TkWinSetMenu(tkwin, winMenuHdl); - ScheduleMenuReconfigure(menuPtr); - } else { - TkWinSetMenu(tkwin, NULL); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpSetMainMenubar -- - * - * Puts the menu associated with a window into the menubar. Should only - * be called when the window is in front. - * - * Results: - * None. - * - * Side effects: - * The menubar is changed. - * - *---------------------------------------------------------------------- - */ - -void -TkpSetMainMenubar( - Tcl_Interp *interp, /* The interpreter of the application */ - Tk_Window tkwin, /* The frame we are setting up */ - const char *menuName) /* The name of the menu to put in front. If - * NULL, use the default menu bar. */ -{ - /* - * Nothing to do. - */ -} - -/* - *---------------------------------------------------------------------- - * - * GetMenuIndicatorGeometry -- - * - * Gets the width and height of the indicator area of a menu. - * - * Results: - * widthPtr and heightPtr are set. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -GetMenuIndicatorGeometry( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* Precalculated font */ - const Tk_FontMetrics *fmPtr,/* Precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ -{ - *heightPtr = indicatorDimensions[0]; - if (mePtr->hideMargin) { - *widthPtr = 0; - } else { - int borderWidth; - - Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, - menuPtr->borderWidthPtr, &borderWidth); - *widthPtr = indicatorDimensions[1] - borderWidth; - } -} - -/* - *---------------------------------------------------------------------- - * - * GetMenuAccelGeometry -- - * - * Gets the width and height of the indicator area of a menu. - * - * Results: - * widthPtr and heightPtr are set. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -GetMenuAccelGeometry( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ -{ - *heightPtr = fmPtr->linespace; - if (mePtr->type == CASCADE_ENTRY) { - *widthPtr = 0; - } else if ((menuPtr->menuType != MENUBAR) && (mePtr->accelPtr != NULL)) { - const char *accel = Tcl_GetString(mePtr->accelPtr); - - *widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength); - } else { - *widthPtr = 0; - } -} - -/* - *---------------------------------------------------------------------- - * - * GetTearoffEntryGeometry -- - * - * Gets the width and height of the indicator area of a menu. - * - * Results: - * widthPtr and heightPtr are set. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -GetTearoffEntryGeometry( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ -{ - if (menuPtr->menuType != MASTER_MENU) { - *heightPtr = 0; - } else { - *heightPtr = fmPtr->linespace; - } - *widthPtr = 0; -} - -/* - *---------------------------------------------------------------------- - * - * GetMenuSeparatorGeometry -- - * - * Gets the width and height of the indicator area of a menu. - * - * Results: - * widthPtr and heightPtr are set. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -GetMenuSeparatorGeometry( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - const Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ -{ - *widthPtr = 0; - *heightPtr = fmPtr->linespace - (2 * fmPtr->descent); -} - -/* - *---------------------------------------------------------------------- - * - * DrawWindowsSystemBitmap -- - * - * Draws the windows system bitmap given by bitmapID into the rect given - * by rectPtr in the drawable. The bitmap is centered in the rectangle. - * It is not clipped, so if the bitmap is bigger than the rect it will - * bleed. - * - * Results: - * None. - * - * Side effects: - * Drawing occurs. Some storage is allocated and released. - * - *---------------------------------------------------------------------- - */ - -static void -DrawWindowsSystemBitmap( - Display *display, /* The display we are drawing into */ - Drawable drawable, /* The drawable we are working with */ - GC gc, /* The GC to draw with */ - const RECT *rectPtr, /* The rectangle to draw into */ - int bitmapID, /* The windows id of the system bitmap to - * draw. */ - int alignFlags) /* How to align the bitmap inside the - * rectangle. */ -{ - TkWinDCState state; - HDC hdc = TkWinGetDrawableDC(display, drawable, &state); - HDC scratchDC; - HBITMAP bitmap; - BITMAP bm; - POINT ptSize; - POINT ptOrg; - int topOffset, leftOffset; - - SetBkColor(hdc, gc->background); - SetTextColor(hdc, gc->foreground); - - scratchDC = CreateCompatibleDC(hdc); - bitmap = LoadBitmap(NULL, MAKEINTRESOURCE(bitmapID)); - - SelectObject(scratchDC, bitmap); - SetMapMode(scratchDC, GetMapMode(hdc)); - GetObjectA(bitmap, sizeof(BITMAP), &bm); - ptSize.x = bm.bmWidth; - ptSize.y = bm.bmHeight; - DPtoLP(scratchDC, &ptSize, 1); - - ptOrg.y = ptOrg.x = 0; - DPtoLP(scratchDC, &ptOrg, 1); - - if (alignFlags & ALIGN_BITMAP_TOP) { - topOffset = 0; - } else if (alignFlags & ALIGN_BITMAP_BOTTOM) { - topOffset = (rectPtr->bottom - rectPtr->top) - ptSize.y; - } else { - topOffset = (rectPtr->bottom - rectPtr->top) / 2 - (ptSize.y / 2); - } - - if (alignFlags & ALIGN_BITMAP_LEFT) { - leftOffset = 0; - } else if (alignFlags & ALIGN_BITMAP_RIGHT) { - leftOffset = (rectPtr->right - rectPtr->left) - ptSize.x; - } else { - leftOffset = (rectPtr->right - rectPtr->left) / 2 - (ptSize.x / 2); - } - - BitBlt(hdc, rectPtr->left + leftOffset, rectPtr->top + topOffset, ptSize.x, - ptSize.y, scratchDC, ptOrg.x, ptOrg.y, SRCCOPY); - DeleteDC(scratchDC); - DeleteObject(bitmap); - - TkWinReleaseDrawableDC(drawable, hdc, &state); -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuEntryIndicator -- - * - * This function draws the indicator part of a menu. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its current mode. - * - *---------------------------------------------------------------------- - */ - -void -DrawMenuEntryIndicator( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc we are drawing with */ - GC indicatorGC, /* The gc for indicator objects */ - Tk_Font tkfont, /* The precalculated font */ - const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ - int x, /* Left edge */ - int y, /* Top edge */ - int width, - int height) -{ - if ((mePtr->type == CHECK_BUTTON_ENTRY) - || (mePtr->type == RADIO_BUTTON_ENTRY)) { - if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) { - RECT rect; - GC whichGC; - int borderWidth, activeBorderWidth; - - if (mePtr->state != ENTRY_NORMAL) { - whichGC = gc; - } else { - whichGC = indicatorGC; - } - - rect.top = y; - rect.bottom = y + mePtr->height; - Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, - menuPtr->borderWidthPtr, &borderWidth); - Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, &activeBorderWidth); - rect.left = borderWidth + activeBorderWidth + x; - rect.right = mePtr->indicatorSpace + x; - - if ((mePtr->state == ENTRY_DISABLED) - && (menuPtr->disabledFgPtr != NULL)) { - RECT hilightRect; - COLORREF oldFgColor = whichGC->foreground; - - whichGC->foreground = GetSysColor(COLOR_3DHILIGHT); - hilightRect.top = rect.top + 1; - hilightRect.bottom = rect.bottom + 1; - hilightRect.left = rect.left + 1; - hilightRect.right = rect.right + 1; - DrawWindowsSystemBitmap(menuPtr->display, d, whichGC, - &hilightRect, OBM_CHECK, 0); - whichGC->foreground = oldFgColor; - } - - DrawWindowsSystemBitmap(menuPtr->display, d, whichGC, &rect, - OBM_CHECK, 0); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuEntryAccelerator -- - * - * This function draws the accelerator part of a menu. For example, the - * string "CTRL-Z" could be drawn to to the right of the label text for - * an Undo menu entry. Need to decide what to draw here. Should we - * replace strings like "Control", "Command", etc? - * - * Results: - * None. - * - * Side effects: - * Commands are output to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ - -void -DrawMenuEntryAccelerator( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc we are drawing with */ - Tk_Font tkfont, /* The precalculated font */ - const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ - Tk_3DBorder activeBorder, /* The border when an item is active */ - int x, /* left edge */ - int y, /* top edge */ - int width, /* Width of menu entry */ - int height) /* Height of menu entry */ -{ - int baseline; - int leftEdge = x + mePtr->indicatorSpace + mePtr->labelWidth; - const char *accel; - - if (menuPtr->menuType == MENUBAR) { - return; - } - - if (mePtr->accelPtr != NULL) { - accel = Tcl_GetString(mePtr->accelPtr); - } else { - accel = NULL; - } - - baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - - /* - * Draw disabled 3D text highlight only with the Win95/98 look. - */ - - if (TkWinGetPlatformTheme() == TK_THEME_WIN_CLASSIC) { - if ((mePtr->state == ENTRY_DISABLED) - && (menuPtr->disabledFgPtr != NULL) && (accel != NULL)) { - COLORREF oldFgColor = gc->foreground; - - gc->foreground = GetSysColor(COLOR_3DHILIGHT); - if (!(mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)) { - Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, - mePtr->accelLength, leftEdge + 1, baseline + 1); - } - gc->foreground = oldFgColor; - } - } - - if (accel != NULL) { - Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, - mePtr->accelLength, leftEdge, baseline); - } -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuEntryArrow -- - * - * This function draws the arrow bitmap on the right side of a menu - * entry. This function is only used when drawing the arrow for a - * disabled cascade menu. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -DrawMenuEntryArrow( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc we are drawing with */ - Tk_3DBorder activeBorder, /* The border when an item is active */ - int x, /* left edge */ - int y, /* top edge */ - int width, /* Width of menu entry */ - int height, /* Height of menu entry */ - int drawArrow) /* For cascade menus, whether of not to draw - * the arraw. I cannot figure out Windows' - * algorithm for where to draw this. */ -{ - COLORREF oldFgColor; - COLORREF oldBgColor; - RECT rect; - - if (!drawArrow || (mePtr->type != CASCADE_ENTRY)) { - return; - } - - oldFgColor = gc->foreground; - oldBgColor = gc->background; - - /* - * Set bitmap bg to highlight color if the menu is highlighted. - */ - - if (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) { - XColor *activeBgColor = Tk_3DBorderColor(Tk_Get3DBorderFromObj( - mePtr->menuPtr->tkwin, (mePtr->activeBorderPtr == NULL) - ? mePtr->menuPtr->activeBorderPtr - : mePtr->activeBorderPtr)); - - gc->background = activeBgColor->pixel; - } - - gc->foreground = GetSysColor((mePtr->state == ENTRY_DISABLED) - ? COLOR_GRAYTEXT - : ((mePtr->state == ENTRY_ACTIVE) - ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT)); - - rect.top = y + GetSystemMetrics(SM_CYBORDER); - rect.bottom = y + height - GetSystemMetrics(SM_CYBORDER); - rect.left = x + mePtr->indicatorSpace + mePtr->labelWidth; - rect.right = x + width; - - DrawWindowsSystemBitmap(menuPtr->display, d, gc, &rect, OBM_MNARROW, - ALIGN_BITMAP_RIGHT); - - gc->foreground = oldFgColor; - gc->background = oldBgColor; - return; -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuSeparator -- - * - * The menu separator is drawn. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its current mode. - * - *---------------------------------------------------------------------- - */ - -void -DrawMenuSeparator( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc we are drawing with */ - Tk_Font tkfont, /* The precalculated font */ - const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ - int x, /* left edge */ - int y, /* top edge */ - int width, /* width of item */ - int height) /* height of item */ -{ - XPoint points[2]; - Tk_3DBorder border; - - points[0].x = x; - points[0].y = y + height / 2; - points[1].x = x + width - 1; - points[1].y = points[0].y; - border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); - Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1, - TK_RELIEF_RAISED); -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuUnderline -- - * - * On appropriate platforms, draw the underline character for the menu. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its current mode. - * - *---------------------------------------------------------------------- - */ - -static void -DrawMenuUnderline( - TkMenu *menuPtr, /* The menu to draw into */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc to draw into */ - Tk_Font tkfont, /* The precalculated font */ - const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ - int x, /* Left Edge */ - int y, /* Top Edge */ - int width, /* Width of entry */ - int height) /* Height of entry */ -{ - if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) { - int len; - - /* do the unicode call just to prevent overruns */ - Tcl_GetUnicodeFromObj(mePtr->labelPtr, &len); - if (mePtr->underline < len) { - const char *label, *start, *end; - - label = Tcl_GetString(mePtr->labelPtr); - start = Tcl_UtfAtIndex(label, mePtr->underline); - end = Tcl_UtfNext(start); - Tk_UnderlineChars(menuPtr->display, d, - gc, tkfont, label, x + mePtr->indicatorSpace, - y + (height + fmPtr->ascent - fmPtr->descent) / 2, - (int) (start - label), (int) (end - label)); - } - } -} - -/* - *-------------------------------------------------------------- - * - * TkWinMenuKeyObjCmd -- - * - * This function is invoked when keys related to pulling down menus is - * pressed. The corresponding Windows events are generated and passed to - * DefWindowProc if appropriate. This cmd is registered as tk::WinMenuKey - * in the interp. - * - * Results: - * Always returns TCL_OK. - * - * Side effects: - * The menu system may take over and process user events for menu input. - * - *-------------------------------------------------------------- - */ - -static int -TkWinMenuKeyObjCmd( - ClientData clientData, /* Unused. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - UINT scanCode; - UINT virtualKey; - XEvent *eventPtr; - Tk_Window tkwin; - TkWindow *winPtr; - KeySym keySym; - int i; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 1, objv, "window keySym"); - return TCL_ERROR; - } - - tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), - Tk_MainWindow(interp)); - - if (tkwin == NULL) { - /* - * If we don't find the key, just return, as the window may have - * been destroyed in the binding. [Bug 1236306] - */ - return TCL_OK; - } - - eventPtr = TkpGetBindingXEvent(interp); - - winPtr = (TkWindow *)tkwin; - - if (Tcl_GetIntFromObj(interp, objv[2], &i) != TCL_OK) { - return TCL_ERROR; - } - keySym = i; - - if (eventPtr->type == KeyPress) { - switch (keySym) { - case XK_Alt_L: - scanCode = MapVirtualKey(VK_LMENU, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSKEYDOWN, VK_MENU, - (int) (scanCode << 16) | (1 << 29)); - break; - case XK_Alt_R: - scanCode = MapVirtualKey(VK_RMENU, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSKEYDOWN, VK_MENU, - (int) (scanCode << 16) | (1 << 29) | (1 << 24)); - break; - case XK_F10: - scanCode = MapVirtualKey(VK_F10, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSKEYDOWN, VK_F10, (int) (scanCode << 16)); - break; - default: - virtualKey = XKeysymToKeycode(winPtr->display, keySym); - scanCode = MapVirtualKey(virtualKey, 0); - if (0 != scanCode) { - XKeyEvent xkey = eventPtr->xkey; - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSKEYDOWN, virtualKey, - (int) ((scanCode << 16) | (1 << 29))); - if (xkey.nbytes > 0) { - for (i = 0; i < xkey.nbytes; i++) { - CallWindowProc(DefWindowProc, - Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR, - xkey.trans_chars[i], - (int) ((scanCode << 16) | (1 << 29))); - } - } - } - } - } else if (eventPtr->type == KeyRelease) { - switch (keySym) { - case XK_Alt_L: - scanCode = MapVirtualKey(VK_LMENU, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16) - | (1 << 29) | (1 << 30) | (1 << 31)); - break; - case XK_Alt_R: - scanCode = MapVirtualKey(VK_RMENU, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16) | (1 << 24) - | (1 << 29) | (1 << 30) | (1 << 31)); - break; - case XK_F10: - scanCode = MapVirtualKey(VK_F10, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSKEYUP, VK_F10, - (int) (scanCode << 16) | (1 << 30) | (1 << 31)); - break; - default: - virtualKey = XKeysymToKeycode(winPtr->display, keySym); - scanCode = MapVirtualKey(virtualKey, 0); - if (0 != scanCode) { - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSKEYUP, virtualKey, (int) ((scanCode << 16) - | (1 << 29) | (1 << 30) | (1 << 31))); - } - } - } - return TCL_OK; -} - -/* - *-------------------------------------------------------------- - * - * TkpInitializeMenuBindings -- - * - * For every interp, initializes the bindings for Windows menus. Does - * nothing on Mac or XWindows. - * - * Results: - * None. - * - * Side effects: - * bindings are setup for the interp which will handle Alt-key sequences - * for menus without beeping or interfering with user-defined Alt-key - * bindings. - * - *-------------------------------------------------------------- - */ - -void -TkpInitializeMenuBindings( - Tcl_Interp *interp, /* The interpreter to set. */ - Tk_BindingTable bindingTable) - /* The table to add to. */ -{ - Tk_Uid uid = Tk_GetUid("all"); - - /* - * We need to set up the bindings for menubars. These have to recreate - * windows events, so we need to invoke C code to generate the - * WM_SYSKEYDOWNS and WM_SYSKEYUPs appropriately. Trick is, we can't - * create a C level binding directly since we may want to modify the - * binding in Tcl code. - */ - - (void) Tcl_CreateObjCommand(interp, "tk::WinMenuKey", - TkWinMenuKeyObjCmd, - (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); - - (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, - "<Alt_L>", "tk::WinMenuKey %W %N", 0); - - (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, - "<KeyRelease-Alt_L>", "tk::WinMenuKey %W %N", 0); - - (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, - "<Alt_R>", "tk::WinMenuKey %W %N", 0); - - (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, - "<KeyRelease-Alt_R>", "tk::WinMenuKey %W %N", 0); - - (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, - "<Alt-KeyPress>", "tk::WinMenuKey %W %N", 0); - - (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, - "<Alt-KeyRelease>", "tk::WinMenuKey %W %N", 0); - - (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, - "<KeyPress-F10>", "tk::WinMenuKey %W %N", 0); - - (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, - "<KeyRelease-F10>", "tk::WinMenuKey %W %N", 0); -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuEntryLabel -- - * - * This function draws the label part of a menu. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ - -static void -DrawMenuEntryLabel( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc we are drawing into */ - Tk_Font tkfont, /* The precalculated font */ - const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ - int x, /* left edge */ - int y, /* right edge */ - int width, /* width of entry */ - int height, /* height of entry */ - int underline) /* accelerator cue should be drawn */ -{ - int indicatorSpace = mePtr->indicatorSpace; - int activeBorderWidth; - int leftEdge; - int imageHeight, imageWidth; - int textHeight = 0, textWidth = 0; - int haveImage = 0, haveText = 0; - int imageXOffset = 0, imageYOffset = 0; - int textXOffset = 0, textYOffset = 0; - - Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, &activeBorderWidth); - leftEdge = x + indicatorSpace + activeBorderWidth; - - /* - * Work out what we will need to draw first. - */ - - if (mePtr->image != NULL) { - Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); - haveImage = 1; - } else if (mePtr->bitmapPtr != NULL) { - Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - - Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight); - haveImage = 1; - } - if (!haveImage || (mePtr->compound != COMPOUND_NONE)) { - if (mePtr->labelLength > 0) { - const char *label = Tcl_GetString(mePtr->labelPtr); - - textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); - textHeight = fmPtr->linespace; - haveText = 1; - } - } - - /* - * Now work out what the relative positions are. - */ - - if (haveImage && haveText) { - int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth); - switch ((enum compound) mePtr->compound) { - case COMPOUND_TOP: - textXOffset = (fullWidth - textWidth)/2; - textYOffset = imageHeight/2 + 2; - imageXOffset = (fullWidth - imageWidth)/2; - imageYOffset = -textHeight/2; - break; - case COMPOUND_BOTTOM: - textXOffset = (fullWidth - textWidth)/2; - textYOffset = -imageHeight/2; - imageXOffset = (fullWidth - imageWidth)/2; - imageYOffset = textHeight/2 + 2; - break; - case COMPOUND_LEFT: - /* - * The standard image position on Windows is in the indicator - * space to the left of the entries, unless this entry is a - * radio|check button because then the indicator space will be - * used. - */ - - textXOffset = imageWidth + 2; - textYOffset = 0; - imageXOffset = 0; - imageYOffset = 0; - if ((mePtr->type != CHECK_BUTTON_ENTRY) - && (mePtr->type != RADIO_BUTTON_ENTRY)) { - textXOffset -= indicatorSpace; - if (textXOffset < 0) { - textXOffset = 0; - } - imageXOffset = -indicatorSpace; - } - break; - case COMPOUND_RIGHT: - textXOffset = 0; - textYOffset = 0; - imageXOffset = textWidth + 2; - imageYOffset = 0; - break; - case COMPOUND_CENTER: - textXOffset = (fullWidth - textWidth)/2; - textYOffset = 0; - imageXOffset = (fullWidth - imageWidth)/2; - imageYOffset = 0; - break; - case COMPOUND_NONE: - break; - } - } else { - textXOffset = 0; - textYOffset = 0; - imageXOffset = 0; - imageYOffset = 0; - } - - /* - * Draw label and/or bitmap or image for entry. - */ - - if (mePtr->image != NULL) { - if ((mePtr->selectImage != NULL) - && (mePtr->entryFlags & ENTRY_SELECTED)) { - Tk_RedrawImage(mePtr->selectImage, 0, 0, - imageWidth, imageHeight, d, leftEdge + imageXOffset, - (int) (y + (mePtr->height-imageHeight)/2 + imageYOffset)); - } else { - Tk_RedrawImage(mePtr->image, 0, 0, imageWidth, - imageHeight, d, leftEdge + imageXOffset, - (int) (y + (mePtr->height-imageHeight)/2 + imageYOffset)); - } - } else if (mePtr->bitmapPtr != NULL) { - Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, - (unsigned) imageWidth, (unsigned) imageHeight, - leftEdge + imageXOffset, - (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1); - } - if ((mePtr->compound != COMPOUND_NONE) || !haveImage) { - if (mePtr->labelLength > 0) { - int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - const char *label = Tcl_GetString(mePtr->labelPtr); - - if (TkWinGetPlatformTheme() == TK_THEME_WIN_CLASSIC) { - /* - * Win 95/98 systems draw disabled menu text with a 3D - * highlight, unless the menu item is highlighted, - */ - - if ((mePtr->state == ENTRY_DISABLED) && - !(mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)) { - COLORREF oldFgColor = gc->foreground; - - gc->foreground = GetSysColor(COLOR_3DHILIGHT); - Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, - mePtr->labelLength, leftEdge + textXOffset + 1, - baseline + textYOffset + 1); - gc->foreground = oldFgColor; - } - } - Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, - mePtr->labelLength, leftEdge + textXOffset, - baseline + textYOffset); - if (underline) { - DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, - x + textXOffset, y + textYOffset, width, height); - } - } - } - - if (mePtr->state == ENTRY_DISABLED) { - if (menuPtr->disabledFgPtr == NULL) { - XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y, - (unsigned) width, (unsigned) height); - } else if ((mePtr->image != NULL) - && (menuPtr->disabledImageGC != None)) { - XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC, - leftEdge + imageXOffset, - (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), - (unsigned) imageWidth, (unsigned) imageHeight); - } - } -} - -/* - *-------------------------------------------------------------- - * - * TkpComputeMenubarGeometry -- - * - * This function is invoked to recompute the size and layout of a menu - * that is a menubar clone. - * - * Results: - * None. - * - * Side effects: - * Fields of menu entries are changed to reflect their current positions, - * and the size of the menu window itself may be changed. - * - *-------------------------------------------------------------- - */ - -void -TkpComputeMenubarGeometry( - TkMenu *menuPtr) /* Structure describing menu. */ -{ - TkpComputeStandardMenuGeometry(menuPtr); -} - -/* - *---------------------------------------------------------------------- - * - * DrawTearoffEntry -- - * - * This function draws the background part of a menu. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its current mode. - * - *---------------------------------------------------------------------- - */ - -void -DrawTearoffEntry( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* The drawable we are drawing into */ - GC gc, /* The gc we are drawing with */ - Tk_Font tkfont, /* The font we are drawing with */ - const Tk_FontMetrics *fmPtr,/* The metrics we are drawing with */ - int x, int y, - int width, int height) -{ - XPoint points[2]; - int segmentWidth, maxX; - Tk_3DBorder border; - - if (menuPtr->menuType != MASTER_MENU) { - return; - } - - points[0].x = x; - points[0].y = y + height/2; - points[1].y = points[0].y; - segmentWidth = 6; - maxX = width - 1; - border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); - - while (points[0].x < maxX) { - points[1].x = points[0].x + segmentWidth; - if (points[1].x > maxX) { - points[1].x = maxX; - } - Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1, - TK_RELIEF_RAISED); - points[0].x += 2*segmentWidth; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpConfigureMenuEntry -- - * - * Processes configurations for menu entries. - * - * Results: - * Returns standard TCL result. If TCL_ERROR is returned, then the - * interp's result contains an error message. - * - * Side effects: - * Configuration information get set for mePtr; old resources get freed, - * if any need it. - * - *---------------------------------------------------------------------- - */ - -int -TkpConfigureMenuEntry( - register TkMenuEntry *mePtr)/* Information about menu entry; may or may - * not already have values for some fields. */ -{ - ScheduleMenuReconfigure(mePtr->menuPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkpDrawMenuEntry -- - * - * Draws the given menu entry at the given coordinates with the given - * attributes. - * - * Results: - * None. - * - * Side effects: - * X Server commands are executed to display the menu entry. - * - *---------------------------------------------------------------------- - */ - -void -TkpDrawMenuEntry( - TkMenuEntry *mePtr, /* The entry to draw */ - Drawable menuDrawable, /* Menu to draw into */ - Tk_Font tkfont, /* Precalculated font for menu */ - const Tk_FontMetrics *menuMetricsPtr, - /* Precalculated metrics for menu */ - int x, /* X-coordinate of topleft of entry */ - int y, /* Y-coordinate of topleft of entry */ - int width, /* Width of the entry rectangle */ - int height, /* Height of the current rectangle */ - int strictMotif, /* Boolean flag */ - int drawingParameters) /* Whether or not to draw the cascade arrow - * for cascade items and accelerator - * cues. Only applies to Windows. */ -{ - GC gc, indicatorGC; - TkMenu *menuPtr = mePtr->menuPtr; - Tk_3DBorder bgBorder, activeBorder; - const Tk_FontMetrics *fmPtr; - Tk_FontMetrics entryMetrics; - int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0; - int adjustedX, adjustedY; - int adjustedHeight = height - 2 * padY; - TkWinDrawable memWinDraw; - TkWinDCState dcState; - HBITMAP oldBitmap = NULL; - Drawable d; - HDC memDc = NULL, menuDc = NULL; - - /* - * If the menu entry includes an image then draw the entry into a - * compatible bitmap first. This avoids problems with clipping on - * animated menus. [Bug 1329198] - */ - - if (mePtr->image != NULL) { - menuDc = TkWinGetDrawableDC(menuPtr->display, menuDrawable, &dcState); - - memDc = CreateCompatibleDC(menuDc); - oldBitmap = SelectObject(memDc, - CreateCompatibleBitmap(menuDc, width, height) ); - - memWinDraw.type = TWD_WINDC; - memWinDraw.winDC.hdc = memDc; - d = (Drawable)&memWinDraw; - adjustedX = 0; - adjustedY = padY; - - } else { - d = menuDrawable; - adjustedX = x; - adjustedY = y + padY; - } - - /* - * Choose the gc for drawing the foreground part of the entry. - */ - - if ((mePtr->state == ENTRY_ACTIVE) && !strictMotif) { - gc = mePtr->activeGC; - if (gc == NULL) { - gc = menuPtr->activeGC; - } - } else { - TkMenuEntry *cascadeEntryPtr; - int parentDisabled = 0; - const char *name; - - for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr; - cascadeEntryPtr != NULL; - cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) { - name = Tcl_GetString(cascadeEntryPtr->namePtr); - if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) { - if (mePtr->state == ENTRY_DISABLED) { - parentDisabled = 1; - } - break; - } - } - - if (((parentDisabled || (mePtr->state == ENTRY_DISABLED))) - && (menuPtr->disabledFgPtr != NULL)) { - gc = mePtr->disabledGC; - if (gc == NULL) { - gc = menuPtr->disabledGC; - } - } else { - gc = mePtr->textGC; - if (gc == NULL) { - gc = menuPtr->textGC; - } - } - } - indicatorGC = mePtr->indicatorGC; - if (indicatorGC == NULL) { - indicatorGC = menuPtr->indicatorGC; - } - - bgBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, - (mePtr->borderPtr == NULL) ? menuPtr->borderPtr - : mePtr->borderPtr); - if (strictMotif) { - activeBorder = bgBorder; - } else { - activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, - (mePtr->activeBorderPtr == NULL) ? menuPtr->activeBorderPtr - : mePtr->activeBorderPtr); - } - - if (mePtr->fontPtr == NULL) { - fmPtr = menuMetricsPtr; - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr); - Tk_GetFontMetrics(tkfont, &entryMetrics); - fmPtr = &entryMetrics; - } - - /* - * Need to draw the entire background, including padding. On Unix, for - * menubars, we have to draw the rest of the entry taking into account the - * padding. - */ - - DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder, - bgBorder, adjustedX, adjustedY-padY, width, height); - - if (mePtr->type == SEPARATOR_ENTRY) { - DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, - fmPtr, adjustedX, adjustedY, width, adjustedHeight); - } else if (mePtr->type == TEAROFF_ENTRY) { - DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, - adjustedX, adjustedY, width, adjustedHeight); - } else { - DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, - adjustedX, adjustedY, width, adjustedHeight, - (drawingParameters & DRAW_MENU_ENTRY_NOUNDERLINE)?0:1); - DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr, - activeBorder, adjustedX, adjustedY, width, adjustedHeight); - DrawMenuEntryArrow(menuPtr, mePtr, d, gc, - activeBorder, adjustedX, adjustedY, width, adjustedHeight, - (drawingParameters & DRAW_MENU_ENTRY_ARROW)?1:0); - if (!mePtr->hideMargin) { - DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, - fmPtr, adjustedX, adjustedY, width, adjustedHeight); - } - } - - /* - * Copy the entry contents from the temporary bitmap to the menu. - */ - - if (mePtr->image != NULL) { - BitBlt(menuDc, x, y, width, height, memDc, 0, 0, SRCCOPY); - DeleteObject(SelectObject(memDc, oldBitmap)); - DeleteDC(memDc); - - TkWinReleaseDrawableDC(menuDrawable, menuDc, &dcState); - } -} - -/* - *---------------------------------------------------------------------- - * - * GetMenuLabelGeometry -- - * - * Figures out the size of the label portion of a menu item. - * - * Results: - * widthPtr and heightPtr are filled in with the correct geometry - * information. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetMenuLabelGeometry( - TkMenuEntry *mePtr, /* The entry we are computing */ - Tk_Font tkfont, /* The precalculated font */ - const Tk_FontMetrics *fmPtr,/* The precalculated metrics */ - int *widthPtr, /* The resulting width of the label portion */ - int *heightPtr) /* The resulting height of the label - * portion */ -{ - TkMenu *menuPtr = mePtr->menuPtr; - int haveImage = 0; - - if (mePtr->image != NULL) { - Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr); - haveImage = 1; - } else if (mePtr->bitmapPtr != NULL) { - Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - - Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr); - haveImage = 1; - } else { - *heightPtr = 0; - *widthPtr = 0; - } - - if (haveImage && (mePtr->compound == COMPOUND_NONE)) { - /* - * We don't care about the text in this case. - */ - } else { - /* - * Either it is compound or we don't have an image, - */ - - if (mePtr->labelPtr != NULL) { - int textWidth; - const char *label = Tcl_GetString(mePtr->labelPtr); - - textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); - - if ((mePtr->compound != COMPOUND_NONE) && haveImage) { - switch ((enum compound) mePtr->compound) { - case COMPOUND_TOP: - case COMPOUND_BOTTOM: - if (textWidth > *widthPtr) { - *widthPtr = textWidth; - } - - /* - * Add text and padding. - */ - - *heightPtr += fmPtr->linespace + 2; - break; - case COMPOUND_LEFT: - case COMPOUND_RIGHT: - if (fmPtr->linespace > *heightPtr) { - *heightPtr = fmPtr->linespace; - } - - /* - * Add text and padding. - */ - - *widthPtr += textWidth + 2; - break; - case COMPOUND_CENTER: - if (fmPtr->linespace > *heightPtr) { - *heightPtr = fmPtr->linespace; - } - if (textWidth > *widthPtr) { - *widthPtr = textWidth; - } - break; - case COMPOUND_NONE: - break; - } - } else { - /* - * We don't have an image or we're not compound. - */ - - *heightPtr = fmPtr->linespace; - *widthPtr = textWidth; - } - } else { - /* - * An empty entry still has this height. - */ - - *heightPtr = fmPtr->linespace; - } - } - *heightPtr += 1; -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuEntryBackground -- - * - * This function draws the background part of a menu. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its current mode. - * - *---------------------------------------------------------------------- - */ - -static void -DrawMenuEntryBackground( - TkMenu *menuPtr, /* The menu we are drawing. */ - TkMenuEntry *mePtr, /* The entry we are drawing. */ - Drawable d, /* What we are drawing into */ - Tk_3DBorder activeBorder, /* Border for active items */ - Tk_3DBorder bgBorder, /* Border for the background */ - int x, /* left edge */ - int y, /* top edge */ - int width, /* width of rectangle to draw */ - int height) /* height of rectangle to draw */ -{ - if (mePtr->state == ENTRY_ACTIVE - || (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)!=0 ) { - bgBorder = activeBorder; - } - Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height, 0, - TK_RELIEF_FLAT); -} - -/* - *-------------------------------------------------------------- - * - * TkpComputeStandardMenuGeometry -- - * - * This function is invoked to recompute the size and layout of a menu - * that is not a menubar clone. - * - * Results: - * None. - * - * Side effects: - * Fields of menu entries are changed to reflect their current positions, - * and the size of the menu window itself may be changed. - * - *-------------------------------------------------------------- - */ - -void -TkpComputeStandardMenuGeometry( - TkMenu *menuPtr) /* Structure describing menu. */ -{ - Tk_Font menuFont, tkfont; - Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr; - int x, y, height, width, indicatorSpace, labelWidth, accelWidth; - int windowWidth, windowHeight, accelSpace; - int i, j, lastColumnBreak = 0; - int activeBorderWidth, borderWidth; - - if (menuPtr->tkwin == NULL) { - return; - } - - Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, - menuPtr->borderWidthPtr, &borderWidth); - x = y = borderWidth; - indicatorSpace = labelWidth = accelWidth = 0; - windowHeight = 0; - - /* - * On the Mac especially, getting font metrics can be quite slow, so we - * want to do it intelligently. We are going to precalculate them and pass - * them down to all of the measuring and drawing routines. We will measure - * the font metrics of the menu once. If an entry does not have its own - * font set, then we give the geometry/drawing routines the menu's font - * and metrics. If an entry has its own font, we will measure that font - * and give all of the geometry/drawing the entry's font and metrics. - */ - - menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - Tk_GetFontMetrics(menuFont, &menuMetrics); - accelSpace = Tk_TextWidth(menuFont, "M", 1); - Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, &activeBorderWidth); - - for (i = 0; i < menuPtr->numEntries; i++) { - if (menuPtr->entries[i]->fontPtr == NULL) { - tkfont = menuFont; - fmPtr = &menuMetrics; - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - menuPtr->entries[i]->fontPtr); - Tk_GetFontMetrics(tkfont, &entryMetrics); - fmPtr = &entryMetrics; - } - if ((i > 0) && menuPtr->entries[i]->columnBreak) { - if (accelWidth != 0) { - labelWidth += accelSpace; - } - for (j = lastColumnBreak; j < i; j++) { - menuPtr->entries[j]->indicatorSpace = indicatorSpace; - menuPtr->entries[j]->labelWidth = labelWidth; - menuPtr->entries[j]->width = indicatorSpace + labelWidth - + accelWidth + 2 * activeBorderWidth; - menuPtr->entries[j]->x = x; - menuPtr->entries[j]->entryFlags &= ~ENTRY_LAST_COLUMN; - } - x += indicatorSpace + labelWidth + accelWidth - + 2 * borderWidth; - indicatorSpace = labelWidth = accelWidth = 0; - lastColumnBreak = i; - y = borderWidth; - } - - if (menuPtr->entries[i]->type == SEPARATOR_ENTRY) { - GetMenuSeparatorGeometry(menuPtr, menuPtr->entries[i], tkfont, - fmPtr, &width, &height); - menuPtr->entries[i]->height = height; - } else if (menuPtr->entries[i]->type == TEAROFF_ENTRY) { - GetTearoffEntryGeometry(menuPtr, menuPtr->entries[i], tkfont, - fmPtr, &width, &height); - menuPtr->entries[i]->height = height; - - } else { - /* - * For each entry, compute the height required by that particular - * entry, plus three widths: the width of the label, the width to - * allow for an indicator to be displayed to the left of the label - * (if any), and the width of the accelerator to be displayed to - * the right of the label (if any). These sizes depend, of course, - * on the type of the entry. - */ - - GetMenuLabelGeometry(menuPtr->entries[i], tkfont, fmPtr, &width, - &height); - menuPtr->entries[i]->height = height; - if (width > labelWidth) { - labelWidth = width; - } - - GetMenuAccelGeometry(menuPtr, menuPtr->entries[i], tkfont, - fmPtr, &width, &height); - if (height > menuPtr->entries[i]->height) { - menuPtr->entries[i]->height = height; - } - if (width > accelWidth) { - accelWidth = width; - } - - GetMenuIndicatorGeometry(menuPtr, menuPtr->entries[i], tkfont, - fmPtr, &width, &height); - if (height > menuPtr->entries[i]->height) { - menuPtr->entries[i]->height = height; - } - if (width > indicatorSpace) { - indicatorSpace = width; - } - - menuPtr->entries[i]->height += 2 * activeBorderWidth + 1; - } - menuPtr->entries[i]->y = y; - y += menuPtr->entries[i]->height; - if (y > windowHeight) { - windowHeight = y; - } - } - - if (accelWidth != 0) { - labelWidth += accelSpace; - } - for (j = lastColumnBreak; j < menuPtr->numEntries; j++) { - menuPtr->entries[j]->indicatorSpace = indicatorSpace; - menuPtr->entries[j]->labelWidth = labelWidth; - menuPtr->entries[j]->width = indicatorSpace + labelWidth - + accelWidth + 2 * activeBorderWidth; - menuPtr->entries[j]->x = x; - menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN; - } - windowWidth = x + indicatorSpace + labelWidth + accelWidth + accelSpace - + 2 * activeBorderWidth + 2 * borderWidth; - - - windowHeight += borderWidth; - - /* - * The X server doesn't like zero dimensions, so round up to at least 1 (a - * zero-sized menu should never really occur, anyway). - */ - - if (windowWidth <= 0) { - windowWidth = 1; - } - if (windowHeight <= 0) { - windowHeight = 1; - } - menuPtr->totalWidth = windowWidth; - menuPtr->totalHeight = windowHeight; -} - -/* - *---------------------------------------------------------------------- - * - * MenuSelectEvent -- - * - * Generates a "MenuSelect" virtual event. This can be used to do - * context-sensitive menu help. - * - * Results: - * None. - * - * Side effects: - * Places a virtual event on the event queue. - * - *---------------------------------------------------------------------- - */ - -static void -MenuSelectEvent( - TkMenu *menuPtr) /* the menu we have selected. */ -{ - XVirtualEvent event; - union {DWORD msgpos; POINTS point;} root; - - event.type = VirtualEvent; - event.serial = menuPtr->display->request; - event.send_event = 0; - event.display = menuPtr->display; - Tk_MakeWindowExist(menuPtr->tkwin); - event.event = Tk_WindowId(menuPtr->tkwin); - event.root = XRootWindow(menuPtr->display, 0); - event.subwindow = None; - event.time = TkpGetMS(); - - root.msgpos = GetMessagePos(); - event.x_root = root.point.x; - event.y_root = root.point.y; - event.state = TkWinGetModifierState(); - event.same_screen = 1; - event.name = Tk_GetUid("MenuSelect"); - event.user_data = NULL; - Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); -} - -/* - *---------------------------------------------------------------------- - * - * TkpMenuNotifyToplevelCreate -- - * - * This routine reconfigures the menu and the clones indicated by - * menuName becuase a toplevel has been created and any system menus need - * to be created. - * - * Results: - * None. - * - * Side effects: - * An idle handler is set up to do the reconfiguration. - * - *---------------------------------------------------------------------- - */ - -void -TkpMenuNotifyToplevelCreate( - Tcl_Interp *interp, /* The interp the menu lives in. */ - const char *menuName) /* The name of the menu to reconfigure. */ -{ - TkMenuReferences *menuRefPtr; - TkMenu *menuPtr; - - if ((menuName != NULL) && (menuName[0] != '\0')) { - menuRefPtr = TkFindMenuReferences(interp, menuName); - if ((menuRefPtr != NULL) && (menuRefPtr->menuPtr != NULL)) { - for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL; - menuPtr = menuPtr->nextInstancePtr) { - if (menuPtr->menuType == MENUBAR) { - ScheduleMenuReconfigure(menuPtr); - } - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetMenuHWND -- - * - * This function returns the HWND of a hidden menu Window that processes - * messages of a popup menu. This hidden menu window is used to handle - * either a dynamic popup menu in the same process or a pull-down menu of - * an embedded window in a different process. - * - * Results: - * Returns the HWND of the hidden menu Window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -HWND -Tk_GetMenuHWND( - Tk_Window tkwin) -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - TkMenuInit(); - return tsdPtr->embeddedMenuHWND; -} - -/* - *---------------------------------------------------------------------- - * - * MenuExitHandler -- - * - * Unregisters the class of utility windows. - * - * Results: - * None. - * - * Side effects: - * Menus have to be reinitialized next time. - * - *---------------------------------------------------------------------- - */ - -static void -MenuExitHandler( - ClientData clientData) /* Not used */ -{ - UnregisterClass(MENU_CLASS_NAME, Tk_GetHINSTANCE()); - UnregisterClass(EMBEDDED_MENU_CLASS_NAME, Tk_GetHINSTANCE()); -} - -/* - *---------------------------------------------------------------------- - * - * MenuExitHandler -- - * - * Throws away the utility window needed for menus and delete hash - * tables. - * - * Results: - * None. - * - * Side effects: - * Menus have to be reinitialized next time. - * - *---------------------------------------------------------------------- - */ - -static void -MenuThreadExitHandler( - ClientData clientData) /* Not used */ -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - DestroyWindow(tsdPtr->menuHWND); - DestroyWindow(tsdPtr->embeddedMenuHWND); - tsdPtr->menuHWND = NULL; - tsdPtr->embeddedMenuHWND = NULL; - - Tcl_DeleteHashTable(&tsdPtr->winMenuTable); - Tcl_DeleteHashTable(&tsdPtr->commandTable); -} - -/* - *---------------------------------------------------------------------- - * - * TkWinGetMenuSystemDefault -- - * - * Gets the Windows specific default value for a given X resource - * database name. - * - * Results: - * Returns a Tcl_Obj* with the default value. If there is no - * Windows-specific default for this attribute, returns NULL. This object - * has a ref count of 0. - * - * Side effects: - * Storage is allocated. - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj * -TkWinGetMenuSystemDefault( - Tk_Window tkwin, /* A window to use. */ - const char *dbName, /* The option database name. */ - const char *className) /* The name of the option class. */ -{ - Tcl_Obj *valuePtr = NULL; - - if ((strcmp(dbName, "activeBorderWidth") == 0) || - (strcmp(dbName, "borderWidth") == 0)) { - valuePtr = Tcl_NewIntObj(defaultBorderWidth); - } else if (strcmp(dbName, "font") == 0) { - valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString), -1); - } - - return valuePtr; -} - -/* - *---------------------------------------------------------------------- - * - * SetDefaults -- - * - * Read system menu settings (font, sizes of items, use of accelerators) - * This is called if the UI theme or settings are changed. - * - * Results: - * None. - * - * Side effects: - * May result in menu items being redrawn with different appearance. - * - *---------------------------------------------------------------------- - */ - -static void -SetDefaults( - int firstTime) /* Is this the first time this has been - * called? */ -{ - char sizeString[TCL_INTEGER_SPACE]; - char faceName[LF_FACESIZE]; - HDC scratchDC; - int bold = 0; - int italic = 0; - TEXTMETRIC tm; - int pointSize; - HFONT menuFont; - /* See: [Bug #3239768] tk8.4.19 (and later) WIN32 menu font support */ - struct { - NONCLIENTMETRICS metrics; -#if (WINVER < 0x0600) - int padding; -#endif - } nc; - OSVERSIONINFOW os; - - /* - * Set all of the default options. The loop will terminate when we run out - * of options via a break statement. - */ - - defaultBorderWidth = GetSystemMetrics(SM_CXBORDER); - if (GetSystemMetrics(SM_CYBORDER) > defaultBorderWidth) { - defaultBorderWidth = GetSystemMetrics(SM_CYBORDER); - } - - scratchDC = CreateDCA("DISPLAY", NULL, NULL, NULL); - if (!firstTime) { - Tcl_DStringFree(&menuFontDString); - } - Tcl_DStringInit(&menuFontDString); - - nc.metrics.cbSize = sizeof(nc); - - os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); - GetVersionExW(&os); - if (os.dwMajorVersion < 6) { - nc.metrics.cbSize -= sizeof(int); - } - - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, nc.metrics.cbSize, - &nc.metrics, 0); - menuFont = CreateFontIndirect(&nc.metrics.lfMenuFont); - SelectObject(scratchDC, menuFont); - GetTextMetrics(scratchDC, &tm); - GetTextFaceA(scratchDC, LF_FACESIZE, faceName); - pointSize = MulDiv(tm.tmHeight - tm.tmInternalLeading, - 72, GetDeviceCaps(scratchDC, LOGPIXELSY)); - if (tm.tmWeight >= 700) { - bold = 1; - } - if (tm.tmItalic) { - italic = 1; - } - - SelectObject(scratchDC, GetStockObject(SYSTEM_FONT)); - DeleteDC(scratchDC); - - DeleteObject(menuFont); - - Tcl_DStringAppendElement(&menuFontDString, faceName); - sprintf(sizeString, "%d", pointSize); - Tcl_DStringAppendElement(&menuFontDString, sizeString); - - if (bold || italic) { - Tcl_DString boldItalicDString; - - Tcl_DStringInit(&boldItalicDString); - if (bold) { - Tcl_DStringAppendElement(&boldItalicDString, "bold"); - } - if (italic) { - Tcl_DStringAppendElement(&boldItalicDString, "italic"); - } - Tcl_DStringAppendElement(&menuFontDString, - Tcl_DStringValue(&boldItalicDString)); - Tcl_DStringFree(&boldItalicDString); - } - - /* - * Now we go ahead and get the dimensions of the check mark and the - * appropriate margins. Since this is fairly hairy, we do it here to save - * time when traversing large sets of menu items. - * - * The code below was given to me by Microsoft over the phone. It is the - * only way to ensure menu items line up, and is not documented. - */ - - indicatorDimensions[0] = GetSystemMetrics(SM_CYMENUCHECK); - indicatorDimensions[1] = ((GetSystemMetrics(SM_CXFIXEDFRAME) + - GetSystemMetrics(SM_CXBORDER) - + GetSystemMetrics(SM_CXMENUCHECK) + 7) & 0xFFF8) - - GetSystemMetrics(SM_CXFIXEDFRAME); - - /* - * Accelerators used to be always underlines until Win2K when a system - * parameter was introduced to hide them unless Alt is pressed. - */ - - showMenuAccelerators = TRUE; - SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &showMenuAccelerators, 0); -} - -/* - *---------------------------------------------------------------------- - * - * TkpMenuInit -- - * - * Sets up the process-wide variables used by the menu package. - * - * Results: - * None. - * - * Side effects: - * lastMenuID gets initialized. - * - *---------------------------------------------------------------------- - */ - -void -TkpMenuInit(void) -{ - WNDCLASS wndClass; - - wndClass.style = CS_OWNDC; - wndClass.lpfnWndProc = TkWinMenuProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = Tk_GetHINSTANCE(); - wndClass.hIcon = NULL; - wndClass.hCursor = NULL; - wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - wndClass.lpszMenuName = NULL; - wndClass.lpszClassName = MENU_CLASS_NAME; - if (!RegisterClass(&wndClass)) { - Tcl_Panic("Failed to register menu window class"); - } - - wndClass.lpfnWndProc = TkWinEmbeddedMenuProc; - wndClass.lpszClassName = EMBEDDED_MENU_CLASS_NAME; - if (!RegisterClass(&wndClass)) { - Tcl_Panic("Failed to register embedded menu window class"); - } - - TkCreateExitHandler(MenuExitHandler, NULL); - SetDefaults(1); -} - -/* - *---------------------------------------------------------------------- - * - * TkpMenuThreadInit -- - * - * Sets up the thread-local hash tables used by the menu module. Assumes - * that TkpMenuInit has been called. - * - * Results: - * None. - * - * Side effects: - * Hash tables winMenuTable and commandTable are initialized. - * - *---------------------------------------------------------------------- - */ - -void -TkpMenuThreadInit(void) -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - tsdPtr->menuHWND = CreateWindow(MENU_CLASS_NAME, TEXT("MenuWindow"), WS_POPUP, - 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL); - - if (!tsdPtr->menuHWND) { - Tcl_Panic("Failed to create the menu window"); - } - - tsdPtr->embeddedMenuHWND = - CreateWindow(EMBEDDED_MENU_CLASS_NAME, TEXT("EmbeddedMenuWindow"), - WS_POPUP, 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL); - - if (!tsdPtr->embeddedMenuHWND) { - Tcl_Panic("Failed to create the embedded menu window"); - } - - Tcl_InitHashTable(&tsdPtr->winMenuTable, TCL_ONE_WORD_KEYS); - Tcl_InitHashTable(&tsdPtr->commandTable, TCL_ONE_WORD_KEYS); - - TkCreateThreadExitHandler(MenuThreadExitHandler, NULL); -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinPixmap.c b/tk8.6/win/tkWinPixmap.c deleted file mode 100644 index 1cf0634..0000000 --- a/tk8.6/win/tkWinPixmap.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * tkWinPixmap.c -- - * - * This file contains the Xlib emulation functions pertaining to creating - * and destroying pixmaps. - * - * Copyright (c) 1995 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - -/* - *---------------------------------------------------------------------- - * - * Tk_GetPixmap -- - * - * Creates an in memory drawing surface. - * - * Results: - * Returns a handle to a new pixmap. - * - * Side effects: - * Allocates a new Win32 bitmap. - * - *---------------------------------------------------------------------- - */ - -Pixmap -Tk_GetPixmap( - Display *display, - Drawable d, - int width, - int height, - int depth) -{ - TkWinDrawable *newTwdPtr, *twdPtr; - int planes; - Screen *screen; - - display->request++; - - newTwdPtr = ckalloc(sizeof(TkWinDrawable)); - newTwdPtr->type = TWD_BITMAP; - newTwdPtr->bitmap.depth = depth; - twdPtr = (TkWinDrawable *) d; - if (twdPtr->type != TWD_BITMAP) { - if (twdPtr->window.winPtr == NULL) { - newTwdPtr->bitmap.colormap = DefaultColormap(display, - DefaultScreen(display)); - } else { - newTwdPtr->bitmap.colormap = twdPtr->window.winPtr->atts.colormap; - } - } else { - newTwdPtr->bitmap.colormap = twdPtr->bitmap.colormap; - } - screen = &display->screens[0]; - planes = 1; - if (depth == screen->root_depth) { - planes = PTR2INT(screen->ext_data); - depth /= planes; - } - newTwdPtr->bitmap.handle = - CreateBitmap(width, height, (DWORD) planes, (DWORD) depth, NULL); - - /* - * CreateBitmap tries to use memory on the graphics card. If it fails, - * call CreateDIBSection which uses real memory; slower, but at least - * still works. [Bug 2080533] - */ - - if (newTwdPtr->bitmap.handle == NULL) { - static int repeatError = 0; - void *bits = NULL; - BITMAPINFO bitmapInfo; - HDC dc; - - memset(&bitmapInfo, 0, sizeof(bitmapInfo)); - bitmapInfo.bmiHeader.biSize = sizeof(bitmapInfo.bmiHeader); - bitmapInfo.bmiHeader.biWidth = width; - bitmapInfo.bmiHeader.biHeight = height; - bitmapInfo.bmiHeader.biPlanes = planes; - bitmapInfo.bmiHeader.biBitCount = depth; - bitmapInfo.bmiHeader.biCompression = BI_RGB; - bitmapInfo.bmiHeader.biSizeImage = 0; - dc = GetDC(NULL); - newTwdPtr->bitmap.handle = CreateDIBSection(dc, &bitmapInfo, - DIB_RGB_COLORS, &bits, 0, 0); - ReleaseDC(NULL, dc); - - /* - * Oh no! Things are still going wrong. Pop up a warning message here - * (because things will probably crash soon) which will encourage - * people to report this as a bug... - */ - - if (newTwdPtr->bitmap.handle == NULL && !repeatError) { - LPVOID lpMsgBuf; - - repeatError = 1; - if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR) &lpMsgBuf, 0, NULL)) { - MessageBoxA(NULL, (LPCSTR) lpMsgBuf, - "Tk_GetPixmap: Error from CreateDIBSection", - MB_OK | MB_ICONINFORMATION); - LocalFree(lpMsgBuf); - } - } - } - - if (newTwdPtr->bitmap.handle == NULL) { - ckfree(newTwdPtr); - return None; - } - - return (Pixmap) newTwdPtr; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_FreePixmap -- - * - * Release the resources associated with a pixmap. - * - * Results: - * None. - * - * Side effects: - * Deletes the bitmap created by Tk_GetPixmap. - * - *---------------------------------------------------------------------- - */ - -void -Tk_FreePixmap( - Display *display, - Pixmap pixmap) -{ - TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap; - - display->request++; - if (twdPtr != NULL) { - DeleteObject(twdPtr->bitmap.handle); - ckfree(twdPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkSetPixmapColormap -- - * - * The following function is a hack used by the photo widget to - * explicitly set the colormap slot of a Pixmap. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkSetPixmapColormap( - Pixmap pixmap, - Colormap colormap) -{ - TkWinDrawable *twdPtr = (TkWinDrawable *)pixmap; - twdPtr->bitmap.colormap = colormap; -} - -/* - *---------------------------------------------------------------------- - * - * XGetGeometry -- - * - * Retrieve the geometry of the given drawable. Note that this is a - * degenerate implementation that only returns the size of a pixmap or - * window. - * - * Results: - * Returns 0. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -XGetGeometry( - Display *display, - Drawable d, - Window *root_return, - int *x_return, - int *y_return, - unsigned int *width_return, - unsigned int *height_return, - unsigned int *border_width_return, - unsigned int *depth_return) -{ - TkWinDrawable *twdPtr = (TkWinDrawable *)d; - - if (twdPtr->type == TWD_BITMAP) { - HDC dc; - BITMAPINFO info; - - if (twdPtr->bitmap.handle == NULL) { - Tcl_Panic("XGetGeometry: invalid pixmap"); - } - dc = GetDC(NULL); - info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - info.bmiHeader.biBitCount = 0; - if (!GetDIBits(dc, twdPtr->bitmap.handle, 0, 0, NULL, &info, - DIB_RGB_COLORS)) { - Tcl_Panic("XGetGeometry: unable to get bitmap size"); - } - ReleaseDC(NULL, dc); - - *width_return = info.bmiHeader.biWidth; - *height_return = info.bmiHeader.biHeight; - } else if (twdPtr->type == TWD_WINDOW) { - RECT rect; - - if (twdPtr->window.handle == NULL) { - Tcl_Panic("XGetGeometry: invalid window"); - } - GetClientRect(twdPtr->window.handle, &rect); - *width_return = rect.right - rect.left; - *height_return = rect.bottom - rect.top; - } else { - Tcl_Panic("XGetGeometry: invalid window"); - } - return 1; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinPointer.c b/tk8.6/win/tkWinPointer.c deleted file mode 100644 index 6f1f840..0000000 --- a/tk8.6/win/tkWinPointer.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * tkWinPointer.c -- - * - * Windows specific mouse tracking code. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-1999 by Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - -/* - * Check for enter/leave events every MOUSE_TIMER_INTERVAL milliseconds. - */ - -#define MOUSE_TIMER_INTERVAL 250 - -/* - * Declarations of static variables used in this file. - */ - -static int captured = 0; /* 1 if mouse is currently captured. */ -static TkWindow *keyboardWinPtr = NULL; /* Current keyboard grab window. */ -static Tcl_TimerToken mouseTimer; /* Handle to the latest mouse timer. */ -static int mouseTimerSet = 0; /* 1 if the mouse timer is active. */ - -/* - * Forward declarations of procedures used in this file. - */ - -static void MouseTimerProc(ClientData clientData); - -/* - *---------------------------------------------------------------------- - * - * TkWinGetModifierState -- - * - * Return the modifier state as of the last message. - * - * Results: - * Returns the X modifier mask. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkWinGetModifierState(void) -{ - int state = 0; - - if (GetKeyState(VK_SHIFT) & 0x8000) { - state |= ShiftMask; - } - if (GetKeyState(VK_CONTROL) & 0x8000) { - state |= ControlMask; - } - if (GetKeyState(VK_MENU) & 0x8000) { - state |= ALT_MASK; - } - if (GetKeyState(VK_CAPITAL) & 0x0001) { - state |= LockMask; - } - if (GetKeyState(VK_NUMLOCK) & 0x0001) { - state |= Mod1Mask; - } - if (GetKeyState(VK_SCROLL) & 0x0001) { - state |= Mod3Mask; - } - if (GetKeyState(VK_LBUTTON) & 0x8000) { - state |= Button1Mask; - } - if (GetKeyState(VK_MBUTTON) & 0x8000) { - state |= Button2Mask; - } - if (GetKeyState(VK_RBUTTON) & 0x8000) { - state |= Button3Mask; - } - return state; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_PointerEvent -- - * - * This procedure is called for each pointer-related event. It converts - * the position to root coords and updates the global pointer state - * machine. It also ensures that the mouse timer is scheduled. - * - * Results: - * None. - * - * Side effects: - * May queue events and change the grab state. - * - *---------------------------------------------------------------------- - */ - -void -Tk_PointerEvent( - HWND hwnd, /* Window for coords, or NULL for the root - * window. */ - int x, int y) /* Coords relative to hwnd, or screen if hwnd - * is NULL. */ -{ - POINT pos; - int state; - Tk_Window tkwin; - - pos.x = x; - pos.y = y; - - /* - * Convert client coords to root coords if we were given a window. - */ - - if (hwnd) { - ClientToScreen(hwnd, &pos); - } - - /* - * If the mouse is captured, Windows will report all pointer events to the - * capture window. So, we need to determine which window the mouse is - * really over and change the event. Note that the computed hwnd may point - * to a window not owned by Tk, or a toplevel decorative frame, so tkwin - * can be NULL. - */ - - if (captured || hwnd == NULL) { - hwnd = WindowFromPoint(pos); - } - tkwin = Tk_HWNDToWindow(hwnd); - - state = TkWinGetModifierState(); - - Tk_UpdatePointer(tkwin, pos.x, pos.y, state); - - if ((captured || tkwin) && !mouseTimerSet) { - mouseTimerSet = 1; - mouseTimer = Tcl_CreateTimerHandler(MOUSE_TIMER_INTERVAL, - MouseTimerProc, NULL); - } -} - -/* - *---------------------------------------------------------------------- - * - * XGrabKeyboard -- - * - * Simulates a keyboard grab by setting the focus. - * - * Results: - * Always returns GrabSuccess. - * - * Side effects: - * Sets the keyboard focus to the specified window. - * - *---------------------------------------------------------------------- - */ - -int -XGrabKeyboard( - Display *display, - Window grab_window, - Bool owner_events, - int pointer_mode, - int keyboard_mode, - Time time) -{ - keyboardWinPtr = TkWinGetWinPtr(grab_window); - return GrabSuccess; -} - -/* - *---------------------------------------------------------------------- - * - * XUngrabKeyboard -- - * - * Releases the simulated keyboard grab. - * - * Results: - * None. - * - * Side effects: - * Sets the keyboard focus back to the value before the grab. - * - *---------------------------------------------------------------------- - */ - -int -XUngrabKeyboard( - Display *display, - Time time) -{ - keyboardWinPtr = NULL; - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * MouseTimerProc -- - * - * Check the current mouse position and look for enter/leave events. - * - * Results: - * None. - * - * Side effects: - * May schedule a new timer and/or generate enter/leave events. - * - *---------------------------------------------------------------------- - */ - -void -MouseTimerProc( - ClientData clientData) -{ - POINT pos; - - mouseTimerSet = 0; - - /* - * Get the current mouse position and window. Don't do anything if the - * mouse hasn't moved since the last time we looked. - */ - - GetCursorPos(&pos); - Tk_PointerEvent(NULL, pos.x, pos.y); -} - -/* - *---------------------------------------------------------------------- - * - * TkWinCancelMouseTimer -- - * - * If the mouse timer is set, cancel it. - * - * Results: - * None. - * - * Side effects: - * May cancel the mouse timer. - * - *---------------------------------------------------------------------- - */ - -void -TkWinCancelMouseTimer(void) -{ - if (mouseTimerSet) { - Tcl_DeleteTimerHandler(mouseTimer); - mouseTimerSet = 0; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkGetPointerCoords -- - * - * Fetch the position of the mouse pointer. - * - * Results: - * *xPtr and *yPtr are filled in with the root coordinates of the mouse - * pointer for the display. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkGetPointerCoords( - Tk_Window tkwin, /* Window that identifies screen on which - * lookup is to be done. */ - int *xPtr, int *yPtr) /* Store pointer coordinates here. */ -{ - POINT point; - - GetCursorPos(&point); - *xPtr = point.x; - *yPtr = point.y; -} - -/* - *---------------------------------------------------------------------- - * - * XQueryPointer -- - * - * Check the current state of the mouse. This is not a complete - * implementation of this function. It only computes the root coordinates - * and the current mask. - * - * Results: - * Sets root_x_return, root_y_return, and mask_return. Returns true on - * success. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Bool -XQueryPointer( - Display *display, - Window w, - Window *root_return, - Window *child_return, - int *root_x_return, - int *root_y_return, - int *win_x_return, - int *win_y_return, - unsigned int *mask_return) -{ - display->request++; - TkGetPointerCoords(NULL, root_x_return, root_y_return); - *mask_return = TkWinGetModifierState(); - return True; -} - -/* - *---------------------------------------------------------------------- - * - * XWarpPointer -- - * - * Move pointer to new location. This is not a complete implementation of - * this function. - * - * Results: - * None. - * - * Side effects: - * Mouse pointer changes position on screen. - * - *---------------------------------------------------------------------- - */ - -int -XWarpPointer( - Display *display, - Window src_w, - Window dest_w, - int src_x, - int src_y, - unsigned int src_width, - unsigned int src_height, - int dest_x, - int dest_y) -{ - RECT r; - - GetWindowRect(Tk_GetHWND(dest_w), &r); - SetCursorPos(r.left+dest_x, r.top+dest_y); - return Success; -} - -void -TkpWarpPointer( - TkDisplay *dispPtr) -{ - if (dispPtr->warpWindow) { - RECT r; - - GetWindowRect(Tk_GetHWND(Tk_WindowId(dispPtr->warpWindow)), &r); - SetCursorPos(r.left + dispPtr->warpX, r.top + dispPtr->warpY); - } else { - SetCursorPos(dispPtr->warpX, dispPtr->warpY); - } -} - -/* - *---------------------------------------------------------------------- - * - * XGetInputFocus -- - * - * Retrieves the current keyboard focus window. - * - * Results: - * Returns the current focus window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -XGetInputFocus( - Display *display, - Window *focus_return, - int *revert_to_return) -{ - Tk_Window tkwin = Tk_HWNDToWindow(GetFocus()); - - *focus_return = tkwin ? Tk_WindowId(tkwin) : None; - *revert_to_return = RevertToParent; - display->request++; - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XSetInputFocus -- - * - * Set the current focus window. - * - * Results: - * None. - * - * Side effects: - * Changes the keyboard focus and causes the selected window to - * be activated. - * - *---------------------------------------------------------------------- - */ - -int -XSetInputFocus( - Display *display, - Window focus, - int revert_to, - Time time) -{ - display->request++; - if (focus != None) { - SetFocus(Tk_GetHWND(focus)); - } - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * TkpChangeFocus -- - * - * This procedure is invoked to move the system focus from one window to - * another. - * - * Results: - * The return value is the serial number of the command that changed the - * focus. It may be needed by the caller to filter out focus change - * events that were queued before the command. If the procedure doesn't - * actually change the focus then it returns 0. - * - * Side effects: - * The official Windows focus window changes; the application's focus - * window isn't changed by this procedure. - * - *---------------------------------------------------------------------- - */ - -int -TkpChangeFocus( - TkWindow *winPtr, /* Window that is to receive the X focus. */ - int force) /* Non-zero means claim the focus even if it - * didn't originally belong to topLevelPtr's - * application. */ -{ - TkDisplay *dispPtr = winPtr->dispPtr; - Window focusWindow; - int dummy, serial; - TkWindow *winPtr2; - - if (!force) { - XGetInputFocus(dispPtr->display, &focusWindow, &dummy); - winPtr2 = (TkWindow *) Tk_IdToWindow(dispPtr->display, focusWindow); - if ((winPtr2 == NULL) || (winPtr2->mainPtr != winPtr->mainPtr)) { - return 0; - } - } - - if (winPtr->window == None) { - Tcl_Panic("ChangeXFocus got null X window"); - } - - /* - * Change the foreground window so the focus window is raised to the top - * of the system stacking order and gets the keyboard focus. - */ - - if (force) { - TkWinSetForegroundWindow(winPtr); - } - XSetInputFocus(dispPtr->display, winPtr->window, RevertToParent, - CurrentTime); - - /* - * Remember the current serial number for the X server and issue a dummy - * server request. This marks the position at which we changed the focus, - * so we can distinguish FocusIn and FocusOut events on either side of the - * mark. - */ - - serial = NextRequest(winPtr->display); - XNoOp(winPtr->display); - return serial; -} - -/* - *---------------------------------------------------------------------- - * - * TkpSetCapture -- - * - * This function captures the mouse so that all future events will be - * reported to this window, even if the mouse is outside the window. If - * the specified window is NULL, then the mouse is released. - * - * Results: - * None. - * - * Side effects: - * Sets the capture flag and captures the mouse. - * - *---------------------------------------------------------------------- - */ - -void -TkpSetCapture( - TkWindow *winPtr) /* Capture window, or NULL. */ -{ - if (winPtr) { - SetCapture(Tk_GetHWND(Tk_WindowId(winPtr))); - captured = 1; - } else { - captured = 0; - ReleaseCapture(); - } -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinPort.h b/tk8.6/win/tkWinPort.h deleted file mode 100644 index 965dbc5..0000000 --- a/tk8.6/win/tkWinPort.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * tkWinPort.h -- - * - * This header file handles porting issues that occur because of - * differences between Windows and Unix. It should be the only - * file that contains #ifdefs to handle different flavors of OS. - * - * Copyright (c) 1995-1996 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#ifndef _WINPORT -#define _WINPORT - -/* - *--------------------------------------------------------------------------- - * The following sets of #includes and #ifdefs are required to get Tcl to - * compile under the windows compilers. - *--------------------------------------------------------------------------- - */ - -#include <wchar.h> -#include <io.h> -#include <stdlib.h> -#include <errno.h> -#include <fcntl.h> -#include <malloc.h> -#include <ctype.h> -#include <math.h> -#include <string.h> -#include <limits.h> - -/* - * Need to block out this include for building extensions with MetroWerks - * compiler for Win32. - */ - -#ifndef __MWERKS__ -#include <sys/stat.h> -#endif - -#include <time.h> - -#ifdef _MSC_VER -# ifndef hypot -# define hypot _hypot -# endif -#endif /* _MSC_VER */ - -/* - * Pull in the typedef of TCHAR for windows. - */ -#include <tchar.h> -#ifndef _TCHAR_DEFINED - /* Borland seems to forget to set this. */ - typedef _TCHAR TCHAR; -# define _TCHAR_DEFINED -#endif -#if defined(_MSC_VER) && defined(__STDC__) - /* VS2005 SP1 misses this. See [Bug #3110161] */ - typedef _TCHAR TCHAR; -#endif - -#include <X11/Xlib.h> -#include <X11/cursorfont.h> -#include <X11/keysym.h> -#include <X11/Xatom.h> -#include <X11/Xutil.h> - -#ifndef __GNUC__ -# define strncasecmp _strnicmp -# define strcasecmp _stricmp -#endif - -#define NBBY 8 - -#ifndef OPEN_MAX -#define OPEN_MAX 32 -#endif - -/* - * The following define causes Tk to use its internal keysym hash table - */ - -#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. - */ - -#ifdef _MSC_VER -# define TK_READ_DATA_PENDING(f) ((f)->_cnt > 0) -#else /* _MSC_VER */ -# define TK_READ_DATA_PENDING(f) ((f)->level > 0) -#endif /* _MSC_VER */ - -/* - * The following Tk functions are implemented as macros under Windows. - */ - -#define TkpGetPixel(p) (((((p)->red >> 8) & 0xff) \ - | ((p)->green & 0xff00) | (((p)->blue << 8) & 0xff0000)) | 0x20000000) - -/* - * These calls implement native bitmaps which are not currently - * supported under Windows. The macros eliminate the calls. - */ - -#define TkpDefineNativeBitmaps() -#define TkpCreateNativeBitmap(display, source) None -#define TkpGetNativeAppBitmap(display, name, w, h) None - -#endif /* _WINPORT */ diff --git a/tk8.6/win/tkWinRegion.c b/tk8.6/win/tkWinRegion.c deleted file mode 100644 index d097047..0000000 --- a/tk8.6/win/tkWinRegion.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * tkWinRegion.c -- - * - * Tk Region emulation code. - * - * Copyright (c) 1995 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - -#undef TkCreateRegion -#undef TkDestroyRegion -#undef TkClipBox -#undef TkIntersectRegion -#undef TkUnionRectWithRegion -#undef TkRectInRegion -#undef TkSubtractRegion - -/* - *---------------------------------------------------------------------- - * - * TkCreateRegion -- - * - * Construct an empty region. - * - * Results: - * Returns a new region handle. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TkRegion -TkCreateRegion(void) -{ - RECT rect; - memset(&rect, 0, sizeof(RECT)); - return (TkRegion) CreateRectRgnIndirect(&rect); -} - -/* - *---------------------------------------------------------------------- - * - * TkDestroyRegion -- - * - * Destroy the specified region. - * - * Results: - * None. - * - * Side effects: - * Frees the storage associated with the specified region. - * - *---------------------------------------------------------------------- - */ - -void -TkDestroyRegion( - TkRegion r) -{ - DeleteObject((HRGN) r); -} - -/* - *---------------------------------------------------------------------- - * - * TkClipBox -- - * - * Computes the bounding box of a region. - * - * Results: - * Sets rect_return to the bounding box of the region. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkClipBox( - TkRegion r, - XRectangle* rect_return) -{ - RECT rect; - - GetRgnBox((HRGN)r, &rect); - rect_return->x = (short) rect.left; - rect_return->y = (short) rect.top; - rect_return->width = (short) (rect.right - rect.left); - rect_return->height = (short) (rect.bottom - rect.top); -} - -/* - *---------------------------------------------------------------------- - * - * TkIntersectRegion -- - * - * Compute the intersection of two regions. - * - * Results: - * Returns the result in the dr_return region. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkIntersectRegion( - TkRegion sra, - TkRegion srb, - TkRegion dr_return) -{ - CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_AND); -} - -/* - *---------------------------------------------------------------------- - * - * TkUnionRectWithRegion -- - * - * Create the union of a source region and a rectangle. - * - * Results: - * Returns the result in the dr_return region. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkUnionRectWithRegion( - XRectangle *rectangle, - TkRegion src_region, - TkRegion dest_region_return) -{ - HRGN rectRgn = CreateRectRgn(rectangle->x, rectangle->y, - rectangle->x + rectangle->width, rectangle->y + rectangle->height); - - CombineRgn((HRGN) dest_region_return, (HRGN) src_region, - (HRGN) rectRgn, RGN_OR); - DeleteObject(rectRgn); -} - -/* - *---------------------------------------------------------------------- - * - * TkpBuildRegionFromAlphaData -- - * - * Set up a rectangle of the given region based on the supplied alpha - * data. - * - * Results: - * None - * - * Side effects: - * The region is updated, with extra pixels added to it. - * - *---------------------------------------------------------------------- - */ - -void -TkpBuildRegionFromAlphaData( - TkRegion region, - unsigned int x, unsigned int y, - /* Where in region to update. */ - unsigned int width, unsigned int height, - /* Size of rectangle to update. */ - unsigned char *dataPtr, /* Data to read from. */ - unsigned int pixelStride, /* Num bytes from one piece of alpha data to - * the next in the line. */ - unsigned int lineStride) /* Num bytes from one line of alpha data to - * the next line. */ -{ - unsigned char *lineDataPtr; - unsigned int x1, y1, end; - HRGN rectRgn = CreateRectRgn(0,0,1,1); /* Workspace region. */ - - for (y1 = 0; y1 < height; y1++) { - lineDataPtr = dataPtr; - for (x1 = 0; x1 < width; x1 = end) { - /* - * Search for first non-transparent pixel. - */ - - while ((x1 < width) && !*lineDataPtr) { - x1++; - lineDataPtr += pixelStride; - } - end = x1; - - /* - * Search for first transparent pixel. - */ - - while ((end < width) && *lineDataPtr) { - end++; - lineDataPtr += pixelStride; - } - if (end > x1) { - /* - * Manipulate Win32 regions directly; it's more efficient. - */ - - SetRectRgn(rectRgn, (int) (x+x1), (int) (y+y1), - (int) (x+end), (int) (y+y1+1)); - CombineRgn((HRGN) region, (HRGN) region, rectRgn, RGN_OR); - } - } - dataPtr += lineStride; - } - - DeleteObject(rectRgn); -} - -/* - *---------------------------------------------------------------------- - * - * TkRectInRegion -- - * - * Test whether a given rectangle overlaps with a region. - * - * Results: - * Returns RectanglePart or RectangleOut. Note that this is not a - * complete implementation since it doesn't test for RectangleIn. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkRectInRegion( - TkRegion r, /* Region to inspect */ - int x, int y, /* Top-left of rectangle */ - unsigned int width, /* Width of rectangle */ - unsigned int height) /* Height of rectangle */ -{ - RECT rect; - rect.top = y; - rect.left = x; - rect.bottom = y+height; - rect.right = x+width; - return RectInRegion((HRGN)r, &rect) ? RectanglePart : RectangleOut; -} - -/* - *---------------------------------------------------------------------- - * - * TkSubtractRegion -- - * - * Compute the set-difference of two regions. - * - * Results: - * Returns the result in the dr_return region. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkSubtractRegion( - TkRegion sra, - TkRegion srb, - TkRegion dr_return) -{ - CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_DIFF); -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinScrlbr.c b/tk8.6/win/tkWinScrlbr.c deleted file mode 100644 index 1b3717e..0000000 --- a/tk8.6/win/tkWinScrlbr.c +++ /dev/null @@ -1,701 +0,0 @@ -/* - * tkWinScrollbar.c -- - * - * This file implements the Windows specific portion of the scrollbar - * widget. - * - * Copyright (c) 1996 by Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" -#include "tkScrollbar.h" - -/* - * The following constant is used to specify the maximum scroll position. This - * value is limited by the Win32 API to either 16-bits or 32-bits, depending - * on the context. For now we'll just use a value small enough to fit in - * 16-bits, but which gives us 4-digits of precision. - */ - -#define MAX_SCROLL 10000 - -/* - * Declaration of Windows specific scrollbar structure. - */ - -typedef struct WinScrollbar { - TkScrollbar info; /* Generic scrollbar info. */ - WNDPROC oldProc; /* Old window procedure. */ - int lastVertical; /* 1 if was vertical at last refresh. */ - HWND hwnd; /* Current window handle. */ - int winFlags; /* Various flags; see below. */ -} WinScrollbar; - -/* - * Flag bits for native scrollbars: - * - * IN_MODAL_LOOP: Non-zero means this scrollbar is in the middle - * of a modal loop. - * ALREADY_DEAD: Non-zero means this scrollbar has been - * destroyed, but has not been cleaned up. - */ - -#define IN_MODAL_LOOP 1 -#define ALREADY_DEAD 2 - -/* - * Cached system metrics used to determine scrollbar geometry. - */ - -static int initialized = 0; -static int hArrowWidth, hThumb; /* Horizontal control metrics. */ -static int vArrowHeight, vThumb; /* Vertical control metrics. */ - -TCL_DECLARE_MUTEX(winScrlbrMutex) - -/* - * Declarations for functions defined in this file. - */ - -static Window CreateProc(Tk_Window tkwin, Window parent, - ClientData instanceData); -static void ModalLoop(WinScrollbar *, XEvent *eventPtr); -static LRESULT CALLBACK ScrollbarProc(HWND hwnd, UINT message, WPARAM wParam, - LPARAM lParam); -static void UpdateScrollbar(WinScrollbar *scrollPtr); -static void UpdateScrollbarMetrics(void); - -/* - * The class procedure table for the scrollbar widget. - */ - -const Tk_ClassProcs tkpScrollbarProcs = { - sizeof(Tk_ClassProcs), /* size */ - NULL, /* worldChangedProc */ - CreateProc, /* createProc */ - NULL /* modalProc */ -}; - -static void -WinScrollbarEventProc(ClientData clientData, XEvent *eventPtr) -{ - WinScrollbar *scrollPtr = clientData; - - if (eventPtr->type == ButtonPress) { - ModalLoop(scrollPtr, eventPtr); - } else { - TkScrollbarEventProc(clientData, eventPtr); - } -} - - -/* - *---------------------------------------------------------------------- - * - * TkpCreateScrollbar -- - * - * Allocate a new TkScrollbar structure. - * - * Results: - * Returns a newly allocated TkScrollbar structure. - * - * Side effects: - * Registers an event handler for the widget. - * - *---------------------------------------------------------------------- - */ - -TkScrollbar * -TkpCreateScrollbar( - Tk_Window tkwin) -{ - WinScrollbar *scrollPtr; - - if (!initialized) { - Tcl_MutexLock(&winScrlbrMutex); - UpdateScrollbarMetrics(); - initialized = 1; - Tcl_MutexUnlock(&winScrlbrMutex); - } - - scrollPtr = ckalloc(sizeof(WinScrollbar)); - scrollPtr->winFlags = 0; - scrollPtr->hwnd = NULL; - - Tk_CreateEventHandler(tkwin, - ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask, - WinScrollbarEventProc, scrollPtr); - - return (TkScrollbar *) scrollPtr; -} - -/* - *---------------------------------------------------------------------- - * - * UpdateScrollbar -- - * - * This function updates the position and size of the scrollbar thumb - * based on the current settings. - * - * Results: - * None. - * - * Side effects: - * Moves the thumb. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateScrollbar( - WinScrollbar *scrollPtr) -{ - SCROLLINFO scrollInfo; - double thumbSize; - - /* - * Update the current scrollbar position and shape. - */ - - scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; - scrollInfo.cbSize = sizeof(scrollInfo); - scrollInfo.nMin = 0; - scrollInfo.nMax = MAX_SCROLL; - thumbSize = (scrollPtr->info.lastFraction - scrollPtr->info.firstFraction); - scrollInfo.nPage = ((UINT) (thumbSize * (double) MAX_SCROLL)) + 1; - if (thumbSize < 1.0) { - scrollInfo.nPos = (int) - ((scrollPtr->info.firstFraction / (1.0-thumbSize)) - * (MAX_SCROLL - (scrollInfo.nPage - 1))); - } else { - scrollInfo.nPos = 0; - - /* - * Disable the scrollbar when there is nothing to scroll. This is - * standard Windows style (see eg Notepad). Also prevents possible - * crash on XP+ systems [Bug #624116]. - */ - - scrollInfo.fMask |= SIF_DISABLENOSCROLL; - } - SetScrollInfo(scrollPtr->hwnd, SB_CTL, &scrollInfo, TRUE); -} - -/* - *---------------------------------------------------------------------- - * - * CreateProc -- - * - * This function creates a new Scrollbar control, subclasses the - * instance, and generates a new Window object. - * - * Results: - * Returns the newly allocated Window object, or None on failure. - * - * Side effects: - * Causes a new Scrollbar control to come into existence. - * - *---------------------------------------------------------------------- - */ - -static Window -CreateProc( - Tk_Window tkwin, /* Token for window. */ - Window parentWin, /* Parent of new window. */ - ClientData instanceData) /* Scrollbar instance data. */ -{ - DWORD style; - Window window; - HWND parent; - TkWindow *winPtr; - WinScrollbar *scrollPtr = (WinScrollbar *)instanceData; - - parent = Tk_GetHWND(parentWin); - - if (scrollPtr->info.vertical) { - style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS - | SBS_VERT; - } else { - style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS - | SBS_HORZ; - } - - scrollPtr->hwnd = CreateWindow(TEXT("SCROLLBAR"), NULL, style, - Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), - parent, NULL, Tk_GetHINSTANCE(), NULL); - - /* - * Ensure new window is inserted into the stacking order at the correct - * place. - */ - - SetWindowPos(scrollPtr->hwnd, HWND_TOP, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - - for (winPtr = ((TkWindow*)tkwin)->nextPtr; winPtr != NULL; - winPtr = winPtr->nextPtr) { - if ((winPtr->window != None) && !(winPtr->flags & TK_TOP_HIERARCHY)) { - TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window), - Below); - break; - } - } - - scrollPtr->lastVertical = scrollPtr->info.vertical; - scrollPtr->oldProc = (WNDPROC)SetWindowLongPtr(scrollPtr->hwnd, - GWLP_WNDPROC, (LONG_PTR) ScrollbarProc); - window = Tk_AttachHWND(tkwin, scrollPtr->hwnd); - - UpdateScrollbar(scrollPtr); - return window; -} - -/* - *-------------------------------------------------------------- - * - * TkpDisplayScrollbar -- - * - * This procedure redraws the contents of a scrollbar window. It is - * invoked as a do-when-idle handler, so it only runs when there's - * nothing else for the application to do. - * - * Results: - * None. - * - * Side effects: - * Information appears on the screen. - * - *-------------------------------------------------------------- - */ - -void -TkpDisplayScrollbar( - ClientData clientData) /* Information about window. */ -{ - WinScrollbar *scrollPtr = (WinScrollbar *) clientData; - Tk_Window tkwin = scrollPtr->info.tkwin; - - scrollPtr->info.flags &= ~REDRAW_PENDING; - if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) { - return; - } - - /* - * Destroy and recreate the scrollbar control if the orientation has - * changed. - */ - - if (scrollPtr->lastVertical != scrollPtr->info.vertical) { - HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin)); - - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) scrollPtr->oldProc); - DestroyWindow(hwnd); - - CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)), - (ClientData) scrollPtr); - } else { - UpdateScrollbar(scrollPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpDestroyScrollbar -- - * - * Free data structures associated with the scrollbar control. - * - * Results: - * None. - * - * Side effects: - * Restores the default control state. - * - *---------------------------------------------------------------------- - */ - -void -TkpDestroyScrollbar( - TkScrollbar *scrollPtr) -{ - WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr; - HWND hwnd = winScrollPtr->hwnd; - - if (hwnd) { - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) winScrollPtr->oldProc); - if (winScrollPtr->winFlags & IN_MODAL_LOOP) { - ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW; - SetParent(hwnd, NULL); - } - } - winScrollPtr->winFlags |= ALREADY_DEAD; -} - -/* - *---------------------------------------------------------------------- - * - * UpdateScrollbarMetrics -- - * - * This function retrieves the current system metrics for a scrollbar. - * - * Results: - * None. - * - * Side effects: - * Updates the geometry cache info for all scrollbars. - * - *---------------------------------------------------------------------- - */ - -void -UpdateScrollbarMetrics(void) -{ - int arrowWidth = GetSystemMetrics(SM_CXVSCROLL); - - hArrowWidth = GetSystemMetrics(SM_CXHSCROLL); - hThumb = GetSystemMetrics(SM_CXHTHUMB); - vArrowHeight = GetSystemMetrics(SM_CYVSCROLL); - vThumb = GetSystemMetrics(SM_CYVTHUMB); - - sprintf(tkDefScrollbarWidth, "%d", arrowWidth); -} - -/* - *---------------------------------------------------------------------- - * - * TkpComputeScrollbarGeometry -- - * - * After changes in a scrollbar's size or configuration, this procedure - * recomputes various geometry information used in displaying the - * scrollbar. - * - * Results: - * None. - * - * Side effects: - * The scrollbar will be displayed differently. - * - *---------------------------------------------------------------------- - */ - -void -TkpComputeScrollbarGeometry( - register TkScrollbar *scrollPtr) - /* Scrollbar whose geometry may have - * changed. */ -{ - int fieldLength, minThumbSize; - - /* - * Windows doesn't use focus rings on scrollbars, but we still perform - * basic sanity checks to appease backwards compatibility. - */ - - if (scrollPtr->highlightWidth < 0) { - scrollPtr->highlightWidth = 0; - } - - if (scrollPtr->vertical) { - scrollPtr->arrowLength = vArrowHeight; - fieldLength = Tk_Height(scrollPtr->tkwin); - minThumbSize = vThumb; - } else { - scrollPtr->arrowLength = hArrowWidth; - fieldLength = Tk_Width(scrollPtr->tkwin); - minThumbSize = hThumb; - } - fieldLength -= 2*scrollPtr->arrowLength; - if (fieldLength < 0) { - fieldLength = 0; - } - scrollPtr->sliderFirst = (int) ((double)fieldLength - * scrollPtr->firstFraction); - scrollPtr->sliderLast = (int) ((double)fieldLength - * scrollPtr->lastFraction); - - /* - * Adjust the slider so that some piece of it is always displayed in the - * scrollbar and so that it has at least a minimal width (so it can be - * grabbed with the mouse). - */ - - if (scrollPtr->sliderFirst > fieldLength) { - scrollPtr->sliderFirst = fieldLength; - } - if (scrollPtr->sliderFirst < 0) { - scrollPtr->sliderFirst = 0; - } - if (scrollPtr->sliderLast < (scrollPtr->sliderFirst - + minThumbSize)) { - scrollPtr->sliderLast = scrollPtr->sliderFirst + minThumbSize; - } - if (scrollPtr->sliderLast > fieldLength) { - scrollPtr->sliderLast = fieldLength; - } - scrollPtr->sliderFirst += scrollPtr->arrowLength; - scrollPtr->sliderLast += scrollPtr->arrowLength; - - /* - * Register the desired geometry for the window (leave enough space for - * the two arrows plus a minimum-size slider, plus border around the whole - * window, if any). Then arrange for the window to be redisplayed. - */ - - if (scrollPtr->vertical) { - Tk_GeometryRequest(scrollPtr->tkwin, - scrollPtr->width, 2*scrollPtr->arrowLength + minThumbSize); - } else { - Tk_GeometryRequest(scrollPtr->tkwin, - 2*scrollPtr->arrowLength + minThumbSize, scrollPtr->width); - } - Tk_SetInternalBorder(scrollPtr->tkwin, 0); -} - -/* - *---------------------------------------------------------------------- - * - * ScrollbarProc -- - * - * This function is call by Windows whenever an event occurs on a - * scrollbar control created by Tk. - * - * Results: - * Standard Windows return value. - * - * Side effects: - * May generate events. - * - *---------------------------------------------------------------------- - */ - -static LRESULT CALLBACK -ScrollbarProc( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - LRESULT result; - POINT point; - WinScrollbar *scrollPtr; - Tk_Window tkwin = Tk_HWNDToWindow(hwnd); - - if (tkwin == NULL) { - Tcl_Panic("ScrollbarProc called on an invalid HWND"); - } - scrollPtr = (WinScrollbar *)((TkWindow*)tkwin)->instanceData; - - switch(message) { - case WM_HSCROLL: - case WM_VSCROLL: { - Tcl_Interp *interp; - Tcl_DString cmdString; - int command = LOWORD(wParam); - int code; - - GetCursorPos(&point); - Tk_TranslateWinEvent(NULL, WM_MOUSEMOVE, 0, - MAKELPARAM(point.x, point.y), &result); - - if (command == SB_ENDSCROLL) { - return 0; - } - - /* - * Bail out immediately if there isn't a command to invoke. - */ - - if (scrollPtr->info.commandSize == 0) { - Tcl_ServiceAll(); - return 0; - } - - Tcl_DStringInit(&cmdString); - Tcl_DStringAppend(&cmdString, scrollPtr->info.command, - scrollPtr->info.commandSize); - - if (command == SB_LINELEFT || command == SB_LINERIGHT) { - Tcl_DStringAppendElement(&cmdString, "scroll"); - Tcl_DStringAppendElement(&cmdString, - (command == SB_LINELEFT ) ? "-1" : "1"); - Tcl_DStringAppendElement(&cmdString, "units"); - } else if (command == SB_PAGELEFT || command == SB_PAGERIGHT) { - Tcl_DStringAppendElement(&cmdString, "scroll"); - Tcl_DStringAppendElement(&cmdString, - (command == SB_PAGELEFT ) ? "-1" : "1"); - Tcl_DStringAppendElement(&cmdString, "pages"); - } else { - char valueString[TCL_DOUBLE_SPACE]; - double pos = 0.0; - - switch (command) { - case SB_THUMBPOSITION: - pos = ((double)HIWORD(wParam)) / MAX_SCROLL; - break; - case SB_THUMBTRACK: - pos = ((double)HIWORD(wParam)) / MAX_SCROLL; - break; - case SB_TOP: - pos = 0.0; - break; - case SB_BOTTOM: - pos = 1.0; - break; - } - - Tcl_PrintDouble(NULL, pos, valueString); - Tcl_DStringAppendElement(&cmdString, "moveto"); - Tcl_DStringAppendElement(&cmdString, valueString); - } - - interp = scrollPtr->info.interp; - code = Tcl_EvalEx(interp, cmdString.string, -1, TCL_EVAL_GLOBAL); - if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) { - Tcl_AddErrorInfo(interp, "\n (scrollbar command)"); - Tcl_BackgroundException(interp, code); - } - Tcl_DStringFree(&cmdString); - - Tcl_ServiceAll(); - return 0; - } - - default: - if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) { - return result; - } - } - return CallWindowProc(scrollPtr->oldProc, hwnd, message, wParam, lParam); -} - -/* - *---------------------------------------------------------------------- - * - * TkpConfigureScrollbar -- - * - * This procedure is called after the generic code has finished - * processing configuration options, in order to configure platform - * specific options. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkpConfigureScrollbar( - register TkScrollbar *scrollPtr) - /* Information about widget; may or may not - * already have values for some fields. */ -{ -} - -/* - *---------------------------------------------------------------------- - * - * ModalLoop -- - * - * This function is invoked in response to a ButtonPress event. - * It resends the event to the Scrollbar window procedure, - * which in turn enters a modal loop. - * - *---------------------------------------------------------------------- - */ - -static void -ModalLoop( - WinScrollbar *scrollPtr, - XEvent *eventPtr) -{ - int oldMode; - - if (scrollPtr->hwnd) { - Tcl_Preserve((ClientData)scrollPtr); - scrollPtr->winFlags |= IN_MODAL_LOOP; - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr); - (void) Tcl_SetServiceMode(oldMode); - scrollPtr->winFlags &= ~IN_MODAL_LOOP; - if (scrollPtr->hwnd && scrollPtr->winFlags & ALREADY_DEAD) { - DestroyWindow(scrollPtr->hwnd); - } - Tcl_Release((ClientData)scrollPtr); - } -} - -/* - *-------------------------------------------------------------- - * - * TkpScrollbarPosition -- - * - * Determine the scrollbar element corresponding to a given position. - * - * Results: - * One of TOP_ARROW, TOP_GAP, etc., indicating which element of the - * scrollbar covers the position given by (x, y). If (x,y) is outside the - * scrollbar entirely, then OUTSIDE is returned. - * - * Side effects: - * None. - * - *-------------------------------------------------------------- - */ - -int -TkpScrollbarPosition( - register TkScrollbar *scrollPtr, - /* Scrollbar widget record. */ - int x, int y) /* Coordinates within scrollPtr's window. */ -{ - int length, width, tmp; - - if (scrollPtr->vertical) { - length = Tk_Height(scrollPtr->tkwin); - width = Tk_Width(scrollPtr->tkwin); - } else { - tmp = x; - x = y; - y = tmp; - length = Tk_Width(scrollPtr->tkwin); - width = Tk_Height(scrollPtr->tkwin); - } - - if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset)) - || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) { - return OUTSIDE; - } - - /* - * All of the calculations in this procedure mirror those in - * TkpDisplayScrollbar. Be sure to keep the two consistent. - */ - - if (y < (scrollPtr->inset + scrollPtr->arrowLength)) { - return TOP_ARROW; - } - if (y < scrollPtr->sliderFirst) { - return TOP_GAP; - } - if (y < scrollPtr->sliderLast) { - return SLIDER; - } - if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) { - return BOTTOM_ARROW; - } - return BOTTOM_GAP; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinSend.c b/tk8.6/win/tkWinSend.c deleted file mode 100644 index fca8561..0000000 --- a/tk8.6/win/tkWinSend.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* - * tkWinSend.c -- - * - * This file provides functions that implement the "send" command, - * allowing commands to be passed from interpreter to interpreter. - * - * Copyright (c) 1997 by Sun Microsystems, Inc. - * Copyright (c) 2003 Pat Thoyts <patthoyts@users.sourceforge.net> - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkInt.h" -#include "tkWinSendCom.h" - -/* - * Should be defined in WTypes.h but mingw 1.0 is missing them. - */ - -#ifndef _ROTFLAGS_DEFINED -#define _ROTFLAGS_DEFINED -#define ROTFLAGS_REGISTRATIONKEEPSALIVE 0x01 -#define ROTFLAGS_ALLOWANYCLIENT 0x02 -#endif /* ! _ROTFLAGS_DEFINED */ - -#define TKWINSEND_CLASS_NAME "TclEval" -#define TKWINSEND_REGISTRATION_BASE L"TclEval" - -#define MK_E_MONIKERALREADYREGISTERED \ - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x02A1) - -/* - * Package information structure. This is used to keep interpreter specific - * details for use when releasing the package resources upon interpreter - * deletion or package removal. - */ - -typedef struct { - char *name; /* The registered application name */ - DWORD cookie; /* ROT cookie returned on registration */ - LPUNKNOWN obj; /* Interface for the registration object */ - Tcl_Interp *interp; - Tcl_Command token; /* Winsend command token */ -} RegisteredInterp; - -typedef struct SendEvent { - Tcl_Event header; - Tcl_Interp *interp; - Tcl_Obj *cmdPtr; -} SendEvent; - -#ifdef TK_SEND_ENABLED_ON_WINDOWS -typedef struct { - int initialized; -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; -#endif /* TK_SEND_ENABLED_ON_WINDOWS */ - -/* - * Functions internal to this file. - */ - -#ifdef TK_SEND_ENABLED_ON_WINDOWS -static void CmdDeleteProc(ClientData clientData); -static void InterpDeleteProc(ClientData clientData, - Tcl_Interp *interp); -static void RevokeObjectRegistration(RegisteredInterp *riPtr); -#endif /* TK_SEND_ENABLED_ON_WINDOWS */ -static HRESULT BuildMoniker(const char *name, LPMONIKER *pmk); -#ifdef TK_SEND_ENABLED_ON_WINDOWS -static HRESULT RegisterInterp(const char *name, - RegisteredInterp *riPtr); -#endif /* TK_SEND_ENABLED_ON_WINDOWS */ -static int FindInterpreterObject(Tcl_Interp *interp, - const char *name, LPDISPATCH *ppdisp); -static int Send(LPDISPATCH pdispInterp, Tcl_Interp *interp, - int async, ClientData clientData, int objc, - Tcl_Obj *const objv[]); -static void SendTrace(const char *format, ...); -static Tcl_EventProc SendEventProc; - -#if defined(DEBUG) || defined(_DEBUG) -#define TRACE SendTrace -#else -#define TRACE 1 ? ((void)0) : SendTrace -#endif /* DEBUG || _DEBUG */ - -/* - *-------------------------------------------------------------- - * - * Tk_SetAppName -- - * - * This function is called to associate an ASCII name with a Tk - * application. If the application has already been named, the name - * replaces the old one. - * - * Results: - * The return value is the name actually given to the application. This - * will normally be the same as name, but if name was already in use for - * an application then a name of the form "name #2" will be chosen, with - * a high enough number to make the name unique. - * - * Side effects: - * Registration info is saved, thereby allowing the "send" command to be - * used later to invoke commands in the application. In addition, the - * "send" command is created in the application's interpreter. The - * registration will be removed automatically if the interpreter is - * deleted or the "send" command is removed. - * - *-------------------------------------------------------------- - */ - -const char * -Tk_SetAppName( - Tk_Window tkwin, /* Token for any window in the application to - * be named: it is just used to identify the - * application and the display. */ - const char *name) /* The name that will be used to refer to the - * interpreter in later "send" commands. Must - * be globally unique. */ -{ -#ifndef TK_SEND_ENABLED_ON_WINDOWS - /* - * Temporarily disabled for bug #858822 - */ - - return name; -#else /* TK_SEND_ENABLED_ON_WINDOWS */ - - ThreadSpecificData *tsdPtr = NULL; - TkWindow *winPtr = (TkWindow *) tkwin; - RegisteredInterp *riPtr = NULL; - Tcl_Interp *interp; - HRESULT hr = S_OK; - - interp = winPtr->mainPtr->interp; - tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - /* - * Initialise the COM library for this interpreter just once. - */ - - if (tsdPtr->initialized == 0) { - hr = CoInitialize(0); - if (FAILED(hr)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "failed to initialize the COM library", -1)); - Tcl_SetErrorCode(interp, "TK", "SEND", "COM", NULL); - return ""; - } - tsdPtr->initialized = 1; - TRACE("Initialized COM library for interp 0x%08X\n", (long)interp); - } - - /* - * If the interp hasn't been registered before then we need to create the - * registration structure and the COM object. If it has been registered - * already then we can reuse all and just register the new name. - */ - - riPtr = Tcl_GetAssocData(interp, "tkWinSend::ri", NULL); - if (riPtr == NULL) { - LPUNKNOWN *objPtr; - - riPtr = ckalloc(sizeof(RegisteredInterp)); - memset(riPtr, 0, sizeof(RegisteredInterp)); - riPtr->interp = interp; - - objPtr = &riPtr->obj; - hr = TkWinSendCom_CreateInstance(interp, &IID_IUnknown, - (void **) objPtr); - - Tcl_CreateObjCommand(interp, "send", Tk_SendObjCmd, riPtr, - CmdDeleteProc); - if (Tcl_IsSafe(interp)) { - Tcl_HideCommand(interp, "send", "send"); - } - Tcl_SetAssocData(interp, "tkWinSend::ri", NULL, riPtr); - } else { - RevokeObjectRegistration(riPtr); - } - - RegisterInterp(name, riPtr); - return (const char *) riPtr->name; -#endif /* TK_SEND_ENABLED_ON_WINDOWS */ -} - -/* - *---------------------------------------------------------------------- - * - * TkGetInterpNames -- - * - * This function is invoked to fetch a list of all the interpreter names - * currently registered for the display of a particular window. - * - * Results: - * A standard Tcl return value. Interp->result will be set to hold a list - * of all the interpreter names defined for tkwin's display. If an error - * occurs, then TCL_ERROR is returned and interp->result will hold an - * error message. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkGetInterpNames( - Tcl_Interp *interp, /* Interpreter for returning a result. */ - Tk_Window tkwin) /* Window whose display is to be used for the - * lookup. */ -{ -#ifndef TK_SEND_ENABLED_ON_WINDOWS - /* - * Temporarily disabled for bug #858822 - */ - - return TCL_OK; -#else /* TK_SEND_ENABLED_ON_WINDOWS */ - - LPRUNNINGOBJECTTABLE pROT = NULL; - LPCOLESTR oleszStub = TKWINSEND_REGISTRATION_BASE; - HRESULT hr = S_OK; - Tcl_Obj *objList = NULL; - int result = TCL_OK; - - hr = GetRunningObjectTable(0, &pROT); - if (SUCCEEDED(hr)) { - IBindCtx* pBindCtx = NULL; - objList = Tcl_NewListObj(0, NULL); - hr = CreateBindCtx(0, &pBindCtx); - - if (SUCCEEDED(hr)) { - IEnumMoniker* pEnum; - - hr = pROT->lpVtbl->EnumRunning(pROT, &pEnum); - if (SUCCEEDED(hr)) { - IMoniker* pmk = NULL; - - while (pEnum->lpVtbl->Next(pEnum, 1, &pmk, NULL) == S_OK) { - LPOLESTR olestr; - - hr = pmk->lpVtbl->GetDisplayName(pmk, pBindCtx, NULL, - &olestr); - if (SUCCEEDED(hr)) { - IMalloc *pMalloc = NULL; - - if (wcsncmp(olestr, oleszStub, - wcslen(oleszStub)) == 0) { - LPOLESTR p = olestr + wcslen(oleszStub); - - if (*p) { - Tcl_DString ds; - - Tcl_WinTCharToUtf(p + 1, -1, &ds); - result = Tcl_ListObjAppendElement(interp, - objList, - Tcl_NewStringObj(Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds))); - Tcl_DStringFree(&ds); - } - } - - hr = CoGetMalloc(1, &pMalloc); - if (SUCCEEDED(hr)) { - pMalloc->lpVtbl->Free(pMalloc, (void*)olestr); - pMalloc->lpVtbl->Release(pMalloc); - } - } - pmk->lpVtbl->Release(pmk); - } - pEnum->lpVtbl->Release(pEnum); - } - pBindCtx->lpVtbl->Release(pBindCtx); - } - pROT->lpVtbl->Release(pROT); - } - - if (FAILED(hr)) { - /* - * Expire the list if set. - */ - - if (objList != NULL) { - Tcl_DecrRefCount(objList); - } - Tcl_SetObjResult(interp, TkWin32ErrorObj(hr)); - result = TCL_ERROR; - } - - if (result == TCL_OK) { - Tcl_SetObjResult(interp, objList); - } - - return result; -#endif /* TK_SEND_ENABLED_ON_WINDOWS */ -} - -/* - *-------------------------------------------------------------- - * - * Tk_SendCmd -- - * - * This function is invoked to process the "send" Tcl command. See the - * user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *-------------------------------------------------------------- - */ - -int -Tk_SendObjCmd( - ClientData clientData, /* Information about sender (only dispPtr - * field is used). */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument strings. */ -{ - enum { - SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST - }; - static const char *const sendOptions[] = { - "-async", "-displayof", "--", NULL - }; - int result = TCL_OK; - int i, optind, async = 0; - Tcl_Obj *displayPtr = NULL; - - /* - * Process the command options. - */ - - for (i = 1; i < objc; i++) { - if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions, - sizeof(char *), "option", 0, &optind) != TCL_OK) { - break; - } - if (optind == SEND_ASYNC) { - ++async; - } else if (optind == SEND_DISPLAYOF) { - displayPtr = objv[++i]; - } else if (optind == SEND_LAST) { - i++; - break; - } - } - - /* - * Ensure we still have a valid command. - */ - - if ((objc - i) < 2) { - Tcl_WrongNumArgs(interp, 1, objv, - "?-async? ?-displayof? ?--? interpName arg ?arg ...?"); - result = TCL_ERROR; - } - - /* - * We don't support displayPtr. See TIP #150. - */ - - if (displayPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "option not implemented: \"displayof\" is not available" - " for this platform.", -1)); - Tcl_SetErrorCode(interp, "TK", "SEND", "DISPLAYOF_WIN", NULL); - result = TCL_ERROR; - } - - /* - * Send the arguments to the foreign interp. - */ - /* FIX ME: we need to check for local interp */ - if (result == TCL_OK) { - LPDISPATCH pdisp; - - result = FindInterpreterObject(interp, Tcl_GetString(objv[i]), &pdisp); - if (result == TCL_OK) { - i++; - result = Send(pdisp, interp, async, clientData, objc-i, objv+i); - pdisp->lpVtbl->Release(pdisp); - } - } - - return result; -} - -/* - *-------------------------------------------------------------- - * - * FindInterpreterObject -- - * - * Search the set of objects currently registered with the Running Object - * Table for one which matches the registered name. Tk objects are named - * using BuildMoniker by always prefixing with TclEval. - * - * Results: - * If a matching object registration is found, then the registered - * IDispatch interface pointer is returned. If not, then an error message - * is placed in the interpreter and TCL_ERROR is returned. - * - * Side effects: - * None. - * - *-------------------------------------------------------------- - */ - -static int -FindInterpreterObject( - Tcl_Interp *interp, - const char *name, - LPDISPATCH *ppdisp) -{ - LPRUNNINGOBJECTTABLE pROT = NULL; - int result = TCL_OK; - HRESULT hr = GetRunningObjectTable(0, &pROT); - - if (SUCCEEDED(hr)) { - IBindCtx* pBindCtx = NULL; - - hr = CreateBindCtx(0, &pBindCtx); - if (SUCCEEDED(hr)) { - LPMONIKER pmk = NULL; - - hr = BuildMoniker(name, &pmk); - if (SUCCEEDED(hr)) { - IUnknown *pUnkInterp = NULL, **ppUnkInterp = &pUnkInterp; - - hr = pROT->lpVtbl->IsRunning(pROT, pmk); - hr = pmk->lpVtbl->BindToObject(pmk, pBindCtx, NULL, - &IID_IUnknown, (void **) ppUnkInterp); - if (SUCCEEDED(hr)) { - hr = pUnkInterp->lpVtbl->QueryInterface(pUnkInterp, - &IID_IDispatch, (void **) ppdisp); - pUnkInterp->lpVtbl->Release(pUnkInterp); - - } else { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "no application named \"%s\"", name)); - Tcl_SetErrorCode(interp, "TK", "LOOKUP", "APPLICATION", - NULL); - result = TCL_ERROR; - } - - pmk->lpVtbl->Release(pmk); - } - pBindCtx->lpVtbl->Release(pBindCtx); - } - pROT->lpVtbl->Release(pROT); - } - if (FAILED(hr) && result == TCL_OK) { - Tcl_SetObjResult(interp, TkWin32ErrorObj(hr)); - result = TCL_ERROR; - } - return result; -} - -/* - *-------------------------------------------------------------- - * - * CmdDeleteProc -- - * - * This function is invoked by Tcl when the "send" command is deleted in - * an interpreter. It unregisters the interpreter. - * - * Results: - * None. - * - * Side effects: - * The interpreter given by riPtr is unregistered, the registration - * structure is free'd and the COM object unregistered and released. - * - *-------------------------------------------------------------- - */ - -#ifdef TK_SEND_ENABLED_ON_WINDOWS -static void -CmdDeleteProc( - ClientData clientData) -{ - RegisteredInterp *riPtr = (RegisteredInterp *)clientData; - - /* - * Lock the package structure in memory. - */ - - Tcl_Preserve(clientData); - - /* - * Revoke the ROT registration. - */ - - RevokeObjectRegistration(riPtr); - - /* - * Release the registration object. - */ - - riPtr->obj->lpVtbl->Release(riPtr->obj); - riPtr->obj = NULL; - - Tcl_DeleteAssocData(riPtr->interp, "tkWinSend::ri"); - - /* - * Unlock the package data structure. - */ - - Tcl_Release(clientData); - - ckfree(clientData); -} - -/* - *-------------------------------------------------------------- - * - * RevokeObjectRegistration -- - * - * Releases the interpreters registration object from the Running Object - * Table. - * - * Results: - * None. - * - * Side effects: - * The stored cookie value is zeroed and the name is free'd and the - * pointer set to NULL. - * - *-------------------------------------------------------------- - */ - -static void -RevokeObjectRegistration( - RegisteredInterp *riPtr) -{ - LPRUNNINGOBJECTTABLE pROT = NULL; - HRESULT hr = S_OK; - - if (riPtr->cookie != 0) { - hr = GetRunningObjectTable(0, &pROT); - if (SUCCEEDED(hr)) { - hr = pROT->lpVtbl->Revoke(pROT, riPtr->cookie); - pROT->lpVtbl->Release(pROT); - riPtr->cookie = 0; - } - } - - /* - * Release the name storage. - */ - - if (riPtr->name != NULL) { - free(riPtr->name); - riPtr->name = NULL; - } -} -#endif /* TK_SEND_ENABLED_ON_WINDOWS */ - -/* - * ---------------------------------------------------------------------- - * - * InterpDeleteProc -- - * - * This is called when the interpreter is deleted and used to unregister - * the COM libraries. - * - * Results: - * None. - * - * Side effects: - * None. - * - * ---------------------------------------------------------------------- - */ - -#ifdef TK_SEND_ENABLED_ON_WINDOWS -static void -InterpDeleteProc( - ClientData clientData, - Tcl_Interp *interp) -{ - CoUninitialize(); -} -#endif /* TK_SEND_ENABLED_ON_WINDOWS */ - -/* - * ---------------------------------------------------------------------- - * - * BuildMoniker -- - * - * Construct a moniker from the given name. This ensures that all our - * monikers have the same prefix. - * - * Results: - * S_OK. If the name cannot be turned into a moniker then a COM error - * code is returned. - * - * Side effects: - * The moniker created is stored at the address given by ppmk. - * - * ---------------------------------------------------------------------- - */ - -static HRESULT -BuildMoniker( - const char *name, - LPMONIKER *ppmk) -{ - LPMONIKER pmkClass = NULL; - HRESULT hr = CreateFileMoniker(TKWINSEND_REGISTRATION_BASE, &pmkClass); - - if (SUCCEEDED(hr)) { - LPMONIKER pmkItem = NULL; - Tcl_DString dString; - - Tcl_WinUtfToTChar(name, -1, &dString); - hr = CreateFileMoniker((LPOLESTR)Tcl_DStringValue(&dString), &pmkItem); - Tcl_DStringFree(&dString); - if (SUCCEEDED(hr)) { - hr = pmkClass->lpVtbl->ComposeWith(pmkClass, pmkItem, FALSE, ppmk); - pmkItem->lpVtbl->Release(pmkItem); - } - pmkClass->lpVtbl->Release(pmkClass); - } - return hr; -} - -/* - * ---------------------------------------------------------------------- - * - * RegisterInterp -- - * - * Attempts to register the provided name for this interpreter. If the - * given name is already in use, then a numeric suffix is appended as - * " #n" until we identify a unique name. - * - * Results: - * Returns S_OK if successful, else a COM error code. - * - * Side effects: - * Registration returns a cookie value which is stored. We also store a - * copy of the name. - * - * ---------------------------------------------------------------------- - */ - -#ifdef TK_SEND_ENABLED_ON_WINDOWS -static HRESULT -RegisterInterp( - const char *name, - RegisteredInterp *riPtr) -{ - HRESULT hr = S_OK; - LPRUNNINGOBJECTTABLE pROT = NULL; - LPMONIKER pmk = NULL; - int i, offset; - const char *actualName = name; - Tcl_DString dString; - Tcl_DStringInit(&dString); - - hr = GetRunningObjectTable(0, &pROT); - if (SUCCEEDED(hr)) { - offset = 0; - for (i = 1; SUCCEEDED(hr); i++) { - if (i > 1) { - if (i == 2) { - Tcl_DStringInit(&dString); - Tcl_DStringAppend(&dString, name, -1); - Tcl_DStringAppend(&dString, " #", 2); - offset = Tcl_DStringLength(&dString); - Tcl_DStringSetLength(&dString, offset+TCL_INTEGER_SPACE); - actualName = Tcl_DStringValue(&dString); - } - sprintf(Tcl_DStringValue(&dString) + offset, "%d", i); - } - - hr = BuildMoniker(actualName, &pmk); - if (SUCCEEDED(hr)) { - - hr = pROT->lpVtbl->Register(pROT, - ROTFLAGS_REGISTRATIONKEEPSALIVE, - riPtr->obj, pmk, &riPtr->cookie); - - pmk->lpVtbl->Release(pmk); - } - - if (hr == MK_S_MONIKERALREADYREGISTERED) { - pROT->lpVtbl->Revoke(pROT, riPtr->cookie); - } else if (hr == S_OK) { - break; - } - } - - pROT->lpVtbl->Release(pROT); - } - - if (SUCCEEDED(hr)) { - riPtr->name = strdup(actualName); - } - - Tcl_DStringFree(&dString); - return hr; -} -#endif /* TK_SEND_ENABLED_ON_WINDOWS */ - -/* - * ---------------------------------------------------------------------- - * - * Send -- - * - * Perform an interface call to the server object. We convert the Tcl - * arguments into a BSTR using 'concat'. The result should be a BSTR that - * we can set as the interp's result string. - * - * Results: - * None. - * - * Side effects: - * None. - * - * ---------------------------------------------------------------------- - */ - -static int -Send( - LPDISPATCH pdispInterp, /* Pointer to the remote interp's COM - * object. */ - Tcl_Interp *interp, /* The local interpreter. */ - int async, /* Flag for the calling style. */ - ClientData clientData, /* The RegisteredInterp structure for this - * interp. */ - int objc, /* Number of arguments to be sent. */ - Tcl_Obj *const objv[]) /* The arguments to be sent. */ -{ - VARIANT vCmd, vResult; - DISPPARAMS dp; - EXCEPINFO ei; - UINT uiErr = 0; - HRESULT hr = S_OK, ehr = S_OK; - Tcl_Obj *cmd = NULL; - DISPID dispid; - Tcl_DString ds; - const char *src; - - cmd = Tcl_ConcatObj(objc, objv); - - /* - * Setup the arguments for the COM method call. - */ - - VariantInit(&vCmd); - VariantInit(&vResult); - memset(&dp, 0, sizeof(dp)); - memset(&ei, 0, sizeof(ei)); - - vCmd.vt = VT_BSTR; - src = Tcl_GetString(cmd); - Tcl_WinUtfToTChar(src, cmd->length, &ds); - vCmd.bstrVal = SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); - Tcl_DStringFree(&ds); - - dp.cArgs = 1; - dp.rgvarg = &vCmd; - - /* - * Select the method to use based upon the async flag and call the method. - */ - - dispid = async ? TKWINSENDCOM_DISPID_ASYNC : TKWINSENDCOM_DISPID_SEND; - - hr = pdispInterp->lpVtbl->Invoke(pdispInterp, dispid, - &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, - &dp, &vResult, &ei, &uiErr); - - /* - * Convert the result into a string and place in the interps result. - */ - - ehr = VariantChangeType(&vResult, &vResult, 0, VT_BSTR); - if (SUCCEEDED(ehr)) { - Tcl_WinTCharToUtf(vResult.bstrVal, (int) SysStringLen(vResult.bstrVal) * - sizeof (WCHAR), &ds); - Tcl_DStringResult(interp, &ds); - } - - /* - * Errors are returned as dispatch exceptions. If an error code was - * returned then we decode the exception and setup the Tcl error - * variables. - */ - - if (hr == DISP_E_EXCEPTION && ei.bstrSource != NULL) { - Tcl_Obj *opError, *opErrorCode, *opErrorInfo; - Tcl_WinTCharToUtf(ei.bstrSource, (int) SysStringLen(ei.bstrSource) * - sizeof (WCHAR), &ds); - opError = Tcl_NewStringObj(Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds)); - Tcl_DStringFree(&ds); - Tcl_ListObjIndex(interp, opError, 0, &opErrorCode); - Tcl_SetObjErrorCode(interp, opErrorCode); - Tcl_ListObjIndex(interp, opError, 1, &opErrorInfo); - Tcl_AppendObjToErrorInfo(interp, opErrorInfo); - } - - /* - * Clean up any COM allocated resources. - */ - - SysFreeString(ei.bstrDescription); - SysFreeString(ei.bstrSource); - SysFreeString(ei.bstrHelpFile); - VariantClear(&vCmd); - - return (SUCCEEDED(hr) ? TCL_OK : TCL_ERROR); -} - -/* - * ---------------------------------------------------------------------- - * - * TkWinSend_SetExcepInfo -- - * - * Convert the error information from a Tcl interpreter into a COM - * exception structure. This information is then registered with the COM - * thread exception object so that it can be used for rich error - * reporting by COM clients. - * - * Results: - * None. - * - * Side effects: - * The current COM thread has its error object modified. - * - * ---------------------------------------------------------------------- - */ - -void -TkWinSend_SetExcepInfo( - Tcl_Interp *interp, - EXCEPINFO *pExcepInfo) -{ - Tcl_Obj *opError, *opErrorInfo, *opErrorCode; - ICreateErrorInfo *pCEI; - IErrorInfo *pEI, **ppEI = &pEI; - HRESULT hr; - Tcl_DString ds; - const char *src; - - if (!pExcepInfo) { - return; - } - - opError = Tcl_GetObjResult(interp); - opErrorInfo = Tcl_GetVar2Ex(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY); - opErrorCode = Tcl_GetVar2Ex(interp, "errorCode", NULL, TCL_GLOBAL_ONLY); - - /* - * Pack the trace onto the end of the Tcl exception descriptor. - */ - - opErrorCode = Tcl_DuplicateObj(opErrorCode); - Tcl_IncrRefCount(opErrorCode); - Tcl_ListObjAppendElement(interp, opErrorCode, opErrorInfo); - /* TODO: Handle failure to append */ - - src = Tcl_GetString(opError); - Tcl_WinUtfToTChar(src, opError->length, &ds); - pExcepInfo->bstrDescription = - SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); - Tcl_DStringFree(&ds); - src = Tcl_GetString(opErrorCode); - Tcl_WinUtfToTChar(src, opErrorCode->length, &ds); - pExcepInfo->bstrSource = - SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); - Tcl_DStringFree(&ds); - Tcl_DecrRefCount(opErrorCode); - pExcepInfo->scode = E_FAIL; - - hr = CreateErrorInfo(&pCEI); - if (!SUCCEEDED(hr)) { - return; - } - - hr = pCEI->lpVtbl->SetGUID(pCEI, &IID_IDispatch); - hr = pCEI->lpVtbl->SetDescription(pCEI, pExcepInfo->bstrDescription); - hr = pCEI->lpVtbl->SetSource(pCEI, pExcepInfo->bstrSource); - hr = pCEI->lpVtbl->QueryInterface(pCEI, &IID_IErrorInfo, (void **) ppEI); - if (SUCCEEDED(hr)) { - SetErrorInfo(0, pEI); - pEI->lpVtbl->Release(pEI); - } - pCEI->lpVtbl->Release(pCEI); -} - -/* - * ---------------------------------------------------------------------- - * - * TkWinSend_QueueCommand -- - * - * Queue a script for asynchronous evaluation. This is called from the - * COM objects Async method. - * - * Results: - * None. - * - * Side effects: - * None. - * - * ---------------------------------------------------------------------- - */ - -int -TkWinSend_QueueCommand( - Tcl_Interp *interp, - Tcl_Obj *cmdPtr) -{ - SendEvent *evPtr; - - TRACE("SendQueueCommand()\n"); - - evPtr = ckalloc(sizeof(SendEvent)); - evPtr->header.proc = SendEventProc; - evPtr->header.nextPtr = NULL; - evPtr->interp = interp; - Tcl_Preserve(evPtr->interp); - - if (Tcl_IsShared(cmdPtr)) { - evPtr->cmdPtr = Tcl_DuplicateObj(cmdPtr); - } else { - evPtr->cmdPtr = cmdPtr; - Tcl_IncrRefCount(evPtr->cmdPtr); - } - - Tcl_QueueEvent((Tcl_Event *)evPtr, TCL_QUEUE_TAIL); - - return 0; -} - -/* - * ---------------------------------------------------------------------- - * - * SendEventProc -- - * - * Handle a request for an asynchronous send. Nothing is returned to the - * caller so the result is discarded. - * - * Results: - * Returns 1 if the event was handled or 0 to indicate it has been - * deferred. - * - * Side effects: - * The target interpreter's result will be modified. - * - * ---------------------------------------------------------------------- - */ - -static int -SendEventProc( - Tcl_Event *eventPtr, - int flags) -{ - SendEvent *evPtr = (SendEvent *)eventPtr; - - TRACE("SendEventProc\n"); - - Tcl_EvalObjEx(evPtr->interp, evPtr->cmdPtr, - TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL); - - Tcl_DecrRefCount(evPtr->cmdPtr); - Tcl_Release(evPtr->interp); - - return 1; /* 1 to indicate the event has been handled */ -} - -/* - * ---------------------------------------------------------------------- - * - * SendTrace -- - * - * Provide trace information to the Windows debug stream. To use this - - * use the TRACE macro, which compiles to nothing when DEBUG is not - * defined. - * - * Results: - * None. - * - * Side effects: - * None. - * - * ---------------------------------------------------------------------- - */ - -static void -SendTrace( - const char *format, ...) -{ - va_list args; - static char buffer[1024]; - - va_start(args, format); - _vsnprintf(buffer, 1023, format, args); - OutputDebugStringA(buffer); - va_end(args); -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinSendCom.c b/tk8.6/win/tkWinSendCom.c deleted file mode 100644 index 9e5b7a0..0000000 --- a/tk8.6/win/tkWinSendCom.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * tkWinSendCom.c -- - * - * This file provides support functions that implement the Windows "send" - * command using COM interfaces, allowing commands to be passed from - * interpreter to interpreter. See also tkWinSend.c, where most of the - * interesting functions are. - * - * We implement a COM class for use in registering Tcl interpreters with the - * system's Running Object Table. This class implements an IDispatch interface - * with the following method: - * Send(String cmd) As String - * In other words the Send methods takes a string and evaluates this in the - * Tcl interpreter. The result is returned as another string. - * - * Copyright (C) 2002 Pat Thoyts <patthoyts@users.sourceforge.net> - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkInt.h" -#include "tkWinSendCom.h" - -/* - * ---------------------------------------------------------------------- - * Non-public prototypes. - * - * These are the interface methods for IUnknown, IDispatch and - * ISupportErrorInfo. - * - * ---------------------------------------------------------------------- - */ - -static void TkWinSendCom_Destroy(LPDISPATCH pdisp); - -static STDMETHODIMP WinSendCom_QueryInterface(IDispatch *This, - REFIID riid, void **ppvObject); -static STDMETHODIMP_(ULONG) WinSendCom_AddRef(IDispatch *This); -static STDMETHODIMP_(ULONG) WinSendCom_Release(IDispatch *This); -static STDMETHODIMP WinSendCom_GetTypeInfoCount(IDispatch *This, - UINT *pctinfo); -static STDMETHODIMP WinSendCom_GetTypeInfo(IDispatch *This, UINT iTInfo, - LCID lcid, ITypeInfo **ppTI); -static STDMETHODIMP WinSendCom_GetIDsOfNames(IDispatch *This, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, LCID lcid, - DISPID *rgDispId); -static STDMETHODIMP WinSendCom_Invoke(IDispatch *This, DISPID dispidMember, - REFIID riid, LCID lcid, WORD wFlags, - DISPPARAMS *pDispParams, VARIANT *pvarResult, - EXCEPINFO *pExcepInfo, UINT *puArgErr); -static STDMETHODIMP ISupportErrorInfo_QueryInterface( - ISupportErrorInfo *This, REFIID riid, - void **ppvObject); -static STDMETHODIMP_(ULONG) ISupportErrorInfo_AddRef( - ISupportErrorInfo *This); -static STDMETHODIMP_(ULONG) ISupportErrorInfo_Release( - ISupportErrorInfo *This); -static STDMETHODIMP ISupportErrorInfo_InterfaceSupportsErrorInfo( - ISupportErrorInfo *This, REFIID riid); -static HRESULT Send(TkWinSendCom *obj, VARIANT vCmd, - VARIANT *pvResult, EXCEPINFO *pExcepInfo, - UINT *puArgErr); -static HRESULT Async(TkWinSendCom *obj, VARIANT Cmd, - EXCEPINFO *pExcepInfo, UINT *puArgErr); - -/* - * ---------------------------------------------------------------------- - * - * CreateInstance -- - * - * Create and initialises a new instance of the WinSend COM class and - * returns an interface pointer for you to use. - * - * ---------------------------------------------------------------------- - */ - -HRESULT -TkWinSendCom_CreateInstance( - Tcl_Interp *interp, - REFIID riid, - void **ppv) -{ - /* - * Construct v-tables for each interface. - */ - - static IDispatchVtbl vtbl = { - WinSendCom_QueryInterface, - WinSendCom_AddRef, - WinSendCom_Release, - WinSendCom_GetTypeInfoCount, - WinSendCom_GetTypeInfo, - WinSendCom_GetIDsOfNames, - WinSendCom_Invoke, - }; - static ISupportErrorInfoVtbl vtbl2 = { - ISupportErrorInfo_QueryInterface, - ISupportErrorInfo_AddRef, - ISupportErrorInfo_Release, - ISupportErrorInfo_InterfaceSupportsErrorInfo, - }; - TkWinSendCom *obj = NULL; - - /* - * This had probably better always be globally visible memory so we shall - * use the COM Task allocator. - */ - - obj = (TkWinSendCom *) CoTaskMemAlloc(sizeof(TkWinSendCom)); - if (obj == NULL) { - *ppv = NULL; - return E_OUTOFMEMORY; - } - - obj->lpVtbl = &vtbl; - obj->lpVtbl2 = &vtbl2; - obj->refcount = 0; - obj->interp = interp; - - /* - * lock the interp? Tcl_AddRef/Retain? - */ - - return obj->lpVtbl->QueryInterface((IDispatch *) obj, riid, ppv); -} - -/* - * ---------------------------------------------------------------------- - * - * TkWinSendCom_Destroy -- - * - * This helper function is the destructor for our COM class. - * - * Results: - * None. - * - * Side effects: - * Releases the storage allocated for this object. - * - * ---------------------------------------------------------------------- - */ -static void -TkWinSendCom_Destroy( - LPDISPATCH pdisp) -{ - CoTaskMemFree((void *) pdisp); -} - -/* - * ---------------------------------------------------------------------- - * - * IDispatch -- - * - * The IDispatch interface implements the 'late-binding' COM methods - * typically used by scripting COM clients. The Invoke method is the most - * important one. - * - * ---------------------------------------------------------------------- - */ - -static STDMETHODIMP -WinSendCom_QueryInterface( - IDispatch *This, - REFIID riid, - void **ppvObject) -{ - HRESULT hr = E_NOINTERFACE; - TkWinSendCom *this = (TkWinSendCom *) This; - *ppvObject = NULL; - - if (memcmp(riid, &IID_IUnknown, sizeof(IID)) == 0 - || memcmp(riid, &IID_IDispatch, sizeof(IID)) == 0) { - *ppvObject = (void **) this; - this->lpVtbl->AddRef(This); - hr = S_OK; - } else if (memcmp(riid, &IID_ISupportErrorInfo, sizeof(IID)) == 0) { - *ppvObject = (void **) (this + 1); - this->lpVtbl2->AddRef((ISupportErrorInfo *) (this + 1)); - hr = S_OK; - } - return hr; -} - -static STDMETHODIMP_(ULONG) -WinSendCom_AddRef( - IDispatch *This) -{ - TkWinSendCom *this = (TkWinSendCom*)This; - - return InterlockedIncrement(&this->refcount); -} - -static STDMETHODIMP_(ULONG) -WinSendCom_Release( - IDispatch *This) -{ - long r = 0; - TkWinSendCom *this = (TkWinSendCom*)This; - - if ((r = InterlockedDecrement(&this->refcount)) == 0) { - TkWinSendCom_Destroy(This); - } - return r; -} - -static STDMETHODIMP -WinSendCom_GetTypeInfoCount( - IDispatch *This, - UINT *pctinfo) -{ - HRESULT hr = E_POINTER; - - if (pctinfo != NULL) { - *pctinfo = 0; - hr = S_OK; - } - return hr; -} - -static STDMETHODIMP -WinSendCom_GetTypeInfo( - IDispatch *This, - UINT iTInfo, - LCID lcid, - ITypeInfo **ppTI) -{ - HRESULT hr = E_POINTER; - - if (ppTI) { - *ppTI = NULL; - hr = E_NOTIMPL; - } - return hr; -} - -static STDMETHODIMP -WinSendCom_GetIDsOfNames( - IDispatch *This, - REFIID riid, - LPOLESTR *rgszNames, - UINT cNames, - LCID lcid, - DISPID *rgDispId) -{ - HRESULT hr = E_POINTER; - - if (rgDispId) { - hr = DISP_E_UNKNOWNNAME; - if (_wcsicmp(*rgszNames, L"Send") == 0) { - *rgDispId = TKWINSENDCOM_DISPID_SEND, hr = S_OK; - } else if (_wcsicmp(*rgszNames, L"Async") == 0) { - *rgDispId = TKWINSENDCOM_DISPID_ASYNC, hr = S_OK; - } - } - return hr; -} - -static STDMETHODIMP -WinSendCom_Invoke( - IDispatch *This, - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS *pDispParams, - VARIANT *pvarResult, - EXCEPINFO *pExcepInfo, - UINT *puArgErr) -{ - HRESULT hr = DISP_E_MEMBERNOTFOUND; - TkWinSendCom *this = (TkWinSendCom*)This; - - switch (dispidMember) { - case TKWINSENDCOM_DISPID_SEND: - if (wFlags | DISPATCH_METHOD) { - if (pDispParams->cArgs != 1) { - hr = DISP_E_BADPARAMCOUNT; - } else { - hr = Send(this, pDispParams->rgvarg[0], pvarResult, - pExcepInfo, puArgErr); - } - } - break; - - case TKWINSENDCOM_DISPID_ASYNC: - if (wFlags | DISPATCH_METHOD) { - if (pDispParams->cArgs != 1) { - hr = DISP_E_BADPARAMCOUNT; - } else { - hr = Async(this, pDispParams->rgvarg[0], pExcepInfo, puArgErr); - } - } - break; - } - return hr; -} - -/* - * ---------------------------------------------------------------------- - * - * ISupportErrorInfo -- - * - * This interface provides rich error information to COM clients. Used by - * VB and scripting COM clients. - * - * ---------------------------------------------------------------------- - */ - -static STDMETHODIMP -ISupportErrorInfo_QueryInterface( - ISupportErrorInfo *This, - REFIID riid, - void **ppvObject) -{ - TkWinSendCom *this = (TkWinSendCom *)(This - 1); - - return this->lpVtbl->QueryInterface((IDispatch *) this, riid, ppvObject); -} - -static STDMETHODIMP_(ULONG) -ISupportErrorInfo_AddRef( - ISupportErrorInfo *This) -{ - TkWinSendCom *this = (TkWinSendCom *)(This - 1); - - return InterlockedIncrement(&this->refcount); -} - -static STDMETHODIMP_(ULONG) -ISupportErrorInfo_Release( - ISupportErrorInfo *This) -{ - TkWinSendCom *this = (TkWinSendCom *)(This - 1); - - return this->lpVtbl->Release((IDispatch *) this); -} - -static STDMETHODIMP -ISupportErrorInfo_InterfaceSupportsErrorInfo( - ISupportErrorInfo *This, - REFIID riid) -{ - /*TkWinSendCom *this = (TkWinSendCom*)(This - 1);*/ - return S_OK; /* or S_FALSE */ -} - -/* - * ---------------------------------------------------------------------- - * - * Async -- - * - * Queues the command for evaluation in the assigned interpreter. - * - * Results: - * A standard COM HRESULT is returned. The Tcl result is discarded. - * - * Side effects: - * The interpreters state and result will be modified. - * - * ---------------------------------------------------------------------- - */ - -static HRESULT -Async( - TkWinSendCom *obj, - VARIANT Cmd, - EXCEPINFO *pExcepInfo, - UINT *puArgErr) -{ - HRESULT hr = S_OK; - VARIANT vCmd; - Tcl_DString ds; - - VariantInit(&vCmd); - - hr = VariantChangeType(&vCmd, &Cmd, 0, VT_BSTR); - if (FAILED(hr)) { - Tcl_SetObjResult(obj->interp, Tcl_NewStringObj( - "invalid args: Async(command)", -1)); - TkWinSend_SetExcepInfo(obj->interp, pExcepInfo); - hr = DISP_E_EXCEPTION; - } - - if (SUCCEEDED(hr) && obj->interp) { - Tcl_Obj *scriptPtr; - - Tcl_WinTCharToUtf(vCmd.bstrVal, (int) SysStringLen(vCmd.bstrVal) * - sizeof (WCHAR), &ds); - scriptPtr = - Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); - Tcl_DStringFree(&ds); - TkWinSend_QueueCommand(obj->interp, scriptPtr); - } - - VariantClear(&vCmd); - return hr; -} - -/* - * ---------------------------------------------------------------------- - * - * Send -- - * - * Evaluates the string in the assigned interpreter. If the result is a - * valid address then set it to the result returned by the evaluation. - * Tcl exceptions are converted into COM exceptions. - * - * Results: - * A standard COM HRESULT is returned. The Tcl result is set as the - * method calls result. - * - * Side effects: - * The interpreters state and result will be modified. - * - * ---------------------------------------------------------------------- - */ - -static HRESULT -Send( - TkWinSendCom *obj, - VARIANT vCmd, - VARIANT *pvResult, - EXCEPINFO *pExcepInfo, - UINT *puArgErr) -{ - HRESULT hr = S_OK; - int result = TCL_OK; - VARIANT v; - register Tcl_Interp *interp = obj->interp; - Tcl_Obj *scriptPtr; - Tcl_DString ds; - - if (interp == NULL) { - return S_OK; - } - VariantInit(&v); - hr = VariantChangeType(&v, &vCmd, 0, VT_BSTR); - if (!SUCCEEDED(hr)) { - return hr; - } - - Tcl_WinTCharToUtf(v.bstrVal, (int) SysStringLen(v.bstrVal) * - sizeof (WCHAR), &ds); - scriptPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); - Tcl_DStringFree(&ds); - Tcl_Preserve(interp); - Tcl_IncrRefCount(scriptPtr); - result = Tcl_EvalObjEx(interp, scriptPtr, - TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL); - Tcl_DecrRefCount(scriptPtr); - if (pvResult != NULL) { - Tcl_Obj *obj; - const char *src; - - VariantInit(pvResult); - pvResult->vt = VT_BSTR; - obj = Tcl_GetObjResult(interp); - src = Tcl_GetString(obj); - Tcl_WinUtfToTChar(src, obj->length, &ds); - pvResult->bstrVal = SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); - Tcl_DStringFree(&ds); - } - if (result == TCL_ERROR) { - hr = DISP_E_EXCEPTION; - TkWinSend_SetExcepInfo(interp, pExcepInfo); - } - Tcl_Release(interp); - VariantClear(&v); - return hr; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinSendCom.h b/tk8.6/win/tkWinSendCom.h deleted file mode 100644 index cd6ec18..0000000 --- a/tk8.6/win/tkWinSendCom.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * tkWinSendCom.h -- - * - * This file provides procedures that implement the Windows "send" - * command, allowing commands to be passed from interpreter to - * interpreter. - * - * Copyright (C) 2002 Pat Thoyts <patthoyts@users.sourceforge.net> - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#ifndef _tkWinSendCom_h_INCLUDE -#define _tkWinSendCom_h_INCLUDE - -#include "tkWinInt.h" -#include <ole2.h> - -#ifdef _MSC_VER -# pragma comment (lib, "ole32.lib") -# pragma comment (lib, "oleaut32.lib") -# pragma comment (lib, "uuid.lib") -#endif - -/* - * TkWinSendCom CoClass structure - */ - -typedef struct { - IDispatchVtbl *lpVtbl; - ISupportErrorInfoVtbl *lpVtbl2; - long refcount; - Tcl_Interp *interp; -} TkWinSendCom; - -/* - * TkWinSendCom Dispatch IDs - */ - -#define TKWINSENDCOM_DISPID_SEND 1 -#define TKWINSENDCOM_DISPID_ASYNC 2 - -/* - * TkWinSendCom public functions - */ - -MODULE_SCOPE HRESULT TkWinSendCom_CreateInstance(Tcl_Interp *interp, - REFIID riid, void **ppv); -MODULE_SCOPE int TkWinSend_QueueCommand(Tcl_Interp *interp, - Tcl_Obj *cmdPtr); -MODULE_SCOPE void TkWinSend_SetExcepInfo(Tcl_Interp *interp, - EXCEPINFO *pExcepInfo); - -#endif /* _tkWinSendCom_h_INCLUDE */ - -/* - * Local Variables: - * mode: c - * End: - */ diff --git a/tk8.6/win/tkWinTest.c b/tk8.6/win/tkWinTest.c deleted file mode 100644 index 6e79df3..0000000 --- a/tk8.6/win/tkWinTest.c +++ /dev/null @@ -1,583 +0,0 @@ -/* - * tkWinTest.c -- - * - * Contains commands for platform specific tests for the Windows - * platform. - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * Copyright (c) 2000 by Scriptics Corporation. - * Copyright (c) 2001 by ActiveState Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#undef USE_TCL_STUBS -#define USE_TCL_STUBS -#undef USE_TK_STUBS -#define USE_TK_STUBS -#include "tkWinInt.h" - -HWND tkWinCurrentDialog; - -/* - * Forward declarations of functions defined later in this file: - */ - -static int TestclipboardObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -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[]); -static int TestgetwindowinfoObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int TestwinlocaleObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static Tk_GetSelProc SetSelectionResult; - -/* - *---------------------------------------------------------------------- - * - * TkplatformtestInit -- - * - * Defines commands that test platform specific functionality for Windows - * platforms. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Defines new commands. - * - *---------------------------------------------------------------------- - */ - -int -TkplatformtestInit( - Tcl_Interp *interp) /* Interpreter to add commands to. */ -{ - /* - * Add commands for platform specific tests on MacOS here. - */ - - Tcl_CreateObjCommand(interp, "testclipboard", TestclipboardObjCmd, - (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateObjCommand(interp, "testwinevent", TestwineventObjCmd, - (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateObjCommand(interp, "testfindwindow", TestfindwindowObjCmd, - (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateObjCommand(interp, "testgetwindowinfo", TestgetwindowinfoObjCmd, - (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateObjCommand(interp, "testwinlocale", TestwinlocaleObjCmd, - (ClientData) Tk_MainWindow(interp), NULL); - 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; -} - - -/* - *---------------------------------------------------------------------- - * - * AppendSystemError -- - * - * This routine formats a Windows system error message and places it into - * the interpreter result. Originally from tclWinReg.c. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -AppendSystemError( - Tcl_Interp *interp, /* Current interpreter. */ - DWORD error) /* Result code from error. */ -{ - int length; - WCHAR *wMsgPtr, **wMsgPtrPtr = &wMsgPtr; - const char *msg; - char id[TCL_INTEGER_SPACE], msgBuf[24 + TCL_INTEGER_SPACE]; - Tcl_DString ds; - Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); - - if (Tcl_IsShared(resultPtr)) { - resultPtr = Tcl_DuplicateObj(resultPtr); - } - length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_IGNORE_INSERTS - | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) wMsgPtrPtr, - 0, NULL); - if (length == 0) { - char *msgPtr; - - length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_IGNORE_INSERTS - | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &msgPtr, - 0, NULL); - if (length > 0) { - wMsgPtr = (WCHAR *) LocalAlloc(LPTR, (length + 1) * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, msgPtr, length + 1, wMsgPtr, - length + 1); - LocalFree(msgPtr); - } - } - if (length == 0) { - if (error == ERROR_CALL_NOT_IMPLEMENTED) { - strcpy(msgBuf, "function not supported under Win32s"); - } else { - sprintf(msgBuf, "unknown error: %ld", error); - } - msg = msgBuf; - } else { - Tcl_Encoding encoding; - char *msgPtr; - - encoding = Tcl_GetEncoding(NULL, "unicode"); - Tcl_ExternalToUtfDString(encoding, (char *) wMsgPtr, -1, &ds); - Tcl_FreeEncoding(encoding); - LocalFree(wMsgPtr); - - msgPtr = Tcl_DStringValue(&ds); - length = Tcl_DStringLength(&ds); - - /* - * Trim the trailing CR/LF from the system message. - */ - - if (msgPtr[length-1] == '\n') { - --length; - } - if (msgPtr[length-1] == '\r') { - --length; - } - msgPtr[length] = 0; - msg = msgPtr; - } - - sprintf(id, "%ld", error); - Tcl_SetErrorCode(interp, "WINDOWS", id, msg, NULL); - Tcl_AppendToObj(resultPtr, msg, length); - Tcl_SetObjResult(interp, resultPtr); - - if (length != 0) { - Tcl_DStringFree(&ds); - } -} - -/* - *---------------------------------------------------------------------- - * - * TestclipboardObjCmd -- - * - * This function implements the testclipboard command. It provides a way - * to determine the actual contents of the Windows clipboard. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -SetSelectionResult( - ClientData dummy, - Tcl_Interp *interp, - const char *selection) -{ - Tcl_AppendResult(interp, selection, NULL); - return TCL_OK; -} - -static int -TestclipboardObjCmd( - ClientData clientData, /* Main window for application. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument values. */ -{ - Tk_Window tkwin = (Tk_Window) clientData; - - if (objc != 1) { - Tcl_WrongNumArgs(interp, 1, objv, NULL); - return TCL_ERROR; - } - return TkSelGetSelection(interp, tkwin, Tk_InternAtom(tkwin, "CLIPBOARD"), - XA_STRING, SetSelectionResult, NULL); -} - -/* - *---------------------------------------------------------------------- - * - * TestwineventObjCmd -- - * - * This function implements the testwinevent command. It provides a way - * to send messages to windows dialogs. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -TestwineventObjCmd( - ClientData clientData, /* Main window for application. */ - Tcl_Interp *interp, /* Current interpreter. */ - 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"}, - {WM_CHAR, "WM_CHAR"}, - {WM_GETTEXT, "WM_GETTEXT"}, - {WM_SETTEXT, "WM_SETTEXT"}, - {WM_COMMAND, "WM_COMMAND"}, - {-1, NULL} - }; - - if ((objc == 3) && (strcmp(Tcl_GetString(objv[1]), "debug") == 0)) { - int b; - - if (Tcl_GetBoolean(interp, Tcl_GetString(objv[2]), &b) != TCL_OK) { - return TCL_ERROR; - } - TkWinDialogDebug(b); - return TCL_OK; - } - - if (objc < 4) { - return TCL_ERROR; - } - - 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; - } - } - UpdateWindow(hwnd); - - 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, Tcl_GetString(objv[2])) == 0) { - id = GetDlgCtrlID(child); - break; - } - child = GetWindow(child, GW_HWNDNEXT); - } - if (child == NULL) { - Tcl_AppendResult(interp, "could not find a control matching \"", - Tcl_GetString(objv[2]), "\"", NULL); - return TCL_ERROR; - } - } - - message = TkFindStateNum(NULL, NULL, messageMap, Tcl_GetString(objv[3])); - wParam = 0; - lParam = 0; - - if (objc > 4) { - wParam = strtol(Tcl_GetString(objv[4]), NULL, 0); - } - if (objc > 5) { - lParam = strtol(Tcl_GetString(objv[5]), NULL, 0); - } - - switch (message) { - case WM_GETTEXT: { - 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); - break; - } - case WM_SETTEXT: { - Tcl_DString 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; - } - break; - } - case WM_COMMAND: { - char buf[TCL_INTEGER_SPACE]; - if (objc < 5) { - wParam = MAKEWPARAM(id, 0); - lParam = (LPARAM)child; - } - sprintf(buf, "%d", (int) SendMessageA(hwnd, message, wParam, lParam)); - Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1)); - break; - } - default: { - char buf[TCL_INTEGER_SPACE]; - - sprintf(buf, "%d", - (int) SendDlgItemMessageA(hwnd, id, message, wParam, lParam)); - Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1)); - break; - } - } - return TCL_OK; -} - -/* - * testfindwindow title ?class? - * Find a Windows window using the FindWindow API call. This takes the window - * title and optionally the window class and if found returns the HWND and - * raises an error if the window is not found. - * eg: testfindwindow Console TkTopLevel - * Can find the console window if it is visible. - * eg: testfindwindow "TkTest #10201" "#32770" - * Can find a messagebox window with this title. - */ - -static int -TestfindwindowObjCmd( - ClientData clientData, /* Main window for application. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument values. */ -{ - const TCHAR *title = NULL, *class = NULL; - Tcl_DString titleString, classString; - HWND hwnd = NULL; - int r = TCL_OK; - DWORD myPid; - - Tcl_DStringInit(&classString); - Tcl_DStringInit(&titleString); - - if (objc < 2 || objc > 3) { - Tcl_WrongNumArgs(interp, 1, objv, "title ?class?"); - return TCL_ERROR; - } - - title = Tcl_WinUtfToTChar(Tcl_GetString(objv[1]), -1, &titleString); - 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)); - AppendSystemError(interp, GetLastError()); - r = TCL_ERROR; - } else { - Tcl_SetObjResult(interp, Tcl_NewLongObj(PTR2INT(hwnd))); - } - - Tcl_DStringFree(&titleString); - Tcl_DStringFree(&classString); - return r; - -} - -static BOOL CALLBACK -EnumChildrenProc( - HWND hwnd, - LPARAM lParam) -{ - Tcl_Obj *listObj = (Tcl_Obj *) lParam; - - Tcl_ListObjAppendElement(NULL, listObj, Tcl_NewLongObj(PTR2INT(hwnd))); - return TRUE; -} - -static int -TestgetwindowinfoObjCmd( - ClientData clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - long hwnd; - Tcl_Obj *dictObj = NULL, *classObj = NULL, *textObj = NULL; - Tcl_Obj *childrenObj = NULL; - TCHAR buf[512]; - int cch, cchBuf = 256; - Tcl_DString ds; - - if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "hwnd"); - return TCL_ERROR; - } - - if (Tcl_GetLongFromObj(interp, objv[1], &hwnd) != TCL_OK) - return TCL_ERROR; - - cch = GetClassName(INT2PTR(hwnd), buf, cchBuf); - if (cch == 0) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to get class name: ", -1)); - AppendSystemError(interp, GetLastError()); - return TCL_ERROR; - } else { - Tcl_DString ds; - Tcl_WinTCharToUtf(buf, -1, &ds); - classObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); - Tcl_DStringFree(&ds); - } - - dictObj = Tcl_NewDictObj(); - Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("class", 5), classObj); - Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("id", 2), - Tcl_NewLongObj(GetWindowLongA(INT2PTR(hwnd), GWL_ID))); - - cch = GetWindowText(INT2PTR(hwnd), (LPTSTR)buf, cchBuf); - Tcl_WinTCharToUtf(buf, cch * sizeof (WCHAR), &ds); - textObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); - Tcl_DStringFree(&ds); - - Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("text", 4), textObj); - Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("parent", 6), - Tcl_NewLongObj(PTR2INT(GetParent((INT2PTR(hwnd)))))); - - childrenObj = Tcl_NewListObj(0, NULL); - EnumChildWindows(INT2PTR(hwnd), EnumChildrenProc, (LPARAM)childrenObj); - Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("children", -1), childrenObj); - - Tcl_SetObjResult(interp, dictObj); - return TCL_OK; -} - -static int -TestwinlocaleObjCmd( - ClientData clientData, /* Main window for application. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument values. */ -{ - if (objc != 1) { - Tcl_WrongNumArgs(interp, 1, objv, NULL); - return TCL_ERROR; - } - Tcl_SetObjResult(interp, Tcl_NewIntObj((int)GetThreadLocale())); - return TCL_OK; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinWindow.c b/tk8.6/win/tkWinWindow.c deleted file mode 100644 index 385e72b..0000000 --- a/tk8.6/win/tkWinWindow.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* - * tkWinWindow.c -- - * - * Xlib emulation routines for Windows related to creating, displaying - * and destroying windows. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" -#include "tkBusy.h" - -typedef struct ThreadSpecificData { - int initialized; /* 0 means table below needs initializing. */ - Tcl_HashTable windowTable; /* The windowTable maps from HWND to Tk_Window - * handles. */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -/* - * Forward declarations for functions defined in this file: - */ - -static void NotifyVisibility(XEvent *eventPtr, TkWindow *winPtr); - -/* - *---------------------------------------------------------------------- - * - * Tk_AttachHWND -- - * - * This function binds an HWND and a reflection function to the specified - * Tk_Window. - * - * Results: - * Returns an X Window that encapsulates the HWND. - * - * Side effects: - * May allocate a new X Window. Also enters the HWND into the global - * window table. - * - *---------------------------------------------------------------------- - */ - -Window -Tk_AttachHWND( - Tk_Window tkwin, - HWND hwnd) -{ - int new; - Tcl_HashEntry *entryPtr; - TkWinDrawable *twdPtr = (TkWinDrawable *) Tk_WindowId(tkwin); - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (!tsdPtr->initialized) { - Tcl_InitHashTable(&tsdPtr->windowTable, TCL_ONE_WORD_KEYS); - tsdPtr->initialized = 1; - } - - /* - * Allocate a new drawable if necessary. Otherwise, remove the previous - * HWND from from the window table. - */ - - if (twdPtr == NULL) { - twdPtr = ckalloc(sizeof(TkWinDrawable)); - twdPtr->type = TWD_WINDOW; - twdPtr->window.winPtr = (TkWindow *) tkwin; - } else if (twdPtr->window.handle != NULL) { - entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, - (char *)twdPtr->window.handle); - Tcl_DeleteHashEntry(entryPtr); - } - - /* - * Insert the new HWND into the window table. - */ - - twdPtr->window.handle = hwnd; - entryPtr = Tcl_CreateHashEntry(&tsdPtr->windowTable, (char *)hwnd, &new); - Tcl_SetHashValue(entryPtr, tkwin); - - return (Window)twdPtr; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_HWNDToWindow -- - * - * This function retrieves a Tk_Window from the window table given an - * HWND. - * - * Results: - * Returns the matching Tk_Window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tk_Window -Tk_HWNDToWindow( - HWND hwnd) -{ - Tcl_HashEntry *entryPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (!tsdPtr->initialized) { - Tcl_InitHashTable(&tsdPtr->windowTable, TCL_ONE_WORD_KEYS); - tsdPtr->initialized = 1; - } - entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, (char *) hwnd); - if (entryPtr != NULL) { - return (Tk_Window) Tcl_GetHashValue(entryPtr); - } - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetHWND -- - * - * This function extracts the HWND from an X Window. - * - * Results: - * Returns the HWND associated with the Window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -HWND -Tk_GetHWND( - Window window) -{ - return ((TkWinDrawable *) window)->window.handle; -} - -/* - *---------------------------------------------------------------------- - * - * TkpPrintWindowId -- - * - * This routine stores the string representation of the platform - * dependent window handle for an X Window in the given buffer. - * - * Results: - * Returns the result in the specified buffer. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkpPrintWindowId( - char *buf, /* Pointer to string large enough to hold the - * hex representation of a pointer. */ - Window window) /* Window to be printed into buffer. */ -{ - HWND hwnd = (window) ? Tk_GetHWND(window) : 0; - - /* - * Use pointer representation, because Win64 is P64 (*not* LP64). Windows - * doesn't print the 0x for %p, so we do it. - * Bug 2026405: cygwin does output 0x for %p so test and recover. - */ - - sprintf(buf, "0x%p", hwnd); - if (buf[2] == '0' && buf[3] == 'x') { - sprintf(buf, "%p", hwnd); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpScanWindowId -- - * - * Given a string which represents the platform dependent window handle, - * produce the X Window id for the window. - * - * Results: - * The return value is normally TCL_OK; in this case *idPtr will be set - * to the X Window id equivalent to string. If string is improperly - * formed then TCL_ERROR is returned and an error message will be left in - * the interp's result. If the number does not correspond to a Tk Window, - * then *idPtr will be set to None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkpScanWindowId( - Tcl_Interp *interp, /* Interpreter to use for error reporting. */ - const char *string, /* String containing a (possibly signed) - * integer in a form acceptable to strtol. */ - Window *idPtr) /* Place to store converted result. */ -{ - Tk_Window tkwin; - union { - HWND hwnd; - int number; - } win; - - /* - * We want sscanf for the 64-bit check, but if that doesn't work, then - * Tcl_GetInt manages the error correctly. - */ - - if ( -#ifdef _WIN64 - (sscanf(string, "0x%p", &win.hwnd) != 1) && -#endif - Tcl_GetInt(interp, string, &win.number) != TCL_OK) { - return TCL_ERROR; - } - - tkwin = Tk_HWNDToWindow(win.hwnd); - if (tkwin) { - *idPtr = Tk_WindowId(tkwin); - } else { - *idPtr = None; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkpMakeWindow -- - * - * Creates a Windows window object based on the current attributes of the - * specified TkWindow. - * - * Results: - * Returns a pointer to a new TkWinDrawable cast to a Window. - * - * Side effects: - * Creates a new window. - * - *---------------------------------------------------------------------- - */ - -Window -TkpMakeWindow( - TkWindow *winPtr, - Window parent) -{ - HWND parentWin; - int style; - HWND hwnd; - - if (parent != None) { - parentWin = Tk_GetHWND(parent); - style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; - } else { - parentWin = NULL; - style = WS_POPUP | WS_CLIPCHILDREN; - } - - /* - * Create the window, then ensure that it is at the top of the stacking - * order. - */ - - hwnd = CreateWindowEx(WS_EX_NOPARENTNOTIFY, TK_WIN_CHILD_CLASS_NAME, NULL, - (DWORD) style, Tk_X(winPtr), Tk_Y(winPtr), Tk_Width(winPtr), - Tk_Height(winPtr), parentWin, NULL, Tk_GetHINSTANCE(), NULL); - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - return Tk_AttachHWND((Tk_Window)winPtr, hwnd); -} - -/* - *---------------------------------------------------------------------- - * - * XDestroyWindow -- - * - * Destroys the given window. - * - * Results: - * None. - * - * Side effects: - * Sends the WM_DESTROY message to the window and then destroys it the - * Win32 resources associated with the window. - * - *---------------------------------------------------------------------- - */ - -int -XDestroyWindow( - Display *display, - Window w) -{ - Tcl_HashEntry *entryPtr; - TkWinDrawable *twdPtr = (TkWinDrawable *)w; - TkWindow *winPtr = TkWinGetWinPtr(w); - HWND hwnd = Tk_GetHWND(w); - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - display->request++; - - /* - * Remove references to the window in the pointer module then release the - * drawable. - */ - - TkPointerDeadWindow(winPtr); - - entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, (char*)hwnd); - if (entryPtr != NULL) { - Tcl_DeleteHashEntry(entryPtr); - } - - ckfree(twdPtr); - - /* - * Don't bother destroying the window if we are going to destroy the - * parent later. - */ - - if (hwnd != NULL && !(winPtr->flags & TK_DONT_DESTROY_WINDOW)) { - DestroyWindow(hwnd); - } - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XMapWindow -- - * - * Cause the given window to become visible. - * - * Results: - * None - * - * Side effects: - * Causes the window state to change, and generates a MapNotify event. - * - *---------------------------------------------------------------------- - */ - -int -XMapWindow( - Display *display, - Window w) -{ - XEvent event; - TkWindow *parentPtr; - TkWindow *winPtr = TkWinGetWinPtr(w); - - display->request++; - - ShowWindow(Tk_GetHWND(w), SW_SHOWNORMAL); - winPtr->flags |= TK_MAPPED; - - /* - * Check to see if this window is visible now. If all of the parent - * windows up to the first toplevel are mapped, then this window and its - * mapped children have just become visible. - */ - - if (!(winPtr->flags & TK_TOP_HIERARCHY)) { - for (parentPtr = winPtr->parentPtr; ; - parentPtr = parentPtr->parentPtr) { - if ((parentPtr == NULL) || !(parentPtr->flags & TK_MAPPED)) { - return Success; - } - if (parentPtr->flags & TK_TOP_HIERARCHY) { - break; - } - } - } else { - event.type = MapNotify; - event.xmap.serial = display->request; - event.xmap.send_event = False; - event.xmap.display = display; - event.xmap.event = winPtr->window; - event.xmap.window = winPtr->window; - event.xmap.override_redirect = winPtr->atts.override_redirect; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - } - - /* - * Generate VisibilityNotify events for this window and its mapped - * children. - */ - - event.type = VisibilityNotify; - event.xvisibility.serial = display->request; - event.xvisibility.send_event = False; - event.xvisibility.display = display; - event.xvisibility.window = winPtr->window; - event.xvisibility.state = VisibilityUnobscured; - NotifyVisibility(&event, winPtr); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * NotifyVisibility -- - * - * This function recursively notifies the mapped children of the - * specified window of a change in visibility. Note that we don't - * properly report the visibility state, since Windows does not provide - * that info. The eventPtr argument must point to an event that has been - * completely initialized except for the window slot. - * - * Results: - * None. - * - * Side effects: - * Generates lots of events. - * - *---------------------------------------------------------------------- - */ - -static void -NotifyVisibility( - XEvent *eventPtr, /* Initialized VisibilityNotify event. */ - TkWindow *winPtr) /* Window to notify. */ -{ - if (winPtr->atts.event_mask & VisibilityChangeMask) { - eventPtr->xvisibility.window = winPtr->window; - Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL); - } - for (winPtr = winPtr->childList; winPtr != NULL; - winPtr = winPtr->nextPtr) { - if (winPtr->flags & TK_MAPPED) { - NotifyVisibility(eventPtr, winPtr); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * XUnmapWindow -- - * - * Cause the given window to become invisible. - * - * Results: - * None - * - * Side effects: - * Causes the window state to change, and generates an UnmapNotify event. - * - *---------------------------------------------------------------------- - */ - -int -XUnmapWindow( - Display *display, - Window w) -{ - XEvent event; - TkWindow *winPtr = TkWinGetWinPtr(w); - - display->request++; - - /* - * Bug fix: Don't short circuit this routine based on TK_MAPPED because it - * will be cleared before XUnmapWindow is called. - */ - - ShowWindow(Tk_GetHWND(w), SW_HIDE); - winPtr->flags &= ~TK_MAPPED; - - if (winPtr->flags & TK_WIN_MANAGED) { - event.type = UnmapNotify; - event.xunmap.serial = display->request; - event.xunmap.send_event = False; - event.xunmap.display = display; - event.xunmap.event = winPtr->window; - event.xunmap.window = winPtr->window; - event.xunmap.from_configure = False; - Tk_HandleEvent(&event); - } - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XMoveResizeWindow -- - * - * Move and resize a window relative to its parent. - * - * Results: - * None. - * - * Side effects: - * Repositions and resizes the specified window. - * - *---------------------------------------------------------------------- - */ - -int -XMoveResizeWindow( - Display *display, - Window w, - int x, int y, /* Position relative to parent. */ - unsigned int width, unsigned int height) -{ - display->request++; - MoveWindow(Tk_GetHWND(w), x, y, (int) width, (int) height, TRUE); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XMoveWindow -- - * - * Move a window relative to its parent. - * - * Results: - * None. - * - * Side effects: - * Repositions the specified window. - * - *---------------------------------------------------------------------- - */ - -int -XMoveWindow( - Display *display, - Window w, - int x, int y) /* Position relative to parent */ -{ - TkWindow *winPtr = TkWinGetWinPtr(w); - - display->request++; - - MoveWindow(Tk_GetHWND(w), x, y, winPtr->changes.width, - winPtr->changes.height, TRUE); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XResizeWindow -- - * - * Resize a window. - * - * Results: - * None. - * - * Side effects: - * Resizes the specified window. - * - *---------------------------------------------------------------------- - */ - -int -XResizeWindow( - Display *display, - Window w, - unsigned int width, unsigned int height) -{ - TkWindow *winPtr = TkWinGetWinPtr(w); - - display->request++; - - MoveWindow(Tk_GetHWND(w), winPtr->changes.x, winPtr->changes.y, (int)width, - (int)height, TRUE); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XRaiseWindow, XLowerWindow -- - * - * Change the stacking order of a window. - * - * Results: - * None. - * - * Side effects: - * Changes the stacking order of the specified window. - * - *---------------------------------------------------------------------- - */ - -int -XRaiseWindow( - Display *display, - Window w) -{ - HWND window = Tk_GetHWND(w); - - display->request++; - SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - return Success; -} - -int -XLowerWindow( - Display *display, - Window w) -{ - HWND window = Tk_GetHWND(w); - - display->request++; - SetWindowPos(window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XConfigureWindow -- - * - * Change the size, position, stacking, or border of the specified - * window. - * - * Results: - * None. - * - * Side effects: - * Changes the attributes of the specified window. Note that we ignore - * the passed in values and use the values stored in the TkWindow data - * structure. - * - *---------------------------------------------------------------------- - */ - -int -XConfigureWindow( - Display *display, - Window w, - unsigned int valueMask, - XWindowChanges *values) -{ - TkWindow *winPtr = TkWinGetWinPtr(w); - HWND hwnd = Tk_GetHWND(w); - - display->request++; - - /* - * Change the shape and/or position of the window. - */ - - if (valueMask & (CWX|CWY|CWWidth|CWHeight)) { - MoveWindow(hwnd, winPtr->changes.x, winPtr->changes.y, - winPtr->changes.width, winPtr->changes.height, TRUE); - } - - /* - * Change the stacking order of the window. - */ - - if (valueMask & CWStackMode) { - HWND sibling; - - if ((valueMask & CWSibling) && (values->sibling != None)) { - sibling = Tk_GetHWND(values->sibling); - } else { - sibling = NULL; - } - TkWinSetWindowPos(hwnd, sibling, values->stack_mode); - } - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XClearWindow -- - * - * Clears the entire window to the current background color. - * - * Results: - * None. - * - * Side effects: - * Erases the current contents of the window. - * - *---------------------------------------------------------------------- - */ - -int -XClearWindow( - Display *display, - Window w) -{ - RECT rc; - HBRUSH brush; - HPALETTE oldPalette, palette; - TkWindow *winPtr; - HWND hwnd = Tk_GetHWND(w); - HDC dc = GetDC(hwnd); - - palette = TkWinGetPalette(display->screens[0].cmap); - oldPalette = SelectPalette(dc, palette, FALSE); - - display->request++; - - winPtr = TkWinGetWinPtr(w); - brush = CreateSolidBrush(winPtr->atts.background_pixel); - GetWindowRect(hwnd, &rc); - rc.right = rc.right - rc.left; - rc.bottom = rc.bottom - rc.top; - rc.left = rc.top = 0; - FillRect(dc, &rc, brush); - - DeleteObject(brush); - SelectPalette(dc, oldPalette, TRUE); - ReleaseDC(hwnd, dc); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XChangeWindowAttributes -- - * - * This function is called when the attributes on a window are updated. - * Since Tk maintains all of the window state, the only relevant value is - * the cursor. - * - * Results: - * None. - * - * Side effects: - * May cause the mouse position to be updated. - * - *---------------------------------------------------------------------- - */ - -int -XChangeWindowAttributes( - Display *display, - Window w, - unsigned long valueMask, - XSetWindowAttributes* attributes) -{ - if (valueMask & CWCursor) { - XDefineCursor(display, w, attributes->cursor); - } - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * XReparentWindow -- - * - * TODO: currently placeholder to satisfy Xlib stubs. - * - * Results: - * None. - * - * Side effects: - * TODO. - * - *---------------------------------------------------------------------- - */ - -int -XReparentWindow( - Display *display, - Window w, - Window parent, - int x, - int y) -{ - return BadWindow; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinSetWindowPos -- - * - * Adjust the stacking order of a window relative to a second window (or - * NULL). - * - * Results: - * None. - * - * Side effects: - * Moves the specified window in the stacking order. - * - *---------------------------------------------------------------------- - */ - -void -TkWinSetWindowPos( - HWND hwnd, /* Window to restack. */ - HWND siblingHwnd, /* Sibling window. */ - int pos) /* One of Above or Below. */ -{ - HWND temp; - - /* - * Since Windows does not support Above mode, we place the specified - * window below the sibling and then swap them. - */ - - if (siblingHwnd) { - if (pos == Above) { - SetWindowPos(hwnd, siblingHwnd, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - temp = hwnd; - hwnd = siblingHwnd; - siblingHwnd = temp; - } - } else { - siblingHwnd = (pos == Above) ? HWND_TOP : HWND_BOTTOM; - } - - SetWindowPos(hwnd, siblingHwnd, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); -} - -/* - *---------------------------------------------------------------------- - * - * TkpShowBusyWindow -- - * - * Makes a busy window "appear". - * - * Results: - * None. - * - * Side effects: - * Arranges for the busy window to start intercepting events and the - * cursor to change to the configured "hey, I'm busy!" setting. - * - *---------------------------------------------------------------------- - */ - -void -TkpShowBusyWindow( - TkBusy busy) -{ - Busy *busyPtr = (Busy *) busy; - HWND hWnd; - POINT point; - Display *display; - Window window; - - if (busyPtr->tkBusy != NULL) { - Tk_MapWindow(busyPtr->tkBusy); - window = Tk_WindowId(busyPtr->tkBusy); - display = Tk_Display(busyPtr->tkBusy); - hWnd = Tk_GetHWND(window); - display->request++; - SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - } - - /* - * Under Win32, cursors aren't associated with windows. Tk fakes this by - * watching Motion events on its windows. So Tk will automatically change - * the cursor when the pointer enters the Busy window. But Windows does - * not immediately change the cursor; it waits for the cursor position to - * change or a system call. We need to change the cursor before the - * application starts processing, so set the cursor position redundantly - * back to the current position. - */ - - GetCursorPos(&point); - SetCursorPos(point.x, point.y); -} - -/* - *---------------------------------------------------------------------- - * - * TkpHideBusyWindow -- - * - * Makes a busy window "disappear". - * - * Results: - * None. - * - * Side effects: - * Arranges for the busy window to stop intercepting events, and the - * cursor to change back to its normal setting. - * - *---------------------------------------------------------------------- - */ - -void -TkpHideBusyWindow( - TkBusy busy) -{ - Busy *busyPtr = (Busy *) busy; - POINT point; - - if (busyPtr->tkBusy != NULL) { - Tk_UnmapWindow(busyPtr->tkBusy); - } - - /* - * Under Win32, cursors aren't associated with windows. Tk fakes this by - * watching Motion events on its windows. So Tk will automatically change - * the cursor when the pointer enters the Busy window. But Windows does - * not immediately change the cursor: it waits for the cursor position to - * change or a system call. We need to change the cursor before the - * application starts processing, so set the cursor position redundantly - * back to the current position. - */ - - GetCursorPos(&point); - SetCursorPos(point.x, point.y); -} - -/* - *---------------------------------------------------------------------- - * - * TkpMakeTransparentWindowExist -- - * - * Construct the platform-specific resources for a transparent window. - * - * Results: - * None. - * - * Side effects: - * Moves the specified window in the stacking order. - * - *---------------------------------------------------------------------- - */ - -void -TkpMakeTransparentWindowExist( - Tk_Window tkwin, /* Token for window. */ - Window parent) /* Parent window. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - HWND hParent = (HWND) parent, hWnd; - int style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; - DWORD exStyle = WS_EX_TRANSPARENT | WS_EX_TOPMOST; - - hWnd = CreateWindowEx(exStyle, TK_WIN_CHILD_CLASS_NAME, NULL, style, - Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), - hParent, NULL, Tk_GetHINSTANCE(), NULL); - winPtr->window = Tk_AttachHWND(tkwin, hWnd); -} - -/* - *---------------------------------------------------------------------- - * - * TkpCreateBusy -- - * - * Construct the platform-specific parts of a busy window. Note that this - * postpones the actual creation of the window resource until later. - * - * Results: - * None. - * - * Side effects: - * Sets up part of the busy window structure. - * - *---------------------------------------------------------------------- - */ - -void -TkpCreateBusy( - Tk_FakeWin *winPtr, - Tk_Window tkRef, - Window *parentPtr, - Tk_Window tkParent, - TkBusy busy) -{ - Busy *busyPtr = (Busy *) busy; - - if (winPtr->flags & TK_REPARENTED) { - /* - * This works around a bug in the implementation of menubars for - * non-Macintosh window systems (Win32 and X11). Tk doesn't reset the - * pointers to the parent window when the menu is reparented - * (winPtr->parentPtr points to the wrong window). We get around this - * by determining the parent via the native API calls. - */ - - HWND hWnd = GetParent(Tk_GetHWND(Tk_WindowId(tkRef))); - RECT rect; - - if (GetWindowRect(hWnd, &rect)) { - busyPtr->width = rect.right - rect.left; - busyPtr->height = rect.bottom - rect.top; - } - } else { - *parentPtr = Tk_WindowId(tkParent); - *parentPtr = (Window) Tk_GetHWND(*parentPtr); - } -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinWm.c b/tk8.6/win/tkWinWm.c deleted file mode 100644 index 4e7618d..0000000 --- a/tk8.6/win/tkWinWm.c +++ /dev/null @@ -1,8688 +0,0 @@ -/* - * tkWinWm.c -- - * - * This module takes care of the interactions between a Tk-based - * application and the window manager. Among other things, it implements - * the "wm" command and passes geometry information to the window - * manager. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-2000 by Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" -#include <shellapi.h> - -/* - * These next two defines are only valid on Win2K/XP+. - */ - -#ifndef WS_EX_LAYERED -#define WS_EX_LAYERED 0x00080000 -#endif -#ifndef LWA_COLORKEY -#define LWA_COLORKEY 0x00000001 -#endif -#ifndef LWA_ALPHA -#define LWA_ALPHA 0x00000002 -#endif - -/* - * Event structure for synthetic activation events. These events are placed on - * the event queue whenever a toplevel gets a WM_MOUSEACTIVATE message or - * a WM_ACTIVATE. If the window is being moved (*flagPtr will be true) - * then the handling of this event must be delayed until the operation - * has completed to avoid a premature WM_EXITSIZEMOVE event. - */ - -typedef struct ActivateEvent { - Tcl_Event ev; - TkWindow *winPtr; - const int *flagPtr; - HWND hwnd; -} ActivateEvent; - -/* - * A data structure of the following type holds information for each window - * manager protocol (such as WM_DELETE_WINDOW) for which a handler (i.e. a Tcl - * command) has been defined for a particular top-level window. - */ - -typedef struct ProtocolHandler { - Atom protocol; /* Identifies the protocol. */ - struct ProtocolHandler *nextPtr; - /* Next in list of protocol handlers for the - * same top-level window, or NULL for end of - * list. */ - Tcl_Interp *interp; /* Interpreter in which to invoke command. */ - char command[1]; /* Tcl command to invoke when a client message - * for this protocol arrives. The actual size - * of the structure varies to accommodate the - * needs of the actual command. THIS MUST BE - * THE LAST FIELD OF THE STRUCTURE. */ -} ProtocolHandler; - -#define HANDLER_SIZE(cmdLength) \ - ((unsigned) ((Tk_Offset(ProtocolHandler, command) + 1) + cmdLength)) - -/* - * Helper type passed via lParam to TkWmStackorderToplevelEnumProc - */ - -typedef struct TkWmStackorderToplevelPair { - Tcl_HashTable *table; - TkWindow **windowPtr; -} TkWmStackorderToplevelPair; - -/* - * This structure represents the contents of a icon, in terms of its image. - * The HICON is an internal Windows format. Most of these icon-specific - * structures originated with the Winico extension. We stripped out unused - * parts of that code, and integrated the code more naturally with Tcl. - */ - -typedef struct { - UINT Width, Height, Colors; /* Width, Height and bpp */ - LPBYTE lpBits; /* Ptr to DIB bits */ - DWORD dwNumBytes; /* How many bytes? */ - LPBITMAPINFO lpbi; /* Ptr to header */ - LPBYTE lpXOR; /* Ptr to XOR image bits */ - LPBYTE lpAND; /* Ptr to AND image bits */ - HICON hIcon; /* DAS ICON */ -} ICONIMAGE, *LPICONIMAGE; - -/* - * This structure is how we represent a block of the above items. We will - * reallocate these structures according to how many images they need to - * contain. - */ - -typedef struct { - int nNumImages; /* How many images? */ - ICONIMAGE IconImages[1]; /* Image entries */ -} BlockOfIconImages, *BlockOfIconImagesPtr; - -/* - * These two structures are used to read in icons from an 'icon directory' - * (i.e. the contents of a .icr file, say). We only use these structures - * temporarily, since we copy the information we want into a - * BlockOfIconImages. - */ - -typedef struct { - BYTE bWidth; /* Width of the image */ - BYTE bHeight; /* Height of the image (times 2) */ - BYTE bColorCount; /* Number of colors in image (0 if >=8bpp) */ - BYTE bReserved; /* Reserved */ - WORD wPlanes; /* Color Planes */ - WORD wBitCount; /* Bits per pixel */ - DWORD dwBytesInRes; /* How many bytes in this resource? */ - DWORD dwImageOffset; /* Where in the file is this image */ -} ICONDIRENTRY, *LPICONDIRENTRY; - -typedef struct { - WORD idReserved; /* Reserved */ - WORD idType; /* Resource type (1 for icons) */ - WORD idCount; /* How many images? */ - ICONDIRENTRY idEntries[1]; /* The entries for each image */ -} ICONDIR, *LPICONDIR; - -/* - * A pointer to one of these strucutures is associated with each toplevel. - * This allows us to free up all memory associated with icon resources when a - * window is deleted or if the window's icon is changed. They are simply - * reference counted according to: - * - * (1) How many WmInfo structures point to this object - * (2) Whether the ThreadSpecificData defined in this file contains a pointer - * to this object. - * - * The former count is for windows whose icons are individually set, and the - * latter is for the global default icon choice. - * - * Icons loaded from .icr/.icr use the iconBlock field, icons loaded from - * .exe/.dll use the hIcon field. - */ - -typedef struct WinIconInstance { - size_t refCount; /* Number of instances that share this data - * structure. */ - BlockOfIconImagesPtr iconBlock; - /* Pointer to icon resource data for image */ -} WinIconInstance; - -typedef struct WinIconInstance *WinIconPtr; - -/* - * A data structure of the following type holds window-manager-related - * information for each top-level window in an application. - */ - -typedef struct TkWmInfo { - TkWindow *winPtr; /* Pointer to main Tk information for this - * window. */ - HWND wrapper; /* This is the decorative frame window created - * by the window manager to wrap a toplevel - * window. This window is a direct child of - * the root window. */ - char *title; /* Title to display in window caption. If - * NULL, use name of widget. Malloced. */ - char *iconName; /* Name to display in icon. Malloced. */ - XWMHints hints; /* Various pieces of information for window - * manager. */ - char *leaderName; /* Path name of leader of window group - * (corresponds to hints.window_group). - * Malloc-ed. Note: this field doesn't get - * updated if leader is destroyed. */ - TkWindow *masterPtr; /* Master window for TRANSIENT_FOR property, - * or NULL. */ - Tk_Window icon; /* Window to use as icon for this window, or - * NULL. */ - Tk_Window iconFor; /* Window for which this window is icon, or - * NULL if this isn't an icon for anyone. */ - - /* - * Information used to construct an XSizeHints structure for the window - * manager: - */ - - int defMinWidth, defMinHeight, defMaxWidth, defMaxHeight; - /* Default resize limits given by system. */ - int sizeHintsFlags; /* Flags word for XSizeHints structure. If the - * PBaseSize flag is set then the window is - * gridded; otherwise it isn't gridded. */ - int minWidth, minHeight; /* Minimum dimensions of window, in pixels or - * grid units. */ - int maxWidth, maxHeight; /* Maximum dimensions of window, in pixels or - * grid units. 0 to default. */ - Tk_Window gridWin; /* Identifies the window that controls - * gridding for this top-level, or NULL if the - * top-level isn't currently gridded. */ - int widthInc, heightInc; /* Increments for size changes (# pixels per - * step). */ - struct { - int x; /* numerator */ - int y; /* denominator */ - } minAspect, maxAspect; /* Min/max aspect ratios for window. */ - int reqGridWidth, reqGridHeight; - /* The dimensions of the window (in grid - * units) requested through the geometry - * manager. */ - int gravity; /* Desired window gravity. */ - - /* - * Information used to manage the size and location of a window. - */ - - int width, height; /* Desired dimensions of window, specified in - * pixels or grid units. These values are set - * by the "wm geometry" command and by - * ConfigureNotify events (for when wm resizes - * window). -1 means user hasn't requested - * dimensions. */ - int x, y; /* Desired X and Y coordinates for window. - * These values are set by "wm geometry", plus - * by ConfigureNotify events (when wm moves - * window). These numbers are different than - * the numbers stored in winPtr->changes - * because (a) they could be measured from the - * right or bottom edge of the screen (see - * WM_NEGATIVE_X and WM_NEGATIVE_Y flags) and - * (b) if the window has been reparented then - * they refer to the parent rather than the - * window itself. */ - int borderWidth, borderHeight; - /* Width and height of window dressing, in - * pixels for the current style/exStyle. This - * includes the border on both sides of the - * window. */ - int configX, configY; /* x,y position of toplevel when window is - * switched into fullscreen state, */ - int configWidth, configHeight; - /* Dimensions passed to last request that we - * issued to change geometry of window. Used - * to eliminate redundant resize operations */ - HMENU hMenu; /* the hMenu associated with this menu */ - DWORD style, exStyle; /* Style flags for the wrapper window. */ - LONG styleConfig; /* Extra user requested style bits */ - LONG exStyleConfig; /* Extra user requested extended style bits */ - Tcl_Obj *crefObj; /* COLORREF object for transparent handling */ - COLORREF colorref; /* COLORREF for transparent handling */ - double alpha; /* Alpha transparency level 0.0 (fully - * transparent) .. 1.0 (opaque) */ - - /* - * List of children of the toplevel which have private colormaps. - */ - - TkWindow **cmapList; /* Array of window with private colormaps. */ - int cmapCount; /* Number of windows in array. */ - - /* - * Miscellaneous information. - */ - - ProtocolHandler *protPtr; /* First in list of protocol handlers for this - * window (NULL means none). */ - int cmdArgc; /* Number of elements in cmdArgv below. */ - const char **cmdArgv; /* Array of strings to store in the WM_COMMAND - * property. NULL means nothing available. */ - char *clientMachine; /* String to store in WM_CLIENT_MACHINE - * property, or NULL. */ - int flags; /* Miscellaneous flags, defined below. */ - int numTransients; /* Number of transients on this window */ - WinIconPtr iconPtr; /* Pointer to titlebar icon structure for this - * window, or NULL. */ - struct TkWmInfo *nextPtr; /* Next in list of all top-level windows. */ -} WmInfo; - -/* - * Flag values for WmInfo structures: - * - * WM_NEVER_MAPPED - Non-zero means window has never been mapped; - * need to update all info when window is first - * mapped. - * WM_UPDATE_PENDING - Non-zero means a call to UpdateGeometryInfo - * has already been scheduled for this window; - * no need to schedule another one. - * WM_NEGATIVE_X - Non-zero means x-coordinate is measured in - * pixels from right edge of screen, rather than - * from left edge. - * WM_NEGATIVE_Y - Non-zero means y-coordinate is measured in - * pixels up from bottom of screen, rather than - * down from top. - * WM_UPDATE_SIZE_HINTS - Non-zero means that new size hints need to be - * propagated to window manager. Not used on Win. - * WM_SYNC_PENDING - Set to non-zero while waiting for the window - * manager to respond to some state change. - * WM_MOVE_PENDING - Non-zero means the application has requested a - * new position for the window, but it hasn't - * been reflected through the window manager yet. - * WM_COLORMAPS_EXPLICIT - Non-zero means the colormap windows were set - * explicitly via "wm colormapwindows". - * WM_ADDED_TOPLEVEL_COLORMAP - Non-zero means that when "wm colormapwindows" - * was called the top-level itself wasn't - * specified, so we added it implicitly at the - * end of the list. - * WM_WIDTH_NOT_RESIZABLE - Non-zero means that we're not supposed to - * allow the user to change the width of the - * window (controlled by "wm resizable" command). - * WM_HEIGHT_NOT_RESIZABLE - Non-zero means that we're not supposed to - * allow the user to change the height of the - * window (controlled by "wm resizable" command). - * WM_WITHDRAWN - Non-zero means that this window has explicitly - * been withdrawn. If it's a transient, it should - * not mirror state changes in the master. - * WM_FULLSCREEN - Non-zero means that this window has been placed - * in the full screen mode. It should be mapped at - * 0,0 and be the width and height of the screen. - */ - -#define WM_NEVER_MAPPED (1<<0) -#define WM_UPDATE_PENDING (1<<1) -#define WM_NEGATIVE_X (1<<2) -#define WM_NEGATIVE_Y (1<<3) -#define WM_UPDATE_SIZE_HINTS (1<<4) -#define WM_SYNC_PENDING (1<<5) -#define WM_CREATE_PENDING (1<<6) -#define WM_MOVE_PENDING (1<<7) -#define WM_COLORMAPS_EXPLICIT (1<<8) -#define WM_ADDED_TOPLEVEL_COLORMAP (1<<9) -#define WM_WIDTH_NOT_RESIZABLE (1<<10) -#define WM_HEIGHT_NOT_RESIZABLE (1<<11) -#define WM_WITHDRAWN (1<<12) -#define WM_FULLSCREEN (1<<13) - -/* - * Window styles for various types of toplevel windows. - */ - -#define WM_OVERRIDE_STYLE (WS_CLIPCHILDREN|WS_CLIPSIBLINGS|CS_DBLCLKS) -#define EX_OVERRIDE_STYLE (WS_EX_TOOLWINDOW) - -#define WM_FULLSCREEN_STYLE (WS_POPUP|WM_OVERRIDE_STYLE) -#define EX_FULLSCREEN_STYLE (WS_EX_APPWINDOW) - -#define WM_TOPLEVEL_STYLE (WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|CS_DBLCLKS) -#define EX_TOPLEVEL_STYLE (0) - -#define WM_TRANSIENT_STYLE \ - (WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_CLIPSIBLINGS|CS_DBLCLKS) -#define EX_TRANSIENT_STYLE (WS_EX_DLGMODALFRAME) - -/* - * The following structure is the official type record for geometry management - * of top-level windows. - */ - -static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin); -static void RemapWindows(TkWindow *winPtr, HWND parentHWND); - -static const Tk_GeomMgr wmMgrType = { - "wm", /* name */ - TopLevelReqProc, /* requestProc */ - NULL, /* lostSlaveProc */ -}; - -typedef struct ThreadSpecificData { - HPALETTE systemPalette; /* System palette; refers to the currently - * installed foreground logical palette. */ - TkWindow *createWindow; /* Window that is being constructed. This - * value is set immediately before a call to - * CreateWindowEx, and is used by SetLimits. - * This is a gross hack needed to work around - * Windows brain damage where it sends the - * WM_GETMINMAXINFO message before the - * WM_CREATE window. */ - int initialized; /* Flag indicating whether thread-specific - * elements of module have been - * initialized. */ - int firstWindow; /* Flag, cleared when the first window is - * mapped in a non-iconic state. */ - WinIconPtr iconPtr; /* IconPtr being used as default for all - * toplevels, or NULL. */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -/* - * The following variables cannot be placed in thread local storage because - * they must be shared across threads. - */ - -static int initialized; /* Flag indicating whether module has been - * initialized. */ - -TCL_DECLARE_MUTEX(winWmMutex) - -/* - * Forward declarations for functions defined in this file: - */ - -static int ActivateWindow(Tcl_Event *evPtr, int flags); -static void ConfigureTopLevel(WINDOWPOS *pos); -static void GenerateConfigureNotify(TkWindow *winPtr); -static void GenerateActivateEvent(TkWindow *winPtr, const int *flagPtr); -static void GetMaxSize(WmInfo *wmPtr, - int *maxWidthPtr, int *maxHeightPtr); -static void GetMinSize(WmInfo *wmPtr, - int *minWidthPtr, int *minHeightPtr); -static TkWindow * GetTopLevel(HWND hwnd); -static void InitWm(void); -static int InstallColormaps(HWND hwnd, int message, - int isForemost); -static void InvalidateSubTree(TkWindow *winPtr, Colormap colormap); -static void InvalidateSubTreeDepth(TkWindow *winPtr); -static int ParseGeometry(Tcl_Interp *interp, const char *string, - TkWindow *winPtr); -static void RefreshColormap(Colormap colormap, TkDisplay *dispPtr); -static void SetLimits(HWND hwnd, MINMAXINFO *info); -static void TkWmStackorderToplevelWrapperMap(TkWindow *winPtr, - Display *display, Tcl_HashTable *table); -static LRESULT CALLBACK TopLevelProc(HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam); -static void TopLevelEventProc(ClientData clientData, - XEvent *eventPtr); -static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin); -static void UpdateGeometryInfo(ClientData clientData); -static void UpdateWrapper(TkWindow *winPtr); -static LRESULT CALLBACK WmProc(HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam); -static void WmWaitVisibilityOrMapProc(ClientData clientData, - XEvent *eventPtr); -static BlockOfIconImagesPtr ReadIconOrCursorFromFile(Tcl_Interp *interp, - Tcl_Obj* fileName, BOOL isIcon); -static WinIconPtr ReadIconFromFile(Tcl_Interp *interp, - Tcl_Obj *fileName); -static WinIconPtr GetIconFromPixmap(Display *dsPtr, Pixmap pixmap); -static int ReadICOHeader(Tcl_Channel channel); -static BOOL AdjustIconImagePointers(LPICONIMAGE lpImage); -static HICON MakeIconOrCursorFromResource(LPICONIMAGE lpIcon, - BOOL isIcon); -static HICON GetIcon(WinIconPtr titlebaricon, int icon_size); -static int WinSetIcon(Tcl_Interp *interp, - WinIconPtr titlebaricon, Tk_Window tkw); -static void FreeIconBlock(BlockOfIconImagesPtr lpIR); -static void DecrIconRefCount(WinIconPtr titlebaricon); - -static int WmAspectCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmAttributesCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmClientCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmColormapwindowsCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmCommandCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmDeiconifyCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmFocusmodelCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmForgetCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmFrameCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmGeometryCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmGridCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmGroupCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconbitmapCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconifyCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconmaskCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconnameCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconphotoCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconpositionCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconwindowCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmManageCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmMaxsizeCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmMinsizeCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmOverrideredirectCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmPositionfromCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmProtocolCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmResizableCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmSizefromCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmStackorderCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmStateCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmTitleCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmTransientCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmWithdrawCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static void WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr); - -/* - * Used in BytesPerLine - */ - -#define WIDTHBYTES(bits) ((((bits) + 31)>>5)<<2) - -/* - *---------------------------------------------------------------------- - * - * DIBNumColors -- - * - * Calculates the number of entries in the color table, given by LPSTR - * lpbi - pointer to the CF_DIB memory block. Used by titlebar icon code. - * - * Results: - * WORD - Number of entries in the color table. - * - *---------------------------------------------------------------------- - */ - -static WORD -DIBNumColors( - LPSTR lpbi) -{ - WORD wBitCount; - DWORD dwClrUsed; - - dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed; - - if (dwClrUsed) { - return (WORD) dwClrUsed; - } - - wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount; - - switch (wBitCount) { - case 1: - return 2; - case 4: - return 16; - case 8: - return 256; - default: - return 0; - } -} - -/* - *---------------------------------------------------------------------- - * - * PaletteSize -- - * - * Calculates the number of bytes in the color table, as given by LPSTR - * lpbi - pointer to the CF_DIB memory block. Used by titlebar icon code. - * - * Results: - * Number of bytes in the color table - * - *---------------------------------------------------------------------- - */ -static WORD -PaletteSize( - LPSTR lpbi) -{ - return (WORD) (DIBNumColors(lpbi) * sizeof(RGBQUAD)); -} - -/* - *---------------------------------------------------------------------- - * - * FindDIBits -- - * - * Locate the image bits in a CF_DIB format DIB, as given by LPSTR lpbi - - * pointer to the CF_DIB memory block. Used by titlebar icon code. - * - * Results: - * pointer to the image bits - * - * Side effects: None - * - * - *---------------------------------------------------------------------- - */ - -static LPSTR -FindDIBBits( - LPSTR lpbi) -{ - return lpbi + *((LPDWORD) lpbi) + PaletteSize(lpbi); -} - -/* - *---------------------------------------------------------------------- - * - * BytesPerLine -- - * - * Calculates the number of bytes in one scan line, as given by - * LPBITMAPINFOHEADER lpBMIH - pointer to the BITMAPINFOHEADER that - * begins the CF_DIB block. Used by titlebar icon code. - * - * Results: - * number of bytes in one scan line (DWORD aligned) - * - *---------------------------------------------------------------------- - */ - -static DWORD -BytesPerLine( - LPBITMAPINFOHEADER lpBMIH) -{ - return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount); -} - -/* - *---------------------------------------------------------------------- - * - * AdjustIconImagePointers -- - * - * Adjusts internal pointers in icon resource struct, as given by - * LPICONIMAGE lpImage - the resource to handle. Used by titlebar icon - * code. - * - * Results: - * BOOL - TRUE for success, FALSE for failure - * - *---------------------------------------------------------------------- - */ - -static BOOL -AdjustIconImagePointers( - LPICONIMAGE lpImage) -{ - /* - * Sanity check. - */ - - if (lpImage == NULL) { - return FALSE; - } - - /* - * BITMAPINFO is at beginning of bits. - */ - - lpImage->lpbi = (LPBITMAPINFO) lpImage->lpBits; - - /* - * Width - simple enough. - */ - - lpImage->Width = lpImage->lpbi->bmiHeader.biWidth; - - /* - * Icons are stored in funky format where height is doubled so account for - * that. - */ - - lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight)/2; - - /* - * How many colors? - */ - - lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes - * lpImage->lpbi->bmiHeader.biBitCount; - - /* - * XOR bits follow the header and color table. - */ - - lpImage->lpXOR = (LPBYTE) FindDIBBits((LPSTR) lpImage->lpbi); - - /* - * AND bits follow the XOR bits. - */ - - lpImage->lpAND = lpImage->lpXOR + - lpImage->Height*BytesPerLine((LPBITMAPINFOHEADER) lpImage->lpbi); - return TRUE; -} - -/* - *---------------------------------------------------------------------- - * - * MakeIconOrCursorFromResource -- - * - * Construct an actual HICON structure from the information in a - * resource. - * - * Results: - * Icon - * - *---------------------------------------------------------------------- - */ - -static HICON -MakeIconOrCursorFromResource( - LPICONIMAGE lpIcon, - BOOL isIcon) -{ - HICON hIcon; - - /* - * Sanity Check - */ - - if (lpIcon == NULL || lpIcon->lpBits == NULL) { - return NULL; - } - - /* - * Let the OS do the real work :) - */ - - hIcon = (HICON) CreateIconFromResourceEx(lpIcon->lpBits, - lpIcon->dwNumBytes, isIcon, 0x00030000, - (*(LPBITMAPINFOHEADER) lpIcon->lpBits).biWidth, - (*(LPBITMAPINFOHEADER) lpIcon->lpBits).biHeight/2, 0); - - /* - * It failed, odds are good we're on NT so try the non-Ex way. - */ - - if (hIcon == NULL) { - /* - * We would break on NT if we try with a 16bpp image. - */ - - if (lpIcon->lpbi->bmiHeader.biBitCount != 16) { - hIcon = CreateIconFromResource(lpIcon->lpBits, lpIcon->dwNumBytes, - isIcon, 0x00030000); - } - } - return hIcon; -} - -/* - *---------------------------------------------------------------------- - * - * ReadICOHeader -- - * - * Reads the header from an ICO file, as specfied by channel. - * - * Results: - * UINT - Number of images in file, -1 for failure. If this succeeds, - * there is a decent chance this is a valid icon file. - * - *---------------------------------------------------------------------- - */ - -static int -ReadICOHeader( - Tcl_Channel channel) -{ - union { - WORD word; - char bytes[sizeof(WORD)]; - } input; - - /* - * Read the 'reserved' WORD, which should be a zero word. - */ - - if (Tcl_Read(channel, input.bytes, sizeof(WORD)) != sizeof(WORD)) { - return -1; - } - if (input.word != 0) { - return -1; - } - - /* - * Read the type WORD, which should be of type 1. - */ - - if (Tcl_Read(channel, input.bytes, sizeof(WORD)) != sizeof(WORD)) { - return -1; - } - if (input.word != 1) { - return -1; - } - - /* - * Get and return the count of images. - */ - - if (Tcl_Read(channel, input.bytes, sizeof(WORD)) != sizeof(WORD)) { - return -1; - } - return (int) input.word; -} - -/* - *---------------------------------------------------------------------- - * - * InitWindowClass -- - * - * This routine creates the Wm toplevel decorative frame class. - * - * Results: - * None. - * - * Side effects: - * Registers a new window class. - * - *---------------------------------------------------------------------- - */ - -static int -InitWindowClass( - WinIconPtr titlebaricon) -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (!tsdPtr->initialized) { - tsdPtr->initialized = 1; - tsdPtr->firstWindow = 1; - tsdPtr->iconPtr = NULL; - } - if (!initialized) { - Tcl_MutexLock(&winWmMutex); - if (!initialized) { - WNDCLASS class; - - initialized = 1; - - /* - * The only difference between WNDCLASSW and WNDCLASSA are in - * pointers, so we can use the generic structure WNDCLASS. - */ - - ZeroMemory(&class, sizeof(WNDCLASS)); - - class.style = CS_HREDRAW | CS_VREDRAW; - class.hInstance = Tk_GetHINSTANCE(); - class.lpszClassName = TK_WIN_TOPLEVEL_CLASS_NAME; - class.lpfnWndProc = WmProc; - if (titlebaricon == NULL) { - class.hIcon = LoadIcon(Tk_GetHINSTANCE(), TEXT("tk")); - } else { - class.hIcon = GetIcon(titlebaricon, ICON_BIG); - if (class.hIcon == NULL) { - return TCL_ERROR; - } - - /* - * Store pointer to default icon so we know when we need to - * free that information - */ - - tsdPtr->iconPtr = titlebaricon; - } - class.hCursor = LoadCursor(NULL, IDC_ARROW); - - if (!RegisterClass(&class)) { - Tcl_Panic("Unable to register TkTopLevel class"); - } - } - Tcl_MutexUnlock(&winWmMutex); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * InitWm -- - * - * This initialises the window manager - * - * Results: - * None. - * - * Side effects: - * Registers a new window class. - * - *---------------------------------------------------------------------- - */ - -static void -InitWm(void) -{ - /* Ignore return result */ - (void) InitWindowClass(NULL); -} - -/* - *---------------------------------------------------------------------- - * - * WinSetIcon -- - * - * Sets either the default toplevel titlebar icon, or the icon for a - * specific toplevel (if tkw is given, then only that window is used). - * - * The ref-count of the titlebaricon is NOT changed. If this function - * returns successfully, the caller should assume the icon was used (and - * therefore the ref-count should be adjusted to reflect that fact). If - * the function returned an error, the caller should assume the icon was - * not used (and may wish to free the memory associated with it). - * - * Results: - * A standard Tcl return code. - * - * Side effects: - * One or all windows may have their icon changed. The Tcl result may be - * modified. The window-manager will be initialised if it wasn't already. - * The given window will be forced into existence. - * - *---------------------------------------------------------------------- - */ - -static int -WinSetIcon( - Tcl_Interp *interp, - WinIconPtr titlebaricon, - Tk_Window tkw) -{ - WmInfo *wmPtr; - HWND hwnd; - int application = 0; - - if (tkw == NULL) { - tkw = Tk_MainWindow(interp); - application = 1; - } - - if (!(Tk_IsTopLevel(tkw))) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't a top-level window", Tk_PathName(tkw))); - Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", Tk_PathName(tkw), - NULL); - return TCL_ERROR; - } - if (Tk_WindowId(tkw) == None) { - Tk_MakeWindowExist(tkw); - } - - /* - * We must get the window's wrapper, not the window itself. - */ - - wmPtr = ((TkWindow *) tkw)->wmInfoPtr; - hwnd = wmPtr->wrapper; - - if (application) { - if (hwnd == NULL) { - /* - * I don't actually think this is ever the correct thing, unless - * perhaps the window doesn't have a wrapper. But I believe all - * windows have wrappers. - */ - - hwnd = Tk_GetHWND(Tk_WindowId(tkw)); - } - - /* - * If we aren't initialised, then just initialise with the user's - * icon. Otherwise our icon choice will be ignored moments later when - * Tk finishes initialising. - */ - - if (!initialized) { - if (InitWindowClass(titlebaricon) != TCL_OK) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "Unable to set icon", -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "FAILED", NULL); - return TCL_ERROR; - } - } else { - ThreadSpecificData *tsdPtr; - - /* - * Don't check return result of SetClassLong() or - * SetClassLongPtr() since they return the previously set value - * which is zero on the initial call or in an error case. The MSDN - * documentation does not indicate that the result needs to be - * checked. - */ - - SetClassLongPtr(hwnd, GCLP_HICONSM, - (LPARAM) GetIcon(titlebaricon, ICON_SMALL)); - SetClassLongPtr(hwnd, GCLP_HICON, - (LPARAM) GetIcon(titlebaricon, ICON_BIG)); - tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - if (tsdPtr->iconPtr != NULL) { - DecrIconRefCount(tsdPtr->iconPtr); - } - tsdPtr->iconPtr = titlebaricon; - } - } else { - if (!initialized) { - /* - * Need to initialise the wm otherwise we will fail on code which - * tries to set a toplevel's icon before that happens. Ignore - * return result. - */ - - (void) InitWindowClass(NULL); - } - - /* - * The following code is exercised if you do - * - * toplevel .t ; wm titlebaricon .t foo.icr - * - * i.e. the wm hasn't had time to properly create the '.t' window - * before you set the icon. - */ - - if (hwnd == NULL) { - /* - * This little snippet is copied from the 'Map' function, and - * should probably be placed in one proper location. - */ - - UpdateWrapper(wmPtr->winPtr); - wmPtr = ((TkWindow *) tkw)->wmInfoPtr; - hwnd = wmPtr->wrapper; - if (hwnd == NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "Can't set icon; window has no wrapper.", -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "WRAPPER", NULL); - return TCL_ERROR; - } - } - SendMessage(hwnd, WM_SETICON, ICON_SMALL, - (LPARAM) GetIcon(titlebaricon, ICON_SMALL)); - SendMessage(hwnd, WM_SETICON, ICON_BIG, - (LPARAM) GetIcon(titlebaricon, ICON_BIG)); - - /* - * Update the iconPtr we keep for each WmInfo structure. - */ - - if (wmPtr->iconPtr != NULL) { - /* - * Free any old icon ptr which is associated with this window. - */ - - DecrIconRefCount(wmPtr->iconPtr); - } - - /* - * We do not need to increment the ref count for the titlebaricon, - * because it was already incremented when we retrieved it. - */ - - wmPtr->iconPtr = titlebaricon; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinGetIcon -- - * - * Gets either the default toplevel titlebar icon, or the icon for a - * specific toplevel (ICON_SMALL or ICON_BIG). - * - * Results: - * A Windows HICON. - * - * Side effects: - * The given window will be forced into existence. - * - *---------------------------------------------------------------------- - */ - -HICON -TkWinGetIcon( - Tk_Window tkwin, - DWORD iconsize) -{ - WmInfo *wmPtr; - HICON icon; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (tsdPtr->iconPtr != NULL) { - /* - * return default toplevel icon - */ - - return GetIcon(tsdPtr->iconPtr, (int) iconsize); - } - - /* - * Ensure we operate on the toplevel, that has the icon refs. - */ - - while (!Tk_IsTopLevel(tkwin)) { - tkwin = Tk_Parent(tkwin); - if (tkwin == NULL) { - return NULL; - } - } - - if (Tk_WindowId(tkwin) == None) { - Tk_MakeWindowExist(tkwin); - } - - wmPtr = ((TkWindow *) tkwin)->wmInfoPtr; - if (wmPtr->iconPtr != NULL) { - /* - * return window toplevel icon - */ - - return GetIcon(wmPtr->iconPtr, (int) iconsize); - } - - /* - * Find the icon otherwise associated with the toplevel, or finally with - * the window class. - */ - - icon = (HICON) SendMessage(wmPtr->wrapper, WM_GETICON, iconsize, - (LPARAM) NULL); - if (icon == (HICON) NULL) { - icon = (HICON) GetClassLongPtr(wmPtr->wrapper, - (iconsize == ICON_BIG) ? GCLP_HICON : GCLP_HICONSM); - } - return icon; -} - -/* - *---------------------------------------------------------------------- - * - * ReadIconFromFile -- - * - * Read the contents of a file (usually .ico, .icr) and extract an icon - * resource, if possible, otherwise check if the shell has an icon - * assigned to the given file and use that. If both of those fail, then - * NULL is returned, and an error message will already be in the - * interpreter. - * - * Results: - * A WinIconPtr structure containing the icons in the file, with its ref - * count already incremented. The calling function should either place - * this structure inside a WmInfo structure, or it should pass it on to - * DecrIconRefCount() to ensure no memory leaks occur. - * - * If the given fileName did not contain a valid icon structure, - * return NULL. - * - * Side effects: - * Memory is allocated for the returned structure and the icons it - * contains. If the structure is not wanted, it should be passed to - * DecrIconRefCount, and in any case a valid ref count should be ensured - * to avoid memory leaks. - * - * Currently icon resources are not shared, so the ref count of one of - * these structures will always be 0 or 1. However all we need do is - * implement some sort of lookup function between filenames and - * WinIconPtr structures and no other code will need to be changed. The - * pseudo-code for this is implemented below in the 'if (0)' branch. It - * did not seem necessary to implement this optimisation here, since - * moving to icon<->image conversions will probably make it obsolete. - * - *---------------------------------------------------------------------- - */ - -static WinIconPtr -ReadIconFromFile( - Tcl_Interp *interp, - Tcl_Obj *fileName) -{ - WinIconPtr titlebaricon = NULL; - BlockOfIconImagesPtr lpIR; - -#if 0 /* TODO: Dead code? */ - if (0 /* If we already have an icon for this filename */) { - titlebaricon = NULL; /* Get the real value from a lookup */ - titlebaricon->refCount++; - return titlebaricon; - } -#endif - - /* - * First check if it is a .ico file. - */ - - lpIR = ReadIconOrCursorFromFile(interp, fileName, TRUE); - - /* - * Then see if we can ask the shell for the icon for this file. We - * want both the regular and small icons so that the Alt-Tab (task- - * switching) display uses the right icon. - */ - - if (lpIR == NULL) { - SHFILEINFO sfiSM; - Tcl_DString ds, ds2; - DWORD *res; - const char *file; - - file = Tcl_TranslateFileName(interp, Tcl_GetString(fileName), &ds); - if (file == NULL) { - return NULL; - } - Tcl_WinUtfToTChar(file, -1, &ds2); - Tcl_DStringFree(&ds); - res = (DWORD *)SHGetFileInfo((TCHAR *)Tcl_DStringValue(&ds2), 0, &sfiSM, - sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON); - - if (res != 0) { - SHFILEINFO sfi; - unsigned size; - - Tcl_ResetResult(interp); - res = (DWORD *)SHGetFileInfo((TCHAR *)Tcl_DStringValue(&ds2), 0, &sfi, - sizeof(SHFILEINFO), SHGFI_ICON); - - /* - * Account for extra icon, if necessary. - */ - - size = sizeof(BlockOfIconImages) - + ((res != 0) ? sizeof(ICONIMAGE) : 0); - lpIR = ckalloc(size); - if (lpIR == NULL) { - if (res != 0) { - DestroyIcon(sfi.hIcon); - } - DestroyIcon(sfiSM.hIcon); - Tcl_DStringFree(&ds2); - return NULL; - } - ZeroMemory(lpIR, size); - - lpIR->nNumImages = ((res != 0) ? 2 : 1); - lpIR->IconImages[0].Width = 16; - lpIR->IconImages[0].Height = 16; - lpIR->IconImages[0].Colors = 4; - lpIR->IconImages[0].hIcon = sfiSM.hIcon; - - /* - * All other IconImages fields are ignored. - */ - - if (res != 0) { - lpIR->IconImages[1].Width = 32; - lpIR->IconImages[1].Height = 32; - lpIR->IconImages[1].Colors = 4; - lpIR->IconImages[1].hIcon = sfi.hIcon; - } - } - Tcl_DStringFree(&ds2); - } - if (lpIR != NULL) { - titlebaricon = ckalloc(sizeof(WinIconInstance)); - titlebaricon->iconBlock = lpIR; - titlebaricon->refCount = 1; - } - return titlebaricon; -} - -/* - *---------------------------------------------------------------------- - * - * GetIconFromPixmap -- - * - * Turn a Tk Pixmap (i.e. a bitmap) into an icon resource, if possible, - * otherwise NULL is returned. - * - * Results: - * A WinIconPtr structure containing a conversion of the given bitmap - * into an icon, with its ref count already incremented. The calling - * function should either place this structure inside a WmInfo structure, - * or it should pass it on to DecrIconRefCount() to ensure no memory - * leaks occur. - * - * If the given pixmap did not contain a valid icon structure, return - * NULL. - * - * Side effects: - * Memory is allocated for the returned structure and the icons it - * contains. If the structure is not wanted, it should be passed to - * DecrIconRefCount, and in any case a valid ref count should be ensured - * to avoid memory leaks. - * - * Currently icon resources are not shared, so the ref count of one of - * these structures will always be 0 or 1. However all we need do is - * implement some sort of lookup function between pixmaps and WinIconPtr - * structures and no other code will need to be changed. - * - *---------------------------------------------------------------------- - */ - -static WinIconPtr -GetIconFromPixmap( - Display *dsPtr, - Pixmap pixmap) -{ - WinIconPtr titlebaricon = NULL; - TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap; - BlockOfIconImagesPtr lpIR; - ICONINFO icon; - HICON hIcon; - int width, height; - - if (twdPtr == NULL) { - return NULL; - } - -#if 0 /* TODO: Dead code?*/ - if (0 /* If we already have an icon for this pixmap */) { - titlebaricon = NULL; /* Get the real value from a lookup */ - titlebaricon->refCount++; - return titlebaricon; - } -#endif - - Tk_SizeOfBitmap(dsPtr, pixmap, &width, &height); - - icon.fIcon = TRUE; - icon.xHotspot = 0; - icon.yHotspot = 0; - icon.hbmMask = twdPtr->bitmap.handle; - icon.hbmColor = twdPtr->bitmap.handle; - - hIcon = CreateIconIndirect(&icon); - if (hIcon == NULL) { - return NULL; - } - - lpIR = ckalloc(sizeof(BlockOfIconImages)); - if (lpIR == NULL) { - DestroyIcon(hIcon); - return NULL; - } - - lpIR->nNumImages = 1; - lpIR->IconImages[0].Width = width; - lpIR->IconImages[0].Height = height; - lpIR->IconImages[0].Colors = 1 << twdPtr->bitmap.depth; - lpIR->IconImages[0].hIcon = hIcon; - - /* - * These fields are ignored. - */ - - lpIR->IconImages[0].lpBits = 0; - lpIR->IconImages[0].dwNumBytes = 0; - lpIR->IconImages[0].lpXOR = 0; - lpIR->IconImages[0].lpAND = 0; - - titlebaricon = ckalloc(sizeof(WinIconInstance)); - titlebaricon->iconBlock = lpIR; - titlebaricon->refCount = 1; - return titlebaricon; -} - -/* - *---------------------------------------------------------------------- - * - * DecrIconRefCount -- - * - * Reduces the reference count. - * - * Results: - * None. - * - * Side effects: - * If the ref count falls to zero, free the memory associated with the - * icon resource structures. In this case the pointer passed into this - * function is no longer valid. - * - *---------------------------------------------------------------------- - */ - -static void -DecrIconRefCount( - WinIconPtr titlebaricon) -{ - if (titlebaricon->refCount-- <= 1) { - if (titlebaricon->iconBlock != NULL) { - FreeIconBlock(titlebaricon->iconBlock); - } - titlebaricon->iconBlock = NULL; - - ckfree(titlebaricon); - } -} - -/* - *---------------------------------------------------------------------- - * - * FreeIconBlock -- - * - * Frees all memory associated with a previously loaded titlebaricon. - * The icon block pointer is no longer valid once this function returns. - * - * Results: - * None. - * - * Side effects: - * - * - *---------------------------------------------------------------------- - */ - -static void -FreeIconBlock( - BlockOfIconImagesPtr lpIR) -{ - int i; - - /* - * Free all the bits. - */ - - for (i=0 ; i<lpIR->nNumImages ; i++) { - if (lpIR->IconImages[i].lpBits != NULL) { - ckfree(lpIR->IconImages[i].lpBits); - } - if (lpIR->IconImages[i].hIcon != NULL) { - DestroyIcon(lpIR->IconImages[i].hIcon); - } - } - ckfree(lpIR); -} - -/* - *---------------------------------------------------------------------- - * - * GetIcon -- - * - * Extracts an icon of a given size from an icon resource - * - * Results: - * Returns the icon, if found, else NULL. - * - *---------------------------------------------------------------------- - */ - -static HICON -GetIcon( - WinIconPtr titlebaricon, - int icon_size) -{ - BlockOfIconImagesPtr lpIR; - unsigned int size = (icon_size == 0 ? 16 : 32); - int i; - - if (titlebaricon == NULL) { - return NULL; - } - - lpIR = titlebaricon->iconBlock; - if (lpIR == NULL) { - return NULL; - } - - for (i=0 ; i<lpIR->nNumImages ; i++) { - /* - * Take the first or a 32x32 16 color icon - */ - - if ((lpIR->IconImages[i].Height == size) - && (lpIR->IconImages[i].Width == size) - && (lpIR->IconImages[i].Colors >= 4)) { - return lpIR->IconImages[i].hIcon; - } - } - - /* - * If we get here, then just return the first one, it will have to do! - */ - - if (lpIR->nNumImages >= 1) { - return lpIR->IconImages[0].hIcon; - } - return NULL; -} - -#if 0 /* UNUSED */ -static HCURSOR -TclWinReadCursorFromFile( - Tcl_Interp* interp, - Tcl_Obj* fileName) -{ - BlockOfIconImagesPtr lpIR; - HICON res = NULL; - - lpIR = ReadIconOrCursorFromFile(interp, fileName, FALSE); - if (lpIR == NULL) { - return NULL; - } - if (lpIR->nNumImages >= 1) { - res = CopyImage(lpIR->IconImages[0].hIcon, IMAGE_CURSOR, 0, 0, 0); - } - FreeIconBlock(lpIR); - return res; -} -#endif - -/* - *---------------------------------------------------------------------- - * - * ReadIconOrCursorFromFile -- - * - * Reads an Icon Resource from an ICO file, as given by char* fileName - - * Name of the ICO file. This name should be in Utf format. - * - * Results: - * Returns an icon resource, if found, else NULL. - * - * Side effects: - * May leave error messages in the Tcl interpreter. - * - *---------------------------------------------------------------------- - */ - -static BlockOfIconImagesPtr -ReadIconOrCursorFromFile( - Tcl_Interp *interp, - Tcl_Obj *fileName, - BOOL isIcon) -{ - BlockOfIconImagesPtr lpIR; - Tcl_Channel channel; - int i; - DWORD dwBytesRead; - LPICONDIRENTRY lpIDE; - - /* - * Open the file. - */ - - channel = Tcl_FSOpenFileChannel(interp, fileName, "r", 0); - if (channel == NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "error opening file \"%s\" for reading: %s", - Tcl_GetString(fileName), Tcl_PosixError(interp))); - return NULL; - } - if (Tcl_SetChannelOption(interp, channel, "-translation", "binary") - != TCL_OK) { - Tcl_Close(NULL, channel); - return NULL; - } - if (Tcl_SetChannelOption(interp, channel, "-encoding", "binary") - != TCL_OK) { - Tcl_Close(NULL, channel); - return NULL; - } - - /* - * Allocate memory for the resource structure - */ - - lpIR = ckalloc(sizeof(BlockOfIconImages)); - - /* - * Read in the header - */ - - lpIR->nNumImages = ReadICOHeader(channel); - if (lpIR->nNumImages == -1) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("Invalid file header", -1)); - Tcl_Close(NULL, channel); - ckfree(lpIR); - return NULL; - } - - /* - * Adjust the size of the struct to account for the images. - */ - - lpIR = ckrealloc(lpIR, sizeof(BlockOfIconImages) - + (lpIR->nNumImages - 1) * sizeof(ICONIMAGE)); - - /* - * Allocate enough memory for the icon directory entries. - */ - - lpIDE = ckalloc(lpIR->nNumImages * sizeof(ICONDIRENTRY)); - - /* - * Read in the icon directory entries. - */ - - dwBytesRead = Tcl_Read(channel, (char *) lpIDE, - (int) (lpIR->nNumImages * sizeof(ICONDIRENTRY))); - if (dwBytesRead != lpIR->nNumImages * sizeof(ICONDIRENTRY)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "error reading file: %s", Tcl_PosixError(interp))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "READ", NULL); - Tcl_Close(NULL, channel); - ckfree(lpIDE); - ckfree(lpIR); - return NULL; - } - - /* - * NULL-out everything to make memory management easier. - */ - - for (i = 0; i < lpIR->nNumImages; i++) { - lpIR->IconImages[i].lpBits = NULL; - } - - /* - * Loop through and read in each image. - */ - - for (i=0 ; i<lpIR->nNumImages ; i++) { - /* - * Allocate memory for the resource. - */ - - lpIR->IconImages[i].lpBits = ckalloc(lpIDE[i].dwBytesInRes); - lpIR->IconImages[i].dwNumBytes = lpIDE[i].dwBytesInRes; - - /* - * Seek to beginning of this image. - */ - - if (Tcl_Seek(channel, lpIDE[i].dwImageOffset, FILE_BEGIN) == -1) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "error seeking in file: %s", Tcl_PosixError(interp))); - goto readError; - } - - /* - * Read it in. - */ - - dwBytesRead = Tcl_Read(channel, (char *)lpIR->IconImages[i].lpBits, - (int) lpIDE[i].dwBytesInRes); - if (dwBytesRead != lpIDE[i].dwBytesInRes) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "error reading file: %s", Tcl_PosixError(interp))); - goto readError; - } - - /* - * Set the internal pointers appropriately. - */ - - if (!AdjustIconImagePointers(&lpIR->IconImages[i])) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "Error converting to internal format", -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "FORMAT", NULL); - goto readError; - } - lpIR->IconImages[i].hIcon = - MakeIconOrCursorFromResource(&lpIR->IconImages[i], isIcon); - } - - /* - * Clean up - */ - - ckfree(lpIDE); - Tcl_Close(NULL, channel); - return lpIR; - - readError: - Tcl_Close(NULL, channel); - for (i = 0; i < lpIR->nNumImages; i++) { - if (lpIR->IconImages[i].lpBits != NULL) { - ckfree(lpIR->IconImages[i].lpBits); - } - } - ckfree(lpIDE); - ckfree(lpIR); - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * GetTopLevel -- - * - * This function retrieves the TkWindow associated with the given HWND. - * - * Results: - * Returns the matching TkWindow. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static TkWindow * -GetTopLevel( - HWND hwnd) -{ - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - /* - * If this function is called before the CreateWindowEx call has - * completed, then the user data slot will not have been set yet, so we - * use the global createWindow variable. - */ - - if (tsdPtr->createWindow) { - return tsdPtr->createWindow; - } - return (TkWindow *) GetWindowLongPtr(hwnd, GWLP_USERDATA); -} - -/* - *---------------------------------------------------------------------- - * - * SetLimits -- - * - * Updates the minimum and maximum window size constraints. - * - * Results: - * None. - * - * Side effects: - * Changes the values of the info pointer to reflect the current minimum - * and maximum size values. - * - *---------------------------------------------------------------------- - */ - -static void -SetLimits( - HWND hwnd, - MINMAXINFO *info) -{ - register WmInfo *wmPtr; - int maxWidth, maxHeight; - int minWidth, minHeight; - int base; - TkWindow *winPtr = GetTopLevel(hwnd); - - if (winPtr == NULL) { - return; - } - - wmPtr = winPtr->wmInfoPtr; - - /* - * Copy latest constraint info. - */ - - wmPtr->defMinWidth = info->ptMinTrackSize.x; - wmPtr->defMinHeight = info->ptMinTrackSize.y; - wmPtr->defMaxWidth = info->ptMaxTrackSize.x; - wmPtr->defMaxHeight = info->ptMaxTrackSize.y; - - GetMaxSize(wmPtr, &maxWidth, &maxHeight); - GetMinSize(wmPtr, &minWidth, &minHeight); - - if (wmPtr->gridWin != NULL) { - base = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc); - if (base < 0) { - base = 0; - } - base += wmPtr->borderWidth; - info->ptMinTrackSize.x = base + (minWidth * wmPtr->widthInc); - info->ptMaxTrackSize.x = base + (maxWidth * wmPtr->widthInc); - - base = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc); - if (base < 0) { - base = 0; - } - base += wmPtr->borderHeight; - info->ptMinTrackSize.y = base + (minHeight * wmPtr->heightInc); - info->ptMaxTrackSize.y = base + (maxHeight * wmPtr->heightInc); - } else { - info->ptMaxTrackSize.x = maxWidth + wmPtr->borderWidth; - info->ptMaxTrackSize.y = maxHeight + wmPtr->borderHeight; - info->ptMinTrackSize.x = minWidth + wmPtr->borderWidth; - info->ptMinTrackSize.y = minHeight + wmPtr->borderHeight; - } - - /* - * If the window isn't supposed to be resizable, then set the minimum and - * maximum dimensions to be the same as the current size. - */ - - if (!(wmPtr->flags & WM_SYNC_PENDING)) { - if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) { - info->ptMinTrackSize.x = winPtr->changes.width - + wmPtr->borderWidth; - info->ptMaxTrackSize.x = info->ptMinTrackSize.x; - } - if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { - info->ptMinTrackSize.y = winPtr->changes.height - + wmPtr->borderHeight; - info->ptMaxTrackSize.y = info->ptMinTrackSize.y; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWinWmCleanup -- - * - * Unregisters classes registered by the window manager. This is called - * from the DLL main entry point when the DLL is unloaded. - * - * Results: - * None. - * - * Side effects: - * The window classes are discarded. - * - *---------------------------------------------------------------------- - */ - -void -TkWinWmCleanup( - HINSTANCE hInstance) -{ - ThreadSpecificData *tsdPtr; - - /* - * If we're using stubs to access the Tcl library, and they haven't been - * initialized, we can't call Tcl_GetThreadData. - */ - -#ifdef USE_TCL_STUBS - if (tclStubsPtr == NULL) { - return; - } -#endif - - if (!initialized) { - return; - } - initialized = 0; - - tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (!tsdPtr->initialized) { - return; - } - tsdPtr->initialized = 0; - - UnregisterClass(TK_WIN_TOPLEVEL_CLASS_NAME, hInstance); -} - -/* - *-------------------------------------------------------------- - * - * TkWmNewWindow -- - * - * This function is invoked whenever a new top-level window is created. - * Its job is to initialize the WmInfo structure for the window. - * - * Results: - * None. - * - * Side effects: - * A WmInfo structure gets allocated and initialized. - * - *-------------------------------------------------------------- - */ - -void -TkWmNewWindow( - TkWindow *winPtr) /* Newly-created top-level window. */ -{ - register WmInfo *wmPtr = ckalloc(sizeof(WmInfo)); - - /* - * Initialize full structure, then set what isn't NULL - */ - - ZeroMemory(wmPtr, sizeof(WmInfo)); - winPtr->wmInfoPtr = wmPtr; - wmPtr->winPtr = winPtr; - wmPtr->hints.flags = InputHint | StateHint; - wmPtr->hints.input = True; - wmPtr->hints.initial_state = NormalState; - wmPtr->hints.icon_pixmap = None; - wmPtr->hints.icon_window = None; - wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0; - wmPtr->hints.icon_mask = None; - wmPtr->hints.window_group = None; - - /* - * Default the maximum dimensions to the size of the display. - */ - - wmPtr->defMinWidth = wmPtr->defMinHeight = 0; - wmPtr->defMaxWidth = DisplayWidth(winPtr->display, winPtr->screenNum); - wmPtr->defMaxHeight = DisplayHeight(winPtr->display, winPtr->screenNum); - wmPtr->minWidth = wmPtr->minHeight = 1; - wmPtr->maxWidth = wmPtr->maxHeight = 0; - wmPtr->widthInc = wmPtr->heightInc = 1; - wmPtr->minAspect.x = wmPtr->minAspect.y = 1; - wmPtr->maxAspect.x = wmPtr->maxAspect.y = 1; - wmPtr->reqGridWidth = wmPtr->reqGridHeight = -1; - wmPtr->gravity = NorthWestGravity; - wmPtr->width = -1; - wmPtr->height = -1; - wmPtr->x = winPtr->changes.x; - wmPtr->y = winPtr->changes.y; - wmPtr->crefObj = NULL; - wmPtr->colorref = (COLORREF) 0; - wmPtr->alpha = 1.0; - - wmPtr->configWidth = -1; - wmPtr->configHeight = -1; - wmPtr->flags = WM_NEVER_MAPPED; - wmPtr->nextPtr = winPtr->dispPtr->firstWmPtr; - winPtr->dispPtr->firstWmPtr = wmPtr; - - /* - * Tk must monitor structure events for top-level windows, in order to - * detect size and position changes caused by window managers. - */ - - Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask, - TopLevelEventProc, winPtr); - - /* - * Arrange for geometry requests to be reflected from the window to the - * window manager. - */ - - Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, NULL); -} - -/* - *---------------------------------------------------------------------- - * - * UpdateWrapper -- - * - * This function creates the wrapper window that contains the window - * decorations and menus for a toplevel. This function may be called - * after a window is mapped to change the window style. - * - * Results: - * None. - * - * Side effects: - * Destroys any old wrapper window and replaces it with a newly created - * wrapper. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateWrapper( - TkWindow *winPtr) /* Top-level window to redecorate. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - HWND parentHWND, oldWrapper = wmPtr->wrapper; - HWND child, nextHWND, focusHWND; - int x, y, width, height, state; - WINDOWPLACEMENT place; - HICON hSmallIcon = NULL; - HICON hBigIcon = NULL; - Tcl_DString titleString; - int *childStateInfo = NULL; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (winPtr->window == None) { - /* - * Ensure existence of the window to update the wrapper for. - */ - - Tk_MakeWindowExist((Tk_Window) winPtr); - } - - child = TkWinGetHWND(winPtr->window); - parentHWND = NULL; - - /* - * nextHWND will help us maintain Z order. focusHWND will help us maintain - * focus, if we had it. - */ - - nextHWND = NULL; - focusHWND = GetFocus(); - if ((oldWrapper == NULL) || (oldWrapper != GetForegroundWindow())) { - focusHWND = NULL; - } - - if (winPtr->flags & TK_EMBEDDED) { - wmPtr->wrapper = (HWND) winPtr->privatePtr; - if (wmPtr->wrapper == NULL) { - Tcl_Panic("UpdateWrapper: Cannot find container window"); - } - if (!IsWindow(wmPtr->wrapper)) { - Tcl_Panic("UpdateWrapper: Container was destroyed"); - } - } else { - /* - * Pick the decorative frame style. Override redirect windows get - * created as undecorated popups if they have no transient parent, - * otherwise they are children. This allows splash screens to operate - * as an independent window, while having dropdows (like for a - * combobox) not grab focus away from their parent. Transient windows - * get a modal dialog frame. Neither override, nor transient windows - * appear in the Windows taskbar. Note that a transient window does - * not resize by default, so we need to explicitly add the - * WS_THICKFRAME style if we want it to be resizeable. - */ - - if (winPtr->atts.override_redirect) { - wmPtr->style = WM_OVERRIDE_STYLE; - wmPtr->exStyle = EX_OVERRIDE_STYLE; - - /* - * Parent must be desktop even if we have a transient parent. - */ - - parentHWND = GetDesktopWindow(); - if (wmPtr->masterPtr) { - wmPtr->style |= WS_CHILD; - } else { - wmPtr->style |= WS_POPUP; - } - } else if (wmPtr->flags & WM_FULLSCREEN) { - wmPtr->style = WM_FULLSCREEN_STYLE; - wmPtr->exStyle = EX_FULLSCREEN_STYLE; - } else if (wmPtr->masterPtr) { - wmPtr->style = WM_TRANSIENT_STYLE; - wmPtr->exStyle = EX_TRANSIENT_STYLE; - parentHWND = Tk_GetHWND(Tk_WindowId(wmPtr->masterPtr)); - if (! ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) - && (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE))) { - wmPtr->style |= WS_THICKFRAME; - } - } else { - wmPtr->style = WM_TOPLEVEL_STYLE; - wmPtr->exStyle = EX_TOPLEVEL_STYLE; - } - - wmPtr->style |= wmPtr->styleConfig; - wmPtr->exStyle |= wmPtr->exStyleConfig; - - if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) - && (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) { - wmPtr->style &= ~ (WS_MAXIMIZEBOX | WS_SIZEBOX); - } - - /* - * Compute the geometry of the parent and child windows. - */ - - wmPtr->flags |= WM_CREATE_PENDING|WM_MOVE_PENDING; - UpdateGeometryInfo(winPtr); - wmPtr->flags &= ~(WM_CREATE_PENDING|WM_MOVE_PENDING); - - width = wmPtr->borderWidth + winPtr->changes.width; - height = wmPtr->borderHeight + winPtr->changes.height; - - /* - * Set the initial position from the user or program specified - * location. If nothing has been specified, then let the system pick a - * location. In full screen mode the x,y origin is 0,0 and the window - * width and height match that of the screen. - */ - - if (wmPtr->flags & WM_FULLSCREEN) { - x = 0; - y = 0; - width = WidthOfScreen(Tk_Screen(winPtr)); - height = HeightOfScreen(Tk_Screen(winPtr)); - } else if (!(wmPtr->sizeHintsFlags & (USPosition | PPosition)) - && (wmPtr->flags & WM_NEVER_MAPPED)) { - x = CW_USEDEFAULT; - y = CW_USEDEFAULT; - } else { - x = winPtr->changes.x; - y = winPtr->changes.y; - } - - /* - * Create the containing window, and set the user data to point to the - * TkWindow. - */ - - tsdPtr->createWindow = winPtr; - Tcl_WinUtfToTChar(((wmPtr->title != NULL) ? - wmPtr->title : winPtr->nameUid), -1, &titleString); - - wmPtr->wrapper = CreateWindowEx(wmPtr->exStyle, - TK_WIN_TOPLEVEL_CLASS_NAME, - (LPCTSTR) Tcl_DStringValue(&titleString), - wmPtr->style, x, y, width, height, - parentHWND, NULL, Tk_GetHINSTANCE(), NULL); - Tcl_DStringFree(&titleString); - SetWindowLongPtr(wmPtr->wrapper, GWLP_USERDATA, (LONG_PTR) winPtr); - tsdPtr->createWindow = NULL; - - if (wmPtr->exStyleConfig & WS_EX_LAYERED) { - /* - * The user supplies a double from [0..1], but Windows wants an - * int (transparent) 0..255 (opaque), so do the translation. Add - * the 0.5 to round the value. - */ - - SetLayeredWindowAttributes((HWND) wmPtr->wrapper, - wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5), - (unsigned)(LWA_ALPHA | (wmPtr->crefObj?LWA_COLORKEY:0))); - } else { - /* - * Layering not used or supported. - */ - - wmPtr->alpha = 1.0; - if (wmPtr->crefObj) { - Tcl_DecrRefCount(wmPtr->crefObj); - wmPtr->crefObj = NULL; - } - } - - place.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(wmPtr->wrapper, &place); - wmPtr->x = place.rcNormalPosition.left; - wmPtr->y = place.rcNormalPosition.top; - - if (!(winPtr->flags & TK_ALREADY_DEAD)) { - TkInstallFrameMenu((Tk_Window) winPtr); - } - - if (oldWrapper && (oldWrapper != wmPtr->wrapper) - && !(wmPtr->exStyle & WS_EX_TOPMOST)) { - /* - * We will adjust wrapper to have the same Z order as oldWrapper - * if it isn't a TOPMOST window. - */ - - nextHWND = GetNextWindow(oldWrapper, GW_HWNDPREV); - } - } - - /* - * Now we need to reparent the contained window and set its style - * appropriately. Be sure to update the style first so that Windows - * doesn't try to set the focus to the child window. - */ - - SetWindowLongPtr(child, GWL_STYLE, - WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - - if (winPtr->flags & TK_EMBEDDED) { - SetWindowLongPtr(child, GWLP_WNDPROC, (LONG_PTR) TopLevelProc); - } - - SetParent(child, wmPtr->wrapper); - if (oldWrapper) { - hSmallIcon = (HICON) - SendMessage(oldWrapper, WM_GETICON, ICON_SMALL, (LPARAM)NULL); - hBigIcon = (HICON) - SendMessage(oldWrapper, WM_GETICON, ICON_BIG, (LPARAM) NULL); - } - - if (oldWrapper && (oldWrapper != wmPtr->wrapper) - && (oldWrapper != GetDesktopWindow())) { - SetWindowLongPtr(oldWrapper, GWLP_USERDATA, (LONG_PTR) 0); - - if (wmPtr->numTransients > 0) { - /* - * Unset the current wrapper as the parent for all transient - * children for whom this is the master - */ - - WmInfo *wmPtr2; - - childStateInfo = ckalloc(wmPtr->numTransients * sizeof(int)); - state = 0; - for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL; - wmPtr2 = wmPtr2->nextPtr) { - if (wmPtr2->masterPtr == winPtr - && !(wmPtr2->flags & WM_NEVER_MAPPED)) { - childStateInfo[state++] = wmPtr2->hints.initial_state; - SetParent(TkWinGetHWND(wmPtr2->winPtr->window), NULL); - } - } - } - - /* - * Remove the menubar before destroying the window so the menubar - * isn't destroyed. - */ - - SetMenu(oldWrapper, NULL); - DestroyWindow(oldWrapper); - } - - wmPtr->flags &= ~WM_NEVER_MAPPED; - if (winPtr->flags & TK_EMBEDDED && - SendMessage(wmPtr->wrapper, TK_ATTACHWINDOW, (WPARAM) child, 0)) { - SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, - Tk_ReqWidth((Tk_Window) winPtr), - Tk_ReqHeight((Tk_Window) winPtr)); - SendMessage(wmPtr->wrapper, TK_SETMENU, (WPARAM) wmPtr->hMenu, - (LPARAM) Tk_GetMenuHWND((Tk_Window) winPtr)); - } - - /* - * Force an initial transition from withdrawn to the real initial state. - * Set the Z order based on previous wrapper before we set the state. - */ - - state = wmPtr->hints.initial_state; - wmPtr->hints.initial_state = WithdrawnState; - if (nextHWND) { - SetWindowPos(wmPtr->wrapper, nextHWND, 0, 0, 0, 0, - SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOSENDCHANGING - |SWP_NOOWNERZORDER); - } - TkpWmSetState(winPtr, state); - wmPtr->hints.initial_state = state; - - if (hSmallIcon != NULL) { - SendMessage(wmPtr->wrapper, WM_SETICON, ICON_SMALL, - (LPARAM) hSmallIcon); - } - if (hBigIcon != NULL) { - SendMessage(wmPtr->wrapper, WM_SETICON, ICON_BIG, (LPARAM) hBigIcon); - } - - /* - * If we are embedded then force a mapping of the window now, because we - * do not necessarily own the wrapper and may not get another opportunity - * to map ourselves. We should not be in either iconified or zoomed states - * when we get here, so it is safe to just check for TK_EMBEDDED without - * checking what state we are supposed to be in (default to NormalState). - */ - - if (winPtr->flags & TK_EMBEDDED) { - if (state+1 != SendMessage(wmPtr->wrapper, TK_STATE, state, 0)) { - TkpWmSetState(winPtr, NormalState); - wmPtr->hints.initial_state = NormalState; - } - XMapWindow(winPtr->display, winPtr->window); - } - - /* - * Set up menus on the wrapper if required. - */ - - if (wmPtr->hMenu != NULL) { - wmPtr->flags |= WM_SYNC_PENDING; - SetMenu(wmPtr->wrapper, wmPtr->hMenu); - wmPtr->flags &= ~WM_SYNC_PENDING; - } - - if (childStateInfo) { - if (wmPtr->numTransients > 0) { - /* - * Reset all transient children for whom this is the master. - */ - - WmInfo *wmPtr2; - - state = 0; - for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL; - wmPtr2 = wmPtr2->nextPtr) { - if (wmPtr2->masterPtr == winPtr - && !(wmPtr2->flags & WM_NEVER_MAPPED)) { - UpdateWrapper(wmPtr2->winPtr); - TkpWmSetState(wmPtr2->winPtr, childStateInfo[state++]); - } - } - } - - ckfree(childStateInfo); - } - - /* - * If this is the first window created by the application, then we should - * activate the initial window. Otherwise, if this had the focus, we need - * to restore that. - * XXX: Rewrapping generates a <FocusOut> and <FocusIn> that would best be - * XXX: avoided, if we could safely mask them. - */ - - if (tsdPtr->firstWindow) { - tsdPtr->firstWindow = 0; - SetActiveWindow(wmPtr->wrapper); - } else if (focusHWND) { - SetFocus(focusHWND); - } -} - -/* - *-------------------------------------------------------------- - * - * TkWmMapWindow -- - * - * This function is invoked to map a top-level window. This module gets a - * chance to update all window-manager-related information in properties - * before the window manager sees the map event and checks the - * properties. It also gets to decide whether or not to even map the - * window after all. - * - * Results: - * None. - * - * Side effects: - * Properties of winPtr may get updated to provide up-to-date information - * to the window manager. The window may also get mapped, but it may not - * be if this function decides that isn't appropriate (e.g. because the - * window is withdrawn). - * - *-------------------------------------------------------------- - */ - -void -TkWmMapWindow( - TkWindow *winPtr) /* Top-level window that's about to be - * mapped. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (!tsdPtr->initialized) { - InitWm(); - } - - if (wmPtr->flags & WM_NEVER_MAPPED) { - /* - * Don't map a transient if the master is not mapped. - */ - - if (wmPtr->masterPtr != NULL && !Tk_IsMapped(wmPtr->masterPtr)) { - wmPtr->hints.initial_state = WithdrawnState; - return; - } - } else { - if (wmPtr->hints.initial_state == WithdrawnState) { - return; - } - - /* - * Map the window in either the iconified or normal state. Note that - * we only send a map event if the window is in the normal state. - */ - - TkpWmSetState(winPtr, wmPtr->hints.initial_state); - } - - /* - * This is the first time this window has ever been mapped. Store all the - * window-manager-related information for the window. - */ - - UpdateWrapper(winPtr); -} - -/* - *-------------------------------------------------------------- - * - * TkWmUnmapWindow -- - * - * This function is invoked to unmap a top-level window. The only thing - * it does special is unmap the decorative frame before unmapping the - * toplevel window. - * - * Results: - * None. - * - * Side effects: - * Unmaps the decorative frame and the window. - * - *-------------------------------------------------------------- - */ - -void -TkWmUnmapWindow( - TkWindow *winPtr) /* Top-level window that's about to be - * unmapped. */ -{ - TkpWmSetState(winPtr, WithdrawnState); -} - -/* - *---------------------------------------------------------------------- - * - * TkpWmSetState -- - * - * Sets the window manager state for the wrapper window of a given - * toplevel window. - * - * Results: - * None. - * - * Side effects: - * May maximize, minimize, restore, or withdraw a window. - * - *---------------------------------------------------------------------- - */ - -int -TkpWmSetState( - TkWindow *winPtr, /* Toplevel window to operate on. */ - int state) /* One of IconicState, ZoomState, NormalState, - * or WithdrawnState. */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - int cmd; - - if (wmPtr->flags & WM_NEVER_MAPPED) { - wmPtr->hints.initial_state = state; - goto setStateEnd; - } - - wmPtr->flags |= WM_SYNC_PENDING; - if (state == WithdrawnState) { - cmd = SW_HIDE; - } else if (state == IconicState) { - cmd = SW_SHOWMINNOACTIVE; - } else if (state == NormalState) { - cmd = SW_SHOWNOACTIVATE; - } else if (state == ZoomState) { - cmd = SW_SHOWMAXIMIZED; - } else { - goto setStateEnd; - } - - ShowWindow(wmPtr->wrapper, cmd); - wmPtr->flags &= ~WM_SYNC_PENDING; -setStateEnd: - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * TkpWmSetFullScreen -- - * - * Sets the fullscreen state for a toplevel window. - * - * Results: - * The WM_FULLSCREEN flag is updated. - * - * Side effects: - * May create a new wrapper window and raise it. - * - *---------------------------------------------------------------------- - */ - -static void -TkpWmSetFullScreen( - TkWindow *winPtr, /* Toplevel window to operate on. */ - int full_screen_state) /* True if window should be full screen */ -{ - int changed = 0; - int full_screen = False; - WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (full_screen_state) { - if (! (wmPtr->flags & WM_FULLSCREEN)) { - full_screen = True; - changed = 1; - } - } else { - if (wmPtr->flags & WM_FULLSCREEN) { - full_screen = False; - changed = 1; - } - } - - if (changed) { - if (full_screen) { - wmPtr->flags |= WM_FULLSCREEN; - wmPtr->configX = wmPtr->x; - wmPtr->configY = wmPtr->y; - } else { - wmPtr->flags &= ~WM_FULLSCREEN; - wmPtr->x = wmPtr->configX; - wmPtr->y = wmPtr->configY; - } - - /* - * If the window has been mapped, then we need to update the native - * wrapper window, and reset the focus to the widget that had it - * before. - */ - - if (!(wmPtr->flags & (WM_NEVER_MAPPED) - && !(winPtr->flags & TK_EMBEDDED))) { - TkWindow *focusWinPtr; - - UpdateWrapper(winPtr); - - focusWinPtr = TkGetFocusWin(winPtr); - if (focusWinPtr) { - TkSetFocusWin(focusWinPtr, 1); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpWinGetState -- - * - * This function returns state value of a toplevel window. - * - * Results: - * none - * - * Side effects: - * May deiconify the toplevel window. - * - *---------------------------------------------------------------------- - */ - -int -TkpWmGetState( - TkWindow *winPtr) -{ - return winPtr->wmInfoPtr->hints.initial_state; -} - -/* - *-------------------------------------------------------------- - * - * TkWmDeadWindow -- - * - * This function is invoked when a top-level window is about to be - * deleted. It cleans up the wm-related data structures for the window. - * - * Results: - * None. - * - * Side effects: - * The WmInfo structure for winPtr gets freed up. - * - *-------------------------------------------------------------- - */ - -void -TkWmDeadWindow( - TkWindow *winPtr) /* Top-level window that's being deleted. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - WmInfo *wmPtr2; - - if (wmPtr == NULL) { - return; - } - - /* - * Clean up event related window info. - */ - - if (winPtr->dispPtr->firstWmPtr == wmPtr) { - winPtr->dispPtr->firstWmPtr = wmPtr->nextPtr; - } else { - register WmInfo *prevPtr; - - for (prevPtr = winPtr->dispPtr->firstWmPtr; ; - prevPtr = prevPtr->nextPtr) { - if (prevPtr == NULL) { - Tcl_Panic("couldn't unlink window in TkWmDeadWindow"); - } - if (prevPtr->nextPtr == wmPtr) { - prevPtr->nextPtr = wmPtr->nextPtr; - break; - } - } - } - - /* - * Reset all transient windows whose master is the dead window. - */ - - for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL; - wmPtr2 = wmPtr2->nextPtr) { - if (wmPtr2->masterPtr == winPtr) { - wmPtr->numTransients--; - Tk_DeleteEventHandler((Tk_Window) wmPtr2->masterPtr, - VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, wmPtr2->winPtr); - wmPtr2->masterPtr = NULL; - if ((wmPtr2->wrapper != None) - && !(wmPtr2->flags & (WM_NEVER_MAPPED))) { - UpdateWrapper(wmPtr2->winPtr); - } - } - } - if (wmPtr->numTransients != 0) - Tcl_Panic("numTransients should be 0"); - - if (wmPtr->title != NULL) { - ckfree(wmPtr->title); - } - if (wmPtr->iconName != NULL) { - ckfree(wmPtr->iconName); - } - if (wmPtr->hints.flags & IconPixmapHint) { - Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap); - } - if (wmPtr->hints.flags & IconMaskHint) { - Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask); - } - if (wmPtr->leaderName != NULL) { - ckfree(wmPtr->leaderName); - } - if (wmPtr->icon != NULL) { - wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; - wmPtr2->iconFor = NULL; - } - if (wmPtr->iconFor != NULL) { - wmPtr2 = ((TkWindow *) wmPtr->iconFor)->wmInfoPtr; - wmPtr2->icon = NULL; - wmPtr2->hints.flags &= ~IconWindowHint; - } - while (wmPtr->protPtr != NULL) { - ProtocolHandler *protPtr; - - protPtr = wmPtr->protPtr; - wmPtr->protPtr = protPtr->nextPtr; - Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); - } - if (wmPtr->cmdArgv != NULL) { - ckfree(wmPtr->cmdArgv); - } - if (wmPtr->clientMachine != NULL) { - ckfree(wmPtr->clientMachine); - } - if (wmPtr->flags & WM_UPDATE_PENDING) { - Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr); - } - if (wmPtr->masterPtr != NULL) { - wmPtr2 = wmPtr->masterPtr->wmInfoPtr; - - /* - * If we had a master, tell them that we aren't tied to them anymore. - */ - - if (wmPtr2 != NULL) { - wmPtr2->numTransients--; - } - Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr, - VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, winPtr); - wmPtr->masterPtr = NULL; - } - if (wmPtr->crefObj != NULL) { - Tcl_DecrRefCount(wmPtr->crefObj); - wmPtr->crefObj = NULL; - } - - /* - * Destroy the decorative frame window. - */ - - if (!(winPtr->flags & TK_EMBEDDED)) { - if (wmPtr->wrapper != NULL) { - DestroyWindow(wmPtr->wrapper); - } else if (winPtr->window) { - DestroyWindow(Tk_GetHWND(winPtr->window)); - } - } else { - if (wmPtr->wrapper != NULL) { - SendMessage(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0); - } - } - if (wmPtr->iconPtr != NULL) { - /* - * This may delete the icon resource data. I believe we should do this - * after destroying the decorative frame, because the decorative frame - * is using this icon. - */ - - DecrIconRefCount(wmPtr->iconPtr); - } - - ckfree(wmPtr); - winPtr->wmInfoPtr = NULL; -} - -/* - *-------------------------------------------------------------- - * - * TkWmSetClass -- - * - * This function is invoked whenever a top-level window's class is - * changed. If the window has been mapped then this function updates the - * window manager property for the class. If the window hasn't been - * mapped, the update is deferred until just before the first mapping. - * - * Results: - * None. - * - * Side effects: - * A window property may get updated. - * - *-------------------------------------------------------------- - */ - -void -TkWmSetClass( - TkWindow *winPtr) /* Newly-created top-level window. */ -{ - /* Do nothing */ - return; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_WmObjCmd -- - * - * This function is invoked to process the "wm" Tcl command. See the user - * documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -int -Tk_WmObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_Window tkwin = clientData; - static const char *const optionStrings[] = { - "aspect", "attributes", "client", "colormapwindows", - "command", "deiconify", "focusmodel", "forget", "frame", - "geometry", "grid", "group", "iconbitmap", - "iconify", "iconmask", "iconname", - "iconphoto", "iconposition", - "iconwindow", "manage", "maxsize", "minsize", "overrideredirect", - "positionfrom", "protocol", "resizable", "sizefrom", - "stackorder", "state", "title", "transient", - "withdraw", NULL - }; - enum options { - WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS, - WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET, - WMOPT_FRAME, - WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP, - WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, - WMOPT_ICONPHOTO, WMOPT_ICONPOSITION, - WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE, - WMOPT_OVERRIDEREDIRECT, - WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM, - WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT, - WMOPT_WITHDRAW - }; - int index; - size_t length; - const char *argv1; - TkWindow *winPtr, **winPtrPtr = &winPtr; - TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - - if (objc < 2) { - wrongNumArgs: - Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?"); - return TCL_ERROR; - } - - argv1 = Tcl_GetString(objv[1]); - length = objv[1]->length; - if ((argv1[0] == 't') && !strncmp(argv1, "tracing", length) - && (length >= 3)) { - int wmTracing; - - if ((objc != 2) && (objc != 3)) { - Tcl_WrongNumArgs(interp, 2, objv, "?boolean?"); - return TCL_ERROR; - } - if (objc == 2) { - Tcl_SetObjResult(interp, Tcl_NewBooleanObj( - dispPtr->flags & TK_DISPLAY_WM_TRACING)); - return TCL_OK; - } - if (Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing) != TCL_OK) { - return TCL_ERROR; - } - if (wmTracing) { - dispPtr->flags |= TK_DISPLAY_WM_TRACING; - } else { - dispPtr->flags &= ~TK_DISPLAY_WM_TRACING; - } - return TCL_OK; - } - - if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, - sizeof(char *), "option", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - - if (objc < 3) { - goto wrongNumArgs; - } - - if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) winPtrPtr) - != TCL_OK) { - return TCL_ERROR; - } - if (!Tk_IsTopLevel(winPtr) && (index != WMOPT_MANAGE) - && (index != WMOPT_FORGET)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't a top-level window", winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName, - NULL); - return TCL_ERROR; - } - - switch ((enum options) index) { - case WMOPT_ASPECT: - return WmAspectCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ATTRIBUTES: - return WmAttributesCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_CLIENT: - return WmClientCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_COLORMAPWINDOWS: - return WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_COMMAND: - return WmCommandCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_DEICONIFY: - return WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_FOCUSMODEL: - return WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_FORGET: - return WmForgetCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_FRAME: - return WmFrameCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_GEOMETRY: - return WmGeometryCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_GRID: - return WmGridCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_GROUP: - return WmGroupCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONBITMAP: - return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONIFY: - return WmIconifyCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONMASK: - return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONNAME: - return WmIconnameCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONPHOTO: - return WmIconphotoCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONPOSITION: - return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONWINDOW: - return WmIconwindowCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_MANAGE: - return WmManageCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_MAXSIZE: - return WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_MINSIZE: - return WmMinsizeCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_OVERRIDEREDIRECT: - return WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_POSITIONFROM: - return WmPositionfromCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_PROTOCOL: - return WmProtocolCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_RESIZABLE: - return WmResizableCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_SIZEFROM: - return WmSizefromCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_STACKORDER: - return WmStackorderCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_STATE: - return WmStateCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_TITLE: - return WmTitleCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_TRANSIENT: - return WmTransientCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_WITHDRAW: - return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv); - } - - /* This should not happen */ - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * WmAspectCmd -- - * - * This function is invoked to process the "wm aspect" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmAspectCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int numer1, denom1, numer2, denom2; - - if ((objc != 3) && (objc != 7)) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?minNumer minDenom maxNumer maxDenom?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->sizeHintsFlags & PAspect) { - Tcl_Obj *results[4]; - - results[0] = Tcl_NewIntObj(wmPtr->minAspect.x); - results[1] = Tcl_NewIntObj(wmPtr->minAspect.y); - results[2] = Tcl_NewIntObj(wmPtr->maxAspect.x); - results[3] = Tcl_NewIntObj(wmPtr->maxAspect.y); - Tcl_SetObjResult(interp, Tcl_NewListObj(4, results)); - } - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->sizeHintsFlags &= ~PAspect; - } else { - if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) { - return TCL_ERROR; - } - if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) || (denom2 <= 0)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "aspect number can't be <= 0", -1)); - Tcl_SetErrorCode(interp, "TK", "VALUE", "ASPECT", NULL); - return TCL_ERROR; - } - wmPtr->minAspect.x = numer1; - wmPtr->minAspect.y = denom1; - wmPtr->maxAspect.x = numer2; - wmPtr->maxAspect.y = denom2; - wmPtr->sizeHintsFlags |= PAspect; - } - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmAttributesCmd -- - * - * This function is invoked to process the "wm attributes" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmAttributesCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - LONG style, exStyle, styleBit, *stylePtr = NULL; - const char *string; - int i, boolean; - size_t length; - int config_fullscreen = 0, updatewrapper = 0; - int fullscreen_attr_changed = 0, fullscreen_attr = 0; - - if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) { - configArgs: - Tcl_WrongNumArgs(interp, 2, objv, - "window" - " ?-alpha ?double??" - " ?-transparentcolor ?color??" - " ?-disabled ?bool??" - " ?-fullscreen ?bool??" - " ?-toolwindow ?bool??" - " ?-topmost ?bool??"); - return TCL_ERROR; - } - exStyle = wmPtr->exStyleConfig; - style = wmPtr->styleConfig; - if (objc == 3) { - Tcl_Obj *objPtr = Tcl_NewObj(); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-alpha", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewDoubleObj(wmPtr->alpha)); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-transparentcolor", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, - wmPtr->crefObj ? wmPtr->crefObj : Tcl_NewObj()); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-disabled", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewBooleanObj((style & WS_DISABLED))); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-fullscreen", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewBooleanObj((wmPtr->flags & WM_FULLSCREEN))); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-toolwindow", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewBooleanObj((exStyle & WS_EX_TOOLWINDOW))); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj("-topmost", -1)); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewBooleanObj((exStyle & WS_EX_TOPMOST))); - Tcl_SetObjResult(interp, objPtr); - return TCL_OK; - } - for (i = 3; i < objc; i += 2) { - string = Tcl_GetString(objv[i]); - length = objv[i]->length; - if ((length < 2) || (string[0] != '-')) { - goto configArgs; - } - if (strncmp(string, "-disabled", length) == 0) { - stylePtr = &style; - styleBit = WS_DISABLED; - } else if ((strncmp(string, "-alpha", length) == 0) - || ((length > 2) && (strncmp(string, "-transparentcolor", - length) == 0))) { - stylePtr = &exStyle; - styleBit = WS_EX_LAYERED; - } else if (strncmp(string, "-fullscreen", length) == 0) { - config_fullscreen = 1; - styleBit = 0; - } else if ((length > 3) - && (strncmp(string, "-toolwindow", length) == 0)) { - stylePtr = &exStyle; - styleBit = WS_EX_TOOLWINDOW; - if (objc != 4) { - /* - * Changes to toolwindow style require an update - */ - updatewrapper = 1; - } - } else if ((length > 3) - && (strncmp(string, "-topmost", length) == 0)) { - stylePtr = &exStyle; - styleBit = WS_EX_TOPMOST; - if ((i < objc-1) && (winPtr->flags & TK_EMBEDDED)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't set topmost flag on %s: it is an embedded window", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "TOPMOST", NULL); - return TCL_ERROR; - } - } else { - goto configArgs; - } - if (styleBit == WS_EX_LAYERED) { - if (objc == 4) { - if (string[1] == 'a') { /* -alpha */ - Tcl_SetObjResult(interp, Tcl_NewDoubleObj(wmPtr->alpha)); - } else { /* -transparentcolor */ - Tcl_SetObjResult(interp, - wmPtr->crefObj ? wmPtr->crefObj : Tcl_NewObj()); - } - } else { - if (string[1] == 'a') { /* -alpha */ - double dval; - - if (Tcl_GetDoubleFromObj(interp, objv[i+1], &dval) - != TCL_OK) { - return TCL_ERROR; - } - - /* - * The user should give (transparent) 0 .. 1.0 (opaque), - * but we ignore the setting of this (it will always be 1) - * in the case that the API is not available. - */ - if (dval < 0.0) { - dval = 0; - } else if (dval > 1.0) { - dval = 1; - } - wmPtr->alpha = dval; - } else { /* -transparentcolor */ - const char *crefstr = Tcl_GetString(objv[i+1]); - - length = objv[i+1]->length; - if (length == 0) { - /* reset to no transparent color */ - if (wmPtr->crefObj) { - Tcl_DecrRefCount(wmPtr->crefObj); - wmPtr->crefObj = NULL; - } - } else { - XColor *cPtr = - Tk_GetColor(interp, tkwin, Tk_GetUid(crefstr)); - if (cPtr == NULL) { - return TCL_ERROR; - } - - if (wmPtr->crefObj) { - Tcl_DecrRefCount(wmPtr->crefObj); - } - wmPtr->crefObj = objv[i+1]; - Tcl_IncrRefCount(wmPtr->crefObj); - wmPtr->colorref = RGB((BYTE) (cPtr->red >> 8), - (BYTE) (cPtr->green >> 8), - (BYTE) (cPtr->blue >> 8)); - Tk_FreeColor(cPtr); - } - } - - /* - * Only ever add the WS_EX_LAYERED bit, as it can cause - * flashing to change this window style. This allows things - * like fading tooltips to avoid flash ugliness without - * forcing all window to be layered. - */ - - if ((wmPtr->alpha < 1.0) || (wmPtr->crefObj != NULL)) { - *stylePtr |= styleBit; - } - if (wmPtr->wrapper != NULL) { - /* - * Set the window directly regardless of UpdateWrapper. - * The user supplies a double from [0..1], but Windows - * wants an int (transparent) 0..255 (opaque), so do the - * translation. Add the 0.5 to round the value. - */ - - if (!(wmPtr->exStyleConfig & WS_EX_LAYERED)) { - SetWindowLongPtr(wmPtr->wrapper, GWL_EXSTYLE, - *stylePtr); - } - SetLayeredWindowAttributes((HWND) wmPtr->wrapper, - wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5), - (unsigned) (LWA_ALPHA | - (wmPtr->crefObj ? LWA_COLORKEY : 0))); - } - } - } else { - if ((i < objc-1) - && Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean) - != TCL_OK) { - return TCL_ERROR; - } - if (config_fullscreen) { - if (objc == 4) { - Tcl_SetObjResult(interp, Tcl_NewBooleanObj( - wmPtr->flags & WM_FULLSCREEN)); - } else { - fullscreen_attr_changed = 1; - fullscreen_attr = boolean; - } - config_fullscreen = 0; - } else if (objc == 4) { - Tcl_SetObjResult(interp, - Tcl_NewBooleanObj(*stylePtr & styleBit)); - } else if (boolean) { - *stylePtr |= styleBit; - } else { - *stylePtr &= ~styleBit; - } - } - if ((styleBit == WS_EX_TOPMOST) && (wmPtr->wrapper != NULL)) { - /* - * Force the topmost position aspect to ensure that switching - * between (no)topmost reflects properly when rewrapped. - */ - - SetWindowPos(wmPtr->wrapper, - ((exStyle & WS_EX_TOPMOST) ? - HWND_TOPMOST : HWND_NOTOPMOST), 0, 0, 0, 0, - SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOSENDCHANGING - |SWP_NOOWNERZORDER); - } - } - if (wmPtr->styleConfig != style) { - /* - * Currently this means only WS_DISABLED changed, which we can effect - * with EnableWindow. - */ - - wmPtr->styleConfig = style; - if ((wmPtr->exStyleConfig == exStyle) - && !(wmPtr->flags & WM_NEVER_MAPPED)) { - EnableWindow(wmPtr->wrapper, (style & WS_DISABLED) ? 0 : 1); - } - } - if (wmPtr->exStyleConfig != exStyle) { - wmPtr->exStyleConfig = exStyle; - if (updatewrapper) { - /* - * UpdateWrapper ensure that all effects are properly handled, - * such as TOOLWINDOW disappearing from the taskbar. - */ - - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - UpdateWrapper(winPtr); - } - } - } - if (fullscreen_attr_changed) { - if (fullscreen_attr) { - if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't set fullscreen attribute for \"%s\":" - " override-redirect flag is set", winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", - "OVERRIDE_REDIRECT", NULL); - return TCL_ERROR; - } - - /* - * Check max width and height if set by the user, don't worry - * about the default values since they will likely be smaller than - * screen width/height. - */ - - if (((wmPtr->maxWidth > 0) && - (WidthOfScreen(Tk_Screen(winPtr)) > wmPtr->maxWidth)) || - ((wmPtr->maxHeight > 0) && - (HeightOfScreen(Tk_Screen(winPtr)) > wmPtr->maxHeight))) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't set fullscreen attribute for \"%s\":" - " max width/height is too small", winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "SMALL_MAX", NULL); - return TCL_ERROR; - } - } - - TkpWmSetFullScreen(winPtr, fullscreen_attr); - } - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmClientCmd -- - * - * This function is invoked to process the "wm client" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmClientCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - const char *argv3; - size_t length; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?name?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->clientMachine != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj(wmPtr->clientMachine, -1)); - } - return TCL_OK; - } - argv3 = Tcl_GetString(objv[3]); - length = objv[3]->length; - if (argv3[0] == 0) { - if (wmPtr->clientMachine != NULL) { - ckfree(wmPtr->clientMachine); - wmPtr->clientMachine = NULL; - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - XDeleteProperty(winPtr->display, winPtr->window, - Tk_InternAtom((Tk_Window) winPtr,"WM_CLIENT_MACHINE")); - } - } - return TCL_OK; - } - if (wmPtr->clientMachine != NULL) { - ckfree(wmPtr->clientMachine); - } - wmPtr->clientMachine = ckalloc(length + 1); - memcpy(wmPtr->clientMachine, argv3, length + 1); - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - XTextProperty textProp; - - if (XStringListToTextProperty(&wmPtr->clientMachine, 1, &textProp) - != 0) { - XSetWMClientMachine(winPtr->display, winPtr->window, - &textProp); - XFree((char *) textProp.value); - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmColormapwindowsCmd -- - * - * This function is invoked to process the "wm colormapwindows" Tcl - * command. See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmColormapwindowsCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - TkWindow **cmapList, *winPtr2, **winPtr2Ptr = &winPtr2; - int i, windowObjc, gotToplevel; - Tcl_Obj **windowObjv, *resultObj; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?"); - return TCL_ERROR; - } - if (objc == 3) { - Tk_MakeWindowExist((Tk_Window) winPtr); - resultObj = Tcl_NewObj(); - for (i = 0; i < wmPtr->cmapCount; i++) { - if ((i == (wmPtr->cmapCount-1)) - && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) { - break; - } - Tcl_ListObjAppendElement(NULL, resultObj, - TkNewWindowObj((Tk_Window) wmPtr->cmapList[i])); - } - Tcl_SetObjResult(interp, resultObj); - return TCL_OK; - } - if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv) - != TCL_OK) { - return TCL_ERROR; - } - cmapList = ckalloc((windowObjc + 1) * sizeof(TkWindow*)); - gotToplevel = 0; - for (i = 0; i < windowObjc; i++) { - if (TkGetWindowFromObj(interp, tkwin, windowObjv[i], - (Tk_Window *) winPtr2Ptr) != TCL_OK) { - ckfree(cmapList); - return TCL_ERROR; - } - if (winPtr2 == winPtr) { - gotToplevel = 1; - } - if (winPtr2->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr2); - } - cmapList[i] = winPtr2; - } - if (!gotToplevel) { - wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP; - cmapList[windowObjc] = winPtr; - windowObjc++; - } else { - wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP; - } - wmPtr->flags |= WM_COLORMAPS_EXPLICIT; - if (wmPtr->cmapList != NULL) { - ckfree(wmPtr->cmapList); - } - wmPtr->cmapList = cmapList; - wmPtr->cmapCount = windowObjc; - - /* - * Now we need to force the updated colormaps to be installed. - */ - - if (wmPtr == winPtr->dispPtr->foregroundWmPtr) { - InstallColormaps(wmPtr->wrapper, WM_QUERYNEWPALETTE, 1); - } else { - InstallColormaps(wmPtr->wrapper, WM_PALETTECHANGED, 0); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmCommandCmd -- - * - * This function is invoked to process the "wm command" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmCommandCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - const char *argv3; - int cmdArgc; - const char **cmdArgv; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?value?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->cmdArgv != NULL) { - char *merged = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv); - - Tcl_SetObjResult(interp, Tcl_NewStringObj(merged, -1)); - ckfree(merged); - } - return TCL_OK; - } - argv3 = Tcl_GetString(objv[3]); - if (argv3[0] == 0) { - if (wmPtr->cmdArgv != NULL) { - ckfree(wmPtr->cmdArgv); - wmPtr->cmdArgv = NULL; - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - XDeleteProperty(winPtr->display, winPtr->window, - Tk_InternAtom((Tk_Window) winPtr, "WM_COMMAND")); - } - } - return TCL_OK; - } - if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) { - return TCL_ERROR; - } - if (wmPtr->cmdArgv != NULL) { - ckfree(wmPtr->cmdArgv); - } - wmPtr->cmdArgc = cmdArgc; - wmPtr->cmdArgv = cmdArgv; - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - XSetCommand(winPtr->display, winPtr->window, (char **) cmdArgv, cmdArgc); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmDeiconifyCmd -- - * - * This function is invoked to process the "wm deiconify" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmDeiconifyCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't deiconify %s: it is an icon for %s", - Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "ICON", NULL); - return TCL_ERROR; - } - if (winPtr->flags & TK_EMBEDDED) { - if (!SendMessage(wmPtr->wrapper, TK_DEICONIFY, 0, 0)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't deiconify %s: the container does not support the request", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL); - return TCL_ERROR; - } - return TCL_OK; - } - TkpWinToplevelDeiconify(winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmFocusmodelCmd -- - * - * This function is invoked to process the "wm focusmodel" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmFocusmodelCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *const optionStrings[] = { - "active", "passive", NULL - }; - enum options { - OPT_ACTIVE, OPT_PASSIVE - }; - int index; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - wmPtr->hints.input ? "passive" : "active", -1)); - return TCL_OK; - } - - if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings, - sizeof(char *), "argument", 0,&index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_ACTIVE) { - wmPtr->hints.input = False; - } else { /* OPT_PASSIVE */ - wmPtr->hints.input = True; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmForgetCmd -- - * - * This procedure is invoked to process the "wm forget" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmForgetCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel or Frame to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register Tk_Window frameWin = (Tk_Window) winPtr; - - if (Tk_IsTopLevel(frameWin)) { - Tk_UnmapWindow(frameWin); - winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED); - Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr); - RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window)); - - /* - * Make sure wm no longer manages this window - */ - Tk_ManageGeometry(frameWin, NULL, NULL); - - TkWmDeadWindow(winPtr); - /* flags (above) must be cleared before calling */ - /* TkMapTopFrame (below) */ - TkMapTopFrame(frameWin); - } else { - /* Already not managed by wm - ignore it */ - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmFrameCmd -- - * - * This function is invoked to process the "wm frame" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmFrameCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - HWND hwnd; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - if (Tk_WindowId((Tk_Window) winPtr) == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); - } - hwnd = wmPtr->wrapper; - if (hwnd == NULL) { - hwnd = Tk_GetHWND(Tk_WindowId((Tk_Window) winPtr)); - } - Tcl_SetObjResult(interp, Tcl_ObjPrintf("0x%x", PTR2INT(hwnd))); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmGeometryCmd -- - * - * This function is invoked to process the "wm geometry" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmGeometryCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - char xSign, ySign; - int width, height; - const char *argv3; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?"); - return TCL_ERROR; - } - - if (objc == 3) { - xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+'; - ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+'; - if (wmPtr->gridWin != NULL) { - width = wmPtr->reqGridWidth + (winPtr->changes.width - - winPtr->reqWidth)/wmPtr->widthInc; - height = wmPtr->reqGridHeight + (winPtr->changes.height - - winPtr->reqHeight)/wmPtr->heightInc; - } else { - width = winPtr->changes.width; - height = winPtr->changes.height; - } - if (winPtr->flags & TK_EMBEDDED) { - int result = SendMessage(wmPtr->wrapper, TK_MOVEWINDOW, -1, -1); - - wmPtr->x = result >> 16; - wmPtr->y = result & 0x0000ffff; - } - Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d%c%d%c%d", - width, height, xSign, wmPtr->x, ySign, wmPtr->y)); - return TCL_OK; - } - - argv3 = Tcl_GetString(objv[3]); - if (*argv3 == '\0') { - wmPtr->width = -1; - wmPtr->height = -1; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; - } - return ParseGeometry(interp, argv3, winPtr); -} - -/* - *---------------------------------------------------------------------- - * - * WmGridCmd -- - * - * This function is invoked to process the "wm grid" Tcl command. See the - * user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmGridCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int reqWidth, reqHeight, widthInc, heightInc; - - if ((objc != 3) && (objc != 7)) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?baseWidth baseHeight widthInc heightInc?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->sizeHintsFlags & PBaseSize) { - Tcl_Obj *results[4]; - - results[0] = Tcl_NewIntObj(wmPtr->reqGridWidth); - results[1] = Tcl_NewIntObj(wmPtr->reqGridHeight); - results[2] = Tcl_NewIntObj(wmPtr->widthInc); - results[3] = Tcl_NewIntObj(wmPtr->heightInc); - Tcl_SetObjResult(interp, Tcl_NewListObj(4, results)); - } - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - /* - * Turn off gridding and reset the width and height to make sense as - * ungridded numbers. - */ - - wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc); - if (wmPtr->width != -1) { - wmPtr->width = winPtr->reqWidth + (wmPtr->width - - wmPtr->reqGridWidth)*wmPtr->widthInc; - wmPtr->height = winPtr->reqHeight + (wmPtr->height - - wmPtr->reqGridHeight)*wmPtr->heightInc; - } - wmPtr->widthInc = 1; - wmPtr->heightInc = 1; - } else { - if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) { - return TCL_ERROR; - } - if (reqWidth < 0) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "baseWidth can't be < 0", -1)); - Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL); - return TCL_ERROR; - } - if (reqHeight < 0) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "baseHeight can't be < 0", -1)); - Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL); - return TCL_ERROR; - } - if (widthInc <= 0) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "widthInc can't be <= 0", -1)); - Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL); - return TCL_ERROR; - } - if (heightInc <= 0) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "heightInc can't be <= 0", -1)); - Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL); - return TCL_ERROR; - } - Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc, - heightInc); - } - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmGroupCmd -- - * - * This function is invoked to process the "wm group" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmGroupCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - Tk_Window tkwin2; - const char *argv3; - size_t length; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->hints.flags & WindowGroupHint) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, -1)); - } - return TCL_OK; - } - argv3 = Tcl_GetString(objv[3]); - length = objv[3]->length; - if (*argv3 == '\0') { - wmPtr->hints.flags &= ~WindowGroupHint; - if (wmPtr->leaderName != NULL) { - ckfree(wmPtr->leaderName); - } - wmPtr->leaderName = NULL; - } else { - if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - Tk_MakeWindowExist(tkwin2); - if (wmPtr->leaderName != NULL) { - ckfree(wmPtr->leaderName); - } - wmPtr->hints.window_group = Tk_WindowId(tkwin2); - wmPtr->hints.flags |= WindowGroupHint; - wmPtr->leaderName = ckalloc(length + 1); - memcpy(wmPtr->leaderName, argv3, length + 1); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconbitmapCmd -- - * - * This function is invoked to process the "wm iconbitmap" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconbitmapCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */ - const char *string; - - if ((objc < 3) || (objc > 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?-default? ?image?"); - return TCL_ERROR; - } else if (objc == 5) { - /* - * If we have 5 arguments, we must have a '-default' flag. - */ - - const char *argv3 = Tcl_GetString(objv[3]); - - if (strcmp(argv3, "-default")) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "illegal option \"%s\" must be \"-default\"", argv3)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONBITMAP", "OPTION",NULL); - return TCL_ERROR; - } - useWinPtr = NULL; - } else if (objc == 3) { - /* - * No arguments were given. - */ - - if (wmPtr->hints.flags & IconPixmapHint) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap), - -1)); - } - return TCL_OK; - } - - string = Tcl_GetString(objv[objc-1]); - if (*string == '\0') { - if (wmPtr->hints.icon_pixmap != None) { - Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap); - wmPtr->hints.icon_pixmap = None; - } - wmPtr->hints.flags &= ~IconPixmapHint; - if (WinSetIcon(interp, NULL, (Tk_Window) useWinPtr) != TCL_OK) { - return TCL_ERROR; - } - } else { - /* - * In the future this block of code will use Tk's 'image' - * functionality to allow all supported image formats. However, this - * will require a change to the way icons are handled. We will need to - * add icon<->image conversions routines. - * - * Until that happens we simply try to find an icon in the given - * argument, and if that fails, we use the older bitmap code. We do - * things this way round (icon then bitmap), because the bitmap code - * actually seems to have no visible effect, so we want to give the - * icon code the first try at doing something. - */ - - /* - * Either return NULL, or return a valid titlebaricon with its ref - * count already incremented. - */ - - WinIconPtr titlebaricon = ReadIconFromFile(interp, objv[objc-1]); - if (titlebaricon != NULL) { - /* - * Try to set the icon for the window. If it is a '-default' icon, - * we must pass in NULL - */ - - if (WinSetIcon(interp, titlebaricon, (Tk_Window) useWinPtr) - != TCL_OK) { - /* - * We didn't use the titlebaricon after all. - */ - - DecrIconRefCount(titlebaricon); - titlebaricon = NULL; - } - } - if (titlebaricon == NULL) { - /* - * We didn't manage to handle the argument as a valid icon. Try as - * a bitmap. First we must clear the error message which was - * placed in the interpreter. - */ - - Pixmap pixmap; - - Tcl_ResetResult(interp); - pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, string); - if (pixmap == None) { - return TCL_ERROR; - } - wmPtr->hints.icon_pixmap = pixmap; - wmPtr->hints.flags |= IconPixmapHint; - titlebaricon = GetIconFromPixmap(Tk_Display(winPtr), pixmap); - if (titlebaricon != NULL && WinSetIcon(interp, titlebaricon, - (Tk_Window) useWinPtr) != TCL_OK) { - /* - * We didn't use the titlebaricon after all. - */ - - DecrIconRefCount(titlebaricon); - titlebaricon = NULL; - } - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconifyCmd -- - * - * This function is invoked to process the "wm iconify" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconifyCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - if (winPtr->flags & TK_EMBEDDED) { - if (!SendMessage(wmPtr->wrapper, TK_ICONIFY, 0, 0)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify %s: the container does not support the request", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "EMBEDDED", NULL); - return TCL_ERROR; - } - } - if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify \"%s\": override-redirect flag is set", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "OVERRIDE_REDIRECT", - NULL); - return TCL_ERROR; - } - if (wmPtr->masterPtr != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify \"%s\": it is a transient", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "TRANSIENT", NULL); - return TCL_ERROR; - } - if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify %s: it is an icon for %s", - winPtr->pathName, Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "ICON", NULL); - return TCL_ERROR; - } - TkpWmSetState(winPtr, IconicState); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconmaskCmd -- - * - * This function is invoked to process the "wm iconmask" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconmaskCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - Pixmap pixmap; - const char *argv3; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->hints.flags & IconMaskHint) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask), - -1)); - } - return TCL_OK; - } - argv3 = Tcl_GetString(objv[3]); - if (*argv3 == '\0') { - if (wmPtr->hints.icon_mask != None) { - Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask); - } - wmPtr->hints.flags &= ~IconMaskHint; - } else { - pixmap = Tk_GetBitmap(interp, tkwin, argv3); - if (pixmap == None) { - return TCL_ERROR; - } - wmPtr->hints.icon_mask = pixmap; - wmPtr->hints.flags |= IconMaskHint; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconnameCmd -- - * - * This function is invoked to process the "wm iconname" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconnameCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - const char *argv3; - size_t length; - - if (objc > 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - (wmPtr->iconName ? wmPtr->iconName : ""), -1)); - return TCL_OK; - } else { - if (wmPtr->iconName != NULL) { - ckfree(wmPtr->iconName); - } - argv3 = Tcl_GetString(objv[3]); - length = objv[3]->length; - wmPtr->iconName = ckalloc(length + 1); - memcpy(wmPtr->iconName, argv3, length + 1); - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName); - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconphotoCmd -- - * - * This function is invoked to process the "wm iconphoto" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconphotoCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */ - Tk_PhotoHandle photo; - Tk_PhotoImageBlock block; - int i, width, height, idx, bufferSize, startObj = 3; - union {unsigned char *ptr; void *voidPtr;} bgraPixel; - union {unsigned char *ptr; void *voidPtr;} bgraMask; - BlockOfIconImagesPtr lpIR; - WinIconPtr titlebaricon = NULL; - HICON hIcon; - unsigned size; - BITMAPINFO bmInfo; - ICONINFO iconInfo; - - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?-default? image1 ?image2 ...?"); - return TCL_ERROR; - } - - /* - * Iterate over all images to validate their existence. - */ - - if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) { - useWinPtr = NULL; - startObj = 4; - if (objc == 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?-default? image1 ?image2 ...?"); - return TCL_ERROR; - } - } - for (i = startObj; i < objc; i++) { - photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i])); - if (photo == NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't use \"%s\" as iconphoto: not a photo image", - Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL); - return TCL_ERROR; - } - } - - /* - * We have calculated the size of the data. Try to allocate the needed - * memory space. - */ - - size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1)); - lpIR = attemptckalloc(size); - if (lpIR == NULL) { - return TCL_ERROR; - } - ZeroMemory(lpIR, size); - - lpIR->nNumImages = objc - startObj; - - for (i = startObj; i < objc; i++) { - photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i])); - Tk_PhotoGetSize(photo, &width, &height); - Tk_PhotoGetImage(photo, &block); - - /* - * Don't use CreateIcon to create the icon, as it requires color - * bitmap data in device-dependent format. Instead we use - * CreateIconIndirect which takes device-independent bitmaps and - * converts them as required. Initialise icon info structure. - */ - - ZeroMemory(&iconInfo, sizeof(iconInfo)); - iconInfo.fIcon = TRUE; - - /* - * Create device-independant color bitmap. - */ - - ZeroMemory(&bmInfo, sizeof bmInfo); - bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmInfo.bmiHeader.biWidth = width; - bmInfo.bmiHeader.biHeight = -height; - bmInfo.bmiHeader.biPlanes = 1; - bmInfo.bmiHeader.biBitCount = 32; - bmInfo.bmiHeader.biCompression = BI_RGB; - - iconInfo.hbmColor = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS, - &bgraPixel.voidPtr, NULL, 0); - if (!iconInfo.hbmColor) { - ckfree(lpIR); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "failed to create color bitmap for \"%s\"", - Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "BITMAP", NULL); - return TCL_ERROR; - } - - /* - * Convert the photo image data into BGRA format (RGBQUAD). - */ - - bufferSize = height * width * 4; - for (idx = 0 ; idx < bufferSize ; idx += 4) { - bgraPixel.ptr[idx] = block.pixelPtr[idx+2]; - bgraPixel.ptr[idx+1] = block.pixelPtr[idx+1]; - bgraPixel.ptr[idx+2] = block.pixelPtr[idx+0]; - bgraPixel.ptr[idx+3] = block.pixelPtr[idx+3]; - } - - /* - * Create a dummy mask bitmap. The contents of this don't appear to - * matter, as CreateIconIndirect will setup the icon mask based on the - * alpha channel in our color bitmap. - */ - - bmInfo.bmiHeader.biBitCount = 1; - - iconInfo.hbmMask = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS, - &bgraMask.voidPtr, NULL, 0); - if (!iconInfo.hbmMask) { - DeleteObject(iconInfo.hbmColor); - ckfree(lpIR); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "failed to create mask bitmap for \"%s\"", - Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "MASK", NULL); - return TCL_ERROR; - } - - ZeroMemory(bgraMask.ptr, width*height/8); - - /* - * Create an icon from the bitmaps. - */ - - hIcon = CreateIconIndirect(&iconInfo); - DeleteObject(iconInfo.hbmColor); - DeleteObject(iconInfo.hbmMask); - if (hIcon == NULL) { - /* - * XXX should free up created icons. - */ - - ckfree(lpIR); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "failed to create icon for \"%s\"", - Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "ICON", NULL); - return TCL_ERROR; - } - lpIR->IconImages[i-startObj].Width = width; - lpIR->IconImages[i-startObj].Height = height; - lpIR->IconImages[i-startObj].Colors = 4; - lpIR->IconImages[i-startObj].hIcon = hIcon; - } - - titlebaricon = ckalloc(sizeof(WinIconInstance)); - titlebaricon->iconBlock = lpIR; - titlebaricon->refCount = 1; - if (WinSetIcon(interp, titlebaricon, (Tk_Window) useWinPtr) != TCL_OK) { - /* - * We didn't use the titlebaricon after all. - */ - - DecrIconRefCount(titlebaricon); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconpositionCmd -- - * - * This function is invoked to process the "wm iconposition" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconpositionCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int x, y; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->hints.flags & IconPositionHint) { - Tcl_Obj *results[2]; - - results[0] = Tcl_NewIntObj(wmPtr->hints.icon_x); - results[1] = Tcl_NewIntObj(wmPtr->hints.icon_y); - Tcl_SetObjResult(interp, Tcl_NewListObj(2, results)); - } - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->hints.flags &= ~IconPositionHint; - } else { - if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) { - return TCL_ERROR; - } - wmPtr->hints.icon_x = x; - wmPtr->hints.icon_y = y; - wmPtr->hints.flags |= IconPositionHint; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconwindowCmd -- - * - * This function is invoked to process the "wm iconwindow" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconwindowCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - Tk_Window tkwin2; - WmInfo *wmPtr2; - XSetWindowAttributes atts; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->icon != NULL) { - Tcl_SetObjResult(interp, TkNewWindowObj(wmPtr->icon)); - } - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->hints.flags &= ~IconWindowHint; - if (wmPtr->icon != NULL) { - /* - * Let the window use button events again, then remove it as icon - * window. - */ - - atts.event_mask = Tk_Attributes(wmPtr->icon)->event_mask - | ButtonPressMask; - Tk_ChangeWindowAttributes(wmPtr->icon, CWEventMask, &atts); - wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; - wmPtr2->iconFor = NULL; - wmPtr2->hints.initial_state = WithdrawnState; - } - wmPtr->icon = NULL; - } else { - if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - if (!Tk_IsTopLevel(tkwin2)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't use %s as icon window: not at top level", - Tcl_GetString(objv[3]))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "INNER", NULL); - return TCL_ERROR; - } - wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr; - if (wmPtr2->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "%s is already an icon for %s", - Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "ICON", NULL); - return TCL_ERROR; - } - if (wmPtr->icon != NULL) { - WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; - wmPtr3->iconFor = NULL; - - /* - * Let the window use button events again. - */ - - atts.event_mask = Tk_Attributes(wmPtr->icon)->event_mask - | ButtonPressMask; - Tk_ChangeWindowAttributes(wmPtr->icon, CWEventMask, &atts); - } - - /* - * Disable button events in the icon window: some window managers - * (like olvwm) want to get the events themselves, but X only allows - * one application at a time to receive button events for a window. - */ - - atts.event_mask = Tk_Attributes(tkwin2)->event_mask - & ~ButtonPressMask; - Tk_ChangeWindowAttributes(tkwin2, CWEventMask, &atts); - Tk_MakeWindowExist(tkwin2); - wmPtr->hints.icon_window = Tk_WindowId(tkwin2); - wmPtr->hints.flags |= IconWindowHint; - wmPtr->icon = tkwin2; - wmPtr2->iconFor = (Tk_Window) winPtr; - if (!(wmPtr2->flags & WM_NEVER_MAPPED)) { - wmPtr2->flags |= WM_WITHDRAWN; - TkpWmSetState(((TkWindow *) tkwin2), WithdrawnState); - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmManageCmd -- - * - * This procedure is invoked to process the "wm manage" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmManageCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel or Frame to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register Tk_Window frameWin = (Tk_Window) winPtr; - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (!Tk_IsTopLevel(frameWin)) { - if (!Tk_IsManageable(frameWin)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" is not manageable: must be a frame," - " labelframe or toplevel", Tk_PathName(frameWin))); - Tcl_SetErrorCode(interp, "TK", "WM", "MANAGE", NULL); - return TCL_ERROR; - } - TkFocusSplit(winPtr); - Tk_UnmapWindow(frameWin); - winPtr->flags |= TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED; - RemapWindows(winPtr, NULL); - if (wmPtr == NULL) { - TkWmNewWindow(winPtr); - } - wmPtr = winPtr->wmInfoPtr; - winPtr->flags &= ~TK_MAPPED; - /* flags (above) must be set before calling */ - /* TkMapTopFrame (below) */ - TkMapTopFrame (frameWin); - } else if (Tk_IsTopLevel(frameWin)) { - /* Already managed by wm - ignore it */ - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmMaxsizeCmd -- - * - * This function is invoked to process the "wm maxsize" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmMaxsizeCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int width, height; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_Obj *results[2]; - - GetMaxSize(wmPtr, &width, &height); - results[0] = Tcl_NewIntObj(width); - results[1] = Tcl_NewIntObj(height); - Tcl_SetObjResult(interp, Tcl_NewListObj(2, results)); - return TCL_OK; - } - if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) { - return TCL_ERROR; - } - wmPtr->maxWidth = width; - wmPtr->maxHeight = height; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmMinsizeCmd -- - * - * This function is invoked to process the "wm minsize" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmMinsizeCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int width, height; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_Obj *results[2]; - - GetMinSize(wmPtr, &width, &height); - results[0] = Tcl_NewIntObj(width); - results[1] = Tcl_NewIntObj(height); - Tcl_SetObjResult(interp, Tcl_NewListObj(2, results)); - return TCL_OK; - } - if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) { - return TCL_ERROR; - } - wmPtr->minWidth = width; - wmPtr->minHeight = height; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmOverrideredirectCmd -- - * - * This function is invoked to process the "wm overrideredirect" Tcl - * command. See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmOverrideredirectCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int boolean, curValue; - XSetWindowAttributes atts; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?"); - return TCL_ERROR; - } - if (winPtr->flags & TK_EMBEDDED) { - curValue = SendMessage(wmPtr->wrapper, TK_OVERRIDEREDIRECT, -1, -1)-1; - if (curValue < 0) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "Container does not support overrideredirect", -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL); - return TCL_ERROR; - } - } else { - curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect; - } - if (objc == 3) { - Tcl_SetObjResult(interp, Tcl_NewBooleanObj(curValue)); - return TCL_OK; - } - if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) { - return TCL_ERROR; - } - if (curValue != boolean) { - if (winPtr->flags & TK_EMBEDDED) { - SendMessage(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolean, 0); - } else { - /* - * Only do this if we are really changing value, because it causes - * some funky stuff to occur. - */ - - atts.override_redirect = (boolean) ? True : False; - Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, - &atts); - if (!(wmPtr->flags & (WM_NEVER_MAPPED)) - && !(winPtr->flags & TK_EMBEDDED)) { - UpdateWrapper(winPtr); - } - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmPositionfromCmd -- - * - * This function is invoked to process the "wm positionfrom" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmPositionfromCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *const optionStrings[] = { - "program", "user", NULL - }; - enum options { - OPT_PROGRAM, OPT_USER - }; - int index; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?"); - return TCL_ERROR; - } - if (objc == 3) { - const char *sourceStr = ""; - - if (wmPtr->sizeHintsFlags & USPosition) { - sourceStr = "user"; - } else if (wmPtr->sizeHintsFlags & PPosition) { - sourceStr = "program"; - } - Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1)); - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->sizeHintsFlags &= ~(USPosition|PPosition); - } else { - if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings, - sizeof(char *), "argument", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_USER) { - wmPtr->sizeHintsFlags &= ~PPosition; - wmPtr->sizeHintsFlags |= USPosition; - } else { - wmPtr->sizeHintsFlags &= ~USPosition; - wmPtr->sizeHintsFlags |= PPosition; - } - } - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmProtocolCmd -- - * - * This function is invoked to process the "wm protocol" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmProtocolCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - register ProtocolHandler *protPtr, *prevPtr; - Atom protocol; - const char *cmd; - size_t cmdLength; - Tcl_Obj *resultObj; - - if ((objc < 3) || (objc > 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?"); - return TCL_ERROR; - } - if (objc == 3) { - /* - * Return a list of all defined protocols for the window. - */ - - resultObj = Tcl_NewObj(); - for (protPtr = wmPtr->protPtr; protPtr != NULL; - protPtr = protPtr->nextPtr) { - Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( - Tk_GetAtomName((Tk_Window)winPtr, protPtr->protocol), -1)); - } - Tcl_SetObjResult(interp, resultObj); - return TCL_OK; - } - protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3])); - if (objc == 4) { - /* - * Return the command to handle a given protocol. - */ - - for (protPtr = wmPtr->protPtr; protPtr != NULL; - protPtr = protPtr->nextPtr) { - if (protPtr->protocol == protocol) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj(protPtr->command, -1)); - return TCL_OK; - } - } - return TCL_OK; - } - - /* - * Delete any current protocol handler, then create a new one with the - * specified command, unless the command is empty. - */ - - for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL; - prevPtr = protPtr, protPtr = protPtr->nextPtr) { - if (protPtr->protocol == protocol) { - if (prevPtr == NULL) { - wmPtr->protPtr = protPtr->nextPtr; - } else { - prevPtr->nextPtr = protPtr->nextPtr; - } - Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); - break; - } - } - cmd = Tcl_GetString(objv[4]); - cmdLength = objv[4]->length; - if (cmdLength > 0) { - protPtr = ckalloc(HANDLER_SIZE(cmdLength)); - protPtr->protocol = protocol; - protPtr->nextPtr = wmPtr->protPtr; - wmPtr->protPtr = protPtr; - protPtr->interp = interp; - memcpy(protPtr->command, cmd, cmdLength + 1); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmResizableCmd -- - * - * This function is invoked to process the "wm resizable" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmResizableCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int width, height; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_Obj *results[2]; - - results[0] = Tcl_NewBooleanObj(!(wmPtr->flags&WM_WIDTH_NOT_RESIZABLE)); - results[1] = Tcl_NewBooleanObj(!(wmPtr->flags&WM_HEIGHT_NOT_RESIZABLE)); - Tcl_SetObjResult(interp, Tcl_NewListObj(2, results)); - return TCL_OK; - } - if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK) - || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) { - return TCL_ERROR; - } - if (width) { - wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE; - } else { - wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE; - } - if (height) { - wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE; - } else { - wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE; - } - if (!((wmPtr->flags & WM_NEVER_MAPPED) - && !(winPtr->flags & TK_EMBEDDED))) { - UpdateWrapper(winPtr); - } - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmSizefromCmd -- - * - * This function is invoked to process the "wm sizefrom" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmSizefromCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *const optionStrings[] = { - "program", "user", NULL - }; - enum options { - OPT_PROGRAM, OPT_USER - }; - int index; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?"); - return TCL_ERROR; - } - if (objc == 3) { - const char *sourceStr = ""; - - if (wmPtr->sizeHintsFlags & USSize) { - sourceStr = "user"; - } else if (wmPtr->sizeHintsFlags & PSize) { - sourceStr = "program"; - } - Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1)); - return TCL_OK; - } - - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->sizeHintsFlags &= ~(USSize|PSize); - } else { - if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings, - sizeof(char *), "argument", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_USER) { - wmPtr->sizeHintsFlags &= ~PSize; - wmPtr->sizeHintsFlags |= USSize; - } else { /* OPT_PROGRAM */ - wmPtr->sizeHintsFlags &= ~USSize; - wmPtr->sizeHintsFlags |= PSize; - } - } - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmStackorderCmd -- - * - * This function is invoked to process the "wm stackorder" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmStackorderCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - TkWindow **windows, **windowPtr; - static const char *const optionStrings[] = { - "isabove", "isbelow", NULL - }; - enum options { - OPT_ISABOVE, OPT_ISBELOW - }; - Tcl_Obj *resultObj; - int index; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?"); - return TCL_ERROR; - } - - if (objc == 3) { - windows = TkWmStackorderToplevel(winPtr); - if (windows == NULL) { - Tcl_Panic("TkWmStackorderToplevel failed"); - } - - resultObj = Tcl_NewObj(); - for (windowPtr = windows; *windowPtr ; windowPtr++) { - Tcl_ListObjAppendElement(NULL, resultObj, - TkNewWindowObj((Tk_Window) *windowPtr)); - } - Tcl_SetObjResult(interp, resultObj); - ckfree(windows); - return TCL_OK; - } else { - TkWindow *winPtr2, **winPtr2Ptr = &winPtr2; - int index1 = -1, index2 = -1, result; - - if (TkGetWindowFromObj(interp, tkwin, objv[4], - (Tk_Window *) winPtr2Ptr) != TCL_OK) { - return TCL_ERROR; - } - - if (!Tk_IsTopLevel(winPtr2)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't a top-level window", - winPtr2->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "TOPLEVEL", NULL); - return TCL_ERROR; - } - - if (!Tk_IsMapped(winPtr)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't mapped", winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL); - return TCL_ERROR; - } - - if (!Tk_IsMapped(winPtr2)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't mapped", winPtr2->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL); - return TCL_ERROR; - } - - /* - * Lookup stacking order of all toplevels that are children of "." and - * find the position of winPtr and winPtr2 in the stacking order. - */ - - windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr); - if (windows == NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "TkWmStackorderToplevel failed", -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL); - return TCL_ERROR; - } - - for (windowPtr = windows; *windowPtr ; windowPtr++) { - if (*windowPtr == winPtr) { - index1 = (windowPtr - windows); - } - if (*windowPtr == winPtr2) { - index2 = (windowPtr - windows); - } - } - if (index1 == -1) { - Tcl_Panic("winPtr window not found"); - } else if (index2 == -1) { - Tcl_Panic("winPtr2 window not found"); - } - - ckfree(windows); - - if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings, - sizeof(char *), "argument", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_ISABOVE) { - result = index1 > index2; - } else { /* OPT_ISBELOW */ - result = index1 < index2; - } - Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result)); - return TCL_OK; - } -} - -/* - *---------------------------------------------------------------------- - * - * WmStateCmd -- - * - * This function is invoked to process the "wm state" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmStateCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *const optionStrings[] = { - "normal", "iconic", "withdrawn", "zoomed", NULL - }; - enum options { - OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED - }; - int index; - - if ((objc < 3) || (objc > 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?state?"); - return TCL_ERROR; - } - if (objc == 4) { - if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't change state of %s: it is an icon for %s", - Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "ICON", NULL); - return TCL_ERROR; - } - if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings, - sizeof(char *), "argument", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - - if (winPtr->flags & TK_EMBEDDED) { - int state = 0; - - switch (index) { - case OPT_NORMAL: - state = NormalState; - break; - case OPT_ICONIC: - state = IconicState; - break; - case OPT_WITHDRAWN: - state = WithdrawnState; - break; - case OPT_ZOOMED: - state = ZoomState; - break; - default: - Tcl_Panic("unexpected index"); - } - - if (state+1 != SendMessage(wmPtr->wrapper, TK_STATE, state, 0)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't change state of %s: the container does not support the request", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL); - return TCL_ERROR; - } - return TCL_OK; - } - - if (index == OPT_NORMAL) { - wmPtr->flags &= ~WM_WITHDRAWN; - TkpWmSetState(winPtr, NormalState); - - /* - * This varies from 'wm deiconify' because it does not force the - * window to be raised and receive focus. - */ - } else if (index == OPT_ICONIC) { - if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify \"%s\": override-redirect flag is set", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STATE", - "OVERRIDE_REDIRECT", NULL); - return TCL_ERROR; - } - if (wmPtr->masterPtr != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify \"%s\": it is a transient", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "TRANSIENT", - NULL); - return TCL_ERROR; - } - TkpWmSetState(winPtr, IconicState); - } else if (index == OPT_WITHDRAWN) { - wmPtr->flags |= WM_WITHDRAWN; - TkpWmSetState(winPtr, WithdrawnState); - } else if (index == OPT_ZOOMED) { - TkpWmSetState(winPtr, ZoomState); - } else { - Tcl_Panic("wm state not matched"); - } - } else { - const char *stateStr = ""; - - if (wmPtr->iconFor != NULL) { - stateStr = "icon"; - } else { - int state; - - if (winPtr->flags & TK_EMBEDDED) { - state = SendMessage(wmPtr->wrapper, TK_STATE, -1, -1) - 1; - } else { - state = wmPtr->hints.initial_state; - } - switch (state) { - case NormalState: stateStr = "normal"; break; - case IconicState: stateStr = "iconic"; break; - case WithdrawnState: stateStr = "withdrawn"; break; - case ZoomState: stateStr = "zoomed"; break; - } - } - Tcl_SetObjResult(interp, Tcl_NewStringObj(stateStr, -1)); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmTitleCmd -- - * - * This function is invoked to process the "wm title" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmTitleCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - const char *argv3; - size_t length; - HWND wrapper; - - if (objc > 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?"); - return TCL_ERROR; - } - - if (winPtr->flags & TK_EMBEDDED) { - wrapper = (HWND) SendMessage(wmPtr->wrapper, TK_GETFRAMEWID, 0, 0); - } else { - wrapper = wmPtr->wrapper; - } - if (objc == 3) { - if (wrapper) { - TCHAR buf[256]; - Tcl_DString titleString; - int size = 256; - - GetWindowText(wrapper, buf, size); - Tcl_WinTCharToUtf(buf, -1, &titleString); - Tcl_SetObjResult(interp, Tcl_NewStringObj( - Tcl_DStringValue(&titleString), - Tcl_DStringLength(&titleString))); - Tcl_DStringFree(&titleString); - } else { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - (wmPtr->title ? wmPtr->title : winPtr->nameUid), -1)); - } - } else { - if (wmPtr->title != NULL) { - ckfree(wmPtr->title); - } - argv3 = Tcl_GetString(objv[3]); - length = objv[3]->length; - wmPtr->title = ckalloc(length + 1); - memcpy(wmPtr->title, argv3, length + 1); - - if (!(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper != NULL) { - Tcl_DString titleString; - - Tcl_WinUtfToTChar(wmPtr->title, -1, &titleString); - SetWindowText(wrapper, (LPCTSTR) Tcl_DStringValue(&titleString)); - Tcl_DStringFree(&titleString); - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmTransientCmd -- - * - * This function is invoked to process the "wm transient" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmTransientCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - TkWindow *masterPtr = wmPtr->masterPtr, **masterPtrPtr = &masterPtr; - WmInfo *wmPtr2; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?master?"); - return TCL_ERROR; - } - if (objc == 3) { - if (masterPtr != NULL) { - Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) masterPtr)); - } - return TCL_OK; - } - if (Tcl_GetString(objv[3])[0] == '\0') { - if (masterPtr != NULL) { - /* - * If we had a master, tell them that we aren't tied to them - * anymore. - */ - - masterPtr->wmInfoPtr->numTransients--; - Tk_DeleteEventHandler((Tk_Window) masterPtr, - VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, winPtr); - } - - wmPtr->masterPtr = NULL; - } else { - if (TkGetWindowFromObj(interp, tkwin, objv[3], - (Tk_Window *) masterPtrPtr) != TCL_OK) { - return TCL_ERROR; - } - while (!Tk_TopWinHierarchy(masterPtr)) { - /* - * Ensure that the master window is actually a Tk toplevel. - */ - - masterPtr = masterPtr->parentPtr; - } - Tk_MakeWindowExist((Tk_Window) masterPtr); - - if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't make \"%s\" a transient: it is an icon for %s", - Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL); - return TCL_ERROR; - } - - wmPtr2 = masterPtr->wmInfoPtr; - - if (wmPtr2->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't make \"%s\" a master: it is an icon for %s", - Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL); - return TCL_ERROR; - } - - if (masterPtr == winPtr) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't make \"%s\" its own master", Tk_PathName(winPtr))); - Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL); - return TCL_ERROR; - } else if (masterPtr != wmPtr->masterPtr) { - /* - * Remove old master map/unmap binding before setting the new - * master. The event handler will ensure that transient states - * reflect the state of the master. - */ - - if (wmPtr->masterPtr != NULL) { - wmPtr->masterPtr->wmInfoPtr->numTransients--; - Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr, - VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, winPtr); - } - - masterPtr->wmInfoPtr->numTransients++; - Tk_CreateEventHandler((Tk_Window) masterPtr, - VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, winPtr); - - wmPtr->masterPtr = masterPtr; - } - } - if (!((wmPtr->flags & WM_NEVER_MAPPED) - && !(winPtr->flags & TK_EMBEDDED))) { - if (wmPtr->masterPtr != NULL - && !Tk_IsMapped(wmPtr->masterPtr)) { - TkpWmSetState(winPtr, WithdrawnState); - } else { - UpdateWrapper(winPtr); - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmWithdrawCmd -- - * - * This function is invoked to process the "wm withdraw" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmWithdrawCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't withdraw %s: it is an icon for %s", - Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL); - return TCL_ERROR; - } - - if (winPtr->flags & TK_EMBEDDED) { - if (SendMessage(wmPtr->wrapper, TK_WITHDRAW, 0, 0) < 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't withdraw %s: the container does not support the request", - Tcl_GetString(objv[2]))); - Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL); - return TCL_ERROR; - } - } else { - wmPtr->flags |= WM_WITHDRAWN; - TkpWmSetState(winPtr, WithdrawnState); - } - return TCL_OK; -} - -/* - * Invoked by those wm subcommands that affect geometry. Schedules a geometry - * update. - */ - -static void -WmUpdateGeom( - WmInfo *wmPtr, - TkWindow *winPtr) -{ - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } -} - - /*ARGSUSED*/ -static void -WmWaitVisibilityOrMapProc( - ClientData clientData, /* Pointer to window. */ - XEvent *eventPtr) /* Information about event. */ -{ - TkWindow *winPtr = clientData; - TkWindow *masterPtr = winPtr->wmInfoPtr->masterPtr; - - if (masterPtr == NULL) - return; - - if (eventPtr->type == MapNotify) { - if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN)) { - TkpWmSetState(winPtr, NormalState); - } - } else if (eventPtr->type == UnmapNotify) { - TkpWmSetState(winPtr, WithdrawnState); - } - - if (eventPtr->type == VisibilityNotify) { - int state = masterPtr->wmInfoPtr->hints.initial_state; - - if ((state == NormalState) || (state == ZoomState)) { - state = winPtr->wmInfoPtr->hints.initial_state; - if ((state == NormalState) || (state == ZoomState)) { - UpdateWrapper(winPtr); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_SetGrid -- - * - * 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 associated with the -setgrid option. - * - * Results: - * None. - * - * Side effects: - * Grid-related information will be passed to the window manager, so that - * the top-level window associated with tkwin will resize on even grid - * units. If some other window already controls gridding for the - * top-level window then this function call has no effect. - * - *---------------------------------------------------------------------- - */ - -void -Tk_SetGrid( - Tk_Window tkwin, /* Token for window. New window mgr info will - * be posted for the top-level window - * associated with this window. */ - int reqWidth, /* Width (in grid units) corresponding to the - * requested geometry for tkwin. */ - int reqHeight, /* Height (in grid units) corresponding to the - * requested geometry for tkwin. */ - int widthInc, int heightInc)/* Pixel increments corresponding to a change - * of one grid unit. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - register WmInfo *wmPtr; - - /* - * Ensure widthInc and heightInc are greater than 0 - */ - - if (widthInc <= 0) { - widthInc = 1; - } - if (heightInc <= 0) { - heightInc = 1; - } - - /* - * Find the top-level window for tkwin, plus the window manager - * information. - */ - - while (!(winPtr->flags & TK_TOP_HIERARCHY)) { - winPtr = winPtr->parentPtr; - } - wmPtr = winPtr->wmInfoPtr; - if (wmPtr == NULL) { - return; - } - - if ((wmPtr->gridWin != NULL) && (wmPtr->gridWin != tkwin)) { - return; - } - - if ((wmPtr->reqGridWidth == reqWidth) - && (wmPtr->reqGridHeight == reqHeight) - && (wmPtr->widthInc == widthInc) - && (wmPtr->heightInc == heightInc) - && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc)) - == (PBaseSize|PResizeInc))) { - return; - } - - /* - * If gridding was previously off, then forget about any window size - * requests made by the user or via "wm geometry": these are in pixel - * units and there's no easy way to translate them to grid units since the - * new requested size of the top-level window in pixels may not yet have - * been registered yet (it may filter up the hierarchy in DoWhenIdle - * handlers). However, if the window has never been mapped yet then just - * leave the window size alone: assume that it is intended to be in grid - * units but just happened to have been specified before this function was - * called. - */ - - if ((wmPtr->gridWin == NULL) && !(wmPtr->flags & WM_NEVER_MAPPED)) { - wmPtr->width = -1; - wmPtr->height = -1; - } - - /* - * Set the new gridding information, and start the process of passing all - * of this information to the window manager. - */ - - wmPtr->gridWin = tkwin; - wmPtr->reqGridWidth = reqWidth; - wmPtr->reqGridHeight = reqHeight; - wmPtr->widthInc = widthInc; - wmPtr->heightInc = heightInc; - wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc; - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_UnsetGrid -- - * - * This function cancels the effect of a previous call to Tk_SetGrid. - * - * Results: - * None. - * - * Side effects: - * If tkwin currently controls gridding for its top-level window, - * gridding is cancelled for that top-level window; if some other window - * controls gridding then this function has no effect. - * - *---------------------------------------------------------------------- - */ - -void -Tk_UnsetGrid( - Tk_Window tkwin) /* Token for window that is currently - * controlling gridding. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - register WmInfo *wmPtr; - - /* - * Find the top-level window for tkwin, plus the window manager - * information. - */ - - while (!(winPtr->flags & TK_TOP_HIERARCHY)) { - winPtr = winPtr->parentPtr; - } - wmPtr = winPtr->wmInfoPtr; - if (wmPtr == NULL) { - return; - } - - if (tkwin != wmPtr->gridWin) { - return; - } - - wmPtr->gridWin = NULL; - wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc); - if (wmPtr->width != -1) { - wmPtr->width = winPtr->reqWidth + (wmPtr->width - - wmPtr->reqGridWidth)*wmPtr->widthInc; - wmPtr->height = winPtr->reqHeight + (wmPtr->height - - wmPtr->reqGridHeight)*wmPtr->heightInc; - } - wmPtr->widthInc = 1; - wmPtr->heightInc = 1; - - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * TopLevelEventProc -- - * - * This function is invoked when a top-level (or other externally-managed - * window) is restructured in any way. - * - * Results: - * None. - * - * Side effects: - * Tk's internal data structures for the window get modified to reflect - * the structural change. - * - *---------------------------------------------------------------------- - */ - -static void -TopLevelEventProc( - ClientData clientData, /* Window for which event occurred. */ - XEvent *eventPtr) /* Event that just happened. */ -{ - register TkWindow *winPtr = clientData; - - if (eventPtr->type == DestroyNotify) { - Tk_ErrorHandler handler; - - if (!(winPtr->flags & TK_ALREADY_DEAD)) { - /* - * A top-level window was deleted externally (e.g., by the window - * manager). This is probably not a good thing, but cleanup as - * best we can. The error handler is needed because - * Tk_DestroyWindow will try to destroy the window, but of course - * it's already gone. - */ - - handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, - NULL, NULL); - Tk_DestroyWindow((Tk_Window) winPtr); - Tk_DeleteErrorHandler(handler); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TopLevelReqProc -- - * - * This function is invoked by the geometry manager whenever the - * requested size for a top-level window is changed. - * - * Results: - * None. - * - * Side effects: - * Arrange for the window to be resized to satisfy the request (this - * happens as a when-idle action). - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -static void -TopLevelReqProc( - ClientData dummy, /* Not used. */ - Tk_Window tkwin) /* Information about window. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - WmInfo *wmPtr; - - wmPtr = winPtr->wmInfoPtr; - if (wmPtr) { - if ((winPtr->flags & TK_EMBEDDED) && (wmPtr->wrapper != NULL)) { - SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin), - Tk_ReqHeight(tkwin)); - } - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * UpdateGeometryInfo -- - * - * This function is invoked when a top-level window is first mapped, and - * also as a when-idle function, to bring the geometry and/or position of - * a top-level window back into line with what has been requested by the - * user and/or widgets. This function doesn't return until the system has - * responded to the geometry change. - * - * Results: - * None. - * - * Side effects: - * The window's size and location may change, unless the WM prevents that - * from happening. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateGeometryInfo( - ClientData clientData) /* Pointer to the window's record. */ -{ - int x, y; /* Position of border on desktop. */ - int width, height; /* Size of client area. */ - int min, max; - RECT rect; - register TkWindow *winPtr = clientData; - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - wmPtr->flags &= ~WM_UPDATE_PENDING; - - /* - * If the window is minimized or maximized, we should not update our - * geometry since it will end up with the wrong values. ConfigureToplevel - * will reschedule UpdateGeometryInfo when the state of the window - * changes. - */ - - if (wmPtr->wrapper && (IsIconic(wmPtr->wrapper) || - IsZoomed(wmPtr->wrapper) || (wmPtr->flags & WM_FULLSCREEN))) { - return; - } - - /* - * Compute the border size for the current window style. This size will - * include the resize handles, the title bar and the menubar. Note that - * this size will not be correct if the menubar spans multiple lines. The - * height will be off by a multiple of the menubar height. It really only - * measures the minimum size of the border. - */ - - rect.left = rect.right = rect.top = rect.bottom = 0; - AdjustWindowRectEx(&rect, wmPtr->style, wmPtr->hMenu != NULL, - wmPtr->exStyle); - wmPtr->borderWidth = rect.right - rect.left; - wmPtr->borderHeight = rect.bottom - rect.top; - - /* - * Compute the new size for the top-level window. See the user - * documentation for details on this, but the size requested depends on - * (a) the size requested internally by the window's widgets, (b) the size - * requested by the user in a "wm geometry" command or via wm-based - * interactive resizing (if any), (c) whether or not the window is - * gridded, and (d) the current min or max size for the toplevel. Don't - * permit sizes <= 0 because this upsets the X server. - */ - - if (wmPtr->width == -1) { - width = winPtr->reqWidth; - } else if (wmPtr->gridWin != NULL) { - width = winPtr->reqWidth - + (wmPtr->width - wmPtr->reqGridWidth)*wmPtr->widthInc; - } else { - width = wmPtr->width; - } - if (width <= 0) { - width = 1; - } - - /* - * Account for window max/min width - */ - - if (wmPtr->gridWin != NULL) { - min = winPtr->reqWidth - + (wmPtr->minWidth - wmPtr->reqGridWidth)*wmPtr->widthInc; - if (wmPtr->maxWidth > 0) { - max = winPtr->reqWidth - + (wmPtr->maxWidth - wmPtr->reqGridWidth)*wmPtr->widthInc; - } else { - max = 0; - } - } else { - min = wmPtr->minWidth; - max = wmPtr->maxWidth; - } - if (width < min) { - width = min; - } else if ((max > 0) && (width > max)) { - width = max; - } - - if (wmPtr->height == -1) { - height = winPtr->reqHeight; - } else if (wmPtr->gridWin != NULL) { - height = winPtr->reqHeight - + (wmPtr->height - wmPtr->reqGridHeight)*wmPtr->heightInc; - } else { - height = wmPtr->height; - } - if (height <= 0) { - height = 1; - } - - /* - * Account for window max/min height - */ - - if (wmPtr->gridWin != NULL) { - min = winPtr->reqHeight - + (wmPtr->minHeight - wmPtr->reqGridHeight)*wmPtr->heightInc; - if (wmPtr->maxHeight > 0) { - max = winPtr->reqHeight - + (wmPtr->maxHeight-wmPtr->reqGridHeight)*wmPtr->heightInc; - } else { - max = 0; - } - } else { - min = wmPtr->minHeight; - max = wmPtr->maxHeight; - } - if (height < min) { - height = min; - } else if ((max > 0) && (height > max)) { - height = max; - } - - /* - * Compute the new position for the upper-left pixel of the window's - * decorative frame. This is tricky, because we need to include the border - * widths supplied by a reparented parent in this calculation, but can't - * use the parent's current overall size since that may change as a result - * of this code. - */ - - if (wmPtr->flags & WM_NEGATIVE_X) { - x = DisplayWidth(winPtr->display, winPtr->screenNum) - wmPtr->x - - (width + wmPtr->borderWidth); - } else { - x = wmPtr->x; - } - if (wmPtr->flags & WM_NEGATIVE_Y) { - y = DisplayHeight(winPtr->display, winPtr->screenNum) - wmPtr->y - - (height + wmPtr->borderHeight); - } else { - y = wmPtr->y; - } - - /* - * Reconfigure the window if it isn't already configured correctly. Base - * the size check on what we *asked for* last time, not what we got. - * Return immediately if there have been no changes in the requested - * geometry of the toplevel. - */ - - /* TODO: need to add flag for possible menu size change */ - - if (!(wmPtr->flags & WM_MOVE_PENDING) - && (width == wmPtr->configWidth) - && (height == wmPtr->configHeight)) { - return; - } - wmPtr->flags &= ~WM_MOVE_PENDING; - - wmPtr->configWidth = width; - wmPtr->configHeight = height; - - /* - * Don't bother moving the window if we are in the process of creating it. - * Just update the geometry info based on what we asked for. - */ - - if (wmPtr->flags & WM_CREATE_PENDING) { - winPtr->changes.x = x; - winPtr->changes.y = y; - winPtr->changes.width = width; - winPtr->changes.height = height; - return; - } - - wmPtr->flags |= WM_SYNC_PENDING; - if (winPtr->flags & TK_EMBEDDED) { - /* - * The wrapper window is in a different process, so we need to send it - * a geometry request. This protocol assumes that the other process - * understands this Tk message, otherwise our requested geometry will - * be ignored. - */ - - SendMessage(wmPtr->wrapper, TK_MOVEWINDOW, x, y); - SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, width, height); - } else { - int reqHeight, reqWidth; - RECT windowRect; - int menuInc = GetSystemMetrics(SM_CYMENU); - int newHeight; - - /* - * We have to keep resizing the window until we get the requested - * height in the client area. If the client area has zero height, then - * the window rect is too small by definition. Try increasing the - * border height and try again. Once we have a positive size, then we - * can adjust the height exactly. If the window rect comes back - * smaller than we requested, we have hit the maximum constraints that - * Windows imposes. Once we find a positive client size, the next size - * is the one we try no matter what. - */ - - reqHeight = height + wmPtr->borderHeight; - reqWidth = width + wmPtr->borderWidth; - - while (1) { - MoveWindow(wmPtr->wrapper, x, y, reqWidth, reqHeight, TRUE); - GetWindowRect(wmPtr->wrapper, &windowRect); - newHeight = windowRect.bottom - windowRect.top; - - /* - * If the request wasn't satisfied, we have hit an external - * constraint and must stop. - */ - - if (newHeight < reqHeight) { - break; - } - - /* - * Now check the size of the client area against our ideal. - */ - - GetClientRect(wmPtr->wrapper, &windowRect); - newHeight = windowRect.bottom - windowRect.top; - - if (newHeight == height) { - /* - * We're done. - */ - - break; - } else if (newHeight > height) { - /* - * One last resize to get rid of the extra space. - */ - - menuInc = newHeight - height; - reqHeight -= menuInc; - if (wmPtr->flags & WM_NEGATIVE_Y) { - y += menuInc; - } - MoveWindow(wmPtr->wrapper, x, y, reqWidth, reqHeight, TRUE); - break; - } - - /* - * We didn't get enough space to satisfy our requested height, so - * the menu must have wrapped. Increase the size of the window by - * one menu height and move the window if it is positioned - * relative to the lower right corner of the screen. - */ - - reqHeight += menuInc; - if (wmPtr->flags & WM_NEGATIVE_Y) { - y -= menuInc; - } - } - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - DrawMenuBar(wmPtr->wrapper); - } - } - wmPtr->flags &= ~WM_SYNC_PENDING; -} - -/* - *-------------------------------------------------------------- - * - * ParseGeometry -- - * - * This function parses a geometry string and updates information used to - * control the geometry of a top-level window. - * - * Results: - * A standard Tcl return value, plus an error message in the interp's - * result if an error occurs. - * - * Side effects: - * The size and/or location of winPtr may change. - * - *-------------------------------------------------------------- - */ - -static int -ParseGeometry( - Tcl_Interp *interp, /* Used for error reporting. */ - const char *string, /* String containing new geometry. Has the - * standard form "=wxh+x+y". */ - TkWindow *winPtr) /* Pointer to top-level window whose geometry - * is to be changed. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int x, y, width, height, flags; - char *end; - register const char *p = string; - - /* - * The leading "=" is optional. - */ - - if (*p == '=') { - p++; - } - - /* - * Parse the width and height, if they are present. Don't actually update - * any of the fields of wmPtr until we've successfully parsed the entire - * geometry string. - */ - - width = wmPtr->width; - height = wmPtr->height; - x = wmPtr->x; - y = wmPtr->y; - flags = wmPtr->flags; - if (isdigit(UCHAR(*p))) { - width = strtoul(p, &end, 10); - p = end; - if (*p != 'x') { - goto error; - } - p++; - if (!isdigit(UCHAR(*p))) { - goto error; - } - height = strtoul(p, &end, 10); - p = end; - } - - /* - * Parse the X and Y coordinates, if they are present. - */ - - if (*p != '\0') { - flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y); - if (*p == '-') { - flags |= WM_NEGATIVE_X; - } else if (*p != '+') { - goto error; - } - p++; - if (!isdigit(UCHAR(*p)) && (*p != '-')) { - goto error; - } - x = strtol(p, &end, 10); - p = end; - if (*p == '-') { - flags |= WM_NEGATIVE_Y; - } else if (*p != '+') { - goto error; - } - p++; - if (!isdigit(UCHAR(*p)) && (*p != '-')) { - goto error; - } - y = strtol(p, &end, 10); - if (*end != '\0') { - goto error; - } - - /* - * Assume that the geometry information came from the user, unless an - * explicit source has been specified. Otherwise most window managers - * assume that the size hints were program-specified and they ignore - * them. - */ - - if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) { - wmPtr->sizeHintsFlags |= USPosition; - } - } - - /* - * Everything was parsed OK. Update the fields of *wmPtr and arrange for - * the appropriate information to be percolated out to the window manager - * at the next idle moment. - */ - - wmPtr->width = width; - wmPtr->height = height; - wmPtr->x = x; - wmPtr->y = y; - flags |= WM_MOVE_PENDING; - wmPtr->flags = flags; - - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } - return TCL_OK; - - error: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad geometry specifier \"%s\"", string)); - Tcl_SetErrorCode(interp, "TK", "VALUE", "GEOMETRY", NULL); - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetRootCoords -- - * - * Given a token for a window, this function traces through the window's - * lineage to find the (virtual) root-window coordinates corresponding to - * point (0,0) in the window. - * - * Results: - * The locations pointed to by xPtr and yPtr are filled in with the root - * coordinates of the (0,0) point in tkwin. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -Tk_GetRootCoords( - Tk_Window tkwin, /* Token for window. */ - int *xPtr, /* Where to store x-displacement of (0,0). */ - int *yPtr) /* Where to store y-displacement of (0,0). */ -{ - register TkWindow *winPtr = (TkWindow *) tkwin; - - /* - * If the window is mapped, let Windows figure out the translation. - */ - - if (winPtr->window != None) { - HWND hwnd = Tk_GetHWND(winPtr->window); - POINT point; - - point.x = 0; - point.y = 0; - - ClientToScreen(hwnd, &point); - - *xPtr = point.x; - *yPtr = point.y; - } else { - *xPtr = 0; - *yPtr = 0; - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_CoordsToWindow -- - * - * Given the (virtual) root coordinates of a point, this function returns - * the token for the top-most window covering that point, if there exists - * such a window in this application. - * - * Results: - * The return result is either a token for the window corresponding to - * rootX and rootY, or else NULL to indicate that there is no such - * window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tk_Window -Tk_CoordsToWindow( - int rootX, int rootY, /* Coordinates of point in root window. If a - * virtual-root window manager is in use, - * these coordinates refer to the virtual - * root, not the real root. */ - Tk_Window tkwin) /* Token for any window in application; used - * to identify the display. */ -{ - POINT pos; - HWND hwnd; - TkWindow *winPtr; - - pos.x = rootX; - pos.y = rootY; - hwnd = WindowFromPoint(pos); - - winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); - if (winPtr && (winPtr->mainPtr == ((TkWindow *) tkwin)->mainPtr)) { - return (Tk_Window) winPtr; - } - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetVRootGeometry -- - * - * This function returns information about the virtual root window - * corresponding to a particular Tk window. - * - * Results: - * The values at xPtr, yPtr, widthPtr, and heightPtr are set with the - * offset and dimensions of the root window corresponding to tkwin. If - * tkwin is being managed by a virtual root window manager these values - * correspond to the virtual root window being used for tkwin; otherwise - * the offsets will be 0 and the dimensions will be those of the screen. - * - * Side effects: - * Vroot window information is refreshed if it is out of date. - * - *---------------------------------------------------------------------- - */ - -void -Tk_GetVRootGeometry( - Tk_Window tkwin, /* Window whose virtual root is to be - * queried. */ - int *xPtr, int *yPtr, /* Store x and y offsets of virtual root - * here. */ - int *widthPtr, int *heightPtr) - /* Store dimensions of virtual root here. */ -{ - *xPtr = GetSystemMetrics(SM_XVIRTUALSCREEN); - *yPtr = GetSystemMetrics(SM_YVIRTUALSCREEN); - *widthPtr = GetSystemMetrics(SM_CXVIRTUALSCREEN); - *heightPtr = GetSystemMetrics(SM_CYVIRTUALSCREEN); -} - -/* - *---------------------------------------------------------------------- - * - * Tk_MoveToplevelWindow -- - * - * This function is called instead of Tk_MoveWindow to adjust the x-y - * location of a top-level window. It delays the actual move to a later - * time and keeps window-manager information up-to-date with the move - * - * Results: - * None. - * - * Side effects: - * The window is eventually moved so that its upper-left corner - * (actually, the upper-left corner of the window's decorative frame, if - * there is one) is at (x,y). - * - *---------------------------------------------------------------------- - */ - -void -Tk_MoveToplevelWindow( - Tk_Window tkwin, /* Window to move. */ - int x, int y) /* New location for window (within parent). */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (!(winPtr->flags & TK_TOP_LEVEL)) { - Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window"); - } - wmPtr->x = x; - wmPtr->y = y; - wmPtr->flags |= WM_MOVE_PENDING; - wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y); - if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) { - wmPtr->sizeHintsFlags |= USPosition; - } - - /* - * If the window has already been mapped, must bring its geometry - * up-to-date immediately, otherwise an event might arrive from the server - * that would overwrite wmPtr->x and wmPtr->y and lose the new position. - */ - - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - if (wmPtr->flags & WM_UPDATE_PENDING) { - Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr); - } - UpdateGeometryInfo(winPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWmProtocolEventProc -- - * - * This function is called by the Tk_HandleEvent whenever a ClientMessage - * event arrives whose type is "WM_PROTOCOLS". This function handles the - * message from the window manager in an appropriate fashion. - * - * Results: - * None. - * - * Side effects: - * Depends on what sort of handler, if any, was set up for the protocol. - * - *---------------------------------------------------------------------- - */ - -void -TkWmProtocolEventProc( - TkWindow *winPtr, /* Window to which the event was sent. */ - XEvent *eventPtr) /* X event. */ -{ - WmInfo *wmPtr; - register ProtocolHandler *protPtr; - Atom protocol; - int result; - Tcl_Interp *interp; - - wmPtr = winPtr->wmInfoPtr; - if (wmPtr == NULL) { - return; - } - protocol = (Atom) eventPtr->xclient.data.l[0]; - for (protPtr = wmPtr->protPtr; protPtr != NULL; - protPtr = protPtr->nextPtr) { - if (protocol == protPtr->protocol) { - /* - * Cache atom name, as we might destroy the window as a result of - * the eval. - */ - - const char *name = Tk_GetAtomName((Tk_Window) winPtr, protocol); - - Tcl_Preserve(protPtr); - interp = protPtr->interp; - Tcl_Preserve(interp); - result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL); - if (result != TCL_OK) { - Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( - "\n (command for \"%s\" window manager protocol)", - name)); - Tcl_BackgroundException(interp, result); - } - Tcl_Release(interp); - Tcl_Release(protPtr); - return; - } - } - - /* - * No handler was present for this protocol. If this is a WM_DELETE_WINDOW - * message then just destroy the window. - */ - - if (protocol == Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW")) { - Tk_DestroyWindow((Tk_Window) winPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWmStackorderToplevelEnumProc -- - * - * This function is invoked once for each HWND Window on the display as a - * result of calling EnumWindows from TkWmStackorderToplevel. - * - * Results: - * TRUE to request further iteration. - * - * Side effects: - * Adds entries to the passed array of TkWindows. - * - *---------------------------------------------------------------------- - */ - -BOOL CALLBACK -TkWmStackorderToplevelEnumProc( - HWND hwnd, /* Handle to parent window */ - LPARAM lParam) /* Application-defined value */ -{ - Tcl_HashEntry *hPtr; - TkWindow *childWinPtr; - - TkWmStackorderToplevelPair *pair = - (TkWmStackorderToplevelPair *) lParam; - - /*fprintf(stderr, "Looking up HWND %d\n", hwnd);*/ - - hPtr = Tcl_FindHashEntry(pair->table, (char *) hwnd); - if (hPtr != NULL) { - childWinPtr = Tcl_GetHashValue(hPtr); - - /* - * Double check that same HWND does not get passed twice. - */ - - if (childWinPtr == NULL) { - Tcl_Panic("duplicate HWND in TkWmStackorderToplevelEnumProc"); - } else { - Tcl_SetHashValue(hPtr, NULL); - } - /* - fprintf(stderr, "Found mapped HWND %d -> %x (%s)\n", hwnd, - childWinPtr, childWinPtr->pathName); - */ - *(pair->windowPtr)-- = childWinPtr; - } - return TRUE; -} - -/* - *---------------------------------------------------------------------- - * - * TkWmStackorderToplevelWrapperMap -- - * - * This function will create a table that maps the wrapper HWND id for a - * toplevel to the TkWindow structure that is wraps. - * - * Results: - * None. - * - * Side effects: - * Adds entries to the passed hashtable. - * - *---------------------------------------------------------------------- - */ - -static void -TkWmStackorderToplevelWrapperMap( - TkWindow *winPtr, /* TkWindow to recurse on */ - Display *display, /* X display of parent window */ - Tcl_HashTable *table) /* Table to maps HWND to TkWindow */ -{ - TkWindow *childPtr; - Tcl_HashEntry *hPtr; - HWND wrapper; - int newEntry; - - if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) - && !Tk_IsEmbedded(winPtr) && (winPtr->display == display)) { - wrapper = TkWinGetWrapperWindow((Tk_Window) winPtr); - - /* - fprintf(stderr, "Mapped HWND %d to %x (%s)\n", wrapper, - winPtr, winPtr->pathName); - */ - - hPtr = Tcl_CreateHashEntry(table, (char *) wrapper, &newEntry); - Tcl_SetHashValue(hPtr, winPtr); - } - - for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - TkWmStackorderToplevelWrapperMap(childPtr, display, table); - } -} -/* - *---------------------------------------------------------------------- - * - * TkWmStackorderToplevel -- - * - * This function returns the stack order of toplevel windows. - * - * Results: - * An array of pointers to tk window objects in stacking order or else - * NULL if there was an error. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TkWindow ** -TkWmStackorderToplevel( - TkWindow *parentPtr) /* Parent toplevel window. */ -{ - TkWmStackorderToplevelPair pair; - TkWindow **windows; - Tcl_HashTable table; - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - - /* - * Map HWND ids to a TkWindow of the wrapped toplevel. - */ - - Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS); - TkWmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table); - - windows = ckalloc((table.numEntries+1) * sizeof(TkWindow *)); - - /* - * Special cases: If zero or one toplevels were mapped there is no need to - * call EnumWindows. - */ - - switch (table.numEntries) { - case 0: - windows[0] = NULL; - goto done; - case 1: - hPtr = Tcl_FirstHashEntry(&table, &search); - windows[0] = Tcl_GetHashValue(hPtr); - windows[1] = NULL; - goto done; - } - - /* - * We will be inserting into the array starting at the end and working our - * way to the beginning since EnumWindows returns windows in highest to - * lowest order. - */ - - pair.table = &table; - pair.windowPtr = windows + table.numEntries; - *pair.windowPtr-- = NULL; - - if (EnumWindows((WNDENUMPROC) TkWmStackorderToplevelEnumProc, - (LPARAM) &pair) == 0) { - ckfree(windows); - windows = NULL; - } else if (pair.windowPtr != (windows-1)) { - Tcl_Panic("num matched toplevel windows does not equal num children"); - } - - done: - Tcl_DeleteHashTable(&table); - return windows; -} - -/* - *---------------------------------------------------------------------- - * - * TkWmRestackToplevel -- - * - * This function restacks a top-level window. - * - * Results: - * None. - * - * Side effects: - * WinPtr gets restacked as specified by aboveBelow and otherPtr. This - * function doesn't return until the restack has taken effect and the - * ConfigureNotify event for it has been received. - * - *---------------------------------------------------------------------- - */ - -void -TkWmRestackToplevel( - TkWindow *winPtr, /* Window to restack. */ - int aboveBelow, /* Gives relative position for restacking; - * must be Above or Below. */ - TkWindow *otherPtr) /* Window relative to which to restack; if - * NULL, then winPtr gets restacked above or - * below *all* siblings. */ -{ - HWND hwnd, insertAfter; - - /* - * Can't set stacking order properly until the window is on the screen - * (mapping it may give it a reparent window). - */ - - if (winPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); - } - if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { - TkWmMapWindow(winPtr); - } - hwnd = (winPtr->wmInfoPtr->wrapper != NULL) - ? winPtr->wmInfoPtr->wrapper : Tk_GetHWND(winPtr->window); - - if (otherPtr != NULL) { - if (otherPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) otherPtr); - } - if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { - TkWmMapWindow(otherPtr); - } - insertAfter = (otherPtr->wmInfoPtr->wrapper != NULL) - ? otherPtr->wmInfoPtr->wrapper : Tk_GetHWND(otherPtr->window); - } else { - insertAfter = NULL; - } - - if (winPtr->flags & TK_EMBEDDED) { - SendMessage(winPtr->wmInfoPtr->wrapper, TK_RAISEWINDOW, - (WPARAM) insertAfter, aboveBelow); - } else { - TkWinSetWindowPos(hwnd, insertAfter, aboveBelow); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWmAddToColormapWindows -- - * - * This function is called to add a given window to the - * WM_COLORMAP_WINDOWS property for its top-level, if it isn't already - * there. It is invoked by the Tk code that creates a new colormap, in - * order to make sure that colormap information is propagated to the - * window manager by default. - * - * Results: - * None. - * - * Side effects: - * WinPtr's window gets added to the WM_COLORMAP_WINDOWS property of its - * nearest top-level ancestor, unless the colormaps have been set - * explicitly with the "wm colormapwindows" command. - * - *---------------------------------------------------------------------- - */ - -void -TkWmAddToColormapWindows( - TkWindow *winPtr) /* Window with a non-default colormap. Should - * not be a top-level window. */ -{ - TkWindow *topPtr; - TkWindow **oldPtr, **newPtr; - int count, i; - - if (winPtr->window == None) { - return; - } - - for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) { - if (topPtr == NULL) { - /* - * Window is being deleted. Skip the whole operation. - */ - - return; - } - if (topPtr->flags & TK_TOP_HIERARCHY) { - break; - } - } - if (topPtr->wmInfoPtr == NULL) { - return; - } - - if (topPtr->wmInfoPtr->flags & WM_COLORMAPS_EXPLICIT) { - return; - } - - /* - * Make sure that the window isn't already in the list. - */ - - count = topPtr->wmInfoPtr->cmapCount; - oldPtr = topPtr->wmInfoPtr->cmapList; - - for (i = 0; i < count; i++) { - if (oldPtr[i] == winPtr) { - return; - } - } - - /* - * Make a new bigger array and use it to reset the property. - * Automatically add the toplevel itself as the last element of the list. - */ - - newPtr = ckalloc((count+2) * sizeof(TkWindow *)); - if (count > 0) { - memcpy(newPtr, oldPtr, count * sizeof(TkWindow*)); - } - if (count == 0) { - count++; - } - newPtr[count-1] = winPtr; - newPtr[count] = topPtr; - if (oldPtr != NULL) { - ckfree(oldPtr); - } - - topPtr->wmInfoPtr->cmapList = newPtr; - topPtr->wmInfoPtr->cmapCount = count+1; - - /* - * Now we need to force the updated colormaps to be installed. - */ - - if (topPtr->wmInfoPtr == winPtr->dispPtr->foregroundWmPtr) { - InstallColormaps(topPtr->wmInfoPtr->wrapper, WM_QUERYNEWPALETTE, 1); - } else { - InstallColormaps(topPtr->wmInfoPtr->wrapper, WM_PALETTECHANGED, 0); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWmRemoveFromColormapWindows -- - * - * This function is called to remove a given window from the - * WM_COLORMAP_WINDOWS property for its top-level. It is invoked when - * windows are deleted. - * - * Results: - * None. - * - * Side effects: - * WinPtr's window gets removed from the WM_COLORMAP_WINDOWS property of - * its nearest top-level ancestor, unless the top-level itself is being - * deleted too. - * - *---------------------------------------------------------------------- - */ - -void -TkWmRemoveFromColormapWindows( - TkWindow *winPtr) /* Window that may be present in - * WM_COLORMAP_WINDOWS property for its - * top-level. Should not be a top-level - * window. */ -{ - TkWindow *topPtr; - TkWindow **oldPtr; - int count, i, j; - - for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) { - if (topPtr == NULL) { - /* - * Ancestors have been deleted, so skip the whole operation. - * Seems like this can't ever happen? - */ - - return; - } - if (topPtr->flags & TK_TOP_LEVEL) { - break; - } - } - if (topPtr->flags & TK_ALREADY_DEAD) { - /* - * Top-level is being deleted, so there's no need to cleanup the - * WM_COLORMAP_WINDOWS property. - */ - - return; - } - - if (topPtr->wmInfoPtr == NULL) { - return; - } - - /* - * Find the window and slide the following ones down to cover it up. - */ - - count = topPtr->wmInfoPtr->cmapCount; - oldPtr = topPtr->wmInfoPtr->cmapList; - for (i = 0; i < count; i++) { - if (oldPtr[i] == winPtr) { - for (j = i ; j < count-1; j++) { - oldPtr[j] = oldPtr[j+1]; - } - topPtr->wmInfoPtr->cmapCount = count-1; - break; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWinSetMenu-- - * - * Associcates a given HMENU to a window. - * - * Results: - * None. - * - * Side effects: - * The menu will end up being drawn in the window, and the geometry of - * the window will have to be changed. - * - *---------------------------------------------------------------------- - */ - -void -TkWinSetMenu( - Tk_Window tkwin, /* the window to put the menu in */ - HMENU hMenu) /* the menu to set */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - WmInfo *wmPtr = winPtr->wmInfoPtr; - - /* Could be a Frame (i.e. not a Toplevel) */ - if (wmPtr == NULL) - return; - - wmPtr->hMenu = hMenu; - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - int syncPending = wmPtr->flags & WM_SYNC_PENDING; - - wmPtr->flags |= WM_SYNC_PENDING; - SetMenu(wmPtr->wrapper, hMenu); - if (!syncPending) { - wmPtr->flags &= ~WM_SYNC_PENDING; - } - } - if (!(winPtr->flags & TK_EMBEDDED)) { - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING|WM_MOVE_PENDING; - } - } else { - SendMessage(wmPtr->wrapper, TK_SETMENU, (WPARAM) hMenu, - (LPARAM) Tk_GetMenuHWND(tkwin)); - } -} - -/* - *---------------------------------------------------------------------- - * - * ConfigureTopLevel -- - * - * Generate a ConfigureNotify event based on the current position - * information. This function is called by TopLevelProc. - * - * Results: - * None. - * - * Side effects: - * Queues a new event. - * - *---------------------------------------------------------------------- - */ - -static void -ConfigureTopLevel( - WINDOWPOS *pos) -{ - TkWindow *winPtr = GetTopLevel(pos->hwnd); - WmInfo *wmPtr; - int state; /* Current window state. */ - RECT rect; - WINDOWPLACEMENT windowPos; - - if (winPtr == NULL) { - return; - } - - wmPtr = winPtr->wmInfoPtr; - - /* - * Determine the current window state. - */ - - if (!IsWindowVisible(wmPtr->wrapper)) { - state = WithdrawnState; - } else { - windowPos.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(wmPtr->wrapper, &windowPos); - switch (windowPos.showCmd) { - case SW_SHOWMAXIMIZED: - state = ZoomState; - break; - case SW_SHOWMINIMIZED: - state = IconicState; - break; - case SW_SHOWNORMAL: - default: - state = NormalState; - break; - } - } - - /* - * If the state of the window just changed, be sure to update the - * child window information. - */ - - if (wmPtr->hints.initial_state != state) { - wmPtr->hints.initial_state = state; - switch (state) { - case WithdrawnState: - case IconicState: - XUnmapWindow(winPtr->display, winPtr->window); - break; - - case NormalState: - /* - * Schedule a geometry update. Since we ignore geometry requests - * while in any other state, the geometry info may be stale. - */ - - if (!(wmPtr->flags & WM_UPDATE_PENDING)) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } - /* fall through */ - case ZoomState: - XMapWindow(winPtr->display, winPtr->window); - pos->flags |= SWP_NOMOVE | SWP_NOSIZE; - break; - } - } - - /* - * Don't report geometry changes in the Iconic or Withdrawn states. - */ - - if (state == WithdrawnState || state == IconicState) { - return; - } - - - /* - * Compute the current geometry of the client area, reshape the Tk window - * and generate a ConfigureNotify event. - */ - - GetClientRect(wmPtr->wrapper, &rect); - winPtr->changes.x = pos->x; - winPtr->changes.y = pos->y; - winPtr->changes.width = rect.right - rect.left; - winPtr->changes.height = rect.bottom - rect.top; - wmPtr->borderHeight = pos->cy - winPtr->changes.height; - MoveWindow(Tk_GetHWND(winPtr->window), 0, 0, - winPtr->changes.width, winPtr->changes.height, TRUE); - GenerateConfigureNotify(winPtr); - - /* - * Update window manager geometry info if needed. - */ - - if (state == NormalState) { - - /* - * Update size information from the event. There are a couple of - * tricky points here: - * - * 1. If the user changed the size externally then set wmPtr->width - * and wmPtr->height just as if a "wm geometry" command had been - * invoked with the same information. - * 2. However, if the size is changing in response to a request coming - * from us (sync is set), then don't set wmPtr->width or - * wmPtr->height (otherwise the window will stop tracking geometry - * manager requests). - */ - - if (!(wmPtr->flags & WM_SYNC_PENDING)) { - if (!(pos->flags & SWP_NOSIZE)) { - if ((wmPtr->width == -1) - && (winPtr->changes.width == winPtr->reqWidth)) { - /* - * Don't set external width, since the user didn't change - * it from what the widgets asked for. - */ - } else { - if (wmPtr->gridWin != NULL) { - wmPtr->width = wmPtr->reqGridWidth - + (winPtr->changes.width - winPtr->reqWidth) - / wmPtr->widthInc; - if (wmPtr->width < 0) { - wmPtr->width = 0; - } - } else { - wmPtr->width = winPtr->changes.width; - } - } - if ((wmPtr->height == -1) - && (winPtr->changes.height == winPtr->reqHeight)) { - /* - * Don't set external height, since the user didn't change - * it from what the widgets asked for. - */ - } else { - if (wmPtr->gridWin != NULL) { - wmPtr->height = wmPtr->reqGridHeight - + (winPtr->changes.height - winPtr->reqHeight) - / wmPtr->heightInc; - if (wmPtr->height < 0) { - wmPtr->height = 0; - } - } else { - wmPtr->height = winPtr->changes.height; - } - } - wmPtr->configWidth = winPtr->changes.width; - wmPtr->configHeight = winPtr->changes.height; - } - - /* - * If the user moved the window, we should switch back to normal - * coordinates. - */ - - if (!(pos->flags & SWP_NOMOVE)) { - wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y); - } - } - - /* - * Update the wrapper window location information. - */ - - if (wmPtr->flags & WM_NEGATIVE_X) { - wmPtr->x = DisplayWidth(winPtr->display, winPtr->screenNum) - - winPtr->changes.x - (winPtr->changes.width - + wmPtr->borderWidth); - } else { - wmPtr->x = winPtr->changes.x; - } - if (wmPtr->flags & WM_NEGATIVE_Y) { - wmPtr->y = DisplayHeight(winPtr->display, winPtr->screenNum) - - winPtr->changes.y - (winPtr->changes.height - + wmPtr->borderHeight); - } else { - wmPtr->y = winPtr->changes.y; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * GenerateConfigureNotify -- - * - * Generate a ConfigureNotify event from the current geometry information - * for the specified toplevel window. - * - * Results: - * None. - * - * Side effects: - * Sends an X event. - * - *---------------------------------------------------------------------- - */ - -static void -GenerateConfigureNotify( - TkWindow *winPtr) -{ - XEvent event; - - /* - * Generate a ConfigureNotify event. - */ - - event.type = ConfigureNotify; - event.xconfigure.serial = winPtr->display->request; - event.xconfigure.send_event = False; - event.xconfigure.display = winPtr->display; - event.xconfigure.event = winPtr->window; - event.xconfigure.window = winPtr->window; - event.xconfigure.border_width = winPtr->changes.border_width; - event.xconfigure.override_redirect = winPtr->atts.override_redirect; - event.xconfigure.x = winPtr->changes.x; - event.xconfigure.y = winPtr->changes.y; - event.xconfigure.width = winPtr->changes.width; - event.xconfigure.height = winPtr->changes.height; - event.xconfigure.above = None; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); -} - -/* - *---------------------------------------------------------------------- - * - * InstallColormaps -- - * - * Installs the colormaps associated with the toplevel which is currently - * active. - * - * Results: - * None. - * - * Side effects: - * May change the system palette and generate damage. - * - *---------------------------------------------------------------------- - */ - -static int -InstallColormaps( - HWND hwnd, /* Toplevel wrapper window whose colormaps - * should be installed. */ - int message, /* Either WM_PALETTECHANGED or - * WM_QUERYNEWPALETTE */ - int isForemost) /* 1 if window is foremost, else 0 */ -{ - int i; - HDC dc; - HPALETTE oldPalette; - TkWindow *winPtr = GetTopLevel(hwnd); - WmInfo *wmPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (winPtr == NULL || (winPtr->flags & TK_ALREADY_DEAD)) { - return 0; - } - - wmPtr = winPtr->wmInfoPtr; - - if (message == WM_QUERYNEWPALETTE) { - /* - * Case 1: This window is about to become the foreground window, so we - * need to install the primary palette. If the system palette was - * updated, then Windows will generate a WM_PALETTECHANGED message. - * Otherwise, we have to synthesize one in order to ensure that the - * secondary palettes are installed properly. - */ - - winPtr->dispPtr->foregroundWmPtr = wmPtr; - - if (wmPtr->cmapCount > 0) { - winPtr = wmPtr->cmapList[0]; - } - - tsdPtr->systemPalette = TkWinGetPalette(winPtr->atts.colormap); - dc = GetDC(hwnd); - oldPalette = SelectPalette(dc, tsdPtr->systemPalette, FALSE); - if (RealizePalette(dc)) { - RefreshColormap(winPtr->atts.colormap, winPtr->dispPtr); - } else if (wmPtr->cmapCount > 1) { - SelectPalette(dc, oldPalette, TRUE); - RealizePalette(dc); - ReleaseDC(hwnd, dc); - SendMessage(hwnd, WM_PALETTECHANGED, (WPARAM) hwnd, (LPARAM) NULL); - return TRUE; - } - } else { - /* - * Window is being notified of a change in the system palette. If this - * window is the foreground window, then we should only install the - * secondary palettes, since the primary was installed in response to - * the WM_QUERYPALETTE message. Otherwise, install all of the - * palettes. - */ - - - if (!isForemost) { - if (wmPtr->cmapCount > 0) { - winPtr = wmPtr->cmapList[0]; - } - i = 1; - } else { - if (wmPtr->cmapCount <= 1) { - return TRUE; - } - winPtr = wmPtr->cmapList[1]; - i = 2; - } - dc = GetDC(hwnd); - oldPalette = SelectPalette(dc, - TkWinGetPalette(winPtr->atts.colormap), TRUE); - if (RealizePalette(dc)) { - RefreshColormap(winPtr->atts.colormap, winPtr->dispPtr); - } - for (; i < wmPtr->cmapCount; i++) { - winPtr = wmPtr->cmapList[i]; - SelectPalette(dc, TkWinGetPalette(winPtr->atts.colormap), TRUE); - if (RealizePalette(dc)) { - RefreshColormap(winPtr->atts.colormap, winPtr->dispPtr); - } - } - } - - SelectPalette(dc, oldPalette, TRUE); - RealizePalette(dc); - ReleaseDC(hwnd, dc); - return TRUE; -} - -/* - *---------------------------------------------------------------------- - * - * RefreshColormap -- - * - * This function is called to force all of the windows that use a given - * colormap to redraw themselves. The quickest way to do this is to - * iterate over the toplevels, looking in the cmapList for matches. This - * will quickly eliminate subtrees that don't use a given colormap. - * - * Results: - * None. - * - * Side effects: - * Causes damage events to be generated. - * - *---------------------------------------------------------------------- - */ - -static void -RefreshColormap( - Colormap colormap, - TkDisplay *dispPtr) -{ - WmInfo *wmPtr; - int i; - - for (wmPtr = dispPtr->firstWmPtr; wmPtr != NULL; wmPtr = wmPtr->nextPtr) { - if (wmPtr->cmapCount > 0) { - for (i = 0; i < wmPtr->cmapCount; i++) { - if ((wmPtr->cmapList[i]->atts.colormap == colormap) - && Tk_IsMapped(wmPtr->cmapList[i])) { - InvalidateSubTree(wmPtr->cmapList[i], colormap); - } - } - } else if ((wmPtr->winPtr->atts.colormap == colormap) - && Tk_IsMapped(wmPtr->winPtr)) { - InvalidateSubTree(wmPtr->winPtr, colormap); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * InvalidateSubTree -- - * - * This function recursively generates damage for a window and all of its - * mapped children that belong to the same toplevel and are using the - * specified colormap. - * - * Results: - * None. - * - * Side effects: - * Generates damage for the specified subtree. - * - *---------------------------------------------------------------------- - */ - -static void -InvalidateSubTree( - TkWindow *winPtr, - Colormap colormap) -{ - TkWindow *childPtr; - - /* - * Generate damage for the current window if it is using the specified - * colormap. - */ - - if (winPtr->atts.colormap == colormap) { - InvalidateRect(Tk_GetHWND(winPtr->window), NULL, FALSE); - } - - for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - /* - * We can stop the descent when we hit an unmapped or toplevel window. - */ - - if (!Tk_TopWinHierarchy(childPtr) && Tk_IsMapped(childPtr)) { - InvalidateSubTree(childPtr, colormap); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * InvalidateSubTreeDepth -- - * - * This function recursively updates depth info for a window and all of - * its children that belong to the same toplevel. - * - * Results: - * None. - * - * Side effects: - * Sets the depth of each window to that of the display. - * - *---------------------------------------------------------------------- - */ - -static void -InvalidateSubTreeDepth( - TkWindow *winPtr) -{ - Display *display = Tk_Display(winPtr); - int screenNum = Tk_ScreenNumber(winPtr); - TkWindow *childPtr; - - winPtr->depth = DefaultDepth(display, screenNum); - -#if 0 - /* - * XXX: What other elements may require changes? Changing just the depth - * works for standard windows and 16/24/32-bpp changes. I suspect 8-bit - * (palettized) displays may require colormap and/or visual changes as - * well. - */ - - if (winPtr->window) { - InvalidateRect(Tk_GetHWND(winPtr->window), NULL, FALSE); - } - winPtr->visual = DefaultVisual(display, screenNum); - winPtr->atts.colormap = DefaultColormap(display, screenNum); - winPtr->dirtyAtts |= CWColormap; -#endif - - for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - /* - * We can stop the descent when we hit a non-embedded toplevel window, - * as it should get its own message. - */ - - if (childPtr->flags & TK_EMBEDDED || !Tk_TopWinHierarchy(childPtr)) { - InvalidateSubTreeDepth(childPtr); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWinGetSystemPalette -- - * - * Retrieves the currently installed foreground palette. - * - * Results: - * Returns the global foreground palette, if there is one. Otherwise, - * returns NULL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -HPALETTE -TkWinGetSystemPalette(void) -{ - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - return tsdPtr->systemPalette; -} - -/* - *---------------------------------------------------------------------- - * - * GetMinSize -- - * - * This function computes the current minWidth and minHeight values for a - * window, taking into account the possibility that they may be - * defaulted. - * - * Results: - * The values at *minWidthPtr and *minHeightPtr are filled in with the - * minimum allowable dimensions of wmPtr's window, in grid units. If the - * requested minimum is smaller than the system required minimum, then - * this function computes the smallest size that will satisfy both the - * system and the grid constraints. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetMinSize( - WmInfo *wmPtr, /* Window manager information for the - * window. */ - int *minWidthPtr, /* Where to store the current minimum width of - * the window. */ - int *minHeightPtr) /* Where to store the current minimum height - * of the window. */ -{ - int tmp, base; - TkWindow *winPtr = wmPtr->winPtr; - - /* - * Compute the minimum width by taking the default client size and - * rounding it up to the nearest grid unit. Return the greater of the - * default minimum and the specified minimum. - */ - - tmp = wmPtr->defMinWidth - wmPtr->borderWidth; - if (tmp < 0) { - tmp = 0; - } - if (wmPtr->gridWin != NULL) { - base = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc); - if (base < 0) { - base = 0; - } - tmp = ((tmp - base) + wmPtr->widthInc - 1)/wmPtr->widthInc; - } - if (tmp < wmPtr->minWidth) { - tmp = wmPtr->minWidth; - } - *minWidthPtr = tmp; - - /* - * Compute the minimum height in a similar fashion. - */ - - tmp = wmPtr->defMinHeight - wmPtr->borderHeight; - if (tmp < 0) { - tmp = 0; - } - if (wmPtr->gridWin != NULL) { - base = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc); - if (base < 0) { - base = 0; - } - tmp = ((tmp - base) + wmPtr->heightInc - 1)/wmPtr->heightInc; - } - if (tmp < wmPtr->minHeight) { - tmp = wmPtr->minHeight; - } - *minHeightPtr = tmp; -} - -/* - *---------------------------------------------------------------------- - * - * GetMaxSize -- - * - * This function computes the current maxWidth and maxHeight values for a - * window, taking into account the possibility that they may be - * defaulted. - * - * Results: - * The values at *maxWidthPtr and *maxHeightPtr are filled in with the - * maximum allowable dimensions of wmPtr's window, in grid units. If no - * maximum has been specified for the window, then this function computes - * the largest sizes that will fit on the screen. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetMaxSize( - WmInfo *wmPtr, /* Window manager information for the - * window. */ - int *maxWidthPtr, /* Where to store the current maximum width of - * the window. */ - int *maxHeightPtr) /* Where to store the current maximum height - * of the window. */ -{ - int tmp; - - if (wmPtr->maxWidth > 0) { - *maxWidthPtr = wmPtr->maxWidth; - } else { - /* - * Must compute a default width. Fill up the display, leaving a bit of - * extra space for the window manager's borders. - */ - - tmp = wmPtr->defMaxWidth - wmPtr->borderWidth; - if (wmPtr->gridWin != NULL) { - /* - * Gridding is turned on; convert from pixels to grid units. - */ - - tmp = wmPtr->reqGridWidth - + (tmp - wmPtr->winPtr->reqWidth)/wmPtr->widthInc; - } - *maxWidthPtr = tmp; - } - if (wmPtr->maxHeight > 0) { - *maxHeightPtr = wmPtr->maxHeight; - } else { - tmp = wmPtr->defMaxHeight - wmPtr->borderHeight; - if (wmPtr->gridWin != NULL) { - tmp = wmPtr->reqGridHeight - + (tmp - wmPtr->winPtr->reqHeight)/wmPtr->heightInc; - } - *maxHeightPtr = tmp; - } -} - -/* - *---------------------------------------------------------------------- - * - * TopLevelProc -- - * - * Callback from Windows whenever an event occurs on a top level window. - * - * Results: - * Standard Windows return value. - * - * Side effects: - * Default window behavior. - * - *---------------------------------------------------------------------- - */ - -static LRESULT CALLBACK -TopLevelProc( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - if (message == WM_WINDOWPOSCHANGED || message == WM_WINDOWPOSCHANGING) { - WINDOWPOS *pos = (WINDOWPOS *) lParam; - TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(pos->hwnd); - - if (winPtr == NULL) { - return 0; - } - - /* - * Update the shape of the contained window. - */ - - if (!(pos->flags & SWP_NOSIZE)) { - winPtr->changes.width = pos->cx; - winPtr->changes.height = pos->cy; - } - if (!(pos->flags & SWP_NOMOVE)) { - long result = SendMessage(winPtr->wmInfoPtr->wrapper, - TK_MOVEWINDOW, -1, -1); - winPtr->wmInfoPtr->x = winPtr->changes.x = result >> 16; - winPtr->wmInfoPtr->y = winPtr->changes.y = result & 0xffff; - } - - GenerateConfigureNotify(winPtr); - - Tcl_ServiceAll(); - return 0; - } - return TkWinChildProc(hwnd, message, wParam, lParam); -} - -/* - *---------------------------------------------------------------------- - * - * WmProc -- - * - * Callback from Windows whenever an event occurs on the decorative - * frame. - * - * Results: - * Standard Windows return value. - * - * Side effects: - * Default window behavior. - * - *---------------------------------------------------------------------- - */ - -static LRESULT CALLBACK -WmProc( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - static int inMoveSize = 0; - static int oldMode; /* This static is set upon entering move/size - * mode and is used to reset the service mode - * after leaving move/size mode. Note that - * this mechanism assumes move/size is only - * one level deep. */ - LRESULT result = 0; - TkWindow *winPtr = NULL; - - switch (message) { - case WM_KILLFOCUS: - case WM_ERASEBKGND: - result = 0; - goto done; - - case WM_ENTERSIZEMOVE: - inMoveSize = 1; - - /* - * Cancel any current mouse timer. If the mouse timer fires during the - * size/move mouse capture, it will release the capture, which is - * wrong. - */ - - TkWinCancelMouseTimer(); - - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - break; - - case WM_ACTIVATE: - if (WA_ACTIVE == LOWORD(wParam)) { - winPtr = GetTopLevel(hwnd); - if (winPtr && (TkGrabState(winPtr) == TK_GRAB_EXCLUDED)) { - /* - * There is a grab in progress so queue an Activate event - */ - - GenerateActivateEvent(winPtr, &inMoveSize); - result = 0; - goto done; - } - } - /* fall through */ - - case WM_EXITSIZEMOVE: - if (inMoveSize) { - inMoveSize = 0; - Tcl_SetServiceMode(oldMode); - } - break; - - case WM_GETMINMAXINFO: - SetLimits(hwnd, (MINMAXINFO *) lParam); - result = 0; - goto done; - - case WM_DISPLAYCHANGE: - /* - * Display and/or color resolution changed. - */ - - winPtr = GetTopLevel(hwnd); - if (winPtr) { - Screen *screen = Tk_Screen(winPtr); - if (screen->root_depth != (int) wParam) { - /* - * Color resolution changed, so do extensive rebuild of - * display parameters. This will affect the display for all Tk - * windows. We will receive this event for each toplevel, but - * this check makes us update only once, for the first - * toplevel that receives the message. - */ - - TkWinDisplayChanged(Tk_Display(winPtr)); - } else { - HDC dc = GetDC(NULL); - - screen->width = LOWORD(lParam); /* horizontal res */ - screen->height = HIWORD(lParam); /* vertical res */ - screen->mwidth = MulDiv(screen->width, 254, - GetDeviceCaps(dc, LOGPIXELSX) * 10); - screen->mheight = MulDiv(screen->height, 254, - GetDeviceCaps(dc, LOGPIXELSY) * 10); - ReleaseDC(NULL, dc); - } - if (Tk_Depth(winPtr) != (int) wParam) { - /* - * Defer the window depth check to here so that each toplevel - * will properly update depth info. - */ - - InvalidateSubTreeDepth(winPtr); - } - } - result = 0; - goto done; - - case WM_SYSCOLORCHANGE: - /* - * XXX: Called when system color changes. We need to update any - * widgets that use a system color. - */ - - break; - - case WM_PALETTECHANGED: - result = InstallColormaps(hwnd, WM_PALETTECHANGED, - hwnd == (HWND) wParam); - goto done; - - case WM_QUERYNEWPALETTE: - result = InstallColormaps(hwnd, WM_QUERYNEWPALETTE, TRUE); - goto done; - - case WM_SETTINGCHANGE: - if (wParam == SPI_SETNONCLIENTMETRICS) { - winPtr = GetTopLevel(hwnd); - TkWinSetupSystemFonts(winPtr->mainPtr); - result = 0; - goto done; - } - break; - - case WM_WINDOWPOSCHANGED: - ConfigureTopLevel((WINDOWPOS *) lParam); - result = 0; - goto done; - - case WM_NCHITTEST: { - winPtr = GetTopLevel(hwnd); - if (winPtr && (TkGrabState(winPtr) == TK_GRAB_EXCLUDED)) { - /* - * This window is outside the grab heirarchy, so don't let any of - * the normal non-client processing occur. Note that this - * implementation is not strictly correct because the grab might - * change between now and when the event would have been processed - * by Tk, but it's close enough. - */ - - result = HTCLIENT; - goto done; - } - break; - } - - case WM_MOUSEACTIVATE: { - winPtr = GetTopLevel((HWND) wParam); - if (winPtr && (TkGrabState(winPtr) != TK_GRAB_EXCLUDED)) { - /* - * This allows us to pass the message onto the native menus [Bug: - * 2272] - */ - - result = DefWindowProc(hwnd, message, wParam, lParam); - goto done; - } - - /* - * Don't activate the window yet since there is a grab that takes - * precedence. Instead we need to queue an event so we can check the - * grab state right before we handle the mouse event. - */ - - if (winPtr) { - GenerateActivateEvent(winPtr, &inMoveSize); - } - result = MA_NOACTIVATE; - goto done; - } - - case WM_QUERYENDSESSION: { - XEvent event; - - /* - * Synthesize WM_SAVE_YOURSELF wm protocol message on Windows logout - * or restart. - */ - winPtr = GetTopLevel(hwnd); - event.xclient.message_type = - Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS"); - event.xclient.data.l[0] = - Tk_InternAtom((Tk_Window) winPtr, "WM_SAVE_YOURSELF"); - TkWmProtocolEventProc(winPtr, &event); - break; - } - - default: - break; - } - - winPtr = GetTopLevel(hwnd); - switch(message) { - case WM_SYSCOMMAND: - /* - * If there is a grab in effect then ignore the minimize command - * unless the grab is on the main window (.). This is to permit - * applications that leave a grab on . to work normally. - * All other toplevels are deemed non-minimizable when a grab is - * present. - * If there is a grab in effect and this window is outside the - * grab tree then ignore all system commands. [Bug 1847002] - */ - - if (winPtr) { - int cmd = wParam & 0xfff0; - int grab = TkGrabState(winPtr); - if ((SC_MINIMIZE == cmd) - && (grab == TK_GRAB_IN_TREE || grab == TK_GRAB_ANCESTOR) - && (winPtr != winPtr->mainPtr->winPtr)) { - goto done; - } - if (grab == TK_GRAB_EXCLUDED - && !(SC_MOVE == cmd || SC_SIZE == cmd)) { - goto done; - } - } - /* fall through */ - - case WM_INITMENU: - case WM_COMMAND: - case WM_MENUCHAR: - case WM_MEASUREITEM: - case WM_DRAWITEM: - case WM_MENUSELECT: - case WM_ENTERIDLE: - case WM_INITMENUPOPUP: - if (winPtr) { - HWND hMenuHWnd = Tk_GetEmbeddedMenuHWND((Tk_Window) winPtr); - - if (hMenuHWnd) { - if (SendMessage(hMenuHWnd, message, wParam, lParam)) { - goto done; - } - } else if (TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, - &result)) { - goto done; - } - } - break; - } - - if (winPtr && winPtr->window) { - HWND child = Tk_GetHWND(winPtr->window); - - if (message == WM_SETFOCUS) { - SetFocus(child); - result = 0; - } else if (!Tk_TranslateWinEvent(child, message, wParam, lParam, - &result)) { - result = DefWindowProc(hwnd, message, wParam, lParam); - } - } else { - result = DefWindowProc(hwnd, message, wParam, lParam); - } - - done: - Tcl_ServiceAll(); - return result; -} - -/* - *---------------------------------------------------------------------- - * - * TkpMakeMenuWindow -- - * - * Configure the window to be either a pull-down (or pop-up) menu, or as - * a toplevel (torn-off) menu or palette. - * - * Results: - * None. - * - * Side effects: - * Changes the style bit used to create a new toplevel. - * - *---------------------------------------------------------------------- - */ - -void -TkpMakeMenuWindow( - Tk_Window tkwin, /* New window. */ - int transient) /* 1 means menu is only posted briefly as a - * popup or pulldown or cascade. 0 means menu - * is always visible, e.g. as a torn-off menu. - * Determines whether save_under and - * override_redirect should be set. */ -{ - XSetWindowAttributes atts; - - if (transient) { - atts.override_redirect = True; - atts.save_under = True; - } else { - atts.override_redirect = False; - atts.save_under = False; - } - - if ((atts.override_redirect != Tk_Attributes(tkwin)->override_redirect) - || (atts.save_under != Tk_Attributes(tkwin)->save_under)) { - Tk_ChangeWindowAttributes(tkwin, CWOverrideRedirect|CWSaveUnder, - &atts); - } - -} - -/* - *---------------------------------------------------------------------- - * - * TkWinGetWrapperWindow -- - * - * Gets the Windows HWND for a given window. - * - * Results: - * Returns the wrapper window for a Tk window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -HWND -TkWinGetWrapperWindow( - Tk_Window tkwin) /* The window we need the wrapper from */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - - return winPtr->wmInfoPtr->wrapper; -} - -/* - *---------------------------------------------------------------------- - * - * TkWmFocusToplevel -- - * - * This is a utility function invoked by focus-management code. It exists - * because of the extra wrapper windows that exist under Unix; its job is - * to map from wrapper windows to the corresponding toplevel windows. On - * PCs and Macs there are no wrapper windows so no mapping is necessary; - * this function just determines whether a window is a toplevel or not. - * - * Results: - * If winPtr is a toplevel window, returns the pointer to the window; - * otherwise returns NULL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TkWindow * -TkWmFocusToplevel( - TkWindow *winPtr) /* Window that received a focus-related - * event. */ -{ - if (!(winPtr->flags & TK_TOP_HIERARCHY)) { - return NULL; - } - return winPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetWrapperWindow -- - * - * This is a utility function invoked by focus-management code. It maps - * to the wrapper for a top-level, which is just the same as the - * top-level on Macs and PCs. - * - * Results: - * If winPtr is a toplevel window, returns the pointer to the window; - * otherwise returns NULL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TkWindow * -TkpGetWrapperWindow( - TkWindow *winPtr) /* Window that received a focus-related - * event. */ -{ - if (!(winPtr->flags & TK_TOP_HIERARCHY)) { - return NULL; - } - return winPtr; -} - -/* - *---------------------------------------------------------------------- - * - * GenerateActivateEvent -- - * - * This function is called to activate a Tk window. - */ - -static void -GenerateActivateEvent(TkWindow * winPtr, const int *flagPtr) -{ - ActivateEvent *eventPtr = ckalloc(sizeof(ActivateEvent)); - - eventPtr->ev.proc = ActivateWindow; - eventPtr->winPtr = winPtr; - eventPtr->flagPtr = flagPtr; - eventPtr->hwnd = Tk_GetHWND(winPtr->window); - Tcl_QueueEvent((Tcl_Event *)eventPtr, TCL_QUEUE_TAIL); -} - -/* - *---------------------------------------------------------------------- - * - * ActivateWindow -- - * - * This function is called when an ActivateEvent is processed. - * - * Results: - * Returns 1 to indicate that the event was handled, else 0. - * - * Side effects: - * May activate the toplevel window associated with the event. - * - *---------------------------------------------------------------------- - */ - -static int -ActivateWindow( - Tcl_Event *evPtr, /* Pointer to ActivateEvent. */ - int flags) /* Notifier event mask. */ -{ - ActivateEvent *eventPtr = (ActivateEvent *)evPtr; - TkWindow *winPtr = eventPtr->winPtr; - - if (! (flags & TCL_WINDOW_EVENTS)) { - return 0; - } - - /* - * Ensure the window has not been destroyed while we delayed - * processing the WM_ACTIVATE message [Bug 2899949]. - */ - - if (!IsWindow(eventPtr->hwnd)) { - return 1; - } - - /* - * If the toplevel is in the middle of a move or size operation then - * we must delay handling of this event to avoid stealing the focus - * while the window manage is in control. - */ - - if (eventPtr->flagPtr && *eventPtr->flagPtr) { - return 0; - } - - /* - * If the window is excluded by a grab, call SetFocus on the grabbed - * window instead. [Bug 220908] - */ - - if (winPtr) { - Window window; - if (TkGrabState(winPtr) != TK_GRAB_EXCLUDED) { - window = winPtr->window; - } else { - window = winPtr->dispPtr->grabWinPtr->window; - } - - /* - * Ensure the window was not destroyed while we were postponing - * the activation [Bug 2799589] - */ - - if (window) { - SetFocus(Tk_GetHWND(window)); - } - } - - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinSetForegroundWindow -- - * - * This function is a wrapper for SetForegroundWindow, calling it on the - * wrapper window because it has no affect on child windows. - * - * Results: - * none - * - * Side effects: - * May activate the toplevel window. - * - *---------------------------------------------------------------------- - */ - -void -TkWinSetForegroundWindow( - TkWindow *winPtr) -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (wmPtr->wrapper != NULL) { - SetForegroundWindow(wmPtr->wrapper); - } else { - SetForegroundWindow(Tk_GetHWND(winPtr->window)); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpWinToplevelWithdraw -- - * - * This function is to be used by a window manage to withdraw a toplevel - * window. - * - * Results: - * none - * - * Side effects: - * May withdraw the toplevel window. - * - *---------------------------------------------------------------------- - */ - -void -TkpWinToplevelWithDraw( - TkWindow *winPtr) -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - wmPtr->flags |= WM_WITHDRAWN; - TkpWmSetState(winPtr, WithdrawnState); -} - -/* - *---------------------------------------------------------------------- - * - * TkpWinToplevelIconify -- - * - * This function is to be used by a window manage to iconify a toplevel - * window. - * - * Results: - * none - * - * Side effects: - * May iconify the toplevel window. - * - *---------------------------------------------------------------------- - */ - -void -TkpWinToplevelIconify( - TkWindow *winPtr) -{ - TkpWmSetState(winPtr, IconicState); -} - -/* - *---------------------------------------------------------------------- - * - * TkpWinToplevelDeiconify -- - * - * This function is to be used by a window manage to deiconify a toplevel - * window. - * - * Results: - * none - * - * Side effects: - * May deiconify the toplevel window. - * - *---------------------------------------------------------------------- - */ - -void -TkpWinToplevelDeiconify( - TkWindow *winPtr) -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - wmPtr->flags &= ~WM_WITHDRAWN; - - /* - * If WM_UPDATE_PENDING is true, a pending UpdateGeometryInfo may need to - * be called first to update a withdrawn toplevel's geometry before it is - * deiconified by TkpWmSetState. Don't bother if we've never been mapped. - */ - - if ((wmPtr->flags & WM_UPDATE_PENDING) - && !(wmPtr->flags & WM_NEVER_MAPPED)) { - Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr); - UpdateGeometryInfo(winPtr); - } - - /* - * If we were in the ZoomState (maximized), 'wm deiconify' should not - * cause the window to shrink - */ - - if (wmPtr->hints.initial_state == ZoomState) { - TkpWmSetState(winPtr, ZoomState); - } else { - TkpWmSetState(winPtr, NormalState); - } - - /* - * An unmapped window will be mapped at idle time by a call to MapFrame. - * That calls CreateWrapper which sets the focus and raises the window. - */ - - if (wmPtr->flags & WM_NEVER_MAPPED) { - return; - } - - /* - * Follow Windows-like style here, raising the window to the top. - */ - - TkWmRestackToplevel(winPtr, Above, NULL); - if (!(Tk_Attributes((Tk_Window) winPtr)->override_redirect)) { - TkSetFocusWin(winPtr, 1); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpWinGeometryIsControlledByWm -- - * - * This function is to be used by a window manage to see if wm has - * canceled geometry control. - * - * Results: - * 0 - if the window manager has canceled its control - * 1 - if the window manager controls the geometry - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -long -TkpWinToplevelIsControlledByWm( - TkWindow *winPtr) -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (!wmPtr) { - return 0; - } - return ((wmPtr->width != -1) && (wmPtr->height != -1)) ? 1 : 0; -} - -/* - *---------------------------------------------------------------------- - * - * TkpWinToplevelMove -- - * - * This function is to be used by a container to move an embedded window. - * - * Results: - * position of the upper left frame in a 32-bit long: - * 16-MSBits - x; 16-LSBits - y - * - * Side effects: - * May move the embedded window. - * - *---------------------------------------------------------------------- - */ - -long -TkpWinToplevelMove( - TkWindow *winPtr, - int x, int y) -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (wmPtr && x >= 0 && y >= 0 && !TkpWinToplevelIsControlledByWm(winPtr)) { - Tk_MoveToplevelWindow((Tk_Window) winPtr, x, y); - } - return ((winPtr->changes.x << 16) & 0xffff0000) - | (winPtr->changes.y & 0xffff); -} - -/* - *---------------------------------------------------------------------- - * - * TkpWinToplevelOverrideRedirect -- - * - * This function is to be used by a container to overrideredirect the - * contaner's frame window. - * - * Results: - * The current overrideredirect value - * - * Side effects: - * May change the overrideredirect value of the container window - * - *---------------------------------------------------------------------- - */ - -long -TkpWinToplevelOverrideRedirect( - TkWindow *winPtr, - int reqValue) -{ - int curValue; - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect; - if (reqValue < 0) { - return curValue; - } - - if (curValue != reqValue) { - XSetWindowAttributes atts; - - /* - * Only do this if we are really changing value, because it causes - * some funky stuff to occur - */ - - atts.override_redirect = reqValue ? True : False; - Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, - &atts); - if (!(wmPtr->flags & (WM_NEVER_MAPPED)) - && !(winPtr->flags & TK_EMBEDDED)) { - UpdateWrapper(winPtr); - } - } - return reqValue; -} - -/* - *---------------------------------------------------------------------- - * - * TkpWinToplevelDetachWindow -- - * - * This function is to be usd for changing a toplevel's wrapper or - * container. - * - * Results: - * The window's wrapper/container is removed. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkpWinToplevelDetachWindow( - TkWindow *winPtr) -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (winPtr->flags & TK_EMBEDDED) { - int state = SendMessage(wmPtr->wrapper, TK_STATE, -1, -1) - 1; - - SendMessage(wmPtr->wrapper, TK_SETMENU, 0, 0); - SendMessage(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0); - winPtr->flags &= ~TK_EMBEDDED; - winPtr->privatePtr = NULL; - wmPtr->wrapper = None; - if (state >= 0 && state <= 3) { - wmPtr->hints.initial_state = state; - } - } - if (winPtr->flags & TK_TOP_LEVEL) { - TkpWinToplevelOverrideRedirect(winPtr, 1); - } -} - -/* - *---------------------------------------------------------------------- - * - * RemapWindows - * - * Adjust parent/child relation ships of the given window hierarchy. - * - * Results: - * none - * - * Side effects: - * keeps windowing system happy - * - *---------------------------------------------------------------------- - */ - -static void -RemapWindows( - TkWindow *winPtr, - HWND parentHWND) -{ - TkWindow *childPtr; - const char *className = Tk_Class(winPtr); - - /* - * Skip menus as they are handled differently. - */ - - if (className != NULL && strcmp(className, "Menu") == 0) { - return; - } - if (winPtr->window) { - SetParent(Tk_GetHWND(winPtr->window), parentHWND); - } - - /* - * Repeat for all the children. - */ - - for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - RemapWindows(childPtr, - winPtr->window ? Tk_GetHWND(winPtr->window) : NULL); - } -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/tkWinX.c b/tk8.6/win/tkWinX.c deleted file mode 100644 index fca72c3..0000000 --- a/tk8.6/win/tkWinX.c +++ /dev/null @@ -1,1955 +0,0 @@ -/* - * tkWinX.c -- - * - * This file contains Windows emulation procedures for X routines. - * - * Copyright (c) 1995-1996 Sun Microsystems, Inc. - * Copyright (c) 1994 Software Research Associates, Inc. - * Copyright (c) 1998-2000 by Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkWinInt.h" - -/* - * The w32api 1.1 package (included in Mingw 1.1) does not define _WIN32_IE by - * default. Define it here to gain access to the InitCommonControlsEx API in - * commctrl.h. - */ - -#ifndef _WIN32_IE -#define _WIN32_IE 0x0550 /* IE 5.5 */ -#endif - -#include <commctrl.h> -#ifdef _MSC_VER -# pragma comment (lib, "comctl32.lib") -# pragma comment (lib, "advapi32.lib") -#endif - -/* - * The zmouse.h file includes the definition for WM_MOUSEWHEEL. - */ - -#include <zmouse.h> - -/* - * imm.h is needed by HandleIMEComposition - */ - -#include <imm.h> -#ifdef _MSC_VER -# pragma comment (lib, "imm32.lib") -#endif - -/* - * WM_UNICHAR is a message for Unicode input on all windows systems. - * Perhaps this definition should be moved in another file. - */ -#ifndef WM_UNICHAR -#define WM_UNICHAR 0x0109 -#define UNICODE_NOCHAR 0xFFFF -#endif - -/* - * Declarations of static variables used in this file. - */ - -static const char winScreenName[] = ":0"; /* Default name of windows display. */ -static HINSTANCE tkInstance = NULL; /* Application instance handle. */ -static int childClassInitialized; /* Registered child class? */ -static WNDCLASS childClass; /* Window class for child windows. */ -static int tkPlatformId = 0; /* version of Windows platform */ -static int tkWinTheme = 0; /* See TkWinGetPlatformTheme */ -static Tcl_Encoding keyInputEncoding = NULL; - /* The current character encoding for - * keyboard input */ -static int keyInputCharset = -1; /* The Win32 CHARSET for the keyboard - * encoding */ -static Tcl_Encoding unicodeEncoding = NULL; - /* The UNICODE encoding */ - -/* - * Thread local storage. Notice that now each thread must have its own - * TkDisplay structure, since this structure contains most of the thread- - * specific date for threads. - */ - -typedef struct ThreadSpecificData { - TkDisplay *winDisplay; /* TkDisplay structure that represents Windows - * screen. */ - int updatingClipboard; /* If 1, we are updating the clipboard. */ - int surrogateBuffer; /* Buffer for first of surrogate pair. */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -/* - * Forward declarations of functions used in this file. - */ - -static void GenerateXEvent(HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam); -static unsigned int GetState(UINT message, WPARAM wParam, LPARAM lParam); -static void GetTranslatedKey(XKeyEvent *xkey, UINT type); -static void UpdateInputLanguage(int charset); -static int HandleIMEComposition(HWND hwnd, LPARAM lParam); - -/* - *---------------------------------------------------------------------- - * - * TkGetServerInfo -- - * - * Given a window, this function returns information about the window - * server for that window. This function provides the guts of the "winfo - * server" command. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkGetServerInfo( - Tcl_Interp *interp, /* The server information is returned in this - * interpreter's result. */ - Tk_Window tkwin) /* Token for window; this selects a particular - * display and server. */ -{ - static char buffer[32]; /* Empty string means not initialized yet. */ - OSVERSIONINFOW os; - - if (!buffer[0]) { - HANDLE handle = GetModuleHandle(TEXT("NTDLL")); - int(__stdcall *getversion)(void *) = - (int(__stdcall *)(void *))GetProcAddress(handle, "RtlGetVersion"); - os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); - if (!getversion || getversion(&os)) { - GetVersionExW(&os); - } - /* Write the first character last, preventing multi-thread issues. */ - sprintf(buffer+1, "indows %d.%d %d %s", (int)os.dwMajorVersion, - (int)os.dwMinorVersion, (int)os.dwBuildNumber, -#ifdef _WIN64 - "Win64" -#else - "Win32" -#endif - ); - buffer[0] = 'W'; - } - Tcl_AppendResult(interp, buffer, NULL); -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetHINSTANCE -- - * - * Retrieves the global instance handle used by the Tk library. - * - * Results: - * Returns the global instance handle. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -HINSTANCE -Tk_GetHINSTANCE(void) -{ - if (tkInstance == NULL) { - tkInstance = GetModuleHandle(NULL); - } - return tkInstance; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinSetHINSTANCE -- - * - * Sets the global instance handle used by the Tk library. This should be - * called by DllMain. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkWinSetHINSTANCE( - HINSTANCE hInstance) -{ - tkInstance = hInstance; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinXInit -- - * - * Initialize Xlib emulation layer. - * - * Results: - * None. - * - * Side effects: - * Sets up various data structures. - * - *---------------------------------------------------------------------- - */ - -void -TkWinXInit( - HINSTANCE hInstance) -{ - INITCOMMONCONTROLSEX comctl; - CHARSETINFO lpCs; - DWORD lpCP; - - if (childClassInitialized != 0) { - return; - } - childClassInitialized = 1; - - comctl.dwSize = sizeof(INITCOMMONCONTROLSEX); - comctl.dwICC = ICC_WIN95_CLASSES; - if (!InitCommonControlsEx(&comctl)) { - Tcl_Panic("Unable to load common controls?!"); - } - - childClass.style = CS_HREDRAW | CS_VREDRAW; - childClass.cbClsExtra = 0; - childClass.cbWndExtra = 0; - childClass.hInstance = hInstance; - childClass.hbrBackground = NULL; - childClass.lpszMenuName = NULL; - - /* - * Register the Child window class. - */ - - childClass.lpszClassName = TK_WIN_CHILD_CLASS_NAME; - childClass.lpfnWndProc = TkWinChildProc; - childClass.hIcon = NULL; - childClass.hCursor = NULL; - - if (!RegisterClass(&childClass)) { - Tcl_Panic("Unable to register TkChild class"); - } - - /* - * Initialize input language info - */ - - if (GetLocaleInfo(LANGIDFROMLCID(PTR2INT(GetKeyboardLayout(0))), - LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, - (LPTSTR) &lpCP, sizeof(lpCP)/sizeof(TCHAR)) - && TranslateCharsetInfo(INT2PTR(lpCP), &lpCs, TCI_SRCCODEPAGE)) { - UpdateInputLanguage((int) lpCs.ciCharset); - } - - /* - * Make sure we cleanup on finalize. - */ - - TkCreateExitHandler(TkWinXCleanup, (ClientData) hInstance); -} - -/* - *---------------------------------------------------------------------- - * - * TkWinXCleanup -- - * - * Removes the registered classes for Tk. - * - * Results: - * None. - * - * Side effects: - * Removes window classes from the system. - * - *---------------------------------------------------------------------- - */ - -void -TkWinXCleanup( - ClientData clientData) -{ - HINSTANCE hInstance = (HINSTANCE) clientData; - - /* - * Clean up our own class. - */ - - if (childClassInitialized) { - childClassInitialized = 0; - UnregisterClass(TK_WIN_CHILD_CLASS_NAME, hInstance); - } - - if (unicodeEncoding != NULL) { - Tcl_FreeEncoding(unicodeEncoding); - unicodeEncoding = NULL; - } - - /* - * And let the window manager clean up its own class(es). - */ - - TkWinWmCleanup(hInstance); - TkWinCleanupContainerList(); -} - -/* - *---------------------------------------------------------------------- - * - * TkWinGetPlatformId -- - * - * Determines whether running under NT, 95, or Win32s, to allow runtime - * conditional code. Win32s is no longer supported. - * - * Results: - * The return value is one of: - * VER_PLATFORM_WIN32s Win32s on Windows 3.1 (not supported) - * VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95, 98, ME (not supported) - * VER_PLATFORM_WIN32_NT Win32 on Windows XP, Vista, Windows 7, Windows 8 - * VER_PLATFORM_WIN32_CE Win32 on Windows CE - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkWinGetPlatformId(void) -{ - if (tkPlatformId == 0) { - OSVERSIONINFOW os; - - os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); - GetVersionExW(&os); - tkPlatformId = os.dwPlatformId; - - /* - * Set tkWinTheme to be TK_THEME_WIN_XP or TK_THEME_WIN_CLASSIC. The - * TK_THEME_WIN_CLASSIC could be set even when running under XP if the - * windows classic theme was selected. - */ - - if ((os.dwPlatformId == VER_PLATFORM_WIN32_NT) && - (os.dwMajorVersion == 5 && os.dwMinorVersion == 1)) { - HKEY hKey; - LPCTSTR szSubKey = TEXT("Control Panel\\Appearance"); - LPCTSTR szCurrent = TEXT("Current"); - DWORD dwSize = 200; - char pBuffer[200]; - - memset(pBuffer, 0, dwSize); - if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0L, - KEY_READ, &hKey) != ERROR_SUCCESS) { - tkWinTheme = TK_THEME_WIN_XP; - } else { - RegQueryValueEx(hKey, szCurrent, NULL, NULL, (LPBYTE) pBuffer, &dwSize); - RegCloseKey(hKey); - if (strcmp(pBuffer, "Windows Standard") == 0) { - tkWinTheme = TK_THEME_WIN_CLASSIC; - } else { - tkWinTheme = TK_THEME_WIN_XP; - } - } - } else { - tkWinTheme = TK_THEME_WIN_CLASSIC; - } - } - return tkPlatformId; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinGetPlatformTheme -- - * - * Return the Windows drawing style we should be using. - * - * Results: - * The return value is one of: - * TK_THEME_WIN_CLASSIC 95/98/NT or XP in classic mode - * TK_THEME_WIN_XP XP not in classic mode - * - * Side effects: - * Could invoke TkWinGetPlatformId. - * - *---------------------------------------------------------------------- - */ - -int -TkWinGetPlatformTheme(void) -{ - if (tkPlatformId == 0) { - TkWinGetPlatformId(); - } - return tkWinTheme; -} - -/* - *---------------------------------------------------------------------- - * - * TkGetDefaultScreenName -- - * - * Returns the name of the screen that Tk should use during - * initialization. - * - * Results: - * Returns a statically allocated string. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -const char * -TkGetDefaultScreenName( - Tcl_Interp *interp, /* Not used. */ - const char *screenName) /* If NULL, use default string. */ -{ - if ((screenName == NULL) || (screenName[0] == '\0')) { - screenName = winScreenName; - } - return screenName; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinDisplayChanged -- - * - * Called to set up initial screen info or when an event indicated - * display (screen) change. - * - * Results: - * None. - * - * Side effects: - * May change info regarding the screen. - * - *---------------------------------------------------------------------- - */ - -void -TkWinDisplayChanged( - Display *display) -{ - HDC dc; - Screen *screen; - - if (display == NULL || display->screens == NULL) { - return; - } - screen = display->screens; - - dc = GetDC(NULL); - screen->width = GetDeviceCaps(dc, HORZRES); - screen->height = GetDeviceCaps(dc, VERTRES); - screen->mwidth = MulDiv(screen->width, 254, - GetDeviceCaps(dc, LOGPIXELSX) * 10); - screen->mheight = MulDiv(screen->height, 254, - GetDeviceCaps(dc, LOGPIXELSY) * 10); - - /* - * On windows, when creating a color bitmap, need two pieces of - * information: the number of color planes and the number of pixels per - * plane. Need to remember both quantities so that when constructing an - * HBITMAP for offscreen rendering, we can specify the correct value for - * the number of planes. Otherwise the HBITMAP won't be compatible with - * the HWND and we'll just get blank spots copied onto the screen. - */ - - screen->ext_data = INT2PTR(GetDeviceCaps(dc, PLANES)); - screen->root_depth = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data); - - if (screen->root_visual != NULL) { - ckfree(screen->root_visual); - } - screen->root_visual = ckalloc(sizeof(Visual)); - screen->root_visual->visualid = 0; - if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) { - screen->root_visual->map_entries = GetDeviceCaps(dc, SIZEPALETTE); - screen->root_visual->class = PseudoColor; - screen->root_visual->red_mask = 0x0; - screen->root_visual->green_mask = 0x0; - screen->root_visual->blue_mask = 0x0; - } else if (screen->root_depth == 4) { - screen->root_visual->class = StaticColor; - screen->root_visual->map_entries = 16; - } else if (screen->root_depth == 8) { - screen->root_visual->class = StaticColor; - screen->root_visual->map_entries = 256; - } else if (screen->root_depth == 12) { - screen->root_visual->class = TrueColor; - screen->root_visual->map_entries = 32; - screen->root_visual->red_mask = 0xf0; - screen->root_visual->green_mask = 0xf000; - screen->root_visual->blue_mask = 0xf00000; - } else if (screen->root_depth == 16) { - screen->root_visual->class = TrueColor; - screen->root_visual->map_entries = 64; - screen->root_visual->red_mask = 0xf8; - screen->root_visual->green_mask = 0xfc00; - screen->root_visual->blue_mask = 0xf80000; - } else if (screen->root_depth >= 24) { - screen->root_visual->class = TrueColor; - screen->root_visual->map_entries = 256; - screen->root_visual->red_mask = 0xff; - screen->root_visual->green_mask = 0xff00; - screen->root_visual->blue_mask = 0xff0000; - } - screen->root_visual->bits_per_rgb = screen->root_depth; - ReleaseDC(NULL, dc); - - if (screen->cmap != None) { - XFreeColormap(display, screen->cmap); - } - screen->cmap = XCreateColormap(display, None, screen->root_visual, - AllocNone); -} - -/* - *---------------------------------------------------------------------- - * - * TkpOpenDisplay -- - * - * Create the Display structure and fill it with device specific - * information. - * - * Results: - * Returns a TkDisplay structure on success or NULL on failure. - * - * Side effects: - * Allocates a new TkDisplay structure. - * - *---------------------------------------------------------------------- - */ - -TkDisplay * -TkpOpenDisplay( - const char *display_name) -{ - Screen *screen; - TkWinDrawable *twdPtr; - Display *display; - ThreadSpecificData *tsdPtr = - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (tsdPtr->winDisplay != NULL) { - if (!strcmp(tsdPtr->winDisplay->display->display_name, display_name)) { - return tsdPtr->winDisplay; - } else { - return NULL; - } - } - - display = ckalloc(sizeof(Display)); - ZeroMemory(display, sizeof(Display)); - - display->display_name = ckalloc(strlen(display_name) + 1); - strcpy(display->display_name, display_name); - - display->cursor_font = 1; - display->nscreens = 1; - display->request = 1; - display->qlen = 0; - - screen = ckalloc(sizeof(Screen)); - ZeroMemory(screen, sizeof(Screen)); - screen->display = display; - - /* - * Set up the root window. - */ - - twdPtr = ckalloc(sizeof(TkWinDrawable)); - if (twdPtr == NULL) { - return None; - } - twdPtr->type = TWD_WINDOW; - twdPtr->window.winPtr = NULL; - twdPtr->window.handle = NULL; - screen->root = (Window)twdPtr; - - /* - * Note that these pixel values are not palette relative. - */ - - screen->white_pixel = RGB(255, 255, 255); - screen->black_pixel = RGB(0, 0, 0); - screen->cmap = None; - - display->screens = screen; - display->nscreens = 1; - display->default_screen = 0; - - TkWinDisplayChanged(display); - - tsdPtr->winDisplay = ckalloc(sizeof(TkDisplay)); - ZeroMemory(tsdPtr->winDisplay, sizeof(TkDisplay)); - tsdPtr->winDisplay->display = display; - tsdPtr->updatingClipboard = FALSE; - - return tsdPtr->winDisplay; -} - -/* - *---------------------------------------------------------------------- - * - * TkpCloseDisplay -- - * - * Closes and deallocates a Display structure created with the - * TkpOpenDisplay function. - * - * Results: - * None. - * - * Side effects: - * Frees up memory. - * - *---------------------------------------------------------------------- - */ - -void -TkpCloseDisplay( - TkDisplay *dispPtr) -{ - Display *display = dispPtr->display; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (dispPtr != tsdPtr->winDisplay) { - Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on another display"); - return; /* not reached */ - } - - tsdPtr->winDisplay = NULL; - - if (display->display_name != NULL) { - ckfree(display->display_name); - } - if (display->screens != NULL) { - if (display->screens->root_visual != NULL) { - ckfree(display->screens->root_visual); - } - if (display->screens->root != None) { - ckfree(display->screens->root); - } - if (display->screens->cmap != None) { - XFreeColormap(display, display->screens->cmap); - } - ckfree(display->screens); - } - ckfree(display); -} - -/* - *---------------------------------------------------------------------- - * - * TkClipCleanup -- - * - * This function is called to cleanup resources associated with claiming - * clipboard ownership and for receiving selection get results. This - * function is called in tkWindow.c. This has to be called by the display - * cleanup function because we still need the access display elements. - * - * Results: - * None. - * - * Side effects: - * Resources are freed - the clipboard may no longer be used. - * - *---------------------------------------------------------------------- - */ - -void -TkClipCleanup( - TkDisplay *dispPtr) /* Display associated with clipboard. */ -{ - if (dispPtr->clipWindow != NULL) { - Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, - dispPtr->applicationAtom); - Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, - dispPtr->windowAtom); - - Tk_DestroyWindow(dispPtr->clipWindow); - Tcl_Release((ClientData) dispPtr->clipWindow); - dispPtr->clipWindow = NULL; - } -} - -/* - *---------------------------------------------------------------------- - * - * XBell -- - * - * Generate a beep. - * - * Results: - * None. - * - * Side effects: - * Plays a sounds out the system speakers. - * - *---------------------------------------------------------------------- - */ - -int -XBell( - Display *display, - int percent) -{ - MessageBeep(MB_OK); - return Success; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinChildProc -- - * - * Callback from Windows whenever an event occurs on a child window. - * - * Results: - * Standard Windows return value. - * - * Side effects: - * May process events off the Tk event queue. - * - *---------------------------------------------------------------------- - */ - -LRESULT CALLBACK -TkWinChildProc( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - LRESULT result; - - switch (message) { - case WM_INPUTLANGCHANGE: - UpdateInputLanguage((int) wParam); - result = 1; - break; - - case WM_IME_COMPOSITION: - result = 0; - if (HandleIMEComposition(hwnd, lParam) == 0) { - result = DefWindowProc(hwnd, message, wParam, lParam); - } - break; - - case WM_SETCURSOR: - /* - * Short circuit the WM_SETCURSOR message since we set the cursor - * elsewhere. - */ - - result = TRUE; - break; - - case WM_CREATE: - case WM_ERASEBKGND: - result = 0; - break; - - case WM_PAINT: - GenerateXEvent(hwnd, message, wParam, lParam); - result = DefWindowProc(hwnd, message, wParam, lParam); - break; - - case TK_CLAIMFOCUS: - case TK_GEOMETRYREQ: - case TK_ATTACHWINDOW: - case TK_DETACHWINDOW: - case TK_ICONIFY: - case TK_DEICONIFY: - case TK_MOVEWINDOW: - case TK_WITHDRAW: - case TK_RAISEWINDOW: - case TK_GETFRAMEWID: - case TK_OVERRIDEREDIRECT: - case TK_SETMENU: - case TK_STATE: - case TK_INFO: - result = TkWinEmbeddedEventProc(hwnd, message, wParam, lParam); - break; - - case WM_UNICHAR: - if (wParam == UNICODE_NOCHAR) { - /* If wParam is UNICODE_NOCHAR and the application processes - * this message, then return TRUE. */ - result = 1; - } else { - /* If the event was translated, we must return 0 */ - if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) { - result = 0; - } else { - result = 1; - } - } - break; - - default: - if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) { - result = DefWindowProc(hwnd, message, wParam, lParam); - } - break; - } - - /* - * Handle any newly queued events before returning control to Windows. - */ - - Tcl_ServiceAll(); - return result; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_TranslateWinEvent -- - * - * This function is called by widget window functions to handle the - * translation from Win32 events to Tk events. - * - * Results: - * Returns 1 if the event was handled, else 0. - * - * Side effects: - * Depends on the event. - * - *---------------------------------------------------------------------- - */ - -int -Tk_TranslateWinEvent( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam, - LRESULT *resultPtr) -{ - *resultPtr = 0; - switch (message) { - case WM_RENDERFORMAT: { - TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); - - if (winPtr) { - TkWinClipboardRender(winPtr->dispPtr, wParam); - } - return 1; - } - - case WM_RENDERALLFORMATS: { - TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); - - if (winPtr && OpenClipboard(hwnd)) { - /* - * Make sure that nobody had taken ownership of the clipboard - * before we opened it. - */ - - if (GetClipboardOwner() == hwnd) { - TkWinClipboardRender(winPtr->dispPtr, CF_TEXT); - } - CloseClipboard(); - } - return 1; - } - - case WM_COMMAND: - case WM_NOTIFY: - case WM_VSCROLL: - case WM_HSCROLL: { - /* - * Reflect these messages back to the sender so that they can be - * handled by the window proc for the control. Note that we need to be - * careful not to reflect a message that is targeted to this window, - * or we will loop. - */ - - HWND target = (message == WM_NOTIFY) - ? ((NMHDR*)lParam)->hwndFrom : (HWND) lParam; - - if (target && target != hwnd) { - *resultPtr = SendMessage(target, message, wParam, lParam); - return 1; - } - break; - } - - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - case WM_MOUSEMOVE: - Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam)); - return 1; - - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - if (wParam == VK_PACKET) { - /* - * This will trigger WM_CHAR event(s) with unicode data. - */ - *resultPtr = - PostMessageW(hwnd, message, HIWORD(lParam), LOWORD(lParam)); - return 1; - } - /* else fall through */ - case WM_CLOSE: - case WM_SETFOCUS: - case WM_KILLFOCUS: - case WM_DESTROYCLIPBOARD: - case WM_UNICHAR: - case WM_CHAR: - case WM_SYSKEYUP: - case WM_KEYUP: - case WM_MOUSEWHEEL: - GenerateXEvent(hwnd, message, wParam, lParam); - return 1; - case WM_MENUCHAR: - GenerateXEvent(hwnd, message, wParam, lParam); - - /* - * MNC_CLOSE is the only one that looks right. This is a hack. - */ - - *resultPtr = MAKELONG (0, MNC_CLOSE); - return 1; - } - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * GenerateXEvent -- - * - * This routine generates an X event from the corresponding Windows - * event. - * - * Results: - * None. - * - * Side effects: - * Queues one or more X events. - * - *---------------------------------------------------------------------- - */ - -static void -GenerateXEvent( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - XEvent event; - TkWindow *winPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - if (message == WM_MOUSEWHEEL) { - union {LPARAM lParam; POINTS point;} root; - POINT pos; - root.lParam = lParam; - - /* - * Redirect mousewheel events to the window containing the cursor. - * That feels much less strange to users, and is how all the other - * platforms work. - */ - - pos.x = root.point.x; - pos.y = root.point.y; - hwnd = WindowFromPoint(pos); - } - - winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); - if (!winPtr || winPtr->window == None) { - return; - } - - memset(&event, 0, sizeof(XEvent)); - event.xany.serial = winPtr->display->request++; - event.xany.send_event = False; - event.xany.display = winPtr->display; - event.xany.window = winPtr->window; - - switch (message) { - case WM_PAINT: { - PAINTSTRUCT ps; - - event.type = Expose; - BeginPaint(hwnd, &ps); - event.xexpose.x = ps.rcPaint.left; - event.xexpose.y = ps.rcPaint.top; - event.xexpose.width = ps.rcPaint.right - ps.rcPaint.left; - event.xexpose.height = ps.rcPaint.bottom - ps.rcPaint.top; - EndPaint(hwnd, &ps); - event.xexpose.count = 0; - break; - } - - case WM_CLOSE: - event.type = ClientMessage; - event.xclient.message_type = - Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS"); - event.xclient.format = 32; - event.xclient.data.l[0] = - Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW"); - break; - - case WM_SETFOCUS: - case WM_KILLFOCUS: { - TkWindow *otherWinPtr = (TkWindow *) Tk_HWNDToWindow((HWND) wParam); - - /* - * Compare toplevel windows to avoid reporting focus changes within - * the same toplevel. - */ - - while (!(winPtr->flags & TK_TOP_LEVEL)) { - winPtr = winPtr->parentPtr; - if (winPtr == NULL) { - return; - } - } - while (otherWinPtr && !(otherWinPtr->flags & TK_TOP_LEVEL)) { - otherWinPtr = otherWinPtr->parentPtr; - } - - /* - * Do a catch-all Tk_SetCaretPos here to make sure that the window - * receiving focus sets the caret at least once. - */ - - if (message == WM_SETFOCUS) { - Tk_SetCaretPos((Tk_Window) winPtr, 0, 0, 0); - } - - if (otherWinPtr == winPtr) { - return; - } - - event.xany.window = winPtr->window; - event.type = (message == WM_SETFOCUS) ? FocusIn : FocusOut; - event.xfocus.mode = NotifyNormal; - event.xfocus.detail = NotifyNonlinear; - - /* - * Destroy the caret if we own it. If we are moving to another Tk - * window, it will reclaim and reposition it with Tk_SetCaretPos. - */ - - if (message == WM_KILLFOCUS) { - DestroyCaret(); - } - break; - } - - case WM_DESTROYCLIPBOARD: - if (tsdPtr->updatingClipboard == TRUE) { - /* - * We want to avoid this event if we are the ones that caused this - * event. - */ - - return; - } - event.type = SelectionClear; - event.xselectionclear.selection = - Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD"); - event.xselectionclear.time = TkpGetMS(); - break; - - case WM_MOUSEWHEEL: - case WM_CHAR: - case WM_UNICHAR: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - case WM_KEYDOWN: - case WM_KEYUP: { - unsigned int state = GetState(message, wParam, lParam); - Time time = TkpGetMS(); - POINT clientPoint; - union {DWORD msgpos; POINTS point;} root; /* Note: POINT and POINTS are different */ - - /* - * Compute the screen and window coordinates of the event. - */ - - root.msgpos = GetMessagePos(); - clientPoint.x = root.point.x; - clientPoint.y = root.point.y; - ScreenToClient(hwnd, &clientPoint); - - /* - * Set up the common event fields. - */ - - event.xbutton.root = RootWindow(winPtr->display, winPtr->screenNum); - event.xbutton.subwindow = None; - event.xbutton.x = clientPoint.x; - event.xbutton.y = clientPoint.y; - event.xbutton.x_root = root.point.x; - event.xbutton.y_root = root.point.y; - event.xbutton.state = state; - event.xbutton.time = time; - event.xbutton.same_screen = True; - - /* - * Now set up event specific fields. - */ - - switch (message) { - case WM_MOUSEWHEEL: - /* - * We have invented a new X event type to handle this event. It - * still uses the KeyPress struct. However, the keycode field has - * been overloaded to hold the zDelta of the wheel. Set nbytes to - * 0 to prevent conversion of the keycode to a keysym in - * TkpGetString. [Bug 1118340]. - */ - - event.type = MouseWheelEvent; - event.xany.send_event = -1; - event.xkey.nbytes = 0; - event.xkey.keycode = (short) HIWORD(wParam); - break; - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - /* - * Check for translated characters in the event queue. Setting - * xany.send_event to -1 indicates to the Windows implementation - * of TkpGetString() that this event was generated by windows and - * that the Windows extension xkey.trans_chars is filled with the - * MBCS characters that came from the TranslateMessage call. - */ - - event.type = KeyPress; - event.xany.send_event = -1; - event.xkey.keycode = wParam; - GetTranslatedKey(&event.xkey, (message == WM_KEYDOWN) ? WM_CHAR : - WM_SYSCHAR); - break; - - case WM_SYSKEYUP: - case WM_KEYUP: - /* - * We don't check for translated characters on keyup because Tk - * won't know what to do with them. Instead, we wait for the - * WM_CHAR messages which will follow. - */ - - event.type = KeyRelease; - event.xkey.keycode = wParam; - event.xkey.nbytes = 0; - break; - - case WM_CHAR: - /* - * Synthesize both a KeyPress and a KeyRelease. Strings generated - * by Input Method Editor are handled in the following manner: - * 1. A series of WM_KEYDOWN & WM_KEYUP messages that cause - * GetTranslatedKey() to be called and return immediately - * because the WM_KEYDOWNs have no associated WM_CHAR messages - * -- the IME window is accumulating the characters and - * translating them itself. In the "bind" command, you get an - * event with a mystery keysym and %A == "" for each WM_KEYDOWN - * that actually was meant for the IME. - * 2. A WM_KEYDOWN corresponding to the "confirm typing" - * character. This causes GetTranslatedKey() to be called. - * 3. A WM_IME_NOTIFY message saying that the IME is done. A side - * effect of this message is that GetTranslatedKey() thinks - * this means that there are no WM_CHAR messages and returns - * immediately. In the "bind" command, you get an another event - * with a mystery keysym and %A == "". - * 4. A sequence of WM_CHAR messages that correspond to the - * characters in the IME window. A bunch of simulated - * KeyPress/KeyRelease events will be generated, one for each - * character. Adjacent WM_CHAR messages may actually specify - * the high and low bytes of a multi-byte character -- in that - * case the two WM_CHAR messages will be combined into one - * event. It is the event-consumer's responsibility to convert - * the string returned from XLookupString from system encoding - * to UTF-8. - * 5. And finally we get the WM_KEYUP for the "confirm typing" - * character. - */ - - event.type = KeyPress; - event.xany.send_event = -1; - event.xkey.keycode = 0; - if ((int)wParam & 0xff00) { - int ch1 = wParam & 0xffff; - - if ((ch1 & 0xfc00) == 0xd800) { - tsdPtr->surrogateBuffer = ch1; - return; - } - if ((ch1 & 0xfc00) == 0xdc00) { - ch1 = ((tsdPtr->surrogateBuffer & 0x3ff) << 10) | - (ch1 & 0x3ff) | 0x10000; - tsdPtr->surrogateBuffer = 0; - } - event.xany.send_event = -3; - event.xkey.nbytes = 0; - event.xkey.keycode = ch1; - } else { - event.xkey.nbytes = 1; - event.xkey.trans_chars[0] = (char) wParam; - - if (IsDBCSLeadByte((BYTE) wParam)) { - MSG msg; - - if ((PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR, - PM_NOREMOVE) != 0) - && (msg.message == WM_CHAR)) { - GetMessage(&msg, NULL, WM_CHAR, WM_CHAR); - event.xkey.nbytes = 2; - event.xkey.trans_chars[1] = (char) msg.wParam; - } - } - } - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - event.type = KeyRelease; - break; - - case WM_UNICHAR: { - event.type = KeyPress; - event.xany.send_event = -3; - event.xkey.keycode = wParam; - event.xkey.nbytes = 0; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - event.type = KeyRelease; - break; - } - - } - break; - } - - default: - /* - * Don't know how to translate this event, so ignore it. (It probably - * should not have got here, but ignoring it should be harmless.) - */ - - return; - } - - /* - * Post the translated event to the main Tk event queue. - */ - - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); -} - -/* - *---------------------------------------------------------------------- - * - * GetState -- - * - * This function constructs a state mask for the mouse buttons and - * modifier keys as they were before the event occured. - * - * Results: - * Returns a composite value of all the modifier and button state flags - * that were set at the time the event occurred. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static unsigned int -GetState( - UINT message, /* Win32 message type */ - WPARAM wParam, /* wParam of message, used if key message */ - LPARAM lParam) /* lParam of message, used if key message */ -{ - int mask; - int prevState; /* 1 if key was previously down */ - unsigned int state = TkWinGetModifierState(); - - /* - * If the event is a key press or release, we check for modifier keys so - * we can report the state of the world before the event. - */ - - if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN - || message == WM_SYSKEYUP || message == WM_KEYUP) { - mask = 0; - prevState = HIWORD(lParam) & KF_REPEAT; - switch(wParam) { - case VK_SHIFT: - mask = ShiftMask; - break; - case VK_CONTROL: - mask = ControlMask; - break; - case VK_MENU: - mask = ALT_MASK; - break; - case VK_CAPITAL: - if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) { - mask = LockMask; - prevState = ((state & mask) ^ prevState) ? 0 : 1; - } - break; - case VK_NUMLOCK: - if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) { - mask = Mod1Mask; - prevState = ((state & mask) ^ prevState) ? 0 : 1; - } - break; - case VK_SCROLL: - if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) { - mask = Mod3Mask; - prevState = ((state & mask) ^ prevState) ? 0 : 1; - } - break; - } - if (prevState) { - state |= mask; - } else { - state &= ~mask; - } - if (HIWORD(lParam) & KF_EXTENDED) { - state |= EXTENDED_MASK; - } - } - return state; -} - -/* - *---------------------------------------------------------------------- - * - * GetTranslatedKey -- - * - * Retrieves WM_CHAR messages that are placed on the system queue by the - * TranslateMessage system call and places them in the given KeyPress - * event. - * - * Results: - * Sets the trans_chars and nbytes member of the key event. - * - * Side effects: - * Removes any WM_CHAR messages waiting on the top of the system event - * queue. - * - *---------------------------------------------------------------------- - */ - -static void -GetTranslatedKey( - XKeyEvent *xkey, - UINT type) -{ - MSG msg; - - xkey->nbytes = 0; - - while ((xkey->nbytes < XMaxTransChars) - && (PeekMessageA(&msg, NULL, type, type, PM_NOREMOVE) != 0)) { - if (msg.message != type) { - break; - } - - GetMessageA(&msg, NULL, type, type); - - /* - * If this is a normal character message, we may need to strip off the - * Alt modifier (e.g. Alt-digits). Note that we don't want to do this - * for system messages, because those were presumably generated as an - * Alt-char sequence (e.g. accelerator keys). - */ - - if ((msg.message == WM_CHAR) && (msg.lParam & 0x20000000)) { - xkey->state = 0; - } - xkey->trans_chars[xkey->nbytes] = (char) msg.wParam; - xkey->nbytes++; - - if (((unsigned short) msg.wParam) > ((unsigned short) 0xff)) { - /* - * Some "addon" input devices, such as the popular PenPower - * Chinese writing pad, generate 16 bit values in WM_CHAR messages - * (instead of passing them in two separate WM_CHAR messages - * containing two 8-bit values. - */ - - xkey->trans_chars[xkey->nbytes] = (char) (msg.wParam >> 8); - xkey->nbytes ++; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * UpdateInputLanguage -- - * - * Gets called when a WM_INPUTLANGCHANGE message is received by the Tk - * child window function. This message is sent by the Input Method Editor - * system when the user chooses a different input method. All subsequent - * WM_CHAR messages will contain characters in the new encoding. We - * record the new encoding so that TkpGetString() knows how to correctly - * translate the WM_CHAR into unicode. - * - * Results: - * Records the new encoding in keyInputEncoding. - * - * Side effects: - * Old value of keyInputEncoding is freed. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateInputLanguage( - int charset) -{ - CHARSETINFO charsetInfo; - Tcl_Encoding encoding; - char codepage[4 + TCL_INTEGER_SPACE]; - - if (keyInputCharset == charset) { - return; - } - if (TranslateCharsetInfo(INT2PTR(charset), &charsetInfo, - TCI_SRCCHARSET) == 0) { - /* - * Some mysterious failure. - */ - - return; - } - - wsprintfA(codepage, "cp%d", charsetInfo.ciACP); - - if ((encoding = Tcl_GetEncoding(NULL, codepage)) == NULL) { - /* - * The encoding is not supported by Tcl. - */ - - return; - } - - if (keyInputEncoding != NULL) { - Tcl_FreeEncoding(keyInputEncoding); - } - - keyInputEncoding = encoding; - keyInputCharset = charset; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinGetKeyInputEncoding -- - * - * Returns the current keyboard input encoding selected by the user (with - * WM_INPUTLANGCHANGE events). - * - * Results: - * The current keyboard input encoding. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_Encoding -TkWinGetKeyInputEncoding(void) -{ - return keyInputEncoding; -} - -/* - *---------------------------------------------------------------------- - * - * TkWinGetUnicodeEncoding -- - * - * Returns the cached unicode encoding. - * - * Results: - * The unicode encoding. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_Encoding -TkWinGetUnicodeEncoding(void) -{ - if (unicodeEncoding == NULL) { - unicodeEncoding = Tcl_GetEncoding(NULL, "unicode"); - } - return unicodeEncoding; -} - -/* - *---------------------------------------------------------------------- - * - * HandleIMEComposition -- - * - * This function works around a deficiency in some versions of Windows - * 2000 to make it possible to entry multi-lingual characters under all - * versions of Windows 2000. - * - * When an Input Method Editor (IME) is ready to send input characters to - * an application, it sends a WM_IME_COMPOSITION message with the - * GCS_RESULTSTR. However, The DefWindowProc() on English Windows 2000 - * arbitrarily converts all non-Latin-1 characters in the composition to - * "?". - * - * This function correctly processes the composition data and sends the - * UNICODE values of the composed characters to TK's event queue. - * - * Results: - * If this function has processed the composition data, returns 1. - * Otherwise returns 0. - * - * Side effects: - * Key events are put into the TK event queue. - * - *---------------------------------------------------------------------- - */ - -static int -HandleIMEComposition( - HWND hwnd, /* Window receiving the message. */ - LPARAM lParam) /* Flags for the WM_IME_COMPOSITION message */ -{ - HIMC hIMC; - int n; - int high = 0; - - if ((lParam & GCS_RESULTSTR) == 0) { - /* - * Composition is not finished yet. - */ - - return 0; - } - - hIMC = ImmGetContext(hwnd); - if (!hIMC) { - return 0; - } - - n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); - - if (n > 0) { - WCHAR *buff = (WCHAR *) ckalloc(n); - TkWindow *winPtr; - XEvent event; - int i; - - n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, buff, (unsigned) n) / 2; - - /* - * Set up the fields pertinent to key event. - * - * We set send_event to the special value of -3, so that TkpGetString - * in tkWinKey.c knows that keycode already contains a UNICODE - * char and there's no need to do encoding conversion. - * - * Note that the event *must* be zeroed out first; Tk plays cunning - * games with the overalls structure. [Bug 2992129] - */ - - winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); - - memset(&event, 0, sizeof(XEvent)); - event.xkey.serial = winPtr->display->request++; - event.xkey.send_event = -3; - event.xkey.display = winPtr->display; - event.xkey.window = winPtr->window; - event.xkey.root = RootWindow(winPtr->display, winPtr->screenNum); - event.xkey.subwindow = None; - event.xkey.state = TkWinGetModifierState(); - event.xkey.time = TkpGetMS(); - event.xkey.same_screen = True; - - for (i=0; i<n; ) { - /* - * Simulate a pair of KeyPress and KeyRelease events for each - * UNICODE character in the composition. - */ - - event.xkey.keycode = buff[i++]; - - if ((event.xkey.keycode & 0xfc00) == 0xd800) { - high = ((event.xkey.keycode & 0x3ff) << 10) + 0x10000; - break; - } else if (high && (event.xkey.keycode & 0xfc00) == 0xdc00) { - event.xkey.keycode &= 0x3ff; - event.xkey.keycode += high; - high = 0; - } - event.type = KeyPress; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - - event.type = KeyRelease; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - } - - ckfree(buff); - } - ImmReleaseContext(hwnd, hIMC); - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_FreeXId -- - * - * This interface is not needed under Windows. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -Tk_FreeXId( - Display *display, - XID xid) -{ - /* Do nothing */ -} - -/* - *---------------------------------------------------------------------- - * - * TkWinResendEvent -- - * - * This function converts an X event into a Windows event and invokes the - * specified windo function. - * - * Results: - * A standard Windows result. - * - * Side effects: - * Invokes the window function - * - *---------------------------------------------------------------------- - */ - -LRESULT -TkWinResendEvent( - WNDPROC wndproc, - HWND hwnd, - XEvent *eventPtr) -{ - UINT msg; - WPARAM wparam; - LPARAM lparam; - - if (eventPtr->type != ButtonPress) { - return 0; - } - - switch (eventPtr->xbutton.button) { - case Button1: - msg = WM_LBUTTONDOWN; - wparam = MK_LBUTTON; - break; - case Button2: - msg = WM_MBUTTONDOWN; - wparam = MK_MBUTTON; - break; - case Button3: - msg = WM_RBUTTONDOWN; - wparam = MK_RBUTTON; - break; - default: - return 0; - } - - if (eventPtr->xbutton.state & Button1Mask) { - wparam |= MK_LBUTTON; - } - if (eventPtr->xbutton.state & Button2Mask) { - wparam |= MK_MBUTTON; - } - if (eventPtr->xbutton.state & Button3Mask) { - wparam |= MK_RBUTTON; - } - if (eventPtr->xbutton.state & ShiftMask) { - wparam |= MK_SHIFT; - } - if (eventPtr->xbutton.state & ControlMask) { - wparam |= MK_CONTROL; - } - lparam = MAKELPARAM((short) eventPtr->xbutton.x, - (short) eventPtr->xbutton.y); - return CallWindowProc(wndproc, hwnd, msg, wparam, lparam); -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetMS -- - * - * Return a relative time in milliseconds. It doesn't matter when the - * epoch was. - * - * Results: - * Number of milliseconds. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -unsigned long -TkpGetMS(void) -{ - return GetTickCount(); -} - -/* - *---------------------------------------------------------------------- - * - * TkWinUpdatingClipboard -- - * - * - * Results: - * Number of milliseconds. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkWinUpdatingClipboard( - int mode) -{ - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - tsdPtr->updatingClipboard = mode; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_SetCaretPos -- - * - * This enables correct movement of focus in the MS Magnifier, as well as - * allowing us to correctly position the IME Window. The following Win32 - * APIs are used to work with MS caret: - * - * CreateCaret DestroyCaret SetCaretPos GetCaretPos - * - * Only one instance of caret can be active at any time (e.g. - * DestroyCaret API does not take any argument such as handle). Since - * do-it-right approach requires to track the create/destroy caret status - * all the time in a global scope among windows (or widgets), we just - * implement this minimal setup to get the job done. - * - * Results: - * None - * - * Side effects: - * Sets the global Windows caret position. - * - *---------------------------------------------------------------------- - */ - -void -Tk_SetCaretPos( - Tk_Window tkwin, - int x, int y, - int height) -{ - static HWND caretHWND = NULL; - TkCaret *caretPtr = &(((TkWindow *) tkwin)->dispPtr->caret); - Window win; - - /* - * Prevent processing anything if the values haven't changed. Windows only - * has one display, so we can do this with statics. - */ - - if ((caretPtr->winPtr == ((TkWindow *) tkwin)) - && (caretPtr->x == x) && (caretPtr->y == y)) { - return; - } - - caretPtr->winPtr = ((TkWindow *) tkwin); - caretPtr->x = x; - caretPtr->y = y; - caretPtr->height = height; - - /* - * We adjust to the toplevel to get the coords right, as setting the IME - * composition window is based on the toplevel hwnd, so ignore height. - */ - - while (!Tk_IsTopLevel(tkwin)) { - x += Tk_X(tkwin); - y += Tk_Y(tkwin); - tkwin = Tk_Parent(tkwin); - if (tkwin == NULL) { - return; - } - } - - win = Tk_WindowId(tkwin); - if (win) { - HIMC hIMC; - HWND hwnd = Tk_GetHWND(win); - - if (hwnd != caretHWND) { - DestroyCaret(); - if (CreateCaret(hwnd, NULL, 0, 0)) { - caretHWND = hwnd; - } - } - - if (!SetCaretPos(x, y) && CreateCaret(hwnd, NULL, 0, 0)) { - caretHWND = hwnd; - SetCaretPos(x, y); - } - - /* - * The IME composition window should be updated whenever the caret - * position is changed because a clause of the composition string may - * be converted to the final characters and the other clauses still - * stay on the composition window. -- yamamoto - */ - - hIMC = ImmGetContext(hwnd); - if (hIMC) { - COMPOSITIONFORM cform; - - cform.dwStyle = CFS_POINT; - cform.ptCurrentPos.x = x; - cform.ptCurrentPos.y = y; - ImmSetCompositionWindow(hIMC, &cform); - ImmReleaseContext(hwnd, hIMC); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetUserInactiveTime -- - * - * Return the number of milliseconds the user was inactive. - * - * Results: - * Milliseconds of user inactive time or -1 if the user32.dll doesn't - * have the symbol GetLastInputInfo or GetLastInputInfo returns an error. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -long -Tk_GetUserInactiveTime( - Display *dpy) /* Ignored on Windows */ -{ - LASTINPUTINFO li; - - li.cbSize = sizeof(li); - if (!(BOOL)GetLastInputInfo(&li)) { - return -1; - } - - /* - * Last input info is in milliseconds, since restart time. - */ - - return (GetTickCount()-li.dwTime); -} - -/* - *---------------------------------------------------------------------- - * - * Tk_ResetUserInactiveTime -- - * - * Reset the user inactivity timer - * - * Results: - * none - * - * Side effects: - * The user inactivity timer of the underlaying windowing system is reset - * to zero. - * - *---------------------------------------------------------------------- - */ - -void -Tk_ResetUserInactiveTime( - Display *dpy) -{ - INPUT inp; - - inp.type = INPUT_MOUSE; - inp.mi.dx = 0; - inp.mi.dy = 0; - inp.mi.mouseData = 0; - inp.mi.dwFlags = MOUSEEVENTF_MOVE; - inp.mi.time = 0; - inp.mi.dwExtraInfo = (DWORD) 0; - - SendInput(1, &inp, sizeof(inp)); -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/ttkWinMonitor.c b/tk8.6/win/ttkWinMonitor.c deleted file mode 100644 index 6e46374..0000000 --- a/tk8.6/win/ttkWinMonitor.c +++ /dev/null @@ -1,161 +0,0 @@ -#ifdef _MSC_VER -#define WIN32_LEAN_AND_MEAN -#endif - -#include <tkWinInt.h> -#include "ttk/ttkTheme.h" - -#if !defined(WM_THEMECHANGED) -#define WM_THEMECHANGED 0x031A -#endif - -static LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); - -/* - * RegisterSystemColors -- - * Register all known Windows system colors (as per GetSysColor) as Tk - * named colors. - */ - -typedef struct { - const char *name; - int index; -} SystemColorEntry; - -static SystemColorEntry sysColors[] = { - { "System3dDarkShadow", COLOR_3DDKSHADOW }, - { "System3dLight", COLOR_3DLIGHT }, - { "SystemActiveBorder", COLOR_ACTIVEBORDER }, - { "SystemActiveCaption", COLOR_ACTIVECAPTION }, - { "SystemAppWorkspace", COLOR_APPWORKSPACE }, - { "SystemBackground", COLOR_BACKGROUND }, - { "SystemButtonFace", COLOR_BTNFACE }, - { "SystemButtonHighlight", COLOR_BTNHIGHLIGHT }, - { "SystemButtonShadow", COLOR_BTNSHADOW }, - { "SystemButtonText", COLOR_BTNTEXT }, - { "SystemCaptionText", COLOR_CAPTIONTEXT }, - { "SystemDisabledText", COLOR_GRAYTEXT }, - { "SystemGrayText", COLOR_GRAYTEXT }, - { "SystemHighlight", COLOR_HIGHLIGHT }, - { "SystemHighlightText", COLOR_HIGHLIGHTTEXT }, - { "SystemInactiveBorder", COLOR_INACTIVEBORDER }, - { "SystemInactiveCaption", COLOR_INACTIVECAPTION }, - { "SystemInactiveCaptionText", COLOR_INACTIVECAPTIONTEXT }, - { "SystemInfoBackground", COLOR_INFOBK }, - { "SystemInfoText", COLOR_INFOTEXT }, - { "SystemMenu", COLOR_MENU }, - { "SystemMenuText", COLOR_MENUTEXT }, - { "SystemScrollbar", COLOR_SCROLLBAR }, - { "SystemWindow", COLOR_WINDOW }, - { "SystemWindowFrame", COLOR_WINDOWFRAME }, - { "SystemWindowText", COLOR_WINDOWTEXT }, - { NULL, 0 } -}; - -static void RegisterSystemColors(Tcl_Interp *interp) -{ - Ttk_ResourceCache cache = Ttk_GetResourceCache(interp); - SystemColorEntry *sysColor; - - for (sysColor = sysColors; sysColor->name; ++sysColor) { - DWORD pixel = GetSysColor(sysColor->index); - XColor colorSpec; - colorSpec.red = GetRValue(pixel) * 257; - colorSpec.green = GetGValue(pixel) * 257; - colorSpec.blue = GetBValue(pixel) * 257; - Ttk_RegisterNamedColor(cache, sysColor->name, &colorSpec); - } -} - -static HWND -CreateThemeMonitorWindow(HINSTANCE hinst, Tcl_Interp *interp) -{ - WNDCLASSEX wc; - HWND hwnd = NULL; - TCHAR title[32] = TEXT("TtkMonitorWindow"); - TCHAR name[32] = TEXT("TtkMonitorClass"); - - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC)WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hinst; - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszMenuName = name; - wc.lpszClassName = name; - - if (RegisterClassEx(&wc)) { - hwnd = CreateWindow( name, title, WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, NULL, hinst, NULL ); - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) interp); - ShowWindow(hwnd, SW_HIDE); - UpdateWindow(hwnd); - } - return hwnd; -} - -static void -DestroyThemeMonitorWindow(void *clientData) -{ - HWND hwnd = (HWND)clientData; - DestroyWindow(hwnd); -} - -static LRESULT WINAPI -WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) -{ - Tcl_Interp *interp = (Tcl_Interp *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - Ttk_Theme theme; - - switch (msg) { - case WM_DESTROY: - break; - - case WM_SYSCOLORCHANGE: - RegisterSystemColors(interp); - break; - - case WM_THEMECHANGED: - /* - * Reset the application theme. - * On windows, it is possible to sign in as a second user, change - * the theme to 'winnative' (by setting the ui to 'best performance'), - * which is a machine-wide change, and then sign back on to the original user. - * Ttk_UseTheme needs to be executed again in order to process the fallback - * from vista/xpnative to winnative. - */ - - theme = Ttk_GetCurrentTheme(interp); - if (theme) { - Ttk_UseTheme(interp, theme); - /* @@@ What to do about errors here? */ - } - break; - } - return DefWindowProc(hwnd, msg, wp, lp); -} - -/* - * Windows-specific platform initialization: - */ - -MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd); -MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *, HWND hwnd); - -MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp) -{ - HWND hwnd; - - hwnd = CreateThemeMonitorWindow(Tk_GetHINSTANCE(), interp); - Ttk_RegisterCleanup(interp, (ClientData)hwnd, DestroyThemeMonitorWindow); - - TtkWinTheme_Init(interp, hwnd); - TtkXPTheme_Init(interp, hwnd); - - return TCL_OK; -} diff --git a/tk8.6/win/ttkWinTheme.c b/tk8.6/win/ttkWinTheme.c deleted file mode 100644 index 63e9704..0000000 --- a/tk8.6/win/ttkWinTheme.c +++ /dev/null @@ -1,733 +0,0 @@ -/* winTheme.c - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sf.net> - */ - -#ifdef _MSC_VER -#define WIN32_LEAN_AND_MEAN -#endif - -#include <tkWinInt.h> - -#ifndef DFCS_HOT /* Windows 98/Me, Windows 200/XP only */ -#define DFCS_HOT 0 -#endif - -#include "ttk/ttkTheme.h" - -/* - * BoxToRect -- - * Helper routine. Converts a Ttk_Box to a Win32 RECT. - */ -static RECT BoxToRect(Ttk_Box b) -{ - RECT rc; - rc.top = b.y; - rc.left = b.x; - rc.bottom = b.y + b.height; - rc.right = b.x + b.width; - return rc; -} - -/* - * ReliefToEdge -- - * Convert a Tk "relief" value into an Windows "edge" value. - * NB: Caller must check for RELIEF_FLAT and RELIEF_SOLID, - * which must be handled specially. - * - * Passing the BF_FLAT flag to DrawEdge() yields something similar - * to TK_RELIEF_SOLID. TK_RELIEF_FLAT can be implemented by not - * drawing anything. - */ -static unsigned int ReliefToEdge(int relief) -{ - switch (relief) { - case TK_RELIEF_RAISED: return EDGE_RAISED; - case TK_RELIEF_SUNKEN: return EDGE_SUNKEN; - case TK_RELIEF_RIDGE: return EDGE_BUMP; - case TK_RELIEF_GROOVE: return EDGE_ETCHED; - case TK_RELIEF_SOLID: return BDR_RAISEDOUTER; - default: - case TK_RELIEF_FLAT: return BDR_RAISEDOUTER; - } -} - -/*------------------------------------------------------------------------ - * +++ State tables for FrameControlElements. - */ - -static Ttk_StateTable checkbutton_statemap[] = { /* see also SF#1865898 */ - { DFCS_BUTTON3STATE|DFCS_CHECKED|DFCS_INACTIVE, - TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0 }, - { DFCS_BUTTON3STATE|DFCS_CHECKED|DFCS_PUSHED, - TTK_STATE_ALTERNATE|TTK_STATE_PRESSED, 0 }, - { DFCS_BUTTON3STATE|DFCS_CHECKED|DFCS_HOT, - TTK_STATE_ALTERNATE|TTK_STATE_ACTIVE, 0 }, - { DFCS_BUTTON3STATE|DFCS_CHECKED, - TTK_STATE_ALTERNATE, 0 }, - - { DFCS_CHECKED|DFCS_INACTIVE, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0 }, - { DFCS_CHECKED|DFCS_PUSHED, TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0 }, - { DFCS_CHECKED|DFCS_HOT, TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0 }, - { DFCS_CHECKED, TTK_STATE_SELECTED, 0 }, - - { DFCS_INACTIVE, TTK_STATE_DISABLED, 0 }, - { DFCS_PUSHED, TTK_STATE_PRESSED, 0 }, - { DFCS_HOT, TTK_STATE_ACTIVE, 0 }, - { 0, 0, 0 }, -}; - -static Ttk_StateTable pushbutton_statemap[] = { - { DFCS_INACTIVE, TTK_STATE_DISABLED, 0 }, - { DFCS_PUSHED, TTK_STATE_PRESSED, 0 }, - { DFCS_HOT, TTK_STATE_ACTIVE, 0 }, - { 0, 0, 0 } -}; - -static Ttk_StateTable arrow_statemap[] = { - { DFCS_INACTIVE, TTK_STATE_DISABLED, 0 }, - { DFCS_PUSHED | DFCS_FLAT, TTK_STATE_PRESSED, 0 }, - { 0, 0, 0 } -}; - -/*------------------------------------------------------------------------ - * +++ FrameControlElement -- - * General-purpose element for things drawn with DrawFrameControl - */ -typedef struct { - const char *name; /* element name */ - int classId; /* class id for DrawFrameControl */ - int partId; /* part id for DrawFrameControl */ - int cxId; /* system metric ids for width/height... */ - int cyId; /* ... or size if FIXEDSIZE bit set */ - Ttk_StateTable *stateMap; /* map Tk states to Win32 flags */ - Ttk_Padding margins; /* additional placement padding */ -} FrameControlElementData; - -#define _FIXEDSIZE 0x80000000L -#define _HALFMETRIC 0x40000000L -#define FIXEDSIZE(id) (id|_FIXEDSIZE) -#define HALFMETRIC(id) (id|_HALFMETRIC) -#define GETMETRIC(m) \ - ((m) & _FIXEDSIZE ? (int)((m) & ~_FIXEDSIZE) : GetSystemMetrics((m)&0x0fffffff)) - -static FrameControlElementData FrameControlElements[] = { - { "Checkbutton.indicator", - DFC_BUTTON, DFCS_BUTTONCHECK, FIXEDSIZE(13), FIXEDSIZE(13), - checkbutton_statemap, {0,0,4,0} }, - { "Radiobutton.indicator", - DFC_BUTTON, DFCS_BUTTONRADIO, FIXEDSIZE(13), FIXEDSIZE(13), - checkbutton_statemap, {0,0,4,0} }, - { "uparrow", - DFC_SCROLL, DFCS_SCROLLUP, SM_CXVSCROLL, SM_CYVSCROLL, - arrow_statemap, {0,0,0,0} }, - { "downarrow", - DFC_SCROLL, DFCS_SCROLLDOWN, SM_CXVSCROLL, SM_CYVSCROLL, - arrow_statemap, {0,0,0,0} }, - { "leftarrow", - DFC_SCROLL, DFCS_SCROLLLEFT, SM_CXHSCROLL, SM_CYHSCROLL, - arrow_statemap, {0,0,0,0} }, - { "rightarrow", - DFC_SCROLL, DFCS_SCROLLRIGHT, SM_CXHSCROLL, SM_CYHSCROLL, - arrow_statemap, {0,0,0,0} }, - { "sizegrip", - DFC_SCROLL, DFCS_SCROLLSIZEGRIP, SM_CXVSCROLL, SM_CYHSCROLL, - arrow_statemap, {0,0,0,0} }, - { "Spinbox.uparrow", - DFC_SCROLL, DFCS_SCROLLUP, SM_CXVSCROLL, HALFMETRIC(SM_CYVSCROLL), - arrow_statemap, {0,0,0,0} }, - { "Spinbox.downarrow", - DFC_SCROLL, DFCS_SCROLLDOWN, SM_CXVSCROLL, HALFMETRIC(SM_CYVSCROLL), - arrow_statemap, {0,0,0,0} }, - - { 0,0,0,0,0,0, {0,0,0,0} } -}; - -/* ---------------------------------------------------------------------- */ - -static void FrameControlElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - FrameControlElementData *p = clientData; - int cx = GETMETRIC(p->cxId); - int cy = GETMETRIC(p->cyId); - if (p->cxId & _HALFMETRIC) cx /= 2; - if (p->cyId & _HALFMETRIC) cy /= 2; - *widthPtr = cx + Ttk_PaddingWidth(p->margins); - *heightPtr = cy + Ttk_PaddingHeight(p->margins); -} - -static void FrameControlElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - FrameControlElementData *elementData = clientData; - RECT rc = BoxToRect(Ttk_PadBox(b, elementData->margins)); - TkWinDCState dcState; - HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - - DrawFrameControl(hdc, &rc, - elementData->classId, - elementData->partId|Ttk_StateTableLookup(elementData->stateMap, state)); - TkWinReleaseDrawableDC(d, hdc, &dcState); -} - -static Ttk_ElementSpec FrameControlElementSpec = { - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - FrameControlElementSize, - FrameControlElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Border element implementation. - */ - -typedef struct { - Tcl_Obj *reliefObj; -} BorderElement; - -static Ttk_ElementOptionSpec BorderElementOptions[] = { - { "-relief",TK_OPTION_RELIEF,Tk_Offset(BorderElement,reliefObj), "flat" }, - {NULL, 0, 0, NULL} -}; - -static void BorderElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE); - paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE); -} - -static void BorderElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - BorderElement *border = elementRecord; - RECT rc = BoxToRect(b); - int relief = TK_RELIEF_FLAT; - TkWinDCState dcState; - HDC hdc; - - Tk_GetReliefFromObj(NULL, border->reliefObj, &relief); - - if (relief != TK_RELIEF_FLAT) { - UINT xFlags = (relief == TK_RELIEF_SOLID) ? BF_FLAT : 0; - hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - DrawEdge(hdc, &rc, ReliefToEdge(relief), BF_RECT | xFlags); - TkWinReleaseDrawableDC(d, hdc, &dcState); - } -} - -static Ttk_ElementSpec BorderElementSpec = { - TK_STYLE_VERSION_2, - sizeof(BorderElement), - BorderElementOptions, - BorderElementSize, - BorderElementDraw -}; - -/* - * Entry field borders: - * Sunken border; also fill with window color. - */ - -typedef struct { - Tcl_Obj *backgroundObj; -} FieldElement; - -static Ttk_ElementOptionSpec FieldElementOptions[] = { - { "-fieldbackground", TK_OPTION_BORDER, - Tk_Offset(FieldElement,backgroundObj), "white" }, - { NULL, 0, 0, NULL } -}; - -static void FieldElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE); - paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE); -} - -static void FieldElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - FieldElement *field = elementRecord; - Tk_3DBorder bg = Tk_Get3DBorderFromObj(tkwin, field->backgroundObj); - RECT rc = BoxToRect(b); - TkWinDCState dcState; - HDC hdc; - - Tk_Fill3DRectangle( - tkwin, d, bg, b.x, b.y, b.width, b.height, 0, TK_RELIEF_FLAT); - - hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT); - TkWinReleaseDrawableDC(d, hdc, &dcState); -} - -static Ttk_ElementSpec FieldElementSpec = { - TK_STYLE_VERSION_2, - sizeof(FieldElement), - FieldElementOptions, - FieldElementSize, - FieldElementDraw -}; - -/*------------------------------------------------------------------------ - * +++ Button borders. - * Drawn with DrawFrameControl instead of DrawEdge; - * Also draw default indicator and focus ring. - */ -typedef struct { - Tcl_Obj *reliefObj; - Tcl_Obj *highlightColorObj; - Tcl_Obj *defaultStateObj; -} ButtonBorderElement; - -static Ttk_ElementOptionSpec ButtonBorderElementOptions[] = { - { "-relief",TK_OPTION_RELIEF, - Tk_Offset(ButtonBorderElement,reliefObj), "flat" }, - { "-highlightcolor",TK_OPTION_COLOR, - Tk_Offset(ButtonBorderElement,highlightColorObj), "black" }, - { "-default", TK_OPTION_ANY, - Tk_Offset(ButtonBorderElement,defaultStateObj), "disabled" }, - {NULL, 0, 0, NULL} -}; - -static void ButtonBorderElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - ButtonBorderElement *bd = elementRecord; - int relief = TK_RELIEF_RAISED; - int defaultState = TTK_BUTTON_DEFAULT_DISABLED; - short int cx, cy; - - Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief); - Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState); - cx = GetSystemMetrics(SM_CXEDGE); - cy = GetSystemMetrics(SM_CYEDGE); - - /* Space for default indicator: - */ - if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) { - ++cx; ++cy; - } - - /* Space for focus ring: - */ - cx += 2; - cy += 2; - - *paddingPtr = Ttk_MakePadding(cx,cy,cx,cy); -} - -static void ButtonBorderElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - ButtonBorderElement *bd = elementRecord; - int relief = TK_RELIEF_FLAT; - int defaultState = TTK_BUTTON_DEFAULT_DISABLED; - TkWinDCState dcState; - HDC hdc; - RECT rc; - - Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief); - Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState); - - if (defaultState == TTK_BUTTON_DEFAULT_ACTIVE) { - XColor *highlightColor = - Tk_GetColorFromObj(tkwin, bd->highlightColorObj); - GC gc = Tk_GCForColor(highlightColor, d); - XDrawRectangle(Tk_Display(tkwin), d, gc, b.x,b.y,b.width-1,b.height-1); - } - if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) { - ++b.x; ++b.y; b.width -= 2; b.height -= 2; - } - - hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - - rc = BoxToRect(b); - DrawFrameControl(hdc, &rc, - DFC_BUTTON, /* classId */ - DFCS_BUTTONPUSH | Ttk_StateTableLookup(pushbutton_statemap, state)); - - /* Draw focus ring: - */ - if (state & TTK_STATE_FOCUS) { - short int borderWidth = 3; /* @@@ Use GetSystemMetrics?*/ - rc = BoxToRect(Ttk_PadBox(b, Ttk_UniformPadding(borderWidth))); - DrawFocusRect(hdc, &rc); - } - TkWinReleaseDrawableDC(d, hdc, &dcState); -} - -static Ttk_ElementSpec ButtonBorderElementSpec = { - TK_STYLE_VERSION_2, - sizeof(ButtonBorderElement), - ButtonBorderElementOptions, - ButtonBorderElementSize, - ButtonBorderElementDraw -}; - -/*------------------------------------------------------------------------ - * +++ Focus element. - * Draw dashed focus rectangle. - */ - -static void FocusElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - *paddingPtr = Ttk_UniformPadding(1); -} - -static void FocusElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - if (state & TTK_STATE_FOCUS) { - RECT rc = BoxToRect(b); - TkWinDCState dcState; - HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - DrawFocusRect(hdc, &rc); - TkWinReleaseDrawableDC(d, hdc, &dcState); - } -} - -static Ttk_ElementSpec FocusElementSpec = { - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - FocusElementSize, - FocusElementDraw -}; - -/* FillFocusElement -- - * Draws a focus ring filled with the selection color - */ - -typedef struct { - Tcl_Obj *fillColorObj; -} FillFocusElement; - -static Ttk_ElementOptionSpec FillFocusElementOptions[] = { - { "-focusfill", TK_OPTION_COLOR, - Tk_Offset(FillFocusElement,fillColorObj), "white" }, - {NULL, 0, 0, NULL} -}; - - /* @@@ FIX THIS */ -static void FillFocusElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - FillFocusElement *focus = elementRecord; - if (state & TTK_STATE_FOCUS) { - RECT rc = BoxToRect(b); - TkWinDCState dcState; - XColor *fillColor = Tk_GetColorFromObj(tkwin, focus->fillColorObj); - GC gc = Tk_GCForColor(fillColor, d); - HDC hdc; - - XFillRectangle(Tk_Display(tkwin),d,gc, b.x,b.y,b.width,b.height); - hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - DrawFocusRect(hdc, &rc); - TkWinReleaseDrawableDC(d, hdc, &dcState); - } -} - -/* - * ComboboxFocusElement -- - * Read-only comboboxes have a filled focus ring, editable ones do not. - */ -static void ComboboxFocusElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - if (state & TTK_STATE_READONLY) { - FillFocusElementDraw(clientData, elementRecord, tkwin, d, b, state); - } -} - -static Ttk_ElementSpec ComboboxFocusElementSpec = { - TK_STYLE_VERSION_2, - sizeof(FillFocusElement), - FillFocusElementOptions, - FocusElementSize, - ComboboxFocusElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Scrollbar trough element. - * - * The native windows scrollbar is drawn using a pattern brush giving a - * stippled appearance when the trough might otherwise be invisible. - * We can deal with this here. - */ - -typedef struct { /* clientData for Trough element */ - HBRUSH PatternBrush; - HBITMAP PatternBitmap; -} TroughClientData; - -static const WORD Pattern[] = { - 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa -}; - -static void TroughClientDataDeleteProc(void *clientData) -{ - TroughClientData *cd = clientData; - DeleteObject(cd->PatternBrush); - DeleteObject(cd->PatternBitmap); - ckfree(clientData); -} - -static TroughClientData *TroughClientDataInit(Tcl_Interp *interp) -{ - TroughClientData *cd = ckalloc(sizeof(*cd)); - cd->PatternBitmap = CreateBitmap(8, 8, 1, 1, Pattern); - cd->PatternBrush = CreatePatternBrush(cd->PatternBitmap); - Ttk_RegisterCleanup(interp, cd, TroughClientDataDeleteProc); - return cd; -} - -static void TroughElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - TroughClientData *cd = clientData; - TkWinDCState dcState; - HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - HBRUSH hbr; - COLORREF bk, oldbk, oldtxt; - - hbr = SelectObject(hdc, GetSysColorBrush(COLOR_SCROLLBAR)); - bk = GetSysColor(COLOR_3DHIGHLIGHT); - oldtxt = SetTextColor(hdc, GetSysColor(COLOR_3DFACE)); - oldbk = SetBkColor(hdc, bk); - - /* WAS: if (bk (COLOR_3DHIGHLIGHT) == GetSysColor(COLOR_WINDOW)) ... */ - if (GetSysColor(COLOR_SCROLLBAR) == GetSysColor(COLOR_BTNFACE)) { - /* Draw using the pattern brush */ - SelectObject(hdc, cd->PatternBrush); - } - - PatBlt(hdc, b.x, b.y, b.width, b.height, PATCOPY); - SetBkColor(hdc, oldbk); - SetTextColor(hdc, oldtxt); - SelectObject(hdc, hbr); - TkWinReleaseDrawableDC(d, hdc, &dcState); -} - -static Ttk_ElementSpec TroughElementSpec = { - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - TtkNullElementSize, - TroughElementDraw -}; - -/*------------------------------------------------------------------------ - * +++ Thumb element. - */ - -typedef struct { - Tcl_Obj *orientObj; -} ThumbElement; - -static Ttk_ElementOptionSpec ThumbElementOptions[] = { - { "-orient", TK_OPTION_ANY,Tk_Offset(ThumbElement,orientObj),"horizontal"}, - { NULL, 0, 0, NULL } -}; - -static void ThumbElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - ThumbElement *thumbPtr = elementRecord; - int orient; - - Ttk_GetOrientFromObj(NULL, thumbPtr->orientObj, &orient); - if (orient == TTK_ORIENT_HORIZONTAL) { - *widthPtr = GetSystemMetrics(SM_CXHTHUMB); - *heightPtr = GetSystemMetrics(SM_CYHSCROLL); - } else { - *widthPtr = GetSystemMetrics(SM_CXVSCROLL); - *heightPtr = GetSystemMetrics(SM_CYVTHUMB); - } -} - -static void ThumbElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - RECT rc = BoxToRect(b); - TkWinDCState dcState; - HDC hdc; - - /* Windows doesn't show a thumb when the scrollbar is disabled */ - if (state & TTK_STATE_DISABLED) - return; - - hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE); - TkWinReleaseDrawableDC(d, hdc, &dcState); -} - -static Ttk_ElementSpec ThumbElementSpec = { - TK_STYLE_VERSION_2, - sizeof(ThumbElement), - ThumbElementOptions, - ThumbElementSize, - ThumbElementDraw -}; - -/* ---------------------------------------------------------------------- - * The slider element is the shaped thumb used in the slider widget. - * Windows likes to call this a trackbar. - */ - -typedef struct { - Tcl_Obj *orientObj; /* orientation of the slider widget */ -} SliderElement; - -static Ttk_ElementOptionSpec SliderElementOptions[] = { - { "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj), - "horizontal" }, - { NULL, 0, 0, NULL } -}; - -static void SliderElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - SliderElement *slider = elementRecord; - int orient; - - Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient); - if (orient == TTK_ORIENT_HORIZONTAL) { - *widthPtr = (GetSystemMetrics(SM_CXHTHUMB) / 2) | 1; - *heightPtr = GetSystemMetrics(SM_CYHSCROLL); - } else { - *widthPtr = GetSystemMetrics(SM_CXVSCROLL); - *heightPtr = (GetSystemMetrics(SM_CYVTHUMB) / 2) | 1; - } -} - -static void SliderElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - RECT rc = BoxToRect(b); - TkWinDCState dcState; - HDC hdc; - - hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE); - TkWinReleaseDrawableDC(d, hdc, &dcState); -} - -static Ttk_ElementSpec SliderElementSpec = { - TK_STYLE_VERSION_2, - sizeof(SliderElement), - SliderElementOptions, - SliderElementSize, - SliderElementDraw -}; - -/*------------------------------------------------------------------------ - * +++ Notebook elements. - */ - -static void ClientElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE); - paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE); -} - -static void ClientElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - RECT rc = BoxToRect(b); - TkWinDCState dcState; - HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState); - DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_SOFT); - TkWinReleaseDrawableDC(d, hdc, &dcState); -} - -static Ttk_ElementSpec ClientElementSpec = { - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - ClientElementSize, - ClientElementDraw -}; - -/*------------------------------------------------------------------------ - * +++ Layouts. - */ - -TTK_BEGIN_LAYOUT_TABLE(LayoutTable) - -TTK_LAYOUT("TButton", - TTK_GROUP("Button.border", TTK_FILL_BOTH, - TTK_GROUP("Button.padding", TTK_FILL_BOTH, - TTK_NODE("Button.label", TTK_FILL_BOTH)))) - -TTK_LAYOUT("TCombobox", - TTK_GROUP("Combobox.field", TTK_FILL_BOTH, - TTK_NODE("Combobox.downarrow", TTK_PACK_RIGHT|TTK_FILL_Y) - TTK_GROUP("Combobox.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_BOTH, - TTK_GROUP("Combobox.focus", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_BOTH, - TTK_NODE("Combobox.textarea", TTK_FILL_BOTH))))) - -TTK_END_LAYOUT_TABLE - -/* ---------------------------------------------------------------------- */ - -MODULE_SCOPE -int TtkWinTheme_Init(Tcl_Interp *interp, HWND hwnd) -{ - Ttk_Theme themePtr, parentPtr; - FrameControlElementData *fce = FrameControlElements; - - parentPtr = Ttk_GetTheme(interp, "alt"); - themePtr = Ttk_CreateTheme(interp, "winnative", parentPtr); - if (!themePtr) { - return TCL_ERROR; - } - - Ttk_RegisterElementSpec(themePtr, "border", &BorderElementSpec, NULL); - Ttk_RegisterElementSpec(themePtr, "Button.border", - &ButtonBorderElementSpec, NULL); - Ttk_RegisterElementSpec(themePtr, "field", &FieldElementSpec, NULL); - Ttk_RegisterElementSpec(themePtr, "focus", &FocusElementSpec, NULL); - Ttk_RegisterElementSpec(themePtr, "Combobox.focus", - &ComboboxFocusElementSpec, NULL); - Ttk_RegisterElementSpec(themePtr, "thumb", &ThumbElementSpec, NULL); - Ttk_RegisterElementSpec(themePtr, "slider", &SliderElementSpec, NULL); - Ttk_RegisterElementSpec(themePtr, "Scrollbar.trough", &TroughElementSpec, - TroughClientDataInit(interp)); - - Ttk_RegisterElementSpec(themePtr, "client", &ClientElementSpec, NULL); - - for (fce = FrameControlElements; fce->name != 0; ++fce) { - Ttk_RegisterElementSpec(themePtr, fce->name, - &FrameControlElementSpec, fce); - } - - Ttk_RegisterLayouts(themePtr, LayoutTable); - - Tcl_PkgProvide(interp, "ttk::theme::winnative", TTK_VERSION); - return TCL_OK; -} - diff --git a/tk8.6/win/ttkWinXPTheme.c b/tk8.6/win/ttkWinXPTheme.c deleted file mode 100644 index 3de1504..0000000 --- a/tk8.6/win/ttkWinXPTheme.c +++ /dev/null @@ -1,1329 +0,0 @@ -/* - * Tk theme engine which uses the Windows XP "Visual Styles" API - * Adapted from Georgios Petasis' XP theme patch. - * - * Copyright (c) 2003 by Georgios Petasis, petasis@iit.demokritos.gr. - * Copyright (c) 2003 by Joe English - * Copyright (c) 2003 by Pat Thoyts - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * See also: - * - * <URL: http://msdn.microsoft.com/library/en-us/ - * shellcc/platform/commctls/userex/refentry.asp > - */ - -#ifndef HAVE_UXTHEME_H -/* Stub for platforms that lack the XP theme API headers: */ -#include <tkWinInt.h> -int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd) { return TCL_OK; } -#else - -#define WINVER 0x0501 /* Requires Windows XP APIs */ - -#include <windows.h> -#include <uxtheme.h> -#if defined(HAVE_VSSYM32_H) || _MSC_VER > 1500 -# include <vssym32.h> -#else -# include <tmschema.h> -#endif - -#include <tkWinInt.h> - -#include "ttk/ttkTheme.h" - -typedef HTHEME (STDAPICALLTYPE OpenThemeDataProc)(HWND hwnd, - LPCWSTR pszClassList); -typedef HRESULT (STDAPICALLTYPE CloseThemeDataProc)(HTHEME hTheme); -typedef HRESULT (STDAPICALLTYPE DrawThemeBackgroundProc)(HTHEME hTheme, - HDC hdc, int iPartId, int iStateId, const RECT *pRect, - OPTIONAL const RECT *pClipRect); -typedef HRESULT (STDAPICALLTYPE GetThemePartSizeProc)(HTHEME,HDC, - int iPartId, int iStateId, - RECT *prc, enum THEMESIZE eSize, SIZE *psz); -typedef int (STDAPICALLTYPE GetThemeSysSizeProc)(HTHEME,int); -/* GetThemeTextExtent and DrawThemeText only used with BROKEN_TEXT_ELEMENT */ -typedef HRESULT (STDAPICALLTYPE GetThemeTextExtentProc)(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, - DWORD dwTextFlags, const RECT *pBoundingRect, RECT *pExtent); -typedef HRESULT (STDAPICALLTYPE DrawThemeTextProc)(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, - DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect); -typedef BOOL (STDAPICALLTYPE IsThemeActiveProc)(void); -typedef BOOL (STDAPICALLTYPE IsAppThemedProc)(void); - -typedef struct -{ - OpenThemeDataProc *OpenThemeData; - CloseThemeDataProc *CloseThemeData; - GetThemePartSizeProc *GetThemePartSize; - GetThemeSysSizeProc *GetThemeSysSize; - DrawThemeBackgroundProc *DrawThemeBackground; - DrawThemeTextProc *DrawThemeText; - GetThemeTextExtentProc *GetThemeTextExtent; - IsThemeActiveProc *IsThemeActive; - IsAppThemedProc *IsAppThemed; - - HWND stubWindow; -} XPThemeProcs; - -typedef struct -{ - HINSTANCE hlibrary; - XPThemeProcs *procs; -} XPThemeData; - -/* - *---------------------------------------------------------------------- - * - * LoadXPThemeProcs -- - * Initialize XP theming support. - * - * XP theme support is included in UXTHEME.DLL - * We dynamically load this DLL at runtime instead of linking - * to it at build-time. - * - * Returns: - * A pointer to an XPThemeProcs table if successful, NULL otherwise. - */ - -static XPThemeProcs * -LoadXPThemeProcs(HINSTANCE *phlib) -{ - /* - * Load the library "uxtheme.dll", where the native widget - * drawing routines are implemented. This will only succeed - * if we are running at least on Windows XP. - */ - HINSTANCE handle; - *phlib = handle = LoadLibrary(TEXT("uxtheme.dll")); - if (handle != 0) - { - /* - * We have successfully loaded the library. Proceed in storing the - * addresses of the functions we want to use. - */ - XPThemeProcs *procs = ckalloc(sizeof(XPThemeProcs)); -#define LOADPROC(name) \ - (0 != (procs->name = (name ## Proc *)GetProcAddress(handle, #name) )) - - if ( LOADPROC(OpenThemeData) - && LOADPROC(CloseThemeData) - && LOADPROC(GetThemePartSize) - && LOADPROC(GetThemeSysSize) - && LOADPROC(DrawThemeBackground) - && LOADPROC(GetThemeTextExtent) - && LOADPROC(DrawThemeText) - && LOADPROC(IsThemeActive) - && LOADPROC(IsAppThemed) - ) - { - return procs; - } -#undef LOADPROC - ckfree(procs); - } - return 0; -} - -/* - * XPThemeDeleteProc -- - * - * Release any theme allocated resources. - */ - -static void -XPThemeDeleteProc(void *clientData) -{ - XPThemeData *themeData = clientData; - FreeLibrary(themeData->hlibrary); - ckfree(clientData); -} - -static int -XPThemeEnabled(Ttk_Theme theme, void *clientData) -{ - XPThemeData *themeData = clientData; - int active = themeData->procs->IsThemeActive(); - int themed = themeData->procs->IsAppThemed(); - return (active && themed); -} - -/* - * BoxToRect -- - * Helper routine. Returns a RECT data structure. - */ -static RECT -BoxToRect(Ttk_Box b) -{ - RECT rc; - rc.top = b.y; - rc.left = b.x; - rc.bottom = b.y + b.height; - rc.right = b.x + b.width; - return rc; -} - -/* - * Map Tk state bitmaps to XP style enumerated values. - */ -static Ttk_StateTable null_statemap[] = { {0,0,0} }; - -/* - * Pushbuttons (Tk: "Button") - */ -static Ttk_StateTable pushbutton_statemap[] = -{ - { PBS_DISABLED, TTK_STATE_DISABLED, 0 }, - { PBS_PRESSED, TTK_STATE_PRESSED, 0 }, - { PBS_HOT, TTK_STATE_ACTIVE, 0 }, - { PBS_DEFAULTED, TTK_STATE_ALTERNATE, 0 }, - { PBS_NORMAL, 0, 0 } -}; - -/* - * Checkboxes (Tk: "Checkbutton") - */ -static Ttk_StateTable checkbox_statemap[] = -{ -{CBS_MIXEDDISABLED, TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0}, -{CBS_MIXEDPRESSED, TTK_STATE_ALTERNATE|TTK_STATE_PRESSED, 0}, -{CBS_MIXEDHOT, TTK_STATE_ALTERNATE|TTK_STATE_ACTIVE, 0}, -{CBS_MIXEDNORMAL, TTK_STATE_ALTERNATE, 0}, -{CBS_CHECKEDDISABLED, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0}, -{CBS_CHECKEDPRESSED, TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0}, -{CBS_CHECKEDHOT, TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0}, -{CBS_CHECKEDNORMAL, TTK_STATE_SELECTED, 0}, -{CBS_UNCHECKEDDISABLED, TTK_STATE_DISABLED, 0}, -{CBS_UNCHECKEDPRESSED, TTK_STATE_PRESSED, 0}, -{CBS_UNCHECKEDHOT, TTK_STATE_ACTIVE, 0}, -{CBS_UNCHECKEDNORMAL, 0,0 } -}; - -/* - * Radiobuttons: - */ -static Ttk_StateTable radiobutton_statemap[] = -{ -{RBS_UNCHECKEDDISABLED, TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0}, -{RBS_UNCHECKEDNORMAL, TTK_STATE_ALTERNATE, 0}, -{RBS_CHECKEDDISABLED, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0}, -{RBS_CHECKEDPRESSED, TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0}, -{RBS_CHECKEDHOT, TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0}, -{RBS_CHECKEDNORMAL, TTK_STATE_SELECTED, 0}, -{RBS_UNCHECKEDDISABLED, TTK_STATE_DISABLED, 0}, -{RBS_UNCHECKEDPRESSED, TTK_STATE_PRESSED, 0}, -{RBS_UNCHECKEDHOT, TTK_STATE_ACTIVE, 0}, -{RBS_UNCHECKEDNORMAL, 0,0 } -}; - -/* - * Groupboxes (tk: "frame") - */ -static Ttk_StateTable groupbox_statemap[] = -{ -{GBS_DISABLED, TTK_STATE_DISABLED, 0}, -{GBS_NORMAL, 0,0 } -}; - -/* - * Edit fields (tk: "entry") - */ -static Ttk_StateTable edittext_statemap[] = -{ - { ETS_DISABLED, TTK_STATE_DISABLED, 0 }, - { ETS_READONLY, TTK_STATE_READONLY, 0 }, - { ETS_FOCUSED, TTK_STATE_FOCUS, 0 }, - { ETS_HOT, TTK_STATE_ACTIVE, 0 }, - { ETS_NORMAL, 0, 0 } -/* NOT USED: ETS_ASSIST, ETS_SELECTED */ -}; - -/* - * Combobox text field statemap: - * Same as edittext_statemap, but doesn't use ETS_READONLY - * (fixes: #1032409) - */ -static Ttk_StateTable combotext_statemap[] = -{ - { ETS_DISABLED, TTK_STATE_DISABLED, 0 }, - { ETS_FOCUSED, TTK_STATE_FOCUS, 0 }, - { ETS_HOT, TTK_STATE_ACTIVE, 0 }, - { ETS_NORMAL, 0, 0 } -}; - -/* - * Combobox button: (CBP_DROPDOWNBUTTON) - */ -static Ttk_StateTable combobox_statemap[] = { - { CBXS_DISABLED, TTK_STATE_DISABLED, 0 }, - { CBXS_PRESSED, TTK_STATE_PRESSED, 0 }, - { CBXS_HOT, TTK_STATE_ACTIVE, 0 }, - { CBXS_HOT, TTK_STATE_HOVER, 0 }, - { CBXS_NORMAL, 0, 0 } -}; - -/* - * Toolbar buttons (TP_BUTTON): - */ -static Ttk_StateTable toolbutton_statemap[] = { - { TS_DISABLED, TTK_STATE_DISABLED, 0 }, - { TS_PRESSED, TTK_STATE_PRESSED, 0 }, - { TS_HOTCHECKED, TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0 }, - { TS_CHECKED, TTK_STATE_SELECTED, 0 }, - { TS_HOT, TTK_STATE_ACTIVE, 0 }, - { TS_NORMAL, 0,0 } -}; - -/* - * Scrollbars (Tk: "Scrollbar.thumb") - */ -static Ttk_StateTable scrollbar_statemap[] = -{ - { SCRBS_DISABLED, TTK_STATE_DISABLED, 0 }, - { SCRBS_PRESSED, TTK_STATE_PRESSED, 0 }, - { SCRBS_HOT, TTK_STATE_ACTIVE, 0 }, - { SCRBS_NORMAL, 0, 0 } -}; - -static Ttk_StateTable uparrow_statemap[] = -{ - { ABS_UPDISABLED, TTK_STATE_DISABLED, 0 }, - { ABS_UPPRESSED, TTK_STATE_PRESSED, 0 }, - { ABS_UPHOT, TTK_STATE_ACTIVE, 0 }, - { ABS_UPNORMAL, 0, 0 } -}; - -static Ttk_StateTable downarrow_statemap[] = -{ - { ABS_DOWNDISABLED, TTK_STATE_DISABLED, 0 }, - { ABS_DOWNPRESSED, TTK_STATE_PRESSED, 0 }, - { ABS_DOWNHOT, TTK_STATE_ACTIVE, 0 }, - { ABS_DOWNNORMAL, 0, 0 } -}; - -static Ttk_StateTable leftarrow_statemap[] = -{ - { ABS_LEFTDISABLED, TTK_STATE_DISABLED, 0 }, - { ABS_LEFTPRESSED, TTK_STATE_PRESSED, 0 }, - { ABS_LEFTHOT, TTK_STATE_ACTIVE, 0 }, - { ABS_LEFTNORMAL, 0, 0 } -}; - -static Ttk_StateTable rightarrow_statemap[] = -{ - { ABS_RIGHTDISABLED,TTK_STATE_DISABLED, 0 }, - { ABS_RIGHTPRESSED, TTK_STATE_PRESSED, 0 }, - { ABS_RIGHTHOT, TTK_STATE_ACTIVE, 0 }, - { ABS_RIGHTNORMAL, 0, 0 } -}; - -static Ttk_StateTable spinbutton_statemap[] = -{ - { DNS_DISABLED, TTK_STATE_DISABLED, 0 }, - { DNS_PRESSED, TTK_STATE_PRESSED, 0 }, - { DNS_HOT, TTK_STATE_ACTIVE, 0 }, - { DNS_NORMAL, 0, 0 }, -}; - -/* - * Trackbar thumb: (Tk: "scale slider") - */ -static Ttk_StateTable scale_statemap[] = -{ - { TUS_DISABLED, TTK_STATE_DISABLED, 0 }, - { TUS_PRESSED, TTK_STATE_PRESSED, 0 }, - { TUS_FOCUSED, TTK_STATE_FOCUS, 0 }, - { TUS_HOT, TTK_STATE_ACTIVE, 0 }, - { TUS_NORMAL, 0, 0 } -}; - -static Ttk_StateTable tabitem_statemap[] = -{ - { TIS_DISABLED, TTK_STATE_DISABLED, 0 }, - { TIS_SELECTED, TTK_STATE_SELECTED, 0 }, - { TIS_HOT, TTK_STATE_ACTIVE, 0 }, - { TIS_FOCUSED, TTK_STATE_FOCUS, 0 }, - { TIS_NORMAL, 0, 0 }, -}; - - -/* - *---------------------------------------------------------------------- - * +++ Element data: - * - * The following structure is passed as the 'clientData' pointer - * to most elements in this theme. It contains data relevant - * to a single XP Theme "part". - * - * <<NOTE-GetThemeMargins>>: - * In theory, we should be call GetThemeMargins(...TMT_CONTENTRECT...) - * to calculate the internal padding. In practice, this routine - * only seems to work properly for BP_PUSHBUTTON. So we hardcode - * the required padding at element registration time instead. - * - * The PAD_MARGINS flag bit determines whether the padding - * should be added on the inside (0) or outside (1) of the element. - * - * <<NOTE-GetThemePartSize>>: - * This gives bogus metrics for some parts (in particular, - * BP_PUSHBUTTONS). Set the IGNORE_THEMESIZE flag to skip this call. - */ - -typedef struct /* XP element specifications */ -{ - const char *elementName; /* Tk theme engine element name */ - Ttk_ElementSpec *elementSpec; - /* Element spec (usually GenericElementSpec) */ - LPCWSTR className; /* Windows window class name */ - int partId; /* BP_PUSHBUTTON, BP_CHECKBUTTON, etc. */ - Ttk_StateTable *statemap; /* Map Tk states to XP states */ - Ttk_Padding padding; /* See NOTE-GetThemeMargins */ - int flags; -# define IGNORE_THEMESIZE 0x80000000 /* See NOTE-GetThemePartSize */ -# define PAD_MARGINS 0x40000000 /* See NOTE-GetThemeMargins */ -# define HEAP_ELEMENT 0x20000000 /* ElementInfo is on heap */ -# define HALF_HEIGHT 0x10000000 /* Used by GenericSizedElements */ -# define HALF_WIDTH 0x08000000 /* Used by GenericSizedElements */ -} ElementInfo; - -typedef struct -{ - /* - * Static data, initialized when element is registered: - */ - ElementInfo *info; - XPThemeProcs *procs; /* Pointer to theme procedure table */ - - /* - * Dynamic data, allocated by InitElementData: - */ - HTHEME hTheme; - HDC hDC; - HWND hwnd; - - /* For TkWinDrawableReleaseDC: */ - Drawable drawable; - TkWinDCState dcState; -} ElementData; - -static ElementData * -NewElementData(XPThemeProcs *procs, ElementInfo *info) -{ - ElementData *elementData = ckalloc(sizeof(ElementData)); - - elementData->procs = procs; - elementData->info = info; - elementData->hTheme = elementData->hDC = 0; - - return elementData; -} - -/* - * Destroy elements. If the element was created by the element factory - * then the info member is dynamically allocated. Otherwise it was - * static data from the C object and only the ElementData needs freeing. - */ -static void DestroyElementData(void *clientData) -{ - ElementData *elementData = clientData; - if (elementData->info->flags & HEAP_ELEMENT) { - ckfree(elementData->info->statemap); - ckfree(elementData->info->className); - ckfree(elementData->info->elementName); - ckfree(elementData->info); - } - ckfree(clientData); -} - -/* - * InitElementData -- - * Looks up theme handle. If Drawable argument is non-NULL, - * also initializes DC. - * - * Returns: - * 1 on success, 0 on error. - * Caller must later call FreeElementData() so this element - * can be reused. - */ - -static int -InitElementData(ElementData *elementData, Tk_Window tkwin, Drawable d) -{ - Window win = Tk_WindowId(tkwin); - - if (win != None) { - elementData->hwnd = Tk_GetHWND(win); - } else { - elementData->hwnd = elementData->procs->stubWindow; - } - - elementData->hTheme = elementData->procs->OpenThemeData( - elementData->hwnd, elementData->info->className); - - if (!elementData->hTheme) - return 0; - - elementData->drawable = d; - if (d != 0) { - elementData->hDC = TkWinGetDrawableDC(Tk_Display(tkwin), d, - &elementData->dcState); - } - - return 1; -} - -static void -FreeElementData(ElementData *elementData) -{ - elementData->procs->CloseThemeData(elementData->hTheme); - if (elementData->drawable != 0) { - TkWinReleaseDrawableDC( - elementData->drawable, elementData->hDC, &elementData->dcState); - } -} - -/*---------------------------------------------------------------------- - * +++ Generic element implementation. - * - * Used for elements which are handled entirely by the XP Theme API, - * such as radiobutton and checkbutton indicators, scrollbar arrows, etc. - */ - -static void GenericElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - ElementData *elementData = clientData; - HRESULT result; - SIZE size; - - if (!InitElementData(elementData, tkwin, 0)) - return; - - if (!(elementData->info->flags & IGNORE_THEMESIZE)) { - result = elementData->procs->GetThemePartSize( - elementData->hTheme, - elementData->hDC, - elementData->info->partId, - Ttk_StateTableLookup(elementData->info->statemap, 0), - NULL /*RECT *prc*/, - TS_TRUE, - &size); - - if (SUCCEEDED(result)) { - *widthPtr = size.cx; - *heightPtr = size.cy; - } - } - - /* See NOTE-GetThemeMargins - */ - *paddingPtr = elementData->info->padding; - if (elementData->info->flags & PAD_MARGINS) { - *widthPtr += Ttk_PaddingWidth(elementData->info->padding); - *heightPtr += Ttk_PaddingHeight(elementData->info->padding); - } -} - -static void GenericElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - ElementData *elementData = clientData; - RECT rc; - - if (!InitElementData(elementData, tkwin, d)) { - return; - } - - if (elementData->info->flags & PAD_MARGINS) { - b = Ttk_PadBox(b, elementData->info->padding); - } - rc = BoxToRect(b); - - elementData->procs->DrawThemeBackground( - elementData->hTheme, - elementData->hDC, - elementData->info->partId, - Ttk_StateTableLookup(elementData->info->statemap, state), - &rc, - NULL/*pContentRect*/); - - FreeElementData(elementData); -} - -static Ttk_ElementSpec GenericElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - GenericElementSize, - GenericElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Sized element implementation. - * - * Used for elements which are handled entirely by the XP Theme API, - * but that require a fixed size adjustment. - * Note that GetThemeSysSize calls through to GetSystemMetrics - */ - -static void -GenericSizedElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - ElementData *elementData = clientData; - - if (!InitElementData(elementData, tkwin, 0)) - return; - - GenericElementSize(clientData, elementRecord, tkwin, - widthPtr, heightPtr, paddingPtr); - - *widthPtr = elementData->procs->GetThemeSysSize(NULL, - (elementData->info->flags >> 8) & 0xff); - *heightPtr = elementData->procs->GetThemeSysSize(NULL, - elementData->info->flags & 0xff); - if (elementData->info->flags & HALF_HEIGHT) - *heightPtr /= 2; - if (elementData->info->flags & HALF_WIDTH) - *widthPtr /= 2; -} - -static Ttk_ElementSpec GenericSizedElementSpec = { - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - GenericSizedElementSize, - GenericElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Spinbox arrow element. - * These are half-height scrollbar buttons. - */ - -static void -SpinboxArrowElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - ElementData *elementData = clientData; - - if (!InitElementData(elementData, tkwin, 0)) - return; - - GenericSizedElementSize(clientData, elementRecord, tkwin, - widthPtr, heightPtr, paddingPtr); - - /* force the arrow button height to half size */ - *heightPtr /= 2; -} - -static Ttk_ElementSpec SpinboxArrowElementSpec = { - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - SpinboxArrowElementSize, - GenericElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Scrollbar thumb element. - * Same as a GenericElement, but don't draw in the disabled state. - */ - -static void ThumbElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - ElementData *elementData = clientData; - unsigned stateId = Ttk_StateTableLookup(elementData->info->statemap, state); - RECT rc = BoxToRect(b); - - /* - * Don't draw the thumb if we are disabled. - */ - if (state & TTK_STATE_DISABLED) - return; - - if (!InitElementData(elementData, tkwin, d)) - return; - - elementData->procs->DrawThemeBackground(elementData->hTheme, - elementData->hDC, elementData->info->partId, stateId, - &rc, NULL); - - FreeElementData(elementData); -} - -static Ttk_ElementSpec ThumbElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - GenericElementSize, - ThumbElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Progress bar element. - * Increases the requested length of PP_CHUNK and PP_CHUNKVERT parts - * so that indeterminate progress bars show 3 bars instead of 1. - */ - -static void PbarElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - ElementData *elementData = clientData; - int nBars = 3; - - GenericElementSize(clientData, elementRecord, tkwin, - widthPtr, heightPtr, paddingPtr); - - if (elementData->info->partId == PP_CHUNK) { - *widthPtr *= nBars; - } else if (elementData->info->partId == PP_CHUNKVERT) { - *heightPtr *= nBars; - } -} - -static Ttk_ElementSpec PbarElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - PbarElementSize, - GenericElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Notebook tab element. - * Same as generic element, with additional logic to select - * proper iPartID for the leftmost tab. - * - * Notes: TABP_TABITEMRIGHTEDGE (or TABP_TOPTABITEMRIGHTEDGE, - * which appears to be identical) should be used if the - * tab is exactly at the right edge of the notebook, but - * not if it's simply the rightmost tab. This information - * is not available. - * - * The TIS_* and TILES_* definitions are identical, so - * we can use the same statemap no matter what the partId. - */ -static void TabElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - ElementData *elementData = clientData; - int partId = elementData->info->partId; - RECT rc = BoxToRect(b); - - if (!InitElementData(elementData, tkwin, d)) - return; - if (state & TTK_STATE_USER1) - partId = TABP_TABITEMLEFTEDGE; - elementData->procs->DrawThemeBackground( - elementData->hTheme, elementData->hDC, partId, - Ttk_StateTableLookup(elementData->info->statemap, state), &rc, NULL); - FreeElementData(elementData); -} - -static Ttk_ElementSpec TabElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - GenericElementSize, - TabElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Tree indicator element. - * - * Generic element, but don't display at all if TTK_STATE_LEAF (=USER2) set - */ - -#define TTK_STATE_OPEN TTK_STATE_USER1 -#define TTK_STATE_LEAF TTK_STATE_USER2 - -static Ttk_StateTable header_statemap[] = -{ - { HIS_PRESSED, TTK_STATE_PRESSED, 0 }, - { HIS_HOT, TTK_STATE_ACTIVE, 0 }, - { HIS_NORMAL, 0,0 }, -}; - -static Ttk_StateTable treeview_statemap[] = -{ - { TREIS_DISABLED, TTK_STATE_DISABLED, 0 }, - { TREIS_SELECTED, TTK_STATE_SELECTED, 0}, - { TREIS_HOT, TTK_STATE_ACTIVE, 0 }, - { TREIS_NORMAL, 0,0 }, -}; - -static Ttk_StateTable tvpglyph_statemap[] = -{ - { GLPS_OPENED, TTK_STATE_OPEN, 0 }, - { GLPS_CLOSED, 0,0 }, -}; - -static void TreeIndicatorElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - if (!(state & TTK_STATE_LEAF)) { - GenericElementDraw(clientData,elementRecord,tkwin,d,b,state); - } -} - -static Ttk_ElementSpec TreeIndicatorElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - GenericElementSize, - TreeIndicatorElementDraw -}; - -#if BROKEN_TEXT_ELEMENT - -/* - *---------------------------------------------------------------------- - * Text element (does not work yet). - * - * According to "Using Windows XP Visual Styles", we need to select - * a font into the DC before calling DrawThemeText(). - * There's just no easy way to get an HFONT out of a Tk_Font. - * Maybe GetThemeFont() would work? - * - */ - -typedef struct -{ - Tcl_Obj *textObj; - Tcl_Obj *fontObj; -} TextElement; - -static Ttk_ElementOptionSpec TextElementOptions[] = -{ - { "-text", TK_OPTION_STRING, - Tk_Offset(TextElement,textObj), "" }, - { "-font", TK_OPTION_FONT, - Tk_Offset(TextElement,fontObj), DEFAULT_FONT }, - { NULL } -}; - -static void TextElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - TextElement *element = elementRecord; - ElementData *elementData = clientData; - RECT rc = {0, 0}; - HRESULT hr = S_OK; - - if (!InitElementData(elementData, tkwin, 0)) - return; - - hr = elementData->procs->GetThemeTextExtent( - elementData->hTheme, - elementData->hDC, - elementData->info->partId, - Ttk_StateTableLookup(elementData->info->statemap, 0), - Tcl_GetUnicode(element->textObj), - -1, - DT_LEFT,// | DT_BOTTOM | DT_NOPREFIX, - NULL, - &rc); - - if (SUCCEEDED(hr)) { - *widthPtr = rc.right - rc.left; - *heightPtr = rc.bottom - rc.top; - } - if (*widthPtr < 80) *widthPtr = 80; - if (*heightPtr < 20) *heightPtr = 20; - - FreeElementData(elementData); -} - -static void TextElementDraw( - ClientData clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, unsigned int state) -{ - TextElement *element = elementRecord; - ElementData *elementData = clientData; - RECT rc = BoxToRect(b); - HRESULT hr = S_OK; - - if (!InitElementData(elementData, tkwin, d)) - return; - - hr = elementData->procs->DrawThemeText( - elementData->hTheme, - elementData->hDC, - elementData->info->partId, - Ttk_StateTableLookup(elementData->info->statemap, state), - Tcl_GetUnicode(element->textObj), - -1, - DT_LEFT,// | DT_BOTTOM | DT_NOPREFIX, - (state & TTK_STATE_DISABLED) ? DTT_GRAYED : 0, - &rc); - FreeElementData(elementData); -} - -static Ttk_ElementSpec TextElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(TextElement), - TextElementOptions, - TextElementSize, - TextElementDraw -}; - -#endif /* BROKEN_TEXT_ELEMENT */ - -/*---------------------------------------------------------------------- - * +++ Widget layouts: - */ - -TTK_BEGIN_LAYOUT_TABLE(LayoutTable) - -TTK_LAYOUT("TButton", - TTK_GROUP("Button.button", TTK_FILL_BOTH, - TTK_GROUP("Button.focus", TTK_FILL_BOTH, - TTK_GROUP("Button.padding", TTK_FILL_BOTH, - TTK_NODE("Button.label", TTK_FILL_BOTH))))) - -TTK_LAYOUT("TMenubutton", - TTK_NODE("Menubutton.dropdown", TTK_PACK_RIGHT|TTK_FILL_Y) - TTK_GROUP("Menubutton.button", TTK_PACK_RIGHT|TTK_EXPAND|TTK_FILL_BOTH, - TTK_GROUP("Menubutton.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_X, - TTK_NODE("Menubutton.label", 0)))) - -TTK_LAYOUT("Horizontal.TScrollbar", - TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X, - TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_LEFT) - TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT) - TTK_GROUP("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT, - TTK_NODE("Horizontal.Scrollbar.grip", 0)))) - -TTK_LAYOUT("Vertical.TScrollbar", - TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y, - TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_TOP) - TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM) - TTK_GROUP("Vertical.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT, - TTK_NODE("Vertical.Scrollbar.grip", 0)))) - -TTK_LAYOUT("Horizontal.TScale", - TTK_GROUP("Scale.focus", TTK_EXPAND|TTK_FILL_BOTH, - TTK_GROUP("Horizontal.Scale.trough", TTK_EXPAND|TTK_FILL_BOTH, - TTK_NODE("Horizontal.Scale.track", TTK_FILL_X) - TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) ))) - -TTK_LAYOUT("Vertical.TScale", - TTK_GROUP("Scale.focus", TTK_EXPAND|TTK_FILL_BOTH, - TTK_GROUP("Vertical.Scale.trough", TTK_EXPAND|TTK_FILL_BOTH, - TTK_NODE("Vertical.Scale.track", TTK_FILL_Y) - TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP) ))) - -TTK_END_LAYOUT_TABLE - -/*---------------------------------------------------------------------- - * +++ XP element info table: - */ - -#define PAD(l,t,r,b) {l,t,r,b} -#define NOPAD {0,0,0,0} - -/* name spec className partId statemap padding flags */ - -static ElementInfo ElementInfoTable[] = { - { "Checkbutton.indicator", &GenericElementSpec, L"BUTTON", - BP_CHECKBOX, checkbox_statemap, PAD(0, 0, 4, 0), PAD_MARGINS }, - { "Radiobutton.indicator", &GenericElementSpec, L"BUTTON", - BP_RADIOBUTTON, radiobutton_statemap, PAD(0, 0, 4, 0), PAD_MARGINS }, - { "Button.button", &GenericElementSpec, L"BUTTON", - BP_PUSHBUTTON, pushbutton_statemap, PAD(3, 3, 3, 3), IGNORE_THEMESIZE }, - { "Labelframe.border", &GenericElementSpec, L"BUTTON", - BP_GROUPBOX, groupbox_statemap, PAD(2, 2, 2, 2), 0 }, - { "Entry.field", &GenericElementSpec, L"EDIT", EP_EDITTEXT, - edittext_statemap, PAD(1, 1, 1, 1), 0 }, - { "Combobox.field", &GenericElementSpec, L"EDIT", - EP_EDITTEXT, combotext_statemap, PAD(1, 1, 1, 1), 0 }, - { "Combobox.downarrow", &GenericSizedElementSpec, L"COMBOBOX", - CP_DROPDOWNBUTTON, combobox_statemap, NOPAD, - (SM_CXVSCROLL << 8) | SM_CYVSCROLL }, - { "Vertical.Scrollbar.trough", &GenericElementSpec, L"SCROLLBAR", - SBP_UPPERTRACKVERT, scrollbar_statemap, NOPAD, 0 }, - { "Vertical.Scrollbar.thumb", &ThumbElementSpec, L"SCROLLBAR", - SBP_THUMBBTNVERT, scrollbar_statemap, NOPAD, 0 }, - { "Vertical.Scrollbar.grip", &GenericElementSpec, L"SCROLLBAR", - SBP_GRIPPERVERT, scrollbar_statemap, NOPAD, 0 }, - { "Horizontal.Scrollbar.trough", &GenericElementSpec, L"SCROLLBAR", - SBP_UPPERTRACKHORZ, scrollbar_statemap, NOPAD, 0 }, - { "Horizontal.Scrollbar.thumb", &ThumbElementSpec, L"SCROLLBAR", - SBP_THUMBBTNHORZ, scrollbar_statemap, NOPAD, 0 }, - { "Horizontal.Scrollbar.grip", &GenericElementSpec, L"SCROLLBAR", - SBP_GRIPPERHORZ, scrollbar_statemap, NOPAD, 0 }, - { "Scrollbar.uparrow", &GenericSizedElementSpec, L"SCROLLBAR", - SBP_ARROWBTN, uparrow_statemap, NOPAD, - (SM_CXVSCROLL << 8) | SM_CYVSCROLL }, - { "Scrollbar.downarrow", &GenericSizedElementSpec, L"SCROLLBAR", - SBP_ARROWBTN, downarrow_statemap, NOPAD, - (SM_CXVSCROLL << 8) | SM_CYVSCROLL }, - { "Scrollbar.leftarrow", &GenericSizedElementSpec, L"SCROLLBAR", - SBP_ARROWBTN, leftarrow_statemap, NOPAD, - (SM_CXHSCROLL << 8) | SM_CYHSCROLL }, - { "Scrollbar.rightarrow", &GenericSizedElementSpec, L"SCROLLBAR", - SBP_ARROWBTN, rightarrow_statemap, NOPAD, - (SM_CXHSCROLL << 8) | SM_CYHSCROLL }, - { "Horizontal.Scale.slider", &GenericElementSpec, L"TRACKBAR", - TKP_THUMB, scale_statemap, NOPAD, 0 }, - { "Vertical.Scale.slider", &GenericElementSpec, L"TRACKBAR", - TKP_THUMBVERT, scale_statemap, NOPAD, 0 }, - { "Horizontal.Scale.track", &GenericElementSpec, L"TRACKBAR", - TKP_TRACK, scale_statemap, NOPAD, 0 }, - { "Vertical.Scale.track", &GenericElementSpec, L"TRACKBAR", - TKP_TRACKVERT, scale_statemap, NOPAD, 0 }, - /* ttk::progressbar elements */ - { "Horizontal.Progressbar.pbar", &PbarElementSpec, L"PROGRESS", - PP_CHUNK, null_statemap, NOPAD, 0 }, - { "Vertical.Progressbar.pbar", &PbarElementSpec, L"PROGRESS", - PP_CHUNKVERT, null_statemap, NOPAD, 0 }, - { "Horizontal.Progressbar.trough", &GenericElementSpec, L"PROGRESS", - PP_BAR, null_statemap, PAD(3,3,3,3), IGNORE_THEMESIZE }, - { "Vertical.Progressbar.trough", &GenericElementSpec, L"PROGRESS", - PP_BARVERT, null_statemap, PAD(3,3,3,3), IGNORE_THEMESIZE }, - /* ttk::notebook */ - { "tab", &TabElementSpec, L"TAB", - TABP_TABITEM, tabitem_statemap, PAD(3,3,3,0), 0 }, - { "client", &GenericElementSpec, L"TAB", - TABP_PANE, null_statemap, PAD(1,1,3,3), 0 }, - { "NotebookPane.background", &GenericElementSpec, L"TAB", - TABP_BODY, null_statemap, NOPAD, 0 }, - { "Toolbutton.border", &GenericElementSpec, L"TOOLBAR", - TP_BUTTON, toolbutton_statemap, NOPAD,0 }, - { "Menubutton.button", &GenericElementSpec, L"TOOLBAR", - TP_SPLITBUTTON,toolbutton_statemap, NOPAD,0 }, - { "Menubutton.dropdown", &GenericElementSpec, L"TOOLBAR", - TP_SPLITBUTTONDROPDOWN,toolbutton_statemap, NOPAD,0 }, - { "Treeview.field", &GenericElementSpec, L"TREEVIEW", - TVP_TREEITEM, treeview_statemap, PAD(1, 1, 1, 1), 0 }, - { "Treeitem.indicator", &TreeIndicatorElementSpec, L"TREEVIEW", - TVP_GLYPH, tvpglyph_statemap, PAD(1,1,6,0), PAD_MARGINS }, - { "Treeheading.border", &GenericElementSpec, L"HEADER", - HP_HEADERITEM, header_statemap, PAD(4,0,4,0),0 }, - { "sizegrip", &GenericElementSpec, L"STATUS", - SP_GRIPPER, null_statemap, NOPAD,0 }, - { "Spinbox.field", &GenericElementSpec, L"EDIT", - EP_EDITTEXT, edittext_statemap, PAD(1, 1, 1, 1), 0 }, - { "Spinbox.uparrow", &SpinboxArrowElementSpec, L"SPIN", - SPNP_UP, spinbutton_statemap, NOPAD, - PAD_MARGINS | ((SM_CXVSCROLL << 8) | SM_CYVSCROLL) }, - { "Spinbox.downarrow", &SpinboxArrowElementSpec, L"SPIN", - SPNP_DOWN, spinbutton_statemap, NOPAD, - PAD_MARGINS | ((SM_CXVSCROLL << 8) | SM_CYVSCROLL) }, - -#if BROKEN_TEXT_ELEMENT - { "Labelframe.text", &TextElementSpec, L"BUTTON", - BP_GROUPBOX, groupbox_statemap, NOPAD,0 }, -#endif - - { 0,0,0,0,0,NOPAD,0 } -}; -#undef PAD - - -static int -GetSysFlagFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr) -{ - static const char *names[] = { - "SM_CXBORDER", "SM_CYBORDER", "SM_CXVSCROLL", "SM_CYVSCROLL", - "SM_CXHSCROLL", "SM_CYHSCROLL", "SM_CXMENUCHECK", "SM_CYMENUCHECK", - "SM_CXMENUSIZE", "SM_CYMENUSIZE", "SM_CXSIZE", "SM_CYSIZE", "SM_CXSMSIZE", - "SM_CYSMSIZE" - }; - int flags[] = { - SM_CXBORDER, SM_CYBORDER, SM_CXVSCROLL, SM_CYVSCROLL, - SM_CXHSCROLL, SM_CYHSCROLL, SM_CXMENUCHECK, SM_CYMENUCHECK, - SM_CXMENUSIZE, SM_CYMENUSIZE, SM_CXSIZE, SM_CYSIZE, SM_CXSMSIZE, - SM_CYSMSIZE - }; - - Tcl_Obj **objv; - int i, objc; - - if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) - return TCL_ERROR; - if (objc != 2) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args", -1)); - Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); - return TCL_ERROR; - } - for (i = 0; i < objc; ++i) { - int option; - if (Tcl_GetIndexFromObjStruct(interp, objv[i], names, - sizeof(char *), "system constant", 0, &option) != TCL_OK) - return TCL_ERROR; - *resultPtr |= (flags[option] << (8 * (1 - i))); - } - return TCL_OK; -} - -/*---------------------------------------------------------------------- - * Windows Visual Styles API Element Factory - * - * The Vista release has shown that the Windows Visual Styles can be - * extended with additional elements. This element factory can permit - * the programmer to create elements for use with script-defined layouts - * - * eg: to create the small close button: - * style element create smallclose vsapi \ - * WINDOW 19 {disabled 4 pressed 3 active 2 {} 1} - */ - -static int -Ttk_CreateVsapiElement( - Tcl_Interp *interp, - void *clientData, - Ttk_Theme theme, - const char *elementName, - int objc, - Tcl_Obj *const objv[]) -{ - XPThemeData *themeData = clientData; - ElementInfo *elementPtr = NULL; - ClientData elementData; - Tcl_UniChar *className; - int partId = 0; - Ttk_StateTable *stateTable; - Ttk_Padding pad = {0, 0, 0, 0}; - int flags = 0; - int length = 0; - char *name; - LPWSTR wname; - Ttk_ElementSpec *elementSpec = &GenericElementSpec; - - static const char *optionStrings[] = - { "-padding","-width","-height","-margins", "-syssize", - "-halfheight", "-halfwidth", NULL }; - enum { O_PADDING, O_WIDTH, O_HEIGHT, O_MARGINS, O_SYSSIZE, - O_HALFHEIGHT, O_HALFWIDTH }; - - if (objc < 2) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "missing required arguments 'class' and/or 'partId'", -1)); - Tcl_SetErrorCode(interp, "TTK", "VSAPI", "REQUIRED", NULL); - return TCL_ERROR; - } - - if (Tcl_GetIntFromObj(interp, objv[1], &partId) != TCL_OK) { - return TCL_ERROR; - } - className = Tcl_GetUnicodeFromObj(objv[0], &length); - - /* flags or padding */ - if (objc > 3) { - int i = 3, option = 0; - for (i = 3; i < objc; i += 2) { - int tmp = 0; - if (i == objc -1) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "Missing value for \"%s\".", - Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TTK", "VSAPI", "MISSING", NULL); - return TCL_ERROR; - } - if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings, - sizeof(char *), "option", 0, &option) != TCL_OK) - return TCL_ERROR; - switch (option) { - case O_PADDING: - if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) { - return TCL_ERROR; - } - break; - case O_MARGINS: - if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) { - return TCL_ERROR; - } - flags |= PAD_MARGINS; - break; - case O_WIDTH: - if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - return TCL_ERROR; - } - pad.left = pad.right = tmp; - flags |= IGNORE_THEMESIZE; - break; - case O_HEIGHT: - if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - return TCL_ERROR; - } - pad.top = pad.bottom = tmp; - flags |= IGNORE_THEMESIZE; - break; - case O_SYSSIZE: - if (GetSysFlagFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - return TCL_ERROR; - } - elementSpec = &GenericSizedElementSpec; - flags |= (tmp & 0xFFFF); - break; - case O_HALFHEIGHT: - if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - return TCL_ERROR; - } - if (tmp) - flags |= HALF_HEIGHT; - break; - case O_HALFWIDTH: - if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - return TCL_ERROR; - } - if (tmp) - flags |= HALF_WIDTH; - break; - } - } - } - - /* convert a statemap into a state table */ - if (objc > 2) { - Tcl_Obj **specs; - int n,j,count, status = TCL_OK; - if (Tcl_ListObjGetElements(interp, objv[2], &count, &specs) != TCL_OK) - return TCL_ERROR; - /* we over-allocate to ensure there is a terminating entry */ - stateTable = ckalloc(sizeof(Ttk_StateTable) * (count + 1)); - memset(stateTable, 0, sizeof(Ttk_StateTable) * (count + 1)); - for (n = 0, j = 0; status == TCL_OK && n < count; n += 2, ++j) { - Ttk_StateSpec spec = {0,0}; - status = Ttk_GetStateSpecFromObj(interp, specs[n], &spec); - if (status == TCL_OK) { - stateTable[j].onBits = spec.onbits; - stateTable[j].offBits = spec.offbits; - status = Tcl_GetIntFromObj(interp, specs[n+1], - &stateTable[j].index); - } - } - if (status != TCL_OK) { - ckfree(stateTable); - return status; - } - } else { - stateTable = ckalloc(sizeof(Ttk_StateTable)); - memset(stateTable, 0, sizeof(Ttk_StateTable)); - } - - elementPtr = ckalloc(sizeof(ElementInfo)); - elementPtr->elementSpec = elementSpec; - elementPtr->partId = partId; - elementPtr->statemap = stateTable; - elementPtr->padding = pad; - elementPtr->flags = HEAP_ELEMENT | flags; - - /* set the element name to an allocated copy */ - name = ckalloc(strlen(elementName) + 1); - strcpy(name, elementName); - elementPtr->elementName = name; - - /* set the class name to an allocated copy */ - wname = ckalloc(sizeof(WCHAR) * (length + 1)); - wcscpy(wname, className); - elementPtr->className = wname; - - elementData = NewElementData(themeData->procs, elementPtr); - Ttk_RegisterElementSpec( - theme, elementName, elementPtr->elementSpec, elementData); - - Ttk_RegisterCleanup(interp, elementData, DestroyElementData); - Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1)); - return TCL_OK; -} - -/*---------------------------------------------------------------------- - * +++ Initialization routine: - */ - -MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd) -{ - XPThemeData *themeData; - XPThemeProcs *procs; - HINSTANCE hlibrary; - Ttk_Theme themePtr, parentPtr, vistaPtr; - ElementInfo *infoPtr; - OSVERSIONINFOW os; - - os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); - GetVersionExW(&os); - - procs = LoadXPThemeProcs(&hlibrary); - if (!procs) - return TCL_ERROR; - procs->stubWindow = hwnd; - - /* - * Create the new style engine. - */ - parentPtr = Ttk_GetTheme(interp, "winnative"); - themePtr = Ttk_CreateTheme(interp, "xpnative", parentPtr); - - if (!themePtr) - return TCL_ERROR; - - /* - * Set theme data and cleanup proc - */ - - themeData = ckalloc(sizeof(XPThemeData)); - themeData->procs = procs; - themeData->hlibrary = hlibrary; - - Ttk_SetThemeEnabledProc(themePtr, XPThemeEnabled, themeData); - Ttk_RegisterCleanup(interp, themeData, XPThemeDeleteProc); - Ttk_RegisterElementFactory(interp, "vsapi", Ttk_CreateVsapiElement, themeData); - - /* - * Create the vista theme on suitable platform versions and set the theme - * enable function. The theme itself is defined in script. - */ - - if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && os.dwMajorVersion > 5) { - vistaPtr = Ttk_CreateTheme(interp, "vista", themePtr); - if (vistaPtr) { - Ttk_SetThemeEnabledProc(vistaPtr, XPThemeEnabled, themeData); - } - } - - /* - * New elements: - */ - for (infoPtr = ElementInfoTable; infoPtr->elementName != 0; ++infoPtr) { - ClientData clientData = NewElementData(procs, infoPtr); - Ttk_RegisterElementSpec( - themePtr, infoPtr->elementName, infoPtr->elementSpec, clientData); - Ttk_RegisterCleanup(interp, clientData, DestroyElementData); - } - - Ttk_RegisterElementSpec(themePtr, "Scale.trough", &ttkNullElementSpec, 0); - - /* - * Layouts: - */ - Ttk_RegisterLayouts(themePtr, LayoutTable); - - Tcl_PkgProvide(interp, "ttk::theme::xpnative", TTK_VERSION); - - return TCL_OK; -} - -#endif /* HAVE_UXTHEME_H */ diff --git a/tk8.6/win/winMain.c b/tk8.6/win/winMain.c deleted file mode 100644 index 62bcbd8..0000000 --- a/tk8.6/win/winMain.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * winMain.c -- - * - * Provides a default version of the main program and Tcl_AppInit - * procedure for wish and other Tk-based applications. - * - * Copyright (c) 1993 The Regents of the University of California. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-1999 Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tk.h" -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#include <locale.h> -#include <stdlib.h> -#include <tchar.h> - -#if defined(__GNUC__) -int _CRT_glob = 0; -#endif /* __GNUC__ */ - -#ifdef TK_TEST -extern Tcl_PackageInitProc Tktest_Init; -#endif /* TK_TEST */ - -#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES -extern Tcl_PackageInitProc Registry_Init; -extern Tcl_PackageInitProc Dde_Init; -extern Tcl_PackageInitProc Dde_SafeInit; -#endif - -#ifdef TCL_BROKEN_MAINARGS -static void setargv(int *argcPtr, TCHAR ***argvPtr); -#endif - -/* - * Forward declarations for procedures defined later in this file: - */ - -static BOOL consoleRequired = TRUE; - -/* - * The following #if block allows you to change the AppInit function by using - * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The - * #if checks for that #define and uses Tcl_AppInit if it doesn't exist. - */ - -#ifndef TK_LOCAL_APPINIT -#define TK_LOCAL_APPINIT Tcl_AppInit -#endif -#ifndef MODULE_SCOPE -# define MODULE_SCOPE extern -#endif -MODULE_SCOPE int TK_LOCAL_APPINIT(Tcl_Interp *interp); - -/* - * The following #if block allows you to change how Tcl finds the startup - * script, prime the library or encoding paths, fiddle with the argv, etc., - * without needing to rewrite Tk_Main() - */ - -#ifdef TK_LOCAL_MAIN_HOOK -MODULE_SCOPE int TK_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); -#endif - -/* Make sure the stubbed variants of those are never used. */ -#undef Tcl_ObjSetVar2 -#undef Tcl_NewStringObj - -/* - *---------------------------------------------------------------------- - * - * _tWinMain -- - * - * Main entry point from Windows. - * - * Results: - * Returns false if initialization fails, otherwise it never returns. - * - * Side effects: - * Just about anything, since from here we call arbitrary Tcl code. - * - *---------------------------------------------------------------------- - */ - -int APIENTRY -#ifdef TCL_BROKEN_MAINARGS -WinMain( - HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpszCmdLine, - int nCmdShow) -#else -_tWinMain( - HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPTSTR lpszCmdLine, - int nCmdShow) -#endif -{ - TCHAR **argv; - int argc; - TCHAR *p; - - /* - * Create the console channels and install them as the standard channels. - * All I/O will be discarded until Tk_CreateConsoleWindow is called to - * attach the console to a text widget. - */ - - consoleRequired = TRUE; - - /* - * Set up the default locale to be standard "C" locale so parsing is - * performed correctly. - */ - - setlocale(LC_ALL, "C"); - - /* - * Get our args from the c-runtime. Ignore lpszCmdLine. - */ - -#if defined(TCL_BROKEN_MAINARGS) - setargv(&argc, &argv); -#else - argc = __argc; - argv = __targv; -#endif - - /* - * Forward slashes substituted for backslashes. - */ - - for (p = argv[0]; *p != '\0'; p++) { - if (*p == '\\') { - *p = '/'; - } - } - -#ifdef TK_LOCAL_MAIN_HOOK - TK_LOCAL_MAIN_HOOK(&argc, &argv); -#endif - - Tk_Main(argc, argv, TK_LOCAL_APPINIT); - return 0; /* Needed only to prevent compiler warning. */ -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AppInit -- - * - * This procedure performs application-specific initialization. Most - * applications, especially those that incorporate additional packages, - * will have their own version of this procedure. - * - * Results: - * Returns a standard Tcl completion code, and leaves an error message in - * the interp's result if an error occurs. - * - * Side effects: - * Depends on the startup script. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_AppInit( - Tcl_Interp *interp) /* Interpreter for application. */ -{ - if ((Tcl_Init)(interp) == TCL_ERROR) { - return TCL_ERROR; - } - if (Tk_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit); - - /* - * Initialize the console only if we are running as an interactive - * application. - */ - - if (consoleRequired) { - if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) { - return TCL_ERROR; - } - } -#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES - if (Registry_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "registry", Registry_Init, 0); - - if (Dde_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit); -#endif - -#ifdef TK_TEST - if (Tktest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0); -#endif /* TK_TEST */ - - /* - * Call the init procedures for included packages. Each call should look - * like this: - * - * if (Mod_Init(interp) == TCL_ERROR) { - * return TCL_ERROR; - * } - * - * where "Mod" is the name of the module. (Dynamically-loadable packages - * should have the same entry-point name.) - */ - - /* - * Call Tcl_CreateObjCommand for application-specific commands, if they - * weren't already created by the init procedures called above. - */ - - /* - * Specify a user-specific startup file to invoke if the application is - * run interactively. Typically the startup file is "~/.apprc" where "app" - * is the name of the application. If this line is deleted then no user- - * specific startup file will be run under any conditions. - */ - - Tcl_ObjSetVar2(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, - Tcl_NewStringObj("~/wishrc.tcl", -1), TCL_GLOBAL_ONLY); - return TCL_OK; -} - -#if defined(TK_TEST) -/* - *---------------------------------------------------------------------- - * - * _tmain -- - * - * Main entry point from the console. - * - * Results: - * None: Tk_Main never returns here, so this procedure never returns - * either. - * - * Side effects: - * Whatever the applications does. - * - *---------------------------------------------------------------------- - */ - -#ifdef TCL_BROKEN_MAINARGS -int -main( - int argc, - char **dummy) -{ - TCHAR **argv; -#else -int -_tmain( - int argc, - TCHAR **argv) -{ -#endif - /* - * Set up the default locale to be standard "C" locale so parsing is - * performed correctly. - */ - - setlocale(LC_ALL, "C"); - -#ifdef TCL_BROKEN_MAINARGS - /* - * Get our args from the c-runtime. Ignore argc/argv. - */ - - setargv(&argc, &argv); -#endif - /* - * Console emulation widget not required as this entry is from the - * console subsystem, thus stdin,out,err already have end-points. - */ - - consoleRequired = FALSE; - -#ifdef TK_LOCAL_MAIN_HOOK - TK_LOCAL_MAIN_HOOK(&argc, &argv); -#endif - - Tk_Main(argc, argv, Tcl_AppInit); - return 0; -} -#endif /* !__GNUC__ || TK_TEST */ - - -/* - *------------------------------------------------------------------------- - * - * setargv -- - * - * Parse the Windows command line string into argc/argv. Done here - * because we don't trust the builtin argument parser in crt0. Windows - * applications are responsible for breaking their command line into - * arguments. - * - * 2N backslashes + quote -> N backslashes + begin quoted string - * 2N + 1 backslashes + quote -> literal - * N backslashes + non-quote -> literal - * quote + quote in a quoted string -> single quote - * quote + quote not in quoted string -> empty string - * quote -> begin quoted string - * - * Results: - * Fills argcPtr with the number of arguments and argvPtr with the array - * of arguments. - * - * Side effects: - * Memory allocated. - * - *-------------------------------------------------------------------------- - */ - -#ifdef TCL_BROKEN_MAINARGS -static void -setargv( - int *argcPtr, /* Filled with number of argument strings. */ - TCHAR ***argvPtr) /* Filled with argument strings (malloc'd). */ -{ - TCHAR *cmdLine, *p, *arg, *argSpace; - TCHAR **argv; - int argc, size, inquote, copy, slashes; - - cmdLine = GetCommandLine(); - - /* - * Precompute an overly pessimistic guess at the number of arguments in - * the command line by counting non-space spans. - */ - - size = 2; - for (p = cmdLine; *p != '\0'; p++) { - if ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ - size++; - while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ - p++; - } - if (*p == '\0') { - break; - } - } - } - - /* Make sure we don't call ckalloc through the (not yet initialized) stub table */ - #undef Tcl_Alloc - #undef Tcl_DbCkalloc - - argSpace = ckalloc(size * sizeof(char *) - + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); - argv = (TCHAR **) argSpace; - argSpace += size * (sizeof(char *)/sizeof(TCHAR)); - size--; - - p = cmdLine; - for (argc = 0; argc < size; argc++) { - argv[argc] = arg = argSpace; - while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ - p++; - } - if (*p == '\0') { - break; - } - - inquote = 0; - slashes = 0; - while (1) { - copy = 1; - while (*p == '\\') { - slashes++; - p++; - } - if (*p == '"') { - if ((slashes & 1) == 0) { - copy = 0; - if ((inquote) && (p[1] == '"')) { - p++; - copy = 1; - } else { - inquote = !inquote; - } - } - slashes >>= 1; - } - - while (slashes) { - *arg = '\\'; - arg++; - slashes--; - } - - if ((*p == '\0') || (!inquote && - ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */ - break; - } - if (copy != 0) { - *arg = *p; - arg++; - } - p++; - } - *arg = '\0'; - argSpace = arg + 1; - } - argv[argc] = NULL; - - *argcPtr = argc; - *argvPtr = argv; -} -#endif /* TCL_BROKEN_MAINARGS */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/tk8.6/win/wish.exe.manifest.in b/tk8.6/win/wish.exe.manifest.in deleted file mode 100644 index 4829471..0000000 --- a/tk8.6/win/wish.exe.manifest.in +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" - xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> - <assemblyIdentity - version="@TK_WIN_VERSION@" - processorArchitecture="@MACHINE@" - name="Tcl.Tk.wish" - type="win32" - /> - <description>Tcl/Tk windowing shell (wish)</description> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel - level="asInvoker" - uiAccess="false" - /> - </requestedPrivileges> - </security> - </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 --> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> - <!-- Windows 7 --> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <!-- Windows Vista --> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> - </application> - </compatibility> - <asmv3:application> - <asmv3:windowsSettings - xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> - <dpiAware>true</dpiAware> - </asmv3:windowsSettings> - </asmv3:application> - <dependency> - <dependentAssembly> - <assemblyIdentity - type="win32" - name="Microsoft.Windows.Common-Controls" - version="6.0.0.0" - processorArchitecture="@MACHINE@" - publicKeyToken="6595b64144ccf1df" - language="*" - /> - </dependentAssembly> - </dependency> -</assembly> |