Import Tk 8.6.6 (as of svn r86089)

This commit is contained in:
Zachary Ware
2017-05-22 16:13:37 -05:00
parent d239d63057
commit b1c28856bb
899 changed files with 545127 additions and 0 deletions

1700
unix/Makefile.in Normal file

File diff suppressed because it is too large Load Diff

173
unix/README Normal file
View File

@@ -0,0 +1,173 @@
Tk UNIX README
--------------
This is the directory where you configure, compile, test, and install UNIX
versions of Tk. This directory also contains source files for Tk that are
specific to UNIX.
The information in this file is maintained at:
http://www.tcl.tk/doc/howto/compile.html
For information on platforms where Tcl/Tk is known to compile, along with any
porting notes for getting it to work on those platforms, see:
http://www.tcl.tk/software/tcltk/platforms.html
The rest of this file contains instructions on how to do this. The release
should compile and run either "out of the box" or with trivial changes on any
UNIX-like system that approximates POSIX, BSD, or System V. We know that it
runs on workstations from Sun, H-P, DEC, IBM, and SGI, as well as PCs running
Linux, BSDI, and SCO UNIX. To compile for a PC running Windows, see the README
file in the directory ../win. To compile for MacOSX, see the README file in
the directory ../macosx.
How To Compile And Install Tk:
------------------------------
(a) Make sure that the Tcl release is present in the directory
../../tcl<version> (or else use the "--with-tcl" switch described below).
This release of Tk will only work with the equivalently versioned Tcl
release. Also, be sure that you have configured Tcl before you configure
Tk.
(b) Check for patches as described in ../README.
(c) If you have already compiled Tk once in this directory and are now
preparing to compile again in the same directory but for a different
platform, or if you have applied patches, type "make distclean" to discard
all the configuration information computed previously.
(d) Type "./configure". This runs a configuration script created by GNU
autoconf, which configures Tk for your system and creates a Makefile. The
configure script allows you to customize the Tk configuration for your
site; for details on how you can do this, type "./configure -help" or
refer to the autoconf documentation (not included here). Tk's "configure"
script supports the following special switches in addition to the standard
ones:
--with-tcl=DIR Specifies the directory containing the Tcl
binaries and Tcl's platform-dependent
configuration information. By default the Tcl
directory is assumed to be in the location
given by (a) above.
--with-x=DIR Tells configure where to find an installation
of the X Window System. Not normally needed.
--enable-threads If this switch is set, Tk will compile itself
with multithreading support.
--enable-shared If this switch is specified, Tk will compile
itself as a shared library if it can figure
out how to do that on this platform. This is
the default on platforms where we know how to
build shared libraries.
--disable-shared If this switch is specified, Tk will compile
itself as a static library.
--disable-rpath Turns off use of the rpath link option on
platforms that would otherwise use it.
--enable-symbols Build with debugging symbols. By default
standard debugging symbols are used. You can
specify the value "mem" to include
TCL_MEM_DEBUG memory debugging.
--disable-symbols Build without debugging symbols
--enable-64bit Enable 64bit support (where applicable)
--disable-64bit Disable 64bit support (where applicable)
--enable-64bit-vis Enable 64bit Sparc VIS support
--disable-64bit-vis Disable 64bit Sparc VIS support
--disable-xft Disable support for antialiased fonts via the
Freetype/xft library. By default, this is
switched on whenever the configure script can
detect the required libraries.
--enable-man-symlinks Use symlinks for linking the manpages that
should be reachable under several names.
--enable-man-compression=PROG
Compress the manpages using PROG.
--enable-man-suffix=STRING
Add STRING to the name of each of the manual
pages. If specified without giving STRING, the
suffix will be "tk".
Mac OS X only:
--enable-framework Package Tk as a framework.
--disable-corefoundation Disable use of CoreFoundation API.
--enable-aqua Use Aqua windowingsystem rather than X11,
requires --enable-corefoundation with Tcl and
Tk.
Note: by default gcc will be used if it can be located on the PATH. If you
want to use cc instead of gcc, set the CC environment variable to "cc"
before running configure. It is not safe to change the Makefile to use gcc
after configure is run.
Note: be sure to use only absolute path names (those starting with "/") in
the --prefix and --exec-prefix options.
(e) Type "make". This will create a library archive called "libtk<version>.a"
or "libtk<version>.so" and an interpreter application called "wish" that
allows you to type Tcl/Tk commands interactively or execute script files.
It will also create a stub library archive "libtkstub<version>.a" that
developers may link against other C code to produce loadable extensions
that call into Tk's public interface routines.
(f) If the make fails then you'll have to personalize the Makefile for your
site or possibly modify the distribution in other ways. First check the
porting Web page above to see if there are hints for compiling on your
system. If you need to modify Makefile, there are comments at the
beginning of it that describe the things you might want to change and how
to change them.
(g) Type "make install" to install Tk's binaries and script files in standard
places. You'll need write permission on the installation directories to do
this. The installation directories are determined by the "configure"
script and may be specified with the --prefix and --exec-prefix options to
"configure". See the Makefile for information on what directories were
chosen. You should not override these choices by modifying the Makefile,
or by copying files post-install. The installed binaries have embedded
within them path values relative to the install directory. If you change
your mind about where Tk should be installed, start this procedure over
again from step (a) so that the path embedded in the binaries agrees with
the install location.
(h) At this point you can play with Tk by running the installed "wish"
executable, or via the "make shell" target, and typing Tcl/Tk commands at
the interactive prompt.
If you have trouble compiling Tk, see the URL noted above about working
platforms. It contains information that people have provided about changes
they had to make to compile Tk in various environments. We're also interested
in hearing how to change the configuration setup so that Tk compiles on
additional platforms "out of the box".
Note: Do not specify either of the TCL_LIBRARY and TK_LIBRARY environment
variables in a production installation, as this can cause conflicts between
different versions of the libraries. Instead, the libraries should have the
correct locations of their associated script directories built into them.
Test suite
----------
Tk has a substantial self-test suite, consisting of a set of scripts in the
subdirectory "tests". To run the test suite just type "make test" in this
directory. You should then see a printout of the test files processed. If any
errors occur, you'll see a much more substantial printout for each error. In
order to avoid false error reports, be sure to run the tests with an empty
resource database (e.g., remove your .Xdefaults file or delete any entries
starting with *). Also, don't try to do anything else with your display or
keyboard while the tests are running, or you may get false violations. See the
README file in the "tests" directory for more information on the test suite.
If the test suite generates errors, most likely they are due to non-portable
tests that are interacting badly with your system configuration. We are
gradually eliminating the non-portable tests, but this release includes many
new tests so there will probably be some portability problems. As long as the
test suite doesn't core dump, it's probably safe to conclude that any errors
represent portability problems in the test suite and not fundamental flaws
with Tk.
There are also a number of visual tests for things such as screen layout,
Postscript generation, etc. These tests all have to be run by manually
enabling the "userInteraction" constraint when testing, and the results have
to be verified visually. This can be done with:
make test TESTFLAGS="-constraints userInteraction"
Some tests will present a main window with a bunch of menus, which you can use
to select various tests.

1
unix/aclocal.m4 vendored Normal file
View File

@@ -0,0 +1 @@
builtin(include,../unix/tcl.m4)

12430
unix/configure vendored Normal file

File diff suppressed because it is too large Load Diff

857
unix/configure.in Normal file
View File

@@ -0,0 +1,857 @@
#! /bin/bash -norc
dnl This file is an input file used by the GNU "autoconf" program to
dnl generate the file "configure", which is run during Tk installation
dnl to configure the system for the local environment.
AC_INIT([tk],[8.6])
AC_PREREQ(2.59)
dnl This is only used when included from macosx/configure.ac
m4_ifdef([SC_USE_CONFIG_HEADERS], [
AC_CONFIG_HEADERS([tkConfig.h:../unix/tkConfig.h.in])
AC_CONFIG_COMMANDS_PRE([DEFS="-DHAVE_TK_CONFIG_H -imacros tkConfig.h"])
AH_TOP([
#ifndef _TKCONFIG
#define _TKCONFIG])
AH_BOTTOM([
/* Undef unused package specific autoheader defines so that we can
* include both tclConfig.h and tkConfig.h at the same time: */
/* override */ #undef PACKAGE_NAME
/* override */ #undef PACKAGE_STRING
/* override */ #undef PACKAGE_TARNAME
#endif /* _TKCONFIG */])
])
TK_VERSION=8.6
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=6
TK_PATCH_LEVEL=".6"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"
#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------
SC_PATH_TCLCONFIG
SC_LOAD_TCLCONFIG
if test "${TCL_MAJOR_VERSION}" -ne 8 ; then
AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6+
Found config for Tcl ${TCL_VERSION}])
fi
if test "${TCL_MINOR_VERSION}" -lt 6 ; then
AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6+
Found config for Tcl ${TCL_VERSION}])
fi
SC_PROG_TCLSH
SC_BUILD_TCLSH
#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------
if test "${prefix}" = "NONE"; then
prefix="$TCL_PREFIX"
fi
if test "${exec_prefix}" = "NONE"; then
exec_prefix=$prefix
fi
# Make sure srcdir is fully qualified!
srcdir="`cd "$srcdir" ; pwd`"
TK_SRC_DIR="`cd "$srcdir"/..; pwd`"
#------------------------------------------------------------------------
# Compress and/or soft link the manpages?
#------------------------------------------------------------------------
SC_CONFIG_MANPAGES
#------------------------------------------------------------------------
# Standard compiler checks
#------------------------------------------------------------------------
# If the user did not set CFLAGS, set it now to keep
# the AC_PROG_CC macro from adding "-g -O2".
if test "${CFLAGS+set}" != "set" ; then
CFLAGS=""
fi
AC_PROG_CC
AC_C_INLINE
#--------------------------------------------------------------------
# Supply a substitute for stdlib.h if it doesn't define strtol,
# strtoul, or strtod (which it doesn't in some versions of SunOS).
#--------------------------------------------------------------------
AC_CHECK_HEADER(stdlib.h, tk_ok=1, tk_ok=0)
AC_EGREP_HEADER(strtol, stdlib.h, , tk_ok=0)
AC_EGREP_HEADER(strtoul, stdlib.h, , tk_ok=0)
AC_EGREP_HEADER(strtod, stdlib.h, , tk_ok=0)
if test $tk_ok = 0; then
AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
fi
#------------------------------------------------------------------------
# If we're using GCC, see if the compiler understands -pipe. If so, use it.
# It makes compiling go faster. (This is only a performance feature.)
#------------------------------------------------------------------------
if test -z "$no_pipe" && test -n "$GCC"; then
AC_CACHE_CHECK([if the compiler understands -pipe],
tcl_cv_cc_pipe, [
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
CFLAGS=$hold_cflags])
if test $tcl_cv_cc_pipe = yes; then
CFLAGS="$CFLAGS -pipe"
fi
fi
#------------------------------------------------------------------------
# Threads support - this auto-enables if Tcl was compiled threaded
#------------------------------------------------------------------------
SC_ENABLE_THREADS
# Add the threads support libraries
LIBS="$LIBS$THREADS_LIBS"
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
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------
SC_CONFIG_CFLAGS
SC_ENABLE_SYMBOLS
#--------------------------------------------------------------------
# Detect what compiler flags to set for 64-bit support.
#--------------------------------------------------------------------
SC_TCL_EARLY_FLAGS
SC_TCL_64BIT_FLAGS
#--------------------------------------------------------------------
# Check endianness because we can optimize some operations
#--------------------------------------------------------------------
AC_C_BIGENDIAN
#------------------------------------------------------------------------
# If Tcl and Tk are installed in different places, adjust the library
# search path to reflect this.
#------------------------------------------------------------------------
LIB_RUNTIME_DIR='$(libdir)'
if test "$TCL_EXEC_PREFIX" != "$exec_prefix"; then
LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib"
fi
if test "$TCL_PREFIX" != "$prefix"; then
AC_MSG_WARN([
Different --prefix selected for Tk and Tcl!
[[package require Tk]] may not work correctly in tclsh.])
fi
#--------------------------------------------------------------------
# Include sys/select.h if it exists and if it supplies things
# that appear to be useful and aren't already in sys/types.h.
# This appears to be true only on the RS/6000 under AIX. Some
# systems like OSF/1 have a sys/select.h that's of no use, and
# other systems like SCO UNIX have a sys/select.h that's
# pernicious. If "fd_set" isn't defined anywhere then set a
# special flag.
#--------------------------------------------------------------------
AC_CACHE_CHECK([for fd_set in sys/types], tcl_cv_type_fd_set, [
AC_TRY_COMPILE([#include <sys/types.h>],[fd_set readMask, writeMask;],
tcl_cv_type_fd_set=yes, tcl_cv_type_fd_set=no)])
tk_ok=$tcl_cv_type_fd_set
if test $tk_ok = no; then
AC_CACHE_CHECK([for fd_mask in sys/select], tcl_cv_grep_fd_mask, [
AC_EGREP_HEADER(fd_mask, sys/select.h,
tcl_cv_grep_fd_mask=present, tcl_cv_grep_fd_mask=missing)])
if test $tcl_cv_grep_fd_mask = present; then
AC_DEFINE(HAVE_SYS_SELECT_H, 1, [Should we include <sys/select.h>?])
tk_ok=yes
fi
fi
if test $tk_ok = no; then
AC_DEFINE(NO_FD_SET, 1, [Do we have fd_set?])
fi
#------------------------------------------------------------------------------
# Find out all about time handling differences.
#------------------------------------------------------------------------------
AC_CHECK_HEADERS(sys/time.h)
AC_HEADER_TIME
#--------------------------------------------------------------------
# Under Solaris 2.4, strtod returns the wrong value for the
# terminating character under some conditions. Check for this
# and if the problem exists use a substitute procedure
# "fixstrtod" (provided by Tcl) that corrects the error.
#--------------------------------------------------------------------
SC_BUGGY_STRTOD
#--------------------------------------------------------------------
# Check for various typedefs and provide substitutes if
# they don't exist.
#--------------------------------------------------------------------
AC_TYPE_MODE_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_UID_T
AC_CHECK_TYPE([intptr_t], [
AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
for tcl_cv_intptr_t in "int" "long" "long long" none; do
if test "$tcl_cv_intptr_t" != none; then
AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
[[sizeof (void *) <= sizeof ($tcl_cv_intptr_t)]])],
[tcl_ok=yes], [tcl_ok=no])
test "$tcl_ok" = yes && break; fi
done])
if test "$tcl_cv_intptr_t" != none; then
AC_DEFINE_UNQUOTED([intptr_t], [$tcl_cv_intptr_t], [Signed integer
type wide enough to hold a pointer.])
fi
])
AC_CHECK_TYPE([uintptr_t], [
AC_DEFINE([HAVE_UINTPTR_T], 1, [Do we have the uintptr_t type?])], [
AC_CACHE_CHECK([for pointer-size unsigned integer type], tcl_cv_uintptr_t, [
for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \
none; do
if test "$tcl_cv_uintptr_t" != none; then
AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
[[sizeof (void *) <= sizeof ($tcl_cv_uintptr_t)]])],
[tcl_ok=yes], [tcl_ok=no])
test "$tcl_ok" = yes && break; fi
done])
if test "$tcl_cv_uintptr_t" != none; then
AC_DEFINE_UNQUOTED([uintptr_t], [$tcl_cv_uintptr_t], [Unsigned integer
type wide enough to hold a pointer.])
fi
])
#-------------------------------------------
# In OS/390 struct pwd has no pw_gecos field
#-------------------------------------------
AC_CACHE_CHECK([pw_gecos in struct pwd], tcl_cv_pwd_pw_gecos, [
AC_TRY_COMPILE([#include <pwd.h>],
[struct passwd pwd; pwd.pw_gecos;],
tcl_cv_pwd_pw_gecos=yes, tcl_cv_pwd_pw_gecos=no)])
if test $tcl_cv_pwd_pw_gecos = yes; then
AC_DEFINE(HAVE_PW_GECOS, 1, [Does struct password have a pw_gecos field?])
fi
#--------------------------------------------------------------------
# On Mac OS X, we can build either with X11 or with Aqua
#--------------------------------------------------------------------
if test "`uname -s`" = "Darwin" ; then
AC_MSG_CHECKING([whether to use Aqua])
AC_ARG_ENABLE(aqua,
AC_HELP_STRING([--enable-aqua=yes|no],
[use Aqua windowingsystem on Mac OS X (default: no)]),
[tk_aqua=$enableval], [tk_aqua=no])
if test $tk_aqua = yes -o $tk_aqua = cocoa; then
tk_aqua=yes
if test $tcl_corefoundation = no; then
AC_MSG_WARN([Aqua can only be used when CoreFoundation is available])
tk_aqua=no
fi
if test ! -d /System/Library/Frameworks/Cocoa.framework; then
AC_MSG_WARN([Aqua can only be used when Cocoa is available])
tk_aqua=no
fi
if test "`uname -r | awk -F. '{print [$]1}'`" -lt 9; then
AC_MSG_WARN([Aqua requires Mac OS X 10.5 or later])
tk_aqua=no
fi
fi
AC_MSG_RESULT([$tk_aqua])
if test "$fat_32_64" = yes; then
if test $tk_aqua = no; then
AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
for v in CFLAGS CPPFLAGS LDFLAGS; do
eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
done
CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
for v in CFLAGS CPPFLAGS LDFLAGS; do
eval $v'="$hold_'$v'"'
done])
fi
# remove 64-bit arch flags from CFLAGS et al. for combined 32 & 64 bit
# fat builds if configuration does not support 64-bit.
if test "$tcl_cv_lib_x11_64" = no; then
AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
for v in CFLAGS CPPFLAGS LDFLAGS; do
eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
done
fi
fi
if test $tk_aqua = no; then
# check if weak linking whole libraries is possible.
AC_CACHE_CHECK([if ld accepts -weak-l flag], tcl_cv_ld_weak_l, [
hold_ldflags=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,-weak-lm"
AC_TRY_LINK([#include <math.h>], [double f = sin(1.0);],
tcl_cv_ld_weak_l=yes, tcl_cv_ld_weak_l=no)
LDFLAGS=$hold_ldflags])
fi
AC_CHECK_HEADERS(AvailabilityMacros.h)
if test "$ac_cv_header_AvailabilityMacros_h" = yes; then
AC_CACHE_CHECK([if weak import is available], tcl_cv_cc_weak_import, [
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
AC_TRY_LINK([
#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
#error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
#endif
#elif MAC_OS_X_VERSION_MIN_REQUIRED < 1020
#error MAC_OS_X_VERSION_MIN_REQUIRED < 1020
#endif
int rand(void) __attribute__((weak_import));
], [rand();],
tcl_cv_cc_weak_import=yes, tcl_cv_cc_weak_import=no)
CFLAGS=$hold_cflags])
if test $tcl_cv_cc_weak_import = yes; then
AC_DEFINE(HAVE_WEAK_IMPORT, 1, [Is weak import available?])
fi
AC_CACHE_CHECK([if Darwin SUSv3 extensions are available],
tcl_cv_cc_darwin_c_source, [
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
AC_TRY_COMPILE([
#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
#error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
#endif
#elif MAC_OS_X_VERSION_MIN_REQUIRED < 1050
#error MAC_OS_X_VERSION_MIN_REQUIRED < 1050
#endif
#define _DARWIN_C_SOURCE 1
#include <sys/cdefs.h>
],,tcl_cv_cc_darwin_c_source=yes, tcl_cv_cc_darwin_c_source=no)
CFLAGS=$hold_cflags])
if test $tcl_cv_cc_darwin_c_source = yes; then
AC_DEFINE(_DARWIN_C_SOURCE, 1,
[Are Darwin SUSv3 extensions available?])
fi
fi
else
tk_aqua=no
fi
if test $tk_aqua = yes; then
AC_DEFINE(MAC_OSX_TK, 1, [Are we building TkAqua?])
LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit"
EXTRA_CC_SWITCHES='-std=gnu99 -x objective-c'
TK_WINDOWINGSYSTEM=AQUA
if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then
AC_DEFINE(TK_MAC_DEBUG, 1, [Are TkAqua debug messages enabled?])
fi
else
#--------------------------------------------------------------------
# Locate the X11 header files and the X11 library archive. Try
# the ac_path_x macro first, but if it doesn't find the X stuff
# (e.g. because there's no xmkmf program) then check through
# a list of possible directories. Under some conditions the
# autoconf macro will return an include directory that contains
# no include files, so double-check its result just to be safe.
#--------------------------------------------------------------------
SC_PATH_X
TK_WINDOWINGSYSTEM=X11
fi
#--------------------------------------------------------------------
# Various manipulations on the search path used at runtime to
# find shared libraries:
# 1. If the X library binaries are in a non-standard directory,
# add the X library location into that search path.
# 2. On systems such as AIX and Ultrix that use "-L" as the
# search path option, colons cannot be used to separate
# directories from each other. Change colons to " -L".
# 3. Create two sets of search flags, one for use in cc lines
# and the other for when the linker is invoked directly. In
# the second case, '-Wl,' must be stripped off and commas must
# be replaced by spaces.
#--------------------------------------------------------------------
if test "x${x_libraries}" != "x"; then
if test "x${x_libraries}" != "xNONE"; then
LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${x_libraries}"
fi
fi
if test "${TCL_LD_SEARCH_FLAGS}" = '-L${LIB_RUNTIME_DIR}'; then
LIB_RUNTIME_DIR=`echo ${LIB_RUNTIME_DIR} |sed -e 's/:/ -L/g'`
fi
#--------------------------------------------------------------------
# Check for the existence of various libraries. The order here
# is important, so that then end up in the right order in the
# command line generated by make. The -lsocket and -lnsl libraries
# require a couple of special tricks:
# 1. Use "connect" and "accept" to check for -lsocket, and
# "gethostbyname" to check for -lnsl.
# 2. Use each function name only once: can't redo a check because
# autoconf caches the results of the last check and won't redo it.
# 3. Use -lnsl and -lsocket only if they supply procedures that
# aren't already present in the normal libraries. This is because
# IRIX 5.2 has libraries, but they aren't needed and they're
# bogus: they goof up name resolution if used.
# 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
# To get around this problem, check for both libraries together
# if -lsocket doesn't work by itself.
#--------------------------------------------------------------------
if test $tk_aqua = no; then
AC_CHECK_LIB(Xbsd, main, [LIBS="$LIBS -lXbsd"])
fi
#--------------------------------------------------------------------
# One more check related to the X libraries. The standard releases
# of Ultrix don't support the "xauth" mechanism, so send won't work
# unless TK_NO_SECURITY is defined. However, there are usually copies
# of the MIT X server available as well, which do support xauth.
# Check for the MIT stuff and use it if it exists.
#
# Note: can't use ac_check_lib macro (at least, not in Autoconf 2.1)
# because it can't deal with the "-" in the library name.
#--------------------------------------------------------------------
if test -d /usr/include/mit -a $tk_aqua = no; then
AC_MSG_CHECKING([MIT X libraries])
tk_oldCFlags=$CFLAGS
CFLAGS="$CFLAGS -I/usr/include/mit"
tk_oldLibs=$LIBS
LIBS="$LIBS -lX11-mit"
AC_TRY_LINK([
#include <X11/Xlib.h>
], [
XOpenDisplay(0);
], [
AC_MSG_RESULT([yes])
XLIBSW="-lX11-mit"
XINCLUDES="-I/usr/include/mit"
], AC_MSG_RESULT([no]))
CFLAGS=$tk_oldCFlags
LIBS=$tk_oldLibs
fi
#--------------------------------------------------------------------
# Check for freetype / fontconfig / Xft support.
#--------------------------------------------------------------------
if test $tk_aqua = no; then
AC_MSG_CHECKING([whether to use xft])
AC_ARG_ENABLE(xft,
AC_HELP_STRING([--enable-xft],
[use freetype/fontconfig/xft (default: on)]),
[enable_xft=$enableval], [enable_xft="default"])
XFT_CFLAGS=""
XFT_LIBS=""
if test "$enable_xft" = "no" ; then
AC_MSG_RESULT([$enable_xft])
else
found_xft="yes"
dnl make sure package configurator (xft-config or pkg-config
dnl says that xft is present.
XFT_CFLAGS=`xft-config --cflags 2>/dev/null` || found_xft="no"
XFT_LIBS=`xft-config --libs 2>/dev/null` || found_xft="no"
if test "$found_xft" = "no" ; then
found_xft=yes
XFT_CFLAGS=`pkg-config --cflags xft 2>/dev/null` || found_xft="no"
XFT_LIBS=`pkg-config --libs xft 2>/dev/null` || found_xft="no"
fi
AC_MSG_RESULT([$found_xft])
dnl make sure that compiling against Xft header file doesn't bomb
if test "$found_xft" = "yes" ; then
tk_oldCFlags=$CFLAGS
CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
tk_oldLibs=$LIBS
LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
AC_CHECK_HEADER(X11/Xft/Xft.h, [], [
found_xft=no
],[#include <X11/Xlib.h>])
CFLAGS=$tk_oldCFlags
LIBS=$tk_oldLibs
fi
dnl make sure that linking against Xft libraries finds freetype
if test "$found_xft" = "yes" ; then
tk_oldCFlags=$CFLAGS
CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
tk_oldLibs=$LIBS
LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
AC_CHECK_LIB(Xft, XftFontOpen, [], [
found_xft=no
])
CFLAGS=$tk_oldCFlags
LIBS=$tk_oldLibs
fi
dnl make sure that linking against fontconfig libraries finds Fc* symbols
if test "$found_xft" = "yes" ; then
tk_oldCFlags=$CFLAGS
CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
tk_oldLibs=$LIBS
LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW -lfontconfig"
AC_CHECK_LIB(fontconfig, FcFontSort, [
XFT_LIBS="$XFT_LIBS -lfontconfig"
], [])
CFLAGS=$tk_oldCFlags
LIBS=$tk_oldLibs
fi
dnl print a warning if xft is unusable and was specifically requested
if test "$found_xft" = "no" ; then
if test "$enable_xft" = "yes" ; then
AC_MSG_WARN([Can't find xft configuration, or xft is unusable])
fi
enable_xft=no
XFT_CFLAGS=""
XFT_LIBS=""
else
enable_xft=yes
fi
fi
if test $enable_xft = "yes" ; then
UNIX_FONT_OBJS=tkUnixRFont.o
AC_DEFINE(HAVE_XFT, 1, [Have we turned on XFT (antialiased fonts)?])
else
UNIX_FONT_OBJS=tkUnixFont.o
fi
AC_SUBST(XFT_CFLAGS)
AC_SUBST(XFT_LIBS)
AC_SUBST(UNIX_FONT_OBJS)
fi
#--------------------------------------------------------------------
# Check for XkbKeycodeToKeysym.
#--------------------------------------------------------------------
if test $tk_aqua = no; then
tk_oldCFlags=$CFLAGS
tk_oldLibs=$LIBS
CFLAGS="$CFLAGS $XINCLUDES"
LIBS="$LIBS $XLIBSW"
AC_CHECK_HEADER(X11/XKBlib.h, [
xkblib_header_found=yes
], [
xkblib_header_found=no
], [#include <X11/Xlib.h>])
if test $xkblib_header_found = "yes" ; then
AC_CHECK_LIB(X11, XkbKeycodeToKeysym, [
xkbkeycodetokeysym_found=yes
], [
xkbkeycodetokeysym_found=no
])
else
xkbkeycodetokeysym_found=no
fi
if test $xkbkeycodetokeysym_found = "yes" ; then
AC_DEFINE(HAVE_XKBKEYCODETOKEYSYM, 1, [Do we have XkbKeycodeToKeysym?])
fi
CFLAGS=$tk_oldCFlags
LIBS=$tk_oldLibs
fi
#--------------------------------------------------------------------
# Check whether XKeycodeToKeysym is deprecated in X11 headers.
#--------------------------------------------------------------------
if test $tk_aqua = no && test "$GCC" = yes; then
AC_MSG_CHECKING([whether XKeycodeToKeysym is deprecated])
tk_oldCFlags=$CFLAGS
CFLAGS="$CFLAGS -Werror"
AC_TRY_LINK([
#include <X11/Xlib.h>
], [
XKeycodeToKeysym(0,0,0);
], [
AC_MSG_RESULT([no])
], [
AC_MSG_RESULT([yes])
AC_DEFINE(XKEYCODETOKEYSYM_IS_DEPRECATED, 1, [Is XKeycodeToKeysym deprecated?])
])
CFLAGS=$tk_oldCFlags
fi
#--------------------------------------------------------------------
# XXX Do this last.
# It might modify XLIBSW which could affect other tests.
#
# Check whether the header and library for the XScreenSaver
# extension are available, and set HAVE_XSS if so.
# XScreenSaver is needed for Tk_GetUserInactiveTime().
#--------------------------------------------------------------------
if test $tk_aqua = no; then
tk_oldCFlags=$CFLAGS
CFLAGS="$CFLAGS $XINCLUDES"
tk_oldLibs=$LIBS
LIBS="$tk_oldLibs $XLIBSW"
xss_header_found=no
xss_lib_found=no
AC_MSG_CHECKING([whether to try to use XScreenSaver])
AC_ARG_ENABLE(xss,
AC_HELP_STRING([--enable-xss],
[use XScreenSaver for activity timer (default: on)]),
[enable_xss=$enableval], [enable_xss=yes])
if test "$enable_xss" = "no" ; then
AC_MSG_RESULT([$enable_xss])
else
AC_MSG_RESULT([$enable_xss])
AC_CHECK_HEADER(X11/extensions/scrnsaver.h, [
xss_header_found=yes
],,[#include <X11/Xlib.h>])
AC_CHECK_FUNC(XScreenSaverQueryInfo,,[
AC_CHECK_LIB(Xext, XScreenSaverQueryInfo, [
XLIBSW="$XLIBSW -lXext"
xss_lib_found=yes
], [
AC_CHECK_LIB(Xss, XScreenSaverQueryInfo, [
if test "$tcl_cv_ld_weak_l" = yes; then
# On Darwin, weak link libXss if possible,
# as it is only available on Tiger or later.
XLIBSW="$XLIBSW -Wl,-weak-lXss -lXext"
else
XLIBSW="$XLIBSW -lXss -lXext"
fi
xss_lib_found=yes
],, -lXext)
])
])
fi
if test $enable_xss = yes -a $xss_lib_found = yes -a $xss_header_found = yes; then
AC_DEFINE(HAVE_XSS, 1, [Is XScreenSaver available?])
fi
CFLAGS=$tk_oldCFlags
LIBS=$tk_oldLibs
fi
#--------------------------------------------------------------------
# Figure out whether "char" is unsigned. If so, set a
# #define for __CHAR_UNSIGNED__.
#--------------------------------------------------------------------
AC_C_CHAR_UNSIGNED
#--------------------------------------------------------------------
# The statements below define a collection of symbols related to
# building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------
eval eval "TK_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}"
eval eval "TK_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}"
eval "TK_LIB_FILE=libtk${LIB_SUFFIX}"
# tkConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TK_LIB_FILE contains shell escapes.
eval "TK_LIB_FILE=${TK_LIB_FILE}"
if test "${SHARED_BUILD}" = "1" -a "${SHLIB_SUFFIX}" != ""; then
SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \${TCL_STUB_LIB_SPEC}"
TCL_STUB_FLAGS="-DUSE_TCL_STUBS"
fi
TK_LIBRARY='$(prefix)/lib/tk$(VERSION)'
PRIVATE_INCLUDE_DIR='$(includedir)'
HTML_DIR='$(DISTDIR)/html'
TK_PKG_DIR='tk$(VERSION)'
TK_RSRC_FILE='tk$(VERSION).rsrc'
WISH_RSRC_FILE='wish$(VERSION).rsrc'
# Note: in the following variable, it's important to use the absolute
# path name of the Tcl directory rather than "..": this is because
# AIX remembers this path and will attempt to use it at run-time to look
# up the Tcl library.
if test "`uname -s`" = "Darwin" ; then
SC_ENABLE_FRAMEWORK
TK_SHLIB_LD_EXTRAS="-compatibility_version ${TK_VERSION} -current_version ${TK_VERSION}`echo ${TK_PATCH_LEVEL} | awk ['{match($0, "\\\.[0-9]+"); print substr($0,RSTART,RLENGTH)}']`"
TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -install_name "${DYLIB_INSTALL_DIR}/${TK_LIB_FILE}" -unexported_symbols_list $$(f=$(TK_LIB_FILE).E && nm -gp tkMacOSX*.o 2>/dev/null | awk "/^[[0-9a-f]]+ . \.objc/ {print \$$3}" > $$f && nm -gjp "$(TCL_BIN_DIR)"/$(TCL_STUB_LIB_FILE) | grep ^_[[^_]] >> $$f && echo $$f)'
echo "$LDFLAGS " | grep -q -- '-prebind ' && TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -seg1addr 0xb000000'
TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -sectcreate __TEXT __info_plist Tk-Info.plist'
EXTRA_WISH_LIBS='-sectcreate __TEXT __info_plist Wish-Info.plist'
EXTRA_APP_CC_SWITCHES="${EXTRA_APP_CC_SWITCHES}"' -mdynamic-no-pic'
AC_CONFIG_FILES([Tk-Info.plist:../macosx/Tk-Info.plist.in Wish-Info.plist:../macosx/Wish-Info.plist.in])
for l in ${LOCALES}; do CFBUNDLELOCALIZATIONS="${CFBUNDLELOCALIZATIONS}<string>$l</string>"; done
TK_YEAR="`date +%Y`"
fi
if test "$FRAMEWORK_BUILD" = "1" ; then
AC_DEFINE(TK_FRAMEWORK, 1, [Is Tk built as a framework?])
# Construct a fake local framework structure to make linking with
# '-framework Tk' and running of tktest work
AC_CONFIG_COMMANDS([Tk.framework], [n=Tk &&
f=$n.framework && v=Versions/$VERSION &&
rm -rf $f && mkdir -p $f/$v/Resources &&
ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v &&
ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist &&
if test $tk_aqua = yes; then ln -s ../../../../$n.rsrc $f/$v/Resources; fi &&
unset n f v
], VERSION=${TK_VERSION} && tk_aqua=${tk_aqua})
LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
if test "${libdir}" = '${exec_prefix}/lib'; then
# override libdir default
libdir="/Library/Frameworks"
fi
TK_LIB_FILE="Tk"
TK_LIB_FLAG="-framework Tk"
TK_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tk"
TK_LIB_SPEC="-F${libdir} -framework Tk"
libdir="${libdir}/Tk.framework/Versions/\${VERSION}"
TK_LIBRARY="${libdir}/Resources/Scripts"
TK_PKG_DIR="Resources/Scripts"
TK_RSRC_FILE="Tk.rsrc"
WISH_RSRC_FILE="Wish.rsrc"
includedir="${libdir}/Headers"
PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders"
HTML_DIR="${libdir}/Resources/Documentation/Reference/Tk"
EXTRA_INSTALL="install-private-headers html-tk"
EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TkTOC.html'
EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tk-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"'
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"'
if test $tk_aqua = yes; then
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Images to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)/Resources"; done'
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing wish$(VERSION) script to $(INSTALL_ROOT)/'"${bindir}"'/" && $(INSTALL_DATA_DIR) "$(INSTALL_ROOT)/'"${bindir}"'" && printf > "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)" "#!/bin/sh\n\"\$$(dirname \$$0)'"`eval d="${bindir}"; echo "$d" | sed -e 's#/[^/][^/]*#/..#g'`"'$(bindir)/Wish\" \"\$$@\"" && chmod +x "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)"'
bindir="${libdir}/Resources/Wish.app/Contents/MacOS"
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Info.plist to $(BIN_INSTALL_DIR)/.." && $(INSTALL_DATA) Wish-Info.plist "$(BIN_INSTALL_DIR)/../Info.plist" && mv -f "$(BIN_INSTALL_DIR)/wish$(VERSION)" "$(BIN_INSTALL_DIR)/Wish"'
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.icns to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA_DIR) "$(BIN_INSTALL_DIR)/../Resources"'
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Tk.icns" "$(BIN_INSTALL_DIR)/../Resources/Wish.icns"'
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.sdef to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Wish.sdef" "$(BIN_INSTALL_DIR)/../Resources"'
fi
EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tk.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tkConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."'
# Don't use AC_DEFINE for the following as the framework version define
# needs to go into the Makefile even when using autoheader, so that we
# can pick up a potential make override of VERSION. Also, don't put this
# into CFLAGS as it should not go into tkConfig.sh
EXTRA_CC_SWITCHES="$EXTRA_CC_SWITCHES"' -DTK_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
if test $tk_aqua = yes; then
EXTRA_INSTALL_BINARIES='@echo "Installing Images to $(LIB_INSTALL_DIR)/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)"; done'
fi
# libdir must be a fully qualified path and not ${exec_prefix}/lib
eval libdir="$libdir"
if test "${ac_cv_cygwin}" = "yes" -a "$SHARED_BUILD" = "1"; then
TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
TK_BUILD_LIB_SPEC="-L\$(TOP_DIR)/win ${TK_LIB_FLAG}"
else
if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
TK_LIB_FLAG="-ltk${TK_VERSION}"
else
TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
fi
TK_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_LIB_FLAG}"
fi
TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
fi
#--------------------------------------------------------------------
# The statements below define various symbols relating to Tk
# stub support.
#--------------------------------------------------------------------
# Replace ${VERSION} with contents of ${TK_VERSION}
eval "TK_STUB_LIB_FILE=libtkstub${TK_UNSHARED_LIB_SUFFIX}"
eval "TK_STUB_LIB_DIR=${libdir}"
if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
TK_STUB_LIB_FLAG="-ltkstub${TK_VERSION}"
else
TK_STUB_LIB_FLAG="-ltkstub`echo ${TK_VERSION} | tr -d .`"
fi
TK_BUILD_STUB_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_SPEC="-L${TK_STUB_LIB_DIR} ${TK_STUB_LIB_FLAG}"
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}\""
#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------
TK_SHARED_BUILD=${SHARED_BUILD}
AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_YEAR)
AC_SUBST(TK_LIB_FILE)
AC_SUBST(TK_LIB_FLAG)
AC_SUBST(TK_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_STUB_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_PATH)
AC_SUBST(TK_INCLUDE_SPEC)
AC_SUBST(TK_BUILD_STUB_LIB_SPEC)
AC_SUBST(TK_BUILD_STUB_LIB_PATH)
AC_SUBST(TK_SRC_DIR)
AC_SUBST(TK_SHARED_BUILD)
AC_SUBST(LD_LIBRARY_PATH_VAR)
AC_SUBST(TK_BUILD_LIB_SPEC)
AC_SUBST(TCL_STUB_FLAGS)
AC_SUBST(XINCLUDES)
AC_SUBST(XLIBSW)
AC_SUBST(LOCALES)
AC_SUBST(TK_WINDOWINGSYSTEM)
AC_SUBST(TK_PKG_DIR)
AC_SUBST(TK_LIBRARY)
AC_SUBST(LIB_RUNTIME_DIR)
AC_SUBST(PRIVATE_INCLUDE_DIR)
AC_SUBST(HTML_DIR)
AC_SUBST(EXTRA_CC_SWITCHES)
AC_SUBST(EXTRA_APP_CC_SWITCHES)
AC_SUBST(EXTRA_INSTALL)
AC_SUBST(EXTRA_INSTALL_BINARIES)
AC_SUBST(EXTRA_BUILD_HTML)
AC_SUBST(EXTRA_WISH_LIBS)
AC_SUBST(CFBUNDLELOCALIZATIONS)
AC_SUBST(TK_RSRC_FILE)
AC_SUBST(WISH_RSRC_FILE)
AC_SUBST(LIB_RSRC_FILE)
AC_SUBST(APP_RSRC_FILE)
AC_SUBST(REZ)
AC_SUBST(REZ_FLAGS)
AC_CONFIG_FILES([
Makefile:../unix/Makefile.in
tkConfig.sh:../unix/tkConfig.sh.in
tk.pc:../unix/tk.pc.in
])
AC_OUTPUT
dnl Local Variables:
dnl mode: autoconf
dnl End:

528
unix/install-sh Normal file
View File

@@ -0,0 +1,528 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-04-20.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-S $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-S) stripcmd="$stripprog $2"
shift;;
-t) dst_arg=$2
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
-*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test -z "$d" && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

117
unix/installManPage Normal file
View File

@@ -0,0 +1,117 @@
#!/bin/sh
########################################################################
### Parse Options
###
Gzip=:
SymOrLoc=""
Gz=""
Suffix=""
while true; do
case $1 in
-s | --symlinks ) SymOrLoc="-s " ;;
-z | --compress ) Gzip=$2; shift ;;
-e | --extension ) Gz=$2; shift ;;
-x | --suffix ) Suffix=$2; shift ;;
-*) cat <<EOF
Unknown option "$1". Supported options:
-s Use symbolic links for manpages with multiple names.
-z PROG Use PROG to compress manual pages.
-e EXT Defines the extension added by -z PROG when compressing.
-x SUFF Defines an extra extension suffix to use.
Option names may not be combined getopt-style.
EOF
exit 1 ;;
*) break ;;
esac
shift
done
if test "$#" != 2; then
echo "Usage: installManPages <options> file dir"
exit 1
fi
########################################################################
### Parse Required Arguments
###
ManPage=$1
Dir=$2
if test -f $ManPage ; then : ; else
echo "source manual page file must exist"
exit 1
fi
if test -d $Dir ; then : ; else
echo "target directory must exist"
exit 1
fi
test -z "$SymOrLoc" && SymOrLoc="$Dir/"
########################################################################
### Extract Target Names from Manual Page
###
# A sed script to parse the alternative names out of a man page.
#
# Backslashes are trippled in the sed script, because it is in
# backticks which doesn't pass backslashes literally.
#
Names=`sed -n '
# Look for a line that starts with .SH NAME
/^\.SH NAME/{
# Read next line
n
# Remove all commas ...
s/,//g
# ... and backslash-escaped spaces.
s/\\\ //g
# Delete from \- to the end of line
s/ \\\-.*//
# Convert all non-space non-alphanum sequences
# to single underscores.
s/[^ A-Za-z0-9][^ A-Za-z0-9]*/_/g
# print the result and exit
p;q
}' $ManPage`
if test -z "$Names" ; then
echo "warning: no target names found in $ManPage"
fi
########################################################################
### Remaining Set Up
###
case $ManPage in
*.1) Section=1 ;;
*.3) Section=3 ;;
*.n) Section=n ;;
*) echo "unknown section for $ManPage"
exit 2 ;;
esac
SrcDir=`dirname $ManPage`
########################################################################
### Process Page to Create Target Pages
###
First=""
for Target in $Names; do
Target=$Target.$Section$Suffix
rm -f $Dir/$Target $Dir/$Target.*
if test -z "$First" ; then
First=$Target
sed -e "/man\.macros/r $SrcDir/man.macros" -e "/man\.macros/d" \
$ManPage > $Dir/$First
chmod 444 $Dir/$First
$Gzip $Dir/$First
else
ln $SymOrLoc$First$Gz $Dir/$Target$Gz
fi
done
########################################################################
exit 0

40
unix/license.terms Normal file
View File

@@ -0,0 +1,40 @@
This software is copyrighted by the Regents of the University of
California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState
Corporation, Apple Inc. and other parties. The following terms apply to
all files associated with the software unless explicitly disclaimed in
individual files.
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors
and need not follow the licensing terms described here, provided that
the new terms are clearly indicated on the first page of each file where
they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS.
GOVERNMENT USE: If you are acquiring this software on behalf of the
U.S. government, the Government shall have only "Restricted Rights"
in the software and related documentation as defined in the Federal
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
are acquiring the software on behalf of the Department of Defense, the
software shall be classified as "Commercial Computer Software" and the
Government shall have only "Restricted Rights" as defined in Clause
252.227-7013 (b) (3) of DFARs. Notwithstanding the foregoing, the
authors grant the U.S. Government and others acting in its behalf
permission to use and distribute the software in accordance with the
terms specified in this license.

3138
unix/tcl.m4 Normal file

File diff suppressed because it is too large Load Diff

15
unix/tk.pc.in Normal file
View File

@@ -0,0 +1,15 @@
# tk pkg-config source file
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
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@
Requires: tcl >= 8.6
Libs: -L${libdir} @TK_LIB_FLAG@ @TK_STUB_LIB_FLAG@
Libs.private: @XFT_LIBS@ @XLIBSW@
Cflags: -I${includedir}

54
unix/tk.spec Normal file
View File

@@ -0,0 +1,54 @@
# This file is the basis for a binary Tk Linux RPM.
%{!?directory:%define directory /usr/local}
Name: tk
Summary: Tk graphical toolkit for the Tcl scripting language.
Version: 8.6.6
Release: 2
License: BSD
Group: Development/Languages
Source: http://prdownloads.sourceforge.net/tcl/tk%{version}-src.tar.gz
URL: http://www.tcl.tk/
Buildroot: /var/tmp/%{name}%{version}
Buildrequires: XFree86-devel tcl >= %version
Requires: tcl >= %version
%description
The Tcl (Tool Command Language) provides a powerful platform for
creating integration applications that tie together diverse
applications, protocols, devices, and frameworks. When paired with
the Tk toolkit, Tcl provides the fastest and most powerful way to
create GUI applications that run on PCs, Unix, and Mac OS X. Tcl
can also be used for a variety of web-related tasks and for creating
powerful command languages for applications.
%prep
%setup -q -n %{name}%{version}
%build
cd unix
CFLAGS="%optflags" ./configure \
--prefix=%{directory} \
--exec-prefix=%{directory} \
--libdir=%{directory}/%{_lib}
make
%install
cd unix
make INSTALL_ROOT=%buildroot install
%clean
rm -rf %buildroot
%files -n tk
%defattr(-,root,root)
%if %{_lib} != lib
%{directory}/%{_lib}
%endif
%{directory}/lib
%{directory}/bin
%{directory}/include
%{directory}/man/man1
%{directory}/man/man3
%{directory}/man/mann

156
unix/tkAppInit.c Normal file
View File

@@ -0,0 +1,156 @@
/*
* tkAppInit.c --
*
* Provides a default version of the main program and Tcl_AppInit
* procedure for wish and other Tk-based applications.
*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 1998-1999 Scriptics Corporation.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#undef BUILD_tk
#undef STATIC_BUILD
#include "tk.h"
#ifdef TK_TEST
extern Tcl_PackageInitProc Tktest_Init;
#endif /* TK_TEST */
/*
* The following #if block allows you to change the AppInit function by using
* a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
* #if checks for that #define and uses Tcl_AppInit if it doesn't exist.
*/
#ifndef TK_LOCAL_APPINIT
#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
#ifndef MODULE_SCOPE
# define MODULE_SCOPE extern
#endif
MODULE_SCOPE int TK_LOCAL_APPINIT(Tcl_Interp *);
MODULE_SCOPE int main(int, char **);
/*
* The following #if block allows you to change how Tcl finds the startup
* script, prime the library or encoding paths, fiddle with the argv, etc.,
* without needing to rewrite Tk_Main()
*/
#ifdef TK_LOCAL_MAIN_HOOK
MODULE_SCOPE int TK_LOCAL_MAIN_HOOK(int *argc, char ***argv);
#endif
/* Make sure the stubbed variants of those are never used. */
#undef Tcl_ObjSetVar2
#undef Tcl_NewStringObj
/*
*----------------------------------------------------------------------
*
* main --
*
* This is the main program for the application.
*
* Results:
* None: Tk_Main never returns here, so this procedure never returns
* either.
*
* Side effects:
* Just about anything, since from here we call arbitrary Tcl code.
*
*----------------------------------------------------------------------
*/
int
main(
int argc, /* Number of command-line arguments. */
char **argv) /* Values of command-line arguments. */
{
#ifdef TK_LOCAL_MAIN_HOOK
TK_LOCAL_MAIN_HOOK(&argc, &argv);
#endif
Tk_Main(argc, argv, TK_LOCAL_APPINIT);
return 0; /* Needed only to prevent compiler warning. */
}
/*
*----------------------------------------------------------------------
*
* Tcl_AppInit --
*
* This procedure performs application-specific initialization. Most
* applications, especially those that incorporate additional packages,
* will have their own version of this procedure.
*
* Results:
* Returns a standard Tcl completion code, and leaves an error message in
* the interp's result if an error occurs.
*
* Side effects:
* Depends on the startup script.
*
*----------------------------------------------------------------------
*/
int
Tcl_AppInit(
Tcl_Interp *interp) /* Interpreter for application. */
{
if ((Tcl_Init)(interp) == TCL_ERROR) {
return TCL_ERROR;
}
if (Tk_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
#ifdef TK_TEST
if (Tktest_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0);
#endif /* TK_TEST */
/*
* Call the init procedures for included packages. Each call should look
* like this:
*
* if (Mod_Init(interp) == TCL_ERROR) {
* return TCL_ERROR;
* }
*
* where "Mod" is the name of the module. (Dynamically-loadable packages
* should have the same entry-point name.)
*/
/*
* Call Tcl_CreateObjCommand for application-specific commands, if they
* weren't already created by the init procedures called above.
*/
/*
* Specify a user-specific startup file to invoke if the application is
* run interactively. Typically the startup file is "~/.apprc" where "app"
* is the name of the application. If this line is deleted then no user-
* specific startup file will be run under any conditions.
*/
Tcl_ObjSetVar2(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL,
Tcl_NewStringObj("~/.wishrc", -1), TCL_GLOBAL_ONLY);
return TCL_OK;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

256
unix/tkConfig.h.in Normal file
View File

@@ -0,0 +1,256 @@
/* ../unix/tkConfig.h.in. Generated from configure.ac by autoheader. */
#ifndef _TKCONFIG
#define _TKCONFIG
/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
#undef HAVE_AVAILABILITYMACROS_H
/* Defined when compiler supports casting to union type. */
#undef HAVE_CAST_TO_UNION
/* Do we have access to Darwin CoreFoundation.framework? */
#undef HAVE_COREFOUNDATION
/* Compiler support for module scope symbols */
#undef HAVE_HIDDEN
/* Do we have the intptr_t type? */
#undef HAVE_INTPTR_T
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `Xft' library (-lXft). */
#undef HAVE_LIBXFT
/* Define to 1 if you have the `lseek64' function. */
#undef HAVE_LSEEK64
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `open64' function. */
#undef HAVE_OPEN64
/* Define to 1 if you have the `pthread_atfork' function. */
#undef HAVE_PTHREAD_ATFORK
/* Define to 1 if you have the `pthread_attr_setstacksize' function. */
#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE
/* Does struct password have a pw_gecos field? */
#undef HAVE_PW_GECOS
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Is 'struct dirent64' in <sys/types.h>? */
#undef HAVE_STRUCT_DIRENT64
/* Is 'struct stat64' in <sys/stat.h>? */
#undef HAVE_STRUCT_STAT64
/* Should we include <sys/select.h>? */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Is off64_t in <sys/types.h>? */
#undef HAVE_TYPE_OFF64_T
/* Do we have the uintptr_t type? */
#undef HAVE_UINTPTR_T
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Is weak import available? */
#undef HAVE_WEAK_IMPORT
/* Have we turned on XFT (antialiased fonts)? */
#undef HAVE_XFT
/* Do we have XkbKeycodeToKeysym? */
#undef HAVE_XKBKEYCODETOKEYSYM
/* Is XScreenSaver available? */
#undef HAVE_XSS
/* Is this a Mac I see before me? */
#undef MAC_OSX_TCL
/* Are we building TkAqua? */
#undef MAC_OSX_TK
/* No Compiler support for module scope symbols */
#undef MODULE_SCOPE
/* Is no debugging enabled? */
#undef NDEBUG
/* Is Darwin CoreFoundation unavailable for 64-bit? */
#undef NO_COREFOUNDATION_64
/* Do we have fd_set? */
#undef NO_FD_SET
/* Do we have <stdlib.h>? */
#undef NO_STDLIB_H
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Is this a static build? */
#undef STATIC_BUILD
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Is this a 64-bit build? */
#undef TCL_CFG_DO64BIT
/* Is this an optimized build? */
#undef TCL_CFG_OPTIMIZED
/* Is bytecode debugging enabled? */
#undef TCL_COMPILE_DEBUG
/* Are bytecode statistics enabled? */
#undef TCL_COMPILE_STATS
/* Is memory debugging enabled? */
#undef TCL_MEM_DEBUG
/* What is the default extension for shared libraries? */
#undef TCL_SHLIB_EXT
/* Are we building with threads enabled? */
#undef TCL_THREADS
/* Are wide integers to be implemented with C 'long's? */
#undef TCL_WIDE_INT_IS_LONG
/* What type should be used to define wide integers? */
#undef TCL_WIDE_INT_TYPE
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Is Tk built as a framework? */
#undef TK_FRAMEWORK
/* Are TkAqua debug messages enabled? */
#undef TK_MAC_DEBUG
/* Do we want to use the threaded memory allocator? */
#undef USE_THREAD_ALLOC
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Is XKeycodeToKeysym deprecated? */
#undef XKEYCODETOKEYSYM_IS_DEPRECATED
/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE
/* Add the _ISOC99_SOURCE flag when building */
#undef _ISOC99_SOURCE
/* Add the _LARGEFILE64_SOURCE flag when building */
#undef _LARGEFILE64_SOURCE
/* Add the _LARGEFILE_SOURCE64 flag when building */
#undef _LARGEFILE_SOURCE64
/* # needed in sys/socket.h Should OS/390 do the right thing with sockets? */
#undef _OE_SOCKETS
/* Do we really want to follow the standard? Yes we do! */
#undef _POSIX_PTHREAD_SEMANTICS
/* Do we want the reentrant OS API? */
#undef _REENTRANT
/* Do we want the thread-safe OS API? */
#undef _THREAD_SAFE
/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE
/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE_EXTENDED
/* Define to 1 if type `char' is unsigned and you are not using gcc. */
#ifndef __CHAR_UNSIGNED__
# undef __CHAR_UNSIGNED__
#endif
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Signed integer type wide enough to hold a pointer. */
#undef intptr_t
/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
/* Do we want to use the strtod() in compat? */
#undef strtod
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t
/* Unsigned integer type wide enough to hold a pointer. */
#undef uintptr_t
/* Undef unused package specific autoheader defines so that we can
* include both tclConfig.h and tkConfig.h at the same time: */
/* override */ #undef PACKAGE_NAME
/* override */ #undef PACKAGE_STRING
/* override */ #undef PACKAGE_TARNAME
#endif /* _TKCONFIG */

97
unix/tkConfig.sh.in Normal file
View File

@@ -0,0 +1,97 @@
# tkConfig.sh --
#
# This shell script (for sh) is generated automatically by Tk's
# configure script. It will create shell variables for most of
# the configuration options discovered by the configure script.
# This script is intended to be included by the configure scripts
# for Tk extensions so that they don't have to figure this all
# out for themselves. This file does not duplicate information
# already provided by tclConfig.sh, so you may need to use that
# file in addition to this one.
#
# The information in this file is specific to a single platform.
# Tk's version number.
TK_VERSION='@TK_VERSION@'
TK_MAJOR_VERSION='@TK_MAJOR_VERSION@'
TK_MINOR_VERSION='@TK_MINOR_VERSION@'
TK_PATCH_LEVEL='@TK_PATCH_LEVEL@'
# -D flags for use with the C compiler.
TK_DEFS='@DEFS@'
# Flag, 1: we built a shared lib, 0 we didn't
TK_SHARED_BUILD=@TK_SHARED_BUILD@
# TK_DBGX used to be used to distinguish debug vs. non-debug builds.
# This was a righteous pain so the core doesn't do that any more.
TK_DBGX=
# The name of the Tk library (may be either a .a file or a shared library):
TK_LIB_FILE='@TK_LIB_FILE@'
# Additional libraries to use when linking Tk.
TK_LIBS='@XLIBSW@ @XFT_LIBS@ @LIBS@ @TCL_LIBS@'
# Top-level directory in which Tk's platform-independent files are
# installed.
TK_PREFIX='@prefix@'
# Top-level directory in which Tk's platform-specific files (e.g.
# executables) are installed.
TK_EXEC_PREFIX='@exec_prefix@'
# -I switch(es) to use to make all of the X11 include files accessible:
TK_XINCLUDES='@XINCLUDES@'
# Linker switch(es) to use to link with the X11 library archive.
TK_XLIBSW='@XLIBSW@'
# -l flag to pass to the linker to pick up the Tk library
TK_LIB_FLAG='@TK_LIB_FLAG@'
# String to pass to linker to pick up the Tk library from its
# build directory.
TK_BUILD_LIB_SPEC='@TK_BUILD_LIB_SPEC@'
# String to pass to linker to pick up the Tk library from its
# installed directory.
TK_LIB_SPEC='@TK_LIB_SPEC@'
# String to pass to the compiler so that an extension can
# find installed Tk headers.
TK_INCLUDE_SPEC='@TK_INCLUDE_SPEC@'
# Location of the top-level source directory from which Tk was built.
# This is the directory that contains a README file as well as
# subdirectories such as generic, unix, etc. If Tk was compiled in a
# different place than the directory containing the source files, this
# points to the location of the sources, not the location where Tk was
# compiled.
TK_SRC_DIR='@TK_SRC_DIR@'
# Needed if you want to make a 'fat' shared library library
# containing tk objects or link a different wish.
TK_CC_SEARCH_FLAGS='@CC_SEARCH_FLAGS@'
TK_LD_SEARCH_FLAGS='@LD_SEARCH_FLAGS@'
# The name of the Tk stub library (.a):
TK_STUB_LIB_FILE='@TK_STUB_LIB_FILE@'
# -l flag to pass to the linker to pick up the Tk stub library
TK_STUB_LIB_FLAG='@TK_STUB_LIB_FLAG@'
# String to pass to linker to pick up the Tk stub library from its
# build directory.
TK_BUILD_STUB_LIB_SPEC='@TK_BUILD_STUB_LIB_SPEC@'
# String to pass to linker to pick up the Tk stub library from its
# installed directory.
TK_STUB_LIB_SPEC='@TK_STUB_LIB_SPEC@'
# Path to the Tk stub library in the build directory.
TK_BUILD_STUB_LIB_PATH='@TK_BUILD_STUB_LIB_PATH@'
# Path to the Tk stub library in the install directory.
TK_STUB_LIB_PATH='@TK_STUB_LIB_PATH@'

265
unix/tkUnix.c Normal file
View File

@@ -0,0 +1,265 @@
/*
* tkUnix.c --
*
* This file contains procedures that are UNIX/X-specific, and will
* probably have to be written differently for Windows or Macintosh
* platforms.
*
* Copyright (c) 1995 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#ifdef HAVE_XSS
# include <X11/extensions/scrnsaver.h>
# ifdef __APPLE__
/* Support for weak-linked libXss. */
# define HaveXSSLibrary() (XScreenSaverQueryInfo != NULL)
# else
/* Other platforms always link libXss. */
# define HaveXSSLibrary() (1)
# endif
#endif
/*
*----------------------------------------------------------------------
*
* TkGetServerInfo --
*
* Given a window, this procedure returns information about the window
* server for that window. This procedure provides the guts of the "winfo
* server" command.
*
* Results:
* Sets the interpreter result.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
TkGetServerInfo(
Tcl_Interp *interp, /* The server information is returned in this
* interpreter's result. */
Tk_Window tkwin) /* Token for window; this selects a particular
* display and server. */
{
Tcl_SetObjResult(interp, Tcl_ObjPrintf("X%dR%d %s %d",
ProtocolVersion(Tk_Display(tkwin)),
ProtocolRevision(Tk_Display(tkwin)),
ServerVendor(Tk_Display(tkwin)),
VendorRelease(Tk_Display(tkwin))));
}
/*
*----------------------------------------------------------------------
*
* TkGetDefaultScreenName --
*
* Returns the name of the screen that Tk should use during
* initialization.
*
* Results:
* Returns the argument or a string that should not be freed by the
* caller.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
const char *
TkGetDefaultScreenName(
Tcl_Interp *interp, /* Interp used to find environment
* variables. */
const char *screenName) /* Screen name from command line, or NULL. */
{
if ((screenName == NULL) || (screenName[0] == '\0')) {
screenName = Tcl_GetVar2(interp, "env", "DISPLAY", TCL_GLOBAL_ONLY);
}
return screenName;
}
/*
*----------------------------------------------------------------------
*
* Tk_UpdatePointer --
*
* Unused function in UNIX
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Tk_UpdatePointer(
Tk_Window tkwin, /* Window to which pointer event is reported.
* May be NULL. */
int x, int y, /* Pointer location in root coords. */
int state) /* Modifier state mask. */
{
/*
* This function intentionally left blank
*/
}
/*
*----------------------------------------------------------------------
*
* TkpBuildRegionFromAlphaData --
*
* Set up a rectangle of the given region based on the supplied alpha
* data.
*
* Results:
* None
*
* Side effects:
* The region is updated, with extra pixels added to it.
*
*----------------------------------------------------------------------
*/
void
TkpBuildRegionFromAlphaData(
TkRegion region, /* Region to be updated. */
unsigned x, unsigned y, /* Where in region to update. */
unsigned width, unsigned height,
/* Size of rectangle to update. */
unsigned char *dataPtr, /* Data to read from. */
unsigned pixelStride, /* Num bytes from one piece of alpha data to
* the next in the line. */
unsigned lineStride) /* Num bytes from one line of alpha data to
* the next line. */
{
unsigned char *lineDataPtr;
unsigned int x1, y1, end;
XRectangle rect;
for (y1 = 0; y1 < height; y1++) {
lineDataPtr = dataPtr;
for (x1 = 0; x1 < width; x1 = end) {
/*
* Search for first non-transparent pixel.
*/
while ((x1 < width) && !*lineDataPtr) {
x1++;
lineDataPtr += pixelStride;
}
end = x1;
/*
* Search for first transparent pixel.
*/
while ((end < width) && *lineDataPtr) {
end++;
lineDataPtr += pixelStride;
}
if (end > x1) {
rect.x = x + x1;
rect.y = y + y1;
rect.width = end - x1;
rect.height = 1;
TkUnionRectWithRegion(&rect, region, region);
}
}
dataPtr += lineStride;
}
}
/*
*----------------------------------------------------------------------
*
* Tk_GetUserInactiveTime --
*
* Return the number of milliseconds the user was inactive.
*
* Results:
* The number of milliseconds since the user's latest interaction with
* the system on the given display, or -1 if the XScreenSaver extension
* is not supported by the client libraries or the X server
* implementation.
*
* Side effects:
* None.
*----------------------------------------------------------------------
*/
long
Tk_GetUserInactiveTime(
Display *dpy) /* The display for which to query the inactive
* time. */
{
long inactiveTime = -1;
#ifdef HAVE_XSS
int eventBase, errorBase, major, minor;
/*
* Calling XScreenSaverQueryVersion seems to be needed to prevent a crash
* on some buggy versions of XFree86.
*/
if (HaveXSSLibrary()
&& XScreenSaverQueryExtension(dpy, &eventBase, &errorBase)
&& XScreenSaverQueryVersion(dpy, &major, &minor)) {
XScreenSaverInfo *info = XScreenSaverAllocInfo();
if (info == NULL) {
/*
* We are out of memory.
*/
Tcl_Panic("Out of memory: XScreenSaverAllocInfo failed in Tk_GetUserInactiveTime");
}
if (XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), info)) {
inactiveTime = info->idle;
}
XFree(info);
}
#endif /* HAVE_XSS */
return inactiveTime;
}
/*
*----------------------------------------------------------------------
*
* Tk_ResetUserInactiveTime --
*
* Reset the user inactivity timer
*
* Results:
* none
*
* Side effects:
* The user inactivity timer of the underlaying windowing system is reset
* to zero.
*
*----------------------------------------------------------------------
*/
void
Tk_ResetUserInactiveTime(
Display *dpy)
{
XResetScreenSaver(dpy);
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

500
unix/tkUnix3d.c Normal file
View File

@@ -0,0 +1,500 @@
/*
* tkUnix3d.c --
*
* This file contains the platform specific routines for drawing 3d
* borders in the Motif style.
*
* Copyright (c) 1996 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "tk3d.h"
#if !(defined(_WIN32) || defined(MAC_OSX_TK))
#include "tkUnixInt.h"
#endif
/*
* This structure is used to keep track of the extra colors used by Unix 3D
* borders.
*/
typedef struct {
TkBorder info;
GC solidGC; /* Used to draw solid relief. */
} UnixBorder;
/*
*----------------------------------------------------------------------
*
* TkpGetBorder --
*
* This function allocates a new TkBorder structure.
*
* Results:
* Returns a newly allocated TkBorder.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
TkBorder *
TkpGetBorder(void)
{
UnixBorder *borderPtr = ckalloc(sizeof(UnixBorder));
borderPtr->solidGC = None;
return (TkBorder *) borderPtr;
}
/*
*----------------------------------------------------------------------
*
* TkpFreeBorder --
*
* This function frees any colors allocated by the platform specific part
* of this module.
*
* Results:
* None.
*
* Side effects:
* May deallocate some colors.
*
*----------------------------------------------------------------------
*/
void
TkpFreeBorder(
TkBorder *borderPtr)
{
UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
Display *display = DisplayOfScreen(borderPtr->screen);
if (unixBorderPtr->solidGC != None) {
Tk_FreeGC(display, unixBorderPtr->solidGC);
}
}
/*
*--------------------------------------------------------------
*
* Tk_3DVerticalBevel --
*
* This procedure draws a vertical bevel along one side of an object. The
* bevel is always rectangular in shape:
* |||
* |||
* |||
* |||
* |||
* |||
* An appropriate shadow color is chosen for the bevel based on the
* leftBevel and relief arguments. Normally this procedure is called
* first, then Tk_3DHorizontalBevel is called next to draw neat corners.
*
* Results:
* None.
*
* Side effects:
* Graphics are drawn in drawable.
*
*--------------------------------------------------------------
*/
void
Tk_3DVerticalBevel(
Tk_Window tkwin, /* Window for which border was allocated. */
Drawable drawable, /* X window or pixmap in which to draw. */
Tk_3DBorder border, /* Token for border to draw. */
int x, int y, int width, int height,
/* Area of vertical bevel. */
int leftBevel, /* Non-zero means this bevel forms the left
* side of the object; 0 means it forms the
* right side. */
int relief) /* Kind of bevel to draw. For example,
* TK_RELIEF_RAISED means interior of object
* should appear higher than exterior. */
{
TkBorder *borderPtr = (TkBorder *) border;
GC left, right;
Display *display = Tk_Display(tkwin);
if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) {
TkpGetShadows(borderPtr, tkwin);
}
if (relief == TK_RELIEF_RAISED) {
XFillRectangle(display, drawable,
(leftBevel) ? borderPtr->lightGC : borderPtr->darkGC,
x, y, (unsigned) width, (unsigned) height);
} else if (relief == TK_RELIEF_SUNKEN) {
XFillRectangle(display, drawable,
(leftBevel) ? borderPtr->darkGC : borderPtr->lightGC,
x, y, (unsigned) width, (unsigned) height);
} else if (relief == TK_RELIEF_RIDGE) {
int half;
left = borderPtr->lightGC;
right = borderPtr->darkGC;
ridgeGroove:
half = width/2;
if (!leftBevel && (width & 1)) {
half++;
}
XFillRectangle(display, drawable, left, x, y, (unsigned) half,
(unsigned) height);
XFillRectangle(display, drawable, right, x+half, y,
(unsigned) (width-half), (unsigned) height);
} else if (relief == TK_RELIEF_GROOVE) {
left = borderPtr->darkGC;
right = borderPtr->lightGC;
goto ridgeGroove;
} else if (relief == TK_RELIEF_FLAT) {
XFillRectangle(display, drawable, borderPtr->bgGC, x, y,
(unsigned) width, (unsigned) height);
} else if (relief == TK_RELIEF_SOLID) {
UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
if (unixBorderPtr->solidGC == None) {
XGCValues gcValues;
gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
unixBorderPtr->solidGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
}
XFillRectangle(display, drawable, unixBorderPtr->solidGC, x, y,
(unsigned) width, (unsigned) height);
}
}
/*
*--------------------------------------------------------------
*
* Tk_3DHorizontalBevel --
*
* This procedure draws a horizontal bevel along one side of an object.
* The bevel has mitered corners (depending on leftIn and rightIn
* arguments).
*
* Results:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
void
Tk_3DHorizontalBevel(
Tk_Window tkwin, /* Window for which border was allocated. */
Drawable drawable, /* X window or pixmap in which to draw. */
Tk_3DBorder border, /* Token for border to draw. */
int x, int y, int width, int height,
/* Bounding box of area of bevel. Height gives
* width of border. */
int leftIn, int rightIn, /* Describes whether the left and right edges
* of the bevel angle in or out as they go
* down. For example, if "leftIn" is true, the
* left side of the bevel looks like this:
* ___________
* __________
* _________
* ________
*/
int topBevel, /* Non-zero means this bevel forms the top
* side of the object; 0 means it forms the
* bottom side. */
int relief) /* Kind of bevel to draw. For example,
* TK_RELIEF_RAISED means interior of object
* should appear higher than exterior. */
{
TkBorder *borderPtr = (TkBorder *) border;
Display *display = Tk_Display(tkwin);
int bottom, halfway, x1, x2, x1Delta, x2Delta;
UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
GC topGC = None, bottomGC = None;
/* Initializations needed only to prevent
* compiler warnings. */
if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT) &&
(relief != TK_RELIEF_SOLID)) {
TkpGetShadows(borderPtr, tkwin);
}
/*
* Compute a GC for the top half of the bevel and a GC for the bottom half
* (they're the same in many cases).
*/
switch (relief) {
case TK_RELIEF_FLAT:
topGC = bottomGC = borderPtr->bgGC;
break;
case TK_RELIEF_GROOVE:
topGC = borderPtr->darkGC;
bottomGC = borderPtr->lightGC;
break;
case TK_RELIEF_RAISED:
topGC = bottomGC = (topBevel? borderPtr->lightGC : borderPtr->darkGC);
break;
case TK_RELIEF_RIDGE:
topGC = borderPtr->lightGC;
bottomGC = borderPtr->darkGC;
break;
case TK_RELIEF_SOLID:
if (unixBorderPtr->solidGC == None) {
XGCValues gcValues;
gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
unixBorderPtr->solidGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
}
XFillRectangle(display, drawable, unixBorderPtr->solidGC, x, y,
(unsigned) width, (unsigned) height);
return;
case TK_RELIEF_SUNKEN:
topGC = bottomGC = (topBevel? borderPtr->darkGC : borderPtr->lightGC);
break;
}
/*
* Compute various other geometry-related stuff.
*/
x1 = x;
if (!leftIn) {
x1 += height;
}
x2 = x+width;
if (!rightIn) {
x2 -= height;
}
x1Delta = (leftIn) ? 1 : -1;
x2Delta = (rightIn) ? -1 : 1;
halfway = y + height/2;
if (!topBevel && (height & 1)) {
halfway++;
}
bottom = y + height;
/*
* Draw one line for each y-coordinate covered by the bevel.
*/
for ( ; y < bottom; y++) {
/*
* X Dimensions are 16-bit, so avoid wraparound or display errors by
* limiting these here.
*/
if (x1 < -32767) {
x1 = -32767;
}
if (x2 > 32767) {
x2 = 32767;
}
/*
* In some weird cases (such as large border widths for skinny
* rectangles) x1 can be >= x2. Don't draw the lines in these cases.
*/
if (x1 < x2) {
XFillRectangle(display, drawable,
(y < halfway) ? topGC : bottomGC, x1, y,
(unsigned) (x2-x1), (unsigned) 1);
}
x1 += x1Delta;
x2 += x2Delta;
}
}
/*
*----------------------------------------------------------------------
*
* TkpGetShadows --
*
* This procedure computes the shadow colors for a 3-D border and fills
* in the corresponding fields of the Border structure. It's called
* lazily, so that the colors aren't allocated until something is
* actually drawn with them. That way, if a border is only used for flat
* backgrounds the shadow colors will never be allocated.
*
* Results:
* None.
*
* Side effects:
* The lightGC and darkGC fields in borderPtr get filled in, if they
* weren't already.
*
*----------------------------------------------------------------------
*/
void
TkpGetShadows(
TkBorder *borderPtr, /* Information about border. */
Tk_Window tkwin) /* Window where border will be used for
* drawing. */
{
XColor lightColor, darkColor;
int stressed, tmp1, tmp2;
int r, g, b;
XGCValues gcValues;
if (borderPtr->lightGC != None) {
return;
}
stressed = TkpCmapStressed(tkwin, borderPtr->colormap);
/*
* First, handle the case of a color display with lots of colors. The
* shadow colors get computed using whichever formula results in the
* greatest change in color:
* 1. Lighter shadow is half-way to white, darker shadow is half way to
* dark.
* 2. Lighter shadow is 40% brighter than background, darker shadow is 40%
* darker than background.
*/
if (!stressed && (Tk_Depth(tkwin) >= 6)) {
/*
* This is a color display with lots of colors. For the dark shadow,
* cut 40% from each of the background color components. But if the
* background is already very dark, make the dark color a little
* lighter than the background by increasing each color component
* 1/4th of the way to MAX_INTENSITY.
*
* For the light shadow, boost each component by 40% or half-way to
* white, whichever is greater (the first approach works better for
* unsaturated colors, the second for saturated ones). But if the
* background is already very bright, instead choose a slightly darker
* color for the light shadow by reducing each color component by 10%.
*
* Compute the colors using integers, not using lightColor.red etc.:
* these are shorts and may have problems with integer overflow.
*/
/*
* Compute the dark shadow color.
*/
r = (int) borderPtr->bgColorPtr->red;
g = (int) borderPtr->bgColorPtr->green;
b = (int) borderPtr->bgColorPtr->blue;
if (r*0.5*r + g*1.0*g + b*0.28*b < MAX_INTENSITY*0.05*MAX_INTENSITY) {
darkColor.red = (MAX_INTENSITY + 3*r)/4;
darkColor.green = (MAX_INTENSITY + 3*g)/4;
darkColor.blue = (MAX_INTENSITY + 3*b)/4;
} else {
darkColor.red = (60 * r)/100;
darkColor.green = (60 * g)/100;
darkColor.blue = (60 * b)/100;
}
/*
* Allocate the dark shadow color and its GC.
*/
borderPtr->darkColorPtr = Tk_GetColorByValue(tkwin, &darkColor);
gcValues.foreground = borderPtr->darkColorPtr->pixel;
borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
/*
* Compute the light shadow color.
*/
if (g > MAX_INTENSITY*0.95) {
lightColor.red = (90 * r)/100;
lightColor.green = (90 * g)/100;
lightColor.blue = (90 * b)/100;
} else {
tmp1 = (14 * r)/10;
if (tmp1 > MAX_INTENSITY) {
tmp1 = MAX_INTENSITY;
}
tmp2 = (MAX_INTENSITY + r)/2;
lightColor.red = (tmp1 > tmp2) ? tmp1 : tmp2;
tmp1 = (14 * g)/10;
if (tmp1 > MAX_INTENSITY) {
tmp1 = MAX_INTENSITY;
}
tmp2 = (MAX_INTENSITY + g)/2;
lightColor.green = (tmp1 > tmp2) ? tmp1 : tmp2;
tmp1 = (14 * b)/10;
if (tmp1 > MAX_INTENSITY) {
tmp1 = MAX_INTENSITY;
}
tmp2 = (MAX_INTENSITY + b)/2;
lightColor.blue = (tmp1 > tmp2) ? tmp1 : tmp2;
}
/*
* Allocate the light shadow color and its GC.
*/
borderPtr->lightColorPtr = Tk_GetColorByValue(tkwin, &lightColor);
gcValues.foreground = borderPtr->lightColorPtr->pixel;
borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
return;
}
if (borderPtr->shadow == None) {
borderPtr->shadow = Tk_GetBitmap((Tcl_Interp *) NULL, tkwin,
Tk_GetUid("gray50"));
if (borderPtr->shadow == None) {
Tcl_Panic("TkpGetShadows couldn't allocate bitmap for border");
}
}
if (borderPtr->visual->map_entries > 2) {
/*
* This isn't a monochrome display, but the colormap either ran out of
* entries or didn't have very many to begin with. Generate the light
* shadows with a white stipple and the dark shadows with a black
* stipple.
*/
gcValues.foreground = borderPtr->bgColorPtr->pixel;
gcValues.background = BlackPixelOfScreen(borderPtr->screen);
gcValues.stipple = borderPtr->shadow;
gcValues.fill_style = FillOpaqueStippled;
borderPtr->darkGC = Tk_GetGC(tkwin,
GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues);
gcValues.background = WhitePixelOfScreen(borderPtr->screen);
borderPtr->lightGC = Tk_GetGC(tkwin,
GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues);
return;
}
/*
* This is just a measly monochrome display, hardly even worth its
* existence on this earth. Make one shadow a 50% stipple and the other
* the opposite of the background.
*/
gcValues.foreground = WhitePixelOfScreen(borderPtr->screen);
gcValues.background = BlackPixelOfScreen(borderPtr->screen);
gcValues.stipple = borderPtr->shadow;
gcValues.fill_style = FillOpaqueStippled;
borderPtr->lightGC = Tk_GetGC(tkwin,
GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues);
if (borderPtr->bgColorPtr->pixel
== WhitePixelOfScreen(borderPtr->screen)) {
gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
} else {
borderPtr->darkGC = borderPtr->lightGC;
borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
}
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

1021
unix/tkUnixButton.c Normal file

File diff suppressed because it is too large Load Diff

450
unix/tkUnixColor.c Normal file
View File

@@ -0,0 +1,450 @@
/*
* tkUnixColor.c --
*
* This file contains the platform specific color routines needed for X
* support.
*
* Copyright (c) 1996 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkUnixInt.h"
#include "tkColor.h"
/*
* If a colormap fills up, attempts to allocate new colors from that colormap
* will fail. When that happens, we'll just choose the closest color from
* those that are available in the colormap. One of the following structures
* will be created for each "stressed" colormap to keep track of the colors
* that are available in the colormap (otherwise we would have to re-query
* from the server on each allocation, which would be very slow). These
* entries are flushed after a few seconds, since other clients may release or
* reallocate colors over time.
*/
struct TkStressedCmap {
Colormap colormap; /* X's token for the colormap. */
int numColors; /* Number of entries currently active at
* *colorPtr. */
XColor *colorPtr; /* Pointer to malloc'ed array of all colors
* that seem to be available in the colormap.
* Some may not actually be available, e.g.
* because they are read-write for another
* client; when we find this out, we remove
* them from the array. */
struct TkStressedCmap *nextPtr;
/* Next in list of all stressed colormaps for
* the display. */
};
/*
* Forward declarations for functions defined in this file:
*/
static void DeleteStressedCmap(Display *display,
Colormap colormap);
static void FindClosestColor(Tk_Window tkwin,
XColor *desiredColorPtr, XColor *actualColorPtr);
/*
*----------------------------------------------------------------------
*
* TkpFreeColor --
*
* Release the specified color back to the system.
*
* Results:
* None
*
* Side effects:
* Invalidates the colormap cache for the colormap associated with the
* given color.
*
*----------------------------------------------------------------------
*/
void
TkpFreeColor(
TkColor *tkColPtr) /* Color to be released. Must have been
* allocated by TkpGetColor or
* TkpGetColorByValue. */
{
Visual *visual;
Screen *screen = tkColPtr->screen;
/*
* Careful! Don't free black or white, since this will make some servers
* very unhappy. Also, there is a bug in some servers (such Sun's X11/NeWS
* server) where reference counting is performed incorrectly, so that if a
* color is allocated twice in different places and then freed twice, the
* second free generates an error (this bug existed as of 10/1/92). To get
* around this problem, ignore errors that occur during the free
* operation.
*/
visual = tkColPtr->visual;
if ((visual->class != StaticGray) && (visual->class != StaticColor)
&& (tkColPtr->color.pixel != BlackPixelOfScreen(screen))
&& (tkColPtr->color.pixel != WhitePixelOfScreen(screen))) {
Tk_ErrorHandler handler;
handler = Tk_CreateErrorHandler(DisplayOfScreen(screen),
-1, -1, -1, NULL, NULL);
XFreeColors(DisplayOfScreen(screen), tkColPtr->colormap,
&tkColPtr->color.pixel, 1, 0L);
Tk_DeleteErrorHandler(handler);
}
DeleteStressedCmap(DisplayOfScreen(screen), tkColPtr->colormap);
}
/*
*----------------------------------------------------------------------
*
* TkpGetColor --
*
* Allocate a new TkColor for the color with the given name.
*
* Results:
* Returns a newly allocated TkColor, or NULL on failure.
*
* Side effects:
* May invalidate the colormap cache associated with tkwin upon
* allocating a new colormap entry. Allocates a new TkColor structure.
*
*----------------------------------------------------------------------
*/
TkColor *
TkpGetColor(
Tk_Window tkwin, /* Window in which color will be used. */
Tk_Uid name) /* Name of color to allocated (in form
* suitable for passing to XParseColor). */
{
Display *display = Tk_Display(tkwin);
Colormap colormap = Tk_Colormap(tkwin);
XColor color;
TkColor *tkColPtr;
/*
* Map from the name to a pixel value. Call XAllocNamedColor rather than
* XParseColor for non-# names: this saves a server round-trip for those
* names.
*/
if (*name != '#') {
XColor screen;
if (((*name - 'A') & 0xdf) < sizeof(tkWebColors)/sizeof(tkWebColors[0])) {
if (!((name[0] - 'G') & 0xdf) && !((name[1] - 'R') & 0xdf)
&& !((name[2] - 'A') & 0xdb) && !((name[3] - 'Y') & 0xdf)
&& !name[4]) {
name = "#808080808080";
goto gotWebColor;
} else {
const char *p = tkWebColors[((*name - 'A') & 0x1f)];
if (p) {
const char *q = name;
while (!((*p - *(++q)) & 0xdf)) {
if (!*p++) {
name = p;
goto gotWebColor;
}
}
}
}
}
if (strlen(name) > 99) {
/* Don't bother to parse this. [Bug 2809525]*/
return (TkColor *) NULL;
} else if (XAllocNamedColor(display, colormap, name, &screen, &color) != 0) {
DeleteStressedCmap(display, colormap);
} else {
/*
* Couldn't allocate the color. Try translating the name to a
* color value, to see whether the problem is a bad color name or
* a full colormap. If the colormap is full, then pick an
* approximation to the desired color.
*/
if (XLookupColor(display, colormap, name, &color, &screen) == 0) {
return NULL;
}
FindClosestColor(tkwin, &screen, &color);
}
} else {
gotWebColor:
if (TkParseColor(display, colormap, name, &color) == 0) {
return NULL;
}
if (XAllocColor(display, colormap, &color) != 0) {
DeleteStressedCmap(display, colormap);
} else {
FindClosestColor(tkwin, &color, &color);
}
}
tkColPtr = ckalloc(sizeof(TkColor));
tkColPtr->color = color;
return tkColPtr;
}
/*
*----------------------------------------------------------------------
*
* TkpGetColorByValue --
*
* Given a desired set of red-green-blue intensities for a color, locate
* a pixel value to use to draw that color in a given window.
*
* Results:
* The return value is a pointer to an TkColor structure that indicates
* the closest red, blue, and green intensities available to those
* specified in colorPtr, and also specifies a pixel value to use to draw
* in that color.
*
* Side effects:
* May invalidate the colormap cache for the specified window. Allocates
* a new TkColor structure.
*
*----------------------------------------------------------------------
*/
TkColor *
TkpGetColorByValue(
Tk_Window tkwin, /* Window in which color will be used. */
XColor *colorPtr) /* Red, green, and blue fields indicate
* desired color. */
{
Display *display = Tk_Display(tkwin);
Colormap colormap = Tk_Colormap(tkwin);
TkColor *tkColPtr = ckalloc(sizeof(TkColor));
tkColPtr->color.red = colorPtr->red;
tkColPtr->color.green = colorPtr->green;
tkColPtr->color.blue = colorPtr->blue;
if (XAllocColor(display, colormap, &tkColPtr->color) != 0) {
DeleteStressedCmap(display, colormap);
} else {
FindClosestColor(tkwin, &tkColPtr->color, &tkColPtr->color);
}
return tkColPtr;
}
/*
*----------------------------------------------------------------------
*
* FindClosestColor --
*
* When Tk can't allocate a color because a colormap has filled up, this
* function is called to find and allocate the closest available color in
* the colormap.
*
* Results:
* There is no return value, but *actualColorPtr is filled in with
* information about the closest available color in tkwin's colormap.
* This color has been allocated via X, so it must be released by the
* caller when the caller is done with it.
*
* Side effects:
* A color is allocated.
*
*----------------------------------------------------------------------
*/
static void
FindClosestColor(
Tk_Window tkwin, /* Window where color will be used. */
XColor *desiredColorPtr, /* RGB values of color that was wanted (but
* unavailable). */
XColor *actualColorPtr) /* Structure to fill in with RGB and pixel for
* closest available color. */
{
TkStressedCmap *stressPtr;
double tmp, distance, closestDistance;
int i, closest, numFound;
XColor *colorPtr;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
Colormap colormap = Tk_Colormap(tkwin);
XVisualInfo template, *visInfoPtr;
/*
* Find the TkStressedCmap structure for this colormap, or create a new
* one if needed.
*/
for (stressPtr = dispPtr->stressPtr; ; stressPtr = stressPtr->nextPtr) {
if (stressPtr == NULL) {
stressPtr = ckalloc(sizeof(TkStressedCmap));
stressPtr->colormap = colormap;
template.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));
visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
VisualIDMask, &template, &numFound);
if (numFound < 1) {
Tcl_Panic("FindClosestColor couldn't lookup visual");
}
stressPtr->numColors = visInfoPtr->colormap_size;
XFree((char *) visInfoPtr);
stressPtr->colorPtr =
ckalloc(stressPtr->numColors * sizeof(XColor));
for (i = 0; i < stressPtr->numColors; i++) {
stressPtr->colorPtr[i].pixel = (unsigned long) i;
}
XQueryColors(dispPtr->display, colormap, stressPtr->colorPtr,
stressPtr->numColors);
stressPtr->nextPtr = dispPtr->stressPtr;
dispPtr->stressPtr = stressPtr;
break;
}
if (stressPtr->colormap == colormap) {
break;
}
}
/*
* Find the color that best approximates the desired one, then try to
* allocate that color. If that fails, it must mean that the color was
* read-write (so we can't use it, since it's owner might change it) or
* else it was already freed. Try again, over and over again, until
* something succeeds.
*/
while (1) {
if (stressPtr->numColors == 0) {
Tcl_Panic("FindClosestColor ran out of colors");
}
closestDistance = 1e30;
closest = 0;
for (colorPtr = stressPtr->colorPtr, i = 0; i < stressPtr->numColors;
colorPtr++, i++) {
/*
* Use Euclidean distance in RGB space, weighted by Y (of YIQ) as
* the objective function; this accounts for differences in the
* color sensitivity of the eye.
*/
tmp = .30*(((int) desiredColorPtr->red) - (int) colorPtr->red);
distance = tmp*tmp;
tmp = .61*(((int) desiredColorPtr->green) - (int) colorPtr->green);
distance += tmp*tmp;
tmp = .11*(((int) desiredColorPtr->blue) - (int) colorPtr->blue);
distance += tmp*tmp;
if (distance < closestDistance) {
closest = i;
closestDistance = distance;
}
}
if (XAllocColor(dispPtr->display, colormap,
&stressPtr->colorPtr[closest]) != 0) {
*actualColorPtr = stressPtr->colorPtr[closest];
return;
}
/*
* Couldn't allocate the color. Remove it from the table and go back
* to look for the next best color.
*/
stressPtr->colorPtr[closest] =
stressPtr->colorPtr[stressPtr->numColors-1];
stressPtr->numColors -= 1;
}
}
/*
*----------------------------------------------------------------------
*
* DeleteStressedCmap --
*
* This function releases the information cached for "colormap" so that
* it will be refetched from the X server the next time it is needed.
*
* Results:
* None.
*
* Side effects:
* The TkStressedCmap structure for colormap is deleted; the colormap is
* no longer considered to be "stressed".
*
* Note:
* This function is invoked whenever a color in a colormap is freed, and
* whenever a color allocation in a colormap succeeds. This guarantees
* that TkStressedCmap structures are always deleted before the
* corresponding Colormap is freed.
*
*----------------------------------------------------------------------
*/
static void
DeleteStressedCmap(
Display *display, /* Xlib's handle for the display containing
* the colormap. */
Colormap colormap) /* Colormap to flush. */
{
TkStressedCmap *prevPtr, *stressPtr;
TkDisplay *dispPtr = TkGetDisplay(display);
for (prevPtr = NULL, stressPtr = dispPtr->stressPtr; stressPtr != NULL;
prevPtr = stressPtr, stressPtr = stressPtr->nextPtr) {
if (stressPtr->colormap == colormap) {
if (prevPtr == NULL) {
dispPtr->stressPtr = stressPtr->nextPtr;
} else {
prevPtr->nextPtr = stressPtr->nextPtr;
}
ckfree(stressPtr->colorPtr);
ckfree(stressPtr);
return;
}
}
}
/*
*----------------------------------------------------------------------
*
* TkpCmapStressed --
*
* Check to see whether a given colormap is known to be out of entries.
*
* Results:
* 1 is returned if "colormap" is stressed (i.e. it has run out of
* entries recently), 0 otherwise.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
TkpCmapStressed(
Tk_Window tkwin, /* Window that identifies the display
* containing the colormap. */
Colormap colormap) /* Colormap to check for stress. */
{
TkStressedCmap *stressPtr;
for (stressPtr = ((TkWindow *) tkwin)->dispPtr->stressPtr;
stressPtr != NULL; stressPtr = stressPtr->nextPtr) {
if (stressPtr->colormap == colormap) {
return 1;
}
}
return 0;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

50
unix/tkUnixConfig.c Normal file
View File

@@ -0,0 +1,50 @@
/*
* tkUnixConfig.c --
*
* This module implements the Unix system defaults for the configuration
* package.
*
* Copyright (c) 1997 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
/*
*----------------------------------------------------------------------
*
* TkpGetSystemDefault --
*
* Given a dbName and className for a configuration option, return a
* string representation of the option.
*
* Results:
* Returns a Tk_Uid that is the string identifier that identifies this
* option. Returns NULL if there are no system defaults that match this
* pair.
*
* Side effects:
* None, once the package is initialized.
*
*----------------------------------------------------------------------
*/
Tcl_Obj *
TkpGetSystemDefault(
Tk_Window tkwin, /* A window to use. */
const char *dbName, /* The option database name. */
const char *className) /* The name of the option class. */
{
return NULL;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

651
unix/tkUnixCursor.c Normal file
View File

@@ -0,0 +1,651 @@
/*
* tkUnixCursor.c --
*
* This file contains X specific cursor manipulation routines.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
/*
* The following data structure is a superset of the TkCursor structure
* defined in tkCursor.c. Each system specific cursor module will define a
* different cursor structure. All of these structures must have the same
* header consisting of the fields in TkCursor.
*/
typedef struct {
TkCursor info; /* Generic cursor info used by tkCursor.c */
Display *display; /* Display for which cursor is valid. */
} TkUnixCursor;
/*
* The table below is used to map from the name of a cursor to its index in
* the official cursor font:
*/
static const struct CursorName {
const char *name;
unsigned int shape;
} cursorNames[] = {
{"X_cursor", XC_X_cursor},
{"arrow", XC_arrow},
{"based_arrow_down", XC_based_arrow_down},
{"based_arrow_up", XC_based_arrow_up},
{"boat", XC_boat},
{"bogosity", XC_bogosity},
{"bottom_left_corner", XC_bottom_left_corner},
{"bottom_right_corner", XC_bottom_right_corner},
{"bottom_side", XC_bottom_side},
{"bottom_tee", XC_bottom_tee},
{"box_spiral", XC_box_spiral},
{"center_ptr", XC_center_ptr},
{"circle", XC_circle},
{"clock", XC_clock},
{"coffee_mug", XC_coffee_mug},
{"cross", XC_cross},
{"cross_reverse", XC_cross_reverse},
{"crosshair", XC_crosshair},
{"diamond_cross", XC_diamond_cross},
{"dot", XC_dot},
{"dotbox", XC_dotbox},
{"double_arrow", XC_double_arrow},
{"draft_large", XC_draft_large},
{"draft_small", XC_draft_small},
{"draped_box", XC_draped_box},
{"exchange", XC_exchange},
{"fleur", XC_fleur},
{"gobbler", XC_gobbler},
{"gumby", XC_gumby},
{"hand1", XC_hand1},
{"hand2", XC_hand2},
{"heart", XC_heart},
{"icon", XC_icon},
{"iron_cross", XC_iron_cross},
{"left_ptr", XC_left_ptr},
{"left_side", XC_left_side},
{"left_tee", XC_left_tee},
{"leftbutton", XC_leftbutton},
{"ll_angle", XC_ll_angle},
{"lr_angle", XC_lr_angle},
{"man", XC_man},
{"middlebutton", XC_middlebutton},
{"mouse", XC_mouse},
{"pencil", XC_pencil},
{"pirate", XC_pirate},
{"plus", XC_plus},
{"question_arrow", XC_question_arrow},
{"right_ptr", XC_right_ptr},
{"right_side", XC_right_side},
{"right_tee", XC_right_tee},
{"rightbutton", XC_rightbutton},
{"rtl_logo", XC_rtl_logo},
{"sailboat", XC_sailboat},
{"sb_down_arrow", XC_sb_down_arrow},
{"sb_h_double_arrow", XC_sb_h_double_arrow},
{"sb_left_arrow", XC_sb_left_arrow},
{"sb_right_arrow", XC_sb_right_arrow},
{"sb_up_arrow", XC_sb_up_arrow},
{"sb_v_double_arrow", XC_sb_v_double_arrow},
{"shuttle", XC_shuttle},
{"sizing", XC_sizing},
{"spider", XC_spider},
{"spraycan", XC_spraycan},
{"star", XC_star},
{"target", XC_target},
{"tcross", XC_tcross},
{"top_left_arrow", XC_top_left_arrow},
{"top_left_corner", XC_top_left_corner},
{"top_right_corner", XC_top_right_corner},
{"top_side", XC_top_side},
{"top_tee", XC_top_tee},
{"trek", XC_trek},
{"ul_angle", XC_ul_angle},
{"umbrella", XC_umbrella},
{"ur_angle", XC_ur_angle},
{"watch", XC_watch},
{"xterm", XC_xterm},
{NULL, 0}
};
/*
* The table below is used to map from a cursor name to the data that defines
* the cursor. This table is used for cursors defined by Tk that don't exist
* in the X cursor table.
*/
#define CURSOR_NONE_DATA \
"#define none_width 1\n" \
"#define none_height 1\n" \
"#define none_x_hot 0\n" \
"#define none_y_hot 0\n" \
"static unsigned char none_bits[] = {\n" \
" 0x00};"
/*
* Define test cursor to check that mask fg and bg color settings are working.
*
* . configure -cursor {center_ptr green red}
* . configure -cursor {@myarrow.xbm myarrow-mask.xbm green red}
* . configure -cursor {myarrow green red}
*/
/*#define DEFINE_MYARROW_CURSOR*/
#ifdef DEFINE_MYARROW_CURSOR
#define CURSOR_MYARROW_DATA \
"#define myarrow_width 16\n" \
"#define myarrow_height 16\n" \
"#define myarrow_x_hot 7\n" \
"#define myarrow_y_hot 0\n" \
"static unsigned char myarrow_bits[] = {\n" \
" 0x7f, 0xff, 0xbf, 0xfe, 0xdf, 0xfd, 0xef, 0xfb, 0xf7, 0xf7, 0xfb, 0xef,\n" \
" 0xfd, 0xdf, 0xfe, 0xbf, 0x80, 0x00, 0xbf, 0xfe, 0xbf, 0xfe, 0xbf, 0xfe,\n" \
" 0xbf, 0xfe, 0xbf, 0xfe, 0xbf, 0xfe, 0x3f, 0xfe};"
#define CURSOR_MYARROW_MASK \
"#define myarrow-mask_width 16\n" \
"#define myarrow-mask_height 16\n" \
"#define myarrow-mask_x_hot 7\n" \
"#define myarrow-mask_y_hot 0\n" \
"static unsigned char myarrow-mask_bits[] = {\n" \
" 0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,\n" \
" 0xfe, 0x3f, 0xff, 0x7f, 0xff, 0xff, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,\n" \
" 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01};"
#endif /* DEFINE_MYARROW_CURSOR */
static const struct TkCursorName {
const char *name;
const char *data;
char *mask;
} tkCursorNames[] = {
{"none", CURSOR_NONE_DATA, NULL},
#ifdef DEFINE_MYARROW_CURSOR
{"myarrow", CURSOR_MYARROW_DATA, CURSOR_MYARROW_MASK},
#endif /* DEFINE_MYARROW_CURSOR */
{NULL, NULL, NULL}
};
/*
* Font to use for cursors:
*/
#ifndef CURSORFONT
#define CURSORFONT "cursor"
#endif
static Cursor CreateCursorFromTableOrFile(Tcl_Interp *interp,
Tk_Window tkwin, int argc, const char **argv,
const struct TkCursorName *tkCursorPtr);
/*
*----------------------------------------------------------------------
*
* TkGetCursorByName --
*
* Retrieve a cursor by name. Parse the cursor name into fields and
* create a cursor, either from the standard cursor font or from bitmap
* files.
*
* Results:
* Returns a new cursor, or NULL on errors.
*
* Side effects:
* Allocates a new cursor.
*
*----------------------------------------------------------------------
*/
TkCursor *
TkGetCursorByName(
Tcl_Interp *interp, /* Interpreter to use for error reporting. */
Tk_Window tkwin, /* Window in which cursor will be used. */
Tk_Uid string) /* Description of cursor. See manual entry for
* details on legal syntax. */
{
TkUnixCursor *cursorPtr = NULL;
Cursor cursor = None;
int argc;
const char **argv = NULL;
Display *display = Tk_Display(tkwin);
int inTkTable = 0;
const struct TkCursorName *tkCursorPtr = NULL;
if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
return NULL;
}
if (argc == 0) {
goto badString;
}
/*
* Check Tk specific table of cursor names. The cursor names don't overlap
* with cursors defined in the X table so search order does not matter.
*/
if (argv[0][0] != '@') {
for (tkCursorPtr = tkCursorNames; ; tkCursorPtr++) {
if (tkCursorPtr->name == NULL) {
tkCursorPtr = NULL;
break;
}
if ((tkCursorPtr->name[0] == argv[0][0]) &&
(strcmp(tkCursorPtr->name, argv[0]) == 0)) {
inTkTable = 1;
break;
}
}
}
if ((argv[0][0] != '@') && !inTkTable) {
XColor fg, bg;
unsigned int maskIndex;
register const struct CursorName *namePtr;
TkDisplay *dispPtr;
/*
* The cursor is to come from the standard cursor font. If one arg, it
* is cursor name (use black and white for fg and bg). If two args,
* they are name and fg color (ignore mask). If three args, they are
* name, fg, bg. Some of the code below is stolen from the
* XCreateFontCursor Xlib function.
*/
if (argc > 3) {
goto badString;
}
for (namePtr = cursorNames; ; namePtr++) {
if (namePtr->name == NULL) {
goto badString;
}
if ((namePtr->name[0] == argv[0][0])
&& (strcmp(namePtr->name, argv[0]) == 0)) {
break;
}
}
maskIndex = namePtr->shape + 1;
if (argc == 1) {
fg.red = fg.green = fg.blue = 0;
bg.red = bg.green = bg.blue = 65535;
} else {
if (TkParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid color name \"%s\"", argv[1]));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
goto cleanup;
}
if (argc == 2) {
bg.red = bg.green = bg.blue = 0;
maskIndex = namePtr->shape;
} else if (TkParseColor(display, Tk_Colormap(tkwin), argv[2],
&bg) == 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid color name \"%s\"", argv[2]));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
goto cleanup;
}
}
dispPtr = ((TkWindow *) tkwin)->dispPtr;
if (dispPtr->cursorFont == None) {
dispPtr->cursorFont = XLoadFont(display, CURSORFONT);
if (dispPtr->cursorFont == None) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"couldn't load cursor font", -1));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "FONT", NULL);
goto cleanup;
}
}
cursor = XCreateGlyphCursor(display, dispPtr->cursorFont,
dispPtr->cursorFont, namePtr->shape, maskIndex,
&fg, &bg);
} else {
/*
* Prevent file system access in safe interpreters.
*/
if (!inTkTable && Tcl_IsSafe(interp)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"can't get cursor from a file in a safe interpreter",
-1));
Tcl_SetErrorCode(interp, "TK", "SAFE", "CURSOR_FILE", NULL);
cursorPtr = NULL;
goto cleanup;
}
/*
* If the cursor is to be created from bitmap files, then there should
* be either two elements in the list (source, color) or four (source
* mask fg bg). A cursor defined in the Tk table accepts the same
* arguments as an X cursor.
*/
if (inTkTable && (argc != 1) && (argc != 2) && (argc != 3)) {
goto badString;
}
if (!inTkTable && (argc != 2) && (argc != 4)) {
goto badString;
}
cursor = CreateCursorFromTableOrFile(interp, tkwin, argc, argv,
tkCursorPtr);
}
if (cursor != None) {
cursorPtr = ckalloc(sizeof(TkUnixCursor));
cursorPtr->info.cursor = (Tk_Cursor) cursor;
cursorPtr->display = display;
}
cleanup:
if (argv != NULL) {
ckfree(argv);
}
return (TkCursor *) cursorPtr;
badString:
if (argv) {
ckfree(argv);
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad cursor spec \"%s\"", string));
Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", NULL);
return NULL;
}
/*
*----------------------------------------------------------------------
*
* CreateCursorFromTableOrFile --
*
* Create a cursor defined in a file or the Tk static cursor table. A
* cursor defined in a file starts with the '@' character. This method
* assumes that the number of arguments in argv has been validated
* already.
*
* Results:
* Returns a new cursor, or None on error.
*
* Side effects:
* Allocates a new X cursor.
*
*----------------------------------------------------------------------
*/
static Cursor
CreateCursorFromTableOrFile(
Tcl_Interp *interp, /* Interpreter to use for error reporting. */
Tk_Window tkwin, /* Window in which cursor will be used. */
int argc,
const char **argv, /* Cursor spec parsed into elements. */
const struct TkCursorName *tkCursorPtr)
/* Non-NULL when cursor is defined in Tk
* table. */
{
Cursor cursor = None;
int width, height, maskWidth, maskHeight;
int xHot = -1, yHot = -1;
int dummy1, dummy2;
XColor fg, bg;
const char *fgColor;
const char *bgColor;
int inTkTable = (tkCursorPtr != NULL);
Display *display = Tk_Display(tkwin);
Drawable drawable = RootWindowOfScreen(Tk_Screen(tkwin));
Pixmap source = None;
Pixmap mask = None;
/*
* A cursor defined in a file accepts either 2 or 4 arguments.
*
* {srcfile fg}
* {srcfile maskfile fg bg}
*
* A cursor defined in the Tk table accepts 1, 2, or 3 arguments.
*
* {tkcursorname}
* {tkcursorname fg}
* {tkcursorname fg bg}
*/
if (inTkTable) {
/*
* This logic is like TkReadBitmapFile().
*/
char *data;
data = TkGetBitmapData(NULL, tkCursorPtr->data, NULL,
&width, &height, &xHot, &yHot);
if (data == NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"error reading bitmap data for \"%s\"", argv[0]));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_DATA", NULL);
goto cleanup;
}
source = XCreateBitmapFromData(display, drawable, data, width,height);
ckfree(data);
} else {
if (TkReadBitmapFile(display, drawable, &argv[0][1],
(unsigned *) &width, (unsigned *) &height,
&source, &xHot, &yHot) != BitmapSuccess) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"cleanup reading bitmap file \"%s\"", &argv[0][1]));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_FILE", NULL);
goto cleanup;
}
}
if ((xHot < 0) || (yHot < 0) || (xHot >= width) || (yHot >= height)) {
if (inTkTable) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad hot spot in bitmap data for \"%s\"", argv[0]));
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad hot spot in bitmap file \"%s\"", &argv[0][1]));
}
Tcl_SetErrorCode(interp, "TK", "CURSOR", "HOTSPOT", NULL);
goto cleanup;
}
/*
* Parse color names from optional fg and bg arguments
*/
if (argc == 1) {
fg.red = fg.green = fg.blue = 0;
bg.red = bg.green = bg.blue = 65535;
} else if (argc == 2) {
fgColor = argv[1];
if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid color name \"%s\"", fgColor));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
goto cleanup;
}
if (inTkTable) {
bg.red = bg.green = bg.blue = 0;
} else {
bg = fg;
}
} else {
/* 3 or 4 arguments */
if (inTkTable) {
fgColor = argv[1];
bgColor = argv[2];
} else {
fgColor = argv[2];
bgColor = argv[3];
}
if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid color name \"%s\"", fgColor));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
goto cleanup;
}
if (TkParseColor(display, Tk_Colormap(tkwin), bgColor, &bg) == 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid color name \"%s\"", bgColor));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
goto cleanup;
}
}
/*
* If there is no mask data, then create the cursor now.
*/
if ((!inTkTable && (argc == 2)) || (inTkTable && tkCursorPtr->mask == NULL)) {
cursor = XCreatePixmapCursor(display, source, source,
&fg, &fg, (unsigned) xHot, (unsigned) yHot);
goto cleanup;
}
/*
* Parse bitmap mask data and create cursor with fg and bg colors.
*/
if (inTkTable) {
/*
* This logic is like TkReadBitmapFile().
*/
char *data;
data = TkGetBitmapData(NULL, tkCursorPtr->mask, NULL,
&maskWidth, &maskHeight, &dummy1, &dummy2);
if (data == NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"error reading bitmap mask data for \"%s\"", argv[0]));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_DATA", NULL);
goto cleanup;
}
mask = XCreateBitmapFromData(display, drawable, data, maskWidth,
maskHeight);
ckfree(data);
} else {
if (TkReadBitmapFile(display, drawable, argv[1],
(unsigned int *) &maskWidth, (unsigned int *) &maskHeight,
&mask, &dummy1, &dummy2) != BitmapSuccess) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"cleanup reading bitmap file \"%s\"", argv[1]));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_FILE", NULL);
goto cleanup;
}
}
if ((maskWidth != width) || (maskHeight != height)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"source and mask bitmaps have different sizes", -1));
Tcl_SetErrorCode(interp, "TK", "CURSOR", "SIZE_MATCH", NULL);
goto cleanup;
}
cursor = XCreatePixmapCursor(display, source, mask,
&fg, &bg, (unsigned) xHot, (unsigned) yHot);
cleanup:
if (source != None) {
Tk_FreePixmap(display, source);
}
if (mask != None) {
Tk_FreePixmap(display, mask);
}
return cursor;
}
/*
*----------------------------------------------------------------------
*
* TkCreateCursorFromData --
*
* Creates a cursor from the source and mask bits.
*
* Results:
* Returns a new cursor, or NULL on errors.
*
* Side effects:
* Allocates a new cursor.
*
*----------------------------------------------------------------------
*/
TkCursor *
TkCreateCursorFromData(
Tk_Window tkwin, /* Window in which cursor will be used. */
const char *source, /* Bitmap data for cursor shape. */
const char *mask, /* Bitmap data for cursor mask. */
int width, int height, /* Dimensions of cursor. */
int xHot, int yHot, /* Location of hot-spot in cursor. */
XColor fgColor, /* Foreground color for cursor. */
XColor bgColor) /* Background color for cursor. */
{
Cursor cursor;
Pixmap sourcePixmap, maskPixmap;
TkUnixCursor *cursorPtr = NULL;
Display *display = Tk_Display(tkwin);
sourcePixmap = XCreateBitmapFromData(display,
RootWindowOfScreen(Tk_Screen(tkwin)), source, (unsigned) width,
(unsigned) height);
maskPixmap = XCreateBitmapFromData(display,
RootWindowOfScreen(Tk_Screen(tkwin)), mask, (unsigned) width,
(unsigned) height);
cursor = XCreatePixmapCursor(display, sourcePixmap,
maskPixmap, &fgColor, &bgColor, (unsigned) xHot, (unsigned) yHot);
Tk_FreePixmap(display, sourcePixmap);
Tk_FreePixmap(display, maskPixmap);
if (cursor != None) {
cursorPtr = ckalloc(sizeof(TkUnixCursor));
cursorPtr->info.cursor = (Tk_Cursor) cursor;
cursorPtr->display = display;
}
return (TkCursor *) cursorPtr;
}
/*
*----------------------------------------------------------------------
*
* TkpFreeCursor --
*
* This function is called to release a cursor allocated by
* TkGetCursorByName.
*
* Results:
* None.
*
* Side effects:
* The cursor data structure is deallocated.
*
*----------------------------------------------------------------------
*/
void
TkpFreeCursor(
TkCursor *cursorPtr)
{
TkUnixCursor *unixCursorPtr = (TkUnixCursor *) cursorPtr;
XFreeCursor(unixCursorPtr->display, (Cursor) unixCursorPtr->info.cursor);
Tk_FreeXId(unixCursorPtr->display, (XID) unixCursorPtr->info.cursor);
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

533
unix/tkUnixDefault.h Normal file
View File

@@ -0,0 +1,533 @@
/*
* tkUnixDefault.h --
*
* This file defines the defaults for all options for all of
* the Tk widgets.
*
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKUNIXDEFAULT
#define _TKUNIXDEFAULT
/*
* The definitions below provide symbolic names for the default colors.
* NORMAL_BG - Normal background color.
* ACTIVE_BG - Background color when widget is active.
* SELECT_BG - Background color for selected text.
* TROUGH - Background color for troughs in scales and scrollbars.
* INDICATOR - Color for indicator when button is selected.
* DISABLED - Foreground color when widget is disabled.
*/
#define BLACK "#000000"
#define WHITE "#ffffff"
#define NORMAL_BG "#d9d9d9"
#define ACTIVE_BG "#ececec"
#define SELECT_BG "#c3c3c3"
#define TROUGH "#b3b3b3"
#define CHECK_INDICATOR WHITE
#define MENU_INDICATOR BLACK
#define DISABLED "#a3a3a3"
/*
* Defaults for labels, buttons, checkbuttons, and radiobuttons:
*/
#define DEF_BUTTON_ANCHOR "center"
#define DEF_BUTTON_ACTIVE_BG_COLOR ACTIVE_BG
#define DEF_BUTTON_ACTIVE_BG_MONO BLACK
#define DEF_BUTTON_ACTIVE_FG_COLOR BLACK
#define DEF_CHKRAD_ACTIVE_FG_COLOR DEF_BUTTON_ACTIVE_FG_COLOR
#define DEF_BUTTON_ACTIVE_FG_MONO WHITE
#define DEF_BUTTON_BG_COLOR NORMAL_BG
#define DEF_BUTTON_BG_MONO WHITE
#define DEF_BUTTON_BITMAP ""
#define DEF_BUTTON_BORDER_WIDTH "1"
#define DEF_BUTTON_CURSOR ""
#define DEF_BUTTON_COMPOUND "none"
#define DEF_BUTTON_COMMAND ""
#define DEF_BUTTON_DEFAULT "disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO ""
#define DEF_BUTTON_FG BLACK
#define DEF_CHKRAD_FG DEF_BUTTON_FG
#define DEF_BUTTON_FONT "TkDefaultFont"
#define DEF_BUTTON_HEIGHT "0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT BLACK
#define DEF_LABEL_HIGHLIGHT_WIDTH "0"
#define DEF_BUTTON_HIGHLIGHT_WIDTH "1"
#define DEF_BUTTON_IMAGE ((char *) NULL)
#define DEF_BUTTON_INDICATOR "1"
#define DEF_BUTTON_JUSTIFY "center"
#define DEF_BUTTON_OFF_VALUE "0"
#define DEF_BUTTON_ON_VALUE "1"
#define DEF_BUTTON_TRISTATE_VALUE ""
#define DEF_BUTTON_OVER_RELIEF ""
#define DEF_BUTTON_PADX "3m"
#define DEF_LABCHKRAD_PADX "1"
#define DEF_BUTTON_PADY "1m"
#define DEF_LABCHKRAD_PADY "1"
#define DEF_BUTTON_RELIEF "raised"
#define DEF_LABCHKRAD_RELIEF "flat"
#define DEF_BUTTON_REPEAT_DELAY "0"
#define DEF_BUTTON_REPEAT_INTERVAL "0"
#define DEF_BUTTON_SELECT_COLOR CHECK_INDICATOR
#define DEF_BUTTON_SELECT_MONO BLACK
#define DEF_BUTTON_SELECT_IMAGE ((char *) NULL)
#define DEF_BUTTON_STATE "normal"
#define DEF_LABEL_TAKE_FOCUS "0"
#define DEF_BUTTON_TAKE_FOCUS ((char *) NULL)
#define DEF_BUTTON_TEXT ""
#define DEF_BUTTON_TEXT_VARIABLE ""
#define DEF_BUTTON_UNDERLINE "-1"
#define DEF_BUTTON_VALUE ""
#define DEF_BUTTON_WIDTH "0"
#define DEF_BUTTON_WRAP_LENGTH "0"
#define DEF_RADIOBUTTON_VARIABLE "selectedButton"
#define DEF_CHECKBUTTON_VARIABLE ""
/*
* Defaults for canvases:
*/
#define DEF_CANVAS_BG_COLOR NORMAL_BG
#define DEF_CANVAS_BG_MONO WHITE
#define DEF_CANVAS_BORDER_WIDTH "0"
#define DEF_CANVAS_CLOSE_ENOUGH "1"
#define DEF_CANVAS_CONFINE "1"
#define DEF_CANVAS_CURSOR ""
#define DEF_CANVAS_HEIGHT "7c"
#define DEF_CANVAS_HIGHLIGHT_BG NORMAL_BG
#define DEF_CANVAS_HIGHLIGHT BLACK
#define DEF_CANVAS_HIGHLIGHT_WIDTH "1"
#define DEF_CANVAS_INSERT_BG BLACK
#define DEF_CANVAS_INSERT_BD_COLOR "0"
#define DEF_CANVAS_INSERT_BD_MONO "0"
#define DEF_CANVAS_INSERT_OFF_TIME "300"
#define DEF_CANVAS_INSERT_ON_TIME "600"
#define DEF_CANVAS_INSERT_WIDTH "2"
#define DEF_CANVAS_RELIEF "flat"
#define DEF_CANVAS_SCROLL_REGION ""
#define DEF_CANVAS_SELECT_COLOR SELECT_BG
#define DEF_CANVAS_SELECT_MONO BLACK
#define DEF_CANVAS_SELECT_BD_COLOR "1"
#define DEF_CANVAS_SELECT_BD_MONO "0"
#define DEF_CANVAS_SELECT_FG_COLOR BLACK
#define DEF_CANVAS_SELECT_FG_MONO WHITE
#define DEF_CANVAS_TAKE_FOCUS ((char *) NULL)
#define DEF_CANVAS_WIDTH "10c"
#define DEF_CANVAS_X_SCROLL_CMD ""
#define DEF_CANVAS_X_SCROLL_INCREMENT "0"
#define DEF_CANVAS_Y_SCROLL_CMD ""
#define DEF_CANVAS_Y_SCROLL_INCREMENT "0"
/*
* Defaults for entries:
*/
#define DEF_ENTRY_BG_COLOR WHITE
#define DEF_ENTRY_BG_MONO WHITE
#define DEF_ENTRY_BORDER_WIDTH "1"
#define DEF_ENTRY_CURSOR "xterm"
#define DEF_ENTRY_DISABLED_BG_COLOR NORMAL_BG
#define DEF_ENTRY_DISABLED_BG_MONO WHITE
#define DEF_ENTRY_DISABLED_FG DISABLED
#define DEF_ENTRY_EXPORT_SELECTION "1"
#define DEF_ENTRY_FONT "TkTextFont"
#define DEF_ENTRY_FG BLACK
#define DEF_ENTRY_HIGHLIGHT_BG NORMAL_BG
#define DEF_ENTRY_HIGHLIGHT BLACK
#define DEF_ENTRY_HIGHLIGHT_WIDTH "1"
#define DEF_ENTRY_INSERT_BG BLACK
#define DEF_ENTRY_INSERT_BD_COLOR "0"
#define DEF_ENTRY_INSERT_BD_MONO "0"
#define DEF_ENTRY_INSERT_OFF_TIME "300"
#define DEF_ENTRY_INSERT_ON_TIME "600"
#define DEF_ENTRY_INSERT_WIDTH "2"
#define DEF_ENTRY_JUSTIFY "left"
#define DEF_ENTRY_READONLY_BG_COLOR NORMAL_BG
#define DEF_ENTRY_READONLY_BG_MONO WHITE
#define DEF_ENTRY_RELIEF "sunken"
#define DEF_ENTRY_SCROLL_COMMAND ""
#define DEF_ENTRY_SELECT_COLOR SELECT_BG
#define DEF_ENTRY_SELECT_MONO BLACK
#define DEF_ENTRY_SELECT_BD_COLOR "0"
#define DEF_ENTRY_SELECT_BD_MONO "0"
#define DEF_ENTRY_SELECT_FG_COLOR BLACK
#define DEF_ENTRY_SELECT_FG_MONO WHITE
#define DEF_ENTRY_SHOW ((char *) NULL)
#define DEF_ENTRY_STATE "normal"
#define DEF_ENTRY_TAKE_FOCUS ((char *) NULL)
#define DEF_ENTRY_TEXT_VARIABLE ""
#define DEF_ENTRY_WIDTH "20"
/*
* Defaults for frames:
*/
#define DEF_FRAME_BG_COLOR NORMAL_BG
#define DEF_FRAME_BG_MONO WHITE
#define DEF_FRAME_BORDER_WIDTH "0"
#define DEF_FRAME_CLASS "Frame"
#define DEF_FRAME_COLORMAP ""
#define DEF_FRAME_CONTAINER "0"
#define DEF_FRAME_CURSOR ""
#define DEF_FRAME_HEIGHT "0"
#define DEF_FRAME_HIGHLIGHT_BG NORMAL_BG
#define DEF_FRAME_HIGHLIGHT BLACK
#define DEF_FRAME_HIGHLIGHT_WIDTH "0"
#define DEF_FRAME_LABEL ""
#define DEF_FRAME_PADX "0"
#define DEF_FRAME_PADY "0"
#define DEF_FRAME_RELIEF "flat"
#define DEF_FRAME_TAKE_FOCUS "0"
#define DEF_FRAME_VISUAL ""
#define DEF_FRAME_WIDTH "0"
/*
* Defaults for labelframes:
*/
#define DEF_LABELFRAME_BORDER_WIDTH "2"
#define DEF_LABELFRAME_CLASS "Labelframe"
#define DEF_LABELFRAME_RELIEF "groove"
#define DEF_LABELFRAME_FG BLACK
#define DEF_LABELFRAME_FONT "TkDefaultFont"
#define DEF_LABELFRAME_TEXT ""
#define DEF_LABELFRAME_LABELANCHOR "nw"
/*
* Defaults for listboxes:
*/
#define DEF_LISTBOX_ACTIVE_STYLE "dotbox"
#define DEF_LISTBOX_BG_COLOR WHITE
#define DEF_LISTBOX_BG_MONO WHITE
#define DEF_LISTBOX_BORDER_WIDTH "1"
#define DEF_LISTBOX_CURSOR ""
#define DEF_LISTBOX_DISABLED_FG DISABLED
#define DEF_LISTBOX_EXPORT_SELECTION "1"
#define DEF_LISTBOX_FONT "TkDefaultFont"
#define DEF_LISTBOX_FG BLACK
#define DEF_LISTBOX_HEIGHT "10"
#define DEF_LISTBOX_HIGHLIGHT_BG NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT BLACK
#define DEF_LISTBOX_HIGHLIGHT_WIDTH "1"
#define DEF_LISTBOX_JUSTIFY "left"
#define DEF_LISTBOX_RELIEF "sunken"
#define DEF_LISTBOX_SCROLL_COMMAND ""
#define DEF_LISTBOX_LIST_VARIABLE ""
#define DEF_LISTBOX_SELECT_COLOR SELECT_BG
#define DEF_LISTBOX_SELECT_MONO BLACK
#define DEF_LISTBOX_SELECT_BD "0"
#define DEF_LISTBOX_SELECT_FG_COLOR BLACK
#define DEF_LISTBOX_SELECT_FG_MONO WHITE
#define DEF_LISTBOX_SELECT_MODE "browse"
#define DEF_LISTBOX_SET_GRID "0"
#define DEF_LISTBOX_STATE "normal"
#define DEF_LISTBOX_TAKE_FOCUS ((char *) NULL)
#define DEF_LISTBOX_WIDTH "20"
/*
* Defaults for individual entries of menus:
*/
#define DEF_MENU_ENTRY_ACTIVE_BG ((char *) NULL)
#define DEF_MENU_ENTRY_ACTIVE_FG ((char *) NULL)
#define DEF_MENU_ENTRY_ACCELERATOR ((char *) NULL)
#define DEF_MENU_ENTRY_BG ((char *) NULL)
#define DEF_MENU_ENTRY_BITMAP None
#define DEF_MENU_ENTRY_COLUMN_BREAK "0"
#define DEF_MENU_ENTRY_COMMAND ((char *) NULL)
#define DEF_MENU_ENTRY_COMPOUND "none"
#define DEF_MENU_ENTRY_FG ((char *) NULL)
#define DEF_MENU_ENTRY_FONT ((char *) NULL)
#define DEF_MENU_ENTRY_HIDE_MARGIN "0"
#define DEF_MENU_ENTRY_IMAGE ((char *) NULL)
#define DEF_MENU_ENTRY_INDICATOR "1"
#define DEF_MENU_ENTRY_LABEL ((char *) NULL)
#define DEF_MENU_ENTRY_MENU ((char *) NULL)
#define DEF_MENU_ENTRY_OFF_VALUE "0"
#define DEF_MENU_ENTRY_ON_VALUE "1"
#define DEF_MENU_ENTRY_SELECT_IMAGE ((char *) NULL)
#define DEF_MENU_ENTRY_STATE "normal"
#define DEF_MENU_ENTRY_VALUE ((char *) NULL)
#define DEF_MENU_ENTRY_CHECK_VARIABLE ((char *) NULL)
#define DEF_MENU_ENTRY_RADIO_VARIABLE "selectedButton"
#define DEF_MENU_ENTRY_SELECT ((char *) NULL)
#define DEF_MENU_ENTRY_UNDERLINE "-1"
/*
* Defaults for menus overall:
*/
#define DEF_MENU_ACTIVE_BG_COLOR ACTIVE_BG
#define DEF_MENU_ACTIVE_BG_MONO BLACK
#define DEF_MENU_ACTIVE_BORDER_WIDTH "1"
#define DEF_MENU_ACTIVE_FG_COLOR BLACK
#define DEF_MENU_ACTIVE_FG_MONO WHITE
#define DEF_MENU_BG_COLOR NORMAL_BG
#define DEF_MENU_BG_MONO WHITE
#define DEF_MENU_BORDER_WIDTH "1"
#define DEF_MENU_CURSOR "arrow"
#define DEF_MENU_DISABLED_FG_COLOR DISABLED
#define DEF_MENU_DISABLED_FG_MONO ""
#define DEF_MENU_FONT "TkMenuFont"
#define DEF_MENU_FG BLACK
#define DEF_MENU_POST_COMMAND ""
#define DEF_MENU_RELIEF "raised"
#define DEF_MENU_SELECT_COLOR MENU_INDICATOR
#define DEF_MENU_SELECT_MONO BLACK
#define DEF_MENU_TAKE_FOCUS "0"
#define DEF_MENU_TEAROFF "1"
#define DEF_MENU_TEAROFF_CMD ((char *) NULL)
#define DEF_MENU_TITLE ""
#define DEF_MENU_TYPE "normal"
/*
* Defaults for menubuttons:
*/
#define DEF_MENUBUTTON_ANCHOR "center"
#define DEF_MENUBUTTON_ACTIVE_BG_COLOR ACTIVE_BG
#define DEF_MENUBUTTON_ACTIVE_BG_MONO BLACK
#define DEF_MENUBUTTON_ACTIVE_FG_COLOR BLACK
#define DEF_MENUBUTTON_ACTIVE_FG_MONO WHITE
#define DEF_MENUBUTTON_BG_COLOR NORMAL_BG
#define DEF_MENUBUTTON_BG_MONO WHITE
#define DEF_MENUBUTTON_BITMAP ""
#define DEF_MENUBUTTON_BORDER_WIDTH "1"
#define DEF_MENUBUTTON_CURSOR ""
#define DEF_MENUBUTTON_DIRECTION "below"
#define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED
#define DEF_MENUBUTTON_DISABLED_FG_MONO ""
#define DEF_MENUBUTTON_FONT "TkDefaultFont"
#define DEF_MENUBUTTON_FG BLACK
#define DEF_MENUBUTTON_HEIGHT "0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT BLACK
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH "0"
#define DEF_MENUBUTTON_IMAGE ((char *) NULL)
#define DEF_MENUBUTTON_INDICATOR "0"
#define DEF_MENUBUTTON_JUSTIFY "center"
#define DEF_MENUBUTTON_MENU ""
#define DEF_MENUBUTTON_PADX "4p"
#define DEF_MENUBUTTON_PADY "3p"
#define DEF_MENUBUTTON_RELIEF "flat"
#define DEF_MENUBUTTON_STATE "normal"
#define DEF_MENUBUTTON_TAKE_FOCUS "0"
#define DEF_MENUBUTTON_TEXT ""
#define DEF_MENUBUTTON_TEXT_VARIABLE ""
#define DEF_MENUBUTTON_UNDERLINE "-1"
#define DEF_MENUBUTTON_WIDTH "0"
#define DEF_MENUBUTTON_WRAP_LENGTH "0"
/*
* Defaults for messages:
*/
#define DEF_MESSAGE_ANCHOR "center"
#define DEF_MESSAGE_ASPECT "150"
#define DEF_MESSAGE_BG_COLOR NORMAL_BG
#define DEF_MESSAGE_BG_MONO WHITE
#define DEF_MESSAGE_BORDER_WIDTH "1"
#define DEF_MESSAGE_CURSOR ""
#define DEF_MESSAGE_FG BLACK
#define DEF_MESSAGE_FONT "TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT BLACK
#define DEF_MESSAGE_HIGHLIGHT_WIDTH "0"
#define DEF_MESSAGE_JUSTIFY "left"
#define DEF_MESSAGE_PADX "-1"
#define DEF_MESSAGE_PADY "-1"
#define DEF_MESSAGE_RELIEF "flat"
#define DEF_MESSAGE_TAKE_FOCUS "0"
#define DEF_MESSAGE_TEXT ""
#define DEF_MESSAGE_TEXT_VARIABLE ""
#define DEF_MESSAGE_WIDTH "0"
/*
* Defaults for panedwindows
*/
#define DEF_PANEDWINDOW_BG_COLOR NORMAL_BG
#define DEF_PANEDWINDOW_BG_MONO WHITE
#define DEF_PANEDWINDOW_BORDERWIDTH "1"
#define DEF_PANEDWINDOW_CURSOR ""
#define DEF_PANEDWINDOW_HANDLEPAD "8"
#define DEF_PANEDWINDOW_HANDLESIZE "8"
#define DEF_PANEDWINDOW_HEIGHT ""
#define DEF_PANEDWINDOW_OPAQUERESIZE "1"
#define DEF_PANEDWINDOW_ORIENT "horizontal"
#define DEF_PANEDWINDOW_PROXYBORDER "2"
#define DEF_PANEDWINDOW_RELIEF "flat"
#define DEF_PANEDWINDOW_SASHCURSOR ""
#define DEF_PANEDWINDOW_SASHPAD "0"
#define DEF_PANEDWINDOW_SASHRELIEF "flat"
#define DEF_PANEDWINDOW_SASHWIDTH "3"
#define DEF_PANEDWINDOW_SHOWHANDLE "0"
#define DEF_PANEDWINDOW_WIDTH ""
/*
* Defaults for panedwindow panes
*/
#define DEF_PANEDWINDOW_PANE_AFTER ""
#define DEF_PANEDWINDOW_PANE_BEFORE ""
#define DEF_PANEDWINDOW_PANE_HEIGHT ""
#define DEF_PANEDWINDOW_PANE_MINSIZE "0"
#define DEF_PANEDWINDOW_PANE_PADX "0"
#define DEF_PANEDWINDOW_PANE_PADY "0"
#define DEF_PANEDWINDOW_PANE_STICKY "nsew"
#define DEF_PANEDWINDOW_PANE_WIDTH ""
#define DEF_PANEDWINDOW_PANE_HIDE "0"
#define DEF_PANEDWINDOW_PANE_STRETCH "last"
/*
* Defaults for scales:
*/
#define DEF_SCALE_ACTIVE_BG_COLOR ACTIVE_BG
#define DEF_SCALE_ACTIVE_BG_MONO BLACK
#define DEF_SCALE_BG_COLOR NORMAL_BG
#define DEF_SCALE_BG_MONO WHITE
#define DEF_SCALE_BIG_INCREMENT "0"
#define DEF_SCALE_BORDER_WIDTH "1"
#define DEF_SCALE_COMMAND ""
#define DEF_SCALE_CURSOR ""
#define DEF_SCALE_DIGITS "0"
#define DEF_SCALE_FONT "TkDefaultFont"
#define DEF_SCALE_FG_COLOR BLACK
#define DEF_SCALE_FG_MONO BLACK
#define DEF_SCALE_FROM "0"
#define DEF_SCALE_HIGHLIGHT_BG_COLOR DEF_SCALE_BG_COLOR
#define DEF_SCALE_HIGHLIGHT_BG_MONO DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT BLACK
#define DEF_SCALE_HIGHLIGHT_WIDTH "1"
#define DEF_SCALE_LABEL ""
#define DEF_SCALE_LENGTH "100"
#define DEF_SCALE_ORIENT "vertical"
#define DEF_SCALE_RELIEF "flat"
#define DEF_SCALE_REPEAT_DELAY "300"
#define DEF_SCALE_REPEAT_INTERVAL "100"
#define DEF_SCALE_RESOLUTION "1"
#define DEF_SCALE_TROUGH_COLOR TROUGH
#define DEF_SCALE_TROUGH_MONO WHITE
#define DEF_SCALE_SHOW_VALUE "1"
#define DEF_SCALE_SLIDER_LENGTH "30"
#define DEF_SCALE_SLIDER_RELIEF "raised"
#define DEF_SCALE_STATE "normal"
#define DEF_SCALE_TAKE_FOCUS ((char *) NULL)
#define DEF_SCALE_TICK_INTERVAL "0"
#define DEF_SCALE_TO "100"
#define DEF_SCALE_VARIABLE ""
#define DEF_SCALE_WIDTH "15"
/*
* Defaults for scrollbars:
*/
#define DEF_SCROLLBAR_ACTIVE_BG_COLOR ACTIVE_BG
#define DEF_SCROLLBAR_ACTIVE_BG_MONO BLACK
#define DEF_SCROLLBAR_ACTIVE_RELIEF "raised"
#define DEF_SCROLLBAR_BG_COLOR NORMAL_BG
#define DEF_SCROLLBAR_BG_MONO WHITE
#define DEF_SCROLLBAR_BORDER_WIDTH "1"
#define DEF_SCROLLBAR_COMMAND ""
#define DEF_SCROLLBAR_CURSOR ""
#define DEF_SCROLLBAR_EL_BORDER_WIDTH "-1"
#define DEF_SCROLLBAR_HIGHLIGHT_BG NORMAL_BG
#define DEF_SCROLLBAR_HIGHLIGHT BLACK
#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH "0"
#define DEF_SCROLLBAR_JUMP "0"
#define DEF_SCROLLBAR_ORIENT "vertical"
#define DEF_SCROLLBAR_RELIEF "sunken"
#define DEF_SCROLLBAR_REPEAT_DELAY "300"
#define DEF_SCROLLBAR_REPEAT_INTERVAL "100"
#define DEF_SCROLLBAR_TAKE_FOCUS ((char *) NULL)
#define DEF_SCROLLBAR_TROUGH_COLOR TROUGH
#define DEF_SCROLLBAR_TROUGH_MONO WHITE
#define DEF_SCROLLBAR_WIDTH "11"
/*
* Defaults for texts:
*/
#define DEF_TEXT_AUTO_SEPARATORS "1"
#define DEF_TEXT_BG_COLOR WHITE
#define DEF_TEXT_BG_MONO WHITE
#define DEF_TEXT_BLOCK_CURSOR "0"
#define DEF_TEXT_BORDER_WIDTH "1"
#define DEF_TEXT_CURSOR "xterm"
#define DEF_TEXT_FG BLACK
#define DEF_TEXT_EXPORT_SELECTION "1"
#define DEF_TEXT_FONT "TkFixedFont"
#define DEF_TEXT_HEIGHT "24"
#define DEF_TEXT_HIGHLIGHT_BG NORMAL_BG
#define DEF_TEXT_HIGHLIGHT BLACK
#define DEF_TEXT_HIGHLIGHT_WIDTH "1"
#define DEF_TEXT_INSERT_BG BLACK
#define DEF_TEXT_INSERT_BD_COLOR "0"
#define DEF_TEXT_INSERT_BD_MONO "0"
#define DEF_TEXT_INSERT_OFF_TIME "300"
#define DEF_TEXT_INSERT_ON_TIME "600"
#define DEF_TEXT_INSERT_UNFOCUSSED "none"
#define DEF_TEXT_INSERT_WIDTH "2"
#define DEF_TEXT_MAX_UNDO "0"
#define DEF_TEXT_PADX "1"
#define DEF_TEXT_PADY "1"
#define DEF_TEXT_RELIEF "sunken"
#define DEF_TEXT_INACTIVE_SELECT_COLOR SELECT_BG
#define DEF_TEXT_SELECT_COLOR SELECT_BG
#define DEF_TEXT_SELECT_MONO BLACK
#define DEF_TEXT_SELECT_BD_COLOR "0"
#define DEF_TEXT_SELECT_BD_MONO "0"
#define DEF_TEXT_SELECT_FG_COLOR BLACK
#define DEF_TEXT_SELECT_FG_MONO WHITE
#define DEF_TEXT_SELECT_RELIEF "raised"
#define DEF_TEXT_SET_GRID "0"
#define DEF_TEXT_SPACING1 "0"
#define DEF_TEXT_SPACING2 "0"
#define DEF_TEXT_SPACING3 "0"
#define DEF_TEXT_STATE "normal"
#define DEF_TEXT_TABS ""
#define DEF_TEXT_TABSTYLE "tabular"
#define DEF_TEXT_TAKE_FOCUS ((char *) NULL)
#define DEF_TEXT_UNDO "0"
#define DEF_TEXT_WIDTH "80"
#define DEF_TEXT_WRAP "char"
#define DEF_TEXT_XSCROLL_COMMAND ""
#define DEF_TEXT_YSCROLL_COMMAND ""
/*
* Defaults for canvas text:
*/
#define DEF_CANVTEXT_FONT "TkDefaultFont"
/*
* Defaults for toplevels (most of the defaults for frames also apply
* to toplevels):
*/
#define DEF_TOPLEVEL_CLASS "Toplevel"
#define DEF_TOPLEVEL_MENU ""
#define DEF_TOPLEVEL_SCREEN ""
#define DEF_TOPLEVEL_USE ""
/*
* Defaults for busy windows:
*/
#define DEF_BUSY_CURSOR "watch"
#endif /* _TKUNIXDEFAULT */

193
unix/tkUnixDialog.c Normal file
View File

@@ -0,0 +1,193 @@
/*
* tkUnixDialog.c --
*
* Contains the Unix implementation of the common dialog boxes:
*
* Copyright (c) 1996 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkUnixInt.h"
/*
* The wrapper code for Unix is actually set up in library/tk.tcl these days;
* the procedure names used here are probably wrong too...
*/
#ifdef TK_OBSOLETE_UNIX_DIALOG_WRAPPERS
/*
*----------------------------------------------------------------------
*
* EvalObjv --
*
* Invokes the Tcl procedure with the arguments.
*
* Results:
* Returns the result of the evaluation of the command.
*
* Side effects:
* The command may be autoloaded.
*
*----------------------------------------------------------------------
*/
static int
EvalObjv(
Tcl_Interp *interp, /* Current interpreter. */
char *cmdName, /* Name of the TCL command to call */
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* Arguments. */
{
Tcl_Obj *cmdObj, **objs;
int result;
cmdObj = Tcl_NewStringObj(cmdName, -1);
Tcl_IncrRefCount(cmdObj);
objs = ckalloc(sizeof(Tcl_Obj *) * (objc+1));
objs[0] = cmdObj;
memcpy(objs+1, objv, sizeof(Tcl_Obj *) * (unsigned)objc);
result = Tcl_EvalObjv(interp, objc+1, objs, 0);
Tcl_DecrRefCount(cmdObj);
ckfree(objs);
return result;
}
/*
*----------------------------------------------------------------------
*
* Tk_ChooseColorObjCmd --
*
* This procedure implements the color dialog box for the Unix platform.
* See the user documentation for details on what it does.
*
* Results:
* See user documentation.
*
* Side effects:
* A dialog window is created the first time this procedure is called.
* This window is not destroyed and will be reused the next time the
* application invokes the "tk_chooseColor" command.
*
*----------------------------------------------------------------------
*/
int
Tk_ChooseColorObjCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* Arguments. */
{
return EvalObjv(interp, "tk::ColorDialog", objc-1, objv+1);
}
/*
*----------------------------------------------------------------------
*
* Tk_GetOpenFileCmd --
*
* This procedure implements the "open file" dialog box for the Unix
* platform. See the user documentation for details on what it does.
*
* Results:
* See user documentation.
*
* Side effects:
* A dialog window is created the first this procedure is called. This
* window is not destroyed and will be reused the next time the
* application invokes the "tk_getOpenFile" or "tk_getSaveFile" command.
*
*----------------------------------------------------------------------
*/
int
Tk_GetOpenFileObjCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* Arguments. */
{
Tk_Window tkwin = clientData;
if (Tk_StrictMotif(tkwin)) {
return EvalObjv(interp, "tk::MotifOpenFDialog", objc-1, objv+1);
} else {
return EvalObjv(interp, "tk::OpenFDialog", objc-1, objv+1);
}
}
/*
*----------------------------------------------------------------------
*
* Tk_GetSaveFileCmd --
*
* Same as Tk_GetOpenFileCmd but opens a "save file" dialog box instead.
*
* Results:
* Same as Tk_GetOpenFileCmd.
*
* Side effects:
* Same as Tk_GetOpenFileCmd.
*
*----------------------------------------------------------------------
*/
int
Tk_GetSaveFileObjCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* Arguments. */
{
Tk_Window tkwin = clientData;
if (Tk_StrictMotif(tkwin)) {
return EvalObjv(interp, "tk::MotifSaveFDialog", objc-1, objv+1);
} else {
return EvalObjv(interp, "tk::SaveFDialog", objc-1, objv+1);
}
}
/*
*----------------------------------------------------------------------
*
* Tk_MessageBoxCmd --
*
* This procedure implements the MessageBox window for the Unix
* platform. See the user documentation for details on what it does.
*
* Results:
* See user documentation.
*
* Side effects:
* None. The MessageBox window will be destroy before this procedure
* returns.
*
*----------------------------------------------------------------------
*/
int
Tk_MessageBoxCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* Arguments. */
{
return EvalObjv(interp, "tk::MessageBox", objc-1, objv+1);
}
#endif /* TK_OBSOLETE_UNIX_DIALOG_WRAPPERS */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

243
unix/tkUnixDraw.c Normal file
View File

@@ -0,0 +1,243 @@
/*
* tkUnixDraw.c --
*
* This file contains X specific drawing routines.
*
* Copyright (c) 1995 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#ifndef _WIN32
#include "tkUnixInt.h"
#endif
/*
* The following structure is used to pass information to ScrollRestrictProc
* from TkScrollWindow.
*/
typedef struct ScrollInfo {
int done; /* Flag is 0 until filtering is done. */
Display *display; /* Display to filter. */
Window window; /* Window to filter. */
TkRegion region; /* Region into which damage is accumulated. */
int dx, dy; /* Amount by which window was shifted. */
} ScrollInfo;
/*
* Forward declarations for functions declared later in this file:
*/
static Tk_RestrictProc ScrollRestrictProc;
/*
*----------------------------------------------------------------------
*
* TkScrollWindow --
*
* Scroll a rectangle of the specified window and accumulate damage
* information in the specified Region.
*
* Results:
* Returns 0 if no damage additional damage was generated. Sets damageRgn
* to contain the damaged areas and returns 1 if GraphicsExpose events
* were detected.
*
* Side effects:
* Scrolls the bits in the window and enters the event loop looking for
* damage events.
*
*----------------------------------------------------------------------
*/
int
TkScrollWindow(
Tk_Window tkwin, /* The window to be scrolled. */
GC gc, /* GC for window to be scrolled. */
int x, int y, int width, int height,
/* Position rectangle to be scrolled. */
int dx, int dy, /* Distance rectangle should be moved. */
TkRegion damageRgn) /* Region to accumulate damage in. */
{
Tk_RestrictProc *prevProc;
ClientData prevArg;
ScrollInfo info;
XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
x, y, (unsigned) width, (unsigned) height, x+dx, y+dy);
info.done = 0;
info.window = Tk_WindowId(tkwin);
info.display = Tk_Display(tkwin);
info.region = damageRgn;
info.dx = dx;
info.dy = dy;
/*
* Sync the event stream so all of the expose events will be on the Tk
* event queue before we start filtering. This avoids busy waiting while
* we filter events.
*/
TkpSync(info.display);
prevProc = Tk_RestrictEvents(ScrollRestrictProc, &info, &prevArg);
while (!info.done) {
Tcl_ServiceEvent(TCL_WINDOW_EVENTS);
}
Tk_RestrictEvents(prevProc, prevArg, &prevArg);
if (XEmptyRegion((Region) damageRgn)) {
return 0;
} else {
return 1;
}
}
/*
*----------------------------------------------------------------------
*
* ScrollRestrictProc --
*
* A Tk_RestrictProc used by TkScrollWindow to gather up Expose
* information into a single damage region. It accumulates damage events
* on the specified window until a NoExpose or the last GraphicsExpose
* event is detected.
*
* Results:
* None.
*
* Side effects:
* Discards Expose events after accumulating damage information
* for a particular window.
*
*----------------------------------------------------------------------
*/
static Tk_RestrictAction
ScrollRestrictProc(
ClientData arg,
XEvent *eventPtr)
{
ScrollInfo *info = (ScrollInfo *) arg;
XRectangle rect;
/*
* Defer events which aren't for the specified window.
*/
if (info->done || (eventPtr->xany.display != info->display)
|| (eventPtr->xany.window != info->window)) {
return TK_DEFER_EVENT;
}
if (eventPtr->type == NoExpose) {
info->done = 1;
} else if (eventPtr->type == GraphicsExpose) {
rect.x = eventPtr->xgraphicsexpose.x;
rect.y = eventPtr->xgraphicsexpose.y;
rect.width = eventPtr->xgraphicsexpose.width;
rect.height = eventPtr->xgraphicsexpose.height;
XUnionRectWithRegion(&rect, (Region) info->region,
(Region) info->region);
if (eventPtr->xgraphicsexpose.count == 0) {
info->done = 1;
}
} else if (eventPtr->type == Expose) {
/*
* This case is tricky. This event was already queued before the
* XCopyArea was issued. If this area overlaps the area being copied,
* then some of the copied area may be invalid. The easiest way to
* handle this case is to mark both the original area and the shifted
* area as damaged.
*/
rect.x = eventPtr->xexpose.x;
rect.y = eventPtr->xexpose.y;
rect.width = eventPtr->xexpose.width;
rect.height = eventPtr->xexpose.height;
XUnionRectWithRegion(&rect, (Region) info->region,
(Region) info->region);
rect.x += info->dx;
rect.y += info->dy;
XUnionRectWithRegion(&rect, (Region) info->region,
(Region) info->region);
} else {
return TK_DEFER_EVENT;
}
return TK_DISCARD_EVENT;
}
/*
*----------------------------------------------------------------------
*
* TkpDrawHighlightBorder --
*
* This function draws a rectangular ring around the outside of a widget
* to indicate that it has received the input focus.
*
* On Unix, we just draw the simple inset ring. On other sytems, e.g. the
* Mac, the focus ring is a little more complicated, so we need this
* abstraction.
*
* Results:
* None.
*
* Side effects:
* A rectangle "width" pixels wide is drawn in "drawable", corresponding
* to the outer area of "tkwin".
*
*----------------------------------------------------------------------
*/
void
TkpDrawHighlightBorder(
Tk_Window tkwin,
GC fgGC,
GC bgGC,
int highlightWidth,
Drawable drawable)
{
TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}
/*
*----------------------------------------------------------------------
*
* TkpDrawFrame --
*
* This function draws the rectangular frame area.
*
* Results:
* None.
*
* Side effects:
* Draws inside the tkwin area.
*
*----------------------------------------------------------------------
*/
void
TkpDrawFrame(
Tk_Window tkwin,
Tk_3DBorder border,
int highlightWidth,
int borderWidth,
int relief)
{
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, highlightWidth,
highlightWidth, Tk_Width(tkwin) - 2*highlightWidth,
Tk_Height(tkwin) - 2*highlightWidth, borderWidth, relief);
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

1185
unix/tkUnixEmbed.c Normal file

File diff suppressed because it is too large Load Diff

773
unix/tkUnixEvent.c Normal file
View File

@@ -0,0 +1,773 @@
/*
* tkUnixEvent.c --
*
* This file implements an event source for X displays for the UNIX
* version of Tk.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkUnixInt.h"
#include <signal.h>
#ifdef HAVE_XKBKEYCODETOKEYSYM
# include <X11/XKBlib.h>
#else
# define XkbOpenDisplay(D,V,E,M,m,R) ((V),(E),(M),(m),(R),(NULL))
#endif
/*
* The following static indicates whether this module has been initialized in
* the current thread.
*/
typedef struct ThreadSpecificData {
int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
* Prototypes for functions that are referenced only in this file:
*/
static void DisplayCheckProc(ClientData clientData, int flags);
static void DisplayExitHandler(ClientData clientData);
static void DisplayFileProc(ClientData clientData, int flags);
static void DisplaySetupProc(ClientData clientData, int flags);
static void TransferXEventsToTcl(Display *display);
#ifdef TK_USE_INPUT_METHODS
static void OpenIM(TkDisplay *dispPtr);
#endif
/*
*----------------------------------------------------------------------
*
* TkCreateXEventSource --
*
* This function is called during Tk initialization to create the event
* source for X Window events.
*
* Results:
* None.
*
* Side effects:
* A new event source is created.
*
*----------------------------------------------------------------------
*/
void
TkCreateXEventSource(void)
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->initialized) {
tsdPtr->initialized = 1;
Tcl_CreateEventSource(DisplaySetupProc, DisplayCheckProc, NULL);
TkCreateExitHandler(DisplayExitHandler, NULL);
}
}
/*
*----------------------------------------------------------------------
*
* DisplayExitHandler --
*
* This function is called during finalization to clean up the display
* module.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static void
DisplayExitHandler(
ClientData clientData) /* Not used. */
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_DeleteEventSource(DisplaySetupProc, DisplayCheckProc, NULL);
tsdPtr->initialized = 0;
}
/*
*----------------------------------------------------------------------
*
* TkpOpenDisplay --
*
* Allocates a new TkDisplay, opens the X display, and establishes the
* file handler for the connection.
*
* Results:
* A pointer to a Tk display structure.
*
* Side effects:
* Opens a display.
*
*----------------------------------------------------------------------
*/
TkDisplay *
TkpOpenDisplay(
const char *displayNameStr)
{
TkDisplay *dispPtr;
Display *display;
int event = 0;
int error = 0;
int major = 1;
int minor = 0;
int reason = 0;
unsigned int use_xkb = 0;
/* Disabled, until we have a better test. See [Bug 3613668] */
#if 0 && defined(XKEYCODETOKEYSYM_IS_DEPRECATED) && defined(TCL_THREADS)
static int xinited = 0;
static Tcl_Mutex xinitMutex = NULL;
if (!xinited) {
Tcl_MutexLock(&xinitMutex);
if (!xinited) {
/* Necessary for threaded apps, of no consequence otherwise */
/* need only be called once, but must be called before *any* */
/* Xlib call is made. If xinitMutex is still NULL after the */
/* Tcl_MutexLock call, Tcl was compiled without threads so */
/* we cannot use XInitThreads() either. */
if (xinitMutex != NULL){
XInitThreads();
}
xinited = 1;
}
Tcl_MutexUnlock(&xinitMutex);
}
#endif
/*
** Bug [3607830]: Before using Xkb, it must be initialized and confirmed
** that the serve supports it. The XkbOpenDisplay call
** will perform this check and return NULL if the extension
** is not supported.
**
** Work around un-const-ified Xkb headers using (char *) cast.
*/
display = XkbOpenDisplay((char *)displayNameStr, &event, &error, &major,
&minor, &reason);
if (display == NULL) {
/*fprintf(stderr,"event=%d error=%d major=%d minor=%d reason=%d\nDisabling xkb\n",
event, error, major, minor, reason);*/
display = XOpenDisplay(displayNameStr);
} else {
use_xkb = TK_DISPLAY_USE_XKB;
/*fprintf(stderr, "Using xkb %d.%d\n", major, minor);*/
}
if (display == NULL) {
return NULL;
}
dispPtr = ckalloc(sizeof(TkDisplay));
memset(dispPtr, 0, sizeof(TkDisplay));
dispPtr->display = display;
dispPtr->flags |= use_xkb;
#ifdef TK_USE_INPUT_METHODS
OpenIM(dispPtr);
#endif
Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE,
DisplayFileProc, dispPtr);
return dispPtr;
}
/*
*----------------------------------------------------------------------
*
* TkpCloseDisplay --
*
* Cancels notifier callbacks and closes a display.
*
* Results:
* None.
*
* Side effects:
* Deallocates the displayPtr and unix-specific resources.
*
*----------------------------------------------------------------------
*/
void
TkpCloseDisplay(
TkDisplay *dispPtr)
{
TkSendCleanup(dispPtr);
TkWmCleanup(dispPtr);
#ifdef TK_USE_INPUT_METHODS
if (dispPtr->inputXfs) {
XFreeFontSet(dispPtr->display, dispPtr->inputXfs);
}
if (dispPtr->inputMethod) {
XCloseIM(dispPtr->inputMethod);
}
#endif
if (dispPtr->display != 0) {
Tcl_DeleteFileHandler(ConnectionNumber(dispPtr->display));
(void) XSync(dispPtr->display, False);
(void) XCloseDisplay(dispPtr->display);
}
}
/*
*----------------------------------------------------------------------
*
* TkClipCleanup --
*
* This function is called to cleanup resources associated with claiming
* clipboard ownership and for receiving selection get results. This
* function is called in tkWindow.c. This has to be called by the display
* cleanup function because we still need the access display elements.
*
* Results:
* None.
*
* Side effects:
* Resources are freed - the clipboard may no longer be used.
*
*----------------------------------------------------------------------
*/
void
TkClipCleanup(
TkDisplay *dispPtr) /* Display associated with clipboard */
{
if (dispPtr->clipWindow != NULL) {
Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
dispPtr->applicationAtom);
Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
dispPtr->windowAtom);
Tk_DestroyWindow(dispPtr->clipWindow);
Tcl_Release(dispPtr->clipWindow);
dispPtr->clipWindow = NULL;
}
}
/*
*----------------------------------------------------------------------
*
* DisplaySetupProc --
*
* This function implements the setup part of the UNIX X display event
* source. It is invoked by Tcl_DoOneEvent before entering the notifier
* to check for events on all displays.
*
* Results:
* None.
*
* Side effects:
* If data is queued on a display inside Xlib, then the maximum block
* time will be set to 0 to ensure that the notifier returns control to
* Tcl even if there is no more data on the X connection.
*
*----------------------------------------------------------------------
*/
static void
DisplaySetupProc(
ClientData clientData, /* Not used. */
int flags)
{
TkDisplay *dispPtr;
static Tcl_Time blockTime = { 0, 0 };
if (!(flags & TCL_WINDOW_EVENTS)) {
return;
}
for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
dispPtr = dispPtr->nextPtr) {
/*
* Flush the display. If data is pending on the X queue, set the block
* time to zero. This ensures that we won't block in the notifier if
* there is data in the X queue, but not on the server socket.
*/
XFlush(dispPtr->display);
if (QLength(dispPtr->display) > 0) {
Tcl_SetMaxBlockTime(&blockTime);
}
}
}
/*
*----------------------------------------------------------------------
*
* TransferXEventsToTcl --
*
* Transfer events from the X event queue to the Tk event queue.
*
* Results:
* None.
*
* Side effects:
* Moves queued X events onto the Tcl event queue.
*
*----------------------------------------------------------------------
*/
static void
TransferXEventsToTcl(
Display *display)
{
union {
int type;
XEvent x;
TkKeyEvent k;
#ifdef GenericEvent
xGenericEvent xge;
#endif
} event;
Window w;
TkDisplay *dispPtr = NULL;
/*
* Transfer events from the X event queue to the Tk event queue after XIM
* event filtering. KeyPress and KeyRelease events need special treatment
* so that they get directed according to Tk's focus rules during XIM
* handling. Theoretically they can go to the wrong place still (if
* there's a focus change in the queue) but if we push the handling off
* until Tk_HandleEvent then many input methods actually cease to work
* correctly. Most of the time, Tk processes its event queue fast enough
* for this to not be an issue anyway. [Bug 1924761]
*/
while (QLength(display) > 0) {
XNextEvent(display, &event.x);
#ifdef GenericEvent
if (event.type == GenericEvent) {
Tcl_Panic("Wild GenericEvent; panic! (extension=%d,evtype=%d)",
event.xge.extension, event.xge.evtype);
}
#endif
w = None;
if (event.type == KeyPress || event.type == KeyRelease) {
for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) {
if (dispPtr == NULL) {
break;
} else if (dispPtr->display == event.x.xany.display) {
if (dispPtr->focusPtr != NULL) {
w = dispPtr->focusPtr->window;
}
break;
}
}
}
if (XFilterEvent(&event.x, w)) {
continue;
}
if (event.type == KeyPress || event.type == KeyRelease) {
event.k.charValuePtr = NULL;
event.k.charValueLen = 0;
event.k.keysym = NoSymbol;
/*
* Force the calling of the input method engine now. The results
* from it will be cached in the event so that they don't get lost
* (to a race condition with other XIM-handled key events) between
* entering the event queue and getting serviced. [Bug 1924761]
*/
#ifdef TK_USE_INPUT_METHODS
if (event.type == KeyPress && dispPtr &&
(dispPtr->flags & TK_DISPLAY_USE_IM)) {
if (dispPtr->focusPtr && dispPtr->focusPtr->inputContext) {
Tcl_DString ds;
Tcl_DStringInit(&ds);
(void) TkpGetString(dispPtr->focusPtr, &event.x, &ds);
Tcl_DStringFree(&ds);
}
}
#endif
}
Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
}
}
/*
*----------------------------------------------------------------------
*
* DisplayCheckProc --
*
* This function checks for events sitting in the X event queue.
*
* Results:
* None.
*
* Side effects:
* Moves queued events onto the Tcl event queue.
*
*----------------------------------------------------------------------
*/
static void
DisplayCheckProc(
ClientData clientData, /* Not used. */
int flags)
{
TkDisplay *dispPtr;
if (!(flags & TCL_WINDOW_EVENTS)) {
return;
}
for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
dispPtr = dispPtr->nextPtr) {
XFlush(dispPtr->display);
TransferXEventsToTcl(dispPtr->display);
}
}
/*
*----------------------------------------------------------------------
*
* DisplayFileProc --
*
* This function implements the file handler for the X connection.
*
* Results:
* None.
*
* Side effects:
* Makes entries on the Tcl event queue for all the events available from
* all the displays.
*
*----------------------------------------------------------------------
*/
static void
DisplayFileProc(
ClientData clientData, /* The display pointer. */
int flags) /* Should be TCL_READABLE. */
{
TkDisplay *dispPtr = (TkDisplay *) clientData;
Display *display = dispPtr->display;
int numFound;
XFlush(display);
numFound = XEventsQueued(display, QueuedAfterReading);
if (numFound == 0) {
/*
* Things are very tricky if there aren't any events readable at this
* point (after all, there was supposedly data available on the
* connection). A couple of things could have occurred:
*
* One possibility is that there were only error events in the input
* from the server. If this happens, we should return (we don't want
* to go to sleep in XNextEvent below, since this would block out
* other sources of input to the process).
*
* Another possibility is that our connection to the server has been
* closed. This will not necessarily be detected in XEventsQueued (!!)
* so if we just return then there will be an infinite loop. To detect
* such an error, generate a NoOp protocol request to exercise the
* connection to the server, then return. However, must disable
* SIGPIPE while sending the request, or else the process will die
* from the signal and won't invoke the X error function to print a
* nice (?!) message.
*/
void (*oldHandler)();
oldHandler = (void (*)()) signal(SIGPIPE, SIG_IGN);
XNoOp(display);
XFlush(display);
(void) signal(SIGPIPE, oldHandler);
}
TransferXEventsToTcl(display);
}
/*
*----------------------------------------------------------------------
*
* TkUnixDoOneXEvent --
*
* This routine waits for an X event to be processed or for a timeout to
* occur. The timeout is specified as an absolute time. This routine is
* called when Tk needs to wait for a particular X event without letting
* arbitrary events be processed. The caller will typically call
* Tk_RestrictEvents to set up an event filter before calling this
* routine. This routine will service at most one event per invocation.
*
* Results:
* Returns 0 if the timeout has expired, otherwise returns 1.
*
* Side effects:
* Can invoke arbitrary Tcl scripts.
*
*----------------------------------------------------------------------
*/
int
TkUnixDoOneXEvent(
Tcl_Time *timePtr) /* Specifies the absolute time when the call
* should time out. */
{
TkDisplay *dispPtr;
static fd_mask readMask[MASK_SIZE];
struct timeval blockTime, *timeoutPtr;
Tcl_Time now;
int fd, index, numFound, numFdBits = 0;
fd_mask bit, *readMaskPtr = readMask;
/*
* Look for queued events first.
*/
if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
return 1;
}
/*
* Compute the next block time and check to see if we have timed out. Note
* that HP-UX defines tv_sec to be unsigned so we have to be careful in
* our arithmetic.
*/
if (timePtr) {
Tcl_GetTime(&now);
blockTime.tv_sec = timePtr->sec;
blockTime.tv_usec = timePtr->usec - now.usec;
if (blockTime.tv_usec < 0) {
now.sec += 1;
blockTime.tv_usec += 1000000;
}
if (blockTime.tv_sec < now.sec) {
blockTime.tv_sec = 0;
blockTime.tv_usec = 0;
} else {
blockTime.tv_sec -= now.sec;
}
timeoutPtr = &blockTime;
} else {
timeoutPtr = NULL;
}
/*
* Set up the select mask for all of the displays. If a display has data
* pending, then we want to poll instead of blocking.
*/
memset(readMask, 0, MASK_SIZE*sizeof(fd_mask));
for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
dispPtr = dispPtr->nextPtr) {
XFlush(dispPtr->display);
if (QLength(dispPtr->display) > 0) {
blockTime.tv_sec = 0;
blockTime.tv_usec = 0;
}
fd = ConnectionNumber(dispPtr->display);
index = fd/(NBBY*sizeof(fd_mask));
bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask)));
readMask[index] |= bit;
if (numFdBits <= fd) {
numFdBits = fd+1;
}
}
numFound = select(numFdBits, (SELECT_MASK *) readMaskPtr, NULL, NULL,
timeoutPtr);
if (numFound <= 0) {
/*
* Some systems don't clear the masks after an error, so we have to do
* it here.
*/
memset(readMask, 0, MASK_SIZE*sizeof(fd_mask));
}
/*
* Process any new events on the display connections.
*/
for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
dispPtr = dispPtr->nextPtr) {
fd = ConnectionNumber(dispPtr->display);
index = fd/(NBBY*sizeof(fd_mask));
bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask)));
if ((readMask[index] & bit) || (QLength(dispPtr->display) > 0)) {
DisplayFileProc(dispPtr, TCL_READABLE);
}
}
if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
return 1;
}
/*
* Check to see if we timed out.
*/
if (timePtr) {
Tcl_GetTime(&now);
if ((now.sec > timePtr->sec) || ((now.sec == timePtr->sec)
&& (now.usec > timePtr->usec))) {
return 0;
}
}
/*
* We had an event but we did not generate a Tcl event from it. Behave as
* though we dealt with it. (JYL&SS)
*/
return 1;
}
/*
*----------------------------------------------------------------------
*
* TkpSync --
*
* This routine ensures that all pending X requests have been seen by the
* server, and that any pending X events have been moved onto the Tk
* event queue.
*
* Results:
* None.
*
* Side effects:
* Places new events on the Tk event queue.
*
*----------------------------------------------------------------------
*/
void
TkpSync(
Display *display) /* Display to sync. */
{
XSync(display, False);
/*
* Transfer events from the X event queue to the Tk event queue.
*/
TransferXEventsToTcl(display);
}
#ifdef TK_USE_INPUT_METHODS
/*
*--------------------------------------------------------------
*
* OpenIM --
*
* Tries to open an X input method associated with the given display.
*
* Results:
* Stores the input method in dispPtr->inputMethod; if there isn't a
* suitable input method, then NULL is stored in dispPtr->inputMethod.
*
* Side effects:
* An input method gets opened.
*
*--------------------------------------------------------------
*/
static void
OpenIM(
TkDisplay *dispPtr) /* Tk's structure for the display. */
{
int i;
XIMStyles *stylePtr;
XIMStyle bestStyle = 0;
if (XSetLocaleModifiers("") == NULL) {
return;
}
dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
if (dispPtr->inputMethod == NULL) {
return;
}
if ((XGetIMValues(dispPtr->inputMethod, XNQueryInputStyle, &stylePtr,
NULL) != NULL) || (stylePtr == NULL)) {
goto error;
}
/*
* Select the best input style supported by both the IM and Tk.
*/
for (i = 0; i < stylePtr->count_styles; i++) {
XIMStyle thisStyle = stylePtr->supported_styles[i];
if (thisStyle == (XIMPreeditPosition | XIMStatusNothing)) {
bestStyle = thisStyle;
break;
} else if (thisStyle == (XIMPreeditNothing | XIMStatusNothing)) {
bestStyle = thisStyle;
}
}
XFree(stylePtr);
if (bestStyle == 0) {
goto error;
}
dispPtr->inputStyle = bestStyle;
/*
* Create an XFontSet for preedit area.
*/
if (dispPtr->inputStyle & XIMPreeditPosition) {
char **missing_list;
int missing_count;
char *def_string;
dispPtr->inputXfs = XCreateFontSet(dispPtr->display,
"-*-*-*-R-Normal--14-130-75-75-*-*",
&missing_list, &missing_count, &def_string);
if (missing_count > 0) {
XFreeStringList(missing_list);
}
}
return;
error:
if (dispPtr->inputMethod) {
XCloseIM(dispPtr->inputMethod);
dispPtr->inputMethod = NULL;
}
}
#endif /* TK_USE_INPUT_METHODS */
void
TkpWarpPointer(
TkDisplay *dispPtr)
{
Window w; /* Which window to warp relative to. */
if (dispPtr->warpWindow != NULL) {
w = Tk_WindowId(dispPtr->warpWindow);
} else {
w = RootWindow(dispPtr->display,
Tk_ScreenNumber(dispPtr->warpMainwin));
}
XWarpPointer(dispPtr->display, None, w, 0, 0, 0, 0,
(int) dispPtr->warpX, (int) dispPtr->warpY);
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

149
unix/tkUnixFocus.c Normal file
View File

@@ -0,0 +1,149 @@
/*
* tkUnixFocus.c --
*
* This file contains platform specific functions that manage focus for
* Tk.
*
* Copyright (c) 1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkUnixInt.h"
/*
*----------------------------------------------------------------------
*
* TkpChangeFocus --
*
* This function is invoked to move the official X focus from one window
* to another.
*
* Results:
* The return value is the serial number of the command that changed the
* focus. It may be needed by the caller to filter out focus change
* events that were queued before the command. If the function doesn't
* actually change the focus then it returns 0.
*
* Side effects:
* The official X focus window changes; the application's focus window
* isn't changed by this function.
*
*----------------------------------------------------------------------
*/
int
TkpChangeFocus(
TkWindow *winPtr, /* Window that is to receive the X focus. */
int force) /* Non-zero means claim the focus even if it
* didn't originally belong to topLevelPtr's
* application. */
{
TkDisplay *dispPtr = winPtr->dispPtr;
Tk_ErrorHandler errHandler;
Window window, root, parent, *children;
unsigned int numChildren, serial;
TkWindow *winPtr2;
int dummy;
/*
* Don't set the X focus to a window that's marked override-redirect.
* This is a hack to avoid problems with menus under olvwm: if we move
* the focus then the focus can get lost during keyboard traversal.
* Fortunately, we don't really need to move the focus for menus: events
* will still find their way to the focus window, and menus aren't
* decorated anyway so the window manager doesn't need to hear about the
* focus change in order to redecorate the menu.
*/
serial = 0;
if (winPtr->atts.override_redirect) {
return serial;
}
/*
* Check to make sure that the focus is still in one of the windows of
* this application or one of their descendants. Furthermore, grab the
* server to make sure that the focus doesn't change in the middle of this
* operation.
*/
XGrabServer(dispPtr->display);
if (!force) {
/*
* Find the focus window, then see if it or one of its ancestors is a
* window in our application (it's possible that the focus window is
* in an embedded application, which may or may not be in the same
* process.
*/
XGetInputFocus(dispPtr->display, &window, &dummy);
while (1) {
winPtr2 = (TkWindow *) Tk_IdToWindow(dispPtr->display, window);
if ((winPtr2 != NULL) && (winPtr2->mainPtr == winPtr->mainPtr)) {
break;
}
if ((window == PointerRoot) || (window == None)) {
goto done;
}
XQueryTree(dispPtr->display, window, &root, &parent, &children,
&numChildren);
if (children != NULL) {
XFree((void *) children);
}
if (parent == root) {
goto done;
}
window = parent;
}
}
/*
* Tell X to change the focus. Ignore errors that occur when changing the
* focus: it is still possible that the window we're focussing to could
* have gotten unmapped, which will generate an error.
*/
errHandler = Tk_CreateErrorHandler(dispPtr->display, -1,-1,-1, NULL,NULL);
if (winPtr->window == None) {
Tcl_Panic("ChangeXFocus got null X window");
}
XSetInputFocus(dispPtr->display, winPtr->window, RevertToParent,
CurrentTime);
Tk_DeleteErrorHandler(errHandler);
/*
* Remember the current serial number for the X server and issue a dummy
* server request. This marks the position at which we changed the focus,
* so we can distinguish FocusIn and FocusOut events on either side of the
* mark.
*/
serial = NextRequest(winPtr->display);
XNoOp(winPtr->display);
done:
XUngrabServer(dispPtr->display);
/*
* After ungrabbing the server, it's important to flush the output
* immediately so that the server sees the ungrab command. Otherwise we
* might do something else that needs to communicate with the server (such
* as invoking a subprocess that needs to do I/O to the screen); if the
* ungrab command is still sitting in our output buffer, we could
* deadlock.
*/
XFlush(dispPtr->display);
return serial;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

3323
unix/tkUnixFont.c Normal file

File diff suppressed because it is too large Load Diff

162
unix/tkUnixInit.c Normal file
View File

@@ -0,0 +1,162 @@
/*
* tkUnixInit.c --
*
* This file contains Unix-specific interpreter initialization functions.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkUnixInt.h"
#ifdef HAVE_COREFOUNDATION
static int GetLibraryPath(Tcl_Interp *interp);
#else
#define GetLibraryPath(dummy) (void)0
#endif /* HAVE_COREFOUNDATION */
/*
*----------------------------------------------------------------------
*
* TkpInit --
*
* Performs Unix-specific interpreter initialization related to the
* tk_library variable.
*
* Results:
* Returns a standard Tcl result. Leaves an error message or result in
* the interp's result.
*
* Side effects:
* Sets "tk_library" Tcl variable, runs "tk.tcl" script.
*
*----------------------------------------------------------------------
*/
int
TkpInit(
Tcl_Interp *interp)
{
TkCreateXEventSource();
GetLibraryPath(interp);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TkpGetAppName --
*
* Retrieves the name of the current application from a platform specific
* location. For Unix, the application name is the tail of the path
* contained in the tcl variable argv0.
*
* Results:
* Returns the application name in the given Tcl_DString.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
TkpGetAppName(
Tcl_Interp *interp,
Tcl_DString *namePtr) /* A previously initialized Tcl_DString. */
{
const char *p, *name;
name = Tcl_GetVar2(interp, "argv0", NULL, TCL_GLOBAL_ONLY);
if ((name == NULL) || (*name == 0)) {
name = "tk";
} else {
p = strrchr(name, '/');
if (p != NULL) {
name = p+1;
}
}
Tcl_DStringAppend(namePtr, name, -1);
}
/*
*----------------------------------------------------------------------
*
* TkpDisplayWarning --
*
* This routines is called from Tk_Main to display warning messages that
* occur during startup.
*
* Results:
* None.
*
* Side effects:
* Generates messages on stdout.
*
*----------------------------------------------------------------------
*/
void
TkpDisplayWarning(
const char *msg, /* Message to be displayed. */
const char *title) /* Title of warning. */
{
Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
if (errChannel) {
Tcl_WriteChars(errChannel, title, -1);
Tcl_WriteChars(errChannel, ": ", 2);
Tcl_WriteChars(errChannel, msg, -1);
Tcl_WriteChars(errChannel, "\n", 1);
}
}
#ifdef HAVE_COREFOUNDATION
/*
*----------------------------------------------------------------------
*
* GetLibraryPath --
*
* If we have a bundle structure for the Tk installation, then check
* there first to see if we can find the libraries there.
*
* Results:
* TCL_OK if we have found the tk library; TCL_ERROR otherwise.
*
* Side effects:
* Same as for Tcl_MacOSXOpenVersionedBundleResources.
*
*----------------------------------------------------------------------
*/
static int
GetLibraryPath(
Tcl_Interp *interp)
{
#ifdef TK_FRAMEWORK
int foundInFramework = TCL_ERROR;
char tkLibPath[PATH_MAX + 1];
foundInFramework = Tcl_MacOSXOpenVersionedBundleResources(interp,
"com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 0, PATH_MAX,
tkLibPath);
if (tkLibPath[0] != '\0') {
Tcl_SetVar2(interp, "tk_library", NULL, tkLibPath, TCL_GLOBAL_ONLY);
}
return foundInFramework;
#else
return TCL_ERROR;
#endif
}
#endif /* HAVE_COREFOUNDATION */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

35
unix/tkUnixInt.h Normal file
View File

@@ -0,0 +1,35 @@
/*
* tkUnixInt.h --
*
* This file contains declarations that are shared among the
* UNIX-specific parts of Tk but aren't used by the rest of Tk.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKUNIXINT
#define _TKUNIXINT
#ifndef _TKINT
#include "tkInt.h"
#endif
/*
* Prototypes for procedures that are referenced in files other than the ones
* they're defined in.
*/
#include "tkIntPlatDecls.h"
#endif /* _TKUNIXINT */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

509
unix/tkUnixKey.c Normal file
View File

@@ -0,0 +1,509 @@
/*
* tkUnixKey.c --
*
* This file contains routines for dealing with international keyboard
* input.
*
* Copyright (c) 1997 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
/*
** Bug [3607830]: Before using Xkb, it must be initialized. TkpOpenDisplay
** does this and sets the USE_XKB flag if xkb is supported.
** (should this be function ptr?)
*/
#ifdef HAVE_XKBKEYCODETOKEYSYM
# include <X11/XKBlib.h>
#else
# define XkbKeycodeToKeysym(D,K,G,L) XKeycodeToKeysym(D,K,L)
#endif
#define TkKeycodeToKeysym(D,K,G,L) \
((D)->flags & TK_DISPLAY_USE_XKB) ? \
XkbKeycodeToKeysym((D)->display,K,G,L) : \
XKeycodeToKeysym((D)->display,K,L)
/*
* Prototypes for local functions defined in this file:
*/
/*
*----------------------------------------------------------------------
*
* Tk_SetCaretPos --
*
* This enables correct placement of the XIM caret. This is called by
* widgets to indicate their cursor placement. This is currently only
* used for over-the-spot XIM.
*
*----------------------------------------------------------------------
*/
void
Tk_SetCaretPos(
Tk_Window tkwin,
int x,
int y,
int height)
{
TkWindow *winPtr = (TkWindow *) tkwin;
TkDisplay *dispPtr = winPtr->dispPtr;
if ((dispPtr->caret.winPtr == winPtr)
&& (dispPtr->caret.x == x)
&& (dispPtr->caret.y == y)
&& (dispPtr->caret.height == height)) {
return;
}
dispPtr->caret.winPtr = winPtr;
dispPtr->caret.x = x;
dispPtr->caret.y = y;
dispPtr->caret.height = height;
/*
* Adjust the XIM caret position.
*/
#ifdef TK_USE_INPUT_METHODS
if ((dispPtr->flags & TK_DISPLAY_USE_IM)
&& (dispPtr->inputStyle & XIMPreeditPosition)
&& (winPtr->inputContext != NULL)) {
XVaNestedList preedit_attr;
XPoint spot;
spot.x = dispPtr->caret.x;
spot.y = dispPtr->caret.y + dispPtr->caret.height;
preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
XSetICValues(winPtr->inputContext, XNPreeditAttributes, preedit_attr,
NULL);
XFree(preedit_attr);
}
#endif
}
/*
*----------------------------------------------------------------------
*
* TkpGetString --
*
* Retrieve the UTF string associated with a keyboard event.
*
* Results:
* Returns the UTF string.
*
* Side effects:
* Stores the input string in the specified Tcl_DString. Modifies the
* internal input state. This routine can only be called once for a given
* event.
*
*----------------------------------------------------------------------
*/
const char *
TkpGetString(
TkWindow *winPtr, /* Window where event occurred */
XEvent *eventPtr, /* X keyboard event. */
Tcl_DString *dsPtr) /* Initialized, empty string to hold result. */
{
int len;
Tcl_DString buf;
TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;
/*
* If we have the value cached already, use it now. [Bug 1373712]
*/
if (kePtr->charValuePtr != NULL) {
Tcl_DStringSetLength(dsPtr, kePtr->charValueLen);
memcpy(Tcl_DStringValue(dsPtr), kePtr->charValuePtr,
(unsigned) kePtr->charValueLen+1);
return Tcl_DStringValue(dsPtr);
}
#ifdef TK_USE_INPUT_METHODS
if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)
&& (winPtr->inputContext != NULL)
&& (eventPtr->type == KeyPress)) {
Status status;
#if X_HAVE_UTF8_STRING
Tcl_DStringSetLength(dsPtr, TCL_DSTRING_STATIC_SIZE-1);
len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
&kePtr->keysym, &status);
if (status == XBufferOverflow) {
/*
* Expand buffer and try again.
*/
Tcl_DStringSetLength(dsPtr, len);
len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
&kePtr->keysym, &status);
}
if ((status != XLookupChars) && (status != XLookupBoth)) {
len = 0;
}
Tcl_DStringSetLength(dsPtr, len);
#else /* !X_HAVE_UTF8_STRING */
/*
* Overallocate the dstring to the maximum stack amount.
*/
Tcl_DStringInit(&buf);
Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
Tcl_DStringValue(&buf), Tcl_DStringLength(&buf),
&kePtr->keysym, &status);
/*
* If the buffer wasn't big enough, grow the buffer and try again.
*/
if (status == XBufferOverflow) {
Tcl_DStringSetLength(&buf, len);
len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
Tcl_DStringValue(&buf), len, &kePtr->keysym, &status);
}
if ((status != XLookupChars) && (status != XLookupBoth)) {
len = 0;
}
Tcl_DStringSetLength(&buf, len);
Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&buf), len, dsPtr);
Tcl_DStringFree(&buf);
#endif /* X_HAVE_UTF8_STRING */
} else
#endif /* TK_USE_INPUT_METHODS */
{
/*
* Fall back to convert a keyboard event to a UTF-8 string using
* XLookupString. This is used when input methods are turned off and
* for KeyRelease events.
*
* Note: XLookupString() normally returns a single ISO Latin 1 or
* ASCII control character.
*/
Tcl_DStringInit(&buf);
Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
TCL_DSTRING_STATIC_SIZE, &kePtr->keysym, 0);
Tcl_DStringValue(&buf)[len] = '\0';
if (len == 1) {
len = Tcl_UniCharToUtf((unsigned char) Tcl_DStringValue(&buf)[0],
Tcl_DStringValue(dsPtr));
Tcl_DStringSetLength(dsPtr, len);
} else {
/*
* len > 1 should only happen if someone has called XRebindKeysym.
* Assume UTF-8.
*/
Tcl_DStringSetLength(dsPtr, len);
strncpy(Tcl_DStringValue(dsPtr), Tcl_DStringValue(&buf), len);
}
}
/*
* Cache the string in the event so that if/when we return to this
* function, we will be able to produce it without asking X. This stops us
* from having to reenter the XIM engine. [Bug 1373712]
*/
kePtr->charValuePtr = ckalloc(len + 1);
kePtr->charValueLen = len;
memcpy(kePtr->charValuePtr, Tcl_DStringValue(dsPtr), (unsigned) len + 1);
return Tcl_DStringValue(dsPtr);
}
/*
* When mapping from a keysym to a keycode, need information about the
* modifier state to be used so that when they call TkKeycodeToKeysym taking
* into account the xkey.state, they will get back the original keysym.
*/
void
TkpSetKeycodeAndState(
Tk_Window tkwin,
KeySym keySym,
XEvent *eventPtr)
{
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
int state;
KeyCode keycode;
if (keySym == NoSymbol) {
keycode = 0;
} else {
keycode = XKeysymToKeycode(dispPtr->display, keySym);
}
eventPtr->xkey.keycode = keycode;
if (keycode != 0) {
for (state = 0; state < 4; state++) {
if (XLookupKeysym(&eventPtr->xkey, state) == keySym) {
if (state & 1) {
eventPtr->xkey.state |= ShiftMask;
}
if (state & 2) {
eventPtr->xkey.state |= dispPtr->modeModMask;
}
break;
}
}
}
eventPtr->xkey.keycode = keycode;
}
/*
*----------------------------------------------------------------------
*
* TkpGetKeySym --
*
* Given an X KeyPress or KeyRelease event, map the keycode in the event
* into a KeySym.
*
* Results:
* The return value is the KeySym corresponding to eventPtr, or NoSymbol
* if no matching Keysym could be found.
*
* Side effects:
* In the first call for a given display, keycode-to-KeySym maps get
* loaded.
*
*----------------------------------------------------------------------
*/
KeySym
TkpGetKeySym(
TkDisplay *dispPtr, /* Display in which to map keycode. */
XEvent *eventPtr) /* Description of X event. */
{
KeySym sym;
int index;
TkKeyEvent* kePtr = (TkKeyEvent*) eventPtr;
/*
* Refresh the mapping information if it's stale. This must happen before
* we do any input method processing. [Bug 3599312]
*/
if (dispPtr->bindInfoStale) {
TkpInitKeymapInfo(dispPtr);
}
#ifdef TK_USE_INPUT_METHODS
/*
* If input methods are active, we may already have determined a keysym.
* Return it.
*/
if (eventPtr->type == KeyPress && dispPtr
&& (dispPtr->flags & TK_DISPLAY_USE_IM)) {
if (kePtr->charValuePtr == NULL) {
Tcl_DString ds;
TkWindow *winPtr = (TkWindow *)
Tk_IdToWindow(eventPtr->xany.display, eventPtr->xany.window);
Tcl_DStringInit(&ds);
(void) TkpGetString(winPtr, eventPtr, &ds);
Tcl_DStringFree(&ds);
}
if (kePtr->charValuePtr != NULL) {
return kePtr->keysym;
}
}
#endif
/*
* Figure out which of the four slots in the keymap vector to use for this
* key. Refer to Xlib documentation for more info on how this computation
* works.
*/
index = 0;
if (eventPtr->xkey.state & dispPtr->modeModMask) {
index = 2;
}
if ((eventPtr->xkey.state & ShiftMask)
|| ((dispPtr->lockUsage != LU_IGNORE)
&& (eventPtr->xkey.state & LockMask))) {
index += 1;
}
sym = TkKeycodeToKeysym(dispPtr, eventPtr->xkey.keycode, 0,
index);
/*
* Special handling: if the key was shifted because of Lock, but lock is
* only caps lock, not shift lock, and the shifted keysym isn't upper-case
* alphabetic, then switch back to the unshifted keysym.
*/
if ((index & 1) && !(eventPtr->xkey.state & ShiftMask)
&& (dispPtr->lockUsage == LU_CAPS)) {
if (!(((sym >= XK_A) && (sym <= XK_Z))
|| ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
|| ((sym >= XK_Ooblique) && (sym <= XK_Thorn)))) {
index &= ~1;
sym = TkKeycodeToKeysym(dispPtr, eventPtr->xkey.keycode,
0, index);
}
}
/*
* Another bit of special handling: if this is a shifted key and there is
* no keysym defined, then use the keysym for the unshifted key.
*/
if ((index & 1) && (sym == NoSymbol)) {
sym = TkKeycodeToKeysym(dispPtr, eventPtr->xkey.keycode,
0, index & ~1);
}
return sym;
}
/*
*--------------------------------------------------------------
*
* TkpInitKeymapInfo --
*
* This function is invoked to scan keymap information to recompute stuff
* that's important for binding, such as the modifier key (if any) that
* corresponds to "mode switch".
*
* Results:
* None.
*
* Side effects:
* Keymap-related information in dispPtr is updated.
*
*--------------------------------------------------------------
*/
void
TkpInitKeymapInfo(
TkDisplay *dispPtr) /* Display for which to recompute keymap
* information. */
{
XModifierKeymap *modMapPtr;
KeyCode *codePtr;
KeySym keysym;
int count, i, j, max, arraySize;
#define KEYCODE_ARRAY_SIZE 20
dispPtr->bindInfoStale = 0;
modMapPtr = XGetModifierMapping(dispPtr->display);
/*
* Check the keycodes associated with the Lock modifier. If any of them is
* associated with the XK_Shift_Lock modifier, then Lock has to be
* interpreted as Shift Lock, not Caps Lock.
*/
dispPtr->lockUsage = LU_IGNORE;
codePtr = modMapPtr->modifiermap + modMapPtr->max_keypermod*LockMapIndex;
for (count = modMapPtr->max_keypermod; count > 0; count--, codePtr++) {
if (*codePtr == 0) {
continue;
}
keysym = TkKeycodeToKeysym(dispPtr, *codePtr, 0, 0);
if (keysym == XK_Shift_Lock) {
dispPtr->lockUsage = LU_SHIFT;
break;
}
if (keysym == XK_Caps_Lock) {
dispPtr->lockUsage = LU_CAPS;
break;
}
}
/*
* Look through the keycodes associated with modifiers to see if the the
* "mode switch", "meta", or "alt" keysyms are associated with any
* modifiers. If so, remember their modifier mask bits.
*/
dispPtr->modeModMask = 0;
dispPtr->metaModMask = 0;
dispPtr->altModMask = 0;
codePtr = modMapPtr->modifiermap;
max = 8 * modMapPtr->max_keypermod;
for (i = 0; i < max; i++, codePtr++) {
if (*codePtr == 0) {
continue;
}
keysym = TkKeycodeToKeysym(dispPtr, *codePtr, 0, 0);
if (keysym == XK_Mode_switch) {
dispPtr->modeModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
}
if ((keysym == XK_Meta_L) || (keysym == XK_Meta_R)) {
dispPtr->metaModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
}
if ((keysym == XK_Alt_L) || (keysym == XK_Alt_R)) {
dispPtr->altModMask |= ShiftMask << (i/modMapPtr->max_keypermod);
}
}
/*
* Create an array of the keycodes for all modifier keys.
*/
if (dispPtr->modKeyCodes != NULL) {
ckfree(dispPtr->modKeyCodes);
}
dispPtr->numModKeyCodes = 0;
arraySize = KEYCODE_ARRAY_SIZE;
dispPtr->modKeyCodes = ckalloc(KEYCODE_ARRAY_SIZE * sizeof(KeyCode));
for (i = 0, codePtr = modMapPtr->modifiermap; i < max; i++, codePtr++) {
if (*codePtr == 0) {
continue;
}
/*
* Make sure that the keycode isn't already in the array.
*/
for (j = 0; j < dispPtr->numModKeyCodes; j++) {
if (dispPtr->modKeyCodes[j] == *codePtr) {
/*
* 'continue' the outer loop.
*/
goto nextModCode;
}
}
if (dispPtr->numModKeyCodes >= arraySize) {
KeyCode *newCodes;
/*
* Ran out of space in the array; grow it.
*/
arraySize *= 2;
newCodes = ckalloc(arraySize * sizeof(KeyCode));
memcpy(newCodes, dispPtr->modKeyCodes,
dispPtr->numModKeyCodes * sizeof(KeyCode));
ckfree(dispPtr->modKeyCodes);
dispPtr->modKeyCodes = newCodes;
}
dispPtr->modKeyCodes[dispPtr->numModKeyCodes] = *codePtr;
dispPtr->numModKeyCodes++;
nextModCode:
continue;
}
XFreeModifiermap(modMapPtr);
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

1823
unix/tkUnixMenu.c Normal file

File diff suppressed because it is too large Load Diff

476
unix/tkUnixMenubu.c Normal file
View File

@@ -0,0 +1,476 @@
/*
* tkUnixMenubu.c --
*
* This file implements the Unix specific portion of the menubutton
* widget.
*
* Copyright (c) 1996-1997 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "tkMenubutton.h"
/*
*----------------------------------------------------------------------
*
* TkpCreateMenuButton --
*
* Allocate a new TkMenuButton structure.
*
* Results:
* Returns a newly allocated TkMenuButton structure.
*
* Side effects:
* Registers an event handler for the widget.
*
*----------------------------------------------------------------------
*/
TkMenuButton *
TkpCreateMenuButton(
Tk_Window tkwin)
{
return ckalloc(sizeof(TkMenuButton));
}
/*
*----------------------------------------------------------------------
*
* TkpDisplayMenuButton --
*
* This function is invoked to display a menubutton widget.
*
* Results:
* None.
*
* Side effects:
* Commands are output to X to display the menubutton in its current
* mode.
*
*----------------------------------------------------------------------
*/
void
TkpDisplayMenuButton(
ClientData clientData) /* Information about widget. */
{
register TkMenuButton *mbPtr = (TkMenuButton *) clientData;
GC gc;
Tk_3DBorder border;
Pixmap pixmap;
int x = 0; /* Initialization needed only to stop compiler
* warning. */
int y = 0;
register Tk_Window tkwin = mbPtr->tkwin;
int fullWidth, fullHeight;
int textXOffset, textYOffset;
int imageWidth, imageHeight;
int imageXOffset, imageYOffset;
int width = 0, height = 0;
/* Image information that will be used to
* restrict disabled pixmap as well */
int haveImage = 0, haveText = 0;
mbPtr->flags &= ~REDRAW_PENDING;
if ((mbPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
return;
}
if ((mbPtr->state == STATE_DISABLED) && (mbPtr->disabledFg != NULL)) {
gc = mbPtr->disabledGC;
border = mbPtr->normalBorder;
} else if ((mbPtr->state == STATE_ACTIVE)
&& !Tk_StrictMotif(mbPtr->tkwin)) {
gc = mbPtr->activeTextGC;
border = mbPtr->activeBorder;
} else {
gc = mbPtr->normalTextGC;
border = mbPtr->normalBorder;
}
if (mbPtr->image != None) {
Tk_SizeOfImage(mbPtr->image, &width, &height);
haveImage = 1;
} else if (mbPtr->bitmap != None) {
Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height);
haveImage = 1;
}
imageWidth = width;
imageHeight = height;
haveText = (mbPtr->textWidth != 0 && mbPtr->textHeight != 0);
/*
* In order to avoid screen flashes, this function redraws the menu button
* in a pixmap, then copies the pixmap to the screen in a single
* operation. This means that there's no point in time where the on-sreen
* image has been cleared.
*/
pixmap = Tk_GetPixmap(mbPtr->display, Tk_WindowId(tkwin),
Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
Tk_Fill3DRectangle(tkwin, pixmap, border, 0, 0, Tk_Width(tkwin),
Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
imageXOffset = 0;
imageYOffset = 0;
textXOffset = 0;
textYOffset = 0;
fullWidth = 0;
fullHeight = 0;
if (mbPtr->compound != COMPOUND_NONE && haveImage && haveText) {
switch ((enum compound) mbPtr->compound) {
case COMPOUND_TOP:
case COMPOUND_BOTTOM:
/*
* Image is above or below text.
*/
if (mbPtr->compound == COMPOUND_TOP) {
textYOffset = height + mbPtr->padY;
} else {
imageYOffset = mbPtr->textHeight + mbPtr->padY;
}
fullHeight = height + mbPtr->textHeight + mbPtr->padY;
fullWidth = (width > mbPtr->textWidth ? width : mbPtr->textWidth);
textXOffset = (fullWidth - mbPtr->textWidth)/2;
imageXOffset = (fullWidth - width)/2;
break;
case COMPOUND_LEFT:
case COMPOUND_RIGHT:
/*
* Image is left or right of text.
*/
if (mbPtr->compound == COMPOUND_LEFT) {
textXOffset = width + mbPtr->padX;
} else {
imageXOffset = mbPtr->textWidth + mbPtr->padX;
}
fullWidth = mbPtr->textWidth + mbPtr->padX + width;
fullHeight = (height > mbPtr->textHeight ? height :
mbPtr->textHeight);
textYOffset = (fullHeight - mbPtr->textHeight)/2;
imageYOffset = (fullHeight - height)/2;
break;
case COMPOUND_CENTER:
/*
* Image and text are superimposed.
*/
fullWidth = (width > mbPtr->textWidth ? width : mbPtr->textWidth);
fullHeight = (height > mbPtr->textHeight ? height :
mbPtr->textHeight);
textXOffset = (fullWidth - mbPtr->textWidth)/2;
imageXOffset = (fullWidth - width)/2;
textYOffset = (fullHeight - mbPtr->textHeight)/2;
imageYOffset = (fullHeight - height)/2;
break;
case COMPOUND_NONE:
break;
}
TkComputeAnchor(mbPtr->anchor, tkwin, 0, 0,
mbPtr->indicatorWidth + fullWidth, fullHeight, &x, &y);
imageXOffset += x;
imageYOffset += y;
if (mbPtr->image != NULL) {
Tk_RedrawImage(mbPtr->image, 0, 0, width, height, pixmap,
imageXOffset, imageYOffset);
} else if (mbPtr->bitmap != None) {
XSetClipOrigin(mbPtr->display, gc, imageXOffset, imageYOffset);
XCopyPlane(mbPtr->display, mbPtr->bitmap, pixmap,
gc, 0, 0, (unsigned) width, (unsigned) height,
imageXOffset, imageYOffset, 1);
XSetClipOrigin(mbPtr->display, gc, 0, 0);
}
Tk_DrawTextLayout(mbPtr->display, pixmap, gc, mbPtr->textLayout,
x + textXOffset, y + textYOffset, 0, -1);
Tk_UnderlineTextLayout(mbPtr->display, pixmap, gc, mbPtr->textLayout,
x + textXOffset, y + textYOffset, mbPtr->underline);
} else if (haveImage) {
TkComputeAnchor(mbPtr->anchor, tkwin, 0, 0,
width + mbPtr->indicatorWidth, height, &x, &y);
imageXOffset += x;
imageYOffset += y;
if (mbPtr->image != NULL) {
Tk_RedrawImage(mbPtr->image, 0, 0, width, height, pixmap,
imageXOffset, imageYOffset);
} else if (mbPtr->bitmap != None) {
XSetClipOrigin(mbPtr->display, gc, x, y);
XCopyPlane(mbPtr->display, mbPtr->bitmap, pixmap,
gc, 0, 0, (unsigned) width, (unsigned) height,
x, y, 1);
XSetClipOrigin(mbPtr->display, gc, 0, 0);
}
} else {
TkComputeAnchor(mbPtr->anchor, tkwin, mbPtr->padX, mbPtr->padY,
mbPtr->textWidth + mbPtr->indicatorWidth,
mbPtr->textHeight, &x, &y);
Tk_DrawTextLayout(mbPtr->display, pixmap, gc, mbPtr->textLayout,
x + textXOffset, y + textYOffset, 0, -1);
Tk_UnderlineTextLayout(mbPtr->display, pixmap, gc,
mbPtr->textLayout, x + textXOffset, y + textYOffset,
mbPtr->underline);
}
/*
* If the menu button is disabled with a stipple rather than a special
* foreground color, generate the stippled effect.
*/
if ((mbPtr->state == STATE_DISABLED)
&& ((mbPtr->disabledFg == NULL) || (mbPtr->image != NULL))) {
/*
* Stipple the whole button if no disabledFg was specified, otherwise
* restrict stippling only to displayed image
*/
if (mbPtr->disabledFg == NULL) {
XFillRectangle(mbPtr->display, pixmap, mbPtr->stippleGC,
mbPtr->inset, mbPtr->inset,
(unsigned) (Tk_Width(tkwin) - 2*mbPtr->inset),
(unsigned) (Tk_Height(tkwin) - 2*mbPtr->inset));
} else {
XFillRectangle(mbPtr->display, pixmap, mbPtr->stippleGC,
imageXOffset, imageYOffset,
(unsigned) imageWidth, (unsigned) imageHeight);
}
}
/*
* Draw the cascade indicator for the menu button on the right side of the
* window, if desired.
*/
if (mbPtr->indicatorOn) {
int borderWidth;
borderWidth = (mbPtr->indicatorHeight+1)/3;
if (borderWidth < 1) {
borderWidth = 1;
}
/*y += mbPtr->textHeight / 2;*/
Tk_Fill3DRectangle(tkwin, pixmap, border,
Tk_Width(tkwin) - mbPtr->inset - mbPtr->indicatorWidth
+ mbPtr->indicatorHeight,
((int) (Tk_Height(tkwin) - mbPtr->indicatorHeight))/2,
mbPtr->indicatorWidth - 2*mbPtr->indicatorHeight,
mbPtr->indicatorHeight, borderWidth, TK_RELIEF_RAISED);
}
/*
* Draw the border and traversal highlight last. This way, if the menu
* button's contents overflow onto the border they'll be covered up by the
* border.
*/
if (mbPtr->relief != TK_RELIEF_FLAT) {
Tk_Draw3DRectangle(tkwin, pixmap, border,
mbPtr->highlightWidth, mbPtr->highlightWidth,
Tk_Width(tkwin) - 2*mbPtr->highlightWidth,
Tk_Height(tkwin) - 2*mbPtr->highlightWidth,
mbPtr->borderWidth, mbPtr->relief);
}
if (mbPtr->highlightWidth != 0) {
GC gc;
if (mbPtr->flags & GOT_FOCUS) {
gc = Tk_GCForColor(mbPtr->highlightColorPtr, pixmap);
} else {
gc = Tk_GCForColor(mbPtr->highlightBgColorPtr, pixmap);
}
Tk_DrawFocusHighlight(tkwin, gc, mbPtr->highlightWidth, pixmap);
}
/*
* Copy the information from the off-screen pixmap onto the screen, then
* delete the pixmap.
*/
XCopyArea(mbPtr->display, pixmap, Tk_WindowId(tkwin),
mbPtr->normalTextGC, 0, 0, (unsigned) Tk_Width(tkwin),
(unsigned) Tk_Height(tkwin), 0, 0);
Tk_FreePixmap(mbPtr->display, pixmap);
}
/*
*----------------------------------------------------------------------
*
* TkpDestroyMenuButton --
*
* Free data structures associated with the menubutton control.
*
* Results:
* None.
*
* Side effects:
* Restores the default control state.
*
*----------------------------------------------------------------------
*/
void
TkpDestroyMenuButton(
TkMenuButton *mbPtr)
{
}
/*
*----------------------------------------------------------------------
*
* TkpComputeMenuButtonGeometry --
*
* After changes in a menu button's text or bitmap, this function
* recomputes the menu button's geometry and passes this information
* along to the geometry manager for the window.
*
* Results:
* None.
*
* Side effects:
* The menu button's window may change size.
*
*----------------------------------------------------------------------
*/
void
TkpComputeMenuButtonGeometry(
TkMenuButton *mbPtr) /* Widget record for menu button. */
{
int width, height, mm, pixels;
int avgWidth, txtWidth, txtHeight;
int haveImage = 0, haveText = 0;
Tk_FontMetrics fm;
mbPtr->inset = mbPtr->highlightWidth + mbPtr->borderWidth;
width = 0;
height = 0;
txtWidth = 0;
txtHeight = 0;
avgWidth = 0;
if (mbPtr->image != None) {
Tk_SizeOfImage(mbPtr->image, &width, &height);
haveImage = 1;
} else if (mbPtr->bitmap != None) {
Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height);
haveImage = 1;
}
if (haveImage == 0 || mbPtr->compound != COMPOUND_NONE) {
Tk_FreeTextLayout(mbPtr->textLayout);
mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text,
-1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth,
&mbPtr->textHeight);
txtWidth = mbPtr->textWidth;
txtHeight = mbPtr->textHeight;
avgWidth = Tk_TextWidth(mbPtr->tkfont, "0", 1);
Tk_GetFontMetrics(mbPtr->tkfont, &fm);
haveText = (txtWidth != 0 && txtHeight != 0);
}
/*
* If the menubutton is compound (ie, it shows both an image and text),
* the new geometry is a combination of the image and text geometry. We
* only honor the compound bit if the menubutton has both text and an
* image, because otherwise it is not really a compound menubutton.
*/
if (mbPtr->compound != COMPOUND_NONE && haveImage && haveText) {
switch ((enum compound) mbPtr->compound) {
case COMPOUND_TOP:
case COMPOUND_BOTTOM:
/*
* Image is above or below text.
*/
height += txtHeight + mbPtr->padY;
width = (width > txtWidth ? width : txtWidth);
break;
case COMPOUND_LEFT:
case COMPOUND_RIGHT:
/*
* Image is left or right of text.
*/
width += txtWidth + mbPtr->padX;
height = (height > txtHeight ? height : txtHeight);
break;
case COMPOUND_CENTER:
/*
* Image and text are superimposed.
*/
width = (width > txtWidth ? width : txtWidth);
height = (height > txtHeight ? height : txtHeight);
break;
case COMPOUND_NONE:
break;
}
if (mbPtr->width > 0) {
width = mbPtr->width;
}
if (mbPtr->height > 0) {
height = mbPtr->height;
}
width += 2*mbPtr->padX;
height += 2*mbPtr->padY;
} else {
if (haveImage) {
if (mbPtr->width > 0) {
width = mbPtr->width;
}
if (mbPtr->height > 0) {
height = mbPtr->height;
}
} else {
width = txtWidth;
height = txtHeight;
if (mbPtr->width > 0) {
width = mbPtr->width * avgWidth;
}
if (mbPtr->height > 0) {
height = mbPtr->height * fm.linespace;
}
}
}
if (! haveImage) {
width += 2*mbPtr->padX;
height += 2*mbPtr->padY;
}
if (mbPtr->indicatorOn) {
mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin));
pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin));
mbPtr->indicatorHeight= (INDICATOR_HEIGHT * pixels)/(10*mm);
mbPtr->indicatorWidth = (INDICATOR_WIDTH * pixels)/(10*mm)
+ 2*mbPtr->indicatorHeight;
width += mbPtr->indicatorWidth;
} else {
mbPtr->indicatorHeight = 0;
mbPtr->indicatorWidth = 0;
}
Tk_GeometryRequest(mbPtr->tkwin, (int) (width + 2*mbPtr->inset),
(int) (height + 2*mbPtr->inset));
Tk_SetInternalBorder(mbPtr->tkwin, mbPtr->inset);
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

192
unix/tkUnixPort.h Normal file
View File

@@ -0,0 +1,192 @@
/*
* tkUnixPort.h --
*
* This file is included by all of the Tk C files. It contains
* information that may be configuration-dependent, such as
* #includes for system include files and a few other things.
*
* Copyright (c) 1991-1993 The Regents of the University of California.
* Copyright (c) 1994-1996 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _UNIXPORT
#define _UNIXPORT
#define __UNIX__ 1
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
#include <math.h>
#include <pwd.h>
#ifdef NO_STDLIB_H
# include "../compat/stdlib.h"
#else
# include <stdlib.h>
#endif
#include <string.h>
#include <sys/types.h>
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#include <sys/stat.h>
#ifndef _TCL
# include <tcl.h>
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#ifndef NO_UNISTD_H
# include <unistd.h>
#else
# include "../compat/unistd.h"
#endif
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xproto.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
/*
* The following macro defines the type of the mask arguments to
* select:
*/
#ifndef NO_FD_SET
# define SELECT_MASK fd_set
#else
# ifndef _AIX
typedef long fd_mask;
# endif
# if defined(_IBMR2)
# define SELECT_MASK void
# else
# define SELECT_MASK int
# endif
#endif
/*
* The following macro defines the number of fd_masks in an fd_set:
*/
#ifndef FD_SETSIZE
# ifdef OPEN_MAX
# define FD_SETSIZE OPEN_MAX
# else
# define FD_SETSIZE 256
# endif
#endif
#if !defined(howmany)
# define howmany(x, y) (((x)+((y)-1))/(y))
#endif
#ifndef NFDBITS
# define NFDBITS NBBY*sizeof(fd_mask)
#endif
#define MASK_SIZE howmany(FD_SETSIZE, NFDBITS)
/*
* Define "NBBY" (number of bits per byte) if it's not already defined.
*/
#ifndef NBBY
# define NBBY 8
#endif
#ifdef __CYGWIN__
# include "tkIntXlibDecls.h"
# define UINT unsigned int
# define HWND void *
# define HDC void *
# define HINSTANCE void *
# define COLORREF void *
# define HMENU void *
# define TkWinDCState void
# define HPALETTE void *
# define WNDPROC void *
# define WPARAM void *
# define LPARAM void *
# define LRESULT void *
#else /* !__CYGWIN__ */
/*
* The TkPutImage macro strips off the color table information, which isn't
* needed for X.
*/
# define TkPutImage(colors, ncolors, display, pixels, gc, image, srcx, srcy, destx, desty, width, height) \
XPutImage(display, pixels, gc, image, srcx, srcy, destx, \
desty, width, height);
#endif /* !__CYGWIN__ */
/*
* Supply macros for seek offsets, if they're not already provided by
* an include file.
*/
#ifndef SEEK_SET
# define SEEK_SET 0
#endif
#ifndef SEEK_CUR
# define SEEK_CUR 1
#endif
#ifndef SEEK_END
# define SEEK_END 2
#endif
/*
* Declarations for various library procedures that may not be declared
* in any other header file.
*/
/*
* These functions do nothing under Unix, so we just eliminate calls to them.
*/
#define TkpButtonSetDefaults() {}
#define TkpDestroyButton(butPtr) {}
#define TkSelUpdateClipboard(a,b) {}
#ifndef __CYGWIN__
#define TkSetPixmapColormap(p,c) {}
#endif
/*
* These calls implement native bitmaps which are not supported under
* UNIX. The macros eliminate the calls.
*/
#define TkpDefineNativeBitmaps()
#define TkpCreateNativeBitmap(display, source) None
#define TkpGetNativeAppBitmap(display, name, w, h) None
/*
* This macro stores a representation of the window handle in a string.
* This should perhaps use the real size of an XID.
*/
#ifndef __CYGWIN__
#define TkpPrintWindowId(buf,w) \
sprintf((buf), "%#08lx", (unsigned long) (w))
#endif
#endif /* _UNIXPORT */

1202
unix/tkUnixRFont.c Normal file

File diff suppressed because it is too large Load Diff

717
unix/tkUnixScale.c Normal file
View File

@@ -0,0 +1,717 @@
/*
* tkUnixScale.c --
*
* This file implements the X specific portion of the scrollbar widget.
*
* Copyright (c) 1996 by Sun Microsystems, Inc.
* Copyright (c) 1998-2000 by Scriptics Corporation.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "tkScale.h"
/*
* Forward declarations for functions defined later in this file:
*/
static void DisplayHorizontalScale(TkScale *scalePtr,
Drawable drawable, XRectangle *drawnAreaPtr);
static void DisplayHorizontalValue(TkScale *scalePtr,
Drawable drawable, double value, int top);
static void DisplayVerticalScale(TkScale *scalePtr,
Drawable drawable, XRectangle *drawnAreaPtr);
static void DisplayVerticalValue(TkScale *scalePtr,
Drawable drawable, double value, int rightEdge);
/*
*----------------------------------------------------------------------
*
* TkpCreateScale --
*
* Allocate a new TkScale structure.
*
* Results:
* Returns a newly allocated TkScale structure.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
TkScale *
TkpCreateScale(
Tk_Window tkwin)
{
return ckalloc(sizeof(TkScale));
}
/*
*----------------------------------------------------------------------
*
* TkpDestroyScale --
*
* Destroy a TkScale structure. It's necessary to do this with
* Tcl_EventuallyFree to allow the Tcl_Preserve(scalePtr) to work as
* expected in TkpDisplayScale. (hobbs)
*
* Results:
* None
*
* Side effects:
* Memory is freed.
*
*----------------------------------------------------------------------
*/
void
TkpDestroyScale(
TkScale *scalePtr)
{
Tcl_EventuallyFree(scalePtr, TCL_DYNAMIC);
}
/*
*--------------------------------------------------------------
*
* DisplayVerticalScale --
*
* This function redraws the contents of a vertical scale window. It is
* invoked as a do-when-idle handler, so it only runs when there's
* nothing else for the application to do.
*
* Results:
* There is no return value. If only a part of the scale needs to be
* redrawn, then drawnAreaPtr is modified to reflect the area that was
* actually modified.
*
* Side effects:
* Information appears on the screen.
*
*--------------------------------------------------------------
*/
static void
DisplayVerticalScale(
TkScale *scalePtr, /* Widget record for scale. */
Drawable drawable, /* Where to display scale (window or
* pixmap). */
XRectangle *drawnAreaPtr) /* Initally contains area of window; if only a
* part of the scale is redrawn, gets modified
* to reflect the part of the window that was
* redrawn. */
{
Tk_Window tkwin = scalePtr->tkwin;
int x, y, width, height, shadowWidth;
double tickValue, tickInterval = scalePtr->tickInterval;
Tk_3DBorder sliderBorder;
/*
* Display the information from left to right across the window.
*/
if (!(scalePtr->flags & REDRAW_OTHER)) {
drawnAreaPtr->x = scalePtr->vertTickRightX;
drawnAreaPtr->y = scalePtr->inset;
drawnAreaPtr->width = scalePtr->vertTroughX + scalePtr->width
+ 2*scalePtr->borderWidth - scalePtr->vertTickRightX;
drawnAreaPtr->height -= 2*scalePtr->inset;
}
Tk_Fill3DRectangle(tkwin, drawable, scalePtr->bgBorder,
drawnAreaPtr->x, drawnAreaPtr->y, drawnAreaPtr->width,
drawnAreaPtr->height, 0, TK_RELIEF_FLAT);
if (scalePtr->flags & REDRAW_OTHER) {
/*
* Display the tick marks.
*/
if (tickInterval != 0) {
double ticks, maxTicks;
/*
* Ensure that we will only draw enough of the tick values such
* that they don't overlap
*/
ticks = fabs((scalePtr->toValue - scalePtr->fromValue)
/ tickInterval);
maxTicks = (double) Tk_Height(tkwin)
/ (double) scalePtr->fontHeight;
if (ticks > maxTicks) {
tickInterval *= (ticks / maxTicks);
}
for (tickValue = scalePtr->fromValue; ;
tickValue += tickInterval) {
/*
* The TkRoundToResolution call gets rid of accumulated
* round-off errors, if any.
*/
tickValue = TkRoundToResolution(scalePtr, tickValue);
if (scalePtr->toValue >= scalePtr->fromValue) {
if (tickValue > scalePtr->toValue) {
break;
}
} else {
if (tickValue < scalePtr->toValue) {
break;
}
}
DisplayVerticalValue(scalePtr, drawable, tickValue,
scalePtr->vertTickRightX);
}
}
}
/*
* Display the value, if it is desired.
*/
if (scalePtr->showValue) {
DisplayVerticalValue(scalePtr, drawable, scalePtr->value,
scalePtr->vertValueRightX);
}
/*
* Display the trough and the slider.
*/
Tk_Draw3DRectangle(tkwin, drawable,
scalePtr->bgBorder, scalePtr->vertTroughX, scalePtr->inset,
scalePtr->width + 2*scalePtr->borderWidth,
Tk_Height(tkwin) - 2*scalePtr->inset, scalePtr->borderWidth,
TK_RELIEF_SUNKEN);
XFillRectangle(scalePtr->display, drawable, scalePtr->troughGC,
scalePtr->vertTroughX + scalePtr->borderWidth,
scalePtr->inset + scalePtr->borderWidth,
(unsigned) scalePtr->width,
(unsigned) (Tk_Height(tkwin) - 2*scalePtr->inset
- 2*scalePtr->borderWidth));
if (scalePtr->state == STATE_ACTIVE) {
sliderBorder = scalePtr->activeBorder;
} else {
sliderBorder = scalePtr->bgBorder;
}
width = scalePtr->width;
height = scalePtr->sliderLength/2;
x = scalePtr->vertTroughX + scalePtr->borderWidth;
y = TkScaleValueToPixel(scalePtr, scalePtr->value) - height;
shadowWidth = scalePtr->borderWidth/2;
if (shadowWidth == 0) {
shadowWidth = 1;
}
Tk_Draw3DRectangle(tkwin, drawable, sliderBorder, x, y, width,
2*height, shadowWidth, scalePtr->sliderRelief);
x += shadowWidth;
y += shadowWidth;
width -= 2*shadowWidth;
height -= shadowWidth;
Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x, y, width,
height, shadowWidth, scalePtr->sliderRelief);
Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x, y+height,
width, height, shadowWidth, scalePtr->sliderRelief);
/*
* Draw the label to the right of the scale.
*/
if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) {
Tk_FontMetrics fm;
Tk_GetFontMetrics(scalePtr->tkfont, &fm);
Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
scalePtr->tkfont, scalePtr->label,
scalePtr->labelLength, scalePtr->vertLabelX,
scalePtr->inset + (3*fm.ascent)/2);
}
}
/*
*----------------------------------------------------------------------
*
* DisplayVerticalValue --
*
* This function is called to display values (scale readings) for
* vertically-oriented scales.
*
* Results:
* None.
*
* Side effects:
* The numerical value corresponding to value is displayed with its right
* edge at "rightEdge", and at a vertical position in the scale that
* corresponds to "value".
*
*----------------------------------------------------------------------
*/
static void
DisplayVerticalValue(
register TkScale *scalePtr, /* Information about widget in which to
* display value. */
Drawable drawable, /* Pixmap or window in which to draw the
* value. */
double value, /* Y-coordinate of number to display,
* specified in application coords, not in
* pixels (we'll compute pixels). */
int rightEdge) /* X-coordinate of right edge of text,
* specified in pixels. */
{
register Tk_Window tkwin = scalePtr->tkwin;
int y, width, length;
char valueString[TCL_DOUBLE_SPACE];
Tk_FontMetrics fm;
Tk_GetFontMetrics(scalePtr->tkfont, &fm);
y = TkScaleValueToPixel(scalePtr, value) + fm.ascent/2;
sprintf(valueString, scalePtr->format, value);
length = (int) strlen(valueString);
width = Tk_TextWidth(scalePtr->tkfont, valueString, length);
/*
* Adjust the y-coordinate if necessary to keep the text entirely inside
* the window.
*/
if ((y - fm.ascent) < (scalePtr->inset + SPACING)) {
y = scalePtr->inset + SPACING + fm.ascent;
}
if ((y + fm.descent) > (Tk_Height(tkwin) - scalePtr->inset - SPACING)) {
y = Tk_Height(tkwin) - scalePtr->inset - SPACING - fm.descent;
}
Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
scalePtr->tkfont, valueString, length, rightEdge - width, y);
}
/*
*--------------------------------------------------------------
*
* DisplayHorizontalScale --
*
* This function redraws the contents of a horizontal scale window. It is
* invoked as a do-when-idle handler, so it only runs when there's
* nothing else for the application to do.
*
* Results:
* There is no return value. If only a part of the scale needs to be
* redrawn, then drawnAreaPtr is modified to reflect the area that was
* actually modified.
*
* Side effects:
* Information appears on the screen.
*
*--------------------------------------------------------------
*/
static void
DisplayHorizontalScale(
TkScale *scalePtr, /* Widget record for scale. */
Drawable drawable, /* Where to display scale (window or
* pixmap). */
XRectangle *drawnAreaPtr) /* Initally contains area of window; if only a
* part of the scale is redrawn, gets modified
* to reflect the part of the window that was
* redrawn. */
{
register Tk_Window tkwin = scalePtr->tkwin;
int x, y, width, height, shadowWidth;
double tickValue, tickInterval = scalePtr->tickInterval;
Tk_3DBorder sliderBorder;
/*
* Display the information from bottom to top across the window.
*/
if (!(scalePtr->flags & REDRAW_OTHER)) {
drawnAreaPtr->x = scalePtr->inset;
drawnAreaPtr->y = scalePtr->horizValueY;
drawnAreaPtr->width -= 2*scalePtr->inset;
drawnAreaPtr->height = scalePtr->horizTroughY + scalePtr->width
+ 2*scalePtr->borderWidth - scalePtr->horizValueY;
}
Tk_Fill3DRectangle(tkwin, drawable, scalePtr->bgBorder,
drawnAreaPtr->x, drawnAreaPtr->y, drawnAreaPtr->width,
drawnAreaPtr->height, 0, TK_RELIEF_FLAT);
if (scalePtr->flags & REDRAW_OTHER) {
/*
* Display the tick marks.
*/
if (tickInterval != 0) {
char valueString[TCL_DOUBLE_SPACE];
double ticks, maxTicks;
/*
* Ensure that we will only draw enough of the tick values such
* that they don't overlap. We base this off the width that
* fromValue would take. Not exact, but better than no constraint.
*/
ticks = fabs((scalePtr->toValue - scalePtr->fromValue)
/ tickInterval);
sprintf(valueString, scalePtr->format, scalePtr->fromValue);
maxTicks = (double) Tk_Width(tkwin)
/ (double) Tk_TextWidth(scalePtr->tkfont, valueString, -1);
if (ticks > maxTicks) {
tickInterval *= (ticks / maxTicks);
}
for (tickValue = scalePtr->fromValue; ;
tickValue += tickInterval) {
/*
* The TkRoundToResolution call gets rid of accumulated
* round-off errors, if any.
*/
tickValue = TkRoundToResolution(scalePtr, tickValue);
if (scalePtr->toValue >= scalePtr->fromValue) {
if (tickValue > scalePtr->toValue) {
break;
}
} else {
if (tickValue < scalePtr->toValue) {
break;
}
}
DisplayHorizontalValue(scalePtr, drawable, tickValue,
scalePtr->horizTickY);
}
}
}
/*
* Display the value, if it is desired.
*/
if (scalePtr->showValue) {
DisplayHorizontalValue(scalePtr, drawable, scalePtr->value,
scalePtr->horizValueY);
}
/*
* Display the trough and the slider.
*/
y = scalePtr->horizTroughY;
Tk_Draw3DRectangle(tkwin, drawable,
scalePtr->bgBorder, scalePtr->inset, y,
Tk_Width(tkwin) - 2*scalePtr->inset,
scalePtr->width + 2*scalePtr->borderWidth,
scalePtr->borderWidth, TK_RELIEF_SUNKEN);
XFillRectangle(scalePtr->display, drawable, scalePtr->troughGC,
scalePtr->inset + scalePtr->borderWidth,
y + scalePtr->borderWidth,
(unsigned) (Tk_Width(tkwin) - 2*scalePtr->inset
- 2*scalePtr->borderWidth),
(unsigned) scalePtr->width);
if (scalePtr->state == STATE_ACTIVE) {
sliderBorder = scalePtr->activeBorder;
} else {
sliderBorder = scalePtr->bgBorder;
}
width = scalePtr->sliderLength/2;
height = scalePtr->width;
x = TkScaleValueToPixel(scalePtr, scalePtr->value) - width;
y += scalePtr->borderWidth;
shadowWidth = scalePtr->borderWidth/2;
if (shadowWidth == 0) {
shadowWidth = 1;
}
Tk_Draw3DRectangle(tkwin, drawable, sliderBorder,
x, y, 2*width, height, shadowWidth, scalePtr->sliderRelief);
x += shadowWidth;
y += shadowWidth;
width -= shadowWidth;
height -= 2*shadowWidth;
Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x, y, width, height,
shadowWidth, scalePtr->sliderRelief);
Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x+width, y,
width, height, shadowWidth, scalePtr->sliderRelief);
/*
* Draw the label at the top of the scale.
*/
if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) {
Tk_FontMetrics fm;
Tk_GetFontMetrics(scalePtr->tkfont, &fm);
Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
scalePtr->tkfont, scalePtr->label,
scalePtr->labelLength, scalePtr->inset + fm.ascent/2,
scalePtr->horizLabelY + fm.ascent);
}
}
/*
*----------------------------------------------------------------------
*
* DisplayHorizontalValue --
*
* This function is called to display values (scale readings) for
* horizontally-oriented scales.
*
* Results:
* None.
*
* Side effects:
* The numerical value corresponding to value is displayed with its
* bottom edge at "bottom", and at a horizontal position in the scale
* that corresponds to "value".
*
*----------------------------------------------------------------------
*/
static void
DisplayHorizontalValue(
register TkScale *scalePtr, /* Information about widget in which to
* display value. */
Drawable drawable, /* Pixmap or window in which to draw the
* value. */
double value, /* X-coordinate of number to display,
* specified in application coords, not in
* pixels (we'll compute pixels). */
int top) /* Y-coordinate of top edge of text, specified
* in pixels. */
{
register Tk_Window tkwin = scalePtr->tkwin;
int x, y, length, width;
char valueString[TCL_DOUBLE_SPACE];
Tk_FontMetrics fm;
x = TkScaleValueToPixel(scalePtr, value);
Tk_GetFontMetrics(scalePtr->tkfont, &fm);
y = top + fm.ascent;
sprintf(valueString, scalePtr->format, value);
length = (int) strlen(valueString);
width = Tk_TextWidth(scalePtr->tkfont, valueString, length);
/*
* Adjust the x-coordinate if necessary to keep the text entirely inside
* the window.
*/
x -= (width)/2;
if (x < (scalePtr->inset + SPACING)) {
x = scalePtr->inset + SPACING;
}
/*
* Check the right border so use starting point +text width for the check.
*/
if (x + width >= (Tk_Width(tkwin) - scalePtr->inset)) {
x = Tk_Width(tkwin) - scalePtr->inset - SPACING - width;
}
Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC,
scalePtr->tkfont, valueString, length, x, y);
}
/*
*----------------------------------------------------------------------
*
* TkpDisplayScale --
*
* This function is invoked as an idle handler to redisplay the contents
* of a scale widget.
*
* Results:
* None.
*
* Side effects:
* The scale gets redisplayed.
*
*----------------------------------------------------------------------
*/
void
TkpDisplayScale(
ClientData clientData) /* Widget record for scale. */
{
TkScale *scalePtr = (TkScale *) clientData;
Tk_Window tkwin = scalePtr->tkwin;
Tcl_Interp *interp = scalePtr->interp;
Pixmap pixmap;
int result;
char string[TCL_DOUBLE_SPACE];
XRectangle drawnArea;
Tcl_DString buf;
scalePtr->flags &= ~REDRAW_PENDING;
if ((scalePtr->tkwin == NULL) || !Tk_IsMapped(scalePtr->tkwin)) {
goto done;
}
/*
* Invoke the scale's command if needed.
*/
Tcl_Preserve(scalePtr);
if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
Tcl_Preserve(interp);
sprintf(string, scalePtr->format, scalePtr->value);
Tcl_DStringInit(&buf);
Tcl_DStringAppend(&buf, scalePtr->command, -1);
Tcl_DStringAppend(&buf, " ", -1);
Tcl_DStringAppend(&buf, string, -1);
result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
Tcl_DStringFree(&buf);
if (result != TCL_OK) {
Tcl_AddErrorInfo(interp, "\n (command executed by scale)");
Tcl_BackgroundException(interp, result);
}
Tcl_Release(interp);
}
scalePtr->flags &= ~INVOKE_COMMAND;
if (scalePtr->flags & SCALE_DELETED) {
Tcl_Release(scalePtr);
return;
}
Tcl_Release(scalePtr);
#ifndef TK_NO_DOUBLE_BUFFERING
/*
* In order to avoid screen flashes, this function redraws the scale in a
* pixmap, then copies the pixmap to the screen in a single operation.
* This means that there's no point in time where the on-sreen image has
* been cleared.
*/
pixmap = Tk_GetPixmap(scalePtr->display, Tk_WindowId(tkwin),
Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
#else
pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */
drawnArea.x = 0;
drawnArea.y = 0;
drawnArea.width = Tk_Width(tkwin);
drawnArea.height = Tk_Height(tkwin);
/*
* Much of the redisplay is done totally differently for horizontal and
* vertical scales. Handle the part that's different.
*/
if (scalePtr->orient == ORIENT_VERTICAL) {
DisplayVerticalScale(scalePtr, pixmap, &drawnArea);
} else {
DisplayHorizontalScale(scalePtr, pixmap, &drawnArea);
}
/*
* Now handle the part of redisplay that is the same for horizontal and
* vertical scales: border and traversal highlight.
*/
if (scalePtr->flags & REDRAW_OTHER) {
if (scalePtr->relief != TK_RELIEF_FLAT) {
Tk_Draw3DRectangle(tkwin, pixmap, scalePtr->bgBorder,
scalePtr->highlightWidth, scalePtr->highlightWidth,
Tk_Width(tkwin) - 2*scalePtr->highlightWidth,
Tk_Height(tkwin) - 2*scalePtr->highlightWidth,
scalePtr->borderWidth, scalePtr->relief);
}
if (scalePtr->highlightWidth != 0) {
GC gc;
if (scalePtr->flags & GOT_FOCUS) {
gc = Tk_GCForColor(scalePtr->highlightColorPtr, pixmap);
} else {
gc = Tk_GCForColor(
Tk_3DBorderColor(scalePtr->highlightBorder), pixmap);
}
Tk_DrawFocusHighlight(tkwin, gc, scalePtr->highlightWidth, pixmap);
}
}
#ifndef TK_NO_DOUBLE_BUFFERING
/*
* Copy the information from the off-screen pixmap onto the screen, then
* delete the pixmap.
*/
XCopyArea(scalePtr->display, pixmap, Tk_WindowId(tkwin),
scalePtr->copyGC, drawnArea.x, drawnArea.y, drawnArea.width,
drawnArea.height, drawnArea.x, drawnArea.y);
Tk_FreePixmap(scalePtr->display, pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
done:
scalePtr->flags &= ~REDRAW_ALL;
}
/*
*----------------------------------------------------------------------
*
* TkpScaleElement --
*
* Determine which part of a scale widget lies under a given point.
*
* Results:
* The return value is either TROUGH1, SLIDER, TROUGH2, or OTHER,
* depending on which of the scale's active elements (if any) is under
* the point at (x,y).
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
TkpScaleElement(
TkScale *scalePtr, /* Widget record for scale. */
int x, int y) /* Coordinates within scalePtr's window. */
{
int sliderFirst;
if (scalePtr->orient == ORIENT_VERTICAL) {
if ((x < scalePtr->vertTroughX)
|| (x >= (scalePtr->vertTroughX + 2*scalePtr->borderWidth +
scalePtr->width))) {
return OTHER;
}
if ((y < scalePtr->inset)
|| (y >= (Tk_Height(scalePtr->tkwin) - scalePtr->inset))) {
return OTHER;
}
sliderFirst = TkScaleValueToPixel(scalePtr, scalePtr->value)
- scalePtr->sliderLength/2;
if (y < sliderFirst) {
return TROUGH1;
}
if (y < (sliderFirst+scalePtr->sliderLength)) {
return SLIDER;
}
return TROUGH2;
}
if ((y < scalePtr->horizTroughY)
|| (y >= (scalePtr->horizTroughY + 2*scalePtr->borderWidth +
scalePtr->width))) {
return OTHER;
}
if ((x < scalePtr->inset)
|| (x >= (Tk_Width(scalePtr->tkwin) - scalePtr->inset))) {
return OTHER;
}
sliderFirst = TkScaleValueToPixel(scalePtr, scalePtr->value)
- scalePtr->sliderLength/2;
if (x < sliderFirst) {
return TROUGH1;
}
if (x < (sliderFirst+scalePtr->sliderLength)) {
return SLIDER;
}
return TROUGH2;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

483
unix/tkUnixScrlbr.c Normal file
View File

@@ -0,0 +1,483 @@
/*
* tkUnixScrollbar.c --
*
* This file implements the Unix specific portion of the scrollbar
* widget.
*
* Copyright (c) 1996 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "tkScrollbar.h"
/*
* Minimum slider length, in pixels (designed to make sure that the slider is
* always easy to grab with the mouse).
*/
#define MIN_SLIDER_LENGTH 5
/*
* Declaration of Unix specific scrollbar structure.
*/
typedef struct UnixScrollbar {
TkScrollbar info; /* Generic scrollbar info. */
GC troughGC; /* For drawing trough. */
GC copyGC; /* Used for copying from pixmap onto screen. */
} UnixScrollbar;
/*
* The class procedure table for the scrollbar widget. All fields except size
* are left initialized to NULL, which should happen automatically since the
* variable is declared at this scope.
*/
const Tk_ClassProcs tkpScrollbarProcs = {
sizeof(Tk_ClassProcs), /* size */
NULL, /* worldChangedProc */
NULL, /* createProc */
NULL /* modalProc */
};
/*
*----------------------------------------------------------------------
*
* TkpCreateScrollbar --
*
* Allocate a new TkScrollbar structure.
*
* Results:
* Returns a newly allocated TkScrollbar structure.
*
* Side effects:
* Registers an event handler for the widget.
*
*----------------------------------------------------------------------
*/
TkScrollbar *
TkpCreateScrollbar(
Tk_Window tkwin)
{
UnixScrollbar *scrollPtr = ckalloc(sizeof(UnixScrollbar));
scrollPtr->troughGC = None;
scrollPtr->copyGC = None;
Tk_CreateEventHandler(tkwin,
ExposureMask|StructureNotifyMask|FocusChangeMask,
TkScrollbarEventProc, scrollPtr);
return (TkScrollbar *) scrollPtr;
}
/*
*--------------------------------------------------------------
*
* TkpDisplayScrollbar --
*
* This procedure redraws the contents of a scrollbar window. It is
* invoked as a do-when-idle handler, so it only runs when there's
* nothing else for the application to do.
*
* Results:
* None.
*
* Side effects:
* Information appears on the screen.
*
*--------------------------------------------------------------
*/
void
TkpDisplayScrollbar(
ClientData clientData) /* Information about window. */
{
register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
register Tk_Window tkwin = scrollPtr->tkwin;
XPoint points[7];
Tk_3DBorder border;
int relief, width, elementBorderWidth;
Pixmap pixmap;
if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
goto done;
}
if (scrollPtr->vertical) {
width = Tk_Width(tkwin) - 2*scrollPtr->inset;
} else {
width = Tk_Height(tkwin) - 2*scrollPtr->inset;
}
elementBorderWidth = scrollPtr->elementBorderWidth;
if (elementBorderWidth < 0) {
elementBorderWidth = scrollPtr->borderWidth;
}
/*
* In order to avoid screen flashes, this procedure redraws the scrollbar
* in a pixmap, then copies the pixmap to the screen in a single
* operation. This means that there's no point in time where the on-sreen
* image has been cleared.
*/
pixmap = Tk_GetPixmap(scrollPtr->display, Tk_WindowId(tkwin),
Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
if (scrollPtr->highlightWidth != 0) {
GC gc;
if (scrollPtr->flags & GOT_FOCUS) {
gc = Tk_GCForColor(scrollPtr->highlightColorPtr, pixmap);
} else {
gc = Tk_GCForColor(scrollPtr->highlightBgColorPtr, pixmap);
}
Tk_DrawFocusHighlight(tkwin, gc, scrollPtr->highlightWidth, pixmap);
}
Tk_Draw3DRectangle(tkwin, pixmap, scrollPtr->bgBorder,
scrollPtr->highlightWidth, scrollPtr->highlightWidth,
Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
scrollPtr->borderWidth, scrollPtr->relief);
XFillRectangle(scrollPtr->display, pixmap,
((UnixScrollbar*)scrollPtr)->troughGC,
scrollPtr->inset, scrollPtr->inset,
(unsigned) (Tk_Width(tkwin) - 2*scrollPtr->inset),
(unsigned) (Tk_Height(tkwin) - 2*scrollPtr->inset));
/*
* Draw the top or left arrow. The coordinates of the polygon points
* probably seem odd, but they were carefully chosen with respect to X's
* rules for filling polygons. These point choices cause the arrows to
* just fill the narrow dimension of the scrollbar and be properly
* centered.
*/
if (scrollPtr->activeField == TOP_ARROW) {
border = scrollPtr->activeBorder;
relief = scrollPtr->activeField == TOP_ARROW ? scrollPtr->activeRelief
: TK_RELIEF_RAISED;
} else {
border = scrollPtr->bgBorder;
relief = TK_RELIEF_RAISED;
}
if (scrollPtr->vertical) {
points[0].x = scrollPtr->inset - 1;
points[0].y = scrollPtr->arrowLength + scrollPtr->inset - 1;
points[1].x = width + scrollPtr->inset;
points[1].y = points[0].y;
points[2].x = width/2 + scrollPtr->inset;
points[2].y = scrollPtr->inset - 1;
Tk_Fill3DPolygon(tkwin, pixmap, border, points, 3,
elementBorderWidth, relief);
} else {
points[0].x = scrollPtr->arrowLength + scrollPtr->inset - 1;
points[0].y = scrollPtr->inset - 1;
points[1].x = scrollPtr->inset;
points[1].y = width/2 + scrollPtr->inset;
points[2].x = points[0].x;
points[2].y = width + scrollPtr->inset;
Tk_Fill3DPolygon(tkwin, pixmap, border, points, 3,
elementBorderWidth, relief);
}
/*
* Display the bottom or right arrow.
*/
if (scrollPtr->activeField == BOTTOM_ARROW) {
border = scrollPtr->activeBorder;
relief = scrollPtr->activeField == BOTTOM_ARROW
? scrollPtr->activeRelief : TK_RELIEF_RAISED;
} else {
border = scrollPtr->bgBorder;
relief = TK_RELIEF_RAISED;
}
if (scrollPtr->vertical) {
points[0].x = scrollPtr->inset;
points[0].y = Tk_Height(tkwin) - scrollPtr->arrowLength
- scrollPtr->inset + 1;
points[1].x = width/2 + scrollPtr->inset;
points[1].y = Tk_Height(tkwin) - scrollPtr->inset;
points[2].x = width + scrollPtr->inset;
points[2].y = points[0].y;
Tk_Fill3DPolygon(tkwin, pixmap, border,
points, 3, elementBorderWidth, relief);
} else {
points[0].x = Tk_Width(tkwin) - scrollPtr->arrowLength
- scrollPtr->inset + 1;
points[0].y = scrollPtr->inset - 1;
points[1].x = points[0].x;
points[1].y = width + scrollPtr->inset;
points[2].x = Tk_Width(tkwin) - scrollPtr->inset;
points[2].y = width/2 + scrollPtr->inset;
Tk_Fill3DPolygon(tkwin, pixmap, border,
points, 3, elementBorderWidth, relief);
}
/*
* Display the slider.
*/
if (scrollPtr->activeField == SLIDER) {
border = scrollPtr->activeBorder;
relief = scrollPtr->activeField == SLIDER ? scrollPtr->activeRelief
: TK_RELIEF_RAISED;
} else {
border = scrollPtr->bgBorder;
relief = TK_RELIEF_RAISED;
}
if (scrollPtr->vertical) {
Tk_Fill3DRectangle(tkwin, pixmap, border,
scrollPtr->inset, scrollPtr->sliderFirst,
width, scrollPtr->sliderLast - scrollPtr->sliderFirst,
elementBorderWidth, relief);
} else {
Tk_Fill3DRectangle(tkwin, pixmap, border,
scrollPtr->sliderFirst, scrollPtr->inset,
scrollPtr->sliderLast - scrollPtr->sliderFirst, width,
elementBorderWidth, relief);
}
/*
* Copy the information from the off-screen pixmap onto the screen, then
* delete the pixmap.
*/
XCopyArea(scrollPtr->display, pixmap, Tk_WindowId(tkwin),
((UnixScrollbar*)scrollPtr)->copyGC, 0, 0,
(unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin), 0, 0);
Tk_FreePixmap(scrollPtr->display, pixmap);
done:
scrollPtr->flags &= ~REDRAW_PENDING;
}
/*
*----------------------------------------------------------------------
*
* TkpComputeScrollbarGeometry --
*
* After changes in a scrollbar's size or configuration, this procedure
* recomputes various geometry information used in displaying the
* scrollbar.
*
* Results:
* None.
*
* Side effects:
* The scrollbar will be displayed differently.
*
*----------------------------------------------------------------------
*/
extern void
TkpComputeScrollbarGeometry(
register TkScrollbar *scrollPtr)
/* Scrollbar whose geometry may have
* changed. */
{
int width, fieldLength;
if (scrollPtr->highlightWidth < 0) {
scrollPtr->highlightWidth = 0;
}
scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
width = (scrollPtr->vertical) ? Tk_Width(scrollPtr->tkwin)
: Tk_Height(scrollPtr->tkwin);
scrollPtr->arrowLength = width - 2*scrollPtr->inset + 1;
fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
: Tk_Width(scrollPtr->tkwin))
- 2*(scrollPtr->arrowLength + scrollPtr->inset);
if (fieldLength < 0) {
fieldLength = 0;
}
scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction;
/*
* Adjust the slider so that some piece of it is always displayed in the
* scrollbar and so that it has at least a minimal width (so it can be
* grabbed with the mouse).
*/
if (scrollPtr->sliderFirst > fieldLength - MIN_SLIDER_LENGTH) {
scrollPtr->sliderFirst = fieldLength - MIN_SLIDER_LENGTH;
}
if (scrollPtr->sliderFirst < 0) {
scrollPtr->sliderFirst = 0;
}
if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) {
scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
}
if (scrollPtr->sliderLast > fieldLength) {
scrollPtr->sliderLast = fieldLength;
}
scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;
/*
* Register the desired geometry for the window (leave enough space for
* the two arrows plus a minimum-size slider, plus border around the whole
* window, if any). Then arrange for the window to be redisplayed.
*/
if (scrollPtr->vertical) {
Tk_GeometryRequest(scrollPtr->tkwin,
scrollPtr->width + 2*scrollPtr->inset,
2*(scrollPtr->arrowLength + scrollPtr->borderWidth
+ scrollPtr->inset));
} else {
Tk_GeometryRequest(scrollPtr->tkwin,
2*(scrollPtr->arrowLength + scrollPtr->borderWidth
+ scrollPtr->inset), scrollPtr->width + 2*scrollPtr->inset);
}
Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset);
}
/*
*----------------------------------------------------------------------
*
* TkpDestroyScrollbar --
*
* Free data structures associated with the scrollbar control.
*
* Results:
* None.
*
* Side effects:
* Frees the GCs associated with the scrollbar.
*
*----------------------------------------------------------------------
*/
void
TkpDestroyScrollbar(
TkScrollbar *scrollPtr)
{
UnixScrollbar *unixScrollPtr = (UnixScrollbar *)scrollPtr;
if (unixScrollPtr->troughGC != None) {
Tk_FreeGC(scrollPtr->display, unixScrollPtr->troughGC);
}
if (unixScrollPtr->copyGC != None) {
Tk_FreeGC(scrollPtr->display, unixScrollPtr->copyGC);
}
}
/*
*----------------------------------------------------------------------
*
* TkpConfigureScrollbar --
*
* This procedure is called after the generic code has finished
* processing configuration options, in order to configure platform
* specific options.
*
* Results:
* None.
*
* Side effects:
* Configuration info may get changed.
*
*----------------------------------------------------------------------
*/
void
TkpConfigureScrollbar(
register TkScrollbar *scrollPtr)
/* Information about widget; may or may not
* already have values for some fields. */
{
XGCValues gcValues;
GC new;
UnixScrollbar *unixScrollPtr = (UnixScrollbar *) scrollPtr;
Tk_SetBackgroundFromBorder(scrollPtr->tkwin, scrollPtr->bgBorder);
gcValues.foreground = scrollPtr->troughColorPtr->pixel;
new = Tk_GetGC(scrollPtr->tkwin, GCForeground, &gcValues);
if (unixScrollPtr->troughGC != None) {
Tk_FreeGC(scrollPtr->display, unixScrollPtr->troughGC);
}
unixScrollPtr->troughGC = new;
if (unixScrollPtr->copyGC == None) {
gcValues.graphics_exposures = False;
unixScrollPtr->copyGC = Tk_GetGC(scrollPtr->tkwin,
GCGraphicsExposures, &gcValues);
}
}
/*
*--------------------------------------------------------------
*
* TkpScrollbarPosition --
*
* Determine the scrollbar element corresponding to a given position.
*
* Results:
* One of TOP_ARROW, TOP_GAP, etc., indicating which element of the
* scrollbar covers the position given by (x, y). If (x,y) is outside the
* scrollbar entirely, then OUTSIDE is returned.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
int
TkpScrollbarPosition(
register TkScrollbar *scrollPtr,
/* Scrollbar widget record. */
int x, int y) /* Coordinates within scrollPtr's window. */
{
int length, width, tmp;
register const int inset = scrollPtr->inset;
if (scrollPtr->vertical) {
length = Tk_Height(scrollPtr->tkwin);
width = Tk_Width(scrollPtr->tkwin);
} else {
tmp = x;
x = y;
y = tmp;
length = Tk_Width(scrollPtr->tkwin);
width = Tk_Height(scrollPtr->tkwin);
}
if (x<inset || x>=width-inset || y<inset || y>=length-inset) {
return OUTSIDE;
}
/*
* All of the calculations in this procedure mirror those in
* TkpDisplayScrollbar. Be sure to keep the two consistent.
*/
if (y < inset + scrollPtr->arrowLength) {
return TOP_ARROW;
}
if (y < scrollPtr->sliderFirst) {
return TOP_GAP;
}
if (y < scrollPtr->sliderLast) {
return SLIDER;
}
if (y >= length - (scrollPtr->arrowLength + inset)) {
return BOTTOM_ARROW;
}
return BOTTOM_GAP;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

1544
unix/tkUnixSelect.c Normal file

File diff suppressed because it is too large Load Diff

2039
unix/tkUnixSend.c Normal file

File diff suppressed because it is too large Load Diff

7421
unix/tkUnixWm.c Normal file

File diff suppressed because it is too large Load Diff

153
unix/tkUnixXId.c Normal file
View File

@@ -0,0 +1,153 @@
/*
* tkUnixXId.c --
*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkUnixInt.h"
/*
*----------------------------------------------------------------------
*
* Tk_FreeXId --
*
* This function is called to indicate that an X resource identifier is
* now free.
*
* Results:
* None.
*
* Side effects:
* The identifier is added to the stack of free identifiers for its
* display, so that it can be re-used.
*
*----------------------------------------------------------------------
*/
void
Tk_FreeXId(
Display *display, /* Display for which xid was allocated. */
XID xid) /* Identifier that is no longer in use. */
{
/*
* This does nothing, because the XC-MISC extension takes care of
* freeing XIDs for us. It has been a standard X11 extension for
* about 15 years as of 2008. Keith Packard and another X.org
* developer suggested that we remove the previous code that used:
* #define XLIB_ILLEGAL_ACCESS.
*/
}
/*
*----------------------------------------------------------------------
*
* Tk_GetPixmap --
*
* Same as the XCreatePixmap function except that it manages resource
* identifiers better.
*
* Results:
* Returns a new pixmap.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
Pixmap
Tk_GetPixmap(
Display *display, /* Display for new pixmap. */
Drawable d, /* Drawable where pixmap will be used. */
int width, int height, /* Dimensions of pixmap. */
int depth) /* Bits per pixel for pixmap. */
{
return XCreatePixmap(display, d, (unsigned) width, (unsigned) height,
(unsigned) depth);
}
/*
*----------------------------------------------------------------------
*
* Tk_FreePixmap --
*
* Same as the XFreePixmap function except that it also marks the
* resource identifier as free.
*
* Results:
* None.
*
* Side effects:
* The pixmap is freed in the X server and its resource identifier is
* saved for re-use.
*
*----------------------------------------------------------------------
*/
void
Tk_FreePixmap(
Display *display, /* Display for which pixmap was allocated. */
Pixmap pixmap) /* Identifier for pixmap. */
{
XFreePixmap(display, pixmap);
Tk_FreeXId(display, (XID) pixmap);
}
/*
*----------------------------------------------------------------------
*
* TkpScanWindowId --
*
* Given a string, produce the corresponding Window Id.
*
* Results:
* The return value is normally TCL_OK; in this case *idPtr will be set
* to the Window value equivalent to string. If string is improperly
* formed then TCL_ERROR is returned and an error message will be left in
* the interp's result.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
TkpScanWindowId(
Tcl_Interp *interp,
const char *string,
Window *idPtr)
{
int code;
Tcl_Obj obj;
obj.refCount = 1;
obj.bytes = (char *) string; /* DANGER?! */
obj.length = strlen(string);
obj.typePtr = NULL;
code = Tcl_GetLongFromObj(interp, &obj, (long *)idPtr);
if (obj.refCount > 1) {
Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
}
if (obj.typePtr && obj.typePtr->freeIntRepProc) {
obj.typePtr->freeIntRepProc(&obj);
}
return code;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/