diff options
Diffstat (limited to 'win')
44 files changed, 2756 insertions, 2444 deletions
diff --git a/win/Makefile.in b/win/Makefile.in index 7958e3c..247e183 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -94,10 +94,6 @@ TCL_BIN_DIR = @TCL_BIN_DIR@ # 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. @@ -124,7 +120,6 @@ 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@ @@ -134,6 +129,8 @@ EXESUFFIX = @EXESUFFIX@ TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ TK_LIB_FILE = @TK_LIB_FILE@ TK_DLL_FILE = @TK_DLL_FILE@ +TEST_DLL_FILE = tktest$(VER)${DLLSUFFIX} +TEST_LIB_FILE = @LIBPREFIX@tktest$(VER)${LIBSUFFIX} SHARED_LIBRARIES = $(TK_DLL_FILE) $(TK_STUB_LIB_FILE) STATIC_LIBRARIES = $(TK_LIB_FILE) @@ -167,7 +164,7 @@ LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@ #CFLAGS = $(CFLAGS_DEBUG) #CFLAGS = $(CFLAGS_OPTIMIZE) #CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE) -CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ +CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DUNICODE -D_UNICODE # Special compiler flags to use when building man2tcl on Windows. MAN2TCLFLAGS = @MAN2TCLFLAGS@ @@ -187,12 +184,12 @@ EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ STLIB_LD = @STLIB_LD@ SHLIB_LD = @SHLIB_LD@ -SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ $(TCL_STUB_LIB_FILE) $(LIBS) +SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_SUFFIX = @SHLIB_SUFFIX@ VER = @TK_MAJOR_VERSION@@TK_MINOR_VERSION@ DOTVER = @TK_MAJOR_VERSION@.@TK_MINOR_VERSION@ -LIBS = @LIBS@ @LIBS_GUI@ +LIBS = $(TCL_STUB_LIB_FILE) @LIBS@ @LIBS_GUI@ RMDIR = rm -rf MKDIR = mkdir -p SHELL = @SHELL@ @@ -211,14 +208,11 @@ TCL_EXE = @TCLSH_PROG@ CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \ -I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \ -I"${XLIB_DIR_NATIVE}" -I"${BITMAP_DIR_NATIVE}" \ --I"${TCL_GENERIC_NATIVE}" -I"${TCL_PLATFORM_NATIVE}" ${AC_FLAGS} +-I"${TCL_GENERIC_NATIVE}" ${AC_FLAGS} -DUSE_TCL_STUBS CC_OBJNAME = @CC_OBJNAME@ CC_EXENAME = @CC_EXENAME@ -STUB_CC_SWITCHES = ${CC_SWITCHES} -DUSE_TCL_STUBS -CON_CC_SWITCHES = ${CC_SWITCHES} -DCONSOLE - # Tk used to let the configure script choose which program to use # for installing, but there are just too many different versions of # "install" around; better to use the install-sh script that comes @@ -232,7 +226,6 @@ WISH_OBJS = \ winMain.$(OBJEXT) TKTEST_OBJS = \ - testMain.$(OBJEXT) \ tkSquare.$(OBJEXT) \ tkTest.$(OBJEXT) \ tkOldTest.$(OBJEXT) \ @@ -280,6 +273,7 @@ TK_OBJS = \ tkAtom.$(OBJEXT) \ tkBind.$(OBJEXT) \ tkBitmap.$(OBJEXT) \ + tkBusy.$(OBJEXT) \ tkButton.$(OBJEXT) \ tkCanvArc.$(OBJEXT) \ tkCanvBmap.$(OBJEXT) \ @@ -311,12 +305,15 @@ TK_OBJS = \ tkImage.$(OBJEXT) \ tkImgBmap.$(OBJEXT) \ tkImgGIF.$(OBJEXT) \ + tkImgPNG.$(OBJEXT) \ tkImgPPM.$(OBJEXT) \ tkImgPhoto.$(OBJEXT) \ + tkImgPhInstance.$(OBJEXT) \ tkImgUtil.$(OBJEXT) \ tkListbox.$(OBJEXT) \ tkMacWinMenu.$(OBJEXT) \ tkMain.$(OBJEXT) \ + tkMain2.$(OBJEXT) \ tkMenu.$(OBJEXT) \ tkMenubutton.$(OBJEXT) \ tkMenuDraw.$(OBJEXT) \ @@ -346,7 +343,6 @@ TK_OBJS = \ tkUtil.$(OBJEXT) \ tkVisual.$(OBJEXT) \ tkStubInit.$(OBJEXT) \ - tkStubLib.$(OBJEXT) \ tkWindow.$(OBJEXT) \ $(TTK_OBJS) @@ -428,15 +424,15 @@ $(MAN2TCL): $(TCL_SRC_DIR_NATIVE)/tools/man2tcl.c test: test-classic test-ttk -test-classic: binaries $(TKTEST) +test-classic: binaries $(TKTEST) $(TEST_DLL_FILE) $(CAT32) $(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/all.tcl" \ $(TESTFLAGS) | ./$(CAT32) -test-ttk: binaries $(TKTEST) +test-ttk: binaries $(TKTEST) $(TEST_DLL_FILE) $(CAT32) $(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/ttk/all.tcl" \ $(TESTFLAGS) | ./$(CAT32) -runtest: binaries $(TKTEST) +runtest: binaries $(TKTEST) $(TEST_DLL_FILE) $(SHELL_ENV) ./$(TKTEST) $(TESTFLAGS) $(SCRIPT) # This target can be used to run wish from the build directory @@ -444,7 +440,7 @@ runtest: binaries $(TKTEST) shell: binaries $(SHELL_ENV) ./$(WISH) $(SCRIPT) -demo: $(WISH) +demo: $(SHELL_ENV) ./$(WISH) $(ROOT_DIR)/library/demos/widget # This target can be used to run wish inside either gdb or insight @@ -477,7 +473,8 @@ install-binaries: binaries @echo "Creating package index $(PKG_INDEX)"; @$(RM) $(PKG_INDEX); @(\ - echo "if {[catch {package present Tcl 8.5.0}]} { return }";\ + echo "if {[catch {package present Tcl\ + $(TCLVERSION)$(TCLPATCHL)}]} { return }";\ echo "package ifneeded Tk $(VERSION)$(PATCH_LEVEL)\ [list load [file join \$$dir .. .. bin $(TK_DLL_FILE)] Tk]";\ ) > $(PKG_INDEX); @@ -513,8 +510,8 @@ 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 \ - $(ROOT_DIR)/library/tclIndex $(UNIX_DIR)/tkAppInit.c; \ + @for i in $(ROOT_DIR)/library/*.tcl $(ROOT_DIR)/library/tclIndex \ + $(UNIX_DIR)/tkAppInit.c; \ do \ $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR); \ done; @@ -597,19 +594,23 @@ install-private-headers: libraries $(INSTALL_DATA) $$i $(PRIVATE_INCLUDE_INSTALL_DIR); \ done; -$(WISH): $(TK_LIB_FILE) $(TK_STUB_LIB_FILE) $(WISH_OBJS) wish.$(RES) - $(CC) $(CFLAGS) $(WISH_OBJS) $(TCL_LIB_FILE) $(TK_LIB_FILE) $(LIBS) \ +$(WISH): $(WISH_OBJS) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES) + $(CC) $(CFLAGS) $(WISH_OBJS) $(TK_LIB_FILE) \ + $(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \ wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW) @VC_MANIFEST_EMBED_EXE@ -tktest : $(TKTEST) +tktest: $(TKTEST) -$(TKTEST): $(TK_LIB_FILE) $(TKTEST_OBJS) wish.$(RES) $(CAT32) - $(CC) $(CFLAGS) $(TKTEST_OBJS) $(TCL_LIB_FILE) \ - $(TK_LIB_FILE) $(LIBS) \ +$(TKTEST): testMain.$(OBJEXT) $(TEST_DLL_FILE) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES) + $(CC) $(CFLAGS) testMain.$(OBJEXT) $(TEST_LIB_FILE) $(TK_LIB_FILE) \ + $(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \ wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW) @VC_MANIFEST_EMBED_EXE@ +${TEST_DLL_FILE}: ${TKTEST_OBJS} ${TK_STUB_LIB_FILE} + @MAKE_DLL@ ${TKTEST_OBJS} $(TK_STUB_LIB_FILE) $(SHLIB_LD_LIBS) + # Msys make requires this next rule for some reason. $(TCL_SRC_DIR)/win/cat.c: @@ -657,6 +658,9 @@ tkWinTest.$(OBJEXT): tkWinTest.c tkSquare.$(OBJEXT): tkSquare.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) +tkMain2.$(OBJEXT): tkMain.c + $(CC) -c $(CC_SWITCHES) -DBUILD_tk -DTK_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) + # Extra dependency info tkConsole.$(OBJEXT): configure Makefile tkMain.$(OBJEXT): configure Makefile @@ -672,10 +676,10 @@ tkWindow.$(OBJEXT): configure Makefile # Implicit rule for all object files that will end up in the Tcl library %.$(OBJEXT): %.c - $(CC) -c $(STUB_CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME) + $(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME) .rc.$(RES): - $(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(TCL_GENERIC_NATIVE)" @RC_INCLUDE@ "$(TCL_PLATFORM_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@ "$(RC_DIR_NATIVE)" @DEPARG@ depend: @@ -708,4 +712,20 @@ genstubs: $(TCL_EXE) "$(TCL_TOOL_DIR)/genStubs.tcl" \ "$(GENERIC_DIR_NATIVE)" \ "$(GENERIC_DIR_NATIVE)/tk.decls" \ - "$(GENERIC_DIR_NATIVE)/tkInt.decls" + "$(GENERIC_DIR_NATIVE)/tkInt.decls" + $(TCL_EXE) "$(TTK_DIR)/ttkGenStubs.tcl" \ + "$(TTK_DIR)" \ + "$(TTK_DIR)/ttk.decls" + +# +# The list of all the targets that do not correspond to real files. This stops +# 'make' from getting confused when someone makes an error in a rule. +# + +.PHONY: all binaries libraries doc tkLibObjs objs tktest-real test test-classic +.PHONY: test-ttk testlang runtest shell demo gdb install install-strip +.PHONY: install-binaries install-libraries install-demos install-doc +.PHONY: install-private-headers clean distclean depend genstubs checkstubs +.PHONY: checkuchar checkexports rpm dist alldist allpatch html html-tcl html-tk + +# DO NOT DELETE THIS LINE -- make depend depends on it. @@ -1,4 +1,4 @@ -Tk 8.5 for Windows +Tk 8.6 for Windows Originally by Scott Stanton while at Sun Microsystems Labs diff --git a/win/buildall.vc.bat b/win/buildall.vc.bat index 16605ee..58360b9 100755 --- a/win/buildall.vc.bat +++ b/win/buildall.vc.bat @@ -56,7 +56,7 @@ if "%TCLDIR%" == "" set TCLDIR=..\..\tcl :: set OPTS=none if not %SYMBOLS%.==. set OPTS=symbols -nmake -nologo -f makefile.vc release winhelp OPTS=%OPTS% %1 +nmake -nologo -f makefile.vc release htmlhelp OPTS=%OPTS% %1 if errorlevel 1 goto error :: Build the static core, dlls and shell. diff --git a/win/configure b/win/configure index c1a1a23..ad99837 100755 --- a/win/configure +++ b/win/configure @@ -309,7 +309,7 @@ ac_includes_default="\ # include <unistd.h> #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_DEFS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING MAN2TCLFLAGS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE BUILD_TCLSH TCLSH_PROG TK_WIN_VERSION MACHINE TK_VERSION TK_MAJOR_VERSION TK_MINOR_VERSION TK_PATCH_LEVEL TK_DBGX TK_LIB_FILE TK_DLL_FILE TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_BUILD_STUB_LIB_SPEC TK_SRC_DIR TK_BIN_DIR TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_DBGX CFG_TK_SHARED_LIB_SUFFIX CFG_TK_UNSHARED_LIB_SUFFIX CFG_TK_EXPORT_FILE_SUFFIX 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_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_DEFS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING MAN2TCLFLAGS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE BUILD_TCLSH TCLSH_PROG TK_WIN_VERSION MACHINE TK_VERSION TK_MAJOR_VERSION TK_MINOR_VERSION TK_PATCH_LEVEL TK_DBGX TK_LIB_FILE TK_DLL_FILE TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_BUILD_STUB_LIB_SPEC TK_SRC_DIR TK_BIN_DIR TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_DBGX CFG_TK_SHARED_LIB_SUFFIX CFG_TK_UNSHARED_LIB_SUFFIX CFG_TK_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW TK_RES STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TK_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TK_LIB_FLAG TK_LIB_SPEC TK_BUILD_LIB_SPEC TK_STUB_LIB_SPEC TK_STUB_LIB_PATH TK_BUILD_STUB_LIB_PATH TK_CC_SEARCH_FLAGS TK_LD_SEARCH_FLAGS RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -851,7 +851,7 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-tcl=DIR use Tcl 8.5 binaries from DIR + --with-tcl=DIR use Tcl 8.6 binaries from DIR --with-celib=DIR use Windows/CE support library from DIR Some influential environment variables: @@ -1308,10 +1308,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # /bin/sh. The bash shell seems to suffer from some strange failures. SHELL=/bin/sh -TK_VERSION=8.5 +TK_VERSION=8.6 TK_MAJOR_VERSION=8 -TK_MINOR_VERSION=5 -TK_PATCH_LEVEL=".11" +TK_MINOR_VERSION=6 +TK_PATCH_LEVEL="b2" VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION #------------------------------------------------------------------------ @@ -3047,7 +3047,7 @@ if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else - tcl_ok=no + tcl_ok=yes fi; if test "$tcl_ok" = "yes"; then @@ -3066,8 +3066,8 @@ _ACEOF else TCL_THREADS=0 - echo "$as_me:$LINENO: result: no (default)" >&5 -echo "${ECHO_T}no (default)" >&6 + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi @@ -3118,10 +3118,10 @@ _ACEOF 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.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 + if test -d ../../tcl8.6$TK_PATCH_LEVEL/win; then + TCL_BIN_DIR_DEFAULT=../../tcl8.6$TK_PATCH_LEVEL/win + elif test -d ../../tcl8.6/win; then + TCL_BIN_DIR_DEFAULT=../../tcl8.6/win else TCL_BIN_DIR_DEFAULT=../../tcl/win fi @@ -3329,6 +3329,11 @@ echo "${ECHO_T}$CELIB_DIR" >&6 # Set some defaults (may get changed below) EXTRA_CFLAGS="" +cat >>confdefs.h <<\_ACEOF +#define MODULE_SCOPE extern +_ACEOF + + # Extract the first word of "cygpath", so it can be a program name with args. set dummy cygpath; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 @@ -3558,14 +3563,80 @@ echo "${ECHO_T}$ac_cv_win32" >&6 echo "$as_me: error: ${CC} cannot produce win32 executables." >&2;} { (exit 1); exit 1; }; } fi + + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain" + echo "$as_me:$LINENO: checking for working -municode linker flag" >&5 +echo $ECHO_N "checking for working -municode linker flag... $ECHO_C" >&6 +if test "${ac_cv_municode+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include <windows.h> + int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;} + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_municode=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_municode=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $ac_cv_municode" >&5 +echo "${ECHO_T}$ac_cv_municode" >&6 + CFLAGS=$hold_cflags + if test "$ac_cv_municode" = "yes" ; then + extra_ldflags="$extra_ldflags -municode" + else + extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS" + fi fi echo "$as_me:$LINENO: checking compiler flags" >&5 echo $ECHO_N "checking compiler flags... $ECHO_C" >&6 if test "${GCC}" = "yes" ; then SHLIB_LD="" - SHLIB_LD_LIBS="" - LIBS="-lws2_32" + SHLIB_LD_LIBS='${LIBS}' + LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -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' @@ -3579,17 +3650,14 @@ echo $ECHO_N "checking compiler flags... $ECHO_C" >&6 MAKE_EXE="\${CC} -o \$@" LIBPREFIX="lib" - extra_cflags="-pipe" - extra_ldflags="-pipe" + extra_ldflags="$extra_ldflags -pipe" + extra_cflags="$extra_cflags -pipe" if test "${SHARED_BUILD}" = "0" ; then # static echo "$as_me:$LINENO: result: using static flags" >&5 echo "${ECHO_T}using static flags" >&6 runtime= - MAKE_DLL="echo " - LIBSUFFIX="s\${DBGX}.a" - LIBFLAGSUFFIX="s\${DBGX}" LIBRARIES="\${STATIC_LIBRARIES}" EXESUFFIX="s\${DBGX}.exe" else @@ -3607,30 +3675,30 @@ echo "$as_me: error: ${CC} does not support the -shared option. fi runtime= - # Link with gcc since ld does not link to default libs like - # -luser32 and -lmsvcrt by default. Make sure CFLAGS is - # included so -mno-cygwin passed the correct libs to the linker. - SHLIB_LD='${CC} -shared ${CFLAGS}' - SHLIB_LD_LIBS='${LIBS}' # Add SHLIB_LD_LIBS to the Make rule, not here. - MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \$@ ${extra_ldflags} \ - -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\$@)" - LIBSUFFIX="\${DBGX}.a" - LIBFLAGSUFFIX="\${DBGX}" EXESUFFIX="\${DBGX}.exe" LIBRARIES="\${SHARED_LIBRARIES}" fi + # Link with gcc since ld does not link to default libs like + # -luser32 and -lmsvcrt by default. Make sure CFLAGS is + # included so -mno-cygwin passed the correct libs to the linker. + SHLIB_LD='${CC} -shared ${CFLAGS}' + SHLIB_LD_LIBS='${LIBS}' + MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \$@ ${extra_ldflags} \ + -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\$@)" # DLLSUFFIX is separate because it is the building block for # users of tclConfig.sh that may build shared or static. DLLSUFFIX="\${DBGX}.dll" + LIBSUFFIX="\${DBGX}.a" + LIBFLAGSUFFIX="\${DBGX}" SHLIB_SUFFIX=.dll EXTRA_CFLAGS="${extra_cflags}" CFLAGS_DEBUG=-g CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" - CFLAGS_WARNING="-Wall" + CFLAGS_WARNING="-Wall -Wdeclaration-after-statement" LDFLAGS_DEBUG= LDFLAGS_OPTIMIZE= @@ -3731,28 +3799,23 @@ echo "${ECHO_T} Using 64-bit $MACHINE mode" >&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" - LIBFLAGSUFFIX="s\${DBGX}" LIBRARIES="\${STATIC_LIBRARIES}" EXESUFFIX="s\${DBGX}.exe" - SHLIB_LD_LIBS="" else # dynamic echo "$as_me:$LINENO: result: using shared flags" >&5 echo "${ECHO_T}using shared flags" >&6 runtime=-MD # Add SHLIB_LD_LIBS to the Make rule, not here. - MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\$@" - LIBSUFFIX="\${DBGX}.lib" - LIBFLAGSUFFIX="\${DBGX}" - EXESUFFIX="\${DBGX}.exe" LIBRARIES="\${SHARED_LIBRARIES}" - SHLIB_LD_LIBS='${LIBS}' + EXESUFFIX="\${DBGX}.exe" fi + MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\$@" # DLLSUFFIX is separate because it is the building block for # users of tclConfig.sh that may build shared or static. DLLSUFFIX="\${DBGX}.dll" + LIBSUFFIX="\${DBGX}.lib" + LIBFLAGSUFFIX="\${DBGX}" # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. @@ -3785,7 +3848,7 @@ echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 fi fi - LIBS="user32.lib advapi32.lib ws2_32.lib" + LIBS="netapi32.lib kernel32.lib 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 @@ -3983,6 +4046,7 @@ _ACEOF fi SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}" + SHLIB_LD_LIBS='${LIBS}' # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" RC_OUT=-fo @@ -4597,6 +4661,63 @@ echo "$as_me: xpnative theme will be unavailable" >&6;} fi +echo "$as_me:$LINENO: checking for vssym32.h" >&5 +echo $ECHO_N "checking for vssym32.h... $ECHO_C" >&6 +if test "${ac_cv_header_vssym32_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <windows.h> +#include <uxtheme.h> + +#include <vssym32.h> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_vssym32_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_vssym32_h=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_vssym32_h" >&5 +echo "${ECHO_T}$ac_cv_header_vssym32_h" >&6 +if test $ac_cv_header_vssym32_h = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_VSSYM32_H 1 +_ACEOF + +fi + + #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols @@ -4890,6 +5011,7 @@ TK_WIN_VERSION="$TK_VERSION.$TK_RELEASE_LEVEL.`echo $TK_PATCH_LEVEL | tr -d ab.` +# win/tcl.m4 doesn't set (LDFLAGS) @@ -4925,10 +5047,15 @@ TK_WIN_VERSION="$TK_VERSION.$TK_RELEASE_LEVEL.`echo $TK_PATCH_LEVEL | tr -d ab.` +# undefined at this point for win + + + + + -# undefined at this point for win @@ -5630,27 +5757,21 @@ 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,@DEPARG@,$DEPARG,;t t s,@CC_OBJNAME@,$CC_OBJNAME,;t t s,@CC_EXENAME@,$CC_EXENAME,;t t s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t s,@LDFLAGS_CONSOLE@,$LDFLAGS_CONSOLE,;t t s,@LDFLAGS_WINDOW@,$LDFLAGS_WINDOW,;t t -s,@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,@STLIB_LD@,$STLIB_LD,;t t +s,@SHLIB_LD@,$SHLIB_LD,;t t +s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t +s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t +s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t +s,@TK_SHARED_BUILD@,$TK_SHARED_BUILD,;t t s,@LIBS_GUI@,$LIBS_GUI,;t t s,@DLLSUFFIX@,$DLLSUFFIX,;t t s,@LIBPREFIX@,$LIBPREFIX,;t t @@ -5669,6 +5790,12 @@ s,@TK_STUB_LIB_PATH@,$TK_STUB_LIB_PATH,;t t s,@TK_BUILD_STUB_LIB_PATH@,$TK_BUILD_STUB_LIB_PATH,;t t s,@TK_CC_SEARCH_FLAGS@,$TK_CC_SEARCH_FLAGS,;t t s,@TK_LD_SEARCH_FLAGS@,$TK_LD_SEARCH_FLAGS,;t t +s,@RC_OUT@,$RC_OUT,;t t +s,@RC_TYPE@,$RC_TYPE,;t t +s,@RC_INCLUDE@,$RC_INCLUDE,;t t +s,@RC_DEFINE@,$RC_DEFINE,;t t +s,@RC_DEFINES@,$RC_DEFINES,;t t +s,@RES@,$RES,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF diff --git a/win/configure.in b/win/configure.in index 4154945..75c9e7a 100644 --- a/win/configure.in +++ b/win/configure.in @@ -11,10 +11,10 @@ AC_PREREQ(2.59) # /bin/sh. The bash shell seems to suffer from some strange failures. SHELL=/bin/sh -TK_VERSION=8.5 +TK_VERSION=8.6 TK_MAJOR_VERSION=8 -TK_MINOR_VERSION=5 -TK_PATCH_LEVEL=".11" +TK_MINOR_VERSION=6 +TK_PATCH_LEVEL="b2" VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION #------------------------------------------------------------------------ @@ -115,6 +115,9 @@ fi AC_CHECK_HEADER([uxtheme.h], [AC_DEFINE(HAVE_UXTHEME_H)], [AC_MSG_NOTICE([xpnative theme will be unavailable])], [#include <windows.h>]) +AC_CHECK_HEADER([vssym32.h], [AC_DEFINE(HAVE_VSSYM32_H)], [], + [#include <windows.h> +#include <uxtheme.h>]) #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols @@ -229,25 +232,22 @@ AC_SUBST(TCL_VERSION) AC_SUBST(TCL_MAJOR_VERSION) AC_SUBST(TCL_MINOR_VERSION) AC_SUBST(TCL_PATCH_LEVEL) + AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_DBGX) AC_SUBST(CFG_TK_SHARED_LIB_SUFFIX) AC_SUBST(CFG_TK_UNSHARED_LIB_SUFFIX) AC_SUBST(CFG_TK_EXPORT_FILE_SUFFIX) -AC_SUBST(TK_SHARED_BUILD) -AC_SUBST(CYGPATH) -AC_SUBST(DEPARG) AC_SUBST(CFLAGS_DEFAULT) AC_SUBST(EXTRA_CFLAGS) -AC_SUBST(STLIB_LD) -AC_SUBST(SHLIB_LD) -AC_SUBST(SHLIB_LD_LIBS) -AC_SUBST(SHLIB_CFLAGS) -AC_SUBST(SHLIB_SUFFIX) +AC_SUBST(CYGPATH) +AC_SUBST(DEPARG) AC_SUBST(CC_OBJNAME) AC_SUBST(CC_EXENAME) + +# win/tcl.m4 doesn't set (LDFLAGS) AC_SUBST(LDFLAGS_DEFAULT) AC_SUBST(LDFLAGS_DEBUG) AC_SUBST(LDFLAGS_OPTIMIZE) @@ -255,14 +255,15 @@ AC_SUBST(LDFLAGS_CONSOLE) AC_SUBST(LDFLAGS_WINDOW) AC_SUBST(AR) AC_SUBST(RANLIB) -AC_SUBST(RC) -AC_SUBST(RC_OUT) -AC_SUBST(RC_TYPE) -AC_SUBST(RC_INCLUDE) -AC_SUBST(RC_DEFINE) -AC_SUBST(RC_DEFINES) AC_SUBST(TK_RES) -AC_SUBST(RES) + +AC_SUBST(STLIB_LD) +AC_SUBST(SHLIB_LD) +AC_SUBST(SHLIB_LD_LIBS) +AC_SUBST(SHLIB_CFLAGS) +AC_SUBST(SHLIB_SUFFIX) +AC_SUBST(TK_SHARED_BUILD) + AC_SUBST(LIBS) AC_SUBST(LIBS_GUI) AC_SUBST(DLLSUFFIX) @@ -286,7 +287,15 @@ AC_SUBST(TK_BUILD_STUB_LIB_PATH) AC_SUBST(TK_CC_SEARCH_FLAGS) AC_SUBST(TK_LD_SEARCH_FLAGS) -AC_OUTPUT([Makefile tkConfig.sh wish.exe.manifest]) +AC_SUBST(RC) +AC_SUBST(RC_OUT) +AC_SUBST(RC_TYPE) +AC_SUBST(RC_INCLUDE) +AC_SUBST(RC_DEFINE) +AC_SUBST(RC_DEFINES) +AC_SUBST(RES) + +AC_OUTPUT(Makefile tkConfig.sh wish.exe.manifest) dnl Local Variables: dnl mode: autoconf; diff --git a/win/makefile.bc b/win/makefile.bc index 12fd5b8..8738da9 100644 --- a/win/makefile.bc +++ b/win/makefile.bc @@ -161,6 +161,7 @@ TKOBJS = \ $(TMPDIR)\tkAtom.obj \ $(TMPDIR)\tkBind.obj \ $(TMPDIR)\tkBitmap.obj \ + $(TMPDIR)\tkBusy.obj \ $(TMPDIR)\tkButton.obj \ $(TMPDIR)\tkCanvArc.obj \ $(TMPDIR)\tkCanvBmap.obj \ @@ -194,6 +195,7 @@ TKOBJS = \ $(TMPDIR)\tkImgGIF.obj \ $(TMPDIR)\tkImgPPM.obj \ $(TMPDIR)\tkImgPhoto.obj \ + $(TMPDIR)\tkImgPhInstance.obj \ $(TMPDIR)\tkImgUtil.obj \ $(TMPDIR)\tkListbox.obj \ $(TMPDIR)\tkMacWinMenu.obj \ @@ -225,7 +227,6 @@ TKOBJS = \ $(TMPDIR)\tkUtil.obj \ $(TMPDIR)\tkVisual.obj \ $(TMPDIR)\tkStubInit.obj \ - $(TMPDIR)\tkStubLib.obj \ $(TMPDIR)\tkWindow.obj # Maintenance hint: Please have multiple members of TKSTUBOBJS be separated diff --git a/win/makefile.vc b/win/makefile.vc index 89dbe30..14dc2d0 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -1,15 +1,16 @@ -#------------------------------------------------------------------------------ +#------------------------------------------------------------- -*- makefile -*- # makefile.vc -- # # Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# +# # Copyright (c) 1995-1996 Sun Microsystems, Inc. # Copyright (c) 1998-2000 Ajuba Solutions. # Copyright (c) 2001-2005 ActiveState Corporation. # Copyright (c) 2001-2004 David Gravereaux. +# Copyright (c) 2003-2008 Pat Thoyts. #------------------------------------------------------------------------------ # Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR) @@ -85,7 +86,9 @@ the build instructions. # 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). +# thrdalloc = Use the thread allocator (shared global free pool) +# This is the default on threaded builds. +# tclalloc = Use the old non-thread allocator # 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 @@ -111,7 +114,7 @@ the build instructions. # Sets special macros for checking compatability. # # nodep = Turns off compatability macros to ensure Tk isn't -# being built with deprecated functions. +# being built with deprecated functions. # fullwarn = Builds with full compiler and link warnings enabled. # Very verbose. # @@ -124,7 +127,7 @@ the build instructions. # TMP_DIR=<path> # OUT_DIR=<path> # Hooks to allow the intermediate and output directories to be -# changed. $(OUT_DIR) is assumed to be +# changed. $(OUT_DIR) is assumed to be # $(BINROOT)\(Release|Debug) based on if symbols are requested. # $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default. # @@ -232,6 +235,7 @@ WISHOBJS = \ !if $(TCL_USE_STATIC_PACKAGES) $(TCLDDELIB) \ $(TCLREGLIB) \ + $(TCLSTUBLIB) \ !endif $(TMP_DIR)\wish.res @@ -284,6 +288,7 @@ TKOBJS = \ $(TMP_DIR)\tkAtom.obj \ $(TMP_DIR)\tkBind.obj \ $(TMP_DIR)\tkBitmap.obj \ + $(TMP_DIR)\tkBusy.obj \ $(TMP_DIR)\tkButton.obj \ $(TMP_DIR)\tkCanvArc.obj \ $(TMP_DIR)\tkCanvBmap.obj \ @@ -315,12 +320,15 @@ TKOBJS = \ $(TMP_DIR)\tkImage.obj \ $(TMP_DIR)\tkImgBmap.obj \ $(TMP_DIR)\tkImgGIF.obj \ + $(TMP_DIR)\tkImgPNG.obj \ $(TMP_DIR)\tkImgPPM.obj \ $(TMP_DIR)\tkImgPhoto.obj \ + $(TMP_DIR)\tkImgPhInstance.obj \ $(TMP_DIR)\tkImgUtil.obj \ $(TMP_DIR)\tkListbox.obj \ $(TMP_DIR)\tkMacWinMenu.obj \ $(TMP_DIR)\tkMain.obj \ + $(TMP_DIR)\tkMain2.obj \ $(TMP_DIR)\tkMenu.obj \ $(TMP_DIR)\tkMenubutton.obj \ $(TMP_DIR)\tkMenuDraw.obj \ @@ -350,7 +358,6 @@ TKOBJS = \ $(TMP_DIR)\tkUtil.obj \ $(TMP_DIR)\tkVisual.obj \ $(TMP_DIR)\tkStubInit.obj \ - $(TMP_DIR)\tkStubLib.obj \ $(TMP_DIR)\tkWindow.obj \ $(TTK_OBJS) \ !if !$(STATIC_BUILD) @@ -418,7 +425,7 @@ CONFIG_DEFS =-DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 \ -DTTK_SQUARE_WIDGET=1 \ !endif -TK_DEFINES =-DBUILD_ttk $(OPTDEFINES) $(CONFIG_DEFS) +TK_DEFINES =-DBUILD_ttk $(OPTDEFINES) $(CONFIG_DEFS) -Dinline=__inline #--------------------------------------------------------------------- # Compile flags @@ -433,7 +440,7 @@ cdebug = $(OPTIMIZATIONS) cdebug = !endif !if $(SYMBOLS) -cdebug = $(cdebug) -Zi +cdebug = $(cdebug) -Zi !endif !else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" ### Warnings are too many, can't support warnings into errors. @@ -461,11 +468,15 @@ crt = -MT !endif BASE_CFLAGS = $(cdebug) $(cflags) $(crt) $(TK_INCLUDES) -TK_CFLAGS = $(BASE_CFLAGS) $(TK_DEFINES) -DUSE_TCL_STUBS +TK_CFLAGS = $(BASE_CFLAGS) $(TK_DEFINES) CON_CFLAGS = $(cdebug) $(cflags) $(crt) -DCONSOLE WISH_CFLAGS = $(BASE_CFLAGS) $(TK_DEFINES) -STUB_CFLAGS = $(cflags) $(cdebug) $(TK_DEFINES) +### Stubs files should not be compiled with -GL +STUB_CFLAGS = $(cflags) $(cdebug:-GL=) $(TK_DEFINES) +!if !$(STATIC_BUILD) +TK_CFLAGS = $(TK_CFLAGS) -DUSE_TCL_STUBS +!endif #--------------------------------------------------------------------- # Link flags @@ -475,6 +486,9 @@ STUB_CFLAGS = $(cflags) $(cdebug) $(TK_DEFINES) ldebug = -debug -debugtype:cv !else ldebug = -release -opt:ref -opt:icf,3 +!if $(SYMBOLS) +ldebug = $(ldebug) -debug -debugtype:cv +!endif !endif ### Declarations common to all linker options @@ -500,7 +514,12 @@ dlllflags = $(lflags) -dll conlflags = $(lflags) -subsystem:console guilflags = $(lflags) -subsystem:windows -baselibs = kernel32.lib user32.lib +tcllibs = $(TCLIMPLIB) +!if !$(STATIC_BUILD) +tcllibs = $(TCLSTUBLIB) $(tcllibs) +!endif + +baselibs = netapi32.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib # Avoid 'unresolved external symbol __security_cookie' errors. # c.f. http://support.microsoft.com/?id=894573 !if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" @@ -544,9 +563,9 @@ test-classic: setup $(TKTEST) $(TKLIB) $(CAT32) @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) !endif !if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE" - $(TKTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) | $(CAT32) + $(DEBUGGER) $(TKTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) | $(CAT32) !else - $(TKTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) | $(CAT32) + $(DEBUGGER) $(TKTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) | $(CAT32) !endif test-ttk: setup $(TKTEST) $(TKLIB) $(CAT32) @@ -559,9 +578,9 @@ test-ttk: setup $(TKTEST) $(TKLIB) $(CAT32) @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) !endif !if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE" - $(TKTEST) "$(ROOT)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32) + $(DEBUGGER) $(TKTEST) "$(ROOT)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32) !else - $(TKTEST) "$(ROOT)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32) + $(DEBUGGER) $(TKTEST) "$(ROOT)/tests/ttk/all.tcl" $(TESTFLAGS) | $(CAT32) !endif runtest: setup $(TKTEST) $(TKLIB) $(CAT32) @@ -573,7 +592,7 @@ runtest: setup $(TKTEST) $(TKLIB) $(CAT32) !else @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) !endif - $(TKTEST) + $(DEBUGGER) $(TKTEST) rundemo: setup $(TKTEST) $(TKLIB) $(CAT32) @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) @@ -595,21 +614,10 @@ shell: setup $(WISH) !else @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) !endif - $(WISH) << + $(DEBUGGER) $(WISH) << console show << -dbgshell: setup $(WISH) - @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) - @set TK_LIBRARY=$(TK_LIBRARY:\=/) - @set TCLLIBPATH= -!if $(TCLINSTALL) - @set PATH=$(_TCLDIR)\bin;$(PATH) -!else - @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) -!endif - windbg $(WISH) - setup: @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) @@ -637,18 +645,18 @@ $(TKSTUBLIB): $(TKSTUBOBJS) $(lib32) -nologo -out:$@ $** -$(WISH): $(WISHOBJS) $(TKIMPLIB) - $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(TCLIMPLIB) $** +$(WISH): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB) + $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(tcllibs) $** $(_VC_MANIFEST_EMBED_EXE) -$(WISHC): $(WISHOBJS) $(TKIMPLIB) - $(link32) $(conlflags) -stack:2300000 -out:$@ $(guilibs) $(TCLIMPLIB) $** +$(WISHC): $(WISHOBJS) $(TKSTUBLIB) $(TKIMPLIB) + $(link32) $(conlflags) -stack:2300000 -out:$@ $(guilibs) $(tcllibs) $** $(_VC_MANIFEST_EMBED_EXE) -$(TKTEST): $(TKTESTOBJS) $(TKIMPLIB) - $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(TCLIMPLIB) $** +$(TKTEST): $(TKTESTOBJS) $(TKSTUBLIB) $(TKIMPLIB) + $(link32) $(guilflags) -stack:2300000 -out:$@ $(guilibs) $(tcllibs) $** $(_VC_MANIFEST_EMBED_EXE) @@ -788,6 +796,9 @@ $(TMP_DIR)\winMain.obj: $(WINDIR)\winMain.c -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ -Fo$@ $? +$(TMP_DIR)\tkMain2.obj: $(GENERICDIR)\tkMain.c + $(cc32) -DBUILD_tk $(TK_CFLAGS) -DTK_ASCII_MAIN -Fo$@ $? + # The following objects are part of the stub library and should not # be built as DLL objects but none of the symbols should be exported # and no reference made to a C runtime. @@ -897,7 +908,7 @@ install-binaries: !if !$(STATIC_BUILD) @echo creating package index @type << > $(OUT_DIR)\pkgIndex.tcl -if {[catch {package present Tcl 8.5.0}]} { return } +if {[package vcompare [package provide Tcl] $(TCL_PATCH_LEVEL)] != 0} { return } package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin $(TKLIBNAME)] Tk] << @$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)\" diff --git a/win/nmakehlp.c b/win/nmakehlp.c index f1b5f34..4803b43 100644 --- a/win/nmakehlp.c +++ b/win/nmakehlp.c @@ -589,7 +589,10 @@ typedef struct 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_insert( + list_item_t **listPtrPtr, + const char *key, + const char *value) { list_item_t *itemPtr = malloc(sizeof(list_item_t)); if (itemPtr) { @@ -606,7 +609,8 @@ list_insert(list_item_t **listPtrPtr, const char *key, const char *value) } static void -list_free(list_item_t **listPtrPtr) +list_free( + list_item_t **listPtrPtr) { list_item_t *tmpPtr, *listPtr = *listPtrPtr; while (listPtr) { diff --git a/win/rc/tk.ico b/win/rc/tk.ico Binary files differindex 5fdb9a7..e254318 100644 --- a/win/rc/tk.ico +++ b/win/rc/tk.ico diff --git a/win/rc/wish.ico b/win/rc/wish.ico Binary files differindex 1825751..05cad66 100644 --- a/win/rc/wish.ico +++ b/win/rc/wish.ico diff --git a/win/rules.vc b/win/rules.vc index 20c967a..f2ee135 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -6,7 +6,7 @@ # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# +# # Copyright (c) 2001-2003 David Gravereaux. # Copyright (c) 2003-2007 Patrick Thoyts #------------------------------------------------------------------------------ @@ -159,7 +159,7 @@ DEBUGFLAGS = $(DEBUGFLAGS) -RTC1 DEBUGFLAGS = $(DEBUGFLAGS) -GZ !endif -COMPILERFLAGS =-W3 +COMPILERFLAGS =-W3 -DUNICODE -D_UNICODE # In v13 -GL and -YX are incompatible. !if [nmakehlp -c -YX] @@ -213,14 +213,15 @@ LINKERFLAGS =-ltcg !if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"] STATIC_BUILD = 0 -TCL_THREADS = 0 +TCL_THREADS = 1 DEBUG = 0 SYMBOLS = 0 PROFILE = 0 +PGO = 0 MSVCRT = 0 LOIMPACT = 0 TCL_USE_STATIC_PACKAGES = 0 -USE_THREAD_ALLOC = 0 +USE_THREAD_ALLOC = 1 UNCHECKED = 0 !else !if [nmakehlp -f $(OPTS) "static"] @@ -241,11 +242,12 @@ TCL_USE_STATIC_PACKAGES = 1 !else TCL_USE_STATIC_PACKAGES = 0 !endif -!if [nmakehlp -f $(OPTS) "threads"] +!if [nmakehlp -f $(OPTS) "nothreads"] +TCL_THREADS = 0 +!else !message *** Doing threads TCL_THREADS = 1 -!else -TCL_THREADS = 0 +USE_THREAD_ALLOC= 1 !endif !if [nmakehlp -f $(OPTS) "symbols"] !message *** Doing symbols @@ -265,6 +267,15 @@ PROFILE = 1 !else PROFILE = 0 !endif +!if [nmakehlp -f $(OPTS) "pgi"] +!message *** Doing profile guided optimization instrumentation +PGO = 1 +!elseif [nmakehlp -f $(OPTS) "pgo"] +!message *** Doing profile guided optimization +PGO = 2 +!else +PGO = 0 +!endif !if [nmakehlp -f $(OPTS) "loimpact"] !message *** Doing loimpact LOIMPACT = 1 @@ -274,7 +285,9 @@ LOIMPACT = 0 !if [nmakehlp -f $(OPTS) "thrdalloc"] !message *** Doing thrdalloc USE_THREAD_ALLOC = 1 -!else +!endif +!if [nmakehlp -f $(OPTS) "tclalloc"] +!message *** Doing thrdalloc USE_THREAD_ALLOC = 0 !endif !if [nmakehlp -f $(OPTS) "unchecked"] @@ -417,6 +430,24 @@ WARNINGS = $(WARNINGS) -Wp64 !endif !endif +!if $(PGO) > 1 +!if [nmakehlp -l -ltcg:pgoptimize] +LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize +!else +MSG=^ +This compiler does not support profile guided optimization. +!error $(MSG) +!endif +!elseif $(PGO) > 0 +!if [nmakehlp -l -ltcg:pginstrument] +LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument +!else +MSG=^ +This compiler does not support profile guided optimization. +!error $(MSG) +!endif +!endif + #---------------------------------------------------------- # Set our defines now armed with our options. #---------------------------------------------------------- @@ -566,7 +597,7 @@ TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe" 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" +TCLREGLIB = "$(_TCLDIR)\lib\tclreg13$(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 @@ -579,7 +610,7 @@ TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe" 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)\tclreg12$(SUFX:t=).lib" +TCLREGLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib" TCLDDELIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde13$(SUFX:t=).lib" COFFBASE = "$(_TCLDIR)\win\coffbase.txt" TCLTOOLSDIR = $(_TCLDIR)\tools @@ -20,15 +20,15 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [ AC_MSG_CHECKING([the location of tclConfig.sh]) - 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 + if test -d ../../tcl8.6$1/win; then + TCL_BIN_DIR_DEFAULT=../../tcl8.6$1/win + elif test -d ../../tcl8.6/win; then + TCL_BIN_DIR_DEFAULT=../../tcl8.6/win else TCL_BIN_DIR_DEFAULT=../../tcl/win fi - AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.5 binaries from DIR], + AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.6 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) @@ -63,15 +63,15 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [ AC_DEFUN([SC_PATH_TKCONFIG], [ AC_MSG_CHECKING([the location of tkConfig.sh]) - 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 + if test -d ../../tk8.6$1/win; then + TK_BIN_DIR_DEFAULT=../../tk8.6$1/win + elif test -d ../../tk8.6/win; then + TK_BIN_DIR_DEFAULT=../../tk8.6/win else TK_BIN_DIR_DEFAULT=../../tk/win fi - AC_ARG_WITH(tk, [ --with-tk=DIR use Tk 8.5 binaries from DIR], + AC_ARG_WITH(tk, [ --with-tk=DIR use Tk 8.6 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) @@ -251,7 +251,7 @@ AC_DEFUN([SC_ENABLE_SHARED], [ AC_DEFUN([SC_ENABLE_THREADS], [ AC_MSG_CHECKING(for building with threads) AC_ARG_ENABLE(threads, [ --enable-threads build with threads], - [tcl_ok=$enableval], [tcl_ok=no]) + [tcl_ok=$enableval], [tcl_ok=yes]) if test "$tcl_ok" = "yes"; then AC_MSG_RESULT(yes) @@ -262,7 +262,7 @@ AC_DEFUN([SC_ENABLE_THREADS], [ AC_DEFINE(USE_THREAD_ALLOC) else TCL_THREADS=0 - AC_MSG_RESULT([no (default)]) + AC_MSG_RESULT(no) fi AC_SUBST(TCL_THREADS) ]) @@ -405,6 +405,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ # Set some defaults (may get changed below) EXTRA_CFLAGS="" + AC_DEFINE(MODULE_SCOPE, [extern], [No need to mark inidividual symbols as hidden]) AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo) @@ -494,13 +495,31 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ if test "$ac_cv_win32" != "yes"; then AC_MSG_ERROR([${CC} cannot produce win32 executables.]) fi + + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain" + AC_CACHE_CHECK(for working -municode linker flag, + ac_cv_municode, + AC_TRY_LINK([ + #include <windows.h> + int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;} + ], + [], + ac_cv_municode=yes, + ac_cv_municode=no) + ) + CFLAGS=$hold_cflags + if test "$ac_cv_municode" = "yes" ; then + extra_ldflags="$extra_ldflags -municode" + else + extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS" + fi fi AC_MSG_CHECKING([compiler flags]) if test "${GCC}" = "yes" ; then SHLIB_LD="" - SHLIB_LD_LIBS="" - LIBS="-lws2_32" + SHLIB_LD_LIBS='${LIBS}' + LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -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' @@ -514,16 +533,13 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ MAKE_EXE="\${CC} -o \[$]@" LIBPREFIX="lib" - extra_cflags="-pipe" - extra_ldflags="-pipe" + extra_ldflags="$extra_ldflags -pipe" + extra_cflags="$extra_cflags -pipe" if test "${SHARED_BUILD}" = "0" ; then # static AC_MSG_RESULT([using static flags]) runtime= - MAKE_DLL="echo " - LIBSUFFIX="s\${DBGX}.a" - LIBFLAGSUFFIX="s\${DBGX}" LIBRARIES="\${STATIC_LIBRARIES}" EXESUFFIX="s\${DBGX}.exe" else @@ -537,30 +553,30 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ fi runtime= - # Link with gcc since ld does not link to default libs like - # -luser32 and -lmsvcrt by default. Make sure CFLAGS is - # included so -mno-cygwin passed the correct libs to the linker. - SHLIB_LD='${CC} -shared ${CFLAGS}' - SHLIB_LD_LIBS='${LIBS}' # Add SHLIB_LD_LIBS to the Make rule, not here. - MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \[$]@ ${extra_ldflags} \ - -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\[$]@)" - LIBSUFFIX="\${DBGX}.a" - LIBFLAGSUFFIX="\${DBGX}" EXESUFFIX="\${DBGX}.exe" LIBRARIES="\${SHARED_LIBRARIES}" fi + # Link with gcc since ld does not link to default libs like + # -luser32 and -lmsvcrt by default. Make sure CFLAGS is + # included so -mno-cygwin passed the correct libs to the linker. + SHLIB_LD='${CC} -shared ${CFLAGS}' + SHLIB_LD_LIBS='${LIBS}' + MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \[$]@ ${extra_ldflags} \ + -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\[$]@)" # DLLSUFFIX is separate because it is the building block for # users of tclConfig.sh that may build shared or static. DLLSUFFIX="\${DBGX}.dll" + LIBSUFFIX="\${DBGX}.a" + LIBFLAGSUFFIX="\${DBGX}" SHLIB_SUFFIX=.dll EXTRA_CFLAGS="${extra_cflags}" CFLAGS_DEBUG=-g CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" - CFLAGS_WARNING="-Wall" + CFLAGS_WARNING="-Wall -Wdeclaration-after-statement" LDFLAGS_DEBUG= LDFLAGS_OPTIMIZE= @@ -615,27 +631,22 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ # static AC_MSG_RESULT([using static flags]) runtime=-MT - MAKE_DLL="echo " - LIBSUFFIX="s\${DBGX}.lib" - LIBFLAGSUFFIX="s\${DBGX}" LIBRARIES="\${STATIC_LIBRARIES}" EXESUFFIX="s\${DBGX}.exe" - SHLIB_LD_LIBS="" else # dynamic AC_MSG_RESULT([using shared flags]) runtime=-MD # Add SHLIB_LD_LIBS to the Make rule, not here. - MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\[$]@" - LIBSUFFIX="\${DBGX}.lib" - LIBFLAGSUFFIX="\${DBGX}" - EXESUFFIX="\${DBGX}.exe" LIBRARIES="\${SHARED_LIBRARIES}" - SHLIB_LD_LIBS='${LIBS}' + EXESUFFIX="\${DBGX}.exe" fi + MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\[$]@" # DLLSUFFIX is separate because it is the building block for # users of tclConfig.sh that may build shared or static. DLLSUFFIX="\${DBGX}.dll" + LIBSUFFIX="\${DBGX}.lib" + LIBFLAGSUFFIX="\${DBGX}" # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. @@ -665,7 +676,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ fi fi - LIBS="user32.lib advapi32.lib ws2_32.lib" + LIBS="netapi32.lib kernel32.lib 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 @@ -790,6 +801,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ fi SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}" + SHLIB_LD_LIBS='${LIBS}' # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" RC_OUT=-fo @@ -949,13 +961,13 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ #------------------------------------------------------------------------ AC_DEFUN([SC_WITH_TCL], [ - if test -d ../../tcl8.5$1/win; then - TCL_BIN_DEFAULT=../../tcl8.5$1/win + if test -d ../../tcl8.6$1/win; then + TCL_BIN_DEFAULT=../../tcl8.6$1/win else - TCL_BIN_DEFAULT=../../tcl8.5/win + TCL_BIN_DEFAULT=../../tcl8.6/win fi - AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.5 binaries from DIR], + AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.6 binaries from DIR], TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DEFAULT; pwd`) if test ! -d $TCL_BIN_DIR; then AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist) diff --git a/win/tkWin.h b/win/tkWin.h index 00d3486..adb943b 100644 --- a/win/tkWin.h +++ b/win/tkWin.h @@ -18,7 +18,7 @@ * 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 + * WINVER = 0x0500 means Windows 2000 and above */ #ifndef WINVER @@ -36,11 +36,6 @@ #include <windows.h> #undef WIN32_LEAN_AND_MEAN -#ifdef BUILD_tk -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLEXPORT -#endif - /* * The following messages are used to communicate between a Tk toplevel * and its container window. A Tk container may not be able to provide @@ -83,7 +78,4 @@ #include "tkPlatDecls.h" -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLIMPORT - #endif /* _TKWIN */ diff --git a/win/tkWin32Dll.c b/win/tkWin32Dll.c index efefe86..b733f78 100644 --- a/win/tkWin32Dll.c +++ b/win/tkWin32Dll.c @@ -133,11 +133,11 @@ DllMain( "leaq %[registration], %%rdx" "\n\t" "movq %%gs:0, %%rax" "\n\t" - "movq %%rax, 0x0(%%edx)" "\n\t" /* link */ + "movq %%rax, 0x0(%%rdx)" "\n\t" /* link */ "leaq 1f, %%rax" "\n\t" "movq %%rax, 0x8(%%rdx)" "\n\t" /* handler */ - "movq %%rbp, 0x10(%%rdx)" "\n\t" /* ebp */ - "movq %%rsp, 0x18(%%rdx)" "\n\t" /* esp */ + "movq %%rbp, 0x10(%%rdx)" "\n\t" /* rbp */ + "movq %%rsp, 0x18(%%rdx)" "\n\t" /* rsp */ "movl %[error], 0x20(%%rdx)" "\n\t" /* status */ /* diff --git a/win/tkWin3d.c b/win/tkWin3d.c index df6aa95..d3c443d 100644 --- a/win/tkWin3d.c +++ b/win/tkWin3d.c @@ -43,7 +43,7 @@ typedef struct { TkBorder * TkpGetBorder(void) { - WinBorder *borderPtr = (WinBorder *) ckalloc(sizeof(WinBorder)); + WinBorder *borderPtr = ckalloc(sizeof(WinBorder)); borderPtr->light2ColorPtr = NULL; borderPtr->dark2ColorPtr = NULL; diff --git a/win/tkWinButton.c b/win/tkWinButton.c index af1058d..ca6d48e 100644 --- a/win/tkWinButton.c +++ b/win/tkWinButton.c @@ -86,11 +86,11 @@ static void InitBoxes(void); * The class procedure table for the button widgets. */ -Tk_ClassProcs tkpButtonProcs = { +const Tk_ClassProcs tkpButtonProcs = { sizeof(Tk_ClassProcs), /* size */ TkButtonWorldChanged, /* worldChangedProc */ CreateProc, /* createProc */ - NULL + NULL /* modalProc */ }; @@ -131,7 +131,7 @@ InitBoxes(void) ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - hrsrc = FindResource(module, "buttons", RT_BITMAP); + hrsrc = FindResource(module, TEXT("buttons"), RT_BITMAP); if (hrsrc == NULL) { Tcl_Panic("FindResource() failed for buttons bitmap resource, " "resources in tk_base.rc must be linked into Tk dll or static executable"); @@ -148,7 +148,7 @@ InitBoxes(void) && !(tsdPtr->boxesPtr->biHeight % 2)) { size = tsdPtr->boxesPtr->biSize + (1 << tsdPtr->boxesPtr->biBitCount) * sizeof(RGBQUAD) + tsdPtr->boxesPtr->biSizeImage; - newBitmap = (LPBITMAPINFOHEADER) ckalloc(size); + newBitmap = ckalloc(size); memcpy(newBitmap, tsdPtr->boxesPtr, size); tsdPtr->boxesPtr = newBitmap; tsdPtr->boxWidth = tsdPtr->boxesPtr->biWidth / 4; @@ -181,15 +181,12 @@ InitBoxes(void) */ void -TkpButtonSetDefaults( - Tk_OptionSpec *specPtr) /* Points to an array of option specs, - * terminated by one with type - * TK_OPTION_END. */ +TkpButtonSetDefaults() { int width = GetSystemMetrics(SM_CXEDGE); - if (width > 0) { - sprintf(tkDefButtonBorderWidth, "%d", width); - } + if (width > 0) { + sprintf(tkDefButtonBorderWidth, "%d", width); + } } /* @@ -214,7 +211,7 @@ TkpCreateButton( { WinButton *butPtr; - butPtr = (WinButton *)ckalloc(sizeof(WinButton)); + butPtr = ckalloc(sizeof(WinButton)); butPtr->hwnd = NULL; return (TkButton *) butPtr; } @@ -244,15 +241,15 @@ CreateProc( { Window window; HWND parent; - char *class; + const TCHAR *class; WinButton *butPtr = (WinButton *)instanceData; parent = Tk_GetHWND(parentWin); if (butPtr->info.type == TYPE_LABEL) { - class = "STATIC"; + class = TEXT("STATIC"); butPtr->style = SS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; } else { - class = "BUTTON"; + class = TEXT("BUTTON"); butPtr->style = BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; } butPtr->hwnd = CreateWindow(class, NULL, butPtr->style, @@ -261,7 +258,7 @@ CreateProc( SetWindowPos(butPtr->hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); butPtr->oldProc = (WNDPROC)SetWindowLongPtr(butPtr->hwnd, GWLP_WNDPROC, - (INT_PTR) ButtonProc); + (LONG_PTR) ButtonProc); window = Tk_AttachHWND(tkwin, butPtr->hwnd); return window; @@ -291,7 +288,7 @@ TkpDestroyButton( HWND hwnd = winButPtr->hwnd; if (hwnd) { - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) winButPtr->oldProc); + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) winButPtr->oldProc); } } @@ -1277,7 +1274,7 @@ ButtonProc( if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) { Tcl_AddErrorInfo(interp, "\n (button invoke)"); - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, code); } Tcl_Release((ClientData)interp); } diff --git a/win/tkWinClipboard.c b/win/tkWinClipboard.c index 6007e56..cffb0ee 100644 --- a/win/tkWinClipboard.c +++ b/win/tkWinClipboard.c @@ -104,7 +104,7 @@ TkSelGetSelection( */ locale = LANGIDFROMLCID(*((int*)data)); - GetLocaleInfo(locale, LOCALE_IDEFAULTANSICODEPAGE, + GetLocaleInfoA(locale, LOCALE_IDEFAULTANSICODEPAGE, Tcl_DStringValue(&ds)+2, Tcl_DStringLength(&ds)-2); GlobalUnlock(handle); @@ -156,7 +156,7 @@ TkSelGetSelection( * Pass the data off to the selection procedure. */ - result = (*proc)(clientData, interp, Tcl_DStringValue(&ds)); + result = proc(clientData, interp, Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); CloseClipboard(); return result; @@ -273,7 +273,7 @@ TkWinClipboardRender( * Copy the data and change EOL characters. */ - buffer = rawText = ckalloc((unsigned)length + 1); + buffer = rawText = ckalloc(length + 1); if (targetPtr != NULL) { for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL; cbPtr = cbPtr->nextPtr) { @@ -293,7 +293,7 @@ TkWinClipboardRender( * encoding before placing it on the clipboard. */ - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { +#ifdef UNICODE Tcl_DStringInit(&ds); Tcl_UtfToUniCharDString(rawText, -1, &ds); ckfree(rawText); @@ -309,7 +309,7 @@ TkWinClipboardRender( GlobalUnlock(handle); Tcl_DStringFree(&ds); SetClipboardData(CF_UNICODETEXT, handle); - } else { +#else Tcl_UtfToExternalDString(NULL, rawText, -1, &ds); ckfree(rawText); handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, @@ -324,7 +324,7 @@ TkWinClipboardRender( GlobalUnlock(handle); Tcl_DStringFree(&ds); SetClipboardData(CF_TEXT, handle); - } +#endif } /* @@ -383,7 +383,7 @@ UpdateClipboard( * possible. */ - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { + if (TkWinGetPlatformId() != VER_PLATFORM_WIN32_WINDOWS) { SetClipboardData(CF_UNICODETEXT, NULL); } else { SetClipboardData(CF_TEXT, NULL); diff --git a/win/tkWinColor.c b/win/tkWinColor.c index f52f6ed..d93143d 100644 --- a/win/tkWinColor.c +++ b/win/tkWinColor.c @@ -31,11 +31,11 @@ typedef struct WinColor { */ typedef struct { - char *name; + const char *name; int index; } SystemColorEntry; -static SystemColorEntry sysColors[] = { +static const SystemColorEntry sysColors[] = { {"3dDarkShadow", COLOR_3DDKSHADOW}, {"3dLight", COLOR_3DLIGHT}, {"ActiveBorder", COLOR_ACTIVEBORDER}, @@ -61,15 +61,9 @@ static SystemColorEntry sysColors[] = { {"Scrollbar", COLOR_SCROLLBAR}, {"Window", COLOR_WINDOW}, {"WindowFrame", COLOR_WINDOWFRAME}, - {"WindowText", COLOR_WINDOWTEXT}, - {NULL, 0} + {"WindowText", COLOR_WINDOWTEXT} }; -typedef struct ThreadSpecificData { - int ncolors; -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - /* * Forward declarations for functions defined later in this file. */ @@ -102,37 +96,15 @@ FindSystemColor( int *indexPtr) /* Out parameter to store color index. */ { int l, u, r, i; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - /* - * Count the number of elements in the color array if we haven't done so - * yet. - */ - - if (tsdPtr->ncolors == 0) { - SystemColorEntry *ePtr; - int version; - - version = LOBYTE(LOWORD(GetVersion())); - for (ePtr = sysColors; ePtr->name != NULL; ePtr++) { - if (version < 4) { - if (ePtr->index == COLOR_3DDKSHADOW) { - ePtr->index = COLOR_BTNSHADOW; - } else if (ePtr->index == COLOR_3DLIGHT) { - ePtr->index = COLOR_BTNHIGHLIGHT; - } - } - tsdPtr->ncolors++; - } - } + int index; + int version = LOBYTE(LOWORD(GetVersion())); /* * Perform a binary search on the sorted array of colors. */ l = 0; - u = tsdPtr->ncolors - 1; + u = (sizeof(sysColors) / sizeof(sysColors[0])) - 1; while (l <= u) { i = (l + u) / 2; r = strcasecmp(name, sysColors[i].name); @@ -148,8 +120,16 @@ FindSystemColor( return 0; } - *indexPtr = sysColors[i].index; - colorPtr->pixel = GetSysColor(sysColors[i].index); + index = sysColors[i].index; + if (version < 4) { + if (index == COLOR_3DDKSHADOW) { + index = COLOR_BTNSHADOW; + } else if (index == COLOR_3DLIGHT) { + index = COLOR_BTNHIGHLIGHT; + } + } + *indexPtr = index; + colorPtr->pixel = GetSysColor(index); /* * x257 is (value<<8 + value) to get the properly bit shifted and padded @@ -202,7 +182,7 @@ TkpGetColor( && FindSystemColor(name+6, &color, &index)) || TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name, &color)) { - winColPtr = (WinColor *) ckalloc(sizeof(WinColor)); + winColPtr = ckalloc(sizeof(WinColor)); winColPtr->info.color = color; winColPtr->index = index; @@ -240,7 +220,7 @@ TkpGetColorByValue( XColor *colorPtr) /* Red, green, and blue fields indicate * desired color. */ { - WinColor *tkColPtr = (WinColor *) ckalloc(sizeof(WinColor)); + WinColor *tkColPtr = ckalloc(sizeof(WinColor)); tkColPtr->info.color.red = colorPtr->red; tkColPtr->info.color.green = colorPtr->green; @@ -375,7 +355,7 @@ XAllocColor( color->blue = closeEntry.peBlue * 257; entry = closeEntry; if (index >= cmap->size) { - OutputDebugString("XAllocColor: Colormap is bigger than we thought"); + OutputDebugStringA("XAllocColor: Colormap is bigger than we thought"); } } else { cmap->size++; @@ -454,7 +434,7 @@ XFreeColors( for (i = 0; i < npixels; i++) { entryPtr = Tcl_FindHashEntry(&cmap->refCounts, INT2PTR(pixels[i])); if (!entryPtr) { - Tcl_Panic("Tried to free a color that isn't allocated."); + Tcl_Panic("Tried to free a color that isn't allocated"); } refCount = PTR2INT(Tcl_GetHashValue(entryPtr)) - 1; if (refCount == 0) { @@ -463,14 +443,13 @@ XFreeColors( 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 = ckalloc(sizeof(PALETTEENTRY) * count); GetPaletteEntries(cmap->palette, index+1, count, entries); SetPaletteEntries(cmap->palette, index, count, entries); - ckfree((char *) entries); + ckfree(entries); cmap->size--; } else { - Tcl_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 { @@ -523,7 +502,7 @@ XCreateColormap( logPalettePtr->palNumEntries = GetPaletteEntries(sysPal, 0, 256, logPalettePtr->palPalEntry); - cmap = (TkWinColormap *) ckalloc(sizeof(TkWinColormap)); + cmap = ckalloc(sizeof(TkWinColormap)); cmap->size = logPalettePtr->palNumEntries; cmap->stale = 0; cmap->palette = CreatePalette(logPalettePtr); @@ -568,10 +547,10 @@ XFreeColormap( TkWinColormap *cmap = (TkWinColormap *) colormap; if (!DeleteObject(cmap->palette)) { - Tcl_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); + ckfree(cmap); } /* diff --git a/win/tkWinConfig.c b/win/tkWinConfig.c index 422e399..aeb9405 100644 --- a/win/tkWinConfig.c +++ b/win/tkWinConfig.c @@ -35,8 +35,8 @@ 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 *dbName, /* The option database name. */ + const char *className) /* The name of the option class. */ { Tcl_Obj *valueObjPtr; Tk_Uid classUid; diff --git a/win/tkWinCursor.c b/win/tkWinCursor.c index dee3419..8366db3 100644 --- a/win/tkWinCursor.c +++ b/win/tkWinCursor.c @@ -40,7 +40,7 @@ typedef struct { */ static struct CursorName { - char *name; + const char *name; LPCTSTR id; } cursorNames[] = { {"starting", IDC_APPSTARTING}, @@ -73,7 +73,7 @@ static struct CursorName { #define TK_DEFAULT_CURSOR IDC_ARROW - + /* *---------------------------------------------------------------------- * @@ -100,7 +100,7 @@ TkGetCursorByName( struct CursorName *namePtr; TkWinCursor *cursorPtr; int argc; - CONST char **argv = NULL; + const char **argv = NULL; /* * All cursor names are valid lists of one element (for @@ -114,7 +114,7 @@ TkGetCursorByName( goto badCursorSpec; } - cursorPtr = (TkWinCursor *) ckalloc(sizeof(TkWinCursor)); + cursorPtr = ckalloc(sizeof(TkWinCursor)); cursorPtr->info.cursor = (Tk_Cursor) cursorPtr; cursorPtr->winCursor = NULL; cursorPtr->system = 0; @@ -133,11 +133,11 @@ TkGetCursorByName( if (Tcl_IsSafe(interp)) { Tcl_AppendResult(interp, "can't get cursor from a file in", " a safe interpreter", NULL); - ckfree((char *) argv); - ckfree((char *) cursorPtr); + ckfree(argv); + ckfree(cursorPtr); return NULL; } - cursorPtr->winCursor = LoadCursorFromFile(&(argv[0][1])); + cursorPtr->winCursor = LoadCursorFromFileA(&(argv[0][1])); } else { /* * Check for the cursor in the system cursor set. @@ -156,24 +156,23 @@ TkGetCursorByName( * one of our application resources. */ - cursorPtr->winCursor = LoadCursor(Tk_GetHINSTANCE(), argv[0]); + cursorPtr->winCursor = LoadCursorA(Tk_GetHINSTANCE(), argv[0]); } else { cursorPtr->system = 1; } } if (cursorPtr->winCursor == NULL) { - ckfree((char *) cursorPtr); + ckfree(cursorPtr); badCursorSpec: - ckfree((char *) argv); + ckfree(argv); Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", NULL); return NULL; - } else { - ckfree((char *) argv); - return (TkCursor *) cursorPtr; } + ckfree(argv); + return (TkCursor *) cursorPtr; } - + /* *---------------------------------------------------------------------- * @@ -193,8 +192,8 @@ TkGetCursorByName( TkCursor * TkCreateCursorFromData( Tk_Window tkwin, /* Window in which cursor will be used. */ - CONST char *source, /* Bitmap data for cursor shape. */ - CONST char *mask, /* Bitmap data for cursor mask. */ + 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. */ @@ -202,7 +201,7 @@ TkCreateCursorFromData( { return NULL; } - + /* *---------------------------------------------------------------------- * @@ -226,7 +225,7 @@ TkpFreeCursor( { /* TkWinCursor *winCursorPtr = (TkWinCursor *) cursorPtr; */ } - + /* *---------------------------------------------------------------------- * @@ -261,7 +260,7 @@ TkpSetCursor( SetCursor(hcursor); } } - + /* * Local Variables: * mode: c diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h index a1a76c7..11c3e6d 100644 --- a/win/tkWinDefault.h +++ b/win/tkWinDefault.h @@ -68,7 +68,7 @@ #define DEF_BUTTON_HIGHLIGHT HIGHLIGHT #define DEF_LABEL_HIGHLIGHT_WIDTH "0" #define DEF_BUTTON_HIGHLIGHT_WIDTH "1" -#define DEF_BUTTON_IMAGE (char *) NULL +#define DEF_BUTTON_IMAGE ((char *) NULL) #define DEF_BUTTON_INDICATOR "1" #define DEF_BUTTON_JUSTIFY "center" #define DEF_BUTTON_OFF_VALUE "0" @@ -84,10 +84,10 @@ #define DEF_BUTTON_REPEAT_INTERVAL "0" #define DEF_BUTTON_SELECT_COLOR INDICATOR #define DEF_BUTTON_SELECT_MONO BLACK -#define DEF_BUTTON_SELECT_IMAGE (char *) NULL +#define DEF_BUTTON_SELECT_IMAGE ((char *) NULL) #define DEF_BUTTON_STATE "normal" #define DEF_LABEL_TAKE_FOCUS "0" -#define DEF_BUTTON_TAKE_FOCUS (char *) NULL +#define DEF_BUTTON_TAKE_FOCUS ((char *) NULL) #define DEF_BUTTON_TEXT "" #define DEF_BUTTON_TEXT_VARIABLE "" #define DEF_BUTTON_TRISTATE_VALUE "" @@ -126,7 +126,7 @@ #define DEF_CANVAS_SELECT_BD_MONO "0" #define DEF_CANVAS_SELECT_FG_COLOR SELECT_FG #define DEF_CANVAS_SELECT_FG_MONO WHITE -#define DEF_CANVAS_TAKE_FOCUS (char *) NULL +#define DEF_CANVAS_TAKE_FOCUS ((char *) NULL) #define DEF_CANVAS_WIDTH "10c" #define DEF_CANVAS_X_SCROLL_CMD "" #define DEF_CANVAS_X_SCROLL_INCREMENT "0" @@ -167,9 +167,9 @@ #define DEF_ENTRY_SELECT_BD_MONO "0" #define DEF_ENTRY_SELECT_FG_COLOR SELECT_FG #define DEF_ENTRY_SELECT_FG_MONO WHITE -#define DEF_ENTRY_SHOW (char *) NULL +#define DEF_ENTRY_SHOW ((char *) NULL) #define DEF_ENTRY_STATE "normal" -#define DEF_ENTRY_TAKE_FOCUS (char *) NULL +#define DEF_ENTRY_TAKE_FOCUS ((char *) NULL) #define DEF_ENTRY_TEXT_VARIABLE "" #define DEF_ENTRY_WIDTH "20" @@ -235,36 +235,36 @@ #define DEF_LISTBOX_SELECT_MODE "browse" #define DEF_LISTBOX_SET_GRID "0" #define DEF_LISTBOX_STATE "normal" -#define DEF_LISTBOX_TAKE_FOCUS (char *) NULL +#define DEF_LISTBOX_TAKE_FOCUS ((char *) NULL) #define DEF_LISTBOX_WIDTH "20" /* * Defaults for individual entries of menus: */ -#define DEF_MENU_ENTRY_ACTIVE_BG (char *) NULL -#define DEF_MENU_ENTRY_ACTIVE_FG (char *) NULL -#define DEF_MENU_ENTRY_ACCELERATOR (char *) NULL -#define DEF_MENU_ENTRY_BG (char *) NULL +#define DEF_MENU_ENTRY_ACTIVE_BG ((char *) NULL) +#define DEF_MENU_ENTRY_ACTIVE_FG ((char *) NULL) +#define DEF_MENU_ENTRY_ACCELERATOR ((char *) NULL) +#define DEF_MENU_ENTRY_BG ((char *) NULL) #define DEF_MENU_ENTRY_BITMAP None #define DEF_MENU_ENTRY_COLUMN_BREAK "0" -#define DEF_MENU_ENTRY_COMMAND (char *) NULL +#define DEF_MENU_ENTRY_COMMAND ((char *) NULL) #define DEF_MENU_ENTRY_COMPOUND "none" -#define DEF_MENU_ENTRY_FG (char *) NULL -#define DEF_MENU_ENTRY_FONT (char *) NULL +#define DEF_MENU_ENTRY_FG ((char *) NULL) +#define DEF_MENU_ENTRY_FONT ((char *) NULL) #define DEF_MENU_ENTRY_HIDE_MARGIN "0" -#define DEF_MENU_ENTRY_IMAGE (char *) NULL +#define DEF_MENU_ENTRY_IMAGE ((char *) NULL) #define DEF_MENU_ENTRY_INDICATOR "1" -#define DEF_MENU_ENTRY_LABEL (char *) NULL -#define DEF_MENU_ENTRY_MENU (char *) NULL +#define DEF_MENU_ENTRY_LABEL ((char *) NULL) +#define DEF_MENU_ENTRY_MENU ((char *) NULL) #define DEF_MENU_ENTRY_OFF_VALUE "0" #define DEF_MENU_ENTRY_ON_VALUE "1" -#define DEF_MENU_ENTRY_SELECT_IMAGE (char *) NULL +#define DEF_MENU_ENTRY_SELECT_IMAGE ((char *) NULL) #define DEF_MENU_ENTRY_STATE "normal" -#define DEF_MENU_ENTRY_VALUE (char *) NULL -#define DEF_MENU_ENTRY_CHECK_VARIABLE (char *) NULL +#define DEF_MENU_ENTRY_VALUE ((char *) NULL) +#define DEF_MENU_ENTRY_CHECK_VARIABLE ((char *) NULL) #define DEF_MENU_ENTRY_RADIO_VARIABLE "selectedButton" -#define DEF_MENU_ENTRY_SELECT (char *) NULL +#define DEF_MENU_ENTRY_SELECT ((char *) NULL) #define DEF_MENU_ENTRY_UNDERLINE "-1" /* @@ -290,7 +290,7 @@ #define DEF_MENU_SELECT_MONO BLACK #define DEF_MENU_TAKE_FOCUS "0" #define DEF_MENU_TEAROFF "1" -#define DEF_MENU_TEAROFF_CMD (char *) NULL +#define DEF_MENU_TEAROFF_CMD ((char *) NULL) #define DEF_MENU_TITLE "" #define DEF_MENU_TYPE "normal" @@ -318,7 +318,7 @@ #define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO DEF_MENUBUTTON_BG_MONO #define DEF_MENUBUTTON_HIGHLIGHT HIGHLIGHT #define DEF_MENUBUTTON_HIGHLIGHT_WIDTH "0" -#define DEF_MENUBUTTON_IMAGE (char *) NULL +#define DEF_MENUBUTTON_IMAGE ((char *) NULL) #define DEF_MENUBUTTON_INDICATOR "0" #define DEF_MENUBUTTON_JUSTIFY "center" #define DEF_MENUBUTTON_MENU "" @@ -418,7 +418,7 @@ #define DEF_SCALE_LENGTH "100" #define DEF_SCALE_ORIENT "vertical" #define DEF_SCALE_RELIEF "flat" -#define DEF_SCALE_REPEAT_DELAY "300" +#define DEF_SCALE_REPEAT_DELAY "300" #define DEF_SCALE_REPEAT_INTERVAL "100" #define DEF_SCALE_RESOLUTION "1" #define DEF_SCALE_TROUGH_COLOR TROUGH @@ -427,7 +427,7 @@ #define DEF_SCALE_SLIDER_LENGTH "30" #define DEF_SCALE_SLIDER_RELIEF "raised" #define DEF_SCALE_STATE "normal" -#define DEF_SCALE_TAKE_FOCUS (char *) NULL +#define DEF_SCALE_TAKE_FOCUS ((char *) NULL) #define DEF_SCALE_TICK_INTERVAL "0" #define DEF_SCALE_TO "100" #define DEF_SCALE_VARIABLE "" @@ -454,7 +454,7 @@ #define DEF_SCROLLBAR_RELIEF "sunken" #define DEF_SCROLLBAR_REPEAT_DELAY "300" #define DEF_SCROLLBAR_REPEAT_INTERVAL "100" -#define DEF_SCROLLBAR_TAKE_FOCUS (char *) NULL +#define DEF_SCROLLBAR_TAKE_FOCUS ((char *) NULL) #define DEF_SCROLLBAR_TROUGH_COLOR TROUGH #define DEF_SCROLLBAR_TROUGH_MONO WHITE #define DEF_SCROLLBAR_WIDTH "10" @@ -481,8 +481,9 @@ #define DEF_TEXT_INSERT_BD_MONO "0" #define DEF_TEXT_INSERT_OFF_TIME "300" #define DEF_TEXT_INSERT_ON_TIME "600" +#define DEF_TEXT_INSERT_UNFOCUSSED "none" #define DEF_TEXT_INSERT_WIDTH "2" -#define DEF_TEXT_MAX_UNDO "0" +#define DEF_TEXT_MAX_UNDO "0" #define DEF_TEXT_PADX "1" #define DEF_TEXT_PADY "1" #define DEF_TEXT_RELIEF "sunken" @@ -501,8 +502,8 @@ #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_TAKE_FOCUS ((char *) NULL) +#define DEF_TEXT_UNDO "0" #define DEF_TEXT_WIDTH "80" #define DEF_TEXT_WRAP "char" #define DEF_TEXT_XSCROLL_COMMAND "" @@ -524,4 +525,10 @@ #define DEF_TOPLEVEL_SCREEN "" #define DEF_TOPLEVEL_USE "" +/* + * Defaults for busy windows: + */ + +#define DEF_BUSY_CURSOR "wait" + #endif /* _TKWINDEFAULT */ diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index 55152e9..67fc637 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -9,10 +9,9 @@ * 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 "tkFont.h" #include <commdlg.h> /* includes common dialog functionality */ #ifdef _MSC_VER @@ -53,12 +52,12 @@ /* * The following structure is used by the new Tk_ChooseDirectoryObjCmd to pass - * data between it and its callback. Unqiue to Winodws platform. + * data between it and its callback. Unique to Windows platform. */ typedef struct ChooseDirData { - TCHAR utfInitDir[MAX_PATH]; /* Initial folder to use */ - TCHAR utfRetDir[MAX_PATH]; /* Returned folder to use */ + TCHAR initDir[MAX_PATH]; /* Initial folder to use */ + TCHAR retDir[MAX_PATH]; /* Returned folder to use */ Tcl_Interp *interp; int mustExist; /* True if file must exist to return from * callback */ @@ -139,7 +138,7 @@ static const struct {int type; int btnIds[3];} allowedTypes[] = { SetWindowLongPtr((to), GWLP_USERDATA, (LPARAM)(what)) /* - * The value of TK_MULTI_MAX_PATH dictactes how many files can be retrieved + * The value of TK_MULTI_MAX_PATH dictates how many files can be retrieved * with tk_get*File -multiple 1. It must be allocated on the stack, so make it * large enough but not too large. - hobbs * @@ -163,7 +162,7 @@ typedef struct ChooseDir { * directory or return. */ int lastIdx; /* Last item that was selected in directory * browser listbox. */ - TCHAR path[MAX_PATH]; /* On return from choose directory dialog, + char 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 @@ -173,8 +172,8 @@ typedef struct ChooseDir { } ChooseDir; /* - * The following structure is used to pass information between GetFileName/W - * functions and OFN dialog hook procedures. [Bug 2896501, Patch 2898255] + * The following structure is used to pass information between GetFileName + * function and OFN dialog hook procedures. [Bug 2896501, Patch 2898255] */ typedef struct OFNData { @@ -183,8 +182,7 @@ typedef struct OFNData { 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 */ + TCHAR *dynFileBuffer; /* Dynamic filename buffer */ } OFNData; /* @@ -195,23 +193,18 @@ static UINT APIENTRY ChooseDirectoryValidateProc(HWND hdlg, UINT uMsg, LPARAM wParam, LPARAM lParam); static UINT CALLBACK ColorDlgHookProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -static int GetFileNameA(ClientData clientData, +static int GetFileName(ClientData clientData, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[], int isOpen); -static int GetFileNameW(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[], int isOpen); + Tcl_Obj *const objv[], int isOpen); 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, + int *indexPtr); +static UINT APIENTRY OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam); static void SetTkDialog(ClientData clientData); -static char * ConvertExternalFilename(Tcl_Encoding encoding, - char *filename, Tcl_DString *dsPtr); +static const char *ConvertExternalFilename(TCHAR *filename, + Tcl_DString *dsPtr); /* *------------------------------------------------------------------------- @@ -252,10 +245,10 @@ EatSpuriousMessageBugFix(void) DWORD nTime = GetTickCount() + 250; while (GetTickCount() < nTime) { - if (PeekMessage(&msg, 0, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE)){ + if (PeekMessageA(&msg, 0, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE)){ break; } - PeekMessage(&msg, 0, WM_LBUTTONUP, WM_LBUTTONUP, PM_REMOVE); + PeekMessageA(&msg, 0, WM_LBUTTONUP, WM_LBUTTONUP, PM_REMOVE); } } @@ -282,7 +275,7 @@ void TkWinDialogDebug( int debug) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->debugFlag = debug; @@ -312,16 +305,16 @@ 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. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData, parent; + Tk_Window tkwin = clientData, parent; HWND hWnd; int i, oldMode, winCode, result; CHOOSECOLOR chooseColor; static int inited = 0; static COLORREF dwCustColors[16]; static long oldColor; /* the color selected last time */ - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "-initialcolor", "-parent", "-title", NULL }; enum options { @@ -357,7 +350,7 @@ Tk_ChooseColorObjCmd( for (i = 1; i < objc; i += 2) { int index; - char *string; + const char *string; Tcl_Obj *optionPtr, *valuePtr; optionPtr = objv[i]; @@ -470,7 +463,7 @@ ColorDlgHookProc( WPARAM wParam, /* First message parameter. */ LPARAM lParam) /* Second message parameter. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); const char *title; CHOOSECOLOR *ccPtr; @@ -487,13 +480,12 @@ ColorDlgHookProc( if ((title != NULL) && (title[0] != '\0')) { Tcl_DString ds; - (*tkWinProcs->setWindowText)(hDlg, - Tcl_WinUtfToTChar(title, -1, &ds)); + SetWindowText(hDlg, Tcl_WinUtfToTChar(title,-1,&ds)); Tcl_DStringFree(&ds); } if (tsdPtr->debugFlag) { tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName; - Tcl_DoWhenIdle(SetTkDialog, (ClientData) hDlg); + Tcl_DoWhenIdle(SetTkDialog, hDlg); } return TRUE; } @@ -522,13 +514,9 @@ 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. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - return GetFileNameW(clientData, interp, objc, objv, 1); - } else { - return GetFileNameA(clientData, interp, objc, objv, 1); - } + return GetFileName(clientData, interp, objc, objv, 1); } /* @@ -553,19 +541,15 @@ 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. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - return GetFileNameW(clientData, interp, objc, objv, 0); - } else { - return GetFileNameA(clientData, interp, objc, objv, 0); - } + return GetFileName(clientData, interp, objc, objv, 0); } /* *---------------------------------------------------------------------- * - * GetFileNameW -- + * GetFileName -- * * Calls GetOpenFileName() or GetSaveFileName(). * @@ -579,36 +563,35 @@ Tk_GetSaveFileObjCmd( */ static int -GetFileNameW( +GetFileName( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[], /* Argument objects. */ + Tcl_Obj *const objv[], /* Argument objects. */ int open) /* 1 to call GetOpenFileName(), 0 to call * GetSaveFileName(). */ { - OPENFILENAMEW ofn; - WCHAR file[TK_MULTI_MAX_PATH]; + OPENFILENAME ofn; + TCHAR file[TK_MULTI_MAX_PATH]; OFNData ofnData; int cdlgerr; int filterIndex = 0, result = TCL_ERROR, winCode, oldMode, i, multi = 0; int inValue, confirmOverwrite = 1; - char *extension = NULL, *title = NULL; - Tk_Window tkwin = (Tk_Window) clientData; + const char *extension = NULL, *title = NULL; + Tk_Window tkwin = clientData; HWND hWnd; Tcl_Obj *filterObj = NULL, *initialTypeObj = NULL, *typeVariableObj = NULL; Tcl_DString utfFilterString, utfDirString, ds; Tcl_DString extString, filterString, dirString, titleString; - Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding(); ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - static CONST char *saveOptionStrings[] = { + static const char *const saveOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", "-parent", "-title", "-typevariable", "-confirmoverwrite", NULL }; - static CONST char *openOptionStrings[] = { + static const char *const openOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", "-parent", "-title", "-typevariable", "-multiple", @@ -627,7 +610,7 @@ GetFileNameW( for (i = 1; i < objc; i += 2) { int index; - char *string; + const char *string; Tcl_Obj *optionPtr, *valuePtr; optionPtr = objv[i]; @@ -668,7 +651,7 @@ GetFileNameW( if (Tcl_TranslateFileName(interp, string, &ds) == NULL) { goto end; } - Tcl_UtfToExternal(NULL, unicodeEncoding, Tcl_DStringValue(&ds), + Tcl_UtfToExternal(NULL, TkWinGetUnicodeEncoding(), Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), 0, NULL, (char *) file, sizeof(file), NULL, NULL, NULL); Tcl_DStringFree(&ds); @@ -708,19 +691,19 @@ GetFileNameW( Tk_MakeWindowExist(tkwin); hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); - ZeroMemory(&ofn, sizeof(OPENFILENAMEW)); + ZeroMemory(&ofn, sizeof(OPENFILENAME)); if (LOBYTE(LOWORD(GetVersion())) < 5) { ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; } else { - ofn.lStructSize = sizeof(OPENFILENAMEW); + ofn.lStructSize = sizeof(OPENFILENAME); } ofn.hwndOwner = hWnd; ofn.hInstance = TkWinGetHInstance(ofn.hwndOwner); - ofn.lpstrFile = (WCHAR *) file; + ofn.lpstrFile = 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.lpfnHook = (LPOFNHOOKPROC) OFNHookProc; ofn.lCustData = (LPARAM) &ofnData; if (open != 0) { @@ -739,24 +722,22 @@ GetFileNameW( * procedure when necessary */ - ofnData.dynFileBufferSize = 1024; - ofnData.dynFileBuffer = ckalloc(1024); + ofnData.dynFileBufferSize = 512; + ofnData.dynFileBuffer = ckalloc(512 * sizeof(TCHAR)); } if (extension != NULL) { - Tcl_UtfToExternalDString(unicodeEncoding, extension, -1, &extString); - ofn.lpstrDefExt = (WCHAR *) Tcl_DStringValue(&extString); + Tcl_WinUtfToTChar(extension, -1, &extString); + ofn.lpstrDefExt = (TCHAR *) Tcl_DStringValue(&extString); } - Tcl_UtfToExternalDString(unicodeEncoding, - Tcl_DStringValue(&utfFilterString), + Tcl_WinUtfToTChar(Tcl_DStringValue(&utfFilterString), Tcl_DStringLength(&utfFilterString), &filterString); - ofn.lpstrFilter = (WCHAR *) Tcl_DStringValue(&filterString); + ofn.lpstrFilter = (TCHAR *) Tcl_DStringValue(&filterString); ofn.nFilterIndex = filterIndex; if (Tcl_DStringValue(&utfDirString)[0] != '\0') { - Tcl_UtfToExternalDString(unicodeEncoding, - Tcl_DStringValue(&utfDirString), + Tcl_WinUtfToTChar(Tcl_DStringValue(&utfDirString), Tcl_DStringLength(&utfDirString), &dirString); } else { /* @@ -772,16 +753,16 @@ GetFileNameW( Tcl_DStringValue(&utfDirString), &cwd) == NULL)) { Tcl_ResetResult(interp); } else { - Tcl_UtfToExternalDString(unicodeEncoding, Tcl_DStringValue(&cwd), + Tcl_WinUtfToTChar(Tcl_DStringValue(&cwd), Tcl_DStringLength(&cwd), &dirString); } Tcl_DStringFree(&cwd); } - ofn.lpstrInitialDir = (WCHAR *) Tcl_DStringValue(&dirString); + ofn.lpstrInitialDir = (TCHAR *) Tcl_DStringValue(&dirString); if (title != NULL) { - Tcl_UtfToExternalDString(unicodeEncoding, title, -1, &titleString); - ofn.lpstrTitle = (WCHAR *) Tcl_DStringValue(&titleString); + Tcl_WinUtfToTChar(title, -1, &titleString); + ofn.lpstrTitle = (TCHAR *) Tcl_DStringValue(&titleString); } /* @@ -790,9 +771,9 @@ GetFileNameW( oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); if (open != 0) { - winCode = GetOpenFileNameW(&ofn); + winCode = GetOpenFileName(&ofn); } else { - winCode = GetSaveFileNameW(&ofn); + winCode = GetSaveFileName(&ofn); } Tcl_SetServiceMode(oldMode); EatSpuriousMessageBugFix(); @@ -846,7 +827,7 @@ GetFileNameW( * first element is the directory path. */ - WCHAR *files = (WCHAR *) ofnData.dynFileBuffer; + TCHAR *files = ofnData.dynFileBuffer; Tcl_Obj *returnList = Tcl_NewObj(); int count = 0; @@ -854,8 +835,7 @@ GetFileNameW( * Get directory. */ - (void) ConvertExternalFilename(unicodeEncoding, (char *) files, - &ds); + ConvertExternalFilename(files, &ds); while (*files != '\0') { while (*files != '\0') { @@ -867,8 +847,7 @@ GetFileNameW( Tcl_DString filenameBuf; count++; - (void) ConvertExternalFilename(unicodeEncoding, - (char *) files, &filenameBuf); + ConvertExternalFilename(files, &filenameBuf); fullnameObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); @@ -894,8 +873,8 @@ GetFileNameW( Tcl_SetObjResult(interp, returnList); Tcl_DStringFree(&ds); } else { - Tcl_AppendResult(interp, ConvertExternalFilename(unicodeEncoding, - (char *) ofn.lpstrFile, &ds), NULL); + Tcl_AppendResult(interp, ConvertExternalFilename(ofn.lpstrFile, + &ds), NULL); gotFilename = (Tcl_DStringLength(&ds) > 0); Tcl_DStringFree(&ds); } @@ -920,8 +899,8 @@ GetFileNameW( } } else if (cdlgerr == FNERR_INVALIDFILENAME) { Tcl_SetResult(interp, "invalid filename \"", TCL_STATIC); - Tcl_AppendResult(interp, ConvertExternalFilename(unicodeEncoding, - (char *) ofn.lpstrFile, &ds), "\"", NULL); + Tcl_AppendResult(interp, ConvertExternalFilename(ofn.lpstrFile, + &ds), "\"", NULL); Tcl_DStringFree(&ds); } else { result = TCL_OK; @@ -952,7 +931,7 @@ GetFileNameW( /* *------------------------------------------------------------------------- * - * OFNHookProcW -- + * OFNHookProc -- * * Dialog box hook function. This is used to sets the "tk_dialog" * variable for test/debugging when the dialog is ready to receive @@ -969,561 +948,13 @@ GetFileNameW( */ static UINT APIENTRY -OFNHookProcW( +OFNHookProc( 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)); - OPENFILENAMEW *ofnPtr; - OFNData *ofnData; - - if (uMsg == WM_INITDIALOG) { - 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, (LPARAM) buffer); - buffer += dirsize; - - SendMessageW(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer); - - /* - * If there are multiple files, delete the quotes and change - * every second quote to NULL terminator - */ - - if (buffer[0] == '"') { - BOOL findquote = TRUE; - 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. - */ - - ofnPtr = (OPENFILENAMEW *) TkWinGetUserData(hdlg); - if (ofnPtr != NULL) { - ofnData = (OFNData *) ofnPtr->lCustData; - if (ofnData->interp != NULL) { - hdlg = GetParent(hdlg); - tsdPtr->debugInterp = ofnData->interp; - Tcl_DoWhenIdle(SetTkDialog, hdlg); - } - TkWinSetUserData(hdlg, NULL); - } - } - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * GetFileNameA -- - * - * Calls GetOpenFileName() or GetSaveFileName(). - * - * Results: - * See user documentation. - * - * Side effects: - * See user documentation. - * - *---------------------------------------------------------------------- - */ - -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]; - 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_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)); - static CONST char *saveOptionStrings[] = { - "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-parent", "-title", "-typevariable", NULL - }; - static CONST char *openOptionStrings[] = { - "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-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_TYPEVARIABLE - }; - - file[0] = '\0'; - ZeroMemory(&ofnData, sizeof(OFNData)); - Tcl_DStringInit(&utfFilterString); - Tcl_DStringInit(&utfDirString); - - /* - * Parse the arguments. - */ - - if (open) { - optionStrings = openOptionStrings; - } else { - optionStrings = saveOptionStrings; - } - - 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 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. - */ - - if (!open && index >= FILE_MULTIPLE) { - index++; - } - if (i + 1 == objc) { - string = Tcl_GetString(optionPtr); - Tcl_AppendResult(interp, "value for \"", string, "\" missing", - NULL); - goto end; - } - - string = Tcl_GetString(valuePtr); - switch ((enum options) index) { - case FILE_DEFAULT: - if (string[0] == '.') { - string++; - } - extension = string; - break; - case FILE_TYPES: - filterObj = valuePtr; - break; - case FILE_INITDIR: - Tcl_DStringFree(&utfDirString); - if (Tcl_TranslateFileName(interp, string, &utfDirString) == NULL) { - goto end; - } - break; - case FILE_INITFILE: - 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); - Tcl_DStringFree(&ds); - break; - case FILE_MULTIPLE: - if (Tcl_GetBooleanFromObj(interp, valuePtr, &multi) != TCL_OK) { - return TCL_ERROR; - } - 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 (MakeFilter(interp, filterObj, &utfFilterString, initialTypeObj, - &filterIndex) != TCL_OK) { - goto end; - } - - Tk_MakeWindowExist(tkwin); - hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); - - 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; - } else { - ofn.Flags |= OFN_OVERWRITEPROMPT; - } - - if (tsdPtr->debugFlag != 0) { - 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) { - Tcl_UtfToExternalDString(NULL, extension, -1, &extString); - ofn.lpstrDefExt = (LPTSTR) Tcl_DStringValue(&extString); - } - 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. - */ - - Tcl_DString cwd; - - Tcl_DStringFree(&utfDirString); - if ((Tcl_GetCwd(interp, &utfDirString) == 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 (title != NULL) { - Tcl_UtfToExternalDString(NULL, title, -1, &titleString); - ofn.lpstrTitle = (LPTSTR) Tcl_DStringValue(&titleString); - } - - /* - * Popup the dialog. - */ - - GetCurrentDirectory(MAX_PATH, savePath); - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - if (open != 0) { - winCode = GetOpenFileName(&ofn); - } else { - winCode = GetSaveFileName(&ofn); - } - Tcl_SetServiceMode(oldMode); - EatSpuriousMessageBugFix(); - 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); - - /* - * Clear the interp result since anything may have happened during the - * modal loop. - */ - - Tcl_ResetResult(interp); - - /* - * Process the results. - * - * Use the CommDlgExtendedError() function to retrieve the error code. - * This function can return one of about two dozen codes; most of these - * indicate some sort of gross system failure (insufficient memory, bad - * window handles, etc.) Most of the error codes will be ignored; as we - * find we want specific error messages for particular errors, we can - * extend the code as needed. - */ - - cdlgerr = CommDlgExtendedError(); - - /* - * We now allow FNERR_BUFFERTOOSMALL when multiselection is enabled. The - * filename buffer has been dynamically allocated by the OFN dialog - * procedure to accomodate all selected files. - */ - - if ((winCode != 0) - || ((cdlgerr == FNERR_BUFFERTOOSMALL) - && (ofn.Flags & OFN_ALLOWMULTISELECT))) { - if (ofn.Flags & OFN_ALLOWMULTISELECT) { - /* - * The result in dynFileBuffer contains many items, separated by - * NUL characters. It is terminated with two nulls in a row. The - * first element is the directory path (if multiple files are - * selected) or the only returned file (if only a single file has - * been chosen). - */ - - char *files = ofnData.dynFileBuffer; - Tcl_Obj *returnList = Tcl_NewObj(); - int count = 0; - - /* - * Get directory. - */ - - (void) ConvertExternalFilename(NULL, (char *) files, &ds); - - while (*files != '\0') { - while (*files != '\0') { - files++; - } - files++; - if (*files != '\0') { - Tcl_Obj *fullnameObj; - Tcl_DString filename; - - count++; - (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(NULL, returnList, Tcl_NewStringObj( - Tcl_DStringValue(&ds), Tcl_DStringLength(&ds))); - } - Tcl_SetObjResult(interp, returnList); - Tcl_DStringFree(&ds); - } else { - Tcl_AppendResult(interp, ConvertExternalFilename(NULL, - (char *) ofn.lpstrFile, &ds), NULL); - Tcl_DStringFree(&ds); - } - result = TCL_OK; - 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; - } - } - } 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) { - Tcl_DStringFree(&titleString); - } - if (ofn.lpstrInitialDir != NULL) { - Tcl_DStringFree(&dirString); - } - Tcl_DStringFree(&filterString); - if (ofn.lpstrDefExt != NULL) { - Tcl_DStringFree(&extString); - } - - end: - Tcl_DStringFree(&utfDirString); - Tcl_DStringFree(&utfFilterString); - if (ofnData.dynFileBuffer != NULL) { - ckfree(ofnData.dynFileBuffer); - ofnData.dynFileBuffer = NULL; - } - - return result; -} - -/* - *------------------------------------------------------------------------- - * - * OFNHookProcA -- - * - * Dialog box hook function. This is used to sets the "tk_dialog" - * variable for test/debugging when the dialog is ready to receive - * messages. When multiple file selection is enabled this function - * is used to process the list of names. - * - * Results: - * Returns 0 to allow default processing of messages to occur. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static UINT APIENTRY -OFNHookProcA( - HWND hdlg, /* handle to child dialog window */ - UINT uMsg, /* message identifier */ - WPARAM wParam, /* message parameter */ - LPARAM lParam) /* message parameter */ -{ - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); OPENFILENAME *ofnPtr; OFNData *ofnData; @@ -1535,8 +966,8 @@ OFNHookProcA( /* * 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 + * exceeds declared buffer size (the nMaxFile member of the OPENFILENAME + * struct passed to GetOpenFileName function). So, we have to rely on * the most recent CDN_SELCHANGE then. Unfortunately this means, that * gathering the selected filenames happens twice when they fit into the * declared buffer. Luckily, it's not frequent operation so it should @@ -1545,7 +976,7 @@ OFNHookProcA( if (notifyPtr->hdr.code == CDN_FILEOK || notifyPtr->hdr.code == CDN_SELCHANGE) { int dirsize, selsize; - char *buffer; + TCHAR *buffer; int buffersize; /* @@ -1560,30 +991,31 @@ OFNHookProcA( selsize = SendMessage(hdlg, CDM_GETSPEC, 0, 0); dirsize = SendMessage(hdlg, CDM_GETFOLDERPATH, 0, 0); - buffersize = selsize + dirsize + 1; + 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); + buffer = ckrealloc(buffer, buffersize * sizeof(TCHAR)); ofnData->dynFileBufferSize = buffersize; ofnData->dynFileBuffer = buffer; } SendMessage(hdlg, CDM_GETFOLDERPATH, dirsize, (LPARAM) buffer); buffer += dirsize; + SendMessage(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer); /* * If there are multiple files, delete the quotes and change - * every second quote to NULL terminator. + * every second quote to NULL terminator */ if (buffer[0] == '"') { BOOL findquote = TRUE; - char *tmp = buffer; + TCHAR *tmp = buffer; while (*buffer != '\0') { if (findquote) { @@ -1610,7 +1042,6 @@ OFNHookProcA( buffer--; *buffer = '\\'; } - } else { /* * Nothing is selected, so just empty the string. @@ -1623,19 +1054,16 @@ OFNHookProcA( } } 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 enable Tk to set the + * debug information. Unhooks itself so it won't set the debug + * information every time it gets a WM_WINDOWPOSCHANGED message. */ ofnPtr = (OPENFILENAME *) TkWinGetUserData(hdlg); if (ofnPtr != NULL) { ofnData = (OFNData *) ofnPtr->lCustData; if (ofnData->interp != NULL) { - if (ofnPtr->Flags & OFN_EXPLORER) { - hdlg = GetParent(hdlg); - } + hdlg = GetParent(hdlg); tsdPtr->debugInterp = ofnData->interp; Tcl_DoWhenIdle(SetTkDialog, hdlg); } @@ -1668,11 +1096,11 @@ MakeFilter( 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 */ + int *indexPtr) /* Index of initial type in filter string */ { char *filterStr; char *p; - char *initial = NULL; + const char *initial = NULL; int pass; int ix = 0; /* index counter */ FileFilterList flist; @@ -1690,9 +1118,9 @@ MakeFilter( /* * Use "All Files (*.*) as the default filter if none is specified */ - char *defaultFilter = "All Files (*.*)"; + const char *defaultFilter = "All Files (*.*)"; - p = filterStr = (char*)ckalloc(30 * sizeof(char)); + p = filterStr = ckalloc(30); strcpy(p, defaultFilter); p+= strlen(defaultFilter); @@ -1728,20 +1156,22 @@ MakeFilter( * twice the size of the string to format the filter */ - filterStr = ckalloc((unsigned int) len * 3); + filterStr = ckalloc(len * 3); for (filterPtr = flist.filters, p = filterStr; filterPtr; filterPtr = filterPtr->next) { - char *sep; + const char *sep; FileFilterClause *clausePtr; /* - * Check initial index for match, set index. Filter index is 1 + * Check initial index for match, set *indexPtr. Filter index is 1 * based so increment first */ + ix++; - if (index && initial && (strcmp(initial, filterPtr->name) == 0)) { - *index = ix; + if (indexPtr && initial + && (strcmp(initial, filterPtr->name) == 0)) { + *indexPtr = ix; } /* @@ -1796,7 +1226,7 @@ MakeFilter( } Tcl_DStringAppend(dsPtr, filterStr, (int) (p - filterStr)); - ckfree((char *) filterStr); + ckfree(filterStr); TkFreeFileFilters(&flist); return TCL_OK; @@ -1868,6 +1298,10 @@ MakeFilter( * - 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?). * *---------------------------------------------------------------------- */ @@ -1877,22 +1311,23 @@ 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. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - char path[MAX_PATH]; + TCHAR path[MAX_PATH]; 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) clientData; + Tk_Window tkwin = clientData; HWND hWnd; - char *utfTitle = NULL;/* Title for window */ + const char *utfTitle = NULL;/* Title for window */ TCHAR saveDir[MAX_PATH]; - Tcl_DString titleString; /* UTF Title */ + Tcl_DString titleString; /* Title */ Tcl_DString initDirString; /* Initial directory */ + Tcl_DString tempString; /* temporary */ Tcl_Obj *objPtr; - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "-initialdir", "-mustexist", "-parent", "-title", NULL }; enum options { @@ -1913,7 +1348,8 @@ Tk_ChooseDirectoryObjCmd( for (i = 1; i < objc; i += 2) { int index; - char *string; + const char *string; + const TCHAR *uniStr; Tcl_Obj *optionPtr, *valuePtr; optionPtr = objv[i]; @@ -1936,16 +1372,18 @@ Tk_ChooseDirectoryObjCmd( if (Tcl_TranslateFileName(interp,string,&initDirString) == NULL) { goto cleanup; } - string = Tcl_DStringValue(&initDirString); + Tcl_WinUtfToTChar(Tcl_DStringValue(&initDirString), -1, &tempString); + uniStr = (TCHAR *) Tcl_DStringValue(&tempString); /* * Convert possible relative path to full path to keep dialog * happy. */ - GetFullPathName(string, MAX_PATH, saveDir, NULL); - lstrcpyn(cdCBData.utfInitDir, saveDir, MAX_PATH); + GetFullPathName(uniStr, MAX_PATH, saveDir, NULL); + _tcsncpy(cdCBData.initDir, saveDir, MAX_PATH); Tcl_DStringFree(&initDirString); + Tcl_DStringFree(&tempString); break; case DIR_EXIST: if (Tcl_GetBooleanFromObj(interp, valuePtr, @@ -1979,16 +1417,16 @@ Tk_ChooseDirectoryObjCmd( bInfo.hwndOwner = hWnd; bInfo.pszDisplayName = path; bInfo.pidlRoot = NULL; - if (lstrlen(cdCBData.utfInitDir) == 0) { - GetCurrentDirectory(MAX_PATH, cdCBData.utfInitDir); + if (_tcslen(cdCBData.initDir) == 0) { + GetCurrentDirectory(MAX_PATH, cdCBData.initDir); } bInfo.lParam = (LPARAM) &cdCBData; if (utfTitle != NULL) { - Tcl_UtfToExternalDString(NULL, utfTitle, -1, &titleString); + Tcl_WinUtfToTChar(utfTitle, -1, &titleString); bInfo.lpszTitle = (LPTSTR) Tcl_DStringValue(&titleString); } else { - bInfo.lpszTitle = "Please choose a directory, then select OK."; + bInfo.lpszTitle = TEXT("Please choose a directory, then select OK."); } /* @@ -2042,8 +1480,8 @@ Tk_ChooseDirectoryObjCmd( TCL_VOLATILE); }; pMalloc->lpVtbl->Free(pMalloc, (void *) pidl); - } else if (lstrlen(cdCBData.utfRetDir) > 0) { - lstrcpy(path, cdCBData.utfRetDir); + } else if (_tcslen(cdCBData.retDir) > 0) { + _tcscpy(path, cdCBData.retDir); } pMalloc->lpVtbl->Release(pMalloc); } @@ -2067,8 +1505,8 @@ Tk_ChooseDirectoryObjCmd( if (*path) { Tcl_DString ds; - Tcl_AppendResult(interp, ConvertExternalFilename(NULL, (char *) path, - &ds), NULL); + Tcl_AppendResult(interp, ConvertExternalFilename(path, &ds), + NULL); Tcl_DStringFree(&ds); } @@ -2107,42 +1545,46 @@ ChooseDirectoryValidateProc( { TCHAR selDir[MAX_PATH]; CHOOSEDIRDATA *chooseDirSharedData = (CHOOSEDIRDATA *) lpData; + Tcl_DString tempString; Tcl_DString initDirString; - char string[MAX_PATH]; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + TCHAR string[MAX_PATH]; + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->debugFlag) { tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp; - Tcl_DoWhenIdle(SetTkDialog, (ClientData) hwnd); + Tcl_DoWhenIdle(SetTkDialog, hwnd); } - chooseDirSharedData->utfRetDir[0] = '\0'; + chooseDirSharedData->retDir[0] = '\0'; switch (message) { case BFFM_VALIDATEFAILED: /* * First save and check to see if it is a valid path name, if so then * make that path the one shown in the window. Otherwise, it failed * the check and should be treated as such. Use - * Set/GetCurrentDirectory which allows relative path names and names + * Set/GetCurrentDirectoryA which allows relative path names and names * with forward slashes. Use Tcl_TranslateFileName to make sure names * like ~ are converted correctly. */ + Tcl_WinTCharToUtf((TCHAR *) lParam, -1, &initDirString); if (Tcl_TranslateFileName(chooseDirSharedData->interp, - (char *) lParam, &initDirString) == NULL) { + Tcl_DStringValue(&initDirString), &tempString) == NULL) { /* * Should we expose the error (in the interp result) to the user * at this point? */ - chooseDirSharedData->utfRetDir[0] = '\0'; + chooseDirSharedData->retDir[0] = '\0'; return 1; } - lstrcpyn(string, Tcl_DStringValue(&initDirString), MAX_PATH); + Tcl_DStringFree(&initDirString); + Tcl_WinUtfToTChar(Tcl_DStringValue(&tempString), -1, &initDirString); + Tcl_DStringFree(&tempString); + _tcsncpy(string, (TCHAR *) Tcl_DStringValue(&initDirString), MAX_PATH); Tcl_DStringFree(&initDirString); - if (SetCurrentDirectory((char *)string) == 0) { - LPTSTR lpFilePart[MAX_PATH]; + if (SetCurrentDirectory(string) == 0) { /* * Get the full path name to the user entry, at this point it does @@ -2151,15 +1593,15 @@ ChooseDirectoryValidateProc( */ GetFullPathName(string, MAX_PATH, - chooseDirSharedData->utfRetDir, /*unused*/ lpFilePart); + chooseDirSharedData->retDir, NULL); 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); + wsprintf(selDir, TEXT("Directory '%s' does not exist,\nplease select or enter an existing directory."), chooseDirSharedData->retDir); MessageBox(NULL, selDir, NULL, MB_ICONEXCLAMATION|MB_OK); - chooseDirSharedData->utfRetDir[0] = '\0'; + chooseDirSharedData->retDir[0] = '\0'; return 1; } } else { @@ -2168,7 +1610,7 @@ ChooseDirectoryValidateProc( * directory in utfRetDir. */ - GetCurrentDirectory(MAX_PATH, chooseDirSharedData->utfRetDir); + GetCurrentDirectory(MAX_PATH, chooseDirSharedData->retDir); return 0; } return 0; @@ -2200,9 +1642,10 @@ ChooseDirectoryValidateProc( * specified parameter. */ - char *initDir = chooseDirSharedData->utfInitDir; + TCHAR *initDir = chooseDirSharedData->initDir; SetCurrentDirectory(initDir); + if (*initDir == '\\') { /* * BFFM_SETSELECTION only understands UNC paths as pidls, so @@ -2216,20 +1659,16 @@ ChooseDirectoryValidateProc( 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)) + psfFolder, hwnd, NULL, (TCHAR *) + initDir, &ulCount,&pidlMain,&ulAttr)) && (pidlMain != NULL)) { SendMessage(hwnd, BFFM_SETSELECTION, FALSE, (LPARAM) pidlMain); pMalloc->lpVtbl->Free(pMalloc, pidlMain); } psfFolder->lpVtbl->Release(psfFolder); - Tcl_DStringFree(&ds); } pMalloc->lpVtbl->Release(pMalloc); } @@ -2267,15 +1706,15 @@ 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. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData, parent; + Tk_Window tkwin = clientData, parent; HWND hWnd; Tcl_Obj *messageObj, *titleObj, *detailObj, *tmpObj; int defaultBtn, icon, type; int i, oldMode, winCode; UINT flags; - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "-default", "-detail", "-icon", "-message", "-parent", "-title", "-type", NULL }; @@ -2283,10 +1722,9 @@ Tk_MessageBoxObjCmd( MSG_DEFAULT, MSG_DETAIL, MSG_ICON, MSG_MESSAGE, MSG_PARENT, MSG_TITLE, MSG_TYPE }; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - (void) TkWinGetUnicodeEncoding(); defaultBtn = -1; detailObj = NULL; icon = MB_ICONINFORMATION; @@ -2297,7 +1735,7 @@ Tk_MessageBoxObjCmd( for (i = 1; i < objc; i += 2) { int index; - char *string; + const char *string; Tcl_Obj *optionPtr, *valuePtr; optionPtr = objv[i]; @@ -2415,7 +1853,7 @@ Tk_MessageBoxObjCmd( tsdPtr->hBigIcon = TkWinGetIcon(parent, ICON_BIG); tsdPtr->hMsgBoxHook = SetWindowsHookEx(WH_CBT, MsgBoxCBTProc, NULL, GetCurrentThreadId()); - winCode = MessageBoxW(hWnd, Tcl_GetUnicode(tmpObj), + winCode = MessageBox(hWnd, Tcl_GetUnicode(tmpObj), titleObj ? Tcl_GetUnicode(titleObj) : L"", flags); UnhookWindowsHookEx(tsdPtr->hMsgBoxHook); (void) Tcl_SetServiceMode(oldMode); @@ -2430,7 +1868,8 @@ Tk_MessageBoxObjCmd( Tcl_DecrRefCount(tmpObj); - Tcl_SetResult(interp, TkFindStateString(buttonMap, winCode), TCL_STATIC); + Tcl_SetResult(interp, + (char *)TkFindStateString(buttonMap, winCode), TCL_STATIC); return TCL_OK; } @@ -2440,8 +1879,8 @@ MsgBoxCBTProc( WPARAM wParam, LPARAM lParam) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (nCode == HCBT_CREATEWND) { /* @@ -2487,7 +1926,7 @@ static void SetTkDialog( ClientData clientData) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); char buf[32]; @@ -2498,15 +1937,14 @@ SetTkDialog( /* * Factored out a common pattern in use in this file. */ -static char * +static const char * ConvertExternalFilename( - Tcl_Encoding encoding, - char *filename, + TCHAR *filename, Tcl_DString *dsPtr) { char *p; - Tcl_ExternalToUtfDString(encoding, filename, -1, dsPtr); + Tcl_WinTCharToUtf(filename, -1, dsPtr); for (p = Tcl_DStringValue(dsPtr); *p != '\0'; p++) { /* * Change the pathname to the Tcl "normalized" pathname, where back @@ -2521,6 +1959,554 @@ ConvertExternalFilename( } /* + * ---------------------------------------------------------------------- + * + * GetFontObj -- + * + * Convert a windows LOGFONT into a Tk font description. + * + * Result: + * A list containing a Tk font description. + * + * ---------------------------------------------------------------------- + */ + +static Tcl_Obj * +GetFontObj(HDC hdc, LOGFONT *plf) +{ + Tcl_DString ds; + Tcl_Obj *resObj; + int pt = 0; + + resObj = Tcl_NewListObj(0, NULL); + Tcl_WinTCharToUtf(plf->lfFaceName, -1, &ds); + Tcl_ListObjAppendElement(NULL, resObj, + Tcl_NewStringObj(Tcl_DStringValue(&ds), -1)); + Tcl_DStringFree(&ds); + pt = -MulDiv(plf->lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY)); + Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewIntObj(pt)); + if (plf->lfWeight >= 700) { + Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj("bold", -1)); + } + if (plf->lfItalic) { + Tcl_ListObjAppendElement(NULL, resObj, + Tcl_NewStringObj("italic", -1)); + } + if (plf->lfUnderline) { + Tcl_ListObjAppendElement(NULL, resObj, + Tcl_NewStringObj("underline", -1)); + } + if (plf->lfStrikeOut) { + Tcl_ListObjAppendElement(NULL, resObj, + Tcl_NewStringObj("overstrike", -1)); + } + return resObj; +} + +static void +ApplyLogfont(Tcl_Interp *interp, Tcl_Obj *cmdObj, HDC hdc, LOGFONT *logfontPtr) +{ + int objc; + Tcl_Obj **objv, **tmpv; + + Tcl_ListObjGetElements(NULL, cmdObj, &objc, &objv); + tmpv = ckalloc(sizeof(Tcl_Obj *) * (objc + 2)); + memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc); + tmpv[objc] = GetFontObj(hdc, logfontPtr); + TkBackgroundEvalObjv(interp, objc+1, tmpv, TCL_EVAL_GLOBAL); + ckfree(tmpv); +} + +/* + * ---------------------------------------------------------------------- + * + * HookProc -- + * + * Font selection hook. If the user selects Apply on the dialog, we call + * the applyProc script with the currently selected font as arguments. + * + * ---------------------------------------------------------------------- + */ + +typedef struct HookData { + Tcl_Interp *interp; + Tcl_Obj *titleObj; + Tcl_Obj *cmdObj; + Tcl_Obj *parentObj; + Tcl_Obj *fontObj; + HWND hwnd; + Tk_Window parent; +} HookData; + +static UINT_PTR CALLBACK +HookProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CHOOSEFONT *pcf = (CHOOSEFONT *) lParam; + HWND hwndCtrl; + static HookData *phd = NULL; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + if (WM_INITDIALOG == msg && lParam != 0) { + phd = (HookData *) pcf->lCustData; + phd->hwnd = hwndDlg; + if (tsdPtr->debugFlag) { + tsdPtr->debugInterp = (Tcl_Interp *) phd->interp; + Tcl_DoWhenIdle(SetTkDialog, hwndDlg); + } + if (phd->titleObj != NULL) { + Tcl_DString title; + + Tcl_WinUtfToTChar(Tcl_GetString(phd->titleObj), -1, &title); + if (Tcl_DStringLength(&title) > 0) { + SetWindowText(hwndDlg, (LPCTSTR) Tcl_DStringValue(&title)); + } + Tcl_DStringFree(&title); + } + + /* + * Disable the colour combobox (0x473) and its label (0x443). + */ + + hwndCtrl = GetDlgItem(hwndDlg, 0x443); + if (IsWindow(hwndCtrl)) { + EnableWindow(hwndCtrl, FALSE); + } + hwndCtrl = GetDlgItem(hwndDlg, 0x473); + if (IsWindow(hwndCtrl)) { + EnableWindow(hwndCtrl, FALSE); + } + TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility"); + return 1; /* we handled the message */ + } + + if (WM_DESTROY == msg) { + phd->hwnd = NULL; + TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility"); + return 0; + } + + /* + * Handle apply button by calling the provided command script as a + * background evaluation (ie: errors dont come back here). + */ + + if (WM_COMMAND == msg && LOWORD(wParam) == 1026) { + LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0}}; + HDC hdc = GetDC(hwndDlg); + + SendMessage(hwndDlg, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM) &lf); + if (phd && phd->cmdObj) { + ApplyLogfont(phd->interp, phd->cmdObj, hdc, &lf); + } + if (phd && phd->parent) { + TkSendVirtualEvent(phd->parent, "TkFontchooserFontChanged"); + } + return 1; + } + return 0; /* pass on for default processing */ +} + +/* + * Helper for the FontchooserConfigure command to return the current value of + * any of the options (which may be NULL in the structure) + */ + +enum FontchooserOption { + FontchooserParent, FontchooserTitle, FontchooserFont, FontchooserCmd, + FontchooserVisible +}; + +static Tcl_Obj * +FontchooserCget(HookData *hdPtr, int optionIndex) +{ + Tcl_Obj *resObj = NULL; + + switch(optionIndex) { + case FontchooserParent: + if (hdPtr->parentObj) { + resObj = hdPtr->parentObj; + } else { + resObj = Tcl_NewStringObj(".", 1); + } + break; + case FontchooserTitle: + if (hdPtr->titleObj) { + resObj = hdPtr->titleObj; + } else { + resObj = Tcl_NewStringObj("", 0); + } + break; + case FontchooserFont: + if (hdPtr->fontObj) { + resObj = hdPtr->fontObj; + } else { + resObj = Tcl_NewStringObj("", 0); + } + break; + case FontchooserCmd: + if (hdPtr->cmdObj) { + resObj = hdPtr->cmdObj; + } else { + resObj = Tcl_NewStringObj("", 0); + } + break; + case FontchooserVisible: + resObj = Tcl_NewBooleanObj(hdPtr->hwnd && IsWindow(hdPtr->hwnd)); + break; + default: + resObj = Tcl_NewStringObj("", 0); + } + return resObj; +} + +/* + * ---------------------------------------------------------------------- + * + * FontchooserConfigureCmd -- + * + * Implementation of the 'tk fontchooser configure' ensemble command. See + * the user documentation for what it does. + * + * Results: + * See the user documentation. + * + * Side effects: + * Per-interp data structure may be modified + * + * ---------------------------------------------------------------------- + */ + +static int +FontchooserConfigureCmd( + ClientData clientData, /* Main window */ + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + Tk_Window tkwin = clientData; + HookData *hdPtr = NULL; + int i, r = TCL_OK; + static const char *const optionStrings[] = { + "-parent", "-title", "-font", "-command", "-visible", NULL + }; + + hdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser", NULL); + + /* + * With no arguments we return all the options in a dict. + */ + + if (objc == 1) { + Tcl_Obj *keyObj, *valueObj; + Tcl_Obj *dictObj = Tcl_NewDictObj(); + + for (i = 0; r == TCL_OK && optionStrings[i] != NULL; ++i) { + keyObj = Tcl_NewStringObj(optionStrings[i], -1); + valueObj = FontchooserCget(hdPtr, i); + r = Tcl_DictObjPut(interp, dictObj, keyObj, valueObj); + } + if (r == TCL_OK) { + Tcl_SetObjResult(interp, dictObj); + } + return r; + } + + for (i = 1; i < objc; i += 2) { + int optionIndex, len; + + if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, + "option", 0, &optionIndex) != TCL_OK) { + return TCL_ERROR; + } + if (objc == 2) { + /* + * If one option and no arg - return the current value. + */ + + Tcl_SetObjResult(interp, FontchooserCget(hdPtr, optionIndex)); + return TCL_OK; + } + if (i + 1 == objc) { + Tcl_AppendResult(interp, "value for \"", + Tcl_GetString(objv[i]), "\" missing", NULL); + return TCL_ERROR; + } + switch (optionIndex) { + case FontchooserVisible: { + const char *msg = "cannot change read-only option " + "\"-visible\": use the show or hide command"; + + Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1)); + return TCL_ERROR; + } + case FontchooserParent: { + Tk_Window parent = Tk_NameToWindow(interp, + Tcl_GetString(objv[i+1]), tkwin); + + if (parent == None) { + return TCL_ERROR; + } + if (hdPtr->parentObj) { + Tcl_DecrRefCount(hdPtr->parentObj); + } + hdPtr->parentObj = objv[i+1]; + if (Tcl_IsShared(hdPtr->parentObj)) { + hdPtr->parentObj = Tcl_DuplicateObj(hdPtr->parentObj); + } + Tcl_IncrRefCount(hdPtr->parentObj); + break; + } + case FontchooserTitle: + if (hdPtr->titleObj) { + Tcl_DecrRefCount(hdPtr->titleObj); + } + hdPtr->titleObj = objv[i+1]; + if (Tcl_IsShared(hdPtr->titleObj)) { + hdPtr->titleObj = Tcl_DuplicateObj(hdPtr->titleObj); + } + Tcl_IncrRefCount(hdPtr->titleObj); + break; + case FontchooserFont: + if (hdPtr->fontObj) { + Tcl_DecrRefCount(hdPtr->fontObj); + } + Tcl_GetStringFromObj(objv[i+1], &len); + if (len) { + hdPtr->fontObj = objv[i+1]; + if (Tcl_IsShared(hdPtr->fontObj)) { + hdPtr->fontObj = Tcl_DuplicateObj(hdPtr->fontObj); + } + Tcl_IncrRefCount(hdPtr->fontObj); + } else { + hdPtr->fontObj = NULL; + } + break; + case FontchooserCmd: + if (hdPtr->cmdObj) { + Tcl_DecrRefCount(hdPtr->cmdObj); + } + Tcl_GetStringFromObj(objv[i+1], &len); + if (len) { + hdPtr->cmdObj = objv[i+1]; + if (Tcl_IsShared(hdPtr->cmdObj)) { + hdPtr->cmdObj = Tcl_DuplicateObj(hdPtr->cmdObj); + } + Tcl_IncrRefCount(hdPtr->cmdObj); + } else { + hdPtr->cmdObj = NULL; + } + break; + } + } + return TCL_OK; +} + +/* + * ---------------------------------------------------------------------- + * + * FontchooserShowCmd -- + * + * Implements the 'tk fontchooser show' ensemble command. The per-interp + * configuration data for the dialog is held in an interp associated + * structure. + * + * Calls the Win32 FontChooser API which provides a modal dialog. See + * HookProc where we make a few changes to the dialog and set some + * additional state. + * + * ---------------------------------------------------------------------- + */ + +static int +FontchooserShowCmd( + ClientData clientData, /* Main window */ + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + Tcl_DString ds; + Tk_Window tkwin = clientData, parent; + CHOOSEFONT cf; + LOGFONT lf; + HDC hdc; + HookData *hdPtr; + int r = TCL_OK, oldMode = 0; + + hdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser", NULL); + + parent = tkwin; + if (hdPtr->parentObj) { + parent = Tk_NameToWindow(interp, Tcl_GetString(hdPtr->parentObj), + tkwin); + if (parent == None) { + return TCL_ERROR; + } + } + + Tk_MakeWindowExist(parent); + + ZeroMemory(&cf, sizeof(CHOOSEFONT)); + ZeroMemory(&lf, sizeof(LOGFONT)); + lf.lfCharSet = DEFAULT_CHARSET; + cf.lStructSize = sizeof(CHOOSEFONT); + cf.hwndOwner = Tk_GetHWND(Tk_WindowId(parent)); + cf.lpLogFont = &lf; + cf.nFontType = SCREEN_FONTTYPE; + cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_ENABLEHOOK; + cf.rgbColors = RGB(0,0,0); + cf.lpfnHook = HookProc; + cf.lCustData = (INT_PTR) hdPtr; + hdPtr->interp = interp; + hdPtr->parent = parent; + hdc = GetDC(cf.hwndOwner); + + if (hdPtr->fontObj != NULL) { + TkFont *fontPtr; + Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, hdPtr->fontObj); + + if (f == NULL) { + return TCL_ERROR; + } + fontPtr = (TkFont *) f; + cf.Flags |= CF_INITTOLOGFONTSTRUCT; + Tcl_WinUtfToTChar(fontPtr->fa.family, -1, &ds); + _tcsncpy(lf.lfFaceName, (TCHAR *)Tcl_DStringValue(&ds), LF_FACESIZE-1); + Tcl_DStringFree(&ds); + lf.lfFaceName[LF_FACESIZE-1] = 0; + lf.lfHeight = -MulDiv(TkFontGetPoints(tkwin, fontPtr->fa.size), + GetDeviceCaps(hdc, LOGPIXELSY), 72); + if (fontPtr->fa.weight == TK_FW_BOLD) { + lf.lfWeight = FW_BOLD; + } + if (fontPtr->fa.slant != TK_FS_ROMAN) { + lf.lfItalic = TRUE; + } + if (fontPtr->fa.underline) { + lf.lfUnderline = TRUE; + } + if (fontPtr->fa.overstrike) { + lf.lfStrikeOut = TRUE; + } + Tk_FreeFont(f); + } + + if (TCL_OK == r && hdPtr->cmdObj != NULL) { + int len = 0; + + r = Tcl_ListObjLength(interp, hdPtr->cmdObj, &len); + if (len > 0) { + cf.Flags |= CF_APPLY; + } + } + + if (TCL_OK == r) { + oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); + if (ChooseFont(&cf)) { + if (hdPtr->cmdObj) { + ApplyLogfont(hdPtr->interp, hdPtr->cmdObj, hdc, &lf); + } + if (hdPtr->parent) { + TkSendVirtualEvent(hdPtr->parent, "TkFontchooserFontChanged"); + } + } + Tcl_SetServiceMode(oldMode); + EnableWindow(cf.hwndOwner, 1); + } + + ReleaseDC(cf.hwndOwner, hdc); + return r; +} + +/* + * ---------------------------------------------------------------------- + * + * FontchooserHideCmd -- + * + * Implementation of the 'tk fontchooser hide' ensemble. See the user + * documentation for details. + * As the Win32 FontChooser function is always modal all we do here is + * destroy the dialog + * + * ---------------------------------------------------------------------- + */ + +static int +FontchooserHideCmd( + ClientData clientData, /* Main window */ + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + HookData *hdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser", NULL); + + if (hdPtr->hwnd && IsWindow(hdPtr->hwnd)) { + EndDialog(hdPtr->hwnd, 0); + } + return TCL_OK; +} + +/* + * ---------------------------------------------------------------------- + * + * DeleteHookData -- + * + * Clean up the font chooser configuration data when the interp is + * destroyed. + * + * ---------------------------------------------------------------------- + */ + +static void +DeleteHookData(ClientData clientData, Tcl_Interp *interp) +{ + HookData *hdPtr = clientData; + + if (hdPtr->parentObj) { + Tcl_DecrRefCount(hdPtr->parentObj); + } + if (hdPtr->fontObj) { + Tcl_DecrRefCount(hdPtr->fontObj); + } + if (hdPtr->titleObj) { + Tcl_DecrRefCount(hdPtr->titleObj); + } + if (hdPtr->cmdObj) { + Tcl_DecrRefCount(hdPtr->cmdObj); + } + ckfree(hdPtr); +} + +/* + * ---------------------------------------------------------------------- + * + * TkInitFontchooser -- + * + * Associate the font chooser configuration data with the Tcl + * interpreter. There is one font chooser per interp. + * + * ---------------------------------------------------------------------- + */ + +MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[]; +const TkEnsemble tkFontchooserEnsemble[] = { + { "configure", FontchooserConfigureCmd, NULL }, + { "show", FontchooserShowCmd, NULL }, + { "hide", FontchooserHideCmd, NULL }, + { NULL, NULL, NULL } +}; + +int +TkInitFontchooser(Tcl_Interp *interp, ClientData clientData) +{ + HookData *hdPtr = ckalloc(sizeof(HookData)); + + memset(hdPtr, 0, sizeof(HookData)); + Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteHookData, hdPtr); + return TCL_OK; +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/win/tkWinDraw.c b/win/tkWinDraw.c index 64f2c72..dd482bd 100644 --- a/win/tkWinDraw.c +++ b/win/tkWinDraw.c @@ -17,14 +17,13 @@ * These macros convert between X's bizarre angle units to radians. */ -#define PI 3.14159265358979 #define XAngleToRadians(a) ((double)(a) / 64 * PI / 180); /* * Translation table between X gc functions and Win32 raster op modes. */ -CONST int tkpWinRopModes[] = { +const int tkpWinRopModes[] = { R2_BLACK, /* GXclear */ R2_MASKPEN, /* GXand */ R2_MASKPENNOT, /* GXandReverse */ @@ -55,7 +54,7 @@ CONST int tkpWinRopModes[] = { #define SRCORREVERSE (DWORD)0x00DD0228 /* dest = source OR (NOT dest) */ #define SRCNAND (DWORD)0x007700E6 /* dest = NOT (source AND dest) */ -CONST int tkpWinBltModes[] = { +const int tkpWinBltModes[] = { BLACKNESS, /* GXclear */ SRCAND, /* GXand */ SRCERASE, /* GXandReverse */ @@ -102,7 +101,7 @@ CONST int tkpWinBltModes[] = { * The followng typedef is used to pass Windows GDI drawing functions. */ -typedef BOOL (CALLBACK *WinDrawFunc)(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. */ @@ -243,9 +242,9 @@ ConvertPoints( if (npoints > tsdPtr->nWinPoints) { if (tsdPtr->winPoints != NULL) { - ckfree((char *) tsdPtr->winPoints); + ckfree(tsdPtr->winPoints); } - tsdPtr->winPoints = (POINT *) ckalloc(sizeof(POINT) * npoints); + tsdPtr->winPoints = ckalloc(sizeof(POINT) * npoints); if (tsdPtr->winPoints == NULL) { tsdPtr->nWinPoints = -1; return NULL; @@ -552,10 +551,10 @@ TkPutImage( usePalette = (image->bits_per_pixel < 16); if (usePalette) { - infoPtr = (BITMAPINFO *) ckalloc(sizeof(BITMAPINFOHEADER) + infoPtr = ckalloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*ncolors); } else { - infoPtr = (BITMAPINFO *) ckalloc(sizeof(BITMAPINFOHEADER)); + infoPtr = ckalloc(sizeof(BITMAPINFOHEADER)); } infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -582,10 +581,10 @@ TkPutImage( } bitmap = CreateDIBitmap(dc, &infoPtr->bmiHeader, CBM_INIT, image->data, infoPtr, DIB_RGB_COLORS); - ckfree((char *) infoPtr); + ckfree(infoPtr); } if (!bitmap) { - Tcl_Panic("Fail to allocate bitmap\n"); + Tcl_Panic("Fail to allocate bitmap"); DeleteDC(dcMem); TkWinReleaseDrawableDC(d, dc, &state); return; @@ -745,7 +744,7 @@ RenderObject( HPEN pen, WinDrawFunc func) { - RECT rect = {0, 0, 0, 0}; + RECT rect = {0,0,0,0}; HPEN oldPen; HBRUSH oldBrush; POINT *winPoints = ConvertPoints(points, npoints, mode, &rect); @@ -813,7 +812,7 @@ RenderObject( SetPolyFillMode(dcMem, (gc->fill_rule == EvenOddRule) ? ALTERNATE : WINDING); oldMemBrush = SelectObject(dcMem, CreateSolidBrush(gc->foreground)); - (*func)(dcMem, winPoints, npoints); + func(dcMem, winPoints, npoints); BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, COPYFG); /* @@ -825,7 +824,7 @@ RenderObject( if (gc->fill_style == FillOpaqueStippled) { DeleteObject(SelectObject(dcMem, CreateSolidBrush(gc->background))); - (*func)(dcMem, winPoints, npoints); + func(dcMem, winPoints, npoints); BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, COPYBG); } @@ -841,9 +840,7 @@ RenderObject( SetPolyFillMode(dc, (gc->fill_rule == EvenOddRule) ? ALTERNATE : WINDING); - - (*func)(dc, winPoints, npoints); - + func(dc, winPoints, npoints); SelectObject(dc, oldPen); } DeleteObject(SelectObject(dc, oldBrush)); diff --git a/win/tkWinEmbed.c b/win/tkWinEmbed.c index b7f5085..43cd419 100644 --- a/win/tkWinEmbed.c +++ b/win/tkWinEmbed.c @@ -69,15 +69,15 @@ void TkWinCleanupContainerList(void) { Container *nextPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - for (; tsdPtr->firstContainerPtr != (Container *) NULL; + for (; tsdPtr->firstContainerPtr != NULL; tsdPtr->firstContainerPtr = nextPtr) { nextPtr = tsdPtr->firstContainerPtr->nextPtr; - ckfree((char *) tsdPtr->firstContainerPtr); + ckfree(tsdPtr->firstContainerPtr); } - tsdPtr->firstContainerPtr = (Container *) NULL; + tsdPtr->firstContainerPtr = NULL; } /* @@ -102,7 +102,7 @@ TkpTestembedCmd( ClientData clientData, Tcl_Interp *interp, int argc, - CONST char **argv) + const char **argv) { return TCL_OK; } @@ -230,7 +230,7 @@ TkpUseWindow( * 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 + const char *string) /* String identifying an X window to use for * tkwin; must be an integer value. */ { TkWindow *winPtr = (TkWindow *) tkwin; @@ -298,7 +298,7 @@ TkpUseWindow( 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", + if (IDCANCEL == MessageBoxA(hwnd, msg, "Tk Warning", MB_OKCANCEL | MB_ICONWARNING)) { Tcl_SetResult(interp, "Operation has been canceled", TCL_STATIC); return TCL_ERROR; @@ -361,7 +361,7 @@ TkpMakeContainer( */ Tk_MakeWindowExist(tkwin); - containerPtr = (Container *) ckalloc(sizeof(Container)); + containerPtr = ckalloc(sizeof(Container)); containerPtr->parentPtr = winPtr; containerPtr->parentHWnd = Tk_GetHWND(Tk_WindowId(tkwin)); containerPtr->embeddedHWnd = NULL; @@ -1095,7 +1095,7 @@ EmbedWindowDeleted( } else { prevPtr->nextPtr = containerPtr->nextPtr; } - ckfree((char *) containerPtr); + ckfree(containerPtr); } } diff --git a/win/tkWinFont.c b/win/tkWinFont.c index f209716..86f63ac 100644 --- a/win/tkWinFont.c +++ b/win/tkWinFont.c @@ -50,7 +50,7 @@ typedef struct FontFamily { int isSymbolFont; /* Non-zero if this is a symbol font. */ int isWideFont; /* 1 if this is a double-byte font, 0 * otherwise. */ - BOOL (WINAPI *textOutProc)(HDC, int, int, TCHAR *, int); + BOOL (WINAPI *textOutProc)(HDC hdc, int x, int y, TCHAR *str, int len); /* The procedure to use to draw text after it * has been converted from UTF-8 to the * encoding of this font. */ @@ -94,10 +94,12 @@ typedef struct FontFamily { typedef struct SubFont { 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 + HFONT hFont0; /* The specific screen font that will be used * when displaying/measuring chars belonging * to the FontFamily. */ FontFamily *familyPtr; /* The FontFamily for this SubFont. */ + HFONT hFontAngled; + double angle; } SubFont; /* @@ -123,7 +125,6 @@ typedef struct WinFont { * attributes. Usually points to * staticSubFonts, but may point to malloced * space if there are lots of SubFonts. */ - HWND hwnd; /* Toplevel window of application that owns * this font, used for getting HDC for * offscreen measurements. */ @@ -172,7 +173,7 @@ typedef struct ThreadSpecificData { * currently loaded. As screen fonts are * loaded, this list grows to hold information * about what characters exist in each font - * family. */ + * family. */ Tcl_HashTable uidTable; } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -189,40 +190,45 @@ static Tcl_Encoding systemEncoding; static FontFamily * AllocFontFamily(HDC hdc, HFONT hFont, int base); static SubFont * CanUseFallback(HDC hdc, WinFont *fontPtr, - char *fallbackName, int ch, + const char *fallbackName, int ch, SubFont **subFontPtrPtr); static SubFont * CanUseFallbackWithAliases(HDC hdc, WinFont *fontPtr, - char *faceName, int ch, Tcl_DString *nameTriedPtr, + const char *faceName, int ch, + Tcl_DString *nameTriedPtr, SubFont **subFontPtrPtr); -static int FamilyExists(HDC hdc, CONST char *faceName); -static char * FamilyOrAliasExists(HDC hdc, CONST char *faceName); +static int FamilyExists(HDC hdc, const char *faceName); +static const char * FamilyOrAliasExists(HDC hdc, const char *faceName); static SubFont * FindSubFontForChar(WinFont *fontPtr, int ch, SubFont **subFontPtrPtr); static void FontMapInsert(SubFont *subFontPtr, int ch); static void FontMapLoadPage(SubFont *subFontPtr, int row); static int FontMapLookup(SubFont *subFontPtr, int ch); static void FreeFontFamily(FontFamily *familyPtr); -static HFONT GetScreenFont(CONST TkFontAttributes *faPtr, - CONST char *faceName, int pixelSize); +static HFONT GetScreenFont(const TkFontAttributes *faPtr, + const char *faceName, int pixelSize, + double angle); static void InitFont(Tk_Window tkwin, HFONT hFont, int overstrike, WinFont *tkFontPtr); -static void InitSubFont(HDC hdc, HFONT hFont, int base, +static inline void InitSubFont(HDC hdc, HFONT hFont, int base, SubFont *subFontPtr); static int CreateNamedSystemLogFont(Tcl_Interp *interp, - Tk_Window tkwin, CONST char* name, + Tk_Window tkwin, const char* name, LOGFONT* logFontPtr); static int CreateNamedSystemFont(Tcl_Interp *interp, - Tk_Window tkwin, CONST char* name, HFONT hFont); + Tk_Window tkwin, const char* name, HFONT hFont); static int LoadFontRanges(HDC hdc, HFONT hFont, USHORT **startCount, USHORT **endCount, int *symbolPtr); static void MultiFontTextOut(HDC hdc, WinFont *fontPtr, - CONST char *source, int numBytes, int x, int y); + const char *source, int numBytes, int x, int y, + double angle); 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 inline void ReleaseSubFont(SubFont *subFontPtr); +static int SeenName(const char *name, Tcl_DString *dsPtr); +static inline HFONT SelectFont(HDC hdc, WinFont *fontPtr, + SubFont *subFontPtr, double angle); +static inline void SwapLong(PULONG p); +static inline void SwapShort(USHORT *p); static int CALLBACK WinFontCanUseProc(ENUMLOGFONT *lfPtr, NEWTEXTMETRIC *tmPtr, int fontType, LPARAM lParam); @@ -298,7 +304,7 @@ TkpFontPkgInit( TkFont * TkpGetNativeFont( Tk_Window tkwin, /* For display where font will be used. */ - CONST char *name) /* Platform-specific font name. */ + const char *name) /* Platform-specific font name. */ { int object; WinFont *fontPtr; @@ -309,7 +315,7 @@ TkpGetNativeFont( } tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr; - fontPtr = (WinFont *) ckalloc(sizeof(WinFont)); + fontPtr = ckalloc(sizeof(WinFont)); InitFont(tkwin, GetStockObject(object), 0, fontPtr); return (TkFont *) fontPtr; @@ -317,13 +323,13 @@ TkpGetNativeFont( /* *--------------------------------------------------------------------------- + * * CreateNamedSystemFont -- * * This function registers a Windows logical font description with the Tk * named font mechanism. * - * Side effects - * + * Side effects: * A new named font is added to the Tk font registry. * *--------------------------------------------------------------------------- @@ -333,12 +339,12 @@ static int CreateNamedSystemLogFont( Tcl_Interp *interp, Tk_Window tkwin, - CONST char* name, - LOGFONTA* logFontPtr) + const char* name, + LOGFONT* logFontPtr) { HFONT hFont; int r; - + hFont = CreateFontIndirect(logFontPtr); r = CreateNamedSystemFont(interp, tkwin, name, hFont); DeleteObject((HGDIOBJ)hFont); @@ -347,13 +353,13 @@ CreateNamedSystemLogFont( /* *--------------------------------------------------------------------------- - * CreateNamedSystemFont -- * - * This function registers a Windows font with the Tk - * named font mechanism. + * CreateNamedSystemFont -- * - * Side effects + * This function registers a Windows font with the Tk named font + * mechanism. * + * Side effects: * A new named font is added to the Tk font registry. * *--------------------------------------------------------------------------- @@ -363,12 +369,12 @@ static int CreateNamedSystemFont( Tcl_Interp *interp, Tk_Window tkwin, - CONST char* name, + 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); @@ -378,16 +384,19 @@ CreateNamedSystemFont( /* *--------------------------------------------------------------------------- + * * TkWinSystemFonts -- * * Create some platform specific named fonts that to give access to the - * system fonts. These are all defined for the Windows desktop parameters. + * system fonts. These are all defined for the Windows desktop + * parameters. * *--------------------------------------------------------------------------- */ void -TkWinSetupSystemFonts(TkMainInfo *mainPtr) +TkWinSetupSystemFonts( + TkMainInfo *mainPtr) { Tcl_Interp *interp; Tk_Window tkwin; @@ -401,14 +410,14 @@ TkWinSetupSystemFonts(TkMainInfo *mainPtr) /* force this for now */ if (((TkWindow *) tkwin)->mainPtr == NULL) { - ((TkWindow *) tkwin)->mainPtr = mainPtr; + ((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). + * If this API call fails then we will fallback to setting these named + * fonts from script in ttk/fonts.tcl. So far I've only seen it fail when + * WINVER has been defined for a higher platform than we are running on. + * (i.e. WINVER=0x0600 and running on XP). */ ZeroMemory(&ncMetrics, sizeof(ncMetrics)); @@ -416,26 +425,26 @@ TkWinSetupSystemFonts(TkMainInfo *mainPtr) if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncMetrics), &ncMetrics, 0)) { CreateNamedSystemLogFont(interp, tkwin, "TkDefaultFont", - &ncMetrics.lfMessageFont); + &ncMetrics.lfMessageFont); CreateNamedSystemLogFont(interp, tkwin, "TkHeadingFont", - &ncMetrics.lfMessageFont); + &ncMetrics.lfMessageFont); CreateNamedSystemLogFont(interp, tkwin, "TkTextFont", - &ncMetrics.lfMessageFont); + &ncMetrics.lfMessageFont); CreateNamedSystemLogFont(interp, tkwin, "TkMenuFont", - &ncMetrics.lfMenuFont); + &ncMetrics.lfMenuFont); CreateNamedSystemLogFont(interp, tkwin, "TkTooltipFont", - &ncMetrics.lfStatusFont); + &ncMetrics.lfStatusFont); CreateNamedSystemLogFont(interp, tkwin, "TkCaptionFont", - &ncMetrics.lfCaptionFont); + &ncMetrics.lfCaptionFont); CreateNamedSystemLogFont(interp, tkwin, "TkSmallCaptionFont", - &ncMetrics.lfSmCaptionFont); + &ncMetrics.lfSmCaptionFont); } iconMetrics.cbSize = sizeof(iconMetrics); if (SystemParametersInfo(SPI_GETICONMETRICS, sizeof(iconMetrics), &iconMetrics, 0)) { CreateNamedSystemLogFont(interp, tkwin, "TkIconFont", - &iconMetrics.lfFont); + &iconMetrics.lfFont); } /* @@ -444,9 +453,9 @@ TkWinSetupSystemFonts(TkMainInfo *mainPtr) */ { - LOGFONTA lfFixed = { + LOGFONT lfFixed = { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, - 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" + 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, TEXT("") }; long pointSize, dpi; HDC hdc = GetDC(NULL); @@ -457,13 +466,13 @@ TkWinSetupSystemFonts(TkMainInfo *mainPtr) 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); + hFont = (HFONT) GetStockObject(mapPtr->numKey); + CreateNamedSystemFont(interp, tkwin, mapPtr->strKey, hFont); } } @@ -505,7 +514,7 @@ TkpGetFontFromAttributes( * will be released. If NULL, a new TkFont * structure is allocated. */ Tk_Window tkwin, /* For display where font will be used. */ - CONST TkFontAttributes *faPtr) + const TkFontAttributes *faPtr) /* Set of attributes to match. */ { int i, j; @@ -514,7 +523,7 @@ TkpGetFontFromAttributes( HFONT hFont; Window window; WinFont *fontPtr; - char ***fontFallbacks; + const char *const *const *fontFallbacks; Tk_Uid faceName, fallback, actualName; tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr; @@ -562,9 +571,9 @@ TkpGetFontFromAttributes( ReleaseDC(hwnd, hdc); hFont = GetScreenFont(faPtr, faceName, - TkFontGetPixels(tkwin, faPtr->size)); + TkFontGetPixels(tkwin, faPtr->size), 0.0); if (tkFontPtr == NULL) { - fontPtr = (WinFont *) ckalloc(sizeof(WinFont)); + fontPtr = ckalloc(sizeof(WinFont)); } else { fontPtr = (WinFont *) tkFontPtr; ReleaseFont(fontPtr); @@ -629,10 +638,12 @@ TkpGetFontFamilies( HDC hdc; HWND hwnd; Window window; + Tcl_Obj *resultObj; window = Tk_WindowId(tkwin); hwnd = (window == None) ? NULL : TkWinGetHWND(window); hdc = GetDC(hwnd); + resultObj = Tcl_NewObj(); /* * On any version NT, there may fonts with international names. Use the @@ -649,14 +660,10 @@ TkpGetFontFamilies( * because it only exists under NT. */ - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - EnumFontFamiliesW(hdc, NULL, (FONTENUMPROCW) WinFontFamilyEnumProc, - (LPARAM) interp); - } else { - EnumFontFamiliesA(hdc, NULL, (FONTENUMPROCA) WinFontFamilyEnumProc, - (LPARAM) interp); - } + EnumFontFamilies(hdc, NULL, (FONTENUMPROC) WinFontFamilyEnumProc, + (LPARAM) resultObj); ReleaseDC(hwnd, hdc); + Tcl_SetObjResult(interp, resultObj); } static int CALLBACK @@ -666,17 +673,13 @@ WinFontFamilyEnumProc( int fontType, /* Type of font (not used). */ LPARAM lParam) /* Result object to hold result. */ { - char *faceName; + char *faceName = (char *) lfPtr->elfLogFont.lfFaceName; + Tcl_Obj *resultObj = (Tcl_Obj *) lParam; Tcl_DString faceString; - Tcl_Obj *strPtr; - Tcl_Interp *interp; - interp = (Tcl_Interp *) lParam; - faceName = lfPtr->elfLogFont.lfFaceName; Tcl_ExternalToUtfDString(systemEncoding, faceName, -1, &faceString); - strPtr = Tcl_NewStringObj(Tcl_DStringValue(&faceString), - Tcl_DStringLength(&faceString)); - Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp), strPtr); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( + Tcl_DStringValue(&faceString), Tcl_DStringLength(&faceString))); Tcl_DStringFree(&faceString); return 1; } @@ -709,13 +712,14 @@ TkpGetSubFonts( FontFamily *familyPtr; Tcl_Obj *resultPtr, *strPtr; - resultPtr = Tcl_GetObjResult(interp); + resultPtr = Tcl_NewObj(); fontPtr = (WinFont *) tkfont; for (i = 0; i < fontPtr->numSubFonts; i++) { familyPtr = fontPtr->subFontArray[i].familyPtr; strPtr = Tcl_NewStringObj(familyPtr->faceName, -1); Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); } + Tcl_SetObjResult(interp, resultPtr); } /* @@ -740,7 +744,7 @@ 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 */ + TkFontAttributes *faPtr) /* Output: Font attributes */ { WinFont *fontPtr = (WinFont *) tkfont; /* Structure describing the logical font */ @@ -748,22 +752,22 @@ TkpGetFontAttrsForChar( /* 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 */ + * 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 */ + TEXTMETRICA tm; /* Font metrics of the selected subfont */ /* * Get the font attributes. */ - oldfont = SelectObject(hdc, thisSubFontPtr->hFont); - GetTextMetrics(hdc, &tm); + oldfont = SelectObject(hdc, thisSubFontPtr->hFont0); + GetTextMetricsA(hdc, &tm); SelectObject(hdc, oldfont); ReleaseDC(fontPtr->hwnd, hdc); faPtr->family = familyPtr->faceName; @@ -778,7 +782,7 @@ TkpGetFontAttrsForChar( /* *--------------------------------------------------------------------------- * - * Tk_MeasureChars -- + * 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 @@ -798,7 +802,7 @@ TkpGetFontAttrsForChar( 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. */ @@ -829,7 +833,7 @@ Tk_MeasureChars( FontFamily *familyPtr; Tcl_DString runString; SubFont *thisSubFontPtr, *lastSubFontPtr; - CONST char *p, *end, *next = NULL, *start; + const char *p, *end, *next = NULL, *start; if (numBytes == 0) { *lengthPtr = 0; @@ -840,7 +844,7 @@ Tk_MeasureChars( hdc = GetDC(fontPtr->hwnd); lastSubFontPtr = &fontPtr->subFontArray[0]; - oldFont = SelectObject(hdc, lastSubFontPtr->hFont); + oldFont = SelectObject(hdc, lastSubFontPtr->hFont0); /* * A three step process: @@ -862,8 +866,8 @@ Tk_MeasureChars( Tcl_UtfToExternalDString(familyPtr->encoding, start, (int) (p - start), &runString); size.cx = 0; - (*familyPtr->getTextExtentPoint32Proc)(hdc, - Tcl_DStringValue(&runString), + familyPtr->getTextExtentPoint32Proc(hdc, + (TCHAR *)Tcl_DStringValue(&runString), Tcl_DStringLength(&runString) >> familyPtr->isWideFont, &size); Tcl_DStringFree(&runString); @@ -875,7 +879,7 @@ Tk_MeasureChars( lastSubFontPtr = thisSubFontPtr; start = p; - SelectObject(hdc, lastSubFontPtr->hFont); + SelectObject(hdc, lastSubFontPtr->hFont0); } p = next; } @@ -890,8 +894,7 @@ Tk_MeasureChars( Tcl_UtfToExternalDString(familyPtr->encoding, start, (int) (p - start), &runString); size.cx = 0; - (*familyPtr->getTextExtentPoint32Proc)(hdc, - Tcl_DStringValue(&runString), + familyPtr->getTextExtentPoint32Proc(hdc, (TCHAR *) Tcl_DStringValue(&runString), Tcl_DStringLength(&runString) >> familyPtr->isWideFont, &size); Tcl_DStringFree(&runString); @@ -924,8 +927,8 @@ Tk_MeasureChars( &dstWrote, NULL); Tcl_DStringAppend(&runString,buf,dstWrote); size.cx = 0; - (*familyPtr->getTextExtentPoint32Proc)(hdc, - Tcl_DStringValue(&runString), + familyPtr->getTextExtentPoint32Proc(hdc, + (TCHAR *) Tcl_DStringValue(&runString), Tcl_DStringLength(&runString) >> familyPtr->isWideFont, &size); if ((curX+size.cx) > maxLength) { @@ -966,7 +969,7 @@ Tk_MeasureChars( * procedure without the maxLength limit or any flags. */ - CONST char *lastWordBreak = NULL; + const char *lastWordBreak = NULL; Tcl_UniChar ch2; end = p; @@ -1000,7 +1003,7 @@ Tk_MeasureChars( /* *--------------------------------------------------------------------------- * - * TkpMeasureCharsInContext -- + * TkpMeasureCharsInContext -- * * Determine the number of bytes from the string that will fit in the * given horizontal span. The measurement is done under the assumption @@ -1025,7 +1028,7 @@ Tk_MeasureChars( int TkpMeasureCharsInContext( 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 in all. */ @@ -1077,7 +1080,7 @@ 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 + 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 @@ -1104,18 +1107,18 @@ Tk_DrawChars( 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); + ((TkpClipMask *) gc->clip_mask)->type == TKP_CLIP_REGION) { + SelectClipRgn(dc, (HRGN)((TkpClipMask *)gc->clip_mask)->value.region); } if ((gc->fill_style == FillStippled || gc->fill_style == FillOpaqueStippled) && gc->stipple != None) { - TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; + TkWinDrawable *twdPtr = (TkWinDrawable *) gc->stipple; HBRUSH oldBrush, stipple; HBITMAP oldBitmap, bitmap; HDC dcMem; - TEXTMETRIC tm; + TEXTMETRICA tm; SIZE size; if (twdPtr->type != TWD_BITMAP) { @@ -1141,8 +1144,8 @@ Tk_DrawChars( * Compute the bounding box and create a compatible bitmap. */ - GetTextExtentPoint(dcMem, source, numBytes, &size); - GetTextMetrics(dcMem, &tm); + GetTextExtentPointA(dcMem, source, numBytes, &size); + GetTextMetricsA(dcMem, &tm); size.cx -= tm.tmOverhang; bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy); oldBitmap = SelectObject(dcMem, bitmap); @@ -1156,11 +1159,11 @@ Tk_DrawChars( */ PatBlt(dcMem, 0, 0, size.cx, size.cy, BLACKNESS); - MultiFontTextOut(dc, fontPtr, source, numBytes, x, y); + MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0); BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem, 0, 0, 0xEA02E9); PatBlt(dcMem, 0, 0, size.cx, size.cy, WHITENESS); - MultiFontTextOut(dc, fontPtr, source, numBytes, x, y); + MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0); BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem, 0, 0, 0x8A0E06); @@ -1177,11 +1180,11 @@ Tk_DrawChars( SetTextAlign(dc, TA_LEFT | TA_BASELINE); SetTextColor(dc, gc->foreground); SetBkMode(dc, TRANSPARENT); - MultiFontTextOut(dc, fontPtr, source, numBytes, x, y); + MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0); } else { HBITMAP oldBitmap, bitmap; HDC dcMem; - TEXTMETRIC tm; + TEXTMETRICA tm; SIZE size; dcMem = CreateCompatibleDC(dc); @@ -1195,13 +1198,14 @@ Tk_DrawChars( * Compute the bounding box and create a compatible bitmap. */ - GetTextExtentPoint(dcMem, source, numBytes, &size); - GetTextMetrics(dcMem, &tm); + GetTextExtentPointA(dcMem, source, numBytes, &size); + GetTextMetricsA(dcMem, &tm); size.cx -= tm.tmOverhang; bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy); oldBitmap = SelectObject(dcMem, bitmap); - MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent); + MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent, + 0.0); BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem, 0, 0, (DWORD) tkpWinBltModes[gc->function]); @@ -1216,6 +1220,154 @@ Tk_DrawChars( TkWinReleaseDrawableDC(drawable, dc, &state); } +void +TkDrawAngledChars( + Display *display, /* Display on which to draw. */ + Drawable drawable, /* Window or pixmap in which to draw. */ + GC gc, /* Graphics context for drawing characters. */ + Tk_Font tkfont, /* Font in which characters will be drawn; + * must be the same as font used in GC. */ + const char *source, /* UTF-8 string to be displayed. Need not be + * '\0' terminated. All Tk meta-characters + * (tabs, control characters, and newlines) + * should be stripped out of the string that + * is passed to this function. If they are not + * stripped out, they will be displayed as + * regular printing characters. */ + int numBytes, /* Number of bytes in string. */ + double x, double y, /* Coordinates at which to place origin of + * string when drawing. */ + double angle) +{ + HDC dc; + WinFont *fontPtr; + TkWinDCState state; + + fontPtr = (WinFont *) gc->font; + display->request++; + + if (drawable == None) { + return; + } + + dc = TkWinGetDrawableDC(display, drawable, &state); + + SetROP2(dc, tkpWinRopModes[gc->function]); + + if ((gc->clip_mask != None) && + ((TkpClipMask *) gc->clip_mask)->type == TKP_CLIP_REGION) { + SelectClipRgn(dc, (HRGN)((TkpClipMask *)gc->clip_mask)->value.region); + } + + if ((gc->fill_style == FillStippled + || gc->fill_style == FillOpaqueStippled) + && gc->stipple != None) { + TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; + HBRUSH oldBrush, stipple; + HBITMAP oldBitmap, bitmap; + HDC dcMem; + TEXTMETRICA tm; + SIZE size; + + if (twdPtr->type != TWD_BITMAP) { + Tcl_Panic("unexpected drawable type in stipple"); + } + + /* + * Select stipple pattern into destination dc. + */ + + dcMem = CreateCompatibleDC(dc); + + stipple = CreatePatternBrush(twdPtr->bitmap.handle); + SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL); + oldBrush = SelectObject(dc, stipple); + + SetTextAlign(dcMem, TA_LEFT | TA_BASELINE); + SetTextColor(dcMem, gc->foreground); + SetBkMode(dcMem, TRANSPARENT); + SetBkColor(dcMem, RGB(0, 0, 0)); + + /* + * Compute the bounding box and create a compatible bitmap. + */ + + GetTextExtentPointA(dcMem, source, numBytes, &size); + GetTextMetricsA(dcMem, &tm); + size.cx -= tm.tmOverhang; + bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy); + oldBitmap = SelectObject(dcMem, bitmap); + + /* + * The following code is tricky because fonts are rendered in multiple + * colors. First we draw onto a black background and copy the white + * bits. Then we draw onto a white background and copy the black bits. + * Both the foreground and background bits of the font are ANDed with + * the stipple pattern as they are copied. + */ + + PatBlt(dcMem, 0, 0, size.cx, size.cy, BLACKNESS); + MultiFontTextOut(dc, fontPtr, source, numBytes, (int)x, (int)y, angle); + BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem, + 0, 0, 0xEA02E9); + PatBlt(dcMem, 0, 0, size.cx, size.cy, WHITENESS); + MultiFontTextOut(dc, fontPtr, source, numBytes, (int)x, (int)y, angle); + BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem, + 0, 0, 0x8A0E06); + + /* + * Destroy the temporary bitmap and restore the device context. + */ + + SelectObject(dcMem, oldBitmap); + DeleteObject(bitmap); + DeleteDC(dcMem); + SelectObject(dc, oldBrush); + DeleteObject(stipple); + } else if (gc->function == GXcopy) { + SetTextAlign(dc, TA_LEFT | TA_BASELINE); + SetTextColor(dc, gc->foreground); + SetBkMode(dc, TRANSPARENT); + MultiFontTextOut(dc, fontPtr, source, numBytes, (int)x, (int)y, angle); + } else { + HBITMAP oldBitmap, bitmap; + HDC dcMem; + TEXTMETRICA tm; + SIZE size; + + dcMem = CreateCompatibleDC(dc); + + SetTextAlign(dcMem, TA_LEFT | TA_BASELINE); + SetTextColor(dcMem, gc->foreground); + SetBkMode(dcMem, TRANSPARENT); + SetBkColor(dcMem, RGB(0, 0, 0)); + + /* + * Compute the bounding box and create a compatible bitmap. + */ + + GetTextExtentPointA(dcMem, source, numBytes, &size); + GetTextMetricsA(dcMem, &tm); + size.cx -= tm.tmOverhang; + bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy); + oldBitmap = SelectObject(dcMem, bitmap); + + MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent, + angle); + BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem, + 0, 0, (DWORD) tkpWinBltModes[gc->function]); + + /* + * Destroy the temporary bitmap and restore the device context. + */ + + SelectObject(dcMem, oldBitmap); + DeleteObject(bitmap); + DeleteDC(dcMem); + } + TkWinReleaseDrawableDC(drawable, dc, &state); +} + /* *--------------------------------------------------------------------------- * @@ -1241,7 +1393,7 @@ TkpDrawCharsInContext( 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 + 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 @@ -1256,8 +1408,8 @@ TkpDrawCharsInContext( * drawing. */ { (void) numBytes; /*unused*/ - Tk_DrawChars(display, drawable, gc, tkfont, - source + rangeStart, rangeLength, x, y); + Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart, + rangeLength, x, y); } /* @@ -1285,23 +1437,24 @@ MultiFontTextOut( HDC hdc, /* HDC to draw into. */ WinFont *fontPtr, /* Contains set of fonts to use when drawing * following string. */ - CONST char *source, /* Potentially multilingual UTF-8 string. */ + 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 + int x, int y, /* Coordinates at which to place origin of * string when drawing. */ + double angle) { Tcl_UniChar ch; SIZE size; HFONT oldFont; FontFamily *familyPtr; Tcl_DString runString; - CONST char *p, *end, *next; + const char *p, *end, *next; SubFont *lastSubFontPtr, *thisSubFontPtr; - TEXTMETRIC tm; + TEXTMETRICA tm; lastSubFontPtr = &fontPtr->subFontArray[0]; - oldFont = SelectObject(hdc, lastSubFontPtr->hFont); - GetTextMetrics(hdc, &tm); + oldFont = SelectFont(hdc, fontPtr, lastSubFontPtr, angle); + GetTextMetricsA(hdc, &tm); end = source + numBytes; for (p = source; p < end; ) { @@ -1312,11 +1465,11 @@ MultiFontTextOut( familyPtr = lastSubFontPtr->familyPtr; Tcl_UtfToExternalDString(familyPtr->encoding, source, (int) (p - source), &runString); - (*familyPtr->textOutProc)(hdc, x-(tm.tmOverhang/2), y, - Tcl_DStringValue(&runString), + familyPtr->textOutProc(hdc, x-(tm.tmOverhang/2), y, + (TCHAR *)Tcl_DStringValue(&runString), Tcl_DStringLength(&runString)>>familyPtr->isWideFont); - (*familyPtr->getTextExtentPoint32Proc)(hdc, - Tcl_DStringValue(&runString), + familyPtr->getTextExtentPoint32Proc(hdc, + (TCHAR *)Tcl_DStringValue(&runString), Tcl_DStringLength(&runString) >> familyPtr->isWideFont, &size); x += size.cx; @@ -1324,8 +1477,8 @@ MultiFontTextOut( } lastSubFontPtr = thisSubFontPtr; source = p; - SelectObject(hdc, lastSubFontPtr->hFont); - GetTextMetrics(hdc, &tm); + SelectFont(hdc, fontPtr, lastSubFontPtr, angle); + GetTextMetricsA(hdc, &tm); } p = next; } @@ -1333,13 +1486,38 @@ MultiFontTextOut( familyPtr = lastSubFontPtr->familyPtr; Tcl_UtfToExternalDString(familyPtr->encoding, source, (int) (p - source), &runString); - (*familyPtr->textOutProc)(hdc, x-(tm.tmOverhang/2), y, - Tcl_DStringValue(&runString), + familyPtr->textOutProc(hdc, x-(tm.tmOverhang/2), y, + (TCHAR *)Tcl_DStringValue(&runString), Tcl_DStringLength(&runString) >> familyPtr->isWideFont); Tcl_DStringFree(&runString); } SelectObject(hdc, oldFont); } + +static inline HFONT +SelectFont( + HDC hdc, + WinFont *fontPtr, + SubFont *subFontPtr, + double angle) +{ + if (angle == 0.0) { + return SelectObject(hdc, subFontPtr->hFont0); + } else if (angle == subFontPtr->angle) { + return SelectObject(hdc, subFontPtr->hFontAngled); + } else { + if (subFontPtr->hFontAngled) { + DeleteObject(subFontPtr->hFontAngled); + } + subFontPtr->hFontAngled = GetScreenFont(&fontPtr->font.fa, + subFontPtr->familyPtr->faceName, fontPtr->pixelSize, angle); + if (subFontPtr->hFontAngled == NULL) { + return SelectObject(hdc, subFontPtr->hFont0); + } + subFontPtr->angle = angle; + return SelectObject(hdc, subFontPtr->hFontAngled); + } +} /* *--------------------------------------------------------------------------- @@ -1378,20 +1556,20 @@ InitFont( HDC hdc; HWND hwnd; HFONT oldFont; - TEXTMETRIC tm; + TEXTMETRICA tm; Window window; TkFontMetrics *fmPtr; Tcl_Encoding encoding; Tcl_DString faceString; TkFontAttributes *faPtr; - char buf[LF_FACESIZE * sizeof(WCHAR)]; + TCHAR buf[LF_FACESIZE]; window = Tk_WindowId(tkwin); hwnd = (window == None) ? NULL : TkWinGetHWND(window); hdc = GetDC(hwnd); oldFont = SelectObject(hdc, hFont); - GetTextMetrics(hdc, &tm); + GetTextMetricsA(hdc, &tm); /* * On any version NT, there may fonts with international names. Use the @@ -1408,12 +1586,8 @@ InitFont( * GetTextFace because it only exists under NT. */ - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - GetTextFaceW(hdc, LF_FACESIZE, (WCHAR *) buf); - } else { - GetTextFaceA(hdc, LF_FACESIZE, (char *) buf); - } - Tcl_ExternalToUtfDString(systemEncoding, buf, -1, &faceString); + GetTextFace(hdc, LF_FACESIZE, buf); + Tcl_ExternalToUtfDString(systemEncoding, (char *) buf, -1, &faceString); fontPtr->font.fid = (Font) fontPtr; fontPtr->hwnd = hwnd; @@ -1423,7 +1597,7 @@ InitFont( faPtr->family = Tk_GetUid(Tcl_DStringValue(&faceString)); faPtr->size = - TkFontGetPoints(tkwin, -(fontPtr->pixelSize)); + 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; @@ -1442,7 +1616,7 @@ InitFont( encoding = fontPtr->subFontArray[0].familyPtr->encoding; if (encoding == TkWinGetUnicodeEncoding()) { - GetCharWidthW(hdc, 0, BASE_CHARS - 1, fontPtr->widths); + GetCharWidth(hdc, 0, BASE_CHARS - 1, fontPtr->widths); } else { GetCharWidthA(hdc, 0, BASE_CHARS - 1, fontPtr->widths); } @@ -1479,7 +1653,7 @@ ReleaseFont( ReleaseSubFont(&fontPtr->subFontArray[i]); } if (fontPtr->subFontArray != fontPtr->staticSubFonts) { - ckfree((char *) fontPtr->subFontArray); + ckfree(fontPtr->subFontArray); } } @@ -1501,7 +1675,7 @@ ReleaseFont( *------------------------------------------------------------------------- */ -static void +static inline void InitSubFont( HDC hdc, /* HDC in which font can be selected. */ HFONT hFont, /* The screen font. */ @@ -1510,9 +1684,11 @@ InitSubFont( SubFont *subFontPtr) /* Filled with SubFont constructed from above * attributes. */ { - subFontPtr->hFont = hFont; + subFontPtr->hFont0 = hFont; subFontPtr->familyPtr = AllocFontFamily(hdc, hFont, base); subFontPtr->fontMap = subFontPtr->familyPtr->fontMap; + subFontPtr->hFontAngled = NULL; + subFontPtr->angle = 0.0; } /* @@ -1532,11 +1708,14 @@ InitSubFont( *--------------------------------------------------------------------------- */ -static void +static inline void ReleaseSubFont( SubFont *subFontPtr) /* The SubFont to delete. */ { - DeleteObject(subFontPtr->hFont); + DeleteObject(subFontPtr->hFont0); + if (subFontPtr->hFontAngled) { + DeleteObject(subFontPtr->hFontAngled); + } FreeFontFamily(subFontPtr->familyPtr); } @@ -1579,17 +1758,13 @@ AllocFontFamily( FontFamily *familyPtr; Tcl_DString faceString; Tcl_Encoding encoding; - char buf[LF_FACESIZE * sizeof(WCHAR)]; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + TCHAR buf[LF_FACESIZE]; + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); hFont = SelectObject(hdc, hFont); - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - GetTextFaceW(hdc, LF_FACESIZE, (WCHAR *) buf); - } else { - GetTextFaceA(hdc, LF_FACESIZE, (char *) buf); - } - Tcl_ExternalToUtfDString(systemEncoding, buf, -1, &faceString); + GetTextFace(hdc, LF_FACESIZE, buf); + Tcl_ExternalToUtfDString(systemEncoding, (char *) buf, -1, &faceString); faceName = Tk_GetUid(Tcl_DStringValue(&faceString)); Tcl_DStringFree(&faceString); hFont = SelectObject(hdc, hFont); @@ -1602,7 +1777,7 @@ AllocFontFamily( } } - familyPtr = (FontFamily *) ckalloc(sizeof(FontFamily)); + familyPtr = ckalloc(sizeof(FontFamily)); memset(familyPtr, 0, sizeof(FontFamily)); familyPtr->nextPtr = tsdPtr->fontFamilyList; tsdPtr->fontFamilyList = familyPtr; @@ -1688,7 +1863,7 @@ FreeFontFamily( { int i; FontFamily **familyPtrPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (familyPtr == NULL) { @@ -1704,10 +1879,10 @@ FreeFontFamily( } } if (familyPtr->startCount != NULL) { - ckfree((char *) familyPtr->startCount); + ckfree(familyPtr->startCount); } if (familyPtr->endCount != NULL) { - ckfree((char *) familyPtr->endCount); + ckfree(familyPtr->endCount); } if (familyPtr->encoding != TkWinGetUnicodeEncoding()) { Tcl_FreeEncoding(familyPtr->encoding); @@ -1719,13 +1894,13 @@ FreeFontFamily( for (familyPtrPtr = &tsdPtr->fontFamilyList; ; ) { if (*familyPtrPtr == familyPtr) { - *familyPtrPtr = familyPtr->nextPtr; + *familyPtrPtr = familyPtr->nextPtr; break; } familyPtrPtr = &(*familyPtrPtr)->nextPtr; } - ckfree((char *) familyPtr); + ckfree(familyPtr); } /* @@ -1759,9 +1934,10 @@ FindSubFontForChar( HDC hdc; int i, j, k; CanUse canUse; - char **aliases, **anyFallbacks; - char ***fontFallbacks; - char *fallbackName; + const char *const *aliases; + const char *const *anyFallbacks; + const char *const *const *fontFallbacks; + const char *fallbackName; SubFont *subFontPtr; Tcl_DString ds; @@ -1850,13 +2026,8 @@ FindSubFontForChar( canUse.ch = ch; canUse.subFontPtr = NULL; canUse.subFontPtrPtr = subFontPtrPtr; - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - EnumFontFamiliesW(hdc, NULL, (FONTENUMPROCW) WinFontCanUseProc, - (LPARAM) &canUse); - } else { - EnumFontFamiliesA(hdc, NULL, (FONTENUMPROCA) WinFontCanUseProc, - (LPARAM) &canUse); - } + EnumFontFamilies(hdc, NULL, (FONTENUMPROC) WinFontCanUseProc, + (LPARAM) &canUse); subFontPtr = canUse.subFontPtr; end: @@ -1864,7 +2035,7 @@ FindSubFontForChar( if (subFontPtr == NULL) { /* - * No font can display this character. We will use the base font and + * No font can display this character. We will use the base font and * have it display the "unknown" character. */ @@ -1897,7 +2068,7 @@ WinFontCanUseProc( fontPtr = canUsePtr->fontPtr; nameTriedPtr = canUsePtr->nameTriedPtr; - fallbackName = lfPtr->elfLogFont.lfFaceName; + fallbackName = (char *) lfPtr->elfLogFont.lfFaceName; Tcl_ExternalToUtfDString(systemEncoding, fallbackName, -1, &faceString); fallbackName = Tcl_DStringValue(&faceString); @@ -2022,7 +2193,7 @@ FontMapLoadPage( USHORT *startCount, *endCount; int i, j, bitOffset, end, segCount; - subFontPtr->fontMap[row] = (char *) ckalloc(FONTMAP_BITSPERPAGE / 8); + subFontPtr->fontMap[row] = ckalloc(FONTMAP_BITSPERPAGE / 8); memset(subFontPtr->fontMap[row], 0, FONTMAP_BITSPERPAGE / 8); familyPtr = subFontPtr->familyPtr; @@ -2046,7 +2217,8 @@ FontMapLoadPage( if (endCount[j] >= i) { if (startCount[j] <= i) { bitOffset = i & (FONTMAP_BITSPERPAGE - 1); - subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7); + subFontPtr->fontMap[row][bitOffset >> 3] |= + 1 << (bitOffset & 7); } break; } @@ -2104,7 +2276,7 @@ CanUseFallbackWithAliases( HDC hdc, /* HDC in which font can be selected. */ WinFont *fontPtr, /* The font object that will own the new * screen font. */ - char *faceName, /* Desired face name for new screen font. */ + const char *faceName, /* Desired face name for new screen font. */ int ch, /* The Unicode character that the new screen * font must be able to display. */ Tcl_DString *nameTriedPtr, /* Records face names that have already been @@ -2115,7 +2287,7 @@ CanUseFallbackWithAliases( * array of subfonts. */ { int i; - char **aliases; + const char *const *aliases; SubFont *subFontPtr; if (SeenName(faceName, nameTriedPtr) == 0) { @@ -2160,11 +2332,11 @@ CanUseFallbackWithAliases( static int SeenName( - CONST char *name, /* The name to check. */ + const char *name, /* The name to check. */ Tcl_DString *dsPtr) /* Contains names that have already been * seen. */ { - CONST char *seen, *end; + const char *seen, *end; seen = Tcl_DStringValue(dsPtr); end = seen + Tcl_DStringLength(dsPtr); @@ -2174,7 +2346,7 @@ SeenName( } seen += strlen(seen) + 1; } - Tcl_DStringAppend(dsPtr, (char *) name, (int) (strlen(name) + 1)); + Tcl_DStringAppend(dsPtr, name, (int) (strlen(name) + 1)); return 0; } @@ -2207,7 +2379,7 @@ CanUseFallback( HDC hdc, /* HDC in which font can be selected. */ WinFont *fontPtr, /* The font object that will own the new * screen font. */ - char *faceName, /* Desired face name for new screen font. */ + const char *faceName, /* Desired face name for new screen font. */ int ch, /* The Unicode character that the new screen * font must be able to display. */ SubFont **subFontPtrPtr) /* Variable to fix-up if we realloc the array @@ -2235,7 +2407,8 @@ CanUseFallback( * Load this font and see if it has the desired character. */ - hFont = GetScreenFont(&fontPtr->font.fa, faceName, fontPtr->pixelSize); + hFont = GetScreenFont(&fontPtr->font.fa, faceName, fontPtr->pixelSize, + 0.0); InitSubFont(hdc, hFont, 0, &subFont); if (((ch < 256) && (subFont.familyPtr->isSymbolFont)) || (FontMapLookup(&subFont, ch) == 0)) { @@ -2251,12 +2424,11 @@ CanUseFallback( if (fontPtr->numSubFonts >= SUBFONT_SPACE) { SubFont *newPtr; - newPtr = (SubFont *) ckalloc(sizeof(SubFont) - * (fontPtr->numSubFonts + 1)); - memcpy((char *) newPtr, fontPtr->subFontArray, + newPtr = ckalloc(sizeof(SubFont) * (fontPtr->numSubFonts + 1)); + memcpy(newPtr, fontPtr->subFontArray, fontPtr->numSubFonts * sizeof(SubFont)); if (fontPtr->subFontArray != fontPtr->staticSubFonts) { - ckfree((char *) fontPtr->subFontArray); + ckfree(fontPtr->subFontArray); } /* @@ -2291,22 +2463,24 @@ CanUseFallback( static HFONT GetScreenFont( - CONST TkFontAttributes *faPtr, + const TkFontAttributes *faPtr, /* Desired font attributes for new HFONT. */ - CONST char *faceName, /* Overrides font family specified in font + 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. */ + double angle) /* What is the desired orientation of the + * font. */ { Tcl_DString ds; HFONT hFont; - LOGFONTW lf; + LOGFONT lf; memset(&lf, 0, sizeof(lf)); lf.lfHeight = -pixelSize; lf.lfWidth = 0; - lf.lfEscapement = 0; - lf.lfOrientation = 0; + lf.lfEscapement = ROUND16(angle * 10); + lf.lfOrientation = ROUND16(angle * 10); lf.lfWeight = (faPtr->weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD; lf.lfItalic = faPtr->slant; lf.lfUnderline = faPtr->underline; @@ -2318,36 +2492,10 @@ GetScreenFont( lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; Tcl_UtfToExternalDString(systemEncoding, faceName, -1, &ds); - - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - Tcl_UniChar *src, *dst; - - /* - * We can only store up to LF_FACESIZE wide characters - */ - - if ((size_t)Tcl_DStringLength(&ds) >= (LF_FACESIZE * sizeof(WCHAR))) { - Tcl_DStringSetLength(&ds, LF_FACESIZE); - } - src = (Tcl_UniChar *) Tcl_DStringValue(&ds); - dst = (Tcl_UniChar *) lf.lfFaceName; - while (*src != '\0') { - *dst++ = *src++; - } - *dst = '\0'; - hFont = CreateFontIndirectW(&lf); - } else { - /* - * We can only store up to LF_FACESIZE characters - */ - - if (Tcl_DStringLength(&ds) >= LF_FACESIZE) { - Tcl_DStringSetLength(&ds, LF_FACESIZE); - } - strcpy((char *) lf.lfFaceName, Tcl_DStringValue(&ds)); - hFont = CreateFontIndirectA((LOGFONTA *) &lf); - } + _tcsncpy(lf.lfFaceName, (TCHAR *)Tcl_DStringValue(&ds), LF_FACESIZE-1); Tcl_DStringFree(&ds); + lf.lfFaceName[LF_FACESIZE-1] = 0; + hFont = CreateFontIndirect(&lf); return hFont; } @@ -2373,7 +2521,7 @@ GetScreenFont( static int FamilyExists( HDC hdc, /* HDC in which font family will be used. */ - CONST char *faceName) /* Font family to query. */ + const char *faceName) /* Font family to query. */ { int result; Tcl_DString faceString; @@ -2403,27 +2551,22 @@ FamilyExists( * non-zero value. */ - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - result = EnumFontFamiliesW(hdc, (WCHAR*) Tcl_DStringValue(&faceString), - (FONTENUMPROCW) WinFontExistProc, 0); - } else { - result = EnumFontFamiliesA(hdc, (char *) Tcl_DStringValue(&faceString), - (FONTENUMPROCA) WinFontExistProc, 0); - } + result = EnumFontFamilies(hdc, (TCHAR*) Tcl_DStringValue(&faceString), + (FONTENUMPROC) WinFontExistProc, 0); Tcl_DStringFree(&faceString); return (result == 0); } -static char * +static const char * FamilyOrAliasExists( HDC hdc, - CONST char *faceName) + const char *faceName) { - char **aliases; + const char *const *aliases; int i; if (FamilyExists(hdc, faceName) != 0) { - return (char *) faceName; + return faceName; } aliases = TkFontGetAliasList(faceName); if (aliases != NULL) { @@ -2453,7 +2596,7 @@ WinFontExistProc( #pragma pack(1) /* Structures are byte aligned in file. */ -#define CMAPHEX 0x636d6170 /* Key for character map resource. */ +#define CMAPHEX 0x636d6170 /* Key for character map resource. */ typedef struct CMAPTABLE { USHORT version; /* Table version number (0). */ @@ -2495,7 +2638,7 @@ typedef struct SUBHEADER { } SUBHEADER; typedef struct HIBYTETABLE { - USHORT format; /* Format number is set to 2. */ + USHORT format; /* Format number is set to 2. */ USHORT length; /* The actual length in bytes of this * subtable. */ USHORT version; /* Version number (starts at 0). */ @@ -2613,7 +2756,7 @@ LoadFontRanges( } n = GetFontData(hdc, cmapKey, 0, &cmapTable, sizeof(cmapTable)); - if (n != (int)GDI_ERROR) { + if (n != (int) GDI_ERROR) { if (swapped) { SwapShort(&cmapTable.numTables); } @@ -2651,8 +2794,8 @@ LoadFontRanges( segCount = subTable.segment.segCountX2 / 2; cbData = segCount * sizeof(USHORT); - startCount = (USHORT *) ckalloc((unsigned)cbData); - endCount = (USHORT *) ckalloc((unsigned)cbData); + startCount = ckalloc(cbData); + endCount = ckalloc(cbData); offset = encTable.offset + sizeof(subTable.segment); GetFontData(hdc, cmapKey, (DWORD) offset, endCount, cbData); @@ -2695,8 +2838,8 @@ LoadFontRanges( segCount = 1; cbData = segCount * sizeof(USHORT); - startCount = (USHORT *) ckalloc((unsigned) cbData); - endCount = (USHORT *) ckalloc((unsigned) cbData); + startCount = ckalloc(cbData); + endCount = ckalloc(cbData); startCount[0] = 0x0000; endCount[0] = 0x00ff; } @@ -2724,14 +2867,14 @@ LoadFontRanges( *------------------------------------------------------------------------- */ -static void +static inline void SwapShort( PUSHORT p) { *p = (SHORT)(HIBYTE(*p) + (LOBYTE(*p) << 8)); } -static void +static inline void SwapLong( PULONG p) { diff --git a/win/tkWinImage.c b/win/tkWinImage.c index 8e6ef38..d61b84a 100644 --- a/win/tkWinImage.c +++ b/win/tkWinImage.c @@ -39,9 +39,9 @@ DestroyImage( { if (imagePtr) { if (imagePtr->data) { - ckfree((char*)imagePtr->data); + ckfree(imagePtr->data); } - ckfree((char*)imagePtr); + ckfree(imagePtr); } return 0; } @@ -211,7 +211,7 @@ XCreateImage( int bitmap_pad, int bytes_per_line) { - XImage* imagePtr = (XImage *) ckalloc(sizeof(XImage)); + XImage* imagePtr = ckalloc(sizeof(XImage)); imagePtr->width = width; imagePtr->height = height; imagePtr->xoffset = offset; @@ -301,8 +301,7 @@ XGetImageZPixmap( BOOL ret; if (format != ZPixmap) { - TkpDisplayWarning( - "XGetImageZPixmap: only ZPixmap types are implemented", + TkpDisplayWarning("Only ZPixmap types are implemented", "XGetImageZPixmap Failure"); return NULL; } @@ -350,7 +349,7 @@ XGetImageZPixmap( if (depth <= 8) { size += sizeof(unsigned short) * (1 << depth); } - bmInfo = (BITMAPINFO *) ckalloc((unsigned)size); + bmInfo = ckalloc(size); bmInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo->bmiHeader.biWidth = width; @@ -368,16 +367,16 @@ XGetImageZPixmap( unsigned char *p, *pend; GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS); - data = (unsigned char *) ckalloc(bmInfo->bmiHeader.biSizeImage); + data = ckalloc(bmInfo->bmiHeader.biSizeImage); if (!data) { /* printf("Failed to allocate data area for XImage.\n"); */ ret_image = NULL; goto cleanup; } - ret_image = XCreateImage(display, NULL, depth, ZPixmap, 0, (char *)data, + 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); + ckfree(data); goto cleanup; } @@ -387,8 +386,8 @@ XGetImageZPixmap( if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo, DIB_PAL_COLORS) == 0) { - ckfree((char *) ret_image->data); - ckfree((char *) ret_image); + ckfree(ret_image->data); + ckfree(ret_image); ret_image = NULL; goto cleanup; } @@ -404,16 +403,16 @@ XGetImageZPixmap( unsigned char *p; GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS); - data = (unsigned char *) ckalloc(bmInfo->bmiHeader.biSizeImage); + data = ckalloc(bmInfo->bmiHeader.biSizeImage); if (!data) { /* printf("Failed to allocate data area for XImage.\n"); */ ret_image = NULL; goto cleanup; } - ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, (char *)data, + ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, (char *) data, width, height, 8, (int) width); if (ret_image == NULL) { - ckfree((char *) data); + ckfree(data); goto cleanup; } @@ -423,8 +422,8 @@ XGetImageZPixmap( if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo, DIB_PAL_COLORS) == 0) { - ckfree((char *) ret_image->data); - ckfree((char *) ret_image); + ckfree(ret_image->data); + ckfree(ret_image); ret_image = NULL; goto cleanup; } @@ -435,7 +434,7 @@ XGetImageZPixmap( } } else if (depth == 16) { GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS); - data = (unsigned char *) ckalloc(bmInfo->bmiHeader.biSizeImage); + data = ckalloc(bmInfo->bmiHeader.biSizeImage); if (!data) { /* printf("Failed to allocate data area for XImage.\n"); */ ret_image = NULL; @@ -444,7 +443,7 @@ XGetImageZPixmap( ret_image = XCreateImage(display, NULL, 16, ZPixmap, 0, (char *) data, width, height, 16, 0 /* will be calc'ed from bitmap_pad */); if (ret_image == NULL) { - ckfree((char *) data); + ckfree(data); goto cleanup; } @@ -454,14 +453,14 @@ XGetImageZPixmap( if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo, DIB_RGB_COLORS) == 0) { - ckfree((char *) ret_image->data); - ckfree((char *) ret_image); + ckfree(ret_image->data); + ckfree(ret_image); ret_image = NULL; goto cleanup; } } else { GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS); - data = (unsigned char *) ckalloc(width * height * 4); + data = ckalloc(width * height * 4); if (!data) { /* printf("Failed to allocate data area for XImage.\n"); */ ret_image = NULL; @@ -470,7 +469,7 @@ XGetImageZPixmap( ret_image = XCreateImage(display, NULL, 32, ZPixmap, 0, (char *) data, width, height, 0, (int) width * 4); if (ret_image == NULL) { - ckfree((char *) data); + ckfree(data); goto cleanup; } @@ -484,10 +483,10 @@ XGetImageZPixmap( unsigned int byte_width, h, w; byte_width = ((width * 3 + 3) & ~(unsigned)3); - smallBitBase = (unsigned char *) ckalloc(byte_width * height); + smallBitBase = ckalloc(byte_width * height); if (!smallBitBase) { - ckfree((char *) ret_image->data); - ckfree((char *) ret_image); + ckfree(ret_image->data); + ckfree(ret_image); ret_image = NULL; goto cleanup; } @@ -499,9 +498,9 @@ XGetImageZPixmap( if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo, DIB_RGB_COLORS) == 0) { - ckfree((char *) ret_image->data); - ckfree((char *) ret_image); - ckfree((char *) smallBitBase); + ckfree(ret_image->data); + ckfree(ret_image); + ckfree(smallBitBase); ret_image = NULL; goto cleanup; } @@ -511,7 +510,7 @@ XGetImageZPixmap( */ 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++) { @@ -526,7 +525,7 @@ XGetImageZPixmap( * Free the Device contexts, and the Bitmap. */ - ckfree((char *) smallBitBase); + ckfree(smallBitBase); } else { /* * Get the BITMAP info directly into the Image. @@ -534,8 +533,8 @@ XGetImageZPixmap( if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo, DIB_RGB_COLORS) == 0) { - ckfree((char *) ret_image->data); - ckfree((char *) ret_image); + ckfree(ret_image->data); + ckfree(ret_image); ret_image = NULL; goto cleanup; } @@ -544,7 +543,7 @@ XGetImageZPixmap( cleanup: if (bmInfo) { - ckfree((char *) bmInfo); + ckfree(bmInfo); } if (hPal) { SelectPalette(hdcMem, hPalPrev1, FALSE); @@ -639,7 +638,7 @@ XGetImage( imagePtr = XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format); } else { - char *errMsg = NULL; + const char *errMsg = NULL; char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)]; BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf; @@ -661,8 +660,7 @@ XGetImage( imagePtr = XCreateImage(display, NULL, 1, XYBitmap, 0, NULL, width, height, 32, 0); - imagePtr->data = - ckalloc((unsigned) imagePtr->bytes_per_line*imagePtr->height); + imagePtr->data = ckalloc(imagePtr->bytes_per_line * imagePtr->height); dc = GetDC(NULL); diff --git a/win/tkWinInit.c b/win/tkWinInit.c index 19556dd..6535dba 100644 --- a/win/tkWinInit.c +++ b/win/tkWinInit.c @@ -68,7 +68,7 @@ TkpGetAppName( Tcl_DString *namePtr) /* A previously initialized Tcl_DString. */ { int argc, namelength; - CONST char **argv = NULL, *name, *p; + const char **argv = NULL, *name, *p; name = Tcl_GetVar(interp, "argv0", TCL_GLOBAL_ONLY); namelength = -1; @@ -90,7 +90,7 @@ TkpGetAppName( } Tcl_DStringAppend(namePtr, name, namelength); if (argv != NULL) { - ckfree((char *)argv); + ckfree(argv); } } @@ -113,24 +113,35 @@ TkpGetAppName( void TkpDisplayWarning( - CONST char *msg, /* Message to be displayed. */ - CONST char *title) /* Title of warning. */ + const char *msg, /* Message to be displayed. */ + const char *title) /* Title of warning. */ { #define TK_MAX_WARN_LEN 1024 - WCHAR msgString[TK_MAX_WARN_LEN + 5]; - WCHAR titleString[TK_MAX_WARN_LEN + 1]; + WCHAR titleString[TK_MAX_WARN_LEN]; + WCHAR *msgString; /* points to titleString, just after title, leaving space for ": " */ + int len; /* size of title, including terminating NULL */ - MultiByteToWideChar(CP_UTF8, 0, msg, -1, msgString, TK_MAX_WARN_LEN); - MultiByteToWideChar(CP_UTF8, 0, title, -1, titleString, TK_MAX_WARN_LEN); + len = MultiByteToWideChar(CP_UTF8, 0, title, -1, titleString, TK_MAX_WARN_LEN); + msgString = &titleString[len + 1]; + titleString[TK_MAX_WARN_LEN - 1] = L'\0'; + MultiByteToWideChar(CP_UTF8, 0, msg, -1, msgString, (TK_MAX_WARN_LEN - 1) - len); /* * Truncate MessageBox string if it is too long to not overflow the screen * and cause possible oversized window error. */ - 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); + if (titleString[TK_MAX_WARN_LEN - 1] != L'\0') { + memcpy(titleString + (TK_MAX_WARN_LEN - 5), L" ...", 5 * sizeof(WCHAR)); + } + if (IsDebuggerPresent()) { + titleString[len - 1] = L':'; + titleString[len] = L' '; + OutputDebugStringW(titleString); + } else { + titleString[len - 1] = L'\0'; + MessageBoxW(NULL, msgString, titleString, + MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL + | MB_SETFOREGROUND | MB_TOPMOST); + } } /* diff --git a/win/tkWinInt.h b/win/tkWinInt.h index abac7b0..580e58f 100644 --- a/win/tkWinInt.h +++ b/win/tkWinInt.h @@ -26,10 +26,6 @@ #include "tkWin.h" #endif -#ifndef _TKPORT -#include "tkPort.h" -#endif - /* * Define constants missing from older Win32 SDK header files. */ @@ -121,8 +117,8 @@ typedef struct { * The following macros define the class names for Tk Window types. */ -#define TK_WIN_TOPLEVEL_CLASS_NAME "TkTopLevel" -#define TK_WIN_CHILD_CLASS_NAME "TkChild" +#define TK_WIN_TOPLEVEL_CLASS_NAME TEXT("TkTopLevel") +#define TK_WIN_CHILD_CLASS_NAME TEXT("TkChild") /* * The following variable is a translation table between X gc functions and @@ -146,70 +142,33 @@ MODULE_SCOPE const int tkpWinBltModes[]; #include "tkIntPlatDecls.h" -#ifdef BUILD_tk -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLEXPORT -#endif - /* * Special proc needed as tsd accessor function between * tkWinX.c:GenerateXEvent and tkWinClipboard.c:UpdateClipboard */ -EXTERN void TkWinUpdatingClipboard(int mode); +MODULE_SCOPE void TkWinUpdatingClipboard(int mode); /* * Used by tkWinDialog.c to associate the right icon with tk_messageBox */ -EXTERN HICON TkWinGetIcon(Tk_Window tkw, DWORD iconsize); +MODULE_SCOPE 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 TkWinDisplayChanged(Display *display); MODULE_SCOPE void TkWinCleanupContainerList(void); /* * Used by tkWinWm.c for embedded menu handling. May become public. */ -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. - * - * 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 - */ - -typedef struct TkWinProcs { - int useWide; - LRESULT (WINAPI *callWindowProc)(WNDPROC lpPrevWndFunc, HWND hWnd, - UINT Msg, WPARAM wParam, LPARAM lParam); - LRESULT (WINAPI *defWindowProc)(HWND hWnd, UINT Msg, WPARAM wParam, - LPARAM lParam); - 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, - int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, - 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; - -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLIMPORT +MODULE_SCOPE HWND Tk_GetMenuHWND(Tk_Window tkwin); +MODULE_SCOPE HWND Tk_GetEmbeddedMenuHWND(Tk_Window tkwin); /* * The following allows us to cache these encoding for multiple functions. @@ -231,15 +190,15 @@ MODULE_SCOPE void TkWinSetupSystemFonts(TkMainInfo *mainPtr); * 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, +MODULE_SCOPE void TkpWinToplevelWithDraw(TkWindow *winPtr); +MODULE_SCOPE void TkpWinToplevelIconify(TkWindow *winPtr); +MODULE_SCOPE void TkpWinToplevelDeiconify(TkWindow *winPtr); +MODULE_SCOPE long TkpWinToplevelIsControlledByWm(TkWindow *winPtr); +MODULE_SCOPE long TkpWinToplevelMove(TkWindow *winPtr, int x, int y); +MODULE_SCOPE long TkpWinToplevelOverrideRedirect(TkWindow *winPtr, int reqValue); -void TkpWinToplevelDetachWindow(TkWindow *winPtr); -int TkpWmGetState(TkWindow *winPtr); +MODULE_SCOPE void TkpWinToplevelDetachWindow(TkWindow *winPtr); +MODULE_SCOPE int TkpWmGetState(TkWindow *winPtr); /* * The following functions are not present in old versions of Windows diff --git a/win/tkWinKey.c b/win/tkWinKey.c index 522bfba..8e66171 100644 --- a/win/tkWinKey.c +++ b/win/tkWinKey.c @@ -23,7 +23,7 @@ #define MAX_KEYCODE 145 /* VK_SCROLL is the last entry in our table below */ -static KeySym keymap[] = { +static const KeySym keymap[] = { NoSymbol, NoSymbol, NoSymbol, XK_Cancel, NoSymbol, NoSymbol, NoSymbol, NoSymbol, XK_BackSpace, XK_Tab, NoSymbol, NoSymbol, XK_Clear, XK_Return, NoSymbol, @@ -79,7 +79,7 @@ static KeySym KeycodeToKeysym(unsigned int keycode, *---------------------------------------------------------------------- */ -char * +const char * TkpGetString( TkWindow *winPtr, /* Window where event occurred: needed to get * input context. */ @@ -502,12 +502,11 @@ TkpInitKeymapInfo( */ if (dispPtr->modKeyCodes != NULL) { - ckfree((char *) dispPtr->modKeyCodes); + ckfree(dispPtr->modKeyCodes); } dispPtr->numModKeyCodes = 0; arraySize = KEYCODE_ARRAY_SIZE; - dispPtr->modKeyCodes = (KeyCode *) ckalloc((unsigned) - (KEYCODE_ARRAY_SIZE * sizeof(KeyCode))); + dispPtr->modKeyCodes = ckalloc(KEYCODE_ARRAY_SIZE * sizeof(KeyCode)); for (i = 0, codePtr = modMapPtr->modifiermap; i < max; i++, codePtr++) { if (*codePtr == 0) { continue; @@ -530,11 +529,10 @@ TkpInitKeymapInfo( */ arraySize *= 2; - new = (KeyCode *) ckalloc((unsigned) - (arraySize * sizeof(KeyCode))); - memcpy((void *) new, (void *) dispPtr->modKeyCodes, - (dispPtr->numModKeyCodes * sizeof(KeyCode))); - ckfree((char *) dispPtr->modKeyCodes); + new = ckalloc(arraySize * sizeof(KeyCode)); + memcpy(new, dispPtr->modKeyCodes, + dispPtr->numModKeyCodes * sizeof(KeyCode)); + ckfree(dispPtr->modKeyCodes); dispPtr->modKeyCodes = new; } dispPtr->modKeyCodes[dispPtr->numModKeyCodes] = *codePtr; @@ -660,11 +658,10 @@ XModifierKeymap * XGetModifierMapping( Display *display) { - XModifierKeymap *map = (XModifierKeymap *) - ckalloc(sizeof(XModifierKeymap)); + XModifierKeymap *map = ckalloc(sizeof(XModifierKeymap)); map->max_keypermod = 1; - map->modifiermap = (KeyCode *) ckalloc(sizeof(KeyCode)*8); + map->modifiermap = ckalloc(sizeof(KeyCode) * 8); map->modifiermap[ShiftMapIndex] = VK_SHIFT; map->modifiermap[LockMapIndex] = VK_CAPITAL; map->modifiermap[ControlMapIndex] = VK_CONTROL; @@ -696,8 +693,8 @@ void XFreeModifiermap( XModifierKeymap *modmap) { - ckfree((char *) modmap->modifiermap); - ckfree((char *) modmap); + ckfree(modmap->modifiermap); + ckfree(modmap); } /* diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c index cb40c50..245639d 100644 --- a/win/tkWinMenu.c +++ b/win/tkWinMenu.c @@ -11,20 +11,16 @@ * 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" -#include <string.h> - /* * The class of the window for popup menus. */ -#define MENU_CLASS_NAME "MenuWindowClass" -#define EMBEDDED_MENU_CLASS_NAME "EmbeddedMenuWindowClass" +#define MENU_CLASS_NAME TEXT("MenuWindowClass") +#define EMBEDDED_MENU_CLASS_NAME TEXT("EmbeddedMenuWindowClass") /* * Used to align a windows bitmap inside a rectangle @@ -159,7 +155,7 @@ 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 char * GetEntryText(TkMenuEntry *mePtr); static void GetMenuAccelGeometry(TkMenu *menuPtr, TkMenuEntry *mePtr, Tk_Font tkfont, const Tk_FontMetrics *fmPtr, int *widthPtr, @@ -241,7 +237,7 @@ GetNewID( commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable, INT2PTR(curID), &new); if (new) { - Tcl_SetHashValue(commandEntryPtr, (char *) mePtr); + Tcl_SetHashValue(commandEntryPtr, mePtr); *menuIDPtr = curID; tsdPtr->lastCommandID = curID; return TCL_OK; @@ -329,7 +325,7 @@ TkpNewMenu( hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, (char *) winMenuHdl, &newEntry); - Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr); + Tcl_SetHashValue(hashEntryPtr, menuPtr); menuPtr->platformData = (TkMenuPlatformData) winMenuHdl; return TCL_OK; @@ -356,7 +352,7 @@ TkpDestroyMenu( TkMenu *menuPtr) /* The common menu structure */ { HMENU winMenuHdl = (HMENU) menuPtr->platformData; - char *searchName; + const char *searchName; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); @@ -489,9 +485,9 @@ GetEntryText( strcpy(itemText, "( )"); } else { int i; - char *label = (mePtr->labelPtr == NULL) ? "" + const char *label = (mePtr->labelPtr == NULL) ? "" : Tcl_GetString(mePtr->labelPtr); - char *accel = (mePtr->accelPtr == NULL) ? "" + const char *accel = (mePtr->accelPtr == NULL) ? "" : Tcl_GetString(mePtr->accelPtr); const char *p, *next; Tcl_DString itemString; @@ -525,7 +521,7 @@ GetEntryText( } } - itemText = ckalloc((unsigned)Tcl_DStringLength(&itemString) + 1); + itemText = ckalloc(Tcl_DStringLength(&itemString) + 1); strcpy(itemText, Tcl_DStringValue(&itemString)); Tcl_DStringFree(&itemString); } @@ -556,7 +552,7 @@ ReconfigureWindowsMenu( TkMenu *menuPtr = (TkMenu *) clientData; TkMenuEntry *mePtr; HMENU winMenuHdl = (HMENU) menuPtr->platformData; - TCHAR *itemText = NULL; + char *itemText = NULL; const TCHAR *lpNewItem; UINT flags; UINT itemID; @@ -594,7 +590,7 @@ ReconfigureWindowsMenu( if ((menuPtr->menuType == MENUBAR) || (menuPtr->menuFlags & MENU_SYSTEM_MENU)) { Tcl_WinUtfToTChar(itemText, -1, &translatedText); - lpNewItem = Tcl_DStringValue(&translatedText); + lpNewItem = (const TCHAR *) Tcl_DStringValue(&translatedText); flags |= MF_STRING; } else { lpNewItem = (LPCTSTR) mePtr; @@ -706,8 +702,7 @@ ReconfigureWindowsMenu( } } if (!systemMenu) { - (*tkWinProcs->insertMenu)(winMenuHdl, 0xFFFFFFFF, flags, - itemID, lpNewItem); + InsertMenu(winMenuHdl, 0xFFFFFFFF, flags, itemID, lpNewItem); } Tcl_DStringFree(&translatedText); if (itemText != NULL) { @@ -719,8 +714,8 @@ ReconfigureWindowsMenu( if ((menuPtr->menuType == MENUBAR) && (menuPtr->parentTopLevelPtr != NULL)) { - HANDLE bar; - bar = TkWinGetWrapperWindow(menuPtr->parentTopLevelPtr); + HANDLE bar = TkWinGetWrapperWindow(menuPtr->parentTopLevelPtr); + if (bar) { DrawMenuBar(bar); } @@ -899,7 +894,7 @@ TkWinMenuProc( LRESULT lResult; if (!TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &lResult)) { - lResult = DefWindowProc(hwnd, message, wParam, lParam); + lResult = DefWindowProcA(hwnd, message, wParam, lParam); } return lResult; } @@ -997,7 +992,7 @@ TkWinEmbeddedMenuProc( } default: - lResult = DefWindowProc(hwnd, message, wParam, lParam); + lResult = DefWindowProcA(hwnd, message, wParam, lParam); break; } return lResult; @@ -1076,7 +1071,7 @@ TkWinHandleMenuEvent( if ((code != TCL_OK) && (code != TCL_CONTINUE) && (code != TCL_BREAK)) { Tcl_AddErrorInfo(interp, "\n (menu preprocess)"); - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, code); } Tcl_Release((ClientData)interp); } @@ -1117,7 +1112,7 @@ TkWinHandleMenuEvent( if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) { for (parentEntryPtr = menuRefPtr->parentEntryPtr ; ; parentEntryPtr = parentEntryPtr->nextCascadePtr) { - char *name = Tcl_GetString(parentEntryPtr->namePtr); + const char *name = Tcl_GetString(parentEntryPtr->namePtr); if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) { break; @@ -1135,7 +1130,7 @@ TkWinHandleMenuEvent( 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_BackgroundException(interp, code); } Tcl_Release((ClientData)interp); *plResult = 0; @@ -1218,7 +1213,7 @@ TkWinHandleMenuEvent( } mePtr = (TkMenuEntry *) itemPtr->itemData; menuPtr = mePtr->menuPtr; - twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable)); + twdPtr = ckalloc(sizeof(TkWinDrawable)); twdPtr->type = TWD_WINDC; twdPtr->winDC.hdc = itemPtr->hDC; @@ -1261,7 +1256,7 @@ TkWinHandleMenuEvent( itemPtr->rcItem.bottom - itemPtr->rcItem.top, 0, drawingParameters); - ckfree((char *) twdPtr); + ckfree(twdPtr); } *plResult = 1; returnResult = 1; @@ -1309,7 +1304,7 @@ TkWinHandleMenuEvent( TkActivateMenuEntry(menuPtr, -1); } else { if (mePtr->index >= menuPtr->numEntries) { - Tcl_Panic("Trying to activate an entry which doesn't exist."); + Tcl_Panic("Trying to activate an entry which doesn't exist"); } TkActivateMenuEntry(menuPtr, mePtr->index); } @@ -1404,7 +1399,7 @@ TkpSetWindowMenuBar( winMenuHdl = CreateMenu(); hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, (char *) winMenuHdl, &newEntry); - Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr); + Tcl_SetHashValue(hashEntryPtr, menuPtr); menuPtr->platformData = (TkMenuPlatformData) winMenuHdl; TkWinSetMenu(tkwin, winMenuHdl); if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { @@ -1437,7 +1432,7 @@ 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 + const char *menuName) /* The name of the menu to put in front. If * NULL, use the default menu bar. */ { /* @@ -1513,7 +1508,7 @@ GetMenuAccelGeometry( } else if (mePtr->accelPtr == NULL) { *widthPtr = 0; } else { - char *accel = Tcl_GetString(mePtr->accelPtr); + const char *accel = Tcl_GetString(mePtr->accelPtr); *widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength); } @@ -1628,7 +1623,7 @@ DrawWindowsSystemBitmap( SelectObject(scratchDC, bitmap); SetMapMode(scratchDC, GetMapMode(hdc)); - GetObject(bitmap, sizeof(BITMAP), &bm); + GetObjectA(bitmap, sizeof(BITMAP), &bm); ptSize.x = bm.bmWidth; ptSize.y = bm.bmHeight; DPtoLP(scratchDC, &ptSize, 1); @@ -1769,7 +1764,7 @@ DrawMenuEntryAccelerator( { int baseline; int leftEdge = x + mePtr->indicatorSpace + mePtr->labelWidth; - char *accel; + const char *accel; if (mePtr->accelPtr != NULL) { accel = Tcl_GetString(mePtr->accelPtr); @@ -2028,33 +2023,33 @@ TkWinMenuKeyObjCmd( if (eventPtr->type == KeyPress) { switch (keySym) { case XK_Alt_L: - scanCode = MapVirtualKey(VK_LMENU, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), + scanCode = MapVirtualKeyA(VK_LMENU, 0); + CallWindowProcA(DefWindowProcA, Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSKEYDOWN, VK_MENU, (int) (scanCode << 16) | (1 << 29)); break; case XK_Alt_R: - scanCode = MapVirtualKey(VK_RMENU, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), + scanCode = MapVirtualKeyA(VK_RMENU, 0); + CallWindowProcA(DefWindowProcA, Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSKEYDOWN, VK_MENU, (int) (scanCode << 16) | (1 << 29) | (1 << 24)); break; case XK_F10: - scanCode = MapVirtualKey(VK_F10, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), + scanCode = MapVirtualKeyA(VK_F10, 0); + CallWindowProcA(DefWindowProcA, Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSKEYDOWN, VK_F10, (int) (scanCode << 16)); break; default: virtualKey = XKeysymToKeycode(winPtr->display, keySym); - scanCode = MapVirtualKey(virtualKey, 0); + scanCode = MapVirtualKeyA(virtualKey, 0); if (0 != scanCode) { XKeyEvent xkey = eventPtr->xkey; - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), + CallWindowProcA(DefWindowProcA, Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSKEYDOWN, virtualKey, (int) ((scanCode << 16) | (1 << 29))); if (xkey.nbytes > 0) { for (i = 0; i < xkey.nbytes; i++) { - CallWindowProc(DefWindowProc, + CallWindowProcA(DefWindowProcA, Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR, xkey.trans_chars[i], (int) ((scanCode << 16) | (1 << 29))); @@ -2065,28 +2060,28 @@ TkWinMenuKeyObjCmd( } else if (eventPtr->type == KeyRelease) { switch (keySym) { case XK_Alt_L: - scanCode = MapVirtualKey(VK_LMENU, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), + scanCode = MapVirtualKeyA(VK_LMENU, 0); + CallWindowProcA(DefWindowProcA, Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16) | (1 << 29) | (1 << 30) | (1 << 31)); break; case XK_Alt_R: - scanCode = MapVirtualKey(VK_RMENU, 0); - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), + scanCode = MapVirtualKeyA(VK_RMENU, 0); + CallWindowProcA(DefWindowProcA, Tk_GetHWND(Tk_WindowId(tkwin)), 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)), + scanCode = MapVirtualKeyA(VK_F10, 0); + CallWindowProcA(DefWindowProcA, Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSKEYUP, VK_F10, (int) (scanCode << 16) | (1 << 30) | (1 << 31)); break; default: virtualKey = XKeysymToKeycode(winPtr->display, keySym); - scanCode = MapVirtualKey(virtualKey, 0); + scanCode = MapVirtualKeyA(virtualKey, 0); if (0 != scanCode) { - CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), + CallWindowProcA(DefWindowProcA, Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSKEYUP, virtualKey, (int) ((scanCode << 16) | (1 << 29) | (1 << 30) | (1 << 31))); } @@ -2217,7 +2212,7 @@ DrawMenuEntryLabel( } if (!haveImage || (mePtr->compound != COMPOUND_NONE)) { if (mePtr->labelLength > 0) { - char *label = Tcl_GetString(mePtr->labelPtr); + const char *label = Tcl_GetString(mePtr->labelPtr); textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); textHeight = fmPtr->linespace; @@ -2312,7 +2307,7 @@ DrawMenuEntryLabel( if ((mePtr->compound != COMPOUND_NONE) || !haveImage) { if (mePtr->labelLength > 0) { int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - char *label = Tcl_GetString(mePtr->labelPtr); + const char *label = Tcl_GetString(mePtr->labelPtr); if (TkWinGetPlatformTheme() == TK_THEME_WIN_CLASSIC) { /* @@ -2548,7 +2543,7 @@ TkpDrawMenuEntry( } else { TkMenuEntry *cascadeEntryPtr; int parentDisabled = 0; - char *name; + const char *name; for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr; cascadeEntryPtr != NULL; @@ -2694,7 +2689,7 @@ GetMenuLabelGeometry( if (mePtr->labelPtr != NULL) { int textWidth; - char *label = Tcl_GetString(mePtr->labelPtr); + const char *label = Tcl_GetString(mePtr->labelPtr); textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); @@ -3024,7 +3019,7 @@ MenuSelectEvent( void TkpMenuNotifyToplevelCreate( Tcl_Interp *interp, /* The interp the menu lives in. */ - char *menuName) /* The name of the menu to reconfigure. */ + const char *menuName) /* The name of the menu to reconfigure. */ { TkMenuReferences *menuRefPtr; TkMenu *menuPtr; @@ -3195,7 +3190,7 @@ SetDefaults( HDC scratchDC; int bold = 0; int italic = 0; - TEXTMETRIC tm; + TEXTMETRICA tm; int pointSize; HFONT menuFont; /* See: [Bug #3239768] tk8.4.19 (and later) WIN32 menu font support */ @@ -3217,7 +3212,7 @@ SetDefaults( defaultBorderWidth = GetSystemMetrics(SM_CYBORDER); } - scratchDC = CreateDC("DISPLAY", NULL, NULL, NULL); + scratchDC = CreateDCA("DISPLAY", NULL, NULL, NULL); if (!firstTime) { Tcl_DStringFree(&menuFontDString); } @@ -3235,8 +3230,8 @@ SetDefaults( &nc.metrics, 0); menuFont = CreateFontIndirect(&nc.metrics.lfMenuFont); SelectObject(scratchDC, menuFont); - GetTextMetrics(scratchDC, &tm); - GetTextFace(scratchDC, LF_FACESIZE, faceName); + GetTextMetricsA(scratchDC, &tm); + GetTextFaceA(scratchDC, LF_FACESIZE, faceName); pointSize = MulDiv(tm.tmHeight - tm.tmInternalLeading, 72, GetDeviceCaps(scratchDC, LOGPIXELSY)); if (tm.tmWeight >= 700) { @@ -3279,17 +3274,11 @@ SetDefaults( * 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_CXMENUCHECK) + 7) & 0xFFF8) - - GetSystemMetrics(SM_CXFIXEDFRAME); - } else { - DWORD dimensions = GetMenuCheckMarkDimensions(); - indicatorDimensions[0] = HIWORD(dimensions); - indicatorDimensions[1] = LOWORD(dimensions); - } + indicatorDimensions[0] = GetSystemMetrics(SM_CYMENUCHECK); + indicatorDimensions[1] = ((GetSystemMetrics(SM_CXFIXEDFRAME) + + GetSystemMetrics(SM_CXBORDER) + + GetSystemMetrics(SM_CXMENUCHECK) + 7) & 0xFFF8) + - GetSystemMetrics(SM_CXFIXEDFRAME); /* * Accelerators used to be always underlines until Win2K when a system @@ -3298,7 +3287,7 @@ SetDefaults( showMenuAccelerators = TRUE; if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &showMenuAccelerators, 0); + SystemParametersInfoA(SPI_GETKEYBOARDCUES, 0, &showMenuAccelerators, 0); } } @@ -3334,13 +3323,13 @@ TkpMenuInit(void) wndClass.lpszMenuName = NULL; wndClass.lpszClassName = MENU_CLASS_NAME; if (!RegisterClass(&wndClass)) { - Tcl_Panic("Failed to register menu window class."); + 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."); + Tcl_Panic("Failed to register embedded menu window class"); } TkCreateExitHandler(MenuExitHandler, (ClientData) NULL); @@ -3370,19 +3359,19 @@ TkpMenuThreadInit(void) ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - tsdPtr->menuHWND = CreateWindow(MENU_CLASS_NAME, "MenuWindow", WS_POPUP, + tsdPtr->menuHWND = CreateWindow(MENU_CLASS_NAME, TEXT("MenuWindow"), WS_POPUP, 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL); if (!tsdPtr->menuHWND) { - Tcl_Panic("Failed to create the menu window."); + Tcl_Panic("Failed to create the menu window"); } tsdPtr->embeddedMenuHWND = - CreateWindow(EMBEDDED_MENU_CLASS_NAME, "EmbeddedMenuWindow", + CreateWindow(EMBEDDED_MENU_CLASS_NAME, TEXT("EmbeddedMenuWindow"), WS_POPUP, 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL); if (!tsdPtr->embeddedMenuHWND) { - Tcl_Panic("Failed to create the embedded menu window."); + Tcl_Panic("Failed to create the embedded menu window"); } Tcl_InitHashTable(&tsdPtr->winMenuTable, TCL_ONE_WORD_KEYS); diff --git a/win/tkWinPixmap.c b/win/tkWinPixmap.c index 51f0f59..1cf0634 100644 --- a/win/tkWinPixmap.c +++ b/win/tkWinPixmap.c @@ -42,7 +42,7 @@ Tk_GetPixmap( display->request++; - newTwdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable)); + newTwdPtr = ckalloc(sizeof(TkWinDrawable)); newTwdPtr->type = TWD_BITMAP; newTwdPtr->bitmap.depth = depth; twdPtr = (TkWinDrawable *) d; @@ -100,12 +100,12 @@ Tk_GetPixmap( LPVOID lpMsgBuf; repeatError = 1; - if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, 0, NULL)) { - MessageBox(NULL, (LPCTSTR) lpMsgBuf, + (LPSTR) &lpMsgBuf, 0, NULL)) { + MessageBoxA(NULL, (LPCSTR) lpMsgBuf, "Tk_GetPixmap: Error from CreateDIBSection", MB_OK | MB_ICONINFORMATION); LocalFree(lpMsgBuf); @@ -114,7 +114,7 @@ Tk_GetPixmap( } if (newTwdPtr->bitmap.handle == NULL) { - ckfree((char *) newTwdPtr); + ckfree(newTwdPtr); return None; } @@ -147,7 +147,7 @@ Tk_FreePixmap( display->request++; if (twdPtr != NULL) { DeleteObject(twdPtr->bitmap.handle); - ckfree((char *) twdPtr); + ckfree(twdPtr); } } diff --git a/win/tkWinPointer.c b/win/tkWinPointer.c index d29e952..c3b3d3c 100644 --- a/win/tkWinPointer.c +++ b/win/tkWinPointer.c @@ -360,6 +360,20 @@ XWarpPointer( GetWindowRect(Tk_GetHWND(dest_w), &r); SetCursorPos(r.left+dest_x, r.top+dest_y); } + +void +TkpWarpPointer( + TkDisplay *dispPtr) +{ + if (dispPtr->warpWindow) { + RECT r; + + GetWindowRect(Tk_GetHWND(Tk_WindowId(dispPtr->warpWindow)), &r); + SetCursorPos(r.left + dispPtr->warpX, r.top + dispPtr->warpY); + } else { + SetCursorPos(dispPtr->warpX, dispPtr->warpY); + } +} /* *---------------------------------------------------------------------- diff --git a/win/tkWinPort.h b/win/tkWinPort.h index 907412b..1b999ab 100644 --- a/win/tkWinPort.h +++ b/win/tkWinPort.h @@ -14,21 +14,23 @@ #ifndef _WINPORT #define _WINPORT -#include <X11/Xlib.h> -#include <X11/cursorfont.h> -#include <X11/keysym.h> -#include <X11/Xatom.h> -#include <X11/Xutil.h> +/* + *--------------------------------------------------------------------------- + * The following sets of #includes and #ifdefs are required to get Tcl to + * compile under the windows compilers. + *--------------------------------------------------------------------------- + */ -#include <malloc.h> +#include <wchar.h> +#include <io.h> +#include <stdlib.h> #include <errno.h> +#include <fcntl.h> +#include <malloc.h> #include <ctype.h> #include <math.h> -#include <stdlib.h> #include <string.h> #include <limits.h> -#include <fcntl.h> -#include <io.h> /* * Need to block out this include for building extensions with MetroWerks @@ -61,6 +63,11 @@ typedef _TCHAR TCHAR; #endif +#include <X11/Xlib.h> +#include <X11/cursorfont.h> +#include <X11/keysym.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> #ifndef __GNUC__ # define strncasecmp strnicmp @@ -103,7 +110,7 @@ * The following functions are implemented as macros under Windows. */ -#define XFree(data) {if ((data) != NULL) ckfree((char *) (data));} +#define XFree(data) {if ((data) != NULL) ckfree(data);} #define XNoOp(display) {display->request++;} #define XSynchronize(display, bool) {display->request++;} #define XSync(display, bool) {display->request++;} diff --git a/win/tkWinScrlbr.c b/win/tkWinScrlbr.c index 5032912..1fd5e13 100644 --- a/win/tkWinScrlbr.c +++ b/win/tkWinScrlbr.c @@ -52,27 +52,17 @@ typedef struct WinScrollbar { static int initialized = 0; static int hArrowWidth, hThumb; /* Horizontal control metrics. */ -static int vArrowWidth, vArrowHeight, vThumb; /* Vertical control metrics. */ +static int 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. - */ - -static char defWidth[TCL_INTEGER_SPACE]; - -/* * Declarations for functions defined in this file. */ 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 void ModalLoop(WinScrollbar *, XEvent *eventPtr); static LRESULT CALLBACK ScrollbarProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); static void UpdateScrollbar(WinScrollbar *scrollPtr); @@ -82,13 +72,25 @@ static void UpdateScrollbarMetrics(void); * The class procedure table for the scrollbar widget. */ -Tk_ClassProcs tkpScrollbarProcs = { +const Tk_ClassProcs tkpScrollbarProcs = { sizeof(Tk_ClassProcs), /* size */ NULL, /* worldChangedProc */ CreateProc, /* createProc */ - ModalLoopProc, /* modalProc */ + NULL /* modalProc */ }; +static void +WinScrollbarEventProc(ClientData clientData, XEvent *eventPtr) +{ + WinScrollbar *scrollPtr = clientData; + + if (eventPtr->type == ButtonPress) { + ModalLoop(scrollPtr, eventPtr); + } else { + TkScrollbarEventProc(clientData, eventPtr); + } +} + /* *---------------------------------------------------------------------- @@ -111,7 +113,6 @@ TkpCreateScrollbar( Tk_Window tkwin) { WinScrollbar *scrollPtr; - TkWindow *winPtr = (TkWindow *)tkwin; if (!initialized) { Tcl_MutexLock(&winScrlbrMutex); @@ -120,22 +121,13 @@ TkpCreateScrollbar( Tcl_MutexUnlock(&winScrlbrMutex); } - scrollPtr = (WinScrollbar *) ckalloc(sizeof(WinScrollbar)); + scrollPtr = ckalloc(sizeof(WinScrollbar)); scrollPtr->winFlags = 0; scrollPtr->hwnd = NULL; Tk_CreateEventHandler(tkwin, - ExposureMask|StructureNotifyMask|FocusChangeMask, - TkScrollbarEventProc, (ClientData) scrollPtr); - - if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) { - Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL, - (ClientData)1); - TkCreateBindingProcedure(winPtr->mainPtr->interp, - winPtr->mainPtr->bindingTable, - (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>", - ScrollbarBindProc, NULL, NULL); - } + ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask, + WinScrollbarEventProc, scrollPtr); return (TkScrollbar *) scrollPtr; } @@ -231,7 +223,7 @@ CreateProc( | SBS_HORZ | SBS_BOTTOMALIGN; } - scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style, + scrollPtr->hwnd = CreateWindow(TEXT("SCROLLBAR"), NULL, style, Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), parent, NULL, Tk_GetHINSTANCE(), NULL); @@ -254,7 +246,7 @@ CreateProc( scrollPtr->lastVertical = scrollPtr->info.vertical; scrollPtr->oldProc = (WNDPROC)SetWindowLongPtr(scrollPtr->hwnd, - GWLP_WNDPROC, (INT_PTR) ScrollbarProc); + GWLP_WNDPROC, (LONG_PTR) ScrollbarProc); window = Tk_AttachHWND(tkwin, scrollPtr->hwnd); UpdateScrollbar(scrollPtr); @@ -299,7 +291,7 @@ TkpDisplayScrollbar( if (scrollPtr->lastVertical != scrollPtr->info.vertical) { HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin)); - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) scrollPtr->oldProc); + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) scrollPtr->oldProc); DestroyWindow(hwnd); CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)), @@ -361,21 +353,14 @@ TkpDestroyScrollbar( void UpdateScrollbarMetrics(void) { - Tk_ConfigSpec *specPtr; + int arrowWidth = GetSystemMetrics(SM_CXVSCROLL); hArrowWidth = GetSystemMetrics(SM_CXHSCROLL); hThumb = GetSystemMetrics(SM_CXHTHUMB); - vArrowWidth = GetSystemMetrics(SM_CXVSCROLL); vArrowHeight = GetSystemMetrics(SM_CYVSCROLL); vThumb = GetSystemMetrics(SM_CYVTHUMB); - sprintf(defWidth, "%d", vArrowWidth); - for (specPtr = tkpScrollbarConfigSpecs; specPtr->type != TK_CONFIG_END; - specPtr++) { - if (specPtr->offset == Tk_Offset(TkScrollbar, width)) { - specPtr->defValue = defWidth; - } - } + sprintf(tkDefScrollbarWidth, "%d", arrowWidth); } /* @@ -570,7 +555,7 @@ ScrollbarProc( 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_BackgroundException(interp, code); } Tcl_DStringFree(&cmdString); @@ -613,66 +598,26 @@ TkpConfigureScrollbar( } /* - *-------------------------------------------------------------- - * - * ScrollbarBindProc -- - * - * This procedure is invoked when the default <ButtonPress> binding on - * the Scrollbar bind tag fires. - * - * Results: - * None. - * - * Side effects: - * The event enters a modal loop. - * - *-------------------------------------------------------------- - */ - -static int -ScrollbarBindProc( - ClientData clientData, - Tcl_Interp *interp, - XEvent *eventPtr, - Tk_Window tkwin, - KeySym keySym) -{ - TkWindow *winPtr = (TkWindow *) tkwin; - - if (eventPtr->type == ButtonPress) { - winPtr->flags |= TK_DEFER_MODAL; - } - return TCL_OK; -} - -/* *---------------------------------------------------------------------- * - * ModalLoopProc -- - * - * This function is invoked at the end of the event processing whenever - * the ScrollbarBindProc has been invoked for a ButtonPress event. + * ModalLoop -- * - * Results: - * None. - * - * Side effects: - * Enters a modal loop. + * This function is invoked in response to a ButtonPress event. + * It resends the event to the Scrollbar window procedure, + * which in turn enters a modal loop. * *---------------------------------------------------------------------- */ static void -ModalLoopProc( - Tk_Window tkwin, +ModalLoop( + WinScrollbar *scrollPtr, XEvent *eventPtr) { - TkWindow *winPtr = (TkWindow *) tkwin; - WinScrollbar *scrollPtr = (WinScrollbar *) winPtr->instanceData; int oldMode; if (scrollPtr->hwnd) { - Tcl_Preserve(scrollPtr); + Tcl_Preserve((ClientData)scrollPtr); scrollPtr->winFlags |= IN_MODAL_LOOP; oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr); @@ -681,7 +626,7 @@ ModalLoopProc( if (scrollPtr->hwnd && scrollPtr->winFlags & ALREADY_DEAD) { DestroyWindow(scrollPtr->hwnd); } - Tcl_Release(scrollPtr); + Tcl_Release((ClientData)scrollPtr); } } diff --git a/win/tkWinSend.c b/win/tkWinSend.c index 4b25963..b3edc62 100644 --- a/win/tkWinSend.c +++ b/win/tkWinSend.c @@ -14,10 +14,6 @@ #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. */ @@ -169,7 +165,7 @@ Tk_SetAppName( if (riPtr == NULL) { LPUNKNOWN *objPtr; - riPtr = (RegisteredInterp *) ckalloc(sizeof(RegisteredInterp)); + riPtr = ckalloc(sizeof(RegisteredInterp)); memset(riPtr, 0, sizeof(RegisteredInterp)); riPtr->interp = interp; @@ -326,7 +322,7 @@ Tk_SendObjCmd( enum { SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST }; - static const char *sendOptions[] = { + static const char *const sendOptions[] = { "-async", "-displayof", "--", NULL }; int result = TCL_OK; @@ -367,9 +363,8 @@ Tk_SendObjCmd( */ if (displayPtr) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - "option not implemented: \"displayof\" is not available " - "for this platform.", -1); + Tcl_SetResult(interp, "option not implemented: \"displayof\" is " + "not available for this platform.", TCL_STATIC); result = TCL_ERROR; } @@ -379,6 +374,7 @@ Tk_SendObjCmd( /* 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++; @@ -791,7 +787,7 @@ Send( if (ei.bstrSource != NULL) { int len; - char *szErrorInfo; + const char *szErrorInfo; opError = Tcl_NewUnicodeObj(ei.bstrSource, -1); Tcl_ListObjIndex(interp, opError, 0, &opErrorCode); @@ -839,9 +835,9 @@ Win32ErrorObj( 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); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)hrError, + LANG_NEUTRAL, (LPTSTR)&lpBuffer, 0, NULL); if (lpBuffer == NULL) { lpBuffer = sBuffer; @@ -955,7 +951,7 @@ TkWinSend_QueueCommand( TRACE("SendQueueCommand()\n"); - evPtr = (SendEvent *)ckalloc(sizeof(SendEvent)); + evPtr = ckalloc(sizeof(SendEvent)); evPtr->header.proc = SendEventProc; evPtr->header.nextPtr = NULL; evPtr->interp = interp; @@ -1035,8 +1031,8 @@ SendTrace( static char buffer[1024]; va_start(args, format); - vsnprintf(buffer, 1023, format, args); - OutputDebugString(buffer); + _vsnprintf(buffer, 1023, format, args); + OutputDebugStringA(buffer); va_end(args); } diff --git a/win/tkWinSendCom.c b/win/tkWinSendCom.c index 3bbdd63..c67e533 100644 --- a/win/tkWinSendCom.c +++ b/win/tkWinSendCom.c @@ -378,8 +378,8 @@ Async( hr = VariantChangeType(&vCmd, &Cmd, 0, VT_BSTR); if (FAILED(hr)) { - Tcl_SetStringObj(Tcl_GetObjResult(obj->interp), - "invalid args: Async(command)", -1); + Tcl_SetObjResult(obj->interp, Tcl_NewStringObj( + "invalid args: Async(command)", -1)); SetExcepInfo(obj->interp, pExcepInfo); hr = DISP_E_EXCEPTION; } @@ -387,13 +387,13 @@ Async( if (SUCCEEDED(hr)) { if (obj->interp) { Tcl_Obj *scriptPtr = Tcl_NewUnicodeObj(vCmd.bstrVal, - (int)SysStringLen(vCmd.bstrVal)); + (int) SysStringLen(vCmd.bstrVal)); + TkWinSend_QueueCommand(obj->interp, scriptPtr); } } VariantClear(&vCmd); - return hr; } diff --git a/win/tkWinTest.c b/win/tkWinTest.c index d361ad7..d7d4d0f 100644 --- a/win/tkWinTest.c +++ b/win/tkWinTest.c @@ -12,6 +12,10 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ +#undef USE_TCL_STUBS +#define USE_TCL_STUBS +#undef USE_TK_STUBS +#define USE_TK_STUBS #include "tkWinInt.h" HWND tkWinCurrentDialog; @@ -22,21 +26,20 @@ HWND tkWinCurrentDialog; static int TestclipboardObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static int TestwineventCmd(ClientData clientData, - Tcl_Interp *interp, int argc, CONST char **argv); + Tcl_Interp *interp, int argc, const char **argv); static int TestfindwindowObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static int TestgetwindowinfoObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]); + 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); +static Tk_GetSelProc SetSelectionResult; - /* *---------------------------------------------------------------------- * @@ -99,12 +102,16 @@ AppendSystemError( { int length; WCHAR *wMsgPtr, **wMsgPtrPtr = &wMsgPtr; - char *msg; + const char *msg; char id[TCL_INTEGER_SPACE], msgBuf[24 + TCL_INTEGER_SPACE]; Tcl_DString ds; Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); - length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM + if (Tcl_IsShared(resultPtr)) { + resultPtr = Tcl_DuplicateObj(resultPtr); + } + length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) wMsgPtrPtr, 0, NULL); @@ -112,6 +119,7 @@ AppendSystemError( char *msgPtr; length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &msgPtr, 0, NULL); @@ -124,36 +132,41 @@ AppendSystemError( } if (length == 0) { if (error == ERROR_CALL_NOT_IMPLEMENTED) { - msg = "function not supported under Win32s"; + strcpy(msgBuf, "function not supported under Win32s"); } else { sprintf(msgBuf, "unknown error: %ld", error); - msg = msgBuf; } + msg = msgBuf; } else { Tcl_Encoding encoding; + char *msgPtr; encoding = Tcl_GetEncoding(NULL, "unicode"); - msg = Tcl_ExternalToUtfDString(encoding, (char *) wMsgPtr, -1, &ds); + Tcl_ExternalToUtfDString(encoding, (char *) wMsgPtr, -1, &ds); Tcl_FreeEncoding(encoding); LocalFree(wMsgPtr); + msgPtr = Tcl_DStringValue(&ds); length = Tcl_DStringLength(&ds); /* * Trim the trailing CR/LF from the system message. */ - if (msg[length-1] == '\n') { - msg[--length] = 0; + if (msgPtr[length-1] == '\n') { + --length; } - if (msg[length-1] == '\r') { - msg[--length] = 0; + if (msgPtr[length-1] == '\r') { + --length; } + msgPtr[length] = 0; + msg = msgPtr; } sprintf(id, "%ld", error); Tcl_SetErrorCode(interp, "WINDOWS", id, msg, NULL); Tcl_AppendToObj(resultPtr, msg, length); + Tcl_SetObjResult(interp, resultPtr); if (length != 0) { Tcl_DStringFree(&ds); @@ -178,44 +191,30 @@ AppendSystemError( */ static int +SetSelectionResult( + ClientData dummy, + Tcl_Interp *interp, + const char *selection) +{ + Tcl_AppendResult(interp, selection, NULL); + return TCL_OK; +} + +static int TestclipboardObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument values. */ + Tcl_Obj *const objv[]) /* Argument values. */ { - HGLOBAL handle; - char *data; - int code = TCL_OK; + Tk_Window tkwin = (Tk_Window) clientData; if (objc != 1) { 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 - */ - - handle = GetClipboardData(CF_TEXT); - if (handle != NULL) { - data = GlobalLock(handle); - Tcl_AppendResult(interp, data, NULL); - GlobalUnlock(handle); - } else { - Tcl_AppendResult(interp, "null clipboard handle", NULL); - code = TCL_ERROR; - } - CloseClipboard(); - return code; - } else { - Tcl_AppendResult(interp, "couldn't open clipboard: ", NULL); - AppendSystemError(interp, GetLastError()); - return TCL_ERROR; - } - return TCL_OK; + return TkSelGetSelection(interp, tkwin, Tk_InternAtom(tkwin, "CLIPBOARD"), + XA_STRING, SetSelectionResult, NULL); } /* @@ -240,7 +239,7 @@ TestwineventCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ - CONST char **argv) /* Argument strings. */ + const char **argv) /* Argument strings. */ { HWND hwnd = 0; HWND child = 0; @@ -273,9 +272,19 @@ TestwineventCmd( return TCL_ERROR; } - hwnd = (HWND) INT2PTR(strtol(argv[1], &rest, 0)); +#if 0 + TkpScanWindowId(interp, argv[1], &id); + if ( +#ifdef _WIN64 + (sscanf(string, "0x%p", &number) != 1) && +#endif /* _WIN64 */ + Tcl_GetInt(interp, string, (int *)&number) != TCL_OK) { + return TCL_ERROR; + } +#endif + hwnd = INT2PTR(strtol(argv[1], &rest, 0)); if (rest == argv[1]) { - hwnd = FindWindow(NULL, argv[1]); + hwnd = FindWindowA(NULL, argv[1]); if (hwnd == NULL) { Tcl_SetResult(interp, "no such window", TCL_STATIC); return TCL_ERROR; @@ -289,7 +298,7 @@ TestwineventCmd( child = GetWindow(hwnd, GW_CHILD); while (child != NULL) { - SendMessage(child, WM_GETTEXT, (WPARAM) sizeof(buf), (LPARAM) buf); + SendMessageA(child, WM_GETTEXT, (WPARAM) sizeof(buf), (LPARAM) buf); if (strcasecmp(buf, argv[2]) == 0) { id = GetDlgCtrlID(child); break; @@ -318,7 +327,7 @@ TestwineventCmd( Tcl_DString ds; char buf[256]; - GetDlgItemText(hwnd, id, buf, 256); + GetDlgItemTextA(hwnd, id, buf, 256); Tcl_ExternalToUtfDString(NULL, buf, -1, &ds); Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL); Tcl_DStringFree(&ds); @@ -328,7 +337,7 @@ TestwineventCmd( Tcl_DString ds; Tcl_UtfToExternalDString(NULL, argv[4], -1, &ds); - SetDlgItemText(hwnd, id, Tcl_DStringValue(&ds)); + SetDlgItemTextA(hwnd, id, Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); break; } @@ -338,7 +347,7 @@ TestwineventCmd( wParam = MAKEWPARAM(id, 0); lParam = (LPARAM)child; } - sprintf(buf, "%d", (int) SendMessage(hwnd, message, wParam, lParam)); + sprintf(buf, "%d", (int) SendMessageA(hwnd, message, wParam, lParam)); Tcl_SetResult(interp, buf, TCL_VOLATILE); break; } @@ -346,7 +355,7 @@ TestwineventCmd( char buf[TCL_INTEGER_SPACE]; sprintf(buf, "%d", - (int) SendDlgItemMessage(hwnd, id, message, wParam, lParam)); + (int) SendDlgItemMessageA(hwnd, id, message, wParam, lParam)); Tcl_SetResult(interp, buf, TCL_VOLATILE); break; } @@ -357,7 +366,7 @@ TestwineventCmd( /* * 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 + * 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. @@ -370,20 +379,27 @@ TestfindwindowObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument values. */ + Tcl_Obj *const objv[]) /* Argument values. */ { - const char *title = NULL, *class = NULL; + const TCHAR *title = NULL, *class = NULL; + Tcl_DString titleString, classString; HWND hwnd = NULL; int r = TCL_OK; + Tcl_DStringInit(&classString); + Tcl_DStringInit(&titleString); + 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); + + title = Tcl_WinUtfToTChar(Tcl_GetString(objv[1]), -1, &titleString); + if (objc == 3) { + class = Tcl_WinUtfToTChar(Tcl_GetString(objv[2]), -1, &classString); + } + + hwnd = FindWindow(class, title); if (hwnd == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to find window: ", -1)); @@ -392,14 +408,20 @@ TestfindwindowObjCmd( } else { Tcl_SetObjResult(interp, Tcl_NewLongObj(PTR2INT(hwnd))); } + + Tcl_DStringFree(&titleString); + Tcl_DStringFree(&classString); return r; - + } static BOOL CALLBACK -EnumChildrenProc(HWND hwnd, LPARAM lParam) +EnumChildrenProc( + HWND hwnd, + LPARAM lParam) { - Tcl_Obj *listObj = (Tcl_Obj *)lParam; + Tcl_Obj *listObj = (Tcl_Obj *) lParam; + Tcl_ListObjAppendElement(NULL, listObj, Tcl_NewLongObj(PTR2INT(hwnd))); return TRUE; } @@ -409,13 +431,13 @@ TestgetwindowinfoObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]) + Tcl_Obj *const objv[]) { long hwnd; - Tcl_Obj *resObj = NULL, *classObj = NULL, *textObj = NULL; + Tcl_Obj *dictObj = NULL, *classObj = NULL, *textObj = NULL; Tcl_Obj *childrenObj = NULL; - char buf[512]; - int cch, cchBuf = tkWinProcs->useWide ? 256 : 512; + TCHAR buf[512]; + int cch, cchBuf = 256; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "hwnd"); @@ -424,49 +446,38 @@ TestgetwindowinfoObjCmd( if (Tcl_GetLongFromObj(interp, objv[1], &hwnd) != TCL_OK) return TCL_ERROR; - - if (tkWinProcs->useWide) { - cch = GetClassNameW(INT2PTR(hwnd), (LPWSTR)buf, sizeof(buf)/sizeof(WCHAR)); - classObj = Tcl_NewUnicodeObj((LPWSTR)buf, cch); - } else { - cch = GetClassNameA(INT2PTR(hwnd), (LPSTR)buf, sizeof(buf)); - classObj = Tcl_NewStringObj((LPSTR)buf, cch); - } + + cch = GetClassName(INT2PTR(hwnd), buf, cchBuf); 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(INT2PTR(hwnd), GWL_ID))); - - cch = tkWinProcs->getWindowText(INT2PTR(hwnd), (LPTSTR)buf, cchBuf); - if (tkWinProcs->useWide) { - textObj = Tcl_NewUnicodeObj((LPCWSTR)buf, cch); } else { - textObj = Tcl_NewStringObj((LPCSTR)buf, cch); + Tcl_DString ds; + Tcl_WinTCharToUtf(buf, -1, &ds); + classObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); } - 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(PTR2INT(GetParent(INT2PTR(hwnd))))); + dictObj = Tcl_NewDictObj(); + Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("class", 5), classObj); + Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("id", 2), + Tcl_NewLongObj(GetWindowLongA(INT2PTR(hwnd), GWL_ID))); + + cch = GetWindowText(INT2PTR(hwnd), (LPTSTR)buf, cchBuf); + textObj = Tcl_NewUnicodeObj((LPCWSTR)buf, cch); + + Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("text", 4), textObj); + Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("parent", 6), + Tcl_NewLongObj(PTR2INT(GetParent((INT2PTR(hwnd)))))); childrenObj = Tcl_NewListObj(0, NULL); EnumChildWindows(INT2PTR(hwnd), EnumChildrenProc, (LPARAM)childrenObj); - Tcl_ListObjAppendElement(interp, resObj, Tcl_NewStringObj("children", -1)); - Tcl_ListObjAppendElement(interp, resObj, childrenObj); + Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("children", -1), childrenObj); - Tcl_SetObjResult(interp, resObj); + Tcl_SetObjResult(interp, dictObj); return TCL_OK; -} +} static int TestwinlocaleObjCmd( @@ -479,7 +490,7 @@ TestwinlocaleObjCmd( Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } - Tcl_SetObjResult(interp, Tcl_NewIntObj((int)GetSystemDefaultLCID())); + Tcl_SetObjResult(interp, Tcl_NewIntObj((int)GetThreadLocale())); return TCL_OK; } diff --git a/win/tkWinWindow.c b/win/tkWinWindow.c index 43ff0aa..ca966fd 100644 --- a/win/tkWinWindow.c +++ b/win/tkWinWindow.c @@ -11,6 +11,7 @@ */ #include "tkWinInt.h" +#include "tkBusy.h" typedef struct ThreadSpecificData { int initialized; /* 0 means table below needs initializing. */ @@ -65,7 +66,7 @@ Tk_AttachHWND( */ if (twdPtr == NULL) { - twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable)); + twdPtr = ckalloc(sizeof(TkWinDrawable)); twdPtr->type = TWD_WINDOW; twdPtr->window.winPtr = (TkWindow *) tkwin; } else if (twdPtr->window.handle != NULL) { @@ -80,7 +81,7 @@ Tk_AttachHWND( twdPtr->window.handle = hwnd; entryPtr = Tcl_CreateHashEntry(&tsdPtr->windowTable, (char *)hwnd, &new); - Tcl_SetHashValue(entryPtr, (ClientData)tkwin); + Tcl_SetHashValue(entryPtr, tkwin); return (Window)twdPtr; } @@ -172,12 +173,13 @@ TkpPrintWindowId( /* * 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. + * Bug 2026405: cygwin does output 0x for %p so test and recover. */ sprintf(buf, "0x%p", hwnd); - if (buf[2] == '0' && buf[3] == 'x') + if (buf[2] == '0' && buf[3] == 'x') { sprintf(buf, "%p", hwnd); + } } /* @@ -204,12 +206,15 @@ TkpPrintWindowId( int TkpScanWindowId( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ - CONST char *string, /* String containing a (possibly signed) + const char *string, /* String containing a (possibly signed) * integer in a form acceptable to strtol. */ Window *idPtr) /* Place to store converted result. */ { Tk_Window tkwin; - void *number, *numberPtr = &number; + union { + HWND hwnd; + int number; + } win; /* * We want sscanf for the 64-bit check, but if that doesn't work, then @@ -218,13 +223,13 @@ TkpScanWindowId( if ( #ifdef _WIN64 - (sscanf(string, "0x%p", &number) != 1) && + (sscanf(string, "0x%p", &win.hwnd) != 1) && #endif - Tcl_GetInt(interp, string, (int *) numberPtr) != TCL_OK) { + Tcl_GetInt(interp, string, &win.number) != TCL_OK) { return TCL_ERROR; } - tkwin = Tk_HWNDToWindow((HWND) number); + tkwin = Tk_HWNDToWindow(win.hwnd); if (tkwin) { *idPtr = Tk_WindowId(tkwin); } else { @@ -323,7 +328,7 @@ XDestroyWindow( Tcl_DeleteHashEntry(entryPtr); } - ckfree((char *)twdPtr); + ckfree(twdPtr); /* * Don't bother destroying the window if we are going to destroy the @@ -784,27 +789,174 @@ TkWinSetWindowPos( /* *---------------------------------------------------------------------- * - * TkpWindowWasRecentlyDeleted -- + * TkpShowBusyWindow -- * - * Determines whether we know if the window given as argument was - * recently deleted. Called by the generic code error handler to handle - * BadWindow events. + * Makes a busy window "appear". * * Results: - * Always 0. We do not keep this information on Windows. + * None. * * Side effects: + * Arranges for the busy window to start intercepting events and the + * cursor to change to the configured "hey, I'm busy!" setting. + * + *---------------------------------------------------------------------- + */ + +void +TkpShowBusyWindow( + TkBusy busy) +{ + Busy *busyPtr = (Busy *) busy; + HWND hWnd; + POINT point; + Display *display; + Window window; + + if (busyPtr->tkBusy != NULL) { + Tk_MapWindow(busyPtr->tkBusy); + window = Tk_WindowId(busyPtr->tkBusy); + display = Tk_Display(busyPtr->tkBusy); + hWnd = Tk_GetHWND(window); + display->request++; + SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } + + /* + * Under Win32, cursors aren't associated with windows. Tk fakes this by + * watching Motion events on its windows. So Tk will automatically change + * the cursor when the pointer enters the Busy window. But Windows does + * not immediately change the cursor; it waits for the cursor position to + * change or a system call. We need to change the cursor before the + * application starts processing, so set the cursor position redundantly + * back to the current position. + */ + + GetCursorPos(&point); + SetCursorPos(point.x, point.y); +} + +/* + *---------------------------------------------------------------------- + * + * TkpHideBusyWindow -- + * + * Makes a busy window "disappear". + * + * Results: * None. * + * Side effects: + * Arranges for the busy window to stop intercepting events, and the + * cursor to change back to its normal setting. + * *---------------------------------------------------------------------- */ -int -TkpWindowWasRecentlyDeleted( - Window win, - TkDisplay *dispPtr) +void +TkpHideBusyWindow( + TkBusy busy) { - return 0; + Busy *busyPtr = (Busy *) busy; + POINT point; + + if (busyPtr->tkBusy != NULL) { + Tk_UnmapWindow(busyPtr->tkBusy); + } + + /* + * Under Win32, cursors aren't associated with windows. Tk fakes this by + * watching Motion events on its windows. So Tk will automatically change + * the cursor when the pointer enters the Busy window. But Windows does + * not immediately change the cursor: it waits for the cursor position to + * change or a system call. We need to change the cursor before the + * application starts processing, so set the cursor position redundantly + * back to the current position. + */ + + GetCursorPos(&point); + SetCursorPos(point.x, point.y); +} + +/* + *---------------------------------------------------------------------- + * + * TkpMakeTransparentWindowExist -- + * + * Construct the platform-specific resources for a transparent window. + * + * Results: + * None. + * + * Side effects: + * Moves the specified window in the stacking order. + * + *---------------------------------------------------------------------- + */ + +void +TkpMakeTransparentWindowExist( + Tk_Window tkwin, /* Token for window. */ + Window parent) /* Parent window. */ +{ + TkWindow *winPtr = (TkWindow *) tkwin; + HWND hParent = (HWND) parent, hWnd; + int style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + DWORD exStyle = WS_EX_TRANSPARENT | WS_EX_TOPMOST; + + hWnd = CreateWindowEx(exStyle, TK_WIN_CHILD_CLASS_NAME, NULL, style, + Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), + hParent, NULL, Tk_GetHINSTANCE(), NULL); + winPtr->window = Tk_AttachHWND(tkwin, hWnd); +} + +/* + *---------------------------------------------------------------------- + * + * TkpCreateBusy -- + * + * Construct the platform-specific parts of a busy window. Note that this + * postpones the actual creation of the window resource until later. + * + * Results: + * None. + * + * Side effects: + * Sets up part of the busy window structure. + * + *---------------------------------------------------------------------- + */ + +void +TkpCreateBusy( + Tk_FakeWin *winPtr, + Tk_Window tkRef, + Window *parentPtr, + Tk_Window tkParent, + TkBusy busy) +{ + Busy *busyPtr = (Busy *) busy; + + if (winPtr->flags & TK_REPARENTED) { + /* + * This works around a bug in the implementation of menubars for + * non-Macintosh window systems (Win32 and X11). Tk doesn't reset the + * pointers to the parent window when the menu is reparented + * (winPtr->parentPtr points to the wrong window). We get around this + * by determining the parent via the native API calls. + */ + + HWND hWnd = GetParent(Tk_GetHWND(Tk_WindowId(tkRef))); + RECT rect; + + if (GetWindowRect(hWnd, &rect)) { + busyPtr->width = rect.right - rect.left; + busyPtr->height = rect.bottom - rect.top; + } + } else { + *parentPtr = Tk_WindowId(tkParent); + *parentPtr = (Window) Tk_GetHWND(*parentPtr); + } } /* diff --git a/win/tkWinWm.c b/win/tkWinWm.c index e3816ca..45ccbe2 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -58,7 +58,7 @@ typedef struct ProtocolHandler { * 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 + char command[1]; /* Tcl command to invoke when a client message * for this protocol arrives. The actual size * of the structure varies to accommodate the * needs of the actual command. THIS MUST BE @@ -66,7 +66,7 @@ typedef struct ProtocolHandler { } ProtocolHandler; #define HANDLER_SIZE(cmdLength) \ - ((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength)) + ((unsigned) ((Tk_Offset(ProtocolHandler, command) + 1) + cmdLength)) /* * Helper type passed via lParam to TkWmStackorderToplevelEnumProc @@ -395,23 +395,6 @@ static Tcl_ThreadDataKey dataKey; 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 - */ - -DWORD* (WINAPI *shgetfileinfoProc) (LPCTSTR pszPath, DWORD dwFileAttributes, - SHFILEINFO* psfi, UINT cbFileInfo, UINT uFlags) = NULL; - -/* - * 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) /* @@ -432,7 +415,7 @@ 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, +static int ParseGeometry(Tcl_Interp *interp, const char *string, TkWindow *winPtr); static void RefreshColormap(Colormap colormap, TkDisplay *dispPtr); static void SetLimits(HWND hwnd, MINMAXINFO *info); @@ -650,7 +633,7 @@ static LPSTR FindDIBBits( LPSTR lpbi) { - return lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi); + return lpbi + *((LPDWORD) lpbi) + PaletteSize(lpbi); } /* @@ -706,7 +689,7 @@ AdjustIconImagePointers( * BITMAPINFO is at beginning of bits. */ - lpImage->lpbi = (LPBITMAPINFO)lpImage->lpBits; + lpImage->lpbi = (LPBITMAPINFO) lpImage->lpBits; /* * Width - simple enough. @@ -732,14 +715,14 @@ AdjustIconImagePointers( * XOR bits follow the header and color table. */ - lpImage->lpXOR = (LPBYTE)FindDIBBits(((LPSTR)lpImage->lpbi)); + lpImage->lpXOR = (LPBYTE) FindDIBBits((LPSTR) lpImage->lpbi); /* * AND bits follow the XOR bits. */ - lpImage->lpAND = lpImage->lpXOR + (lpImage->Height* - BytesPerLine((LPBITMAPINFOHEADER)(lpImage->lpbi))); + lpImage->lpAND = lpImage->lpXOR + + lpImage->Height*BytesPerLine((LPBITMAPINFOHEADER) lpImage->lpbi); return TRUE; } @@ -762,49 +745,30 @@ MakeIconOrCursorFromResource( LPICONIMAGE lpIcon, BOOL isIcon) { - HICON hIcon ; - static FARPROC pfnCreateIconFromResourceEx=NULL; - static int initinfo=0; + HICON hIcon; /* * Sanity Check */ - if (lpIcon == NULL) { + if (lpIcon == NULL || lpIcon->lpBits == NULL) { return 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); - } else { - hIcon = NULL; - } + hIcon = (HICON) CreateIconFromResourceEx(lpIcon->lpBits, + lpIcon->dwNumBytes, isIcon, 0x00030000, + (*(LPBITMAPINFOHEADER) lpIcon->lpBits).biWidth, + (*(LPBITMAPINFOHEADER) lpIcon->lpBits).biHeight/2, 0); /* * It failed, odds are good we're on NT so try the non-Ex way. */ - if (hIcon == NULL) { + if (hIcon == NULL) { /* * We would break on NT if we try with a 16bpp image. */ @@ -892,40 +856,20 @@ static int InitWindowClass( WinIconPtr titlebaricon) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - if (! tsdPtr->initialized) { + if (!tsdPtr->initialized) { tsdPtr->initialized = 1; tsdPtr->firstWindow = 1; tsdPtr->iconPtr = NULL; } - if (! initialized) { + if (!initialized) { Tcl_MutexLock(&winWmMutex); - if (! initialized) { - Tcl_DString classString; + if (!initialized) { WNDCLASS class; - initialized = 1; - 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"); - 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"); - FreeLibrary(hInstance); - } - } + initialized = 1; /* * The only difference between WNDCLASSW and WNDCLASSA are in @@ -936,11 +880,10 @@ InitWindowClass( class.style = CS_HREDRAW | CS_VREDRAW; class.hInstance = Tk_GetHINSTANCE(); - Tcl_WinUtfToTChar(TK_WIN_TOPLEVEL_CLASS_NAME, -1, &classString); - class.lpszClassName = (LPCTSTR) Tcl_DStringValue(&classString); + class.lpszClassName = TK_WIN_TOPLEVEL_CLASS_NAME; class.lpfnWndProc = WmProc; if (titlebaricon == NULL) { - class.hIcon = LoadIcon(Tk_GetHINSTANCE(), "tk"); + class.hIcon = LoadIcon(Tk_GetHINSTANCE(), TEXT("tk")); } else { class.hIcon = GetIcon(titlebaricon, ICON_BIG); if (class.hIcon == NULL) { @@ -956,11 +899,9 @@ InitWindowClass( } class.hCursor = LoadCursor(NULL, IDC_ARROW); - if (!(*tkWinProcs->registerClass)(&class)) { + if (!RegisterClass(&class)) { Tcl_Panic("Unable to register TkTopLevel class"); } - - Tcl_DStringFree(&classString); } Tcl_MutexUnlock(&winWmMutex); } @@ -1043,7 +984,7 @@ WinSetIcon( * We must get the window's wrapper, not the window itself. */ - wmPtr = ((TkWindow*)tkw)->wmInfoPtr; + wmPtr = ((TkWindow *) tkw)->wmInfoPtr; hwnd = wmPtr->wrapper; if (application) { @@ -1104,7 +1045,7 @@ WinSetIcon( /* * The following code is exercised if you do * - * toplevel .t ; wm titlebaricon .t foo.icr + * 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. @@ -1117,7 +1058,7 @@ WinSetIcon( */ UpdateWrapper(wmPtr->winPtr); - wmPtr = ((TkWindow*)tkw)->wmInfoPtr; + wmPtr = ((TkWindow *) tkw)->wmInfoPtr; hwnd = wmPtr->wrapper; if (hwnd == NULL) { Tcl_AppendResult(interp, @@ -1176,7 +1117,7 @@ TkWinGetIcon( { WmInfo *wmPtr; HICON icon; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->iconPtr != NULL) { @@ -1184,7 +1125,7 @@ TkWinGetIcon( * return default toplevel icon */ - return GetIcon(tsdPtr->iconPtr, (int)iconsize); + return GetIcon(tsdPtr->iconPtr, (int) iconsize); } /* @@ -1208,7 +1149,7 @@ TkWinGetIcon( * return window toplevel icon */ - return GetIcon(wmPtr->iconPtr, (int)iconsize); + return GetIcon(wmPtr->iconPtr, (int) iconsize); } /* @@ -1270,11 +1211,13 @@ ReadIconFromFile( WinIconPtr titlebaricon = NULL; BlockOfIconImagesPtr lpIR; +#if 0 /* TODO: Dead code? */ if (0 /* If we already have an icon for this filename */) { titlebaricon = NULL; /* Get the real value from a lookup */ titlebaricon->refCount++; return titlebaricon; } +#endif /* * First check if it is a .ico file. @@ -1288,7 +1231,7 @@ ReadIconFromFile( * switching) display uses the right icon. */ - if (lpIR == NULL && shgetfileinfoProc != NULL) { + if (lpIR == NULL) { SHFILEINFO sfiSM; Tcl_DString ds, ds2; DWORD *res; @@ -1298,9 +1241,9 @@ ReadIconFromFile( if (file == NULL) { return NULL; } - Tcl_UtfToExternalDString(NULL, file, -1, &ds2); + Tcl_WinUtfToTChar(file, -1, &ds2); Tcl_DStringFree(&ds); - res = (*shgetfileinfoProc)(Tcl_DStringValue(&ds2), 0, &sfiSM, + res = (DWORD *)SHGetFileInfo((TCHAR *)Tcl_DStringValue(&ds2), 0, &sfiSM, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON); if (res != 0) { @@ -1308,7 +1251,7 @@ ReadIconFromFile( unsigned size; Tcl_ResetResult(interp); - res = (*shgetfileinfoProc)(Tcl_DStringValue(&ds2), 0, &sfi, + res = (DWORD *)SHGetFileInfo((TCHAR *)Tcl_DStringValue(&ds2), 0, &sfi, sizeof(SHFILEINFO), SHGFI_ICON); /* @@ -1317,7 +1260,7 @@ ReadIconFromFile( size = sizeof(BlockOfIconImages) + ((res != 0) ? sizeof(ICONIMAGE) : 0); - lpIR = (BlockOfIconImagesPtr) ckalloc(size); + lpIR = ckalloc(size); if (lpIR == NULL) { if (res != 0) { DestroyIcon(sfi.hIcon); @@ -1348,7 +1291,7 @@ ReadIconFromFile( Tcl_DStringFree(&ds2); } if (lpIR != NULL) { - titlebaricon = (WinIconPtr) ckalloc(sizeof(WinIconInstance)); + titlebaricon = ckalloc(sizeof(WinIconInstance)); titlebaricon->iconBlock = lpIR; titlebaricon->refCount = 1; } @@ -1393,7 +1336,7 @@ GetIconFromPixmap( Pixmap pixmap) { WinIconPtr titlebaricon = NULL; - TkWinDrawable *twdPtr = (TkWinDrawable*) pixmap; + TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap; BlockOfIconImagesPtr lpIR; ICONINFO icon; HICON hIcon; @@ -1403,11 +1346,13 @@ GetIconFromPixmap( return NULL; } +#if 0 /* TODO: Dead code?*/ if (0 /* If we already have an icon for this pixmap */) { titlebaricon = NULL; /* Get the real value from a lookup */ titlebaricon->refCount++; return titlebaricon; } +#endif Tk_SizeOfBitmap(dsPtr, pixmap, &width, &height); @@ -1422,7 +1367,7 @@ GetIconFromPixmap( return NULL; } - lpIR = (BlockOfIconImagesPtr) ckalloc(sizeof(BlockOfIconImages)); + lpIR = ckalloc(sizeof(BlockOfIconImages)); if (lpIR == NULL) { DestroyIcon(hIcon); return NULL; @@ -1443,7 +1388,7 @@ GetIconFromPixmap( lpIR->IconImages[0].lpXOR = 0; lpIR->IconImages[0].lpAND = 0; - titlebaricon = (WinIconPtr) ckalloc(sizeof(WinIconInstance)); + titlebaricon = ckalloc(sizeof(WinIconInstance)); titlebaricon->iconBlock = lpIR; titlebaricon->refCount = 1; return titlebaricon; @@ -1479,7 +1424,7 @@ DecrIconRefCount( } titlebaricon->iconBlock = NULL; - ckfree((char*)titlebaricon); + ckfree(titlebaricon); } } @@ -1510,15 +1455,15 @@ FreeIconBlock( * Free all the bits. */ - for (i=0; i< lpIR->nNumImages; i++) { + for (i=0 ; i<lpIR->nNumImages ; i++) { if (lpIR->IconImages[i].lpBits != NULL) { - ckfree((char*)lpIR->IconImages[i].lpBits); + ckfree(lpIR->IconImages[i].lpBits); } if (lpIR->IconImages[i].hIcon != NULL) { DestroyIcon(lpIR->IconImages[i].hIcon); } } - ckfree ((char*)lpIR); + ckfree(lpIR); } /* @@ -1540,6 +1485,8 @@ GetIcon( int icon_size) { BlockOfIconImagesPtr lpIR; + unsigned int size = (icon_size == 0 ? 16 : 32); + int i; if (titlebaricon == NULL) { return NULL; @@ -1548,30 +1495,27 @@ GetIcon( lpIR = titlebaricon->iconBlock; if (lpIR == NULL) { return NULL; - } else { - unsigned int size = (icon_size == 0 ? 16 : 32); - int i; - - for (i = 0; i < lpIR->nNumImages; i++) { - /* - * Take the first or a 32x32 16 color icon - */ - - if ((lpIR->IconImages[i].Height == size) - && (lpIR->IconImages[i].Width == size) - && (lpIR->IconImages[i].Colors >= 4)) { - return lpIR->IconImages[i].hIcon; - } - } + } + for (i=0 ; i<lpIR->nNumImages ; i++) { /* - * If we get here, then just return the first one, it will have to do! + * Take the first or a 32x32 16 color icon */ - if (lpIR->nNumImages >= 1) { - return lpIR->IconImages[0].hIcon; + if ((lpIR->IconImages[i].Height == size) + && (lpIR->IconImages[i].Width == size) + && (lpIR->IconImages[i].Colors >= 4)) { + return lpIR->IconImages[i].hIcon; } } + + /* + * If we get here, then just return the first one, it will have to do! + */ + + if (lpIR->nNumImages >= 1) { + return lpIR->IconImages[0].hIcon; + } return NULL; } @@ -1589,7 +1533,7 @@ TclWinReadCursorFromFile( return NULL; } if (lpIR->nNumImages >= 1) { - res = CopyImage(lpIR->IconImages[0].hIcon, IMAGE_CURSOR,0,0,0); + res = CopyImage(lpIR->IconImages[0].hIcon, IMAGE_CURSOR, 0, 0, 0); } FreeIconBlock(lpIR); return res; @@ -1631,7 +1575,7 @@ ReadIconOrCursorFromFile( channel = Tcl_FSOpenFileChannel(interp, fileName, "r", 0); if (channel == NULL) { - Tcl_AppendResult(interp,"Error opening file \"", + Tcl_AppendResult(interp, "Error opening file \"", Tcl_GetString(fileName), "\" for reading", NULL); return NULL; } @@ -1650,16 +1594,17 @@ ReadIconOrCursorFromFile( * Allocate memory for the resource structure */ - lpIR = (BlockOfIconImagesPtr) ckalloc(sizeof(BlockOfIconImages)); + lpIR = ckalloc(sizeof(BlockOfIconImages)); /* * Read in the header */ - if ((lpIR->nNumImages = ReadICOHeader(channel)) == -1) { + lpIR->nNumImages = ReadICOHeader(channel); + if (lpIR->nNumImages == -1) { Tcl_AppendResult(interp, "Invalid file header", NULL); Tcl_Close(NULL, channel); - ckfree((char*) lpIR); + ckfree(lpIR); return NULL; } @@ -1667,27 +1612,26 @@ ReadIconOrCursorFromFile( * Adjust the size of the struct to account for the images. */ - lpIR = (BlockOfIconImagesPtr) ckrealloc((char*) lpIR, - sizeof(BlockOfIconImages) - + ((lpIR->nNumImages - 1) * sizeof(ICONIMAGE))); + lpIR = ckrealloc(lpIR, sizeof(BlockOfIconImages) + + (lpIR->nNumImages - 1) * sizeof(ICONIMAGE)); /* * Allocate enough memory for the icon directory entries. */ - lpIDE = (LPICONDIRENTRY) ckalloc(lpIR->nNumImages * sizeof(ICONDIRENTRY)); + lpIDE = ckalloc(lpIR->nNumImages * sizeof(ICONDIRENTRY)); /* * Read in the icon directory entries. */ - dwBytesRead = Tcl_Read(channel, (char*) lpIDE, - (int)(lpIR->nNumImages * sizeof(ICONDIRENTRY))); + 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 *) lpIDE); - ckfree((char *) lpIR); + ckfree(lpIDE); + ckfree(lpIR); return NULL; } @@ -1708,7 +1652,7 @@ ReadIconOrCursorFromFile( * Allocate memory for the resource. */ - lpIR->IconImages[i].lpBits = (LPBYTE) ckalloc(lpIDE[i].dwBytesInRes); + lpIR->IconImages[i].lpBits = ckalloc(lpIDE[i].dwBytesInRes); lpIR->IconImages[i].dwNumBytes = lpIDE[i].dwBytesInRes; /* @@ -1724,7 +1668,7 @@ ReadIconOrCursorFromFile( * Read it in. */ - dwBytesRead = Tcl_Read(channel, (char *) lpIR->IconImages[i].lpBits, + dwBytesRead = Tcl_Read(channel, (char *)lpIR->IconImages[i].lpBits, (int) lpIDE[i].dwBytesInRes); if (dwBytesRead != lpIDE[i].dwBytesInRes) { Tcl_AppendResult(interp, "Error reading file", NULL); @@ -1735,22 +1679,22 @@ ReadIconOrCursorFromFile( * Set the internal pointers appropriately. */ - if (!AdjustIconImagePointers( &(lpIR->IconImages[i]))) { + if (!AdjustIconImagePointers(&lpIR->IconImages[i])) { 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); + ckfree(lpIDE); Tcl_Close(NULL, channel); - if (lpIR == NULL){ + if (lpIR == NULL) { Tcl_AppendResult(interp, "Reading of ", Tcl_GetString(fileName), " failed!", NULL); return NULL; @@ -1761,11 +1705,11 @@ ReadIconOrCursorFromFile( Tcl_Close(NULL, channel); for (i = 0; i < lpIR->nNumImages; i++) { if (lpIR->IconImages[i].lpBits != NULL) { - ckfree((char *) lpIR->IconImages[i].lpBits); + ckfree(lpIR->IconImages[i].lpBits); } } - ckfree((char *) lpIDE); - ckfree((char *) lpIR); + ckfree(lpIDE); + ckfree(lpIR); return NULL; } @@ -1789,7 +1733,7 @@ static TkWindow * GetTopLevel( HWND hwnd) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -1931,8 +1875,7 @@ TkWinWmCleanup( } initialized = 0; - tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { return; @@ -1963,9 +1906,7 @@ void TkWmNewWindow( TkWindow *winPtr) /* Newly-created top-level window. */ { - register WmInfo *wmPtr; - - wmPtr = (WmInfo *) ckalloc(sizeof(WmInfo)); + register WmInfo *wmPtr = ckalloc(sizeof(WmInfo)); /* * Initialize full structure, then set what isn't NULL @@ -2002,7 +1943,7 @@ TkWmNewWindow( wmPtr->x = winPtr->changes.x; wmPtr->y = winPtr->changes.y; wmPtr->crefObj = NULL; - wmPtr->colorref = (COLORREF)0; + wmPtr->colorref = (COLORREF) 0; wmPtr->alpha = 1.0; wmPtr->configWidth = -1; @@ -2017,14 +1958,14 @@ TkWmNewWindow( */ Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask, - TopLevelEventProc, (ClientData) winPtr); + TopLevelEventProc, winPtr); /* * Arrange for geometry requests to be reflected from the window to the * window manager. */ - Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0); + Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, NULL); } /* @@ -2057,9 +1998,9 @@ UpdateWrapper( WINDOWPLACEMENT place; HICON hSmallIcon = NULL; HICON hBigIcon = NULL; - Tcl_DString titleString, classString; + Tcl_DString titleString; int *childStateInfo = NULL; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->window == None) { @@ -2092,7 +2033,6 @@ UpdateWrapper( if (!IsWindow(wmPtr->wrapper)) { Tcl_Panic("UpdateWrapper: Container was destroyed"); } - } else { /* * Pick the decorative frame style. Override redirect windows get @@ -2127,8 +2067,8 @@ UpdateWrapper( wmPtr->style = WM_TRANSIENT_STYLE; wmPtr->exStyle = EX_TRANSIENT_STYLE; parentHWND = Tk_GetHWND(Tk_WindowId(wmPtr->masterPtr)); - if (! ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) && - (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE))) { + if (! ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) + && (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE))) { wmPtr->style |= WS_THICKFRAME; } } else { @@ -2149,7 +2089,7 @@ UpdateWrapper( */ wmPtr->flags |= WM_CREATE_PENDING|WM_MOVE_PENDING; - UpdateGeometryInfo((ClientData)winPtr); + UpdateGeometryInfo(winPtr); wmPtr->flags &= ~(WM_CREATE_PENDING|WM_MOVE_PENDING); width = wmPtr->borderWidth + winPtr->changes.width; @@ -2185,33 +2125,30 @@ UpdateWrapper( Tcl_WinUtfToTChar(((wmPtr->title != NULL) ? 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), + wmPtr->wrapper = CreateWindowEx(wmPtr->exStyle, + TK_WIN_TOPLEVEL_CLASS_NAME, (LPCTSTR) Tcl_DStringValue(&titleString), wmPtr->style, x, y, width, height, parentHWND, NULL, Tk_GetHINSTANCE(), NULL); - Tcl_DStringFree(&classString); Tcl_DStringFree(&titleString); - SetWindowLongPtr(wmPtr->wrapper, GWLP_USERDATA, (INT_PTR) winPtr); + SetWindowLongPtr(wmPtr->wrapper, GWLP_USERDATA, (LONG_PTR) winPtr); tsdPtr->createWindow = NULL; - if ((wmPtr->exStyleConfig & WS_EX_LAYERED) - && setLayeredWindowAttributesProc != NULL) { + if (wmPtr->exStyleConfig & WS_EX_LAYERED) { /* * The user supplies a double from [0..1], but Windows wants an * int (transparent) 0..255 (opaque), so do the translation. Add * the 0.5 to round the value. */ - setLayeredWindowAttributesProc((HWND) wmPtr->wrapper, + SetLayeredWindowAttributes((HWND) wmPtr->wrapper, wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5), (unsigned)(LWA_ALPHA | (wmPtr->crefObj?LWA_COLORKEY:0))); } else { /* * Layering not used or supported. */ + wmPtr->alpha = 1.0; if (wmPtr->crefObj) { Tcl_DecrRefCount(wmPtr->crefObj); @@ -2224,8 +2161,9 @@ UpdateWrapper( 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)) { @@ -2248,20 +2186,20 @@ UpdateWrapper( WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); if (winPtr->flags & TK_EMBEDDED) { - SetWindowLongPtr(child, GWLP_WNDPROC, (INT_PTR) TopLevelProc); + SetWindowLongPtr(child, GWLP_WNDPROC, (LONG_PTR) TopLevelProc); } SetParent(child, wmPtr->wrapper); if (oldWrapper) { - hSmallIcon = (HICON) SendMessage(oldWrapper, WM_GETICON, ICON_SMALL, - (LPARAM) NULL); - hBigIcon = (HICON) SendMessage(oldWrapper, WM_GETICON, ICON_BIG, - (LPARAM) NULL); + hSmallIcon = (HICON) + SendMessage(oldWrapper, WM_GETICON, ICON_SMALL, (LPARAM)NULL); + hBigIcon = (HICON) + SendMessage(oldWrapper, WM_GETICON, ICON_BIG, (LPARAM) NULL); } if (oldWrapper && (oldWrapper != wmPtr->wrapper) && (oldWrapper != GetDesktopWindow())) { - SetWindowLongPtr(oldWrapper, GWLP_USERDATA, (LONG) 0); + SetWindowLongPtr(oldWrapper, GWLP_USERDATA, (LONG_PTR) 0); if (wmPtr->numTransients > 0) { /* @@ -2271,8 +2209,7 @@ UpdateWrapper( WmInfo *wmPtr2; - childStateInfo = (int *) - ckalloc((unsigned) wmPtr->numTransients * sizeof(int)); + childStateInfo = ckalloc(wmPtr->numTransients * sizeof(int)); state = 0; for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL; wmPtr2 = wmPtr2->nextPtr) { @@ -2294,11 +2231,11 @@ UpdateWrapper( } wmPtr->flags &= ~WM_NEVER_MAPPED; - if (winPtr->flags & TK_EMBEDDED - && 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)); + Tk_ReqWidth((Tk_Window) winPtr), + Tk_ReqHeight((Tk_Window) winPtr)); SendMessage(wmPtr->wrapper, TK_SETMENU, (WPARAM) wmPtr->hMenu, (LPARAM) Tk_GetMenuHWND((Tk_Window) winPtr)); } @@ -2319,10 +2256,11 @@ UpdateWrapper( wmPtr->hints.initial_state = state; if (hSmallIcon != NULL) { - SendMessage(wmPtr->wrapper,WM_SETICON,ICON_SMALL,(LPARAM)hSmallIcon); + SendMessage(wmPtr->wrapper, WM_SETICON, ICON_SMALL, + (LPARAM) hSmallIcon); } if (hBigIcon != NULL) { - SendMessage(wmPtr->wrapper,WM_SETICON,ICON_BIG,(LPARAM)hBigIcon); + SendMessage(wmPtr->wrapper, WM_SETICON, ICON_BIG, (LPARAM) hBigIcon); } /* @@ -2334,7 +2272,7 @@ UpdateWrapper( */ if (winPtr->flags & TK_EMBEDDED) { - if(state+1 != SendMessage(wmPtr->wrapper, TK_STATE, state, 0)) { + if (state+1 != SendMessage(wmPtr->wrapper, TK_STATE, state, 0)) { TkpWmSetState(winPtr, NormalState); wmPtr->hints.initial_state = NormalState; } @@ -2370,7 +2308,7 @@ UpdateWrapper( } } - ckfree((char *) childStateInfo); + ckfree(childStateInfo); } /* @@ -2418,7 +2356,7 @@ TkWmMapWindow( * mapped. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { @@ -2430,8 +2368,7 @@ TkWmMapWindow( * Don't map a transient if the master is not mapped. */ - if (wmPtr->masterPtr != NULL && - !Tk_IsMapped(wmPtr->masterPtr)) { + if (wmPtr->masterPtr != NULL && !Tk_IsMapped(wmPtr->masterPtr)) { wmPtr->hints.initial_state = WithdrawnState; return; } @@ -2523,7 +2460,7 @@ TkpWmSetState( } else if (state == ZoomState) { cmd = SW_SHOWMAXIMIZED; } else { - goto setStateEnd; + goto setStateEnd; } ShowWindow(wmPtr->wrapper, cmd); @@ -2659,6 +2596,7 @@ TkWmDeadWindow( winPtr->dispPtr->firstWmPtr = wmPtr->nextPtr; } else { register WmInfo *prevPtr; + for (prevPtr = winPtr->dispPtr->firstWmPtr; ; prevPtr = prevPtr->nextPtr) { if (prevPtr == NULL) { @@ -2681,7 +2619,7 @@ TkWmDeadWindow( wmPtr->numTransients--; Tk_DeleteEventHandler((Tk_Window) wmPtr2->masterPtr, VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, (ClientData) wmPtr2->winPtr); + WmWaitVisibilityOrMapProc, wmPtr2->winPtr); wmPtr2->masterPtr = NULL; if ((wmPtr2->wrapper != None) && !(wmPtr2->flags & (WM_NEVER_MAPPED))) { @@ -2721,16 +2659,16 @@ TkWmDeadWindow( protPtr = wmPtr->protPtr; wmPtr->protPtr = protPtr->nextPtr; - Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC); + Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); } if (wmPtr->cmdArgv != NULL) { - ckfree((char *) wmPtr->cmdArgv); + ckfree(wmPtr->cmdArgv); } if (wmPtr->clientMachine != NULL) { - ckfree((char *) wmPtr->clientMachine); + ckfree(wmPtr->clientMachine); } if (wmPtr->flags & WM_UPDATE_PENDING) { - Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr); + Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr); } if (wmPtr->masterPtr != NULL) { wmPtr2 = wmPtr->masterPtr->wmInfoPtr; @@ -2744,7 +2682,7 @@ TkWmDeadWindow( } Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr, VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, (ClientData) winPtr); + WmWaitVisibilityOrMapProc, winPtr); wmPtr->masterPtr = NULL; } if (wmPtr->crefObj != NULL) { @@ -2777,7 +2715,7 @@ TkWmDeadWindow( DecrIconRefCount(wmPtr->iconPtr); } - ckfree((char *) wmPtr); + ckfree(wmPtr); winPtr->wmInfoPtr = NULL; } @@ -2833,8 +2771,8 @@ Tk_WmObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; - static const char *optionStrings[] = { + Tk_Window tkwin = clientData; + static const char *const optionStrings[] = { "aspect", "attributes", "client", "colormapwindows", "command", "deiconify", "focusmodel", "forget", "frame", "geometry", "grid", "group", "iconbitmap", @@ -2847,17 +2785,19 @@ Tk_WmObjCmd( }; enum options { WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS, - WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET, WMOPT_FRAME, + WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET, + WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP, WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, WMOPT_ICONPHOTO, WMOPT_ICONPOSITION, - WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT, + WMOPT_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; + const char *argv1; TkWindow *winPtr, **winPtrPtr = &winPtr; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; @@ -2906,8 +2846,8 @@ Tk_WmObjCmd( != TCL_OK) { return TCL_ERROR; } - if (!Tk_IsTopLevel(winPtr) && - (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) { + if (!Tk_IsTopLevel(winPtr) && (index != WMOPT_MANAGE) + && (index != WMOPT_FORGET)) { Tcl_AppendResult(interp, "window \"", winPtr->pathName, "\" isn't a top-level window", NULL); return TCL_ERROR; @@ -3019,12 +2959,9 @@ WmAspectCmd( } if (objc == 3) { if (wmPtr->sizeHintsFlags & PAspect) { - char buf[TCL_INTEGER_SPACE * 4]; - - sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x, - wmPtr->minAspect.y, wmPtr->maxAspect.x, - wmPtr->maxAspect.y); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d %d %d", + wmPtr->minAspect.x, wmPtr->minAspect.y, + wmPtr->maxAspect.x, wmPtr->maxAspect.y)); } return TCL_OK; } @@ -3078,7 +3015,7 @@ WmAttributesCmd( { register WmInfo *wmPtr = winPtr->wmInfoPtr; LONG style, exStyle, styleBit, *stylePtr = NULL; - char *string; + const char *string; int i, boolean, length; int config_fullscreen = 0, updatewrapper = 0; int fullscreen_attr_changed = 0, fullscreen_attr = 0; @@ -3192,7 +3129,7 @@ WmAttributesCmd( } wmPtr->alpha = dval; } else { /* -transparentcolor */ - char *crefstr = Tcl_GetStringFromObj(objv[i+1], &length); + const char *crefstr = Tcl_GetStringFromObj(objv[i+1], &length); if (length == 0) { /* reset to no transparent color */ @@ -3221,15 +3158,15 @@ WmAttributesCmd( /* * Only ever add the WS_EX_LAYERED bit, as it can cause - * flashing to change this window style. This allows things + * flashing to change this window style. This allows things * like fading tooltips to avoid flash ugliness without * forcing all window to be layered. */ + if ((wmPtr->alpha < 1.0) || (wmPtr->crefObj != NULL)) { *stylePtr |= styleBit; } - if ((setLayeredWindowAttributesProc != NULL) - && (wmPtr->wrapper != NULL)) { + if (wmPtr->wrapper != NULL) { /* * Set the window directly regardless of UpdateWrapper. * The user supplies a double from [0..1], but Windows @@ -3241,30 +3178,30 @@ WmAttributesCmd( SetWindowLongPtr(wmPtr->wrapper, GWL_EXSTYLE, *stylePtr); } - setLayeredWindowAttributesProc((HWND) wmPtr->wrapper, + SetLayeredWindowAttributes((HWND) wmPtr->wrapper, wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5), (unsigned) (LWA_ALPHA | (wmPtr->crefObj ? LWA_COLORKEY : 0))); } } } else { - if ((i < objc-1) && - (Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean) - != TCL_OK)) { + if ((i < objc-1) + && Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean) + != TCL_OK) { return TCL_ERROR; } if (config_fullscreen) { if (objc == 4) { - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), - (wmPtr->flags & WM_FULLSCREEN)); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj( + wmPtr->flags & WM_FULLSCREEN)); } else { fullscreen_attr_changed = 1; fullscreen_attr = boolean; } config_fullscreen = 0; } else if (objc == 4) { - Tcl_SetIntObj(Tcl_GetObjResult(interp), - ((*stylePtr & styleBit) != 0)); + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj(*stylePtr & styleBit)); } else if (boolean) { *stylePtr |= styleBit; } else { @@ -3276,6 +3213,7 @@ WmAttributesCmd( * Force the topmost position aspect to ensure that switching * between (no)topmost reflects properly when rewrapped. */ + SetWindowPos(wmPtr->wrapper, ((exStyle & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_NOTOPMOST), 0, 0, 0, 0, @@ -3368,7 +3306,7 @@ WmClientCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - char *argv3; + const char *argv3; int length; if ((objc != 3) && (objc != 4)) { @@ -3384,7 +3322,7 @@ WmClientCmd( argv3 = Tcl_GetStringFromObj(objv[3], &length); if (argv3[0] == 0) { if (wmPtr->clientMachine != NULL) { - ckfree((char *) wmPtr->clientMachine); + ckfree(wmPtr->clientMachine); wmPtr->clientMachine = NULL; if (!(wmPtr->flags & WM_NEVER_MAPPED)) { XDeleteProperty(winPtr->display, winPtr->window, @@ -3394,11 +3332,10 @@ WmClientCmd( return TCL_OK; } if (wmPtr->clientMachine != NULL) { - ckfree((char *) wmPtr->clientMachine); + ckfree(wmPtr->clientMachine); } - wmPtr->clientMachine = (char *) - ckalloc((unsigned) (length + 1)); - strcpy(wmPtr->clientMachine, argv3); + wmPtr->clientMachine = ckalloc(length + 1); + memcpy(wmPtr->clientMachine, argv3, (unsigned) length + 1); if (!(wmPtr->flags & WM_NEVER_MAPPED)) { XTextProperty textProp; @@ -3462,13 +3399,12 @@ WmColormapwindowsCmd( != TCL_OK) { return TCL_ERROR; } - cmapList = (TkWindow **) ckalloc((unsigned) - ((windowObjc+1)*sizeof(TkWindow*))); + cmapList = ckalloc((windowObjc + 1) * sizeof(TkWindow*)); gotToplevel = 0; for (i = 0; i < windowObjc; i++) { if (TkGetWindowFromObj(interp, tkwin, windowObjv[i], (Tk_Window *) winPtr2Ptr) != TCL_OK) { - ckfree((char *) cmapList); + ckfree(cmapList); return TCL_ERROR; } if (winPtr2 == winPtr) { @@ -3488,7 +3424,7 @@ WmColormapwindowsCmd( } wmPtr->flags |= WM_COLORMAPS_EXPLICIT; if (wmPtr->cmapList != NULL) { - ckfree((char *)wmPtr->cmapList); + ckfree(wmPtr->cmapList); } wmPtr->cmapList = cmapList; wmPtr->cmapCount = windowObjc; @@ -3531,7 +3467,7 @@ WmCommandCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - char *argv3; + const char *argv3; int cmdArgc; const char **cmdArgv; @@ -3541,15 +3477,15 @@ WmCommandCmd( } if (objc == 3) { if (wmPtr->cmdArgv != NULL) { - Tcl_SetResult(interp, - Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv), TCL_DYNAMIC); + char *merged = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv); + Tcl_SetResult(interp, merged, TCL_DYNAMIC); } return TCL_OK; } argv3 = Tcl_GetString(objv[3]); if (argv3[0] == 0) { if (wmPtr->cmdArgv != NULL) { - ckfree((char *) wmPtr->cmdArgv); + ckfree(wmPtr->cmdArgv); wmPtr->cmdArgv = NULL; if (!(wmPtr->flags & WM_NEVER_MAPPED)) { XDeleteProperty(winPtr->display, winPtr->window, @@ -3562,7 +3498,7 @@ WmCommandCmd( return TCL_ERROR; } if (wmPtr->cmdArgv != NULL) { - ckfree((char *) wmPtr->cmdArgv); + ckfree(wmPtr->cmdArgv); } wmPtr->cmdArgc = cmdArgc; wmPtr->cmdArgv = cmdArgv; @@ -3646,7 +3582,7 @@ WmFocusmodelCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "active", "passive", NULL }; enum options { @@ -3694,14 +3630,14 @@ WmFocusmodelCmd( */ static int -WmForgetCmd(tkwin, winPtr, interp, objc, objv) - Tk_Window tkwin; /* Main window of the application. */ - TkWindow *winPtr; /* Toplevel or Frame to work with */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *const objv[]; /* Argument objects. */ +WmForgetCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel or Frame to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - register Tk_Window frameWin = (Tk_Window)winPtr; + register Tk_Window frameWin = (Tk_Window) winPtr; if (Tk_IsTopLevel(frameWin)) { Tk_UnmapWindow(frameWin); @@ -3716,7 +3652,8 @@ WmForgetCmd(tkwin, winPtr, interp, objc, objv) /* Already not managed by wm - ignore it */ } return TCL_OK; -} +} + /* *---------------------------------------------------------------------- * @@ -3744,7 +3681,6 @@ WmFrameCmd( { register WmInfo *wmPtr = winPtr->wmInfoPtr; HWND hwnd; - char buf[TCL_INTEGER_SPACE]; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "window"); @@ -3757,8 +3693,7 @@ WmFrameCmd( if (hwnd == NULL) { hwnd = Tk_GetHWND(Tk_WindowId((Tk_Window) winPtr)); } - sprintf(buf, "0x%x", PTR2INT(hwnd)); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("0x%x", PTR2INT(hwnd))); return TCL_OK; } @@ -3790,16 +3725,14 @@ WmGeometryCmd( register WmInfo *wmPtr = winPtr->wmInfoPtr; char xSign, ySign; int width, height; - char *argv3; + const char *argv3; if ((objc != 3) && (objc != 4)) { Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?"); return TCL_ERROR; } - if (objc == 3) { - char buf[16 + TCL_INTEGER_SPACE * 4]; - int x, y; + if (objc == 3) { xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+'; ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+'; if (wmPtr->gridWin != NULL) { @@ -3811,17 +3744,17 @@ WmGeometryCmd( width = winPtr->changes.width; height = winPtr->changes.height; } - if(winPtr->flags & TK_EMBEDDED) { + 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); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d%c%d%c%d", + width, height, xSign, wmPtr->x, ySign, wmPtr->y)); return TCL_OK; } + argv3 = Tcl_GetString(objv[3]); if (*argv3 == '\0') { wmPtr->width = -1; @@ -3867,12 +3800,9 @@ WmGridCmd( } if (objc == 3) { if (wmPtr->sizeHintsFlags & PBaseSize) { - char buf[TCL_INTEGER_SPACE * 4]; - - sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth, - wmPtr->reqGridHeight, wmPtr->widthInc, - wmPtr->heightInc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d %d %d", + wmPtr->reqGridWidth, wmPtr->reqGridHeight, + wmPtr->widthInc, wmPtr->heightInc)); } return TCL_OK; } @@ -3948,7 +3878,7 @@ WmGroupCmd( { register WmInfo *wmPtr = winPtr->wmInfoPtr; Tk_Window tkwin2; - char *argv3; + const char *argv3; int length; if ((objc != 3) && (objc != 4)) { @@ -3978,8 +3908,8 @@ WmGroupCmd( } wmPtr->hints.window_group = Tk_WindowId(tkwin2); wmPtr->hints.flags |= WindowGroupHint; - wmPtr->leaderName = ckalloc((unsigned) (length + 1)); - strcpy(wmPtr->leaderName, argv3); + wmPtr->leaderName = ckalloc(length + 1); + memcpy(wmPtr->leaderName, argv3, (unsigned) length + 1); } return TCL_OK; } @@ -4011,7 +3941,7 @@ WmIconbitmapCmd( { register WmInfo *wmPtr = winPtr->wmInfoPtr; TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */ - char *string; + const char *string; if ((objc < 3) || (objc > 5)) { Tcl_WrongNumArgs(interp, 2, objv, "window ?-default? ?image?"); @@ -4021,7 +3951,7 @@ WmIconbitmapCmd( * If we have 5 arguments, we must have a '-default' flag. */ - char *argv3 = Tcl_GetString(objv[3]); + const char *argv3 = Tcl_GetString(objv[3]); if (strcmp(argv3, "-default")) { Tcl_AppendResult(interp, "illegal option \"", argv3, @@ -4149,7 +4079,7 @@ WmIconifyCmd( return TCL_ERROR; } if (winPtr->flags & TK_EMBEDDED) { - if(!SendMessage(wmPtr->wrapper, TK_ICONIFY, 0, 0)) { + 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; @@ -4201,7 +4131,7 @@ WmIconmaskCmd( { register WmInfo *wmPtr = winPtr->wmInfoPtr; Pixmap pixmap; - char *argv3; + const char *argv3; if ((objc != 3) && (objc != 4)) { Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?"); @@ -4258,7 +4188,7 @@ WmIconnameCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - char *argv3; + const char *argv3; int length; if (objc > 4) { @@ -4272,11 +4202,11 @@ WmIconnameCmd( return TCL_OK; } else { if (wmPtr->iconName != NULL) { - ckfree((char *) wmPtr->iconName); + ckfree(wmPtr->iconName); } argv3 = Tcl_GetStringFromObj(objv[3], &length); - wmPtr->iconName = ckalloc((unsigned) (length + 1)); - strcpy(wmPtr->iconName, argv3); + wmPtr->iconName = ckalloc(length + 1); + memcpy(wmPtr->iconName, argv3, (unsigned) length + 1); if (!(wmPtr->flags & WM_NEVER_MAPPED)) { XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName); } @@ -4314,7 +4244,7 @@ WmIconphotoCmd( Tk_PhotoImageBlock block; int i, width, height, idx, bufferSize, startObj = 3; union {unsigned char *ptr; void *voidPtr;} bgraPixel; - void *bgraMaskPtr; + union {unsigned char *ptr; void *voidPtr;} bgraMask; BlockOfIconImagesPtr lpIR; WinIconPtr titlebaricon = NULL; HICON hIcon; @@ -4356,7 +4286,7 @@ WmIconphotoCmd( */ size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1)); - lpIR = (BlockOfIconImagesPtr) attemptckalloc(size); + lpIR = attemptckalloc(size); if (lpIR == NULL) { return TCL_ERROR; } @@ -4371,18 +4301,19 @@ WmIconphotoCmd( /* * 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. + * 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 ); + ZeroMemory(&iconInfo, sizeof(iconInfo)); iconInfo.fIcon = TRUE; /* * Create device-independant color bitmap. */ - ZeroMemory(&bmInfo,sizeof bmInfo); + + ZeroMemory(&bmInfo, sizeof bmInfo); bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth = width; bmInfo.bmiHeader.biHeight = -height; @@ -4390,10 +4321,10 @@ WmIconphotoCmd( 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); + iconInfo.hbmColor = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS, + &bgraPixel.voidPtr, NULL, 0); + if (!iconInfo.hbmColor) { + ckfree(lpIR); Tcl_AppendResult(interp, "failed to create color bitmap for \"", Tcl_GetString(objv[i]), "\"", NULL); return TCL_ERROR; @@ -4402,6 +4333,7 @@ WmIconphotoCmd( /* * Convert the photo image data into BGRA format (RGBQUAD). */ + bufferSize = height * width * 4; for (idx = 0 ; idx < bufferSize ; idx += 4) { bgraPixel.ptr[idx] = block.pixelPtr[idx+2]; @@ -4411,28 +4343,30 @@ WmIconphotoCmd( } /* - * 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. + * 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 ) { + iconInfo.hbmMask = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS, + &bgraMask.voidPtr, NULL, 0); + if (!iconInfo.hbmMask) { DeleteObject(iconInfo.hbmColor); - ckfree((char *) lpIR); + ckfree(lpIR); Tcl_AppendResult(interp, "failed to create mask bitmap for \"", Tcl_GetString(objv[i]), "\"", NULL); return TCL_ERROR; } - ZeroMemory( bgraMaskPtr, width*height/8 ); + ZeroMemory(bgraMask.ptr, width*height/8); /* * Create an icon from the bitmaps. */ - hIcon = CreateIconIndirect( &iconInfo); + + hIcon = CreateIconIndirect(&iconInfo); DeleteObject(iconInfo.hbmColor); DeleteObject(iconInfo.hbmMask); if (hIcon == NULL) { @@ -4440,7 +4374,7 @@ WmIconphotoCmd( * XXX should free up created icons. */ - ckfree((char *) lpIR); + ckfree(lpIR); Tcl_AppendResult(interp, "failed to create icon for \"", Tcl_GetString(objv[i]), "\"", NULL); return TCL_ERROR; @@ -4451,7 +4385,7 @@ WmIconphotoCmd( lpIR->IconImages[i-startObj].hIcon = hIcon; } - titlebaricon = (WinIconPtr) ckalloc(sizeof(WinIconInstance)); + titlebaricon = ckalloc(sizeof(WinIconInstance)); titlebaricon->iconBlock = lpIR; titlebaricon->refCount = 1; if (WinSetIcon(interp, titlebaricon, (Tk_Window) useWinPtr) != TCL_OK) { @@ -4499,11 +4433,8 @@ WmIconpositionCmd( } if (objc == 3) { if (wmPtr->hints.flags & IconPositionHint) { - char buf[TCL_INTEGER_SPACE * 2]; - - sprintf(buf, "%d %d", wmPtr->hints.icon_x, - wmPtr->hints.icon_y); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d", + wmPtr->hints.icon_x, wmPtr->hints.icon_y)); } return TCL_OK; } @@ -4511,7 +4442,7 @@ WmIconpositionCmd( wmPtr->hints.flags &= ~IconPositionHint; } else { if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){ + || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) { return TCL_ERROR; } wmPtr->hints.icon_x = x; @@ -4646,14 +4577,14 @@ WmIconwindowCmd( */ static int -WmManageCmd(tkwin, winPtr, interp, objc, objv) - Tk_Window tkwin; /* Main window of the application. */ - TkWindow *winPtr; /* Toplevel or Frame to work with */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *const objv[]; /* Argument objects. */ +WmManageCmd( + Tk_Window tkwin, /* Main window of the application. */ + TkWindow *winPtr, /* Toplevel or Frame to work with */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - register Tk_Window frameWin = (Tk_Window)winPtr; + register Tk_Window frameWin = (Tk_Window) winPtr; register WmInfo *wmPtr = winPtr->wmInfoPtr; if (!Tk_IsTopLevel(frameWin)) { @@ -4714,11 +4645,8 @@ WmMaxsizeCmd( return TCL_ERROR; } if (objc == 3) { - char buf[TCL_INTEGER_SPACE * 2]; - GetMaxSize(wmPtr, &width, &height); - sprintf(buf, "%d %d", width, height); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d", width, height)); return TCL_OK; } if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK) @@ -4764,11 +4692,8 @@ WmMinsizeCmd( return TCL_ERROR; } if (objc == 3) { - char buf[TCL_INTEGER_SPACE * 2]; - GetMinSize(wmPtr, &width, &height); - sprintf(buf, "%d %d", width, height); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d", width, height)); return TCL_OK; } if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK) @@ -4814,7 +4739,7 @@ WmOverrideredirectCmd( Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?"); return TCL_ERROR; } - if(winPtr->flags & TK_EMBEDDED) { + if (winPtr->flags & TK_EMBEDDED) { curValue = SendMessage(wmPtr->wrapper, TK_OVERRIDEREDIRECT, -1, -1)-1; if (curValue < 0) { Tcl_AppendResult(interp, @@ -4825,14 +4750,14 @@ WmOverrideredirectCmd( curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect; } if (objc == 3) { - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), curValue); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(curValue)); return TCL_OK; } if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) { return TCL_ERROR; } if (curValue != boolean) { - if(winPtr->flags & TK_EMBEDDED) { + if (winPtr->flags & TK_EMBEDDED) { SendMessage(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolean, 0); } else { /* @@ -4844,7 +4769,7 @@ WmOverrideredirectCmd( Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, &atts); if (!(wmPtr->flags & (WM_NEVER_MAPPED)) - && !(winPtr->flags & TK_EMBEDDED)) { + && !(winPtr->flags & TK_EMBEDDED)) { UpdateWrapper(winPtr); } } @@ -4878,7 +4803,7 @@ WmPositionfromCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "program", "user", NULL }; enum options { @@ -4945,7 +4870,7 @@ WmProtocolCmd( register WmInfo *wmPtr = winPtr->wmInfoPtr; register ProtocolHandler *protPtr, *prevPtr; Atom protocol; - char *cmd; + const char *cmd; int cmdLength; if ((objc < 3) || (objc > 5)) { @@ -4993,13 +4918,13 @@ WmProtocolCmd( } else { prevPtr->nextPtr = protPtr->nextPtr; } - Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC); + Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); break; } } cmd = Tcl_GetStringFromObj(objv[4], &cmdLength); if (cmdLength > 0) { - protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength)); + protPtr = ckalloc(HANDLER_SIZE(cmdLength)); protPtr->protocol = protocol; protPtr->nextPtr = wmPtr->protPtr; wmPtr->protPtr = protPtr; @@ -5042,12 +4967,9 @@ WmResizableCmd( return TCL_ERROR; } if (objc == 3) { - char buf[TCL_INTEGER_SPACE * 2]; - - sprintf(buf, "%d %d", + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d", (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1, - (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1)); return TCL_OK; } if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK) @@ -5098,7 +5020,7 @@ WmSizefromCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "program", "user", NULL }; enum options { @@ -5164,7 +5086,7 @@ WmStackorderCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { TkWindow **windows, **window_ptr; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "isabove", "isbelow", NULL }; enum options { @@ -5181,13 +5103,12 @@ WmStackorderCmd( windows = TkWmStackorderToplevel(winPtr); if (windows == NULL) { Tcl_Panic("TkWmStackorderToplevel failed"); - } else { - for (window_ptr = windows; *window_ptr ; window_ptr++) { - Tcl_AppendElement(interp, (*window_ptr)->pathName); - } - ckfree((char *) windows); - return TCL_OK; } + for (window_ptr = windows; *window_ptr ; window_ptr++) { + Tcl_AppendElement(interp, (*window_ptr)->pathName); + } + ckfree(windows); + return TCL_OK; } else { TkWindow *winPtr2, **winPtr2Ptr = &winPtr2; int index1=-1, index2=-1, result; @@ -5221,29 +5142,28 @@ WmStackorderCmd( */ windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr); - if (windows == NULL) { Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", NULL); return TCL_ERROR; - } else { - for (window_ptr = windows; *window_ptr ; window_ptr++) { - if (*window_ptr == winPtr) { - index1 = (window_ptr - windows); - } - if (*window_ptr == winPtr2) { - index2 = (window_ptr - windows); - } - } - if (index1 == -1) { - Tcl_Panic("winPtr window not found"); + } + + for (window_ptr = windows; *window_ptr ; window_ptr++) { + if (*window_ptr == winPtr) { + index1 = (window_ptr - windows); } - if (index2 == -1) { - Tcl_Panic("winPtr2 window not found"); + if (*window_ptr == winPtr2) { + index2 = (window_ptr - windows); } - - ckfree((char *) windows); + } + if (index1 == -1) { + Tcl_Panic("winPtr window not found"); + } + if (index2 == -1) { + Tcl_Panic("winPtr2 window not found"); } + ckfree(windows); + if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, &index) != TCL_OK) { return TCL_ERROR; @@ -5253,10 +5173,9 @@ WmStackorderCmd( } else { /* OPT_ISBELOW */ result = index1 < index2; } - Tcl_SetIntObj(Tcl_GetObjResult(interp), result); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result)); return TCL_OK; } - return TCL_OK; } /* @@ -5285,7 +5204,7 @@ WmStateCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "normal", "iconic", "withdrawn", "zoomed", NULL }; enum options { @@ -5427,7 +5346,7 @@ WmTitleCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; - char *argv3; + const char *argv3; int length; HWND wrapper; @@ -5436,20 +5355,20 @@ WmTitleCmd( return TCL_ERROR; } - if(winPtr->flags & TK_EMBEDDED) { - wrapper = (HWND)SendMessage(wmPtr->wrapper, TK_GETFRAMEWID, 0, 0); + if (winPtr->flags & TK_EMBEDDED) { + wrapper = (HWND) SendMessage(wmPtr->wrapper, TK_GETFRAMEWID, 0, 0); } else { wrapper = wmPtr->wrapper; } if (objc == 3) { if (wrapper) { - char buf[512]; + TCHAR buf[256]; Tcl_DString titleString; - int size = tkWinProcs->useWide ? 256 : 512; + int size = 256; - (*tkWinProcs->getWindowText)(wrapper, (LPCTSTR)buf, size); + GetWindowText(wrapper, buf, size); Tcl_WinTCharToUtf(buf, -1, &titleString); - Tcl_SetResult(interp, Tcl_DStringValue(&titleString),TCL_VOLATILE); + Tcl_SetResult(interp, Tcl_DStringValue(&titleString), TCL_VOLATILE); Tcl_DStringFree(&titleString); } else { Tcl_SetResult(interp, (char *) @@ -5458,17 +5377,17 @@ WmTitleCmd( } } else { if (wmPtr->title != NULL) { - ckfree((char *) wmPtr->title); + ckfree(wmPtr->title); } argv3 = Tcl_GetStringFromObj(objv[3], &length); - wmPtr->title = ckalloc((unsigned) (length + 1)); - strcpy(wmPtr->title, argv3); + wmPtr->title = ckalloc(length + 1); + memcpy(wmPtr->title, argv3, (unsigned) length + 1); if (!(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper != NULL) { Tcl_DString titleString; + Tcl_WinUtfToTChar(wmPtr->title, -1, &titleString); - (*tkWinProcs->setWindowText)(wrapper, - (LPCTSTR) Tcl_DStringValue(&titleString)); + SetWindowText(wrapper, (LPCTSTR) Tcl_DStringValue(&titleString)); Tcl_DStringFree(&titleString); } } @@ -5524,7 +5443,7 @@ WmTransientCmd( masterPtr->wmInfoPtr->numTransients--; Tk_DeleteEventHandler((Tk_Window) masterPtr, VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, (ClientData) winPtr); + WmWaitVisibilityOrMapProc, winPtr); } wmPtr->masterPtr = NULL; @@ -5573,21 +5492,21 @@ WmTransientCmd( wmPtr->masterPtr->wmInfoPtr->numTransients--; Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr, VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, (ClientData) winPtr); + WmWaitVisibilityOrMapProc, winPtr); } masterPtr->wmInfoPtr->numTransients++; Tk_CreateEventHandler((Tk_Window) masterPtr, VisibilityChangeMask|StructureNotifyMask, - WmWaitVisibilityOrMapProc, (ClientData) winPtr); + WmWaitVisibilityOrMapProc, winPtr); wmPtr->masterPtr = masterPtr; } } if (!((wmPtr->flags & WM_NEVER_MAPPED) && !(winPtr->flags & TK_EMBEDDED))) { - if (wmPtr->masterPtr != NULL && - !Tk_IsMapped(wmPtr->masterPtr)) { + if (wmPtr->masterPtr != NULL + && !Tk_IsMapped(wmPtr->masterPtr)) { TkpWmSetState(winPtr, WithdrawnState); } else { UpdateWrapper(winPtr); @@ -5657,7 +5576,7 @@ WmUpdateGeom( TkWindow *winPtr) { if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); + Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); wmPtr->flags |= WM_UPDATE_PENDING; } } @@ -5668,7 +5587,7 @@ WmWaitVisibilityOrMapProc( ClientData clientData, /* Pointer to window. */ XEvent *eventPtr) /* Information about event. */ { - TkWindow *winPtr = (TkWindow *) clientData; + TkWindow *winPtr = clientData; TkWindow *masterPtr = winPtr->wmInfoPtr->masterPtr; if (masterPtr == NULL) @@ -5797,7 +5716,7 @@ Tk_SetGrid( wmPtr->heightInc = heightInc; wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc; if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); + Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); wmPtr->flags |= WM_UPDATE_PENDING; } } @@ -5857,7 +5776,7 @@ Tk_UnsetGrid( wmPtr->heightInc = 1; if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); + Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); wmPtr->flags |= WM_UPDATE_PENDING; } } @@ -5885,7 +5804,7 @@ TopLevelEventProc( ClientData clientData, /* Window for which event occurred. */ XEvent *eventPtr) /* Event that just happened. */ { - register TkWindow *winPtr = (TkWindow *) clientData; + register TkWindow *winPtr = clientData; if (eventPtr->type == DestroyNotify) { Tk_ErrorHandler handler; @@ -5900,7 +5819,7 @@ TopLevelEventProc( */ handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, - (Tk_ErrorProc *) NULL, (ClientData) NULL); + NULL, NULL); Tk_DestroyWindow((Tk_Window) winPtr); Tk_DeleteErrorHandler(handler); } @@ -5976,7 +5895,7 @@ UpdateGeometryInfo( int width, height; /* Size of client area. */ int min, max; RECT rect; - register TkWindow *winPtr = (TkWindow *) clientData; + register TkWindow *winPtr = clientData; register WmInfo *wmPtr = winPtr->wmInfoPtr; wmPtr->flags &= ~WM_UPDATE_PENDING; @@ -6252,7 +6171,7 @@ UpdateGeometryInfo( static int ParseGeometry( Tcl_Interp *interp, /* Used for error reporting. */ - char *string, /* String containing new geometry. Has the + const char *string, /* String containing new geometry. Has the * standard form "=wxh+x+y". */ TkWindow *winPtr) /* Pointer to top-level window whose geometry * is to be changed. */ @@ -6260,7 +6179,7 @@ ParseGeometry( register WmInfo *wmPtr = winPtr->wmInfoPtr; int x, y, width, height, flags; char *end; - register char *p = string; + register const char *p = string; /* * The leading "=" is optional. @@ -6352,7 +6271,7 @@ ParseGeometry( wmPtr->flags = flags; if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); + Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); wmPtr->flags |= WM_UPDATE_PENDING; } return TCL_OK; @@ -6537,9 +6456,9 @@ Tk_MoveToplevelWindow( if (!(wmPtr->flags & WM_NEVER_MAPPED)) { if (wmPtr->flags & WM_UPDATE_PENDING) { - Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr); + Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr); } - UpdateGeometryInfo((ClientData) winPtr); + UpdateGeometryInfo(winPtr); } } @@ -6587,18 +6506,18 @@ TkWmProtocolEventProc( const char *name = Tk_GetAtomName((Tk_Window) winPtr, protocol); - Tcl_Preserve((ClientData) protPtr); + Tcl_Preserve(protPtr); interp = protPtr->interp; - Tcl_Preserve((ClientData) interp); + Tcl_Preserve(interp); result = Tcl_GlobalEval(interp, protPtr->command); if (result != TCL_OK) { - Tcl_AddErrorInfo(interp, "\n (command for \""); - Tcl_AddErrorInfo(interp, name); - Tcl_AddErrorInfo(interp, "\" window manager protocol)"); - Tcl_BackgroundError(interp); + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (command for \"%s\" window manager protocol)", + name)); + Tcl_BackgroundException(interp, result); } - Tcl_Release((ClientData) interp); - Tcl_Release((ClientData) protPtr); + Tcl_Release(interp); + Tcl_Release(protPtr); return; } } @@ -6645,7 +6564,7 @@ TkWmStackorderToplevelEnumProc( hPtr = Tcl_FindHashEntry(pair->table, (char *) hwnd); if (hPtr != NULL) { - childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr); + childWinPtr = Tcl_GetHashValue(hPtr); /* * Double check that same HWND does not get passed twice. @@ -6693,8 +6612,8 @@ TkWmStackorderToplevelWrapperMap( HWND wrapper; int newEntry; - if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) && - !Tk_IsEmbedded(winPtr) && (winPtr->display == display)) { + if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) + && !Tk_IsEmbedded(winPtr) && (winPtr->display == display)) { wrapper = TkWinGetWrapperWindow((Tk_Window) winPtr); /* @@ -6745,8 +6664,7 @@ TkWmStackorderToplevel( Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS); TkWmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table); - windows = (TkWindow **) ckalloc((table.numEntries+1) - * sizeof(TkWindow *)); + windows = ckalloc((table.numEntries+1) * sizeof(TkWindow *)); /* * Special cases: If zero or one toplevels were mapped there is no need to @@ -6759,7 +6677,7 @@ TkWmStackorderToplevel( goto done; case 1: hPtr = Tcl_FirstHashEntry(&table, &search); - windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr); + windows[0] = Tcl_GetHashValue(hPtr); windows[1] = NULL; goto done; } @@ -6776,7 +6694,7 @@ TkWmStackorderToplevel( if (EnumWindows((WNDENUMPROC) TkWmStackorderToplevelEnumProc, (LPARAM) &pair) == 0) { - ckfree((char *) windows); + ckfree(windows); windows = NULL; } else if (pair.window_ptr != (windows-1)) { Tcl_Panic("num matched toplevel windows does not equal num children"); @@ -6845,7 +6763,7 @@ TkWmRestackToplevel( if (winPtr->flags & TK_EMBEDDED) { SendMessage(winPtr->wmInfoPtr->wrapper, TK_RAISEWINDOW, - (WPARAM)insertAfter, aboveBelow); + (WPARAM) insertAfter, aboveBelow); } else { TkWinSetWindowPos(hwnd, insertAfter, aboveBelow); } @@ -6924,7 +6842,7 @@ TkWmAddToColormapWindows( * Automatically add the toplevel itself as the last element of the list. */ - newPtr = (TkWindow **) ckalloc((unsigned) ((count+2)*sizeof(TkWindow*))); + newPtr = ckalloc((count+2) * sizeof(TkWindow *)); if (count > 0) { memcpy(newPtr, oldPtr, count * sizeof(TkWindow*)); } @@ -6934,7 +6852,7 @@ TkWmAddToColormapWindows( newPtr[count-1] = winPtr; newPtr[count] = topPtr; if (oldPtr != NULL) { - ckfree((char *) oldPtr); + ckfree(oldPtr); } topPtr->wmInfoPtr->cmapList = newPtr; @@ -7066,12 +6984,12 @@ TkWinSetMenu( } if (!(winPtr->flags & TK_EMBEDDED)) { if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); + Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); wmPtr->flags |= WM_UPDATE_PENDING|WM_MOVE_PENDING; } } else { - SendMessage(wmPtr->wrapper, TK_SETMENU, - (WPARAM)hMenu, (LPARAM)Tk_GetMenuHWND(tkwin)); + SendMessage(wmPtr->wrapper, TK_SETMENU, (WPARAM) hMenu, + (LPARAM) Tk_GetMenuHWND(tkwin)); } } @@ -7151,7 +7069,7 @@ ConfigureTopLevel( */ if (!(wmPtr->flags & WM_UPDATE_PENDING)) { - Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); + Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); wmPtr->flags |= WM_UPDATE_PENDING; } /* fall through */ @@ -7354,7 +7272,7 @@ InstallColormaps( ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - if (winPtr == NULL || (winPtr->flags & TK_ALREADY_DEAD) ) { + if (winPtr == NULL || (winPtr->flags & TK_ALREADY_DEAD)) { return 0; } @@ -7384,11 +7302,9 @@ InstallColormaps( SelectPalette(dc, oldPalette, TRUE); RealizePalette(dc); ReleaseDC(hwnd, dc); - SendMessage(hwnd, WM_PALETTECHANGED, (WPARAM)hwnd, - (LPARAM)NULL); + SendMessage(hwnd, WM_PALETTECHANGED, (WPARAM) hwnd, (LPARAM) NULL); return TRUE; } - } else { /* * Window is being notified of a change in the system palette. If this @@ -7850,7 +7766,7 @@ WmProc( break; case WM_ACTIVATE: - if ( WA_ACTIVE == LOWORD(wParam) ) { + if (WA_ACTIVE == LOWORD(wParam)) { winPtr = GetTopLevel(hwnd); if (winPtr && (TkGrabState(winPtr) == TK_GRAB_EXCLUDED)) { /* @@ -7927,7 +7843,7 @@ WmProc( case WM_PALETTECHANGED: result = InstallColormaps(hwnd, WM_PALETTECHANGED, - hwnd == (HWND)wParam); + hwnd == (HWND) wParam); goto done; case WM_QUERYNEWPALETTE: @@ -7973,8 +7889,7 @@ WmProc( * 2272] */ - result = (*tkWinProcs->defWindowProc)(hwnd, message, - wParam, lParam); + result = DefWindowProc(hwnd, message, wParam, lParam); goto done; } @@ -8048,7 +7963,7 @@ WmProc( case WM_ENTERIDLE: case WM_INITMENUPOPUP: if (winPtr) { - HWND hMenuHWnd = Tk_GetEmbeddedMenuHWND((Tk_Window)winPtr); + HWND hMenuHWnd = Tk_GetEmbeddedMenuHWND((Tk_Window) winPtr); if (hMenuHWnd) { if (SendMessage(hMenuHWnd, message, wParam, lParam)) { @@ -8070,11 +7985,10 @@ WmProc( result = 0; } else if (!Tk_TranslateWinEvent(child, message, wParam, lParam, &result)) { - result = (*tkWinProcs->defWindowProc)(hwnd, message, - wParam, lParam); + result = DefWindowProc(hwnd, message, wParam, lParam); } } else { - result = (*tkWinProcs->defWindowProc)(hwnd, message, wParam, lParam); + result = DefWindowProc(hwnd, message, wParam, lParam); } done: @@ -8120,8 +8034,8 @@ TkpMakeMenuWindow( if ((atts.override_redirect != Tk_Attributes(tkwin)->override_redirect) || (atts.save_under != Tk_Attributes(tkwin)->save_under)) { - Tk_ChangeWindowAttributes(tkwin, - CWOverrideRedirect|CWSaveUnder, &atts); + Tk_ChangeWindowAttributes(tkwin, CWOverrideRedirect|CWSaveUnder, + &atts); } } @@ -8146,8 +8060,9 @@ HWND TkWinGetWrapperWindow( Tk_Window tkwin) /* The window we need the wrapper from */ { - TkWindow *winPtr = (TkWindow *)tkwin; - return (winPtr->wmInfoPtr->wrapper); + TkWindow *winPtr = (TkWindow *) tkwin; + + return winPtr->wmInfoPtr->wrapper; } /* @@ -8223,8 +8138,8 @@ TkpGetWrapperWindow( static void GenerateActivateEvent(TkWindow * winPtr, const int *flagPtr) { - ActivateEvent *eventPtr; - eventPtr = (ActivateEvent *)ckalloc(sizeof(ActivateEvent)); + ActivateEvent *eventPtr = ckalloc(sizeof(ActivateEvent)); + eventPtr->ev.proc = ActivateWindow; eventPtr->winPtr = winPtr; eventPtr->flagPtr = flagPtr; @@ -8357,6 +8272,7 @@ TkpWinToplevelWithDraw( TkWindow *winPtr) { register WmInfo *wmPtr = winPtr->wmInfoPtr; + wmPtr->flags |= WM_WITHDRAWN; TkpWmSetState(winPtr, WithdrawnState); } @@ -8416,10 +8332,10 @@ TkpWinToplevelDeiconify( * 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 ((wmPtr->flags & WM_UPDATE_PENDING) + && !(wmPtr->flags & WM_NEVER_MAPPED)) { + Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr); + UpdateGeometryInfo(winPtr); } /* @@ -8476,11 +8392,10 @@ TkpWinToplevelIsControlledByWm( { register WmInfo *wmPtr = winPtr->wmInfoPtr; - if (wmPtr) { - return ((wmPtr->width != -1) && (wmPtr->height != -1))? 1:0; - } else { + if (!wmPtr) { return 0; } + return ((wmPtr->width != -1) && (wmPtr->height != -1)) ? 1 : 0; } /* @@ -8508,7 +8423,7 @@ TkpWinToplevelMove( register WmInfo *wmPtr = winPtr->wmInfoPtr; if (wmPtr && x >= 0 && y >= 0 && !TkpWinToplevelIsControlledByWm(winPtr)) { - Tk_MoveToplevelWindow((Tk_Window)winPtr, x, y); + Tk_MoveToplevelWindow((Tk_Window) winPtr, x, y); } return ((winPtr->changes.x << 16) & 0xffff0000) | (winPtr->changes.y & 0xffff); @@ -8540,7 +8455,9 @@ TkpWinToplevelOverrideRedirect( register WmInfo *wmPtr = winPtr->wmInfoPtr; curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect; - if(reqValue < 0) return curValue; + if (reqValue < 0) { + return curValue; + } if (curValue != reqValue) { XSetWindowAttributes atts; @@ -8606,8 +8523,7 @@ TkpWinToplevelDetachWindow( * * RemapWindows * - * Adjust parent/child relation ships of - * the given window hierarchy. + * Adjust parent/child relation ships of the given window hierarchy. * * Results: * none @@ -8619,14 +8535,17 @@ TkpWinToplevelDetachWindow( */ static void -RemapWindows(winPtr, parentHWND) - TkWindow *winPtr; - HWND parentHWND; +RemapWindows( + TkWindow *winPtr, + HWND parentHWND) { TkWindow *childPtr; const char *className = Tk_Class(winPtr); - /* Skip Menus as they are handled differently */ + /* + * Skip menus as they are handled differently. + */ + if (className != NULL && strcmp(className, "Menu") == 0) { return; } @@ -8634,9 +8553,12 @@ RemapWindows(winPtr, parentHWND) SetParent(Tk_GetHWND(winPtr->window), parentHWND); } - /* Repeat for all the children */ + /* + * Repeat for all the children. + */ + for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { + childPtr = childPtr->nextPtr) { RemapWindows(childPtr, winPtr->window ? Tk_GetHWND(winPtr->window) : NULL); } diff --git a/win/tkWinX.c b/win/tkWinX.c index 2d5f5f5..3a02d05 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -11,14 +11,6 @@ * 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" /* @@ -28,7 +20,7 @@ */ #ifndef _WIN32_IE -#define _WIN32_IE 0x0501 /* IE 5 */ +#define _WIN32_IE 0x0550 /* IE 5.5 */ #endif #include <commctrl.h> @@ -61,49 +53,11 @@ #define UNICODE_NOCHAR 0xFFFF #endif -static TkWinProcs asciiProcs = { - 0, - - (LRESULT (WINAPI *)(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, - WPARAM wParam, LPARAM lParam)) CallWindowProcA, - (LRESULT (WINAPI *)(HWND hWnd, UINT Msg, WPARAM wParam, - LPARAM lParam)) DefWindowProcA, - (ATOM (WINAPI *)(CONST WNDCLASS *lpWndClass)) RegisterClassA, - (BOOL (WINAPI *)(HWND hWnd, LPCTSTR lpString)) SetWindowTextA, - (HWND (WINAPI *)(DWORD dwExStyle, LPCTSTR lpClassName, - LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, - int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, - 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 = { - 1, - - (LRESULT (WINAPI *)(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, - WPARAM wParam, LPARAM lParam)) CallWindowProcW, - (LRESULT (WINAPI *)(HWND hWnd, UINT Msg, WPARAM wParam, - LPARAM lParam)) DefWindowProcW, - (ATOM (WINAPI *)(CONST WNDCLASS *lpWndClass)) RegisterClassW, - (BOOL (WINAPI *)(HWND hWnd, LPCTSTR lpString)) SetWindowTextW, - (HWND (WINAPI *)(DWORD dwExStyle, LPCTSTR lpClassName, - LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, - int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, - 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; - /* * Declarations of static variables used in this file. */ -static char winScreenName[] = ":0"; /* Default name of windows display. */ +static const char winScreenName[] = ":0"; /* Default name of windows display. */ static HINSTANCE tkInstance = NULL; /* Application instance handle. */ static int childClassInitialized; /* Registered child class? */ static WNDCLASS childClass; /* Window class for child windows. */ @@ -266,12 +220,6 @@ TkWinXInit( Tcl_Panic("Unable to load common controls?!"); } - if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - tkWinProcs = &unicodeProcs; - } else { - tkWinProcs = &asciiProcs; - } - childClass.style = CS_HREDRAW | CS_VREDRAW; childClass.cbClsExtra = 0; childClass.cbWndExtra = 0; @@ -364,9 +312,10 @@ TkWinXCleanup( * * Results: * The return value is one of: - * VER_PLATFORM_WIN32s Win32s on Windows 3.1. - * VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95. - * VER_PLATFORM_WIN32_NT Win32 on Windows NT + * VER_PLATFORM_WIN32s Win32s on Windows 3.1 (not supported) + * VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95, 98, ME (not supported) + * VER_PLATFORM_WIN32_NT Win32 on Windows NT, 2000, XP + * VER_PLATFORM_WIN32_CE Win32 on Windows CE * * Side effects: * None. @@ -393,8 +342,8 @@ TkWinGetPlatformId(void) if ((os.dwPlatformId == VER_PLATFORM_WIN32_NT) && (os.dwMajorVersion == 5 && os.dwMinorVersion == 1)) { HKEY hKey; - LPCSTR szSubKey = TEXT("Control Panel\\Appearance"); - LPCSTR szCurrent = TEXT("Current"); + LPCTSTR szSubKey = TEXT("Control Panel\\Appearance"); + LPCTSTR szCurrent = TEXT("Current"); DWORD dwSize = 200; char pBuffer[200]; @@ -462,10 +411,10 @@ TkWinGetPlatformTheme(void) *---------------------------------------------------------------------- */ -CONST char * +const char * TkGetDefaultScreenName( Tcl_Interp *interp, /* Not used. */ - CONST char *screenName) /* If NULL, use default string. */ + const char *screenName) /* If NULL, use default string. */ { if ((screenName == NULL) || (screenName[0] == '\0')) { screenName = winScreenName; @@ -523,9 +472,9 @@ TkWinDisplayChanged( screen->root_depth = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data); if (screen->root_visual != NULL) { - ckfree((char *) screen->root_visual); + ckfree(screen->root_visual); } - screen->root_visual = (Visual *) ckalloc(sizeof(Visual)); + screen->root_visual = ckalloc(sizeof(Visual)); screen->root_visual->visualid = 0; if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) { screen->root_visual->map_entries = GetDeviceCaps(dc, SIZEPALETTE); @@ -587,12 +536,12 @@ TkWinDisplayChanged( TkDisplay * TkpOpenDisplay( - CONST char *display_name) + const char *display_name) { Screen *screen; TkWinDrawable *twdPtr; Display *display; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->winDisplay != NULL) { @@ -603,10 +552,10 @@ TkpOpenDisplay( } } - display = (Display *) ckalloc(sizeof(Display)); + display = ckalloc(sizeof(Display)); ZeroMemory(display, sizeof(Display)); - display->display_name = (char *) ckalloc(strlen(display_name)+1); + display->display_name = ckalloc(strlen(display_name) + 1); strcpy(display->display_name, display_name); display->cursor_font = 1; @@ -614,7 +563,7 @@ TkpOpenDisplay( display->request = 1; display->qlen = 0; - screen = (Screen *) ckalloc(sizeof(Screen)); + screen = ckalloc(sizeof(Screen)); ZeroMemory(screen, sizeof(Screen)); screen->display = display; @@ -622,7 +571,7 @@ TkpOpenDisplay( * Set up the root window. */ - twdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable)); + twdPtr = ckalloc(sizeof(TkWinDrawable)); if (twdPtr == NULL) { return None; } @@ -645,7 +594,7 @@ TkpOpenDisplay( TkWinDisplayChanged(display); - tsdPtr->winDisplay = (TkDisplay *) ckalloc(sizeof(TkDisplay)); + tsdPtr->winDisplay = ckalloc(sizeof(TkDisplay)); ZeroMemory(tsdPtr->winDisplay, sizeof(TkDisplay)); tsdPtr->winDisplay->display = display; tsdPtr->updatingClipboard = FALSE; @@ -690,17 +639,17 @@ TkpCloseDisplay( } if (display->screens != NULL) { if (display->screens->root_visual != NULL) { - ckfree((char *) display->screens->root_visual); + ckfree(display->screens->root_visual); } if (display->screens->root != None) { - ckfree((char *) display->screens->root); + ckfree(display->screens->root); } if (display->screens->cmap != None) { XFreeColormap(display, display->screens->cmap); } - ckfree((char *) display->screens); + ckfree(display->screens); } - ckfree((char *) display); + ckfree(display); } /* @@ -1004,7 +953,23 @@ GenerateXEvent( ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - winPtr = (TkWindow *)Tk_HWNDToWindow(hwnd); + if (message == WM_MOUSEWHEEL) { + union {LPARAM lParam; POINTS point;} root; + POINT pos; + root.lParam = lParam; + + /* + * Redirect mousewheel events to the window containing the cursor. + * That feels much less strange to users, and is how all the other + * platforms work. + */ + + pos.x = root.point.x; + pos.y = root.point.y; + hwnd = WindowFromPoint(pos); + } + + winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); if (!winPtr || winPtr->window == None) { return; } @@ -1103,11 +1068,6 @@ GenerateXEvent( 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: @@ -1386,12 +1346,12 @@ GetTranslatedKey( xkey->nbytes = 0; while ((xkey->nbytes < XMaxTransChars) - && PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { + && PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE)) { if ((msg.message != WM_CHAR) && (msg.message != WM_SYSCHAR)) { break; } - GetMessage(&msg, NULL, 0, 0); + GetMessageA(&msg, NULL, 0, 0); /* * If this is a normal character message, we may need to strip off the @@ -1562,7 +1522,6 @@ HandleIMEComposition( { HIMC hIMC; int n; - BOOL isWinNT = (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT); if ((lParam & GCS_RESULTSTR) == 0) { /* @@ -1577,47 +1536,15 @@ HandleIMEComposition( return 0; } - if (isWinNT) { - n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0); - } else { - n = ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, NULL, 0); - } + n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); if (n > 0) { - char *buff = ckalloc((unsigned) n); + char *buff = ckalloc(n); TkWindow *winPtr; XEvent event; int i; - if (isWinNT) { - n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff, - (unsigned) n); - } else { - 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. - */ - - ckfree((char *) buff); - buff = (char *) ckalloc((unsigned) i); - } - n = i; - memcpy(buff, Tcl_DStringValue(&unicodeString), (unsigned) n); - Tcl_DStringFree(&utfString); - Tcl_DStringFree(&unicodeString); - } + n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, buff, (unsigned) n); /* * Set up the fields pertinent to key event. @@ -1930,32 +1857,10 @@ long Tk_GetUserInactiveTime( Display *dpy) /* Ignored on Windows */ { - struct tagLASTINPUTINFO { - UINT cbSize; - DWORD dwTime; - } li; + LASTINPUTINFO 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)) { + if (!(BOOL)GetLastInputInfo(&li)) { return -1; } diff --git a/win/ttkWinMonitor.c b/win/ttkWinMonitor.c index 25c9c0c..04baa16 100644 --- a/win/ttkWinMonitor.c +++ b/win/ttkWinMonitor.c @@ -92,7 +92,7 @@ CreateThemeMonitorWindow(HINSTANCE hinst, Tcl_Interp *interp) hwnd = CreateWindow( name, title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hinst, NULL ); - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)interp); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) interp); ShowWindow(hwnd, SW_HIDE); UpdateWindow(hwnd); } diff --git a/win/ttkWinTheme.c b/win/ttkWinTheme.c index e0a0eda..63e9704 100644 --- a/win/ttkWinTheme.c +++ b/win/ttkWinTheme.c @@ -490,7 +490,7 @@ static void TroughClientDataDeleteProc(void *clientData) static TroughClientData *TroughClientDataInit(Tcl_Interp *interp) { - TroughClientData *cd = (TroughClientData*)ckalloc(sizeof(*cd)); + TroughClientData *cd = ckalloc(sizeof(*cd)); cd->PatternBitmap = CreateBitmap(8, 8, 1, 1, Pattern); cd->PatternBrush = CreatePatternBrush(cd->PatternBitmap); Ttk_RegisterCleanup(interp, cd, TroughClientDataDeleteProc); diff --git a/win/ttkWinXPTheme.c b/win/ttkWinXPTheme.c index e2f916f..af6103b 100644 --- a/win/ttkWinXPTheme.c +++ b/win/ttkWinXPTheme.c @@ -106,7 +106,7 @@ LoadXPThemeProcs(HINSTANCE *phlib) * We have successfully loaded the library. Proceed in storing the * addresses of the functions we want to use. */ - XPThemeProcs *procs = (XPThemeProcs*)ckalloc(sizeof(XPThemeProcs)); + XPThemeProcs *procs = ckalloc(sizeof(XPThemeProcs)); #define LOADPROC(name) \ (0 != (procs->name = (name ## Proc *)GetProcAddress(handle, #name) )) @@ -124,7 +124,7 @@ LoadXPThemeProcs(HINSTANCE *phlib) return procs; } #undef LOADPROC - ckfree((char*)procs); + ckfree(procs); } return 0; } @@ -411,7 +411,7 @@ typedef struct static ElementData * NewElementData(XPThemeProcs *procs, ElementInfo *info) { - ElementData *elementData = (ElementData*)ckalloc(sizeof(ElementData)); + ElementData *elementData = ckalloc(sizeof(ElementData)); elementData->procs = procs; elementData->info = info; @@ -429,10 +429,10 @@ 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(elementData->info->statemap); + ckfree(elementData->info->className); + ckfree(elementData->info->elementName); + ckfree(elementData->info); } ckfree(clientData); } @@ -1197,8 +1197,7 @@ Ttk_CreateVsapiElement( 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)); + 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}; @@ -1211,15 +1210,15 @@ Ttk_CreateVsapiElement( } } if (status != TCL_OK) { - ckfree((char *)stateTable); + ckfree(stateTable); return status; } } else { - stateTable = (Ttk_StateTable *)ckalloc(sizeof(Ttk_StateTable)); + stateTable = ckalloc(sizeof(Ttk_StateTable)); memset(stateTable, 0, sizeof(Ttk_StateTable)); } - elementPtr = (ElementInfo *)ckalloc(sizeof(ElementInfo)); + elementPtr = ckalloc(sizeof(ElementInfo)); elementPtr->elementSpec = elementSpec; elementPtr->partId = partId; elementPtr->statemap = stateTable; @@ -1232,7 +1231,7 @@ Ttk_CreateVsapiElement( elementPtr->elementName = name; /* set the class name to an allocated copy */ - wname = (LPWSTR) ckalloc(sizeof(WCHAR) * (length + 1)); + wname = ckalloc(sizeof(WCHAR) * (length + 1)); wcscpy(wname, className); elementPtr->className = wname; @@ -1279,7 +1278,7 @@ MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd) * Set theme data and cleanup proc */ - themeData = (XPThemeData *)ckalloc(sizeof(XPThemeData)); + themeData = ckalloc(sizeof(XPThemeData)); themeData->procs = procs; themeData->hlibrary = hlibrary; diff --git a/win/winMain.c b/win/winMain.c index eea7004..353c2b8 100644 --- a/win/winMain.c +++ b/win/winMain.c @@ -1,25 +1,25 @@ /* * winMain.c -- * - * Main entry point for wish and other Tk-based applications. + * Provides a default version of the main program and Tcl_AppInit + * procedure for wish and other Tk-based applications. * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-1999 by Scriptics Corporation. + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-1999 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "tkInt.h" +#include "tk.h" #define WIN32_LEAN_AND_MEAN #include <windows.h> #undef WIN32_LEAN_AND_MEAN #include <locale.h> +#include <stdlib.h> +#include <tchar.h> -/* - * 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 */ @@ -30,12 +30,14 @@ extern Tcl_PackageInitProc Dde_Init; extern Tcl_PackageInitProc Dde_SafeInit; #endif +#ifdef TCL_BROKEN_MAINARGS +static void setargv(int *argcPtr, TCHAR ***argvPtr); +#endif + /* * Forward declarations for procedures defined later in this file: */ -static void WishPanic(CONST char *format, ...); - static BOOL consoleRequired = TRUE; /* @@ -56,13 +58,13 @@ extern int TK_LOCAL_APPINIT(Tcl_Interp *interp); */ #ifdef TK_LOCAL_MAIN_HOOK -extern int TK_LOCAL_MAIN_HOOK(int *argc, char ***argv); +extern int TK_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); #endif /* *---------------------------------------------------------------------- * - * WinMain -- + * _tWinMain -- * * Main entry point from Windows. * @@ -76,17 +78,23 @@ extern int TK_LOCAL_MAIN_HOOK(int *argc, char ***argv); */ int APIENTRY +#ifdef TCL_BROKEN_MAINARGS WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) +#else +_tWinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpszCmdLine, + int nCmdShow) +#endif { - char **argv; + TCHAR **argv; int argc; - char *p; - - Tcl_SetPanicProc(WishPanic); + TCHAR *p; /* * Create the console channels and install them as the standard channels. @@ -107,16 +115,20 @@ WinMain( * Get our args from the c-runtime. Ignore lpszCmdLine. */ +#if defined(TCL_BROKEN_MAINARGS) + setargv(&argc, &argv); +#else argc = __argc; - argv = __argv; + argv = __targv; +#endif /* * Forward slashes substituted for backslashes. */ - for (p = argv[0]; *p != '\0'; p++) { - if (*p == '\\') { - *p = '/'; + for (p = argv[0]; *p != TEXT('\0'); p++) { + if (*p == TEXT('\\')) { + *p = TEXT('/'); } } @@ -125,7 +137,7 @@ WinMain( #endif Tk_Main(argc, argv, TK_LOCAL_APPINIT); - return 1; + return 0; /* Needed only to prevent compiler warning. */ } /* @@ -151,14 +163,11 @@ int 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; + if ((Tcl_Init)(interp) == TCL_ERROR) { + return TCL_ERROR; } if (Tk_Init(interp) == TCL_ERROR) { - goto error; + return TCL_ERROR; } Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit); @@ -169,26 +178,26 @@ Tcl_AppInit( if (consoleRequired) { if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) { - goto error; + return TCL_ERROR; } } #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES if (Registry_Init(interp) == TCL_ERROR) { - goto error; + return TCL_ERROR; } - Tcl_StaticPackage(interp, "registry", Registry_Init, NULL); + Tcl_StaticPackage(interp, "registry", Registry_Init, 0); if (Dde_Init(interp) == TCL_ERROR) { - goto error; + return TCL_ERROR; } - Tcl_StaticPackage(interp, "dde", Dde_Init, NULL); + Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit); #endif #ifdef TK_TEST if (Tktest_Init(interp) == TCL_ERROR) { - goto error; + return TCL_ERROR; } - Tcl_StaticPackage(interp, "Tktest", Tktest_Init, NULL); + Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0); #endif /* TK_TEST */ /* @@ -215,76 +224,15 @@ Tcl_AppInit( * specific startup file will be run under any conditions. */ - Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY); + (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); - 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. - */ - - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * WishPanic -- - * - * Display a message and exit. - * - * Results: - * None. - * - * Side effects: - * Exits the program. - * - *---------------------------------------------------------------------- - */ - -void -WishPanic( - CONST char *format, ...) -{ - va_list 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); - 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(TK_TEST) /* *---------------------------------------------------------------------- * - * main -- + * _tmain -- * * Main entry point from the console. * @@ -298,13 +246,20 @@ WishPanic( *---------------------------------------------------------------------- */ +#ifdef TCL_BROKEN_MAINARGS int main( int argc, - char **argv) + char **dummy) { - Tcl_SetPanicProc(WishPanic); - + TCHAR **argv; +#else +int +_tmain( + int argc, + TCHAR **argv) +{ +#endif /* * Set up the default locale to be standard "C" locale so parsing is * performed correctly. @@ -312,6 +267,13 @@ main( setlocale(LC_ALL, "C"); +#ifdef TCL_BROKEN_MAINARGS + /* + * Get our args from the c-runtime. Ignore argc/argv. + */ + + setargv(&argc, &argv); +#endif /* * Console emulation widget not required as this entry is from the * console subsystem, thus stdin,out,err already have end-points. @@ -319,10 +281,140 @@ main( consoleRequired = FALSE; +#ifdef TK_LOCAL_MAIN_HOOK + TK_LOCAL_MAIN_HOOK(&argc, &argv); +#endif + Tk_Main(argc, argv, Tcl_AppInit); return 0; } -#endif /* TK_TEST */ +#endif /* !__GNUC__ || TK_TEST */ + + +/* + *------------------------------------------------------------------------- + * + * setargv -- + * + * Parse the Windows command line string into argc/argv. Done here + * because we don't trust the builtin argument parser in crt0. Windows + * applications are responsible for breaking their command line into + * arguments. + * + * 2N backslashes + quote -> N backslashes + begin quoted string + * 2N + 1 backslashes + quote -> literal + * N backslashes + non-quote -> literal + * quote + quote in a quoted string -> single quote + * quote + quote not in quoted string -> empty string + * quote -> begin quoted string + * + * Results: + * Fills argcPtr with the number of arguments and argvPtr with the array + * of arguments. + * + * Side effects: + * Memory allocated. + * + *-------------------------------------------------------------------------- + */ + +#ifdef TCL_BROKEN_MAINARGS +static void +setargv( + int *argcPtr, /* Filled with number of argument strings. */ + TCHAR ***argvPtr) /* Filled with argument strings (malloc'd). */ +{ + TCHAR *cmdLine, *p, *arg, *argSpace; + TCHAR **argv; + int argc, size, inquote, copy, slashes; + + cmdLine = GetCommandLine(); + + /* + * Precompute an overly pessimistic guess at the number of arguments in + * the command line by counting non-space spans. + */ + + size = 2; + for (p = cmdLine; *p != TEXT('\0'); p++) { + if ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */ + size++; + while ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */ + p++; + } + if (*p == TEXT('\0')) { + break; + } + } + } + + /* Make sure we don't call ckalloc through the (not yet initialized) stub table */ + #undef Tcl_Alloc + #undef Tcl_DbCkalloc + + argSpace = ckalloc(size*sizeof(char *) + + (_tcslen(cmdLine)+1) * sizeof(TCHAR)); + argv = (TCHAR **) argSpace; + argSpace += size * (sizeof(char *)/sizeof(TCHAR)); + size--; + + p = cmdLine; + for (argc = 0; argc < size; argc++) { + argv[argc] = arg = argSpace; + while ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */ + p++; + } + if (*p == TEXT('\0')) { + break; + } + + inquote = 0; + slashes = 0; + while (1) { + copy = 1; + while (*p == TEXT('\\')) { + slashes++; + p++; + } + if (*p == TEXT('"')) { + if ((slashes & 1) == 0) { + copy = 0; + if ((inquote) && (p[1] == TEXT('"'))) { + p++; + copy = 1; + } else { + inquote = !inquote; + } + } + slashes >>= 1; + } + + while (slashes) { + *arg = TEXT('\\'); + arg++; + slashes--; + } + + if ((*p == TEXT('\0')) || (!inquote && + ((*p == TEXT(' ')) || (*p == TEXT('\t'))))) { /* INTL: ISO space. */ + break; + } + if (copy != 0) { + *arg = *p; + arg++; + } + p++; + } + *arg = '\0'; + argSpace = arg + 1; + } + argv[argc] = 0; + + *argcPtr = argc; + *argvPtr = argv; +} +#endif /* TCL_BROKEN_MAINARGS */ + /* * Local Variables: * mode: c |