Import Tk 8.6.6 (as of svn r86089)
This commit is contained in:
1700
unix/Makefile.in
Normal file
1700
unix/Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
173
unix/README
Normal file
173
unix/README
Normal 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
1
unix/aclocal.m4
vendored
Normal file
@@ -0,0 +1 @@
|
||||
builtin(include,../unix/tcl.m4)
|
||||
12430
unix/configure
vendored
Normal file
12430
unix/configure
vendored
Normal file
File diff suppressed because it is too large
Load Diff
857
unix/configure.in
Normal file
857
unix/configure.in
Normal 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
528
unix/install-sh
Normal 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
117
unix/installManPage
Normal 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
40
unix/license.terms
Normal 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
3138
unix/tcl.m4
Normal file
File diff suppressed because it is too large
Load Diff
15
unix/tk.pc.in
Normal file
15
unix/tk.pc.in
Normal 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
54
unix/tk.spec
Normal 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
156
unix/tkAppInit.c
Normal 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
256
unix/tkConfig.h.in
Normal 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
97
unix/tkConfig.sh.in
Normal 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
265
unix/tkUnix.c
Normal 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
500
unix/tkUnix3d.c
Normal 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
1021
unix/tkUnixButton.c
Normal file
File diff suppressed because it is too large
Load Diff
450
unix/tkUnixColor.c
Normal file
450
unix/tkUnixColor.c
Normal 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
50
unix/tkUnixConfig.c
Normal 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
651
unix/tkUnixCursor.c
Normal 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
533
unix/tkUnixDefault.h
Normal 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
193
unix/tkUnixDialog.c
Normal 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
243
unix/tkUnixDraw.c
Normal 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
1185
unix/tkUnixEmbed.c
Normal file
File diff suppressed because it is too large
Load Diff
773
unix/tkUnixEvent.c
Normal file
773
unix/tkUnixEvent.c
Normal 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
149
unix/tkUnixFocus.c
Normal 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
3323
unix/tkUnixFont.c
Normal file
File diff suppressed because it is too large
Load Diff
162
unix/tkUnixInit.c
Normal file
162
unix/tkUnixInit.c
Normal 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
35
unix/tkUnixInt.h
Normal 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
509
unix/tkUnixKey.c
Normal 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
1823
unix/tkUnixMenu.c
Normal file
File diff suppressed because it is too large
Load Diff
476
unix/tkUnixMenubu.c
Normal file
476
unix/tkUnixMenubu.c
Normal 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
192
unix/tkUnixPort.h
Normal 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
1202
unix/tkUnixRFont.c
Normal file
File diff suppressed because it is too large
Load Diff
717
unix/tkUnixScale.c
Normal file
717
unix/tkUnixScale.c
Normal 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
483
unix/tkUnixScrlbr.c
Normal 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
1544
unix/tkUnixSelect.c
Normal file
File diff suppressed because it is too large
Load Diff
2039
unix/tkUnixSend.c
Normal file
2039
unix/tkUnixSend.c
Normal file
File diff suppressed because it is too large
Load Diff
7421
unix/tkUnixWm.c
Normal file
7421
unix/tkUnixWm.c
Normal file
File diff suppressed because it is too large
Load Diff
153
unix/tkUnixXId.c
Normal file
153
unix/tkUnixXId.c
Normal 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:
|
||||
*/
|
||||
Reference in New Issue
Block a user