Index: generic/tkInt.h ================================================================== --- generic/tkInt.h +++ generic/tkInt.h @@ -1222,10 +1222,12 @@ ClientData clientData, const TkEnsemble *map); MODULE_SCOPE int TkInitTkCmd(Tcl_Interp *interp, ClientData clientData); MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp, ClientData clientData); +MODULE_SCOPE void TkInitEmbeddedConfigurationInformation( + Tcl_Interp *interp); MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr); MODULE_SCOPE void TkpCancelWarp(TkDisplay *dispPtr); MODULE_SCOPE int TkListCreateFrame(ClientData clientData, Tcl_Interp *interp, Tcl_Obj *listObj, int toplevel, Tcl_Obj *nameObj); ADDED generic/tkPkgConfig.c Index: generic/tkPkgConfig.c ================================================================== --- /dev/null +++ generic/tkPkgConfig.c @@ -0,0 +1,142 @@ +/* + * tkPkgConfig.c -- + * + * This file contains the configuration information to embed into the tcl + * binary library. + * + * Copyright (c) 2002 Andreas Kupries + * Copyright (c) 2017 Stuart Cassoff + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +/* Note, the definitions in this module are influenced by the following C + * preprocessor macros: + * + * OSCMa = shortcut for "old style configuration macro activates" + * NSCMdt = shortcut for "new style configuration macro declares that" + * + * - TCL_THREADS OSCMa compilation as threaded. + * - TCL_MEM_DEBUG OSCMa memory debugging. + * + * - TCL_CFG_DO64BIT NSCMdt tk is compiled for a 64bit system. + * - NDEBUG NSCMdt tk is compiled with symbol info off. + * - TCL_CFG_OPTIMIZED NSCMdt tk is compiled with cc optimizations on + * - TCL_CFG_PROFILED NSCMdt tk is compiled with profiling info. + * + * - _WIN32 || __CYGWIN__ The value for the fontsytem key will be + * MAC_OSX_TK chosen based on these macros/defines. + * HAVE_XFT NSCMdt xft font support was requested. + * + * - CFG_RUNTIME_* Paths to various stuff at runtime. + * - CFG_INSTALL_* Paths to various stuff at installation time. + * + * - TCL_CFGVAL_ENCODING string containing the encoding used for the + * configuration values. + */ + +#include "tkInt.h" + + +#ifndef TCL_CFGVAL_ENCODING +#define TCL_CFGVAL_ENCODING "ascii" +#endif + +/* + * Use C preprocessor statements to define the various values for the embedded + * configuration information. + */ + +#ifdef TCL_THREADS +# define CFG_THREADED "1" +#else +# define CFG_THREADED "0" +#endif + +#ifdef TCL_MEM_DEBUG +# define CFG_MEMDEBUG "1" +#else +# define CFG_MEMDEBUG "0" +#endif + +#ifdef TCL_CFG_DO64BIT +# define CFG_64 "1" +#else +# define CFG_64 "0" +#endif + +#ifndef NDEBUG +# define CFG_DEBUG "1" +#else +# define CFG_DEBUG "0" +#endif + +#ifdef TCL_CFG_OPTIMIZED +# define CFG_OPTIMIZED "1" +#else +# define CFG_OPTIMIZED "0" +#endif + +#ifdef TCL_CFG_PROFILED +# define CFG_PROFILED "1" +#else +# define CFG_PROFILED "0" +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# define CFG_FONTSYSTEM "gdi" +#elif defined(MAC_OSX_TK) +# define CFG_FONTSYSTEM "cocoa" +#elif defined(HAVE_XFT) +# define CFG_FONTSYSTEM "xft" +#else +# define CFG_FONTSYSTEM "x11" +#endif + +static Tcl_Config const cfg[] = { + {"debug", CFG_DEBUG}, + {"threaded", CFG_THREADED}, + {"profiled", CFG_PROFILED}, + {"64bit", CFG_64}, + {"optimized", CFG_OPTIMIZED}, + {"mem_debug", CFG_MEMDEBUG}, + {"fontsystem", CFG_FONTSYSTEM}, + + /* Runtime paths to various stuff */ + + {"libdir,runtime", CFG_RUNTIME_LIBDIR}, + {"bindir,runtime", CFG_RUNTIME_BINDIR}, + {"scriptdir,runtime", CFG_RUNTIME_SCRDIR}, + {"includedir,runtime", CFG_RUNTIME_INCDIR}, + {"docdir,runtime", CFG_RUNTIME_DOCDIR}, + {"demodir,runtime", CFG_RUNTIME_DEMODIR}, + + /* Installation paths to various stuff */ + + {"libdir,install", CFG_INSTALL_LIBDIR}, + {"bindir,install", CFG_INSTALL_BINDIR}, + {"scriptdir,install", CFG_INSTALL_SCRDIR}, + {"includedir,install", CFG_INSTALL_INCDIR}, + {"docdir,install", CFG_INSTALL_DOCDIR}, + {"demodir,install", CFG_INSTALL_DEMODIR}, + + /* Last entry, closes the array */ + {NULL, NULL} +}; + +void +TkInitEmbeddedConfigurationInformation( + Tcl_Interp *interp) /* Interpreter the configuration command is + * registered in. */ +{ + Tcl_RegisterConfig(interp, "tk", cfg, TCL_CFGVAL_ENCODING); +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ Index: generic/tkWindow.c ================================================================== --- generic/tkWindow.c +++ generic/tkWindow.c @@ -3062,10 +3062,16 @@ if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { return TCL_ERROR; } + /* + * TIP #59: Make embedded configuration information available. + */ + + TkInitEmbeddedConfigurationInformation(interp); + /* * Ensure that our obj-types are registered with the Tcl runtime. */ TkRegisterObjTypes(); Index: macosx/tkMacOSXMenus.c ================================================================== --- macosx/tkMacOSXMenus.c +++ macosx/tkMacOSXMenus.c @@ -289,23 +289,22 @@ static Tcl_Obj * GetWidgetDemoPath( Tcl_Interp *interp) { - Tcl_Obj *libpath, *result = NULL; + Tcl_Obj *result = NULL; - libpath = Tcl_GetVar2Ex(interp, "tk_library", NULL, TCL_GLOBAL_ONLY); - if (libpath) { - Tcl_Obj *demo[2] = { Tcl_NewStringObj("demos", 5), - Tcl_NewStringObj("widget", 6) }; + if (Tcl_EvalEx(interp, "::tk::pkgconfig get demodir,runtime", + -1, TCL_EVAL_GLOBAL) == TCL_OK) { + Tcl_Obj *libpath, *demo[1] = { Tcl_NewStringObj("widget", 6) }; + libpath = Tcl_GetObjResult(interp); Tcl_IncrRefCount(libpath); - result = Tcl_FSJoinToPath(libpath, 2, demo); + result = Tcl_FSJoinToPath(libpath, 1, demo); Tcl_DecrRefCount(libpath); - } else { - Tcl_ResetResult(interp); } + Tcl_ResetResult(interp); return result; } /* *---------------------------------------------------------------------- ADDED tests/pkgconfig.test Index: tests/pkgconfig.test ================================================================== --- /dev/null +++ tests/pkgconfig.test @@ -0,0 +1,66 @@ +# -*- tcl -*- +# Commands covered: pkgconfig +# +# This file contains a collection of tests for one or more of the Tk +# built-in commands. Sourcing this file into Tk runs the tests and +# generates output for errors. No output means no errors were found. +# +# Copyright (c) 1991-1993 The Regents of the University of California. +# Copyright (c) 1994-1996 Sun Microsystems, Inc. +# Copyright (c) 1998-1999 by Scriptics Corporation. +# Copyright (c) 2017 Stuart Cassoff +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +package require tcltest 2.2 +namespace import ::tcltest::* +eval tcltest::configure $argv +tcltest::loadTestedCommands + +test pkgconfig-1.1 {query keys} { + lsort [::tk::pkgconfig list] +} [list \ + 64bit bindir,install bindir,runtime debug demodir,install demodir,runtime \ + docdir,install docdir,runtime fontsystem includedir,install includedir,runtime \ + libdir,install libdir,runtime mem_debug optimized profiled \ + scriptdir,install scriptdir,runtime threaded \ +] +test pkgconfig-1.2 {query keys multiple times} { + string compare [::tk::pkgconfig list] [::tk::pkgconfig list] +} 0 +test pkgconfig-1.3 {query value multiple times} { + string compare \ + [::tk::pkgconfig get bindir,install] \ + [::tk::pkgconfig get bindir,install] +} 0 + + +test pkgconfig-2.0 {error: missing subcommand} { + catch {::tk::pkgconfig} msg + set msg +} {wrong # args: should be "::tk::pkgconfig subcommand ?arg?"} +test pkgconfig-2.1 {error: illegal subcommand} { + catch {::tk::pkgconfig foo} msg + set msg +} {bad subcommand "foo": must be get or list} +test pkgconfig-2.2 {error: list with arguments} { + catch {::tk::pkgconfig list foo} msg + set msg +} {wrong # args: should be "::tk::pkgconfig list"} +test pkgconfig-2.3 {error: get without arguments} { + catch {::tk::pkgconfig get} msg + set msg +} {wrong # args: should be "::tk::pkgconfig get key"} +test pkgconfig-2.4 {error: query unknown key} { + catch {::tk::pkgconfig get foo} msg + set msg +} {key not known} +test pkgconfig-2.5 {error: query with to many arguments} { + catch {::tk::pkgconfig get foo bar} msg + set msg +} {wrong # args: should be "::tk::pkgconfig subcommand ?arg?"} + +# cleanup +cleanupTests +return Index: unix/Makefile.in ================================================================== --- unix/Makefile.in +++ unix/Makefile.in @@ -93,11 +93,11 @@ # Directory in which to install the configuration file tkConfig.sh: CONFIG_INSTALL_DIR = $(INSTALL_ROOT)$(libdir) # Directory in which to install the demo files: -DEMO_INSTALL_DIR = $(INSTALL_ROOT)$(TK_LIBRARY)/demos +DEMO_INSTALL_DIR = $(INSTALL_ROOT)@DEMO_DIR@ # The directory containing the Tcl sources and headers appropriate # for this version of Tk ("srcdir" will be replaced or has already # been replaced by the configure script): TCL_GENERIC_DIR = @TCL_SRC_DIR@/generic @@ -367,12 +367,13 @@ GENERIC_OBJS = tk3d.o tkArgv.o tkAtom.o tkBind.o tkBitmap.o tkBusy.o \ tkClipboard.o \ tkCmds.o tkColor.o tkConfig.o tkConsole.o tkCursor.o tkError.o \ tkEvent.o tkFocus.o tkFont.o tkGet.o tkGC.o tkGeometry.o tkGrab.o \ - tkGrid.o tkMain.o tkObj.o tkOldConfig.o tkOption.o tkPack.o tkPlace.o \ - tkSelect.o tkStyle.o tkUndo.o tkUtil.o tkVisual.o tkWindow.o + tkGrid.o tkMain.o tkObj.o tkOldConfig.o tkOption.o tkPack.o \ + tkPkgConfig.o tkPlace.o tkSelect.o tkStyle.o tkUndo.o tkUtil.o \ + tkVisual.o tkWindow.o TTK_OBJS = \ ttkBlink.o ttkButton.o ttkCache.o ttkClamTheme.o ttkClassicTheme.o \ ttkDefaultTheme.o ttkElements.o ttkEntry.o ttkFrame.o ttkImage.o \ ttkInit.o ttkLabel.o ttkLayout.o ttkManager.o ttkNotebook.o \ @@ -429,10 +430,11 @@ $(GENERIC_DIR)/tkGet.c $(GENERIC_DIR)/tkGC.c \ $(GENERIC_DIR)/tkGeometry.c $(GENERIC_DIR)/tkGrab.c \ $(GENERIC_DIR)/tkGrid.c $(GENERIC_DIR)/tkConsole.c \ $(GENERIC_DIR)/tkMain.c $(GENERIC_DIR)/tkOption.c \ $(GENERIC_DIR)/tkPack.c $(GENERIC_DIR)/tkPlace.c \ + $(GENERIC_DIR)/tkPkgConfig.c \ $(GENERIC_DIR)/tkSelect.c $(GENERIC_DIR)/tkStyle.c \ $(GENERIC_DIR)/tkUndo.c $(GENERIC_DIR)/tkUtil.c \ $(GENERIC_DIR)/tkVisual.c $(GENERIC_DIR)/tkWindow.c \ $(GENERIC_DIR)/tkButton.c $(GENERIC_DIR)/tkObj.c \ $(GENERIC_DIR)/tkEntry.c $(GENERIC_DIR)/tkFrame.c \ @@ -1007,10 +1009,36 @@ tkOption.o: $(GENERIC_DIR)/tkOption.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkOption.c tkPack.o: $(GENERIC_DIR)/tkPack.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkPack.c + +# TIP #59, embedding of configuration information into the binary library. +# +# Part of Tk's configuration information are the paths where it was installed +# and where it will look for its libraries (which can be different). We derive +# this information from the variables which can be overridden by the user. As +# every path can be configured separately we do not remember one general +# prefix/exec_prefix but all the different paths individually. + +tkPkgConfig.o: $(GENERIC_DIR)/tkPkgConfig.c + $(CC) -c $(CC_SWITCHES) \ + -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR)\"" \ + -DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR)\"" \ + -DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR)\"" \ + -DCFG_INSTALL_INCDIR="\"$(INCLUDE_INSTALL_DIR)\"" \ + -DCFG_INSTALL_DOCDIR="\"$(MAN_INSTALL_DIR)\"" \ + -DCFG_INSTALL_DEMODIR="\"$(DEMO_INSTALL_DIR)\"" \ + \ + -DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \ + -DCFG_RUNTIME_BINDIR="\"$(bindir)\"" \ + -DCFG_RUNTIME_SCRDIR="\"$(TK_LIBRARY)\"" \ + -DCFG_RUNTIME_INCDIR="\"$(includedir)\"" \ + -DCFG_RUNTIME_DOCDIR="\"$(mandir)\"" \ + -DCFG_RUNTIME_DEMODIR="\"$(DEMO_INSTALL_DIR)\"" \ + \ + $(GENERIC_DIR)/tkPkgConfig.c tkPlace.o: $(GENERIC_DIR)/tkPlace.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkPlace.c tkSelect.o: $(GENERIC_DIR)/tkSelect.c Index: unix/configure ================================================================== --- unix/configure +++ unix/configure @@ -659,10 +659,12 @@ TK_YEAR TK_PATCH_LEVEL TK_MINOR_VERSION TK_MAJOR_VERSION TK_VERSION +TK_DEMO_DIR +DEMO_DIR UNIX_FONT_OBJS XFT_LIBS XFT_CFLAGS XMKMF LDFLAGS_DEFAULT @@ -761,10 +763,11 @@ enable_option_checking with_tcl enable_man_symlinks enable_man_compression enable_man_suffix +with_encoding enable_shared enable_64bit enable_64bit_vis enable_rpath enable_corefoundation @@ -1423,10 +1426,12 @@ Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-tcl directory containing tcl configuration (tclConfig.sh) + --with-encoding encoding for configuration values (default: + iso8859-1) --with-x use the X Window System Some influential environment variables: CC C compiler command CFLAGS C compiler flags @@ -3946,10 +3951,35 @@ $as_echo "$tcl_cv_cc_pipe" >&6; } if test $tcl_cv_cc_pipe = yes; then CFLAGS="$CFLAGS -pipe" fi fi + +#------------------------------------------------------------------------ +# Embedded configuration information, encoding to use for the values, TIP #59 +#------------------------------------------------------------------------ + + + +# Check whether --with-encoding was given. +if test "${with_encoding+set}" = set; then : + withval=$with_encoding; with_tcencoding=${withval} +fi + + + if test x"${with_tcencoding}" != x ; then + +cat >>confdefs.h <<_ACEOF +#define TCL_CFGVAL_ENCODING "${with_tcencoding}" +_ACEOF + + else + +$as_echo "#define TCL_CFGVAL_ENCODING \"iso8859-1\"" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5 $as_echo_n "checking how to build libraries... " >&6; } # Check whether --enable-shared was given. @@ -8395,10 +8425,22 @@ TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}" TK_STUB_LIB_PATH="${TK_STUB_LIB_DIR}/${TK_STUB_LIB_FILE}" # Install time header dir can be set via --includedir eval "TK_INCLUDE_SPEC=\"-I${includedir}\"" + +#------------------------------------------------------------------------ +# Demo dir +#------------------------------------------------------------------------ + +if test x"${DEMO_DIR}" = x; then : + DEMO_DIR='$(TK_LIBRARY)/demos' +fi +eval "TK_DEMO_DIR=\"`echo ${DEMO_DIR} | tr '()' '{}'`\"" +eval "TK_DEMO_DIR=\"`echo ${TK_DEMO_DIR} | tr '()' '{}'`\"" + + #------------------------------------------------------------------------ # tkConfig.sh refers to this by a different name #------------------------------------------------------------------------ Index: unix/configure.ac ================================================================== --- unix/configure.ac +++ unix/configure.ac @@ -110,10 +110,16 @@ if test $tcl_cv_cc_pipe = yes; then CFLAGS="$CFLAGS -pipe" fi fi +#------------------------------------------------------------------------ +# Embedded configuration information, encoding to use for the values, TIP #59 +#------------------------------------------------------------------------ + +SC_TCL_CFG_ENCODING + SC_ENABLE_SHARED #-------------------------------------------------------------------- # The statements below define a collection of compile flags. This # macro depends on the value of SHARED_BUILD, and should be called @@ -778,10 +784,20 @@ TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}" TK_STUB_LIB_PATH="${TK_STUB_LIB_DIR}/${TK_STUB_LIB_FILE}" # Install time header dir can be set via --includedir eval "TK_INCLUDE_SPEC=\"-I${includedir}\"" + +#------------------------------------------------------------------------ +# Demo dir +#------------------------------------------------------------------------ + +AS_IF([test x"${DEMO_DIR}" = x], [DEMO_DIR='$(TK_LIBRARY)/demos']) +eval "TK_DEMO_DIR=\"`echo ${DEMO_DIR} | tr '()' '{}'`\"" +eval "TK_DEMO_DIR=\"`echo ${TK_DEMO_DIR} | tr '()' '{}'`\"" +AC_SUBST(DEMO_DIR) +AC_SUBST(TK_DEMO_DIR) #------------------------------------------------------------------------ # tkConfig.sh refers to this by a different name #------------------------------------------------------------------------ Index: unix/tk.pc.in ================================================================== --- unix/tk.pc.in +++ unix/tk.pc.in @@ -2,10 +2,11 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ +demodir=@TK_DEMO_DIR@ Name: The Tk Toolkit Description: Tk is a cross-platform graphical user interface toolkit, the standard GUI not only for Tcl, but for many other dynamic languages as well. URL: http://www.tcl.tk/ Version: @TK_VERSION@@TK_PATCH_LEVEL@ Index: unix/tkConfig.h.in ================================================================== --- unix/tkConfig.h.in +++ unix/tkConfig.h.in @@ -133,10 +133,13 @@ /* Is this a static build? */ #undef STATIC_BUILD /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS + +/* What encoding should be used for embedded configuration info? */ +#undef TCL_CFGVAL_ENCODING /* Is this a 64-bit build? */ #undef TCL_CFG_DO64BIT /* Is this an optimized build? */ Index: unix/tkConfig.sh.in ================================================================== --- unix/tkConfig.sh.in +++ unix/tkConfig.sh.in @@ -93,5 +93,8 @@ # Path to the Tk stub library in the build directory. TK_BUILD_STUB_LIB_PATH='@TK_BUILD_STUB_LIB_PATH@' # Path to the Tk stub library in the install directory. TK_STUB_LIB_PATH='@TK_STUB_LIB_PATH@' + +# Top-level directory in which Tk's demo files are installed. +TK_DEMO_DIR='@TK_DEMO_DIR@' Index: unix/tkUnixRFont.c ================================================================== --- unix/tkUnixRFont.c +++ unix/tkUnixRFont.c @@ -54,29 +54,32 @@ Region clipRegion; /* The clipping region, or None. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* - * Package initialization: - * Nothing to do here except register the fact that we're using Xft in - * the TIP 59 configuration database. + *------------------------------------------------------------------------- + * + * TkpFontPkgInit -- + * + * This procedure is called when an application is created. It + * initializes all the structures that are used by the + * platform-dependant code on a per application basis. + * Note that this is called before TkpInit() ! + * + * Results: + * None. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- */ -#ifndef TCL_CFGVAL_ENCODING -#define TCL_CFGVAL_ENCODING "ascii" -#endif - void TkpFontPkgInit( TkMainInfo *mainPtr) /* The application being created. */ { - static const Tcl_Config cfg[] = { - { "fontsystem", "xft" }, - { 0,0 } - }; - - Tcl_RegisterConfig(mainPtr->interp, "tk", cfg, TCL_CFGVAL_ENCODING); } static XftFont * GetFont( UnixFtFont *fontPtr,