summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
Diffstat (limited to 'win')
-rw-r--r--win/Makefile.in125
-rw-r--r--win/README2
-rwxr-xr-xwin/buildall.vc.bat91
-rwxr-xr-xwin/configure5347
-rw-r--r--win/configure.in92
-rw-r--r--win/makefile.bc10
-rw-r--r--win/makefile.vc531
-rw-r--r--win/nmakehlp.c266
-rw-r--r--win/rc/cursor00.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor02.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor04.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor06.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor0a.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor0c.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor0e.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor12.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor1e.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor20.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor2a.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor3a.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor46.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor48.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor4c.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor4e.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor60.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor62.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor66.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor6c.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor72.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor74.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor86.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor88.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor8a.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor8c.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor90.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor94.curbin326 -> 326 bytes
-rw-r--r--win/rc/cursor9a.curbin0 -> 326 bytes
-rw-r--r--win/rc/lamp.bmp (renamed from win/lamp.bmp)bin2102 -> 2102 bytes
-rw-r--r--win/rc/tk.rc8
-rw-r--r--win/rc/tk_base.rc2
-rw-r--r--win/rc/wish.rc12
-rw-r--r--win/rules.vc341
-rw-r--r--win/stubs.c379
-rw-r--r--win/tcl.m496
-rw-r--r--win/tkConfig.sh.in2
-rw-r--r--win/tkWin.h48
-rw-r--r--win/tkWin32Dll.c24
-rw-r--r--win/tkWin3d.c374
-rw-r--r--win/tkWinButton.c937
-rw-r--r--win/tkWinClipboard.c181
-rw-r--r--win/tkWinColor.c235
-rw-r--r--win/tkWinConfig.c32
-rw-r--r--win/tkWinCursor.c90
-rw-r--r--win/tkWinDefault.h49
-rw-r--r--win/tkWinDialog.c2787
-rw-r--r--win/tkWinDraw.c593
-rw-r--r--win/tkWinEmbed.c1029
-rw-r--r--win/tkWinFont.c1500
-rw-r--r--win/tkWinImage.c402
-rw-r--r--win/tkWinInit.c74
-rw-r--r--win/tkWinInt.h149
-rw-r--r--win/tkWinKey.c540
-rw-r--r--win/tkWinMenu.c2323
-rw-r--r--win/tkWinPixmap.c124
-rw-r--r--win/tkWinPointer.c218
-rw-r--r--win/tkWinPort.h46
-rw-r--r--win/tkWinRegion.c139
-rw-r--r--win/tkWinScrlbr.c399
-rw-r--r--win/tkWinSend.c1043
-rw-r--r--win/tkWinSendCom.c462
-rw-r--r--win/tkWinSendCom.h61
-rw-r--r--win/tkWinTest.c313
-rw-r--r--win/tkWinWindow.c335
-rw-r--r--win/tkWinWm.c5229
-rw-r--r--win/tkWinX.c1632
-rw-r--r--win/ttkWinMonitor.c158
-rw-r--r--win/ttkWinTheme.c733
-rw-r--r--win/ttkWinXPTheme.c1324
-rw-r--r--win/winMain.c330
-rw-r--r--win/wish.exe.manifest.in47
80 files changed, 20580 insertions, 10684 deletions
diff --git a/win/Makefile.in b/win/Makefile.in
index 71e04e9..851566d 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -7,6 +7,7 @@
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
@@ -92,6 +93,11 @@ TCL_BIN_DIR = @TCL_BIN_DIR@
# 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.
@@ -106,6 +112,7 @@ 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
@@ -117,6 +124,7 @@ 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@
@@ -141,7 +149,7 @@ MAN2TCL = man2tcl$(EXEEXT)
# makefile to look into these paths when resolving .c to .obj
# dependencies.
-VPATH = $(GENERIC_DIR):$(WIN_DIR):$(UNIX_DIR):$(XLIB_DIR):$(RC_DIR)
+VPATH = $(GENERIC_DIR):$(TTK_DIR):$(WIN_DIR):$(UNIX_DIR):$(XLIB_DIR):$(RC_DIR)
# warning flags
CFLAGS_WARNING = @CFLAGS_WARNING@
@@ -203,7 +211,7 @@ 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}" ${AC_FLAGS}
+-I"${TCL_GENERIC_NATIVE}" -I"${TCL_PLATFORM_NATIVE}" ${AC_FLAGS}
CC_OBJNAME = @CC_OBJNAME@
CC_EXENAME = @CC_EXENAME@
@@ -227,6 +235,7 @@ TKTEST_OBJS = \
testMain.$(OBJEXT) \
tkSquare.$(OBJEXT) \
tkTest.$(OBJEXT) \
+ tkOldTest.$(OBJEXT) \
tkWinTest.$(OBJEXT)
XLIB_OBJS = \
@@ -261,6 +270,7 @@ TK_OBJS = \
tkWinRegion.$(OBJEXT) \
tkWinScrlbr.$(OBJEXT) \
tkWinSend.$(OBJEXT) \
+ tkWinSendCom.$(OBJEXT) \
tkWinWindow.$(OBJEXT) \
tkWinWm.$(OBJEXT) \
tkWinX.$(OBJEXT) \
@@ -337,11 +347,46 @@ TK_OBJS = \
tkVisual.$(OBJEXT) \
tkStubInit.$(OBJEXT) \
tkStubLib.$(OBJEXT) \
- tkWindow.$(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) \
- tkStubImg.$(OBJEXT)
+ tkStubLib.$(OBJEXT) ttkStubLib.$(OBJEXT)
TCL_DOCS = "$(TCL_SRC_DIR_NATIVE)"/doc/*.[13n]
TK_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n]
@@ -349,6 +394,11 @@ 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.
@@ -376,26 +426,26 @@ $(MAN2TCL): $(TCL_SRC_DIR_NATIVE)/tools/man2tcl.c
# args to tcltest, ie:
# % make test TESTFLAGS="-verbose bps -file fileName.test"
-test: binaries $(TKTEST)
- @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; \
- ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \
- | ./$(CAT32)
+test: test-classic test-ttk
+
+test-classic: binaries $(TKTEST)
+ $(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/all.tcl" \
+ $(TESTFLAGS) | ./$(CAT32)
+
+test-ttk: binaries $(TKTEST)
+ $(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/ttk/all.tcl" \
+ $(TESTFLAGS) | ./$(CAT32)
runtest: binaries $(TKTEST)
- @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; \
- ./$(TKTEST) $(TESTFLAGS) $(SCRIPT)
+ $(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
- @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; \
- ./$(WISH) $(SCRIPT)
+ $(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
@@ -427,9 +477,8 @@ install-binaries: binaries
@echo "Creating package index $(PKG_INDEX)";
@$(RM) $(PKG_INDEX);
@(\
- echo "if {[package vcompare [package provide Tcl]\
- $(TCLVERSION)] != 0} { return }";\
- echo "package ifneeded Tk $(VERSION)\
+ echo "if {[catch {package present Tcl 8.5.0}]} { return }";\
+ echo "package ifneeded Tk $(VERSION)$(PATCH_LEVEL)\
[list load [file join \$$dir .. .. bin $(TK_DLL_FILE)] Tk]";\
) > $(PKG_INDEX);
@for i in tkConfig.sh $(TK_LIB_FILE) $(TK_STUB_LIB_FILE); \
@@ -444,7 +493,7 @@ 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)/msgs $(SCRIPT_INSTALL_DIR)/ttk; \
do \
if [ ! -d $$i ] ; then \
echo "Making directory $$i"; \
@@ -464,11 +513,18 @@ install-libraries: libraries
$(INSTALL_DATA) $$i $(INCLUDE_INSTALL_DIR)/X11; \
done;
@echo "Installing library files to $(SCRIPT_INSTALL_DIR)";
- @for i in $(ROOT_DIR)/library/*.tcl $(GENERIC_DIR)/prolog.ps \
+ @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 \
@@ -532,8 +588,7 @@ install-private-headers: libraries
@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; \
+ $(WIN_DIR)/tkWinPort.h $(WIN_DIR)/tkWinInt.h $(WIN_DIR)/tkWin.h; \
do \
$(INSTALL_DATA) $$i $(PRIVATE_INCLUDE_INSTALL_DIR); \
done;
@@ -555,7 +610,7 @@ $(TKTEST): $(TK_LIB_FILE) $(TKTEST_OBJS) wish.$(RES) $(CAT32)
$(TCL_SRC_DIR)/win/cat.c:
cat32.${OBJEXT}: $(TCL_SRC_DIR)/win/cat.c
- $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)
+ $(CC) -c $(CC_SWITCHES) "$(TCL_SRC_DIR)/win/cat.c" $(CC_OBJNAME)
$(CAT32): cat32.${OBJEXT}
$(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE)
@@ -589,12 +644,20 @@ testMain.$(OBJEXT): winMain.c
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)
+# 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.
@@ -604,11 +667,11 @@ tkSquare.$(OBJEXT): tkSquare.c
# Implicit rule for all object files that will end up in the Tcl library
-.c.$(OBJEXT):
- $(CC) -c $(STUB_CC_SWITCHES) -DBUILD_tk @DEPARG@ $(CC_OBJNAME)
+%.$(OBJEXT): %.c
+ $(CC) -c $(STUB_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@
+ $(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(TCL_GENERIC_NATIVE)" @RC_INCLUDE@ "$(TCL_PLATFORM_NATIVE)" @RC_INCLUDE@ "$(RC_DIR_NATIVE)" @DEPARG@
depend:
@@ -638,7 +701,7 @@ $(GENERIC_DIR)/tkStubInit.c: $(GENERIC_DIR)/tk.decls \
@echo "This warning can be safely ignored, do not report as a bug!"
genstubs:
- $(TCL_EXE) "$(TCL_TOOL_DIR}\genStubs.tcl" \
+ $(TCL_EXE) "$(TCL_TOOL_DIR)\genStubs.tcl" \
"$(GENERIC_DIR_NATIVE)" \
"$(GENERIC_DIR_NATIVE)\tk.decls" \
"$(GENERIC_DIR_NATIVE)\tkInt.decls"
diff --git a/win/README b/win/README
index f6e1a34..1d4b27a 100644
--- a/win/README
+++ b/win/README
@@ -1,4 +1,4 @@
-Tk 8.4 for Windows
+Tk 8.5 for Windows
Originally by Scott Stanton while at Sun Microsystems Labs
diff --git a/win/buildall.vc.bat b/win/buildall.vc.bat
index dd69d09..16605ee 100755
--- a/win/buildall.vc.bat
+++ b/win/buildall.vc.bat
@@ -4,58 +4,123 @@
:: 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
+
+:: We need to run the development environment batch script that comes
+:: with developer studio (v4,5,6,7,etc...) All have it. These paths
+:: might not be correct. You may need to edit these.
+::
+if not defined MSDevDir (
+ call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat"
+ ::call "C:\Program Files\Microsoft Developer Studio\vc\bin\vcvars32.bat"
+ ::call c:\dev\devstudio60\vc98\bin\vcvars32.bat
+ if errorlevel 1 goto no_vcvars
+)
+
+
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...
-if "%MSVCDir%" == "" call c:\dev\devstudio60\vc98\bin\vcvars32.bat
-::if "%MSVCDir%" == "" call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat"
-set INSTALLDIR=C:\Program Files\Tcl
+:: 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?
-set TCLDIR=..\..\tcl_head_stock
-::set TCLDIR=..\..\tcl8.4
+:: 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.
::
-nmake -nologo -f makefile.vc release winhelp OPTS=none
+set OPTS=none
+if not %SYMBOLS%.==. set OPTS=symbols
+nmake -nologo -f makefile.vc release winhelp OPTS=%OPTS% %1
if errorlevel 1 goto error
:: Build the static core, dlls and shell.
::
-nmake -nologo -f makefile.vc release OPTS=static
+set OPTS=static
+if not %SYMBOLS%.==. set OPTS=symbols,static
+nmake -nologo -f makefile.vc release OPTS=%OPTS% %1
if errorlevel 1 goto error
:: Build the special static libraries that use the dynamic runtime.
::
-nmake -nologo -f makefile.vc core OPTS=static,msvcrt
+set OPTS=static,msvcrt
+if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt
+nmake -nologo -f makefile.vc core OPTS=%OPTS% %1
if errorlevel 1 goto error
:: Build the core and shell for thread support.
::
-nmake -nologo -f makefile.vc release OPTS=threads
+set OPTS=threads
+if not %SYMBOLS%.==. set OPTS=symbols,threads
+nmake -nologo -f makefile.vc release OPTS=%OPTS% %1
if errorlevel 1 goto error
:: Build a static, thread support core library (no shell).
::
-nmake -nologo -f makefile.vc core OPTS=static,threads
+set OPTS=static,threads
+if not %SYMBOLS%.==. set OPTS=symbols,static,threads
+nmake -nologo -f makefile.vc core OPTS=%OPTS% %1
if errorlevel 1 goto error
:: Build the special static libraries the use the dynamic runtime,
:: but now with thread support.
::
-nmake -nologo -f makefile.vc core OPTS=static,msvcrt,threads
+set OPTS=static,msvcrt,threads
+if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt,threads
+nmake -nologo -f makefile.vc core OPTS=%OPTS% %1
if errorlevel 1 goto error
+set SYMBOLS=
goto end
:error
echo *** BOOM! ***
+goto end
+
+:no_vcvars
+echo vcvars32.bat not found. You'll need to edit this batch script.
+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!
+title Building Tk, please wait... DONE!
echo DONE!
+goto out
+
+:out
pause
+title Command Prompt
diff --git a/win/configure b/win/configure
index 211b35c..b3a6294 100755
--- a/win/configure
+++ b/win/configure
@@ -1,42 +1,325 @@
#! /bin/sh
-
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+# 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
-# Defaults:
-ac_help=
+#
+# Initializations.
+#
ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
- --enable-threads build with threads"
-ac_help="$ac_help
- --enable-shared build and link with shared libraries [--enable-shared]"
-ac_help="$ac_help
- --enable-64bit enable 64bit support (where applicable)"
-ac_help="$ac_help
- --enable-wince enable Win/CE support (where applicable)"
-ac_help="$ac_help
- --with-celib=DIR use Windows/CE support library from DIR"
-ac_help="$ac_help
- --enable-symbols build with debugging symbols [--disable-symbols]"
-ac_help="$ac_help
- --enable-embedded-manifest embed manifest if possible (default: yes)"
-ac_help="$ac_help
- --with-tcl=DIR use Tcl 8.4 binaries from DIR"
+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 CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING MAN2TCLFLAGS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE 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 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 TK_SHARED_BUILD DEPARG EXTRA_CFLAGS STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES TK_RES RES LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_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 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.
-build=NONE
-cache_file=./config.cache
+cache_file=/dev/null
exec_prefix=NONE
-host=NONE
no_create=
-nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
@@ -45,10 +328,15 @@ program_transform_name=s,x,x,
silent=
site=
srcdir=
-target=NONE
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'
@@ -62,17 +350,9 @@ oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
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"
@@ -80,59 +360,59 @@ do
continue
fi
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
# Accept the important Cygnus configure options, so we can diagnose typos.
- case "$ac_option" in
+ case $ac_option in
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
+ bindir=$ac_optarg ;;
-build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
+ ac_prev=build_alias ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
+ 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" ;;
+ 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" ;;
+ datadir=$ac_optarg ;;
-disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
+ 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=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
+ 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'" ;;
+ eval "enable_$ac_feature='$ac_optarg'" ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -141,95 +421,47 @@ do
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
+ exec_prefix=$ac_optarg ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
- -help | --help | --hel | --he)
- # 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 << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
+ -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 ;;
+ ac_prev=host_alias ;;
-host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
+ 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" ;;
+ includedir=$ac_optarg ;;
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
+ infodir=$ac_optarg ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
+ 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" ;;
+ libexecdir=$ac_optarg ;;
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
@@ -238,19 +470,19 @@ EOF
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* \
| --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
+ localstatedir=$ac_optarg ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
+ 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)
+ | --no-cr | --no-c | -n)
no_create=yes ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
@@ -264,26 +496,26 @@ EOF
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
+ oldincludedir=$ac_optarg ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
+ 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_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_suffix=$ac_optarg ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
@@ -300,7 +532,7 @@ EOF
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
+ program_transform_name=$ac_optarg ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
@@ -310,7 +542,7 @@ EOF
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
+ sbindir=$ac_optarg ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
@@ -321,58 +553,57 @@ EOF
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
+ sharedstatedir=$ac_optarg ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
+ site=$ac_optarg ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
+ 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" ;;
+ sysconfdir=$ac_optarg ;;
-target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
+ ac_prev=target_alias ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
+ target_alias=$ac_optarg ;;
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.13"
- exit 0 ;;
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
-with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
+ 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
- *=*) ;;
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
*) ac_optarg=yes ;;
esac
- eval "with_${ac_package}='$ac_optarg'" ;;
+ eval "with_$ac_package='$ac_optarg'" ;;
-without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
+ 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.
@@ -383,99 +614,110 @@ EOF
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_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" ;;
+ x_libraries=$ac_optarg ;;
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ -*) { 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 ;;
+
*)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
+ # 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
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
fi
-exec 5>./config.log
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
+# 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
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ 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
-# NLS nuisances.
-# Only set these to C if already set. These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+# 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
-# 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
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=../generic/tk.h
# 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_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ 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=..
@@ -485,13 +727,471 @@ else
fi
if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
fi
fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+(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
+ --enable-shared build and link with shared libraries --enable-shared
+ --enable-64bit enable 64bit support (where applicable)
+ --enable-wince enable Win/CE support (where applicable)
+ --enable-symbols build with debugging symbols --disable-symbols
+ --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-celib=DIR use Windows/CE support library from DIR
+ --with-tcl=DIR use Tcl 8.5 binaries 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
@@ -502,47 +1202,116 @@ if test -z "$CONFIG_SITE"; then
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
+ { 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
- echo "loading cache $cache_file"
- . $cache_file
+ # 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 "creating cache $cache_file"
- > $cache_file
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
fi
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-ac_exeext=
-ac_objext=o
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
+# 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
-else
- ac_n= ac_c='\c' ac_t=
+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
+
+
+
+
+
+
+
+
+
+
+
+
+
-TK_VERSION=8.4
+
+
+
+
+
+# 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.5
TK_MAJOR_VERSION=8
-TK_MINOR_VERSION=4
-TK_PATCH_LEVEL=".19"
+TK_MINOR_VERSION=5
+TK_PATCH_LEVEL=".10"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION
#------------------------------------------------------------------------
@@ -568,214 +1337,659 @@ if test "${CFLAGS+set}" != "set" ; then
CFLAGS=""
fi
-# Extract the first word of "gcc", so it can be a program name with args.
+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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:575: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
+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"
+CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
+ 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
- echo "$ac_t""no" 1>&6
+ 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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:605: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
+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 $# -gt 0; then
+ 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
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
fi
fi
fi
fi
-CC="$ac_cv_prog_CC"
+CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
- if test -z "$CC"; then
- case "`uname -s`" in
- *win32* | *WIN32*)
- # Extract the first word of "cl", so it can be a program name with args.
-set dummy cl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:656: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="cl"
- break
- fi
- done
- IFS="$ac_save_ifs"
+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"
+CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
- ;;
- esac
+
+ 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
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+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
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:688: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+fi
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 699 "configure"
-#include "confdefs.h"
-
-main(){return(0);}
-EOF
-if { (eval echo configure:704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- ac_cv_prog_cc_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cc_cross=no
+
+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
- ac_cv_prog_cc_cross=yes
+ 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
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cc_works=no
fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-if test $ac_cv_prog_cc_works = no; then
- { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:730: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:735: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:744: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
+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
- ac_cv_prog_gcc=no
-fi
+ { { 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
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
+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
- GCC=
+ 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
-ac_test_CFLAGS="${CFLAGS+set}"
-ac_save_CFLAGS="$CFLAGS"
-CFLAGS=
-echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:763: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_cc_g=yes
+ 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
- ac_cv_prog_cc_g=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
fi
-rm -f conftest*
+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
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+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"
+ CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2"
@@ -789,146 +2003,1027 @@ 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
-# To properly support cross-compilation, one would
-# need to use these tool checks instead of
-# the ones below and reconfigure with
-# autoconf 2.50. You can also just set
-# the CC, AR, RANLIB, and RC environment
-# variables if you want to cross compile.
-#AC_CHECK_TOOL(AR, ar)
-#AC_CHECK_TOOL(RANLIB, ranlib)
-#AC_CHECK_TOOL(RC, windres)
+fi
-if test "${GCC}" = "yes" ; then
- # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:809: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_AR="ar"
- break
- fi
- done
- IFS="$ac_save_ifs"
+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"
+AR=$ac_cv_prog_AR
if test -n "$AR"; then
- echo "$ac_t""$AR" 1>&6
+ echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:838: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RANLIB="ranlib"
- break
- fi
- done
- IFS="$ac_save_ifs"
+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"
+RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
- echo "$ac_t""$RANLIB" 1>&6
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
- # Extract the first word of "windres", so it can be a program name with args.
-set dummy windres; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:867: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RC="windres"
- break
- fi
- done
- IFS="$ac_save_ifs"
+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"
+RC=$ac_cv_prog_RC
if test -n "$RC"; then
- echo "$ac_t""$RC" 1>&6
+ echo "$as_me:$LINENO: result: $RC" >&5
+echo "${ECHO_T}$RC" >&6
else
- echo "$ac_t""no" 1>&6
+ 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
- if test "${AR}" = "" ; then
- { echo "configure: error: Required archive tool 'ar' not found on PATH." 1>&2; exit 1; }
- fi
- if test "${RANLIB}" = "" ; then
- { echo "configure: error: Required archive index tool 'ranlib' not found on PATH." 1>&2; exit 1; }
- fi
- if test "${RC}" = "" ; then
- { echo "configure: error: Required resource tool 'windres' not found on PATH." 1>&2; exit 1; }
- fi
+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 progeam sets the $MAKE variable.
+# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
-echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:910: checking whether ${MAKE-make} sets \${MAKE}" >&5
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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 > conftestmake <<\EOF
+ cat >conftest.make <<\_ACEOF
all:
- @echo 'ac_maketemp="${MAKE}"'
-EOF
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+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 conftestmake
+rm -f conftest.make
fi
if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
- echo "$ac_t""yes" 1>&6
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
SET_MAKE=
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
SET_MAKE="MAKE=${MAKE-make}"
fi
@@ -937,129 +3032,80 @@ fi
# Perform additinal compiler tests.
#--------------------------------------------------------------------
-echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
-echo "configure:942: checking for Cygwin environment" >&5
-if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 947 "configure"
-#include "confdefs.h"
-
-int main() {
-#ifndef __CYGWIN__
-#define __CYGWIN__ __CYGWIN32__
+echo "$as_me:$LINENO: checking for Cygwin version of gcc" >&5
+echo $ECHO_N "checking for Cygwin version of gcc... $ECHO_C" >&6
+if test "${ac_cv_cygwin+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 __CYGWIN__
+#error cygwin
#endif
-return __CYGWIN__;
-; return 0; }
-EOF
-if { (eval echo configure:958: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_cygwin=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_cygwin=no
-fi
-rm -f conftest*
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_cygwin" 1>&6
-CYGWIN=
-test "$ac_cv_cygwin" = yes && CYGWIN=yes
-
-#--------------------------------------------------------------------
-# Determines the correct binary file extension (.o, .obj, .exe etc.)
-#--------------------------------------------------------------------
-echo $ac_n "checking for object suffix""... $ac_c" 1>&6
-echo "configure:980: checking for object suffix" >&5
-if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- rm -f conftest*
-echo 'int i = 1;' > conftest.$ac_ext
-if { (eval echo configure:986: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- for ac_file in conftest.*; do
- case $ac_file in
- *.c) ;;
- *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
- esac
- done
+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_cygwin=no
else
- { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
-fi
-rm -f conftest*
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_cygwin=yes
fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$ac_t""$ac_cv_objext" 1>&6
-OBJEXT=$ac_cv_objext
-ac_objext=$ac_cv_objext
-
-echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:1004: checking for mingw32 environment" >&5
-if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1009 "configure"
-#include "confdefs.h"
-
-int main() {
-return __MINGW32__;
-; return 0; }
-EOF
-if { (eval echo configure:1016: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_mingw32=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_mingw32=no
fi
-rm -f conftest*
-rm -f conftest*
+echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5
+echo "${ECHO_T}$ac_cv_cygwin" >&6
+if test "$ac_cv_cygwin" = "yes" ; then
+ { { echo "$as_me:$LINENO: error: Compiling under Cygwin is not currently supported.
+A maintainer for the Cygwin port of Tcl/Tk is needed. See the README
+file for information about building with Mingw." >&5
+echo "$as_me: error: Compiling under Cygwin is not currently supported.
+A maintainer for the Cygwin port of Tcl/Tk is needed. See the README
+file for information about building with Mingw." >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$ac_t""$ac_cv_mingw32" 1>&6
-MINGW32=
-test "$ac_cv_mingw32" = yes && MINGW32=yes
+#--------------------------------------------------------------------
+# Determines the correct binary file extension (.o, .obj, .exe etc.)
+#--------------------------------------------------------------------
-echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:1035: checking for executable suffix" >&5
-if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
- ac_cv_exeext=.exe
-else
- rm -f conftest*
- echo 'int main () { return 0; }' > conftest.$ac_ext
- ac_cv_exeext=
- if { (eval echo configure:1045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
- for file in conftest.*; do
- case $file in
- *.c | *.o | *.obj) ;;
- *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
- esac
- done
- else
- { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
- fi
- rm -f conftest*
- test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
-fi
-fi
-
-EXEEXT=""
-test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
-echo "$ac_t""${ac_cv_exeext}" 1>&6
-ac_exeext=$EXEEXT
#--------------------------------------------------------------------
@@ -1067,35 +3113,36 @@ ac_exeext=$EXEEXT
#--------------------------------------------------------------------
- echo $ac_n "checking for building with threads""... $ac_c" 1>&6
-echo "configure:1072: checking for building with threads" >&5
+ 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=no
-fi
-
+fi;
if test "$tcl_ok" = "yes"; then
- echo "$ac_t""yes" 1>&6
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
TCL_THREADS=1
- cat >> confdefs.h <<\EOF
+ cat >>confdefs.h <<\_ACEOF
#define TCL_THREADS 1
-EOF
+_ACEOF
# USE_THREAD_ALLOC tells us to try the special thread-based
# allocator that significantly reduces lock contention
- cat >> confdefs.h <<\EOF
+ cat >>confdefs.h <<\_ACEOF
#define USE_THREAD_ALLOC 1
-EOF
+_ACEOF
else
TCL_THREADS=0
- echo "$ac_t""no (default)" 1>&6
+ echo "$as_me:$LINENO: result: no (default)" >&5
+echo "${ECHO_T}no (default)" >&6
fi
-
+
#--------------------------------------------------------------------
@@ -1104,16 +3151,15 @@ EOF
#--------------------------------------------------------------------
- echo $ac_n "checking how to build libraries""... $ac_c" 1>&6
-echo "configure:1109: checking how to build libraries" >&5
+ 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
-
+fi;
if test "${enable_shared+set}" = set; then
enableval="$enable_shared"
@@ -1123,14 +3169,16 @@ fi
fi
if test "$tcl_ok" = "yes" ; then
- echo "$ac_t""shared" 1>&6
+ echo "$as_me:$LINENO: result: shared" >&5
+echo "${ECHO_T}shared" >&6
SHARED_BUILD=1
else
- echo "$ac_t""static" 1>&6
+ echo "$as_me:$LINENO: result: static" >&5
+echo "${ECHO_T}static" >&6
SHARED_BUILD=0
- cat >> confdefs.h <<\EOF
+ cat >>confdefs.h <<\_ACEOF
#define STATIC_BUILD 1
-EOF
+_ACEOF
fi
@@ -1141,79 +3189,158 @@ EOF
# 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 $ac_n "checking if 64bit support is requested""... $ac_c" 1>&6
-echo "configure:1150: checking if 64bit support is requested" >&5
+ 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 "$ac_t""$do64bit" 1>&6
+fi;
+ echo "$as_me:$LINENO: result: $do64bit" >&5
+echo "${ECHO_T}$do64bit" >&6
# Cross-compiling options for Windows/CE builds
- echo $ac_n "checking if Windows/CE build is requested""... $ac_c" 1>&6
-echo "configure:1164: checking if Windows/CE build is requested" >&5
+ 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
+fi;
+ echo "$as_me:$LINENO: result: $doWince" >&5
+echo "${ECHO_T}$doWince" >&6
- echo "$ac_t""$doWince" 1>&6
+ echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5
+echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6
- echo $ac_n "checking for Windows/CE celib directory""... $ac_c" 1>&6
-echo "configure:1176: checking for Windows/CE celib directory" >&5
- # Check whether --with-celib or --without-celib was given.
+# 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 "$ac_t""$CELIB_DIR" 1>&6
+fi;
+ echo "$as_me:$LINENO: result: $CELIB_DIR" >&5
+echo "${ECHO_T}$CELIB_DIR" >&6
# Set some defaults (may get changed below)
EXTRA_CFLAGS=""
# Extract the first word of "cygpath", so it can be a program name with args.
set dummy cygpath; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1193: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CYGPATH'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CYGPATH="cygpath -w"
- break
- fi
- done
- IFS="$ac_save_ifs"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CYGPATH="cygpath -w"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
fi
fi
-CYGPATH="$ac_cv_prog_CYGPATH"
+CYGPATH=$ac_cv_prog_CYGPATH
if test -n "$CYGPATH"; then
- echo "$ac_t""$CYGPATH" 1>&6
+ echo "$as_me:$LINENO: result: $CYGPATH" >&5
+echo "${ECHO_T}$CYGPATH" >&6
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
@@ -1236,13 +3363,20 @@ fi
echo "101 \"name\"" >> $conftest
echo "END" >> $conftest
- echo $ac_n "checking for Windows native path bug in windres""... $ac_c" 1>&6
-echo "configure:1241: checking for Windows native path bug in windres" >&5
+ 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 configure:1243: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } ; then
- echo "$ac_t""no" 1>&6
+ 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 "$ac_t""yes" 1>&6
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
CYGPATH=echo
fi
conftest=
@@ -1257,13 +3391,14 @@ echo "configure:1241: checking for Windows native path bug in windres" >&5
# set various compiler flags depending on whether we are using gcc or cl
- echo $ac_n "checking compiler flags""... $ac_c" 1>&6
-echo "configure:1262: checking compiler flags" >&5
+ 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_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32"
+ LIBS="-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=
@@ -1295,7 +3430,8 @@ echo "configure:1262: checking compiler flags" >&5
if test "${SHARED_BUILD}" = "0" ; then
# static
- echo "$ac_t""using static flags" 1>&6
+ echo "$as_me:$LINENO: result: using static flags" >&5
+echo "${ECHO_T}using static flags" >&6
runtime=
MAKE_DLL="echo "
LIBSUFFIX="s\${DBGX}.a"
@@ -1304,12 +3440,16 @@ echo "configure:1262: checking compiler flags" >&5
EXESUFFIX="s\${DBGX}.exe"
else
# dynamic
- echo "$ac_t""using shared flags" 1>&6
+ 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 "configure: error: ${CC} does not support the -shared option.
- You will need to upgrade to a newer version of the toolchain." 1>&2; exit 1; }
+ { { 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=
@@ -1336,7 +3476,7 @@ echo "configure:1262: checking compiler flags" >&5
CFLAGS_DEBUG=-g
CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- CFLAGS_WARNING="-Wall -fno-strict-aliasing"
+ CFLAGS_WARNING="-Wall"
LDFLAGS_DEBUG=
LDFLAGS_OPTIMIZE=
@@ -1364,47 +3504,78 @@ echo "configure:1262: checking compiler flags" >&5
case "$do64bit" in
amd64|x64|yes)
MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
- echo "$ac_t"" Using 64-bit $MACHINE mode" 1>&6
+ echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5
+echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6
;;
ia64)
MACHINE="IA64"
- echo "$ac_t"" Using 64-bit $MACHINE mode" 1>&6
+ echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5
+echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6
;;
*)
- cat > conftest.$ac_ext <<EOF
-#line 1376 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#ifdef _WIN64
#error 64-bit
#endif
-
-int main() {
-; return 0; }
-EOF
-if { (eval echo configure:1387: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+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=no
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- tcl_win_64bit=yes
-
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_win_64bit=yes
+
fi
-rm -f conftest*
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
if test "$tcl_win_64bit" = "yes" ; then
do64bit=amd64
MACHINE="AMD64"
- echo "$ac_t"" Using 64-bit $MACHINE mode" 1>&6
+ 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 "$ac_t""using static flags" 1>&6
+ echo "$as_me:$LINENO: result: using static flags" >&5
+echo "${ECHO_T}using static flags" >&6
runtime=-MT
MAKE_DLL="echo "
LIBSUFFIX="s\${DBGX}.lib"
@@ -1414,7 +3585,8 @@ rm -f conftest*
SHLIB_LD_LIBS=""
else
# dynamic
- echo "$ac_t""using shared flags" 1>&6
+ 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.
MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\$@"
@@ -1448,21 +3620,88 @@ rm -f conftest*
;;
esac
if test ! -d "${PATH64}" ; then
- echo "configure: warning: Could not find 64-bit $MACHINE SDK to enable 64bit mode" 1>&2
- echo "configure: warning: Ensure latest Platform SDK is installed" 1>&2
+ { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
+echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
+ { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5
+echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
do64bit="no"
else
- echo "$ac_t"" Using 64-bit $MACHINE mode" 1>&6
+ echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5
+echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6
fi
fi
- LIBS="user32.lib advapi32.lib"
+ LIBS="user32.lib advapi32.lib ws2_32.lib"
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.
- CC="\"${PATH64}/cl.exe\" -I\"${MSSDK}/Include\" \
- -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+ # 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.
@@ -1524,11 +3763,15 @@ rm -f conftest*
SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
if test ! -d "${CELIB_DIR}/inc"; then
- { echo "configure: error: Invalid celib directory "${CELIB_DIR}"" 1>&2; exit 1; }
+ { { 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 "configure: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" 1>&2; exit 1; }
+ { { 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
@@ -1550,28 +3793,28 @@ rm -f conftest*
arch=`echo ${ARCH} | awk '{print tolower($0)}'`
defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _DLL _WINDOWS"
for i in $defs ; do
- cat >> confdefs.h <<EOF
+ cat >>confdefs.h <<_ACEOF
#define $i 1
-EOF
+_ACEOF
done
# if test "${ARCH}" = "X86EM"; then
# AC_DEFINE_UNQUOTED(_WIN32_WCE_EMULATION)
# fi
- cat >> confdefs.h <<EOF
+ cat >>confdefs.h <<_ACEOF
#define _WIN32_WCE $CEVERSION
-EOF
+_ACEOF
- cat >> confdefs.h <<EOF
+ cat >>confdefs.h <<_ACEOF
#define UNDER_CE $CEVERSION
-EOF
+_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
@@ -1582,7 +3825,7 @@ EOF
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"
+ LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"
fi
SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
@@ -1621,190 +3864,303 @@ EOF
fi
fi
+ if test "$do64bit" != "no" ; then
+ cat >>confdefs.h <<\_ACEOF
+#define TCL_CFG_DO64BIT 1
+_ACEOF
+
+ fi
+
# DL_LIBS is empty, but then we match the Unix version
-
-
-
-
+
+
+
+
#--------------------------------------------------------------------
# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1637: checking how to run the C preprocessor" >&5
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
+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
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 1652 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1658: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 1669 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1675: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
+ # 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 "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -nologo -E"
- cat > conftest.$ac_ext <<EOF
-#line 1686 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1692: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
+ 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
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP=/lib/cpp
+ ac_cpp_err=yes
fi
-rm -f conftest*
+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*
+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
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
+
fi
- CPP="$ac_cv_prog_CPP"
+if test $ac_cv_header_errno_h = yes; then
+ :
else
- ac_cv_prog_CPP="$CPP"
+ MAN2TCLFLAGS="-DNO_ERRNO_H"
fi
-echo "$ac_t""$CPP" 1>&6
-ac_safe=`echo "errno.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for errno.h""... $ac_c" 1>&6
-echo "configure:1718: checking for errno.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+
+
+
+#--------------------------------------------------------------------
+# 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 <<EOF
-#line 1723 "configure"
-#include "confdefs.h"
-#include <errno.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1728: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
+ 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*
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- :
+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 "$ac_t""no" 1>&6
-MAN2TCLFLAGS="-DNO_ERRNO_H"
+ { echo "$as_me:$LINENO: xpnative theme will be unavailable" >&5
+echo "$as_me: xpnative theme will be unavailable" >&6;}
fi
#--------------------------------------------------------------------
-# Set the default compiler switches based on the --enable-symbols
+# 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 $ac_n "checking for build with symbols""... $ac_c" 1>&6
-echo "configure:1760: checking for build with symbols" >&5
+ 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
-
+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=""
- echo "$ac_t""no" 1>&6
+ 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 "$ac_t""yes (standard debugging)" 1>&6
+ echo "$as_me:$LINENO: result: yes (standard debugging)" >&5
+echo "${ECHO_T}yes (standard debugging)" >&6
fi
fi
-
-
+
+
+ cat >>confdefs.h <<\_ACEOF
+#define TCL_CFG_DEBUG 1
+_ACEOF
+
if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
- cat >> confdefs.h <<\EOF
+ cat >>confdefs.h <<\_ACEOF
#define TCL_MEM_DEBUG 1
-EOF
+_ACEOF
fi
if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then
- cat >> confdefs.h <<\EOF
+ cat >>confdefs.h <<\_ACEOF
#define TCL_COMPILE_DEBUG 1
-EOF
+_ACEOF
- cat >> confdefs.h <<\EOF
+ cat >>confdefs.h <<\_ACEOF
#define TCL_COMPILE_STATS 1
-EOF
+_ACEOF
fi
if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
if test "$tcl_ok" = "all"; then
- echo "$ac_t""enabled symbols mem compile debugging" 1>&6
+ echo "$as_me:$LINENO: result: enabled symbols mem compile debugging" >&5
+echo "${ECHO_T}enabled symbols mem compile debugging" >&6
else
- echo "$ac_t""enabled $tcl_ok debugging" 1>&6
+ echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
+echo "${ECHO_T}enabled $tcl_ok debugging" >&6
fi
fi
@@ -1816,53 +4172,58 @@ TK_DBGX=${DBGX}
#--------------------------------------------------------------------
- echo $ac_n "checking whether to embed manifest""... $ac_c" 1>&6
-echo "configure:1821: checking whether to embed manifest" >&5
+ 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
-
+fi;
- VC_MANIFEST_EMBED_DLL=
- VC_MANIFEST_EMBED_EXE=
+ 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 <<EOF
-#line 1838 "configure"
-#include "confdefs.h"
+ 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
-
-EOF
+
+_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "manifest needed" >/dev/null 2>&1; then
- rm -rf conftest*
-
+ $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
- VC_MANIFEST_EMBED_DLL="mt.exe -nologo -manifest \$@.manifest wish.exe.manifest -outputresource:\$@\;2"
- VC_MANIFEST_EMBED_EXE="mt.exe -nologo -manifest \$@.manifest wish.exe.manifest -outputresource:\$@\;1"
+ # 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 "$ac_t""$result" 1>&6
-
-
+ echo "$as_me:$LINENO: result: $result" >&5
+echo "${ECHO_T}$result" >&6
+
+
#--------------------------------------------------------------------
@@ -1870,42 +4231,49 @@ rm -f conftest*
#--------------------------------------------------------------------
- echo $ac_n "checking the location of tclConfig.sh""... $ac_c" 1>&6
-echo "configure:1875: checking the location of tclConfig.sh" >&5
+ echo "$as_me:$LINENO: checking the location of tclConfig.sh" >&5
+echo $ECHO_N "checking the location of tclConfig.sh... $ECHO_C" >&6
- if test -d ../../tcl8.4$TK_PATCH_LEVEL/win; then
- TCL_BIN_DIR_DEFAULT=../../tcl8.4$TK_PATCH_LEVEL/win
- elif test -d ../../tcl8.4/win; then
- TCL_BIN_DIR_DEFAULT=../../tcl8.4/win
+ if test -d ../../tcl8.5$TK_PATCH_LEVEL/win; then
+ TCL_BIN_DIR_DEFAULT=../../tcl8.5$TK_PATCH_LEVEL/win
+ elif test -d ../../tcl8.5/win; then
+ TCL_BIN_DIR_DEFAULT=../../tcl8.5/win
else
TCL_BIN_DIR_DEFAULT=../../tcl/win
fi
- # Check whether --with-tcl or --without-tcl was given.
+
+# Check whether --with-tcl or --without-tcl was given.
if test "${with_tcl+set}" = set; then
withval="$with_tcl"
TCL_BIN_DIR=$withval
else
TCL_BIN_DIR=`cd $TCL_BIN_DIR_DEFAULT; pwd`
-fi
-
+fi;
if test ! -d $TCL_BIN_DIR; then
- { echo "configure: error: Tcl directory $TCL_BIN_DIR does not exist" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: Tcl directory $TCL_BIN_DIR does not exist" >&5
+echo "$as_me: error: Tcl directory $TCL_BIN_DIR does not exist" >&2;}
+ { (exit 1); exit 1; }; }
fi
if test ! -f $TCL_BIN_DIR/tclConfig.sh; then
- { echo "configure: error: There is no tclConfig.sh in $TCL_BIN_DIR: perhaps you did not specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: There is no tclConfig.sh in $TCL_BIN_DIR: perhaps you did not specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?" >&5
+echo "$as_me: error: There is no tclConfig.sh in $TCL_BIN_DIR: perhaps you did not specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?" >&2;}
+ { (exit 1); exit 1; }; }
fi
- echo "$ac_t""$TCL_BIN_DIR/tclConfig.sh" 1>&6
+ echo "$as_me:$LINENO: result: $TCL_BIN_DIR/tclConfig.sh" >&5
+echo "${ECHO_T}$TCL_BIN_DIR/tclConfig.sh" >&6
- echo $ac_n "checking for existence of $TCL_BIN_DIR/tclConfig.sh""... $ac_c" 1>&6
-echo "configure:1903: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5
+ 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 "$ac_t""loading" 1>&6
+ echo "$as_me:$LINENO: result: loading" >&5
+echo "${ECHO_T}loading" >&6
. $TCL_BIN_DIR/tclConfig.sh
else
- echo "$ac_t""file not found" 1>&6
+ echo "$as_me:$LINENO: result: file not found" >&5
+echo "${ECHO_T}file not found" >&6
fi
#
@@ -1935,36 +4303,37 @@ echo "configure:1903: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5
eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
-
-
-
-
-
-
-
-
-
-
- echo $ac_n "checking for tclsh in Tcl build directory""... $ac_c" 1>&6
-echo "configure:1956: checking for tclsh in Tcl build directory" >&5
+
+
+
+
+
+
+
+
+
+
+ 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 "$ac_t""$BUILD_TCLSH" 1>&6
-
+ echo "$as_me:$LINENO: result: $BUILD_TCLSH" >&5
+echo "${ECHO_T}$BUILD_TCLSH" >&6
+
- echo $ac_n "checking for tclsh""... $ac_c" 1>&6
-echo "configure:1963: checking for tclsh" >&5
+ echo "$as_me:$LINENO: checking for tclsh" >&5
+echo $ECHO_N "checking for tclsh... $ECHO_C" >&6
- if eval "test \"`echo '$''{'ac_cv_path_tclsh'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&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` \
@@ -1977,19 +4346,21 @@ else
fi
done
done
-
+
fi
if test -f "$ac_cv_path_tclsh" ; then
TCLSH_PROG="$ac_cv_path_tclsh"
- echo "$ac_t""$TCLSH_PROG" 1>&6
+ 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 "$ac_t""No tclsh found on PATH" 1>&6
+ echo "$as_me:$LINENO: result: No tclsh found on PATH" >&5
+echo "${ECHO_T}No tclsh found on PATH" >&6
fi
-
+
#------------------------------------------------------------------------
@@ -2057,12 +4428,14 @@ else
fi
# The wish.exe.manifest requires these
-# TK_WIN_VERSION is the 4 dotted pair Windows version format
+# 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_WIN_VERSION="$TK_VERSION.0.`echo $TK_PATCH_LEVEL | tr -d a`" ;;
- b*) TK_WIN_VERSION="$TK_VERSION.1.`echo $TK_PATCH_LEVEL | tr -d b`" ;;
- .*) TK_WIN_VERSION="$TK_VERSION.2$TK_PATCH_LEVEL" ;;
+ *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
@@ -2137,358 +4510,1010 @@ esac
-
-
-
-
-
# undefined at this point for win
-trap '' 1 2 15
-cat > confcache <<\EOF
+ 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. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
+# 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.
#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
#
-EOF
+# `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 \
- -e "s/'/'\\\\''/g" \
- -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
- ;;
- esac >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
+{
+ (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
- echo "updating cache $cache_file"
- cat confcache > $cache_file
+ 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
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
+# 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[ ]*=[^:]*$/d'
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
fi
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
-cat > conftest.defs <<\EOF
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
-s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
-s%\[%\\&%g
-s%\]%\\&%g
-s%\$%$$%g
-EOF
-DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
-rm -f conftest.defs
-
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
+#
+# 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
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
+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.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
+# 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
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
+# 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
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.13"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
+ 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
-ac_given_srcdir=$srcdir
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
-trap 'rm -fr `echo "Makefile tkConfig.sh wish.exe.manifest" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@SHELL@%$SHELL%g
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@FFLAGS@%$FFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@CC@%$CC%g
-s%@AR@%$AR%g
-s%@RANLIB@%$RANLIB%g
-s%@RC@%$RC%g
-s%@SET_MAKE@%$SET_MAKE%g
-s%@OBJEXT@%$OBJEXT%g
-s%@EXEEXT@%$EXEEXT%g
-s%@TCL_THREADS@%$TCL_THREADS%g
-s%@CYGPATH@%$CYGPATH%g
-s%@CELIB_DIR@%$CELIB_DIR%g
-s%@DL_LIBS@%$DL_LIBS%g
-s%@CFLAGS_DEBUG@%$CFLAGS_DEBUG%g
-s%@CFLAGS_OPTIMIZE@%$CFLAGS_OPTIMIZE%g
-s%@CFLAGS_WARNING@%$CFLAGS_WARNING%g
-s%@CPP@%$CPP%g
-s%@MAN2TCLFLAGS@%$MAN2TCLFLAGS%g
-s%@CFLAGS_DEFAULT@%$CFLAGS_DEFAULT%g
-s%@LDFLAGS_DEFAULT@%$LDFLAGS_DEFAULT%g
-s%@VC_MANIFEST_EMBED_DLL@%$VC_MANIFEST_EMBED_DLL%g
-s%@VC_MANIFEST_EMBED_EXE@%$VC_MANIFEST_EMBED_EXE%g
-s%@TCL_VERSION@%$TCL_VERSION%g
-s%@TCL_BIN_DIR@%$TCL_BIN_DIR%g
-s%@TCL_SRC_DIR@%$TCL_SRC_DIR%g
-s%@TCL_LIB_FILE@%$TCL_LIB_FILE%g
-s%@TCL_LIB_FLAG@%$TCL_LIB_FLAG%g
-s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g
-s%@TCL_STUB_LIB_FILE@%$TCL_STUB_LIB_FILE%g
-s%@TCL_STUB_LIB_FLAG@%$TCL_STUB_LIB_FLAG%g
-s%@TCL_STUB_LIB_SPEC@%$TCL_STUB_LIB_SPEC%g
-s%@TCL_DEFS@%$TCL_DEFS%g
-s%@BUILD_TCLSH@%$BUILD_TCLSH%g
-s%@TCLSH_PROG@%$TCLSH_PROG%g
-s%@TK_WIN_VERSION@%$TK_WIN_VERSION%g
-s%@MACHINE@%$MACHINE%g
-s%@TK_VERSION@%$TK_VERSION%g
-s%@TK_MAJOR_VERSION@%$TK_MAJOR_VERSION%g
-s%@TK_MINOR_VERSION@%$TK_MINOR_VERSION%g
-s%@TK_PATCH_LEVEL@%$TK_PATCH_LEVEL%g
-s%@TK_DBGX@%$TK_DBGX%g
-s%@TK_LIB_FILE@%$TK_LIB_FILE%g
-s%@TK_DLL_FILE@%$TK_DLL_FILE%g
-s%@TK_STUB_LIB_FILE@%$TK_STUB_LIB_FILE%g
-s%@TK_STUB_LIB_FLAG@%$TK_STUB_LIB_FLAG%g
-s%@TK_BUILD_STUB_LIB_SPEC@%$TK_BUILD_STUB_LIB_SPEC%g
-s%@TK_SRC_DIR@%$TK_SRC_DIR%g
-s%@TK_BIN_DIR@%$TK_BIN_DIR%g
-s%@TCL_MAJOR_VERSION@%$TCL_MAJOR_VERSION%g
-s%@TCL_MINOR_VERSION@%$TCL_MINOR_VERSION%g
-s%@TCL_PATCH_LEVEL@%$TCL_PATCH_LEVEL%g
-s%@TCL_DLL_FILE@%$TCL_DLL_FILE%g
-s%@TCL_BUILD_STUB_LIB_SPEC@%$TCL_BUILD_STUB_LIB_SPEC%g
-s%@TCL_DBGX@%$TCL_DBGX%g
-s%@CFG_TK_SHARED_LIB_SUFFIX@%$CFG_TK_SHARED_LIB_SUFFIX%g
-s%@CFG_TK_UNSHARED_LIB_SUFFIX@%$CFG_TK_UNSHARED_LIB_SUFFIX%g
-s%@CFG_TK_EXPORT_FILE_SUFFIX@%$CFG_TK_EXPORT_FILE_SUFFIX%g
-s%@TK_SHARED_BUILD@%$TK_SHARED_BUILD%g
-s%@DEPARG@%$DEPARG%g
-s%@EXTRA_CFLAGS@%$EXTRA_CFLAGS%g
-s%@STLIB_LD@%$STLIB_LD%g
-s%@SHLIB_LD@%$SHLIB_LD%g
-s%@SHLIB_LD_LIBS@%$SHLIB_LD_LIBS%g
-s%@SHLIB_CFLAGS@%$SHLIB_CFLAGS%g
-s%@SHLIB_SUFFIX@%$SHLIB_SUFFIX%g
-s%@CC_OBJNAME@%$CC_OBJNAME%g
-s%@CC_EXENAME@%$CC_EXENAME%g
-s%@LDFLAGS_DEBUG@%$LDFLAGS_DEBUG%g
-s%@LDFLAGS_OPTIMIZE@%$LDFLAGS_OPTIMIZE%g
-s%@LDFLAGS_CONSOLE@%$LDFLAGS_CONSOLE%g
-s%@LDFLAGS_WINDOW@%$LDFLAGS_WINDOW%g
-s%@RC_OUT@%$RC_OUT%g
-s%@RC_TYPE@%$RC_TYPE%g
-s%@RC_INCLUDE@%$RC_INCLUDE%g
-s%@RC_DEFINE@%$RC_DEFINE%g
-s%@RC_DEFINES@%$RC_DEFINES%g
-s%@TK_RES@%$TK_RES%g
-s%@RES@%$RES%g
-s%@LIBS_GUI@%$LIBS_GUI%g
-s%@DLLSUFFIX@%$DLLSUFFIX%g
-s%@LIBPREFIX@%$LIBPREFIX%g
-s%@LIBSUFFIX@%$LIBSUFFIX%g
-s%@EXESUFFIX@%$EXESUFFIX%g
-s%@LIBRARIES@%$LIBRARIES%g
-s%@MAKE_LIB@%$MAKE_LIB%g
-s%@POST_MAKE_LIB@%$POST_MAKE_LIB%g
-s%@MAKE_DLL@%$MAKE_DLL%g
-s%@MAKE_EXE@%$MAKE_EXE%g
-s%@TK_LIB_FLAG@%$TK_LIB_FLAG%g
-s%@TK_LIB_SPEC@%$TK_LIB_SPEC%g
-s%@TK_BUILD_LIB_SPEC@%$TK_BUILD_LIB_SPEC%g
-s%@TK_STUB_LIB_SPEC@%$TK_STUB_LIB_SPEC%g
-s%@TK_STUB_LIB_PATH@%$TK_STUB_LIB_PATH%g
-s%@TK_BUILD_STUB_LIB_PATH@%$TK_BUILD_STUB_LIB_PATH%g
-s%@TK_CC_SEARCH_FLAGS@%$TK_CC_SEARCH_FLAGS%g
-s%@TK_LD_SEARCH_FLAGS@%$TK_LD_SEARCH_FLAGS%g
-CEOF
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-
-# 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_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # 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" conftest.subs > conftest.s$ac_file
+# 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
- sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ PATH_SEPARATOR=:
fi
- if test ! -s conftest.s$ac_file; then
- ac_more_lines=false
- rm -f conftest.s$ac_file
+ 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
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f conftest.s$ac_file"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
- fi
- ac_file=`expr $ac_file + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ 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
-if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
fi
-EOF
-cat >> $CONFIG_STATUS <<EOF
+_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
-CONFIG_FILES=\${CONFIG_FILES-"Makefile tkConfig.sh wish.exe.manifest"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
+_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
- # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+# 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
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dir_suffix= ac_dots=
+# 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,@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,@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,@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,@TK_SHARED_BUILD@,$TK_SHARED_BUILD,;t t
+s,@DEPARG@,$DEPARG,;t t
+s,@EXTRA_CFLAGS@,$EXTRA_CFLAGS,;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,@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,@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,@TK_RES@,$TK_RES,;t t
+s,@RES@,$RES,;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,@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,@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"
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
+_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
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
- esac
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
-EOF
-cat >> $CONFIG_STATUS <<EOF
+ 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
-EOF
-cat >> $CONFIG_STATUS <<\EOF
+cat >>$CONFIG_STATUS <<\_ACEOF
-exit 0
-EOF
+{ (exit 0); exit 0; }
+_ACEOF
chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+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/win/configure.in b/win/configure.in
index f7b0f33..bb29f41 100644
--- a/win/configure.in
+++ b/win/configure.in
@@ -4,12 +4,17 @@
# to configure the system for the local environment.
AC_INIT(../generic/tk.h)
-AC_PREREQ(2.13)
+AC_PREREQ(2.59)
-TK_VERSION=8.4
+# 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.5
TK_MAJOR_VERSION=8
-TK_MINOR_VERSION=4
-TK_PATCH_LEVEL=".19"
+TK_MINOR_VERSION=5
+TK_PATCH_LEVEL=".10"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION
#------------------------------------------------------------------------
@@ -36,35 +41,15 @@ if test "${CFLAGS+set}" != "set" ; then
fi
AC_PROG_CC
+AC_C_INLINE
+AC_HEADER_STDC
-# To properly support cross-compilation, one would
-# need to use these tool checks instead of
-# the ones below and reconfigure with
-# autoconf 2.50. You can also just set
-# the CC, AR, RANLIB, and RC environment
-# variables if you want to cross compile.
-#AC_CHECK_TOOL(AR, ar)
-#AC_CHECK_TOOL(RANLIB, ranlib)
-#AC_CHECK_TOOL(RC, windres)
-
-if test "${GCC}" = "yes" ; then
- AC_CHECK_PROG(AR, ar, ar)
- AC_CHECK_PROG(RANLIB, ranlib, ranlib)
- AC_CHECK_PROG(RC, windres, windres)
-
- if test "${AR}" = "" ; then
- AC_MSG_ERROR([Required archive tool 'ar' not found on PATH.])
- fi
- if test "${RANLIB}" = "" ; then
- AC_MSG_ERROR([Required archive index tool 'ranlib' not found on PATH.])
- fi
- if test "${RC}" = "" ; then
- AC_MSG_ERROR([Required resource tool 'windres' not found on PATH.])
- fi
-fi
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib)
+AC_CHECK_TOOL(RC, windres)
#--------------------------------------------------------------------
-# Checks to see if the make progeam sets the $MAKE variable.
+# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
AC_PROG_MAKE_SET
@@ -73,7 +58,27 @@ AC_PROG_MAKE_SET
# Perform additinal compiler tests.
#--------------------------------------------------------------------
-AC_CYGWIN
+dnl Currently AC_CYGWIN is disabled since it invokes AC_CANONICAL_HOST
+dnl under autoconf 2.5X.
+dnl
+dnl AC_CYGWIN
+
+AC_CACHE_CHECK(for Cygwin version of gcc,
+ ac_cv_cygwin,
+AC_TRY_COMPILE([
+#ifdef __CYGWIN__
+#error cygwin
+#endif
+],
+[],
+ ac_cv_cygwin=no,
+ ac_cv_cygwin=yes)
+)
+if test "$ac_cv_cygwin" = "yes" ; then
+ AC_MSG_ERROR([Compiling under Cygwin is not currently supported.
+A maintainer for the Cygwin port of Tcl/Tk is needed. See the README
+file for information about building with Mingw.])
+fi
#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
@@ -111,7 +116,15 @@ AC_CHECK_HEADER(errno.h, , MAN2TCLFLAGS="-DNO_ERRNO_H")
AC_SUBST(MAN2TCLFLAGS)
#--------------------------------------------------------------------
-# Set the default compiler switches based on the --enable-symbols
+# 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>])
+
+#--------------------------------------------------------------------
+# 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.
#--------------------------------------------------------------------
@@ -201,12 +214,14 @@ else
fi
# The wish.exe.manifest requires these
-# TK_WIN_VERSION is the 4 dotted pair Windows version format
+# 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_WIN_VERSION="$TK_VERSION.0.`echo $TK_PATCH_LEVEL | tr -d a`" ;;
- b*) TK_WIN_VERSION="$TK_VERSION.1.`echo $TK_PATCH_LEVEL | tr -d b`" ;;
- .*) TK_WIN_VERSION="$TK_VERSION.2$TK_PATCH_LEVEL" ;;
+ *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)
@@ -228,11 +243,6 @@ AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_MAJOR_VERSION)
AC_SUBST(TCL_MINOR_VERSION)
AC_SUBST(TCL_PATCH_LEVEL)
-AC_SUBST(TCL_LIB_FILE)
-AC_SUBST(TCL_DLL_FILE)
-AC_SUBST(TCL_STUB_LIB_FILE)
-AC_SUBST(TCL_STUB_LIB_FLAG)
-AC_SUBST(TCL_BUILD_STUB_LIB_SPEC)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(TCL_DBGX)
diff --git a/win/makefile.bc b/win/makefile.bc
index b62b1a4..12fd5b8 100644
--- a/win/makefile.bc
+++ b/win/makefile.bc
@@ -116,6 +116,7 @@ TKTESTOBJS = \
$(TMPDIR)\tkTest.obj \
$(TMPDIR)\tkSquare.obj \
$(TMPDIR)\testMain.obj \
+ $(TMPDIR)\tkOldTest.obj \
$(TMPDIR)\tkWinTest.obj \
$(TCLLIBDIR)\tclThreadTest.obj
@@ -229,7 +230,7 @@ TKOBJS = \
# Maintenance hint: Please have multiple members of TKSTUBOBJS be separated
# by exactly one ' ' (see below the rule for making TKSTUBLIB)
-TKSTUBOBJS = $(TMPDIR)\tkStubLib.obj $(TMPDIR)\tkStubImg.obj
+TKSTUBOBJS = $(TMPDIR)\tkStubLib.obj
WINDIR = $(ROOT)\win
GENERICDIR = $(ROOT)\generic
@@ -239,9 +240,9 @@ TCLLIBDIR = $(TCLDIR)\win\$(OUTDIRNAME)
RCDIR = $(WINDIR)\rc
TK_INCLUDES = -I$(WINDIR) -I$(GENERICDIR) -I$(BITMAPDIR) -I$(XLIBDIR) \
- -I$(TCLDIR)\generic
+ -I$(TCLDIR)\generic -I$(TCLDIR)\win
-TK_DEFINES = -D__WIN32__ $(DEBUGDEFINES) $(THREADDEFINES)
+TK_DEFINES = -D__WIN32__ $(DEBUGDEFINES) $(THREADDEFINES) SUPPORT_CONFIG_EMBEDDED
######################################################################
# Compile flags
@@ -447,6 +448,9 @@ $(TMPDIR)\testMain.obj: $(WINDIR)\winMain.c
$(TMPDIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
$(cc32) $(WISH_CFLAGS) -o$@ $?
+$(TMPDIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
+ $(cc32) $(WISH_CFLAGS) -o$@ $?
+
$(TMPDIR)\tkWinTest.obj: $(WINDIR)\tkWinTest.c
$(cc32) $(WISH_CFLAGS) -o$@ $?
diff --git a/win/makefile.vc b/win/makefile.vc
index 32dd4d5..89dbe30 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -9,7 +9,7 @@
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2001-2005 ActiveState Corporation.
-# Copyright (c) 2001-2002 David Gravereaux.
+# Copyright (c) 2001-2004 David Gravereaux.
#------------------------------------------------------------------------------
# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
@@ -71,25 +71,32 @@ the build instructions.
# Sets where to install Tcl from the built binaries.
# C:\Progra~1\Tcl is assumed when not specified.
#
-# OPTS=static,msvcrt,linkexten,threads,symbols,profile,none
+# OPTS=static,msvcrt,linkexten,threads,symbols,profile,unchecked,none
# Sets special options for the core. The default is for none.
# Any combination of the above may be used (comma separated).
# 'none' will over-ride everything to nothing.
#
-# static = Builds a static library of the core instead of a
+# static = Builds a static library of the core instead of a
# dll. The shell will be static (and large), as well.
-# msvcrt = Effects the static option only to switch it from
+# msvcrt = Effects the static option only to switch it from
# using libcmt(d) as the C runtime [by default] to
# msvcrt(d). This is useful for static embedding
# support.
-# staticpkg = Affects the static option only to switch wishXX.exe
+# staticpkg= Affects the static option only to switch wishXX.exe
# to have the dde and reg extension linked inside it.
-# threads = Turns on full multithreading support.
-# thrdalloc = Use the thread allocator (shared global free pool).
-# symbols = Adds symbols for step debugging.
-# profile = Adds profiling hooks. Map file is assumed.
-# loimpact = Adds a flag for how NT treats the heap to keep memory
-# in use, low. This is said to impact alloc performance.
+# threads = Turns on full multithreading support.
+# thrdalloc= Use the thread allocator (shared global free pool).
+# symbols = Adds symbols for step debugging.
+# profile = Adds profiling hooks. Map file is assumed.
+# loimpact = Adds a flag for how NT treats the heap to keep
+# memory in use, low. This is said to impact alloc
+# performance.
+# unchecked= Allows a symbols build to not use the debug
+# enabled runtime (msvcrt.dll not msvcrtd.dll
+# or libcmt.lib not libcmtd.lib).
+# noxp = If you do not have the uxtheme.h header then you
+# cannot include support for XP themeing.
+# square = Include the demo square widget.
#
# STATS=memdbg,compdbg,none
# Sets optional memory and bytecode compiler debugging code added
@@ -100,6 +107,14 @@ the build instructions.
# memdbg = Enables the debugging memory allocator.
# compdbg = Enables byte compilation logging.
#
+# CHECKS=nodep,fullwarn,none
+# Sets special macros for checking compatability.
+#
+# nodep = Turns off compatability macros to ensure Tk isn't
+# being built with deprecated functions.
+# fullwarn = Builds with full compiler and link warnings enabled.
+# Very verbose.
+#
# MACHINE=(IX86|IA64|AMD64|ALPHA)
# Set the machine type used for the compiler, linker, and
# resource compiler. This hook is needed to tell the tools
@@ -166,9 +181,26 @@ PROJECT = tk
!message *** Tcl sources.
!endif
+# Extra makefile options processing...
+!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
+HAVE_UXTHEME_H = 1
+TTK_SQUARE_WIDGET = 0
+!else
+!if [nmakehlp -f $(OPTS) "noxp"]
+!message *** Exclude support for XP theme
+HAVE_UXTHEME_H = 0
+!else
+HAVE_UXTHEME_H = 1
+!endif
+!if [nmakehlp -f "$(OPTS)" "square"]
+!message *** Include ttk square demo widget
+TTK_SQUARE_WIDGET = 1
+!else
+TTK_SQUARE_WIDGET = 0
+!endif
+!endif
+
STUBPREFIX = $(PROJECT)stub
-DOTVERSION = 8.4
-VERSION = $(DOTVERSION:.=)
WISHNAMEPREFIX = wish
BINROOT = .
@@ -176,15 +208,15 @@ ROOT = ..
TK_LIBRARY = $(ROOT)\library
-TKIMPLIB = "$(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib"
-TKLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+TKIMPLIB = "$(OUT_DIR)\$(PROJECT)$(TK_VERSION)$(SUFX).lib"
+TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
TKLIB = "$(OUT_DIR)\$(TKLIBNAME)"
-TKSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+TKSTUBLIBNAME = $(STUBPREFIX)$(TK_VERSION).lib
TKSTUBLIB = "$(OUT_DIR)\$(TKSTUBLIBNAME)"
-WISH = "$(OUT_DIR)\$(WISHNAMEPREFIX)$(VERSION)$(SUFX).exe"
-WISHC = "$(OUT_DIR)\$(WISHNAMEPREFIX)c$(VERSION)$(SUFX).exe"
+WISH = "$(OUT_DIR)\$(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe"
+WISHC = "$(OUT_DIR)\$(WISHNAMEPREFIX)c$(TK_VERSION)$(SUFX).exe"
TKTEST = "$(OUT_DIR)\$(PROJECT)test.exe"
CAT32 = "$(OUT_DIR)\cat32.exe"
@@ -192,7 +224,7 @@ CAT32 = "$(OUT_DIR)\cat32.exe"
LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(DOTVERSION)
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_DOTVERSION)
INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
WISHOBJS = \
@@ -204,11 +236,11 @@ WISHOBJS = \
$(TMP_DIR)\wish.res
TKTESTOBJS = \
- $(TMP_DIR)\tkTest.obj \
- $(TMP_DIR)\tkSquare.obj \
$(TMP_DIR)\testMain.obj \
- $(TMP_DIR)\tkWinTest.obj \
- $(TMP_DIR)\wish.res
+ $(TMP_DIR)\tkSquare.obj \
+ $(TMP_DIR)\tkTest.obj \
+ $(TMP_DIR)\tkOldTest.obj \
+ $(TMP_DIR)\tkWinTest.obj
XLIBOBJS = \
$(TMP_DIR)\xcolors.obj \
@@ -242,6 +274,7 @@ TKOBJS = \
$(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 \
@@ -319,32 +352,73 @@ TKOBJS = \
$(TMP_DIR)\tkStubInit.obj \
$(TMP_DIR)\tkStubLib.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)\tkStubImg.obj
+ $(TMP_DIR)\tkStubLib.obj $(TMP_DIR)\ttkStubLib.obj
WINDIR = $(ROOT)\win
GENERICDIR = $(ROOT)\generic
XLIBDIR = $(ROOT)\xlib
+TTKDIR = $(ROOT)\generic\ttk
BITMAPDIR = $(ROOT)\bitmaps
DOCDIR = $(ROOT)\doc
RCDIR = $(WINDIR)\rc
-!if $(TCLINSTALL)
-TCL_INCLUDES = -I "$(_TCLDIR)\include"
-!else
-TCL_INCLUDES = -I "$(_TCLDIR)\win" -I "$(_TCLDIR)\generic"
-!endif
TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(BITMAPDIR)" -I"$(XLIBDIR)" \
$(TCL_INCLUDES)
-TK_DEFINES = $(OPTDEFINES)
+CONFIG_DEFS =-DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 \
+ -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 \
+ -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 \
+ -DSUPPORT_CONFIG_EMBEDDED \
+!if $(HAVE_UXTHEME_H)
+ -DHAVE_UXTHEME_H=1 \
+!endif
+!if $(TTK_SQUARE_WIDGET)
+ -DTTK_SQUARE_WIDGET=1 \
+!endif
+TK_DEFINES =-DBUILD_ttk $(OPTDEFINES) $(CONFIG_DEFS)
#---------------------------------------------------------------------
# Compile flags
@@ -353,10 +427,14 @@ TK_DEFINES = $(OPTDEFINES)
!if !$(DEBUG)
!if $(OPTIMIZING)
### This cranks the optimization level to maximize speed
-cdebug = -O2 $(OPTIMIZATIONS)
+### We can't use -O2 because sometimes it causes problems.
+cdebug = $(OPTIMIZATIONS)
!else
cdebug =
!endif
+!if $(SYMBOLS)
+cdebug = $(cdebug) -Zi
+!endif
!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
### Warnings are too many, can't support warnings into errors.
cdebug = -Zi -Od $(DEBUGFLAGS)
@@ -365,26 +443,20 @@ cdebug = -Zi -WX $(DEBUGFLAGS)
!endif
### Declarations common to all compiler options
-cwarn = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
+cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
-!if $(FULLWARNINGS)
-cflags = $(cflags) -W4
-!else
-cflags = $(cflags) -W3
-!endif
-
!if $(MSVCRT)
-!if "$(DBGX)" == ""
-crt = -MD
-!else
+!if $(DEBUG) && !$(UNCHECKED)
crt = -MDd
-!endif
!else
-!if "$(DBGX)" == ""
-crt = -MT
+crt = -MD
+!endif
!else
+!if $(DEBUG) && !$(UNCHECKED)
crt = -MTd
+!else
+crt = -MT
!endif
!endif
@@ -392,6 +464,7 @@ BASE_CFLAGS = $(cdebug) $(cflags) $(crt) $(TK_INCLUDES)
TK_CFLAGS = $(BASE_CFLAGS) $(TK_DEFINES) -DUSE_TCL_STUBS
CON_CFLAGS = $(cdebug) $(cflags) $(crt) -DCONSOLE
WISH_CFLAGS = $(BASE_CFLAGS) $(TK_DEFINES)
+STUB_CFLAGS = $(cflags) $(cdebug) $(TK_DEFINES)
#---------------------------------------------------------------------
@@ -407,10 +480,6 @@ ldebug = -release -opt:ref -opt:icf,3
### Declarations common to all linker options
lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
-!if $(FULLWARNINGS)
-lflags = $(lflags) -warn:3
-!endif
-
!if $(PROFILE)
lflags = $(lflags) -profile
!endif
@@ -431,13 +500,15 @@ dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows
-baselibs = kernel32.lib advapi32.lib user32.lib
+baselibs = kernel32.lib user32.lib
# Avoid 'unresolved external symbol __security_cookie' errors.
# c.f. http://support.microsoft.com/?id=894573
!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
baselibs = $(baselibs) bufferoverflowU.lib
!endif
-guilibs = $(baselibs) shell32.lib gdi32.lib comdlg32.lib winspool.lib imm32.lib comctl32.lib
+!endif
+guilibs = $(baselibs) gdi32.lib
#---------------------------------------------------------------------
@@ -445,7 +516,7 @@ guilibs = $(baselibs) shell32.lib gdi32.lib comdlg32.lib winspool.lib imm32.li
#---------------------------------------------------------------------
!if "$(TESTPAT)" != ""
-TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!endif
@@ -461,40 +532,84 @@ install: install-binaries install-libraries install-docs
tktest: setup $(TKTEST) $(CAT32)
-test: setup $(TKTEST) $(TKLIB) $(CAT32)
- set TCL_LIBRARY=$(TCL_LIBRARY)
- set TK_LIBRARY=$(TK_LIBRARY)
+test: test-classic test-ttk
+
+test-classic: setup $(TKTEST) $(TKLIB) $(CAT32)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
!if $(TCLINSTALL)
- set PATH=$(_TCLDIR)\bin;$(PATH)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
!else
- set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
!if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE"
$(TKTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) | $(CAT32)
!else
- $(TKTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) > tests.log
- type tests.log | more
+ $(TKTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) | $(CAT32)
+!endif
+
+test-ttk: setup $(TKTEST) $(TKLIB) $(CAT32)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+!if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE"
+ $(TKTEST) "$(ROOT)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32)
+!else
+ $(TKTEST) "$(ROOT)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32)
!endif
runtest: setup $(TKTEST) $(TKLIB) $(CAT32)
- set TCL_LIBRARY=$(TCL_LIBRARY)
- set TK_LIBRARY=$(TK_LIBRARY)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
!if $(TCLINSTALL)
- set PATH=$(_TCLDIR)\bin;$(PATH)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
!else
- set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
$(TKTEST)
rundemo: setup $(TKTEST) $(TKLIB) $(CAT32)
- set TCL_LIBRARY=$(TCL_LIBRARY)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
!if $(TCLINSTALL)
- set PATH=$(_TCLDIR)\bin;$(PATH)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
!else
- set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
!endif
$(TKTEST) $(ROOT)\library\demos\widget
+shell: setup $(WISH)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+ $(WISH) <<
+ console show
+<<
+
+dbgshell: setup $(WISH)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TK_LIBRARY=$(TK_LIBRARY:\=/)
+ @set TCLLIBPATH=
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+ windbg $(WISH)
+
setup:
@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
@@ -523,77 +638,37 @@ $(TKSTUBLIB): $(TKSTUBOBJS)
$(WISH): $(WISHOBJS) $(TKIMPLIB)
- $(link32) $(guilflags) -out:$@ $(guilibs) $(TCLIMPLIB) $**
+ $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(TCLIMPLIB) $**
$(_VC_MANIFEST_EMBED_EXE)
+
$(WISHC): $(WISHOBJS) $(TKIMPLIB)
- $(link32) $(conlflags) -out:$@ $(guilibs) $(TCLIMPLIB) $**
+ $(link32) $(conlflags) -stack:2300000 -out:$@ $(guilibs) $(TCLIMPLIB) $**
$(_VC_MANIFEST_EMBED_EXE)
+
$(TKTEST): $(TKTESTOBJS) $(TKIMPLIB)
- $(link32) $(guilflags) -out:$@ $(guilibs) $(TCLIMPLIB) $**
+ $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(TCLIMPLIB) $**
$(_VC_MANIFEST_EMBED_EXE)
+
$(CAT32): $(_TCLDIR)\win\cat.c
$(cc32) $(CON_CFLAGS) -Fo$(TMP_DIR)\ $?
$(link32) $(conlflags) -out:$@ -stack:16384 $(TMP_DIR)\cat.obj $(baselibs)
$(_VC_MANIFEST_EMBED_EXE)
-install-binaries:
- @echo installing binaries in "$(BIN_INSTALL_DIR)"
- @$(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)
- @-del "$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
- @echo if {[package vcompare [package provide Tcl] $(TCL_DOTVERSION)] != 0} { return } > "$(OUT_DIR)\pkgIndex.tcl"
- @echo package ifneeded Tk $(DOTVERSION) [list load [file join $$dir .. .. bin $(TKLIBNAME)] Tk] >>"$(OUT_DIR)\pkgIndex.tcl"
- @$(CPY) "$(OUT_DIR)\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\"
-!endif
-
-install-libraries:
- @echo installing headers in "$(INCLUDE_INSTALL_DIR)"
- @$(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 library files in "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) "$(ROOT)\library\*" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\images\*" "$(SCRIPT_INSTALL_DIR)\images\"
- @$(CPY) "$(ROOT)\library\msgs\*" "$(SCRIPT_INSTALL_DIR)\msgs\"
- @echo installing demo files in "$(SCRIPT_INSTALL_DIR)\demos"
- @$(CPY) "$(ROOT)\library\demos\*" "$(SCRIPT_INSTALL_DIR)\demos\"
- @$(CPY) "$(ROOT)\library\demos\images\*" "$(SCRIPT_INSTALL_DIR)\demos\images\"
-
#---------------------------------------------------------------------
# Regenerate the stubs files.
#---------------------------------------------------------------------
genstubs:
- set TCL_LIBRARY=$(TCL_LIBRARY)
- $(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
- $(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls
-
-
-#---------------------------------------------------------------------
-# Generate the makefile depedancies.
-#---------------------------------------------------------------------
-
-depend:
!if !exist($(TCLSH))
@echo Build tclsh first!
!else
set TCL_LIBRARY=$(TCL_LIBRARY)
- $(TCLSH) $(TOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \
- -passthru:"-DBUILD_tcl $(TK_INCLUDES:"="")" $(GENERICDIR) \
- $(COMPATDIR) $(WINDIR) @<<
-$(TKOBJS)
-<<
+ $(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
+ $(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls
!endif
@@ -601,7 +676,7 @@ $(TKOBJS)
# Regenerate the windows help files.
#---------------------------------------------------------------------
-HLPBASE = $(PROJECT)$(VERSION)
+HLPBASE = $(PROJECT)$(TK_VERSION)
HELPFILE = $(OUT_DIR)\$(HLPBASE).hlp
HELPCNT = $(OUT_DIR)\$(HLPBASE).cnt
DOCTMP_DIR = $(OUT_DIR)\$(PROJECT)_docs
@@ -622,7 +697,7 @@ $(MAN2HELP) $(MAN2HELP2) $(INDEX): $(TCLTOOLSDIR)\$$(@F)
$(CPY) $(TCLTOOLSDIR)\$(@F) $(@D)
$(BMP):
- $(CPY) $(WINDIR)\$(@F) $(@D)
+ $(CPY) $(WINDIR)\rc\$(@F) $(@D)
$(HELPFILE): $(HELPRTF) $(BMP)
cd $(DOCTMP_DIR)
@@ -653,10 +728,12 @@ CreateButton(4, "FAQ", ExecFile("http://www.purl.org/NET/Tcl-FAQ/"))
$(CPY) "$(DOCTMP_DIR)\$(@B).cnt" "$(OUT_DIR)"
$(MAN2TCL): $(TCLTOOLSDIR)\$$(@B).c
- $(cc32) -nologo -G4 -ML -O2 -Fo$(@D)\ $(TCLTOOLSDIR)\$(@B).c -link -out:$@
+ $(cc32) $(TK_CFLAGS) -Fo$(@D)\ $(TCLTOOLSDIR)\$(@B).c
+ $(link32) $(conlflags) -out:$@ -stack:16384 $(@D)\man2tcl.obj
+ $(_VC_MANIFEST_EMBED_EXE)
$(HELPRTF): $(MAN2TCL) $(MAN2HELP) $(MAN2HELP2) $(INDEX)
- $(TCLSH) $(MAN2HELP) -bitmap $(BMP_NOPATH) $(PROJECT) $(VERSION) $(DOCDIR:\=/)
+ $(TCLSH) $(MAN2HELP) -bitmap $(BMP_NOPATH) $(PROJECT) $(TK_VERSION) $(DOCDIR:\=/)
install-docs:
!if exist($(HELPFILE))
@@ -664,25 +741,25 @@ install-docs:
$(CPY) "$(HELPCNT)" "$(DOC_INSTALL_DIR)\"
$(TCLSH) <<
puts "Installing $(PROJECT)'s helpfile contents into Tcl's ..."
-set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(VERSION).cnt" r]
+set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(TK_VERSION).cnt" r]
while {![eof $$f]} {
if {[regexp {:Include $(PROJECT)([0-9]{2}).cnt} [gets $$f] dummy ver]} {
- if {$$ver == $(VERSION)} {
+ if {$$ver == $(TK_VERSION)} {
puts "Already installed."
exit
} else {
# do something here logical to remove (or replace) it.
- puts "$$ver != $(VERSION), unfinished code path, die, die!"
+ puts "$$ver != $(TK_VERSION), unfinished code path, die, die!"
exit 1
}
}
}
close $$f
-set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(VERSION).cnt" a]
+set f [open "$(DOC_INSTALL_DIR:\=/)/tcl$(TK_VERSION).cnt" a]
puts $$f {:Include $(HLPBASE).cnt}
close $$f
<<
- start /wait winhlp32 -g $(DOC_INSTALL_DIR)\tcl$(VERSION).hlp
+ start /wait winhlp32 -g $(DOC_INSTALL_DIR)\tcl$(TK_VERSION).hlp
!endif
#---------------------------------------------------------------------
@@ -690,15 +767,16 @@ close $$f
#---------------------------------------------------------------------
$(TMP_DIR)\testMain.obj: $(WINDIR)\winMain.c
-!if $(TCL_USE_STATIC_PACKAGES)
- $(cc32) $(WISH_CFLAGS) -DTK_TEST -DTCL_USE_STATIC_PACKAGES -Fo$@ $?
-!else
- $(cc32) $(WISH_CFLAGS) -DTK_TEST -Fo$@ $?
-!endif
+ $(cc32) $(WISH_CFLAGS) -DTK_TEST \
+ -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
+ -Fo$@ $?
$(TMP_DIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
$(cc32) $(WISH_CFLAGS) -Fo$@ $?
+$(TMP_DIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
+ $(cc32) $(WISH_CFLAGS) -Fo$@ $?
+
$(TMP_DIR)\tkWinTest.obj: $(WINDIR)\tkWinTest.c
$(cc32) $(WISH_CFLAGS) -Fo$@ $?
@@ -706,87 +784,51 @@ $(TMP_DIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
$(cc32) $(WISH_CFLAGS) -Fo$@ $?
$(TMP_DIR)\winMain.obj: $(WINDIR)\winMain.c
-!if $(TCL_USE_STATIC_PACKAGES)
- $(cc32) $(WISH_CFLAGS) -DTCL_USE_STATIC_PACKAGES -Fo$@ $?
-!else
- $(cc32) $(WISH_CFLAGS) -Fo$@ $?
-!endif
+ $(cc32) $(WISH_CFLAGS) \
+ -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
+ -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) $(cdebug) $(cflags) $(TK_INCLUDES) -Zl -DSTATIC_BUILD -Fo$@ $?
+ $(cc32) $(STUB_CFLAGS) $(TK_INCLUDES) -Zl -DSTATIC_BUILD -Fo$@ $?
-$(TMP_DIR)\tkStubImg.obj : $(GENERICDIR)\tkStubImg.c
- $(cc32) $(cdebug) $(cflags) $(TK_INCLUDES) -Zl -DSTATIC_BUILD -Fo$@ $?
+$(TMP_DIR)\wish.exe.manifest: $(WINDIR)\wish.exe.manifest.in
+ @nmakehlp -s << $** >$@
+@MACHINE@ $(MACHINE:IX86=X86)
+@TK_WIN_VERSION@ $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION).0.0
+<<
#---------------------------------------------------------------------
-# Dedependency rules
+# Generate the makefile depedancies.
#---------------------------------------------------------------------
-$(TMP_DIR)\wish.exe.manifest: $(WINDIR)\wish.exe.manifest.in
-!if ![sed "1d" < NUL > NUL]
- sed -f << $** > $@
-s/@MACHINE@/$(MACHINE:IX86=X86)/
-s/@TK_WIN_VERSION@/$(DOTVERSION).0.0/
-<<
+depend:
+!if !exist($(TCLSH))
+ @echo Build tclsh first!
!else
- $(TCLSH) <<
-set f [open {$(WINDIR:\=/)/wish.exe.manifest.in} r]
-set data [read $$f]
-close $$f
-set mach {$(MACHINE)}
-if {[regexp -nocase {$(IX86)$$} $mach ]} {set mach X86}
-set winver "$(DOTVERSION).0.0"
-set data [string map [list @MACHINE@ $$mach @TK_WIN_VERSION@ $$winver] $$data]
-puts {Creating $(TMP_DIR:\=/)/wish.exe.manifest}
-set f [open {$(TMP_DIR:\=/)/wish.exe.manifest} w]
-puts -nonewline $$f $$data
-close $$f
-exit
+ 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
+
+#---------------------------------------------------------------------
+# Dedependency rules
+#---------------------------------------------------------------------
+
$(TMP_DIR)\tk.res: \
$(RCDIR)\buttons.bmp \
$(RCDIR)\cursor*.cur \
$(RCDIR)\tk.ico
-$(GENERICDIR)/default.h: $(WINDIR)/tkWinDefault.h
-$(GENERICDIR)/tkButton.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkCanvas.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkEntry.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkFrame.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkListbox.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkMenu.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkMenubutton.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkMessage.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkPanedWindow.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkScale.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkScrollbar.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkText.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkTextIndex.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkTextTag.c: $(GENERICDIR)/default.h
-$(GENERICDIR)/tkUndo.c: $(GENERICDIR)/tkUndo.h
-
-$(GENERICDIR)/tkText.c: $(GENERICDIR)/tkText.h
-$(GENERICDIR)/tkTextBTree.c: $(GENERICDIR)/tkText.h
-$(GENERICDIR)/tkTextDisp.c: $(GENERICDIR)/tkText.h
-$(GENERICDIR)/tkTextDisp.c: $(GENERICDIR)/tkText.h
-$(GENERICDIR)/tkTextImage.c: $(GENERICDIR)/tkText.h
-$(GENERICDIR)/tkTextIndex.c: $(GENERICDIR)/tkText.h
-$(GENERICDIR)/tkTextMark.c: $(GENERICDIR)/tkText.h
-$(GENERICDIR)/tkTextTag.c: $(GENERICDIR)/tkText.h
-$(GENERICDIR)/tkTextWind.c: $(GENERICDIR)/tkText.h
-
-$(GENERICDIR)/tkMacWinMenu.c: $(GENERICDIR)/tkMenu.h
-$(GENERICDIR)/tkMenu.c: $(GENERICDIR)/tkMenu.h
-$(GENERICDIR)/tkMenuDraw.c: $(GENERICDIR)/tkMenu.h
-$(WINDIR)/tkWinMenu.c: $(GENERICDIR)/tkMenu.h
-
!if exist("$(OUT_DIR)\depend.mk")
!include "$(OUT_DIR)\depend.mk"
!message *** Dependency rules in effect.
@@ -811,6 +853,11 @@ $<
$<
<<
+{$(TTKDIR)}.c{$(TMP_DIR)}.obj::
+ $(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
{$(WINDIR)}.c{$(TMP_DIR)}.obj::
$(cc32) -DBUILD_tk $(TK_CFLAGS) -Fo$(TMP_DIR)\ @<<
$<
@@ -821,40 +868,98 @@ $<
$<
<<
-!if $(DEBUG)
-RCDEBUG = -d DEBUG
-!else
-RCDEBUG =
-!endif
-!if $(TCL_THREADS)
-RCTHREADS = -d TCL_THREADS
-!else
-RCTHREADS =
-!endif
-!if $(STATIC_BUILD)
-RCSTATIC = -d STATIC_BUILD
-!else
-RCSTATIC =
-!endif
-
{$(RCDIR)}.rc{$(TMP_DIR)}.res:
$(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" $(TCL_INCLUDES) \
- $(RCDEBUG) $(RCTHREADS) $(RCSTATIC) \
- $<
+ -d DEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
+ -d TCL_THREADS=$(TCL_THREADS) \
+ -d STATIC_BUILD=$(STATIC_BUILD) \
+ $<
$(TMP_DIR)\tk.res: $(TMP_DIR)\wish.exe.manifest
$(TMP_DIR)\wish.res: $(TMP_DIR)\wish.exe.manifest
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+
#---------------------------------------------------------------------
-# Clean up
+# Installation.
#---------------------------------------------------------------------
-clean:
- -@$(RMDIR) $(TMP_DIR)
+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.5.0}]} { return }
+package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin $(TKLIBNAME)] Tk]
+<<
+ @$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)\"
+!endif
-hose: clean
- -@$(RMDIR) $(OUT_DIR)
+#"
+install-libraries:
+ @echo installing Tk headers
+ @$(CPY) "$(GENERICDIR)\tk.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(GENERICDIR)\tkDecls.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(GENERICDIR)\tkPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(XLIBDIR)\X11\*.h" "$(INCLUDE_INSTALL_DIR)\X11\"
+ @echo installing script library
+ @$(CPY) "$(ROOT)\library\*" "$(SCRIPT_INSTALL_DIR)\"
+ @echo installing theme library
+ @$(CPY) "$(ROOT)\library\ttk\*" "$(SCRIPT_INSTALL_DIR)\ttk\"
+ @echo installing demos
+ @$(CPY) "$(ROOT)\library\demos\*" "$(SCRIPT_INSTALL_DIR)\demos\"
+ @$(CPY) "$(ROOT)\library\demos\images\*" "$(SCRIPT_INSTALL_DIR)\demos\images\"
+ @echo installing images
+ @$(CPY) "$(ROOT)\library\images\*" "$(SCRIPT_INSTALL_DIR)\images\"
+ @echo installing language files
+ @$(CPY) "$(ROOT)\library\msgs\*" "$(SCRIPT_INSTALL_DIR)\msgs\"
-.SUFFIXES:
-.SUFFIXES:.c .rc
+#"
+
+#---------------------------------------------------------------------
+# Clean up
+#---------------------------------------------------------------------
+
+tidy:
+!if $(TKLIB) != $(TKIMPLIB)
+ @echo Removing $(TKLIB) ...
+ @if exist $(TKLIB) del $(TKLIB)
+!endif
+ @echo Removing $(TKIMPLIB) ...
+ @if exist $(TKIMPLIB) del $(TKIMPLIB)
+ @echo Removing $(WISH) ...
+ @if exist $(WISH) del $(WISH)
+ @echo Removing $(TKTEST) ...
+ @if exist $(TKTEST) del $(TKTEST)
+ @echo Removing $(TKSTUBLIB) ...
+ @if exist $(TKSTUBLIB) del $(TKSTUBLIB)
+
+clean:
+ @echo Cleaning $(TMP_DIR)\* ...
+ @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+ @echo Cleaning $(WINDIR)\nmakehlp.obj ...
+ @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+ @echo Cleaning $(WINDIR)\nmakehlp.exe ...
+ @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+ @echo Cleaning $(WINDIR)\_junk.pch ...
+ @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+ @echo Cleaning $(WINDIR)\vercl.x ...
+ @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+ @echo Cleaning $(WINDIR)\vercl.i ...
+ @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+ @echo Cleaning $(WINDIR)\versions.vc ...
+ @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+
+hose:
+ @echo Hosing $(OUT_DIR)\* ...
+ @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
diff --git a/win/nmakehlp.c b/win/nmakehlp.c
index 4657c81..f1b5f34 100644
--- a/win/nmakehlp.c
+++ b/win/nmakehlp.c
@@ -5,9 +5,10 @@
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
* ----------------------------------------------------------------------------
*/
@@ -17,9 +18,15 @@
#pragma comment (lib, "kernel32.lib")
#include <stdio.h>
#include <math.h>
+
+/*
+ * This library is required for x64 builds with _some_ versions
+ */
#if defined(_M_IA64) || defined(_M_AMD64)
+#if _MSC_FULL_VER > 140000000 && _MSC_FULL_VER <= 140040310
#pragma comment(lib, "bufferoverflowU")
#endif
+#endif
/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
@@ -34,6 +41,8 @@ int CheckForCompilerFeature(const char *option);
int CheckForLinkerFeature(const char *option);
int IsIn(const char *string, const char *substring);
int GrepForDefine(const char *file, const char *string);
+int SubstituteFile(const char *substs, const char *filename);
+const char * GetVersionFromFile(const char *filename, const char *match);
DWORD WINAPI ReadFromPipe(LPVOID args);
/* globals */
@@ -128,10 +137,35 @@ main(
return 2;
}
return GrepForDefine(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;
+ }
+ printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
+ return 0;
}
}
chars = snprintf(msg, sizeof(msg) - 1,
- "usage: %s -c|-l|-f ...\n"
+ "usage: %s -c|-l|-f|-g|-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]);
@@ -190,7 +224,7 @@ CheckForCompilerFeature(
* Base command line.
*/
- lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X ");
+ lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
/*
* Append our option for testing
@@ -224,7 +258,7 @@ CheckForCompilerFeature(
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);
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
return 2;
}
@@ -268,7 +302,9 @@ CheckForCompilerFeature(
return !(strstr(Out.buffer, "D4002") != NULL
|| strstr(Err.buffer, "D4002") != NULL
|| strstr(Out.buffer, "D9002") != NULL
- || strstr(Err.buffer, "D9002") != NULL);
+ || strstr(Err.buffer, "D9002") != NULL
+ || strstr(Out.buffer, "D2021") != NULL
+ || strstr(Err.buffer, "D2021") != NULL);
}
int
@@ -350,7 +386,7 @@ CheckForLinkerFeature(
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);
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
return 2;
}
@@ -391,9 +427,9 @@ CheckForLinkerFeature(
*/
return !(strstr(Out.buffer, "LNK1117") != NULL ||
- strstr(Err.buffer, "LNK1117") != NULL ||
- strstr(Out.buffer, "LNK4044") != NULL ||
- strstr(Err.buffer, "LNK4044") != NULL);
+ strstr(Err.buffer, "LNK1117") != NULL ||
+ strstr(Out.buffer, "LNK4044") != NULL ||
+ strstr(Err.buffer, "LNK4044") != NULL);
}
DWORD WINAPI
@@ -440,18 +476,16 @@ GrepForDefine(
const char *file,
const char *string)
{
- FILE *f;
char s1[51], s2[51], s3[51];
- int r = 0;
- double d1;
+ FILE *f = fopen(file, "rt");
- f = fopen(file, "rt");
if (f == NULL) {
return 0;
}
do {
- r = fscanf(f, "%50s", s1);
+ int r = fscanf(f, "%50s", s1);
+
if (r == 1 && !strcmp(s1, "#define")) {
/*
* Get next two words.
@@ -467,6 +501,8 @@ GrepForDefine(
*/
if (!strcmp(s2, string)) {
+ double d1;
+
fclose(f);
/*
@@ -485,3 +521,203 @@ GrepForDefine(
fclose(f);
return 0;
}
+
+/*
+ * 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.
+ */
+
+const char *
+GetVersionFromFile(
+ const char *filename,
+ const char *match)
+{
+ 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.
+ */
+
+ while (*p && !isdigit(*p)) {
+ ++p;
+ }
+
+ /*
+ * Find ending whitespace.
+ */
+
+ q = p;
+ while (*q && (isalnum(*q) || *q == '.')) {
+ ++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)
+ * <<
+ */
+
+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) {
+ char *ks, *ke, *vs, *ve;
+ ks = 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, ks, 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;
+}
+
+/*
+ * Local variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * indent-tabs-mode: t
+ * tab-width: 8
+ * End:
+ */
diff --git a/win/rc/cursor00.cur b/win/rc/cursor00.cur
index 337e6d4..0c58bfe 100644
--- a/win/rc/cursor00.cur
+++ b/win/rc/cursor00.cur
Binary files differ
diff --git a/win/rc/cursor02.cur b/win/rc/cursor02.cur
index fbc4774..46f0f11 100644
--- a/win/rc/cursor02.cur
+++ b/win/rc/cursor02.cur
Binary files differ
diff --git a/win/rc/cursor04.cur b/win/rc/cursor04.cur
index 9634c42..1b3028d 100644
--- a/win/rc/cursor04.cur
+++ b/win/rc/cursor04.cur
Binary files differ
diff --git a/win/rc/cursor06.cur b/win/rc/cursor06.cur
index f7188b2..bb06edf 100644
--- a/win/rc/cursor06.cur
+++ b/win/rc/cursor06.cur
Binary files differ
diff --git a/win/rc/cursor0a.cur b/win/rc/cursor0a.cur
index 3f8ef45..6bffda5 100644
--- a/win/rc/cursor0a.cur
+++ b/win/rc/cursor0a.cur
Binary files differ
diff --git a/win/rc/cursor0c.cur b/win/rc/cursor0c.cur
index 1014edd..a991da6 100644
--- a/win/rc/cursor0c.cur
+++ b/win/rc/cursor0c.cur
Binary files differ
diff --git a/win/rc/cursor0e.cur b/win/rc/cursor0e.cur
index 964058d..6e0434d 100644
--- a/win/rc/cursor0e.cur
+++ b/win/rc/cursor0e.cur
Binary files differ
diff --git a/win/rc/cursor12.cur b/win/rc/cursor12.cur
index 920c936..0d0d667 100644
--- a/win/rc/cursor12.cur
+++ b/win/rc/cursor12.cur
Binary files differ
diff --git a/win/rc/cursor1e.cur b/win/rc/cursor1e.cur
index 49fa7f7..3272db1 100644
--- a/win/rc/cursor1e.cur
+++ b/win/rc/cursor1e.cur
Binary files differ
diff --git a/win/rc/cursor20.cur b/win/rc/cursor20.cur
index cf177a1..48080be 100644
--- a/win/rc/cursor20.cur
+++ b/win/rc/cursor20.cur
Binary files differ
diff --git a/win/rc/cursor2a.cur b/win/rc/cursor2a.cur
index 8dca432..5e75f16 100644
--- a/win/rc/cursor2a.cur
+++ b/win/rc/cursor2a.cur
Binary files differ
diff --git a/win/rc/cursor3a.cur b/win/rc/cursor3a.cur
index 8176d1d..e3eda81 100644
--- a/win/rc/cursor3a.cur
+++ b/win/rc/cursor3a.cur
Binary files differ
diff --git a/win/rc/cursor46.cur b/win/rc/cursor46.cur
index 3e97094..4f969d1 100644
--- a/win/rc/cursor46.cur
+++ b/win/rc/cursor46.cur
Binary files differ
diff --git a/win/rc/cursor48.cur b/win/rc/cursor48.cur
index 2a56897..97e499a 100644
--- a/win/rc/cursor48.cur
+++ b/win/rc/cursor48.cur
Binary files differ
diff --git a/win/rc/cursor4c.cur b/win/rc/cursor4c.cur
index 0407d77..3512a51 100644
--- a/win/rc/cursor4c.cur
+++ b/win/rc/cursor4c.cur
Binary files differ
diff --git a/win/rc/cursor4e.cur b/win/rc/cursor4e.cur
index a58e3db..28992c4 100644
--- a/win/rc/cursor4e.cur
+++ b/win/rc/cursor4e.cur
Binary files differ
diff --git a/win/rc/cursor60.cur b/win/rc/cursor60.cur
index 847969d..dc61469 100644
--- a/win/rc/cursor60.cur
+++ b/win/rc/cursor60.cur
Binary files differ
diff --git a/win/rc/cursor62.cur b/win/rc/cursor62.cur
index 36404a5..ff7c009 100644
--- a/win/rc/cursor62.cur
+++ b/win/rc/cursor62.cur
Binary files differ
diff --git a/win/rc/cursor66.cur b/win/rc/cursor66.cur
index 81d53b4..269f772 100644
--- a/win/rc/cursor66.cur
+++ b/win/rc/cursor66.cur
Binary files differ
diff --git a/win/rc/cursor6c.cur b/win/rc/cursor6c.cur
index 1e8d6d8..d8fb0f1 100644
--- a/win/rc/cursor6c.cur
+++ b/win/rc/cursor6c.cur
Binary files differ
diff --git a/win/rc/cursor72.cur b/win/rc/cursor72.cur
index 4994c6e..471bcf0 100644
--- a/win/rc/cursor72.cur
+++ b/win/rc/cursor72.cur
Binary files differ
diff --git a/win/rc/cursor74.cur b/win/rc/cursor74.cur
index d5e4361..176d2b0 100644
--- a/win/rc/cursor74.cur
+++ b/win/rc/cursor74.cur
Binary files differ
diff --git a/win/rc/cursor86.cur b/win/rc/cursor86.cur
index 2d38c03..52cb5c3 100644
--- a/win/rc/cursor86.cur
+++ b/win/rc/cursor86.cur
Binary files differ
diff --git a/win/rc/cursor88.cur b/win/rc/cursor88.cur
index 62b8061..fdba0d63 100644
--- a/win/rc/cursor88.cur
+++ b/win/rc/cursor88.cur
Binary files differ
diff --git a/win/rc/cursor8a.cur b/win/rc/cursor8a.cur
index 6c5358d..369e71f 100644
--- a/win/rc/cursor8a.cur
+++ b/win/rc/cursor8a.cur
Binary files differ
diff --git a/win/rc/cursor8c.cur b/win/rc/cursor8c.cur
index 103010b..811a0c3 100644
--- a/win/rc/cursor8c.cur
+++ b/win/rc/cursor8c.cur
Binary files differ
diff --git a/win/rc/cursor90.cur b/win/rc/cursor90.cur
index 08731f8..3c655d5 100644
--- a/win/rc/cursor90.cur
+++ b/win/rc/cursor90.cur
Binary files differ
diff --git a/win/rc/cursor94.cur b/win/rc/cursor94.cur
index 7777d53..16e6b61 100644
--- a/win/rc/cursor94.cur
+++ b/win/rc/cursor94.cur
Binary files differ
diff --git a/win/rc/cursor9a.cur b/win/rc/cursor9a.cur
new file mode 100644
index 0000000..048f06b
--- /dev/null
+++ b/win/rc/cursor9a.cur
Binary files differ
diff --git a/win/lamp.bmp b/win/rc/lamp.bmp
index 834c0f9..834c0f9 100644
--- a/win/lamp.bmp
+++ b/win/rc/lamp.bmp
Binary files differ
diff --git a/win/rc/tk.rc b/win/rc/tk.rc
index 3c023cf..6a74be3 100644
--- a/win/rc/tk.rc
+++ b/win/rc/tk.rc
@@ -8,14 +8,14 @@
//
// build-up the name suffix that defines the type of build this is.
//
-#ifdef TCL_THREADS
+#if TCL_THREADS
#define SUFFIX_THREADS "t"
#else
#define SUFFIX_THREADS ""
#endif
-#ifdef DEBUG
-#define SUFFIX_DEBUG "d"
+#if DEBUG && !UNCHECKED
+#define SUFFIX_DEBUG "g"
#else
#define SUFFIX_DEBUG ""
#endif
@@ -41,7 +41,7 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Tk DLL\0"
- VALUE "OriginalFilename", "tk" STRINGIFY(JOIN(TK_MAJOR_VERSION,TK_MINOR_VERSION)) SUFFIX ".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"
diff --git a/win/rc/tk_base.rc b/win/rc/tk_base.rc
index 67d6807..3e065c9 100644
--- a/win/rc/tk_base.rc
+++ b/win/rc/tk_base.rc
@@ -136,3 +136,5 @@ 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/win/rc/wish.rc b/win/rc/wish.rc
index 533a97e..5cc2fa4 100644
--- a/win/rc/wish.rc
+++ b/win/rc/wish.rc
@@ -8,20 +8,20 @@
//
// build-up the name suffix that defines the type of build this is.
//
-#ifdef TCL_THREADS
+#if TCL_THREADS
#define SUFFIX_THREADS "t"
#else
#define SUFFIX_THREADS ""
#endif
-#ifdef STATIC_BUILD
+#if STATIC_BUILD
#define SUFFIX_STATIC "s"
#else
#define SUFFIX_STATIC ""
#endif
-#ifdef DEBUG
-#define SUFFIX_DEBUG "d"
+#if DEBUG && !UNCHECKED
+#define SUFFIX_DEBUG "g"
#else
#define SUFFIX_DEBUG ""
#endif
@@ -47,7 +47,7 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Wish Application\0"
- VALUE "OriginalFilename", "wish" STRINGIFY(JOIN(TK_MAJOR_VERSION,TK_MINOR_VERSION)) SUFFIX ".exe\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"
@@ -70,7 +70,7 @@ END
app ICON DISCARDABLE "wish.ico"
-#ifdef STATIC_BUILD
+#if STATIC_BUILD
#include "tk_base.rc"
#endif
diff --git a/win/rules.vc b/win/rules.vc
index eab35c8..e18dca9 100644
--- a/win/rules.vc
+++ b/win/rules.vc
@@ -8,7 +8,7 @@
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 2001-2003 David Gravereaux.
-# Copyright (c) 2003-2006 Patrick Thoyts
+# Copyright (c) 2003-2007 Patrick Thoyts
#------------------------------------------------------------------------------
!ifndef _RULES_VC
@@ -27,18 +27,6 @@ _INSTALLDIR = C:\Program Files\Tcl
_INSTALLDIR = $(INSTALLDIR:/=\)
!endif
-!ifndef MACHINE
-!if "$(CPU)" == "" || "$(CPU)" == "i386"
-MACHINE = IX86
-!else
-MACHINE = $(CPU)
-!endif
-!endif
-
-!ifndef CFG_ENCODING
-CFG_ENCODING = \"cp1252\"
-!endif
-
#----------------------------------------------------------
# Set the proper copy method to avoid overwrite questions
# to the user when copying files and selecting the right
@@ -47,17 +35,66 @@ CFG_ENCODING = \"cp1252\"
!if "$(OS)" == "Windows_NT"
RMDIR = rmdir /S /Q
+ERRNULL = 2>NUL
!if ![ver | find "4.0" > nul]
-CPY = echo y | xcopy /i
+CPY = echo y | xcopy /i >NUL
+COPY = copy >NUL
!else
CPY = xcopy /i /y >NUL
+COPY = copy /y >NUL
!endif
-!else
-CPY = xcopy /i
+!else # "$(OS)" != "Windows_NT"
+CPY = xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
+COPY = copy >_JUNK.OUT # On Win98 NUL does not work here.
RMDIR = deltree /Y
+NULL = \NUL # Used in testing directory existence
+ERRNULL = >NUL # Win9x shell cannot redirect stderr
!endif
MKDIR = mkdir
-COPY = copy /y >NUL
+
+#------------------------------------------------------------------------------
+# Determine the host and target architectures and compiler version.
+#------------------------------------------------------------------------------
+
+_HASH=^#
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+ && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
+ && ![echo ARCH=IX86 >> vercl.x] \
+ && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
+ && ![echo ARCH=AMD64 >> vercl.x] \
+ && ![echo $(_HASH)endif >> vercl.x] \
+ && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
+!include vercl.i
+!if ![echo VCVER= ^\> vercl.vc] \
+ && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
+!include vercl.vc
+!endif
+!endif
+!if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc]
+!endif
+
+!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
+NATIVE_ARCH=IX86
+!else
+NATIVE_ARCH=AMD64
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+!ifndef MACHINE
+MACHINE=$(ARCH)
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING = \"cp1252\"
+!endif
!message ===============================================================================
@@ -98,12 +135,8 @@ OPTIMIZATIONS = $(OPTIMIZATIONS) -Oi
OPTIMIZATIONS = $(OPTIMIZATIONS) -Op
!endif
-!if [nmakehlp -c -fp:precise]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -fp:precise
-!endif
-
-!if [nmakehlp -c -fp:except]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -fp:except
+!if [nmakehlp -c -fp:strict]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -fp:strict
!endif
!if [nmakehlp -c -Gs]
@@ -120,14 +153,11 @@ OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
DEBUGFLAGS =
-# the platform SDK has broken headers that break the runtime checks for amd64
-!if "$(MACHINE)" != "AMD64"
!if [nmakehlp -c -RTC1]
DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
!elseif [nmakehlp -c -GZ]
DEBUGFLAGS = $(DEBUGFLAGS) -GZ
!endif
-!endif
COMPILERFLAGS =-W3
@@ -178,36 +208,6 @@ LINKERFLAGS =-ltcg
!endif
#----------------------------------------------------------
-# MSVC8 (ships with Visual Studio 2005) generates a manifest
-# file that we should link into the binaries. This is how.
-#----------------------------------------------------------
-
-_VC_MANIFEST_EMBED_EXE=
-_VC_MANIFEST_EMBED_DLL=
-VCVER=0
-!if ![echo VCVERSION=_MSC_VER > vercl.x] \
- && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
-!include vercl.i
-!if $(VCVERSION) >= 1600
-VCVER=10
-!elseif $(VCVERSION) >= 1500
-VCVER=9
-!elseif $(VCVERSION) >= 1400
-VCVER=8
-!elseif $(VCVERSION) >= 1300
-VCVER=7
-!elseif $(VCVERSION) >= 1200
-VCVER=6
-!endif
-!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
-
-#----------------------------------------------------------
# Decode the options requested.
#----------------------------------------------------------
@@ -215,6 +215,7 @@ _VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -ou
STATIC_BUILD = 0
TCL_THREADS = 0
DEBUG = 0
+SYMBOLS = 0
PROFILE = 0
MSVCRT = 0
LOIMPACT = 0
@@ -252,6 +253,12 @@ 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
@@ -307,11 +314,8 @@ SUFX = tsgx
!if $(DEBUG)
BUILDDIRTOP = Debug
-DBGX = g
!else
BUILDDIRTOP = Release
-DBGX =
-SUFX = $(SUFX:g=)
!endif
!if "$(MACHINE)" != "IX86"
@@ -321,6 +325,10 @@ BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
!endif
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX = $(SUFX:g=)
+!endif
+
TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
!if !$(STATIC_BUILD)
@@ -379,13 +387,14 @@ TCL_COMPILE_DEBUG = 0
!endif
!endif
+
#----------------------------------------------------------
# Decode the checks requested.
#----------------------------------------------------------
!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
TCL_NO_DEPRECATED = 0
-FULLWARNINGS = 0
+WARNINGS = -W3
!else
!if [nmakehlp -f $(CHECKS) "nodep"]
!message *** Doing nodep check
@@ -395,9 +404,16 @@ TCL_NO_DEPRECATED = 0
!endif
!if [nmakehlp -f $(CHECKS) "fullwarn"]
!message *** Doing full warnings check
-FULLWARNINGS = 1
+WARNINGS = -W4
+!if [nmakehlp -l -warn:3]
+LINKERFLAGS = $(LINKERFLAGS) -warn:3
+!endif
!else
-FULLWARNINGS = 0
+WARNINGS = -W3
+!endif
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS = $(WARNINGS) -Wp64
!endif
!endif
@@ -405,7 +421,8 @@ FULLWARNINGS = 0
# Set our defines now armed with our options.
#----------------------------------------------------------
-OPTDEFINES =
+OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
!if $(TCL_MEM_DEBUG)
OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
!endif
@@ -421,6 +438,9 @@ OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
!if $(STATIC_BUILD)
OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
!if $(DEBUG)
OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DEBUG
@@ -436,16 +456,26 @@ OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
#----------------------------------------------------------
-# Get common info used when building extensions.
+# Locate the Tcl headers to build against
#----------------------------------------------------------
-!if "$(PROJECT)" != "tcl"
+!if "$(PROJECT)" == "tcl"
-!if !defined(TCLDIR)
+_TCL_H = ..\generic\tcl.h
+
+!else
+
+# If INSTALLDIR set to tcl root dir then reset to the lib dir.
!if exist("$(_INSTALLDIR)\include\tcl.h")
-TCLH = "$(_INSTALLDIR)\include\tcl.h"
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+!if !defined(TCLDIR)
+!if exist("$(_INSTALLDIR)\..\include\tcl.h")
TCLINSTALL = 1
-_TCLDIR = $(_INSTALLDIR)
+_TCLDIR = $(_INSTALLDIR)\..
+_TCL_H = $(_INSTALLDIR)\..\include\tcl.h
+TCLDIR = $(_INSTALLDIR)\..
!else
MSG=^
Failed to find tcl.h. Set the TCLDIR macro.
@@ -454,53 +484,181 @@ Failed to find tcl.h. Set the TCLDIR macro.
!else
_TCLDIR = $(TCLDIR:/=\)
!if exist("$(_TCLDIR)\include\tcl.h")
-TCLH = "$(_TCLDIR)\include\tcl.h"
TCLINSTALL = 1
+_TCL_H = $(_TCLDIR)\include\tcl.h
!elseif exist("$(_TCLDIR)\generic\tcl.h")
-TCLH = "$(_TCLDIR)\generic\tcl.h"
TCLINSTALL = 0
+_TCL_H = $(_TCLDIR)\generic\tcl.h
!else
MSG =^
Failed to find tcl.h. The TCLDIR macro does not appear correct.
!error $(MSG)
!endif
!endif
+!endif
-### TODO: add a command to nmakehlp.c to grep for Tcl's version from tcl.h.
-### Because nmake can't return a string, we'll need to play games with return
-### codes. It might look something like this:
-#!if [nmakehlp -g $(TCL.H)] == 81
-#TCL_DOTVERSION = 8.1
-#!elseif [nmakehlp -g $(TCL.H)] == 82
-#TCL_DOTVERSION = 8.2
-#...
-#!endif
+#--------------------------------------------------------------
+# Extract various version numbers from tcl headers
+# The generated file is then included in the makefile.
+#--------------------------------------------------------------
-TCL_DOTVERSION = 8.4
-TCL_VERSION = $(TCL_DOTVERSION:.=)
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
+
+# If building the tcl core then we need additional package versions
+!if "$(PROJECT)" == "tcl"
+!if [echo PKG_HTTP_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc]
+!endif
+!if [echo PKG_TCLTEST_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc]
+!endif
+!if [echo PKG_MSGCAT_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc]
+!endif
+!if [echo PKG_PLATFORM_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc]
+!endif
+!if [echo PKG_SHELL_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc]
+!endif
+!if [echo PKG_DDE_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\dde\pkgIndex.tcl "dde " >> versions.vc]
+!endif
+!if [echo PKG_REG_VER =\>> versions.vc] \
+ && [nmakehlp -V ..\library\reg\pkgIndex.tcl registry >> versions.vc]
+!endif
+!endif
+
+!include versions.vc
+
+#--------------------------------------------------------------
+# Setup tcl version dependent stuff headers
+#--------------------------------------------------------------
+
+!if "$(PROJECT)" != "tcl"
+
+TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+
+!if $(TCL_VERSION) < 81
+TCL_DOES_STUBS = 0
+!else
+TCL_DOES_STUBS = 1
+!endif
!if $(TCLINSTALL)
-TCLSH = "$(_INSTALLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
-TCLSTUBLIB = "$(_INSTALLDIR)\lib\tclstub$(TCL_VERSION).lib"
-TCLIMPLIB = "$(_INSTALLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
-TCL_LIBRARY = $(_INSTALLDIR)\lib
-TCLREGLIB = "$(_INSTALLDIR)\lib\tclreg11$(SUFX:t=).lib"
-TCLDDELIB = "$(_INSTALLDIR)\lib\tcldde12$(SUFX:t=).lib"
+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\tclreg12$(SUFX:t=).lib"
+TCLDDELIB = "$(_TCLDIR)\lib\tcldde13$(SUFX:t=).lib"
COFFBASE = \must\have\tcl\sources\to\build\this\target
TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES = -I"$(_TCLDIR)\include"
!else
TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH)) && $(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)\tclreg11$(SUFX:t=).lib"
-TCLDDELIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde12$(SUFX:t=).lib"
+TCLREGLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg12$(SUFX:t=).lib"
+TCLDDELIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde13$(SUFX:t=).lib"
COFFBASE = "$(_TCLDIR)\win\coffbase.txt"
TCLTOOLSDIR = $(_TCLDIR)\tools
+TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+!endif
+
!endif
+#-------------------------------------------------------------------------
+# Locate the Tk headers to build against
+#-------------------------------------------------------------------------
+
+!if "$(PROJECT)" == "tk"
+_TK_H = ..\generic\tk.h
+_INSTALLDIR = $(_INSTALLDIR)\..
!endif
+!ifdef PROJECT_REQUIRES_TK
+!if !defined(TKDIR)
+!if exist("$(_INSTALLDIR)\..\include\tk.h")
+TKINSTALL = 1
+_TKDIR = $(_INSTALLDIR)\..
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+!elseif exist("$(_TCLDIR)\include\tk.h")
+TKINSTALL = 1
+_TKDIR = $(_TCLDIR)
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+!endif
+!else
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL = 1
+_TK_H = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL = 0
+_TK_H = $(_TKDIR)\generic\tk.h
+!else
+MSG =^
+Failed to find tk.h. The TKDIR macro does not appear correct.
+!error $(MSG)
+!endif
+!endif
+!endif
+
+#-------------------------------------------------------------------------
+# Extract Tk version numbers
+#-------------------------------------------------------------------------
+
+!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk"
+
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+
+!include versions.vc
+
+TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+
+!if "$(PROJECT)" != "tk"
+!if $(TKINSTALL)
+WISH = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
+TKSTUBLIB = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
+TKIMPLIB = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
+TK_INCLUDES = -I"$(_TKDIR)\include"
+!else
+WISH = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
+TKSTUBLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
+TKIMPLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
+TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!endif
+!endif
+
+!endif
#----------------------------------------------------------
# Display stats being used.
@@ -510,8 +668,9 @@ TCLTOOLSDIR = $(_TCLDIR)\tools
!message *** Output directory will be '$(OUT_DIR)'
!message *** Suffix for binaries will be '$(SUFX)'
!message *** Optional defines are '$(OPTDEFINES)'
-!message *** Compiler version $(VCVER)
-!message *** Compiler options '$(OPTIMIZATIONS) $(DEBUGFLAGS)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Host architecture is $(NATIVE_ARCH)
+!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
!message *** Link options '$(LINKERFLAGS)'
!endif
diff --git a/win/stubs.c b/win/stubs.c
index 5fbc8d1..678b176 100644
--- a/win/stubs.c
+++ b/win/stubs.c
@@ -4,7 +4,9 @@
* Undocumented Xlib internal function
*/
-int _XInitImageFuncPtrs(XImage *image)
+int
+_XInitImageFuncPtrs(
+ XImage *image)
{
return 0;
}
@@ -14,18 +16,18 @@ int _XInitImageFuncPtrs(XImage *image)
*/
void
-XSetWMClientMachine(display, w, text_prop)
- Display* display;
- Window w;
- XTextProperty* text_prop;
+XSetWMClientMachine(
+ Display *display,
+ Window w,
+ XTextProperty *text_prop)
{
}
Status
-XStringListToTextProperty(list, count, text_prop_return)
- char** list;
- int count;
- XTextProperty* text_prop_return;
+XStringListToTextProperty(
+ char **list,
+ int count,
+ XTextProperty *text_prop_return)
{
return (Status) NULL;
}
@@ -35,354 +37,347 @@ XStringListToTextProperty(list, count, text_prop_return)
*/
void
-XChangeProperty(display, w, property, type, format, mode, data, nelements)
- Display* display;
- Window w;
- Atom property;
- Atom type;
- int format;
- int mode;
- _Xconst unsigned char* data;
- int nelements;
+XChangeProperty(
+ Display *display,
+ Window w,
+ Atom property,
+ Atom type,
+ int format,
+ int mode,
+ _Xconst unsigned char *data,
+ int nelements)
{
}
Cursor
-XCreateGlyphCursor(display, source_font, mask_font, source_char, mask_char,
- foreground_color, background_color)
- Display* display;
- Font source_font;
- Font mask_font;
- unsigned int source_char;
- unsigned int mask_char;
- XColor* foreground_color;
- XColor* background_color;
+XCreateGlyphCursor(
+ Display *display,
+ Font source_font,
+ Font mask_font,
+ unsigned int source_char,
+ unsigned int mask_char,
+ XColor *foreground_color,
+ XColor *background_color)
{
return 1;
}
XIC
-XCreateIC()
+XCreateIC(void)
{
return NULL;
}
Cursor
-XCreatePixmapCursor(display, source, mask, foreground_color,
- background_color, x, y)
- Display* display;
- Pixmap source;
- Pixmap mask;
- XColor* foreground_color;
- XColor* background_color;
- unsigned int x;
- unsigned int y;
+XCreatePixmapCursor(
+ Display *display,
+ Pixmap source,
+ Pixmap mask,
+ XColor *foreground_color,
+ XColor *background_color,
+ unsigned int x,
+ unsigned int y)
{
return (Cursor) NULL;
}
void
-XDeleteProperty(display, w, property)
- Display* display;
- Window w;
- Atom property;
+XDeleteProperty(
+ Display *display,
+ Window w,
+ Atom property)
{
}
void
-XDestroyIC(ic)
- XIC ic;
+XDestroyIC(
+ XIC ic)
{
}
Bool
-XFilterEvent(event, window)
- XEvent* event;
- Window window;
+XFilterEvent(
+ XEvent *event,
+ Window window)
{
return 0;
}
-extern void XForceScreenSaver(display, mode)
- Display* display;
- int mode;
+void
+XForceScreenSaver(
+ Display *display,
+ int mode)
{
}
void
-XFreeCursor(display, cursor)
- Display* display;
- Cursor cursor;
+XFreeCursor(
+ Display *display,
+ Cursor cursor)
{
}
GContext
-XGContextFromGC(gc)
- GC gc;
+XGContextFromGC(
+ GC gc)
{
return (GContext) NULL;
}
char *
-XGetAtomName(display, atom)
- Display* display;
- Atom atom;
+XGetAtomName(
+ Display *display,
+ Atom atom)
{
return NULL;
}
int
-XGetWindowAttributes(display, w, window_attributes_return)
- Display* display;
- Window w;
- XWindowAttributes* window_attributes_return;
+XGetWindowAttributes(
+ Display *display,
+ Window w,
+ XWindowAttributes *window_attributes_return)
{
return 0;
}
Status
-XGetWMColormapWindows(display, w, windows_return, count_return)
- Display* display;
- Window w;
- Window** windows_return;
- int* count_return;
+XGetWMColormapWindows(
+ Display *display,
+ Window w,
+ Window **windows_return,
+ int *count_return)
{
return (Status) NULL;
}
int
-XIconifyWindow(display, w, screen_number)
- Display* display;
- Window w;
- int screen_number;
+XIconifyWindow(
+ Display *display,
+ Window w,
+ int screen_number)
{
return 0;
}
XHostAddress *
-XListHosts(display, nhosts_return, state_return)
- Display* display;
- int* nhosts_return;
- Bool* state_return;
+XListHosts(
+ Display *display,
+ int *nhosts_return,
+ Bool *state_return)
{
return NULL;
}
int
-XLookupColor(display, colormap, color_name, exact_def_return,
- screen_def_return)
- Display* display;
- Colormap colormap;
- _Xconst char* color_name;
- XColor* exact_def_return;
- XColor* screen_def_return;
+XLookupColor(
+ Display *display,
+ Colormap colormap,
+ _Xconst char *color_name,
+ XColor *exact_def_return,
+ XColor *screen_def_return)
{
return 0;
}
void
-XNextEvent(display, event_return)
- Display* display;
- XEvent* event_return;
+XNextEvent(
+ Display *display,
+ XEvent *event_return)
{
}
void
-XPutBackEvent(display, event)
- Display* display;
- XEvent* event;
+XPutBackEvent(
+ Display *display,
+ XEvent *event)
{
}
void
-XQueryColors(display, colormap, defs_in_out, ncolors)
- Display* display;
- Colormap colormap;
- XColor* defs_in_out;
- int ncolors;
+XQueryColors(
+ Display *display,
+ Colormap colormap,
+ XColor *defs_in_out,
+ int ncolors)
{
}
int
-XQueryTree(display, w, root_return, parent_return, children_return,
- nchildren_return)
- Display* display;
- Window w;
- Window* root_return;
- Window* parent_return;
- Window** children_return;
- unsigned int* nchildren_return;
+XQueryTree(
+ Display *display,
+ Window w,
+ Window *root_return,
+ Window *parent_return,
+ Window **children_return,
+ unsigned int *nchildren_return)
{
return 0;
}
void
-XRefreshKeyboardMapping(event_map)
- XMappingEvent* event_map;
+XRefreshKeyboardMapping(
+ XMappingEvent *event_map)
{
}
Window
-XRootWindow(display, screen_number)
- Display* display;
- int screen_number;
+XRootWindow(
+ Display *display,
+ int screen_number)
{
return (Window) NULL;
}
void
-XSelectInput(display, w, event_mask)
- Display* display;
- Window w;
- long event_mask;
+XSelectInput(
+ Display *display,
+ Window w,
+ long event_mask)
{
}
int
-XSendEvent(display, w, propagate, event_mask, event_send)
- Display* display;
- Window w;
- Bool propagate;
- long event_mask;
- XEvent* event_send;
+XSendEvent(
+ Display *display,
+ Window w,
+ Bool propagate,
+ long event_mask,
+ XEvent *event_send)
{
return 0;
}
void
-XSetCommand(display, w, argv, argc)
- Display* display;
- Window w;
- CONST char** argv;
- int argc;
+XSetCommand(
+ Display *display,
+ Window w,
+ CONST char **argv,
+ int argc)
{
}
XErrorHandler
-XSetErrorHandler (handler)
- XErrorHandler handler;
+XSetErrorHandler(
+ XErrorHandler handler)
{
return NULL;
}
void
-XSetIconName(display, w, icon_name)
- Display* display;
- Window w;
- _Xconst char* icon_name;
+XSetIconName(
+ Display *display,
+ Window w,
+ _Xconst char *icon_name)
{
}
void
-XSetWindowBackground(display, w, background_pixel)
- Display* display;
- Window w;
- unsigned long background_pixel;
+XSetWindowBackground(
+ Display *display,
+ Window w,
+ unsigned long background_pixel)
{
}
void
-XSetWindowBackgroundPixmap(display, w, background_pixmap)
- Display* display;
- Window w;
- Pixmap background_pixmap;
+XSetWindowBackgroundPixmap(
+ Display *display,
+ Window w,
+ Pixmap background_pixmap)
{
}
void
-XSetWindowBorder(display, w, border_pixel)
- Display* display;
- Window w;
- unsigned long border_pixel;
+XSetWindowBorder(
+ Display *display,
+ Window w,
+ unsigned long border_pixel)
{
}
void
-XSetWindowBorderPixmap(display, w, border_pixmap)
- Display* display;
- Window w;
- Pixmap border_pixmap;
+XSetWindowBorderPixmap(
+ Display *display,
+ Window w,
+ Pixmap border_pixmap)
{
}
void
-XSetWindowBorderWidth(display, w, width)
- Display* display;
- Window w;
- unsigned int width;
+XSetWindowBorderWidth(
+ Display *display,
+ Window w,
+ unsigned int width)
{
}
void
-XSetWindowColormap(display, w, colormap)
- Display* display;
- Window w;
- Colormap colormap;
+XSetWindowColormap(
+ Display *display,
+ Window w,
+ Colormap colormap)
{
}
Bool
-XTranslateCoordinates(display, src_w, dest_w, src_x, src_y, dest_x_return,
- dest_y_return, child_return)
- 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;
+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;
}
void
-XWindowEvent(display, w, event_mask, event_return)
- Display* display;
- Window w;
- long event_mask;
- XEvent* event_return;
+XWindowEvent(
+ Display *display,
+ Window w,
+ long event_mask,
+ XEvent *event_return)
{
}
int
-XWithdrawWindow(display, w, screen_number)
- Display* display;
- Window w;
- int screen_number;
+XWithdrawWindow(
+ Display *display,
+ Window w,
+ int screen_number)
{
return 0;
}
int
-XmbLookupString(ic, event, buffer_return, bytes_buffer, keysym_return,
- status_return)
- XIC ic;
- XKeyPressedEvent* event;
- char* buffer_return;
- int bytes_buffer;
- KeySym* keysym_return;
- Status* status_return;
+XmbLookupString(
+ XIC ic,
+ XKeyPressedEvent *event,
+ char *buffer_return,
+ int bytes_buffer,
+ KeySym *keysym_return,
+ Status *status_return)
{
return 0;
}
int
-XGetWindowProperty(display, w, property, long_offset, long_length, delete,
- req_type, actual_type_return, actual_format_return, nitems_return,
- bytes_after_return, prop_return)
- 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;
+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;
diff --git a/win/tcl.m4 b/win/tcl.m4
index 82bef11..83a4ea3 100644
--- a/win/tcl.m4
+++ b/win/tcl.m4
@@ -20,15 +20,15 @@
AC_DEFUN([SC_PATH_TCLCONFIG], [
AC_MSG_CHECKING([the location of tclConfig.sh])
- if test -d ../../tcl8.4$1/win; then
- TCL_BIN_DIR_DEFAULT=../../tcl8.4$1/win
- elif test -d ../../tcl8.4/win; then
- TCL_BIN_DIR_DEFAULT=../../tcl8.4/win
+ if test -d ../../tcl8.5$1/win; then
+ TCL_BIN_DIR_DEFAULT=../../tcl8.5$1/win
+ elif test -d ../../tcl8.5/win; then
+ TCL_BIN_DIR_DEFAULT=../../tcl8.5/win
else
TCL_BIN_DIR_DEFAULT=../../tcl/win
fi
- AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.4 binaries from DIR],
+ AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.5 binaries from DIR],
TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DIR_DEFAULT; pwd`)
if test ! -d $TCL_BIN_DIR; then
AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist)
@@ -60,15 +60,15 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [
AC_DEFUN([SC_PATH_TKCONFIG], [
AC_MSG_CHECKING([the location of tkConfig.sh])
- if test -d ../../tk8.4$1/win; then
- TK_BIN_DIR_DEFAULT=../../tk8.4$1/win
- elif test -d ../../tk8.4/win; then
- TK_BIN_DIR_DEFAULT=../../tk8.4/win
+ if test -d ../../tk8.5$1/win; then
+ TK_BIN_DIR_DEFAULT=../../tk8.5$1/win
+ elif test -d ../../tk8.5/win; then
+ TK_BIN_DIR_DEFAULT=../../tk8.5/win
else
TK_BIN_DIR_DEFAULT=../../tk/win
fi
- AC_ARG_WITH(tk, [ --with-tk=DIR use Tk 8.4 binaries from DIR],
+ AC_ARG_WITH(tk, [ --with-tk=DIR use Tk 8.5 binaries from DIR],
TK_BIN_DIR=$withval, TK_BIN_DIR=`cd $TK_BIN_DIR_DEFAULT; pwd`)
if test ! -d $TK_BIN_DIR; then
AC_MSG_ERROR(Tk directory $TK_BIN_DIR does not exist)
@@ -301,6 +301,8 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
DBGX=""
AC_MSG_RESULT([no])
+
+ AC_DEFINE(TCL_CFG_OPTIMIZED)
else
CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
@@ -311,6 +313,7 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
fi
AC_SUBST(CFLAGS_DEFAULT)
AC_SUBST(LDFLAGS_DEFAULT)
+ AC_DEFINE(TCL_CFG_DEBUG)
if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
AC_DEFINE(TCL_MEM_DEBUG)
@@ -445,8 +448,9 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
if test "${GCC}" = "yes" ; then
SHLIB_LD=""
SHLIB_LD_LIBS=""
- LIBS=""
- LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32"
+ LIBS="-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=
@@ -519,7 +523,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
CFLAGS_DEBUG=-g
CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- CFLAGS_WARNING="-Wall -fno-strict-aliasing"
+ CFLAGS_WARNING="-Wall"
LDFLAGS_DEBUG=
LDFLAGS_OPTIMIZE=
@@ -624,13 +628,17 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
fi
fi
- LIBS="user32.lib advapi32.lib"
+ LIBS="user32.lib advapi32.lib ws2_32.lib"
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.
- CC="\"${PATH64}/cl.exe\" -I\"${MSSDK}/Include\" \
- -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+ # 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.
@@ -741,7 +749,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
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"
+ LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"
fi
SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
@@ -780,6 +788,10 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
fi
fi
+ if test "$do64bit" != "no" ; then
+ AC_DEFINE(TCL_CFG_DO64BIT)
+ fi
+
# DL_LIBS is empty, but then we match the Unix version
AC_SUBST(DL_LIBS)
AC_SUBST(CFLAGS_DEBUG)
@@ -805,13 +817,13 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
#------------------------------------------------------------------------
AC_DEFUN([SC_WITH_TCL], [
- if test -d ../../tcl8.4$1/win; then
- TCL_BIN_DEFAULT=../../tcl8.4$1/win
+ if test -d ../../tcl8.5$1/win; then
+ TCL_BIN_DEFAULT=../../tcl8.5$1/win
else
- TCL_BIN_DEFAULT=../../tcl8.4/win
+ TCL_BIN_DEFAULT=../../tcl8.5/win
fi
- AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.4 binaries from DIR],
+ AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.5 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)
@@ -898,6 +910,34 @@ AC_DEFUN([SC_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
@@ -915,11 +955,12 @@ AC_DEFUN([SC_BUILD_TCLSH], [
AC_DEFUN([SC_EMBED_MANIFEST], [
AC_MSG_CHECKING(whether to embed manifest)
AC_ARG_ENABLE(embedded-manifest,
- [ --enable-embedded-manifest embed manifest if possible (default: yes)],
+ 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=
+ VC_MANIFEST_EMBED_DLL=
+ VC_MANIFEST_EMBED_EXE=
result=no
if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \
-a "$GCC" != "yes" ; then
@@ -932,8 +973,11 @@ print("manifest needed")
# 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
- VC_MANIFEST_EMBED_DLL="mt.exe -nologo -manifest \[$]@.manifest $1 -outputresource:\[$]@\;2"
- VC_MANIFEST_EMBED_EXE="mt.exe -nologo -manifest \[$]@.manifest $1 -outputresource:\[$]@\;1"
+ # 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)"
diff --git a/win/tkConfig.sh.in b/win/tkConfig.sh.in
index 0c53602..7816b15 100644
--- a/win/tkConfig.sh.in
+++ b/win/tkConfig.sh.in
@@ -11,6 +11,8 @@
#
# 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@'
diff --git a/win/tkWin.h b/win/tkWin.h
index 7c8eb59..d97adc7 100644
--- a/win/tkWin.h
+++ b/win/tkWin.h
@@ -13,6 +13,21 @@
#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 assignements.
+ *
+ * WINVER = 0x0410 means Windows 98 and above
+ */
+
+#ifndef WINVER
+#define WINVER 0x0410
+#endif
+#ifndef _WIN32_WINDOWS
+#define _WIN32_WINDOWS 0x0410
+#endif
+
#ifndef _TK
#include <tk.h>
#endif
@@ -27,14 +42,35 @@
#endif
/*
- * The following messages are use to communicate between a Tk toplevel
- * and its container window.
+ * 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)
-#define TK_GEOMETRYREQ (WM_USER+1)
-#define TK_ATTACHWINDOW (WM_USER+2)
-#define TK_DETACHWINDOW (WM_USER+3)
+#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
/*
diff --git a/win/tkWin32Dll.c b/win/tkWin32Dll.c
index cd9942a..efefe86 100644
--- a/win/tkWin32Dll.c
+++ b/win/tkWin32Dll.c
@@ -5,8 +5,8 @@
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkWinInt.h"
@@ -66,10 +66,10 @@ BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
*/
BOOL APIENTRY
-DllEntryPoint(hInst, reason, reserved)
- HINSTANCE hInst; /* Library instance handle. */
- DWORD reason; /* Reason this function is being called. */
- LPVOID reserved; /* Not used. */
+DllEntryPoint(
+ HINSTANCE hInst, /* Library instance handle. */
+ DWORD reason, /* Reason this function is being called. */
+ LPVOID reserved) /* Not used. */
{
return DllMain(hInst, reason, reserved);
}
@@ -95,11 +95,11 @@ DllEntryPoint(hInst, reason, reserved)
*----------------------------------------------------------------------
*/
-BOOL WINAPI
-DllMain(hInstance, reason, reserved)
- HINSTANCE hInstance;
- DWORD reason;
- LPVOID reserved;
+BOOL APIENTRY
+DllMain(
+ HINSTANCE hInstance,
+ DWORD reason,
+ LPVOID reserved)
{
#ifdef HAVE_NO_SEH
EXCEPTION_REGISTRATION registration;
@@ -150,7 +150,7 @@ DllMain(hInstance, reason, reserved)
* Call TkFinalize
*/
- "movq $0x0, %%rcx" "\n\t"
+ "movq $0x0, 0x0(%%esp)" "\n\t"
"call TkFinalize" "\n\t"
/*
diff --git a/win/tkWin3d.c b/win/tkWin3d.c
index 8b541e7..df6aa95 100644
--- a/win/tkWin3d.c
+++ b/win/tkWin3d.c
@@ -1,29 +1,28 @@
-/*
+/*
* tkWin3d.c --
*
- * This file contains the platform specific routines for
- * drawing 3d borders in the Windows 95 style.
+ * 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.
+ * 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.
+ * 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 */
+ XColor *light2ColorPtr; /* System3dLight */
+ XColor *dark2ColorPtr; /* System3dDarkShadow */
} WinBorder;
-
/*
*----------------------------------------------------------------------
@@ -42,9 +41,10 @@ typedef struct {
*/
TkBorder *
-TkpGetBorder()
+TkpGetBorder(void)
{
WinBorder *borderPtr = (WinBorder *) ckalloc(sizeof(WinBorder));
+
borderPtr->light2ColorPtr = NULL;
borderPtr->dark2ColorPtr = NULL;
return (TkBorder *) borderPtr;
@@ -55,8 +55,8 @@ TkpGetBorder()
*
* TkpFreeBorder --
*
- * This function frees any colors allocated by the platform
- * specific part of this module.
+ * This function frees any colors allocated by the platform specific part
+ * of this module.
*
* Results:
* None.
@@ -68,8 +68,8 @@ TkpGetBorder()
*/
void
-TkpFreeBorder(borderPtr)
- TkBorder *borderPtr;
+TkpFreeBorder(
+ TkBorder *borderPtr)
{
WinBorder *winBorderPtr = (WinBorder *) borderPtr;
if (winBorderPtr->light2ColorPtr) {
@@ -85,18 +85,17 @@ TkpFreeBorder(borderPtr)
*
* Tk_3DVerticalBevel --
*
- * This procedure draws a vertical bevel along one side of
- * an object. The bevel is always rectangular in shape:
+ * 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.
+ * 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.
@@ -108,22 +107,21 @@ TkpFreeBorder(borderPtr)
*/
void
-Tk_3DVerticalBevel(tkwin, drawable, border, x, y, width, height,
- leftBevel, relief)
- 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, y, width, 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. */
+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 = 0, right = 0;
+ int left, right;
Display *display = Tk_Display(tkwin);
TkWinDCState state;
HDC dc = TkWinGetDrawableDC(display, drawable, &state);
@@ -134,36 +132,37 @@ Tk_3DVerticalBevel(tkwin, drawable, border, x, y, width, height,
}
switch (relief) {
- case TK_RELIEF_RAISED:
- left = (leftBevel)
+ case TK_RELIEF_RAISED:
+ left = (leftBevel)
? borderPtr->lightGC->foreground
: borderPtr->darkGC->foreground;
- right = (leftBevel)
+ right = (leftBevel)
? ((WinBorder *)borderPtr)->light2ColorPtr->pixel
: ((WinBorder *)borderPtr)->dark2ColorPtr->pixel;
- break;
- case TK_RELIEF_SUNKEN:
- left = (leftBevel)
- ? ((WinBorder *)borderPtr)->dark2ColorPtr->pixel
- : ((WinBorder *)borderPtr)->light2ColorPtr->pixel;
- right = (leftBevel)
+ 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:
- left = right = RGB(0,0,0);
- break;
+ 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)) {
@@ -179,9 +178,9 @@ Tk_3DVerticalBevel(tkwin, drawable, border, x, y, width, height,
*
* 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).
+ * 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.
@@ -193,77 +192,76 @@ Tk_3DVerticalBevel(tkwin, drawable, border, x, y, width, height,
*/
void
-Tk_3DHorizontalBevel(tkwin, drawable, border, x, y, width, height,
- leftIn, rightIn, topBevel, relief)
- 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, y, width, height; /* Bounding box of area of bevel. Height
- * gives width of border. */
- int leftIn, 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:
+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. */
+ 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 = 0, bottomColor = 0;
+ 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).
+ * 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)
+ case TK_RELIEF_RAISED:
+ topColor = (topBevel)
? borderPtr->lightGC->foreground
: borderPtr->darkGC->foreground;
- bottomColor = (topBevel)
+ bottomColor = (topBevel)
? ((WinBorder *)borderPtr)->light2ColorPtr->pixel
: ((WinBorder *)borderPtr)->dark2ColorPtr->pixel;
- break;
- case TK_RELIEF_SUNKEN:
- topColor = (topBevel)
- ? ((WinBorder *)borderPtr)->dark2ColorPtr->pixel
- : ((WinBorder *)borderPtr)->light2ColorPtr->pixel;
- bottomColor = (topBevel)
+ 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:
- topColor = bottomColor = RGB(0,0,0);
+ 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);
}
/*
@@ -296,8 +294,7 @@ Tk_3DHorizontalBevel(tkwin, drawable, border, x, y, width, height,
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.
+ * rectangles) x1 can be >= x2. Don't draw the lines in these cases.
*/
if (x1 < x2) {
@@ -315,27 +312,26 @@ Tk_3DHorizontalBevel(tkwin, drawable, border, x, y, width, height,
*
* 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.
+ * 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.
+ * The lightGC and darkGC fields in borderPtr get filled in, if they
+ * weren't already.
*
*----------------------------------------------------------------------
*/
void
-TkpGetShadows(borderPtr, tkwin)
- TkBorder *borderPtr; /* Information about border. */
- Tk_Window tkwin; /* Window where border will be used for
+TkpGetShadows(
+ TkBorder *borderPtr, /* Information about border. */
+ Tk_Window tkwin) /* Window where border will be used for
* drawing. */
{
XColor lightColor, darkColor;
@@ -352,13 +348,13 @@ TkpGetShadows(borderPtr, tkwin)
*/
if ((TkWinIndexOfColor(borderPtr->bgColorPtr) == COLOR_3DFACE)
- || (TkWinIndexOfColor(borderPtr->bgColorPtr) == COLOR_WINDOW)) {
+ || (TkWinIndexOfColor(borderPtr->bgColorPtr) == COLOR_WINDOW)) {
borderPtr->darkColorPtr = Tk_GetColor(NULL, tkwin,
- Tk_GetUid("SystemButtonShadow"));
+ Tk_GetUid("SystemButtonShadow"));
gcValues.foreground = borderPtr->darkColorPtr->pixel;
borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
borderPtr->lightColorPtr = Tk_GetColor(NULL, tkwin,
- Tk_GetUid("SystemButtonHighlight"));
+ Tk_GetUid("SystemButtonHighlight"));
gcValues.foreground = borderPtr->lightColorPtr->pixel;
borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
((WinBorder*)borderPtr)->dark2ColorPtr = Tk_GetColor(NULL, tkwin,
@@ -366,45 +362,42 @@ TkpGetShadows(borderPtr, tkwin)
((WinBorder*)borderPtr)->light2ColorPtr = Tk_GetColor(NULL, tkwin,
Tk_GetUid("System3dLight"));
return;
- } else {
- darkColor.red = 0;
- darkColor.green = 0;
- darkColor.blue = 0;
- ((WinBorder*)borderPtr)->dark2ColorPtr = Tk_GetColorByValue(tkwin,
+ }
+ 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 = *(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.
+ * 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.
+ * 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%.
+ * 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 colors using integers, not using lightColor.red etc.:
+ * these are shorts and may have problems with integer overflow.
*/
/*
@@ -461,10 +454,10 @@ TkpGetShadows(borderPtr, tkwin)
tmp2 = (MAX_INTENSITY + b)/2;
lightColor.blue = (tmp1 > tmp2) ? tmp1 : tmp2;
}
-
- /*
- * Allocate the light shadow color and its GC
- */
+
+ /*
+ * Allocate the light shadow color and its GC
+ */
borderPtr->lightColorPtr = Tk_GetColorByValue(tkwin, &lightColor);
gcValues.foreground = borderPtr->lightColorPtr->pixel;
@@ -476,15 +469,15 @@ TkpGetShadows(borderPtr, tkwin)
borderPtr->shadow = Tk_GetBitmap((Tcl_Interp *) NULL, tkwin,
Tk_GetUid("gray50"));
if (borderPtr->shadow == None) {
- panic("TkpGetShadows couldn't allocate bitmap for border");
+ 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.
+ * 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;
@@ -502,8 +495,8 @@ TkpGetShadows(borderPtr, tkwin)
/*
* 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.
+ * existence on this earth. Make one shadow a 50% stipple and the other
+ * the opposite of the background.
*/
gcValues.foreground = WhitePixelOfScreen(borderPtr->screen);
@@ -527,8 +520,7 @@ TkpGetShadows(borderPtr, tkwin)
*
* TkWinGetBorderPixels --
*
- * This routine returns the 5 COLORREFs used to draw a given
- * 3d border.
+ * This routine returns the 5 COLORREFs used to draw a given 3d border.
*
* Results:
* Returns the colors in the specified array.
@@ -540,34 +532,42 @@ TkpGetShadows(borderPtr, tkwin)
*/
COLORREF
-TkWinGetBorderPixels(tkwin, border, which)
- Tk_Window tkwin;
- Tk_3DBorder border;
- int which; /* One of TK_3D_FLAT_GC, TK_3D_LIGHT_GC,
+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;
+ 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/win/tkWinButton.c b/win/tkWinButton.c
index a002b9c..af1058d 100644
--- a/win/tkWinButton.c
+++ b/win/tkWinButton.c
@@ -19,9 +19,9 @@
*/
#define LABEL_STYLE (BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS)
-#define PUSH_STYLE (BS_OWNERDRAW | BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS)
-#define CHECK_STYLE (BS_OWNERDRAW | BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS)
-#define RADIO_STYLE (BS_OWNERDRAW | BS_RADIOBUTTON | 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.
@@ -64,11 +64,11 @@ enum {
*/
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. */
+ 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;
@@ -76,11 +76,11 @@ static Tcl_ThreadDataKey dataKey;
* Declarations for functions defined in this file.
*/
-static LRESULT CALLBACK ButtonProc _ANSI_ARGS_((HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam));
-static Window CreateProc _ANSI_ARGS_((Tk_Window tkwin,
- Window parent, ClientData instanceData));
-static void InitBoxes _ANSI_ARGS_((void));
+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.
@@ -90,6 +90,7 @@ Tk_ClassProcs tkpButtonProcs = {
sizeof(Tk_ClassProcs), /* size */
TkButtonWorldChanged, /* worldChangedProc */
CreateProc, /* createProc */
+ NULL
};
@@ -98,13 +99,13 @@ Tk_ClassProcs tkpButtonProcs = {
*
* 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.
+ * 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.
@@ -116,7 +117,7 @@ Tk_ClassProcs tkpButtonProcs = {
*/
static void
-InitBoxes()
+InitBoxes(void)
{
/*
* For DLLs like Tk, the HINSTANCE is the same as the HMODULE.
@@ -127,11 +128,14 @@ InitBoxes()
HGLOBAL hblk;
LPBITMAPINFOHEADER newBitmap;
DWORD size;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
hrsrc = FindResource(module, "buttons", RT_BITMAP);
- if (hrsrc) {
+ 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);
}
@@ -142,15 +146,15 @@ InitBoxes()
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;
+ size = tsdPtr->boxesPtr->biSize + (1 << tsdPtr->boxesPtr->biBitCount)
+ * sizeof(RGBQUAD) + tsdPtr->boxesPtr->biSizeImage;
newBitmap = (LPBITMAPINFOHEADER) 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->boxesPalette = (DWORD*) (((LPSTR) tsdPtr->boxesPtr)
+ + tsdPtr->boxesPtr->biSize);
tsdPtr->boxesBits = ((LPSTR) tsdPtr->boxesPalette)
+ ((1 << tsdPtr->boxesPtr->biBitCount) * sizeof(RGBQUAD));
} else {
@@ -164,8 +168,8 @@ InitBoxes()
* 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.
+ * 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.
@@ -177,8 +181,8 @@ InitBoxes()
*/
void
-TkpButtonSetDefaults(specPtr)
- Tk_OptionSpec *specPtr; /* Points to an array of option specs,
+TkpButtonSetDefaults(
+ Tk_OptionSpec *specPtr) /* Points to an array of option specs,
* terminated by one with type
* TK_OPTION_END. */
{
@@ -205,8 +209,8 @@ TkpButtonSetDefaults(specPtr)
*/
TkButton *
-TkpCreateButton(tkwin)
- Tk_Window tkwin;
+TkpCreateButton(
+ Tk_Window tkwin)
{
WinButton *butPtr;
@@ -220,8 +224,8 @@ TkpCreateButton(tkwin)
*
* CreateProc --
*
- * This function creates a new Button control, subclasses
- * the instance, and generates a new Window object.
+ * 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.
@@ -233,10 +237,10 @@ TkpCreateButton(tkwin)
*/
static Window
-CreateProc(tkwin, parentWin, instanceData)
- Tk_Window tkwin; /* Token for window. */
- Window parentWin; /* Parent of new window. */
- ClientData instanceData; /* Button instance data. */
+CreateProc(
+ Tk_Window tkwin, /* Token for window. */
+ Window parentWin, /* Parent of new window. */
+ ClientData instanceData) /* Button instance data. */
{
Window window;
HWND parent;
@@ -256,13 +260,8 @@ CreateProc(tkwin, parentWin, instanceData)
parent, NULL, Tk_GetHINSTANCE(), NULL);
SetWindowPos(butPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-#ifdef _WIN64
butPtr->oldProc = (WNDPROC)SetWindowLongPtr(butPtr->hwnd, GWLP_WNDPROC,
- (LONG_PTR) ButtonProc);
-#else
- butPtr->oldProc = (WNDPROC)SetWindowLong(butPtr->hwnd, GWL_WNDPROC,
- (DWORD) ButtonProc);
-#endif
+ (INT_PTR) ButtonProc);
window = Tk_AttachHWND(tkwin, butPtr->hwnd);
return window;
@@ -285,17 +284,14 @@ CreateProc(tkwin, parentWin, instanceData)
*/
void
-TkpDestroyButton(butPtr)
- TkButton *butPtr;
+TkpDestroyButton(
+ TkButton *butPtr)
{
WinButton *winButPtr = (WinButton *)butPtr;
HWND hwnd = winButPtr->hwnd;
+
if (hwnd) {
-#ifdef _WIN64
- SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) winButPtr->oldProc);
-#else
- SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) winButPtr->oldProc);
-#endif
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) winButPtr->oldProc);
}
}
@@ -304,22 +300,21 @@ TkpDestroyButton(butPtr)
*
* TkpDisplayButton --
*
- * This procedure is invoked to display a button widget. It is
- * normally invoked as an idle handler.
+ * 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.
+ * Information appears on the screen. The REDRAW_PENDING flag is cleared.
*
*----------------------------------------------------------------------
*/
void
-TkpDisplayButton(clientData)
- ClientData clientData; /* Information about widget. */
+TkpDisplayButton(
+ ClientData clientData) /* Information about widget. */
{
TkWinDCState state;
HDC dc;
@@ -327,27 +322,28 @@ TkpDisplayButton(clientData)
GC gc;
Tk_3DBorder border;
Pixmap pixmap;
- int x = 0; /* Initialization only needed to stop
- * compiler warning. */
+ 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 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 */
+ 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));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
boxesPalette= tsdPtr->boxesPalette;
butPtr->flags &= ~REDRAW_PENDING;
@@ -371,9 +367,8 @@ TkpDisplayButton(clientData)
}
/*
- * 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:
+ * 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
@@ -387,15 +382,15 @@ TkpDisplayButton(clientData)
* on no sunken
* on yes sunken
*
- * This is accomplished by configuring the checkbutton or radiobutton
- * like this:
+ * 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
+ * -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.
*/
@@ -426,10 +421,10 @@ TkpDisplayButton(clientData)
}
/*
- * 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.
+ * 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),
@@ -448,7 +443,7 @@ TkpDisplayButton(clientData)
Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
haveImage = 1;
}
- imageWidth = width;
+ imageWidth = width;
imageHeight = height;
haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
@@ -457,49 +452,58 @@ TkpDisplayButton(clientData)
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_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;
}
- 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;
+ 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;
}
- case COMPOUND_NONE: {break;}
+ 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);
@@ -515,9 +519,13 @@ TkpDisplayButton(clientData)
if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
Tk_RedrawImage(butPtr->selectImage, 0, 0,
width, height, pixmap, imageXOffset, imageYOffset);
- } else {
- Tk_RedrawImage(butPtr->image, 0, 0,
+ } 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);
@@ -526,6 +534,22 @@ TkpDisplayButton(clientData)
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);
@@ -539,7 +563,7 @@ TkpDisplayButton(clientData)
TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
butPtr->indicatorSpace + width, height, &x, &y);
x += butPtr->indicatorSpace;
-
+
if (relief == TK_RELIEF_SUNKEN) {
x += offset;
y += offset;
@@ -551,6 +575,10 @@ TkpDisplayButton(clientData)
(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);
@@ -567,11 +595,24 @@ TkpDisplayButton(clientData)
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,
@@ -583,12 +624,12 @@ TkpDisplayButton(clientData)
}
/*
- * 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.
+ * 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) {
@@ -609,11 +650,10 @@ TkpDisplayButton(clientData)
}
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.
+ * 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
@@ -623,7 +663,7 @@ TkpDisplayButton(clientData)
x -= butPtr->indicatorSpace;
y -= butPtr->indicatorDiameter / 2;
- xSrc = (butPtr->flags & SELECTED) ? tsdPtr->boxWidth : 0;
+ xSrc = (butPtr->flags & (SELECTED|TRISTATED)) ? tsdPtr->boxWidth : 0;
if (butPtr->state == STATE_ACTIVE) {
xSrc += tsdPtr->boxWidth*2;
}
@@ -631,11 +671,11 @@ TkpDisplayButton(clientData)
/*
* 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.
+ * 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)
@@ -653,7 +693,7 @@ TkpDisplayButton(clientData)
border, TK_3D_LIGHT2));
boxesPalette[PAL_BOTTOM_OUTER] = FlipColor(TkWinGetBorderPixels(tkwin,
border, TK_3D_LIGHT_GC));
- if (butPtr->state == STATE_DISABLED) {
+ if ((butPtr->state == STATE_DISABLED) || (butPtr->flags & TRISTATED)) {
boxesPalette[PAL_INTERIOR] = FlipColor(TkWinGetBorderPixels(tkwin,
border, TK_3D_LIGHT2));
} else if (butPtr->selectBorder != NULL) {
@@ -666,18 +706,18 @@ TkpDisplayButton(clientData)
border, TK_3D_FLAT_GC));
dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state);
- StretchDIBits(dc, x, y, tsdPtr->boxWidth, tsdPtr->boxHeight,
- xSrc, ySrc, tsdPtr->boxWidth, tsdPtr->boxHeight,
- tsdPtr->boxesBits, (LPBITMAPINFO) tsdPtr->boxesPtr,
- DIB_RGB_COLORS, SRCCOPY);
+ 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.
+ * 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)
@@ -687,10 +727,12 @@ TkpDisplayButton(clientData)
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
+ * 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));
@@ -707,8 +749,8 @@ TkpDisplayButton(clientData)
}
/*
- * Draw the border and traversal highlight last. This way, if the
- * button's contents overflow they'll be covered up by the border.
+ * 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) {
@@ -721,15 +763,15 @@ TkpDisplayButton(clientData)
if (defaultWidth != 0) {
dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state);
TkWinFillRect(dc, 0, 0, Tk_Width(tkwin), defaultWidth,
- butPtr->highlightColorPtr->pixel);
+ (int) butPtr->highlightColorPtr->pixel);
TkWinFillRect(dc, 0, 0, defaultWidth, Tk_Height(tkwin),
- butPtr->highlightColorPtr->pixel);
+ (int) butPtr->highlightColorPtr->pixel);
TkWinFillRect(dc, 0, Tk_Height(tkwin) - defaultWidth,
Tk_Width(tkwin), defaultWidth,
- butPtr->highlightColorPtr->pixel);
+ (int) butPtr->highlightColorPtr->pixel);
TkWinFillRect(dc, Tk_Width(tkwin) - defaultWidth, 0,
defaultWidth, Tk_Height(tkwin),
- butPtr->highlightColorPtr->pixel);
+ (int) butPtr->highlightColorPtr->pixel);
TkWinReleaseDrawableDC(pixmap, dc, &state);
}
@@ -738,8 +780,8 @@ TkpDisplayButton(clientData)
}
/*
- * Copy the information from the off-screen pixmap onto the screen,
- * then delete the pixmap.
+ * Copy the information from the off-screen pixmap onto the screen, then
+ * delete the pixmap.
*/
XCopyArea(butPtr->display, pixmap, Tk_WindowId(tkwin),
@@ -753,9 +795,9 @@ TkpDisplayButton(clientData)
*
* 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.
+ * 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.
@@ -767,21 +809,21 @@ TkpDisplayButton(clientData)
*/
void
-TkpComputeButtonGeometry(butPtr)
- register TkButton *butPtr; /* Button whose geometry may have changed. */
+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 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));
+
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (butPtr->highlightWidth < 0) {
butPtr->highlightWidth = 0;
@@ -793,13 +835,16 @@ TkpComputeButtonGeometry(butPtr)
InitBoxes();
}
- /* Figure out image metrics */
+ /*
+ * 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);
+ &imgWidth, &imgHeight);
haveImage = 1;
} else {
imgWidth = 0;
@@ -807,10 +852,11 @@ TkpComputeButtonGeometry(butPtr)
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,
@@ -824,7 +870,10 @@ TkpComputeButtonGeometry(butPtr)
52) + 26) / 52;
Tk_GetFontMetrics(butPtr->tkfont, &fm);
- /* Compute dialog units for layout calculations. */
+ /*
+ * Compute dialog units for layout calculations.
+ */
+
hDLU = avgWidth / 4.0;
vDLU = fm.linespace / 8.0;
@@ -841,182 +890,199 @@ TkpComputeButtonGeometry(butPtr)
/*
* 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.
+ * 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) {
- /* Min width in characters */
- minWidth = -(butPtr->width);
- /* Allow for characters */
- width = avgWidth * minWidth;
- /* Add for padding */
- width += (int)(0.5 + (6 * hDLU));
- }
+ 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 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));
- }
+ 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) {
/*
- * 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.
+ * Extra inset for the focus ring.
*/
- height = txtHeight + (int)(0.5 + (6 * vDLU));
+ 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 {
/*
- * 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.
+ * If there's no text, we want the height to be one linespace.
*/
- width -= 10;
- height -= 10;
-
- if (!haveImage) {
- /*
- * Extra inset for the focus ring.
- */
- butPtr->inset += 1;
- }
- break;
+ height = fm.linespace;
}
+ 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;
- }
+ 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.
+ * 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 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_TOP:
+ case COMPOUND_BOTTOM:
+ /*
+ * Image is above or below text.
+ */
+
+ if (imgWidth > width) {
+ width = imgWidth;
}
- 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;
- }
+ height += imgHeight + butPtr->padY;
+ break;
- if (imgHeight > height) {
- height = imgHeight;
- }
- 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;
}
- case COMPOUND_CENTER: {
- /* Image and text are superimposed */
- if (imgWidth > width) {
- width = imgWidth;
- }
- if (imgHeight > height) {
- height = imgHeight;
- }
- break;
+
+ if (imgHeight > height) {
+ height = imgHeight;
}
- case COMPOUND_NONE: {
- break;
+ 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) {
+ /*
+ * 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;
}
@@ -1038,68 +1104,76 @@ TkpComputeButtonGeometry(butPtr)
height = imgHeight;
}
} else {
- /* No image. May or may not be text. May or may not be compound. */
+ /*
+ * 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
+ /*
+ * 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) {
+
+ 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.
+ * 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]
+ * 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;
- }
+ 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;
+
+ width += 2 * butPtr->padX;
height += 2 * butPtr->padY;
}
- /* Fix up width and height for indicator sizing and spacing */
+ /*
+ * 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;
- }
+ /*
+ * 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".
+ * 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));
+ (int)(0.5 + (3.0 * hDLU));
width += butPtr->indicatorSpace;
}
}
@@ -1107,7 +1181,8 @@ TkpComputeButtonGeometry(butPtr)
/*
* Inset is always added to the size.
*/
- width += 2 * butPtr->inset;
+
+ width += 2 * butPtr->inset;
height += 2 * butPtr->inset;
Tk_GeometryRequest(butPtr->tkwin, width, height);
@@ -1119,8 +1194,8 @@ TkpComputeButtonGeometry(butPtr)
*
* ButtonProc --
*
- * This function is call by Windows whenever an event occurs on
- * a button control created by Tk.
+ * This function is call by Windows whenever an event occurs on a button
+ * control created by Tk.
*
* Results:
* Standard Windows return value.
@@ -1132,86 +1207,96 @@ TkpComputeButtonGeometry(butPtr)
*/
static LRESULT CALLBACK
-ButtonProc(hwnd, message, wParam, lParam)
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
+ButtonProc(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
LRESULT result;
WinButton *butPtr;
Tk_Window tkwin = Tk_HWNDToWindow(hwnd);
if (tkwin == NULL) {
- panic("ButtonProc called on an invalid HWND");
+ 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)
+ 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;
- }
- if (butPtr->info.flags & GOT_FOCUS) {
- state |= BST_FOCUS;
- }
- return state;
}
- case WM_ENABLE:
- break;
+ return 0;
- case WM_PAINT: {
- PAINTSTRUCT ps;
- BeginPaint(hwnd, &ps);
- EndPaint(hwnd, &ps);
- TkpDisplayButton((ClientData)butPtr);
+ case BM_GETSTATE: {
+ DWORD state = 0;
- /*
- * 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;
+ 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;
}
- case BN_CLICKED: {
- int code;
- Tcl_Interp *interp = butPtr->info.interp;
- if (butPtr->info.state != STATE_DISABLED) {
- Tcl_Preserve((ClientData)interp);
- code = TkInvokeButton((TkButton*)butPtr);
- if (code != TCL_OK && code != TCL_CONTINUE
- && code != TCL_BREAK) {
- Tcl_AddErrorInfo(interp, "\n (button invoke)");
- Tcl_BackgroundError(interp);
- }
- Tcl_Release((ClientData)interp);
- }
- Tcl_ServiceAll();
- return 0;
+ 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);
- default:
- if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
- return result;
+ /*
+ * 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: {
+ 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_BackgroundError(interp);
}
+ 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/win/tkWinClipboard.c b/win/tkWinClipboard.c
index 19dcc11..6007e56 100644
--- a/win/tkWinClipboard.c
+++ b/win/tkWinClipboard.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkWinClipboard.c --
*
* This file contains functions for managing the clipboard.
@@ -6,28 +6,28 @@
* 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.
+ * 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"
-static void UpdateClipboard _ANSI_ARGS_((HWND hwnd));
+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.
- *
+ * 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.
+ * 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.
@@ -36,18 +36,17 @@ static void UpdateClipboard _ANSI_ARGS_((HWND hwnd));
*/
int
-TkSelGetSelection(interp, tkwin, selection, target, proc, clientData)
- 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. */
+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;
@@ -62,8 +61,8 @@ TkSelGetSelection(interp, tkwin, selection, target, proc, clientData)
}
/*
- * Attempt to get the data in Unicode form if available as this is
- * less work that CF_TEXT.
+ * Attempt to get the data in Unicode form if available as this is less
+ * work that CF_TEXT.
*/
result = TCL_ERROR;
@@ -91,19 +90,17 @@ TkSelGetSelection(interp, tkwin, selection, target, proc, clientData)
}
/*
- * Get the locale identifier, determine the proper code page
- * to use, and find the corresponding encoding.
+ * 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.
+ * Even though the documentation claims that GetLocaleInfo expects
+ * an LCID, on Windows 9x it really seems to expect a LanguageID.
*/
locale = LANGIDFROMLCID(*((int*)data));
@@ -144,7 +141,7 @@ TkSelGetSelection(interp, tkwin, selection, target, proc, clientData)
/*
* Translate CR/LF to LF.
*/
-
+
data = destPtr = Tcl_DStringValue(&ds);
while (*data) {
if (data[0] == '\r' && data[1] == '\n') {
@@ -163,12 +160,11 @@ TkSelGetSelection(interp, tkwin, selection, target, proc, clientData)
Tcl_DStringFree(&ds);
CloseClipboard();
return result;
-
-error:
+
+ error:
Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
" selection doesn't exist or form \"",
- Tk_GetAtomName(tkwin, target),
- "\" not defined", (char *) NULL);
+ Tk_GetAtomName(tkwin, target), "\" not defined", NULL);
return TCL_ERROR;
}
@@ -177,9 +173,8 @@ error:
*
* TkSetSelectionOwner --
*
- * This function claims ownership of the specified selection.
- * If the selection is CLIPBOARD, then we empty the system
- * clipboard.
+ * This function claims ownership of the specified selection. If the
+ * selection is CLIPBOARD, then we empty the system clipboard.
*
* Results:
* None.
@@ -191,27 +186,26 @@ error:
*/
void
-XSetSelectionOwner(display, selection, owner, time)
- Display* display;
- Atom selection;
- Window owner;
- Time time;
+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.
+ * 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.
+ * Only claim and empty the clipboard if we aren't already the owner
+ * of the clipboard.
*/
if (GetClipboardOwner() != hwnd) {
@@ -225,8 +219,8 @@ XSetSelectionOwner(display, selection, owner, time)
*
* TkWinClipboardRender --
*
- * This function supplies the contents of the clipboard in
- * response to a WM_RENDERFORMAT message.
+ * This function supplies the contents of the clipboard in response to a
+ * WM_RENDERFORMAT message.
*
* Results:
* None.
@@ -238,9 +232,9 @@ XSetSelectionOwner(display, selection, owner, time)
*/
void
-TkWinClipboardRender(dispPtr, format)
- TkDisplay *dispPtr;
- UINT format;
+TkWinClipboardRender(
+ TkDisplay *dispPtr,
+ UINT format)
{
TkClipboardTarget *targetPtr;
TkClipboardBuffer *cbPtr;
@@ -251,13 +245,14 @@ TkWinClipboardRender(dispPtr, format)
for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
targetPtr = targetPtr->nextPtr) {
- if (targetPtr->type == XA_STRING)
+ if (targetPtr->type == XA_STRING) {
break;
+ }
}
/*
- * Count the number of newlines so we can add space for them in
- * the resulting string.
+ * Count the number of newlines so we can add space for them in the
+ * resulting string.
*/
length = 0;
@@ -278,7 +273,7 @@ TkWinClipboardRender(dispPtr, format)
* Copy the data and change EOL characters.
*/
- buffer = rawText = ckalloc(length + 1);
+ buffer = rawText = ckalloc((unsigned)length + 1);
if (targetPtr != NULL) {
for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
cbPtr = cbPtr->nextPtr) {
@@ -294,8 +289,8 @@ TkWinClipboardRender(dispPtr, format)
*buffer = '\0';
/*
- * Depending on the platform, turn the data into Unicode or the
- * system encoding before placing it on the clipboard.
+ * Depending on the platform, turn the data into Unicode or the system
+ * encoding before placing it on the clipboard.
*/
if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
@@ -303,13 +298,14 @@ TkWinClipboardRender(dispPtr, format)
Tcl_UtfToUniCharDString(rawText, -1, &ds);
ckfree(rawText);
handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
- Tcl_DStringLength(&ds)+2);
+ (unsigned) Tcl_DStringLength(&ds) + 2);
if (!handle) {
Tcl_DStringFree(&ds);
return;
}
buffer = GlobalLock(handle);
- memcpy(buffer, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds) + 2);
+ memcpy(buffer, Tcl_DStringValue(&ds),
+ (unsigned) Tcl_DStringLength(&ds) + 2);
GlobalUnlock(handle);
Tcl_DStringFree(&ds);
SetClipboardData(CF_UNICODETEXT, handle);
@@ -317,19 +313,18 @@ TkWinClipboardRender(dispPtr, format)
Tcl_UtfToExternalDString(NULL, rawText, -1, &ds);
ckfree(rawText);
handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
- Tcl_DStringLength(&ds)+1);
+ (unsigned) Tcl_DStringLength(&ds) + 1);
if (!handle) {
Tcl_DStringFree(&ds);
return;
}
buffer = GlobalLock(handle);
- memcpy(buffer, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds) + 1);
+ memcpy(buffer, Tcl_DStringValue(&ds),
+ (unsigned) Tcl_DStringLength(&ds) + 1);
GlobalUnlock(handle);
Tcl_DStringFree(&ds);
SetClipboardData(CF_TEXT, handle);
}
-
- return;
}
/*
@@ -337,8 +332,8 @@ TkWinClipboardRender(dispPtr, format)
*
* TkSelUpdateClipboard --
*
- * This function is called to force the clipboard to be updated
- * after new data is added.
+ * This function is called to force the clipboard to be updated after new
+ * data is added.
*
* Results:
* None.
@@ -350,9 +345,9 @@ TkWinClipboardRender(dispPtr, format)
*/
void
-TkSelUpdateClipboard(winPtr, targetPtr)
- TkWindow *winPtr;
- TkClipboardTarget *targetPtr;
+TkSelUpdateClipboard(
+ TkWindow *winPtr,
+ TkClipboardTarget *targetPtr)
{
HWND hwnd = TkWinGetHWND(winPtr->window);
UpdateClipboard(hwnd);
@@ -363,8 +358,8 @@ TkSelUpdateClipboard(winPtr, targetPtr)
*
* UpdateClipboard --
*
- * Take ownership of the clipboard, clear it, and indicate to the
- * system the supported formats.
+ * Take ownership of the clipboard, clear it, and indicate to the system
+ * the supported formats.
*
* Results:
* None.
@@ -376,16 +371,16 @@ TkSelUpdateClipboard(winPtr, targetPtr)
*/
static void
-UpdateClipboard(hwnd)
- HWND hwnd;
+UpdateClipboard(
+ HWND hwnd)
{
TkWinUpdatingClipboard(TRUE);
OpenClipboard(hwnd);
EmptyClipboard();
/*
- * CF_UNICODETEXT is only supported on NT, but it it is prefered
- * when possible.
+ * CF_UNICODETEXT is only supported on NT, but it it is prefered when
+ * possible.
*/
if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
@@ -402,25 +397,22 @@ UpdateClipboard(hwnd)
*
* TkSelEventProc --
*
- * This procedure is invoked whenever a selection-related
- * event occurs.
+ * This procedure is invoked whenever a selection-related event occurs.
*
* Results:
* None.
*
* Side effects:
- * Lots: depends on the type of event.
+ * Lots: depends on the type of event.
*
*--------------------------------------------------------------
*/
void
-TkSelEventProc(tkwin, eventPtr)
- Tk_Window tkwin; /* Window for which event was
- * targeted. */
- register XEvent *eventPtr; /* X event: either SelectionClear,
- * SelectionRequest, or
- * SelectionNotify. */
+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);
@@ -432,9 +424,8 @@ TkSelEventProc(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.
+ * 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.
@@ -446,7 +437,15 @@ TkSelEventProc(tkwin, eventPtr)
*/
void
-TkSelPropProc(eventPtr)
- register XEvent *eventPtr; /* X PropertyChange event. */
+TkSelPropProc(
+ register XEvent *eventPtr) /* X PropertyChange event. */
{
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinColor.c b/win/tkWinColor.c
index d3b3cad..f4181b5 100644
--- a/win/tkWinColor.c
+++ b/win/tkWinColor.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkWinColor.c --
*
* Functions to map color names to system color values.
@@ -6,8 +6,8 @@
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkWinInt.h"
@@ -20,15 +20,14 @@
typedef struct WinColor {
TkColor info; /* Generic color information. */
- int index; /* Index for GetSysColor(), -1 if color
- * is not a "live" system color. */
+ 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.
+ * 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 {
@@ -36,7 +35,6 @@ typedef struct {
int index;
} SystemColorEntry;
-
static SystemColorEntry sysColors[] = {
{"3dDarkShadow", COLOR_3DDKSHADOW},
{"3dLight", COLOR_3DLIGHT},
@@ -50,16 +48,16 @@ static SystemColorEntry sysColors[] = {
{"ButtonText", COLOR_BTNTEXT},
{"CaptionText", COLOR_CAPTIONTEXT},
{"DisabledText", COLOR_GRAYTEXT},
- {"GrayText", 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},
+ {"InfoText", COLOR_INFOTEXT},
{"Menu", COLOR_MENU},
- {"MenuText", COLOR_MENUTEXT},
+ {"MenuText", COLOR_MENUTEXT},
{"Scrollbar", COLOR_SCROLLBAR},
{"Window", COLOR_WINDOW},
{"WindowFrame", COLOR_WINDOWFRAME},
@@ -67,7 +65,7 @@ static SystemColorEntry sysColors[] = {
{NULL, 0}
};
-typedef struct ThreadSpecificData {
+typedef struct ThreadSpecificData {
int ncolors;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -76,20 +74,20 @@ static Tcl_ThreadDataKey dataKey;
* Forward declarations for functions defined later in this file.
*/
-static int FindSystemColor _ANSI_ARGS_((const char *name,
- XColor *colorPtr, int *indexPtr));
+static int FindSystemColor(const char *name, XColor *colorPtr,
+ int *indexPtr);
/*
*----------------------------------------------------------------------
*
* FindSystemColor --
*
- * This routine finds the color entry that corresponds to the
- * specified color.
+ * 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.
+ * Returns non-zero on success. The RGB values of the XColor will be
+ * initialized to the proper values on success.
*
* Side effects:
* None.
@@ -98,18 +96,18 @@ static int FindSystemColor _ANSI_ARGS_((const char *name,
*/
static int
-FindSystemColor(name, colorPtr, indexPtr)
- const char *name; /* Color name. */
- XColor *colorPtr; /* Where to store results. */
- int *indexPtr; /* Out parameter to store color index. */
+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;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * Count the number of elements in the color array if we haven't
- * done so yet.
+ * Count the number of elements in the color array if we haven't done so
+ * yet.
*/
if (tsdPtr->ncolors == 0) {
@@ -152,10 +150,12 @@ FindSystemColor(name, colorPtr, indexPtr)
*indexPtr = sysColors[i].index;
colorPtr->pixel = GetSysColor(sysColors[i].index);
+
/*
- * x257 is (value<<8 + value) to get the properly bit shifted
- * and padded value. [Bug: 4919]
+ * 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;
@@ -176,27 +176,26 @@ FindSystemColor(name, colorPtr, indexPtr)
*
* Side effects:
* May invalidate the colormap cache associated with tkwin upon
- * allocating a new colormap entry. Allocates a new TkColor
- * structure.
+ * allocating a new colormap entry. Allocates a new TkColor structure.
*
*----------------------------------------------------------------------
*/
TkColor *
-TkpGetColor(tkwin, name)
- Tk_Window tkwin; /* Window in which color will be used. */
- Tk_Uid name; /* Name of color to allocated (in form
+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
- * sytem color. */
+ * 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.
+ * 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)
@@ -209,7 +208,7 @@ TkpGetColor(tkwin, name)
XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
&winColPtr->info.color);
- return (TkColor *) winColPtr;
+ return (TkColor *) winColPtr;
}
return (TkColor *) NULL;
}
@@ -219,27 +218,26 @@ TkpGetColor(tkwin, name)
*
* 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.
+ * 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.
+ * 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.
+ * May invalidate the colormap cache for the specified window. Allocates
+ * a new TkColor structure.
*
*----------------------------------------------------------------------
*/
TkColor *
-TkpGetColorByValue(tkwin, colorPtr)
- Tk_Window tkwin; /* Window in which color will be used. */
- XColor *colorPtr; /* Red, green, and blue fields indicate
+TkpGetColorByValue(
+ Tk_Window tkwin, /* Window in which color will be used. */
+ XColor *colorPtr) /* Red, green, and blue fields indicate
* desired color. */
{
WinColor *tkColPtr = (WinColor *) ckalloc(sizeof(WinColor));
@@ -264,15 +262,15 @@ TkpGetColorByValue(tkwin, colorPtr)
* None
*
* Side effects:
- * Invalidates the colormap cache for the colormap associated with
- * the given color.
+ * Invalidates the colormap cache for the colormap associated with the
+ * given color.
*
*----------------------------------------------------------------------
*/
void
-TkpFreeColor(tkColPtr)
- TkColor *tkColPtr; /* Color to be released. Must have been
+TkpFreeColor(
+ TkColor *tkColPtr) /* Color to be released. Must have been
* allocated by TkpGetColor or
* TkpGetColorByValue. */
{
@@ -287,13 +285,13 @@ TkpFreeColor(tkColPtr)
*
* TkWinIndexOfColor --
*
- * Given a color, return the system color index that was used
- * to create the color.
+ * 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.
+ * 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.
@@ -302,13 +300,13 @@ TkpFreeColor(tkColPtr)
*/
int
-TkWinIndexOfColor(colorPtr)
- XColor *colorPtr;
+TkWinIndexOfColor(
+ XColor *colorPtr)
{
register WinColor *winColPtr = (WinColor *) colorPtr;
if (winColPtr->info.magic == COLOR_MAGIC) {
return winColPtr->index;
- }
+ }
return -1;
}
@@ -320,8 +318,8 @@ TkWinIndexOfColor(colorPtr)
* Find the closest available color to the specified XColor.
*
* Results:
- * Updates the color argument and returns 1 on success. Otherwise
- * returns 0.
+ * Updates the color argument and returns 1 on success. Otherwise returns
+ * 0.
*
* Side effects:
* Allocates a new color in the palette.
@@ -330,10 +328,10 @@ TkWinIndexOfColor(colorPtr)
*/
int
-XAllocColor(display, colormap, color)
- Display* display;
- Colormap colormap;
- XColor* color;
+XAllocColor(
+ Display *display,
+ Colormap colormap,
+ XColor *color)
{
TkWinColormap *cmap = (TkWinColormap *) colormap;
PALETTEENTRY entry, closeEntry;
@@ -354,7 +352,7 @@ XAllocColor(display, colormap, color)
/*
* 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);
@@ -362,15 +360,14 @@ XAllocColor(display, colormap, color)
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 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;
@@ -397,11 +394,10 @@ XAllocColor(display, colormap, color)
}
Tcl_SetHashValue(entryPtr, (ClientData)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;
@@ -424,19 +420,19 @@ XAllocColor(display, colormap, color)
* None.
*
* Side effects:
- * Removes entries for the current palette and compacts the
- * remaining set.
+ * Removes entries for the current palette and compacts the remaining
+ * set.
*
*----------------------------------------------------------------------
*/
void
-XFreeColors(display, colormap, pixels, npixels, planes)
- Display* display;
- Colormap colormap;
- unsigned long* pixels;
- int npixels;
- unsigned long planes;
+XFreeColors(
+ Display *display,
+ Colormap colormap,
+ unsigned long *pixels,
+ int npixels,
+ unsigned long planes)
{
TkWinColormap *cmap = (TkWinColormap *) colormap;
COLORREF cref;
@@ -449,18 +445,16 @@ XFreeColors(display, colormap, pixels, npixels, planes)
/*
* We don't have to do anything for non-palette devices.
*/
-
- if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
+ 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,
- (char *) pixels[i]);
+ entryPtr = Tcl_FindHashEntry(&cmap->refCounts, (char *) pixels[i]);
if (!entryPtr) {
- panic("Tried to free a color that isn't allocated.");
+ Tcl_Panic("Tried to free a color that isn't allocated.");
}
refCount = (int) Tcl_GetHashValue(entryPtr) - 1;
if (refCount == 0) {
@@ -469,14 +463,14 @@ XFreeColors(display, colormap, pixels, npixels, planes)
GetPaletteEntries(cmap->palette, index, 1, &entry);
if (cref == RGB(entry.peRed, entry.peGreen, entry.peBlue)) {
count = cmap->size - index;
- entries = (PALETTEENTRY *) ckalloc(sizeof(PALETTEENTRY)
- * count);
+ entries = (PALETTEENTRY *)
+ ckalloc(sizeof(PALETTEENTRY) * count);
GetPaletteEntries(cmap->palette, index+1, count, entries);
SetPaletteEntries(cmap->palette, index, count, entries);
ckfree((char *) entries);
cmap->size--;
} else {
- panic("Tried to free a color that isn't allocated.");
+ Tcl_Panic("Tried to free a color that isn't allocated.");
}
Tcl_DeleteHashEntry(entryPtr);
} else {
@@ -504,11 +498,11 @@ XFreeColors(display, colormap, pixels, npixels, planes)
*/
Colormap
-XCreateColormap(display, w, visual, alloc)
- Display* display;
- Window w;
- Visual* visual;
- int alloc;
+XCreateColormap(
+ Display *display,
+ Window w,
+ Visual *visual,
+ int alloc)
{
char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
LOGPALETTE *logPalettePtr;
@@ -542,7 +536,7 @@ XCreateColormap(display, w, visual, alloc)
for (i = 0; i < logPalettePtr->palNumEntries; i++) {
entryPtr = logPalettePtr->palPalEntry + i;
hashPtr = Tcl_CreateHashEntry(&cmap->refCounts, (char*) PALETTERGB(
- entryPtr->peRed, entryPtr->peGreen, entryPtr->peBlue), &new);
+ entryPtr->peRed, entryPtr->peGreen, entryPtr->peBlue), &new);
Tcl_SetHashValue(hashPtr, (ClientData)1);
}
@@ -560,21 +554,21 @@ XCreateColormap(display, w, visual, alloc)
* 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.
+ * Deletes the palette associated with the colormap. Note that the
+ * palette must not be selected into a device context when this occurs.
*
*----------------------------------------------------------------------
*/
void
-XFreeColormap(display, colormap)
- Display* display;
- Colormap colormap;
+XFreeColormap(
+ Display *display,
+ Colormap colormap)
{
TkWinColormap *cmap = (TkWinColormap *) colormap;
+
if (!DeleteObject(cmap->palette)) {
- panic("Unable to free colormap, palette is still selected.");
+ Tcl_Panic("Unable to free colormap, palette is still selected.");
}
Tcl_DeleteHashTable(&cmap->refCounts);
ckfree((char *) cmap);
@@ -585,10 +579,9 @@ XFreeColormap(display, colormap)
*
* 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.
+ * 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.
@@ -600,9 +593,9 @@ XFreeColormap(display, colormap)
*/
HPALETTE
-TkWinSelectPalette(dc, colormap)
- HDC dc;
- Colormap colormap;
+TkWinSelectPalette(
+ HDC dc,
+ Colormap colormap)
{
TkWinColormap *cmap = (TkWinColormap *) colormap;
HPALETTE oldPalette;
@@ -612,3 +605,11 @@ TkWinSelectPalette(dc, colormap)
RealizePalette(dc);
return oldPalette;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinConfig.c b/win/tkWinConfig.c
index efb619e..422e399 100644
--- a/win/tkWinConfig.c
+++ b/win/tkWinConfig.c
@@ -1,17 +1,15 @@
-/*
+/*
* tkWinConfig.c --
*
- * This module implements the Windows system defaults for
- * the configuration package.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tk.h"
-#include "tkInt.h"
#include "tkWinInt.h"
@@ -20,13 +18,13 @@
*
* TkpGetSystemDefault --
*
- * Given a dbName and className for a configuration option,
- * return a string representation of the option.
+ * 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.
+ * 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.
@@ -38,7 +36,7 @@ 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. */
+ CONST char *className) /* The name of the option class. */
{
Tcl_Obj *valueObjPtr;
Tk_Uid classUid;
@@ -56,3 +54,11 @@ TkpGetSystemDefault(
return valueObjPtr;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinCursor.c b/win/tkWinCursor.c
index 4a0f11a..dee3419 100644
--- a/win/tkWinCursor.c
+++ b/win/tkWinCursor.c
@@ -1,19 +1,19 @@
-/*
+/*
* 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.
+ * 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.
+ * The following data structure contains the system specific data necessary to
+ * control Windows cursors.
*/
typedef struct {
@@ -23,16 +23,20 @@ typedef struct {
} 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.
+ * 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.
+ * The table below is used to map from the name of a predefined cursor to its
+ * resource identifier.
*/
static struct CursorName {
@@ -59,6 +63,7 @@ static struct CursorName {
{"watch", IDC_WAIT},
{"xterm", IDC_IBEAM},
{"hand2", IDC_HAND},
+ {"question_arrow", IDC_HELP},
{NULL, 0}
};
@@ -74,10 +79,10 @@ static struct CursorName {
*
* TkGetCursorByName --
*
- * Retrieve a system cursor by name.
+ * Retrieve a system cursor by name.
*
* Results:
- * Returns a new cursor, or NULL on errors.
+ * Returns a new cursor, or NULL on errors.
*
* Side effects:
* Allocates a new cursor.
@@ -86,11 +91,11 @@ static struct CursorName {
*/
TkCursor *
-TkGetCursorByName(interp, tkwin, string)
- 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. */
+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;
@@ -116,8 +121,8 @@ TkGetCursorByName(interp, tkwin, string)
if (argv[0][0] == '@') {
/*
- * Check for system cursor of type @<filename>, where only
- * the name is allowed. This accepts any of:
+ * 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}
@@ -127,7 +132,7 @@ TkGetCursorByName(interp, tkwin, string)
if (Tcl_IsSafe(interp)) {
Tcl_AppendResult(interp, "can't get cursor from a file in",
- " a safe interpreter", (char *) NULL);
+ " a safe interpreter", NULL);
ckfree((char *) argv);
ckfree((char *) cursorPtr);
return NULL;
@@ -137,6 +142,7 @@ TkGetCursorByName(interp, tkwin, string)
/*
* 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);
@@ -146,9 +152,10 @@ TkGetCursorByName(interp, tkwin, string)
if (cursorPtr->winCursor == NULL) {
/*
- * Hmm, it is not in the system cursor set. Check to see
- * if it is one of our application resources.
+ * Hmm, it is not in the system cursor set. Check to see if it is
+ * one of our application resources.
*/
+
cursorPtr->winCursor = LoadCursor(Tk_GetHINSTANCE(), argv[0]);
} else {
cursorPtr->system = 1;
@@ -159,8 +166,7 @@ TkGetCursorByName(interp, tkwin, string)
ckfree((char *) cursorPtr);
badCursorSpec:
ckfree((char *) argv);
- Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"",
- (char *) NULL);
+ Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", NULL);
return NULL;
} else {
ckfree((char *) argv);
@@ -185,15 +191,14 @@ TkGetCursorByName(interp, tkwin, string)
*/
TkCursor *
-TkCreateCursorFromData(tkwin, source, mask, width, height, xHot, yHot,
- fgColor, bgColor)
- 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, height; /* Dimensions of cursor. */
- int xHot, yHot; /* Location of hot-spot in cursor. */
- XColor fgColor; /* Foreground color for cursor. */
- XColor bgColor; /* Background color for cursor. */
+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;
}
@@ -216,9 +221,10 @@ TkCreateCursorFromData(tkwin, source, mask, width, height, xHot, yHot,
*/
void
-TkpFreeCursor(cursorPtr)
- TkCursor *cursorPtr;
+TkpFreeCursor(
+ TkCursor *cursorPtr)
{
+ /* TkWinCursor *winCursorPtr = (TkWinCursor *) cursorPtr; */
}
/*
@@ -226,8 +232,8 @@ TkpFreeCursor(cursorPtr)
*
* TkpSetCursor --
*
- * Set the global cursor. If the cursor is None, then use the
- * default Tk cursor.
+ * Set the global cursor. If the cursor is None, then use the default Tk
+ * cursor.
*
* Results:
* None.
@@ -239,8 +245,8 @@ TkpFreeCursor(cursorPtr)
*/
void
-TkpSetCursor(cursor)
- TkpCursor cursor;
+TkpSetCursor(
+ TkpCursor cursor)
{
HCURSOR hcursor;
TkWinCursor *winCursor = (TkWinCursor *) cursor;
@@ -255,3 +261,11 @@ TkpSetCursor(cursor)
SetCursor(hcursor);
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h
index dcc810e..a1a76c7 100644
--- a/win/tkWinDefault.h
+++ b/win/tkWinDefault.h
@@ -26,7 +26,6 @@
#define BLACK "Black"
#define WHITE "White"
-#define CTL_FONT "{MS Sans Serif} 8"
#define NORMAL_BG "SystemButtonFace"
#define NORMAL_FG "SystemButtonText"
#define ACTIVE_BG NORMAL_BG
@@ -62,7 +61,7 @@
#define DEF_BUTTON_DISABLED_FG_MONO ""
#define DEF_BUTTON_FG NORMAL_FG
#define DEF_CHKRAD_FG TEXT_FG
-#define DEF_BUTTON_FONT CTL_FONT
+#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
@@ -91,6 +90,7 @@
#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"
@@ -139,13 +139,13 @@
#define DEF_ENTRY_BG_COLOR "SystemWindow"
#define DEF_ENTRY_BG_MONO WHITE
-#define DEF_ENTRY_BORDER_WIDTH "2"
+#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 CTL_FONT
+#define DEF_ENTRY_FONT "TkTextFont"
#define DEF_ENTRY_FG TEXT_FG
#define DEF_ENTRY_HIGHLIGHT_BG NORMAL_BG
#define DEF_ENTRY_HIGHLIGHT HIGHLIGHT
@@ -203,7 +203,7 @@
#define DEF_LABELFRAME_CLASS "Labelframe"
#define DEF_LABELFRAME_RELIEF "groove"
#define DEF_LABELFRAME_FG NORMAL_FG
-#define DEF_LABELFRAME_FONT CTL_FONT
+#define DEF_LABELFRAME_FONT "TkDefaultFont"
#define DEF_LABELFRAME_TEXT ""
#define DEF_LABELFRAME_LABELANCHOR "nw"
@@ -214,11 +214,11 @@
#define DEF_LISTBOX_ACTIVE_STYLE "underline"
#define DEF_LISTBOX_BG_COLOR "SystemWindow"
#define DEF_LISTBOX_BG_MONO WHITE
-#define DEF_LISTBOX_BORDER_WIDTH "2"
+#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 CTL_FONT
+#define DEF_LISTBOX_FONT "TkDefaultFont"
#define DEF_LISTBOX_FG NORMAL_FG
#define DEF_LISTBOX_HEIGHT "10"
#define DEF_LISTBOX_HIGHLIGHT_BG NORMAL_BG
@@ -282,7 +282,7 @@
#define DEF_MENU_CURSOR "arrow"
#define DEF_MENU_DISABLED_FG_COLOR DISABLED
#define DEF_MENU_DISABLED_FG_MONO ""
-#define DEF_MENU_FONT CTL_FONT
+#define DEF_MENU_FONT "TkMenuFont"
#define DEF_MENU_FG MENU_FG
#define DEF_MENU_POST_COMMAND ""
#define DEF_MENU_RELIEF "flat"
@@ -306,12 +306,12 @@
#define DEF_MENUBUTTON_BG_COLOR NORMAL_BG
#define DEF_MENUBUTTON_BG_MONO WHITE
#define DEF_MENUBUTTON_BITMAP ""
-#define DEF_MENUBUTTON_BORDER_WIDTH "2"
+#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 CTL_FONT
+#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
@@ -341,10 +341,10 @@
#define DEF_MESSAGE_ASPECT "150"
#define DEF_MESSAGE_BG_COLOR NORMAL_BG
#define DEF_MESSAGE_BG_MONO WHITE
-#define DEF_MESSAGE_BORDER_WIDTH "2"
+#define DEF_MESSAGE_BORDER_WIDTH "1"
#define DEF_MESSAGE_CURSOR ""
#define DEF_MESSAGE_FG NORMAL_FG
-#define DEF_MESSAGE_FONT CTL_FONT
+#define DEF_MESSAGE_FONT "TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT HIGHLIGHT
#define DEF_MESSAGE_HIGHLIGHT_WIDTH "0"
@@ -363,18 +363,18 @@
#define DEF_PANEDWINDOW_BG_COLOR NORMAL_BG
#define DEF_PANEDWINDOW_BG_MONO WHITE
-#define DEF_PANEDWINDOW_BORDERWIDTH "2"
+#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 "0"
+#define DEF_PANEDWINDOW_OPAQUERESIZE "1"
#define DEF_PANEDWINDOW_ORIENT "horizontal"
#define DEF_PANEDWINDOW_RELIEF "flat"
#define DEF_PANEDWINDOW_SASHCURSOR ""
-#define DEF_PANEDWINDOW_SASHPAD "2"
-#define DEF_PANEDWINDOW_SASHRELIEF "raised"
-#define DEF_PANEDWINDOW_SASHWIDTH "2"
+#define DEF_PANEDWINDOW_SASHPAD "0"
+#define DEF_PANEDWINDOW_SASHRELIEF "flat"
+#define DEF_PANEDWINDOW_SASHWIDTH "3"
#define DEF_PANEDWINDOW_SHOWHANDLE "0"
#define DEF_PANEDWINDOW_WIDTH ""
@@ -390,6 +390,8 @@
#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:
@@ -400,11 +402,11 @@
#define DEF_SCALE_BG_COLOR NORMAL_BG
#define DEF_SCALE_BG_MONO WHITE
#define DEF_SCALE_BIG_INCREMENT "0"
-#define DEF_SCALE_BORDER_WIDTH "2"
+#define DEF_SCALE_BORDER_WIDTH "1"
#define DEF_SCALE_COMMAND ""
#define DEF_SCALE_CURSOR ""
#define DEF_SCALE_DIGITS "0"
-#define DEF_SCALE_FONT CTL_FONT
+#define DEF_SCALE_FONT "TkDefaultFont"
#define DEF_SCALE_FG_COLOR NORMAL_FG
#define DEF_SCALE_FG_MONO BLACK
#define DEF_SCALE_FROM "0"
@@ -464,11 +466,12 @@
#define DEF_TEXT_AUTO_SEPARATORS "1"
#define DEF_TEXT_BG_COLOR "SystemWindow"
#define DEF_TEXT_BG_MONO WHITE
-#define DEF_TEXT_BORDER_WIDTH "2"
+#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 CTL_FONT
+#define DEF_TEXT_FONT "TkFixedFont"
#define DEF_TEXT_HEIGHT "24"
#define DEF_TEXT_HIGHLIGHT_BG NORMAL_BG
#define DEF_TEXT_HIGHLIGHT HIGHLIGHT
@@ -483,6 +486,7 @@
#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"
@@ -496,6 +500,7 @@
#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"
@@ -507,7 +512,7 @@
* Defaults for canvas text:
*/
-#define DEF_CANVTEXT_FONT CTL_FONT
+#define DEF_CANVTEXT_FONT "TkDefaultFont"
/*
* Defaults for toplevels (most of the defaults for frames also apply
diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c
index 775d06b..4110848 100644
--- a/win/tkWinDialog.c
+++ b/win/tkWinDialog.c
@@ -5,69 +5,82 @@
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#define WINVER 0x0500 /* Requires Windows 2K definitions */
+#define _WIN32_WINNT 0x0500
#include "tkWinInt.h"
#include "tkFileFilter.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 <commdlg.h> /* includes common dialog functionality */
+#ifdef _MSC_VER
+# pragma comment (lib, "comdlg32.lib")
+#endif
+#include <dlgs.h> /* includes common dialog template defines */
+#include <cderr.h> /* includes the common dialog error codes */
-/*
- * This controls the use of the new style tk_chooseDirectory dialog.
- */
-#define USE_NEW_CHOOSEDIR 1
-#ifdef USE_NEW_CHOOSEDIR
-#include <shlobj.h> /* includes SHBrowseForFolder */
+#include <shlobj.h> /* includes SHBrowseForFolder */
+#ifdef _MSC_VER
+# pragma comment (lib, "shell32.lib")
+#endif
/* These needed for compilation with VC++ 5.2 */
#ifndef BIF_EDITBOX
#define BIF_EDITBOX 0x10
#endif
+
#ifndef BIF_VALIDATE
#define BIF_VALIDATE 0x0020
#endif
+
+#ifndef BIF_NEWDIALOGSTYLE
+#define BIF_NEWDIALOGSTYLE 0x0040
+#endif
+
#ifndef BFFM_VALIDATEFAILED
#ifdef UNICODE
#define BFFM_VALIDATEFAILED 4
#else
#define BFFM_VALIDATEFAILED 3
#endif
-#endif
+#endif /* BFFM_VALIDATEFAILED */
+
+#ifndef OPENFILENAME_SIZE_VERSION_400
+#define OPENFILENAME_SIZE_VERSION_400 76
+#endif
/*
- * The following structure is used by the new Tk_ChooseDirectoryObjCmd
- * to pass data between it and its callback. Unqiue to Winodws platform.
+ * The following structure is used by the new Tk_ChooseDirectoryObjCmd to pass
+ * data between it and its callback. Unqiue to Winodws platform.
*/
+
typedef struct ChooseDirData {
- TCHAR utfInitDir[MAX_PATH]; /* Initial folder to use */
- TCHAR utfRetDir[MAX_PATH]; /* Returned folder to use */
+ TCHAR utfInitDir[MAX_PATH]; /* Initial folder to use */
+ TCHAR utfRetDir[MAX_PATH]; /* Returned folder to use */
Tcl_Interp *interp;
- int mustExist; /* true if file must exist to return from
- * callback */
+ int mustExist; /* True if file must exist to return from
+ * callback */
} CHOOSEDIRDATA;
-#endif
-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 */
+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 */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * The following structures are used by Tk_MessageBoxCmd() to parse
- * arguments and return results.
+ * The following structures are used by Tk_MessageBoxCmd() to parse arguments
+ * and return results.
*/
static const TkStateMap iconMap[] = {
@@ -77,10 +90,10 @@ static const TkStateMap iconMap[] = {
{MB_ICONWARNING, "warning"},
{-1, NULL}
};
-
+
static const TkStateMap typeMap[] = {
{MB_ABORTRETRYIGNORE, "abortretryignore"},
- {MB_OK, "ok"},
+ {MB_OK, "ok"},
{MB_OKCANCEL, "okcancel"},
{MB_RETRYCANCEL, "retrycancel"},
{MB_YESNO, "yesno"},
@@ -105,99 +118,123 @@ static const int buttonFlagMap[] = {
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}}
+ {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]))
/*
- * The value of TK_MULTI_MAX_PATH dictactes 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.
- * MAX_PATH == 260 on Win2K/NT, so *40 is ~10K.
+ * 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 dictactes 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 procedure, Tk_ChooseDirectoryObjCmd(), and its dialog hook proc.
+ * chooser function, Tk_ChooseDirectoryObjCmd(), and its dialog hook proc.
*/
typedef struct ChooseDir {
- Tcl_Interp *interp; /* Interp, used only if debug is turned on,
+ Tcl_Interp *interp; /* Interp, used only if debug is turned on,
* for setting the "tk_dialog" variable. */
int lastCtrl; /* Used by hook proc to keep track of last
- * control that had input focus, so when OK
- * is pressed we know whether to browse a
- * new directory or return. */
- int lastIdx; /* Last item that was selected in directory
+ * control that had input focus, so when OK is
+ * pressed we know whether to browse a new
+ * directory or return. */
+ int lastIdx; /* Last item that was selected in directory
* browser listbox. */
- TCHAR path[MAX_PATH]; /* On return from choose directory dialog,
- * holds the selected path. Cannot return
+ TCHAR path[MAX_PATH]; /* On return from choose directory dialog,
+ * holds the selected path. Cannot return
* selected path in ofnPtr->lpstrFile because
- * the default dialog proc stores a '\0' in
- * it, since, of course, no _file_ was
+ * the default dialog proc stores a '\0' in
+ * it, since, of course, no _file_ was
* selected. */
OPENFILENAME *ofnPtr; /* pointer to the OFN structure */
} ChooseDir;
/*
- * Definitions of procedures used only in this file.
+ * The following structure is used to pass information between GetFileName/W
+ * functions 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 */
+ char *dynFileBuffer; /* Dynamic filename buffer, cast to WCHAR* in
+ * UNICODE procedures */
+} OFNData;
+
+/*
+ * Definitions of functions used only in this file.
*/
-#ifdef USE_NEW_CHOOSEDIR
static UINT APIENTRY ChooseDirectoryValidateProc(HWND hdlg, UINT uMsg,
LPARAM wParam, LPARAM lParam);
-#else
-static UINT APIENTRY ChooseDirectoryHookProc(HWND hdlg, UINT uMsg,
- WPARAM wParam, LPARAM lParam);
-#endif
static UINT CALLBACK ColorDlgHookProc(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
-static int GetFileNameA(ClientData clientData,
- Tcl_Interp *interp, int objc,
+static int GetFileNameA(ClientData clientData,
+ Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[], int isOpen);
-static int GetFileNameW(ClientData clientData,
- Tcl_Interp *interp, int objc,
+static int GetFileNameW(ClientData clientData,
+ Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[], int isOpen);
-static int MakeFilter(Tcl_Interp *interp, char *string,
- Tcl_DString *dsPtr);
-static UINT APIENTRY OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam,
+static int MakeFilter(Tcl_Interp *interp, Tcl_Obj *valuePtr,
+ Tcl_DString *dsPtr, Tcl_Obj *initialPtr,
+ int *index);
+static UINT APIENTRY OFNHookProcA(HWND hdlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
-static UINT APIENTRY OFNHookProcW(HWND hdlg, UINT uMsg, WPARAM wParam,
+static UINT APIENTRY OFNHookProcW(HWND hdlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam);
static void SetTkDialog(ClientData clientData);
+static char * ConvertExternalFilename(Tcl_Encoding encoding,
+ char *filename, Tcl_DString *dsPtr);
/*
*-------------------------------------------------------------------------
*
* 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 poll the message queue
- * for 200ms looking for WM_LBUTTON up messages. If we see one it's
- * consumed. If we get a WM_LBUTTONDOWN message, then we exit early,
- * since the user must be doing something new. 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.
+ * 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 poll the message queue for
+ * 1/4s looking for WM_LBUTTON up messages. If we see one it's consumed.
+ * If we get a WM_LBUTTONDOWN message, then we exit early, since the user
+ * must be doing something new. 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.
@@ -212,12 +249,13 @@ static void
EatSpuriousMessageBugFix(void)
{
MSG msg;
- DWORD nTime = GetTickCount() + 200;
+ DWORD nTime = GetTickCount() + 250;
+
while (GetTickCount() < nTime) {
- if (PeekMessage(&msg,0,WM_LBUTTONDOWN,WM_LBUTTONDOWN,PM_NOREMOVE)) {
+ if (PeekMessage(&msg, 0, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE)){
break;
}
- PeekMessage(&msg,0,WM_LBUTTONUP,WM_LBUTTONUP,PM_REMOVE);
+ PeekMessage(&msg, 0, WM_LBUTTONUP, WM_LBUTTONUP, PM_REMOVE);
}
}
@@ -227,8 +265,8 @@ EatSpuriousMessageBugFix(void)
* 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
+ * 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:
@@ -240,12 +278,12 @@ EatSpuriousMessageBugFix(void)
*-------------------------------------------------------------------------
*/
-void
+void
TkWinDialogDebug(
int debug)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
tsdPtr->debugFlag = debug;
}
@@ -255,15 +293,14 @@ TkWinDialogDebug(
*
* Tk_ChooseColorObjCmd --
*
- * This procedure implements the color dialog box for the Windows
- * platform. See the user documentation for details on what it
- * does.
+ * 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 procedure is called.
+ * 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.
*
@@ -271,13 +308,13 @@ TkWinDialogDebug(
*/
int
-Tk_ChooseColorObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+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, parent;
+ Tk_Window tkwin = (Tk_Window) clientData, parent;
HWND hWnd;
int i, oldMode, winCode, result;
CHOOSECOLOR chooseColor;
@@ -294,11 +331,12 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv)
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.
+ * 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);
}
@@ -306,11 +344,9 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv)
inited = 1;
}
- tkwin = (Tk_Window) clientData;
-
parent = tkwin;
chooseColor.lStructSize = sizeof(CHOOSECOLOR);
- chooseColor.hwndOwner = NULL;
+ chooseColor.hwndOwner = NULL;
chooseColor.hInstance = NULL;
chooseColor.rgbResult = oldColor;
chooseColor.lpCustColors = dwCustColors;
@@ -332,36 +368,34 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
if (i + 1 == objc) {
- string = Tcl_GetStringFromObj(optionPtr, NULL);
- Tcl_AppendResult(interp, "value for \"", string, "\" missing",
- (char *) NULL);
+ string = Tcl_GetString(optionPtr);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ NULL);
return TCL_ERROR;
}
- string = Tcl_GetStringFromObj(valuePtr, NULL);
+ string = Tcl_GetString(valuePtr);
switch ((enum options) index) {
- case COLOR_INITIAL: {
- XColor *colorPtr;
+ 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;
+ colorPtr = Tk_GetColor(interp, tkwin, string);
+ if (colorPtr == NULL) {
+ return TCL_ERROR;
}
- case COLOR_TITLE: {
- chooseColor.lCustData = (LPARAM) string;
- break;
+ 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;
}
}
@@ -369,16 +403,17 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv)
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).
+ * 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);
/*
@@ -399,10 +434,10 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv)
char color[100];
sprintf(color, "#%02x%02x%02x",
- GetRValue(chooseColor.rgbResult),
- GetGValue(chooseColor.rgbResult),
+ GetRValue(chooseColor.rgbResult),
+ GetGValue(chooseColor.rgbResult),
GetBValue(chooseColor.rgbResult));
- Tcl_AppendResult(interp, color, NULL);
+ Tcl_AppendResult(interp, color, NULL);
oldColor = chooseColor.rgbResult;
result = TCL_OK;
}
@@ -415,12 +450,12 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv)
*
* ColorDlgHookProc --
*
- * Provides special handling of messages for the Color common dialog
- * box. Used to set the title when the dialog first appears.
+ * 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 procedure should
- * handle the message, non-zero otherwise.
+ * 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.
@@ -428,39 +463,39 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv)
*----------------------------------------------------------------------
*/
-static UINT CALLBACK
-ColorDlgHookProc(hDlg, uMsg, wParam, lParam)
- HWND hDlg; /* Handle to the color dialog. */
- UINT uMsg; /* Type of message. */
- WPARAM wParam; /* First message parameter. */
- LPARAM lParam; /* Second message parameter. */
+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 = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ const char *title;
+ CHOOSECOLOR *ccPtr;
- switch (uMsg) {
- case WM_INITDIALOG: {
- const char *title;
- CHOOSECOLOR *ccPtr;
- Tcl_DString ds;
+ if (WM_INITDIALOG == uMsg) {
- /*
- * Set the title string of the dialog.
- */
+ /*
+ * Set the title string of the dialog.
+ */
- ccPtr = (CHOOSECOLOR *) lParam;
- title = (const char *) ccPtr->lCustData;
- if ((title != NULL) && (title[0] != '\0')) {
- (*tkWinProcs->setWindowText)(hDlg,
- Tcl_WinUtfToTChar(title, -1, &ds));
- Tcl_DStringFree(&ds);
- }
- if (tsdPtr->debugFlag) {
- tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName;
- Tcl_DoWhenIdle(SetTkDialog, (ClientData) hDlg);
- }
- return TRUE;
+ ccPtr = (CHOOSECOLOR *) lParam;
+ title = (const char *) ccPtr->lCustData;
+
+ if ((title != NULL) && (title[0] != '\0')) {
+ Tcl_DString ds;
+
+ (*tkWinProcs->setWindowText)(hDlg,
+ Tcl_WinUtfToTChar(title, -1, &ds));
+ Tcl_DStringFree(&ds);
}
+ if (tsdPtr->debugFlag) {
+ tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName;
+ Tcl_DoWhenIdle(SetTkDialog, (ClientData) hDlg);
+ }
+ return TRUE;
}
return FALSE;
}
@@ -470,25 +505,24 @@ ColorDlgHookProc(hDlg, uMsg, wParam, lParam)
*
* Tk_GetOpenFileCmd --
*
- * This procedure implements the "open file" dialog box for the
- * Windows platform. See the user documentation for details on what
- * it does.
+ * 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 procedure is called.
+ * A dialog window is created the first this function is called.
*
*----------------------------------------------------------------------
*/
int
-Tk_GetOpenFileObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+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. */
{
if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
return GetFileNameW(clientData, interp, objc, objv, 1);
@@ -515,11 +549,11 @@ Tk_GetOpenFileObjCmd(clientData, interp, objc, objv)
*/
int
-Tk_GetSaveFileObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+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. */
{
if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
return GetFileNameW(clientData, interp, objc, objv, 0);
@@ -544,55 +578,53 @@ Tk_GetSaveFileObjCmd(clientData, interp, objc, objv)
*----------------------------------------------------------------------
*/
-static int
-GetFileNameW(clientData, interp, objc, objv, open)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
- int open; /* 1 to call GetOpenFileName(), 0 to
- * call GetSaveFileName(). */
+static int
+GetFileNameW(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument objects. */
+ int open) /* 1 to call GetOpenFileName(), 0 to call
+ * GetSaveFileName(). */
{
OPENFILENAMEW ofn;
WCHAR file[TK_MULTI_MAX_PATH];
- int result, winCode, oldMode, i, multi = 0;
- char *extension, *filter, *title;
- Tk_Window tkwin;
+ OFNData ofnData;
+ int cdlgerr;
+ int filterIndex = 0, result = TCL_ERROR, winCode, oldMode, i, multi = 0;
+ char *extension = NULL, *title = NULL;
+ Tk_Window tkwin = (Tk_Window) clientData;
HWND hWnd;
- Tcl_DString utfFilterString, utfDirString;
+ Tcl_Obj *filterObj = NULL, *initialTypeObj = NULL, *typeVariableObj = NULL;
+ Tcl_DString utfFilterString, utfDirString, ds;
Tcl_DString extString, filterString, dirString, titleString;
Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding();
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
static CONST char *saveOptionStrings[] = {
"-defaultextension", "-filetypes", "-initialdir", "-initialfile",
- "-parent", "-title", NULL
+ "-parent", "-title", "-typevariable", NULL
};
static CONST char *openOptionStrings[] = {
"-defaultextension", "-filetypes", "-initialdir", "-initialfile",
- "-multiple", "-parent", "-title", NULL
+ "-multiple", "-parent", "-title", "-typevariable", NULL
};
CONST char **optionStrings;
enum options {
FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE,
- FILE_MULTIPLE, FILE_PARENT, FILE_TITLE
+ FILE_MULTIPLE, FILE_PARENT, FILE_TITLE, FILE_TYPEVARIABLE
};
- result = TCL_ERROR;
file[0] = '\0';
+ ZeroMemory(&ofnData, sizeof(OFNData));
+ Tcl_DStringInit(&utfFilterString);
+ Tcl_DStringInit(&utfDirString);
/*
* Parse the arguments.
*/
- extension = NULL;
- filter = NULL;
- Tcl_DStringInit(&utfFilterString);
- Tcl_DStringInit(&utfDirString);
- tkwin = (Tk_Window) clientData;
- title = NULL;
-
if (open) {
optionStrings = openOptionStrings;
} else {
@@ -611,122 +643,119 @@ GetFileNameW(clientData, interp, objc, objv, open)
"option", 0, &index) != TCL_OK) {
goto end;
}
+
/*
* We want to maximize code sharing between the open and save file
* dialog implementations; in particular, the switch statement below.
* We use different sets of option strings from the GetIndexFromObj
- * call above, but a single enumeration for both. The save file
- * dialog doesn't support -multiple, but it falls in the middle of
- * the enumeration. Ultimately, this means that when the index found
- * by GetIndexFromObj is >= FILE_MULTIPLE, when doing a save file
- * dialog, we have to increment the index, so that it matches the
- * open file dialog enumeration.
+ * call above, but a single enumeration for both. The save file dialog
+ * doesn't support -multiple, but it falls in the middle of the
+ * enumeration. Ultimately, this means that when the index found by
+ * GetIndexFromObj is >= FILE_MULTIPLE, when doing a save file dialog,
+ * we have to increment the index, so that it matches the open file
+ * dialog enumeration.
*/
+
if (!open && index >= FILE_MULTIPLE) {
index++;
}
if (i + 1 == objc) {
- string = Tcl_GetStringFromObj(optionPtr, NULL);
- Tcl_AppendResult(interp, "value for \"", string, "\" missing",
- (char *) NULL);
+ string = Tcl_GetString(optionPtr);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ NULL);
goto end;
}
- string = Tcl_GetStringFromObj(valuePtr, NULL);
+ string = Tcl_GetString(valuePtr);
switch ((enum options) index) {
- case FILE_DEFAULT: {
- if (string[0] == '.') {
- string++;
- }
- extension = string;
- break;
- }
- case FILE_TYPES: {
- Tcl_DStringFree(&utfFilterString);
- if (MakeFilter(interp, string, &utfFilterString) != TCL_OK) {
- goto end;
- }
- filter = Tcl_DStringValue(&utfFilterString);
- break;
+ case FILE_DEFAULT:
+ if (string[0] == '.') {
+ string++;
}
- case FILE_INITDIR: {
- Tcl_DStringFree(&utfDirString);
- if (Tcl_TranslateFileName(interp, string,
- &utfDirString) == NULL) {
- goto end;
- }
- break;
- }
- case FILE_INITFILE: {
- Tcl_DString ds;
-
- if (Tcl_TranslateFileName(interp, string, &ds) == NULL) {
- goto end;
- }
- Tcl_UtfToExternal(NULL, unicodeEncoding, Tcl_DStringValue(&ds),
- Tcl_DStringLength(&ds), 0, NULL, (char *) file,
- sizeof(file), NULL, NULL, NULL);
- break;
+ extension = string;
+ break;
+ case FILE_TYPES:
+ filterObj = valuePtr;
+ break;
+ case FILE_INITDIR:
+ Tcl_DStringFree(&utfDirString);
+ if (Tcl_TranslateFileName(interp, string,
+ &utfDirString) == NULL) {
+ goto end;
}
- case FILE_MULTIPLE: {
- if (Tcl_GetBooleanFromObj(interp, valuePtr,
- &multi) != TCL_OK) {
- return TCL_ERROR;
- }
- break;
+ break;
+ case FILE_INITFILE:
+ if (Tcl_TranslateFileName(interp, string, &ds) == NULL) {
+ goto end;
}
- case FILE_PARENT: {
- tkwin = Tk_NameToWindow(interp, string, tkwin);
- if (tkwin == NULL) {
- goto end;
- }
- break;
+ Tcl_UtfToExternal(NULL, unicodeEncoding, Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds), 0, NULL, (char *) file,
+ sizeof(file), NULL, NULL, NULL);
+ Tcl_DStringFree(&ds);
+ break;
+ case FILE_MULTIPLE:
+ if (Tcl_GetBooleanFromObj(interp, valuePtr, &multi) != TCL_OK) {
+ return TCL_ERROR;
}
- case FILE_TITLE: {
- title = string;
- break;
+ break;
+ case FILE_PARENT:
+ tkwin = Tk_NameToWindow(interp, string, tkwin);
+ if (tkwin == NULL) {
+ goto end;
}
+ break;
+ case FILE_TITLE:
+ title = string;
+ break;
+ case FILE_TYPEVARIABLE:
+ typeVariableObj = valuePtr;
+ initialTypeObj = Tcl_ObjGetVar2(interp, typeVariableObj, NULL,
+ TCL_GLOBAL_ONLY);
+ break;
}
}
- if (filter == NULL) {
- if (MakeFilter(interp, "", &utfFilterString) != TCL_OK) {
- goto end;
- }
+ if (MakeFilter(interp, filterObj, &utfFilterString, initialTypeObj,
+ &filterIndex) != TCL_OK) {
+ goto end;
}
Tk_MakeWindowExist(tkwin);
hWnd = Tk_GetHWND(Tk_WindowId(tkwin));
ZeroMemory(&ofn, sizeof(OPENFILENAMEW));
- ofn.lStructSize = sizeof(OPENFILENAMEW);
- ofn.hwndOwner = hWnd;
-#ifdef _WIN64
- ofn.hInstance = (HINSTANCE) GetWindowLongPtr(ofn.hwndOwner,
- GWLP_HINSTANCE);
-#else
- ofn.hInstance = (HINSTANCE) GetWindowLong(ofn.hwndOwner,
- GWL_HINSTANCE);
-#endif
- ofn.lpstrFile = (WCHAR *) file;
- ofn.nMaxFile = TK_MULTI_MAX_PATH;
- ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST
- | OFN_NOCHANGEDIR | OFN_EXPLORER;
- ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProcW;
- ofn.lCustData = (LPARAM) interp;
+ if (LOBYTE(LOWORD(GetVersion())) < 5) {
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ } else {
+ ofn.lStructSize = sizeof(OPENFILENAMEW);
+ }
+ ofn.hwndOwner = hWnd;
+ ofn.hInstance = TkWinGetHInstance(ofn.hwndOwner);
+ ofn.lpstrFile = (WCHAR *) file;
+ ofn.nMaxFile = TK_MULTI_MAX_PATH;
+ ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR
+ | OFN_EXPLORER | OFN_ENABLEHOOK| OFN_ENABLESIZING;
+ ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProcW;
+ ofn.lCustData = (LPARAM) &ofnData;
if (open != 0) {
ofn.Flags |= OFN_FILEMUSTEXIST;
} else {
ofn.Flags |= OFN_OVERWRITEPROMPT;
}
-
if (tsdPtr->debugFlag != 0) {
- ofn.Flags |= OFN_ENABLEHOOK;
+ ofnData.interp = interp;
}
-
if (multi != 0) {
ofn.Flags |= OFN_ALLOWMULTISELECT;
+
+ /*
+ * Starting buffer size. The buffer will be expanded by the OFN dialog
+ * procedure when necessary
+ */
+
+ ofnData.dynFileBufferSize = 1024;
+ ofnData.dynFileBuffer = ckalloc(1024);
}
if (extension != NULL) {
@@ -738,6 +767,7 @@ GetFileNameW(clientData, interp, objc, objv, open)
Tcl_DStringValue(&utfFilterString),
Tcl_DStringLength(&utfFilterString), &filterString);
ofn.lpstrFilter = (WCHAR *) Tcl_DStringValue(&filterString);
+ ofn.nFilterIndex = filterIndex;
if (Tcl_DStringValue(&utfDirString)[0] != '\0') {
Tcl_UtfToExternalDString(unicodeEncoding,
@@ -745,14 +775,14 @@ GetFileNameW(clientData, interp, objc, objv, open)
Tcl_DStringLength(&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.
+ * 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(&utfDirString);
- if ((Tcl_GetCwd(interp, &utfDirString) == (char *) NULL) ||
+ if ((Tcl_GetCwd(interp, &utfDirString) == NULL) ||
(Tcl_TranslateFileName(interp,
Tcl_DStringValue(&utfDirString), &cwd) == NULL)) {
Tcl_ResetResult(interp);
@@ -783,10 +813,11 @@ GetFileNameW(clientData, interp, objc, objv, open)
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).
+ * 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);
/*
@@ -798,42 +829,43 @@ GetFileNameW(clientData, interp, objc, objv, open)
/*
* 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.
*/
- if (winCode != 0) {
+ 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))) {
if (ofn.Flags & OFN_ALLOWMULTISELECT) {
- /*
- * The result in custData->szFile contains many items,
- * separated with null characters. It is terminated with
- * two nulls in a row. The first element is the directory
- * path.
+ /*
+ * 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.
*/
- char *dir;
- char *p;
- char *file;
- WCHAR *files;
- Tcl_DString ds;
- Tcl_DString fullname, filename;
- Tcl_Obj *returnList;
+
+ WCHAR *files = (WCHAR *) ofnData.dynFileBuffer;
+ Tcl_Obj *returnList = Tcl_NewObj();
int count = 0;
- returnList = Tcl_NewObj();
- Tcl_IncrRefCount(returnList);
+ /*
+ * Get directory.
+ */
- files = ofn.lpstrFile;
- Tcl_ExternalToUtfDString(unicodeEncoding, (char *) files, -1, &ds);
-
- /* Get directory */
- dir = Tcl_DStringValue(&ds);
- for (p = dir; p && *p; p++) {
- /*
- * Change the pathname to the Tcl "normalized" pathname, where
- * back slashes are used instead of forward slashes
- */
- if (*p == '\\') {
- *p = '/';
- }
- }
+ (void) ConvertExternalFilename(unicodeEncoding, (char *) files,
+ &ds);
while (*files != '\0') {
while (*files != '\0') {
@@ -841,90 +873,68 @@ GetFileNameW(clientData, interp, objc, objv, open)
}
files++;
if (*files != '\0') {
+ Tcl_Obj *fullnameObj;
+ Tcl_DString filenameBuf;
+
count++;
- Tcl_ExternalToUtfDString(unicodeEncoding,
- (char *)files, -1, &filename);
- file = Tcl_DStringValue(&filename);
- for (p = file; *p != '\0'; p++) {
- if (*p == '\\') {
- *p = '/';
- }
- }
- Tcl_DStringInit(&fullname);
- Tcl_DStringAppend(&fullname, dir, -1);
- Tcl_DStringAppend(&fullname, "/", -1);
- Tcl_DStringAppend(&fullname, file, -1);
- Tcl_ListObjAppendElement(interp, returnList,
- Tcl_NewStringObj(Tcl_DStringValue(&fullname), -1));
- Tcl_DStringFree(&fullname);
- Tcl_DStringFree(&filename);
+ (void) ConvertExternalFilename(unicodeEncoding,
+ (char *) files, &filenameBuf);
+
+ fullnameObj = Tcl_NewStringObj(Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds));
+ Tcl_AppendToObj(fullnameObj, "/", -1);
+ Tcl_AppendToObj(fullnameObj, Tcl_DStringValue(&filenameBuf),
+ Tcl_DStringLength(&filenameBuf));
+ Tcl_DStringFree(&filenameBuf);
+ Tcl_ListObjAppendElement(NULL, returnList, fullnameObj);
}
}
+
if (count == 0) {
/*
* Only one file was returned.
*/
- Tcl_ListObjAppendElement(interp, returnList,
- Tcl_NewStringObj(dir, -1));
+
+ Tcl_ListObjAppendElement(NULL, returnList,
+ Tcl_NewStringObj(Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds)));
}
Tcl_SetObjResult(interp, returnList);
- Tcl_DecrRefCount(returnList);
Tcl_DStringFree(&ds);
} else {
- char *p;
- Tcl_DString ds;
-
- Tcl_ExternalToUtfDString(unicodeEncoding,
- (char *) ofn.lpstrFile, -1, &ds);
- for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) {
- /*
- * Change the pathname to the Tcl "normalized" pathname, where
- * back slashes are used instead of forward slashes
- */
- if (*p == '\\') {
- *p = '/';
- }
- }
- Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
+ Tcl_AppendResult(interp, ConvertExternalFilename(unicodeEncoding,
+ (char *) ofn.lpstrFile, &ds), NULL);
Tcl_DStringFree(&ds);
}
result = TCL_OK;
- } else {
- /*
- * 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.
- *
- * We could also check for FNERR_BUFFERTOOSMALL, but we can't
- * really do anything about it when it happens.
- */
-
- if (CommDlgExtendedError() == FNERR_INVALIDFILENAME) {
- char *p;
- Tcl_DString ds;
-
- Tcl_ExternalToUtfDString(unicodeEncoding,
- (char *) ofn.lpstrFile, -1, &ds);
- for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) {
- /*
- * Change the pathname to the Tcl "normalized" pathname,
- * where back slashes are used instead of forward slashes
- */
- if (*p == '\\') {
- *p = '/';
- }
+ if ((ofn.nFilterIndex > 0) &&
+ Tcl_GetCharLength(Tcl_GetObjResult(interp)) > 0 &&
+ typeVariableObj && filterObj) {
+ int listObjc, count;
+ Tcl_Obj **listObjv = NULL;
+ Tcl_Obj **typeInfo = NULL;
+
+ if (Tcl_ListObjGetElements(interp, filterObj,
+ &listObjc, &listObjv) != TCL_OK) {
+ result = TCL_ERROR;
+ } else if (Tcl_ListObjGetElements(interp,
+ listObjv[ofn.nFilterIndex - 1], &count,
+ &typeInfo) != TCL_OK) {
+ result = TCL_ERROR;
+ } else if (Tcl_ObjSetVar2(interp, typeVariableObj, NULL,
+ typeInfo[0], TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
+ result = TCL_ERROR;
}
- Tcl_SetResult(interp, "invalid filename \"", TCL_STATIC);
- Tcl_AppendResult(interp, Tcl_DStringValue(&ds), "\"", NULL);
- Tcl_DStringFree(&ds);
- } else {
- result = TCL_OK;
}
+ } else if (cdlgerr == FNERR_INVALIDFILENAME) {
+ Tcl_SetResult(interp, "invalid filename \"", TCL_STATIC);
+ Tcl_AppendResult(interp, ConvertExternalFilename(unicodeEncoding,
+ (char *) ofn.lpstrFile, &ds), "\"", NULL);
+ Tcl_DStringFree(&ds);
+ } else {
+ result = TCL_OK;
}
-
+
if (ofn.lpstrTitle != NULL) {
Tcl_DStringFree(&titleString);
}
@@ -936,9 +946,13 @@ GetFileNameW(clientData, interp, objc, objv, open)
Tcl_DStringFree(&extString);
}
- end:
+ end:
Tcl_DStringFree(&utfDirString);
Tcl_DStringFree(&utfFilterString);
+ if (ofnData.dynFileBuffer != NULL) {
+ ckfree(ofnData.dynFileBuffer);
+ ofnData.dynFileBuffer = NULL;
+ }
return result;
}
@@ -948,9 +962,10 @@ GetFileNameW(clientData, interp, objc, objv, open)
*
* OFNHookProcW --
*
- * Hook procedure called only if debugging is turned on. Sets
- * the "tk_dialog" variable when the dialog is ready to receive
- * messages.
+ * 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.
@@ -961,45 +976,127 @@ GetFileNameW(clientData, interp, objc, objv, open)
*-------------------------------------------------------------------------
*/
-static UINT APIENTRY
+static UINT APIENTRY
OFNHookProcW(
- HWND hdlg, // handle to child dialog window
- UINT uMsg, // message identifier
- WPARAM wParam, // message parameter
- LPARAM lParam) // message parameter
+ HWND hdlg, /* Handle to child dialog window. */
+ UINT uMsg, /* Message identifier */
+ WPARAM wParam, /* Message parameter */
+ LPARAM lParam) /* Message parameter */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
OPENFILENAMEW *ofnPtr;
+ OFNData *ofnData;
if (uMsg == WM_INITDIALOG) {
-#ifdef _WIN64
- SetWindowLongPtr(hdlg, GWLP_USERDATA, lParam);
-#else
- SetWindowLong(hdlg, GWL_USERDATA, lParam);
-#endif
+ TkWinSetUserData(hdlg, lParam);
+ } else if (uMsg == WM_NOTIFY) {
+ OFNOTIFYW *notifyPtr = (OFNOTIFYW *) lParam;
+
+ /*
+ * This is weird... or not. The CDN_FILEOK is NOT sent when the selection
+ * exceeds declared buffer size (the nMaxFile member of the OPENFILENAMEW
+ * struct passed to GetOpenFileNameW 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 [tktoolkit-Bugs-2987995]
+ */
+ if (notifyPtr->hdr.code == CDN_FILEOK ||
+ notifyPtr->hdr.code == CDN_SELCHANGE) {
+ int dirsize, selsize;
+ WCHAR *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 = (WCHAR *) ofnData->dynFileBuffer;
+ hdlg = GetParent(hdlg);
+
+ selsize = SendMessageW(hdlg, CDM_GETSPEC, 0, 0);
+ dirsize = SendMessageW(hdlg, CDM_GETFOLDERPATH, 0, 0);
+ buffersize = (selsize + dirsize + 1) * 2;
+
+ /*
+ * Just empty the buffer if dirsize indicates an error [Bug 3071836]
+ */
+ if ((selsize > 1) && (dirsize > 0)) {
+ if (ofnData->dynFileBufferSize < buffersize) {
+ buffer = (WCHAR *) ckrealloc((char *) buffer, buffersize);
+ ofnData->dynFileBufferSize = buffersize;
+ ofnData->dynFileBuffer = (char *) buffer;
+ }
+
+ SendMessageW(hdlg, CDM_GETFOLDERPATH, dirsize, (int) buffer);
+ buffer += dirsize;
+
+ SendMessageW(hdlg, CDM_GETSPEC, selsize, (int) buffer);
+
+ /*
+ * If there are multiple files, delete the quotes and change
+ * every second quote to NULL terminator
+ */
+
+ if (buffer[0] == '"') {
+ BOOL findquote = TRUE;
+ WCHAR *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 {
+ buffer[selsize] = '\0'; /* Second NULL terminator. */
+
+ /*
+ * Replace directory terminating NULL with a backslash.
+ */
+
+ buffer--;
+ *buffer = '\\';
+ }
+ } 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.
+ * 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.
*/
-#ifdef _WIN64
- ofnPtr = (OPENFILENAMEW *) GetWindowLongPtr(hdlg, GWLP_USERDATA);
-#else
- ofnPtr = (OPENFILENAMEW *) GetWindowLong(hdlg, GWL_USERDATA);
-#endif
+ ofnPtr = (OPENFILENAMEW *) TkWinGetUserData(hdlg);
if (ofnPtr != NULL) {
- hdlg = GetParent(hdlg);
- tsdPtr->debugInterp = (Tcl_Interp *) ofnPtr->lCustData;
- Tcl_DoWhenIdle(SetTkDialog, (ClientData) hdlg);
-#ifdef _WIN64
- SetWindowLongPtr(hdlg, GWLP_USERDATA, (LPARAM) NULL);
-#else
- SetWindowLong(hdlg, GWL_USERDATA, (LPARAM) NULL);
-#endif
+ ofnData = (OFNData *) ofnPtr->lCustData;
+ if (ofnData->interp != NULL) {
+ hdlg = GetParent(hdlg);
+ tsdPtr->debugInterp = ofnData->interp;
+ Tcl_DoWhenIdle(SetTkDialog, hdlg);
+ }
+ TkWinSetUserData(hdlg, NULL);
}
}
return 0;
@@ -1021,54 +1118,52 @@ OFNHookProcW(
*----------------------------------------------------------------------
*/
-static int
-GetFileNameA(clientData, interp, objc, objv, open)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
- int open; /* 1 to call GetOpenFileName(), 0 to
- * call GetSaveFileName(). */
+static int
+GetFileNameA(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument objects. */
+ int open) /* 1 to call GetOpenFileName(), 0 to call
+ * GetSaveFileName(). */
{
OPENFILENAME ofn;
TCHAR file[TK_MULTI_MAX_PATH], savePath[MAX_PATH];
- int result, winCode, oldMode, i, multi = 0;
- char *extension, *filter, *title;
- Tk_Window tkwin;
+ OFNData ofnData;
+ int cdlgerr;
+ int filterIndex = 0, result = TCL_ERROR, winCode, oldMode, i, multi = 0;
+ char *extension = NULL, *title = NULL;
+ Tk_Window tkwin = (Tk_Window) clientData;
HWND hWnd;
- Tcl_DString utfFilterString, utfDirString;
+ Tcl_Obj *filterObj = NULL, *initialTypeObj = NULL, *typeVariableObj = NULL;
+ Tcl_DString utfFilterString, utfDirString, ds;
Tcl_DString extString, filterString, dirString, titleString;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
static CONST char *saveOptionStrings[] = {
"-defaultextension", "-filetypes", "-initialdir", "-initialfile",
- "-parent", "-title", NULL
+ "-parent", "-title", "-typevariable", NULL
};
static CONST char *openOptionStrings[] = {
"-defaultextension", "-filetypes", "-initialdir", "-initialfile",
- "-multiple", "-parent", "-title", NULL
+ "-multiple", "-parent", "-title", "-typevariable", NULL
};
CONST char **optionStrings;
enum options {
FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE,
- FILE_MULTIPLE, FILE_PARENT, FILE_TITLE
+ FILE_MULTIPLE, FILE_PARENT, FILE_TITLE, FILE_TYPEVARIABLE
};
- result = TCL_ERROR;
file[0] = '\0';
+ ZeroMemory(&ofnData, sizeof(OFNData));
+ Tcl_DStringInit(&utfFilterString);
+ Tcl_DStringInit(&utfDirString);
/*
* Parse the arguments.
*/
- extension = NULL;
- filter = NULL;
- Tcl_DStringInit(&utfFilterString);
- Tcl_DStringInit(&utfDirString);
- tkwin = (Tk_Window) clientData;
- title = NULL;
-
if (open) {
optionStrings = openOptionStrings;
} else {
@@ -1083,124 +1178,114 @@ GetFileNameA(clientData, interp, objc, objv, open)
optionPtr = objv[i];
valuePtr = objv[i + 1];
- if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings,
- "option", 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option", 0,
+ &index) != TCL_OK) {
goto end;
}
+
/*
* We want to maximize code sharing between the open and save file
* dialog implementations; in particular, the switch statement below.
* We use different sets of option strings from the GetIndexFromObj
- * call above, but a single enumeration for both. The save file
- * dialog doesn't support -multiple, but it falls in the middle of
- * the enumeration. Ultimately, this means that when the index found
- * by GetIndexFromObj is >= FILE_MULTIPLE, when doing a save file
- * dialog, we have to increment the index, so that it matches the
- * open file dialog enumeration.
+ * call above, but a single enumeration for both. The save file dialog
+ * doesn't support -multiple, but it falls in the middle of the
+ * enumeration. Ultimately, this means that when the index found by
+ * GetIndexFromObj is >= FILE_MULTIPLE, when doing a save file dialog,
+ * we have to increment the index, so that it matches the open file
+ * dialog enumeration.
*/
+
if (!open && index >= FILE_MULTIPLE) {
index++;
}
if (i + 1 == objc) {
- string = Tcl_GetStringFromObj(optionPtr, NULL);
- Tcl_AppendResult(interp, "value for \"", string, "\" missing",
- (char *) NULL);
+ string = Tcl_GetString(optionPtr);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ NULL);
goto end;
}
- string = Tcl_GetStringFromObj(valuePtr, NULL);
+ string = Tcl_GetString(valuePtr);
switch ((enum options) index) {
- case FILE_DEFAULT: {
- if (string[0] == '.') {
- string++;
- }
- extension = string;
- break;
- }
- case FILE_TYPES: {
- Tcl_DStringFree(&utfFilterString);
- if (MakeFilter(interp, string, &utfFilterString) != TCL_OK) {
- goto end;
- }
- filter = Tcl_DStringValue(&utfFilterString);
- break;
- }
- case FILE_INITDIR: {
- Tcl_DStringFree(&utfDirString);
- if (Tcl_TranslateFileName(interp, string,
- &utfDirString) == NULL) {
- goto end;
- }
- break;
+ case FILE_DEFAULT:
+ if (string[0] == '.') {
+ string++;
}
- case FILE_INITFILE: {
- Tcl_DString ds;
-
- if (Tcl_TranslateFileName(interp, string, &ds) == NULL) {
- goto end;
- }
- Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&ds),
- Tcl_DStringLength(&ds), 0, NULL, (char *) file,
- sizeof(file), NULL, NULL, NULL);
- break;
+ extension = string;
+ break;
+ case FILE_TYPES:
+ filterObj = valuePtr;
+ break;
+ case FILE_INITDIR:
+ Tcl_DStringFree(&utfDirString);
+ if (Tcl_TranslateFileName(interp, string, &utfDirString) == NULL) {
+ goto end;
}
- case FILE_MULTIPLE: {
- if (Tcl_GetBooleanFromObj(interp, valuePtr,
- &multi) != TCL_OK) {
- return TCL_ERROR;
- }
- break;
+ break;
+ case FILE_INITFILE:
+ if (Tcl_TranslateFileName(interp, string, &ds) == NULL) {
+ goto end;
}
- case FILE_PARENT: {
- tkwin = Tk_NameToWindow(interp, string, tkwin);
- if (tkwin == NULL) {
- goto end;
- }
- break;
+ Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds), 0, NULL, (char *) file,
+ sizeof(file), NULL, NULL, NULL);
+ Tcl_DStringFree(&ds);
+ break;
+ case FILE_MULTIPLE:
+ if (Tcl_GetBooleanFromObj(interp, valuePtr, &multi) != TCL_OK) {
+ return TCL_ERROR;
}
- case FILE_TITLE: {
- title = string;
- break;
+ break;
+ case FILE_PARENT:
+ tkwin = Tk_NameToWindow(interp, string, tkwin);
+ if (tkwin == NULL) {
+ goto end;
}
+ break;
+ case FILE_TITLE:
+ title = string;
+ break;
+ case FILE_TYPEVARIABLE:
+ typeVariableObj = valuePtr;
+ initialTypeObj = Tcl_ObjGetVar2(interp, typeVariableObj, NULL,
+ TCL_GLOBAL_ONLY);
+ break;
}
}
- if (filter == NULL) {
- if (MakeFilter(interp, "", &utfFilterString) != TCL_OK) {
- goto end;
- }
+ if (MakeFilter(interp, filterObj, &utfFilterString, initialTypeObj,
+ &filterIndex) != TCL_OK) {
+ goto end;
}
Tk_MakeWindowExist(tkwin);
hWnd = Tk_GetHWND(Tk_WindowId(tkwin));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = hWnd;
-#ifdef _WIN64
- ofn.hInstance = (HINSTANCE) GetWindowLongPtr(ofn.hwndOwner,
- GWLP_HINSTANCE);
-#else
- ofn.hInstance = (HINSTANCE) GetWindowLong(ofn.hwndOwner,
- GWL_HINSTANCE);
-#endif
- ofn.lpstrFilter = NULL;
- ofn.lpstrCustomFilter = NULL;
- ofn.nMaxCustFilter = 0;
- ofn.nFilterIndex = 0;
- ofn.lpstrFile = (LPTSTR) file;
- ofn.nMaxFile = TK_MULTI_MAX_PATH;
- ofn.lpstrFileTitle = NULL;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = NULL;
- ofn.lpstrTitle = NULL;
- ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST
- | OFN_NOCHANGEDIR | OFN_EXPLORER;
- ofn.nFileOffset = 0;
- ofn.nFileExtension = 0;
- ofn.lpstrDefExt = NULL;
- ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProc;
- ofn.lCustData = (LPARAM) interp;
- ofn.lpTemplateName = NULL;
+ ZeroMemory(&ofn, sizeof(OPENFILENAMEA));
+ if (LOBYTE(LOWORD(GetVersion())) < 5) {
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ } else {
+ ofn.lStructSize = sizeof(ofn);
+ }
+ ofn.hwndOwner = hWnd;
+ ofn.hInstance = TkWinGetHInstance(ofn.hwndOwner);
+ ofn.lpstrFilter = NULL;
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.lpstrFile = (LPTSTR) file;
+ ofn.nMaxFile = TK_MULTI_MAX_PATH;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.lpstrTitle = NULL;
+ ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR
+ | OFN_EXPLORER | OFN_ENABLEHOOK;
+ ofn.nFileOffset = 0;
+ ofn.nFileExtension = 0;
+ ofn.lpstrDefExt = NULL;
+ ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProcA;
+ ofn.lCustData = (LPARAM) &ofnData;
+ ofn.lpTemplateName = NULL;
if (open != 0) {
ofn.Flags |= OFN_FILEMUSTEXIST;
@@ -1209,11 +1294,19 @@ GetFileNameA(clientData, interp, objc, objv, open)
}
if (tsdPtr->debugFlag != 0) {
- ofn.Flags |= OFN_ENABLEHOOK;
+ ofnData.interp = interp;
}
if (multi != 0) {
ofn.Flags |= OFN_ALLOWMULTISELECT;
+
+ /*
+ * Starting buffer size. The buffer will be expanded by the OFN dialog
+ * procedure when necessary
+ */
+
+ ofnData.dynFileBufferSize = 1024;
+ ofnData.dynFileBuffer = ckalloc(1024);
}
if (extension != NULL) {
@@ -1223,20 +1316,21 @@ GetFileNameA(clientData, interp, objc, objv, open)
Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&utfFilterString),
Tcl_DStringLength(&utfFilterString), &filterString);
ofn.lpstrFilter = (LPTSTR) Tcl_DStringValue(&filterString);
+ ofn.nFilterIndex = filterIndex;
if (Tcl_DStringValue(&utfDirString)[0] != '\0') {
Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&utfDirString),
Tcl_DStringLength(&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.
+ * 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(&utfDirString);
- if ((Tcl_GetCwd(interp, &utfDirString) == (char *) NULL) ||
+ if ((Tcl_GetCwd(interp, &utfDirString) == NULL) ||
(Tcl_TranslateFileName(interp,
Tcl_DStringValue(&utfDirString), &cwd) == NULL)) {
Tcl_ResetResult(interp);
@@ -1269,10 +1363,11 @@ GetFileNameA(clientData, interp, objc, objv, open)
SetCurrentDirectory(savePath);
/*
- * 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).
+ * 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);
/*
@@ -1284,42 +1379,44 @@ GetFileNameA(clientData, interp, objc, objv, open)
/*
* 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 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) {
+ if ((winCode != 0)
+ || ((cdlgerr == FNERR_BUFFERTOOSMALL)
+ && (ofn.Flags & OFN_ALLOWMULTISELECT))) {
if (ofn.Flags & OFN_ALLOWMULTISELECT) {
- /*
- * The result in custData->szFile contains many items,
- * separated with null characters. It is terminated with
- * two nulls in a row. The first element is the directory
- * path.
+ /*
+ * 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 (if multiple files are
+ * selected) or the only returned file (if only a single file has
+ * been chosen).
*/
- char *dir;
- char *p;
- char *file;
- char *files;
- Tcl_DString ds;
- Tcl_DString fullname, filename;
- Tcl_Obj *returnList;
- int count = 0;
- returnList = Tcl_NewObj();
- Tcl_IncrRefCount(returnList);
+ char *files = ofnData.dynFileBuffer;
+ Tcl_Obj *returnList = Tcl_NewObj();
+ int count = 0;
- files = ofn.lpstrFile;
- Tcl_ExternalToUtfDString(NULL, (char *) files, -1, &ds);
+ /*
+ * Get directory.
+ */
- /* Get directory */
- dir = Tcl_DStringValue(&ds);
- for (p = dir; p && *p; p++) {
- /*
- * Change the pathname to the Tcl "normalized" pathname, where
- * back slashes are used instead of forward slashes
- */
- if (*p == '\\') {
- *p = '/';
- }
- }
+ (void) ConvertExternalFilename(NULL, (char *) files, &ds);
while (*files != '\0') {
while (*files != '\0') {
@@ -1327,85 +1424,63 @@ GetFileNameA(clientData, interp, objc, objv, open)
}
files++;
if (*files != '\0') {
+ Tcl_Obj *fullnameObj;
+ Tcl_DString filename;
+
count++;
- Tcl_ExternalToUtfDString(NULL,
- (char *)files, -1, &filename);
- file = Tcl_DStringValue(&filename);
- for (p = file; *p != '\0'; p++) {
- if (*p == '\\') {
- *p = '/';
- }
- }
- Tcl_DStringInit(&fullname);
- Tcl_DStringAppend(&fullname, dir, -1);
- Tcl_DStringAppend(&fullname, "/", -1);
- Tcl_DStringAppend(&fullname, file, -1);
- Tcl_ListObjAppendElement(interp, returnList,
- Tcl_NewStringObj(Tcl_DStringValue(&fullname), -1));
- Tcl_DStringFree(&fullname);
+ (void) ConvertExternalFilename(NULL, (char *) files,
+ &filename);
+ fullnameObj = Tcl_NewStringObj(Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds));
+ Tcl_AppendToObj(fullnameObj, "/", -1);
+ Tcl_AppendToObj(fullnameObj, Tcl_DStringValue(&filename),
+ Tcl_DStringLength(&filename));
Tcl_DStringFree(&filename);
+ Tcl_ListObjAppendElement(NULL, returnList, fullnameObj);
}
}
if (count == 0) {
/*
* Only one file was returned.
*/
- Tcl_ListObjAppendElement(interp, returnList,
- Tcl_NewStringObj(dir, -1));
+
+ Tcl_ListObjAppendElement(NULL, returnList, Tcl_NewStringObj(
+ Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)));
}
Tcl_SetObjResult(interp, returnList);
- Tcl_DecrRefCount(returnList);
Tcl_DStringFree(&ds);
} else {
- char *p;
- Tcl_DString ds;
-
- Tcl_ExternalToUtfDString(NULL, (char *) ofn.lpstrFile, -1, &ds);
- for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) {
- /*
- * Change the pathname to the Tcl "normalized" pathname, where
- * back slashes are used instead of forward slashes
- */
- if (*p == '\\') {
- *p = '/';
- }
- }
- Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
+ Tcl_AppendResult(interp, ConvertExternalFilename(NULL,
+ (char *) ofn.lpstrFile, &ds), NULL);
Tcl_DStringFree(&ds);
}
result = TCL_OK;
- } else {
- /*
- * 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 specific error messages for particular
- * errors, we can extend the code as needed.
- *
- * We could also check for FNERR_BUFFERTOOSMALL, but we can't
- * really do anything about it when it happens.
- */
- if (CommDlgExtendedError() == FNERR_INVALIDFILENAME) {
- char *p;
- Tcl_DString ds;
-
- Tcl_ExternalToUtfDString(NULL, (char *) ofn.lpstrFile, -1, &ds);
- for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) {
- /*
- * Change the pathname to the Tcl "normalized" pathname,
- * where back slashes are used instead of forward slashes
- */
- if (*p == '\\') {
- *p = '/';
- }
+ if ((ofn.nFilterIndex > 0) &&
+ (Tcl_GetCharLength(Tcl_GetObjResult(interp)) > 0) &&
+ typeVariableObj && filterObj) {
+ int listObjc, count;
+ Tcl_Obj **listObjv = NULL;
+ Tcl_Obj **typeInfo = NULL;
+
+ if (Tcl_ListObjGetElements(interp, filterObj, &listObjc,
+ &listObjv) != TCL_OK) {
+ result = TCL_ERROR;
+ } else if (Tcl_ListObjGetElements(interp,
+ listObjv[ofn.nFilterIndex - 1], &count,
+ &typeInfo) != TCL_OK) {
+ result = TCL_ERROR;
+ } else if (Tcl_ObjSetVar2(interp, typeVariableObj, NULL,
+ typeInfo[0], TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
+ result = TCL_ERROR;
}
- Tcl_SetResult(interp, "invalid filename \"", TCL_STATIC);
- Tcl_AppendResult(interp, Tcl_DStringValue(&ds), "\"", NULL);
- Tcl_DStringFree(&ds);
- } else {
- result = TCL_OK;
}
+ } else if (cdlgerr == FNERR_INVALIDFILENAME) {
+ Tcl_SetResult(interp, "invalid filename \"", TCL_STATIC);
+ Tcl_AppendResult(interp, ConvertExternalFilename(NULL,
+ (char *) ofn.lpstrFile, &ds), "\"", NULL);
+ Tcl_DStringFree(&ds);
+ } else {
+ result = TCL_OK;
}
if (ofn.lpstrTitle != NULL) {
@@ -1419,9 +1494,13 @@ GetFileNameA(clientData, interp, objc, objv, open)
Tcl_DStringFree(&extString);
}
- end:
+ end:
Tcl_DStringFree(&utfDirString);
Tcl_DStringFree(&utfFilterString);
+ if (ofnData.dynFileBuffer != NULL) {
+ ckfree(ofnData.dynFileBuffer);
+ ofnData.dynFileBuffer = NULL;
+ }
return result;
}
@@ -1429,11 +1508,12 @@ GetFileNameA(clientData, interp, objc, objv, open)
/*
*-------------------------------------------------------------------------
*
- * OFNHookProc --
+ * OFNHookProcA --
*
- * Hook procedure called only if debugging is turned on. Sets
- * the "tk_dialog" variable when the dialog is ready to receive
- * messages.
+ * 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.
@@ -1444,48 +1524,130 @@ GetFileNameA(clientData, interp, objc, objv, open)
*-------------------------------------------------------------------------
*/
-static UINT APIENTRY
-OFNHookProc(
- HWND hdlg, // handle to child dialog window
- UINT uMsg, // message identifier
- WPARAM wParam, // message parameter
- LPARAM lParam) // message parameter
+static UINT APIENTRY
+OFNHookProcA(
+ HWND hdlg, /* handle to child dialog window */
+ UINT uMsg, /* message identifier */
+ WPARAM wParam, /* message parameter */
+ LPARAM lParam) /* message parameter */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
OPENFILENAME *ofnPtr;
+ OFNData *ofnData;
if (uMsg == WM_INITDIALOG) {
-#ifdef _WIN64
- SetWindowLongPtr(hdlg, GWLP_USERDATA, lParam);
-#else
- SetWindowLong(hdlg, GWL_USERDATA, lParam);
-#endif
+ 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 OPENFILENAMEW
+ * struct passed to GetOpenFileNameW 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 [tktoolkit-Bugs-2987995]
+ */
+ if (notifyPtr->hdr.code == CDN_FILEOK ||
+ notifyPtr->hdr.code == CDN_SELCHANGE) {
+ int dirsize, selsize;
+ char *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 = SendMessage(hdlg, CDM_GETSPEC, 0, 0);
+ dirsize = 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);
+ ofnData->dynFileBufferSize = buffersize;
+ ofnData->dynFileBuffer = buffer;
+ }
+
+ SendMessage(hdlg, CDM_GETFOLDERPATH, dirsize, (int) buffer);
+ buffer += dirsize;
+ SendMessage(hdlg, CDM_GETSPEC, selsize, (int) buffer);
+
+ /*
+ * If there are multiple files, delete the quotes and change
+ * every second quote to NULL terminator.
+ */
+
+ if (buffer[0] == '"') {
+ BOOL findquote = TRUE;
+ char *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 {
+ buffer[selsize] = '\0'; /* Second NULL terminator. */
+
+ /*
+ * Replace directory terminating NULL with a backslash.
+ */
+
+ buffer--;
+ *buffer = '\\';
+ }
+
+ } 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 both
- * old-style and explorer-style hook procs 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.
+ * This message is delivered at the right time to both old-style and
+ * explorer-style hook procs 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.
*/
-#ifdef _WIN64
- ofnPtr = (OPENFILENAME *) GetWindowLongPtr(hdlg, GWLP_USERDATA);
-#else
- ofnPtr = (OPENFILENAME *) GetWindowLong(hdlg, GWL_USERDATA);
-#endif
+ ofnPtr = (OPENFILENAME *) TkWinGetUserData(hdlg);
if (ofnPtr != NULL) {
- if (ofnPtr->Flags & OFN_EXPLORER) {
- hdlg = GetParent(hdlg);
+ ofnData = (OFNData *) ofnPtr->lCustData;
+ if (ofnData->interp != NULL) {
+ if (ofnPtr->Flags & OFN_EXPLORER) {
+ hdlg = GetParent(hdlg);
+ }
+ tsdPtr->debugInterp = ofnData->interp;
+ Tcl_DoWhenIdle(SetTkDialog, hdlg);
}
- tsdPtr->debugInterp = (Tcl_Interp *) ofnPtr->lCustData;
- Tcl_DoWhenIdle(SetTkDialog, (ClientData) hdlg);
-#ifdef _WIN64
- SetWindowLongPtr(hdlg, GWLP_USERDATA, (LPARAM) NULL);
-#else
- SetWindowLong(hdlg, GWL_USERDATA, (LPARAM) NULL);
-#endif
+ TkWinSetUserData(hdlg, NULL);
}
}
return 0;
@@ -1497,7 +1659,7 @@ OFNHookProc(
* MakeFilter --
*
* Allocate a buffer to store the filters in a format understood by
- * Windows
+ * Windows.
*
* Results:
* A standard TCL return value.
@@ -1507,20 +1669,28 @@ OFNHookProc(
*
*----------------------------------------------------------------------
*/
-static int
-MakeFilter(interp, string, dsPtr)
- Tcl_Interp *interp; /* Current interpreter. */
- char *string; /* String value of the -filetypes option */
- Tcl_DString *dsPtr; /* Filled with windows filter string. */
+
+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 *index) /* Index of initial type in filter string */
{
char *filterStr;
char *p;
+ char *initial = NULL;
int pass;
+ int ix = 0; /* index counter */
FileFilterList flist;
FileFilter *filterPtr;
+ if (initialPtr) {
+ initial = Tcl_GetStringFromObj(initialPtr, NULL);
+ }
TkInitFileFilters(&flist);
- if (TkGetFileFilters(interp, &flist, string, 1) != TCL_OK) {
+ if (TkGetFileFilters(interp, &flist, valuePtr, 1) != TCL_OK) {
return TCL_ERROR;
}
@@ -1544,9 +1714,18 @@ MakeFilter(interp, string, dsPtr)
*p = '\0';
} else {
- /* We format the filetype into a string understood by Windows:
- * {"Text Documents" {.doc .txt} {TEXT}} becomes
- * "Text Documents (*.doc,*.txt)\0*.doc;*.txt\0"
+ int len;
+
+ if (valuePtr == NULL) {
+ len = 0;
+ } else {
+ (void) Tcl_GetStringFromObj(valuePtr, &len);
+ }
+
+ /*
+ * 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.
@@ -1556,16 +1735,27 @@ MakeFilter(interp, string, dsPtr)
* 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((unsigned int) strlen(string) * 3);
+
+ filterStr = ckalloc((unsigned int) len * 3);
for (filterPtr = flist.filters, p = filterStr; filterPtr;
- filterPtr = filterPtr->next) {
+ filterPtr = filterPtr->next) {
char *sep;
FileFilterClause *clausePtr;
/*
- * First, put in the name of the file type
+ * Check initial index for match, set index. Filter index is 1
+ * based so increment first
*/
+ ix++;
+ if (index && initial && (strcmp(initial, filterPtr->name) == 0)) {
+ *index = ix;
+ }
+
+ /*
+ * First, put in the name of the file type.
+ */
+
strcpy(p, filterPtr->name);
p+= strlen(filterPtr->name);
*p++ = ' ';
@@ -1573,24 +1763,24 @@ MakeFilter(interp, string, dsPtr)
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
+ * 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) {
+ clausePtr=clausePtr->next) {
GlobPattern *globPtr;
-
- for (globPtr=clausePtr->patterns; globPtr;
- globPtr=globPtr->next) {
+ for (globPtr = clausePtr->patterns; globPtr;
+ globPtr = globPtr->next) {
strcpy(p, sep);
- p+= strlen(sep);
+ p += strlen(sep);
strcpy(p, globPtr->pattern);
- p+= strlen(globPtr->pattern);
+ p += strlen(globPtr->pattern);
- if (pass==1) {
+ if (pass == 1) {
sep = ",";
} else {
sep = ";";
@@ -1598,11 +1788,9 @@ MakeFilter(interp, string, dsPtr)
}
}
if (pass == 1) {
- if (pass == 1) {
- *p ++ = ')';
- }
+ *p ++ = ')';
}
- *p ++ = '\0';
+ *p++ = '\0';
}
}
@@ -1610,6 +1798,7 @@ MakeFilter(interp, string, dsPtr)
* Windows requires the filter string to be ended by two NULL
* characters.
*/
+
*p++ = '\0';
*p = '\0';
}
@@ -1621,176 +1810,167 @@ MakeFilter(interp, string, dsPtr)
return TCL_OK;
}
-#ifdef USE_NEW_CHOOSEDIR
/*
*----------------------------------------------------------------------
*
* Tk_ChooseDirectoryObjCmd --
*
- * This procedure 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.
+ * 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.
+ * See user documentation.
*
* Side effects:
- * A modal dialog window is created. Tcl_SetServiceMode() is
- * called to allow background events to be processed
+ * A modal dialog window is created. Tcl_SetServiceMode() is called to
+ * allow background events to be processed
*
*----------------------------------------------------------------------
-
-The procedure 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.
-ToDo:
-- Fix bugs.
-- test to see what platforms this really works on. May require v4.71
- of shell32.dll everywhere (what is standard?).
*
+ * 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, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+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. */
{
char path[MAX_PATH];
- int oldMode, result, i;
+ int oldMode, result = TCL_ERROR, i;
LPCITEMIDLIST pidl; /* Returned by browser */
BROWSEINFO bInfo; /* Used by browser */
CHOOSEDIRDATA cdCBData; /* Structure to pass back and forth */
LPMALLOC pMalloc; /* Used by shell */
-
- Tk_Window tkwin;
+ Tk_Window tkwin = (Tk_Window) clientData;
HWND hWnd;
- char *utfTitle; /* Title for window */
+ char *utfTitle = NULL;/* Title for window */
TCHAR saveDir[MAX_PATH];
Tcl_DString titleString; /* UTF Title */
Tcl_DString initDirString; /* Initial directory */
+ Tcl_Obj *objPtr;
static CONST char *optionStrings[] = {
- "-initialdir", "-mustexist", "-parent", "-title", (char *) NULL
+ "-initialdir", "-mustexist", "-parent", "-title", NULL
};
enum options {
- DIR_INITIAL, DIR_EXIST, DIR_PARENT, FILE_TITLE
+ DIR_INITIAL, DIR_EXIST, DIR_PARENT, FILE_TITLE
};
/*
* Initialize
*/
- result = TCL_ERROR;
- path[0] = '\0';
- utfTitle = NULL;
+ path[0] = '\0';
ZeroMemory(&cdCBData, sizeof(CHOOSEDIRDATA));
- cdCBData.interp = interp;
+ cdCBData.interp = interp;
- tkwin = (Tk_Window) clientData;
/*
* Process the command line options
*/
+
for (i = 1; i < objc; i += 2) {
- int index;
- char *string;
- Tcl_Obj *optionPtr, *valuePtr;
-
- optionPtr = objv[i];
- valuePtr = objv[i + 1];
-
- if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option",
- 0, &index) != TCL_OK) {
- goto cleanup;
- }
- if (i + 1 == objc) {
- string = Tcl_GetStringFromObj(optionPtr, NULL);
- Tcl_AppendResult(interp, "value for \"", string, "\" missing",
- (char *) NULL);
- goto cleanup;
- }
+ int index;
+ char *string;
+ Tcl_Obj *optionPtr, *valuePtr;
+
+ optionPtr = objv[i];
+ valuePtr = objv[i + 1];
+
+ if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option", 0,
+ &index) != TCL_OK) {
+ goto cleanup;
+ }
+ if (i + 1 == objc) {
+ string = Tcl_GetString(optionPtr);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ NULL);
+ goto cleanup;
+ }
string = Tcl_GetString(valuePtr);
- switch ((enum options) index) {
- case DIR_INITIAL: {
- if (Tcl_TranslateFileName(interp, string,
- &initDirString) == NULL) {
- goto cleanup;
- }
- string = Tcl_DStringValue(&initDirString);
- /*
- * Convert possible relative path to full path to keep
- * dialog happy
- */
- GetFullPathName(string, MAX_PATH, saveDir, NULL);
- lstrcpyn(cdCBData.utfInitDir, saveDir, MAX_PATH);
- Tcl_DStringFree(&initDirString);
- break;
- }
- case DIR_EXIST: {
- if (Tcl_GetBooleanFromObj(interp, valuePtr,
- &cdCBData.mustExist) != TCL_OK) {
- goto cleanup;
- }
- break;
- }
- case DIR_PARENT: {
- tkwin = Tk_NameToWindow(interp, string, tkwin);
- if (tkwin == NULL) {
- goto cleanup;
- }
- break;
- }
- case FILE_TITLE: {
- utfTitle = string;
- break;
- }
- }
+ switch ((enum options) index) {
+ case DIR_INITIAL:
+ if (Tcl_TranslateFileName(interp,string,&initDirString) == NULL) {
+ goto cleanup;
+ }
+ string = Tcl_DStringValue(&initDirString);
+
+ /*
+ * Convert possible relative path to full path to keep dialog
+ * happy.
+ */
+
+ GetFullPathName(string, MAX_PATH, saveDir, NULL);
+ lstrcpyn(cdCBData.utfInitDir, saveDir, MAX_PATH);
+ Tcl_DStringFree(&initDirString);
+ break;
+ case DIR_EXIST:
+ if (Tcl_GetBooleanFromObj(interp, valuePtr,
+ &cdCBData.mustExist) != TCL_OK) {
+ goto cleanup;
+ }
+ break;
+ case DIR_PARENT:
+ tkwin = Tk_NameToWindow(interp, string, tkwin);
+ if (tkwin == NULL) {
+ goto cleanup;
+ }
+ break;
+ case FILE_TITLE:
+ utfTitle = string;
+ break;
+ }
}
/*
@@ -1804,44 +1984,66 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv)
* Setup the parameters used by SHBrowseForFolder
*/
- bInfo.hwndOwner = hWnd;
+ bInfo.hwndOwner = hWnd;
bInfo.pszDisplayName = path;
- bInfo.pidlRoot = NULL;
+ bInfo.pidlRoot = NULL;
if (lstrlen(cdCBData.utfInitDir) == 0) {
- GetCurrentDirectory(MAX_PATH, cdCBData.utfInitDir);
+ GetCurrentDirectory(MAX_PATH, cdCBData.utfInitDir);
}
bInfo.lParam = (LPARAM) &cdCBData;
if (utfTitle != NULL) {
- Tcl_UtfToExternalDString(NULL, utfTitle, -1, &titleString);
- bInfo.lpszTitle = (LPTSTR) Tcl_DStringValue(&titleString);
+ Tcl_UtfToExternalDString(NULL, utfTitle, -1, &titleString);
+ bInfo.lpszTitle = (LPTSTR) Tcl_DStringValue(&titleString);
} else {
- bInfo.lpszTitle = "Please choose a directory, then select OK.";
+ bInfo.lpszTitle = "Please choose a directory, then select OK.";
}
/*
- * Set flags to add edit box (needs 4.71 Shell DLLs), status text line,
- * validate edit box and
+ * 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;
+
+ 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;
+
+ 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;
+ * 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) {
pidl = SHBrowseForFolder(&bInfo);
- /* Null for cancel button or invalid dir, otherwise valid*/
+
+ /*
+ * 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_SetResult(interp, "Error: Not a file system folder\n",
@@ -1857,38 +2059,34 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv)
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).
+ * 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
+ * Change the pathname to the Tcl "normalized" pathname, where back
+ * slashes are used instead of forward slashes
*/
+
Tcl_ResetResult(interp);
if (*path) {
- char *p;
- Tcl_DString ds;
-
- Tcl_ExternalToUtfDString(NULL, (char *) path, -1, &ds);
- for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) {
- if (*p == '\\') {
- *p = '/';
- }
- }
- Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
- Tcl_DStringFree(&ds);
+ Tcl_DString ds;
+
+ Tcl_AppendResult(interp, ConvertExternalFilename(NULL, (char *) path,
+ &ds), NULL);
+ Tcl_DStringFree(&ds);
}
result = TCL_OK;
if (utfTitle != NULL) {
- Tcl_DStringFree(&titleString);
+ Tcl_DStringFree(&titleString);
}
- cleanup:
+ cleanup:
return result;
}
@@ -1897,658 +2095,213 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv)
*
* ChooseDirectoryValidateProc --
*
- * Hook procedure called by the explorer ChooseDirectory dialog when events
- * occur. It is used to validate the text entry the user may have entered.
+ * 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 procedure not to close.
+ * Returns 0 to allow default processing of message, or 1 to tell default
+ * dialog function not to close.
*
*----------------------------------------------------------------------
*/
+
static UINT APIENTRY
-ChooseDirectoryValidateProc (
+ChooseDirectoryValidateProc(
HWND hwnd,
UINT message,
LPARAM lParam,
LPARAM lpData)
{
TCHAR selDir[MAX_PATH];
- CHOOSEDIRDATA *chooseDirSharedData;
+ CHOOSEDIRDATA *chooseDirSharedData = (CHOOSEDIRDATA *) lpData;
Tcl_DString initDirString;
char string[MAX_PATH];
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- chooseDirSharedData = (CHOOSEDIRDATA *)lpData;
-
-#ifdef _WIN64
- SetWindowLongPtr(hwnd, GWLP_USERDATA, lpData);
-#else
- SetWindowLong(hwnd, GWL_USERDATA, lpData);
-#endif
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (tsdPtr->debugFlag) {
- tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp;
- Tcl_DoWhenIdle(SetTkDialog, (ClientData) hwnd);
+ tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp;
+ Tcl_DoWhenIdle(SetTkDialog, (ClientData) hwnd);
}
chooseDirSharedData->utfRetDir[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_TranslateFileName(chooseDirSharedData->interp,
- (char *)lParam, &initDirString);
- lstrcpyn (string, Tcl_DStringValue(&initDirString), MAX_PATH);
- Tcl_DStringFree(&initDirString);
-
- if (SetCurrentDirectory((char *)string) == 0) {
- LPTSTR lpFilePart[MAX_PATH];
-
- /*
- * Get the full path name to the user entry,
- * at this point it doesn't exist so see if
- * it is supposed to. Otherwise just return it.
- */
- GetFullPathName(string, MAX_PATH,
- chooseDirSharedData->utfRetDir, /*unused*/ lpFilePart);
- if (chooseDirSharedData->mustExist) {
- /*
- * User HAS to select a valid directory.
- */
- wsprintf(selDir, TEXT("Directory '%.200s' does not exist,\nplease select or enter an existing directory."), chooseDirSharedData->utfRetDir);
- MessageBox(NULL, selDir, NULL, MB_ICONEXCLAMATION|MB_OK);
- chooseDirSharedData->utfRetDir[0] = '\0';
- return 1;
- }
- } else {
- /*
- * Changed to new folder OK, return immediatly with the
- * current directory in utfRetDir.
- */
- GetCurrentDirectory(MAX_PATH, chooseDirSharedData->utfRetDir);
- 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);
- SetCurrentDirectory(selDir);
- } 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.
- */
- char *initDir = chooseDirSharedData->utfInitDir;
-
- 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;
- Tcl_DString ds;
-
- Tcl_UtfToExternalDString(TkWinGetUnicodeEncoding(),
- initDir, -1, &ds);
- if (SUCCEEDED(psfFolder->lpVtbl->ParseDisplayName(
- psfFolder, hwnd, NULL,
- (WCHAR *) Tcl_DStringValue(&ds),
- &ulCount, &pidlMain, &ulAttr))
- && (pidlMain != NULL)) {
- SendMessage(hwnd, BFFM_SETSELECTION, FALSE,
- (LPARAM)pidlMain);
- pMalloc->lpVtbl->Free(pMalloc, pidlMain);
- }
- psfFolder->lpVtbl->Release(psfFolder);
- Tcl_DStringFree(&ds);
- }
- pMalloc->lpVtbl->Release(pMalloc);
- }
- } else {
- SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)initDir);
- }
- SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1);
- break;
- }
-
- }
- return 0;
-}
-#else
-/*
- *----------------------------------------------------------------------
- *
- * Tk_ChooseDirectoryObjCmd --
- *
- * This procedure implements the "tk_chooseDirectory" dialog box
- * for the Windows platform. See the user documentation for details
- * on what it does.
- *
- * Results:
- * See user documentation.
- *
- * Side effects:
- * A modal dialog window is created. Tcl_SetServiceMode() is
- * called to allow background events to be processed
- *
- *----------------------------------------------------------------------
- */
-
-int
-Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
-{
- OPENFILENAME ofn;
- TCHAR path[MAX_PATH], savePath[MAX_PATH];
- ChooseDir cd;
- int result, mustExist, code, mode, i;
- Tk_Window tkwin;
- HWND hWnd;
- char *utfTitle;
- Tcl_DString utfDirString;
- Tcl_DString titleString, dirString;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- static CONST char *optionStrings[] = {
- "-initialdir", "-mustexist", "-parent", "-title",
- NULL
- };
- enum options {
- DIR_INITIAL, DIR_EXIST, DIR_PARENT, FILE_TITLE
- };
-
- if (tsdPtr->WM_LBSELCHANGED == 0) {
- tsdPtr->WM_LBSELCHANGED = RegisterWindowMessage(LBSELCHSTRING);
- }
-
- result = TCL_ERROR;
- path[0] = '\0';
-
- Tcl_DStringInit(&utfDirString);
- mustExist = 0;
- tkwin = (Tk_Window) clientData;
- utfTitle = NULL;
-
- for (i = 1; i < objc; i += 2) {
- int index;
- char *string;
- Tcl_Obj *optionPtr, *valuePtr;
-
- optionPtr = objv[i];
- valuePtr = objv[i + 1];
-
- if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option",
- 0, &index) != TCL_OK) {
- goto cleanup;
- }
- if (i + 1 == objc) {
- string = Tcl_GetStringFromObj(optionPtr, NULL);
- Tcl_AppendResult(interp, "value for \"", string, "\" missing",
- (char *) NULL);
- goto cleanup;
- }
-
- string = Tcl_GetStringFromObj(valuePtr, NULL);
- switch ((enum options) index) {
- case DIR_INITIAL: {
- Tcl_DStringFree(&utfDirString);
- if (Tcl_TranslateFileName(interp, string,
- &utfDirString) == NULL) {
- goto cleanup;
- }
- break;
- }
- case DIR_EXIST: {
- if (Tcl_GetBooleanFromObj(interp, valuePtr, &mustExist) != TCL_OK) {
- goto cleanup;
- }
- break;
- }
- case DIR_PARENT: {
- tkwin = Tk_NameToWindow(interp, string, tkwin);
- if (tkwin == NULL) {
- goto cleanup;
- }
- break;
- }
- case FILE_TITLE: {
- utfTitle = string;
- break;
- }
- }
- }
-
- Tk_MakeWindowExist(tkwin);
- hWnd = Tk_GetHWND(Tk_WindowId(tkwin));
-
- cd.interp = interp;
- cd.ofnPtr = &ofn;
-
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = hWnd;
-#ifdef _WIN64
- ofn.hInstance = (HINSTANCE) GetWindowLongPtr(ofn.hwndOwner,
- GWLP_HINSTANCE);
-#else
- ofn.hInstance = (HINSTANCE) GetWindowLong(ofn.hwndOwner,
- GWL_HINSTANCE);
-#endif
- ofn.lpstrFilter = NULL;
- ofn.lpstrCustomFilter = NULL;
- ofn.nMaxCustFilter = 0;
- ofn.nFilterIndex = 0;
- ofn.lpstrFile = NULL; //(TCHAR *) path;
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFileTitle = NULL;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = NULL;
- ofn.lpstrTitle = NULL;
- ofn.Flags = OFN_HIDEREADONLY
- | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE;
- ofn.nFileOffset = 0;
- ofn.nFileExtension = 0;
- ofn.lpstrDefExt = NULL;
- ofn.lCustData = (LPARAM) &cd;
- ofn.lpfnHook = (LPOFNHOOKPROC) ChooseDirectoryHookProc;
- ofn.lpTemplateName = MAKEINTRESOURCE(FILEOPENORD);
-
- if (Tcl_DStringValue(&utfDirString)[0] != '\0') {
- Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&utfDirString),
- Tcl_DStringLength(&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(&utfDirString);
- if ((Tcl_GetCwd(interp, &utfDirString) == (char *) NULL) ||
- (Tcl_TranslateFileName(interp,
- Tcl_DStringValue(&utfDirString), &cwd) == NULL)) {
- Tcl_ResetResult(interp);
- } else {
- Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&cwd),
- Tcl_DStringLength(&cwd), &dirString);
- }
- Tcl_DStringFree(&cwd);
- }
- ofn.lpstrInitialDir = (LPTSTR) Tcl_DStringValue(&dirString);
-
- if (mustExist) {
- ofn.Flags |= OFN_PATHMUSTEXIST;
- }
- if (utfTitle != NULL) {
- Tcl_UtfToExternalDString(NULL, utfTitle, -1, &titleString);
- ofn.lpstrTitle = (LPTSTR) Tcl_DStringValue(&titleString);
- }
-
- /*
- * Display dialog. The choose directory dialog doesn't preserve the
- * current directory, so it must be saved and restored here.
- */
-
- GetCurrentDirectory(MAX_PATH, savePath);
- mode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
- code = GetOpenFileName(&ofn);
- Tcl_SetServiceMode(mode);
- SetCurrentDirectory(savePath);
-
- /*
- * 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_ResetResult(interp);
- if (code != 0) {
+ case BFFM_VALIDATEFAILED:
/*
- * Change the pathname to the Tcl "normalized" pathname, where
- * back slashes are used instead of forward slashes
+ * 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.
*/
- char *p;
- Tcl_DString ds;
-
- Tcl_ExternalToUtfDString(NULL, (char *) cd.path, -1, &ds);
- for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) {
- if (*p == '\\') {
- *p = '/';
- }
- }
- Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
- Tcl_DStringFree(&ds);
- }
-
- if (ofn.lpstrTitle != NULL) {
- Tcl_DStringFree(&titleString);
- }
- if (ofn.lpstrInitialDir != NULL) {
- Tcl_DStringFree(&dirString);
- }
- result = TCL_OK;
-
- cleanup:
- Tcl_DStringFree(&utfDirString);
-
- return result;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * ChooseDirectoryHookProc --
- *
- * Hook procedure called by the ChooseDirectory dialog to modify
- * its default behavior. The ChooseDirectory dialog is really an
- * OpenFile dialog with certain controls rearranged and certain
- * behaviors changed. For instance, typing a name in the
- * ChooseDirectory dialog selects a directory, rather than
- * selecting a file.
- *
- * Results:
- * Returns 0 to allow default processing of message, or 1 to
- * tell default dialog procedure not to process the message.
- *
- * Side effects:
- * A dialog window is created the first this procedure is called.
- * This window is not destroyed and will be reused the next time
- * the application invokes the "tk_getOpenFile" or
- * "tk_getSaveFile" command.
- *
- *----------------------------------------------------------------------
- */
-
-static UINT APIENTRY
-ChooseDirectoryHookProc(
- HWND hwnd,
- UINT message,
- WPARAM wParam,
- LPARAM lParam)
-{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- OPENFILENAME *ofnPtr;
- ChooseDir *cdPtr;
-
- if (message == WM_INITDIALOG) {
- ofnPtr = (OPENFILENAME *) lParam;
- cdPtr = (ChooseDir *) ofnPtr->lCustData;
- cdPtr->lastCtrl = 0;
- cdPtr->lastIdx = 1000;
- cdPtr->path[0] = '\0';
-#ifdef _WIN64
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) cdPtr);
-#else
- SetWindowLong(hwnd, GWL_USERDATA, (LONG) cdPtr);
-#endif
+ if (Tcl_TranslateFileName(chooseDirSharedData->interp,
+ (char *) lParam, &initDirString) == NULL) {
+ /*
+ * Should we expose the error (in the interp result) to the user
+ * at this point?
+ */
- if (ofnPtr->lpstrInitialDir == NULL) {
- GetCurrentDirectory(MAX_PATH, cdPtr->path);
- } else {
- lstrcpy(cdPtr->path, ofnPtr->lpstrInitialDir);
- }
- SetDlgItemText(hwnd, edt10, cdPtr->path);
- SendDlgItemMessage(hwnd, edt10, EM_SETSEL, 0, -1);
- if (tsdPtr->debugFlag) {
- tsdPtr->debugInterp = cdPtr->interp;
- Tcl_DoWhenIdle(SetTkDialog, (ClientData) hwnd);
+ chooseDirSharedData->utfRetDir[0] = '\0';
+ return 1;
}
- return 0;
- }
-
- /*
- * GWL_USERDATA keeps track of cdPtr.
- */
-
-#ifdef _WIN64
- cdPtr = (ChooseDir *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
-#else
- cdPtr = (ChooseDir *) GetWindowLong(hwnd, GWL_USERDATA);
-#endif
- if (cdPtr == NULL) {
- return 0;
- }
- ofnPtr = cdPtr->ofnPtr;
+ lstrcpyn(string, Tcl_DStringValue(&initDirString), MAX_PATH);
+ Tcl_DStringFree(&initDirString);
- if (message == tsdPtr->WM_LBSELCHANGED) {
- /*
- * Called when double-clicking on directory.
- * If directory wasn't already open, browse that directory.
- * If directory was already open, return selected directory.
- */
+ if (SetCurrentDirectory((char *)string) == 0) {
+ LPTSTR lpFilePart[MAX_PATH];
- int idCtrl, thisItem;
+ /*
+ * 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.
+ */
- idCtrl = (int) wParam;
- thisItem = LOWORD(lParam);
+ GetFullPathName(string, MAX_PATH,
+ chooseDirSharedData->utfRetDir, /*unused*/ lpFilePart);
+ if (chooseDirSharedData->mustExist) {
+ /*
+ * User HAS to select a valid directory.
+ */
- GetCurrentDirectory(MAX_PATH, cdPtr->path);
- if (idCtrl == lst2) {
- if (cdPtr->lastIdx == thisItem) {
- EndDialog(hwnd, IDOK);
+ wsprintf(selDir, TEXT("Directory '%.200s' does not exist,\nplease select or enter an existing directory."), chooseDirSharedData->utfRetDir);
+ MessageBox(NULL, selDir, NULL, MB_ICONEXCLAMATION|MB_OK);
+ chooseDirSharedData->utfRetDir[0] = '\0';
return 1;
}
- cdPtr->lastIdx = thisItem;
- }
- SetDlgItemText(hwnd, edt10, cdPtr->path);
- SendDlgItemMessage(hwnd, edt10, EM_SETSEL, 0, -1);
- } else if (message == WM_COMMAND) {
- int idCtrl, notifyCode;
-
- idCtrl = LOWORD(wParam);
- notifyCode = HIWORD(wParam);
-
- if ((idCtrl != IDOK) || (notifyCode != BN_CLICKED)) {
+ } else {
/*
- * OK Button wasn't clicked. Do the default.
+ * Changed to new folder OK, return immediatly with the current
+ * directory in utfRetDir.
*/
- if ((idCtrl == lst2) || (idCtrl == edt10)) {
- cdPtr->lastCtrl = idCtrl;
- }
+ GetCurrentDirectory(MAX_PATH, chooseDirSharedData->utfRetDir);
return 0;
}
+ return 0;
+ case BFFM_SELCHANGED:
/*
- * Dialogs also get the message that OK was clicked when Enter
- * is pressed in some other control. Find out what window
- * we were really in when we got the supposed "OK", because the
- * behavior is different.
+ * 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 (cdPtr->lastCtrl == edt10) {
- /*
- * Hit Enter or clicked OK while typing a directory name in the
- * edit control.
- * If it's a new name, try to go to that directory.
- * If the name hasn't changed since last time, return selected
- * directory.
- */
-
- int changed;
- TCHAR tmp[MAX_PATH];
-
- if (GetDlgItemText(hwnd, edt10, tmp, MAX_PATH) == 0) {
- return 0;
- }
-
- changed = lstrcmp(cdPtr->path, tmp);
- lstrcpy(cdPtr->path, tmp);
-
- if (SetCurrentDirectory(cdPtr->path) == 0) {
- /*
- * Non-existent directory.
- */
-
- if (ofnPtr->Flags & OFN_PATHMUSTEXIST) {
- /*
- * Directory must exist. Complain, then rehighlight text.
- */
-
- wsprintf(tmp, _T("Cannot change directory to \"%.200s\"."),
- cdPtr->path);
- MessageBox(hwnd, tmp, NULL, MB_OK);
- SendDlgItemMessage(hwnd, edt10, EM_SETSEL, 0, -1);
- return 0;
- }
- if (changed) {
- /*
- * Directory was invalid, but we want to keep displaying
- * this name. Don't update the listbox that displays the
- * current directory heirarchy, or it'll erase the name.
- */
-
- SendDlgItemMessage(hwnd, edt10, EM_SETSEL, 0, -1);
- return 0;
- }
- }
- if (changed == 0) {
- /*
- * Name hasn't changed since the last time we hit return
- * or double-clicked on a directory, so return this.
- */
+ 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;
- EndDialog(hwnd, IDOK);
- return 1;
- }
-
- cdPtr->lastCtrl = IDOK;
+ case BFFM_INITIALIZED: {
+ /*
+ * Directory browser intializing - tell it where to start from, user
+ * specified parameter.
+ */
- /*
- * The following is the magic code, determined by running
- * Spy++ on some other directory chooser, that it takes to
- * get this dialog to update the listbox to display the
- * current directory.
- */
+ char *initDir = chooseDirSharedData->utfInitDir;
- SetDlgItemText(hwnd, edt1, cdPtr->path);
- SendMessage(hwnd, WM_COMMAND, (WPARAM) MAKELONG(cmb2, 0x8003),
- (LPARAM) GetDlgItem(hwnd, cmb2));
- return 0;
- } else if (idCtrl == lst2) {
+ SetCurrentDirectory(initDir);
+ if (*initDir == '\\') {
/*
- * Enter key was pressed while in listbox.
- * If it's a new directory, allow default behavior to open dir.
- * If the directory hasn't changed, return selected directory.
+ * BFFM_SETSELECTION only understands UNC paths as pidls, so
+ * convert path to pidl using IShellFolder interface.
*/
- int thisItem;
-
- thisItem = (int) SendDlgItemMessage(hwnd, lst2, LB_GETCURSEL, 0, 0);
- if (cdPtr->lastIdx == thisItem) {
- GetCurrentDirectory(MAX_PATH, cdPtr->path);
- EndDialog(hwnd, IDOK);
- return 1;
+ LPMALLOC pMalloc;
+ LPSHELLFOLDER psfFolder;
+
+ if (SUCCEEDED(SHGetMalloc(&pMalloc))) {
+ if (SUCCEEDED(SHGetDesktopFolder(&psfFolder))) {
+ LPITEMIDLIST pidlMain;
+ ULONG ulCount, ulAttr;
+ Tcl_DString ds;
+
+ Tcl_UtfToExternalDString(TkWinGetUnicodeEncoding(),
+ initDir, -1, &ds);
+ if (SUCCEEDED(psfFolder->lpVtbl->ParseDisplayName(
+ psfFolder, hwnd, NULL, (WCHAR *)
+ Tcl_DStringValue(&ds), &ulCount,&pidlMain,&ulAttr))
+ && (pidlMain != NULL)) {
+ SendMessage(hwnd, BFFM_SETSELECTION, FALSE,
+ (LPARAM) pidlMain);
+ pMalloc->lpVtbl->Free(pMalloc, pidlMain);
+ }
+ psfFolder->lpVtbl->Release(psfFolder);
+ Tcl_DStringFree(&ds);
+ }
+ pMalloc->lpVtbl->Release(pMalloc);
}
- } else if (idCtrl == IDOK) {
- /*
- * The OK button was clicked. Return the value currently selected
- * in the entry.
- */
-
- GetCurrentDirectory(MAX_PATH, cdPtr->path);
- EndDialog(hwnd, IDOK);
- return 1;
+ } else {
+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM) initDir);
}
+ SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1);
+ break;
+ }
+
}
return 0;
}
-#endif
/*
*----------------------------------------------------------------------
*
* Tk_MessageBoxObjCmd --
*
- * This procedure implements the MessageBox window for the
- * Windows platform. See the user documentation for details on what
- * it does.
+ * 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 procedure
+ * None. The MessageBox window will be destroy before this function
* returns.
*
*----------------------------------------------------------------------
*/
int
-Tk_MessageBoxObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+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, parent;
+ Tk_Window tkwin = (Tk_Window) clientData, parent;
HWND hWnd;
- char *message, *title;
+ Tcl_Obj *messageObj, *titleObj, *detailObj, *tmpObj;
int defaultBtn, icon, type;
int i, oldMode, winCode;
UINT flags;
- Tcl_DString messageString, titleString;
- Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding();
static CONST char *optionStrings[] = {
- "-default", "-icon", "-message", "-parent",
- "-title", "-type", NULL
+ "-default", "-detail", "-icon", "-message",
+ "-parent", "-title", "-type", NULL
};
enum options {
- MSG_DEFAULT, MSG_ICON, MSG_MESSAGE, MSG_PARENT,
- MSG_TITLE, MSG_TYPE
+ MSG_DEFAULT, MSG_DETAIL, MSG_ICON, MSG_MESSAGE,
+ MSG_PARENT, MSG_TITLE, MSG_TYPE
};
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- tkwin = (Tk_Window) clientData;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- defaultBtn = -1;
- icon = MB_ICONINFORMATION;
- message = NULL;
- parent = tkwin;
- title = NULL;
- type = MB_OK;
+ (void) TkWinGetUnicodeEncoding();
+ 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;
@@ -2563,22 +2316,25 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
if (i + 1 == objc) {
- string = Tcl_GetStringFromObj(optionPtr, NULL);
- Tcl_AppendResult(interp, "value for \"", string, "\" missing",
- (char *) NULL);
+ string = Tcl_GetString(optionPtr);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ NULL);
return TCL_ERROR;
}
- string = Tcl_GetStringFromObj(valuePtr, NULL);
switch ((enum options) index) {
- case MSG_DEFAULT:
- defaultBtn = TkFindStateNumObj(interp, optionPtr, buttonMap,
+ 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) {
@@ -2587,18 +2343,18 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv)
break;
case MSG_MESSAGE:
- message = string;
+ messageObj = valuePtr;
break;
- case MSG_PARENT:
- parent = Tk_NameToWindow(interp, string, tkwin);
+ case MSG_PARENT:
+ parent = Tk_NameToWindow(interp, Tcl_GetString(valuePtr), tkwin);
if (parent == NULL) {
return TCL_ERROR;
}
break;
case MSG_TITLE:
- title = string;
+ titleObj = valuePtr;
break;
case MSG_TYPE:
@@ -2607,19 +2363,20 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv)
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;
+ int defaultBtnIdx = -1;
- defaultBtnIdx = -1;
- for (i = 0; i < NUM_TYPES; i++) {
+ for (i = 0; i < (int) NUM_TYPES; i++) {
if (type == allowedTypes[i].type) {
int j;
@@ -2631,7 +2388,7 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv)
}
if (defaultBtnIdx < 0) {
Tcl_AppendResult(interp, "invalid default button \"",
- TkFindStateString(buttonMap, defaultBtn),
+ TkFindStateString(buttonMap, defaultBtn),
"\"", NULL);
return TCL_ERROR;
}
@@ -2641,82 +2398,140 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv)
flags = buttonFlagMap[defaultBtnIdx];
}
- flags |= icon | type | MB_SYSTEMMODAL;
+ flags |= icon | type | MB_TASKMODAL | MB_SETFOREGROUND;
- Tcl_UtfToExternalDString(unicodeEncoding, message, -1, &messageString);
- Tcl_UtfToExternalDString(unicodeEncoding, title, -1, &titleString);
+ tmpObj = messageObj ? Tcl_DuplicateObj(messageObj)
+ : Tcl_NewUnicodeObj(NULL, 0);
+ Tcl_IncrRefCount(tmpObj);
+ if (detailObj) {
+ Tcl_AppendUnicodeToObj(tmpObj, L"\n\n", 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.
+ * 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.
+ * 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());
- winCode = MessageBoxW(hWnd, (WCHAR *) Tcl_DStringValue(&messageString),
- (WCHAR *) Tcl_DStringValue(&titleString), flags);
+ winCode = MessageBoxW(hWnd, Tcl_GetUnicode(tmpObj),
+ titleObj ? Tcl_GetUnicode(titleObj) : L"", flags);
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).
+ * 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_DStringFree(&messageString);
- Tcl_DStringFree(&titleString);
+ Tcl_DecrRefCount(tmpObj);
Tcl_SetResult(interp, TkFindStateString(buttonMap, winCode), TCL_STATIC);
return TCL_OK;
}
-
+
static LRESULT CALLBACK
-MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam)
+MsgBoxCBTProc(
+ int nCode,
+ WPARAM wParam,
+ LPARAM lParam)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (nCode == HCBT_CREATEWND) {
/*
- * Window owned by our task is being created. Since the hook is
+ * 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.
+ * 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;
+
+ 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);
+ 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)
+static void
+SetTkDialog(
+ ClientData clientData)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
char buf[32];
sprintf(buf, "0x%p", (HWND) clientData);
Tcl_SetVar(tsdPtr->debugInterp, "tk_dialog", buf, TCL_GLOBAL_ONLY);
}
+
+/*
+ * Factored out a common pattern in use in this file.
+ */
+static char *
+ConvertExternalFilename(
+ Tcl_Encoding encoding,
+ char *filename,
+ Tcl_DString *dsPtr)
+{
+ char *p;
+
+ Tcl_ExternalToUtfDString(encoding, 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);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinDraw.c b/win/tkWinDraw.c
index d0a609f..366fc61 100644
--- a/win/tkWinDraw.c
+++ b/win/tkWinDraw.c
@@ -1,14 +1,14 @@
-/*
+/*
* tkWinDraw.c --
*
- * This file contains the Xlib emulation functions pertaining to
- * actually drawing objects on a window.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkWinInt.h"
@@ -44,9 +44,9 @@ int tkpWinRopModes[] = {
};
/*
- * 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
+ * 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.
*/
@@ -75,9 +75,9 @@ int tkpWinBltModes[] = {
};
/*
- * 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.
+ * 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) */
@@ -101,29 +101,27 @@ int tkpWinBltModes[] = {
* The followng typedef is used to pass Windows GDI drawing functions.
*/
-typedef BOOL (CALLBACK *WinDrawFunc) _ANSI_ARGS_((HDC dc,
- CONST POINT* points, int npoints));
+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. */
+ POINT *winPoints; /* Array of points that is reused. */
+ int nWinPoints; /* Current size of point array. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-static POINT * ConvertPoints _ANSI_ARGS_((XPoint *points, int npoints,
- int mode, RECT *bbox));
-static void DrawOrFillArc _ANSI_ARGS_((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 _ANSI_ARGS_((HDC dc, GC gc,
- XPoint* points, int npoints, int mode, HPEN pen,
- WinDrawFunc func));
-static HPEN SetUpGraphicsPort _ANSI_ARGS_((GC gc));
+static POINT * ConvertPoints(XPoint *points, int npoints, int mode,
+ RECT *bbox);
+static void 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);
/*
*----------------------------------------------------------------------
@@ -133,21 +131,21 @@ static HPEN SetUpGraphicsPort _ANSI_ARGS_((GC gc));
* Retrieve the DC from a drawable.
*
* Results:
- * Returns the window DC for windows. Returns a new memory DC
- * for pixmaps.
+ * 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.
+ * Sets up the palette for the device context, and saves the old device
+ * context state in the passed in TkWinDCState structure.
*
*----------------------------------------------------------------------
*/
HDC
-TkWinGetDrawableDC(display, d, state)
- Display *display;
- Drawable d;
- TkWinDCState* state;
+TkWinGetDrawableDC(
+ Display *display,
+ Drawable d,
+ TkWinDCState *state)
{
HDC dc;
TkWinDrawable *twdPtr = (TkWinDrawable *)d;
@@ -155,7 +153,7 @@ TkWinGetDrawableDC(display, d, state)
if (twdPtr->type == TWD_WINDOW) {
TkWindow *winPtr = twdPtr->window.winPtr;
-
+
dc = GetDC(twdPtr->window.handle);
if (winPtr == NULL) {
cmap = DefaultColormap(display, DefaultScreen(display));
@@ -192,12 +190,13 @@ TkWinGetDrawableDC(display, d, state)
*/
void
-TkWinReleaseDrawableDC(d, dc, state)
- Drawable d;
- HDC dc;
- TkWinDCState *state;
+TkWinReleaseDrawableDC(
+ Drawable d,
+ HDC dc,
+ TkWinDCState *state)
{
TkWinDrawable *twdPtr = (TkWinDrawable *)d;
+
SetBkMode(dc, state->bkmode);
SelectPalette(dc, state->palette, TRUE);
RealizePalette(dc);
@@ -219,26 +218,26 @@ TkWinReleaseDrawableDC(d, dc, state)
* Returns the converted array of POINTs.
*
* Side effects:
- * Allocates a block of memory in thread local storage that
- * should not be freed.
+ * Allocates a block of memory in thread local storage that should not be
+ * freed.
*
*----------------------------------------------------------------------
*/
static POINT *
-ConvertPoints(points, npoints, mode, bbox)
- XPoint *points;
- int npoints;
- int mode; /* CoordModeOrigin or CoordModePrevious. */
- RECT *bbox; /* Bounding box of points. */
+ConvertPoints(
+ XPoint *points,
+ int npoints,
+ int mode, /* CoordModeOrigin or CoordModePrevious. */
+ RECT *bbox) /* Bounding box of points. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ 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.
+ * 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) {
@@ -255,7 +254,7 @@ ConvertPoints(points, npoints, mode, bbox)
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;
@@ -292,21 +291,20 @@ ConvertPoints(points, npoints, mode, bbox)
* None.
*
* Side effects:
- * Data is moved from a window or bitmap to a second window or
- * bitmap.
+ * Data is moved from a window or bitmap to a second window or bitmap.
*
*----------------------------------------------------------------------
*/
void
-XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y)
- Display* display;
- Drawable src;
- Drawable dest;
- GC gc;
- int src_x, src_y;
- unsigned int width, height;
- int dest_x, dest_y;
+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;
@@ -325,8 +323,8 @@ XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y)
OffsetClipRgn(destDC, gc->clip_x_origin, gc->clip_y_origin);
}
- BitBlt(destDC, dest_x, dest_y, width, height, srcDC, src_x, src_y,
- tkpWinBltModes[gc->function]);
+ BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, srcDC,
+ src_x, src_y, (DWORD) tkpWinBltModes[gc->function]);
SelectClipRgn(destDC, NULL);
@@ -341,10 +339,9 @@ XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y)
*
* 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.
+ * 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.
@@ -356,16 +353,15 @@ XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y)
*/
void
-XCopyPlane(display, src, dest, gc, src_x, src_y, width, height, dest_x,
- dest_y, plane)
- Display* display;
- Drawable src;
- Drawable dest;
- GC gc;
- int src_x, src_y;
- unsigned int width, height;
- int dest_x, dest_y;
- unsigned long plane;
+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;
@@ -375,7 +371,7 @@ XCopyPlane(display, src, dest, gc, src_x, src_y, width, height, dest_x,
display->request++;
if (plane != 1) {
- panic("Unexpected plane specified for XCopyPlane");
+ Tcl_Panic("Unexpected plane specified for XCopyPlane");
}
srcDC = TkWinGetDrawableDC(display, src, &srcState);
@@ -387,12 +383,10 @@ XCopyPlane(display, src, dest, gc, src_x, src_y, width, height, dest_x,
}
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).
+ * 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) {
@@ -403,8 +397,8 @@ XCopyPlane(display, src, dest, gc, src_x, src_y, width, height, dest_x,
SetBkMode(destDC, OPAQUE);
SetBkColor(destDC, gc->foreground);
SetTextColor(destDC, gc->background);
- BitBlt(destDC, dest_x, dest_y, width, height, srcDC, src_x, src_y,
- SRCCOPY);
+ 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) {
@@ -412,25 +406,24 @@ XCopyPlane(display, src, dest, gc, src_x, src_y, width, height, dest_x,
/*
* Case 2: transparent bitmaps are handled by setting the
- * destination to the foreground color whenever the source
- * pixel is set. We need to reset the BkColor and TextColor,
- * because they affect bitmap color mapping.
+ * 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, width, height, srcDC, src_x, src_y,
- MASKPAT);
+ 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.
+ * 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;
@@ -442,36 +435,37 @@ XCopyPlane(display, src, dest, gc, src_x, src_y, width, height, dest_x,
maskDC = TkWinGetDrawableDC(display, clipPtr->value.pixmap,
&maskState);
memDC = CreateCompatibleDC(destDC);
- bitmap = CreateBitmap(width, height, 1, 1, NULL);
+ 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.
+ * 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, width, height, srcDC, src_x, src_y, SRCCOPY);
- BitBlt(memDC, 0, 0, width, height, maskDC,
+ 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, width, height, memDC, 0, 0,
- MASKPAT);
+ 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.
+ * Set background bits. Same as foreground, except we use ((NOT
+ * source) AND mask) and the background brush.
*/
- BitBlt(memDC, 0, 0, width, height, srcDC, src_x, src_y,
+ BitBlt(memDC, 0, 0, (int) width, (int) height, srcDC, src_x, src_y,
NOTSRCCOPY);
- BitBlt(memDC, 0, 0, width, height, maskDC,
+ 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, width, height, memDC, 0, 0,
- MASKPAT);
+ BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, memDC,
+ 0, 0, MASKPAT);
TkWinReleaseDrawableDC(clipPtr->value.pixmap, maskDC, &maskState);
SelectObject(destDC, oldBrush);
@@ -492,8 +486,8 @@ XCopyPlane(display, src, dest, gc, src_x, src_y, width, height, dest_x,
*
* TkPutImage --
*
- * Copies a subimage from an in-memory image to a rectangle of
- * of the specified drawable.
+ * Copies a subimage from an in-memory image to a rectangle of of the
+ * specified drawable.
*
* Results:
* None.
@@ -505,19 +499,18 @@ XCopyPlane(display, src, dest, gc, src_x, src_y, width, height, dest_x,
*/
void
-TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x,
- dest_y, width, height)
- 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, src_y; /* Offset of subimage. */
- int dest_x, dest_y; /* Position of subimage origin in
- * drawable. */
- unsigned int width, height; /* Dimensions of subimage. */
+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;
@@ -533,8 +526,8 @@ TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x,
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 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)
@@ -548,22 +541,22 @@ TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x,
}
SetTextColor(dc, gc->foreground);
SetBkColor(dc, gc->background);
- } else {
+ } else {
int i, usePalette;
/*
* Do not use a palette for TrueColor images.
*/
-
+
usePalette = (image->bits_per_pixel < 16);
-
+
if (usePalette) {
- infoPtr = (BITMAPINFO*) ckalloc(sizeof(BITMAPINFOHEADER)
+ infoPtr = (BITMAPINFO *) ckalloc(sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD)*ncolors);
} else {
- infoPtr = (BITMAPINFO*) ckalloc(sizeof(BITMAPINFOHEADER));
+ infoPtr = (BITMAPINFO *) ckalloc(sizeof(BITMAPINFOHEADER));
}
-
+
infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
infoPtr->bmiHeader.biWidth = image->width;
infoPtr->bmiHeader.biHeight = -image->height; /* Top-down order */
@@ -590,14 +583,15 @@ TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x,
image->data, infoPtr, DIB_RGB_COLORS);
ckfree((char *) infoPtr);
}
- if(!bitmap) {
- panic("Fail to allocate bitmap\n");
+ if (!bitmap) {
+ Tcl_Panic("Fail to allocate bitmap\n");
DeleteDC(dcMem);
TkWinReleaseDrawableDC(d, dc, &state);
return;
}
bitmap = SelectObject(dcMem, bitmap);
- BitBlt(dc, dest_x, dest_y, width, height, dcMem, src_x, src_y, SRCCOPY);
+ 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);
@@ -620,12 +614,12 @@ TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x,
*/
void
-XFillRectangles(display, d, gc, rectangles, nrectangles)
- Display* display;
- Drawable d;
- GC gc;
- XRectangle* rectangles;
- int nrectangles;
+XFillRectangles(
+ Display *display,
+ Drawable d,
+ GC gc,
+ XRectangle *rectangles,
+ int nrectangles)
{
HDC dc;
int i;
@@ -651,13 +645,13 @@ XFillRectangles(display, d, gc, rectangles, nrectangles)
HBRUSH bgBrush = CreateSolidBrush(gc->background);
if (twdPtr->type != TWD_BITMAP) {
- panic("unexpected drawable type in stipple");
+ 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);
@@ -665,7 +659,7 @@ XFillRectangles(display, d, gc, rectangles, nrectangles)
/*
* For each rectangle, create a drawing surface which is the size of
- * the rectangle and fill it with the background color. Then merge the
+ * the rectangle and fill it with the background color. Then merge the
* result with the stipple pattern.
*/
@@ -689,7 +683,7 @@ XFillRectangles(display, d, gc, rectangles, nrectangles)
SelectObject(dcMem, oldBitmap);
DeleteObject(bitmap);
}
-
+
DeleteDC(dcMem);
SelectObject(dc, oldBrush);
DeleteObject(stipple);
@@ -707,7 +701,7 @@ XFillRectangles(display, d, gc, rectangles, nrectangles)
HPEN newPen = CreatePen(PS_NULL, 0, gc->foreground);
HPEN oldPen = SelectObject(dc, newPen);
oldBrush = SelectObject(dc, brush);
-
+
for (i = 0; i < nrectangles; i++) {
Rectangle(dc, rectangles[i].x, rectangles[i].y,
rectangles[i].x + rectangles[i].width + 1,
@@ -728,8 +722,8 @@ XFillRectangles(display, d, gc, rectangles, nrectangles)
*
* RenderObject --
*
- * This function draws a shape using a list of points, a
- * stipple pattern, and the specified drawing function.
+ * This function draws a shape using a list of points, a stipple pattern,
+ * and the specified drawing function.
*
* Results:
* None.
@@ -741,20 +735,20 @@ XFillRectangles(display, d, gc, rectangles, nrectangles)
*/
static void
-RenderObject(dc, gc, points, npoints, mode, pen, func)
- HDC dc;
- GC gc;
- XPoint* points;
- int npoints;
- int mode;
- HPEN pen;
- WinDrawFunc func;
+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) {
@@ -765,9 +759,9 @@ RenderObject(dc, gc, points, npoints, mode, pen, func)
HBITMAP oldBitmap;
int i;
HBRUSH oldMemBrush;
-
+
if (twdPtr->type != TWD_BITMAP) {
- panic("unexpected drawable type in stipple");
+ Tcl_Panic("unexpected drawable type in stipple");
}
/*
@@ -785,7 +779,7 @@ RenderObject(dc, gc, points, npoints, mode, pen, func)
/*
* Select stipple pattern into destination dc.
*/
-
+
SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL);
oldBrush = SelectObject(dc, CreatePatternBrush(twdPtr->bitmap.handle));
@@ -793,7 +787,7 @@ RenderObject(dc, gc, points, npoints, mode, pen, func)
* 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));
@@ -802,7 +796,7 @@ RenderObject(dc, gc, points, npoints, mode, pen, func)
/*
* Translate the object for rendering in the temporary drawing
- * surface.
+ * surface.
*/
for (i = 0; i < npoints; i++) {
@@ -823,8 +817,8 @@ RenderObject(dc, gc, points, npoints, mode, pen, func)
/*
* 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.
+ * background color and copy it to the destination wherever the
+ * pattern is clear.
*/
if (gc->fill_style == FillOpaqueStippled) {
@@ -871,18 +865,18 @@ RenderObject(dc, gc, points, npoints, mode, pen, func)
*/
void
-XDrawLines(display, d, gc, points, npoints, mode)
- Display* display;
- Drawable d;
- GC gc;
- XPoint* points;
- int npoints;
- int mode;
+XDrawLines(
+ Display *display,
+ Drawable d,
+ GC gc,
+ XPoint *points,
+ int npoints,
+ int mode)
{
HPEN pen;
TkWinDCState state;
HDC dc;
-
+
if (d == None) {
return;
}
@@ -893,7 +887,7 @@ XDrawLines(display, d, gc, points, npoints, mode)
SetBkMode(dc, TRANSPARENT);
RenderObject(dc, gc, points, npoints, mode, pen, Polyline);
DeleteObject(pen);
-
+
TkWinReleaseDrawableDC(d, dc, &state);
}
@@ -914,14 +908,14 @@ XDrawLines(display, d, gc, points, npoints, mode)
*/
void
-XFillPolygon(display, d, gc, points, npoints, shape, mode)
- Display* display;
- Drawable d;
- GC gc;
- XPoint* points;
- int npoints;
- int shape;
- int mode;
+XFillPolygon(
+ Display *display,
+ Drawable d,
+ GC gc,
+ XPoint *points,
+ int npoints,
+ int shape,
+ int mode)
{
HPEN pen;
TkWinDCState state;
@@ -956,14 +950,12 @@ XFillPolygon(display, d, gc, points, npoints, shape, mode)
*/
void
-XDrawRectangle(display, d, gc, x, y, width, height)
- Display* display;
- Drawable d;
- GC gc;
- int x;
- int y;
- unsigned int width;
- unsigned int height;
+XDrawRectangle(
+ Display *display,
+ Drawable d,
+ GC gc,
+ int x, int y,
+ unsigned int width, unsigned int height)
{
HPEN pen, oldPen;
TkWinDCState state;
@@ -982,7 +974,7 @@ XDrawRectangle(display, d, gc, x, y, width, height)
oldBrush = SelectObject(dc, GetStockObject(NULL_BRUSH));
SetROP2(dc, tkpWinRopModes[gc->function]);
- Rectangle(dc, x, y, x+width+1, y+height+1);
+ Rectangle(dc, x, y, (int) x+width+1, (int) y+height+1);
DeleteObject(SelectObject(dc, oldPen));
SelectObject(dc, oldBrush);
@@ -1006,16 +998,13 @@ XDrawRectangle(display, d, gc, x, y, width, height)
*/
void
-XDrawArc(display, d, gc, x, y, width, height, start, extent)
- Display* display;
- Drawable d;
- GC gc;
- int x;
- int y;
- unsigned int width;
- unsigned int height;
- int start;
- int extent;
+XDrawArc(
+ Display *display,
+ Drawable d,
+ GC gc,
+ int x, int y,
+ unsigned int width, unsigned int height,
+ int start, int extent)
{
display->request++;
@@ -1039,16 +1028,13 @@ XDrawArc(display, d, gc, x, y, width, height, start, extent)
*/
void
-XFillArc(display, d, gc, x, y, width, height, start, extent)
- Display* display;
- Drawable d;
- GC gc;
- int x;
- int y;
- unsigned int width;
- unsigned int height;
- int start;
- int extent;
+XFillArc(
+ Display *display,
+ Drawable d,
+ GC gc,
+ int x, int y,
+ unsigned int width, unsigned int height,
+ int start, int extent)
{
display->request++;
@@ -1060,8 +1046,8 @@ XFillArc(display, d, gc, x, y, width, height, start, extent)
*
* DrawOrFillArc --
*
- * This procedure handles the rendering of drawn or filled
- * arcs and chords.
+ * This function handles the rendering of drawn or filled arcs and
+ * chords.
*
* Results:
* None.
@@ -1073,15 +1059,15 @@ XFillArc(display, d, gc, x, y, width, height, start, extent)
*/
static void
-DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, fill)
- Display *display;
- Drawable d;
- GC gc;
- int x, y; /* left top */
- unsigned int width, height;
- int start; /* start: three-o'clock (deg*64) */
- int extent; /* extent: relative (deg*64) */
- int fill; /* ==0 draw, !=0 fill */
+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;
@@ -1122,7 +1108,7 @@ DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, fill)
/*
* Now compute points on the radial lines that define the starting and
- * ending angles. Be sure to take into account that the y-coordinate
+ * ending angles. Be sure to take into account that the y-coordinate
* system is inverted.
*/
@@ -1134,29 +1120,32 @@ DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, fill)
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.
+ * 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.
+ * 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, x+width+1, y+height+1, xstart, ystart, xend, yend);
+ 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, x+width+1, y+height+1, xstart, ystart, xend, yend);
- } else if ( gc->arc_mode == ArcPieSlice ) {
- Pie(dc, x, y, x+width+1, y+height+1, xstart, ystart, xend, yend);
+ 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));
}
@@ -1181,8 +1170,8 @@ DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, fill)
*/
static HPEN
-SetUpGraphicsPort(gc)
- GC gc;
+SetUpGraphicsPort(
+ GC gc)
{
DWORD style;
@@ -1191,10 +1180,9 @@ SetUpGraphicsPort(gc)
/* 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>
+ * 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]) {
@@ -1214,7 +1202,7 @@ SetUpGraphicsPort(gc)
style = PS_SOLID;
}
if (gc->line_width < 2) {
- return CreatePen(style, gc->line_width, gc->foreground);
+ return CreatePen((int) style, gc->line_width, gc->foreground);
} else {
LOGBRUSH lb;
@@ -1224,29 +1212,29 @@ SetUpGraphicsPort(gc)
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;
+ 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;
+ case JoinMiter:
+ style |= PS_JOIN_MITER;
+ break;
+ case JoinRound:
+ style |= PS_JOIN_ROUND;
+ break;
+ default:
+ style |= PS_JOIN_BEVEL;
+ break;
}
- return ExtCreatePen(style, gc->line_width, &lb, 0, NULL);
+ return ExtCreatePen(style, (DWORD) gc->line_width, &lb, 0, NULL);
}
}
@@ -1255,13 +1243,13 @@ SetUpGraphicsPort(gc)
*
* TkScrollWindow --
*
- * Scroll a rectangle of the specified window and accumulate
- * a damage region.
+ * 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.
+ * 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.
@@ -1270,12 +1258,13 @@ SetUpGraphicsPort(gc)
*/
int
-TkScrollWindow(tkwin, gc, x, y, width, height, dx, dy, damageRgn)
- Tk_Window tkwin; /* The window to be scrolled. */
- GC gc; /* GC for window to be scrolled. */
- int x, y, width, height; /* Position rectangle to be scrolled. */
- int dx, dy; /* Distance rectangle should be moved. */
- TkRegion damageRgn; /* Region to accumulate damage in. */
+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;
@@ -1293,9 +1282,9 @@ TkScrollWindow(tkwin, gc, x, y, width, height, dx, dy, damageRgn)
*
* 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.
+ * 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.
@@ -1307,10 +1296,10 @@ TkScrollWindow(tkwin, gc, x, y, width, height, dx, dy, damageRgn)
*/
void
-TkWinFillRect(dc, x, y, width, height, pixel)
- HDC dc;
- int x, y, width, height;
- int pixel;
+TkWinFillRect(
+ HDC dc,
+ int x, int y, int width, int height,
+ int pixel)
{
RECT rect;
COLORREF oldColor;
@@ -1330,30 +1319,30 @@ TkWinFillRect(dc, x, y, width, height, pixel)
*
* TkpDrawHighlightBorder --
*
- * This procedure draws a rectangular ring around the outside of
- * a widget to indicate that it has received the input focus.
+ * 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.
+ * 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".
+ * A rectangle "width" pixels wide is drawn in "drawable", corresponding
+ * to the outer area of "tkwin".
*
*----------------------------------------------------------------------
*/
-void
-TkpDrawHighlightBorder(tkwin, fgGC, bgGC, highlightWidth, drawable)
- Tk_Window tkwin;
- GC fgGC;
- GC bgGC;
- int highlightWidth;
- Drawable drawable;
+void
+TkpDrawHighlightBorder(
+ Tk_Window tkwin,
+ GC fgGC,
+ GC bgGC,
+ int highlightWidth,
+ Drawable drawable)
{
TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}
@@ -1363,7 +1352,7 @@ TkpDrawHighlightBorder(tkwin, fgGC, bgGC, highlightWidth, drawable)
*
* TkpDrawFrame --
*
- * This procedure draws the rectangular frame area.
+ * This function draws the rectangular frame area.
*
* Results:
* None.
@@ -1375,12 +1364,22 @@ TkpDrawHighlightBorder(tkwin, fgGC, bgGC, highlightWidth, drawable)
*/
void
-TkpDrawFrame (Tk_Window tkwin, Tk_3DBorder border,
- int highlightWidth, int borderWidth, int relief)
+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);
+ 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/win/tkWinEmbed.c b/win/tkWinEmbed.c
index d0e0c05..bc86019 100644
--- a/win/tkWinEmbed.c
+++ b/win/tkWinEmbed.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkWinEmbed.c --
*
* This file contains platform specific procedures for Windows platforms
@@ -8,54 +8,51 @@
*
* 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.
+ * 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.
+ * 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. */
- struct Container *nextPtr; /* Next in list of all containers in
- * this process. */
+ 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. */
+ Container *firstContainerPtr;
+ /* First in list of all containers managed by
+ * this process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
-static void CleanupContainerList _ANSI_ARGS_((
- ClientData clientData));
-static void ContainerEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void EmbeddedEventProc _ANSI_ARGS_((
- ClientData clientData, XEvent *eventPtr));
-static void EmbedGeometryRequest _ANSI_ARGS_((
- Container*containerPtr, int width, int height));
-static void EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr));
+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);
/*
*----------------------------------------------------------------------
*
- * CleanupContainerList --
+ * TkWinCleanupContainerList --
*
* Finalizes the list of containers.
*
@@ -68,20 +65,17 @@ static void EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr));
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
-static void
-CleanupContainerList(clientData)
- ClientData clientData;
+void
+TkWinCleanupContainerList(void)
{
Container *nextPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- for (;
- tsdPtr->firstContainerPtr != (Container *) NULL;
- tsdPtr->firstContainerPtr = nextPtr) {
- nextPtr = tsdPtr->firstContainerPtr->nextPtr;
- ckfree((char *) tsdPtr->firstContainerPtr);
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ for (; tsdPtr->firstContainerPtr != (Container *) NULL;
+ tsdPtr->firstContainerPtr = nextPtr) {
+ nextPtr = tsdPtr->firstContainerPtr->nextPtr;
+ ckfree((char *) tsdPtr->firstContainerPtr);
}
tsdPtr->firstContainerPtr = (Container *) NULL;
}
@@ -104,11 +98,11 @@ CleanupContainerList(clientData)
/* ARGSUSED */
int
-TkpTestembedCmd(clientData, interp, argc, argv)
- ClientData clientData;
- Tcl_Interp *interp;
- int argc;
- CONST char **argv;
+TkpTestembedCmd(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int argc,
+ CONST char **argv)
{
return TCL_OK;
}
@@ -116,19 +110,113 @@ TkpTestembedCmd(clientData, interp, argc, argv)
/*
*----------------------------------------------------------------------
*
+ * 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 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),
- * the return value is TCL_ERROR and an error message is left in the
- * the interp's result if interp is not NULL.
+ * 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.
@@ -136,31 +224,45 @@ TkpTestembedCmd(clientData, interp, argc, argv)
*----------------------------------------------------------------------
*/
-int
-TkpUseWindow(interp, tkwin, string)
- 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
+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. */
+ CONST char *string) /* String identifying an X window to use for
+ * tkwin; must be an integer value. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
- TkWindow *usePtr;
int id;
HWND hwnd;
- Container *containerPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+/*
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+*/
+/*
if (winPtr->window != None) {
- panic("TkpUseWindow: Already assigned a window");
+ Tcl_AppendResult(interp,
+ "can't modify container after widget is created", NULL);
+ return TCL_ERROR;
+ }
+*/
+
+ if (strcmp(string, "") == 0) {
+ if (winPtr->flags & TK_EMBEDDED) {
+ Tk_DetachEmbeddedWindow(winPtr, TRUE);
+ }
+ return TCL_OK;
}
if (Tcl_GetInt(interp, string, &id) != TCL_OK) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
hwnd = (HWND) id;
+ if ((HWND)winPtr->privatePtr == hwnd) {
+ return TCL_OK;
+ }
/*
* Check if the window is a valid handle. If it is invalid, return
@@ -169,81 +271,58 @@ TkpUseWindow(interp, tkwin, string)
*/
if (!IsWindow(hwnd)) {
- if (interp != (Tcl_Interp *) NULL) {
- Tcl_AppendResult(interp, "window \"", string,
- "\" doesn't exist", (char *) NULL);
- }
- return TCL_ERROR;
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "window \"", string,
+ "\" doesn't exist", NULL);
+ }
+ return TCL_ERROR;
}
- usePtr = (TkWindow *) Tk_HWNDToWindow(hwnd);
- if (usePtr != NULL) {
- if (!(usePtr->flags & TK_CONTAINER)) {
- Tcl_AppendResult(interp, "window \"", usePtr->pathName,
- "\" doesn't have -container option set", (char *) NULL);
+ id = SendMessage(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0);
+ if (id == (long)hwnd) {
+ if (!SendMessage(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
+ Tcl_AppendResult(interp, "The container is already in use", NULL);
+ return TCL_ERROR;
+ }
+ } else if (id == -(long)hwnd) {
+ Tcl_AppendResult(interp, "the window to use is not a Tk 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 == MessageBox(hwnd, msg, "Tk Warning",
+ MB_OKCANCEL | MB_ICONWARNING)) {
+ Tcl_SetResult(interp, "Operation has been canceled", TCL_STATIC);
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);
/*
- * Create an event handler to clean up the Container structure when
- * tkwin is eventually deleted.
- */
-
- Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,
- (ClientData) winPtr);
-
- /*
- * If this is the first container, register an exit handler so that
- * things will get cleaned up at finalization.
- */
-
- if (tsdPtr->firstContainerPtr == (Container *) NULL) {
- TkCreateExitHandler(CleanupContainerList, (ClientData) NULL);
- }
-
- /*
- * Save information about the container and the embedded window
- * in a Container structure. If there is already an existing
- * Container structure, it means that both container and embedded
- * app. are in the same process.
+ * Preserve the winPtr and create an idle handler to map the embedded
+ * window.
*/
- for (containerPtr = tsdPtr->firstContainerPtr;
- containerPtr != NULL; containerPtr = containerPtr->nextPtr) {
- if (containerPtr->parentHWnd == hwnd) {
- winPtr->flags |= TK_BOTH_HALVES;
- containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
- break;
- }
- }
- if (containerPtr == NULL) {
- containerPtr = (Container *) ckalloc(sizeof(Container));
- containerPtr->parentPtr = NULL;
- containerPtr->parentHWnd = hwnd;
- containerPtr->nextPtr = tsdPtr->firstContainerPtr;
- tsdPtr->firstContainerPtr = containerPtr;
- }
-
- /*
- * embeddedHWnd is not created yet. It will be created by TkWmMapWindow(),
- * which will send a TK_ATTACHWINDOW to the container window.
- * TkWinEmbeddedEventProc will process this message and set the embeddedHWnd
- * variable
- */
-
- containerPtr->embeddedPtr = winPtr;
- containerPtr->embeddedHWnd = NULL;
-
- winPtr->flags |= TK_EMBEDDED;
- winPtr->flags &= (~(TK_MAPPED));
+ Tcl_Preserve((ClientData) winPtr);
+ Tcl_DoWhenIdle((Tcl_IdleProc*) Tk_MapEmbeddedWindow, (ClientData) winPtr);
return TCL_OK;
}
@@ -253,10 +332,10 @@ TkpUseWindow(interp, tkwin, string)
*
* 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.
+ * 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.
@@ -268,26 +347,17 @@ TkpUseWindow(interp, tkwin, string)
*/
void
-TkpMakeContainer(tkwin)
- Tk_Window tkwin;
+TkpMakeContainer(
+ Tk_Window tkwin)
{
TkWindow *winPtr = (TkWindow *) tkwin;
Container *containerPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * If this is the first container, register an exit handler so that
- * things will get cleaned up at finalization.
- */
-
- if (tsdPtr->firstContainerPtr == (Container *) NULL) {
- TkCreateExitHandler(CleanupContainerList, (ClientData) NULL);
- }
-
- /*
- * Register the window as a container so that, for example, we can
- * find out later if the embedded app. is in the same process.
+ * 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);
@@ -296,54 +366,23 @@ TkpMakeContainer(tkwin)
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.
+ * 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);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * EmbeddedEventProc --
- *
- * This procedure is invoked by the Tk event dispatcher when various
- * useful events are received for a window that is embedded in
- * another application.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Our internal state gets cleaned up when an embedded window is
- * destroyed.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-EmbeddedEventProc(clientData, eventPtr)
- ClientData clientData; /* Token for container window. */
- XEvent *eventPtr; /* ResizeRequest event. */
-{
- TkWindow *winPtr = (TkWindow *) clientData;
-
- if (eventPtr->type == DestroyNotify) {
- EmbedWindowDeleted(winPtr);
- }
+ ContainerEventProc, (ClientData) containerPtr);
}
/*
@@ -351,32 +390,32 @@ EmbeddedEventProc(clientData, eventPtr)
*
* 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.
+ * 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.
+ * Depends on the event. For example, when ConfigureRequest events occur,
+ * geometry information gets set for the container window.
*
*----------------------------------------------------------------------
*/
LRESULT
-TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
+TkWinEmbeddedEventProc(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
+ int result = 1;
Container *containerPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
* Find the Container structure associated with the parent window.
@@ -388,29 +427,345 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)
/* empty loop body */
}
- if (containerPtr == NULL) {
- Tcl_Panic("TkWinContainerProc couldn't find Container record");
- }
+ 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 (message) {
- 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.
- */
- if (containerPtr->embeddedHWnd == NULL) {
- containerPtr->embeddedHWnd = (HWND)wParam;
- } else {
- return 0;
+ switch(wParam) {
+ case TK_CONTAINER_ISAVAILABLE:
+ result = containerPtr->embeddedHWnd == NULL? 1:0;
+ break;
+ case TK_CONTAINER_VERIFY:
+ result = (long)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 = (long)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 = (long)GetParent(containerPtr->parentHWnd);
+ } else {
+ topwinPtr = containerPtr->parentPtr;
+ while (!(topwinPtr->flags & TK_TOP_HIERARCHY)) {
+ topwinPtr = topwinPtr->parentPtr;
+ }
+ if (topwinPtr && topwinPtr->window) {
+ result = (long)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
+ */
- break;
- case TK_GEOMETRYREQ:
- EmbedGeometryRequest(containerPtr, (int) wParam, lParam);
- break;
+ return -(long)hwnd;
+ } else {
+ result = 0;
+ }
}
- return 1;
+
+ return result;
}
/*
@@ -418,39 +773,40 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)
*
* 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.
+ * 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.
+ * 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(containerPtr, width, height)
- Container *containerPtr; /* Information about the container window. */
- int width, height; /* Size that the child has requested. */
+EmbedGeometryRequest(
+ Container *containerPtr, /* Information about the container window. */
+ int width, int height) /* Size that the child has requested. */
{
- TkWindow * winPtr = containerPtr->parentPtr;
-
+ 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.
+ * 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) {
@@ -458,8 +814,8 @@ EmbedGeometryRequest(containerPtr, width, height)
/* Empty loop body. */
}
- SetWindowPos(containerPtr->embeddedHWnd, NULL,
- 0, 0, winPtr->changes.width, winPtr->changes.height, SWP_NOZORDER);
+ SetWindowPos(containerPtr->embeddedHWnd, NULL, 0, 0,
+ winPtr->changes.width, winPtr->changes.height, SWP_NOZORDER);
}
}
@@ -468,38 +824,41 @@ EmbedGeometryRequest(containerPtr, width, height)
*
* ContainerEventProc --
*
- * This procedure is invoked by the Tk event dispatcher when
- * various useful events are received for the container window.
+ * 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.
+ * Depends on the event. For example, when ConfigureRequest events occur,
+ * geometry information gets set for the container window.
*
*----------------------------------------------------------------------
*/
static void
-ContainerEventProc(clientData, eventPtr)
- ClientData clientData; /* Token for container window. */
- XEvent *eventPtr; /* ResizeRequest event. */
+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) {
- if (containerPtr->embeddedPtr == NULL) {
- return;
- }
- /* Resize the embedded window, if there is any */
+ /*
+ * 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);
+ 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 */
+ /*
+ * The container is gone, remove it from the list.
+ */
+
EmbedWindowDeleted(containerPtr->parentPtr);
}
}
@@ -509,13 +868,13 @@ ContainerEventProc(clientData, eventPtr)
*
* TkpGetOtherWindow --
*
- * If both the container and embedded window are in the same
- * process, this procedure will return either one, given the other.
+ * 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.
+ * embedded window, and vice versa. If the "other" window isn't in this
+ * process, NULL is returned.
*
* Side effects:
* None.
@@ -524,13 +883,13 @@ ContainerEventProc(clientData, eventPtr)
*/
TkWindow *
-TkpGetOtherWindow(winPtr)
- TkWindow *winPtr; /* Tk's structure for a container or
- * embedded window. */
+TkpGetOtherWindow(
+ TkWindow *winPtr) /* Tk's structure for a container or embedded
+ * window. */
{
Container *containerPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
containerPtr = containerPtr->nextPtr) {
@@ -546,12 +905,81 @@ TkpGetOtherWindow(winPtr)
/*
*----------------------------------------------------------------------
*
+ * 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.
+ * 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.
@@ -563,12 +991,12 @@ TkpGetOtherWindow(winPtr)
*/
void
-TkpClaimFocus(topLevelPtr, force)
- 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. */
+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);
@@ -579,13 +1007,13 @@ TkpClaimFocus(topLevelPtr, force)
*
* 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.
+ * 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.
@@ -597,11 +1025,11 @@ TkpClaimFocus(topLevelPtr, force)
*/
void
-TkpRedirectKeyEvent(winPtr, eventPtr)
- TkWindow *winPtr; /* Window to which the event was originally
+TkpRedirectKeyEvent(
+ TkWindow *winPtr, /* Window to which the event was originally
* reported. */
- XEvent *eventPtr; /* X event to redirect (should be KeyPress
- * or KeyRelease). */
+ XEvent *eventPtr) /* X event to redirect (should be KeyPress or
+ * KeyRelease). */
{
/* not implemented */
}
@@ -611,9 +1039,9 @@ TkpRedirectKeyEvent(winPtr, eventPtr)
*
* 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.
+ * 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.
@@ -625,19 +1053,18 @@ TkpRedirectKeyEvent(winPtr, eventPtr)
*/
static void
-EmbedWindowDeleted(winPtr)
- TkWindow *winPtr; /* Tk's information about window that
- * was deleted. */
+EmbedWindowDeleted(
+ TkWindow *winPtr) /* Tk's information about window that was
+ * deleted. */
{
Container *containerPtr, *prevPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * Find the Container structure for this window work. Delete the
+ * 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]
+ * record. The main container may be null. [Bug #476176]
*/
prevPtr = NULL;
@@ -650,13 +1077,15 @@ EmbedWindowDeleted(winPtr)
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) {
- panic("EmbedWindowDeleted couldn't find window");
+ return;
}
}
if ((containerPtr->embeddedPtr == NULL)
@@ -669,3 +1098,11 @@ EmbedWindowDeleted(winPtr)
ckfree((char *) containerPtr);
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinFont.c b/win/tkWinFont.c
index 6fc184d..f209716 100644
--- a/win/tkWinFont.c
+++ b/win/tkWinFont.c
@@ -1,27 +1,27 @@
-/*
+/*
* tkWinFont.c --
*
- * Contains the Windows implementation of the platform-independant
- * font package interface.
+ * Contains the Windows implementation of the platform-independant font
+ * package interface.
*
- * Copyright (c) 1994 Software Research Associates, Inc.
+ * 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.
+ * 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.
+ * 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.
*/
@@ -34,69 +34,69 @@
typedef struct FontFamily {
struct FontFamily *nextPtr; /* Next in list of all known font families. */
int refCount; /* How many SubFonts are referring to this
- * FontFamily. When the refCount drops to
+ * 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
+ int isWideFont; /* 1 if this is a double-byte font, 0
* otherwise. */
BOOL (WINAPI *textOutProc)(HDC, int, int, TCHAR *, int);
- /* The procedure to use to draw text after
- * it has been converted from UTF-8 to the
+ /* 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
+ * 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
+ * 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
+ * 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. */
+ 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
+ * 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,
+ char **fontMap; /* Pointer to font map from the FontFamily,
* cached here to save a dereference. */
- HFONT hFont; /* The specific screen font that will be
- * used when displaying/measuring chars
- * belonging to the FontFamily. */
+ HFONT hFont; /* The specific screen font that will be used
+ * when displaying/measuring chars belonging
+ * to the FontFamily. */
FontFamily *familyPtr; /* The FontFamily for this SubFont. */
} SubFont;
@@ -109,18 +109,18 @@ typedef struct SubFont {
#define BASE_CHARS 128
typedef struct WinFont {
- TkFont font; /* Stuff used by generic font package. Must
- * be first in structure. */
+ 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
+ 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
+ * attributes. Usually points to
* staticSubFonts, but may point to malloced
* space if there are lots of SubFonts. */
@@ -129,10 +129,10 @@ typedef struct WinFont {
* 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. */
+ 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;
/*
@@ -155,10 +155,12 @@ typedef struct CanUse {
* represent the system fonts and the numbers used by Windows.
*/
-static TkStateMap systemMap[] = {
+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"},
@@ -166,11 +168,11 @@ static TkStateMap systemMap[] = {
};
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. */
+ 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;
@@ -178,7 +180,7 @@ static Tcl_ThreadDataKey dataKey;
/*
* Information cached about the system at startup time.
*/
-
+
static Tcl_Encoding systemEncoding;
/*
@@ -186,10 +188,10 @@ static Tcl_Encoding systemEncoding;
*/
static FontFamily * AllocFontFamily(HDC hdc, HFONT hFont, int base);
-static SubFont * CanUseFallback(HDC hdc, WinFont *fontPtr,
+static SubFont * CanUseFallback(HDC hdc, WinFont *fontPtr,
char *fallbackName, int ch,
SubFont **subFontPtrPtr);
-static SubFont * CanUseFallbackWithAliases(HDC hdc, WinFont *fontPtr,
+static SubFont * CanUseFallbackWithAliases(HDC hdc, WinFont *fontPtr,
char *faceName, int ch, Tcl_DString *nameTriedPtr,
SubFont **subFontPtrPtr);
static int FamilyExists(HDC hdc, CONST char *faceName);
@@ -202,44 +204,49 @@ static int FontMapLookup(SubFont *subFontPtr, int ch);
static void FreeFontFamily(FontFamily *familyPtr);
static HFONT GetScreenFont(CONST TkFontAttributes *faPtr,
CONST char *faceName, int pixelSize);
-static void InitFont(Tk_Window tkwin, HFONT hFont,
+static void InitFont(Tk_Window tkwin, HFONT hFont,
int overstrike, WinFont *tkFontPtr);
-static void InitSubFont(HDC hdc, HFONT hFont, int base,
+static void InitSubFont(HDC hdc, HFONT hFont, int base,
SubFont *subFontPtr);
-static int LoadFontRanges(HDC hdc, HFONT hFont,
+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,
+static void MultiFontTextOut(HDC hdc, WinFont *fontPtr,
CONST char *source, int numBytes, int x, int y);
static void ReleaseFont(WinFont *fontPtr);
static void ReleaseSubFont(SubFont *subFontPtr);
static int SeenName(CONST char *name, Tcl_DString *dsPtr);
static void SwapLong(PULONG p);
static void SwapShort(USHORT *p);
-static int CALLBACK WinFontCanUseProc(ENUMLOGFONT *lfPtr,
- NEWTEXTMETRIC *tmPtr, int fontType,
+static int CALLBACK WinFontCanUseProc(ENUMLOGFONT *lfPtr,
+ NEWTEXTMETRIC *tmPtr, int fontType,
LPARAM lParam);
-static int CALLBACK WinFontExistProc(ENUMLOGFONT *lfPtr,
- NEWTEXTMETRIC *tmPtr, int fontType,
+static int CALLBACK WinFontExistProc(ENUMLOGFONT *lfPtr,
+ NEWTEXTMETRIC *tmPtr, int fontType,
LPARAM lParam);
-static int CALLBACK WinFontFamilyEnumProc(ENUMLOGFONT *lfPtr,
- NEWTEXTMETRIC *tmPtr, int fontType,
+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.
+ * 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.
+ * None.
*
* Side effects:
- *
+ *
* None.
*
*-------------------------------------------------------------------------
@@ -251,13 +258,15 @@ TkpFontPkgInit(
{
if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
/*
- * If running NT, then we will be calling some Unicode functions
- * explictly. So, even if the Tcl system encoding isn't Unicode,
- * make sure we convert to/from the Unicode char set.
+ * If running NT, then we will be calling some Unicode functions
+ * explictly. So, even if the Tcl system encoding isn't Unicode, make
+ * sure we convert to/from the Unicode char set.
*/
systemEncoding = TkWinGetUnicodeEncoding();
}
+
+ TkWinSetupSystemFonts(mainPtr);
}
/*
@@ -268,17 +277,17 @@ TkpFontPkgInit(
* 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.
+ * 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.
+ * 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().
+ * 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.
@@ -308,26 +317,178 @@ TkpGetNativeFont(
/*
*---------------------------------------------------------------------------
+ * 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,
+ LOGFONTA* logFontPtr)
+{
+ HFONT hFont;
+ int r;
+
+ hFont = CreateFontIndirect(logFontPtr);
+ r = CreateNamedSystemFont(interp, tkwin, name, hFont);
+ DeleteObject((HGDIOBJ)hFont);
+ return r;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * CreateNamedSystemFont --
*
- * TkpGetFontFromAttributes --
+ * This function registers a Windows font with the Tk
+ * named font mechanism.
*
- * Given a desired set of attributes for a font, find a font with
- * the closest matching attributes.
+ * 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. (ie: 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.
+ */
+
+ {
+ LOGFONTA lfFixed = {
+ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, ""
+ };
+ 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.
+ * 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.
+ * 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().
+ * 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.
@@ -337,11 +498,11 @@ TkpGetNativeFont(
TkFont *
TkpGetFontFromAttributes(
- TkFont *tkFontPtr, /* If non-NULL, store the information in
- * this existing TkFont structure, rather than
+ 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
+ * will be released. If NULL, a new TkFont
* structure is allocated. */
Tk_Window tkwin, /* For display where font will be used. */
CONST TkFontAttributes *faPtr)
@@ -356,10 +517,10 @@ TkpGetFontFromAttributes(
char ***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);
+ 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.
@@ -397,10 +558,11 @@ TkpGetFontFromAttributes(
}
}
- found:
+ found:
ReleaseDC(hwnd, hdc);
- hFont = GetScreenFont(faPtr, faceName, TkFontGetPixels(tkwin, faPtr->size));
+ hFont = GetScreenFont(faPtr, faceName,
+ TkFontGetPixels(tkwin, faPtr->size));
if (tkFontPtr == NULL) {
fontPtr = (WinFont *) ckalloc(sizeof(WinFont));
} else {
@@ -418,9 +580,9 @@ TkpGetFontFromAttributes(
* 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.
+ * TkpGetFontFromAttributes(). The caller should have already released
+ * the fields of the TkFont that are used exclusively by the generic
+ * TkFont code.
*
* Results:
* None.
@@ -446,8 +608,8 @@ TkpDeleteFont(
*
* TkpGetFontFamilies, WinFontFamilyEnumProc --
*
- * Return information about the font families that are available
- * on the display of the given window.
+ * 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
@@ -458,33 +620,33 @@ TkpDeleteFont(
*
*---------------------------------------------------------------------------
*/
-
+
void
TkpGetFontFamilies(
Tcl_Interp *interp, /* Interp to hold result. */
Tk_Window tkwin) /* For display to query. */
-{
+{
HDC hdc;
HWND hwnd;
Window window;
- window = Tk_WindowId(tkwin);
- hwnd = (window == None) ? NULL : TkWinGetHWND(window);
- hdc = GetDC(hwnd);
+ window = Tk_WindowId(tkwin);
+ hwnd = (window == None) ? NULL : TkWinGetHWND(window);
+ hdc = GetDC(hwnd);
/*
- * 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 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.
+ * 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.
*/
if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
@@ -493,10 +655,10 @@ TkpGetFontFamilies(
} else {
EnumFontFamiliesA(hdc, NULL, (FONTENUMPROCA) WinFontFamilyEnumProc,
(LPARAM) interp);
- }
+ }
ReleaseDC(hwnd, hdc);
}
-
+
static int CALLBACK
WinFontFamilyEnumProc(
ENUMLOGFONT *lfPtr, /* Logical-font data. */
@@ -524,19 +686,19 @@ WinFontFamilyEnumProc(
*
* TkpGetSubFonts --
*
- * A function used by the testing package for querying the actual
- * screen fonts that make up a font object.
+ * 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.
+ * 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. */
@@ -547,7 +709,7 @@ TkpGetSubFonts(
FontFamily *familyPtr;
Tcl_Obj *resultPtr, *strPtr;
- resultPtr = Tcl_GetObjResult(interp);
+ resultPtr = Tcl_GetObjResult(interp);
fontPtr = (WinFont *) tkfont;
for (i = 0; i < fontPtr->numSubFonts; i++) {
familyPtr = fontPtr->subFontArray[i].familyPtr;
@@ -557,20 +719,75 @@ TkpGetSubFonts(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * 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 */
+ Tcl_UniChar 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->hFont);
+ GetTextMetrics(hdc, &tm);
+ SelectObject(hdc, oldfont);
+ ReleaseDC(fontPtr->hwnd, hdc);
+ faPtr->family = familyPtr->faceName;
+ faPtr->size = TkFontGetPoints(tkwin,
+ 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.
+ * 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.
+ * 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.
@@ -581,45 +798,42 @@ TkpGetSubFonts(
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
+ 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 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
+ * 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. */
+ * 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;
+ int curX, moretomeasure;
Tcl_UniChar ch;
SIZE size;
- int moretomeasure;
FontFamily *familyPtr;
Tcl_DString runString;
- SubFont *thisSubFontPtr;
- SubFont *lastSubFontPtr;
- CONST char *p, *end, *next, *start;
-
+ SubFont *thisSubFontPtr, *lastSubFontPtr;
+ CONST char *p, *end, *next = NULL, *start;
if (numBytes == 0) {
- *lengthPtr = 0;
- return 0;
+ *lengthPtr = 0;
+ return 0;
}
fontPtr = (WinFont *) tkfont;
@@ -630,8 +844,8 @@ Tk_MeasureChars(
/*
* A three step process:
- * 1. Find a contiguous range of characters that can all be
- * represented by a single screen font.
+ * 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.
*/
@@ -641,107 +855,103 @@ Tk_MeasureChars(
start = source;
end = start + numBytes;
for (p = start; p < end; ) {
- next = p + Tcl_UtfToUniChar(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,
- 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->hFont);
- }
- p = next;
+ next = p + Tcl_UtfToUniChar(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,
+ 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->hFont);
+ }
+ 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.
- */
+ /*
+ * 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;
+ Tcl_UtfToExternalDString(familyPtr->encoding, start,
+ (int) (p - start), &runString);
+ size.cx = 0;
(*familyPtr->getTextExtentPoint32Proc)(hdc,
Tcl_DStringValue(&runString),
- Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
+ Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
&size);
- Tcl_DStringFree(&runString);
- if (maxLength >= 0 && (curX+size.cx) > maxLength) {
- moretomeasure = 1;
- } else {
+ Tcl_DStringFree(&runString);
+ if (maxLength >= 0 && (curX+size.cx) > maxLength) {
+ moretomeasure = 1;
+ } else {
curX += size.cx;
- p = end;
- }
+ 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).
+ * 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;
+ char buf[16];
+ int dstWrote;
+ int lastSize = 0;
familyPtr = lastSubFontPtr->familyPtr;
- Tcl_DStringInit(&runString);
- for (p = start; p < end; ) {
- next = p + Tcl_UtfToUniChar(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,
- Tcl_DStringValue(&runString),
- Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
- &size);
- if ((curX+size.cx) > maxLength) {
+ Tcl_DStringInit(&runString);
+ for (p = start; p < end; ) {
+ next = p + Tcl_UtfToUniChar(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,
+ Tcl_DStringValue(&runString),
+ Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
+ &size);
+ if ((curX+size.cx) > maxLength) {
break;
}
- lastSize = size.cx;
+ 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;
+ 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;
}
@@ -751,38 +961,36 @@ Tk_MeasureChars(
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;
+ Tcl_UniChar ch2;
- /*
- * 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;
- Tcl_UniChar ch2;
-
- end = p;
- p = source;
- ch = ' ';
- while (p < end) {
- next = p + Tcl_UtfToUniChar(p, &ch2);
- if ((ch != ' ') && (ch2 == ' ')) {
- lastWordBreak = p;
- }
- p = next;
- ch = ch2;
- }
-
- if (lastWordBreak != NULL) {
- return Tk_MeasureChars(
- tkfont, source, lastWordBreak-source, -1, 0, lengthPtr);
- } else {
- if (flags & TK_AT_LEAST_ONE) {
- p = end;
- } else {
- p = source;
- curX = 0;
- }
- }
+ end = p;
+ p = source;
+ ch = ' ';
+ while (p < end) {
+ next = p + Tcl_UtfToUniChar(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;
@@ -792,9 +1000,66 @@ Tk_MeasureChars(
/*
*---------------------------------------------------------------------------
*
+ * 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.
+ * Draw a string of characters on the screen.
*
* Results:
* None.
@@ -812,12 +1077,12 @@ Tk_DrawChars(
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
+ 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
+ * 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
@@ -837,10 +1102,10 @@ Tk_DrawChars(
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->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
@@ -860,7 +1125,7 @@ Tk_DrawChars(
/*
* Select stipple pattern into destination dc.
*/
-
+
dcMem = CreateCompatibleDC(dc);
stipple = CreatePatternBrush(twdPtr->bitmap.handle);
@@ -884,8 +1149,8 @@ Tk_DrawChars(
/*
* 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.
+ * 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.
*/
@@ -938,7 +1203,7 @@ Tk_DrawChars(
MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent);
BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem,
- 0, 0, tkpWinBltModes[gc->function]);
+ 0, 0, (DWORD) tkpWinBltModes[gc->function]);
/*
* Destroy the temporary bitmap and restore the device context.
@@ -952,22 +1217,65 @@ Tk_DrawChars(
}
/*
+ *---------------------------------------------------------------------------
+ *
+ * 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. */
+{
+ (void) numBytes; /*unused*/
+ Tk_DrawChars(display, drawable, gc, tkfont,
+ source + rangeStart, rangeLength, x, y);
+}
+
+/*
*-------------------------------------------------------------------------
*
* MultiFontTextOut --
*
- * Helper function for Tk_DrawChars. Draws characters, using the
- * various screen fonts in fontPtr to draw multilingual characters.
- * Note: No bidirectional support.
+ * 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.
+ * 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.
*
*-------------------------------------------------------------------------
*/
@@ -979,8 +1287,8 @@ MultiFontTextOut(
* 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. */
+ int x, int y) /* Coordinates at which to place origin of
+ * string when drawing. */
{
Tcl_UniChar ch;
SIZE size;
@@ -997,27 +1305,27 @@ MultiFontTextOut(
end = source + numBytes;
for (p = source; p < end; ) {
- next = p + Tcl_UtfToUniChar(p, &ch);
- thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
- if (thisSubFontPtr != lastSubFontPtr) {
- if (p > source) {
+ next = p + Tcl_UtfToUniChar(p, &ch);
+ thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
+ if (thisSubFontPtr != lastSubFontPtr) {
+ if (p > source) {
familyPtr = lastSubFontPtr->familyPtr;
Tcl_UtfToExternalDString(familyPtr->encoding, source,
(int) (p - source), &runString);
- (*familyPtr->textOutProc)(hdc, x-(tm.tmOverhang/2), y,
+ (*familyPtr->textOutProc)(hdc, x-(tm.tmOverhang/2), y,
Tcl_DStringValue(&runString),
- Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
- (*familyPtr->getTextExtentPoint32Proc)(hdc,
+ Tcl_DStringLength(&runString)>>familyPtr->isWideFont);
+ (*familyPtr->getTextExtentPoint32Proc)(hdc,
Tcl_DStringValue(&runString),
- Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
+ Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
&size);
x += size.cx;
Tcl_DStringFree(&runString);
}
- lastSubFontPtr = thisSubFontPtr;
- source = p;
+ lastSubFontPtr = thisSubFontPtr;
+ source = p;
SelectObject(hdc, lastSubFontPtr->hFont);
- GetTextMetrics(hdc, &tm);
+ GetTextMetrics(hdc, &tm);
}
p = next;
}
@@ -1026,7 +1334,7 @@ MultiFontTextOut(
Tcl_UtfToExternalDString(familyPtr->encoding, source,
(int) (p - source), &runString);
(*familyPtr->textOutProc)(hdc, x-(tm.tmOverhang/2), y,
- Tcl_DStringValue(&runString),
+ Tcl_DStringValue(&runString),
Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
Tcl_DStringFree(&runString);
}
@@ -1039,12 +1347,12 @@ MultiFontTextOut(
* InitFont --
*
* Helper for TkpGetNativeFont() and TkpGetFontFromAttributes().
- * Initializes the memory for a new WinFont that wraps the
+ * 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().
+ * 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.
@@ -1053,17 +1361,17 @@ MultiFontTextOut(
* Memory allocated.
*
*---------------------------------------------------------------------------
- */
+ */
static void
InitFont(
- Tk_Window tkwin, /* Main window of interp in which font will
- * be used, for getting HDC. */
+ 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. */
+ 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. */
{
@@ -1077,27 +1385,27 @@ InitFont(
Tcl_DString faceString;
TkFontAttributes *faPtr;
char buf[LF_FACESIZE * sizeof(WCHAR)];
-
- window = Tk_WindowId(tkwin);
- hwnd = (window == None) ? NULL : TkWinGetHWND(window);
- hdc = GetDC(hwnd);
+
+ 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 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.
+ * 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.
*/
if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
@@ -1108,24 +1416,26 @@ InitFont(
Tcl_ExternalToUtfDString(systemEncoding, 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, -(tm.tmHeight - tm.tmInternalLeading));
- faPtr->weight = (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
+
+ faPtr->size =
+ TkFontGetPoints(tkwin, -(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->hwnd = hwnd;
- fontPtr->pixelSize = tm.tmHeight - tm.tmInternalLeading;
-
fontPtr->numSubFonts = 1;
fontPtr->subFontArray = fontPtr->staticSubFonts;
InitSubFont(hdc, hFont, 1, &fontPtr->subFontArray[0]);
@@ -1135,7 +1445,7 @@ InitFont(
GetCharWidthW(hdc, 0, BASE_CHARS - 1, fontPtr->widths);
} else {
GetCharWidthA(hdc, 0, BASE_CHARS - 1, fontPtr->widths);
- }
+ }
Tcl_DStringFree(&faceString);
SelectObject(hdc, oldFont);
@@ -1146,10 +1456,9 @@ InitFont(
*-------------------------------------------------------------------------
*
* ReleaseFont --
- *
- * Called to release the windows-specific contents of a TkFont.
- * The caller is responsible for freeing the memory used by the
- * font itself.
+ *
+ * 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.
@@ -1159,7 +1468,7 @@ InitFont(
*
*---------------------------------------------------------------------------
*/
-
+
static void
ReleaseFont(
WinFont *fontPtr) /* The font to delete. */
@@ -1179,9 +1488,9 @@ ReleaseFont(
*
* 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.
+ * 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.
@@ -1196,10 +1505,10 @@ static 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. */
+ 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->hFont = hFont;
subFontPtr->familyPtr = AllocFontFamily(hdc, hFont, base);
@@ -1211,8 +1520,8 @@ InitSubFont(
*
* ReleaseSubFont --
*
- * Called to release the contents of a SubFont. The caller is
- * responsible for freeing the memory used by the SubFont itself.
+ * Called to release the contents of a SubFont. The caller is responsible
+ * for freeing the memory used by the SubFont itself.
*
* Results:
* None.
@@ -1236,26 +1545,24 @@ ReleaseSubFont(
*
* 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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.
*
*-------------------------------------------------------------------------
*/
@@ -1265,16 +1572,16 @@ 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. */
+ 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;
char buf[LF_FACESIZE * sizeof(WCHAR)];
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
hFont = SelectObject(hdc, hFont);
if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
@@ -1287,7 +1594,7 @@ AllocFontFamily(
Tcl_DStringFree(&faceString);
hFont = SelectObject(hdc, hFont);
- familyPtr = tsdPtr->fontFamilyList;
+ familyPtr = tsdPtr->fontFamilyList;
for ( ; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
if (familyPtr->faceName == faceName) {
familyPtr->refCount++;
@@ -1300,38 +1607,38 @@ AllocFontFamily(
familyPtr->nextPtr = tsdPtr->fontFamilyList;
tsdPtr->fontFamilyList = familyPtr;
- /*
- * Set key for this FontFamily.
+ /*
+ * 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.
+ /*
+ * 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->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
+ * 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.
+ * (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.
+ * 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);
@@ -1341,16 +1648,16 @@ AllocFontFamily(
encoding = Tcl_GetEncoding(NULL, "unicode");
familyPtr->textOutProc =
(BOOL (WINAPI *)(HDC, int, int, TCHAR *, int)) TextOutW;
- familyPtr->getTextExtentPoint32Proc =
+ familyPtr->getTextExtentPoint32Proc =
(BOOL (WINAPI *)(HDC, TCHAR *, int, LPSIZE)) GetTextExtentPoint32W;
familyPtr->isWideFont = 1;
} else {
- familyPtr->textOutProc =
+ familyPtr->textOutProc =
(BOOL (WINAPI *)(HDC, int, int, TCHAR *, int)) TextOutA;
- familyPtr->getTextExtentPoint32Proc =
+ familyPtr->getTextExtentPoint32Proc =
(BOOL (WINAPI *)(HDC, TCHAR *, int, LPSIZE)) GetTextExtentPoint32A;
familyPtr->isWideFont = 0;
- }
+ }
familyPtr->encoding = encoding;
@@ -1374,27 +1681,27 @@ AllocFontFamily(
*
*-------------------------------------------------------------------------
*/
-
+
static void
FreeFontFamily(
FontFamily *familyPtr) /* The FontFamily to delete. */
{
int i;
FontFamily **familyPtrPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (familyPtr == NULL) {
- return;
+ return;
}
familyPtr->refCount--;
if (familyPtr->refCount > 0) {
return;
}
for (i = 0; i < FONTMAP_PAGES; i++) {
- if (familyPtr->fontMap[i] != NULL) {
- ckfree(familyPtr->fontMap[i]);
- }
+ if (familyPtr->fontMap[i] != NULL) {
+ ckfree(familyPtr->fontMap[i]);
+ }
}
if (familyPtr->startCount != NULL) {
ckfree((char *) familyPtr->startCount);
@@ -1405,19 +1712,19 @@ FreeFontFamily(
if (familyPtr->encoding != TkWinGetUnicodeEncoding()) {
Tcl_FreeEncoding(familyPtr->encoding);
}
-
- /*
- * Delete from list.
+
+ /*
+ * Delete from list.
*/
-
+
for (familyPtrPtr = &tsdPtr->fontFamilyList; ; ) {
- if (*familyPtrPtr == familyPtr) {
+ if (*familyPtrPtr == familyPtr) {
*familyPtrPtr = familyPtr->nextPtr;
break;
}
familyPtrPtr = &(*familyPtrPtr)->nextPtr;
}
-
+
ckfree((char *) familyPtr);
}
@@ -1426,19 +1733,17 @@ FreeFontFamily(
*
* 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.
+ * 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.
+ * 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.
+ * The contents of fontPtr are modified to cache the results of the
+ * lookup and remember any SubFonts that were dynamically loaded.
*
*-------------------------------------------------------------------------
*/
@@ -1459,7 +1764,7 @@ FindSubFontForChar(
char *fallbackName;
SubFont *subFontPtr;
Tcl_DString ds;
-
+
if (ch < BASE_CHARS) {
return &fontPtr->subFontArray[0];
}
@@ -1471,13 +1776,13 @@ FindSubFontForChar(
}
/*
- * 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.
+ * 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();
@@ -1491,25 +1796,25 @@ FindSubFontForChar(
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;
+ goto tryfallbacks;
}
}
}
}
continue;
- /*
- * ...then see if we can use one of the fallbacks, or an
- * alias for one of the fallbacks.
+ /*
+ * ...then see if we can use one of the fallbacks, or an alias for one
+ * of the fallbacks.
*/
- tryfallbacks:
+ tryfallbacks:
for (j = 0; fontFallbacks[i][j] != NULL; j++) {
fallbackName = fontFallbacks[i][j];
subFontPtr = CanUseFallbackWithAliases(hdc, fontPtr, fallbackName,
@@ -1521,13 +1826,13 @@ FindSubFontForChar(
}
/*
- * See if we can use something from the global fallback list.
+ * 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,
+ subFontPtr = CanUseFallbackWithAliases(hdc, fontPtr, fallbackName,
ch, &ds, subFontPtrPtr);
if (subFontPtr != NULL) {
goto end;
@@ -1535,8 +1840,8 @@ FindSubFontForChar(
}
/*
- * Try all face names available in the whole system until we
- * find one that can be used.
+ * Try all face names available in the whole system until we find one that
+ * can be used.
*/
canUse.hdc = hdc;
@@ -1554,22 +1859,22 @@ FindSubFontForChar(
}
subFontPtr = canUse.subFontPtr;
- end:
+ 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.
- */
+ /*
+ * 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);
+ FontMapInsert(subFontPtr, ch);
}
ReleaseDC(fontPtr->hwnd, hdc);
return subFontPtr;
}
-
+
static int CALLBACK
WinFontCanUseProc(
ENUMLOGFONT *lfPtr, /* Logical-font data. */
@@ -1617,15 +1922,14 @@ WinFontCanUseProc(
* 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.
+ * 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.
+ * 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.
*
*-------------------------------------------------------------------------
*/
@@ -1651,29 +1955,28 @@ FontMapLookup(
*
* 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.
+ * 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.
+ * 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
+ SubFont *subFontPtr, /* Contains font mapping cache to be
* updated. */
int ch) /* Character to be added to cache. */
{
@@ -1692,10 +1995,10 @@ FontMapInsert(
*
* 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.
+ * 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.
@@ -1705,12 +2008,13 @@ FontMapInsert(
*
*-------------------------------------------------------------------------
*/
-static void
+
+static void
FontMapLoadPage(
- SubFont *subFontPtr, /* Contains font mapping cache to be
+ SubFont *subFontPtr, /* Contains font mapping cache to be
* updated. */
- int row) /* Index of the page to be loaded into
- * the cache. */
+ int row) /* Index of the page to be loaded into the
+ * cache. */
{
FontFamily *familyPtr;
Tcl_Encoding encoding;
@@ -1726,9 +2030,9 @@ FontMapLoadPage(
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.
+ * 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;
@@ -1750,24 +2054,23 @@ FontMapLoadPage(
}
} 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.
+ * 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;
+ 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,
+ if (Tcl_UtfToExternal(NULL, encoding, src,
+ Tcl_UniCharToUtf(i, src), TCL_ENCODING_STOPONERROR, NULL,
buf, sizeof(buf), NULL, NULL, NULL) != TCL_OK) {
continue;
}
@@ -1782,18 +2085,16 @@ FontMapLoadPage(
*
* 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.
+ * 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.
+ * 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.
*
*---------------------------------------------------------------------------
*/
@@ -1804,11 +2105,11 @@ CanUseFallbackWithAliases(
WinFont *fontPtr, /* The font object that will own the new
* screen font. */
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
+ 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. */
@@ -1816,7 +2117,7 @@ CanUseFallbackWithAliases(
int i;
char **aliases;
SubFont *subFontPtr;
-
+
if (SeenName(faceName, nameTriedPtr) == 0) {
subFontPtr = CanUseFallback(hdc, fontPtr, faceName, ch, subFontPtrPtr);
if (subFontPtr != NULL) {
@@ -1843,9 +2144,9 @@ CanUseFallbackWithAliases(
*
* 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.
+ * 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,
@@ -1882,21 +2183,21 @@ SeenName(
*
* CanUseFallback --
*
- * If the specified screen font has not already been loaded into
- * the font object, determine if it can display the given character.
+ * 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.
+ * 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.
*
*-------------------------------------------------------------------------
*/
@@ -1907,8 +2208,8 @@ CanUseFallback(
WinFont *fontPtr, /* The font object that will own the new
* screen font. */
char *faceName, /* Desired face name for new screen font. */
- int ch, /* The Unicode character that the new
- * screen font must be able to display. */
+ 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. */
{
@@ -1920,10 +2221,10 @@ CanUseFallback(
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;
@@ -1936,7 +2237,7 @@ CanUseFallback(
hFont = GetScreenFont(&fontPtr->font.fa, faceName, fontPtr->pixelSize);
InitSubFont(hdc, hFont, 0, &subFont);
- if (((ch < 256) && (subFont.familyPtr->isSymbolFont))
+ if (((ch < 256) && (subFont.familyPtr->isSymbolFont))
|| (FontMapLookup(&subFont, ch) == 0)) {
/*
* Don't use a symbol font as a fallback font for characters below
@@ -1950,17 +2251,19 @@ CanUseFallback(
if (fontPtr->numSubFonts >= SUBFONT_SPACE) {
SubFont *newPtr;
- newPtr = (SubFont *) ckalloc(sizeof(SubFont)
+ newPtr = (SubFont *) ckalloc(sizeof(SubFont)
* (fontPtr->numSubFonts + 1));
memcpy((char *) newPtr, fontPtr->subFontArray,
fontPtr->numSubFonts * sizeof(SubFont));
if (fontPtr->subFontArray != fontPtr->staticSubFonts) {
ckfree((char *) fontPtr->subFontArray);
}
+
/*
- * Fix up the variable pointed to by subFontPtrPtr so it still
- * points into the live array. [Bug 618872]
+ * 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;
}
@@ -1974,9 +2277,8 @@ CanUseFallback(
*
* GetScreenFont --
*
- * Given the name and other attributes, construct an HFONT.
- * This is where all the alias and fallback substitution bottoms
- * out.
+ * 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.
@@ -1987,13 +2289,13 @@ CanUseFallback(
*---------------------------------------------------------------------------
*/
-static HFONT
+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
+ int pixelSize) /* Overrides size specified in font
* attributes. */
{
Tcl_DString ds;
@@ -2005,7 +2307,7 @@ GetScreenFont(
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
- lf.lfWeight = (faPtr->weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD;
+ lf.lfWeight = (faPtr->weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD;
lf.lfItalic = faPtr->slant;
lf.lfUnderline = faPtr->underline;
lf.lfStrikeOut = faPtr->overstrike;
@@ -2023,7 +2325,8 @@ GetScreenFont(
/*
* We can only store up to LF_FACESIZE wide characters
*/
- if (Tcl_DStringLength(&ds) >= (LF_FACESIZE * sizeof(WCHAR))) {
+
+ if ((size_t)Tcl_DStringLength(&ds) >= (LF_FACESIZE * sizeof(WCHAR))) {
Tcl_DStringSetLength(&ds, LF_FACESIZE);
}
src = (Tcl_UniChar *) Tcl_DStringValue(&ds);
@@ -2037,6 +2340,7 @@ GetScreenFont(
/*
* We can only store up to LF_FACESIZE characters
*/
+
if (Tcl_DStringLength(&ds) >= LF_FACESIZE) {
Tcl_DStringSetLength(&ds, LF_FACESIZE);
}
@@ -2052,10 +2356,9 @@ GetScreenFont(
*
* 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.
+ * 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,
@@ -2077,7 +2380,7 @@ FamilyExists(
/*
* Just immediately rule out the following fonts, because they look so
- * ugly on windows. The caller's fallback mechanism will cause the
+ * ugly on windows. The caller's fallback mechanism will cause the
* corresponding appropriate TrueType fonts to be selected.
*/
@@ -2090,18 +2393,18 @@ FamilyExists(
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
+ * 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.
*/
if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
- result = EnumFontFamiliesW(hdc, (WCHAR *) Tcl_DStringValue(&faceString),
+ result = EnumFontFamiliesW(hdc, (WCHAR*) Tcl_DStringValue(&faceString),
(FONTENUMPROCW) WinFontExistProc, 0);
} else {
result = EnumFontFamiliesA(hdc, (char *) Tcl_DStringValue(&faceString),
@@ -2110,10 +2413,10 @@ FamilyExists(
Tcl_DStringFree(&faceString);
return (result == 0);
}
-
+
static char *
FamilyOrAliasExists(
- HDC hdc,
+ HDC hdc,
CONST char *faceName)
{
char **aliases;
@@ -2132,7 +2435,7 @@ FamilyOrAliasExists(
}
return NULL;
}
-
+
static int CALLBACK
WinFontExistProc(
ENUMLOGFONT *lfPtr, /* Logical-font data. */
@@ -2158,25 +2461,25 @@ typedef struct CMAPTABLE {
} 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. */
+ 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
+ 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
+ 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
@@ -2187,7 +2490,7 @@ 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
+ USHORT idRangeOffset; /* Byte offset from here to appropriate
* glyphIndexArray. */
} SUBHEADER;
@@ -2196,12 +2499,12 @@ typedef struct HIBYTETABLE {
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
+ 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
+ USHORT glyphIndexArray[]; /* Variable-length array containing subarrays
+ * used for mapping the low byte of 2-byte
* characters. */
#endif
} HIBYTETABLE;
@@ -2233,8 +2536,8 @@ typedef struct TRIMMEDTABLE {
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. */
+ USHORT glyphIdArray[]; /* Array of glyph index values for
+ * character codes in the range. */
#endif
} TRIMMEDTABLE;
@@ -2253,16 +2556,16 @@ typedef union SUBTABLE {
*
* LoadFontRanges --
*
- * Given an HFONT, get the information about the characters that
- * this font can display.
+ * 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).
+ * 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.
@@ -2274,10 +2577,10 @@ 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. */
+ 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;
@@ -2310,20 +2613,21 @@ LoadFontRanges(
}
n = GetFontData(hdc, cmapKey, 0, &cmapTable, sizeof(cmapTable));
- if (n != GDI_ERROR) {
+ 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, offset, &encTable, 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.
*/
@@ -2335,7 +2639,7 @@ LoadFontRanges(
continue;
}
- GetFontData(hdc, cmapKey, encTable.offset, &subTable,
+ GetFontData(hdc, cmapKey, (DWORD) encTable.offset, &subTable,
sizeof(subTable));
if (swapped) {
SwapShort(&subTable.any.format);
@@ -2347,13 +2651,13 @@ LoadFontRanges(
segCount = subTable.segment.segCountX2 / 2;
cbData = segCount * sizeof(USHORT);
- startCount = (USHORT *) ckalloc(cbData);
- endCount = (USHORT *) ckalloc(cbData);
+ startCount = (USHORT *) ckalloc((unsigned)cbData);
+ endCount = (USHORT *) ckalloc((unsigned)cbData);
offset = encTable.offset + sizeof(subTable.segment);
- GetFontData(hdc, cmapKey, offset, endCount, cbData);
+ GetFontData(hdc, cmapKey, (DWORD) offset, endCount, cbData);
offset += cbData + sizeof(USHORT);
- GetFontData(hdc, cmapKey, offset, startCount, cbData);
+ GetFontData(hdc, cmapKey, (DWORD) offset, startCount, cbData);
if (swapped) {
for (i = 0; i < segCount; i++) {
SwapShort(&endCount[i]);
@@ -2362,16 +2666,15 @@ LoadFontRanges(
}
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.
+ * 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]
+ * Symbol fonts should only use the symbol encoding for
+ * 8-bit characters [note Bug: 2406]
*/
for (i = 0; i < segCount; i++) {
@@ -2386,13 +2689,14 @@ LoadFontRanges(
}
} else if (GetTextCharset(hdc) == ANSI_CHARSET) {
/*
- * Bitmap font. We should also support ranges for the other
- * *_CHARSET values.
+ * Bitmap font. We should also support ranges for the other *_CHARSET
+ * values.
*/
+
segCount = 1;
cbData = segCount * sizeof(USHORT);
- startCount = (USHORT *) ckalloc(cbData);
- endCount = (USHORT *) ckalloc(cbData);
+ startCount = (USHORT *) ckalloc((unsigned) cbData);
+ endCount = (USHORT *) ckalloc((unsigned) cbData);
startCount[0] = 0x0000;
endCount[0] = 0x00ff;
}
@@ -2405,11 +2709,11 @@ LoadFontRanges(
/*
*-------------------------------------------------------------------------
- *
+ *
* SwapShort, SwapLong --
*
- * Helper functions to convert the data loaded from TrueType font
- * files to Intel byte ordering.
+ * 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.
@@ -2421,14 +2725,16 @@ LoadFontRanges(
*/
static void
-SwapShort(PUSHORT p)
+SwapShort(
+ PUSHORT p)
{
*p = (SHORT)(HIBYTE(*p) + (LOBYTE(*p) << 8));
}
-static void
-SwapLong(PULONG p)
-{
+static void
+SwapLong(
+ PULONG p)
+{
ULONG temp;
temp = (LONG) ((BYTE) *p);
@@ -2446,3 +2752,11 @@ SwapLong(PULONG p)
temp += (LONG) ((BYTE) *p);
*p = temp;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinImage.c b/win/tkWinImage.c
index 9e927fe..8e6ef38 100644
--- a/win/tkWinImage.c
+++ b/win/tkWinImage.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkWinImage.c --
*
* This file contains routines for manipulation full-color images.
@@ -11,18 +11,18 @@
#include "tkWinInt.h"
-static int DestroyImage _ANSI_ARGS_((XImage* data));
-static unsigned long ImageGetPixel _ANSI_ARGS_((XImage *image, int x, int y));
-static int PutPixel _ANSI_ARGS_((XImage *image, int x, int y,
- unsigned long pixel));
+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.
+ * This is a trivial wrapper around ckfree to make it possible to pass
+ * ckfree as a pointer.
*
* Results:
* None.
@@ -34,8 +34,8 @@ static int PutPixel _ANSI_ARGS_((XImage *image, int x, int y,
*/
static int
-DestroyImage(imagePtr)
- XImage *imagePtr; /* image to free */
+DestroyImage(
+ XImage *imagePtr) /* Image to free. */
{
if (imagePtr) {
if (imagePtr->data) {
@@ -63,33 +63,33 @@ DestroyImage(imagePtr)
*/
static unsigned long
-ImageGetPixel(image, x, y)
- XImage *image;
- int x, y;
+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;
+ 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;
}
@@ -111,73 +111,74 @@ ImageGetPixel(image, x, y)
*/
static int
-PutPixel(image, x, y, pixel)
- XImage *image;
- int x, y;
- unsigned long pixel;
+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
- */
+ case 32:
+ /*
+ * Pixel is DWORD: 0x00BBGGRR
+ */
- destPtr[3] = 0;
- case 24:
- /*
- * Pixel is triplet: 0xBBGGRR.
- */
+ 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)
- */
+ 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)
+ (*(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.
- */
+ 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)
+ (*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)
+ } else {
+ (*destPtr) = (unsigned char) (((*destPtr) & 0x0f)
| ((pixel << 4) & 0xf0));
- }
- break;
- case 1: {
- /*
- * Pixel is bit in MSBFirst order.
- */
+ }
+ break;
+ case 1: {
+ /*
+ * Pixel is bit in MSBFirst order.
+ */
- int mask = (0x80 >> (x%8));
- if (pixel) {
- (*destPtr) |= mask;
- } else {
- (*destPtr) &= ~mask;
- }
+ int mask = (0x80 >> (x%8));
+
+ if (pixel) {
+ (*destPtr) |= mask;
+ } else {
+ (*destPtr) &= ~mask;
}
break;
}
+ }
return 0;
}
@@ -198,18 +199,17 @@ PutPixel(image, x, y, pixel)
*/
XImage *
-XCreateImage(display, visual, depth, format, offset, data, width, height,
- bitmap_pad, bytes_per_line)
- 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;
+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 = (XImage *) ckalloc(sizeof(XImage));
imagePtr->width = width;
@@ -253,47 +253,46 @@ XCreateImage(display, visual, depth, format, offset, data, width, height,
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.
+ * 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.
+ * 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.
+ * This procedure is adapted from the XGetImage implementation in TkNT. That
+ * code is Copyright (c) 1994 Software Research Associates, Inc.
*
*----------------------------------------------------------------------
*/
static XImage *
-XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
- Display* display;
- Drawable d;
- int x;
- int y;
- unsigned int width;
- unsigned int height;
- unsigned long plane_mask;
- int format;
+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 = NULL;
+ XImage *ret_image;
HDC hdc, hdcMem;
HBITMAP hbmp, hbmpPrev;
BITMAPINFO *bmInfo = NULL;
- HPALETTE hPal, hPalPrev1, hPalPrev2;
+ HPALETTE hPal, hPalPrev1 = 0, hPalPrev2 = 0;
int size;
unsigned int n;
unsigned int depth;
@@ -303,38 +302,42 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
if (format != ZPixmap) {
TkpDisplayWarning(
- "XGetImageZPixmap: only ZPixmap types are implemented",
- "XGetImageZPixmap Failure");
+ "XGetImageZPixmap: 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, width, height);
+ /*
+ * 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);
- }
+ 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);
- }
+ n = RealizePalette(hdc);
+ if (n > 0) {
+ UpdateColors(hdc);
+ }
}
- ret = BitBlt(hdcMem, 0, 0, width, height, hdc, x, y, SRCCOPY);
+ 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) {
@@ -347,22 +350,23 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
if (depth <= 8) {
size += sizeof(unsigned short) * (1 << depth);
}
- bmInfo = (BITMAPINFO *) 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;
+ bmInfo = (BITMAPINFO *) ckalloc((unsigned)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 = (unsigned char *) ckalloc(bmInfo->bmiHeader.biSizeImage);
if (!data) {
@@ -370,14 +374,17 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
ret_image = NULL;
goto cleanup;
}
- ret_image = XCreateImage(display, NULL, depth, ZPixmap, 0, (char *) data,
- width, height, 32, ((width + 31) >> 3) & ~1);
+ ret_image = XCreateImage(display, NULL, depth, ZPixmap, 0, (char *)data,
+ width, height, 32, (int) ((width + 31) >> 3) & ~1);
if (ret_image == NULL) {
ckfree((char *)data);
goto cleanup;
}
- /* Get the BITMAP info into the Image. */
+ /*
+ * Get the BITMAP info into the Image.
+ */
+
if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
DIB_PAL_COLORS) == 0) {
ckfree((char *) ret_image->data);
@@ -403,14 +410,17 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
ret_image = NULL;
goto cleanup;
}
- ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, (char *) data,
- width, height, 8, width);
+ ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, (char *)data,
+ width, height, 8, (int) width);
if (ret_image == NULL) {
ckfree((char *) data);
goto cleanup;
}
- /* Get the BITMAP info into the Image. */
+ /*
+ * Get the BITMAP info into the Image.
+ */
+
if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
DIB_PAL_COLORS) == 0) {
ckfree((char *) ret_image->data);
@@ -438,9 +448,12 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
goto cleanup;
}
- /* Get the BITMAP info directly into the Image. */
+ /*
+ * Get the BITMAP info directly into the Image.
+ */
+
if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
- DIB_RGB_COLORS) == 0) {
+ DIB_RGB_COLORS) == 0) {
ckfree((char *) ret_image->data);
ckfree((char *) ret_image);
ret_image = NULL;
@@ -455,7 +468,7 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
goto cleanup;
}
ret_image = XCreateImage(display, NULL, 32, ZPixmap, 0, (char *) data,
- width, height, 0, width * 4);
+ width, height, 0, (int) width * 4);
if (ret_image == NULL) {
ckfree((char *) data);
goto cleanup;
@@ -463,13 +476,14 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
if (depth <= 24) {
/*
- * This used to handle 16 and 24 bpp, but now just handles 24.
- * It can likely be optimized for that. -- hobbs
+ * 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) & ~3);
+ byte_width = ((width * 3 + 3) & ~(unsigned)3);
smallBitBase = (unsigned char *) ckalloc(byte_width * height);
if (!smallBitBase) {
ckfree((char *) ret_image->data);
@@ -479,18 +493,25 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
}
smallBitData = smallBitBase;
- /* Get the BITMAP info into the Image. */
+ /*
+ * Get the BITMAP info into the Image.
+ */
+
if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo,
- DIB_RGB_COLORS) == 0) {
+ DIB_RGB_COLORS) == 0) {
ckfree((char *) ret_image->data);
ckfree((char *) ret_image);
ckfree((char *) smallBitBase);
ret_image = NULL;
goto cleanup;
}
- /* Copy the 24 Bit Pixmap to a 32-Bit one. */
+
+ /*
+ * 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;
+ bigBitData = (unsigned char *) (ret_image->data + h * ret_image->bytes_per_line);
smallBitData = smallBitBase + h * byte_width;
for (w = 0; w < width; w++) {
@@ -500,10 +521,17 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
*bigBitData++ = 0;
}
}
- /* Free the Device contexts, and the Bitmap */
+
+ /*
+ * Free the Device contexts, and the Bitmap.
+ */
+
ckfree((char *) smallBitBase);
} else {
- /* Get the BITMAP info directly into the Image. */
+ /*
+ * Get the BITMAP info directly into the Image.
+ */
+
if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
DIB_RGB_COLORS) == 0) {
ckfree((char *) ret_image->data);
@@ -532,12 +560,11 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
*
* XGetImage --
*
- * This function copies data from a pixmap or window into an
- * XImage.
+ * 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.
+ * Returns a newly allocated image containing the data from the given
+ * rectangle of the given drawable.
*
* Side effects:
* None.
@@ -546,15 +573,13 @@ XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
*/
XImage *
-XGetImage(display, d, x, y, width, height, plane_mask, format)
- Display* display;
- Drawable d;
- int x;
- int y;
- unsigned int width;
- unsigned int height;
- unsigned long plane_mask;
- int format;
+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;
@@ -566,26 +591,28 @@ XGetImage(display, d, x, y, width, height, plane_mask, format)
/*
* 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.
+ * 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);
+ 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);
@@ -596,18 +623,19 @@ XGetImage(display, d, x, y, width, height, plane_mask, format)
if (pixel == CLR_INVALID) {
break;
}
- PutPixel(imagePtr, xx, yy, pixel);
+ 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
+ * 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 {
@@ -626,13 +654,15 @@ XGetImage(display, d, x, y, width, height, plane_mask, format)
/*
* 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);
+ imagePtr->data =
+ ckalloc((unsigned) imagePtr->bytes_per_line*imagePtr->height);
dc = GetDC(NULL);
@@ -645,7 +675,7 @@ XGetImage(display, d, x, y, width, height, plane_mask, format)
infoPtr->bmiHeader.biPlanes = 1;
infoPtr->bmiHeader.biBitCount = 1;
infoPtr->bmiHeader.biCompression = BI_RGB;
- infoPtr->bmiHeader.biSizeImage = 0;
+ infoPtr->bmiHeader.biSizeImage = 0;
infoPtr->bmiHeader.biXPelsPerMeter = 0;
infoPtr->bmiHeader.biYPelsPerMeter = 0;
infoPtr->bmiHeader.biClrUsed = 0;
@@ -658,3 +688,11 @@ XGetImage(display, d, x, y, width, height, plane_mask, format)
return imagePtr;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinInit.c b/win/tkWinInit.c
index ab33607..19556dd 100644
--- a/win/tkWinInit.c
+++ b/win/tkWinInit.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkWinInit.c --
*
* This file contains Windows-specific interpreter initialization
@@ -12,12 +12,6 @@
#include "tkWinInt.h"
-/*
- * The Init script (common to Windows and Unix platforms) is
- * defined in tkInitScript.h
- */
-#include "tkInitScript.h"
-
/*
*----------------------------------------------------------------------
@@ -28,8 +22,8 @@
* tk_library variable.
*
* Results:
- * A standard Tcl completion code (TCL_OK or TCL_ERROR). Also
- * leaves information in the interp's result.
+ * 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.
@@ -38,15 +32,16 @@
*/
int
-TkpInit(interp)
- Tcl_Interp *interp;
+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_Eval(interp, initScript);
+ return TCL_OK;
}
/*
@@ -54,9 +49,9 @@ TkpInit(interp)
*
* 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.
+ * 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.
@@ -68,9 +63,9 @@ TkpInit(interp)
*/
void
-TkpGetAppName(interp, namePtr)
- Tcl_Interp *interp;
- Tcl_DString *namePtr; /* A previously initialized Tcl_DString. */
+TkpGetAppName(
+ Tcl_Interp *interp,
+ Tcl_DString *namePtr) /* A previously initialized Tcl_DString. */
{
int argc, namelength;
CONST char **argv = NULL, *name, *p;
@@ -104,8 +99,8 @@ TkpGetAppName(interp, namePtr)
*
* TkpDisplayWarning --
*
- * This routines is called from Tk_Main to display warning
- * messages that occur during startup.
+ * This routines is called from Tk_Main to display warning messages that
+ * occur during startup.
*
* Results:
* None.
@@ -117,28 +112,31 @@ TkpGetAppName(interp, namePtr)
*/
void
-TkpDisplayWarning(msg, title)
- CONST char *msg; /* Message to be displayed. */
- CONST char *title; /* Title of warning. */
+TkpDisplayWarning(
+ CONST char *msg, /* Message to be displayed. */
+ CONST char *title) /* Title of warning. */
{
- Tcl_DString msgString, titleString;
- Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding();
+#define TK_MAX_WARN_LEN 1024
+ WCHAR msgString[TK_MAX_WARN_LEN + 5];
+ WCHAR titleString[TK_MAX_WARN_LEN + 1];
+ MultiByteToWideChar(CP_UTF8, 0, msg, -1, msgString, TK_MAX_WARN_LEN);
+ MultiByteToWideChar(CP_UTF8, 0, title, -1, titleString, TK_MAX_WARN_LEN);
/*
- * Truncate MessageBox string if it is too long to not overflow
- * the screen and cause possible oversized window error.
+ * Truncate MessageBox string if it is too long to not overflow the screen
+ * and cause possible oversized window error.
*/
-#define TK_MAX_WARN_LEN (1024 * sizeof(WCHAR))
- Tcl_UtfToExternalDString(unicodeEncoding, msg, -1, &msgString);
- Tcl_UtfToExternalDString(unicodeEncoding, title, -1, &titleString);
- if (Tcl_DStringLength(&msgString) > TK_MAX_WARN_LEN) {
- Tcl_DStringSetLength(&msgString, TK_MAX_WARN_LEN);
- Tcl_DStringAppend(&msgString, (char *) L" ...", 4 * sizeof(WCHAR));
- }
- MessageBoxW(NULL, (WCHAR *) Tcl_DStringValue(&msgString),
- (WCHAR *) Tcl_DStringValue(&titleString),
+ memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR));
+ titleString[TK_MAX_WARN_LEN] = L'\0';
+ MessageBoxW(NULL, msgString, titleString,
MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL
| MB_SETFOREGROUND | MB_TOPMOST);
- Tcl_DStringFree(&msgString);
- Tcl_DStringFree(&titleString);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinInt.h b/win/tkWinInt.h
index efff755..5616e20 100644
--- a/win/tkWinInt.h
+++ b/win/tkWinInt.h
@@ -2,14 +2,13 @@
* 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.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKWININT
@@ -31,18 +30,20 @@
#include "tkPort.h"
#endif
-
/*
* Define constants missing from older Win32 SDK header files.
*/
#ifndef WS_EX_TOOLWINDOW
-#define WS_EX_TOOLWINDOW 0x00000080L
+#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.
+ * The TkWinDCState is used to save the state of a device context so that it
+ * can be restored later.
*/
typedef struct TkWinDCState {
@@ -51,8 +52,8 @@ typedef struct TkWinDCState {
} TkWinDCState;
/*
- * The TkWinDrawable is the internal implementation of an X Drawable (either
- * a Window or a Pixmap). The following constants define the valid Drawable
+ * The TkWinDrawable is the internal implementation of an X Drawable (either a
+ * Window or a Pixmap). The following constants define the valid Drawable
* types.
*/
@@ -103,11 +104,11 @@ 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. */
+ * 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;
/*
@@ -128,59 +129,64 @@ typedef struct {
* Win32 raster and BitBlt op modes.
*/
-extern int tkpWinRopModes[];
-extern int tkpWinBltModes[];
+MODULE_SCOPE int tkpWinRopModes[];
+MODULE_SCOPE int tkpWinBltModes[];
/*
- * The following defines are used with TkWinGetBorderPixels to get the
- * extra 2 border colors from a Tk_3DBorder.
+ * 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 procedures used by more than one source file.
+ * Internal functions used by more than one source file.
*/
#include "tkIntPlatDecls.h"
-/*
- * We need to specially add the TkWinChildProc because of the special
- * prototype it has (doesn't fit into stubs schema)
- */
#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif
-EXTERN LRESULT CALLBACK TkWinChildProc _ANSI_ARGS_((HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam));
-
/*
* Special proc needed as tsd accessor function between
* tkWinX.c:GenerateXEvent and tkWinClipboard.c:UpdateClipboard
*/
-EXTERN void TkWinUpdatingClipboard(int mode);
+
+EXTERN void TkWinUpdatingClipboard(int mode);
/*
* Used by tkWinDialog.c to associate the right icon with tk_messageBox
*/
-EXTERN HICON TkWinGetIcon(Tk_Window tkw, DWORD iconsize);
+
+EXTERN HICON TkWinGetIcon(Tk_Window tkw, DWORD iconsize);
+
+/*
+ * Used by tkWinX.c on for certain system display change messages and cleanup
+ * up containers
+ */
+
+EXTERN void TkWinDisplayChanged(Display *display);
+MODULE_SCOPE void TkWinCleanupContainerList(void);
/*
- * Used by tkWinX.c on for certain system display change messages
+ * Used by tkWinWm.c for embedded menu handling. May become public.
*/
-EXTERN void TkWinDisplayChanged(Display *display);
+
+EXTERN HWND Tk_GetMenuHWND(Tk_Window tkwin);
+EXTERN HWND Tk_GetEmbeddedMenuHWND(Tk_Window tkwin);
/*
- * The following structure keeps track of whether we are using the
- * multi-byte or the wide-character interfaces to the operating system.
- * System calls should be made through the following function table.
+ * The following structure keeps track of whether we are using the multi-byte
+ * or the wide-character interfaces to the operating system. System calls
+ * should be made through the following function table.
*
* While some system calls need to use this A/W jump-table, it is not
- * necessary for all calls to do it, which is why you won't see this
- * used throughout the Tk code, but only in key areas. -- hobbs
+ * necessary for all calls to do it, which is why you won't see this used
+ * throughout the Tk code, but only in key areas. -- hobbs
*/
typedef struct TkWinProcs {
@@ -189,7 +195,7 @@ typedef struct TkWinProcs {
UINT Msg, WPARAM wParam, LPARAM lParam);
LRESULT (WINAPI *defWindowProc)(HWND hWnd, UINT Msg, WPARAM wParam,
LPARAM lParam);
- ATOM (WINAPI *registerClass)(CONST WNDCLASS *lpWndClass);
+ ATOM (WINAPI *registerClass)(const WNDCLASS *lpWndClass);
BOOL (WINAPI *setWindowText)(HWND hWnd, LPCTSTR lpString);
HWND (WINAPI *createWindowEx)(DWORD dwExStyle, LPCTSTR lpClassName,
LPCTSTR lpWindowName, DWORD dwStyle, int x, int y,
@@ -197,6 +203,7 @@ typedef struct TkWinProcs {
HINSTANCE hInstance, LPVOID lpParam);
BOOL (WINAPI *insertMenu)(HMENU hMenu, UINT uPosition, UINT uFlags,
UINT uIDNewItem, LPCTSTR lpNewItem);
+ int (WINAPI *getWindowText)(HWND hWnd, LPCTSTR lpString, int nMaxCount);
} TkWinProcs;
EXTERN TkWinProcs *tkWinProcs;
@@ -209,14 +216,76 @@ EXTERN TkWinProcs *tkWinProcs;
*/
-extern Tcl_Encoding TkWinGetKeyInputEncoding _ANSI_ARGS_((void));
-extern Tcl_Encoding TkWinGetUnicodeEncoding _ANSI_ARGS_((void));
+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
-#endif /* _TKWININT */
+/*
+ * The following is implemented in tkWinWm and used by tkWinEmbed.c
+ */
+
+void TkpWinToplevelWithDraw(TkWindow *winPtr);
+void TkpWinToplevelIconify(TkWindow *winPtr);
+void TkpWinToplevelDeiconify(TkWindow *winPtr);
+long TkpWinToplevelIsControlledByWm(TkWindow *winPtr);
+long TkpWinToplevelMove(TkWindow *winPtr, int x, int y);
+long TkpWinToplevelOverrideRedirect(TkWindow *winPtr,
+ int reqValue);
+void TkpWinToplevelDetachWindow(TkWindow *winPtr);
+int TkpWmGetState(TkWindow *winPtr);
+/*
+ * The following functions are not present in old versions of Windows
+ * API headers but are used in the Tk source to ensure 64bit
+ * compatability.
+ */
+
+#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/win/tkWinKey.c b/win/tkWinKey.c
index aa532bf..522bfba 100644
--- a/win/tkWinKey.c
+++ b/win/tkWinKey.c
@@ -6,59 +6,62 @@
*
* 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.
+ * 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.
+ * 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 145 /* VK_SCROLL is the last entry in our table below */
+
static 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, 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
};
/*
- * Prototypes for local procedures defined in this file:
+ * Prototypes for local functions defined in this file:
*/
-static KeySym KeycodeToKeysym _ANSI_ARGS_((unsigned int keycode,
- int state, int noascii));
+static KeySym KeycodeToKeysym(unsigned int keycode,
+ int state, int noascii);
/*
*----------------------------------------------------------------------
@@ -77,58 +80,59 @@ static KeySym KeycodeToKeysym _ANSI_ARGS_((unsigned int keycode,
*/
char *
-TkpGetString(winPtr, eventPtr, dsPtr)
- 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
+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. */
{
- KeySym keysym;
+ XKeyEvent *keyEv = &eventPtr->xkey;
Tcl_DStringInit(dsPtr);
- if (eventPtr->xkey.send_event == -1) {
- if (eventPtr->xkey.nbytes > 0) {
+ if (keyEv->send_event == -1) {
+ if (keyEv->nbytes > 0) {
Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(),
- eventPtr->xkey.trans_chars, eventPtr->xkey.nbytes, dsPtr);
- }
- } else if (eventPtr->xkey.send_event == -2) {
- /*
- * Special case for win2000 multi-lingal IME input.
- * xkey.trans_chars[] already contains a UNICODE char.
- */
-
- int unichar;
- char buf[TCL_UTF_MAX];
- int len;
-
- unichar = (eventPtr->xkey.trans_chars[1] & 0xff);
- unichar <<= 8;
- unichar |= (eventPtr->xkey.trans_chars[0] & 0xff);
-
- len = Tcl_UniCharToUtf((Tcl_UniChar) unichar, buf);
-
- Tcl_DStringAppend(dsPtr, buf, len);
- } else if (eventPtr->xkey.send_event == -3) {
+ keyEv->trans_chars, keyEv->nbytes, dsPtr);
+ }
+ } else if (keyEv->send_event == -2) {
/*
- * Special case for WM_UNICHAR.
- * xkey.trans_chars[] already contains a UTF-8 char.
+ * Special case for win2000 multi-lingal IME input. xkey.trans_chars[]
+ * already contains a UNICODE char.
*/
- Tcl_DStringAppend(dsPtr, eventPtr->xkey.trans_chars,
- eventPtr->xkey.nbytes);
- } else {
+
+ int unichar;
+ char buf[TCL_UTF_MAX];
+ int len;
+
+ unichar = keyEv->trans_chars[1] & 0xff;
+ unichar <<= 8;
+ unichar |= keyEv->trans_chars[0] & 0xff;
+
+ len = Tcl_UniCharToUtf((Tcl_UniChar) unichar, buf);
+
+ Tcl_DStringAppend(dsPtr, buf, len);
+ } else if (keyEv->send_event == -3) {
+ /*
+ * Special case for WM_UNICHAR. xkey.trans_chars[] already contains a
+ * UTF-8 char.
+ */
+
+ Tcl_DStringAppend(dsPtr, keyEv->trans_chars, keyEv->nbytes);
+ } else {
/*
- * This is an event generated from generic code. It has no
- * nchars or trans_chars members.
+ * This is an event generated from generic code. It has no nchars or
+ * trans_chars members.
*/
- keysym = KeycodeToKeysym(eventPtr->xkey.keycode,
- eventPtr->xkey.state, 0);
- if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256))
- || (keysym == XK_Return)
- || (keysym == XK_Tab)) {
+ KeySym keysym = KeycodeToKeysym(keyEv->keycode, keyEv->state, 0);
+
+ if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256))
+ || (keysym == XK_Return) || (keysym == XK_Tab)) {
char buf[TCL_UTF_MAX];
- int len = Tcl_UniCharToUtf((Tcl_UniChar) (keysym & 255), buf);
+ int len;
+
+ len = Tcl_UniCharToUtf((Tcl_UniChar) (keysym & 255), buf);
Tcl_DStringAppend(dsPtr, buf, len);
}
}
@@ -140,8 +144,8 @@ TkpGetString(winPtr, eventPtr, dsPtr)
*
* XKeycodeToKeysym --
*
- * Translate from a system-dependent keycode to a
- * system-independent keysym.
+ * Translate from a system-dependent keycode to a system-independent
+ * keysym.
*
* Results:
* Returns the translated keysym, or NoSymbol on failure.
@@ -153,10 +157,10 @@ TkpGetString(winPtr, eventPtr, dsPtr)
*/
KeySym
-XKeycodeToKeysym(display, keycode, index)
- Display* display;
- unsigned int keycode;
- int index;
+XKeycodeToKeysym(
+ Display *display,
+ unsigned int keycode,
+ int index)
{
int state = 0;
@@ -165,32 +169,30 @@ XKeycodeToKeysym(display, keycode, index)
}
return KeycodeToKeysym(keycode, state, 0);
}
-
-
/*
*----------------------------------------------------------------------
*
* KeycodeToKeysym --
*
- * Translate from a system-dependent keycode to a
- * system-independent keysym.
+ * 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.
+ * It may affect the internal state of the keyboard, such as remembered
+ * dead key or lock indicator lamps.
*
*----------------------------------------------------------------------
*/
static KeySym
-KeycodeToKeysym(keycode, state, noascii)
- unsigned int keycode;
- int state;
- int noascii;
+KeycodeToKeysym(
+ unsigned int keycode,
+ int state,
+ int noascii)
{
BYTE keys[256];
int result, deadkey, shift;
@@ -198,115 +200,123 @@ KeycodeToKeysym(keycode, state, noascii)
unsigned int scancode = MapVirtualKey(keycode, 0);
/*
- * Do not run keycodes of lock keys through ToAscii().
- * One of ToAscii()'s side effects is to handle the lights
- * on the keyboard, and we don't want to mess that up.
+ * Do not run keycodes of lock keys through ToAscii(). One of ToAscii()'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 skipToAscii;
+ keycode == VK_NUMLOCK) {
+ goto skipToAscii;
+ }
/*
* Use MapVirtualKey() to detect some dead keys.
*/
- if (MapVirtualKey(keycode, 2) > 0x7fffUL)
- return XK_Multi_key;
+ 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)
+ if (state & ShiftMask) {
+ keys[VK_SHIFT] = 0x80;
+ }
+ if (state & ControlMask) {
keys[VK_CONTROL] = 0x80;
- if (state & Mod2Mask)
+ }
+ if (state & Mod2Mask) {
keys[VK_MENU] = 0x80;
+ }
- /*
+ /*
* Make sure all lock button info is correct so we don't mess up the
- * lights
+ * lights.
*/
- if (state & LockMask)
+ if (state & LockMask) {
keys[VK_CAPITAL] = 1;
- if (state & Mod3Mask)
+ }
+ if (state & Mod3Mask) {
keys[VK_SCROLL] = 1;
- if (state & Mod1Mask)
+ }
+ if (state & Mod1Mask) {
keys[VK_NUMLOCK] = 1;
+ }
result = ToAscii(keycode, scancode, keys, (LPWORD) buf, 0);
if (result < 0) {
- /*
- * Win95/98:
- * This was a dead char, which is now remembered by the keyboard.
- * Call ToAscii() again to forget it.
- * WinNT:
- * This was a dead char, overwriting any previously remembered
- * key. Calling ToAscii() again does not affect anything.
- */
-
- ToAscii(keycode, scancode, keys, (LPWORD) buf, 0);
- return XK_Multi_key;
+ /*
+ * Win95/98: This was a dead char, which is now remembered by the
+ * keyboard. Call ToAscii() again to forget it.
+ * WinNT: This was a dead char, overwriting any previously remembered
+ * key. Calling ToAscii() again does not affect anything.
+ */
+
+ ToAscii(keycode, scancode, keys, (LPWORD) buf, 0);
+ return XK_Multi_key;
}
- if (result == 2) {
- /*
- * This was a dead char, and there were one previously remembered
- * by the keyboard.
- * Call ToAscii() again with proper parameters to restore it.
- */
- /*
+ if (result == 2) {
+ /*
+ * This was a dead char, and there were one previously remembered by
+ * the keyboard. Call ToAscii() 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);
+ 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;
- ToAscii(deadkey, scancode, keys, (LPWORD) buf, 0);
- return XK_Multi_key;
+ 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;
+ }
+ ToAscii(deadkey, scancode, keys, (LPWORD) buf, 0);
+ return XK_Multi_key;
}
/*
- * Keycode mapped to a valid Latin-1 character. Since the keysyms
- * for alphanumeric characters map onto Latin-1, we just return it.
+ * Keycode mapped to a valid Latin-1 character. Since the keysyms for
+ * alphanumeric characters map onto Latin-1, 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 ToAscii, 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.
+ * 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 ToAscii, 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
+ * 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 dependant
* on whether you believe that ToAscii 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).
+ * 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 && UCHAR(buf[0]) >= 0x20 && UCHAR(buf[0]) != 0x7F) {
@@ -317,69 +327,64 @@ KeycodeToKeysym(keycode, state, noascii)
* Keycode is a non-alphanumeric key, so we have to do the lookup.
*/
- skipToAscii:
- if (keycode < 0 || keycode > MAX_KEYCODE) {
+ skipToAscii:
+ 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 have to query the
- * state of one of the two to determine which was actually
- * pressed. So if the keycode indicates Control, Shift, or Menu
- * (the key that everybody else calls Alt), do this extra test.
- * If the right-side key was pressed, return the appropriate
- * keycode. Otherwise, we fall through and rely on the
+ * Windows only gives us an undifferentiated VK_CONTROL code (for
+ * example) when either Control key is pressed. To distinguish between
+ * left and right, we have to query the state of one of the two to
+ * determine which was actually pressed. So if the keycode indicates
+ * Control, Shift, or Menu (the key that everybody else calls Alt), 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.
*/
- case VK_CONTROL: {
- if (GetKeyState(VK_RCONTROL) & 0x80) {
- return XK_Control_R;
- }
- break;
+
+ case VK_CONTROL:
+ if (GetKeyState(VK_RCONTROL) & 0x80) {
+ return XK_Control_R;
}
- case VK_SHIFT: {
- if (GetKeyState(VK_RSHIFT) & 0x80) {
- return XK_Shift_R;
- }
- break;
+ break;
+ case VK_SHIFT:
+ if (GetKeyState(VK_RSHIFT) & 0x80) {
+ return XK_Shift_R;
}
- case VK_MENU: {
- if (GetKeyState(VK_RMENU) & 0x80) {
- return XK_Alt_R;
- }
- break;
+ break;
+ case VK_MENU:
+ if (GetKeyState(VK_RMENU) & 0x80) {
+ 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.
+ * 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.
+ * 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.
+ * In the first call for a given display, keycode-to-KeySym maps get
+ * loaded.
*
*----------------------------------------------------------------------
*/
KeySym
-TkpGetKeySym(dispPtr, eventPtr)
- TkDisplay *dispPtr; /* Display in which to map keycode. */
- XEvent *eventPtr; /* Description of X event. */
+TkpGetKeySym(
+ TkDisplay *dispPtr, /* Display in which to map keycode. */
+ XEvent *eventPtr) /* Description of X event. */
{
KeySym sym;
int state = eventPtr->xkey.state;
@@ -395,17 +400,17 @@ TkpGetKeySym(dispPtr, eventPtr)
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.
+ * 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);
+ state &= ~(ControlMask | Mod2Mask);
+ sym = KeycodeToKeysym(eventPtr->xkey.keycode, state, 0);
}
if ((sym == NoSymbol) && (state & ShiftMask)) {
- state &= ~ShiftMask;
- sym = KeycodeToKeysym(eventPtr->xkey.keycode, state, 0);
+ state &= ~ShiftMask;
+ sym = KeycodeToKeysym(eventPtr->xkey.keycode, state, 0);
}
return sym;
}
@@ -415,10 +420,9 @@ TkpGetKeySym(dispPtr, eventPtr)
*
* TkpInitKeymapInfo --
*
- * This procedure 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".
+ * 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.
@@ -430,8 +434,8 @@ TkpGetKeySym(dispPtr, eventPtr)
*/
void
-TkpInitKeymapInfo(dispPtr)
- TkDisplay *dispPtr; /* Display for which to recompute keymap
+TkpInitKeymapInfo(
+ TkDisplay *dispPtr) /* Display for which to recompute keymap
* information. */
{
XModifierKeymap *modMapPtr;
@@ -444,9 +448,9 @@ TkpInitKeymapInfo(dispPtr)
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.
+ * 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;
@@ -467,9 +471,9 @@ TkpInitKeymapInfo(dispPtr)
}
/*
- * 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.
+ * 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;
@@ -522,13 +526,13 @@ TkpInitKeymapInfo(dispPtr)
KeyCode *new;
/*
- * Ran out of space in the array; grow it.
+ * Ran out of space in the array; grow it.
*/
arraySize *= 2;
new = (KeyCode *) ckalloc((unsigned)
(arraySize * sizeof(KeyCode)));
- memcpy((VOID *) new, (VOID *) dispPtr->modKeyCodes,
+ memcpy((void *) new, (void *) dispPtr->modKeyCodes,
(dispPtr->numModKeyCodes * sizeof(KeyCode)));
ckfree((char *) dispPtr->modKeyCodes);
dispPtr->modKeyCodes = new;
@@ -541,51 +545,49 @@ TkpInitKeymapInfo(dispPtr)
}
/*
- * 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.
+ * 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(tkwin, keySym, eventPtr)
- Tk_Window tkwin;
- KeySym keySym;
- XEvent *eventPtr;
+TkpSetKeycodeAndState(
+ Tk_Window tkwin,
+ KeySym keySym,
+ XEvent *eventPtr)
{
int i;
SHORT result;
int shift;
-
+
eventPtr->xkey.keycode = 0;
if (keySym == NoSymbol) {
- return;
+ 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.
+ * 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;
+ eventPtr->xkey.keycode = i;
+ return;
}
}
if (keySym >= 0x20) {
result = VkKeyScan((char) 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);
+ 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);
}
}
}
@@ -607,19 +609,19 @@ TkpSetKeycodeAndState(tkwin, keySym, eventPtr)
*/
KeyCode
-XKeysymToKeycode(display, keysym)
- Display* display;
- KeySym keysym;
+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.
+ * 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;
}
@@ -655,10 +657,11 @@ XKeysymToKeycode(display, keysym)
*/
XModifierKeymap *
-XGetModifierMapping(display)
- Display* display;
+XGetModifierMapping(
+ Display *display)
{
- XModifierKeymap *map = (XModifierKeymap *)ckalloc(sizeof(XModifierKeymap));
+ XModifierKeymap *map = (XModifierKeymap *)
+ ckalloc(sizeof(XModifierKeymap));
map->max_keypermod = 1;
map->modifiermap = (KeyCode *) ckalloc(sizeof(KeyCode)*8);
@@ -678,8 +681,7 @@ XGetModifierMapping(display)
*
* XFreeModifiermap --
*
- * Deallocate a modifier map that was created by
- * XGetModifierMapping.
+ * Deallocate a modifier map that was created by XGetModifierMapping.
*
* Results:
* None.
@@ -691,8 +693,8 @@ XGetModifierMapping(display)
*/
void
-XFreeModifiermap(modmap)
- XModifierKeymap* modmap;
+XFreeModifiermap(
+ XModifierKeymap *modmap)
{
ckfree((char *) modmap->modifiermap);
ckfree((char *) modmap);
@@ -703,11 +705,11 @@ XFreeModifiermap(modmap)
*
* XStringToKeysym --
*
- * Translate a keysym name to the matching keysym.
+ * 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.
+ * Returns the keysym. Since this is already handled by Tk's
+ * StringToKeysym function, we just return NoSymbol.
*
* Side effects:
* None.
@@ -716,8 +718,8 @@ XFreeModifiermap(modmap)
*/
KeySym
-XStringToKeysym(string)
- _Xconst char *string;
+XStringToKeysym(
+ _Xconst char *string)
{
return NoSymbol;
}
@@ -739,8 +741,16 @@ XStringToKeysym(string)
*/
char *
-XKeysymToString(keysym)
- KeySym keysym;
+XKeysymToString(
+ KeySym keysym)
{
return NULL;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c
index fe6132f..686c47d 100644
--- a/win/tkWinMenu.c
+++ b/win/tkWinMenu.c
@@ -1,15 +1,18 @@
-/*
+/*
* tkWinMenu.c --
*
- * This module implements the Windows platform-specific features of menus.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#define WINVER 0x0500 /* Requires Windows 2K definitions */
+#define _WIN32_WINNT 0x0500
#define OEMRESOURCE
#include "tkWinInt.h"
#include "tkMenu.h"
@@ -20,59 +23,88 @@
* The class of the window for popup menus.
*/
-#define MENU_CLASS_NAME "MenuWindowClass"
+#define MENU_CLASS_NAME "MenuWindowClass"
+#define EMBEDDED_MENU_CLASS_NAME "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
+#define ALIGN_BITMAP_LEFT 0x00000001
+#define ALIGN_BITMAP_RIGHT 0x00000002
+#define ALIGN_BITMAP_TOP 0x00000004
+#define ALIGN_BITMAP_BOTTOM 0x00000008
-#ifndef TPM_NOANIMATION
-#define TPM_NOANIMATION 0x4000L
-#endif
/*
* 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_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.
+ * 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
+#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. */
+ /* 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. */
+ WORD lastCommandID; /* The last command ID we allocated. */
HWND menuHWND; /* A window to service popup-menu messages
* in. */
- 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. */
+ 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
+ * 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. */
+ * 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;
@@ -87,90 +119,78 @@ static Tcl_DString menuFontDString;
/* A buffer to store the default menu font
* string. */
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void DrawMenuEntryAccelerator _ANSI_ARGS_((
- 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 _ANSI_ARGS_((
- TkMenu *menuPtr, TkMenuEntry *mePtr,
- Drawable d, GC gc,
+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, int drawArrow));
-static void DrawMenuEntryBackground _ANSI_ARGS_((
- TkMenu *menuPtr, TkMenuEntry *mePtr,
- Drawable d, Tk_3DBorder activeBorder,
- Tk_3DBorder bgBorder, int x, int y,
- int width, int heigth));
-static void DrawMenuEntryIndicator _ANSI_ARGS_((
- 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 _ANSI_ARGS_((
- 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 DrawMenuSeparator _ANSI_ARGS_((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 _ANSI_ARGS_((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 _ANSI_ARGS_((TkMenu *menuPtr,
+ 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,
- Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x,
- int y, int width, int height));
-static void DrawWindowsSystemBitmap _ANSI_ARGS_((
- Display *display, Drawable drawable,
- GC gc, CONST RECT *rectPtr, int bitmapID,
- int alignFlags));
-static void FreeID _ANSI_ARGS_((WORD commandID));
-static TCHAR * GetEntryText _ANSI_ARGS_((TkMenuEntry *mePtr));
-static void GetMenuAccelGeometry _ANSI_ARGS_((TkMenu *menuPtr,
+ 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 TCHAR * GetEntryText(TkMenuEntry *mePtr);
+static void GetMenuAccelGeometry(TkMenu *menuPtr,
TkMenuEntry *mePtr, Tk_Font tkfont,
- CONST Tk_FontMetrics *fmPtr, int *widthPtr,
- int *heightPtr));
-static void GetMenuLabelGeometry _ANSI_ARGS_((TkMenuEntry *mePtr,
- Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
- int *widthPtr, int *heightPtr));
-static void GetMenuIndicatorGeometry _ANSI_ARGS_((
- TkMenu *menuPtr, TkMenuEntry *mePtr,
- Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
- int *widthPtr, int *heightPtr));
-static void GetMenuSeparatorGeometry _ANSI_ARGS_((
- TkMenu *menuPtr, TkMenuEntry *mePtr,
- Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,
- int *widthPtr, int *heightPtr));
-static void GetTearoffEntryGeometry _ANSI_ARGS_((TkMenu *menuPtr,
+ 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 int GetNewID _ANSI_ARGS_((TkMenuEntry *mePtr,
- WORD *menuIDPtr));
-static int MenuKeyBindProc _ANSI_ARGS_((
- ClientData clientData,
- Tcl_Interp *interp, XEvent *eventPtr,
- Tk_Window tkwin, KeySym keySym));
-static void MenuSelectEvent _ANSI_ARGS_((TkMenu *menuPtr));
-static void ReconfigureWindowsMenu _ANSI_ARGS_((
- ClientData clientData));
-static void RecursivelyClearActiveMenu _ANSI_ARGS_((
- TkMenu *menuPtr));
-static void SetDefaults _ANSI_ARGS_((int firstTime));
-static LRESULT CALLBACK TkWinMenuProc _ANSI_ARGS_((HWND hwnd,
- UINT message, WPARAM wParam,
- LPARAM lParam));
-
-
+ 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);
/*
*----------------------------------------------------------------------
@@ -180,56 +200,47 @@ static LRESULT CALLBACK TkWinMenuProc _ANSI_ARGS_((HWND hwnd,
* 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.
+ * 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.
+ * 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(mePtr, menuIDPtr)
- TkMenuEntry *mePtr; /* The menu we are working with */
- WORD *menuIDPtr; /* The resulting id */
+GetNewID(
+ TkMenuEntry *mePtr, /* The menu we are working with. */
+ WORD *menuIDPtr) /* The resulting id. */
{
- int found = 0;
- int newEntry;
- Tcl_HashEntry *commandEntryPtr;
- WORD returnID;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
WORD curID = tsdPtr->lastCommandID + 1;
/*
* The following code relies on WORD wrapping when the highest value is
* incremented.
*/
-
+
while (curID != tsdPtr->lastCommandID) {
+ Tcl_HashEntry *commandEntryPtr;
+ int newEntry;
+
commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable,
- (char *) curID, &newEntry);
+ ((char *) NULL) + curID, &newEntry);
if (newEntry == 1) {
- found = 1;
- returnID = curID;
- break;
+ Tcl_SetHashValue(commandEntryPtr, (char *) mePtr);
+ *menuIDPtr = curID;
+ tsdPtr->lastCommandID = curID;
+ return TCL_OK;
}
curID++;
}
-
- if (found) {
- Tcl_SetHashValue(commandEntryPtr, (char *) mePtr);
- *menuIDPtr = returnID;
- tsdPtr->lastCommandID = returnID;
- return TCL_OK;
- } else {
- return TCL_ERROR;
- }
+ return TCL_ERROR;
}
/*
@@ -249,11 +260,11 @@ GetNewID(mePtr, menuIDPtr)
*/
static void
-FreeID(commandID)
- WORD commandID;
+FreeID(
+ WORD commandID)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
* If the menuHWND is NULL, this table has been finalized already.
@@ -261,7 +272,7 @@ FreeID(commandID)
if (tsdPtr->menuHWND != NULL) {
Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
- (char *) commandID);
+ ((char *) NULL) + commandID);
if (entryPtr != NULL) {
Tcl_DeleteHashEntry(entryPtr);
}
@@ -287,15 +298,15 @@ FreeID(commandID)
*/
int
-TkpNewMenu(menuPtr)
- TkMenu *menuPtr; /* The common structure we are making the
- * platform structure for. */
+TkpNewMenu(
+ TkMenu *menuPtr) /* The common structure we are making the
+ * platform structure for. */
{
HMENU winMenuHdl;
Tcl_HashEntry *hashEntryPtr;
int newEntry;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
winMenuHdl = CreatePopupMenu();
@@ -306,8 +317,8 @@ TkpNewMenu(menuPtr)
}
/*
- * We hash all of the HMENU's so that we can get their menu ptrs
- * back when dispatch messages.
+ * We hash all of the HMENU's so that we can get their menu ptrs back when
+ * dispatch messages.
*/
hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable,
@@ -335,18 +346,18 @@ TkpNewMenu(menuPtr)
*/
void
-TkpDestroyMenu(menuPtr)
- TkMenu *menuPtr; /* The common menu structure */
+TkpDestroyMenu(
+ TkMenu *menuPtr) /* The common menu structure */
{
HMENU winMenuHdl = (HMENU) menuPtr->platformData;
char *searchName;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
Tcl_CancelIdleCall(ReconfigureWindowsMenu, (ClientData) menuPtr);
}
-
+
if (winMenuHdl == NULL) {
return;
}
@@ -354,7 +365,7 @@ TkpDestroyMenu(menuPtr)
if (menuPtr->menuFlags & MENU_SYSTEM_MENU) {
TkMenuEntry *searchEntryPtr;
Tcl_HashTable *tablePtr = TkGetMenuHashTable(menuPtr->interp);
- char *menuName = Tcl_GetHashKey(tablePtr,
+ char *menuName = Tcl_GetHashKey(tablePtr,
menuPtr->menuRefPtr->hashEntryPtr);
/*
@@ -364,16 +375,16 @@ TkpDestroyMenu(menuPtr)
*/
for (searchEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
- searchEntryPtr != NULL;
- searchEntryPtr = searchEntryPtr->nextCascadePtr) {
- searchName = Tcl_GetStringFromObj(searchEntryPtr->namePtr, NULL);
+ searchEntryPtr != NULL;
+ searchEntryPtr = searchEntryPtr->nextCascadePtr) {
+ searchName = Tcl_GetString(searchEntryPtr->namePtr);
if (strcmp(searchName, menuName) == 0) {
Tk_Window parentTopLevelPtr = searchEntryPtr
- ->menuPtr->parentTopLevelPtr;
+ ->menuPtr->parentTopLevelPtr;
if (parentTopLevelPtr != NULL) {
- GetSystemMenu(TkWinGetWrapperWindow(parentTopLevelPtr),
- TRUE);
+ GetSystemMenu(
+ TkWinGetWrapperWindow(parentTopLevelPtr), TRUE);
}
break;
}
@@ -417,19 +428,19 @@ TkpDestroyMenu(menuPtr)
*/
void
-TkpDestroyMenuEntry(mePtr)
- TkMenuEntry *mePtr; /* The entry to destroy */
+TkpDestroyMenuEntry(
+ TkMenuEntry *mePtr) /* The entry to destroy */
{
TkMenu *menuPtr = mePtr->menuPtr;
HMENU winMenuHdl = (HMENU) menuPtr->platformData;
if (NULL != winMenuHdl) {
- if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
+ if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);
}
}
- FreeID((WORD) mePtr->platformEntryData);
+ FreeID((WORD) (UINT) mePtr->platformEntryData);
mePtr->platformEntryData = NULL;
}
@@ -439,9 +450,9 @@ TkpDestroyMenuEntry(mePtr)
* 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.
+ * 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.
@@ -453,8 +464,8 @@ TkpDestroyMenuEntry(mePtr)
*/
static char *
-GetEntryText(mePtr)
- TkMenuEntry *mePtr; /* A pointer to the menu entry. */
+GetEntryText(
+ TkMenuEntry *mePtr) /* A pointer to the menu entry. */
{
char *itemText;
@@ -472,18 +483,17 @@ GetEntryText(mePtr)
strcpy(itemText, "( )");
} else {
int i;
- char *label = (mePtr->labelPtr == NULL) ? ""
- : Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
- char *accel = (mePtr->accelPtr == NULL) ? ""
- : Tcl_GetStringFromObj(mePtr->accelPtr, NULL);
- CONST char *p, *next;
+ char *label = (mePtr->labelPtr == NULL) ? ""
+ : Tcl_GetString(mePtr->labelPtr);
+ char *accel = (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.
+ * 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);
@@ -498,7 +508,7 @@ GetEntryText(mePtr)
next = Tcl_UtfNext(p);
Tcl_DStringAppend(&itemString, p, (int) (next - p));
}
- if (mePtr->accelLength > 0) {
+ if (mePtr->accelLength > 0) {
Tcl_DStringAppend(&itemString, "\t", 1);
for (p = accel, i = 0; *p != '\0'; i++, p = next) {
if (*p == '&') {
@@ -509,7 +519,7 @@ GetEntryText(mePtr)
}
}
- itemText = ckalloc(Tcl_DStringLength(&itemString) + 1);
+ itemText = ckalloc((unsigned)Tcl_DStringLength(&itemString) + 1);
strcpy(itemText, Tcl_DStringValue(&itemString));
Tcl_DStringFree(&itemString);
}
@@ -527,15 +537,15 @@ GetEntryText(mePtr)
* None.
*
* Side effects:
- * Configuration information get set for mePtr; old resources
- * get freed, if any need it.
+ * Configuration information get set for mePtr; old resources get freed,
+ * if any need it.
*
*----------------------------------------------------------------------
*/
static void
ReconfigureWindowsMenu(
- ClientData clientData) /* The menu we are rebuilding */
+ ClientData clientData) /* The menu we are rebuilding */
{
TkMenu *menuPtr = (TkMenu *) clientData;
TkMenuEntry *mePtr;
@@ -545,9 +555,8 @@ ReconfigureWindowsMenu(
UINT flags;
UINT itemID;
int i, count, systemMenu = 0, base;
- int width = 0, height = 0;
Tcl_DString translatedText;
-
+
if (NULL == winMenuHdl) {
return;
}
@@ -555,15 +564,8 @@ ReconfigureWindowsMenu(
/*
* Reconstruct the entire menu. Takes care of nasty system menu and index
* problem.
- *
*/
- if ((menuPtr->menuType == MENUBAR)
- && (menuPtr->parentTopLevelPtr != NULL)) {
- width = Tk_Width(menuPtr->parentTopLevelPtr);
- height = Tk_Height(menuPtr->parentTopLevelPtr);
- }
-
base = (menuPtr->menuFlags & MENU_SYSTEM_MENU) ? 7 : 0;
count = GetMenuItemCount(winMenuHdl);
for (i = base; i < count; i++) {
@@ -596,37 +598,37 @@ ReconfigureWindowsMenu(
/*
* 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
+ * 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 = (UINT) mePtr->platformEntryData;
if ((mePtr->type == CASCADE_ENTRY)
&& (mePtr->childMenuRefPtr != NULL)
@@ -634,44 +636,45 @@ ReconfigureWindowsMenu(
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.
+ /*
+ * 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.
+ * If the MF_POPUP flag is set, then the id is interpreted
+ * as the handle of a submenu.
*/
itemID = (UINT) childMenuHdl;
- }
+ }
}
- if ((menuPtr->menuType == MENUBAR)
+ 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)
+
+ if ((menuRefPtr != NULL)
&& (menuRefPtr->menuPtr != NULL)
&& (menuPtr->parentTopLevelPtr != NULL)
&& (systemMenuPtr->masterMenuPtr
== menuRefPtr->menuPtr)) {
- HMENU systemMenuHdl =
+ HMENU systemMenuHdl =
(HMENU) systemMenuPtr->platformData;
HWND wrapper = TkWinGetWrapperWindow(menuPtr
->parentTopLevelPtr);
@@ -679,12 +682,12 @@ ReconfigureWindowsMenu(
DestroyMenu(systemMenuHdl);
systemMenuHdl = GetSystemMenu(wrapper, FALSE);
systemMenuPtr->menuFlags |= MENU_SYSTEM_MENU;
- systemMenuPtr->platformData =
- (TkMenuPlatformData) systemMenuHdl;
- if (!(systemMenuPtr->menuFlags
+ systemMenuPtr->platformData =
+ (TkMenuPlatformData) systemMenuHdl;
+ if (!(systemMenuPtr->menuFlags
& MENU_RECONFIGURE_PENDING)) {
- systemMenuPtr->menuFlags
- |= MENU_RECONFIGURE_PENDING;
+ systemMenuPtr->menuFlags
+ |= MENU_RECONFIGURE_PENDING;
Tcl_DoWhenIdle(ReconfigureWindowsMenu,
(ClientData) systemMenuPtr);
}
@@ -708,12 +711,15 @@ ReconfigureWindowsMenu(
}
- if ((menuPtr->menuType == MENUBAR)
+ if ((menuPtr->menuType == MENUBAR)
&& (menuPtr->parentTopLevelPtr != NULL)) {
- DrawMenuBar(TkWinGetWrapperWindow(menuPtr->parentTopLevelPtr));
- Tk_GeometryRequest(menuPtr->parentTopLevelPtr, width, height);
+ HANDLE bar;
+ bar = TkWinGetWrapperWindow(menuPtr->parentTopLevelPtr);
+ if (bar) {
+ DrawMenuBar(bar);
+ }
}
-
+
menuPtr->menuFlags &= ~(MENU_RECONFIGURE_PENDING);
}
@@ -734,21 +740,19 @@ ReconfigureWindowsMenu(
*/
int
-TkpPostMenu(interp, menuPtr, x, y)
- Tcl_Interp *interp;
- TkMenu *menuPtr;
- int x;
- int y;
+TkpPostMenu(
+ Tcl_Interp *interp,
+ TkMenu *menuPtr,
+ int x, int y)
{
HMENU winMenuHdl = (HMENU) menuPtr->platformData;
- int i, result, flags;
+ int result, flags;
RECT noGoawayRect;
POINT point;
Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin);
int oldServiceMode = Tcl_GetServiceMode();
- TkMenuEntry *mePtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
tsdPtr->inPostMenu++;
@@ -809,19 +813,7 @@ TkpPostMenu(interp, menuPtr, x, y)
}
}
- /*
- * Disable menu animation if an image is present, as clipping isn't
- * handled correctly with temp DCs. [Bug 1329198]
- */
- for (i = 0; i < menuPtr->numEntries; i++) {
- mePtr = menuPtr->entries[i];
- if (mePtr->image != NULL) {
- flags |= TPM_NOANIMATION;
- break;
- }
- }
-
- TrackPopupMenu(winMenuHdl, flags, x, y, 0,
+ TrackPopupMenu(winMenuHdl, flags, x, y, 0,
tsdPtr->menuHWND, &noGoawayRect);
Tcl_SetServiceMode(oldServiceMode);
@@ -853,8 +845,8 @@ TkpPostMenu(interp, menuPtr, x, y)
*/
int
-TkpMenuNewEntry(mePtr)
- TkMenuEntry *mePtr;
+TkpMenuNewEntry(
+ TkMenuEntry *mePtr)
{
WORD commandID;
TkMenu *menuPtr = mePtr->menuPtr;
@@ -867,8 +859,8 @@ TkpMenuNewEntry(mePtr)
menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);
}
-
- mePtr->platformEntryData = (TkMenuPlatformEntryData) commandID;
+
+ mePtr->platformEntryData = (TkMenuPlatformEntryData) (UINT) commandID;
return TCL_OK;
}
@@ -892,11 +884,11 @@ TkpMenuNewEntry(mePtr)
*/
static LRESULT CALLBACK
-TkWinMenuProc(hwnd, message, wParam, lParam)
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
+TkWinMenuProc(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
LRESULT lResult;
@@ -909,321 +901,420 @@ TkWinMenuProc(hwnd, message, wParam, lParam)
/*
*----------------------------------------------------------------------
*
+ * 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 = (ThreadSpecificData *)
+ 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
+ * 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.
+ * 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(phwnd, pMessage, pwParam, plParam, plResult)
- HWND *phwnd;
- UINT *pMessage;
- WPARAM *pwParam;
- LPARAM *plParam;
- LRESULT *plResult;
+TkWinHandleMenuEvent(
+ HWND *phwnd,
+ UINT *pMessage,
+ WPARAM *pwParam,
+ LPARAM *plParam,
+ LRESULT *plResult)
{
Tcl_HashEntry *hashEntryPtr;
int returnResult = 0;
TkMenu *menuPtr;
TkMenuEntry *mePtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
switch (*pMessage) {
- case WM_UNINITMENUPOPUP:
- hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
- (char *) *pwParam);
- if (hashEntryPtr != NULL) {
- menuPtr = (TkMenu *) 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 = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
- tsdPtr->modalMenuPtr = menuPtr;
- if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
- Tcl_CancelIdleCall(ReconfigureWindowsMenu,
- (ClientData) menuPtr);
- ReconfigureWindowsMenu((ClientData) menuPtr);
- }
- RecursivelyClearActiveMenu(menuPtr);
- if (!tsdPtr->inPostMenu) {
- Tcl_Interp *interp;
- int code;
-
- interp = menuPtr->interp;
- Tcl_Preserve((ClientData)interp);
- code = TkPreprocessMenu(menuPtr);
- if ((code != TCL_OK) && (code != TCL_CONTINUE)
- && (code != TCL_BREAK)) {
- Tcl_AddErrorInfo(interp, "\n (menu preprocess)");
- Tcl_BackgroundError(interp);
- }
- Tcl_Release((ClientData)interp);
- }
- TkActivateMenuEntry(menuPtr, -1);
- *plResult = 0;
- returnResult = 1;
- } else {
- tsdPtr->modalMenuPtr = NULL;
+ case WM_UNINITMENUPOPUP:
+ hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
+ (char *) *pwParam);
+ if (hashEntryPtr != NULL) {
+ menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
+ if ((menuPtr->menuRefPtr != NULL)
+ && (menuPtr->menuRefPtr->parentEntryPtr != NULL)) {
+ TkPostSubmenu(menuPtr->interp,
+ menuPtr->menuRefPtr->parentEntryPtr->menuPtr, NULL);
}
- break;
-
- case WM_SYSCOMMAND:
- case WM_COMMAND: {
- TkMenuInit();
- if (HIWORD(*pwParam) != 0) {
- break;
- }
- hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
- (char *)LOWORD(*pwParam));
- if (hashEntryPtr == NULL) {
- break;
+ }
+ break;
+
+ case WM_INITMENU:
+ TkMenuInit();
+ hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
+ (char *) *pwParam);
+ if (hashEntryPtr != NULL) {
+ tsdPtr->oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
+ menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
+ tsdPtr->modalMenuPtr = menuPtr;
+ if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {
+ Tcl_CancelIdleCall(ReconfigureWindowsMenu,
+ (ClientData) menuPtr);
+ ReconfigureWindowsMenu((ClientData) menuPtr);
}
- mePtr = (TkMenuEntry *) Tcl_GetHashValue(hashEntryPtr);
- if (mePtr != NULL) {
- TkMenuReferences *menuRefPtr;
- TkMenuEntry *parentEntryPtr;
+ RecursivelyClearActiveMenu(menuPtr);
+ if (!tsdPtr->inPostMenu) {
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)) {
- char *name;
-
- for (parentEntryPtr = menuRefPtr->parentEntryPtr;
- ;
- parentEntryPtr =
- parentEntryPtr->nextCascadePtr) {
- name = Tcl_GetStringFromObj(
- parentEntryPtr->namePtr, NULL);
- 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((ClientData)interp);
- code = TkInvokeMenu(interp, menuPtr, mePtr->index);
- if (code != TCL_OK && code != TCL_CONTINUE
- && code != TCL_BREAK) {
- Tcl_AddErrorInfo(interp, "\n (menu invoke)");
+ code = TkPreprocessMenu(menuPtr);
+ if ((code != TCL_OK) && (code != TCL_CONTINUE)
+ && (code != TCL_BREAK)) {
+ Tcl_AddErrorInfo(interp, "\n (menu preprocess)");
Tcl_BackgroundError(interp);
}
Tcl_Release((ClientData)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,
+ ((char *) NULL) + LOWORD(*pwParam));
+ if (hashEntryPtr == NULL) {
break;
}
+ mePtr = (TkMenuEntry *) 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.
+ */
- case WM_MENUCHAR: {
- hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
- (char *) *plParam);
- if (hashEntryPtr != NULL) {
- int i, len, underline;
- Tcl_Obj *labelPtr;
- Tcl_UniChar *wlabel, menuChar;
+ menuPtr = mePtr->menuPtr;
+ menuRefPtr = TkFindMenuReferences(menuPtr->interp,
+ Tk_PathName(menuPtr->tkwin));
+ if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) {
+ for (parentEntryPtr = menuRefPtr->parentEntryPtr ; ;
+ parentEntryPtr = parentEntryPtr->nextCascadePtr) {
+ char *name = Tcl_GetString(parentEntryPtr->namePtr);
- *plResult = 0;
- menuPtr = (TkMenu *) 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;
- }
+ if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
+ break;
}
}
+ if (parentEntryPtr->menuPtr->entries[parentEntryPtr->index]
+ ->state != ENTRY_DISABLED) {
+ TkActivateMenuEntry(parentEntryPtr->menuPtr,
+ parentEntryPtr->index);
+ }
}
- break;
- }
- case WM_MEASUREITEM: {
- LPMEASUREITEMSTRUCT itemPtr = (LPMEASUREITEMSTRUCT) *plParam;
+ interp = menuPtr->interp;
+ Tcl_Preserve((ClientData)interp);
+ code = TkInvokeMenu(interp, menuPtr, mePtr->index);
+ if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
+ Tcl_AddErrorInfo(interp, "\n (menu invoke)");
+ Tcl_BackgroundError(interp);
+ }
+ Tcl_Release((ClientData)interp);
+ *plResult = 0;
+ returnResult = 1;
+ }
+ break;
- if (itemPtr != NULL) {
- mePtr = (TkMenuEntry *) itemPtr->itemData;
- menuPtr = mePtr->menuPtr;
+ case WM_MENUCHAR: {
+ hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
+ (char *) *plParam);
+ if (hashEntryPtr != NULL) {
+ int i, len, underline;
+ Tcl_Obj *labelPtr;
+ Tcl_UniChar *wlabel, menuChar;
- TkRecomputeMenu(menuPtr);
- itemPtr->itemHeight = mePtr->height;
- itemPtr->itemWidth = mePtr->width;
- if (mePtr->hideMargin) {
- itemPtr->itemWidth += 2 - indicatorDimensions[1];
- } else {
- int activeBorderWidth;
+ *plResult = 0;
+ menuPtr = (TkMenu *) 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));
- Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,
- menuPtr->activeBorderWidthPtr,
- &activeBorderWidth);
- itemPtr->itemWidth += 2 * activeBorderWidth;
+ 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;
+ }
}
- *plResult = 1;
- returnResult = 1;
}
- break;
}
+ break;
+ }
- case WM_DRAWITEM: {
- TkWinDrawable *twdPtr;
- LPDRAWITEMSTRUCT itemPtr = (LPDRAWITEMSTRUCT) *plParam;
- Tk_FontMetrics fontMetrics;
- int drawArrow = 0;
+ case WM_MEASUREITEM: {
+ LPMEASUREITEMSTRUCT itemPtr = (LPMEASUREITEMSTRUCT) *plParam;
- if (itemPtr != NULL) {
- Tk_Font tkfont;
+ if (itemPtr != NULL && tsdPtr->modalMenuPtr != NULL) {
+ mePtr = (TkMenuEntry *) itemPtr->itemData;
+ menuPtr = mePtr->menuPtr;
- mePtr = (TkMenuEntry *) itemPtr->itemData;
- menuPtr = mePtr->menuPtr;
- twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable));
- twdPtr->type = TWD_WINDC;
- twdPtr->winDC.hdc = itemPtr->hDC;
+ TkRecomputeMenu(menuPtr);
+ itemPtr->itemHeight = mePtr->height;
+ itemPtr->itemWidth = mePtr->width;
+ if (mePtr->hideMargin) {
+ itemPtr->itemWidth += 2 - indicatorDimensions[1];
+ } else {
+ int activeBorderWidth;
- if (mePtr->state != ENTRY_DISABLED) {
- if (itemPtr->itemState & ODS_SELECTED) {
- TkActivateMenuEntry(menuPtr, mePtr->index);
- } else {
- TkActivateMenuEntry(menuPtr, -1);
- }
+ 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 = (TkWinDrawable *) 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 {
- /* 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 drawArrow flag for a disabled cascade
- ** menu since we need to draw the arrow ourselves.
- */
- if (mePtr->type == CASCADE_ENTRY) {
- drawArrow = 1;
- }
+ 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.
+ */
- 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, drawArrow);
+ if (itemPtr->itemState & ODS_SELECTED) {
+ mePtr->entryFlags |= ENTRY_PLATFORM_FLAG1;
+ } else {
+ mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1;
+ }
- ckfree((char *) twdPtr);
- *plResult = 1;
- returnResult = 1;
+ /*
+ * 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;
+ }
}
- break;
+
+ 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((char *) twdPtr);
}
+ *plResult = 1;
+ returnResult = 1;
+ break;
+ }
- case WM_MENUSELECT: {
- UINT flags = HIWORD(*pwParam);
+ case WM_MENUSELECT: {
+ UINT flags = HIWORD(*pwParam);
- TkMenuInit();
+ 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 = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
- }
+ 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 = (TkMenu *) Tcl_GetHashValue(hashEntryPtr);
}
+ }
- if (menuPtr != NULL) {
- mePtr = NULL;
- if (flags != 0xFFFF) {
- if (flags & MF_POPUP) {
- mePtr = menuPtr->entries[LOWORD(*pwParam)];
- } else {
- hashEntryPtr = Tcl_FindHashEntry(
- &tsdPtr->commandTable,
- (char *) LOWORD(*pwParam));
- if (hashEntryPtr != NULL) {
- mePtr = (TkMenuEntry *)
- Tcl_GetHashValue(hashEntryPtr);
- }
- }
- }
+ if (menuPtr != NULL) {
+ long entryIndex = LOWORD(*pwParam);
- if ((mePtr == NULL) || (mePtr->state == ENTRY_DISABLED)) {
- TkActivateMenuEntry(menuPtr, -1);
+ mePtr = NULL;
+ if (flags != 0xFFFF) {
+ if ((flags&MF_POPUP) && (entryIndex<menuPtr->numEntries)) {
+ mePtr = menuPtr->entries[entryIndex];
} else {
- if (mePtr->index >= menuPtr->numEntries) {
- Tcl_Panic("Trying to activate an entry which doesn't exist.");
+ hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
+ ((char *) NULL) + entryIndex);
+ if (hashEntryPtr != NULL) {
+ mePtr = (TkMenuEntry *)
+ Tcl_GetHashValue(hashEntryPtr);
}
- TkActivateMenuEntry(menuPtr, mePtr->index);
}
- MenuSelectEvent(menuPtr);
- Tcl_ServiceAll();
}
+
+ 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;
}
+ break;
+ }
}
return returnResult;
}
@@ -1250,7 +1341,7 @@ RecursivelyClearActiveMenu(
{
int i;
TkMenuEntry *mePtr;
-
+
TkActivateMenuEntry(menuPtr, -1);
MenuSelectEvent(menuPtr);
for (i = 0; i < menuPtr->numEntries; i++) {
@@ -1286,26 +1377,27 @@ RecursivelyClearActiveMenu(
*/
void
-TkpSetWindowMenuBar(tkwin, menuPtr)
- Tk_Window tkwin; /* The window we are putting the menubar into.*/
- TkMenu *menuPtr; /* The menu we are inserting */
+TkpSetWindowMenuBar(
+ Tk_Window tkwin, /* The window we are putting the menubar
+ * into.*/
+ TkMenu *menuPtr) /* The menu we are inserting */
{
HMENU winMenuHdl;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (menuPtr != NULL) {
Tcl_HashEntry *hashEntryPtr;
int newEntry;
winMenuHdl = (HMENU) menuPtr->platformData;
- hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
- (char *) winMenuHdl);
+ hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
+ (char *) winMenuHdl);
Tcl_DeleteHashEntry(hashEntryPtr);
DestroyMenu(winMenuHdl);
winMenuHdl = CreateMenu();
- hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable,
- (char *) winMenuHdl, &newEntry);
+ hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable,
+ (char *) winMenuHdl, &newEntry);
Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr);
menuPtr->platformData = (TkMenuPlatformData) winMenuHdl;
TkWinSetMenu(tkwin, winMenuHdl);
@@ -1323,8 +1415,8 @@ TkpSetWindowMenuBar(tkwin, menuPtr)
*
* TkpSetMainMenubar --
*
- * Puts the menu associated with a window into the menubar. Should
- * only be called when the window is in front.
+ * Puts the menu associated with a window into the menubar. Should only
+ * be called when the window is in front.
*
* Results:
* None.
@@ -1334,13 +1426,13 @@ TkpSetWindowMenuBar(tkwin, menuPtr)
*
*----------------------------------------------------------------------
*/
+
void
TkpSetMainMenubar(
Tcl_Interp *interp, /* The interpreter of the application */
Tk_Window tkwin, /* The frame we are setting up */
- char *menuName) /* The name of the menu to put in front.
- * If NULL, use the default menu bar.
- */
+ char *menuName) /* The name of the menu to put in front. If
+ * NULL, use the default menu bar. */
{
/*
* Nothing to do.
@@ -1364,13 +1456,13 @@ TkpSetMainMenubar(
*/
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 */
+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) {
@@ -1401,13 +1493,13 @@ GetMenuIndicatorGeometry (
*/
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 */
+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) {
@@ -1415,7 +1507,8 @@ GetMenuAccelGeometry (
} else if (mePtr->accelPtr == NULL) {
*widthPtr = 0;
} else {
- char *accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL);
+ char *accel = Tcl_GetString(mePtr->accelPtr);
+
*widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength);
}
}
@@ -1437,13 +1530,13 @@ GetMenuAccelGeometry (
*/
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 */
+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;
@@ -1470,13 +1563,13 @@ GetTearoffEntryGeometry (
*/
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 */
+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);
@@ -1487,10 +1580,10 @@ GetMenuSeparatorGeometry (
*
* 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.
+ * 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.
@@ -1502,15 +1595,15 @@ GetMenuSeparatorGeometry (
*/
static void
-DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags)
- 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. */
+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);
@@ -1520,7 +1613,7 @@ DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags)
POINT ptSize;
POINT ptOrg;
int topOffset, leftOffset;
-
+
SetBkColor(hdc, gc->background);
SetTextColor(hdc, gc->foreground);
@@ -1552,7 +1645,7 @@ DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags)
} 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);
@@ -1566,38 +1659,38 @@ DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags)
*
* DrawMenuEntryIndicator --
*
- * This procedure draws the indicator part of a menu.
+ * 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.
+ * Commands are output to X to display the menu in its current mode.
*
*----------------------------------------------------------------------
*/
+
void
-DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x,
- y, width, height)
- 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;
+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)
+ 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 {
@@ -1617,21 +1710,21 @@ DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x,
&& (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,
+ DrawWindowsSystemBitmap(menuPtr->display, d, whichGC,
&hilightRect, OBM_CHECK, 0);
whichGC->foreground = oldFgColor;
}
- DrawWindowsSystemBitmap(menuPtr->display, d, whichGC, &rect,
+ DrawWindowsSystemBitmap(menuPtr->display, d, whichGC, &rect,
OBM_CHECK, 0);
}
- }
+ }
}
/*
@@ -1639,11 +1732,10 @@ DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x,
*
* DrawMenuEntryAccelerator --
*
- * This procedure 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?
+ * 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.
@@ -1656,49 +1748,51 @@ DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x,
*/
void
-DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
- activeBorder, x, y, width, height)
- 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 */
+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;
- char *accel = NULL;
-
+ char *accel;
+
if (mePtr->accelPtr != NULL) {
- accel = Tcl_GetStringFromObj(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. */
+ /*
+ * 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)
- && (mePtr->accelPtr != NULL)) {
+ if ((mePtr->state == ENTRY_DISABLED)
+ && (menuPtr->disabledFgPtr != NULL) && (accel != NULL)) {
COLORREF oldFgColor = gc->foreground;
gc->foreground = GetSysColor(COLOR_3DHILIGHT);
- if ((mePtr->accelPtr != NULL) &&
- ((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0)) {
- Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
- mePtr->accelLength, leftEdge + 1, baseline + 1);
+ if ((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0) {
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
+ mePtr->accelLength, leftEdge + 1, baseline + 1);
}
gc->foreground = oldFgColor;
}
}
- if (mePtr->accelPtr != NULL) {
- Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
+ if (accel != NULL) {
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
mePtr->accelLength, leftEdge, baseline);
}
}
@@ -1708,8 +1802,9 @@ DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
*
* DrawMenuEntryArrow --
*
- * This function draws the arrow bitmap on the right side of a
- * a menu entry. This function is currently unused.
+ * 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.
@@ -1721,44 +1816,47 @@ DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
*/
void
-DrawMenuEntryArrow(menuPtr, mePtr, d, gc,
- activeBorder, x, y, width, height, drawArrow)
- 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. */
+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;
+ if (!drawArrow || (mePtr->type != CASCADE_ENTRY)) {
+ return;
+ }
oldFgColor = gc->foreground;
oldBgColor = gc->background;
- /* Set bitmap bg to highlight color if the menu is highlighted */
+ /*
+ * 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;
+ 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 : COLOR_MENUTEXT);
+ 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);
@@ -1766,7 +1864,7 @@ DrawMenuEntryArrow(menuPtr, mePtr, d, gc,
rect.right = x + width;
DrawWindowsSystemBitmap(menuPtr->display, d, gc, &rect, OBM_MNARROW,
- ALIGN_BITMAP_RIGHT);
+ ALIGN_BITMAP_RIGHT);
gc->foreground = oldFgColor;
gc->background = oldBgColor;
@@ -1784,23 +1882,23 @@ DrawMenuEntryArrow(menuPtr, mePtr, d, gc,
* None.
*
* Side effects:
- * Commands are output to X to display the menu in its
- * current mode.
+ * Commands are output to X to display the menu in its current mode.
*
*----------------------------------------------------------------------
*/
+
void
-DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height)
- 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 */
+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;
@@ -1810,7 +1908,7 @@ DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height)
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_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,
TK_RELIEF_RAISED);
}
@@ -1825,23 +1923,23 @@ DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height)
* None.
*
* Side effects:
- * Commands are output to X to display the menu in its
- * current mode.
+ * 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 */
+ 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;
@@ -1849,7 +1947,7 @@ DrawMenuUnderline(
/* do the unicode call just to prevent overruns */
Tcl_GetUnicodeFromObj(mePtr->labelPtr, &len);
if (mePtr->underline < len) {
- CONST char *label, *start, *end;
+ const char *label, *start, *end;
label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
start = Tcl_UtfAtIndex(label, mePtr->underline);
@@ -1865,68 +1963,95 @@ DrawMenuUnderline(
/*
*--------------------------------------------------------------
*
- * MenuKeyBindProc --
+ * TkWinMenuKeyObjCmd --
*
- * This procedure is invoked when keys related to pulling
- * down menus is pressed. The corresponding Windows events
- * are generated and passed to DefWindowProc if appropriate.
+ * 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.
+ * The menu system may take over and process user events for menu input.
*
*--------------------------------------------------------------
*/
static int
-MenuKeyBindProc(clientData, interp, eventPtr, tkwin, keySym)
- ClientData clientData; /* not used in this proc */
- Tcl_Interp *interp; /* The interpreter of the receiving window. */
- XEvent *eventPtr; /* The XEvent to process */
- Tk_Window tkwin; /* The window receiving the event */
- KeySym keySym; /* The key sym that is produced. */
+TkWinMenuKeyObjCmd(
+ ClientData clientData, /* Unused. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
UINT scanCode;
UINT virtualKey;
- TkWindow *winPtr = (TkWindow *)tkwin;
+ 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, (scanCode << 16)
- | (1 << 29));
+ 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, (scanCode << 16)
- | (1 << 29) | (1 << 24));
+ 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, (scanCode << 16));
+ 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, ((scanCode << 16)
- | (1 << 29)));
- if (eventPtr->xkey.nbytes > 0) {
- for (i = 0; i < eventPtr->xkey.nbytes; i++) {
+ 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,
- eventPtr->xkey.trans_chars[i],
- ((scanCode << 16) | (1 << 29)));
+ Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR,
+ xkey.trans_chars[i],
+ (int) ((scanCode << 16) | (1 << 29)));
}
}
}
@@ -1936,83 +2061,96 @@ MenuKeyBindProc(clientData, interp, eventPtr, tkwin, keySym)
case XK_Alt_L:
scanCode = MapVirtualKey(VK_LMENU, 0);
CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
- WM_SYSKEYUP, VK_MENU, (scanCode << 16)
+ 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, (scanCode << 16) | (1 << 24)
+ WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16) | (1 << 24)
| (0x111 << 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, (scanCode << 16)
- | (1 << 30) | (1 << 31));
+ 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, ((scanCode << 16)
+ 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.
+ * For every interp, initializes the bindings for Windows menus. Does
+ * nothing on Mac or XWindows.
*
* Results:
* None.
*
* Side effects:
- * C-level bindings are setup for the interp which will
- * handle Alt-key sequences for menus without beeping
- * or interfering with user-defined Alt-key bindings.
+ * 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(interp, bindingTable)
- Tcl_Interp *interp; /* The interpreter to set. */
- Tk_BindingTable bindingTable; /* The table to add to. */
+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 have a C-level
- * binding for this. We have to generate the WM_SYSKEYDOWNS
- * and WM_SYSKEYUPs appropriately.
+ * 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.
*/
-
- TkCreateBindingProcedure(interp, bindingTable, (ClientData)uid,
- "<Alt_L>", MenuKeyBindProc, NULL, NULL);
- TkCreateBindingProcedure(interp, bindingTable, (ClientData)uid,
- "<KeyRelease-Alt_L>", MenuKeyBindProc, NULL, NULL);
- TkCreateBindingProcedure(interp, bindingTable, (ClientData)uid,
- "<Alt_R>", MenuKeyBindProc, NULL, NULL);
- TkCreateBindingProcedure(interp, bindingTable, (ClientData)uid,
- "<KeyRelease-Alt_R>", MenuKeyBindProc, NULL, NULL);
- TkCreateBindingProcedure(interp, bindingTable, (ClientData)uid,
- "<Alt-KeyPress>", MenuKeyBindProc, NULL, NULL);
- TkCreateBindingProcedure(interp, bindingTable, (ClientData)uid,
- "<Alt-KeyRelease>", MenuKeyBindProc, NULL, NULL);
- TkCreateBindingProcedure(interp, bindingTable, (ClientData)uid,
- "<KeyPress-F10>", MenuKeyBindProc, NULL, NULL);
- TkCreateBindingProcedure(interp, bindingTable, (ClientData)uid,
- "<KeyRelease-F10>", MenuKeyBindProc, NULL, NULL);
+
+ (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);
}
/*
@@ -2020,7 +2158,7 @@ TkpInitializeMenuBindings(interp, bindingTable)
*
* DrawMenuEntryLabel --
*
- * This procedure draws the label part of a menu.
+ * This function draws the label part of a menu.
*
* Results:
* None.
@@ -2031,24 +2169,26 @@ TkpInitializeMenuBindings(interp, bindingTable)
*
*----------------------------------------------------------------------
*/
+
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 */
+ 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 indicatorSpace = mePtr->indicatorSpace;
int activeBorderWidth;
int leftEdge;
int imageHeight, imageWidth;
- int textHeight, textWidth;
+ int textHeight = 0, textWidth = 0;
int haveImage = 0, haveText = 0;
int imageXOffset = 0, imageYOffset = 0;
int textXOffset = 0, textYOffset = 0;
@@ -2063,21 +2203,22 @@ DrawMenuEntryLabel(
if (mePtr->image != NULL) {
Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
- haveImage = 1;
+ 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) {
- char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
+ if (mePtr->labelLength > 0) {
+ 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.
*/
@@ -2085,56 +2226,53 @@ DrawMenuEntryLabel(
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;
+ 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;
}
- 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;
+ imageXOffset = -indicatorSpace;
}
- case COMPOUND_NONE: {break;}
+ 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;
@@ -2142,7 +2280,7 @@ DrawMenuEntryLabel(
imageXOffset = 0;
imageYOffset = 0;
}
-
+
/*
* Draw label and/or bitmap or image for entry.
*/
@@ -2152,42 +2290,47 @@ DrawMenuEntryLabel(
&& (mePtr->entryFlags & ENTRY_SELECTED)) {
Tk_RedrawImage(mePtr->selectImage, 0, 0,
imageWidth, imageHeight, d, leftEdge + imageXOffset,
- (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset));
+ (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));
+ (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,
+ 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;
- char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
+ 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) == 0)) {
- COLORREF oldFgColor = gc->foreground;
+ /*
+ * 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) == 0)) {
+ 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);
+ 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,
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, label,
+ mePtr->labelLength, leftEdge + textXOffset,
baseline + textYOffset);
- DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr,
- x + textXOffset, y + textYOffset,
- width, height);
+ if (underline) {
+ DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr,
+ x + textXOffset, y + textYOffset, width, height);
+ }
}
}
@@ -2195,7 +2338,7 @@ DrawMenuEntryLabel(
if (menuPtr->disabledFgPtr == NULL) {
XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y,
(unsigned) width, (unsigned) height);
- } else if ((mePtr->image != NULL)
+ } else if ((mePtr->image != NULL)
&& (menuPtr->disabledImageGC != None)) {
XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC,
leftEdge + imageXOffset,
@@ -2210,23 +2353,22 @@ DrawMenuEntryLabel(
*
* TkpComputeMenubarGeometry --
*
- * This procedure is invoked to recompute the size and
- * layout of a menu that is a menubar clone.
+ * 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.
+ * Fields of menu entries are changed to reflect their current positions,
+ * and the size of the menu window itself may be changed.
*
*--------------------------------------------------------------
*/
void
-TkpComputeMenubarGeometry(menuPtr)
- TkMenu *menuPtr; /* Structure describing menu. */
+TkpComputeMenubarGeometry(
+ TkMenu *menuPtr) /* Structure describing menu. */
{
TkpComputeStandardMenuGeometry(menuPtr);
}
@@ -2236,30 +2378,27 @@ TkpComputeMenubarGeometry(menuPtr)
*
* DrawTearoffEntry --
*
- * This procedure draws the background part of a menu.
+ * 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.
+ * Commands are output to X to display the menu in its current mode.
*
*----------------------------------------------------------------------
*/
void
-DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height)
- 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;
+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;
@@ -2268,12 +2407,12 @@ DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height)
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;
+ maxX = width - 1;
border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
while (points[0].x < maxX) {
@@ -2295,21 +2434,20 @@ DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height)
* Processes configurations for menu entries.
*
* Results:
- * Returns standard TCL result. If TCL_ERROR is returned, then
- * the interp's result contains an error message.
+ * 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.
+ * Configuration information get set for mePtr; old resources get freed,
+ * if any need it.
*
*----------------------------------------------------------------------
*/
int
-TkpConfigureMenuEntry(mePtr)
- register TkMenuEntry *mePtr; /* Information about menu entry; may
- * or may not already have values for
- * some fields. */
+TkpConfigureMenuEntry(
+ register TkMenuEntry *mePtr)/* Information about menu entry; may or may
+ * not already have values for some fields. */
{
TkMenu *menuPtr = mePtr->menuPtr;
@@ -2325,8 +2463,8 @@ TkpConfigureMenuEntry(mePtr)
*
* TkpDrawMenuEntry --
*
- * Draws the given menu entry at the given coordinates with the
- * given attributes.
+ * Draws the given menu entry at the given coordinates with the given
+ * attributes.
*
* Results:
* None.
@@ -2338,30 +2476,59 @@ TkpConfigureMenuEntry(mePtr)
*/
void
-TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height,
- strictMotif, drawArrow)
- TkMenuEntry *mePtr; /* The entry to draw */
- Drawable d; /* What 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 drawArrow; /* Whether or not to draw the cascade
- * arrow for cascade items. Only applies
- * to Windows. */
+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;
+ const Tk_FontMetrics *fmPtr;
Tk_FontMetrics entryMetrics;
int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0;
- int adjustedY = y + padY;
+ 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.
@@ -2376,11 +2543,11 @@ TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height,
TkMenuEntry *cascadeEntryPtr;
int parentDisabled = 0;
char *name;
-
+
for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
cascadeEntryPtr != NULL;
cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
- name = Tcl_GetStringFromObj(cascadeEntryPtr->namePtr, NULL);
+ name = Tcl_GetString(cascadeEntryPtr->namePtr);
if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
if (mePtr->state == ENTRY_DISABLED) {
parentDisabled = 1;
@@ -2427,32 +2594,46 @@ TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height,
}
/*
- * 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.
+ * 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, x, y, width, height);
-
+
+ DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder,
+ bgBorder, adjustedX, adjustedY-padY, width, height);
+
if (mePtr->type == SEPARATOR_ENTRY) {
- DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont,
- fmPtr, x, adjustedY, width, adjustedHeight);
+ DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont,
+ fmPtr, adjustedX, adjustedY, width, adjustedHeight);
} else if (mePtr->type == TEAROFF_ENTRY) {
- DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
- width, adjustedHeight);
+ DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr,
+ adjustedX, adjustedY, width, adjustedHeight);
} else {
- DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
- width, adjustedHeight);
+ 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, x, adjustedY, width, adjustedHeight);
+ activeBorder, adjustedX, adjustedY, width, adjustedHeight);
DrawMenuEntryArrow(menuPtr, mePtr, d, gc,
- activeBorder, x, adjustedY, width, adjustedHeight, drawArrow);
+ activeBorder, adjustedX, adjustedY, width, adjustedHeight,
+ (drawingParameters & DRAW_MENU_ENTRY_ARROW)?1:0);
if (!mePtr->hideMargin) {
DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont,
- fmPtr, x, adjustedY, width, adjustedHeight);
+ 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);
+ }
}
/*
@@ -2473,18 +2654,17 @@ TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height,
*/
static void
-GetMenuLabelGeometry(mePtr, tkfont, fmPtr, widthPtr, heightPtr)
- 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 */
+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;
@@ -2496,54 +2676,72 @@ GetMenuLabelGeometry(mePtr, tkfont, fmPtr, widthPtr, heightPtr)
*heightPtr = 0;
*widthPtr = 0;
}
-
+
if (haveImage && (mePtr->compound == COMPOUND_NONE)) {
- /* We don't care about the text in this case */
+ /*
+ * We don't care about the text in this case.
+ */
} else {
- /* Either it is compound or we don't have an image */
+ /*
+ * Either it is compound or we don't have an image,
+ */
+
if (mePtr->labelPtr != NULL) {
int textWidth;
- char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
+ 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_TOP:
+ case COMPOUND_BOTTOM:
+ if (textWidth > *widthPtr) {
+ *widthPtr = textWidth;
}
- case COMPOUND_LEFT:
- case COMPOUND_RIGHT: {
- if (fmPtr->linespace > *heightPtr) {
- *heightPtr = fmPtr->linespace;
- }
- /* Add text and padding */
- *widthPtr += textWidth + 2;
- break;
+
+ /*
+ * Add text and padding.
+ */
+
+ *heightPtr += fmPtr->linespace + 2;
+ break;
+ case COMPOUND_LEFT:
+ case COMPOUND_RIGHT:
+ if (fmPtr->linespace > *heightPtr) {
+ *heightPtr = fmPtr->linespace;
}
- case COMPOUND_CENTER: {
- if (fmPtr->linespace > *heightPtr) {
- *heightPtr = fmPtr->linespace;
- }
- if (textWidth > *widthPtr) {
- *widthPtr = textWidth;
- }
- break;
+
+ /*
+ * Add text and padding.
+ */
+
+ *widthPtr += textWidth + 2;
+ break;
+ case COMPOUND_CENTER:
+ if (fmPtr->linespace > *heightPtr) {
+ *heightPtr = fmPtr->linespace;
+ }
+ if (textWidth > *widthPtr) {
+ *widthPtr = textWidth;
}
- case COMPOUND_NONE: {break;}
+ break;
+ case COMPOUND_NONE:
+ break;
}
- } else {
- /* We don't have an image or we're not compound */
+ } 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 */
+ /*
+ * An empty entry still has this height.
+ */
+
*heightPtr = fmPtr->linespace;
}
}
@@ -2555,36 +2753,35 @@ GetMenuLabelGeometry(mePtr, tkfont, fmPtr, widthPtr, heightPtr)
*
* DrawMenuEntryBackground --
*
- * This procedure draws the background part of a menu.
+ * 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.
+ * 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 */
+ 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
+ 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);
+ Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height, 0,
+ TK_RELIEF_FLAT);
}
/*
@@ -2592,16 +2789,15 @@ DrawMenuEntryBackground(
*
* TkpComputeStandardMenuGeometry --
*
- * This procedure is invoked to recompute the size and
- * layout of a menu that is not a menubar clone.
+ * 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.
+ * Fields of menu entries are changed to reflect their current positions,
+ * and the size of the menu window itself may be changed.
*
*--------------------------------------------------------------
*/
@@ -2616,26 +2812,25 @@ TkpComputeStandardMenuGeometry(
int windowWidth, windowHeight, accelSpace;
int i, j, lastColumnBreak = 0;
int activeBorderWidth, borderWidth;
-
+
if (menuPtr->tkwin == NULL) {
return;
}
- Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,
+ 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.
+ * 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);
@@ -2678,28 +2873,27 @@ TkpComputeStandardMenuGeometry(
fmPtr, &width, &height);
menuPtr->entries[i]->height = height;
} else if (menuPtr->entries[i]->type == TEAROFF_ENTRY) {
- GetTearoffEntryGeometry(menuPtr, menuPtr->entries[i], tkfont,
+ 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.
+ * 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) {
@@ -2709,7 +2903,7 @@ TkpComputeStandardMenuGeometry(
accelWidth = width;
}
- GetMenuIndicatorGeometry(menuPtr, menuPtr->entries[i], tkfont,
+ GetMenuIndicatorGeometry(menuPtr, menuPtr->entries[i], tkfont,
fmPtr, &width, &height);
if (height > menuPtr->entries[i]->height) {
menuPtr->entries[i]->height = height;
@@ -2720,7 +2914,7 @@ TkpComputeStandardMenuGeometry(
menuPtr->entries[i]->height += 2 * activeBorderWidth + 1;
}
- menuPtr->entries[i]->y = y;
+ menuPtr->entries[i]->y = y;
y += menuPtr->entries[i]->height;
if (y > windowHeight) {
windowHeight = y;
@@ -2743,10 +2937,10 @@ TkpComputeStandardMenuGeometry(
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).
+ * 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) {
@@ -2764,8 +2958,8 @@ TkpComputeStandardMenuGeometry(
*
* MenuSelectEvent --
*
- * Generates a "MenuSelect" virtual event. This can be used to
- * do context-sensitive menu help.
+ * Generates a "MenuSelect" virtual event. This can be used to do
+ * context-sensitive menu help.
*
* Results:
* None.
@@ -2781,9 +2975,8 @@ MenuSelectEvent(
TkMenu *menuPtr) /* the menu we have selected. */
{
XVirtualEvent event;
- POINTS rootPoint;
- DWORD msgPos;
-
+ union {DWORD msgpos; POINTS point;} root;
+
event.type = VirtualEvent;
event.serial = menuPtr->display->request;
event.send_event = 0;
@@ -2793,14 +2986,14 @@ MenuSelectEvent(
event.root = XRootWindow(menuPtr->display, 0);
event.subwindow = None;
event.time = TkpGetMS();
-
- msgPos = GetMessagePos();
- rootPoint = MAKEPOINTS(msgPos);
- event.x_root = rootPoint.x;
- event.y_root = rootPoint.y;
+
+ 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);
}
@@ -2810,8 +3003,8 @@ MenuSelectEvent(
* 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.
+ * menuName becuase a toplevel has been created and any system menus need
+ * to be created.
*
* Results:
* None.
@@ -2824,9 +3017,8 @@ MenuSelectEvent(
void
TkpMenuNotifyToplevelCreate(
- Tcl_Interp *interp, /* The interp the menu lives in. */
- char *menuName) /* The name of the menu to
- * reconfigure. */
+ Tcl_Interp *interp, /* The interp the menu lives in. */
+ char *menuName) /* The name of the menu to reconfigure. */
{
TkMenuReferences *menuRefPtr;
TkMenu *menuPtr;
@@ -2836,10 +3028,10 @@ TkpMenuNotifyToplevelCreate(
if ((menuRefPtr != NULL) && (menuRefPtr->menuPtr != NULL)) {
for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL;
menuPtr = menuPtr->nextInstancePtr) {
- if ((menuPtr->menuType == MENUBAR)
+ if ((menuPtr->menuType == MENUBAR)
&& !(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {
menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;
- Tcl_DoWhenIdle(ReconfigureWindowsMenu,
+ Tcl_DoWhenIdle(ReconfigureWindowsMenu,
(ClientData) menuPtr);
}
}
@@ -2850,6 +3042,35 @@ TkpMenuNotifyToplevelCreate(
/*
*----------------------------------------------------------------------
*
+ * 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 = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ TkMenuInit();
+ return tsdPtr->embeddedMenuHWND;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* MenuExitHandler --
*
* Unregisters the class of utility windows.
@@ -2868,6 +3089,7 @@ MenuExitHandler(
ClientData clientData) /* Not used */
{
UnregisterClass(MENU_CLASS_NAME, Tk_GetHINSTANCE());
+ UnregisterClass(EMBEDDED_MENU_CLASS_NAME, Tk_GetHINSTANCE());
}
/*
@@ -2895,7 +3117,9 @@ MenuThreadExitHandler(
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);
@@ -2910,9 +3134,9 @@ MenuThreadExitHandler(
* 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.
+ * 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.
@@ -2923,8 +3147,8 @@ MenuThreadExitHandler(
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. */
+ const char *dbName, /* The option database name. */
+ const char *className) /* The name of the option class. */
{
Tcl_Obj *valuePtr = NULL;
@@ -2932,8 +3156,7 @@ TkWinGetMenuSystemDefault(
(strcmp(dbName, "borderWidth") == 0)) {
valuePtr = Tcl_NewIntObj(defaultBorderWidth);
} else if (strcmp(dbName, "font") == 0) {
- valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString),
- -1);
+ valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString), -1);
}
return valuePtr;
@@ -2942,30 +3165,29 @@ TkWinGetMenuSystemDefault(
/*
*----------------------------------------------------------------------
*
- * TkWinMenuSetDefaults --
+ * SetDefaults --
*
- * Sets up the hash tables and the variables used by the menu package.
+ * 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:
- * lastMenuID gets initialized, and the parent hash and the command hash
- * are allocated.
+ * May result in menu items being redrawn with different appearance.
*
*----------------------------------------------------------------------
*/
-void
+static void
SetDefaults(
- int firstTime) /* Is this the first time this
- * has been called? */
+ int firstTime) /* Is this the first time this has been
+ * called? */
{
char sizeString[TCL_INTEGER_SPACE];
char faceName[LF_FACESIZE];
HDC scratchDC;
- Tcl_DString boldItalicDString;
- int bold = 0;
+ int bold = 0;
int italic = 0;
TEXTMETRIC tm;
int pointSize;
@@ -2980,8 +3202,8 @@ SetDefaults(
OSVERSIONINFO os;
/*
- * Set all of the default options. The loop will terminate when we run
- * out of options via a break statement.
+ * Set all of the default options. The loop will terminate when we run out
+ * of options via a break statement.
*/
defaultBorderWidth = GetSystemMetrics(SM_CXBORDER);
@@ -3022,44 +3244,56 @@ SetDefaults(
DeleteDC(scratchDC);
DeleteObject(menuFont);
-
+
Tcl_DStringAppendElement(&menuFontDString, faceName);
sprintf(sizeString, "%d", pointSize);
Tcl_DStringAppendElement(&menuFontDString, sizeString);
- if (bold == 1 || italic == 1) {
+ if (bold || italic) {
+ Tcl_DString boldItalicDString;
+
Tcl_DStringInit(&boldItalicDString);
- if (bold == 1) {
+ if (bold) {
Tcl_DStringAppendElement(&boldItalicDString, "bold");
}
- if (italic == 1) {
+ if (italic) {
Tcl_DStringAppendElement(&boldItalicDString, "italic");
}
- Tcl_DStringAppendElement(&menuFontDString,
+ 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.
+ * 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 insure menu items lining up, and is not
- * documented.
+ * 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.
*/
if (TkWinGetPlatformId() >= VER_PLATFORM_WIN32_WINDOWS) {
indicatorDimensions[0] = GetSystemMetrics(SM_CYMENUCHECK);
indicatorDimensions[1] = ((GetSystemMetrics(SM_CXFIXEDFRAME) +
- GetSystemMetrics(SM_CXBORDER)
+ GetSystemMetrics(SM_CXBORDER)
+ GetSystemMetrics(SM_CXMENUCHECK) + 7) & 0xFFF8)
- GetSystemMetrics(SM_CXFIXEDFRAME);
} else {
DWORD dimensions = GetMenuCheckMarkDimensions();
indicatorDimensions[0] = HIWORD(dimensions);
indicatorDimensions[1] = LOWORD(dimensions);
- }
+ }
+
+ /*
+ * Accelerators used to be always underlines until Win2K when a system
+ * parameter was introduced to hide them unless Alt is pressed.
+ */
+
+ showMenuAccelerators = TRUE;
+ if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
+ SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &showMenuAccelerators, 0);
+ }
}
/*
@@ -3079,7 +3313,7 @@ SetDefaults(
*/
void
-TkpMenuInit()
+TkpMenuInit(void)
{
WNDCLASS wndClass;
@@ -3093,7 +3327,15 @@ TkpMenuInit()
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = MENU_CLASS_NAME;
- RegisterClass(&wndClass);
+ 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, (ClientData) NULL);
SetDefaults(1);
@@ -3104,7 +3346,8 @@ TkpMenuInit()
*
* TkpMenuThreadInit --
*
- * Sets up the thread-local hash tables used by the menu module.
+ * Sets up the thread-local hash tables used by the menu module. Assumes
+ * that TkpMenuInit has been called.
*
* Results:
* None.
@@ -3116,16 +3359,36 @@ TkpMenuInit()
*/
void
-TkpMenuThreadInit()
+TkpMenuThreadInit(void)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
tsdPtr->menuHWND = CreateWindow(MENU_CLASS_NAME, "MenuWindow", WS_POPUP,
- 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL);
+ 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, "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);
- Tcl_CreateThreadExitHandler(MenuThreadExitHandler, (ClientData) NULL);
+ TkCreateThreadExitHandler(MenuThreadExitHandler, (ClientData) NULL);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinPixmap.c b/win/tkWinPixmap.c
index 4a7954f..8eff2c5 100644
--- a/win/tkWinPixmap.c
+++ b/win/tkWinPixmap.c
@@ -1,17 +1,16 @@
-/*
+/*
* tkWinPixmap.c --
*
- * This file contains the Xlib emulation functions pertaining to
- * creating and destroying pixmaps.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkWinInt.h"
-
/*
*----------------------------------------------------------------------
@@ -30,23 +29,23 @@
*/
Pixmap
-Tk_GetPixmap(display, d, width, height, depth)
- Display* display;
- Drawable d;
- int width;
- int height;
- int depth;
+Tk_GetPixmap(
+ Display *display,
+ Drawable d,
+ int width,
+ int height,
+ int depth)
{
TkWinDrawable *newTwdPtr, *twdPtr;
int planes;
Screen *screen;
-
+
display->request++;
newTwdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable));
newTwdPtr->type = TWD_BITMAP;
newTwdPtr->bitmap.depth = depth;
- twdPtr = (TkWinDrawable *)d;
+ twdPtr = (TkWinDrawable *) d;
if (twdPtr->type != TWD_BITMAP) {
if (twdPtr->window.winPtr == NULL) {
newTwdPtr->bitmap.colormap = DefaultColormap(display,
@@ -74,7 +73,7 @@ Tk_GetPixmap(display, d, width, height, depth)
if (newTwdPtr->bitmap.handle == NULL) {
static int repeatError = 0;
- unsigned char *bits = NULL;
+ void *bits = NULL;
BITMAPINFO bitmapInfo;
HDC dc;
@@ -88,7 +87,7 @@ Tk_GetPixmap(display, d, width, height, depth)
bitmapInfo.bmiHeader.biSizeImage = 0;
dc = GetDC(NULL);
newTwdPtr->bitmap.handle = CreateDIBSection(dc, &bitmapInfo,
- DIB_RGB_COLORS, (void **) &bits, 0, 0);
+ DIB_RGB_COLORS, &bits, 0, 0);
ReleaseDC(NULL, dc);
/*
@@ -118,8 +117,8 @@ Tk_GetPixmap(display, d, width, height, depth)
ckfree((char *) newTwdPtr);
return None;
}
-
- return (Pixmap)newTwdPtr;
+
+ return (Pixmap) newTwdPtr;
}
/*
@@ -139,16 +138,16 @@ Tk_GetPixmap(display, d, width, height, depth)
*/
void
-Tk_FreePixmap(display, pixmap)
- Display* display;
- Pixmap pixmap;
+Tk_FreePixmap(
+ Display *display,
+ Pixmap pixmap)
{
TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap;
display->request++;
if (twdPtr != NULL) {
DeleteObject(twdPtr->bitmap.handle);
- ckfree((char *)twdPtr);
+ ckfree((char *) twdPtr);
}
}
@@ -170,9 +169,9 @@ Tk_FreePixmap(display, pixmap)
*/
void
-TkSetPixmapColormap(pixmap, colormap)
- Pixmap pixmap;
- Colormap colormap;
+TkSetPixmapColormap(
+ Pixmap pixmap,
+ Colormap colormap)
{
TkWinDrawable *twdPtr = (TkWinDrawable *)pixmap;
twdPtr->bitmap.colormap = colormap;
@@ -183,9 +182,9 @@ TkSetPixmapColormap(pixmap, 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.
+ * 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.
@@ -197,17 +196,16 @@ TkSetPixmapColormap(pixmap, colormap)
*/
int
-XGetGeometry(display, d, root_return, x_return, y_return, width_return,
- height_return, border_width_return, depth_return)
- 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;
+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;
@@ -216,30 +214,38 @@ XGetGeometry(display, d, root_return, x_return, y_return, width_return,
BITMAPINFO info;
if (twdPtr->bitmap.handle == NULL) {
- 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)) {
- panic("XGetGeometry: unable to get bitmap size");
- }
- ReleaseDC(NULL, dc);
-
- *width_return = info.bmiHeader.biWidth;
- *height_return = info.bmiHeader.biHeight;
+ 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) {
- panic("XGetGeometry: invalid window");
- }
- GetClientRect(twdPtr->window.handle, &rect);
- *width_return = rect.right - rect.left;
- *height_return = rect.bottom - rect.top;
+ 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 {
- panic("XGetGeometry: invalid window");
+ Tcl_Panic("XGetGeometry: invalid window");
}
return 1;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinPointer.c b/win/tkWinPointer.c
index 0d9ed61..d29e952 100644
--- a/win/tkWinPointer.c
+++ b/win/tkWinPointer.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkWinPointer.c --
*
* Windows specific mouse tracking code.
@@ -6,8 +6,8 @@
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkWinInt.h"
@@ -31,7 +31,7 @@ static int mouseTimerSet = 0; /* 1 if the mouse timer is active. */
* Forward declarations of procedures used in this file.
*/
-static void MouseTimerProc _ANSI_ARGS_((ClientData clientData));
+static void MouseTimerProc(ClientData clientData);
/*
*----------------------------------------------------------------------
@@ -50,7 +50,7 @@ static void MouseTimerProc _ANSI_ARGS_((ClientData clientData));
*/
int
-TkWinGetModifierState()
+TkWinGetModifierState(void)
{
int state = 0;
@@ -89,10 +89,9 @@ TkWinGetModifierState()
*
* 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.
+ * 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.
@@ -104,11 +103,11 @@ TkWinGetModifierState()
*/
void
-Tk_PointerEvent(hwnd, x, y)
- HWND hwnd; /* Window for coords, or NULL for
- * the root window. */
- int x, y; /* Coords relative to hwnd, or screen
- * if hwnd is NULL. */
+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;
@@ -126,11 +125,11 @@ Tk_PointerEvent(hwnd, x, y)
}
/*
- * 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 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) {
@@ -166,14 +165,13 @@ Tk_PointerEvent(hwnd, x, y)
*/
int
-XGrabKeyboard(display, grab_window, owner_events, pointer_mode,
- keyboard_mode, time)
- Display* display;
- Window grab_window;
- Bool owner_events;
- int pointer_mode;
- int keyboard_mode;
- Time time;
+XGrabKeyboard(
+ Display *display,
+ Window grab_window,
+ Bool owner_events,
+ int pointer_mode,
+ int keyboard_mode,
+ Time time)
{
keyboardWinPtr = TkWinGetWinPtr(grab_window);
return GrabSuccess;
@@ -196,9 +194,9 @@ XGrabKeyboard(display, grab_window, owner_events, pointer_mode,
*/
void
-XUngrabKeyboard(display, time)
- Display* display;
- Time time;
+XUngrabKeyboard(
+ Display *display,
+ Time time)
{
keyboardWinPtr = NULL;
}
@@ -208,8 +206,7 @@ XUngrabKeyboard(display, time)
*
* MouseTimerProc --
*
- * Check the current mouse position and look for enter/leave
- * events.
+ * Check the current mouse position and look for enter/leave events.
*
* Results:
* None.
@@ -221,16 +218,16 @@ XUngrabKeyboard(display, time)
*/
void
-MouseTimerProc(clientData)
- ClientData clientData;
+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.
+ * 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);
@@ -254,7 +251,7 @@ MouseTimerProc(clientData)
*/
void
-TkWinCancelMouseTimer()
+TkWinCancelMouseTimer(void)
{
if (mouseTimerSet) {
Tcl_DeleteTimerHandler(mouseTimer);
@@ -270,8 +267,8 @@ TkWinCancelMouseTimer()
* 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.
+ * *xPtr and *yPtr are filled in with the root coordinates of the mouse
+ * pointer for the display.
*
* Side effects:
* None.
@@ -280,10 +277,10 @@ TkWinCancelMouseTimer()
*/
void
-TkGetPointerCoords(tkwin, xPtr, yPtr)
- Tk_Window tkwin; /* Window that identifies screen on which
+TkGetPointerCoords(
+ Tk_Window tkwin, /* Window that identifies screen on which
* lookup is to be done. */
- int *xPtr, *yPtr; /* Store pointer coordinates here. */
+ int *xPtr, int *yPtr) /* Store pointer coordinates here. */
{
POINT point;
@@ -297,13 +294,13 @@ TkGetPointerCoords(tkwin, xPtr, yPtr)
*
* 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.
+ * 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.
+ * Sets root_x_return, root_y_return, and mask_return. Returns true on
+ * success.
*
* Side effects:
* None.
@@ -312,17 +309,16 @@ TkGetPointerCoords(tkwin, xPtr, yPtr)
*/
Bool
-XQueryPointer(display, w, root_return, child_return, root_x_return,
- root_y_return, win_x_return, win_y_return, mask_return)
- 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;
+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);
@@ -335,8 +331,8 @@ XQueryPointer(display, w, root_return, child_return, root_x_return,
*
* XWarpPointer --
*
- * Move pointer to new location. This is not a complete
- * implementation of this function.
+ * Move pointer to new location. This is not a complete implementation of
+ * this function.
*
* Results:
* None.
@@ -348,22 +344,21 @@ XQueryPointer(display, w, root_return, child_return, root_x_return,
*/
void
-XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width,
- src_height, dest_x, dest_y)
- 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;
+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);
+ SetCursorPos(r.left+dest_x, r.top+dest_y);
}
/*
@@ -383,12 +378,13 @@ XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width,
*/
void
-XGetInputFocus(display, focus_return, revert_to_return)
- Display *display;
- Window *focus_return;
- int *revert_to_return;
+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++;
@@ -412,11 +408,11 @@ XGetInputFocus(display, focus_return, revert_to_return)
*/
void
-XSetInputFocus(display, focus, revert_to, time)
- Display* display;
- Window focus;
- int revert_to;
- Time time;
+XSetInputFocus(
+ Display *display,
+ Window focus,
+ int revert_to,
+ Time time)
{
display->request++;
if (focus != None) {
@@ -429,29 +425,28 @@ XSetInputFocus(display, focus, revert_to, time)
*
* TkpChangeFocus --
*
- * This procedure is invoked to move the system focus from
- * one window to another.
+ * 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.
+ * 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
+ * The official Windows focus window changes; the application's focus
* window isn't changed by this procedure.
*
*----------------------------------------------------------------------
*/
int
-TkpChangeFocus(winPtr, force)
- 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. */
+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;
@@ -467,12 +462,12 @@ TkpChangeFocus(winPtr, force)
}
if (winPtr->window == None) {
- panic("ChangeXFocus got null X window");
+ 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.
+ * 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) {
@@ -482,10 +477,10 @@ TkpChangeFocus(winPtr, force)
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.
+ * 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);
@@ -498,10 +493,9 @@ TkpChangeFocus(winPtr, force)
*
* 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.
+ * 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.
@@ -513,8 +507,8 @@ TkpChangeFocus(winPtr, force)
*/
void
-TkpSetCapture(winPtr)
- TkWindow *winPtr; /* Capture window, or NULL. */
+TkpSetCapture(
+ TkWindow *winPtr) /* Capture window, or NULL. */
{
if (winPtr) {
SetCapture(Tk_GetHWND(Tk_WindowId(winPtr)));
@@ -524,3 +518,11 @@ TkpSetCapture(winPtr)
ReleaseCapture();
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinPort.h b/win/tkWinPort.h
index f991195..9deefce 100644
--- a/win/tkWinPort.h
+++ b/win/tkWinPort.h
@@ -40,19 +40,43 @@
#endif
#include <time.h>
-#ifdef __CYGWIN__
-# define _T(x) L##x
-#else
-# include <tchar.h>
-#endif
#ifdef _MSC_VER
-# define hypot _hypot
+# ifndef hypot
+# define hypot _hypot
+# endif
#endif /* _MSC_VER */
-#ifndef __GNUC__
-# define strncasecmp strnicmp
-# define strcasecmp stricmp
+/*
+ * Pull in the typedef of TCHAR for windows.
+ */
+#if !defined(_TCHAR_DEFINED)
+# 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
+#endif
+
+#ifdef __CYGWIN__
+# ifndef _vsnprintf
+# define _vsnprintf vsnprintf
+# endif
+# ifndef _wcsicmp
+# define _wcsicmp wcscasecmp
+# endif
+#else
+# ifndef strncasecmp
+# define strncasecmp strnicmp
+# endif
+# ifndef strcasecmp
+# define strcasecmp stricmp
+# endif
#endif
#define NBBY 8
@@ -117,8 +141,4 @@
#define TkpCreateNativeBitmap(display, source) None
#define TkpGetNativeAppBitmap(display, name, w, h) None
-#ifndef _TCLINT
-#include <tclInt.h>
-#endif
-
#endif /* _WINPORT */
diff --git a/win/tkWinRegion.c b/win/tkWinRegion.c
index 713a6b1..a996ca5 100644
--- a/win/tkWinRegion.c
+++ b/win/tkWinRegion.c
@@ -1,12 +1,12 @@
-/*
+/*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkWinInt.h"
@@ -29,7 +29,7 @@
*/
TkRegion
-TkCreateRegion()
+TkCreateRegion(void)
{
RECT rect;
memset(&rect, 0, sizeof(RECT));
@@ -53,8 +53,8 @@ TkCreateRegion()
*/
void
-TkDestroyRegion(r)
- TkRegion r;
+TkDestroyRegion(
+ TkRegion r)
{
DeleteObject((HRGN) r);
}
@@ -76,11 +76,12 @@ TkDestroyRegion(r)
*/
void
-TkClipBox(r, rect_return)
- TkRegion r;
- XRectangle* rect_return;
+TkClipBox(
+ TkRegion r,
+ XRectangle* rect_return)
{
RECT rect;
+
GetRgnBox((HRGN)r, &rect);
rect_return->x = (short) rect.left;
rect_return->y = (short) rect.top;
@@ -105,10 +106,10 @@ TkClipBox(r, rect_return)
*/
void
-TkIntersectRegion(sra, srb, dr_return)
- TkRegion sra;
- TkRegion srb;
- TkRegion dr_return;
+TkIntersectRegion(
+ TkRegion sra,
+ TkRegion srb,
+ TkRegion dr_return)
{
CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_AND);
}
@@ -130,13 +131,14 @@ TkIntersectRegion(sra, srb, dr_return)
*/
void
-TkUnionRectWithRegion(rectangle, src_region, dest_region_return)
- XRectangle* rectangle;
- TkRegion src_region;
- TkRegion dest_region_return;
+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);
@@ -145,14 +147,84 @@ TkUnionRectWithRegion(rectangle, src_region, dest_region_return)
/*
*----------------------------------------------------------------------
*
+ * 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.
+ * Returns RectanglePart or RectangleOut. Note that this is not a
+ * complete implementation since it doesn't test for RectangleIn.
*
* Side effects:
* None.
@@ -161,12 +233,11 @@ TkUnionRectWithRegion(rectangle, src_region, dest_region_return)
*/
int
-TkRectInRegion(r, x, y, width, height)
- TkRegion r;
- int x;
- int y;
- unsigned int width;
- unsigned int height;
+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;
@@ -193,10 +264,18 @@ TkRectInRegion(r, x, y, width, height)
*/
void
-TkSubtractRegion(sra, srb, dr_return)
- TkRegion sra;
- TkRegion srb;
- TkRegion dr_return;
+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/win/tkWinScrlbr.c b/win/tkWinScrlbr.c
index 130daa6..5032912 100644
--- a/win/tkWinScrlbr.c
+++ b/win/tkWinScrlbr.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkWinScrollbar.c --
*
* This file implements the Windows specific portion of the scrollbar
@@ -6,19 +6,18 @@
*
* 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.
+ * 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.
+ * 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
@@ -37,7 +36,7 @@ typedef struct 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
@@ -58,8 +57,8 @@ static int vArrowWidth, vArrowHeight, vThumb; /* Vertical control metrics. */
TCL_DECLARE_MUTEX(winScrlbrMutex)
/*
- * This variable holds the default width for a scrollbar in string
- * form for use in a Tk_ConfigSpec.
+ * This variable holds the default width for a scrollbar in string form for
+ * use in a Tk_ConfigSpec.
*/
static char defWidth[TCL_INTEGER_SPACE];
@@ -68,18 +67,16 @@ static char defWidth[TCL_INTEGER_SPACE];
* Declarations for functions defined in this file.
*/
-static Window CreateProc _ANSI_ARGS_((Tk_Window tkwin,
- Window parent, ClientData instanceData));
-static void ModalLoopProc _ANSI_ARGS_((Tk_Window tkwin,
- XEvent *eventPtr));
-static int ScrollbarBindProc _ANSI_ARGS_((ClientData clientData,
+static Window CreateProc(Tk_Window tkwin, Window parent,
+ ClientData instanceData);
+static void ModalLoopProc(Tk_Window tkwin, XEvent *eventPtr);
+static int ScrollbarBindProc(ClientData clientData,
Tcl_Interp *interp, XEvent *eventPtr,
- Tk_Window tkwin, KeySym keySym));
-static LRESULT CALLBACK ScrollbarProc _ANSI_ARGS_((HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam));
-static void UpdateScrollbar _ANSI_ARGS_((
- WinScrollbar *scrollPtr));
-static void UpdateScrollbarMetrics _ANSI_ARGS_((void));
+ Tk_Window tkwin, KeySym keySym);
+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.
@@ -110,14 +107,14 @@ Tk_ClassProcs tkpScrollbarProcs = {
*/
TkScrollbar *
-TkpCreateScrollbar(tkwin)
- Tk_Window tkwin;
+TkpCreateScrollbar(
+ Tk_Window tkwin)
{
WinScrollbar *scrollPtr;
TkWindow *winPtr = (TkWindow *)tkwin;
-
+
if (!initialized) {
- Tcl_MutexLock(&winScrlbrMutex);
+ Tcl_MutexLock(&winScrlbrMutex);
UpdateScrollbarMetrics();
initialized = 1;
Tcl_MutexUnlock(&winScrlbrMutex);
@@ -140,7 +137,7 @@ TkpCreateScrollbar(tkwin)
ScrollbarBindProc, NULL, NULL);
}
- return (TkScrollbar*) scrollPtr;
+ return (TkScrollbar *) scrollPtr;
}
/*
@@ -148,8 +145,8 @@ TkpCreateScrollbar(tkwin)
*
* UpdateScrollbar --
*
- * This function updates the position and size of the scrollbar
- * thumb based on the current settings.
+ * This function updates the position and size of the scrollbar thumb
+ * based on the current settings.
*
* Results:
* None.
@@ -161,8 +158,8 @@ TkpCreateScrollbar(tkwin)
*/
static void
-UpdateScrollbar(scrollPtr)
- WinScrollbar *scrollPtr;
+UpdateScrollbar(
+ WinScrollbar *scrollPtr)
{
SCROLLINFO scrollInfo;
double thumbSize;
@@ -179,15 +176,17 @@ UpdateScrollbar(scrollPtr)
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)));
+ ((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].
+ * 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);
@@ -198,8 +197,8 @@ UpdateScrollbar(scrollPtr)
*
* CreateProc --
*
- * This function creates a new Scrollbar control, subclasses
- * the instance, and generates a new Window object.
+ * 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.
@@ -211,10 +210,10 @@ UpdateScrollbar(scrollPtr)
*/
static Window
-CreateProc(tkwin, parentWin, instanceData)
- Tk_Window tkwin; /* Token for window. */
- Window parentWin; /* Parent of new window. */
- ClientData instanceData; /* Scrollbar instance data. */
+CreateProc(
+ Tk_Window tkwin, /* Token for window. */
+ Window parentWin, /* Parent of new window. */
+ ClientData instanceData) /* Scrollbar instance data. */
{
DWORD style;
Window window;
@@ -226,10 +225,10 @@ CreateProc(tkwin, parentWin, instanceData)
if (scrollPtr->info.vertical) {
style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
- | SBS_VERT | SBS_RIGHTALIGN;
+ | SBS_VERT | SBS_RIGHTALIGN;
} else {
style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
- | SBS_HORZ | SBS_BOTTOMALIGN;
+ | SBS_HORZ | SBS_BOTTOMALIGN;
}
scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style,
@@ -238,14 +237,14 @@ CreateProc(tkwin, parentWin, instanceData)
/*
* Ensure new window is inserted into the stacking order at the correct
- * place.
+ * 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) {
+ winPtr = winPtr->nextPtr) {
if ((winPtr->window != None) && !(winPtr->flags & TK_TOP_HIERARCHY)) {
TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
Below);
@@ -254,13 +253,8 @@ CreateProc(tkwin, parentWin, instanceData)
}
scrollPtr->lastVertical = scrollPtr->info.vertical;
-#ifdef _WIN64
scrollPtr->oldProc = (WNDPROC)SetWindowLongPtr(scrollPtr->hwnd,
- GWLP_WNDPROC, (LONG_PTR) ScrollbarProc);
-#else
- scrollPtr->oldProc = (WNDPROC)SetWindowLong(scrollPtr->hwnd, GWL_WNDPROC,
- (DWORD) ScrollbarProc);
-#endif
+ GWLP_WNDPROC, (INT_PTR) ScrollbarProc);
window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);
UpdateScrollbar(scrollPtr);
@@ -272,9 +266,9 @@ CreateProc(tkwin, parentWin, instanceData)
*
* 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.
+ * 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.
@@ -286,8 +280,8 @@ CreateProc(tkwin, parentWin, instanceData)
*/
void
-TkpDisplayScrollbar(clientData)
- ClientData clientData; /* Information about window. */
+TkpDisplayScrollbar(
+ ClientData clientData) /* Information about window. */
{
WinScrollbar *scrollPtr = (WinScrollbar *) clientData;
Tk_Window tkwin = scrollPtr->info.tkwin;
@@ -298,18 +292,14 @@ TkpDisplayScrollbar(clientData)
}
/*
- * Destroy and recreate the scrollbar control if the orientation
- * has changed.
+ * Destroy and recreate the scrollbar control if the orientation has
+ * changed.
*/
if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));
-#ifdef _WIN64
- SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) scrollPtr->oldProc);
-#else
- SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) scrollPtr->oldProc);
-#endif
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) scrollPtr->oldProc);
DestroyWindow(hwnd);
CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
@@ -336,17 +326,14 @@ TkpDisplayScrollbar(clientData)
*/
void
-TkpDestroyScrollbar(scrollPtr)
- TkScrollbar *scrollPtr;
+TkpDestroyScrollbar(
+ TkScrollbar *scrollPtr)
{
WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
HWND hwnd = winScrollPtr->hwnd;
+
if (hwnd) {
-#ifdef _WIN64
- SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) winScrollPtr->oldProc);
-#else
- SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) winScrollPtr->oldProc);
-#endif
+ 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);
@@ -360,8 +347,7 @@ TkpDestroyScrollbar(scrollPtr)
*
* UpdateScrollbarMetrics --
*
- * This function retrieves the current system metrics for a
- * scrollbar.
+ * This function retrieves the current system metrics for a scrollbar.
*
* Results:
* None.
@@ -373,7 +359,7 @@ TkpDestroyScrollbar(scrollPtr)
*/
void
-UpdateScrollbarMetrics()
+UpdateScrollbarMetrics(void)
{
Tk_ConfigSpec *specPtr;
@@ -397,9 +383,9 @@ UpdateScrollbarMetrics()
*
* TkpComputeScrollbarGeometry --
*
- * After changes in a scrollbar's size or configuration, this
- * procedure recomputes various geometry information used in
- * displaying the scrollbar.
+ * After changes in a scrollbar's size or configuration, this procedure
+ * recomputes various geometry information used in displaying the
+ * scrollbar.
*
* Results:
* None.
@@ -411,15 +397,16 @@ UpdateScrollbarMetrics()
*/
void
-TkpComputeScrollbarGeometry(scrollPtr)
- register TkScrollbar *scrollPtr; /* Scrollbar whose geometry may
- * have changed. */
+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.
+ * Windows doesn't use focus rings on scrollbars, but we still perform
+ * basic sanity checks to appease backwards compatibility.
*/
if (scrollPtr->highlightWidth < 0) {
@@ -445,9 +432,9 @@ TkpComputeScrollbarGeometry(scrollPtr)
* 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).
+ * 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) {
@@ -467,10 +454,9 @@ TkpComputeScrollbarGeometry(scrollPtr)
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.
+ * 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) {
@@ -488,8 +474,8 @@ TkpComputeScrollbarGeometry(scrollPtr)
*
* ScrollbarProc --
*
- * This function is call by Windows whenever an event occurs on
- * a scrollbar control created by Tk.
+ * This function is call by Windows whenever an event occurs on a
+ * scrollbar control created by Tk.
*
* Results:
* Standard Windows return value.
@@ -501,11 +487,11 @@ TkpComputeScrollbarGeometry(scrollPtr)
*/
static LRESULT CALLBACK
-ScrollbarProc(hwnd, message, wParam, lParam)
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
+ScrollbarProc(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
LRESULT result;
POINT point;
@@ -513,90 +499,89 @@ ScrollbarProc(hwnd, message, wParam, lParam)
Tk_Window tkwin = Tk_HWNDToWindow(hwnd);
if (tkwin == NULL) {
- panic("ScrollbarProc called on an invalid HWND");
+ 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;
- }
- sprintf(valueString, "%g", pos);
- Tcl_DStringAppendElement(&cmdString, "moveto");
- Tcl_DStringAppendElement(&cmdString, valueString);
- }
+ 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;
+ }
- interp = scrollPtr->info.interp;
- code = Tcl_GlobalEval(interp, cmdString.string);
- if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
- Tcl_AddErrorInfo(interp, "\n (scrollbar command)");
- Tcl_BackgroundError(interp);
- }
- Tcl_DStringFree(&cmdString);
+ /*
+ * Bail out immediately if there isn't a command to invoke.
+ */
+ if (scrollPtr->info.commandSize == 0) {
Tcl_ServiceAll();
return 0;
}
- default:
- if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
- return result;
+ 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_GlobalEval(interp, cmdString.string);
+ if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
+ Tcl_AddErrorInfo(interp, "\n (scrollbar command)");
+ Tcl_BackgroundError(interp);
+ }
+ 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);
}
@@ -607,8 +592,8 @@ ScrollbarProc(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.
+ * processing configuration options, in order to configure platform
+ * specific options.
*
* Results:
* None.
@@ -620,10 +605,10 @@ ScrollbarProc(hwnd, message, wParam, lParam)
*/
void
-TkpConfigureScrollbar(scrollPtr)
- register TkScrollbar *scrollPtr; /* Information about widget; may or
- * may not already have values for
- * some fields. */
+TkpConfigureScrollbar(
+ register TkScrollbar *scrollPtr)
+ /* Information about widget; may or may not
+ * already have values for some fields. */
{
}
@@ -632,8 +617,8 @@ TkpConfigureScrollbar(scrollPtr)
*
* ScrollbarBindProc --
*
- * This procedure is invoked when the default <ButtonPress>
- * binding on the Scrollbar bind tag fires.
+ * This procedure is invoked when the default <ButtonPress> binding on
+ * the Scrollbar bind tag fires.
*
* Results:
* None.
@@ -645,14 +630,15 @@ TkpConfigureScrollbar(scrollPtr)
*/
static int
-ScrollbarBindProc(clientData, interp, eventPtr, tkwin, keySym)
- ClientData clientData;
- Tcl_Interp *interp;
- XEvent *eventPtr;
- Tk_Window tkwin;
- KeySym keySym;
+ScrollbarBindProc(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ XEvent *eventPtr,
+ Tk_Window tkwin,
+ KeySym keySym)
{
- TkWindow *winPtr = (TkWindow*)tkwin;
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
if (eventPtr->type == ButtonPress) {
winPtr->flags |= TK_DEFER_MODAL;
}
@@ -664,9 +650,8 @@ ScrollbarBindProc(clientData, interp, eventPtr, tkwin, keySym)
*
* ModalLoopProc --
*
- * This function is invoked at the end of the event processing
- * whenever the ScrollbarBindProc has been invoked for a ButtonPress
- * event.
+ * This function is invoked at the end of the event processing whenever
+ * the ScrollbarBindProc has been invoked for a ButtonPress event.
*
* Results:
* None.
@@ -678,16 +663,16 @@ ScrollbarBindProc(clientData, interp, eventPtr, tkwin, keySym)
*/
static void
-ModalLoopProc(tkwin, eventPtr)
- Tk_Window tkwin;
- XEvent *eventPtr;
+ModalLoopProc(
+ Tk_Window tkwin,
+ XEvent *eventPtr)
{
- TkWindow *winPtr = (TkWindow*)tkwin;
+ TkWindow *winPtr = (TkWindow *) tkwin;
WinScrollbar *scrollPtr = (WinScrollbar *) winPtr->instanceData;
int oldMode;
if (scrollPtr->hwnd) {
- Tcl_Preserve((ClientData)scrollPtr);
+ Tcl_Preserve(scrollPtr);
scrollPtr->winFlags |= IN_MODAL_LOOP;
oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr);
@@ -696,7 +681,7 @@ ModalLoopProc(tkwin, eventPtr)
if (scrollPtr->hwnd && scrollPtr->winFlags & ALREADY_DEAD) {
DestroyWindow(scrollPtr->hwnd);
}
- Tcl_Release((ClientData)scrollPtr);
+ Tcl_Release(scrollPtr);
}
}
@@ -705,14 +690,12 @@ ModalLoopProc(tkwin, eventPtr)
*
* TkpScrollbarPosition --
*
- * Determine the scrollbar element corresponding to a
- * given position.
+ * 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.
+ * 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.
@@ -721,10 +704,10 @@ ModalLoopProc(tkwin, eventPtr)
*/
int
-TkpScrollbarPosition(scrollPtr, x, y)
- register TkScrollbar *scrollPtr; /* Scrollbar widget record. */
- int x, y; /* Coordinates within scrollPtr's
- * window. */
+TkpScrollbarPosition(
+ register TkScrollbar *scrollPtr,
+ /* Scrollbar widget record. */
+ int x, int y) /* Coordinates within scrollPtr's window. */
{
int length, width, tmp;
@@ -746,7 +729,7 @@ TkpScrollbarPosition(scrollPtr, x, y)
/*
* All of the calculations in this procedure mirror those in
- * TkpDisplayScrollbar. Be sure to keep the two consistent.
+ * TkpDisplayScrollbar. Be sure to keep the two consistent.
*/
if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
@@ -763,3 +746,11 @@ TkpScrollbarPosition(scrollPtr, x, y)
}
return BOTTOM_GAP;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinSend.c b/win/tkWinSend.c
index 781aa5d..4b25963 100644
--- a/win/tkWinSend.c
+++ b/win/tkWinSend.c
@@ -1,56 +1,195 @@
-/*
+/*
* tkWinSend.c --
*
- * This file provides procedures that implement the "send"
- * command, allowing commands to be passed from interpreter
- * to interpreter.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
+#include "tkWinSendCom.h"
+
+#ifdef _MSC_VER
+#define vsnprintf _vsnprintf
+#endif
+
+/*
+ * 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
+
+/*
+ * 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
+static HRESULT BuildMoniker(const char *name, LPMONIKER *pmk);
+#ifdef TK_SEND_ENABLED_ON_WINDOWS
+static HRESULT RegisterInterp(const char *name,
+ RegisteredInterp *riPtr);
+#endif
+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 Tcl_Obj * Win32ErrorObj(HRESULT hrError);
+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
/*
*--------------------------------------------------------------
*
* Tk_SetAppName --
*
- * This procedure is called to associate an ASCII name with a Tk
- * application. If the application has already been named, the
- * name replaces the old one.
+ * 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.
+ * 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.
+ * 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(tkwin, name)
- 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. */
+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 = (ThreadSpecificData *)
+ 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_SetResult(interp,
+ "failed to initialize the COM library", TCL_STATIC);
+ 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 = (RegisteredInterp *) 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 */
}
/*
@@ -58,15 +197,14 @@ Tk_SetAppName(tkwin, name)
*
* TkGetInterpNames --
*
- * This procedure is invoked to fetch a list of all the
- * interpreter names currently registered for the display
- * of a particular window.
+ * 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.
+ * 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.
@@ -75,10 +213,837 @@ Tk_SetAppName(tkwin, name)
*/
int
-TkGetInterpNames(interp, tkwin)
- Tcl_Interp *interp; /* Interpreter for returning a result. */
- Tk_Window tkwin; /* Window whose display is to be used
- * for the lookup. */
+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) {
+ result = Tcl_ListObjAppendElement(interp,
+ objList, Tcl_NewUnicodeObj(p + 1, -1));
+ }
+ }
+
+ 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, Win32ErrorObj(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 *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_GetIndexFromObj(interp, objv[i], sendOptions,
+ "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_SetStringObj(Tcl_GetObjResult(interp),
+ "option not implemented: \"displayof\" is not available "
+ "for this platform.", -1);
+ 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_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "no application named \"", name, "\"", 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, Win32ErrorObj(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
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * 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
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * 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_DStringInit(&dString);
+ Tcl_UtfToUniCharDString(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
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * 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;
+
+ 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;
+ vCmd.bstrVal = SysAllocString(Tcl_GetUnicode(cmd));
+
+ 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_SetObjResult(interp, Tcl_NewUnicodeObj(vResult.bstrVal, -1));
+ }
+
+ /*
+ * 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) {
+ Tcl_Obj *opError, *opErrorCode, *opErrorInfo;
+
+ if (ei.bstrSource != NULL) {
+ int len;
+ char *szErrorInfo;
+
+ opError = Tcl_NewUnicodeObj(ei.bstrSource, -1);
+ Tcl_ListObjIndex(interp, opError, 0, &opErrorCode);
+ Tcl_SetObjErrorCode(interp, opErrorCode);
+
+ Tcl_ListObjIndex(interp, opError, 1, &opErrorInfo);
+ szErrorInfo = Tcl_GetStringFromObj(opErrorInfo, &len);
+ Tcl_AddObjErrorInfo(interp, szErrorInfo, len);
+ }
+ }
+
+ /*
+ * Clean up any COM allocated resources.
+ */
+
+ SysFreeString(ei.bstrDescription);
+ SysFreeString(ei.bstrSource);
+ SysFreeString(ei.bstrHelpFile);
+ VariantClear(&vCmd);
+
+ return (SUCCEEDED(hr) ? TCL_OK : TCL_ERROR);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Win32ErrorObj --
+ *
+ * Returns a string object containing text from a COM or Win32 error code
+ *
+ * Results:
+ * A Tcl_Obj containing the Win32 error message.
+ *
+ * Side effects:
+ * Removed the error message from the COM threads error object.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static Tcl_Obj*
+Win32ErrorObj(
+ HRESULT hrError)
+{
+ LPTSTR lpBuffer = NULL, p = NULL;
+ TCHAR sBuffer[30];
+ Tcl_Obj* errPtr = NULL;
+
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, (DWORD)hrError, LANG_NEUTRAL,
+ (LPTSTR)&lpBuffer, 0, NULL);
+
+ if (lpBuffer == NULL) {
+ lpBuffer = sBuffer;
+ wsprintf(sBuffer, TEXT("Error Code: %08lX"), hrError);
+ }
+
+ if ((p = _tcsrchr(lpBuffer, TEXT('\r'))) != NULL) {
+ *p = TEXT('\0');
+ }
+
+#ifdef _UNICODE
+ errPtr = Tcl_NewUnicodeObj(lpBuffer, (int)wcslen(lpBuffer));
+#else
+ errPtr = Tcl_NewStringObj(lpBuffer, (int)strlen(lpBuffer));
+#endif
+
+ if (lpBuffer != sBuffer) {
+ LocalFree((HLOCAL)lpBuffer);
+ }
+
+ return errPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * SetErrorInfo --
+ *
+ * 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
+SetExcepInfo(
+ Tcl_Interp* interp,
+ EXCEPINFO *pExcepInfo)
+{
+ if (pExcepInfo) {
+ Tcl_Obj *opError, *opErrorInfo, *opErrorCode;
+ ICreateErrorInfo *pCEI;
+ IErrorInfo *pEI, **ppEI = &pEI;
+ HRESULT hr;
+
+ opError = Tcl_GetObjResult(interp);
+ opErrorInfo = Tcl_GetVar2Ex(interp, "errorInfo",NULL, TCL_GLOBAL_ONLY);
+ opErrorCode = Tcl_GetVar2Ex(interp, "errorCode",NULL, TCL_GLOBAL_ONLY);
+
+ if (Tcl_IsShared(opErrorCode)) {
+ Tcl_Obj *ec = Tcl_DuplicateObj(opErrorCode);
+
+ Tcl_IncrRefCount(ec);
+ Tcl_DecrRefCount(opErrorCode);
+ opErrorCode = ec;
+ }
+ Tcl_ListObjAppendElement(interp, opErrorCode, opErrorInfo);
+
+ pExcepInfo->bstrDescription = SysAllocString(Tcl_GetUnicode(opError));
+ pExcepInfo->bstrSource = SysAllocString(Tcl_GetUnicode(opErrorCode));
+ pExcepInfo->scode = E_FAIL;
+
+ hr = CreateErrorInfo(&pCEI);
+ if (SUCCEEDED(hr)) {
+ 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 = (SendEvent *)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);
+ OutputDebugString(buffer);
+ va_end(args);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinSendCom.c b/win/tkWinSendCom.c
new file mode 100644
index 0000000..3bbdd63
--- /dev/null
+++ b/win/tkWinSendCom.c
@@ -0,0 +1,462 @@
+/*
+ * 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,
+ };
+ HRESULT hr = S_OK;
+ 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;
+ hr = E_OUTOFMEMORY;
+ } else {
+ obj->lpVtbl = &vtbl;
+ obj->lpVtbl2 = &vtbl2;
+ obj->refcount = 0;
+ obj->interp = interp;
+
+ /*
+ * lock the interp? Tcl_AddRef/Retain?
+ */
+
+ hr = obj->lpVtbl->QueryInterface((IDispatch*)obj, riid, ppv);
+ }
+
+ return hr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * 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;
+
+ VariantInit(&vCmd);
+
+ hr = VariantChangeType(&vCmd, &Cmd, 0, VT_BSTR);
+ if (FAILED(hr)) {
+ Tcl_SetStringObj(Tcl_GetObjResult(obj->interp),
+ "invalid args: Async(command)", -1);
+ SetExcepInfo(obj->interp, pExcepInfo);
+ hr = DISP_E_EXCEPTION;
+ }
+
+ if (SUCCEEDED(hr)) {
+ if (obj->interp) {
+ Tcl_Obj *scriptPtr = Tcl_NewUnicodeObj(vCmd.bstrVal,
+ (int)SysStringLen(vCmd.bstrVal));
+ 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;
+
+ VariantInit(&v);
+ hr = VariantChangeType(&v, &vCmd, 0, VT_BSTR);
+ if (SUCCEEDED(hr)) {
+ if (obj->interp) {
+ Tcl_Obj *scriptPtr = Tcl_NewUnicodeObj(v.bstrVal,
+ (int)SysStringLen(v.bstrVal));
+
+ result = Tcl_EvalObjEx(obj->interp, scriptPtr,
+ TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);
+ if (pvResult) {
+ VariantInit(pvResult);
+ pvResult->vt = VT_BSTR;
+ pvResult->bstrVal = SysAllocString(
+ Tcl_GetUnicode(Tcl_GetObjResult(obj->interp)));
+ }
+ if (result == TCL_ERROR) {
+ hr = DISP_E_EXCEPTION;
+ SetExcepInfo(obj->interp, pExcepInfo);
+ }
+ }
+ VariantClear(&v);
+ }
+ return hr;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinSendCom.h b/win/tkWinSendCom.h
new file mode 100644
index 0000000..4928bc7
--- /dev/null
+++ b/win/tkWinSendCom.h
@@ -0,0 +1,61 @@
+/*
+ * 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
+ */
+
+HRESULT TkWinSendCom_CreateInstance(Tcl_Interp *interp,
+ REFIID riid, void **ppv);
+int TkWinSend_QueueCommand(Tcl_Interp *interp,
+ Tcl_Obj *cmdPtr);
+void SetExcepInfo(Tcl_Interp *interp,
+ EXCEPINFO *pExcepInfo);
+
+#endif /* _tkWinSendCom_h_INCLUDE */
+
+/*
+ * Local Variables:
+ * mode: c
+ * End:
+ */
diff --git a/win/tkWinTest.c b/win/tkWinTest.c
index bad3df3..ed2e3e5 100644
--- a/win/tkWinTest.c
+++ b/win/tkWinTest.c
@@ -1,40 +1,49 @@
-/*
+/*
* tkWinTest.c --
*
- * Contains commands for platform specific tests for
- * the Windows platform.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkWinInt.h"
HWND tkWinCurrentDialog;
-
+
/*
- * Forward declarations of procedures defined later in this file:
+ * Forward declarations of functions defined later in this file:
*/
-int TkplatformtestInit(Tcl_Interp *interp);
static int TestclipboardObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[]);
-static int TestwineventCmd(ClientData clientData,
+static int TestwineventCmd(ClientData clientData,
Tcl_Interp *interp, int argc, CONST char **argv);
-
+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[]);
+MODULE_SCOPE int TkplatformtestInit(Tcl_Interp *interp);
+
/*
*----------------------------------------------------------------------
*
* TkplatformtestInit --
*
- * Defines commands that test platform specific functionality for
- * Unix platforms.
+ * Defines commands that test platform specific functionality for Windows
+ * platforms.
*
* Results:
* A standard Tcl result.
@@ -52,12 +61,17 @@ TkplatformtestInit(
/*
* Add commands for platform specific tests on MacOS here.
*/
-
+
Tcl_CreateObjCommand(interp, "testclipboard", TestclipboardObjCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateCommand(interp, "testwinevent", TestwineventCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
-
+ (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;
}
@@ -66,8 +80,8 @@ TkplatformtestInit(
*
* AppendSystemError --
*
- * This routine formats a Windows system error message and places
- * it into the interpreter result. Originally from tclWinReg.c.
+ * This routine formats a Windows system error message and places it into
+ * the interpreter result. Originally from tclWinReg.c.
*
* Results:
* None.
@@ -84,7 +98,7 @@ AppendSystemError(
DWORD error) /* Result code from error. */
{
int length;
- WCHAR *wMsgPtr;
+ WCHAR *wMsgPtr, **wMsgPtrPtr = &wMsgPtr;
char *msg;
char id[TCL_INTEGER_SPACE], msgBuf[24 + TCL_INTEGER_SPACE];
Tcl_DString ds;
@@ -92,7 +106,7 @@ AppendSystemError(
length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) &wMsgPtr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) wMsgPtrPtr,
0, NULL);
if (length == 0) {
char *msgPtr;
@@ -128,6 +142,7 @@ AppendSystemError(
/*
* Trim the trailing CR/LF from the system message.
*/
+
if (msg[length-1] == '\n') {
msg[--length] = 0;
}
@@ -137,7 +152,7 @@ AppendSystemError(
}
sprintf(id, "%ld", error);
- Tcl_SetErrorCode(interp, "WINDOWS", id, msg, (char *) NULL);
+ Tcl_SetErrorCode(interp, "WINDOWS", id, msg, NULL);
Tcl_AppendToObj(resultPtr, msg, length);
if (length != 0) {
@@ -150,8 +165,8 @@ AppendSystemError(
*
* TestclipboardObjCmd --
*
- * This procedure implements the testclipboard command. It provides
- * a way to determine the actual contents of the Windows clipboard.
+ * This function implements the testclipboard command. It provides a way
+ * to determine the actual contents of the Windows clipboard.
*
* Results:
* A standard Tcl result.
@@ -163,40 +178,40 @@ AppendSystemError(
*/
static int
-TestclipboardObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+TestclipboardObjCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument values. */
{
HGLOBAL handle;
char *data;
int code = TCL_OK;
if (objc != 1) {
- Tcl_WrongNumArgs(interp, 1, objv, (char *) NULL);
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
if (OpenClipboard(NULL)) {
/*
- * We could consider using CF_UNICODETEXT on NT, but then we
- * would have to convert it from External. Instead we'll just
- * take this and do "bytestring" at the Tcl level for Unicode
- * inclusive text
+ * We could consider using CF_UNICODETEXT on NT, but then we would
+ * have to convert it from External. Instead we'll just take this and
+ * do "bytestring" at the Tcl level for Unicode inclusive text
*/
+
handle = GetClipboardData(CF_TEXT);
if (handle != NULL) {
data = GlobalLock(handle);
- Tcl_AppendResult(interp, data, (char *) NULL);
+ Tcl_AppendResult(interp, data, NULL);
GlobalUnlock(handle);
} else {
- Tcl_AppendResult(interp, "null clipboard handle", (char *) NULL);
+ Tcl_AppendResult(interp, "null clipboard handle", NULL);
code = TCL_ERROR;
}
CloseClipboard();
return code;
} else {
- Tcl_AppendResult(interp, "couldn't open clipboard: ", (char *) NULL);
+ Tcl_AppendResult(interp, "couldn't open clipboard: ", NULL);
AppendSystemError(interp, GetLastError());
return TCL_ERROR;
}
@@ -208,8 +223,8 @@ TestclipboardObjCmd(clientData, interp, objc, objv)
*
* TestwineventCmd --
*
- * This procedure implements the testwinevent command. It provides
- * a way to send messages to windows dialogs.
+ * This function implements the testwinevent command. It provides a way
+ * to send messages to windows dialogs.
*
* Results:
* A standard Tcl result.
@@ -221,24 +236,26 @@ TestclipboardObjCmd(clientData, interp, objc, objv)
*/
static int
-TestwineventCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TestwineventCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ CONST char **argv) /* Argument strings. */
{
HWND hwnd = 0;
+ HWND child = 0;
int id;
char *rest;
UINT message;
WPARAM wParam;
LPARAM lParam;
- static TkStateMap messageMap[] = {
+ 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}
};
@@ -256,16 +273,6 @@ TestwineventCmd(clientData, interp, argc, argv)
return TCL_ERROR;
}
-#if 0
- TkpScanWindowId(interp, argv[1], &id);
- if (
-#ifdef _WIN64
- (sscanf(string, "0x%p", &number) != 1) &&
-#endif
- Tcl_GetInt(interp, string, (int *)&number) != TCL_OK) {
- return TCL_ERROR;
- }
-#endif
hwnd = (HWND) strtol(argv[1], &rest, 0);
if (rest == argv[1]) {
hwnd = FindWindow(NULL, argv[1]);
@@ -278,7 +285,6 @@ TestwineventCmd(clientData, interp, argc, argv)
id = strtol(argv[2], &rest, 0);
if (rest == argv[2]) {
- HWND child;
char buf[256];
child = GetWindow(hwnd, GW_CHILD);
@@ -291,13 +297,12 @@ TestwineventCmd(clientData, interp, argc, argv)
child = GetWindow(child, GW_HWNDNEXT);
}
if (child == NULL) {
+ Tcl_AppendResult(interp, "could not find a control matching \"",
+ argv[2], "\"", NULL);
return TCL_ERROR;
}
}
message = TkFindStateNum(NULL, NULL, messageMap, argv[3]);
- if (message < 0) {
- message = strtol(argv[3], NULL, 0);
- }
wParam = 0;
lParam = 0;
@@ -309,35 +314,179 @@ TestwineventCmd(clientData, interp, argc, argv)
}
switch (message) {
- case WM_GETTEXT: {
- Tcl_DString ds;
- char buf[256];
-
- GetDlgItemText(hwnd, id, buf, 256);
- Tcl_ExternalToUtfDString(NULL, buf, -1, &ds);
- Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
- Tcl_DStringFree(&ds);
- break;
- }
- case WM_SETTEXT: {
- Tcl_DString ds;
+ case WM_GETTEXT: {
+ Tcl_DString ds;
+ char buf[256];
- Tcl_UtfToExternalDString(NULL, argv[4], -1, &ds);
- SetDlgItemText(hwnd, id, Tcl_DStringValue(&ds));
- Tcl_DStringFree(&ds);
- break;
- }
- default: {
- char buf[TCL_INTEGER_SPACE];
-
- sprintf(buf, "%d",
- (int) SendDlgItemMessage(hwnd, id, message, wParam, lParam));
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
- break;
+ GetDlgItemText(hwnd, id, buf, 256);
+ Tcl_ExternalToUtfDString(NULL, buf, -1, &ds);
+ Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
+ Tcl_DStringFree(&ds);
+ break;
+ }
+ case WM_SETTEXT: {
+ Tcl_DString ds;
+
+ Tcl_UtfToExternalDString(NULL, argv[4], -1, &ds);
+ SetDlgItemText(hwnd, id, Tcl_DStringValue(&ds));
+ Tcl_DStringFree(&ds);
+ break;
+ }
+ case WM_COMMAND: {
+ char buf[TCL_INTEGER_SPACE];
+ if (argc < 5) {
+ wParam = MAKEWPARAM(id, 0);
+ lParam = (LPARAM)child;
}
+ sprintf(buf, "%d", (int) SendMessage(hwnd, message, wParam, lParam));
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ break;
+ }
+ default: {
+ char buf[TCL_INTEGER_SPACE];
+
+ sprintf(buf, "%d",
+ (int) SendDlgItemMessage(hwnd, id, message, wParam, lParam));
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ 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 char *title = NULL, *class = NULL;
+ HWND hwnd = NULL;
+ int r = TCL_OK;
+
+ if (objc < 2 || objc > 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "title ?class?");
+ return TCL_ERROR;
+ }
+ title = Tcl_GetString(objv[1]);
+ if (objc == 3)
+ class = Tcl_GetString(objv[2]);
+ hwnd = FindWindowA(class, title);
+
+ 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((long)hwnd));
+ }
+ return r;
+}
+
+static BOOL CALLBACK
+EnumChildrenProc(HWND hwnd, LPARAM lParam)
+{
+ Tcl_Obj *listObj = (Tcl_Obj *)lParam;
+ Tcl_ListObjAppendElement(NULL, listObj, Tcl_NewLongObj((long)hwnd));
+ return TRUE;
+}
+
+static int
+TestgetwindowinfoObjCmd(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[])
+{
+ long hwnd;
+ Tcl_Obj *resObj = NULL, *classObj = NULL, *textObj = NULL;
+ Tcl_Obj *childrenObj = NULL;
+ char buf[512];
+ int cch, cchBuf = tkWinProcs->useWide ? 256 : 512;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "hwnd");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetLongFromObj(interp, objv[1], &hwnd) != TCL_OK)
+ return TCL_ERROR;
+
+ if (tkWinProcs->useWide) {
+ cch = GetClassNameW((HWND)hwnd, (LPWSTR)buf, sizeof(buf)/sizeof(WCHAR));
+ classObj = Tcl_NewUnicodeObj((LPWSTR)buf, cch);
+ } else {
+ cch = GetClassNameA((HWND)hwnd, (LPSTR)buf, sizeof(buf));
+ classObj = Tcl_NewStringObj((LPSTR)buf, cch);
+ }
+ if (cch == 0) {
+ Tcl_SetResult(interp, "failed to get class name: ", TCL_STATIC);
+ AppendSystemError(interp, GetLastError());
+ return TCL_ERROR;
+ }
+ resObj = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("class", -1));
+ Tcl_ListObjAppendElement(interp, resObj, classObj);
+ Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("id", -1));
+ Tcl_ListObjAppendElement(interp, resObj,
+ Tcl_NewLongObj(GetWindowLong((HWND)hwnd, GWL_ID)));
+
+ cch = tkWinProcs->getWindowText((HWND)hwnd, (LPTSTR)buf, cchBuf);
+ if (tkWinProcs->useWide) {
+ textObj = Tcl_NewUnicodeObj((LPCWSTR)buf, cch);
+ } else {
+ textObj = Tcl_NewStringObj((LPCSTR)buf, cch);
+ }
+
+ Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("text", -1));
+ Tcl_ListObjAppendElement(interp, resObj, textObj);
+ Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("parent", -1));
+ Tcl_ListObjAppendElement(interp, resObj,
+ Tcl_NewLongObj((long)GetParent((HWND)hwnd)));
+
+ childrenObj = Tcl_NewListObj(0, NULL);
+ EnumChildWindows((HWND)hwnd, EnumChildrenProc, (LPARAM)childrenObj);
+ Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("children", -1));
+ Tcl_ListObjAppendElement(interp, resObj, childrenObj);
+
+ Tcl_SetObjResult(interp, resObj);
+ 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)GetSystemDefaultLCID()));
+ return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinWindow.c b/win/tkWinWindow.c
index cd20aad..83fa033 100644
--- a/win/tkWinWindow.c
+++ b/win/tkWinWindow.c
@@ -1,59 +1,58 @@
-/*
+/*
* tkWinWindow.c --
*
- * Xlib emulation routines for Windows related to creating,
- * displaying and destroying windows.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkWinInt.h"
typedef struct ThreadSpecificData {
- int initialized; /* 0 means table below needs initializing. */
- Tcl_HashTable windowTable; /* The windowTable maps from HWND to
- * Tk_Window handles. */
+ 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 procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-static void NotifyVisibility _ANSI_ARGS_((XEvent *eventPtr,
- TkWindow *winPtr));
+static void NotifyVisibility(XEvent *eventPtr, TkWindow *winPtr);
/*
*----------------------------------------------------------------------
*
* Tk_AttachHWND --
*
- * This function binds an HWND and a reflection procedure to
- * the specified Tk_Window.
+ * 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.
+ * May allocate a new X Window. Also enters the HWND into the global
+ * window table.
*
*----------------------------------------------------------------------
*/
Window
-Tk_AttachHWND(tkwin, hwnd)
- Tk_Window tkwin;
- HWND hwnd;
+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));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->initialized) {
Tcl_InitHashTable(&tsdPtr->windowTable, TCL_ONE_WORD_KEYS);
@@ -61,12 +60,12 @@ Tk_AttachHWND(tkwin, hwnd)
}
/*
- * Allocate a new drawable if necessary. Otherwise, remove the
- * previous HWND from from the window table.
+ * Allocate a new drawable if necessary. Otherwise, remove the previous
+ * HWND from from the window table.
*/
if (twdPtr == NULL) {
- twdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable));
+ twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable));
twdPtr->type = TWD_WINDOW;
twdPtr->window.winPtr = (TkWindow *) tkwin;
} else if (twdPtr->window.handle != NULL) {
@@ -91,8 +90,8 @@ Tk_AttachHWND(tkwin, hwnd)
*
* Tk_HWNDToWindow --
*
- * This function retrieves a Tk_Window from the window table
- * given an HWND.
+ * This function retrieves a Tk_Window from the window table given an
+ * HWND.
*
* Results:
* Returns the matching Tk_Window.
@@ -104,18 +103,18 @@ Tk_AttachHWND(tkwin, hwnd)
*/
Tk_Window
-Tk_HWNDToWindow(hwnd)
- HWND hwnd;
+Tk_HWNDToWindow(
+ HWND hwnd)
{
Tcl_HashEntry *entryPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ 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);
+ entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, (char *) hwnd);
if (entryPtr != NULL) {
return (Tk_Window) Tcl_GetHashValue(entryPtr);
}
@@ -139,8 +138,8 @@ Tk_HWNDToWindow(hwnd)
*/
HWND
-Tk_GetHWND(window)
- Window window;
+Tk_GetHWND(
+ Window window)
{
return ((TkWinDrawable *) window)->window.handle;
}
@@ -150,9 +149,8 @@ Tk_GetHWND(window)
*
* TkpPrintWindowId --
*
- * This routine stores the string representation of the
- * platform dependent window handle for an X Window in the
- * given buffer.
+ * 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.
@@ -164,17 +162,22 @@ Tk_GetHWND(window)
*/
void
-TkpPrintWindowId(buf, window)
- char *buf; /* Pointer to string large enough to hold
- * the hex representation of a pointer. */
- Window window; /* Window to be printed into buffer. */
+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.
+ * 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);
}
/*
@@ -182,16 +185,15 @@ TkpPrintWindowId(buf, window)
*
* TkpScanWindowId --
*
- * Given a string which represents the platform dependent window
- * handle, produce the X Window id for the window.
+ * 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.
+ * 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.
@@ -200,28 +202,29 @@ TkpPrintWindowId(buf, window)
*/
int
-TkpScanWindowId(interp, string, idPtr)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- CONST char *string; /* String containing a (possibly signed)
+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. */
+ Window *idPtr) /* Place to store converted result. */
{
Tk_Window tkwin;
- Window number;
+ Window number, *numberPtr = &number;
/*
- * We want sscanf for the 64-bit check, but if that doesn't work,
- * then Tcl_GetInt manages the error correctly.
+ * 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", &number) != 1) &&
+ (sscanf(string, "0x%p", &number) != 1) &&
#endif
- Tcl_GetInt(interp, string, (int *)&number) != TCL_OK) {
+ Tcl_GetInt(interp, string, (int *) numberPtr) != TCL_OK) {
return TCL_ERROR;
}
- tkwin = Tk_HWNDToWindow((HWND)number);
+ tkwin = Tk_HWNDToWindow((HWND) number);
if (tkwin) {
*idPtr = Tk_WindowId(tkwin);
} else {
@@ -235,8 +238,8 @@ TkpScanWindowId(interp, string, idPtr)
*
* TkpMakeWindow --
*
- * Creates a Windows window object based on the current attributes
- * of the specified TkWindow.
+ * 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.
@@ -248,14 +251,14 @@ TkpScanWindowId(interp, string, idPtr)
*/
Window
-TkpMakeWindow(winPtr, parent)
- TkWindow *winPtr;
- Window parent;
+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;
@@ -265,15 +268,15 @@ TkpMakeWindow(winPtr, parent)
}
/*
- * Create the window, then ensure that it is at the top of the
- * stacking order.
+ * 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,
- style, Tk_X(winPtr), Tk_Y(winPtr), Tk_Width(winPtr),
+ (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);
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
return Tk_AttachHWND((Tk_Window)winPtr, hwnd);
}
@@ -288,29 +291,29 @@ TkpMakeWindow(winPtr, parent)
* None.
*
* Side effects:
- * Sends the WM_DESTROY message to the window and then destroys
- * it the Win32 resources associated with the window.
+ * Sends the WM_DESTROY message to the window and then destroys it the
+ * Win32 resources associated with the window.
*
*----------------------------------------------------------------------
*/
void
-XDestroyWindow(display, w)
- Display* display;
- Window w;
+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));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
display->request++;
/*
- * Remove references to the window in the pointer module then
- * release the drawable.
+ * Remove references to the window in the pointer module then release the
+ * drawable.
*/
TkPointerDeadWindow(winPtr);
@@ -323,8 +326,8 @@ XDestroyWindow(display, w)
ckfree((char *)twdPtr);
/*
- * Don't bother destroying the window if we are going to destroy
- * the parent later.
+ * Don't bother destroying the window if we are going to destroy the
+ * parent later.
*/
if (hwnd != NULL && !(winPtr->flags & TK_DONT_DESTROY_WINDOW)) {
@@ -343,16 +346,15 @@ XDestroyWindow(display, w)
* None
*
* Side effects:
- * Causes the window state to change, and generates a MapNotify
- * event.
+ * Causes the window state to change, and generates a MapNotify event.
*
*----------------------------------------------------------------------
*/
void
-XMapWindow(display, w)
- Display* display;
- Window w;
+XMapWindow(
+ Display *display,
+ Window w)
{
XEvent event;
TkWindow *parentPtr;
@@ -364,14 +366,14 @@ XMapWindow(display, w)
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.
+ * 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) {
+ parentPtr = parentPtr->parentPtr) {
if ((parentPtr == NULL) || !(parentPtr->flags & TK_MAPPED)) {
return;
}
@@ -389,7 +391,7 @@ XMapWindow(display, w)
event.xmap.override_redirect = winPtr->atts.override_redirect;
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
}
-
+
/*
* Generate VisibilityNotify events for this window and its mapped
* children.
@@ -410,10 +412,10 @@ XMapWindow(display, w)
* 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.
+ * 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.
@@ -425,15 +427,15 @@ XMapWindow(display, w)
*/
static void
-NotifyVisibility(eventPtr, winPtr)
- XEvent *eventPtr; /* Initialized VisibilityNotify event. */
- TkWindow *winPtr; /* Window to notify. */
+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;
+ for (winPtr = winPtr->childList; winPtr != NULL;
winPtr = winPtr->nextPtr) {
if (winPtr->flags & TK_MAPPED) {
NotifyVisibility(eventPtr, winPtr);
@@ -452,16 +454,15 @@ NotifyVisibility(eventPtr, winPtr)
* None
*
* Side effects:
- * Causes the window state to change, and generates an UnmapNotify
- * event.
+ * Causes the window state to change, and generates an UnmapNotify event.
*
*----------------------------------------------------------------------
*/
void
-XUnmapWindow(display, w)
- Display* display;
- Window w;
+XUnmapWindow(
+ Display *display,
+ Window w)
{
XEvent event;
TkWindow *winPtr = TkWinGetWinPtr(w);
@@ -469,8 +470,8 @@ XUnmapWindow(display, w)
display->request++;
/*
- * Bug fix: Don't short circuit this routine based on TK_MAPPED because
- * it will be cleared before XUnmapWindow is called.
+ * 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);
@@ -505,16 +506,14 @@ XUnmapWindow(display, w)
*/
void
-XMoveResizeWindow(display, w, x, y, width, height)
- Display* display;
- Window w;
- int x; /* Position relative to parent. */
- int y;
- unsigned int width;
- unsigned int height;
+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, width, height, TRUE);
+ MoveWindow(Tk_GetHWND(w), x, y, (int) width, (int) height, TRUE);
}
/*
@@ -534,11 +533,10 @@ XMoveResizeWindow(display, w, x, y, width, height)
*/
void
-XMoveWindow(display, w, x, y)
- Display* display;
- Window w;
- int x;
- int y;
+XMoveWindow(
+ Display *display,
+ Window w,
+ int x, int y) /* Position relative to parent */
{
TkWindow *winPtr = TkWinGetWinPtr(w);
@@ -565,18 +563,17 @@ XMoveWindow(display, w, x, y)
*/
void
-XResizeWindow(display, w, width, height)
- Display* display;
- Window w;
- unsigned int width;
- unsigned int height;
+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, width,
- height, TRUE);
+ MoveWindow(Tk_GetHWND(w), winPtr->changes.x, winPtr->changes.y, (int)width,
+ (int)height, TRUE);
}
/*
@@ -596,15 +593,14 @@ XResizeWindow(display, w, width, height)
*/
void
-XRaiseWindow(display, w)
- Display* display;
- Window w;
+XRaiseWindow(
+ Display *display,
+ Window w)
{
HWND window = Tk_GetHWND(w);
display->request++;
- SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE);
+ SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
/*
@@ -619,19 +615,19 @@ XRaiseWindow(display, w)
* 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.
+ * 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.
*
*----------------------------------------------------------------------
*/
void
-XConfigureWindow(display, w, value_mask, values)
- Display* display;
- Window w;
- unsigned int value_mask;
- XWindowChanges* values;
+XConfigureWindow(
+ Display *display,
+ Window w,
+ unsigned int valueMask,
+ XWindowChanges *values)
{
TkWindow *winPtr = TkWinGetWinPtr(w);
HWND hwnd = Tk_GetHWND(w);
@@ -642,7 +638,7 @@ XConfigureWindow(display, w, value_mask, values)
* Change the shape and/or position of the window.
*/
- if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
+ if (valueMask & (CWX|CWY|CWWidth|CWHeight)) {
MoveWindow(hwnd, winPtr->changes.x, winPtr->changes.y,
winPtr->changes.width, winPtr->changes.height, TRUE);
}
@@ -651,9 +647,10 @@ XConfigureWindow(display, w, value_mask, values)
* Change the stacking order of the window.
*/
- if (value_mask & CWStackMode) {
+ if (valueMask & CWStackMode) {
HWND sibling;
- if ((value_mask & CWSibling) && (values->sibling != None)) {
+
+ if ((valueMask & CWSibling) && (values->sibling != None)) {
sibling = Tk_GetHWND(values->sibling);
} else {
sibling = NULL;
@@ -679,9 +676,9 @@ XConfigureWindow(display, w, value_mask, values)
*/
void
-XClearWindow(display, w)
- Display* display;
- Window w;
+XClearWindow(
+ Display *display,
+ Window w)
{
RECT rc;
HBRUSH brush;
@@ -713,9 +710,9 @@ XClearWindow(display, w)
*
* 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.
+ * 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.
@@ -727,11 +724,11 @@ XClearWindow(display, w)
*/
void
-XChangeWindowAttributes(display, w, valueMask, attributes)
- Display* display;
- Window w;
- unsigned long valueMask;
- XSetWindowAttributes* attributes;
+XChangeWindowAttributes(
+ Display *display,
+ Window w,
+ unsigned long valueMask,
+ XSetWindowAttributes* attributes)
{
if (valueMask & CWCursor) {
XDefineCursor(display, w, attributes->cursor);
@@ -743,8 +740,8 @@ XChangeWindowAttributes(display, w, valueMask, attributes)
*
* TkWinSetWindowPos --
*
- * Adjust the stacking order of a window relative to a second
- * window (or NULL).
+ * Adjust the stacking order of a window relative to a second window (or
+ * NULL).
*
* Results:
* None.
@@ -756,16 +753,16 @@ XChangeWindowAttributes(display, w, valueMask, attributes)
*/
void
-TkWinSetWindowPos(hwnd, siblingHwnd, pos)
- HWND hwnd; /* Window to restack. */
- HWND siblingHwnd; /* Sibling window. */
- int pos; /* One of Above or Below. */
+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.
+ * Since Windows does not support Above mode, we place the specified
+ * window below the sibling and then swap them.
*/
if (siblingHwnd) {
@@ -790,8 +787,8 @@ TkWinSetWindowPos(hwnd, siblingHwnd, pos)
* TkpWindowWasRecentlyDeleted --
*
* Determines whether we know if the window given as argument was
- * recently deleted. Called by the generic code error handler to
- * handle BadWindow events.
+ * recently deleted. Called by the generic code error handler to handle
+ * BadWindow events.
*
* Results:
* Always 0. We do not keep this information on Windows.
@@ -803,9 +800,17 @@ TkWinSetWindowPos(hwnd, siblingHwnd, pos)
*/
int
-TkpWindowWasRecentlyDeleted(win, dispPtr)
- Window win;
- TkDisplay *dispPtr;
+TkpWindowWasRecentlyDeleted(
+ Window win,
+ TkDisplay *dispPtr)
{
return 0;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 2097938..b3af26a 100644
--- a/win/tkWinWm.c
+++ b/win/tkWinWm.c
@@ -2,15 +2,15 @@
* 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.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkWinInt.h"
@@ -19,6 +19,7 @@
/*
* These next two defines are only valid on Win2K/XP+.
*/
+
#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x00080000
#endif
@@ -30,36 +31,38 @@
#endif
/*
- * Event structure for synthetic activation events. These events are
- * placed on the event queue whenever a toplevel gets a WM_MOUSEACTIVATE
- * message.
+ * 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.
+ * 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. */
+ /* 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[4]; /* 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. */
+ char command[4]; /* 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) \
@@ -68,81 +71,87 @@ typedef struct ProtocolHandler {
/*
* Helper type passed via lParam to TkWmStackorderToplevelEnumProc
*/
+
typedef struct TkWmStackorderToplevelPair {
Tcl_HashTable *table;
TkWindow **window_ptr;
} 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.
+ * 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 */
+ 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.
+ * 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 */
+ 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.
+ * 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 */
+ 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 */
+ 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:
+ * 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:
*
- * (i) how many WmInfo structures point to this object
- * (ii) whether the ThreadSpecificData defined in this file contains
- * a pointer to this object.
+ * (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.
+ * 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.
+ * Icons loaded from .icr/.icr use the iconBlock field, icons loaded from
+ * .exe/.dll use the hIcon field.
*/
+
typedef struct WinIconInstance {
- int refCount; /* Number of instances that share this
- * data structure. */
+ int refCount; /* Number of instances that share this data
+ * structure. */
BlockOfIconImagesPtr iconBlock;
- /* Pointer to icon resource data for
- * image. */
+ /* Pointer to icon resource data for image */
} WinIconInstance;
typedef struct WinIconInstance *WinIconPtr;
@@ -153,96 +162,97 @@ typedef struct WinIconInstance *WinIconPtr;
*/
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. */
+ 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. */
+ * 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 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:
+ * 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. */
+ 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). */
+ * 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 */
+ 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. */
+ /* 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 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. */
+ * 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
+ * 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. */
+ * 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) */
+ double alpha; /* Alpha transparency level 0.0 (fully
+ * transparent) .. 1.0 (opaque) */
/*
* List of children of the toplevel which have private colormaps.
@@ -255,61 +265,60 @@ typedef struct TkWmInfo {
* Miscellaneous information.
*/
- ProtocolHandler *protPtr; /* First in list of protocol handlers for
- * this window (NULL means none). */
+ 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. */
+ 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. */
+ 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
+ * 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
+ * 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
+ * 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"
+ * 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
+ * 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
+ * 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
+ * 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)
@@ -325,6 +334,7 @@ typedef struct TkWmInfo {
#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.
@@ -333,6 +343,9 @@ typedef struct TkWmInfo {
#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)
@@ -341,257 +354,258 @@ typedef struct TkWmInfo {
#define EX_TRANSIENT_STYLE (WS_EX_DLGMODALFRAME)
/*
- * The following structure is the official type record for geometry
- * management of top-level windows.
+ * 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 Tk_GeomMgr wmMgrType = {
- "wm", /* name */
- TopLevelReqProc, /* requestProc */
- (Tk_GeomLostSlaveProc *) NULL, /* lostSlaveProc */
+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. */
+ 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.
+ * 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. */
+static int initialized; /* Flag indicating whether module has been
+ * initialized. */
-/*
- * A pointer to a shell proc which allows us to extract icons from
- * any file. We just initialize this when we start up (if we can)
- * and then it never changes
+/*
+ * A pointer to a shell proc which allows us to extract icons from any file.
+ * We just initialize this when we start up (if we can) and then it never
+ * changes
*/
+
DWORD* (WINAPI *shgetfileinfoProc) (LPCTSTR pszPath, DWORD dwFileAttributes,
- SHFILEINFO* psfi, UINT cbFileInfo, UINT uFlags) = NULL;
+ SHFILEINFO* psfi, UINT cbFileInfo, UINT uFlags) = NULL;
/*
- * A pointer to SetLayeredWindowAttributes (user32.dll) which we
- * retrieve dynamically because it is only valid on Win2K+.
+ * A pointer to SetLayeredWindowAttributes (user32.dll) which we retrieve
+ * dynamically because it is only valid on Win2K+.
*/
+
BOOL (WINAPI *setLayeredWindowAttributesProc) (HWND hwnd, COLORREF crKey,
BYTE bAlpha, DWORD dwFlags) = NULL;
TCL_DECLARE_MUTEX(winWmMutex)
/*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-static int ActivateWindow _ANSI_ARGS_((Tcl_Event *evPtr,
- int flags));
-static void ConfigureTopLevel _ANSI_ARGS_((WINDOWPOS *pos));
-static void GenerateConfigureNotify _ANSI_ARGS_((
- TkWindow *winPtr));
-static void GetMaxSize _ANSI_ARGS_((WmInfo *wmPtr,
- int *maxWidthPtr, int *maxHeightPtr));
-static void GetMinSize _ANSI_ARGS_((WmInfo *wmPtr,
- int *minWidthPtr, int *minHeightPtr));
-static TkWindow * GetTopLevel _ANSI_ARGS_((HWND hwnd));
-static void InitWm _ANSI_ARGS_((void));
-static int InstallColormaps _ANSI_ARGS_((HWND hwnd, int message,
- int isForemost));
-static void InvalidateSubTree _ANSI_ARGS_((TkWindow *winPtr,
- Colormap colormap));
-static void InvalidateSubTreeDepth _ANSI_ARGS_((TkWindow *winPtr));
-static int ParseGeometry _ANSI_ARGS_((Tcl_Interp *interp,
- char *string, TkWindow *winPtr));
-static void RefreshColormap _ANSI_ARGS_((Colormap colormap,
- TkDisplay *dispPtr));
-static void SetLimits _ANSI_ARGS_((HWND hwnd, MINMAXINFO *info));
-static void TkWmStackorderToplevelWrapperMap _ANSI_ARGS_((
- TkWindow *winPtr,
- Display *display,
- Tcl_HashTable *table));
-static LRESULT CALLBACK TopLevelProc _ANSI_ARGS_((HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam));
-static void TopLevelEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void TopLevelReqProc _ANSI_ARGS_((ClientData dummy,
- Tk_Window tkwin));
-static void UpdateGeometryInfo _ANSI_ARGS_((
- ClientData clientData));
-static void UpdateWrapper _ANSI_ARGS_((TkWindow *winPtr));
-static LRESULT CALLBACK WmProc _ANSI_ARGS_((HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam));
-static void WmWaitVisibilityOrMapProc _ANSI_ARGS_((
- ClientData clientData, XEvent *eventPtr));
-static BlockOfIconImagesPtr ReadIconOrCursorFromFile _ANSI_ARGS_((
- Tcl_Interp *interp, Tcl_Obj* fileName, BOOL isIcon));
-static WinIconPtr ReadIconFromFile _ANSI_ARGS_((
- Tcl_Interp *interp, Tcl_Obj *fileName));
-static WinIconPtr GetIconFromPixmap _ANSI_ARGS_((Display *dsPtr,
- Pixmap pixmap));
-static int ReadICOHeader _ANSI_ARGS_((Tcl_Channel channel));
-static BOOL AdjustIconImagePointers _ANSI_ARGS_((LPICONIMAGE lpImage));
-static HICON MakeIconOrCursorFromResource
- _ANSI_ARGS_((LPICONIMAGE lpIcon, BOOL isIcon));
-static HICON GetIcon _ANSI_ARGS_((WinIconPtr titlebaricon,
- int icon_size));
-static int WinSetIcon _ANSI_ARGS_((Tcl_Interp *interp,
- WinIconPtr titlebaricon, Tk_Window tkw));
-static void FreeIconBlock _ANSI_ARGS_((BlockOfIconImagesPtr lpIR));
-static void DecrIconRefCount _ANSI_ARGS_((WinIconPtr titlebaricon));
-
-static int WmAspectCmd _ANSI_ARGS_((Tk_Window tkwin,
+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, 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 WmAttributesCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmClientCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmClientCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmColormapwindowsCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmColormapwindowsCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmCommandCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmCommandCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmDeiconifyCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmDeiconifyCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmFocusmodelCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmFocusmodelCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmForgetCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmFrameCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmFrameCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmGeometryCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmGeometryCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmGridCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmGridCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmGroupCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmGroupCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmIconbitmapCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmIconbitmapCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmIconifyCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmIconifyCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmIconmaskCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmIconmaskCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmIconnameCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmIconnameCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmIconphotoCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmIconphotoCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmIconpositionCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmIconpositionCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmIconwindowCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmIconwindowCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmMaxsizeCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmManageCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmMinsizeCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmMaxsizeCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmOverrideredirectCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmMinsizeCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmPositionfromCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmOverrideredirectCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmProtocolCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmPositionfromCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmResizableCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmProtocolCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmSizefromCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmResizableCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmStackorderCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmSizefromCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmStateCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmStackorderCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmTitleCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmStateCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmTransientCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmTitleCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int WmWithdrawCmd _ANSI_ARGS_((Tk_Window tkwin,
+ Tcl_Obj *CONST objv[]);
+static int WmTransientCmd(Tk_Window tkwin,
TkWindow *winPtr, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static void WmUpdateGeom _ANSI_ARGS_((WmInfo *wmPtr,
- TkWindow *winPtr));
+ 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)
+/*
+ * 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.
+ * 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.
- *
- * Side effects: None.
- *
+ * WORD - Number of entries in the color table.
*
*----------------------------------------------------------------------
*/
-static WORD
-DIBNumColors( LPSTR lpbi )
+
+static WORD
+DIBNumColors(
+ LPSTR lpbi)
{
WORD wBitCount;
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;
- if (dwClrUsed)
+ 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;
+ switch (wBitCount) {
+ case 1:
+ return 2;
+ case 4:
+ return 16;
+ case 8:
+ return 256;
+ default:
+ return 0;
}
}
@@ -600,22 +614,19 @@ DIBNumColors( LPSTR lpbi )
*
* 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.
+ * 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
- *
- * Side effects: None.
- *
+ * Number of bytes in the color table
*
*----------------------------------------------------------------------
*/
-static WORD
-PaletteSize( LPSTR lpbi )
+static WORD
+PaletteSize(
+ LPSTR lpbi)
{
- return ((WORD)( DIBNumColors( lpbi ) * sizeof( RGBQUAD )) );
+ return (WORD) (DIBNumColors(lpbi) * sizeof(RGBQUAD));
}
/*
@@ -623,9 +634,8 @@ PaletteSize( LPSTR lpbi )
*
* 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.
+ * 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
@@ -635,10 +645,12 @@ PaletteSize( LPSTR lpbi )
*
*----------------------------------------------------------------------
*/
-static LPSTR
-FindDIBBits( LPSTR lpbi )
+
+static LPSTR
+FindDIBBits(
+ LPSTR lpbi)
{
- return ( lpbi + *(LPDWORD)lpbi + PaletteSize( lpbi ) );
+ return lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi);
}
/*
@@ -647,19 +659,18 @@ FindDIBBits( LPSTR 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.
+ * 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)
*
- * Side effects: None
- *
- *
*----------------------------------------------------------------------
*/
-static DWORD
-BytesPerLine( LPBITMAPINFOHEADER lpBMIH )
+
+static DWORD
+BytesPerLine(
+ LPBITMAPINFOHEADER lpBMIH)
{
return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount);
}
@@ -669,41 +680,66 @@ BytesPerLine( LPBITMAPINFOHEADER lpBMIH )
*
* AdjustIconImagePointers --
*
- * Adjusts internal pointers in icon resource struct, as given
- * by LPICONIMAGE lpImage - the resource to handle. Used by
- * titlebar icon code.
+ * 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
*
- * Side effects:
- *
- *
*----------------------------------------------------------------------
*/
-static BOOL
-AdjustIconImagePointers( LPICONIMAGE lpImage )
+
+static BOOL
+AdjustIconImagePointers(
+ LPICONIMAGE lpImage)
{
- /* Sanity check */
- if (lpImage==NULL)
+ /*
+ * Sanity check.
+ */
+
+ if (lpImage == NULL) {
return FALSE;
- /* BITMAPINFO is at beginning of bits */
+ }
+
+ /*
+ * BITMAPINFO is at beginning of bits.
+ */
+
lpImage->lpbi = (LPBITMAPINFO)lpImage->lpBits;
- /* Width - simple enough */
+
+ /*
+ * Width - simple enough.
+ */
+
lpImage->Width = lpImage->lpbi->bmiHeader.biWidth;
- /*
- * Icons are stored in funky format where height is doubled
- * so account for that
+
+ /*
+ * 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 */
+
+ /*
+ * 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 */
+
+ /*
+ * AND bits follow the XOR bits.
+ */
+
lpImage->lpAND = lpImage->lpXOR + (lpImage->Height*
- BytesPerLine((LPBITMAPINFOHEADER)(lpImage->lpbi)));
+ BytesPerLine((LPBITMAPINFOHEADER)(lpImage->lpbi)));
return TRUE;
}
@@ -712,50 +748,70 @@ AdjustIconImagePointers( LPICONIMAGE lpImage )
*
* MakeIconOrCursorFromResource --
*
- * Construct an actual HICON structure from the information
- * in a resource.
+ * Construct an actual HICON structure from the information in a
+ * resource.
*
* Results:
- *
- *
- * Side effects:
- *
+ * Icon
*
*----------------------------------------------------------------------
*/
-static HICON
-MakeIconOrCursorFromResource(LPICONIMAGE lpIcon, BOOL isIcon) {
+
+static HICON
+MakeIconOrCursorFromResource(
+ LPICONIMAGE lpIcon,
+ BOOL isIcon)
+{
HICON hIcon ;
static FARPROC pfnCreateIconFromResourceEx=NULL;
static int initinfo=0;
- /* Sanity Check */
- if (lpIcon == NULL)
+
+ /*
+ * Sanity Check
+ */
+
+ if (lpIcon == NULL) {
return NULL;
- if (lpIcon->lpBits == NULL)
+ }
+ if (lpIcon->lpBits == NULL) {
return NULL;
+ }
+
if (!initinfo) {
HMODULE hMod = GetModuleHandleA("USER32.DLL");
- initinfo=1;
- if (hMod){
- pfnCreateIconFromResourceEx =
- GetProcAddress(hMod, "CreateIconFromResourceEx");
- }
- }
- /* Let the OS do the real work :) */
- if (pfnCreateIconFromResourceEx!=NULL) {
- hIcon = (HICON) (pfnCreateIconFromResourceEx)
- (lpIcon->lpBits, lpIcon->dwNumBytes, isIcon, 0x00030000,
- (*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biWidth,
- (*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biHeight/2, 0);
+
+ initinfo = 1;
+ if (hMod) {
+ pfnCreateIconFromResourceEx =
+ GetProcAddress(hMod, "CreateIconFromResourceEx");
+ }
+ }
+
+ /*
+ * Let the OS do the real work :)
+ */
+
+ if (pfnCreateIconFromResourceEx != NULL) {
+ hIcon = (HICON) (pfnCreateIconFromResourceEx) (lpIcon->lpBits,
+ lpIcon->dwNumBytes, isIcon, 0x00030000,
+ (*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biWidth,
+ (*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biHeight/2, 0);
} else {
hIcon = NULL;
}
- /* It failed, odds are good we're on NT so try the non-Ex way */
+
+ /*
+ * 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 */
+ /*
+ * 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);
+ hIcon = CreateIconFromResource(lpIcon->lpBits, lpIcon->dwNumBytes,
+ isIcon, 0x00030000);
}
}
return hIcon;
@@ -769,44 +825,51 @@ MakeIconOrCursorFromResource(LPICONIMAGE lpIcon, BOOL isIcon) {
* 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.
- *
- * Side effects:
- *
+ * 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 )
+
+static int
+ReadICOHeader(
+ Tcl_Channel channel)
{
- WORD Input;
- DWORD dwBytesRead;
+ union {
+ WORD word;
+ char bytes[sizeof(WORD)];
+ } input;
+
+ /*
+ * Read the 'reserved' WORD, which should be a zero word.
+ */
- /* Read the 'reserved' WORD */
- dwBytesRead = Tcl_Read( channel, (char*)&Input, sizeof( WORD ));
- /* Did we get a WORD? */
- if (dwBytesRead != sizeof( WORD ))
+ if (Tcl_Read(channel, input.bytes, sizeof(WORD)) != sizeof(WORD)) {
return -1;
- /* Was it 'reserved' ? (ie 0) */
- if (Input != 0)
+ }
+ if (input.word != 0) {
return -1;
- /* Read the type WORD */
- dwBytesRead = Tcl_Read( channel, (char*)&Input, sizeof( WORD ));
- /* Did we get a WORD? */
- if (dwBytesRead != sizeof( WORD ))
+ }
+
+ /*
+ * Read the type WORD, which should be of type 1.
+ */
+
+ if (Tcl_Read(channel, input.bytes, sizeof(WORD)) != sizeof(WORD)) {
return -1;
- /* Was it type 1? */
- if (Input != 1)
+ }
+ if (input.word != 1) {
return -1;
- /* Get the count of images */
- dwBytesRead = Tcl_Read( channel, (char*)&Input, sizeof( WORD ));
- /* Did we get a WORD? */
- if (dwBytesRead != sizeof( WORD ))
+ }
+
+ /*
+ * Get and return the count of images.
+ */
+
+ if (Tcl_Read(channel, input.bytes, sizeof(WORD)) != sizeof(WORD)) {
return -1;
- /* Return the count */
- return (int)Input;
+ }
+ return (int) input.word;
}
/*
@@ -824,10 +887,12 @@ ReadICOHeader( Tcl_Channel channel )
*
*----------------------------------------------------------------------
*/
-static int
-InitWindowClass(WinIconPtr titlebaricon)
+
+static int
+InitWindowClass(
+ WinIconPtr titlebaricon)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (! tsdPtr->initialized) {
@@ -845,28 +910,28 @@ InitWindowClass(WinIconPtr titlebaricon)
if (shgetfileinfoProc == NULL) {
HINSTANCE hInstance = LoadLibraryA("shell32");
if (hInstance != NULL) {
- shgetfileinfoProc =
- (DWORD* (WINAPI *) (LPCTSTR pszPath, DWORD dwFileAttributes,
- SHFILEINFO* psfi, UINT cbFileInfo, UINT uFlags)) GetProcAddress(hInstance,
- "SHGetFileInfo");
+ shgetfileinfoProc = (DWORD* (WINAPI *) (LPCTSTR pszPath,
+ DWORD dwFileAttributes, SHFILEINFO* psfi,
+ UINT cbFileInfo, UINT uFlags))
+ GetProcAddress(hInstance, "SHGetFileInfo");
FreeLibrary(hInstance);
}
}
if (setLayeredWindowAttributesProc == NULL) {
HINSTANCE hInstance = LoadLibraryA("user32");
if (hInstance != NULL) {
- setLayeredWindowAttributesProc =
- (BOOL (WINAPI *) (HWND hwnd, COLORREF crKey,
- BYTE bAlpha, DWORD dwFlags))
- GetProcAddress(hInstance,
- "SetLayeredWindowAttributes");
+ setLayeredWindowAttributesProc = (BOOL (WINAPI*)(HWND hwnd,
+ COLORREF crKey, BYTE bAlpha, DWORD dwFlags))
+ GetProcAddress(hInstance,"SetLayeredWindowAttributes");
FreeLibrary(hInstance);
}
}
+
/*
- * The only difference between WNDCLASSW and WNDCLASSA are
- * in pointers, so we can use the generic structure WNDCLASS.
+ * 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;
@@ -881,10 +946,12 @@ InitWindowClass(WinIconPtr titlebaricon)
if (class.hIcon == NULL) {
return TCL_ERROR;
}
+
/*
- * Store pointer to default icon so we know when
- * we need to free that information
+ * Store pointer to default icon so we know when we need to
+ * free that information
*/
+
tsdPtr->iconPtr = titlebaricon;
}
class.hCursor = LoadCursor(NULL, IDC_ARROW);
@@ -915,6 +982,7 @@ InitWindowClass(WinIconPtr titlebaricon)
*
*----------------------------------------------------------------------
*/
+
static void
InitWm(void)
{
@@ -927,52 +995,54 @@ InitWm(void)
*
* 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).
+ * 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).
+ * 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.
+ * 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(interp, titlebaricon, tkw)
- Tcl_Interp *interp;
- WinIconPtr titlebaricon;
- Tk_Window tkw;
+WinSetIcon(
+ Tcl_Interp *interp,
+ WinIconPtr titlebaricon,
+ Tk_Window tkw)
{
WmInfo *wmPtr;
HWND hwnd;
int application = 0;
if (tkw == NULL) {
- tkw = Tk_MainWindow(interp);
+ tkw = Tk_MainWindow(interp);
application = 1;
}
if (!(Tk_IsTopLevel(tkw))) {
Tcl_AppendResult(interp, "window \"", Tk_PathName(tkw),
- "\" isn't a top-level window", (char *) NULL);
+ "\" isn't a top-level window", NULL);
return TCL_ERROR;
}
if (Tk_WindowId(tkw) == None) {
Tk_MakeWindowExist(tkw);
}
- /* We must get the window's wrapper, not the window itself */
+
+ /*
+ * We must get the window's wrapper, not the window itself.
+ */
+
wmPtr = ((TkWindow*)tkw)->wmInfoPtr;
hwnd = wmPtr->wrapper;
@@ -980,56 +1050,39 @@ WinSetIcon(interp, titlebaricon, tkw)
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
+ * 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.
+ * icon. Otherwise our icon choice will be ignored moments later when
+ * Tk finishes initialising.
*/
+
if (!initialized) {
if (InitWindowClass(titlebaricon) != TCL_OK) {
- Tcl_AppendResult(interp,"Unable to set icon", (char*)NULL);
+ Tcl_AppendResult(interp, "Unable to set icon", NULL);
return TCL_ERROR;
}
} else {
ThreadSpecificData *tsdPtr;
- if (
-#ifdef _WIN64
- !SetClassLongPtr(hwnd, GCLP_HICONSM,
- (LPARAM)GetIcon(titlebaricon, ICON_SMALL))
-#else
- !SetClassLong(hwnd, GCL_HICONSM,
- (LPARAM)GetIcon(titlebaricon, ICON_SMALL))
-#endif
- ) {
- /*
- * For some reason this triggers, even though it seems
- * to be successful This is probably related to the
- * WNDCLASS vs WNDCLASSEX difference. Anyway it seems
- * we have to ignore errors returned here.
- */
- /*
- * Tcl_AppendResult(interp,"Unable to set new small icon", (char*)NULL);
- * return TCL_ERROR;
- */
- }
- if (
-#ifdef _WIN64
- !SetClassLongPtr(hwnd, GCLP_HICON,
- (LPARAM)GetIcon(titlebaricon, ICON_BIG))
-#else
- !SetClassLong(hwnd, GCL_HICON,
- (LPARAM)GetIcon(titlebaricon, ICON_BIG))
-#endif
- ) {
- Tcl_AppendResult(interp,"Unable to set new icon", (char*)NULL);
- return TCL_ERROR;
- }
+ /*
+ * 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) {
@@ -1040,31 +1093,35 @@ WinSetIcon(interp, titlebaricon, tkw)
} 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.
+ * 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);
+
+ (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.
+ * 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
+ * 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_AppendResult(interp,
- "Can't set icon; window has no wrapper.", (char*)NULL);
+ "Can't set icon; window has no wrapper.", NULL);
return TCL_ERROR;
}
}
@@ -1073,16 +1130,23 @@ WinSetIcon(interp, titlebaricon, tkw)
SendMessage(hwnd, WM_SETICON, ICON_BIG,
(LPARAM) GetIcon(titlebaricon, ICON_BIG));
- /* Update the iconPtr we keep for each WmInfo structure. */
+ /*
+ * Update the iconPtr we keep for each WmInfo structure.
+ */
+
if (wmPtr->iconPtr != NULL) {
- /* Free any old icon ptr which is associated with this window. */
+ /*
+ * 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.
+ * 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;
@@ -1093,8 +1157,8 @@ WinSetIcon(interp, titlebaricon, tkw)
*
* TkWinGetIcon --
*
- * Gets either the default toplevel titlebar icon, or the icon
- * for a specific toplevel (ICON_SMALL or ICON_BIG).
+ * Gets either the default toplevel titlebar icon, or the icon for a
+ * specific toplevel (ICON_SMALL or ICON_BIG).
*
* Results:
* A Windows HICON.
@@ -1104,22 +1168,29 @@ WinSetIcon(interp, titlebaricon, tkw)
*
*----------------------------------------------------------------------
*/
+
HICON
-TkWinGetIcon(Tk_Window tkwin, DWORD iconsize)
+TkWinGetIcon(
+ Tk_Window tkwin,
+ DWORD iconsize)
{
WmInfo *wmPtr;
HICON icon;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (tsdPtr->iconPtr != NULL) {
/*
* return default toplevel icon
*/
- return GetIcon(tsdPtr->iconPtr, iconsize);
+
+ return GetIcon(tsdPtr->iconPtr, (int)iconsize);
}
- /* ensure we operate on the toplevel, that has the icon refs */
+ /*
+ * Ensure we operate on the toplevel, that has the icon refs.
+ */
+
while (!Tk_IsTopLevel(tkwin)) {
tkwin = Tk_Parent(tkwin);
if (tkwin == NULL) {
@@ -1136,23 +1207,20 @@ TkWinGetIcon(Tk_Window tkwin, DWORD iconsize)
/*
* return window toplevel icon
*/
- return GetIcon(wmPtr->iconPtr, iconsize);
+
+ return GetIcon(wmPtr->iconPtr, (int)iconsize);
}
/*
- * Find the icon otherwise associated with the toplevel, or
- * finally with the window class.
+ * 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) {
-#ifdef _WIN64
icon = (HICON) GetClassLongPtr(wmPtr->wrapper,
(iconsize == ICON_BIG) ? GCLP_HICON : GCLP_HICONSM);
-#else
- icon = (HICON) GetClassLong(wmPtr->wrapper,
- (iconsize == ICON_BIG) ? GCL_HICON : GCL_HICONSM);
-#endif
}
return icon;
}
@@ -1162,117 +1230,129 @@ TkWinGetIcon(Tk_Window tkwin, DWORD iconsize)
*
* 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.
- *
+ * 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 procedure should
- * either place this structure inside a WmInfo structure, or it should
- * pass it on to DecrIconRefCount() to ensure no memory leaks occur.
+ * 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.
+ * 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.
+ * 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(interp, fileName)
- Tcl_Interp *interp;
- Tcl_Obj *fileName;
+ReadIconFromFile(
+ Tcl_Interp *interp,
+ Tcl_Obj *fileName)
{
WinIconPtr titlebaricon = NULL;
+ BlockOfIconImagesPtr lpIR;
if (0 /* If we already have an icon for this filename */) {
titlebaricon = NULL; /* Get the real value from a lookup */
titlebaricon->refCount++;
return titlebaricon;
- } else {
- /* First check if it is a .ico file */
- BlockOfIconImagesPtr lpIR;
- 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 && shgetfileinfoProc != 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_UtfToExternalDString(NULL, file, -1, &ds2);
- Tcl_DStringFree(&ds);
- res = (*shgetfileinfoProc)(Tcl_DStringValue(&ds2), 0, &sfiSM,
- sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON);
+ /*
+ * First check if it is a .ico file.
+ */
- if (res != 0) {
- SHFILEINFO sfi;
- int size;
-
- Tcl_ResetResult(interp);
- res = (*shgetfileinfoProc)(Tcl_DStringValue(&ds2), 0, &sfi,
- sizeof(SHFILEINFO), SHGFI_ICON);
-
- /* Account for extra icon, if necessary */
- size = sizeof(BlockOfIconImages) +
- ((res != 0) ? sizeof(ICONIMAGE) : 0);
- lpIR = (BlockOfIconImagesPtr) ckalloc(size);
- if (lpIR == NULL) {
- if (res != 0) {
- DestroyIcon(sfi.hIcon);
- }
- DestroyIcon(sfiSM.hIcon);
- Tcl_DStringFree(&ds2);
- return NULL;
- }
- ZeroMemory(lpIR, size);
+ 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 && shgetfileinfoProc != 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_UtfToExternalDString(NULL, file, -1, &ds2);
+ Tcl_DStringFree(&ds);
+ res = (*shgetfileinfoProc)(Tcl_DStringValue(&ds2), 0, &sfiSM,
+ sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON);
+
+ if (res != 0) {
+ SHFILEINFO sfi;
+ unsigned 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 */
+ Tcl_ResetResult(interp);
+ res = (*shgetfileinfoProc)(Tcl_DStringValue(&ds2), 0, &sfi,
+ sizeof(SHFILEINFO), SHGFI_ICON);
+
+ /*
+ * Account for extra icon, if necessary.
+ */
+ size = sizeof(BlockOfIconImages)
+ + ((res != 0) ? sizeof(ICONIMAGE) : 0);
+ lpIR = (BlockOfIconImagesPtr) ckalloc(size);
+ if (lpIR == NULL) {
if (res != 0) {
- lpIR->IconImages[1].Width = 32;
- lpIR->IconImages[1].Height = 32;
- lpIR->IconImages[1].Colors = 4;
- lpIR->IconImages[1].hIcon = sfi.hIcon;
+ 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 = (WinIconPtr) ckalloc(sizeof(WinIconInstance));
- titlebaricon->iconBlock = lpIR;
- titlebaricon->refCount = 1;
}
- return titlebaricon;
+ Tcl_DStringFree(&ds2);
}
+ if (lpIR != NULL) {
+ titlebaricon = (WinIconPtr) ckalloc(sizeof(WinIconInstance));
+ titlebaricon->iconBlock = lpIR;
+ titlebaricon->refCount = 1;
+ }
+ return titlebaricon;
}
/*
@@ -1280,90 +1360,93 @@ ReadIconFromFile(interp, fileName)
*
* GetIconFromPixmap --
*
- * Turn a Tk Pixmap (i.e. a bitmap) into an icon resource, if
- * possible, otherwise NULL is returned.
+ * 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 procedure 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.
+ * 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.
+ * 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(dsPtr, pixmap)
- Display *dsPtr;
- Pixmap pixmap;
+
+static WinIconPtr
+GetIconFromPixmap(
+ Display *dsPtr,
+ Pixmap pixmap)
{
WinIconPtr titlebaricon = NULL;
- TkWinDrawable* twdPtr = (TkWinDrawable*) pixmap;
-
+ TkWinDrawable *twdPtr = (TkWinDrawable*) pixmap;
+ BlockOfIconImagesPtr lpIR;
+ ICONINFO icon;
+ HICON hIcon;
+ int width, height;
+
if (twdPtr == NULL) {
- return NULL;
+ return NULL;
}
-
+
if (0 /* If we already have an icon for this pixmap */) {
titlebaricon = NULL; /* Get the real value from a lookup */
titlebaricon->refCount++;
return titlebaricon;
- } else {
- BlockOfIconImagesPtr lpIR;
- ICONINFO icon;
- HICON hIcon;
- int width, height;
+ }
- Tk_SizeOfBitmap(dsPtr, pixmap, &width, &height);
+ 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;
+ 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;
- }
+ hIcon = CreateIconIndirect(&icon);
+ if (hIcon == NULL) {
+ return NULL;
+ }
- lpIR = (BlockOfIconImagesPtr) ckalloc(sizeof(BlockOfIconImages));
- if (lpIR == NULL) {
- DestroyIcon(hIcon);
- return NULL;
- }
+ lpIR = (BlockOfIconImagesPtr) 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;
+ 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;
- titlebaricon = (WinIconPtr) ckalloc(sizeof(WinIconInstance));
- titlebaricon->iconBlock = lpIR;
- titlebaricon->refCount = 1;
- return titlebaricon;
- }
+ /*
+ * 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 = (WinIconPtr) ckalloc(sizeof(WinIconInstance));
+ titlebaricon->iconBlock = lpIR;
+ titlebaricon->refCount = 1;
+ return titlebaricon;
}
/*
@@ -1377,14 +1460,17 @@ GetIconFromPixmap(dsPtr, pixmap)
* 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.
+ * 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) {
+
+static void
+DecrIconRefCount(
+ WinIconPtr titlebaricon)
+{
titlebaricon->refCount--;
if (titlebaricon->refCount <= 0) {
@@ -1402,9 +1488,8 @@ DecrIconRefCount(WinIconPtr titlebaricon) {
*
* FreeIconBlock --
*
- * Frees all memory associated with a previously loaded
- * titlebaricon. The icon block pointer is no longer
- * valid once this function returns.
+ * Frees all memory associated with a previously loaded titlebaricon.
+ * The icon block pointer is no longer valid once this function returns.
*
* Results:
* None.
@@ -1414,12 +1499,17 @@ DecrIconRefCount(WinIconPtr titlebaricon) {
*
*----------------------------------------------------------------------
*/
-static void
-FreeIconBlock(BlockOfIconImagesPtr lpIR)
+
+static void
+FreeIconBlock(
+ BlockOfIconImagesPtr lpIR)
{
int i;
- /* Free all the bits */
+ /*
+ * Free all the bits.
+ */
+
for (i=0; i< lpIR->nNumImages; i++) {
if (lpIR->IconImages[i].lpBits != NULL) {
ckfree((char*)lpIR->IconImages[i].lpBits);
@@ -1441,18 +1531,18 @@ FreeIconBlock(BlockOfIconImagesPtr lpIR)
* Results:
* Returns the icon, if found, else NULL.
*
- * Side effects:
- *
- *
*----------------------------------------------------------------------
*/
-static HICON
-GetIcon(WinIconPtr titlebaricon, int icon_size)
+
+static HICON
+GetIcon(
+ WinIconPtr titlebaricon,
+ int icon_size)
{
BlockOfIconImagesPtr lpIR;
-
+
if (titlebaricon == NULL) {
- return NULL;
+ return NULL;
}
lpIR = titlebaricon->iconBlock;
@@ -1463,18 +1553,21 @@ GetIcon(WinIconPtr titlebaricon, int icon_size)
int i;
for (i = 0; i < lpIR->nNumImages; i++) {
- /* Take the first or a 32x32 16 color icon*/
+ /*
+ * 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)) {
+ && (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 we get here, then just return the first one, it will have to do!
*/
+
if (lpIR->nNumImages >= 1) {
return lpIR->IconImages[0].hIcon;
}
@@ -1482,38 +1575,64 @@ GetIcon(WinIconPtr titlebaricon, int icon_size)
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.
+ * 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.
+ * May leave error messages in the Tcl interpreter.
*
*----------------------------------------------------------------------
*/
-static BlockOfIconImagesPtr
-ReadIconOrCursorFromFile(Tcl_Interp* interp, Tcl_Obj* fileName, BOOL isIcon)
+
+static BlockOfIconImagesPtr
+ReadIconOrCursorFromFile(
+ Tcl_Interp *interp,
+ Tcl_Obj *fileName,
+ BOOL isIcon)
{
- BlockOfIconImagesPtr lpIR, lpNew;
- Tcl_Channel channel;
- int i;
- DWORD dwBytesRead;
- LPICONDIRENTRY lpIDE;
+ BlockOfIconImagesPtr lpIR;
+ Tcl_Channel channel;
+ int i;
+ DWORD dwBytesRead;
+ LPICONDIRENTRY lpIDE;
+
+ /*
+ * Open the file.
+ */
- /* Open the file */
channel = Tcl_FSOpenFileChannel(interp, fileName, "r", 0);
if (channel == NULL) {
- Tcl_AppendResult(interp,"Error opening file \"",
- Tcl_GetString(fileName),
- "\" for reading",(char*)NULL);
+ Tcl_AppendResult(interp,"Error opening file \"",
+ Tcl_GetString(fileName), "\" for reading", NULL);
return NULL;
}
if (Tcl_SetChannelOption(interp, channel, "-translation", "binary")
@@ -1526,99 +1645,127 @@ ReadIconOrCursorFromFile(Tcl_Interp* interp, Tcl_Obj* fileName, BOOL isIcon)
Tcl_Close(NULL, channel);
return NULL;
}
- /* Allocate memory for the resource structure */
+
+ /*
+ * Allocate memory for the resource structure
+ */
+
lpIR = (BlockOfIconImagesPtr) ckalloc(sizeof(BlockOfIconImages));
- if (lpIR == NULL) {
- Tcl_AppendResult(interp,"Error allocating memory",(char*)NULL);
- Tcl_Close(NULL, channel);
- return NULL;
- }
- /* Read in the header */
- if ((lpIR->nNumImages = ReadICOHeader( channel )) == -1) {
- Tcl_AppendResult(interp,"Invalid file header",(char*)NULL);
- Tcl_Close(NULL, channel);
- ckfree((char*) lpIR );
- return NULL;
- }
- /* Adjust the size of the struct to account for the images */
- lpNew = (BlockOfIconImagesPtr) ckrealloc((char*)lpIR,
- sizeof(BlockOfIconImages) + ((lpIR->nNumImages-1) * sizeof(ICONIMAGE)));
- if (lpNew == NULL) {
- Tcl_AppendResult(interp,"Error allocating memory",(char*)NULL);
+
+ /*
+ * Read in the header
+ */
+
+ if ((lpIR->nNumImages = ReadICOHeader(channel)) == -1) {
+ Tcl_AppendResult(interp, "Invalid file header", NULL);
Tcl_Close(NULL, channel);
- ckfree( (char*)lpIR );
+ ckfree((char*) lpIR);
return NULL;
}
- lpIR = lpNew;
- /* Allocate enough memory for the icon directory entries */
+
+ /*
+ * Adjust the size of the struct to account for the images.
+ */
+
+ lpIR = (BlockOfIconImagesPtr) ckrealloc((char*) lpIR,
+ sizeof(BlockOfIconImages)
+ + ((lpIR->nNumImages - 1) * sizeof(ICONIMAGE)));
+
+ /*
+ * Allocate enough memory for the icon directory entries.
+ */
+
lpIDE = (LPICONDIRENTRY) ckalloc(lpIR->nNumImages * sizeof(ICONDIRENTRY));
- if (lpIDE == NULL) {
- Tcl_AppendResult(interp,"Error allocating memory",(char*)NULL);
- Tcl_Close(NULL, channel);
- ckfree( (char*)lpIR );
- return NULL;
- }
- /* Read in the icon directory entries */
- dwBytesRead = Tcl_Read(channel, (char*)lpIDE,
- lpIR->nNumImages * sizeof( ICONDIRENTRY ));
- if (dwBytesRead != lpIR->nNumImages * sizeof( ICONDIRENTRY )) {
- Tcl_AppendResult(interp,"Error reading file",(char*)NULL);
+
+ /*
+ * Read in the icon directory entries.
+ */
+
+ dwBytesRead = Tcl_Read(channel, (char*) lpIDE,
+ (int)(lpIR->nNumImages * sizeof(ICONDIRENTRY)));
+ if (dwBytesRead != lpIR->nNumImages * sizeof(ICONDIRENTRY)) {
+ Tcl_AppendResult(interp, "Error reading file", NULL);
Tcl_Close(NULL, channel);
- ckfree( (char*)lpIR );
+ ckfree((char *) lpIDE);
+ ckfree((char *) lpIR);
return NULL;
}
- /* NULL-out everything to make memory management easier */
- for( i = 0; i < lpIR->nNumImages; i++ ) {
+
+ /*
+ * 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 */
+
+ /*
+ * Loop through and read in each image.
+ */
+
+ for (i=0 ; i<lpIR->nNumImages ; i++) {
+ /*
+ * Allocate memory for the resource.
+ */
+
lpIR->IconImages[i].lpBits = (LPBYTE) ckalloc(lpIDE[i].dwBytesInRes);
- if (lpIR->IconImages[i].lpBits == NULL) {
- Tcl_AppendResult(interp,"Error allocating memory",(char*)NULL);
- goto readError;
- }
lpIR->IconImages[i].dwNumBytes = lpIDE[i].dwBytesInRes;
- /* Seek to beginning of this image */
+
+ /*
+ * Seek to beginning of this image.
+ */
+
if (Tcl_Seek(channel, lpIDE[i].dwImageOffset, FILE_BEGIN) == -1) {
- Tcl_AppendResult(interp,"Error seeking in file",(char*)NULL);
+ Tcl_AppendResult(interp, "Error seeking in file", NULL);
goto readError;
}
- /* Read it in */
- dwBytesRead = Tcl_Read(channel, (char *) lpIR->IconImages[i].lpBits,
- lpIDE[i].dwBytesInRes);
+
+ /*
+ * Read it in.
+ */
+
+ dwBytesRead = Tcl_Read(channel, (char *) lpIR->IconImages[i].lpBits,
+ (int) lpIDE[i].dwBytesInRes);
if (dwBytesRead != lpIDE[i].dwBytesInRes) {
- Tcl_AppendResult(interp,"Error reading file",(char*)NULL);
+ Tcl_AppendResult(interp, "Error reading file", NULL);
goto readError;
}
- /* Set the internal pointers appropriately */
+
+ /*
+ * Set the internal pointers appropriately.
+ */
+
if (!AdjustIconImagePointers( &(lpIR->IconImages[i]))) {
- Tcl_AppendResult(interp,"Error converting to internal format",
- (char*)NULL);
+ Tcl_AppendResult(interp, "Error converting to internal format",
+ NULL);
goto readError;
}
lpIR->IconImages[i].hIcon =
- MakeIconOrCursorFromResource(&(lpIR->IconImages[i]), isIcon);
+ MakeIconOrCursorFromResource(&(lpIR->IconImages[i]), isIcon);
}
- /* Clean up */
- ckfree((char*)lpIDE);
+
+ /*
+ * Clean up
+ */
+
+ ckfree((char *) lpIDE);
Tcl_Close(NULL, channel);
if (lpIR == NULL){
- Tcl_AppendResult(interp,"Reading of ", Tcl_GetString(fileName),
- " failed!",(char*)NULL);
+ Tcl_AppendResult(interp, "Reading of ", Tcl_GetString(fileName),
+ " failed!", NULL);
return NULL;
}
return lpIR;
+
readError:
Tcl_Close(NULL, channel);
- for( i = 0; i < lpIR->nNumImages; i++ ) {
- if (lpIR->IconImages[i].lpBits != NULL) {
- ckfree((char*)lpIR->IconImages[i].lpBits);
+ for (i = 0; i < lpIR->nNumImages; i++) {
+ if (lpIR->IconImages[i].lpBits != NULL) {
+ ckfree((char *) lpIR->IconImages[i].lpBits);
}
}
- ckfree((char*)lpIDE );
- ckfree((char*)lpIR );
+ ckfree((char *) lpIDE);
+ ckfree((char *) lpIR);
return NULL;
}
@@ -1627,8 +1774,7 @@ ReadIconOrCursorFromFile(Tcl_Interp* interp, Tcl_Obj* fileName, BOOL isIcon)
*
* GetTopLevel --
*
- * This function retrieves the TkWindow associated with the
- * given HWND.
+ * This function retrieves the TkWindow associated with the given HWND.
*
* Results:
* Returns the matching TkWindow.
@@ -1638,27 +1784,24 @@ ReadIconOrCursorFromFile(Tcl_Interp* interp, Tcl_Obj* fileName, BOOL isIcon)
*
*----------------------------------------------------------------------
*/
+
static TkWindow *
-GetTopLevel(hwnd)
- HWND hwnd;
+GetTopLevel(
+ HWND hwnd)
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ 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 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;
}
-#ifdef _WIN64
return (TkWindow *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
-#else
- return (TkWindow *) GetWindowLong(hwnd, GWL_USERDATA);
-#endif
}
/*
@@ -1672,16 +1815,16 @@ GetTopLevel(hwnd)
* None.
*
* Side effects:
- * Changes the values of the info pointer to reflect the current
- * minimum and maximum size values.
+ * Changes the values of the info pointer to reflect the current minimum
+ * and maximum size values.
*
*----------------------------------------------------------------------
*/
static void
-SetLimits(hwnd, info)
- HWND hwnd;
- MINMAXINFO *info;
+SetLimits(
+ HWND hwnd,
+ MINMAXINFO *info)
{
register WmInfo *wmPtr;
int maxWidth, maxHeight;
@@ -1731,8 +1874,8 @@ SetLimits(hwnd, info)
}
/*
- * 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 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)) {
@@ -1754,8 +1897,8 @@ SetLimits(hwnd, info)
*
* TkWinWmCleanup --
*
- * Unregisters classes registered by the window manager. This is
- * called from the DLL main entry point when the DLL is unloaded.
+ * Unregisters classes registered by the window manager. This is called
+ * from the DLL main entry point when the DLL is unloaded.
*
* Results:
* None.
@@ -1767,19 +1910,19 @@ SetLimits(hwnd, info)
*/
void
-TkWinWmCleanup(hInstance)
- HINSTANCE hInstance;
+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.
+ * 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;
+ return;
}
#endif
@@ -1789,10 +1932,10 @@ TkWinWmCleanup(hInstance)
initialized = 0;
tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->initialized) {
- return;
+ return;
}
tsdPtr->initialized = 0;
@@ -1804,9 +1947,8 @@ TkWinWmCleanup(hInstance)
*
* TkWmNewWindow --
*
- * This procedure is invoked whenever a new top-level
- * window is created. Its job is to initialize the WmInfo
- * structure for the window.
+ * 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.
@@ -1818,8 +1960,8 @@ TkWinWmCleanup(hInstance)
*/
void
-TkWmNewWindow(winPtr)
- TkWindow *winPtr; /* Newly-created top-level window. */
+TkWmNewWindow(
+ TkWindow *winPtr) /* Newly-created top-level window. */
{
register WmInfo *wmPtr;
@@ -1828,6 +1970,7 @@ TkWmNewWindow(winPtr)
/*
* Initialize full structure, then set what isn't NULL
*/
+
ZeroMemory(wmPtr, sizeof(WmInfo));
winPtr->wmInfoPtr = wmPtr;
wmPtr->winPtr = winPtr;
@@ -1869,16 +2012,16 @@ TkWmNewWindow(winPtr)
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 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, (ClientData) winPtr);
/*
- * Arrange for geometry requests to be reflected from the window
- * to the window manager.
+ * Arrange for geometry requests to be reflected from the window to the
+ * window manager.
*/
Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);
@@ -1889,24 +2032,23 @@ TkWmNewWindow(winPtr)
*
* 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.
+ * 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.
+ * Destroys any old wrapper window and replaces it with a newly created
+ * wrapper.
*
*----------------------------------------------------------------------
*/
static void
-UpdateWrapper(winPtr)
- TkWindow *winPtr; /* Top-level window to redecorate. */
+UpdateWrapper(
+ TkWindow *winPtr) /* Top-level window to redecorate. */
{
register WmInfo *wmPtr = winPtr->wmInfoPtr;
HWND parentHWND, oldWrapper = wmPtr->wrapper;
@@ -1918,21 +2060,24 @@ UpdateWrapper(winPtr)
Tcl_DString titleString, classString;
int *childStateInfo = NULL;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ 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 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())) {
@@ -1950,13 +2095,13 @@ UpdateWrapper(winPtr)
} else {
/*
- * Pick the decorative frame style. Override redirect windows get
+ * 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
+ * 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
+ * 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.
*/
@@ -1964,13 +2109,20 @@ UpdateWrapper(winPtr)
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 */
+
+ /*
+ * 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;
@@ -1984,7 +2136,7 @@ UpdateWrapper(winPtr)
wmPtr->exStyle = EX_TOPLEVEL_STYLE;
}
- wmPtr->style |= wmPtr->styleConfig;
+ wmPtr->style |= wmPtr->styleConfig;
wmPtr->exStyle |= wmPtr->exStyleConfig;
if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE)
@@ -1996,10 +2148,6 @@ UpdateWrapper(winPtr)
* Compute the geometry of the parent and child windows.
*/
- if ((wmPtr->flags & WM_UPDATE_PENDING)) {
- Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
- }
-
wmPtr->flags |= WM_CREATE_PENDING|WM_MOVE_PENDING;
UpdateGeometryInfo((ClientData)winPtr);
wmPtr->flags &= ~(WM_CREATE_PENDING|WM_MOVE_PENDING);
@@ -2009,11 +2157,17 @@ UpdateWrapper(winPtr)
/*
* Set the initial position from the user or program specified
- * location. If nothing has been specified, then let the system
- * pick a location.
+ * 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->sizeHintsFlags & (USPosition | PPosition))
+ 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;
@@ -2023,14 +2177,16 @@ UpdateWrapper(winPtr)
}
/*
- * Create the containing window, and set the user data to point
- * to the TkWindow.
+ * 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->title : winPtr->nameUid), -1, &titleString);
+
Tcl_WinUtfToTChar(TK_WIN_TOPLEVEL_CLASS_NAME, -1, &classString);
+
wmPtr->wrapper = (*tkWinProcs->createWindowEx)(wmPtr->exStyle,
(LPCTSTR) Tcl_DStringValue(&classString),
(LPCTSTR) Tcl_DStringValue(&titleString),
@@ -2038,23 +2194,20 @@ UpdateWrapper(winPtr)
parentHWND, NULL, Tk_GetHINSTANCE(), NULL);
Tcl_DStringFree(&classString);
Tcl_DStringFree(&titleString);
-#ifdef _WIN64
- SetWindowLongPtr(wmPtr->wrapper, GWLP_USERDATA, (LONG_PTR) winPtr);
-#else
- SetWindowLong(wmPtr->wrapper, GWL_USERDATA, (LONG) winPtr);
-#endif
+ SetWindowLongPtr(wmPtr->wrapper, GWLP_USERDATA, (INT_PTR) winPtr);
tsdPtr->createWindow = NULL;
if ((wmPtr->exStyleConfig & WS_EX_LAYERED)
&& setLayeredWindowAttributesProc != NULL) {
/*
* 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.
+ * int (transparent) 0..255 (opaque), so do the translation. Add
+ * the 0.5 to round the value.
*/
+
setLayeredWindowAttributesProc((HWND) wmPtr->wrapper,
wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
- LWA_ALPHA | (wmPtr->crefObj ? LWA_COLORKEY : 0));
+ (unsigned)(LWA_ALPHA | (wmPtr->crefObj?LWA_COLORKEY:0)));
} else {
/*
* Layering not used or supported.
@@ -2071,9 +2224,8 @@ UpdateWrapper(winPtr)
wmPtr->x = place.rcNormalPosition.left;
wmPtr->y = place.rcNormalPosition.top;
- if (!(winPtr->flags & TK_ALREADY_DEAD)) {
+ if( !(winPtr->flags & TK_ALREADY_DEAD) )
TkInstallFrameMenu((Tk_Window) winPtr);
- }
if (oldWrapper && (oldWrapper != wmPtr->wrapper)
&& !(wmPtr->exStyle & WS_EX_TOPMOST)) {
@@ -2081,30 +2233,24 @@ UpdateWrapper(winPtr)
* 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.
+ * 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.
*/
-#ifdef _WIN64
SetWindowLongPtr(child, GWL_STYLE,
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
-#else
- SetWindowLong(child, GWL_STYLE,
- WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
-#endif
+
if (winPtr->flags & TK_EMBEDDED) {
-#ifdef _WIN64
- SetWindowLongPtr(child, GWLP_WNDPROC, (LONG_PTR) TopLevelProc);
-#else
- SetWindowLong(child, GWL_WNDPROC, (LONG) TopLevelProc);
-#endif
+ SetWindowLongPtr(child, GWLP_WNDPROC, (INT_PTR) TopLevelProc);
}
+
SetParent(child, wmPtr->wrapper);
if (oldWrapper) {
hSmallIcon = (HICON) SendMessage(oldWrapper, WM_GETICON, ICON_SMALL,
@@ -2115,32 +2261,29 @@ UpdateWrapper(winPtr)
if (oldWrapper && (oldWrapper != wmPtr->wrapper)
&& (oldWrapper != GetDesktopWindow())) {
-#ifdef _WIN64
SetWindowLongPtr(oldWrapper, GWLP_USERDATA, (LONG) NULL);
-#else
- SetWindowLong(oldWrapper, GWL_USERDATA, (LONG) NULL);
-#endif
if (wmPtr->numTransients > 0) {
/*
* Unset the current wrapper as the parent for all transient
* children for whom this is the master
*/
+
WmInfo *wmPtr2;
- childStateInfo = (int *)ckalloc((unsigned) wmPtr->numTransients
- * sizeof(int));
+ childStateInfo = (int *)
+ ckalloc((unsigned) wmPtr->numTransients * sizeof(int));
state = 0;
for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
- wmPtr2 = wmPtr2->nextPtr) {
- if (wmPtr2->masterPtr == winPtr) {
- if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
- childStateInfo[state++] = wmPtr2->hints.initial_state;
- SetParent(TkWinGetHWND(wmPtr2->winPtr->window), 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.
@@ -2151,12 +2294,18 @@ UpdateWrapper(winPtr)
}
wmPtr->flags &= ~WM_NEVER_MAPPED;
- SendMessage(wmPtr->wrapper, TK_ATTACHWINDOW, (WPARAM) child, 0);
+ 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.
+ * 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;
@@ -2167,6 +2316,7 @@ UpdateWrapper(winPtr)
|SWP_NOOWNERZORDER);
}
TkpWmSetState(winPtr, state);
+ wmPtr->hints.initial_state = state;
if (hSmallIcon != NULL) {
SendMessage(wmPtr->wrapper,WM_SETICON,ICON_SMALL,(LPARAM)hSmallIcon);
@@ -2176,15 +2326,18 @@ UpdateWrapper(winPtr)
}
/*
- * 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 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);
}
@@ -2193,7 +2346,7 @@ UpdateWrapper(winPtr)
*/
if (wmPtr->hMenu != NULL) {
- wmPtr->flags = WM_SYNC_PENDING;
+ wmPtr->flags |= WM_SYNC_PENDING;
SetMenu(wmPtr->wrapper, wmPtr->hMenu);
wmPtr->flags &= ~WM_SYNC_PENDING;
}
@@ -2201,18 +2354,18 @@ UpdateWrapper(winPtr)
if (childStateInfo) {
if (wmPtr->numTransients > 0) {
/*
- * Reset all transient children for whom this is the master
+ * 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) {
- if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
- UpdateWrapper(wmPtr2->winPtr);
- TkpWmSetState(wmPtr2->winPtr, childStateInfo[state++]);
- }
+ wmPtr2 = wmPtr2->nextPtr) {
+ if (wmPtr2->masterPtr == winPtr
+ && !(wmPtr2->flags & WM_NEVER_MAPPED)) {
+ UpdateWrapper(wmPtr2->winPtr);
+ TkpWmSetState(wmPtr2->winPtr, childStateInfo[state++]);
}
}
}
@@ -2221,11 +2374,11 @@ UpdateWrapper(winPtr)
}
/*
- * 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
- * XXX: best be avoided, if we could safely mask them.
+ * 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) {
@@ -2241,32 +2394,32 @@ UpdateWrapper(winPtr)
*
* TkWmMapWindow --
*
- * This procedure 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.
+ * 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 procedure decides that
- * isn't appropriate (e.g. because the window is withdrawn).
+ * 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(winPtr)
- TkWindow *winPtr; /* Top-level window that's about to
- * be mapped. */
+TkWmMapWindow(
+ TkWindow *winPtr) /* Top-level window that's about to be
+ * mapped. */
{
register WmInfo *wmPtr = winPtr->wmInfoPtr;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->initialized) {
InitWm();
@@ -2278,7 +2431,7 @@ TkWmMapWindow(winPtr)
*/
if (wmPtr->masterPtr != NULL &&
- !Tk_IsMapped(wmPtr->masterPtr)) {
+ !Tk_IsMapped(wmPtr->masterPtr)) {
wmPtr->hints.initial_state = WithdrawnState;
return;
}
@@ -2288,7 +2441,7 @@ TkWmMapWindow(winPtr)
}
/*
- * Map the window in either the iconified or normal state. Note that
+ * 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.
*/
@@ -2296,9 +2449,8 @@ TkWmMapWindow(winPtr)
}
/*
- * This is the first time this window has ever been mapped.
- * Store all the window-manager-related information for the
- * window.
+ * This is the first time this window has ever been mapped. Store all the
+ * window-manager-related information for the window.
*/
UpdateWrapper(winPtr);
@@ -2309,9 +2461,9 @@ TkWmMapWindow(winPtr)
*
* TkWmUnmapWindow --
*
- * This procedure is invoked to unmap a top-level window. The
- * only thing it does special is unmap the decorative frame before
- * unmapping the toplevel window.
+ * 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.
@@ -2323,9 +2475,9 @@ TkWmMapWindow(winPtr)
*/
void
-TkWmUnmapWindow(winPtr)
- TkWindow *winPtr; /* Top-level window that's about to
- * be unmapped. */
+TkWmUnmapWindow(
+ TkWindow *winPtr) /* Top-level window that's about to be
+ * unmapped. */
{
TkpWmSetState(winPtr, WithdrawnState);
}
@@ -2335,8 +2487,8 @@ TkWmUnmapWindow(winPtr)
*
* TkpWmSetState --
*
- * Sets the window manager state for the wrapper window of a
- * given toplevel window.
+ * Sets the window manager state for the wrapper window of a given
+ * toplevel window.
*
* Results:
* None.
@@ -2348,13 +2500,13 @@ TkWmUnmapWindow(winPtr)
*/
void
-TkpWmSetState(winPtr, state)
- TkWindow *winPtr; /* Toplevel window to operate on. */
- int state; /* One of IconicState, ZoomState, NormalState,
+TkpWmSetState(
+ TkWindow *winPtr, /* Toplevel window to operate on. */
+ int state) /* One of IconicState, ZoomState, NormalState,
* or WithdrawnState. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr;
- int cmd = 0;
+ int cmd;
if (wmPtr->flags & WM_NEVER_MAPPED) {
wmPtr->hints.initial_state = state;
@@ -2370,6 +2522,8 @@ TkpWmSetState(winPtr, state)
cmd = SW_SHOWNOACTIVATE;
} else if (state == ZoomState) {
cmd = SW_SHOWMAXIMIZED;
+ } else {
+ return;
}
ShowWindow(wmPtr->wrapper, cmd);
@@ -2377,13 +2531,103 @@ TkpWmSetState(winPtr, state)
}
/*
+ *----------------------------------------------------------------------
+ *
+ * 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 procedure is invoked when a top-level window is
- * about to be deleted. It cleans up the wm-related data
- * structures for the window.
+ * 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.
@@ -2395,8 +2639,8 @@ TkpWmSetState(winPtr, state)
*/
void
-TkWmDeadWindow(winPtr)
- TkWindow *winPtr; /* Top-level window that's being deleted. */
+TkWmDeadWindow(
+ TkWindow *winPtr) /* Top-level window that's being deleted. */
{
register WmInfo *wmPtr = winPtr->wmInfoPtr;
WmInfo *wmPtr2;
@@ -2414,7 +2658,7 @@ TkWmDeadWindow(winPtr)
} else {
register WmInfo *prevPtr;
for (prevPtr = winPtr->dispPtr->firstWmPtr; ;
- prevPtr = prevPtr->nextPtr) {
+ prevPtr = prevPtr->nextPtr) {
if (prevPtr == NULL) {
Tcl_Panic("couldn't unlink window in TkWmDeadWindow");
}
@@ -2434,8 +2678,8 @@ TkWmDeadWindow(winPtr)
if (wmPtr2->masterPtr == winPtr) {
wmPtr->numTransients--;
Tk_DeleteEventHandler((Tk_Window) wmPtr2->masterPtr,
- VisibilityChangeMask|StructureNotifyMask,
- WmWaitVisibilityOrMapProc, (ClientData) wmPtr2->winPtr);
+ VisibilityChangeMask|StructureNotifyMask,
+ WmWaitVisibilityOrMapProc, (ClientData) wmPtr2->winPtr);
wmPtr2->masterPtr = NULL;
if ((wmPtr2->wrapper != None)
&& !(wmPtr2->flags & (WM_NEVER_MAPPED))) {
@@ -2444,7 +2688,7 @@ TkWmDeadWindow(winPtr)
}
}
if (wmPtr->numTransients != 0)
- Tcl_Panic("numTransients should be 0");
+ Tcl_Panic("numTransients should be 0");
if (wmPtr->title != NULL) {
ckfree(wmPtr->title);
@@ -2488,10 +2732,11 @@ TkWmDeadWindow(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 we had a master, tell them that we aren't tied to them anymore.
*/
+
if (wmPtr2 != NULL) {
wmPtr2->numTransients--;
}
@@ -2512,17 +2757,22 @@ TkWmDeadWindow(winPtr)
if (!(winPtr->flags & TK_EMBEDDED)) {
if (wmPtr->wrapper != NULL) {
DestroyWindow(wmPtr->wrapper);
- } else {
+ } 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.
+ * 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);
+
+ DecrIconRefCount(wmPtr->iconPtr);
}
ckfree((char *) wmPtr);
@@ -2534,11 +2784,10 @@ TkWmDeadWindow(winPtr)
*
* TkWmSetClass --
*
- * This procedure is invoked whenever a top-level window's
- * class is changed. If the window has been mapped then this
- * procedure 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.
+ * 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.
@@ -2550,9 +2799,10 @@ TkWmDeadWindow(winPtr)
*/
void
-TkWmSetClass(winPtr)
- TkWindow *winPtr; /* Newly-created top-level window. */
+TkWmSetClass(
+ TkWindow *winPtr) /* Newly-created top-level window. */
{
+ /* Do nothing */
return;
}
@@ -2561,8 +2811,8 @@ TkWmSetClass(winPtr)
*
* Tk_WmObjCmd --
*
- * This procedure is invoked to process the "wm" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -2575,49 +2825,51 @@ TkWmSetClass(winPtr)
/* ARGSUSED */
int
-Tk_WmObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+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 = (Tk_Window) clientData;
static CONST char *optionStrings[] = {
"aspect", "attributes", "client", "colormapwindows",
- "command", "deiconify", "focusmodel", "frame",
+ "command", "deiconify", "focusmodel", "forget", "frame",
"geometry", "grid", "group", "iconbitmap",
"iconify", "iconmask", "iconname",
"iconphoto", "iconposition",
- "iconwindow", "maxsize", "minsize", "overrideredirect",
- "positionfrom", "protocol", "resizable", "sizefrom",
- "stackorder", "state", "title", "transient",
- "withdraw", (char *) NULL };
+ "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_FRAME,
+ 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_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT,
- WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
- WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
- WMOPT_WITHDRAW };
+ 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, length;
char *argv1;
- TkWindow *winPtr;
+ TkWindow *winPtr, **winPtrPtr = &winPtr;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
if (objc < 2) {
- wrongNumArgs:
+ wrongNumArgs:
Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
return TCL_ERROR;
}
argv1 = Tcl_GetStringFromObj(objv[1], &length);
- if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0)
+ if ((argv1[0] == 't') && !strncmp(argv1, "tracing", (unsigned) length)
&& (length >= 3)) {
int wmTracing;
+
if ((objc != 2) && (objc != 3)) {
Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
return TCL_ERROR;
@@ -2648,76 +2900,81 @@ Tk_WmObjCmd(clientData, interp, objc, objv)
goto wrongNumArgs;
}
- if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
+ if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) winPtrPtr)
!= TCL_OK) {
return TCL_ERROR;
}
- if (!Tk_IsTopLevel(winPtr)) {
+ if (!Tk_IsTopLevel(winPtr) &&
+ (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) {
Tcl_AppendResult(interp, "window \"", winPtr->pathName,
- "\" isn't a top-level window", (char *) NULL);
+ "\" isn't a top-level window", NULL);
return TCL_ERROR;
}
switch ((enum options) index) {
- case WMOPT_ASPECT:
+ case WMOPT_ASPECT:
return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_ATTRIBUTES:
+ case WMOPT_ATTRIBUTES:
return WmAttributesCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_CLIENT:
+ case WMOPT_CLIENT:
return WmClientCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_COLORMAPWINDOWS:
+ case WMOPT_COLORMAPWINDOWS:
return WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_COMMAND:
+ case WMOPT_COMMAND:
return WmCommandCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_DEICONIFY:
+ case WMOPT_DEICONIFY:
return WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_FOCUSMODEL:
+ case WMOPT_FOCUSMODEL:
return WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_FRAME:
+ case WMOPT_FORGET:
+ return WmForgetCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_FRAME:
return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_GEOMETRY:
+ case WMOPT_GEOMETRY:
return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_GRID:
+ case WMOPT_GRID:
return WmGridCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_GROUP:
+ case WMOPT_GROUP:
return WmGroupCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_ICONBITMAP:
+ case WMOPT_ICONBITMAP:
return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_ICONIFY:
+ case WMOPT_ICONIFY:
return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_ICONMASK:
+ case WMOPT_ICONMASK:
return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_ICONNAME:
+ case WMOPT_ICONNAME:
return WmIconnameCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_ICONPHOTO:
- return WmIconphotoCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_ICONPOSITION:
+ case WMOPT_ICONPHOTO:
+ return WmIconphotoCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_ICONPOSITION:
return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_ICONWINDOW:
+ case WMOPT_ICONWINDOW:
return WmIconwindowCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_MAXSIZE:
+ case WMOPT_MANAGE:
+ return WmManageCmd(tkwin, winPtr, interp, objc, objv);
+ case WMOPT_MAXSIZE:
return WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_MINSIZE:
+ case WMOPT_MINSIZE:
return WmMinsizeCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_OVERRIDEREDIRECT:
+ case WMOPT_OVERRIDEREDIRECT:
return WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_POSITIONFROM:
+ case WMOPT_POSITIONFROM:
return WmPositionfromCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_PROTOCOL:
+ case WMOPT_PROTOCOL:
return WmProtocolCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_RESIZABLE:
+ case WMOPT_RESIZABLE:
return WmResizableCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_SIZEFROM:
+ case WMOPT_SIZEFROM:
return WmSizefromCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_STACKORDER:
+ case WMOPT_STACKORDER:
return WmStackorderCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_STATE:
+ case WMOPT_STATE:
return WmStateCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_TITLE:
+ case WMOPT_TITLE:
return WmTitleCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_TRANSIENT:
+ case WMOPT_TRANSIENT:
return WmTransientCmd(tkwin, winPtr, interp, objc, objv);
- case WMOPT_WITHDRAW:
+ case WMOPT_WITHDRAW:
return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv);
}
@@ -2730,8 +2987,8 @@ Tk_WmObjCmd(clientData, interp, objc, objv)
*
* WmAspectCmd --
*
- * This procedure is invoked to process the "wm aspect" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -2743,12 +3000,12 @@ Tk_WmObjCmd(clientData, interp, objc, objv)
*/
static int
-WmAspectCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -2778,10 +3035,8 @@ WmAspectCmd(tkwin, winPtr, interp, objc, objv)
|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
return TCL_ERROR;
}
- if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
- (denom2 <= 0)) {
- Tcl_SetResult(interp, "aspect number can't be <= 0",
- TCL_STATIC);
+ if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) || (denom2 <= 0)) {
+ Tcl_SetResult(interp, "aspect number can't be <= 0", TCL_STATIC);
return TCL_ERROR;
}
wmPtr->minAspect.x = numer1;
@@ -2799,7 +3054,7 @@ WmAspectCmd(tkwin, winPtr, interp, objc, objv)
*
* WmAttributesCmd --
*
- * This procedure is invoked to process the "wm attributes" Tcl command.
+ * This function is invoked to process the "wm attributes" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -2812,31 +3067,34 @@ WmAspectCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
+ LONG style, exStyle, styleBit, *stylePtr = NULL;
char *string;
- int i, boolean, length, updatewrapper = 0;
+ int i, boolean, length;
+ int config_fullscreen = 0, updatewrapper = 0;
+ int fullscreen_attr_changed = 0, fullscreen_attr = 0;
if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) {
- configArgs:
+ 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;
+ style = wmPtr->styleConfig;
if (objc == 3) {
Tcl_Obj *objPtr = Tcl_NewObj();
Tcl_ListObjAppendElement(NULL, objPtr,
@@ -2851,6 +3109,10 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
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)));
@@ -2866,16 +3128,19 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
if ((length < 2) || (string[0] != '-')) {
goto configArgs;
}
- if (strncmp(string, "-disabled", length) == 0) {
+ if (strncmp(string, "-disabled", (unsigned) length) == 0) {
stylePtr = &style;
styleBit = WS_DISABLED;
- } else if ((strncmp(string, "-alpha", length) == 0)
+ } else if ((strncmp(string, "-alpha", (unsigned) length) == 0)
|| ((length > 2) && (strncmp(string, "-transparentcolor",
- length) == 0))) {
+ (unsigned) length) == 0))) {
stylePtr = &exStyle;
styleBit = WS_EX_LAYERED;
+ } else if (strncmp(string, "-fullscreen", (unsigned) length) == 0) {
+ config_fullscreen = 1;
+ styleBit = 0;
} else if ((length > 3)
- && (strncmp(string, "-toolwindow", length) == 0)) {
+ && (strncmp(string, "-toolwindow", (unsigned) length) == 0)) {
stylePtr = &exStyle;
styleBit = WS_EX_TOOLWINDOW;
if (objc != 4) {
@@ -2885,13 +3150,12 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
updatewrapper = 1;
}
} else if ((length > 3)
- && (strncmp(string, "-topmost", length) == 0)) {
+ && (strncmp(string, "-topmost", (unsigned) length) == 0)) {
stylePtr = &exStyle;
styleBit = WS_EX_TOPMOST;
if ((i < objc-1) && (winPtr->flags & TK_EMBEDDED)) {
Tcl_AppendResult(interp, "can't set topmost flag on ",
- winPtr->pathName, ": it is an embedded window",
- (char *) NULL);
+ winPtr->pathName, ": it is an embedded window", NULL);
return TCL_ERROR;
}
} else {
@@ -2968,20 +3232,17 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
* 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.
+ * translation. Add the 0.5 to round the value.
*/
+
if (!(wmPtr->exStyleConfig & WS_EX_LAYERED)) {
-#ifdef _WIN64
SetWindowLongPtr(wmPtr->wrapper, GWL_EXSTYLE,
*stylePtr);
-#else
- SetWindowLong(wmPtr->wrapper, GWL_EXSTYLE,
- *stylePtr);
-#endif
}
setLayeredWindowAttributesProc((HWND) wmPtr->wrapper,
wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
- LWA_ALPHA | (wmPtr->crefObj ? LWA_COLORKEY : 0));
+ (unsigned) (LWA_ALPHA |
+ (wmPtr->crefObj ? LWA_COLORKEY : 0)));
}
}
} else {
@@ -2990,7 +3251,16 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
!= TCL_OK)) {
return TCL_ERROR;
}
- if (objc == 4) {
+ if (config_fullscreen) {
+ if (objc == 4) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->flags & WM_FULLSCREEN));
+ } else {
+ fullscreen_attr_changed = 1;
+ fullscreen_attr = boolean;
+ }
+ config_fullscreen = 0;
+ } else if (objc == 4) {
Tcl_SetIntObj(Tcl_GetObjResult(interp),
((*stylePtr & styleBit) != 0));
} else if (boolean) {
@@ -3013,9 +3283,10 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
}
if (wmPtr->styleConfig != style) {
/*
- * Currently this means only WS_DISABLED changed, which we can
- * effect with EnableWindow.
+ * 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)) {
@@ -3029,11 +3300,43 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
* 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_AppendResult(interp,
+ "can't set fullscreen attribute for \"",
+ winPtr->pathName, "\": override-redirect flag is set",
+ 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_AppendResult(interp,
+ "can't set fullscreen attribute for \"",
+ winPtr->pathName, "\": max width/height is too small",
+ NULL);
+ return TCL_ERROR;
+ }
+ }
+
+ TkpWmSetFullScreen(winPtr, fullscreen_attr);
+ }
+
return TCL_OK;
}
@@ -3042,8 +3345,8 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
*
* WmClientCmd --
*
- * This procedure is invoked to process the "wm client" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -3055,12 +3358,12 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmClientCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
char *argv3;
@@ -3083,8 +3386,7 @@ WmClientCmd(tkwin, winPtr, interp, objc, objv)
wmPtr->clientMachine = NULL;
if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
XDeleteProperty(winPtr->display, winPtr->window,
- Tk_InternAtom((Tk_Window) winPtr,
- "WM_CLIENT_MACHINE"));
+ Tk_InternAtom((Tk_Window) winPtr,"WM_CLIENT_MACHINE"));
}
}
return TCL_OK;
@@ -3097,6 +3399,7 @@ WmClientCmd(tkwin, winPtr, interp, objc, objv)
strcpy(wmPtr->clientMachine, argv3);
if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
XTextProperty textProp;
+
if (XStringListToTextProperty(&wmPtr->clientMachine, 1, &textProp)
!= 0) {
XSetWMClientMachine(winPtr->display, winPtr->window,
@@ -3112,9 +3415,8 @@ WmClientCmd(tkwin, winPtr, interp, objc, objv)
*
* WmColormapwindowsCmd --
*
- * This procedure is invoked to process the "wm colormapwindows"
- * Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -3126,16 +3428,16 @@ WmClientCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
- TkWindow *winPtr2;
+ TkWindow *winPtr2, **winPtr2Ptr = &winPtr2;
int i, windowObjc, gotToplevel;
Tcl_Obj **windowObjv;
@@ -3163,8 +3465,7 @@ WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv)
gotToplevel = 0;
for (i = 0; i < windowObjc; i++) {
if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
- (Tk_Window *) &winPtr2) != TCL_OK)
- {
+ (Tk_Window *) winPtr2Ptr) != TCL_OK) {
ckfree((char *) cmapList);
return TCL_ERROR;
}
@@ -3207,8 +3508,8 @@ WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv)
*
* WmCommandCmd --
*
- * This procedure is invoked to process the "wm command" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -3220,12 +3521,12 @@ WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmCommandCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
char *argv3;
@@ -3239,8 +3540,7 @@ WmCommandCmd(tkwin, winPtr, interp, objc, objv)
if (objc == 3) {
if (wmPtr->cmdArgv != NULL) {
Tcl_SetResult(interp,
- Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv),
- TCL_DYNAMIC);
+ Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv), TCL_DYNAMIC);
}
return TCL_OK;
}
@@ -3275,7 +3575,7 @@ WmCommandCmd(tkwin, winPtr, interp, objc, objv)
*
* WmDeiconifyCmd --
*
- * This procedure is invoked to process the "wm deiconify" Tcl command.
+ * This function is invoked to process the "wm deiconify" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -3288,12 +3588,12 @@ WmCommandCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -3303,56 +3603,18 @@ WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv)
}
if (wmPtr->iconFor != NULL) {
Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
- ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
- (char *) NULL);
+ ": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);
return TCL_ERROR;
}
if (winPtr->flags & TK_EMBEDDED) {
- Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
- ": it is an embedded window", (char *) NULL);
- return TCL_ERROR;
- }
-
- 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, (ClientData) winPtr);
- UpdateGeometryInfo((ClientData) 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) {
+ if (!SendMessage(wmPtr->wrapper, TK_DEICONIFY, 0, 0)) {
+ Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
+ ": the container does not support the request", NULL);
+ return TCL_ERROR;
+ }
return TCL_OK;
}
-
- /*
- * 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);
- }
+ TkpWinToplevelDeiconify(winPtr);
return TCL_OK;
}
@@ -3361,7 +3623,7 @@ WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv)
*
* WmFocusmodelCmd --
*
- * This procedure is invoked to process the "wm focusmodel" Tcl command.
+ * This function is invoked to process the "wm focusmodel" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -3374,18 +3636,20 @@ WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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 *optionStrings[] = {
- "active", "passive", (char *) NULL };
+ "active", "passive", NULL
+ };
enum options {
- OPT_ACTIVE, OPT_PASSIVE };
+ OPT_ACTIVE, OPT_PASSIVE
+ };
int index;
if ((objc != 3) && (objc != 4)) {
@@ -3413,9 +3677,9 @@ WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv)
/*
*----------------------------------------------------------------------
*
- * WmFrameCmd --
+ * WmForgetCmd --
*
- * This procedure is invoked to process the "wm frame" Tcl command.
+ * This procedure is invoked to process the "wm forget" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -3428,13 +3692,54 @@ WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmFrameCmd(tkwin, winPtr, interp, objc, objv)
+WmForgetCmd(tkwin, winPtr, interp, objc, objv)
Tk_Window tkwin; /* Main window of the application. */
- TkWindow *winPtr; /* Toplevel to work with */
+ 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));
+ 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;
char buf[TCL_INTEGER_SPACE];
@@ -3460,7 +3765,7 @@ WmFrameCmd(tkwin, winPtr, interp, objc, objv)
*
* WmGeometryCmd --
*
- * This procedure is invoked to process the "wm geometry" Tcl command.
+ * This function is invoked to process the "wm geometry" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -3473,12 +3778,12 @@ WmFrameCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmGeometryCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -3491,6 +3796,7 @@ WmGeometryCmd(tkwin, winPtr, interp, objc, objv)
}
if (objc == 3) {
char buf[16 + TCL_INTEGER_SPACE * 4];
+ int x, y;
xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+';
@@ -3503,8 +3809,14 @@ WmGeometryCmd(tkwin, winPtr, interp, objc, objv)
width = winPtr->changes.width;
height = winPtr->changes.height;
}
- sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x,
- ySign, wmPtr->y);
+ if(winPtr->flags & TK_EMBEDDED) {
+ int result = SendMessage(wmPtr->wrapper, TK_MOVEWINDOW, -1, -1);
+ wmPtr->x = result >> 16;
+ wmPtr->y = result & 0x0000ffff;
+ }
+ x = wmPtr->x;
+ y = wmPtr->y;
+ sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, x, ySign, y);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_OK;
}
@@ -3523,8 +3835,8 @@ WmGeometryCmd(tkwin, winPtr, interp, objc, objv)
*
* WmGridCmd --
*
- * This procedure is invoked to process the "wm grid" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -3536,12 +3848,12 @@ WmGeometryCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmGridCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -3564,8 +3876,8 @@ WmGridCmd(tkwin, winPtr, interp, objc, objv)
}
if (*Tcl_GetString(objv[3]) == '\0') {
/*
- * Turn off gridding and reset the width and height
- * to make sense as ungridded numbers.
+ * Turn off gridding and reset the width and height to make sense as
+ * ungridded numbers.
*/
wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
@@ -3612,8 +3924,8 @@ WmGridCmd(tkwin, winPtr, interp, objc, objv)
*
* WmGroupCmd --
*
- * This procedure is invoked to process the "wm group" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -3625,12 +3937,12 @@ WmGridCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmGroupCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -3675,7 +3987,7 @@ WmGroupCmd(tkwin, winPtr, interp, objc, objv)
*
* WmIconbitmapCmd --
*
- * This procedure is invoked to process the "wm iconbitmap" Tcl command.
+ * This function is invoked to process the "wm iconbitmap" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -3688,12 +4000,12 @@ WmGroupCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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) */
@@ -3703,17 +4015,23 @@ WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv)
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 */
+ /*
+ * If we have 5 arguments, we must have a '-default' flag.
+ */
+
char *argv3 = Tcl_GetString(objv[3]);
+
if (strcmp(argv3, "-default")) {
- Tcl_AppendResult(interp, "illegal option \"",
- argv3, "\" must be \"-default\"",
- (char *) NULL);
+ Tcl_AppendResult(interp, "illegal option \"", argv3,
+ "\" must be \"-default\"", NULL);
return TCL_ERROR;
}
useWinPtr = NULL;
} else if (objc == 3) {
- /* No arguments were given */
+ /*
+ * No arguments were given.
+ */
+
if (wmPtr->hints.flags & IconPixmapHint) {
Tcl_SetResult(interp, (char *)
Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
@@ -3735,42 +4053,46 @@ WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv)
} 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.
+ * 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.
+ * 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.
+ * 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
+ * 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 */
+ /*
+ * 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
+ * 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);
@@ -3780,13 +4102,14 @@ WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv)
wmPtr->hints.icon_pixmap = pixmap;
wmPtr->hints.flags |= IconPixmapHint;
titlebaricon = GetIconFromPixmap(Tk_Display(winPtr), pixmap);
- if (titlebaricon != 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 && WinSetIcon(interp, titlebaricon,
+ (Tk_Window) useWinPtr) != TCL_OK) {
+ /*
+ * We didn't use the titlebaricon after all.
+ */
+
+ DecrIconRefCount(titlebaricon);
+ titlebaricon = NULL;
}
}
}
@@ -3798,8 +4121,8 @@ WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv)
*
* WmIconifyCmd --
*
- * This procedure is invoked to process the "wm iconify" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -3811,37 +4134,38 @@ WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmIconifyCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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_AppendResult(interp, "can't iconify ", winPtr->pathName,
+ ": the container does not support the request", NULL);
+ return TCL_ERROR;
+ }
+ }
if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
- "\": override-redirect flag is set", (char *) NULL);
+ "\": override-redirect flag is set", NULL);
return TCL_ERROR;
}
if (wmPtr->masterPtr != NULL) {
Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
- "\": it is a transient", (char *) NULL);
+ "\": it is a transient", NULL);
return TCL_ERROR;
}
if (wmPtr->iconFor != NULL) {
Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
- ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
- (char *) NULL);
- return TCL_ERROR;
- }
- if (winPtr->flags & TK_EMBEDDED) {
- Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
- ": it is an embedded window", (char *) NULL);
+ ": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);
return TCL_ERROR;
}
TkpWmSetState(winPtr, IconicState);
@@ -3853,7 +4177,7 @@ WmIconifyCmd(tkwin, winPtr, interp, objc, objv)
*
* WmIconmaskCmd --
*
- * This procedure is invoked to process the "wm iconmask" Tcl command.
+ * This function is invoked to process the "wm iconmask" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -3866,12 +4190,12 @@ WmIconifyCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmIconmaskCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -3911,7 +4235,7 @@ WmIconmaskCmd(tkwin, winPtr, interp, objc, objv)
*
* WmIconnameCmd --
*
- * This procedure is invoked to process the "wm iconname" Tcl command.
+ * This function is invoked to process the "wm iconname" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -3924,12 +4248,12 @@ WmIconmaskCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmIconnameCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
char *argv3;
@@ -3963,8 +4287,7 @@ WmIconnameCmd(tkwin, winPtr, interp, objc, objv)
*
* WmIconphotoCmd --
*
- * This procedure is invoked to process the "wm iconphoto"
- * Tcl command.
+ * This function is invoked to process the "wm iconphoto" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -3977,30 +4300,36 @@ WmIconnameCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmIconphotoCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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, size, width, height, idx, bufferSize, startObj = 3;
- unsigned char *bgraPixelPtr;
+ int i, width, height, idx, bufferSize, startObj = 3;
+ union {unsigned char *ptr; void *voidPtr;} bgraPixel;
+ void *bgraMaskPtr;
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;
@@ -4014,58 +4343,120 @@ WmIconphotoCmd(tkwin, winPtr, interp, objc, objv)
photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
if (photo == NULL) {
Tcl_AppendResult(interp, "can't use \"", Tcl_GetString(objv[i]),
- "\" as iconphoto: not a photo image", (char *) NULL);
+ "\" as iconphoto: not a photo image", 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 = (BlockOfIconImagesPtr) Tcl_AttemptAlloc(size);
+
+ /*
+ * We have calculated the size of the data. Try to allocate the needed
+ * memory space.
+ */
+
+ size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1));
+ lpIR = (BlockOfIconImagesPtr) 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);
/*
- * Convert the image data into BGRA format (RGBQUAD) and then
- * encode the image data into an HICON.
+ * 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((char *) lpIR);
+ Tcl_AppendResult(interp, "failed to create color bitmap for \"",
+ Tcl_GetString(objv[i]), "\"", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Convert the photo image data into BGRA format (RGBQUAD).
*/
- bufferSize = height * width * block.pixelSize;
- bgraPixelPtr = (unsigned char *) ckalloc(bufferSize);
+ bufferSize = height * width * 4;
for (idx = 0 ; idx < bufferSize ; idx += 4) {
- bgraPixelPtr[idx] = block.pixelPtr[idx+2];
- bgraPixelPtr[idx+1] = block.pixelPtr[idx+1];
- bgraPixelPtr[idx+2] = block.pixelPtr[idx+0];
- bgraPixelPtr[idx+3] = block.pixelPtr[idx+3];
- }
- hIcon = CreateIcon(Tk_GetHINSTANCE(), width, height, 1, 32,
- NULL, (BYTE *) bgraPixelPtr);
- ckfree((char *) bgraPixelPtr);
+ 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, &bgraMaskPtr, NULL, 0 );
+ if ( !iconInfo.hbmMask ) {
+ DeleteObject(iconInfo.hbmColor);
+ ckfree((char *) lpIR);
+ Tcl_AppendResult(interp, "failed to create mask bitmap for \"",
+ Tcl_GetString(objv[i]), "\"", NULL);
+ return TCL_ERROR;
+ }
+
+ ZeroMemory( bgraMaskPtr, 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 */
- Tcl_Free((char *) lpIR);
+ /*
+ * XXX should free up created icons.
+ */
+
+ ckfree((char *) lpIR);
Tcl_AppendResult(interp, "failed to create icon for \"",
- Tcl_GetString(objv[i]), "\"", (char *) NULL);
+ Tcl_GetString(objv[i]), "\"", NULL);
return TCL_ERROR;
}
- lpIR->IconImages[i-startObj].Width = width;
+ lpIR->IconImages[i-startObj].Width = width;
lpIR->IconImages[i-startObj].Height = height;
lpIR->IconImages[i-startObj].Colors = 4;
- lpIR->IconImages[i-startObj].hIcon = hIcon;
+ lpIR->IconImages[i-startObj].hIcon = hIcon;
}
+
titlebaricon = (WinIconPtr) 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 */
+ /*
+ * We didn't use the titlebaricon after all.
+ */
+
DecrIconRefCount(titlebaricon);
return TCL_ERROR;
}
@@ -4077,8 +4468,7 @@ WmIconphotoCmd(tkwin, winPtr, interp, objc, objv)
*
* WmIconpositionCmd --
*
- * This procedure is invoked to process the "wm iconposition"
- * Tcl command.
+ * This function is invoked to process the "wm iconposition" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -4091,12 +4481,12 @@ WmIconphotoCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmIconpositionCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -4134,7 +4524,7 @@ WmIconpositionCmd(tkwin, winPtr, interp, objc, objv)
*
* WmIconwindowCmd --
*
- * This procedure is invoked to process the "wm iconwindow" Tcl command.
+ * This function is invoked to process the "wm iconwindow" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -4147,12 +4537,12 @@ WmIconpositionCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmIconwindowCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -4173,8 +4563,8 @@ WmIconwindowCmd(tkwin, winPtr, interp, objc, objv)
wmPtr->hints.flags &= ~IconWindowHint;
if (wmPtr->icon != NULL) {
/*
- * Let the window use button events again, then remove
- * it as icon window.
+ * Let the window use button events again, then remove it as icon
+ * window.
*/
atts.event_mask = Tk_Attributes(wmPtr->icon)->event_mask
@@ -4191,14 +4581,14 @@ WmIconwindowCmd(tkwin, winPtr, interp, objc, objv)
}
if (!Tk_IsTopLevel(tkwin2)) {
Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]),
- " as icon window: not at top level", (char *) NULL);
+ " as icon window: not at top level", NULL);
return TCL_ERROR;
}
wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
if (wmPtr2->iconFor != NULL) {
Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
- " is already an icon for ",
- Tk_PathName(wmPtr2->iconFor), (char *) NULL);
+ " is already an icon for ", Tk_PathName(wmPtr2->iconFor),
+ NULL);
return TCL_ERROR;
}
if (wmPtr->icon != NULL) {
@@ -4215,10 +4605,9 @@ WmIconwindowCmd(tkwin, winPtr, interp, objc, objv)
}
/*
- * 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.
+ * 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
@@ -4240,9 +4629,9 @@ WmIconwindowCmd(tkwin, winPtr, interp, objc, objv)
/*
*----------------------------------------------------------------------
*
- * WmMaxsizeCmd --
+ * WmManageCmd --
*
- * This procedure is invoked to process the "wm maxsize" Tcl command.
+ * This procedure is invoked to process the "wm manage" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -4255,13 +4644,66 @@ WmIconwindowCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv)
+WmManageCmd(tkwin, winPtr, interp, objc, objv)
Tk_Window tkwin; /* Main window of the application. */
- TkWindow *winPtr; /* Toplevel to work with */
+ 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_AppendResult(interp, "window \"",
+ Tk_PathName(frameWin), "\" is not manageable: must be "
+ "a frame, labelframe or toplevel", 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;
@@ -4292,8 +4734,8 @@ WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv)
*
* WmMinsizeCmd --
*
- * This procedure is invoked to process the "wm minsize" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -4305,12 +4747,12 @@ WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmMinsizeCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -4342,9 +4784,8 @@ WmMinsizeCmd(tkwin, winPtr, interp, objc, objv)
*
* WmOverrideredirectCmd --
*
- * This procedure is invoked to process the "wm overrideredirect"
- * Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -4356,12 +4797,12 @@ WmMinsizeCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -4371,7 +4812,16 @@ WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv)
Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
return TCL_ERROR;
}
- curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
+ if(winPtr->flags & TK_EMBEDDED) {
+ curValue = SendMessage(wmPtr->wrapper, TK_OVERRIDEREDIRECT, -1, -1)-1;
+ if (curValue < 0) {
+ Tcl_AppendResult(interp,
+ "Container does not support overrideredirect", NULL);
+ return TCL_ERROR;
+ }
+ } else {
+ curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
+ }
if (objc == 3) {
Tcl_SetBooleanObj(Tcl_GetObjResult(interp), curValue);
return TCL_OK;
@@ -4380,16 +4830,21 @@ WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv)
return TCL_ERROR;
}
if (curValue != boolean) {
- /*
- * 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);
+ 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;
@@ -4400,8 +4855,7 @@ WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv)
*
* WmPositionfromCmd --
*
- * This procedure is invoked to process the "wm positionfrom"
- * Tcl command.
+ * This function is invoked to process the "wm positionfrom" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -4414,18 +4868,20 @@ WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmPositionfromCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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 *optionStrings[] = {
- "program", "user", (char *) NULL };
+ "program", "user", NULL
+ };
enum options {
- OPT_PROGRAM, OPT_USER };
+ OPT_PROGRAM, OPT_USER
+ };
int index;
if ((objc != 3) && (objc != 4)) {
@@ -4464,7 +4920,7 @@ WmPositionfromCmd(tkwin, winPtr, interp, objc, objv)
*
* WmProtocolCmd --
*
- * This procedure is invoked to process the "wm protocol" Tcl command.
+ * This function is invoked to process the "wm protocol" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -4477,12 +4933,12 @@ WmPositionfromCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmProtocolCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -4498,8 +4954,9 @@ WmProtocolCmd(tkwin, winPtr, interp, objc, objv)
/*
* Return a list of all defined protocols for the window.
*/
+
for (protPtr = wmPtr->protPtr; protPtr != NULL;
- protPtr = protPtr->nextPtr) {
+ protPtr = protPtr->nextPtr) {
Tcl_AppendElement(interp,
Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
}
@@ -4510,8 +4967,9 @@ WmProtocolCmd(tkwin, winPtr, interp, objc, objv)
/*
* Return the command to handle a given protocol.
*/
+
for (protPtr = wmPtr->protPtr; protPtr != NULL;
- protPtr = protPtr->nextPtr) {
+ protPtr = protPtr->nextPtr) {
if (protPtr->protocol == protocol) {
Tcl_SetResult(interp, protPtr->command, TCL_STATIC);
return TCL_OK;
@@ -4521,13 +4979,12 @@ WmProtocolCmd(tkwin, winPtr, interp, objc, objv)
}
/*
- * Delete any current protocol handler, then create a new
- * one with the specified command, unless the command is
- * empty.
+ * 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) {
+ prevPtr = protPtr, protPtr = protPtr->nextPtr) {
if (protPtr->protocol == protocol) {
if (prevPtr == NULL) {
wmPtr->protPtr = protPtr->nextPtr;
@@ -4555,7 +5012,7 @@ WmProtocolCmd(tkwin, winPtr, interp, objc, objv)
*
* WmResizableCmd --
*
- * This procedure is invoked to process the "wm resizable" Tcl command.
+ * This function is invoked to process the "wm resizable" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -4568,12 +5025,12 @@ WmProtocolCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmResizableCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -4586,8 +5043,8 @@ WmResizableCmd(tkwin, winPtr, interp, objc, objv)
char buf[TCL_INTEGER_SPACE * 2];
sprintf(buf, "%d %d",
- (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
- (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
+ (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
+ (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_OK;
}
@@ -4618,7 +5075,7 @@ WmResizableCmd(tkwin, winPtr, interp, objc, objv)
*
* WmSizefromCmd --
*
- * This procedure is invoked to process the "wm sizefrom" Tcl command.
+ * This function is invoked to process the "wm sizefrom" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -4631,18 +5088,20 @@ WmResizableCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmSizefromCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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 *optionStrings[] = {
- "program", "user", (char *) NULL };
+ "program", "user", NULL
+ };
enum options {
- OPT_PROGRAM, OPT_USER };
+ OPT_PROGRAM, OPT_USER
+ };
int index;
if ((objc != 3) && (objc != 4)) {
@@ -4682,7 +5141,7 @@ WmSizefromCmd(tkwin, winPtr, interp, objc, objv)
*
* WmStackorderCmd --
*
- * This procedure is invoked to process the "wm stackorder" Tcl command.
+ * This function is invoked to process the "wm stackorder" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -4695,18 +5154,20 @@ WmSizefromCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmStackorderCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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, **window_ptr;
static CONST char *optionStrings[] = {
- "isabove", "isbelow", (char *) NULL };
+ "isabove", "isbelow", NULL
+ };
enum options {
- OPT_ISABOVE, OPT_ISBELOW };
+ OPT_ISABOVE, OPT_ISBELOW
+ };
int index;
if ((objc != 3) && (objc != 5)) {
@@ -4726,55 +5187,57 @@ WmStackorderCmd(tkwin, winPtr, interp, objc, objv)
return TCL_OK;
}
} else {
- TkWindow *winPtr2;
+ TkWindow *winPtr2, **winPtr2Ptr = &winPtr2;
int index1=-1, index2=-1, result;
- if (TkGetWindowFromObj(interp, tkwin, objv[4], (Tk_Window *) &winPtr2)
- != TCL_OK) {
+ if (TkGetWindowFromObj(interp, tkwin, objv[4],
+ (Tk_Window *) winPtr2Ptr) != TCL_OK) {
return TCL_ERROR;
}
if (!Tk_IsTopLevel(winPtr2)) {
Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
- "\" isn't a top-level window", (char *) NULL);
+ "\" isn't a top-level window", NULL);
return TCL_ERROR;
}
if (!Tk_IsMapped(winPtr)) {
Tcl_AppendResult(interp, "window \"", winPtr->pathName,
- "\" isn't mapped", (char *) NULL);
+ "\" isn't mapped", NULL);
return TCL_ERROR;
}
if (!Tk_IsMapped(winPtr2)) {
Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
- "\" isn't mapped", (char *) NULL);
+ "\" isn't 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.
+ * 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_AppendResult(interp, "TkWmStackorderToplevel failed",
- (char *) NULL);
+ Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", NULL);
return TCL_ERROR;
} else {
for (window_ptr = windows; *window_ptr ; window_ptr++) {
- if (*window_ptr == winPtr)
+ if (*window_ptr == winPtr) {
index1 = (window_ptr - windows);
- if (*window_ptr == winPtr2)
+ }
+ if (*window_ptr == winPtr2) {
index2 = (window_ptr - windows);
+ }
}
- if (index1 == -1)
+ if (index1 == -1) {
Tcl_Panic("winPtr window not found");
- if (index2 == -1)
+ }
+ if (index2 == -1) {
Tcl_Panic("winPtr2 window not found");
+ }
ckfree((char *) windows);
}
@@ -4799,8 +5262,8 @@ WmStackorderCmd(tkwin, winPtr, interp, objc, objv)
*
* WmStateCmd --
*
- * This procedure is invoked to process the "wm state" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -4812,18 +5275,20 @@ WmStackorderCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmStateCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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 *optionStrings[] = {
- "normal", "iconic", "withdrawn", "zoomed", (char *) NULL };
+ "normal", "iconic", "withdrawn", "zoomed", NULL
+ };
enum options {
- OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED };
+ OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED
+ };
int index;
if ((objc < 3) || (objc > 4)) {
@@ -4833,15 +5298,12 @@ WmStateCmd(tkwin, winPtr, interp, objc, objv)
if (objc == 4) {
if (wmPtr->iconFor != NULL) {
Tcl_AppendResult(interp, "can't change state of ",
- Tcl_GetString(objv[2]),
- ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
- (char *) NULL);
+ Tcl_GetString(objv[2]), ": it is an icon for ",
+ Tk_PathName(wmPtr->iconFor), NULL);
return TCL_ERROR;
}
- if (winPtr->flags & TK_EMBEDDED) {
- Tcl_AppendResult(interp, "can't change state of ",
- winPtr->pathName, ": it is an embedded window",
- (char *) NULL);
+ if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
+ &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -4850,25 +5312,52 @@ WmStateCmd(tkwin, winPtr, interp, objc, objv)
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_AppendResult(interp, "can't change state of ",
+ winPtr->pathName,
+ ": the container does not support the request", 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
+ * 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_AppendResult(interp, "can't iconify \"",
- winPtr->pathName,
- "\": override-redirect flag is set",
- (char *) NULL);
+ Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
+ "\": override-redirect flag is set", NULL);
return TCL_ERROR;
}
if (wmPtr->masterPtr != NULL) {
Tcl_AppendResult(interp, "can't iconify \"",
- winPtr->pathName,
- "\": it is a transient", (char *) NULL);
+ winPtr->pathName, "\": it is a transient", NULL);
return TCL_ERROR;
}
TkpWmSetState(winPtr, IconicState);
@@ -4884,17 +5373,24 @@ WmStateCmd(tkwin, winPtr, interp, objc, objv)
if (wmPtr->iconFor != NULL) {
Tcl_SetResult(interp, "icon", TCL_STATIC);
} else {
- switch (wmPtr->hints.initial_state) {
- case NormalState:
+ 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:
Tcl_SetResult(interp, "normal", TCL_STATIC);
break;
- case IconicState:
+ case IconicState:
Tcl_SetResult(interp, "iconic", TCL_STATIC);
break;
- case WithdrawnState:
+ case WithdrawnState:
Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
break;
- case ZoomState:
+ case ZoomState:
Tcl_SetResult(interp, "zoomed", TCL_STATIC);
break;
}
@@ -4908,8 +5404,8 @@ WmStateCmd(tkwin, winPtr, interp, objc, objv)
*
* WmTitleCmd --
*
- * This procedure is invoked to process the "wm title" Tcl command.
- * See the user documentation for details on what it does.
+ * 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.
@@ -4921,26 +5417,43 @@ WmStateCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmTitleCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
char *argv3;
int 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) {
- Tcl_SetResult(interp, (char *)
- ((wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid),
- TCL_STATIC);
- return TCL_OK;
+ if (wrapper) {
+ char buf[512];
+ Tcl_DString titleString;
+ int size = tkWinProcs->useWide ? 256 : 512;
+
+ (*tkWinProcs->getWindowText)(wrapper, (LPCTSTR)buf, size);
+ Tcl_WinTCharToUtf(buf, -1, &titleString);
+ Tcl_SetResult(interp, Tcl_DStringValue(&titleString),TCL_VOLATILE);
+ Tcl_DStringFree(&titleString);
+ } else {
+ Tcl_SetResult(interp, (char *)
+ ((wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid),
+ TCL_STATIC);
+ }
} else {
if (wmPtr->title != NULL) {
ckfree((char *) wmPtr->title);
@@ -4952,7 +5465,7 @@ WmTitleCmd(tkwin, winPtr, interp, objc, objv)
if (!(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper != NULL) {
Tcl_DString titleString;
Tcl_WinUtfToTChar(wmPtr->title, -1, &titleString);
- (*tkWinProcs->setWindowText)(wmPtr->wrapper,
+ (*tkWinProcs->setWindowText)(wrapper,
(LPCTSTR) Tcl_DStringValue(&titleString));
Tcl_DStringFree(&titleString);
}
@@ -4965,7 +5478,7 @@ WmTitleCmd(tkwin, winPtr, interp, objc, objv)
*
* WmTransientCmd --
*
- * This procedure is invoked to process the "wm transient" Tcl command.
+ * This function is invoked to process the "wm transient" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -4978,15 +5491,15 @@ WmTitleCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmTransientCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
+ TkWindow *masterPtr = wmPtr->masterPtr, **masterPtrPtr = &masterPtr;
WmInfo *wmPtr2;
if ((objc != 3) && (objc != 4)) {
@@ -5002,8 +5515,8 @@ WmTransientCmd(tkwin, winPtr, interp, objc, objv)
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
+ * If we had a master, tell them that we aren't tied to them
+ * anymore.
*/
masterPtr->wmInfoPtr->numTransients--;
@@ -5015,7 +5528,7 @@ WmTransientCmd(tkwin, winPtr, interp, objc, objv)
wmPtr->masterPtr = NULL;
} else {
if (TkGetWindowFromObj(interp, tkwin, objv[3],
- (Tk_Window *) &masterPtr) != TCL_OK) {
+ (Tk_Window *) masterPtrPtr) != TCL_OK) {
return TCL_ERROR;
}
while (!Tk_TopWinHierarchy(masterPtr)) {
@@ -5028,35 +5541,30 @@ WmTransientCmd(tkwin, winPtr, interp, objc, objv)
Tk_MakeWindowExist((Tk_Window) masterPtr);
if (wmPtr->iconFor != NULL) {
- Tcl_AppendResult(interp, "can't make \"",
- Tcl_GetString(objv[2]),
+ Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[2]),
"\" a transient: it is an icon for ",
- Tk_PathName(wmPtr->iconFor),
- (char *) NULL);
+ Tk_PathName(wmPtr->iconFor), NULL);
return TCL_ERROR;
}
wmPtr2 = masterPtr->wmInfoPtr;
if (wmPtr2->iconFor != NULL) {
- Tcl_AppendResult(interp, "can't make \"",
- Tcl_GetString(objv[3]),
+ Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[3]),
"\" a master: it is an icon for ",
- Tk_PathName(wmPtr2->iconFor),
- (char *) NULL);
+ Tk_PathName(wmPtr2->iconFor), NULL);
return TCL_ERROR;
}
if (masterPtr == winPtr) {
Tcl_AppendResult(interp, "can't make \"", Tk_PathName(winPtr),
- "\" its own master",
- (char *) NULL);
+ "\" its own master", 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.
+ * 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) {
@@ -5091,7 +5599,7 @@ WmTransientCmd(tkwin, winPtr, interp, objc, objv)
*
* WmWithdrawCmd --
*
- * This procedure is invoked to process the "wm withdraw" Tcl command.
+ * This function is invoked to process the "wm withdraw" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
@@ -5104,12 +5612,12 @@ WmTransientCmd(tkwin, winPtr, interp, objc, objv)
*/
static int
-WmWithdrawCmd(tkwin, winPtr, interp, objc, objv)
- 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. */
+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;
@@ -5119,23 +5627,32 @@ WmWithdrawCmd(tkwin, winPtr, interp, objc, objv)
}
if (wmPtr->iconFor != NULL) {
Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
- ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
- (char *) NULL);
+ ": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);
return TCL_ERROR;
}
- wmPtr->flags |= WM_WITHDRAWN;
- TkpWmSetState(winPtr, WithdrawnState);
+
+ if (winPtr->flags & TK_EMBEDDED) {
+ if (SendMessage(wmPtr->wrapper, TK_WITHDRAW, 0, 0) < 0) {
+ Tcl_AppendResult(interp, "can't withdraw", Tcl_GetString(objv[2]),
+ ": the container does not support the request", 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.
+ * Invoked by those wm subcommands that affect geometry. Schedules a geometry
+ * update.
*/
+
static void
-WmUpdateGeom(wmPtr, winPtr)
- WmInfo *wmPtr;
- TkWindow *winPtr;
+WmUpdateGeom(
+ WmInfo *wmPtr,
+ TkWindow *winPtr)
{
if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
@@ -5145,9 +5662,9 @@ WmUpdateGeom(wmPtr, winPtr)
/*ARGSUSED*/
static void
-WmWaitVisibilityOrMapProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to window. */
- XEvent *eventPtr; /* Information about event. */
+WmWaitVisibilityOrMapProc(
+ ClientData clientData, /* Pointer to window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkWindow *winPtr = (TkWindow *) clientData;
TkWindow *masterPtr = winPtr->wmInfoPtr->masterPtr;
@@ -5156,8 +5673,9 @@ WmWaitVisibilityOrMapProc(clientData, eventPtr)
return;
if (eventPtr->type == MapNotify) {
- if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN))
+ if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN)) {
TkpWmSetState(winPtr, NormalState);
+ }
} else if (eventPtr->type == UnmapNotify) {
TkpWmSetState(winPtr, WithdrawnState);
}
@@ -5179,34 +5697,34 @@ WmWaitVisibilityOrMapProc(clientData, eventPtr)
*
* Tk_SetGrid --
*
- * This procedure is invoked by a widget when it wishes to set a grid
- * coordinate system that controls the size of a top-level window.
- * It provides a C interface equivalent to the "wm grid" command and
- * is usually asscoiated with the -setgrid option.
+ * This function is invoked by a widget when it wishes to set a grid
+ * coordinate system that controls the size of a top-level window. It
+ * provides a C interface equivalent to the "wm grid" command and is
+ * usually asscoiated with the -setgrid option.
*
* 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 procedure call has no effect.
+ * 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(tkwin, reqWidth, reqHeight, widthInc, heightInc)
- Tk_Window tkwin; /* Token for window. New window mgr info
- * will be posted for the top-level window
+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, heightInc; /* Pixel increments corresponding to a
- * change of one grid unit. */
+ 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;
@@ -5214,6 +5732,7 @@ Tk_SetGrid(tkwin, reqWidth, reqHeight, widthInc, heightInc)
/*
* Ensure widthInc and heightInc are greater than 0
*/
+
if (widthInc <= 0) {
widthInc = 1;
}
@@ -5221,7 +5740,6 @@ Tk_SetGrid(tkwin, reqWidth, reqHeight, widthInc, heightInc)
heightInc = 1;
}
-
/*
* Find the top-level window for tkwin, plus the window manager
* information.
@@ -5249,15 +5767,15 @@ Tk_SetGrid(tkwin, reqWidth, reqHeight, widthInc, heightInc)
}
/*
- * 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 procedure was called.
+ * 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)) {
@@ -5266,8 +5784,8 @@ Tk_SetGrid(tkwin, reqWidth, reqHeight, widthInc, heightInc)
}
/*
- * Set the new gridding information, and start the process of passing
- * all of this information to the window manager.
+ * Set the new gridding information, and start the process of passing all
+ * of this information to the window manager.
*/
wmPtr->gridWin = tkwin;
@@ -5287,23 +5805,22 @@ Tk_SetGrid(tkwin, reqWidth, reqHeight, widthInc, heightInc)
*
* Tk_UnsetGrid --
*
- * This procedure cancels the effect of a previous call
- * to Tk_SetGrid.
+ * 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 procedure has no effect.
+ * gridding is cancelled for that top-level window; if some other window
+ * controls gridding then this function has no effect.
*
*----------------------------------------------------------------------
*/
void
-Tk_UnsetGrid(tkwin)
- Tk_Window tkwin; /* Token for window that is currently
+Tk_UnsetGrid(
+ Tk_Window tkwin) /* Token for window that is currently
* controlling gridding. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
@@ -5348,23 +5865,23 @@ Tk_UnsetGrid(tkwin)
*
* TopLevelEventProc --
*
- * This procedure is invoked when a top-level (or other externally-
- * managed window) is restructured in any way.
+ * 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.
+ * Tk's internal data structures for the window get modified to reflect
+ * the structural change.
*
*----------------------------------------------------------------------
*/
static void
-TopLevelEventProc(clientData, eventPtr)
- ClientData clientData; /* Window for which event occurred. */
- XEvent *eventPtr; /* Event that just happened. */
+TopLevelEventProc(
+ ClientData clientData, /* Window for which event occurred. */
+ XEvent *eventPtr) /* Event that just happened. */
{
register TkWindow *winPtr = (TkWindow *) clientData;
@@ -5374,8 +5891,8 @@ TopLevelEventProc(clientData, eventPtr)
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
+ * 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.
*/
@@ -5386,16 +5903,6 @@ TopLevelEventProc(clientData, eventPtr)
Tk_DeleteErrorHandler(handler);
}
}
- else if (eventPtr->type == ConfigureNotify) {
- WmInfo *wmPtr;
- wmPtr = winPtr->wmInfoPtr;
-
- if (winPtr->flags & TK_EMBEDDED) {
- Tk_Window tkwin = (Tk_Window)winPtr;
- SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin),
- Tk_ReqHeight(tkwin));
- }
- }
}
/*
@@ -5403,36 +5910,38 @@ TopLevelEventProc(clientData, eventPtr)
*
* TopLevelReqProc --
*
- * This procedure is invoked by the geometry manager whenever
- * the requested size for a top-level window is changed.
+ * 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).
+ * Arrange for the window to be resized to satisfy the request (this
+ * happens as a when-idle action).
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static void
-TopLevelReqProc(dummy, tkwin)
- ClientData dummy; /* Not used. */
- Tk_Window tkwin; /* Information about window. */
+TopLevelReqProc(
+ ClientData dummy, /* Not used. */
+ Tk_Window tkwin) /* Information about window. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
WmInfo *wmPtr;
wmPtr = winPtr->wmInfoPtr;
- 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, (ClientData) winPtr);
- wmPtr->flags |= WM_UPDATE_PENDING;
+ 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;
+ }
}
}
@@ -5441,26 +5950,25 @@ TopLevelReqProc(dummy, tkwin)
*
* UpdateGeometryInfo --
*
- * This procedure is invoked when a top-level window is first
- * mapped, and also as a when-idle procedure, 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 procedure doesn't return until the system has
+ * 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.
+ * The window's size and location may change, unless the WM prevents that
+ * from happening.
*
*----------------------------------------------------------------------
*/
static void
-UpdateGeometryInfo(clientData)
- ClientData clientData; /* Pointer to the window's record. */
+UpdateGeometryInfo(
+ ClientData clientData) /* Pointer to the window's record. */
{
int x, y; /* Position of border on desktop. */
int width, height; /* Size of client area. */
@@ -5472,24 +5980,23 @@ UpdateGeometryInfo(clientData)
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 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))) {
+ 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.
+ * 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;
@@ -5499,15 +6006,13 @@ UpdateGeometryInfo(clientData)
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.
+ * 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) {
@@ -5521,15 +6026,17 @@ UpdateGeometryInfo(clientData)
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;
+ + (wmPtr->maxWidth - wmPtr->reqGridWidth)*wmPtr->widthInc;
} else {
max = 0;
}
@@ -5554,15 +6061,17 @@ UpdateGeometryInfo(clientData)
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;
+ + (wmPtr->maxHeight-wmPtr->reqGridHeight)*wmPtr->heightInc;
} else {
max = 0;
}
@@ -5578,55 +6087,37 @@ UpdateGeometryInfo(clientData)
/*
* 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.
+ * 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;
+ x = wmPtr->x;
}
if (wmPtr->flags & WM_NEGATIVE_Y) {
y = DisplayHeight(winPtr->display, winPtr->screenNum) - wmPtr->y
- (height + wmPtr->borderHeight);
} else {
- y = wmPtr->y;
- }
-
- /*
- * If this window is embedded and the container is also in this
- * process, we don't need to do anything special about the
- * geometry, except to make sure that the desired size is known
- * by the container. Also, zero out any position information,
- * since embedded windows are not allowed to move.
- */
-
- if (winPtr->flags & TK_BOTH_HALVES) {
- TkWindow *childPtr = TkpGetOtherWindow(winPtr);
-
- wmPtr->x = wmPtr->y = 0;
- wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
- if (childPtr != NULL) {
- Tk_GeometryRequest((Tk_Window) childPtr, width, height);
- }
- return;
+ y = wmPtr->y;
}
/*
- * Reconfigure the window if it isn't already configured correctly. Base
+ * 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))) {
+ if (!(wmPtr->flags & WM_MOVE_PENDING)
+ && (width == wmPtr->configWidth)
+ && (height == wmPtr->configHeight)) {
return;
}
wmPtr->flags &= ~WM_MOVE_PENDING;
@@ -5635,9 +6126,8 @@ UpdateGeometryInfo(clientData)
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.
+ * 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) {
@@ -5651,12 +6141,13 @@ UpdateGeometryInfo(clientData)
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.
+ * 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;
@@ -5665,15 +6156,13 @@ UpdateGeometryInfo(clientData)
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
+ * 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.
*/
@@ -5705,11 +6194,13 @@ UpdateGeometryInfo(clientData)
/*
* 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) {
@@ -5720,11 +6211,10 @@ UpdateGeometryInfo(clientData)
}
/*
- * 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.
+ * 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;
@@ -5744,13 +6234,12 @@ UpdateGeometryInfo(clientData)
*
* ParseGeometry --
*
- * This procedure parses a geometry string and updates
- * information used to control the geometry of a top-level
- * window.
+ * 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.
+ * 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.
@@ -5759,12 +6248,12 @@ UpdateGeometryInfo(clientData)
*/
static int
-ParseGeometry(interp, string, winPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- char *string; /* String containing new geometry. Has the
+ParseGeometry(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ 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. */
+ TkWindow *winPtr) /* Pointer to top-level window whose geometry
+ * is to be changed. */
{
register WmInfo *wmPtr = winPtr->wmInfoPtr;
int x, y, width, height, flags;
@@ -5780,9 +6269,9 @@ ParseGeometry(interp, string, winPtr)
}
/*
- * 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.
+ * 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;
@@ -5836,10 +6325,10 @@ ParseGeometry(interp, string, winPtr)
}
/*
- * 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.
+ * 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)) == 0) {
@@ -5848,9 +6337,9 @@ ParseGeometry(interp, string, winPtr)
}
/*
- * 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.
+ * 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;
@@ -5866,9 +6355,8 @@ ParseGeometry(interp, string, winPtr)
}
return TCL_OK;
- error:
- Tcl_AppendResult(interp, "bad geometry specifier \"",
- string, "\"", (char *) NULL);
+ error:
+ Tcl_AppendResult(interp, "bad geometry specifier \"", string, "\"", NULL);
return TCL_ERROR;
}
@@ -5877,13 +6365,13 @@ ParseGeometry(interp, string, winPtr)
*
* Tk_GetRootCoords --
*
- * Given a token for a window, this procedure traces through the
- * window's lineage to find the (virtual) root-window coordinates
- * corresponding to point (0,0) in the window.
+ * 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.
+ * 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.
@@ -5892,10 +6380,10 @@ ParseGeometry(interp, string, winPtr)
*/
void
-Tk_GetRootCoords(tkwin, xPtr, yPtr)
- 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). */
+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;
@@ -5925,13 +6413,13 @@ Tk_GetRootCoords(tkwin, xPtr, yPtr)
*
* Tk_CoordsToWindow --
*
- * Given the (virtual) root coordinates of a point, this procedure
- * returns the token for the top-most window covering that point,
- * if there exists such a window in this application.
+ * 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
+ * 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:
@@ -5941,13 +6429,13 @@ Tk_GetRootCoords(tkwin, xPtr, yPtr)
*/
Tk_Window
-Tk_CoordsToWindow(rootX, rootY, tkwin)
- int rootX, rootY; /* Coordinates of point in root window. If
- * a virtual-root window manager is in use,
+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. */
+ Tk_Window tkwin) /* Token for any window in application; used
+ * to identify the display. */
{
POINT pos;
HWND hwnd;
@@ -5969,16 +6457,15 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
*
* Tk_GetVRootGeometry --
*
- * This procedure returns information about the virtual root
- * window corresponding to a particular Tk window.
+ * 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.
+ * 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.
@@ -5987,22 +6474,24 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
*/
void
-Tk_GetVRootGeometry(tkwin, xPtr, yPtr, widthPtr, heightPtr)
- Tk_Window tkwin; /* Window whose virtual root is to be
+Tk_GetVRootGeometry(
+ Tk_Window tkwin, /* Window whose virtual root is to be
* queried. */
- int *xPtr, *yPtr; /* Store x and y offsets of virtual root
+ int *xPtr, int *yPtr, /* Store x and y offsets of virtual root
* here. */
- int *widthPtr, *heightPtr; /* Store dimensions of virtual root here. */
+ int *widthPtr, int *heightPtr)
+ /* Store dimensions of virtual root here. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
/*
- * XXX: This is not correct for multiple monitors. There may be many
+ * XXX: This is not correct for multiple monitors. There may be many
* changes required to get this right, and it may effect existing
- * applications that don't consider possible <0 vroot. See
- * http://msdn.microsoft.com/library/en-us/gdi/monitor_3lrn.asp
- * for more info.
+ * applications that don't consider possible <0 vroot. See
+ * http://msdn.microsoft.com/library/en-us/gdi/monitor_3lrn.asp for more
+ * info.
*/
+
*xPtr = 0;
*yPtr = 0;
*widthPtr = DisplayWidth(winPtr->display, winPtr->screenNum);
@@ -6014,27 +6503,25 @@ Tk_GetVRootGeometry(tkwin, xPtr, yPtr, widthPtr, heightPtr)
*
* Tk_MoveToplevelWindow --
*
- * This procedure 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
+ * 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).
+ * (actually, the upper-left corner of the window's decorative frame, if
+ * there is one) is at (x,y).
*
*----------------------------------------------------------------------
*/
void
-Tk_MoveToplevelWindow(tkwin, x, y)
- Tk_Window tkwin; /* Window to move. */
- int x, y; /* New location for window (within
- * parent). */
+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;
@@ -6052,9 +6539,8 @@ Tk_MoveToplevelWindow(tkwin, x, y)
/*
* 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.
+ * 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)) {
@@ -6070,25 +6556,23 @@ Tk_MoveToplevelWindow(tkwin, x, y)
*
* TkWmProtocolEventProc --
*
- * This procedure is called by the Tk_HandleEvent whenever a
- * ClientMessage event arrives whose type is "WM_PROTOCOLS".
- * This procedure handles the message from the window manager
- * in an appropriate fashion.
+ * 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.
+ * Depends on what sort of handler, if any, was set up for the protocol.
*
*----------------------------------------------------------------------
*/
void
-TkWmProtocolEventProc(winPtr, eventPtr)
- TkWindow *winPtr; /* Window to which the event was sent. */
- XEvent *eventPtr; /* X event. */
+TkWmProtocolEventProc(
+ TkWindow *winPtr, /* Window to which the event was sent. */
+ XEvent *eventPtr) /* X event. */
{
WmInfo *wmPtr;
register ProtocolHandler *protPtr;
@@ -6105,14 +6589,15 @@ TkWmProtocolEventProc(winPtr, eventPtr)
protPtr = protPtr->nextPtr) {
if (protocol == protPtr->protocol) {
/*
- * Cache atom name, as we might destroy the window as a
- * result of the eval.
+ * 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((ClientData) protPtr);
- interp = protPtr->interp;
- Tcl_Preserve((ClientData) interp);
+ interp = protPtr->interp;
+ Tcl_Preserve((ClientData) interp);
result = Tcl_GlobalEval(interp, protPtr->command);
if (result != TCL_OK) {
Tcl_AddErrorInfo(interp, "\n (command for \"");
@@ -6120,15 +6605,15 @@ TkWmProtocolEventProc(winPtr, eventPtr)
Tcl_AddErrorInfo(interp, "\" window manager protocol)");
Tcl_BackgroundError(interp);
}
- Tcl_Release((ClientData) interp);
+ Tcl_Release((ClientData) interp);
Tcl_Release((ClientData) protPtr);
return;
}
}
/*
- * No handler was present for this protocol. If this is a
- * WM_DELETE_WINDOW message then just destroy the window.
+ * 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")) {
@@ -6141,9 +6626,8 @@ TkWmProtocolEventProc(winPtr, eventPtr)
*
* TkWmStackorderToplevelEnumProc --
*
- * This procedure is invoked once for each HWND Window on the
- * display as a result of calling EnumWindows from
- * TkWmStackorderToplevel.
+ * 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.
@@ -6154,30 +6638,37 @@ TkWmProtocolEventProc(winPtr, eventPtr)
*----------------------------------------------------------------------
*/
-BOOL CALLBACK TkWmStackorderToplevelEnumProc(hwnd, lParam)
- HWND hwnd; /* handle to parent window */
- LPARAM lParam; /* application-defined value */
+BOOL CALLBACK
+TkWmStackorderToplevelEnumProc(
+ HWND hwnd, /* Handle to parent window */
+ LPARAM lParam) /* Application-defined value */
{
Tcl_HashEntry *hPtr;
TkWindow *childWinPtr;
TkWmStackorderToplevelPair *pair =
- (TkWmStackorderToplevelPair *) lParam;
+ (TkWmStackorderToplevelPair *) lParam;
/*fprintf(stderr, "Looking up HWND %d\n", hwnd);*/
hPtr = Tcl_FindHashEntry(pair->table, (char *) hwnd);
if (hPtr != NULL) {
- childWinPtr = (TkWindow *) 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->window_ptr)-- = childWinPtr;
+ childWinPtr = (TkWindow *) 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->window_ptr)-- = childWinPtr;
}
return TRUE;
}
@@ -6187,8 +6678,8 @@ BOOL CALLBACK TkWmStackorderToplevelEnumProc(hwnd, lParam)
*
* TkWmStackorderToplevelWrapperMap --
*
- * This procedure will create a table that maps the wrapper
- * HWND id for a toplevel to the TkWindow structure that is wraps.
+ * This function will create a table that maps the wrapper HWND id for a
+ * toplevel to the TkWindow structure that is wraps.
*
* Results:
* None.
@@ -6200,10 +6691,10 @@ BOOL CALLBACK TkWmStackorderToplevelEnumProc(hwnd, lParam)
*/
static void
-TkWmStackorderToplevelWrapperMap(winPtr, display, table)
- TkWindow *winPtr; /* TkWindow to recurse on */
- Display *display; /* X display of parent window */
- Tcl_HashTable *table; /* Table to maps HWND to TkWindow */
+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;
@@ -6211,20 +6702,21 @@ TkWmStackorderToplevelWrapperMap(winPtr, display, table)
int newEntry;
if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) &&
- !Tk_IsEmbedded(winPtr) && (winPtr->display == display)) {
- wrapper = TkWinGetWrapperWindow((Tk_Window) 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);*/
+ /*
+ fprintf(stderr, "Mapped HWND %d to %x (%s)\n", wrapper,
+ winPtr, winPtr->pathName);
+ */
- hPtr = Tcl_CreateHashEntry(table,
- (char *) wrapper, &newEntry);
- Tcl_SetHashValue(hPtr, winPtr);
+ hPtr = Tcl_CreateHashEntry(table, (char *) wrapper, &newEntry);
+ Tcl_SetHashValue(hPtr, winPtr);
}
for (childPtr = winPtr->childList; childPtr != NULL;
- childPtr = childPtr->nextPtr) {
- TkWmStackorderToplevelWrapperMap(childPtr, display, table);
+ childPtr = childPtr->nextPtr) {
+ TkWmStackorderToplevelWrapperMap(childPtr, display, table);
}
}
/*
@@ -6232,11 +6724,11 @@ TkWmStackorderToplevelWrapperMap(winPtr, display, table)
*
* TkWmStackorderToplevel --
*
- * This procedure returns the stack order of toplevel windows.
+ * 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.
+ * An array of pointers to tk window objects in stacking order or else
+ * NULL if there was an error.
*
* Side effects:
* None.
@@ -6245,8 +6737,8 @@ TkWmStackorderToplevelWrapperMap(winPtr, display, table)
*/
TkWindow **
-TkWmStackorderToplevel(parentPtr)
- TkWindow *parentPtr; /* Parent toplevel window. */
+TkWmStackorderToplevel(
+ TkWindow *parentPtr) /* Parent toplevel window. */
{
TkWmStackorderToplevelPair pair;
TkWindow **windows;
@@ -6262,28 +6754,28 @@ TkWmStackorderToplevel(parentPtr)
TkWmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
windows = (TkWindow **) ckalloc((table.numEntries+1)
- * sizeof(TkWindow *));
+ * sizeof(TkWindow *));
/*
- * Special cases: If zero or one toplevels were mapped
- * there is no need to call EnumWindows.
+ * 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;
+ windows[0] = NULL;
+ goto done;
case 1:
- hPtr = Tcl_FirstHashEntry(&table, &search);
- windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr);
- windows[1] = NULL;
- goto done;
+ hPtr = Tcl_FirstHashEntry(&table, &search);
+ windows[0] = (TkWindow *) 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.
+ * 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;
@@ -6292,14 +6784,13 @@ TkWmStackorderToplevel(parentPtr)
if (EnumWindows((WNDENUMPROC) TkWmStackorderToplevelEnumProc,
(LPARAM) &pair) == 0) {
- ckfree((char *) windows);
- windows = NULL;
- } else {
- if (pair.window_ptr != (windows-1))
- Tcl_Panic("num matched toplevel windows does not equal num children");
+ ckfree((char *) windows);
+ windows = NULL;
+ } else if (pair.window_ptr != (windows-1)) {
+ Tcl_Panic("num matched toplevel windows does not equal num children");
}
- done:
+ done:
Tcl_DeleteHashTable(&table);
return windows;
}
@@ -6309,33 +6800,33 @@ TkWmStackorderToplevel(parentPtr)
*
* TkWmRestackToplevel --
*
- * This procedure restacks a top-level window.
+ * This function restacks a top-level window.
*
* Results:
* None.
*
* Side effects:
- * WinPtr gets restacked as specified by aboveBelow and otherPtr.
- * This procedure doesn't return until the restack has taken
- * effect and the ConfigureNotify event for it has been received.
+ * 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(winPtr, aboveBelow, otherPtr)
- TkWindow *winPtr; /* Window to restack. */
- int aboveBelow; /* Gives relative position for restacking;
+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. */
+ 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).
+ * 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) {
@@ -6355,12 +6846,17 @@ TkWmRestackToplevel(winPtr, aboveBelow, otherPtr)
TkWmMapWindow(otherPtr);
}
insertAfter = (otherPtr->wmInfoPtr->wrapper != NULL)
- ? otherPtr->wmInfoPtr->wrapper : Tk_GetHWND(otherPtr->window);
+ ? otherPtr->wmInfoPtr->wrapper : Tk_GetHWND(otherPtr->window);
} else {
insertAfter = NULL;
}
- TkWinSetWindowPos(hwnd, insertAfter, aboveBelow);
+ if (winPtr->flags & TK_EMBEDDED) {
+ SendMessage(winPtr->wmInfoPtr->wrapper, TK_RAISEWINDOW,
+ (WPARAM)insertAfter, aboveBelow);
+ } else {
+ TkWinSetWindowPos(hwnd, insertAfter, aboveBelow);
+ }
}
/*
@@ -6368,28 +6864,27 @@ TkWmRestackToplevel(winPtr, aboveBelow, otherPtr)
*
* TkWmAddToColormapWindows --
*
- * This procedure 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.
+ * 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.
+ * 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(winPtr)
- TkWindow *winPtr; /* Window with a non-default colormap.
- * Should not be a top-level window. */
+TkWmAddToColormapWindows(
+ TkWindow *winPtr) /* Window with a non-default colormap. Should
+ * not be a top-level window. */
{
TkWindow *topPtr;
TkWindow **oldPtr, **newPtr;
@@ -6402,7 +6897,7 @@ TkWmAddToColormapWindows(winPtr)
for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) {
if (topPtr == NULL) {
/*
- * Window is being deleted. Skip the whole operation.
+ * Window is being deleted. Skip the whole operation.
*/
return;
@@ -6434,8 +6929,7 @@ TkWmAddToColormapWindows(winPtr)
/*
* Make a new bigger array and use it to reset the property.
- * Automatically add the toplevel itself as the last element
- * of the list.
+ * Automatically add the toplevel itself as the last element of the list.
*/
newPtr = (TkWindow **) ckalloc((unsigned) ((count+2)*sizeof(TkWindow*)));
@@ -6470,26 +6964,26 @@ TkWmAddToColormapWindows(winPtr)
*
* TkWmRemoveFromColormapWindows --
*
- * This procedure is called to remove a given window from the
- * WM_COLORMAP_WINDOWS property for its top-level. It is invoked
- * when windows are deleted.
+ * 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.
+ * 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(winPtr)
- TkWindow *winPtr; /* Window that may be present in
+TkWmRemoveFromColormapWindows(
+ TkWindow *winPtr) /* Window that may be present in
* WM_COLORMAP_WINDOWS property for its
- * top-level. Should not be a top-level
+ * top-level. Should not be a top-level
* window. */
{
TkWindow *topPtr;
@@ -6511,8 +7005,8 @@ TkWmRemoveFromColormapWindows(winPtr)
}
if (topPtr->flags & TK_ALREADY_DEAD) {
/*
- * Top-level is being deleted, so there's no need to cleanup
- * the WM_COLORMAP_WINDOWS property.
+ * Top-level is being deleted, so there's no need to cleanup the
+ * WM_COLORMAP_WINDOWS property.
*/
return;
@@ -6523,8 +7017,7 @@ TkWmRemoveFromColormapWindows(winPtr)
}
/*
- * Find the window and slide the following ones down to cover
- * it up.
+ * Find the window and slide the following ones down to cover it up.
*/
count = topPtr->wmInfoPtr->cmapCount;
@@ -6551,36 +7044,42 @@ TkWmRemoveFromColormapWindows(winPtr)
* None.
*
* Side effects:
- * The menu will end up being drawn in the window, and the geometry
- * of the window will have to be changed.
+ * The menu will end up being drawn in the window, and the geometry of
+ * the window will have to be changed.
*
*----------------------------------------------------------------------
*/
void
-TkWinSetMenu(tkwin, hMenu)
- Tk_Window tkwin; /* the window to put the menu in */
- HMENU hMenu; /* the menu to set */
+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;
- wmPtr->hMenu = hMenu;
+ /* Could be a Frame (i.e. not a Toplevel) */
+ if (wmPtr == NULL)
+ return;
- if (!(wmPtr->flags & TK_EMBEDDED)) {
- if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
- int syncPending = wmPtr->flags & WM_SYNC_PENDING;
+ 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;
- }
+ 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, (ClientData) winPtr);
wmPtr->flags |= WM_UPDATE_PENDING|WM_MOVE_PENDING;
}
+ } else {
+ SendMessage(wmPtr->wrapper, TK_SETMENU,
+ (WPARAM)hMenu, (LPARAM)Tk_GetMenuHWND(tkwin));
}
}
@@ -6590,7 +7089,7 @@ TkWinSetMenu(tkwin, hMenu)
* ConfigureTopLevel --
*
* Generate a ConfigureNotify event based on the current position
- * information. This procedure is called by TopLevelProc.
+ * information. This function is called by TopLevelProc.
*
* Results:
* None.
@@ -6602,12 +7101,12 @@ TkWinSetMenu(tkwin, hMenu)
*/
static void
-ConfigureTopLevel(pos)
- WINDOWPOS *pos;
+ConfigureTopLevel(
+ WINDOWPOS *pos)
{
TkWindow *winPtr = GetTopLevel(pos->hwnd);
WmInfo *wmPtr;
- int state = 0; /* Current window state. */
+ int state; /* Current window state. */
RECT rect;
WINDOWPLACEMENT windowPos;
@@ -6627,15 +7126,16 @@ ConfigureTopLevel(pos)
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:
- state = NormalState;
- break;
+ case SW_SHOWMAXIMIZED:
+ state = ZoomState;
+ break;
+ case SW_SHOWMINIMIZED:
+ state = IconicState;
+ break;
+ case SW_SHOWNORMAL:
+ default:
+ state = NormalState;
+ break;
}
}
@@ -6647,27 +7147,26 @@ ConfigureTopLevel(pos)
if (wmPtr->hints.initial_state != state) {
wmPtr->hints.initial_state = state;
switch (state) {
- case WithdrawnState:
- case IconicState:
- XUnmapWindow(winPtr->display, winPtr->window);
- break;
+ 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.
- */
+ 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, (ClientData) winPtr);
- wmPtr->flags |= WM_UPDATE_PENDING;
- }
- /* fall through */
- case ZoomState:
- XMapWindow(winPtr->display, winPtr->window);
- pos->flags |= SWP_NOMOVE | SWP_NOSIZE;
- break;
+ if (!(wmPtr->flags & WM_UPDATE_PENDING)) {
+ Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
+ wmPtr->flags |= WM_UPDATE_PENDING;
+ }
+ /* fall through */
+ case ZoomState:
+ XMapWindow(winPtr->display, winPtr->window);
+ pos->flags |= SWP_NOMOVE | SWP_NOSIZE;
+ break;
}
}
@@ -6681,8 +7180,8 @@ ConfigureTopLevel(pos)
/*
- * Compute the current geometry of the client area, reshape the
- * Tk window and generate a ConfigureNotify event.
+ * Compute the current geometry of the client area, reshape the Tk window
+ * and generate a ConfigureNotify event.
*/
GetClientRect(wmPtr->wrapper, &rect);
@@ -6702,16 +7201,16 @@ ConfigureTopLevel(pos)
if (state == NormalState) {
/*
- * Update size information from the event. There are a couple of
+ * 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).
+ * 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)) {
@@ -6719,14 +7218,14 @@ ConfigureTopLevel(pos)
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.
+ * 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;
+ + (winPtr->changes.width - winPtr->reqWidth)
+ / wmPtr->widthInc;
if (wmPtr->width < 0) {
wmPtr->width = 0;
}
@@ -6743,8 +7242,8 @@ ConfigureTopLevel(pos)
} else {
if (wmPtr->gridWin != NULL) {
wmPtr->height = wmPtr->reqGridHeight
- + (winPtr->changes.height - winPtr->reqHeight)
- / wmPtr->heightInc;
+ + (winPtr->changes.height - winPtr->reqHeight)
+ / wmPtr->heightInc;
if (wmPtr->height < 0) {
wmPtr->height = 0;
}
@@ -6755,9 +7254,10 @@ ConfigureTopLevel(pos)
wmPtr->configWidth = winPtr->changes.width;
wmPtr->configHeight = winPtr->changes.height;
}
+
/*
- * If the user moved the window, we should switch back
- * to normal coordinates.
+ * If the user moved the window, we should switch back to normal
+ * coordinates.
*/
if (!(pos->flags & SWP_NOMOVE)) {
@@ -6771,15 +7271,15 @@ ConfigureTopLevel(pos)
if (wmPtr->flags & WM_NEGATIVE_X) {
wmPtr->x = DisplayWidth(winPtr->display, winPtr->screenNum)
- - winPtr->changes.x - (winPtr->changes.width
- + wmPtr->borderWidth);
+ - 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);
+ - winPtr->changes.y - (winPtr->changes.height
+ + wmPtr->borderHeight);
} else {
wmPtr->y = winPtr->changes.y;
}
@@ -6791,8 +7291,8 @@ ConfigureTopLevel(pos)
*
* GenerateConfigureNotify --
*
- * Generate a ConfigureNotify event from the current geometry
- * information for the specified toplevel window.
+ * Generate a ConfigureNotify event from the current geometry information
+ * for the specified toplevel window.
*
* Results:
* None.
@@ -6804,8 +7304,8 @@ ConfigureTopLevel(pos)
*/
static void
-GenerateConfigureNotify(winPtr)
- TkWindow *winPtr;
+GenerateConfigureNotify(
+ TkWindow *winPtr)
{
XEvent event;
@@ -6834,8 +7334,8 @@ GenerateConfigureNotify(winPtr)
*
* InstallColormaps --
*
- * Installs the colormaps associated with the toplevel which is
- * currently active.
+ * Installs the colormaps associated with the toplevel which is currently
+ * active.
*
* Results:
* None.
@@ -6847,12 +7347,12 @@ GenerateConfigureNotify(winPtr)
*/
static int
-InstallColormaps(hwnd, message, isForemost)
- HWND hwnd; /* Toplevel wrapper window whose colormaps
+InstallColormaps(
+ HWND hwnd, /* Toplevel wrapper window whose colormaps
* should be installed. */
- int message; /* Either WM_PALETTECHANGED or
+ int message, /* Either WM_PALETTECHANGED or
* WM_QUERYNEWPALETTE */
- int isForemost; /* 1 if window is foremost, else 0 */
+ int isForemost) /* 1 if window is foremost, else 0 */
{
int i;
HDC dc;
@@ -6860,7 +7360,7 @@ InstallColormaps(hwnd, message, isForemost)
TkWindow *winPtr = GetTopLevel(hwnd);
WmInfo *wmPtr;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (winPtr == NULL || (winPtr->flags & TK_ALREADY_DEAD) ) {
return 0;
@@ -6899,11 +7399,11 @@ InstallColormaps(hwnd, message, isForemost)
} 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.
+ * 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.
*/
@@ -6945,11 +7445,10 @@ InstallColormaps(hwnd, message, isForemost)
*
* 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.
+ * 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.
@@ -6961,9 +7460,9 @@ InstallColormaps(hwnd, message, isForemost)
*/
static void
-RefreshColormap(colormap, dispPtr)
- Colormap colormap;
- TkDisplay *dispPtr;
+RefreshColormap(
+ Colormap colormap,
+ TkDisplay *dispPtr)
{
WmInfo *wmPtr;
int i;
@@ -6988,9 +7487,9 @@ RefreshColormap(colormap, dispPtr)
*
* 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.
+ * 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.
@@ -7002,15 +7501,15 @@ RefreshColormap(colormap, dispPtr)
*/
static void
-InvalidateSubTree(winPtr, colormap)
- TkWindow *winPtr;
- Colormap colormap;
+InvalidateSubTree(
+ TkWindow *winPtr,
+ Colormap colormap)
{
TkWindow *childPtr;
/*
- * Generate damage for the current window if it is using the
- * specified colormap.
+ * Generate damage for the current window if it is using the specified
+ * colormap.
*/
if (winPtr->atts.colormap == colormap) {
@@ -7020,8 +7519,7 @@ InvalidateSubTree(winPtr, colormap)
for (childPtr = winPtr->childList; childPtr != NULL;
childPtr = childPtr->nextPtr) {
/*
- * We can stop the descent when we hit an unmapped or
- * toplevel window.
+ * We can stop the descent when we hit an unmapped or toplevel window.
*/
if (!Tk_TopWinHierarchy(childPtr) && Tk_IsMapped(childPtr)) {
@@ -7035,8 +7533,8 @@ InvalidateSubTree(winPtr, colormap)
*
* InvalidateSubTreeDepth --
*
- * This function recursively updates depth info for a window and
- * all of its children that belong to the same toplevel.
+ * This function recursively updates depth info for a window and all of
+ * its children that belong to the same toplevel.
*
* Results:
* None.
@@ -7048,8 +7546,8 @@ InvalidateSubTree(winPtr, colormap)
*/
static void
-InvalidateSubTreeDepth(winPtr)
- TkWindow *winPtr;
+InvalidateSubTreeDepth(
+ TkWindow *winPtr)
{
Display *display = Tk_Display(winPtr);
int screenNum = Tk_ScreenNumber(winPtr);
@@ -7059,10 +7557,10 @@ InvalidateSubTreeDepth(winPtr)
#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.
+ * 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) {
@@ -7074,13 +7572,13 @@ InvalidateSubTreeDepth(winPtr)
#endif
for (childPtr = winPtr->childList; childPtr != NULL;
- childPtr = childPtr->nextPtr) {
+ childPtr = childPtr->nextPtr) {
/*
- * We can stop the descent when we hit a toplevel window, as it
- * should get its own message.
+ * We can stop the descent when we hit a non-embedded toplevel window,
+ * as it should get its own message.
*/
- if (!Tk_TopWinHierarchy(childPtr)) {
+ if (childPtr->flags & TK_EMBEDDED || !Tk_TopWinHierarchy(childPtr)) {
InvalidateSubTreeDepth(childPtr);
}
}
@@ -7094,8 +7592,8 @@ InvalidateSubTreeDepth(winPtr)
* Retrieves the currently installed foreground palette.
*
* Results:
- * Returns the global foreground palette, if there is one.
- * Otherwise, returns NULL.
+ * Returns the global foreground palette, if there is one. Otherwise,
+ * returns NULL.
*
* Side effects:
* None.
@@ -7104,10 +7602,10 @@ InvalidateSubTreeDepth(winPtr)
*/
HPALETTE
-TkWinGetSystemPalette()
+TkWinGetSystemPalette(void)
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
return tsdPtr->systemPalette;
}
@@ -7117,17 +7615,16 @@ TkWinGetSystemPalette()
*
* GetMinSize --
*
- * This procedure computes the current minWidth and minHeight
- * values for a window, taking into account the possibility
- * that they may be defaulted.
+ * 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 procedure computes the
- * smallest size that will satisfy both the system and the
- * grid constraints.
+ * 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.
@@ -7136,21 +7633,21 @@ TkWinGetSystemPalette()
*/
static void
-GetMinSize(wmPtr, minWidthPtr, minHeightPtr)
- WmInfo *wmPtr; /* Window manager information for the
+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 *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.
+ * 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;
@@ -7195,16 +7692,15 @@ GetMinSize(wmPtr, minWidthPtr, minHeightPtr)
*
* GetMaxSize --
*
- * This procedure computes the current maxWidth and maxHeight
- * values for a window, taking into account the possibility
- * that they may be defaulted.
+ * 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 procedure computes the largest sizes that
- * will fit on the screen.
+ * 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.
@@ -7213,13 +7709,13 @@ GetMinSize(wmPtr, minWidthPtr, minHeightPtr)
*/
static void
-GetMaxSize(wmPtr, maxWidthPtr, maxHeightPtr)
- WmInfo *wmPtr; /* Window manager information for the
+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 *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;
@@ -7227,14 +7723,14 @@ GetMaxSize(wmPtr, maxWidthPtr, maxHeightPtr)
*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.
+ * 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.
+ * Gridding is turned on; convert from pixels to grid units.
*/
tmp = wmPtr->reqGridWidth
@@ -7259,8 +7755,7 @@ GetMaxSize(wmPtr, maxWidthPtr, maxHeightPtr)
*
* TopLevelProc --
*
- * Callback from Windows whenever an event occurs on a top level
- * window.
+ * Callback from Windows whenever an event occurs on a top level window.
*
* Results:
* Standard Windows return value.
@@ -7272,13 +7767,13 @@ GetMaxSize(wmPtr, maxWidthPtr, maxHeightPtr)
*/
static LRESULT CALLBACK
-TopLevelProc(hwnd, message, wParam, lParam)
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
+TopLevelProc(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
- if (message == WM_WINDOWPOSCHANGED) {
+ if (message == WM_WINDOWPOSCHANGED || message == WM_WINDOWPOSCHANGING) {
WINDOWPOS *pos = (WINDOWPOS *) lParam;
TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(pos->hwnd);
@@ -7295,8 +7790,10 @@ TopLevelProc(hwnd, message, wParam, lParam)
winPtr->changes.height = pos->cy;
}
if (!(pos->flags & SWP_NOMOVE)) {
- winPtr->changes.x = pos->x;
- winPtr->changes.y = pos->y;
+ 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);
@@ -7325,180 +7822,257 @@ TopLevelProc(hwnd, message, wParam, lParam)
*/
static LRESULT CALLBACK
-WmProc(hwnd, message, wParam, lParam)
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
+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;
+ 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;
- if (TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &result)) {
+ switch (message) {
+ case WM_KILLFOCUS:
+ case WM_ERASEBKGND:
+ result = 0;
goto done;
- }
- switch (message) {
- case WM_KILLFOCUS:
- case WM_ERASEBKGND:
- result = 0;
- goto done;
+ case WM_ENTERSIZEMOVE:
+ inMoveSize = 1;
- 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.
+ */
- /*
- * 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();
- TkWinCancelMouseTimer();
+ oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
+ break;
- 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
+ */
- case WM_ACTIVATE:
- case WM_EXITSIZEMOVE:
- if (inMoveSize) {
- inMoveSize = 0;
- Tcl_SetServiceMode(oldMode);
+ GenerateActivateEvent(winPtr, &inMoveSize);
+ result = 0;
+ goto done;
}
- break;
+ }
+ /* 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_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);
- }
+ 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);
}
- result = 0;
- goto done;
+ if (Tk_Depth(winPtr) != (int) wParam) {
+ /*
+ * Defer the window depth check to here so that each toplevel
+ * will properly update depth info.
+ */
- case WM_SYSCOLORCHANGE:
- /*
- * XXX: Called when system color changes. We need to
- * update any widgets that use a system color.
- */
- break;
+ InvalidateSubTreeDepth(winPtr);
+ }
+ }
+ result = 0;
+ goto done;
- case WM_PALETTECHANGED:
- result = InstallColormaps(hwnd, WM_PALETTECHANGED,
- hwnd == (HWND)wParam);
- goto done;
+ case WM_SYSCOLORCHANGE:
+ /*
+ * XXX: Called when system color changes. We need to update any
+ * widgets that use a system color.
+ */
- case WM_QUERYNEWPALETTE:
- result = InstallColormaps(hwnd, WM_QUERYNEWPALETTE, TRUE);
- goto done;
+ break;
- case WM_WINDOWPOSCHANGED:
- ConfigureTopLevel((WINDOWPOS *) lParam);
- result = 0;
- goto done;
+ case WM_PALETTECHANGED:
+ result = InstallColormaps(hwnd, WM_PALETTECHANGED,
+ hwnd == (HWND)wParam);
+ 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.
- */
+ case WM_QUERYNEWPALETTE:
+ result = InstallColormaps(hwnd, WM_QUERYNEWPALETTE, TRUE);
+ goto done;
- result = HTCLIENT;
- goto done;
- }
- break;
+ case WM_SETTINGCHANGE:
+ if (wParam == SPI_SETNONCLIENTMETRICS) {
+ winPtr = GetTopLevel(hwnd);
+ TkWinSetupSystemFonts(winPtr->mainPtr);
+ result = 0;
+ goto done;
}
+ break;
- case WM_MOUSEACTIVATE: {
- ActivateEvent *eventPtr;
- winPtr = GetTopLevel((HWND) wParam);
+ case WM_WINDOWPOSCHANGED:
+ ConfigureTopLevel((WINDOWPOS *) lParam);
+ result = 0;
+ goto done;
- if (winPtr && (TkGrabState(winPtr) != TK_GRAB_EXCLUDED)) {
- /*
- * This allows us to pass the message onto the
- * native menus [Bug: 2272]
- */
- result = (*tkWinProcs->defWindowProc)(hwnd, message,
- wParam, lParam);
- 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)) {
/*
- * 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.
+ * This allows us to pass the message onto the native menus [Bug:
+ * 2272]
*/
- if (winPtr) {
- eventPtr = (ActivateEvent *)ckalloc(sizeof(ActivateEvent));
- eventPtr->ev.proc = ActivateWindow;
- eventPtr->winPtr = winPtr;
- Tcl_QueueEvent((Tcl_Event*)eventPtr, TCL_QUEUE_TAIL);
- }
- result = MA_NOACTIVATE;
+ result = (*tkWinProcs->defWindowProc)(hwnd, message,
+ wParam, lParam);
goto done;
}
- case WM_QUERYENDSESSION: {
- XEvent event;
+ /*
+ * 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.
+ */
- 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;
+ if (winPtr) {
+ GenerateActivateEvent(winPtr, &inMoveSize);
}
+ result = MA_NOACTIVATE;
+ goto done;
+ }
- default:
- break;
+ 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;
@@ -7511,7 +8085,7 @@ WmProc(hwnd, message, wParam, lParam)
result = (*tkWinProcs->defWindowProc)(hwnd, message, wParam, lParam);
}
- done:
+ done:
Tcl_ServiceAll();
return result;
}
@@ -7521,8 +8095,8 @@ WmProc(hwnd, message, wParam, lParam)
*
* TkpMakeMenuWindow --
*
- * Configure the window to be either a pull-down (or pop-up)
- * menu, or as a toplevel (torn-off) menu or palette.
+ * Configure the window to be either a pull-down (or pop-up) menu, or as
+ * a toplevel (torn-off) menu or palette.
*
* Results:
* None.
@@ -7534,12 +8108,12 @@ WmProc(hwnd, message, wParam, lParam)
*/
void
-TkpMakeMenuWindow(tkwin, transient)
- 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
+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;
@@ -7583,23 +8157,21 @@ TkWinGetWrapperWindow(
TkWindow *winPtr = (TkWindow *)tkwin;
return (winPtr->wmInfoPtr->wrapper);
}
-
/*
*----------------------------------------------------------------------
*
* TkWmFocusToplevel --
*
- * This is a utility procedure 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 procedure just
- * determines whether a window is a toplevel or not.
+ * 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.
+ * If winPtr is a toplevel window, returns the pointer to the window;
+ * otherwise returns NULL.
*
* Side effects:
* None.
@@ -7608,8 +8180,8 @@ TkWinGetWrapperWindow(
*/
TkWindow *
-TkWmFocusToplevel(winPtr)
- TkWindow *winPtr; /* Window that received a focus-related
+TkWmFocusToplevel(
+ TkWindow *winPtr) /* Window that received a focus-related
* event. */
{
if (!(winPtr->flags & TK_TOP_HIERARCHY)) {
@@ -7617,19 +8189,19 @@ TkWmFocusToplevel(winPtr)
}
return winPtr;
}
-
+
/*
*----------------------------------------------------------------------
*
* TkpGetWrapperWindow --
*
- * This is a utility procedure 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.
+ * 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.
+ * If winPtr is a toplevel window, returns the pointer to the window;
+ * otherwise returns NULL.
*
* Side effects:
* None.
@@ -7651,6 +8223,26 @@ TkpGetWrapperWindow(
/*
*----------------------------------------------------------------------
*
+ * GenerateActivateEvent --
+ *
+ * This function is called to activate a Tk window.
+ */
+
+static void
+GenerateActivateEvent(TkWindow * winPtr, const int *flagPtr)
+{
+ ActivateEvent *eventPtr;
+ eventPtr = (ActivateEvent *)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.
@@ -7669,39 +8261,65 @@ ActivateWindow(
Tcl_Event *evPtr, /* Pointer to ActivateEvent. */
int flags) /* Notifier event mask. */
{
- TkWindow *winPtr;
+ ActivateEvent *eventPtr = (ActivateEvent *)evPtr;
+ TkWindow *winPtr = eventPtr->winPtr;
if (! (flags & TCL_WINDOW_EVENTS)) {
return 0;
}
- winPtr = ((ActivateEvent *) evPtr)->winPtr;
+ /*
+ * 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 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) {
- SetFocus(Tk_GetHWND(winPtr->window));
+ window = winPtr->window;
} else {
- SetFocus(Tk_GetHWND(winPtr->dispPtr->grabWinPtr->window));
+ 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.
+ * This function is a wrapper for SetForegroundWindow, calling it on the
+ * wrapper window because it has no affect on child windows.
*
* Results:
* none
@@ -7713,8 +8331,8 @@ ActivateWindow(
*/
void
-TkWinSetForegroundWindow(winPtr)
- TkWindow *winPtr;
+TkWinSetForegroundWindow(
+ TkWindow *winPtr)
{
register WmInfo *wmPtr = winPtr->wmInfoPtr;
@@ -7724,3 +8342,318 @@ TkWinSetForegroundWindow(winPtr)
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, (ClientData) winPtr);
+ UpdateGeometryInfo((ClientData) 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 ((wmPtr->width != -1) && (wmPtr->height != -1))? 1:0;
+ } else {
+ return 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(winPtr, parentHWND)
+ 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/win/tkWinX.c b/win/tkWinX.c
index cdbdc84..288da26 100644
--- a/win/tkWinX.c
+++ b/win/tkWinX.c
@@ -1,22 +1,30 @@
-/*
+/*
* tkWinX.c --
*
- * This file contains Windows emulation procedures for X routines.
+ * 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+/*
+ * Make sure the SendInput API is available (NT SP 3):
+ */
+#if (_WIN32_WINNT <= 0x0400)
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0403
+#endif
+
#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.
+ * 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
@@ -24,6 +32,10 @@
#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.
@@ -36,6 +48,9 @@
*/
#include <imm.h>
+#ifdef _MSC_VER
+# pragma comment (lib, "imm32.lib")
+#endif
/*
* WM_UNICHAR is a message for Unicode input on all windows systems.
@@ -61,6 +76,7 @@ static TkWinProcs asciiProcs = {
HINSTANCE hInstance, LPVOID lpParam)) CreateWindowExA,
(BOOL (WINAPI *)(HMENU hMenu, UINT uPosition, UINT uFlags,
UINT uIDNewItem, LPCTSTR lpNewItem)) InsertMenuA,
+ (int (WINAPI *)(HWND hWnd, LPCTSTR lpString, int nMaxCount)) GetWindowTextA,
};
static TkWinProcs unicodeProcs = {
@@ -78,6 +94,7 @@ static TkWinProcs unicodeProcs = {
HINSTANCE hInstance, LPVOID lpParam)) CreateWindowExW,
(BOOL (WINAPI *)(HMENU hMenu, UINT uPosition, UINT uFlags,
UINT uIDNewItem, LPCTSTR lpNewItem)) InsertMenuW,
+ (int (WINAPI *)(HWND hWnd, LPCTSTR lpString, int nMaxCount)) GetWindowTextW,
};
TkWinProcs *tkWinProcs;
@@ -86,51 +103,52 @@ TkWinProcs *tkWinProcs;
* Declarations of static variables used in this file.
*/
-static 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; /* unicode encoding */
+static 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.
+ * 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 */
+ TkDisplay *winDisplay; /* TkDisplay structure that represents Windows
+ * screen. */
+ int updatingClipboard; /* If 1, we are updating the clipboard. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * Forward declarations of procedures used in this file.
+ * Forward declarations of functions used in this file.
*/
-static void GenerateXEvent _ANSI_ARGS_((HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam));
-static unsigned int GetState _ANSI_ARGS_((UINT message, WPARAM wParam,
- LPARAM lParam));
-static void GetTranslatedKey _ANSI_ARGS_((XKeyEvent *xkey));
-static void UpdateInputLanguage _ANSI_ARGS_((int charset));
-static int HandleIMEComposition _ANSI_ARGS_((HWND hwnd,
- LPARAM lParam));
+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);
+static void UpdateInputLanguage(int charset);
+static int HandleIMEComposition(HWND hwnd, LPARAM lParam);
/*
*----------------------------------------------------------------------
*
* TkGetServerInfo --
*
- * Given a window, this procedure returns information about
- * the window server for that window. This procedure provides
- * the guts of the "winfo server" command.
+ * 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.
@@ -142,11 +160,11 @@ static int HandleIMEComposition _ANSI_ARGS_((HWND hwnd,
*/
void
-TkGetServerInfo(interp, tkwin)
- 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. */
+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. */
{
char buffer[60];
OSVERSIONINFO os;
@@ -160,7 +178,7 @@ TkGetServerInfo(interp, tkwin)
#else
"Win32"
#endif
- );
+ );
Tcl_SetResult(interp, buffer, TCL_VOLATILE);
}
@@ -181,7 +199,7 @@ TkGetServerInfo(interp, tkwin)
*/
HINSTANCE
-Tk_GetHINSTANCE()
+Tk_GetHINSTANCE(void)
{
if (tkInstance == NULL) {
tkInstance = GetModuleHandle(NULL);
@@ -194,8 +212,8 @@ Tk_GetHINSTANCE()
*
* TkWinSetHINSTANCE --
*
- * Sets the global instance handle used by the Tk library.
- * This should be called by DllMain.
+ * Sets the global instance handle used by the Tk library. This should be
+ * called by DllMain.
*
* Results:
* None.
@@ -207,8 +225,8 @@ Tk_GetHINSTANCE()
*/
void
-TkWinSetHINSTANCE(hInstance)
- HINSTANCE hInstance;
+TkWinSetHINSTANCE(
+ HINSTANCE hInstance)
{
tkInstance = hInstance;
}
@@ -230,9 +248,10 @@ TkWinSetHINSTANCE(hInstance)
*/
void
-TkWinXInit(hInstance)
- HINSTANCE hInstance;
+TkWinXInit(
+ HINSTANCE hInstance)
{
+ INITCOMMONCONTROLSEX comctl;
CHARSETINFO lpCs;
DWORD lpCP;
@@ -241,16 +260,13 @@ TkWinXInit(hInstance)
}
childClassInitialized = 1;
- if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
- /*
- * This is necessary to enable the use of themeable elements on XP,
- * so we don't even try and call it for Win9*.
- */
-
- INITCOMMONCONTROLSEX comctl;
- ZeroMemory(&comctl, sizeof(comctl));
- (void) InitCommonControlsEx(&comctl);
+ comctl.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ comctl.dwICC = ICC_WIN95_CLASSES;
+ if (!InitCommonControlsEx(&comctl)) {
+ Tcl_Panic("Unable to load common controls?!");
+ }
+ if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
tkWinProcs = &unicodeProcs;
} else {
tkWinProcs = &asciiProcs;
@@ -273,23 +289,24 @@ TkWinXInit(hInstance)
childClass.hCursor = NULL;
if (!RegisterClass(&childClass)) {
- panic("Unable to register TkChild class");
+ Tcl_Panic("Unable to register TkChild class");
}
/*
* Initialize input language info
*/
- if (GetLocaleInfo(LANGIDFROMLCID(GetKeyboardLayout(0)),
+ if (GetLocaleInfo(LANGIDFROMLCID((DWORD)GetKeyboardLayout(0)),
LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
(LPTSTR) &lpCP, sizeof(lpCP)/sizeof(TCHAR))
&& TranslateCharsetInfo((DWORD *)lpCP, &lpCs, TCI_SRCCODEPAGE)) {
- UpdateInputLanguage(lpCs.ciCharset);
+ UpdateInputLanguage((int) lpCs.ciCharset);
}
/*
* Make sure we cleanup on finalize.
*/
+
TkCreateExitHandler(TkWinXCleanup, (ClientData) hInstance);
}
@@ -310,17 +327,18 @@ TkWinXInit(hInstance)
*/
void
-TkWinXCleanup(clientData)
- ClientData clientData;
+TkWinXCleanup(
+ ClientData clientData)
{
HINSTANCE hInstance = (HINSTANCE) clientData;
+
/*
* Clean up our own class.
*/
-
+
if (childClassInitialized) {
- childClassInitialized = 0;
- UnregisterClass(TK_WIN_CHILD_CLASS_NAME, hInstance);
+ childClassInitialized = 0;
+ UnregisterClass(TK_WIN_CHILD_CLASS_NAME, hInstance);
}
if (unicodeEncoding != NULL) {
@@ -331,8 +349,9 @@ TkWinXCleanup(clientData)
/*
* And let the window manager clean up its own class(es).
*/
-
+
TkWinWmCleanup(hInstance);
+ TkWinCleanupContainerList();
}
/*
@@ -340,12 +359,12 @@ TkWinXCleanup(clientData)
*
* TkWinGetPlatformId --
*
- * Determines whether running under NT, 95, or Win32s, to allow
- * runtime conditional code. Win32s is no longer supported.
+ * 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.
+ * VER_PLATFORM_WIN32s Win32s on Windows 3.1.
* VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95.
* VER_PLATFORM_WIN32_NT Win32 on Windows NT
*
@@ -356,7 +375,7 @@ TkWinXCleanup(clientData)
*/
int
-TkWinGetPlatformId()
+TkWinGetPlatformId(void)
{
if (tkPlatformId == 0) {
OSVERSIONINFO os;
@@ -364,29 +383,33 @@ TkWinGetPlatformId()
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&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. */
+
+ /*
+ * 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;
- LPCSTR szSubKey = TEXT("Control Panel\\Appearance");
+ (os.dwMajorVersion == 5 && os.dwMinorVersion == 1)) {
+ HKEY hKey;
+ LPCSTR szSubKey = TEXT("Control Panel\\Appearance");
LPCSTR szCurrent = TEXT("Current");
- DWORD dwSize = 200;
+ 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;
+ KEY_READ, &hKey) != ERROR_SUCCESS) {
+ tkWinTheme = TK_THEME_WIN_XP;
} else {
- RegQueryValueEx(hKey, szCurrent, NULL, NULL, (BYTE *) pBuffer, &dwSize);
- RegCloseKey(hKey);
- if (strcmp(pBuffer, "Windows Standard") == 0) {
- tkWinTheme = TK_THEME_WIN_CLASSIC;
- } else {
- tkWinTheme = TK_THEME_WIN_XP;
- }
+ 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;
@@ -404,8 +427,8 @@ TkWinGetPlatformId()
*
* 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
+ * 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.
@@ -414,10 +437,10 @@ TkWinGetPlatformId()
*/
int
-TkWinGetPlatformTheme()
+TkWinGetPlatformTheme(void)
{
if (tkPlatformId == 0) {
- TkWinGetPlatformId();
+ TkWinGetPlatformId();
}
return tkWinTheme;
}
@@ -440,9 +463,9 @@ TkWinGetPlatformTheme()
*/
CONST char *
-TkGetDefaultScreenName(interp, screenName)
- Tcl_Interp *interp; /* Not used. */
- CONST char *screenName; /* If NULL, use default string. */
+TkGetDefaultScreenName(
+ Tcl_Interp *interp, /* Not used. */
+ CONST char *screenName) /* If NULL, use default string. */
{
if ((screenName == NULL) || (screenName[0] == '\0')) {
screenName = winScreenName;
@@ -468,7 +491,8 @@ TkGetDefaultScreenName(interp, screenName)
*/
void
-TkWinDisplayChanged(Display *display)
+TkWinDisplayChanged(
+ Display *display)
{
HDC dc;
Screen *screen;
@@ -489,9 +513,9 @@ TkWinDisplayChanged(Display *display)
/*
* 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
+ * 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 number of planes. Otherwise the HBITMAP won't be compatible with
* the HWND and we'll just get blank spots copied onto the screen.
*/
@@ -549,8 +573,8 @@ TkWinDisplayChanged(Display *display)
*
* TkpOpenDisplay --
*
- * Create the Display structure and fill it with device
- * specific information.
+ * Create the Display structure and fill it with device specific
+ * information.
*
* Results:
* Returns a TkDisplay structure on success or NULL on failure.
@@ -562,18 +586,17 @@ TkWinDisplayChanged(Display *display)
*/
TkDisplay *
-TkpOpenDisplay(display_name)
- CONST char *display_name;
+TkpOpenDisplay(
+ CONST char *display_name)
{
Screen *screen;
TkWinDrawable *twdPtr;
Display *display;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (tsdPtr->winDisplay != NULL) {
- if (strcmp(tsdPtr->winDisplay->display->display_name, display_name)
- == 0) {
+ if (!strcmp(tsdPtr->winDisplay->display->display_name, display_name)) {
return tsdPtr->winDisplay;
} else {
return NULL;
@@ -587,9 +610,9 @@ TkpOpenDisplay(display_name)
strcpy(display->display_name, display_name);
display->cursor_font = 1;
- display->nscreens = 1;
- display->request = 1;
- display->qlen = 0;
+ display->nscreens = 1;
+ display->request = 1;
+ display->qlen = 0;
screen = (Screen *) ckalloc(sizeof(Screen));
ZeroMemory(screen, sizeof(Screen));
@@ -614,7 +637,7 @@ TkpOpenDisplay(display_name)
screen->white_pixel = RGB(255, 255, 255);
screen->black_pixel = RGB(0, 0, 0);
- screen->cmap = None;
+ screen->cmap = None;
display->screens = screen;
display->nscreens = 1;
@@ -648,49 +671,34 @@ TkpOpenDisplay(display_name)
*/
void
-TkpCloseDisplay(dispPtr)
- TkDisplay *dispPtr;
+TkpCloseDisplay(
+ TkDisplay *dispPtr)
{
Display *display = dispPtr->display;
- HWND hwnd;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (dispPtr != tsdPtr->winDisplay) {
- panic("TkpCloseDisplay: tried to call TkpCloseDisplay on another display");
- return;
- }
-
- /*
- * Force the clipboard to be rendered if we are the clipboard owner.
- */
-
- if (dispPtr->clipWindow) {
- hwnd = Tk_GetHWND(Tk_WindowId(dispPtr->clipWindow));
- if (GetClipboardOwner() == hwnd) {
- OpenClipboard(hwnd);
- EmptyClipboard();
- TkWinClipboardRender(dispPtr, CF_TEXT);
- CloseClipboard();
- }
+ Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on another display");
+ return; /* not reached */
}
tsdPtr->winDisplay = NULL;
- if (display->display_name != (char *) NULL) {
- ckfree(display->display_name);
+ if (display->display_name != NULL) {
+ ckfree(display->display_name);
}
- if (display->screens != (Screen *) NULL) {
- if (display->screens->root_visual != NULL) {
- ckfree((char *) display->screens->root_visual);
- }
- if (display->screens->root != None) {
- ckfree((char *) display->screens->root);
- }
- if (display->screens->cmap != None) {
- XFreeColormap(display, display->screens->cmap);
- }
- ckfree((char *) display->screens);
+ if (display->screens != NULL) {
+ if (display->screens->root_visual != NULL) {
+ ckfree((char *) display->screens->root_visual);
+ }
+ if (display->screens->root != None) {
+ ckfree((char *) display->screens->root);
+ }
+ if (display->screens->cmap != None) {
+ XFreeColormap(display, display->screens->cmap);
+ }
+ ckfree((char *) display->screens);
}
ckfree((char *) display);
}
@@ -700,11 +708,10 @@ TkpCloseDisplay(dispPtr)
*
* TkClipCleanup --
*
- * This procedure 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.
+ * 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.
@@ -716,8 +723,8 @@ TkpCloseDisplay(dispPtr)
*/
void
-TkClipCleanup(dispPtr)
- TkDisplay *dispPtr; /* display associated with clipboard */
+TkClipCleanup(
+ TkDisplay *dispPtr) /* Display associated with clipboard. */
{
if (dispPtr->clipWindow != NULL) {
/*
@@ -725,6 +732,7 @@ TkClipCleanup(dispPtr)
*/
HWND hwnd = Tk_GetHWND(Tk_WindowId(dispPtr->clipWindow));
+
if (GetClipboardOwner() == hwnd) {
OpenClipboard(hwnd);
EmptyClipboard();
@@ -760,9 +768,9 @@ TkClipCleanup(dispPtr)
*/
void
-XBell(display, percent)
- Display* display;
- int percent;
+XBell(
+ Display *display,
+ int percent)
{
MessageBeep(MB_OK);
}
@@ -772,8 +780,7 @@ XBell(display, percent)
*
* TkWinChildProc --
*
- * Callback from Windows whenever an event occurs on a child
- * window.
+ * Callback from Windows whenever an event occurs on a child window.
*
* Results:
* Standard Windows return value.
@@ -785,75 +792,83 @@ XBell(display, percent)
*/
LRESULT CALLBACK
-TkWinChildProc(hwnd, message, wParam, lParam)
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
+TkWinChildProc(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
LRESULT result;
switch (message) {
- case WM_INPUTLANGCHANGE:
- UpdateInputLanguage(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);
+ 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;
+ }
+ break;
- case TK_CLAIMFOCUS:
- case TK_GEOMETRYREQ:
- case TK_ATTACHWINDOW:
- case TK_DETACHWINDOW:
- result = TkWinEmbeddedEventProc(hwnd, message, wParam, lParam);
- break;
+ case WM_SETCURSOR:
+ /*
+ * Short circuit the WM_SETCURSOR message since we set the cursor
+ * elsewhere.
+ */
- case WM_UNICHAR:
- if (wParam == UNICODE_NOCHAR) {
- /* If wParam is UNICODE_NOCHAR and the application processes
- * this message, then return TRUE. */
- result = 1;
+ 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 {
- /* If the event was translated, we must return 0 */
- if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam,
- &result)) {
- result = 0;
- } else {
- result = 1;
- }
+ result = 1;
}
- break;
+ }
+ break;
- default:
- if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam,
- &result)) {
- result = DefWindowProc(hwnd, message, wParam, lParam);
- }
- break;
+ default:
+ if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
+ result = DefWindowProc(hwnd, message, wParam, lParam);
+ }
+ break;
}
/*
@@ -869,8 +884,8 @@ TkWinChildProc(hwnd, message, wParam, lParam)
*
* Tk_TranslateWinEvent --
*
- * This function is called by widget window procedures to handle
- * the translation from Win32 events to Tk events.
+ * 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.
@@ -882,75 +897,80 @@ TkWinChildProc(hwnd, message, wParam, lParam)
*/
int
-Tk_TranslateWinEvent(hwnd, message, wParam, lParam, resultPtr)
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
- LRESULT *resultPtr;
+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_RENDERFORMAT: {
+ TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);
+
+ if (winPtr) {
+ TkWinClipboardRender(winPtr->dispPtr, wParam);
}
+ 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.
- */
+ 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)
+ 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));
+ if (target && target != hwnd) {
+ *resultPtr = SendMessage(target, message, wParam, lParam);
return 1;
+ }
+ break;
+ }
- case WM_CLOSE:
- case WM_SETFOCUS:
- case WM_KILLFOCUS:
- case WM_DESTROYCLIPBOARD:
- case WM_UNICHAR:
- case WM_CHAR:
- case WM_SYSKEYDOWN:
- case WM_SYSKEYUP:
- case WM_KEYDOWN:
- 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;
+ 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_CLOSE:
+ case WM_SETFOCUS:
+ case WM_KILLFOCUS:
+ case WM_DESTROYCLIPBOARD:
+ case WM_UNICHAR:
+ case WM_CHAR:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_KEYDOWN:
+ 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;
}
@@ -960,8 +980,8 @@ Tk_TranslateWinEvent(hwnd, message, wParam, lParam, resultPtr)
*
* GenerateXEvent --
*
- * This routine generates an X event from the corresponding
- * Windows event.
+ * This routine generates an X event from the corresponding Windows
+ * event.
*
* Results:
* None.
@@ -973,281 +993,286 @@ Tk_TranslateWinEvent(hwnd, message, wParam, lParam, resultPtr)
*/
static void
-GenerateXEvent(hwnd, message, wParam, lParam)
- HWND hwnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
+GenerateXEvent(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
XEvent event;
- TkWindow *winPtr = (TkWindow *)Tk_HWNDToWindow(hwnd);
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ TkWindow *winPtr;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ 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_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 =
+ 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] =
+ event.xclient.format = 32;
+ event.xclient.data.l[0] =
Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW");
- break;
+ break;
- case WM_SETFOCUS:
- case WM_KILLFOCUS: {
- TkWindow *otherWinPtr = (TkWindow *)Tk_HWNDToWindow((HWND) wParam);
+ 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.
- */
+ /*
+ * 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;
+ 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);
- }
+ /*
+ * Do a catch-all Tk_SetCaretPos here to make sure that the window
+ * receiving focus sets the caret at least once.
+ */
- if (otherWinPtr == winPtr) {
- return;
- }
+ if (message == WM_SETFOCUS) {
+ Tk_SetCaretPos((Tk_Window) winPtr, 0, 0, 0);
+ }
- event.xany.window = winPtr->window;
- event.type = (message == WM_SETFOCUS) ? FocusIn : FocusOut;
- event.xfocus.mode = NotifyNormal;
- event.xfocus.detail = NotifyNonlinear;
+ 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) {
/*
- * Destroy the caret if we own it. If we are moving to another Tk
- * window, it will reclaim and reposition it with Tk_SetCaretPos.
+ * We want to avoid this event if we are the ones that caused this
+ * event.
*/
- 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 =
+ return;
+ }
+ event.type = SelectionClear;
+ event.xselectionclear.selection =
Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD");
- event.xselectionclear.time = TkpGetMS();
- break;
+ event.xselectionclear.time = TkpGetMS();
+ break;
+ case WM_MOUSEWHEEL:
+ /*
+ * The mouse wheel event is closer to a key event than a mouse event
+ * in that the message is sent to the window that has focus.
+ */
+
+ 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:
/*
- * The mouse wheel event is closer to a key event than a
- * mouse event in that the message is sent to the window
- * that has focus.
+ * 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].
*/
- case WM_CHAR:
- case WM_UNICHAR:
+ event.type = MouseWheelEvent;
+ event.xany.send_event = -1;
+ event.xkey.nbytes = 0;
+ event.xkey.keycode = (short) HIWORD(wParam);
+ break;
case WM_SYSKEYDOWN:
- case WM_SYSKEYUP:
case WM_KEYDOWN:
- case WM_KEYUP: {
- unsigned int state = GetState(message, wParam, lParam);
- Time time = TkpGetMS();
- POINT clientPoint;
- POINTS rootPoint; /* Note: POINT and POINTS are different */
- DWORD msgPos;
-
/*
- * Compute the screen and window coordinates of the event.
+ * 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.
*/
- msgPos = GetMessagePos();
- rootPoint = MAKEPOINTS(msgPos);
- clientPoint.x = rootPoint.x;
- clientPoint.y = rootPoint.y;
- ScreenToClient(hwnd, &clientPoint);
+ event.type = KeyPress;
+ event.xany.send_event = -1;
+ event.xkey.keycode = wParam;
+ GetTranslatedKey(&event.xkey);
+ break;
+ case WM_SYSKEYUP:
+ case WM_KEYUP:
/*
- * Set up the common event fields.
+ * 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.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 = rootPoint.x;
- event.xbutton.y_root = rootPoint.y;
- event.xbutton.state = state;
- event.xbutton.time = time;
- event.xbutton.same_screen = True;
+ event.type = KeyRelease;
+ event.xkey.keycode = wParam;
+ event.xkey.nbytes = 0;
+ break;
+ case WM_CHAR:
/*
- * Now set up event specific fields.
+ * 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.
*/
- 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);
- 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;
- event.xkey.nbytes = 1;
- event.xkey.trans_chars[0] = (char) wParam;
-
- if (IsDBCSLeadByte((BYTE) wParam)) {
- MSG msg;
-
- if ((PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0)
- && (msg.message == WM_CHAR)) {
- GetMessage(&msg, NULL, 0, 0);
- 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: {
- char buffer[TCL_UTF_MAX+1];
- int i;
- event.type = KeyPress;
- event.xany.send_event = -3;
- event.xkey.keycode = wParam;
- event.xkey.nbytes = Tcl_UniCharToUtf(wParam, buffer);
- for (i=0; i<event.xkey.nbytes && i<TCL_UTF_MAX; ++i) {
- event.xkey.trans_chars[i] = buffer[i];
- }
- Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
- event.type = KeyRelease;
- break;
+ event.type = KeyPress;
+ event.xany.send_event = -1;
+ event.xkey.keycode = 0;
+ event.xkey.nbytes = 1;
+ event.xkey.trans_chars[0] = (char) wParam;
+
+ if (IsDBCSLeadByte((BYTE) wParam)) {
+ MSG msg;
+
+ if ((PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0)
+ && (msg.message == WM_CHAR)) {
+ GetMessage(&msg, NULL, 0, 0);
+ 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: {
+ char buffer[TCL_UTF_MAX+1];
+ int i;
+ event.type = KeyPress;
+ event.xany.send_event = -3;
+ event.xkey.keycode = wParam;
+ event.xkey.nbytes = Tcl_UniCharToUtf((int)wParam, buffer);
+ for (i=0; i<event.xkey.nbytes && i<TCL_UTF_MAX; ++i) {
+ event.xkey.trans_chars[i] = buffer[i];
+ }
+ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+ event.type = KeyRelease;
break;
}
- default:
- return;
+ }
+ 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);
}
@@ -1256,12 +1281,12 @@ GenerateXEvent(hwnd, message, wParam, lParam)
*
* GetState --
*
- * This function constructs a state mask for the mouse buttons
- * and modifier keys as they were before the event occured.
+ * 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.
+ * Returns a composite value of all the modifier and button state flags
+ * that were set at the time the event occurred.
*
* Side effects:
* None.
@@ -1270,18 +1295,18 @@ GenerateXEvent(hwnd, message, wParam, lParam)
*/
static unsigned int
-GetState(message, wParam, lParam)
- UINT message; /* Win32 message type */
- WPARAM wParam; /* wParam of message, used if key message */
- LPARAM lParam; /* lParam of message, used if key message */
+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 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
@@ -1289,39 +1314,46 @@ GetState(message, wParam, lParam)
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;
+ 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) {
+ if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) {
+ state |= EXTENDED_MASK;
+ } else {
+ state &= ~EXTENDED_MASK;
+ }
+ }
}
return state;
}
@@ -1331,61 +1363,59 @@ GetState(message, wParam, lParam)
*
* 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.
+ * 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.
+ * Removes any WM_CHAR messages waiting on the top of the system event
+ * queue.
*
*----------------------------------------------------------------------
*/
static void
-GetTranslatedKey(xkey)
- XKeyEvent *xkey;
+GetTranslatedKey(
+ XKeyEvent *xkey)
{
MSG msg;
-
+
xkey->nbytes = 0;
while ((xkey->nbytes < XMaxTransChars)
&& PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
- if ((msg.message == WM_CHAR) || (msg.message == WM_SYSCHAR)) {
- GetMessage(&msg, NULL, 0, 0);
+ if ((msg.message != WM_CHAR) && (msg.message != WM_SYSCHAR)) {
+ break;
+ }
+
+ GetMessage(&msg, NULL, 0, 0);
+
+ /*
+ * 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)) {
/*
- * 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).
+ * 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.
*/
- 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 ++;
- }
- } else {
- break;
+ xkey->trans_chars[xkey->nbytes] = (char) (msg.wParam >> 8);
+ xkey->nbytes ++;
}
}
}
@@ -1396,11 +1426,11 @@ GetTranslatedKey(xkey)
* UpdateInputLanguage --
*
* Gets called when a WM_INPUTLANGCHANGE message is received by the Tk
- * child window procedure. 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.
+ * 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.
@@ -1412,8 +1442,8 @@ GetTranslatedKey(xkey)
*/
static void
-UpdateInputLanguage(charset)
- int charset;
+UpdateInputLanguage(
+ int charset)
{
CHARSETINFO charsetInfo;
Tcl_Encoding encoding;
@@ -1422,8 +1452,8 @@ UpdateInputLanguage(charset)
if (keyInputCharset == charset) {
return;
}
- if (TranslateCharsetInfo((DWORD*)charset, &charsetInfo, TCI_SRCCHARSET)
- == 0) {
+ if (TranslateCharsetInfo((DWORD*)charset, &charsetInfo,
+ TCI_SRCCHARSET) == 0) {
/*
* Some mysterious failure.
*/
@@ -1454,8 +1484,8 @@ UpdateInputLanguage(charset)
*
* TkWinGetKeyInputEncoding --
*
- * Returns the current keyboard input encoding selected by the
- * user (with WM_INPUTLANGCHANGE events).
+ * Returns the current keyboard input encoding selected by the user (with
+ * WM_INPUTLANGCHANGE events).
*
* Results:
* The current keyboard input encoding.
@@ -1467,7 +1497,7 @@ UpdateInputLanguage(charset)
*/
Tcl_Encoding
-TkWinGetKeyInputEncoding()
+TkWinGetKeyInputEncoding(void)
{
return keyInputEncoding;
}
@@ -1489,7 +1519,7 @@ TkWinGetKeyInputEncoding()
*/
Tcl_Encoding
-TkWinGetUnicodeEncoding()
+TkWinGetUnicodeEncoding(void)
{
if (unicodeEncoding == NULL) {
unicodeEncoding = Tcl_GetEncoding(NULL, "unicode");
@@ -1502,23 +1532,22 @@ TkWinGetUnicodeEncoding()
*
* HandleIMEComposition --
*
- * This function works around a definciency in some versions
- * of Windows 2000 to make it possible to entry multi-lingual
- * characters under all versions of Windows 2000.
+ * This function works around a definciency 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 "?".
+ * 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.
+ * 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.
+ * Otherwise returns 0.
*
* Side effects:
* Key events are put into the TK event queue.
@@ -1527,109 +1556,115 @@ TkWinGetUnicodeEncoding()
*/
static int
-HandleIMEComposition(hwnd, lParam)
- HWND hwnd; /* Window receiving the message. */
- LPARAM lParam; /* Flags for the WM_IME_COMPOSITION
- * message */
+HandleIMEComposition(
+ HWND hwnd, /* Window receiving the message. */
+ LPARAM lParam) /* Flags for the WM_IME_COMPOSITION message */
{
HIMC hIMC;
- int i, n;
- XEvent event;
- char * buff;
- TkWindow *winPtr;
- Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding();
+ int n;
BOOL isWinNT = (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT);
if ((lParam & GCS_RESULTSTR) == 0) {
- /*
- * Composition is not finished yet.
- */
+ /*
+ * Composition is not finished yet.
+ */
- return 0;
+ return 0;
}
hIMC = ImmGetContext(hwnd);
- if (hIMC) {
+ if (!hIMC) {
+ return 0;
+ }
+
+ if (isWinNT) {
+ n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);
+ } else {
+ n = ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, NULL, 0);
+ }
+
+ if (n > 0) {
+ char *buff = ckalloc((unsigned) n);
+ TkWindow *winPtr;
+ XEvent event;
+ int i;
+
if (isWinNT) {
- n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);
+ n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff,
+ (unsigned) n);
} else {
- n = ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, NULL, 0);
- }
+ Tcl_DString utfString, unicodeString;
+ Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding();
+
+ n = ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, buff,
+ (unsigned) n);
+ Tcl_DStringInit(&utfString);
+ Tcl_ExternalToUtfDString(keyInputEncoding, buff, n, &utfString);
+ Tcl_UtfToExternalDString(unicodeEncoding,
+ Tcl_DStringValue(&utfString), -1, &unicodeString);
+ i = Tcl_DStringLength(&unicodeString);
+ if (n < i) {
+ /*
+ * Only alloc more space if we need, otherwise just use what
+ * we've created. Don't realloc as that may copy data we no
+ * longer need.
+ */
- if ((n > 0) && ((buff = (char *) ckalloc(n)) != NULL)) {
- if (isWinNT) {
- n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff, n);
- } else {
- Tcl_DString utfString, unicodeString;
-
- n = ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, buff, n);
- Tcl_DStringInit(&utfString);
- Tcl_ExternalToUtfDString(keyInputEncoding, buff, n,
- &utfString);
- Tcl_UtfToExternalDString(unicodeEncoding,
- Tcl_DStringValue(&utfString), -1, &unicodeString);
- i = Tcl_DStringLength(&unicodeString);
- if (n < i) {
- /*
- * Only alloc more space if we need, otherwise just
- * use what we've created. Don't realloc as that may
- * copy data we no longer need.
- */
- ckfree((char *) buff);
- buff = (char *) ckalloc(i);
- }
- n = i;
- memcpy(buff, Tcl_DStringValue(&unicodeString), n);
- Tcl_DStringFree(&utfString);
- Tcl_DStringFree(&unicodeString);
+ ckfree((char *) buff);
+ buff = (char *) ckalloc((unsigned) i);
}
+ n = i;
+ memcpy(buff, Tcl_DStringValue(&unicodeString), (unsigned) n);
+ Tcl_DStringFree(&utfString);
+ Tcl_DStringFree(&unicodeString);
+ }
+ /*
+ * Set up the fields pertinent to key event.
+ *
+ * We set send_event to the special value of -2, so that TkpGetString
+ * in tkWinKey.c knows that trans_chars[] 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 = -2;
+ 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;
+ event.xkey.keycode = 0;
+ event.xkey.nbytes = 2;
+
+ for (i=0; i<n; ) {
/*
- * Set up the fields pertinent to key event.
- *
- * We set send_event to the special value of -2, so that
- * TkpGetString() in tkWinKey.c knows that trans_chars[]
- * already contains a UNICODE char and there's no need to
- * do encoding conversion.
+ * Simulate a pair of KeyPress and KeyRelease events for each
+ * UNICODE character in the composition.
*/
- winPtr = (TkWindow *)Tk_HWNDToWindow(hwnd);
-
- event.xkey.serial = winPtr->display->request++;
- event.xkey.send_event = -2;
- 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;
- event.xkey.keycode = 0;
- event.xkey.nbytes = 2;
-
- for (i=0; i<n;) {
- /*
- * Simulate a pair of KeyPress and KeyRelease events
- * for each UNICODE character in the composition.
- */
-
- event.xkey.trans_chars[0] = (char) buff[i++];
- event.xkey.trans_chars[1] = (char) buff[i++];
-
- 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;
- }
+ event.xkey.trans_chars[0] = (char) buff[i++];
+ event.xkey.trans_chars[1] = (char) buff[i++];
- return 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;
}
/*
@@ -1649,10 +1684,11 @@ HandleIMEComposition(hwnd, lParam)
*/
void
-Tk_FreeXId(display, xid)
- Display *display;
- XID xid;
+Tk_FreeXId(
+ Display *display,
+ XID xid)
{
+ /* Do nothing */
}
/*
@@ -1660,65 +1696,66 @@ Tk_FreeXId(display, xid)
*
* TkWinResendEvent --
*
- * This function converts an X event into a Windows event and
- * invokes the specified windo procedure.
+ * 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 procedure
+ * Invokes the window function
*
*----------------------------------------------------------------------
*/
LRESULT
-TkWinResendEvent(wndproc, hwnd, eventPtr)
- WNDPROC wndproc;
- HWND hwnd;
- XEvent *eventPtr;
+TkWinResendEvent(
+ WNDPROC wndproc,
+ HWND hwnd,
+ XEvent *eventPtr)
{
UINT msg;
WPARAM wparam;
LPARAM lparam;
- if (eventPtr->type == ButtonPress) {
- 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);
- } else {
+ 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);
}
@@ -1727,8 +1764,8 @@ TkWinResendEvent(wndproc, hwnd, eventPtr)
*
* TkpGetMS --
*
- * Return a relative time in milliseconds. It doesn't matter
- * when the epoch was.
+ * Return a relative time in milliseconds. It doesn't matter when the
+ * epoch was.
*
* Results:
* Number of milliseconds.
@@ -1740,7 +1777,7 @@ TkWinResendEvent(wndproc, hwnd, eventPtr)
*/
unsigned long
-TkpGetMS()
+TkpGetMS(void)
{
return GetTickCount();
}
@@ -1761,9 +1798,10 @@ TkpGetMS()
*/
void
-TkWinUpdatingClipboard(int mode)
+TkWinUpdatingClipboard(
+ int mode)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
tsdPtr->updatingClipboard = mode;
@@ -1774,17 +1812,17 @@ TkWinUpdatingClipboard(int 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:
+ * 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.
+ * 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
@@ -1796,16 +1834,20 @@ TkWinUpdatingClipboard(int mode)
*/
void
-Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
+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.
+ * 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;
@@ -1817,9 +1859,8 @@ Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
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.
+ * 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)) {
@@ -1852,11 +1893,13 @@ Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
* 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
+ * 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;
@@ -1865,3 +1908,102 @@ Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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 */
+{
+ struct tagLASTINPUTINFO {
+ UINT cbSize;
+ DWORD dwTime;
+ } li;
+
+ /*
+ * Multiple settings of either of these variables should be OK; any thread
+ * hazards should just cause inefficiency...
+ */
+
+ static FARPROC pfnGetLastInputInfo = NULL;
+ static int initinfo = 0;
+
+ if (!initinfo) {
+ HMODULE hMod = GetModuleHandleA("USER32.DLL");
+
+ initinfo = 1;
+ if (hMod){
+ pfnGetLastInputInfo = GetProcAddress(hMod, "GetLastInputInfo");
+ }
+ }
+ if (pfnGetLastInputInfo == NULL) {
+ return -1;
+ }
+ li.cbSize = sizeof(li);
+ if (!(BOOL)(pfnGetLastInputInfo)(&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) NULL;
+
+ SendInput(1, &inp, sizeof(inp));
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/win/ttkWinMonitor.c b/win/ttkWinMonitor.c
new file mode 100644
index 0000000..fda8304
--- /dev/null
+++ b/win/ttkWinMonitor.c
@@ -0,0 +1,158 @@
+#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)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 to 'xpnative' if present,
+ * which will in turn fall back to 'winnative' if XP theming
+ * is disabled.
+ */
+
+ theme = Ttk_GetTheme(interp, "xpnative");
+ 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/win/ttkWinTheme.c b/win/ttkWinTheme.c
new file mode 100644
index 0000000..e0a0eda
--- /dev/null
+++ b/win/ttkWinTheme.c
@@ -0,0 +1,733 @@
+/* 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 = (TroughClientData*)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/win/ttkWinXPTheme.c b/win/ttkWinXPTheme.c
new file mode 100644
index 0000000..e2f916f
--- /dev/null
+++ b/win/ttkWinXPTheme.c
@@ -0,0 +1,1324 @@
+/*
+ * 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>
+#ifdef HAVE_VSSYM32_H
+# 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 = (XPThemeProcs*)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((char*)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_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 = (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((char *)elementData->info->statemap);
+ ckfree((char *)elementData->info->className);
+ ckfree((char *)elementData->info->elementName);
+ ckfree((char *)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_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ for (i = 0; i < objc; ++i) {
+ int option;
+ if (Tcl_GetIndexFromObj(interp, objv[i], names, "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;
+
+ 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_AppendResult(interp,
+ "missing required arguments 'class' and/or 'partId'", 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_AppendResult(interp, "Missing value for \"",
+ Tcl_GetString(objv[i]), "\".", NULL);
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
+ "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 = (Ttk_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((char *)stateTable);
+ return status;
+ }
+ } else {
+ stateTable = (Ttk_StateTable *)ckalloc(sizeof(Ttk_StateTable));
+ memset(stateTable, 0, sizeof(Ttk_StateTable));
+ }
+
+ elementPtr = (ElementInfo *)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 = (LPWSTR) 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;
+ OSVERSIONINFO os;
+
+ os.dwOSVersionInfoSize = sizeof(os);
+ GetVersionEx(&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 = (XPThemeData *)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/win/winMain.c b/win/winMain.c
index b4e11f7..2883ad7 100644
--- a/win/winMain.c
+++ b/win/winMain.c
@@ -1,4 +1,4 @@
-/*
+/*
* winMain.c --
*
* Main entry point for wish and other Tk-based applications.
@@ -6,60 +6,63 @@
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include <tk.h>
+#include "tkInt.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
-#include <malloc.h>
#include <locale.h>
-#include "tkInt.h"
/*
- * The following declarations refer to internal Tk routines. These
- * interfaces are available for use, but are not supported.
+ * The following declarations refer to internal Tk routines. These interfaces
+ * are available for use, but are not supported.
*/
+#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
/*
* Forward declarations for procedures defined later in this file:
*/
-static void setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));
-static Tcl_PanicProc WishPanic;
+static void WishPanic(CONST char *format, ...);
-#ifdef TK_TEST
-extern int Tktest_Init(Tcl_Interp *interp);
-#endif /* TK_TEST */
+#if defined(__CYGWIN__)
+static void setargv(int *argcPtr, char ***argvPtr);
+#endif /* __CYGWIN__ */
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.
+ * 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
+#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
-extern int TK_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
-
+extern 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()
+ * script, prime the library or encoding paths, fiddle with the argv, etc.,
+ * without needing to rewrite Tk_Main()
*/
#ifdef TK_LOCAL_MAIN_HOOK
-extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
+extern int TK_LOCAL_MAIN_HOOK(int *argc, char ***argv);
#endif
-
/*
*----------------------------------------------------------------------
@@ -69,8 +72,7 @@ extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
* Main entry point from Windows.
*
* Results:
- * Returns false if initialization fails, otherwise it never
- * returns.
+ * Returns false if initialization fails, otherwise it never returns.
*
* Side effects:
* Just about anything, since from here we call arbitrary Tcl code.
@@ -79,43 +81,49 @@ extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
*/
int APIENTRY
-WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
- HINSTANCE hInstance;
- HINSTANCE hPrevInstance;
- LPSTR lpszCmdLine;
- int nCmdShow;
+WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow)
{
char **argv;
int argc;
- char buffer[MAX_PATH+1];
char *p;
Tcl_SetPanicProc(WishPanic);
/*
- * 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.
+ * 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.
+ * 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(__CYGWIN__)
setargv(&argc, &argv);
+#else
+ argc = __argc;
+ argv = __argv;
+#endif
/*
- * Replace argv[0] with full pathname of executable, and forward
- * slashes substituted for backslashes.
+ * Forward slashes substituted for backslashes.
*/
- GetModuleFileName(NULL, buffer, sizeof(buffer));
- argv[0] = buffer;
- for (p = buffer; *p != '\0'; p++) {
+ for (p = argv[0]; *p != '\0'; p++) {
if (*p == '\\') {
*p = '/';
}
@@ -128,20 +136,19 @@ WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
Tk_Main(argc, argv, TK_LOCAL_APPINIT);
return 1;
}
-
/*
*----------------------------------------------------------------------
*
* Tcl_AppInit --
*
- * This procedure performs application-specific initialization.
- * Most applications, especially those that incorporate additional
- * packages, will have their own version of this procedure.
+ * 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.
+ * 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.
@@ -150,9 +157,12 @@ WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
*/
int
-Tcl_AppInit(interp)
- Tcl_Interp *interp; /* Interpreter for application. */
+Tcl_AppInit(
+ Tcl_Interp *interp) /* Interpreter for application. */
{
+#define TK_MAX_WARN_LEN 1024
+ WCHAR msgString[TK_MAX_WARN_LEN + 5];
+
if (Tcl_Init(interp) == TCL_ERROR) {
goto error;
}
@@ -171,40 +181,69 @@ Tcl_AppInit(interp)
goto error;
}
}
-#if defined(STATIC_BUILD) && defined(TCL_USE_STATIC_PACKAGES)
- {
- extern Tcl_PackageInitProc Registry_Init;
- extern Tcl_PackageInitProc Dde_Init;
-
- if (Registry_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
- Tcl_StaticPackage(interp, "registry", Registry_Init, NULL);
+#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
+ if (Registry_Init(interp) == TCL_ERROR) {
+ goto error;
+ }
+ Tcl_StaticPackage(interp, "registry", Registry_Init, NULL);
- if (Dde_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
- Tcl_StaticPackage(interp, "dde", Dde_Init, NULL);
- }
+ if (Dde_Init(interp) == TCL_ERROR) {
+ goto error;
+ }
+ Tcl_StaticPackage(interp, "dde", Dde_Init, NULL);
#endif
#ifdef TK_TEST
if (Tktest_Init(interp) == TCL_ERROR) {
goto error;
}
- Tcl_StaticPackage(interp, "Tktest", Tktest_Init,
- (Tcl_PackageInitProc *) NULL);
+ Tcl_StaticPackage(interp, "Tktest", Tktest_Init, NULL);
#endif /* TK_TEST */
+ /*
+ * Call the init procedures for included packages. Each call should look
+ * like this:
+ *
+ * if (Mod_Init(interp) == TCL_ERROR) {
+ * return TCL_ERROR;
+ * }
+ *
+ * where "Mod" is the name of the module. (Dynamically-loadable packages
+ * should have the same entry-point name.)
+ */
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if they
+ * weren't already created by the init procedures called above.
+ */
+
+ /*
+ * Specify a user-specific startup file to invoke if the application is
+ * run interactively. Typically the startup file is "~/.apprc" where "app"
+ * is the name of the application. If this line is deleted then no user-
+ * specific startup file will be run under any conditions.
+ */
+
Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY);
return TCL_OK;
error:
+ MultiByteToWideChar(CP_UTF8, 0, Tcl_GetStringResult(interp), -1,
+ msgString, TK_MAX_WARN_LEN);
+ /*
+ * Truncate MessageBox string if it is too long to not overflow the screen
+ * and cause possible oversized window error.
+ */
+ memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR));
MessageBeep(MB_ICONEXCLAMATION);
- MessageBox(NULL, Tcl_GetStringResult(interp), "Error in Wish",
+ MessageBoxW(NULL, msgString, L"Error in Wish",
MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
ExitProcess(1);
- /* we won't reach this, but we need the return */
+
+ /*
+ * We won't reach this, but we need the return.
+ */
+
return TCL_ERROR;
}
@@ -225,32 +264,85 @@ error:
*/
void
-WishPanic TCL_VARARGS_DEF(CONST char *,arg1)
+WishPanic(
+ CONST char *format, ...)
{
va_list argList;
- char buf[1024];
- CONST char *format;
-
- format = TCL_VARARGS_START(CONST char *,arg1,argList);
+ char buf[TK_MAX_WARN_LEN];
+ WCHAR msgString[TK_MAX_WARN_LEN + 5];
+
+ va_start(argList, format);
vsprintf(buf, format, argList);
+ MultiByteToWideChar(CP_UTF8, 0, buf, -1, msgString, TK_MAX_WARN_LEN);
+ /*
+ * Truncate MessageBox string if it is too long to not overflow the screen
+ * and cause possible oversized window error.
+ */
+ memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR));
MessageBeep(MB_ICONEXCLAMATION);
- MessageBox(NULL, buf, "Fatal Error in Wish",
+ MessageBoxW(NULL, msgString, L"Fatal Error in Wish",
MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
#ifdef _MSC_VER
DebugBreak();
#endif
ExitProcess(1);
}
+
+#if !defined(__GNUC__) || defined(TK_TEST)
+/*
+ *----------------------------------------------------------------------
+ *
+ * main --
+ *
+ * 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.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+main(
+ int argc,
+ char **argv)
+{
+ Tcl_SetPanicProc(WishPanic);
+
+ /*
+ * Set up the default locale to be standard "C" locale so parsing is
+ * performed correctly.
+ */
+
+ setlocale(LC_ALL, "C");
+
+ /*
+ * Console emulation widget not required as this entry is from the
+ * console subsystem, thus stdin,out,err already have end-points.
+ */
+
+ consoleRequired = FALSE;
+
+ 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.
+ * 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
@@ -260,8 +352,8 @@ WishPanic TCL_VARARGS_DEF(CONST char *,arg1)
* quote -> begin quoted string
*
* Results:
- * Fills argcPtr with the number of arguments and argvPtr with the
- * array of arguments.
+ * Fills argcPtr with the number of arguments and argvPtr with the array
+ * of arguments.
*
* Side effects:
* Memory allocated.
@@ -269,20 +361,21 @@ WishPanic TCL_VARARGS_DEF(CONST char *,arg1)
*--------------------------------------------------------------------------
*/
+#if defined(__CYGWIN__)
static void
-setargv(argcPtr, argvPtr)
- int *argcPtr; /* Filled with number of argument strings. */
- char ***argvPtr; /* Filled with argument strings (malloc'd). */
+setargv(
+ int *argcPtr, /* Filled with number of argument strings. */
+ char ***argvPtr) /* Filled with argument strings (malloc'd). */
{
char *cmdLine, *p, *arg, *argSpace;
char **argv;
int argc, size, inquote, copy, slashes;
-
+
cmdLine = GetCommandLine(); /* INTL: BUG */
/*
- * Precompute an overly pessimistic guess at the number of arguments
- * in the command line by counting non-space spans.
+ * Precompute an overly pessimistic guess at the number of arguments in
+ * the command line by counting non-space spans.
*/
size = 2;
@@ -297,7 +390,7 @@ setargv(argcPtr, argvPtr)
}
}
}
- argSpace = (char *) Tcl_Alloc(
+ argSpace = (char *) ckalloc(
(unsigned) (size * sizeof(char *) + strlen(cmdLine) + 1));
argv = (char **) argSpace;
argSpace += size * sizeof(char *);
@@ -330,18 +423,18 @@ setargv(argcPtr, argvPtr)
} else {
inquote = !inquote;
}
- }
- slashes >>= 1;
- }
+ }
+ slashes >>= 1;
+ }
- while (slashes) {
+ while (slashes) {
*arg = '\\';
arg++;
slashes--;
}
- if ((*p == '\0')
- || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
+ if ((*p == '\0') || (!inquote &&
+ ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
break;
}
if (copy != 0) {
@@ -349,7 +442,7 @@ setargv(argcPtr, argvPtr)
arg++;
}
p++;
- }
+ }
*arg = '\0';
argSpace = arg + 1;
}
@@ -358,45 +451,12 @@ setargv(argcPtr, argvPtr)
*argcPtr = argc;
*argvPtr = argv;
}
-
-#if !defined(__GNUC__) || defined(TK_TEST)
+#endif /* __CYGWIN__ */
+
/*
- *----------------------------------------------------------------------
- *
- * main --
- *
- * 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.
- *
- *----------------------------------------------------------------------
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
*/
-
-int main(int argc, char **argv)
-{
- Tcl_SetPanicProc(WishPanic);
-
- /*
- * Set up the default locale to be standard "C" locale so parsing
- * is performed correctly.
- */
-
- setlocale(LC_ALL, "C");
-
- /*
- * 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 = FALSE;
-
- Tk_Main(argc, argv, Tcl_AppInit);
- return 0;
-}
-#endif /* !__GNUC__ || TK_TEST */
diff --git a/win/wish.exe.manifest.in b/win/wish.exe.manifest.in
index 236768e..2cae0c0 100644
--- a/win/wish.exe.manifest.in
+++ b/win/wish.exe.manifest.in
@@ -1,22 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
-<assemblyIdentity
- version="@TK_WIN_VERSION@"
- processorArchitecture="@MACHINE@"
- name="Tcl.Tk.wish"
- type="win32"
-/>
-<description>Tcl/Tk windowing shell (wish)</description>
-<dependency>
-<dependentAssembly>
-<assemblyIdentity
- type="win32"
- name="Microsoft.Windows.Common-Controls"
- version="6.0.0.0"
- processorArchitecture="@MACHINE@"
- publicKeyToken="6595b64144ccf1df"
- language="*"
-/>
-</dependentAssembly>
-</dependency>
+<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>
+ <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>