>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X " :F $CONFIG_FILES "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+
+ esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/ng/Togl2.1/configure.in b/ng/Togl2.1/configure.in
new file mode 100755
index 00000000..836073c4
--- /dev/null
+++ b/ng/Togl2.1/configure.in
@@ -0,0 +1,281 @@
+#!/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 Tcl installation
+dnl to configure the system for the local environment.
+#
+# RCS: @(#) $Id: configure.in,v 1.17 2009/03/03 21:49:56 gregcouch Exp $
+
+#-----------------------------------------------------------------------
+# Sample configure.in for Tcl Extensions. The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Set your package name and version numbers here.
+#
+# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
+# set as provided. These will also be added as -D defs in your Makefile
+# so you can encode the package version directly into the source files.
+#-----------------------------------------------------------------------
+
+AC_INIT([Togl], [2.1])
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+TEA_INIT([3.7])
+
+AC_CONFIG_AUX_DIR(tclconfig)
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+TEA_PATH_TKCONFIG
+TEA_LOAD_TKCONFIG
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+TEA_PREFIX
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
+# the basic setup necessary to compile executables.
+#-----------------------------------------------------------------------
+
+TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+TOGL_ENABLE_STUBS
+
+TEA_ADD_SOURCES([togl.c toglProcAddr.c toglStubInit.c])
+# togl_ws.h is added in Makefile.in because it is generated
+TEA_ADD_HEADERS([togl.h toglDecls.h])
+TEA_ADD_INCLUDES([])
+TEA_ADD_LIBS([])
+TEA_ADD_CFLAGS([])
+if test "${USE_STUBS}" = "1" ; then
+ TEA_ADD_STUB_SOURCES([toglStubLib.c])
+fi
+TEA_ADD_TCL_SOURCES([])
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_sample in this case) so
+# that we create the export library with the dll.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
+# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
+#CLEANFILES="pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ AC_DEFINE(BUILD_togl, 1, [Build windows export dll])
+ CLEANFILES="$CLEANFILES *.lib *.dll *.exp *.ilk *.pdb vc*.pch *.manifest"
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ CLEANFILES="so_locations"
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+fi
+AC_SUBST(CLEANFILES)
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Choose which headers you need. Extension authors should try very
+# hard to only rely on the Tcl public header files. Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
+#--------------------------------------------------------------------
+
+# find Tcl, Tk, and X11 headers
+#TEA_PUBLIC_TCL_HEADERS
+TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+TEA_PRIVATE_TK_HEADERS
+TEA_PATH_X
+
+# find autostereo header, lib, and daemon
+AC_ARG_WITH([autostereo],
+ [AS_HELP_STRING([--with-autostereo],
+ [directory with autostereo source (for SGI)])],
+ [with_autostereo=${withval}])
+AC_ARG_WITH([autostereod],
+ [AS_HELP_STRING([--with-autostereod],
+ [path to autostereod daemon (for SGI)])],
+ [with_autostereod=${withval}])
+AC_ARG_VAR([AUTOSTEREOD], [Path to autostereod for SGI IRIX computers])
+
+AC_MSG_CHECKING([for autostereo directory])
+if test x"${with_autostereo}" != x ; then
+ if test -f "${with_autostereo}/lib/autostereo.h" ; then
+ with_autostereo=`(cd ${with_autostereo}; pwd)`
+ TEA_ADD_INCLUDES([-I${with_autostereo}/lib])
+ TEA_ADD_LIBS([-L${with_autostereo}/lib -lautostereo])
+ AC_DEFINE_UNQUOTED(HAVE_AUTOSTEREO, 1,
+ [Define this if you have the autostereo header])
+ else
+ AC_MSG_ERROR([${with_autostereo} directory doesn't contain lib/autostereo.h])
+ fi
+fi
+
+AC_PATH_PROG([AUTOSTEREOD], [autostereod], [],
+ [`eval \"echo $sbindir\"`:$PATH:/sbin:/usr/sbin])
+
+
+# Choose OpenGL platform
+case "${TEA_WINDOWINGSYSTEM}" in
+ aqua)
+ AC_SUBST(TOGL_WINDOWINGSYSTEM,TOGL_AGL)
+ TEA_ADD_LIBS([-framework AGL -framework OpenGL -framework ApplicationServices])
+ # libGLU is implicit in OpenGL framework
+ LIBGLU=
+ ;;
+ x11)
+ AC_SUBST(TOGL_WINDOWINGSYSTEM,TOGL_X11)
+ AC_ARG_WITH([Xmu],
+ [AS_HELP_STRING([--with-Xmu],
+ [use system's shared Xmu library])],
+ [],
+ [with_Xmu=no])
+ AS_IF([test "x$with_Xmu" != xno],
+ [AC_CHECK_LIB([Xmu], [XmuLookupStandardColormap],
+ [TEA_ADD_LIBS([-lXmu])
+ AC_DEFINE(USE_SYSTEM_LIBXMU, 1,
+ [Define to use system Xmu library])
+ ],
+ [with_Xmu=no],
+ [-lXt -lX11]
+ )])
+ AS_IF([test "x$with_Xmu" = xno],
+ [TEA_ADD_SOURCES([Xmu/CmapAlloc.c Xmu/CrCmap.c Xmu/DelCmap.c Xmu/LookupCmap.c Xmu/StdCmap.c])])
+ TEA_ADD_LIBS([-lGL])
+ LIBGLU=-lGLU
+ TOGL_UNDEF_GET_PROC_ADDRESS
+ ;;
+ win32)
+ AC_SUBST(TOGL_WINDOWINGSYSTEM,TOGL_WGL)
+ TEA_ADD_LIBS([opengl32.lib user32.lib gdi32.lib])
+ if test "$GCC" = "yes" ; then
+ LIBGLU=-lglu32
+ else
+ # assume Microsoft compiler
+ LIBGLU=glu32.lib
+ fi
+ ;;
+ *)
+ AC_MSG_ERROR([Unsupported windowing system: ${TEA_WINDOWINGSYSTEM}])
+ ;;
+esac
+AC_SUBST(LIBGLU)
+AC_SUBST(TEA_WINDOWINGSYSTEM)
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_THREADS
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SHARED
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects. This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+TEA_CONFIG_CFLAGS
+# should be part of TEA_CONFIG_CFLAGS, but more visible modification here
+AC_SUBST(SHLIB_SUFFIX)
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SYMBOLS
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library. If you
+# can't for some reason, remove this definition. If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library. Add Tk too if necessary.
+#--------------------------------------------------------------------
+
+if test "${USE_STUBS}" = "1" ; then
+ AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
+ AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
+fi
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library. It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+TEA_MAKE_LIB
+
+if test "${USE_STUBS}" = "0" ; then
+ SHLIB_LD_LIBS=`echo "$SHLIB_LD_LIBS" | sed -e 's!stub!!g'`
+fi
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+TEA_PROG_TCLSH
+#TEA_PROG_WISH
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+# You may alternatively have a special pkgIndex.tcl.in or other files
+# which require substituting th AC variables in. Include these here.
+#--------------------------------------------------------------------
+
+AC_OUTPUT([Makefile pkgIndex.tcl togl_ws.h])
diff --git a/ng/Togl2.1/doc/README.txt b/ng/Togl2.1/doc/README.txt
new file mode 100644
index 00000000..07f6577b
--- /dev/null
+++ b/ng/Togl2.1/doc/README.txt
@@ -0,0 +1,2 @@
+This directory contains the documentation of Togl, the Tk OpenGL widget.
+The documentation also doubles as the contents of the Togl home page.
diff --git a/ng/Togl2.1/doc/capi.html b/ng/Togl2.1/doc/capi.html
new file mode 100644
index 00000000..b86c4a42
--- /dev/null
+++ b/ng/Togl2.1/doc/capi.html
@@ -0,0 +1,652 @@
+
+
+
+
+
+
+
+ Togl C API
+
+
+
+
+
+
+ Togl C API
+
+ Contents
+
+ - Compiling and linking C Togl Functions
+
- Setup and Initialization Functions
+
+ Togl_Init
,
+ Togl_InitStubs
+
+ - Drawing-related Commands
+
+ Togl_PostRedisplay
,
+ Togl_SwapBuffers
,
+ Togl_MakeCurrent
,
+ Togl_SwapInterval
+ Togl_CopyContext
+
+ - Query Functions
+
+ Togl_Ident
,
+ Togl_Width
,
+ Togl_Height
,
+ Togl_Interp
,
+ Togl_TkWin
,
+ Togl_GetProcAddr
,
+ Togl_ContextTag
+ Togl_UpdatePending
+ Togl_HasRGBA
+ Togl_IsDoubleBuffered
+ Togl_HasDepthBuffer
+ Togl_HasAccumulationBuffer
+ Togl_HasDestinationAlpha
+ Togl_HasStencilBuffer
+ Togl_StereoMode
+ Togl_HasMultisample
+
+ - Color Index Mode Functions
+
+ Togl_AllocColor
,
+ Togl_FreeColor
,
+ Togl_SetColor
+
+ - Font Functions
+
+ Togl_LoadBitmapFont
,
+ Togl_UnloadBitmapFont
,
+ Togl_WriteObj
,
+ Togl_WriteChars
+
+ - Client Data Functions
+
+ Togl_SetClientData
,
+ Togl_GetClientData
+
+ - Overlay Functions
+
+ Togl_UseLayer
,
+ Togl_ShowOverlay
,
+ Togl_HideOverlay
,
+ Togl_PostOveralyRedisplay
,
+ Togl_ExistsOverlay
,
+ Togl_GetOverlayTransparentValue
,
+ Togl_IsMappedOverlay
,
+ Togl_AllocColorOverlay
,
+ Togl_FreeColorOverlay
+
+ - Stereo Functions
+
+ Togl_Drawbuffer
,
+ Togl_Clear
+ Togl_Frustum
+ Togl_Ortho
+ Togl_NumEyes
+
+ - Image Functions
+
+
- Conversion Functions
+
+ Togl_GetToglFromObj
,
+ Togl_GetToglFromName
+
+
+
+
+
+
+
+
+ All Togl functions are found in the Togl header file.
+
+
+
+ #include "togl.h"
+
+
+
+
+ For portability, you should include the togl.h
header
+ before any other OpenGL headers
+ so it will compile on Microsoft Windows.
+
+
+ Before calling any Togl functions, you need to initialize it.
+ Regardless if you're using stubs (by defining USE_TOGL_STUBS
)
+ or not, the following code will properly initialize togl:
+
+
+if (Tcl_InitStubs(interp, "8.1", 0) == NULL
+|| Togl_InitStubs(interp, "2.0", 0) == NULL) {
+ /* fail */
+}
+
+
+
+ If you are using a prebuilt binary distribution,
+ you should be sure to define USE_TOGL_STUBS
beforehand.
+
+
+ See the source for the demo programs in the Togl source distribution
+ for working examples.
+
+
Linking
+
+
+ If you are using a prebuilt binary,
+ be sure to link against the stub library.
+ On Microsoft Windows,
+ link against Toglstub21.lib opengl32.lib user32.lib gdi32.lib
,
+ on Mac OS X,
+ link against -lToglstub2.1 -framework OpenGL
,
+ on other platforms,
+ link against -lToglstub2.1 -lGLU -lGL -lm
.
+
+
+ If building your own Togl package,
+ you can use the stubs interface or link in the Tcl and Tk libraries as well.
+ If using the stubs interface, link as shown above.
+ Otherwise:
+ on Microsoft Windows,
+ link against Togl21.lib tk84.lib tcl84.lib opengl32.lib user32.lib gdi32.lib
,
+ on Mac OS X,
+ link against -lTogl2.1 -framework Tk -framework Tcl -framework OpenGL
,
+ on other platforms,
+ link against -lTogl2.1 -ltk8.4 -ltcl8.4 -lGLU -lGL -lm
.
+
+
+
+
+ int Togl_Init(Tcl_Interp *interp)
+ -
+ Initializes the Togl module. This is typically called from the
+ Tk_Main() function
+ or other Tcl package initialization function that is directly linked
+ to the Togl (shared) library.
+ It is also indirectly called via
+ Tcl's
package require Togl
command.
+ If successful, the return value is TCL_OK.
+
+
+
+ -
+
const char *Togl_InitStubs(Tcl_Interp *interp, const char *version, int exact)
+ -
+ Loads the Togl package into the given
interp
reter
+ and initializes it.
+ version
should be "2.0"
or higher.
+ This is typically called from C/C++ code that accesses Togl's C API
+ and has installed Togl into the standard TCL hierarchy.
+ See the Tcl InitStubs(3) or the Tk TkInitStubs(3) manual pages for
+ more information.
+
+
+
+
+
+ void Togl_PostRedisplay(Togl *togl)
+ -
+ Signals that the widget should be redrawn. When Tk is next idle,
+ the
displaycommand
callback will be invoked.
+
+
+
+ void Togl_SwapBuffers(const Togl *togl)
+ -
+ Swaps the front and back color buffers for a double-buffered widget.
+
+ glFlush is executed if the window is single-buffered. So this call
+ works for both single- and double-buffered contexts. This is
+ typically called in the
displaycommand
callback function.
+
+
+
+ void Togl_MakeCurrent(const Togl *togl)
+ -
+ Sets the current rendering context to the given widget. This is done
+ automatically before any Togl callback functions is called. So the
+ call is only needed if you have multiple widgets with separate OpenGL
+ contexts. If the argument is NULL, then the rendering context is cleared
+ and subsequent OpenGL commands will fail.
+
+
+
+ Bool Togl_SwapInterval(const Togl *togl, int interval)
+ -
+ Returns True if successful.
+ Attempts to change the maximum refresh rate
+ by setting the minimum number of cycles between successive swap buffers.
+ For benchmarking purposes, you should set the swap interval to 0.
+
+
+
+ int Togl_CopyContext(const Togl *from, const Togl *to, unsigned int mask)
+ -
+ Copy a subset of the OpenGL context state from from one context
+ to another using the mask parameter who values are the same as
+
+ glPushAttrib.
+ The return value is TCL_OK if the context was copied.
+
+
+
+
+
+ char *Togl_Ident(const Togl *togl)
+ -
+ Returns a pointer to the identification string associated with a Togl
+ widget or NULL if there's no identifier string.
+
+
+
+ int Togl_Width(const Togl *togl)
+ -
+ Returns the width of the given Togl widget. Typically called in the
+
reshapecommand
callback function.
+
+
+
+ int Togl_Height(const Togl *togl)
+ -
+ Returns the height of the given Togl widget. Typically called in the
+
reshapecommand
callback function.
+
+
+
+ Tcl_Interp *Togl_Interp(const Togl *togl)
+ -
+ Returns the Tcl interpreter associated with the given Togl widget.
+
+
+ -
+
Tk_Window Togl_TkWin(const Togl *togl)
+ -
+ Returns the Tk window associated with the given Togl widget.
+
+
+
+ Togl_FuncPtr Togl_GetProcAddr(const char *funcname)
+ -
+ Platform-independent way to get OpenGL function pointers from a
+ function name.
+ Note that in Microsoft Windows (WGL) versions that
+ "the extension function addresses are unique for each pixel format.
+ All rendering contexts of a given pixel format
+ share the same extension function addresses."
+ And on *nix (GLX/X11) platforms,
+ "the function pointers returned are context independent"
+ (Linux ABI documentation).
+ The Mac OS X (AGL) platform acts like a *nix platform.
+
+
+
+ int Togl_ContextTag(const Togl *t)
+ -
+ Returns an integer that represents the context tag.
+ All Togl widgets with the same context tag share display lists.
+
+
+
+ Bool Togl_UpdatePending(const Togl *t)
+ -
+ Returns True if the window should be redrawn. See Togl_PostRedisplay.
+
+
+
+ Bool Togl_HasRGBA(const Togl *t)
+ -
+ Return True if Togl widget has a RBGA color buffer.
+ False means that the widget is using a color index buffer.
+
+
+
+ Bool Togl_IsDoubleBuffered(const Togl *t)
+ -
+ Return True if Togl widget is double buffered.
+
+
+
+ Bool Togl_HasDepthBuffer(const Togl *t)
+ -
+ Return True if Togl widget is has a depth buffer.
+
+
+
+ Bool Togl_HasAccumulationBuffer(const Togl *t)
+ -
+ Return True if Togl widget has an accumulation buffer.
+
+
+
+ Bool Togl_HasDestinationAlpha(const Togl *t)
+ -
+ Return True if Togl widget has a destination alpha buffer.
+
+
+
+ Bool Togl_HasStencilBuffer(const Togl *t)
+ -
+ Return True if Togl widget has a stencil buffer.
+
+
+
+ int Togl_StereoMode(const Togl *t)
+ -
+ Return current stereo mode. See ??
+
+
+
+ Bool Togl_HasMultisample(const Togl *t)
+ -
+ Return True if Togl widget has a multisample buffer.
+
+
+
+
+
+ These functions are only used for color index mode.
+
+
+ unsigned long Togl_AllocColor(Togl *togl, float red, float green, float blue)
+ -
+ Allocate a color from a read-only colormap. Given a color specified
+ by red, green, and blue return a colormap index (aka pixel value)
+ whose entry most closely matches the red, green, blue color. Red,
+ green, and blue are values in [0,1]. This function is only used in
+ color index mode when the
-privatecmap
option is false.
+
+
+
+ void Togl_FreeColor(Togl *togl, unsigned long index)
+ -
+ Free a color in a read-only colormap. Index is a value which was
+ returned by the Togl_AllocColor() function. This function is only
+ used in color index mode when the
-privatecmap
option
+ is false.
+
+
+
+ void Togl_SetColor(Togl *togl,
+ int index, float red, float green, float blue)
+ -
+ Load the colormap entry specified by index with the given red, green
+ and blue values. Red, green, and blue are values in [0,1]. This
+ function is only used in color index mode when the
+
-privatecmap
option is true.
+
+
+
+
+
+
+ These functions provide an interface to the simple bitmap font capabilities
+ that every OpenGL implementation provides.
+ Better font support is found in other C APIs, e.g.,
+ QuesoGLC
+ or FTGL.
+
+
+ Tcl_Obj *Togl_LoadBitmapFont(Togl *togl,
+ const char *fontname)
+ -
+ Load the named font as a set of
+
+ glBitmap display lists.
+ fontname may be any of the font description styles
+ accepted by the Tk font command.
+ For maximum portability, one of the standard Tk fonts,
+ Courier, Times, and Helvetica, should be used.
+ Unicode fonts are treated as if they have only have an 8-bit index
+ (so poorly).
+ If successful, a Togl BitmapFont object is returned.
+ NULL is returned on failure.
+
+
+
+ int Togl_UnloadBitmapFont(Togl *togl, Tcl_Obj *toglfont)
+
+ -
+ Destroys the bitmap display lists created by by Togl_LoadBitmapFont().
+ If successful, the return value is TCL_OK.
+
+
+
+ int Togl_WriteChars(const Togl *togl, const Tcl_Obj *toglfont, const char *string, int length)
+
+ Draw the given string.
+ If the given length is zero, then it is computed using strlen.
+ Returns the length of the drawn string.
+ -
+
+
+
+ int Togl_WriteObj(const Togl *togl, const Tcl_Obj *toglfont, Tcl_Obj *obj)
+
+ -
+ Tcl_Obj interface to
Tcl_WriteChars
.
+
+
+
+
+
+ Each Togl structure has a pointer to an arbitrary client data structure.
+
+
+ void Togl_SetClientData(Togl *togl, ClientData clientData)
+ -
+ Set the Togl widget's client data pointer to clientData.
+
+
+
+ ClientData Togl_GetClientData(const Togl *togl)
+ -
+ Return the Togl widget's client data pointer.
+
+
+
+
+
+
+ These functions are modeled after GLUT's overlay sub-API.
+
+
+ void Togl_UseLayer(Togl *togl, int layer)
+ -
+ Select the layer into which subsequent OpenGL rendering will be
+ directed. layer may be either TOGL_OVERLAY or
+ TOGL_NORMAL.
+
+
+
+ void Togl_ShowOverlay(Togl *togl)
+ -
+ Display the overlay planes, if any.
+
+
+
+ void Togl_HideOverlay(Togl *togl)
+ -
+ Hide the overlay planes, if any.
+
+
+
+ void Togl_PostOverlayRedisplay(Togl *togl)
+ -
+ Signal that the overlay planes should be redraw.
+ When Tk is next idle,
+ the
overlaydisplaycommand
callback will be invoked.
+
+
+
+ int Togl_ExistsOverlay(Togl *togl)
+ -
+ Returns 1 if overlay planes exist, 0 otherwise.
+
+
+
+ int Togl_GetOverlayTransparentValue(const Togl *togl)
+ -
+ Returns the color index of the overlay's transparent pixel value.
+
+
+
+ int Togl_IsMappedOverlay(const Togl *togl)
+ -
+ Returns 1 if the overlay planes are currently displayed, 0 otherwise.
+
+
+
+ unsigned long Togl_AllocColorOverlay(const Togl *togl,
+ float red, float green, float blue)
+ -
+ Allocate a color in the overlay planes. Red, green, and blue are
+ values in [0,1]. Return the color index or -1 if the allocation
+ fails.
+
+
+
+ void Togl_FreeColorOverlay(const Togl *togl, unsigned long index)
+ -
+ Free a color which was allocated with Togl_AllocColorOverlay().
+
+
+
+
+
+ Togl abstracts part of the stereo drawing process to seamlessly
+ support quad-buffered stereo as well as various alternative stereo
+ formats. The stereo viewing parameters, eyeseparation
+ and convergence
need to be set with the Togl's
+ stereo options.
+
+
+ void Togl_DrawBuffer(Togl *togl, GLenum mode)
+ -
+ Switch to OpenGL draw buffer.
+ Should be one of GL_BACK_LEFT, GL_BACK_RIGHT, GL_FRONT_LEFT, or
+ GL_FRONT_RIGHT.
+ It is not possible to draw in the left and right buffers at the same
+ time in the alternate stereo modes.
+
+
+
+ void Togl_Clear(const Togl *togl, GLbitfield mask)
+ -
+ Replacement for OpenGL's
+
+ glClear that takes into account the alternate stereo mode.
+
+
+
+ void Togl_Frustum(const Togl *togl, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)
+ -
+ Replacement for OpenGL's
+
+ glFrustum that takes into account the alternate stereo mode.
+
+
+
+ void Togl_Ortho(const Togl *togl, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)
+ -
+ Replacement for OpenGL's
+
+ glOrtho that takes into account the alternate stereo mode.
+
+
+
+ int Togl_NumEyes(const Togl *togl)
+ -
+
+
+ Stereo Example
+
+
+ This code works for quad-buffered stereo,
+ as well as the other stereo modes.
+
+
+if (Togl_NumEyes(togl) == 1) {
+ Togl_DrawBuffer(togl, GL_BACK);
+ Togl_Clear(togl);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ Togl_Frustum(togl, left, right, bottom, top, near, far);
+ glMatrixMode(GL_MODELVIEW);
+ draw image
+} else {
+ Togl_DrawBuffer(togl, GL_BACK_LEFT);
+ Togl_Clear(togl);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ Togl_Frustum(togl, left, right, bottom, top, near, far);
+ glMatrixMode(GL_MODELVIEW);
+ draw left-eye image
+ Togl_DrawBuffer(togl, GL_BACK_RIGHT);
+ Togl_Clear(togl);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ Togl_Frustum(togl, left, right, bottom, top, near, far);
+ glMatrixMode(GL_MODELVIEW);
+ draw right-eye image
+}
+Togl_SwapBuffers(togl);
+
+
+
+
+
+
+
+
+ int Togl_TakePhoto(Togl *togl, Tk_PhotoHandle photo)
+ -
+ Take a photo image of the current Togl window and place it in the
+ given
photo
object.
+ If the window is partially obscured,
+ either by other windows or by the edges of the display,
+ the results are undefined in the obscured region.
+ If successful, the return value is TCL_OK.
+
+
+
+
+
+ These functions aid the programmer when writing Togl callback functions.
+
+
+ int Togl_GetToglFromObj(Tcl_Interp *interp, Tcl_Obj *obj, Togl **toglPtr)
+ -
+ Attempt to return a Togl structure "toglPtr" from the Tcl object "obj".
+ If successful, the return value is TCL_OK.
+
+
+
+ int Togl_GetToglFromName(Tcl_Interp *interp, const char *cmdName, Togl **toglPtr)
+ -
+ Attempt to return a Togl structure "toglPtr" from the Tcl command name "cmdName".
+ If successful, the return value is TCL_OK.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ng/Togl2.1/doc/download.html b/ng/Togl2.1/doc/download.html
new file mode 100644
index 00000000..72b7c7b2
--- /dev/null
+++ b/ng/Togl2.1/doc/download.html
@@ -0,0 +1,340 @@
+
+
+
+
+
+
+
+ Downloading and Installing Togl
+
+
+
+
+
+
+ Downloading and Installing Togl
+
+ Contents
+
+
+
+
+
+
+
+ You should have
+ Tcl and Tk
+ installed on your computer.
+ Togl works with Tcl/Tk version 8.1 and up
+ (all recent testing has been with version 8.4).
+ The Mac OS X version requires version 8.4
+ (note: versions 8.4.12 and 8.4.13 have a bug when unmapping Togl widgets).
+
+
+ You must also have
+ OpenGL or
+ Mesa
+ (a free alternative to OpenGL with the same API)
+ installed on your computer.
+
+
+ And one should be familiar with Tcl, Tk, OpenGL,
+ and C programming to use Togl effectively.
+
+
+
+
+
+ Togl can be downloaded from the
+
+ SourceForge Files page.
+
+
+ Several prebuilt binary distributions are available
+ as well as a source distribution.
+
+
+
+ Installing prebuild binaries
+
+
+ Prebuilt binaries provide a Togl2.1 directory,
+ the togl.h, togl_ws.h and toglDecls.h include files,
+ and the togl stub library
+ (libToglstub2.1.a or Toglstub20.lib, etc).
+ The Togl2.1 directory needs to copied
+ into one of the directories on Tcl's package path
+ (type puts $auto_path
in the Tcl interpreter to see
+ the list of directories).
+ If you have C code that needs to access Togl's subroutines directly,
+ place the include file in the same place as Tcl's include file and
+ the stub library in the same place as Tcl's stub library.
+
+
Installing from source
+
+
+ Togl uses the Tcl Extension Architecture to be able to build on the
+ same platforms Tcl can be built on.
+ In addition to the Togl source,
+ you will need to have the Tcl and Tk source distributions
+ because not all installations have the needed Tcl and Tk internal header files.
+
+
+ How you link with Togl depends on how you're planning to use it.
+ There are basically three ways of using Togl with your application:
+
+ -
+ Install the Togl shared library and pkgIndex.tcl file
+ (using
make install
)
+ and link to the Togl stubs library with your executable or shared library.
+ In this case you must call Togl_InitStubs() (and probably Tcl_InitStubs()
+ — Tk_InitStubs is only needed if you call Tk functions).
+ This is the way the included Togl examples are built.
+
+ -
+ Link to the Togl shared library
+ or "compile in" the Togl object files
+ with your executable or shared library.
+ In this case you must call Togl_Init() from your C code
+ to initialize Togl.
+
+
-
+ Install the Togl shared library and pkgIndex.tcl file
+ (using
make install
)
+ and then load it using Tcl commands or Tcl_PkgRequire().
+ Then use Tcl commands to create and manipulate the Togl widget.
+
+
+ Since Togl is compiled into a shared library using the Tcl/Tk stubs-interface,
+ the same binary can be used with any version of Tck/Tk from 8.1 and up.
+ See README.stubs
for more info.
+
+
+ Specific platform notes follow:
+
+
+
+
+ Unix/X systems only need the public Tcl/Tk include files.
+ Just configure
, make
,
+ and optionally make install
.
+
+
+
+
+ Microsoft Windows platforms need tkWinInt.h
+ and other internal Tk header files. So you need a Tcl/Tk
+ source distribution in addition to the Togl distribution
+ (or copy over the various include files).
+
+ Here's the minimal way to build Togl with Tcl/Tk
+ using the gcc that is distributed
+ as part of the cygwin tools
+ (Microsoft's compilers work too):
+
+VER=8.4.12
+SRCDIR=`pwd`
+
+cd $SRCDIR/tcl$VER/win
+env 'CC=gcc -mno-cygwin' ./configure --enable-threads
+make libtclstub84.a
+
+cd $SRCDIR/tk$VER/win
+env 'CC=gcc -mno-cygwin' ./configure --enable-threads
+make libtkstub84.a
+
+cd $SRCDIR/Togl2.1
+env 'CC=gcc -mno-cygwin' ./configure --with-tcl=../tcl$VER/win --with-tk=../tk$VER/win
+
+make
+
+ The resulting Togl21.dll
and pkgIndex.tcl
+ should be installed into your Tcl installation just like any other package.
+
+
+ If you change all of the above make
's
+ to make install
instead,
+ then the Togl package is installed correctly.
+
+
+
+
+ These special instructions are for building the Aqua version of Togl.
+ Mac OS X needs tkMacOSXInt.h
+ and other internal Tk header files.
+ Unfortunately, the Tcl and Tk frameworks that Apple distributes
+ are missing the internal headers.
+ So you need a Tcl/Tk source distribution in addition to the Togl
+ distribution (or copy over the various include files).
+ You would probably want a newer version of Tcl and Tk anyway
+ because each minor revision of 8.4 has many Aqua bug fixes.
+
+ Here's one way to build Tcl, Tk, and Togl on Mac OS X
+ (assuming they are all in the same directory)
+ to install in your home directory:
+
+VER=8.4.12
+
+mkdir -p ~/bin
+make -C tcl$VER/macosx install PREFIX="${HOME}" INSTALL_PATH="${HOME}/Library/Frameworks"
+make -C tk$VER/macosx install PREFIX="${HOME}" INSTALL_PATH="${HOME}/Library/Frameworks" APPLICATION_INSTALL_PATH="${HOME}/Applications"
+
+cd Togl2.1
+./configure --prefix="${HOME}"
+make install
+
+
+
+
+
+ Version 1.0 — March, 1996
+
+
+ Version 1.1 (never officially released)
+
+ - Added Togl_LoadBitmapFont function
+
- Fixed a few bugs
+
+
+ Version 1.2 — November, 1996
+
+ - added swapbuffers and makecurrent Tcl commands
+
- more bug fixes
+
- upgraded to suport Tcl 7.6 and Tk 4.2
+
- added stereo and overlay plane support
+
- added Togl_Get/SetClientData() functions
+
- added Togl_DestroyFunc()
+
+
+ Version 1.3 — May 2, 1997
+
+ - fixed a bug in Togl_Configure()
+
- fixed a compilation problem in using Tcl_PkgProvide() with Tcl < 7.4
+
- new overlay functions: Togl_ExistsOverlay, Togl_GetOverlayTransparentValue,
+ Togl_IsMappedOverlay, Togl_AllocColorOverlay, Togl_FreeColorOverlay
+
- added X11 functions: Togl_Display, Togl_Screen, Togl_ScreenNumber,
+ Togl_Colormap
+
- added Togl_DumpToEpsFile function
+
- fixed a C++ compilation problem
+
- more robust overlay code
+
- added timers (Togl_TimerFunc) from Peter Dern and Elmar Gerwalin
+
+
+ Version 1.4 — September 17, 1997
+
+ - ported to Microsoft Windows NT (Robert Casto)
+
- updated for Tcl/Tk 8.0
+
- added many config flags (-redsize, -depthsize, etc) (Matthias Ott)
+
- added Togl_Set*Func() functions to reassign callback functions (Matthias Ott)
+
- added Togl_ResetDefaultCallbacks() and Togl_ClientData() functions (Greg Couch)
+
+
+ Version 1.5 — September 18, 1998
+
+ - fixed a few Unix and Microsoft Windows compilation bugs
+
- added Ben Evan's SGI stereo functions
+
- multiple expose events now reduced to one redraw
+
- destroying Togl widgets caused problems, patched by Adrian J. Chung
+
- added Togl_TkWin() function
+
- updated for Tcl/Tk 8.0p2
+
- added gears demo from Philip Quaife
+
- added
-sharelist
and -sharecontext
config flags
+ - fixed a few overlay update bugs
+
- added
-indirect
config flag
+
+
+ Version 1.6 — May 7, 2003
+
+ - added Togl_SetTimerFunc function
+
- updated for Tcl/Tk 8.0.5 and 8.1
+
- context sharing added for Microsoft Windows
+
- Macintosh support (by Paul Thiessen)
+
- Tcl/Tk stubs support — see README.tcl (by Jonas Beskow)
+
+
+ Version 1.7 — January 6, 2006
+
+ - added Mac OS X support
+
- enabled asking for quad-buffered stereo pixel formats on all platforms
+ (use -oldstereo on SGIs for splitscreen stereo — C API changed too)
+
- configuring the cursor is no longer slow
+
- added
-pixelformat
config flag
+ - added setgrid support (unfortunately many window managers can't cope with 1x1 pixel grid)
+
- only free context when last reference is gone
+
- switched to TEA-based configure (instead of editting make files)
+
+
+ Version 2.0 — April 22, 2008
+
+ - stubified C API
+
- replaced EPS support with TK photo image support
+
- simplified C API by requiring callback command options
+
- Added command arguments for create, destroy, etc. callbacks,
+ so there is a -createcommand option to the togl command (etc.).
+ (and removed Togl_*Func from the C API)
+
- added togl instance commands that call C API —
+ see documentation
+
- use Tcl objects internally
+
- use Tcl object interface for callbacks
+
- vertical sync control
+
- fix thread safety in anticipation that OpenGL drivers may someday be thread safe
+
- added simple stereo rendering interface
+
- revised font C API
+
- updated font support for Tk 8.4 on all platforms
+
- updated documentation
+
- prebuilt binaries
+
+
+ Version 2.1 — December 2009
+
+ - incorporate the part of the X11R6 Xmu library that Togl uses
+ so it will work on (Linux) systems that don't have the Xmu shared library
+
- Mac OS X Aqua delete context bug fix
+
- multisampling support
+
- pbuffer support (Unix/X11, Microsoft Windows, Mac OS X)
+
- Ability to copy context state
+
- row interleaved stereo support
+
+
+
+ Future plans
+ Patches for the following are especially welcome:
+
+ - Tk 8.5 fonts
+
- Aqua Cocoa support (Tk 8.6b2)
+
- OpenGL 3 contexts
+
- EGL support
+
- RGB overlays
+
- Tcl access to colormap manipulation
+
- NVidia consumer stereo support
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ng/Togl2.1/doc/faq.html b/ng/Togl2.1/doc/faq.html
new file mode 100644
index 00000000..81018051
--- /dev/null
+++ b/ng/Togl2.1/doc/faq.html
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+ Togl Frequently Asked Questions
+
+
+
+
+
+
+ Togl Frequently Asked Questions
+
+ Contents
+
+ Frequently Asked Questions (and Problems)
+
+
+
+
+ If you have something to add to this section please let us know.
+
+
+ -
+ Bad Match X errors on Sun systems
+
-
+ There is(was?) a bug in Sun's XmuLookupStandardColormap
+ X library function.
+ If you compile togl.c with the SOLARIS_BUG symbol defined (-DSOLARIS_BUG)
+ this function call will be omitted.
+
+
+
-
+ Is stereo rendering supported?
+
-
+ Several different stereo modes are supported.
+
+
+
-
+ Is fullscreen stereo rendering supported?
+
-
+ Before Tk 8.5,
+ Tk does not support true fullscreen windows.
+ Consequenly the full-screen stereo,
+ that gaming graphics cards support (ATI Radeon, NVidia GeForce),
+ won't be added until sometime after Tk 8.5 is available.
+ Fullscreen stereo on workstation graphics cards
+ (ATI FireGL, NVidia Quadro, Matrix Parhelia, 3Dlabs Wildcat)
+ does work.
+
+
-
+ How do I get the Microsoft Windows device context?
+
-
+ First call
Togl_MakeCurrent
to make sure you have the
+ right OpenGL context and device context set,
+ then call wglGetCurrentDC
.
+
+
+
-
+ How do I use Togl from Python?
+
-
+ The Togl source distribution comes with a
Togl.py
file
+ that provides a Tkinter-style Togl widget.
+ And for Togl callbacks that are C functions,
+ there is a toglpy.h
file that provides a function
+ that converts a Python object into its corresponding Togl widget:
+
+ Togl *getToglFromWidget(PyObject *widget)
+
+
+
+
-
+ Is Togl compatible with Tile and Tk 8.5?
+
-
+ Yes, Togl works as is (except for the bitmap font support for X11 and Aqua).
+ From Joe English:
+
+ Complex "owner-draw" widgets like tkZinc,
+ or the text and canvas widgets,
+ really don't benefit much from themability,
+ so there's no reason to rewrite them.
+ (http://wiki.tcl.tk/13373)
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ng/Togl2.1/doc/header.js b/ng/Togl2.1/doc/header.js
new file mode 100644
index 00000000..5e87cd50
--- /dev/null
+++ b/ng/Togl2.1/doc/header.js
@@ -0,0 +1,20 @@
+function displayHeader(pageTitle)
+{
+ document.write("" + pageTitle + "
");
+}
+
+function NavigationBar()
+{
+ document.write("");
+ document.write(" ");
+ document.write(" Index | ");
+ document.write(" Intro | ");
+ document.write(" Download/Install | ");
+ document.write(" Using Togl | ");
+ document.write(" Tcl API | ");
+ document.write(" C API | ");
+ document.write(" FAQ | ");
+ document.write("
");
+ document.write("
");
+ document.write("
");
+}
diff --git a/ng/Togl2.1/doc/index.html b/ng/Togl2.1/doc/index.html
new file mode 100644
index 00000000..222099e9
--- /dev/null
+++ b/ng/Togl2.1/doc/index.html
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+ Togl, a Tk OpenGL widget
+
+
+
+
+
+ Togl — a Tk OpenGL widget
+ Copyright © 1996-2009 Brian Paul, Ben Bederson, and Greg Couch
+
+ Index
+
+
+
+
+
+
+
+ Togl is a Tk widget for
+ OpenGL rendering.
+ Togl was originally based on OGLTK, written by Benjamin Bederson at
+ the University of New Mexico.
+
+ Togl's main features are:
+
+
+ - unifies Microsoft Windows, X11 (Linux/IRIX/...), and Mac OS X Aqua support
+
- support for requesting stencil, accumulation, alpha buffers, etc.
+
- multiple OpenGL drawing windows
+
- simple stereo rendering support
+
- simple, portable font support
+
- color-index mode support including color allocation functions
+
- overlay plane support
+
- OpenGL extension testing from Tcl
+
- Tcl Extension Architecture (TEA) 3 compliant
+
+
+
+ Togl does almost no OpenGL drawing itself,
+ instead it manages OpenGL drawing by calling various Tcl commands
+ (a.k.a., callback functions).
+ Those commands can be C functions that call OpenGL (in)directly
+ or another Tcl package
+ (e.g., Tcl3D).
+
+
+ Togl is copyrighted by
+ Brian Paul
+ (brian_e_paulATyahooDOTcom),
+ Benjamin Bederson
+ (bedersonATcsDOTumdDOTedu), and
+ Greg Couch
+ (gregcouchATusersDOTsourceforgeDOTnet).
+ See the LICENSE file for details.
+
+
+ The
+ Togl project and
+ home page are
+ hosted by SourceForge.
+
+
+
+
+
+ See the
+ Togl project at SourceForge for mailing list information.
+
+
+
+
+
+ There is a bug database on the
+ Togl Project Page.
+ You may also discuss bugs on the mailing list.
+
+ It may be worth upgrading your graphics driver and retesting
+ before reporting a bug,
+ as, historically,
+ many Togl "bugs" have been fixed by a graphics driver upgrade,
+ especially on Microsoft Windows.
+
+ When reporting bugs please provide as much information as possible.
+ Such as the version of Togl, which operating system
+ (e,g., Microsoft Windows, Red Hat Linux, Mac OS X, etc.),
+ the version of the operating system,
+ and the version of the graphics driver.
+ Also, it's very helpful to us if you can provide an example program
+ which demonstrates the problem.
+
+
+
+
+
+ Several people have contributed new features to Togl. Among them are:
+
+
+ - Ramon Ramsan — overlay plane support
+
- Miguel A. De Riera Pasenau — more overlay functions, X11 functions
+ and EPS output
+
- Peter Dern and Elmar Gerwalin — Togl_TimerFunc and related code
+
- Robert Casto — Microsoft Windows NT port
+
- Geza Groma — Microsoft Windows 95/NT patches
+
- Ben Evans — SGI stereo support
+
- Paul Thiessen — Macintosh support
+
- Jonas Beskow — Tcl/Tk stubs support
+
- Paul Kienzle — TEA debugging and patches
+
- Greg Couch — version 1.7, 2.0, 2.1
+
+
+ Many others have contributed bug fixes. Thanks for your contributions!
+
+
+
+ Last edited on 4 February 2009 by Greg Couch.
+
+
+
+
+
+
+
+
+
+
diff --git a/ng/Togl2.1/doc/stereo.html b/ng/Togl2.1/doc/stereo.html
new file mode 100644
index 00000000..72d4ec8d
--- /dev/null
+++ b/ng/Togl2.1/doc/stereo.html
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+ Togl Stereo Modes
+
+
+
+
+
+
+ Togl Stereo Modes
+
+ Contents
+
+
+
+
+
+ There are lots of stereo modes in Togl because there are many ways to
+ draw stereo with different tradeoffs.
+ All of the stereo modes are choosen with the
+
+ -stereo
configuration option.
+ All of the non-native stereo techniques
+ are software-only and can be changed at anytime.
+
+ When using a non-native stereo mode, the OpenGL
+ glDrawBuffer
, glClear
,
+ glFrustum
, and glOrtho
calls
+ should be replaced with the Togl
+ Tcl or
+ C versions
+ for seemless stereo rendering.
+
+ The various stereo modes are:
+
+ -
+
none
or "" or any false boolean value
+ -
+ Turn off stereo.
+
native
or any true boolean value
+ -
+ Use native OpenGL hardware accelerated stereo
+ (single- or double-buffered for both the left and the right eyes).
+ Each eye is drawn at full window resolution
+ which gives the best stereo image.
+ This mode requires support from the graphics driver and is
+ typically only supported on workstation-class graphics cards, e.g.,
+ NVidia Quadro,
+ ATI FireGL,
+ Matrix Parhelia,
+ 3DLabs Wildcat
+ graphics cards
+ and SGI workstations.
+ The video refresh rate is changed automatically by the windowing system
+ except on SGI workstations.
+ Developers for SGI workstations can either switch the video manually with
+
/usr/gfx/setmon
or /usr/bin/X11/xsetmon
, or use the
+
+ autostereo package.
+
+ Currently, there is a limitation that a togl widget can not be
+ reconfigured in or out of the native stereo mode.
+ And if/when it is supported,
+ some graphics drivers might not allow it.
+
-
+
anaglyph
+ -
+ Draw the left eye in the red part of the color buffer
+ and the right eye in the blue and green parts.
+ Designed to be viewed with inexpensive red-blue or red-cyan glasses.
+ Works best with gray scale and non-saturated color images.
+
-
+
cross-eye
+ -
+ Draw right eye image on the left half of screen,
+ and draw left eye image on the right half of screen.
+ So each eye is drawn at less than half of the window resolution.
+
-
+
wall-eye
+ -
+ Draw left eye image on the left half of the screen,
+ and draw right eye image on the right half of the screen.
+ So each eye is drawn at less than half of the window resolution.
+
-
+
dti
+ -
+ Designed for DTI displays.
+ If you look at the window unassisted,
+ you'll see horizonally squished images
+ with the left eye image on the left,
+ and right eye image on the right.
+ So each eye is drawn at half of the window resolution.
+
-
+
row interleaved
+ -
+ Designed for
+ VRex,
+ Zalman, and
+ Hyundai displays.
+ Where the right eye is on the even scanlines
+ and the left is on the odd ones.
+ Requires that there be a stencil buffer
+ and uses the most significant stencil bit.
+ Changes to the stencil state should be placed within
+
+ glPushAttrib(GL_STENCIL_BUFFER_BIT) and glPopAttrib() calls.
+
-
+
left eye
+ -
+ Only draw left eye view at full resolution.
+
-
+
right eye
+ -
+ Only draw right eye view at full resolution.
+
-
+
sgioldstyle
+ -
+ Support older-style SGI stereo where you lose half of the vertical resolution.
+ This uses the SGIStereo X extension,
+ that is only available on SGI workstations,
+ to tell the X server to duplicate non-stereo windows into both eyes.
+ This option only works when the monitor has been changed to the one
+ of the
str_top
, str_bot
, or str_rect
video output modes.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ng/Togl2.1/doc/tclapi.html b/ng/Togl2.1/doc/tclapi.html
new file mode 100644
index 00000000..6d6c9a97
--- /dev/null
+++ b/ng/Togl2.1/doc/tclapi.html
@@ -0,0 +1,774 @@
+
+
+
+
+
+
+
+ Togl Tcl API
+
+
+
+
+
+
+ Togl Tcl API
+
+ Contents
+
+
+
+
+
+
+
+ The togl command creates a new Tk widget, a Tcl command,
+ whose name is pathName.
+ This command may be used to invoke various operations on the widget.
+
+ togl pathName [options]
+
+ If no options are given, a 400 by 400 pixel RGB window is created.
+ This command may be used to invoke various operations on the widget.
+
+
+
+ The following commands are possible for an existing togl widget:
+
+
+
+
+ pathName cget -option
+ -
+ Return current value of given configuration option.
+
+
+
+ -
+
pathName configure
+ pathName configure -option
+ -
+ If no option is given,
+ then return information about
+ all configuration options.
+ Otherwise,
+ return configuration information for given option.
+ All configuration information consists of five values:
+ the configuration option name,
+ the option database name,
+ the option database class,
+ the default value,
+ and the current value.
+
+
+
+ pathName configure -option value
+ -
+ Reconfigure a Togl widget.
+ option may be any one of the options listed below.
+
+
+
+ pathName contexttag
+ -
+ Returns an integer that represents the context tag.
+ All Togl widgets with the same context tag share display lists.
+
+
+
+
+
+ pathName extensions
+ -
+ Returns a list of OpenGL extensions available. For example:
+
+if {[lsearch [pathName extensions] GL_EXT_bgra] != -1]} {
+ ....
+}
+
+ would check if the GL_EXT_bgra extension were supported.
+
+
+
+
+
+ pathName postredisplay
+ -
+ Cause the displaycommand callback to be called
+ the next time the event loop is idle.
+
+
+
+ pathName render
+ -
+ Causes the displaycommand callback to be called for pathName.
+
+
+
+ pathName swapbuffers
+ -
+ Causes front/back buffers to be swapped if in double buffer mode.
+ And flushs the OpenGL command buffer if in single buffer mode.
+ (So this is appropriate to call after every frame is drawn.)
+
+
+
+ pathName makecurrent
+ -
+ Make the widget specified by pathName and its OpenGL context
+ the current ones.
+ This is implicitly called before any callback command is invoked.
+
+
+
+ pathName copycontextto toPathName mask
+ -
+ Copy a subset of the OpenGL context state from pathName to
+ toPathName according the given mask.
+ The mask is an integer corresponding to the same values as
+
+ glPushAttrib.
+
+
+
+
+
+ pathName takephoto imagename
+ -
+ Copy the contents of the togl window into the given Tk photo image.
+ Transparency values are copied and should be fully opaque for windows
+ without alpha bitplanes.
+
+
+
+
+
+ These functions provide an interface to the simple bitmap font capabilities
+ that every OpenGL implementation provides.
+ Better font support is found in other packages, e.g.,
+ Tcl3D
+ or with different C APIs.
+
+
+ pathName loadbitmapfont font
+ -
+ font can be any of font descriptions listed in the Tk
+ font command.
+ It returns a togl font object.
+
+
+
+ pathName unloadbitmapfont toglfont
+ -
+ Releases the OpenGL resources needed by the toglfont.
+
+
+
+ pathName write toglfont [-pos xyzw] [-color rgba] string
+ -
+ Write the given string in the given toglfont,
+ optionally at a particular position, xyzw
+ and color, rgba.
+ xyzw is either a 2, 3, or 4 element list of numbers.
+ rgba is either a 3 or 4 element list of numbers.
+
+
+
+
+
+ pathName uselayer layer
+ -
+ This is a variation on the
makecurrent
command
+ that makes the overlay OpenGL context current
+ if layer is 2
+ and makes the normal OpenGL context current
+ if layer is 1.
+
+
+
+ pathName showoverlay
+ -
+ Turn on drawing in the overlay planes.
+
+
+
+ pathName hideoverlay
+ -
+ Turn off drawing in the overlay planes.
+
+
+
+ pathName postredisplayoverlay
+ -
+ Cause the overlay OpenGL context to be redrawn the next time
+ the Tcl event loop is idle.
+
+
+
+ pathName renderoverlay
+ -
+ Causes the overlaydisplaycommand callback to be called for pathName.
+
+
+
+ pathName existsoverlay
+ -
+ Return true if togl widget has overlay planes.
+
+
+
+ pathName ismappedoverlay
+ -
+ Return true if overlay planes are shown.
+
+
+
+ pathName getoverlaytransparentvalue
+ -
+ Return overlay plane's transparent pixel value.
+
+
+
+ These commands exist to support stereo rendering.
+ Just replace select OpenGL calls with the Togl versions
+ and stereo rendering will magically work. And don't forget
+ to update the stereo options.
+
+
+ pathName drawbuffer mode
+ -
+ Replaces calls to
+
+ glDrawBuffer.
+ The mode is an integer.
+
+
+
+ pathName clear mask
+ -
+ Replaces calls to
+
+ glClear.
+ The mask is an integer.
+
+
+
+ pathName frustum left right bottom top near far
+ -
+ Replaces calls to
+
+ glFrustum.
+
+
+
+ pathName ortho left right bottom top near far
+ -
+ Replaces calls to
+
+ glOrtho.
+
+
+
+ pathName numeyes
+ -
+ Returns numbers of eyes — basically,
+ 2 for stereo views and 1 for all others,
+ except some stereo views only need one eye from OpenGL.
+
+
+
+
+ Togl's configuration options can be separated into several categories:
+ geometry, pixel format, and other.
+ The pixel format related options can only be set at widget creation time.
+ The other options can be changed dynamically
+ by the pathName configure
command (see above).
+
+
+
+
+
+
+ Option |
+ Default |
+ Comments |
+
+
+
+
+ -createcommand |
+ {} |
+
+ Can be abbreviated -create .
+ |
+
+
+ -displaycommand |
+ {} |
+
+ Can be abbreviated -display .
+ |
+
+
+ -reshapecommand |
+ {} |
+
+ Can be abbreviated -reshape .
+ |
+
+
+ -destroycommand |
+ {} |
+
+ Can be abbreviated -destroy .
+ |
+
+
+ -overlaydisplaycommand |
+ {} |
+
+ Can be abbreviated -overlaydisplay .
+ |
+
+
+
+
+
+
+
+
+
+ Option |
+ Default |
+ Comments |
+
+
+
+
+ -width |
+ 400 |
+
+ Set width of widget in pixels.
+ It may have any of the forms accepted by Tk_GetPixels.
+ |
+
+
+ -height |
+ 400 |
+
+ Set height of widget in pixels.
+ It may have any of the forms accepted by Tk_GetPixels(3).
+ |
+
+
+ -setgrid |
+ 0 |
+
+ Turn on gridded geometry management for togl widget's toplevel
+ window and specify the geometry of the grid.
+ See the manual pages for Tk's wm(n) and Tk_SetGrid(3)
+ for more information.
+ Unlike the text widget,
+ the same value is used for both width and height increments.
+ |
+
+
+
+
+
+
+
+
+
+ Option |
+ Default |
+ Comments |
+
+
+
+
+ -time |
+ 1 |
+
+ Specifies the interval, in milliseconds, for
+ calling the timer callback function which
+ was registered with -timercommand. |
+
+
+ -timercommand |
+ {} |
+
+ Can be abbreviated -timer .
+ |
+
+
+
+
+
+
+
+
+
+ Option |
+ Default |
+ Comments |
+
+
+
+
+ -eyeseparation |
+ 2.0 |
+
+ Set the distance between the eyes in viewing coordinates.
+ |
+
+
+
+ -convergence |
+ 30.0 |
+
+ Set the distance to the screen from the eye in viewing coordinates
+ (the distance at which the eyes converge).
+ |
+
+
+
+
+
+ You'd think these values would be given in physical units,
+ but there's no single right way to convert to viewing coordinates
+ from physical units.
+ So if you're willing to use Tk's idea of the horizontal size of a
+ window in millimeters (not always correct),
+ you could convert the average eye separation of 63 mm
+ to your viewing coordinates, and use that value as the eye separation.
+
+
+
+
+
+
+
+ Option |
+ Default |
+ Comments |
+
+
+
+
+ -cursor |
+ "" |
+
+ Set the cursor in the widget window.
+ |
+
+
+
+ -swapinterval |
+ 1 |
+
+ Set the minimum swap interval measure in video frame periods.
+ The default is 1 for for non-tearing artifacts
+ when swapping buffers.
+ Use a value of 0 when benchmarking frame rates.
+ |
+
+
+
+ -ident |
+ "" |
+
+ A user identification string. This is used match widgets
+ for the -sharecontext
+ and the -sharelist options (see below).
+ This is also useful in your callback functions
+ to determine which Togl widget is the caller.
+ |
+
+
+
+
+
+
+ The following options can only be given when the togl widget is created
+ — that is, unlike other options,
+ the togl widget can not be reconfigured with different values
+ for the following options after it is created.
+
+
+
+
+ Option |
+ Default |
+ Comments |
+
+
+
+
+ -rgba |
+ true |
+ If true, use RGB(A) mode, otherwise use Color Index mode. |
+
+
+ -redsize |
+ 1 |
+ Minimum number of bits in red component. |
+
+
+ -greensize |
+ 1 |
+ Minimum number of bits in green component. |
+
+
+ -bluesize |
+ 1 |
+ Minimum number of bits in blue component. |
+
+
+ -alpha |
+ 1 |
+
+ If true and -rgba is true, request an alpha channel.
+ |
+
+
+ -alphasize |
+ 1 |
+ Minimum number of bits in alpha component. |
+
+
+ |
+
+ -double |
+ false |
+
+ If true, request a double-buffered window, otherwise
+ request a single-buffered window.
+ |
+
+
+ |
+
+ -depth |
+ false |
+ If true, request a depth buffer. |
+
+
+ -depthsize |
+ 1 |
+ Minimum number of bits in depth buffer. |
+
+
+ |
+
+ -accum |
+ false |
+ If true, request an accumulation buffer. |
+
+
+ -accumredsize |
+ 1 |
+ Minimum number of bits in accumulation buffer red component. |
+
+
+ -accumgreensize |
+ 1 |
+
+ Minimum number of bits in accumulation buffer green component.
+ |
+
+
+ -accumbluesize |
+ 1 |
+ Minimum number of bits in accumulation buffer blue component. |
+
+
+ -accumalphasize |
+ 1 |
+
+ Minimum number of bits in accumulation buffer alpha component.
+ |
+
+
+ |
+
+ -stencil |
+ false |
+ If true, request a stencil buffer. |
+
+
+ -stencilsize |
+ 1 |
+ Minimum number of bits in stencil component. |
+
+
+ |
+
+ -auxbuffers |
+ 0 |
+ Desired number of auxiliary buffers. |
+
+
+ |
+
+ -privatecmap |
+ false |
+
+ Only applicable in color index mode.
+ If false, use a shared read-only colormap.
+ If true, use a private read/write colormap.
+ |
+
+
+ |
+
+ -overlay |
+ false |
+ If true, request overlay planes. |
+
+
+ |
+
+ -stereo |
+ mode |
+
+ See the stereo information
+ for details about the various modes.
+ Stereo parameters are changed with the
+ stereo options.
+
+ When using a non-native stereo mode, the OpenGL
+
+ glDrawBuffer,
+
+ glClear,
+
+ glFrustum, and
+
+ glOrtho calls
+ must be replaced with the Togl
+ Tcl or
+ C versions.
+ |
+
+
+ |
+
+ -pbuffer |
+ false |
+
+ If true, request off-screen framebuffer memory for the graphics.
+ The resulting togl widget should not be managed.
+ |
+
+
+ -largestpbuffer |
+ false |
+
+ If true, when asking for a pbuffer of a given size
+ and there isn't enough framebuffer memory available,
+ fallback to the largest size available.
+ |
+
+
+ |
+
+ -multisample |
+ false |
+
+ If true, request an multisampled rendering context.
+ |
+
+
+
+
+
+ -indirect |
+ false |
+
+ If present, request an indirect rendering context.
+ A direct rendering context is normally requested.
+ Only significant on Unix/X11.
+ |
+
+
+
+ -sharelist |
+ "" |
+
+ Togl identification string or window path name
+ of an existing Togl widget with which to share display lists.
+ If it is not possible to share display lists
+ between the two togl widgets
+ (depends on the graphics driver and the particular formats),
+ it fails.
+ |
+
+
+ -sharecontext |
+ "" |
+
+ Togl identification string or window path name
+ of an existing Togl widget with which to share the OpenGL context.
+ Note: all other pixel format options are ignored.
+ |
+
+
+ -pixelformat |
+ 0 |
+
+ Set the pixel format to the (platform-dependent) given value.
+ This is a backdoor into choosing a particular pixel format
+ that was determined by other means.
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ng/Togl2.1/doc/upgrading.html b/ng/Togl2.1/doc/upgrading.html
new file mode 100644
index 00000000..790cc732
--- /dev/null
+++ b/ng/Togl2.1/doc/upgrading.html
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+ Upgrading to Version 2
+
+
+
+
+
+
+ Upgrading to Version 2
+
+ Contents
+
+
+
+
+
+ Internally, Togl version 2 isn't very different from version 1,
+ and much of the C interface is the same.
+ The main difference is that the focus of the Togl API has changed
+ from being a C API to being a Tcl API.
+ Which means that the full power of Togl is accessible from Tcl
+ (the few exceptions are considered bugs).
+
+
+
+ The biggest change is how the various callback are initialized.
+ In version 1,
+ the C API Togl_Set*Func functions had to be used
+ to setup the callback functions before creating the Togl widget.
+ And once the callbacks were set for a particular Togl widget,
+ they could not be changed.
+ If more than once Togl widget was needed,
+ the callback functions would need to be reset before each widget creation.
+ In version 2,
+ the callbacks are configuration arguments to the widget
+ and can be updated like any other standard widget configuration option.
+ See the Tcl API for details.
+
+
+
+ Version 1 also allowed new subcommands to be added
+ to the togl widget command via the C API.
+ This was dropped for a variety of reasons:
+ there is no exact Tcl equivalent,
+ there is no standard object-oriented technique
+ currently in the Tcl core (8.4.13),
+ it is unclear how to make the API thread safe,
+ and the internal Tcl C API doesn't support
+ dynamicly changing sets of subcommands.
+ That said, this functionality might come back, especially when
+ TIP #257 is implemented.
+ Instead, in version 2,
+ create a Tcl function that takes the Togl widget as an argument.
+ Functions written in C can get the underlying Togl structure handle
+ with either the Togl_GetToglFromObj
+ or the Togl_GetToglFromName
function,
+ as appropriate.
+ This means that there are no special Togl commands, only Tcl commands.
+ See the C API for details.
+
+
+
+ The stereo support has been totally revamped.
+ Some form of stereo is available all of the time.
+
+
+
+ Tcl support for writing strings has been added.
+
+
+ The font C API has been revised
+ so that Togl_LoadBitmapFont returns a font object instead an integer
+ (likewise for Togl_UnloadBitmapFont).
+ So instead of calling glListBase and glCallLists directly,
+ use Togl_WriteObj or Togl_WriteChars.
+
+ The TOGL_BITMAP_* constants remain for limited backwards
+ source compatibility and are deprecated.
+ The acceptable font names are now the same as Tk_GetFont
+ and the Tk font command on all platforms.
+
+
+
+
+
+
+
+
+
+
diff --git a/ng/Togl2.1/doc/using.html b/ng/Togl2.1/doc/using.html
new file mode 100644
index 00000000..0e847d1f
--- /dev/null
+++ b/ng/Togl2.1/doc/using.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+ Using the Togl Widget
+
+
+
+
+
+
+ Using the Togl Widget
+
+ Contents
+
+
+
+
+
+
+
+ First, double check that you have all of the
+ prerequisites
+ and that you have
+ compiled and installed Togl.
+
+ Then, Togl acts like any other extension package —
+ to load it, you use the Tcl package
command:
+
+ package require Togl 2.0
+
+ After that, you can create a Togl widget just like any other Tk widget.
+
+
+
+
+ There are eight working examples:
+
+
+
+
+ double.tcl |
+ — compares single vs double buffering with two Togl widgets |
+
+
+ texture.tcl |
+ — lets you play with texture mapping options |
+
+
+ index.tcl |
+ — example of using color index mode |
+
+
+ overlay.tcl |
+ — example of using overlay planes (requires overlay hardware) |
+
+
+ stereo.tcl |
+ — stereo example |
+
+
+ gears.tcl |
+ — spinning gears example |
+
+
+ multisample.tcl |
+ — multisampling example |
+
+
+ pbuffer.tcl |
+ — pbuffer (off-screen rendering) example |
+
+
+
+
+
+ Each example consists of two files: a Tcl script for the user interface,
+ and a Tcl C package that does the OpenGL drawing.
+ To compile the examples, type make examples
+ in the Togl source directory.
+ The C packages are compiled into shared libraries
+ that are loaded into the Tcl interpreter as Tcl/Tk-extensions.
+ The examples are started by running the corrsponding Tcl script:
+ just type ./double.tcl
+ (or ./texture.tcl
etc.)
+ or run under one of the Tcl interpreters, i.e.,
+ tclsh
or wish
.
+ For example:
+
+ tclsh84 double.tcl
+
+
+
+ Other examples that use Tcl for OpenGL drawing can be found in the
+ Tcl3D demos.
+
+
+
+ All of the examples have similar structure.
+ First they create the user interface with one or more Togl widgets.
+ Each Togl widget is configured with the desired pixel format
+ and several callback commands (not all are needed):
+
+
+ -createcommand |
+
+ Called when Togl widget is mapped —
+ when it is safe to initialize the OpenGL context.
+ |
+
+
+ -reshapecommand |
+
+ Called when the Togl widget is resized —
+ when the OpenGL context's viewport needs to be changed.
+ |
+
+
+ -displaycommand |
+
+ Called when the contents of the Togl widget needs to be redrawn.
+ Redraws are normally delayed to be when the Tcl event loop is idle
+ (see the togl widget's postredisplay command),
+ or as the result of an explict call to the togl's widgets
+ render command.
+ |
+
+
+ -destroycommand |
+
+ Called when the Togl widget is destroyed.
+ While OpenGL frees display lists and other resources,
+ sometimes there's some associated state that is no longer needed.
+ |
+
+
+ -timercommand |
+
+ Called every n milliseconds
+ as given by the -time option.
+ |
+
+
+ -overlaydisplaycommand |
+
+ Called when the overlay planes needs to be redrawn.
+ The overlay planes are created and reshaped
+ at the same time as the main OpenGL context.
+ |
+
+
+
+ Typically, only -createcommand
, -reshapecommand
+ and -displaycommand
are used.
+
+
+
+
+
+
+
+
+
+
diff --git a/ng/Togl2.1/double.c b/ng/Togl2.1/double.c
new file mode 100644
index 00000000..be6f5a38
--- /dev/null
+++ b/ng/Togl2.1/double.c
@@ -0,0 +1,279 @@
+/* $Id: double.c,v 1.22 2009/03/12 23:59:35 gregcouch Exp $ */
+
+/*
+ * Togl - a Tk OpenGL widget
+ * Copyright (C) 1996-1997 Brian Paul and Ben Bederson
+ * Copyright (C) 2006-2007 Greg Couch
+ * See the LICENSE file for copyright details.
+ */
+
+#define USE_TOGL_STUBS
+
+#include "togl.h"
+#include
+#include
+#include
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+
+static Tcl_Obj *toglFont;
+static double xAngle = 0, yAngle = 0, zAngle = 0;
+static GLdouble CornerX, CornerY, CornerZ; /* where to print strings */
+
+
+/*
+ * Togl widget create callback. This is called by Tcl/Tk when the widget has
+ * been realized. Here's where one may do some one-time context setup or
+ * initializations.
+ */
+static int
+create_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (!toglFont)
+ toglFont = Togl_LoadBitmapFont(togl, "Helvetica");
+ if (!toglFont) {
+ static int shown;
+
+ if (!shown) {
+ fprintf(stderr, "Couldn't load font!\n");
+ shown = 1;
+ }
+ }
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget reshape callback. This is called by Tcl/Tk when the widget
+ * has been resized. Typically, we call glViewport and perhaps setup the
+ * projection matrix.
+ */
+static int
+reshape_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ int width;
+ int height;
+ double aspect;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ width = Togl_Width(togl);
+ height = Togl_Height(togl);
+ aspect = (double) width / (double) height;
+
+ glViewport(0, 0, width, height);
+
+ /* Set up projection transform */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-aspect, aspect, -1, 1, 1, 10);
+
+ CornerX = -aspect;
+ CornerY = -1;
+ CornerZ = -1.1;
+
+ /* Change back to model view transform for rendering */
+ glMatrixMode(GL_MODELVIEW);
+
+ return TCL_OK;
+}
+
+
+
+static void
+print_string(Togl *togl, const char *s)
+{
+ if (toglFont)
+ Togl_WriteChars(togl, toglFont, s, 0);
+}
+
+
+/*
+ * Togl widget display callback. This is called by Tcl/Tk when the widget's
+ * contents have to be redrawn. Typically, we clear the color and depth
+ * buffers, render our objects, then swap the front/back color buffers.
+ */
+static int
+display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ static GLuint cubeList = 0;
+ const char *ident;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK)
+ return TCL_ERROR;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glLoadIdentity(); /* Reset modelview matrix to the identity
+ * matrix */
+ glTranslatef(0, 0, -3); /* Move the camera back three units */
+ glRotated(xAngle, 1, 0, 0); /* Rotate by X, Y, and Z angles */
+ glRotated(yAngle, 0, 1, 0);
+ glRotated(zAngle, 0, 0, 1);
+
+ glEnable(GL_DEPTH_TEST);
+
+ if (!cubeList) {
+ cubeList = glGenLists(1);
+ glNewList(cubeList, GL_COMPILE);
+
+ /* Front face */
+ glBegin(GL_QUADS);
+ glColor3f(0, 0.7f, 0.1f); /* Green */
+ glVertex3f(-1, 1, 1);
+ glVertex3f(1, 1, 1);
+ glVertex3f(1, -1, 1);
+ glVertex3f(-1, -1, 1);
+ /* Back face */
+ glColor3f(0.9f, 1, 0); /* Yellow */
+ glVertex3f(-1, 1, -1);
+ glVertex3f(1, 1, -1);
+ glVertex3f(1, -1, -1);
+ glVertex3f(-1, -1, -1);
+ /* Top side face */
+ glColor3f(0.2f, 0.2f, 1); /* Blue */
+ glVertex3f(-1, 1, 1);
+ glVertex3f(1, 1, 1);
+ glVertex3f(1, 1, -1);
+ glVertex3f(-1, 1, -1);
+ /* Bottom side face */
+ glColor3f(0.7f, 0, 0.1f); /* Red */
+ glVertex3f(-1, -1, 1);
+ glVertex3f(1, -1, 1);
+ glVertex3f(1, -1, -1);
+ glVertex3f(-1, -1, -1);
+ glEnd();
+
+ glEndList();
+
+ }
+ glCallList(cubeList);
+
+ glDisable(GL_DEPTH_TEST);
+ glLoadIdentity();
+ glColor3f(1, 1, 1);
+ glRasterPos3d(CornerX, CornerY, CornerZ);
+ ident = Togl_Ident(togl);
+ if (ident)
+ print_string(togl, ident);
+ Togl_SwapBuffers(togl);
+ return TCL_OK;
+}
+
+
+
+
+static int
+setXrot_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "angle");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[1], &xAngle) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* printf( "before %f ", xAngle ); */
+
+ xAngle = fmod(xAngle, 360.0);
+ if (xAngle < 0)
+ xAngle += 360.0;
+
+ /* printf( "after %f \n", xAngle ); */
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+}
+
+
+static int
+setYrot_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName angle");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[1], &yAngle) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ yAngle = fmod(yAngle, 360.0);
+ if (yAngle < 0)
+ yAngle += 360.0;
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+}
+
+/*
+ * Called by Tcl to let me initialize the modules (Togl) I will need.
+ */
+EXTERN int
+Double_Init(Tcl_Interp *interp)
+{
+ /*
+ * Initialize Tcl and the Togl widget module.
+ */
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL
+ || Togl_InitStubs(interp, "2.0", 0) == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Specify the C callback functions for widget creation, display,
+ * and reshape.
+ */
+ Tcl_CreateObjCommand(interp, "double::create_cb", create_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "double::display_cb", display_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "double::reshape_cb", reshape_cb, NULL, NULL);
+
+ /*
+ * Make a new Togl widget command so the Tcl code can set a C variable.
+ */
+
+ Tcl_CreateObjCommand(interp, "double::setXrot", setXrot_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "double::setYrot", setYrot_cb, NULL, NULL);
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+
+ return TCL_OK;
+}
diff --git a/ng/Togl2.1/double.tcl b/ng/Togl2.1/double.tcl
new file mode 100644
index 00000000..ed749430
--- /dev/null
+++ b/ng/Togl2.1/double.tcl
@@ -0,0 +1,96 @@
+#!/bin/sh
+# the next line restarts using tclsh \
+exec tclsh "$0" "$@"
+
+# $Id: double.tcl,v 1.11 2009/03/12 23:59:35 gregcouch Exp $
+
+# Togl - a Tk OpenGL widget
+# Copyright (C) 1996 Brian Paul and Ben Bederson
+# Copyright (C) 2006-2007 Greg Couch
+# See the LICENSE file for copyright details.
+
+
+# An Tk/OpenGL widget demo with two windows, one single buffered and the
+# other double buffered.
+
+package provide double 1.0
+
+# add parent directory to path to find Togl's pkgIndex in current directory
+if { [file exists pkgIndex.tcl] } {
+ set auto_path [linsert $auto_path 0 ..]
+}
+# following load also loads Tk and Togl packages
+load [file dirname [info script]]/double[info sharedlibextension]
+
+# create ::double namespace
+namespace eval ::double {
+}
+
+proc double::setup {} {
+ wm title . "Single vs Double Buffering"
+
+ # create first Togl widget
+ togl .o1 -width 200 -height 200 -rgba true -double false -depth true -ident "Single Buffered" -create double::create_cb -display double::display_cb -reshape double::reshape_cb
+
+ # create second Togl widget, share display lists with first widget
+ togl .o2 -width 200 -height 200 -rgba true -double true -depth true -ident "Double Buffered" -sharelist "Single Buffered" -create double::create_cb -display double::display_cb -reshape double::reshape_cb
+
+ scale .sx -label {X Axis} -from 0 -to 360 -command {::double::setAngle x} -orient horizontal
+ scale .sy -label {Y Axis} -from 0 -to 360 -command {::double::setAngle y} -orient horizontal
+ button .btn -text Quit -command exit
+
+ bind .o1 {
+ ::double::motion_event [lindex [%W config -width] 4] \
+ [lindex [%W config -height] 4] \
+ %x %y
+ }
+
+ bind .o2 {
+ ::double::motion_event [lindex [%W config -width] 4] \
+ [lindex [%W config -height] 4] \
+ %x %y
+ }
+
+ grid rowconfigure . 0 -weight 1
+ grid columnconfigure . 0 -weight 1 -uniform same
+ grid columnconfigure . 1 -weight 1 -uniform same
+ grid .o1 -row 0 -column 0 -sticky nesw -padx 3 -pady 3
+ grid .o2 -row 0 -column 1 -sticky nesw -padx 3 -pady 3
+ #grid .l1 -row 1 -column 0 -sticky ew -padx 3 -pady 3
+ #grid .l2 -row 1 -column 1 -sticky ew -padx 3 -pady 3
+ grid .sx -row 2 -column 0 -columnspan 2 -sticky ew
+ grid .sy -row 3 -column 0 -columnspan 2 -sticky ew
+ grid .btn -row 4 -column 0 -columnspan 2 -sticky ew
+}
+
+
+
+# This is called when mouse button 1 is pressed and moved in either of
+# the OpenGL windows.
+proc double::motion_event { width height x y } {
+ .sx set [double::setXrot [expr 360.0 * $y / $height]]
+ .sy set [double::setYrot [expr 360.0 * ($width - $x) / $width]]
+
+ .o1 postredisplay
+ .o2 postredisplay
+}
+
+# This is called when a slider is changed.
+proc double::setAngle {axis value} {
+ global xAngle yAngle zAngle
+
+ switch -exact $axis {
+ x {double::setXrot $value
+ double::setXrot $value}
+ y {double::setYrot $value
+ double::setYrot $value}
+ }
+
+ .o1 postredisplay
+ .o2 postredisplay
+}
+
+# Execution starts here!
+if { [info script] == $argv0 } {
+ ::double::setup
+}
diff --git a/ng/Togl2.1/gears.c b/ng/Togl2.1/gears.c
new file mode 100644
index 00000000..8e557dc3
--- /dev/null
+++ b/ng/Togl2.1/gears.c
@@ -0,0 +1,491 @@
+/* gears.c */
+
+/*
+ * 3-D gear wheels. This program is in the public domain.
+ *
+ * Brian Paul
+ *
+ *
+ * Modified to work under Togl as a widget for TK 1997
+ *
+ * Philip Quaife
+ *
+ */
+
+#define USE_TOGL_STUBS
+
+#include "togl.h"
+#include
+#include
+#include
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+
+#ifndef M_PI
+# define M_PI 3.14159265
+#endif
+#define FM_PI ((float) M_PI)
+
+#ifdef _MSC_VER
+__inline float
+sinf(double a)
+{
+ return (float) sin(a);
+}
+__inline float
+cosf(double a)
+{
+ return (float) cos(a);
+}
+__inline float
+sqrtf(double a)
+{
+ return (float) sqrt(a);
+}
+
+# define sin sinf
+# define cos cosf
+# define sqrt sqrtf
+#endif
+
+struct WHIRLYGIZMO
+{
+ int Gear1, Gear2, Gear3;
+ double Rotx, Roty, Rotz;
+ double Angle;
+ int Height, Width;
+};
+
+typedef struct WHIRLYGIZMO WHIRLYGIZMO;
+
+/*
+ * Draw a gear wheel. You'll probably want to call this function when
+ * building a display list since we do a lot of trig here.
+ *
+ * Input: inner_radius - radius of hole at center
+ * outer_radius - radius at center of teeth
+ * width - width of gear
+ * teeth - number of teeth
+ * tooth_depth - depth of tooth
+ */
+static void
+gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
+ GLint teeth, GLfloat tooth_depth)
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth / 2;
+ r2 = outer_radius + tooth_depth / 2;
+
+ da = 2 * FM_PI / teeth / 4;
+
+ glShadeModel(GL_FLAT);
+
+ glNormal3f(0, 0, 1);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2 * FM_PI / teeth;
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5f);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5f);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5f);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5f);
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2 * FM_PI / teeth / 4;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2 * FM_PI / teeth;
+
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5f);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5f);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ width * 0.5f);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5f);
+ }
+ glEnd();
+
+
+ glNormal3f(0, 0, -1);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2 * FM_PI / teeth;
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5f);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5f);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5f);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5f);
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2 * FM_PI / teeth / 4;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2 * FM_PI / teeth;
+
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5f);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ -width * 0.5f);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5f);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5f);
+ }
+ glEnd();
+
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2 * FM_PI / teeth;
+
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5f);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5f);
+ u = r2 * cos(angle + da) - r1 * cos(angle);
+ v = r2 * sin(angle + da) - r1 * sin(angle);
+ len = sqrt(u * u + v * v);
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5f);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5f);
+ glNormal3f(cos(angle), sin(angle), 0);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ width * 0.5f);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ -width * 0.5f);
+ u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
+ v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
+ glNormal3f(v, -u, 0);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5f);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5f);
+ glNormal3f(cos(angle), sin(angle), 0);
+ }
+
+ glVertex3f(r1 /* * cos(0) */ , /* r1 * sin(0) */ 0, width * 0.5f);
+ glVertex3f(r1 /* * cos(0) */ , /* r1 * sin(0) */ 0, -width * 0.5f);
+
+ glEnd();
+
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2 * FM_PI / teeth;
+ glNormal3f(-cos(angle), -sin(angle), 0);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5f);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5f);
+ }
+ glEnd();
+
+}
+
+/*
+ * static GLfloat view_rotx=20, view_roty=30, view_rotz=0; static GLint
+ * gear1, gear2, gear3; static GLfloat angle = 0; */
+static GLuint limit;
+static GLuint count = 1;
+
+static GLubyte polycolor[4] = { 255, 255, 255, 255 };
+
+static int
+draw(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+ WHIRLYGIZMO *Wg;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ Wg = (WHIRLYGIZMO *) Togl_GetClientData(togl);
+ glDisable(GL_TEXTURE_2D);
+ glPushMatrix();
+ glRotatef((float) Wg->Rotx, 1, 0, 0);
+ glRotatef((float) Wg->Roty, 0, 1, 0);
+ glRotatef((float) Wg->Rotz, 0, 0, 1);
+
+ glPushMatrix();
+ glTranslatef(-3, -2, 0);
+ glRotatef((float) Wg->Angle, 0, 0, 1);
+ glEnable(GL_DEPTH_TEST);
+ glCallList(Wg->Gear1);
+ glEnable(GL_DEPTH_TEST);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(3.1f, -2, 0);
+ glRotatef(-2 * (float) Wg->Angle - 9, 0, 0, 1);
+ glCallList(Wg->Gear2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-3.1f, 4.2f, 0);
+ glRotatef(-2 * (float) Wg->Angle - 25, 0, 0, 1);
+ glCallList(Wg->Gear3);
+ glPopMatrix();
+
+ glPopMatrix();
+
+ Togl_SwapBuffers(togl);
+
+ return TCL_OK;
+}
+
+
+static int
+zap(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+ WHIRLYGIZMO *Wg;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Wg = (WHIRLYGIZMO *) Togl_GetClientData(togl);
+ free(Wg);
+
+ return TCL_OK;
+}
+
+
+static int
+idle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+ WHIRLYGIZMO *Wg;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Wg = (WHIRLYGIZMO *) Togl_GetClientData(togl);
+ Wg->Angle += 2;
+ Togl_PostRedisplay(togl);
+
+ return TCL_OK;
+}
+
+
+/* change view angle, exit upon ESC */
+/*
+ * static GLenum key(int k, GLenum mask) { switch (k) { case TK_UP: view_rotx
+ * += 5; return GL_TRUE; case TK_DOWN: view_rotx -= 5; return GL_TRUE; case
+ * TK_LEFT: view_roty += 5; return GL_TRUE; case TK_RIGHT: view_roty -= 5;
+ * return GL_TRUE; case TK_z: view_rotz += 5; return GL_TRUE; case TK_Z:
+ * view_rotz -= 5; return GL_TRUE; } return GL_FALSE; } */
+
+/* new window size or exposure */
+static int
+reshape(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ int width, height;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ width = Togl_Width(togl);
+ height = Togl_Height(togl);
+ glViewport(0, 0, (GLint) width, (GLint) height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ if (width > height) {
+ GLfloat w = (GLfloat) width / (GLfloat) height;
+
+ glFrustum(-w, w, -1, 1, 5, 60);
+ } else {
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glFrustum(-1, 1, -h, h, 5, 60);
+ }
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -40);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ return TCL_OK;
+}
+
+
+static int
+init(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+ WHIRLYGIZMO *Wg;
+ static GLfloat red[4] = { 0.8f, 0.1f, 0, 1 };
+ static GLfloat green[4] = { 0, 0.8f, 0.2f, 1 };
+ static GLfloat blue[4] = { 0.2f, 0.2f, 1, 1 };
+ static GLfloat pos[4] = { 5, 5, 10, 0 };
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+ /* make the gears */
+ Wg = (WHIRLYGIZMO *) malloc(sizeof (WHIRLYGIZMO));
+ if (!Wg) {
+ Tcl_SetResult(Togl_Interp(togl),
+ "\"Cannot allocate client data for widget\"", TCL_STATIC);
+ }
+ Wg->Gear1 = glGenLists(1);
+ glNewList(Wg->Gear1, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
+ gear(1, 4, 1, 20, 0.7f);
+ glEndList();
+
+ Wg->Gear2 = glGenLists(1);
+ glNewList(Wg->Gear2, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
+ gear(0.5f, 2, 2, 10, 0.7f);
+ glEndList();
+
+ Wg->Gear3 = glGenLists(1);
+ glNewList(Wg->Gear3, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
+ gear(1.3f, 2, 0.5f, 10, 0.7f);
+ glEndList();
+
+ glEnable(GL_NORMALIZE);
+ Wg->Height = Togl_Height(togl);
+ Wg->Width = Togl_Width(togl);
+ Wg->Angle = 0;
+ Wg->Rotx = 0;
+ Wg->Roty = 0;
+ Wg->Rotz = 0;
+ Togl_SetClientData(togl, (ClientData) Wg);
+
+ return TCL_OK;
+}
+
+static int
+position(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ WHIRLYGIZMO *Wg;
+ char Result[100];
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Wg = (WHIRLYGIZMO *) Togl_GetClientData(togl);
+
+ /* Let result string equal value */
+ sprintf(Result, "%g %g", Wg->Roty, Wg->Rotx);
+
+ Tcl_SetResult(interp, Result, TCL_VOLATILE);
+ return TCL_OK;
+}
+
+static int
+rotate(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ WHIRLYGIZMO *Wg;
+ Togl *togl;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName yrot xrot");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Wg = (WHIRLYGIZMO *) Togl_GetClientData(togl);
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &Wg->Roty) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (Tcl_GetDoubleFromObj(interp, objv[3], &Wg->Rotx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Togl_PostRedisplay(togl);
+
+ return TCL_OK;
+}
+
+EXTERN int
+Gears_Init(Tcl_Interp *interp)
+{
+ /*
+ * Initialize Tcl and the Togl widget module.
+ */
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL
+ || Togl_InitStubs(interp, "2.0", 0) == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Specify the C callback functions for widget creation, display,
+ * and reshape.
+ */
+ Tcl_CreateObjCommand(interp, "init", init, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "zap", zap, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "draw", draw, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "reshape", reshape, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "idle", idle, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "rotate", rotate, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "position", position, NULL, NULL);
+ return TCL_OK;
+}
diff --git a/ng/Togl2.1/gears.tcl b/ng/Togl2.1/gears.tcl
new file mode 100644
index 00000000..42a77314
--- /dev/null
+++ b/ng/Togl2.1/gears.tcl
@@ -0,0 +1,90 @@
+#!/bin/sh
+# the next line restarts using tclsh \
+exec tclsh "$0" "$@"
+
+# Togl - a Tk OpenGL widget
+# Copyright (C) 1996-1997 Brian Paul and Ben Bederson
+# Copyright (C) 2006-2007 Greg Couch
+# See the LICENSE file for copyright details.
+
+
+#
+# Test Togl using GL Gears Demo
+#
+# Copyright (C) 1997 Philip Quaife
+#
+
+package provide gears 1.0
+
+# add parent directory to path to find Togl's pkgIndex in current directory
+if { [file exists pkgIndex.tcl] } {
+ set auto_path [linsert $auto_path 0 ..]
+}
+# following load also loads Tk and Togl packages
+load [file dirname [info script]]/gears[info sharedlibextension]
+
+# create ::gears namespace
+namespace eval ::gears {
+}
+
+proc ::gears::setup {} {
+ global startx starty xangle0 yangle0 xangle yangle RotCnt
+ global vTime
+ set RotCnt 1
+ set xangle 0.0
+ set yangle 0.0
+ set vTime 100
+ wm title . "Rotating Gear Widget Test"
+
+ label .t -text "Click and drag to rotate image"
+ pack .t -side top -padx 2 -pady 10
+ frame .f
+ pack .f -side top
+ button .f.n1 -text " Add " -command ::gears::AutoRot
+ button .f.r1 -text "Remove" -command ::gears::DelRot
+ button .f.b1 -text " Quit " -command exit
+ entry .f.t -width 4 -textvariable vTime
+ pack .f.n1 .f.t .f.r1 .f.b1 -side left -anchor w -padx 5
+ newRot .w0 10
+
+}
+proc ::gears::AutoRot {} {
+ global RotCnt vTime
+ newRot .w$RotCnt $vTime
+ set RotCnt [expr $RotCnt + 1]
+}
+
+proc ::gears::DelRot {} {
+ global RotCnt vTime
+ if { $RotCnt != 0 } {
+ set RotCnt [expr $RotCnt - 1]
+ destroy .w$RotCnt
+ }
+}
+
+proc ::gears::newRot {win {tick 100} } {
+ togl $win -width 200 -height 200 -rgba true -double true -depth true -privatecmap false -time $tick -create init -destroy zap -display draw -reshape reshape -timer idle
+ bind $win {::gears::RotStart %x %y %W}
+ bind $win {::gears::RotMove %x %y %W}
+ pack $win -expand true -fill both
+}
+
+proc ::gears::RotStart {x y W} {
+ global startx starty xangle0 yangle0 xangle yangle
+ set startx $x
+ set starty $y
+ set vPos [position $W]
+ set xangle0 [lindex $vPos 0]
+ set yangle0 [lindex $vPos 1]
+}
+
+proc ::gears::RotMove {x y W} {
+ global startx starty xangle0 yangle0 xangle yangle
+ set xangle [expr $xangle0 + ($x - $startx)]
+ set yangle [expr $yangle0 + ($y - $starty)]
+ rotate $W $xangle $yangle
+}
+
+if { [info script] == $argv0 } {
+ ::gears::setup
+}
diff --git a/ng/Togl2.1/image.c b/ng/Togl2.1/image.c
new file mode 100644
index 00000000..33e6a6a3
--- /dev/null
+++ b/ng/Togl2.1/image.c
@@ -0,0 +1,249 @@
+/*
+ * SGI rgb file reader borrowed from gltk library
+ */
+
+#include "togl.h" /* added by GG to include windows.h */
+#include
+#include
+#include
+#include "image.h"
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+#endif
+
+
+static void
+tkQuit(void)
+{
+ exit(0);
+}
+
+
+/******************************************************************************/
+
+typedef struct _rawImageRec
+{
+ unsigned short imagic;
+ unsigned short type;
+ unsigned short dim;
+ unsigned short sizeX, sizeY, sizeZ;
+ unsigned long min, max;
+ unsigned long wasteBytes;
+ char name[80];
+ unsigned long colorMap;
+ FILE *file;
+ unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
+ unsigned long rleEnd;
+ GLuint *rowStart;
+ GLint *rowSize;
+} rawImageRec;
+
+
+/******************************************************************************/
+
+static void
+ConvertShort(unsigned short *array, long length)
+{
+ unsigned long b1, b2;
+ unsigned char *ptr;
+
+ ptr = (unsigned char *) array;
+ while (length--) {
+ b1 = *ptr++;
+ b2 = *ptr++;
+ *array++ = (unsigned short) ((b1 << 8) | b2);
+ }
+}
+
+static void
+ConvertLong(GLuint *array, long length)
+{
+ unsigned long b1, b2, b3, b4;
+ unsigned char *ptr;
+
+ ptr = (unsigned char *) array;
+ while (length--) {
+ b1 = *ptr++;
+ b2 = *ptr++;
+ b3 = *ptr++;
+ b4 = *ptr++;
+ *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
+ }
+}
+
+static rawImageRec *
+RawImageOpen(const char *fileName)
+{
+ union
+ {
+ int testWord;
+ char testByte[4];
+ } endianTest;
+ rawImageRec *raw;
+ GLenum swapFlag;
+ int x;
+
+ endianTest.testWord = 1;
+ if (endianTest.testByte[0] == 1) {
+ swapFlag = GL_TRUE;
+ } else {
+ swapFlag = GL_FALSE;
+ }
+
+ raw = (rawImageRec *) malloc(sizeof (rawImageRec));
+ if (raw == NULL) {
+ fprintf(stderr, "Out of memory!\n");
+ tkQuit();
+ }
+ if ((raw->file = fopen(fileName, "rb")) == NULL) {
+ perror(fileName);
+ tkQuit();
+ }
+
+ fread(raw, 1, 12, raw->file);
+
+ if (swapFlag) {
+ ConvertShort(&raw->imagic, 6);
+ }
+
+ raw->tmp = (unsigned char *) malloc(raw->sizeX * 256);
+ raw->tmpR = (unsigned char *) malloc(raw->sizeX * 256);
+ raw->tmpG = (unsigned char *) malloc(raw->sizeX * 256);
+ raw->tmpB = (unsigned char *) malloc(raw->sizeX * 256);
+ raw->tmpA = (unsigned char *) malloc(raw->sizeX * 256);
+ if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
+ raw->tmpB == NULL || raw->tmpA == NULL) {
+ fprintf(stderr, "Out of memory!\n");
+ tkQuit();
+ }
+
+ if ((raw->type & 0xFF00) == 0x0100) {
+ x = raw->sizeY * raw->sizeZ * sizeof (GLuint);
+ raw->rowStart = (GLuint *) malloc(x);
+ raw->rowSize = (GLint *) malloc(x);
+ if (raw->rowStart == NULL || raw->rowSize == NULL) {
+ fprintf(stderr, "Out of memory!\n");
+ tkQuit();
+ }
+ raw->rleEnd = 512 + (2 * x);
+ fseek(raw->file, 512, SEEK_SET);
+ fread(raw->rowStart, 1, x, raw->file);
+ fread(raw->rowSize, 1, x, raw->file);
+ if (swapFlag) {
+ ConvertLong(raw->rowStart, x / sizeof (GLuint));
+ ConvertLong((GLuint *) raw->rowSize, x / sizeof (GLint));
+ }
+ }
+ return raw;
+}
+
+static void
+RawImageClose(rawImageRec * raw)
+{
+
+ fclose(raw->file);
+ free(raw->tmp);
+ free(raw->tmpR);
+ free(raw->tmpG);
+ free(raw->tmpB);
+ free(raw->tmpA);
+ free(raw);
+}
+
+static void
+RawImageGetRow(rawImageRec * raw, unsigned char *buf, int y, int z)
+{
+ unsigned char *iPtr, *oPtr, pixel;
+ int count;
+
+ if ((raw->type & 0xFF00) == 0x0100) {
+ fseek(raw->file, raw->rowStart[y + z * raw->sizeY], SEEK_SET);
+ fread(raw->tmp, 1, (unsigned int) raw->rowSize[y + z * raw->sizeY],
+ raw->file);
+
+ iPtr = raw->tmp;
+ oPtr = buf;
+ while (1) {
+ pixel = *iPtr++;
+ count = (int) (pixel & 0x7F);
+ if (!count) {
+ return;
+ }
+ if (pixel & 0x80) {
+ while (count--) {
+ *oPtr++ = *iPtr++;
+ }
+ } else {
+ pixel = *iPtr++;
+ while (count--) {
+ *oPtr++ = pixel;
+ }
+ }
+ }
+ } else {
+ fseek(raw->file, 512 + (y * raw->sizeX) + (z * raw->sizeX * raw->sizeY),
+ SEEK_SET);
+ fread(buf, 1, raw->sizeX, raw->file);
+ }
+}
+
+static void
+RawImageGetData(rawImageRec * raw, TK_RGBImageRec * final)
+{
+ unsigned char *ptr;
+ int i, j;
+
+ final->data =
+ (unsigned char *) malloc((raw->sizeX + 1) * (raw->sizeY + 1) * 4);
+ if (final->data == NULL) {
+ fprintf(stderr, "Out of memory!\n");
+ tkQuit();
+ }
+
+ ptr = final->data;
+ for (i = 0; i < (int) (raw->sizeY); i++) {
+ RawImageGetRow(raw, raw->tmpR, i, 0);
+ RawImageGetRow(raw, raw->tmpG, i, 1);
+ RawImageGetRow(raw, raw->tmpB, i, 2);
+ if (raw->sizeZ == 4) {
+ /* 4 components */
+ RawImageGetRow(raw, raw->tmpA, i, 3);
+ for (j = 0; j < (int) (raw->sizeX); j++) {
+ *ptr++ = *(raw->tmpR + j);
+ *ptr++ = *(raw->tmpG + j);
+ *ptr++ = *(raw->tmpB + j);
+ *ptr++ = *(raw->tmpA + j);
+ }
+ } else {
+ /* 3 components */
+ for (j = 0; j < (int) (raw->sizeX); j++) {
+ *ptr++ = *(raw->tmpR + j);
+ *ptr++ = *(raw->tmpG + j);
+ *ptr++ = *(raw->tmpB + j);
+ }
+ }
+ }
+}
+
+TK_RGBImageRec *
+tkRGBImageLoad(const char *fileName)
+{
+ rawImageRec *raw;
+ TK_RGBImageRec *final;
+
+ raw = RawImageOpen(fileName);
+ final = (TK_RGBImageRec *) malloc(sizeof (TK_RGBImageRec));
+ if (final == NULL) {
+ fprintf(stderr, "Out of memory!\n");
+ tkQuit();
+ }
+ final->sizeX = raw->sizeX;
+ final->sizeY = raw->sizeY;
+ final->sizeZ = raw->sizeZ;
+ RawImageGetData(raw, final);
+ RawImageClose(raw);
+ return final;
+}
+
+/******************************************************************************/
diff --git a/ng/Togl2.1/image.h b/ng/Togl2.1/image.h
new file mode 100644
index 00000000..30b537bc
--- /dev/null
+++ b/ng/Togl2.1/image.h
@@ -0,0 +1,14 @@
+/* image.h */
+
+#ifndef IMAGE_H
+# define IMAGE_H
+
+typedef struct _TK_RGBImageRec
+{
+ int sizeX, sizeY, sizeZ;
+ unsigned char *data;
+} TK_RGBImageRec;
+
+extern TK_RGBImageRec *tkRGBImageLoad(const char *fileName);
+
+#endif
diff --git a/ng/Togl2.1/index.c b/ng/Togl2.1/index.c
new file mode 100644
index 00000000..7bbffccc
--- /dev/null
+++ b/ng/Togl2.1/index.c
@@ -0,0 +1,227 @@
+/* $Id: index.c,v 1.13 2007/08/03 16:48:50 gregcouch Exp $ */
+
+/*
+ * Togl - a Tk OpenGL widget
+ * Copyright (C) 1996-1997 Brian Paul and Ben Bederson
+ * Copyright (C) 2006-2007 Greg Couch
+ * See the LICENSE file for copyright details.
+ */
+
+
+/*
+ * An example Togl program using color-index mode.
+ */
+
+#define USE_TOGL_STUBS
+
+#include "togl.h"
+#include
+#include
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+
+
+/* Our color indexes: */
+static unsigned long black, red, green, blue;
+
+/* Rotation angle */
+static float Angle = 0;
+
+
+/*
+ * Togl widget create callback. This is called by Tcl/Tk when the widget has
+ * been realized. Here's where one may do some one-time context setup or
+ * initializations.
+ */
+static int
+create_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* allocate color indexes */
+ black = Togl_AllocColor(togl, 0, 0, 0);
+ red = Togl_AllocColor(togl, 1, 0, 0);
+ green = Togl_AllocColor(togl, 0, 1, 0);
+ blue = Togl_AllocColor(togl, 0, 0, 1);
+
+ /* If we were using a private read/write colormap we'd setup our color
+ * table with something like this: */
+ /*
+ * black = 1; Togl_SetColor( togl, black, 0, 0, 0 ); red = 2;
+ * Togl_SetColor( togl, red, 1, 0, 0 ); green = 3; Togl_SetColor(
+ * togl, green, 0, 1, 0 ); blue = 4; Togl_SetColor( togl, blue, 0,
+ * 0, 1 ); */
+
+ glShadeModel(GL_FLAT);
+ glDisable(GL_DITHER);
+
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget reshape callback. This is called by Tcl/Tk when the widget
+ * has been resized. Typically, we call glViewport and perhaps setup the
+ * projection matrix.
+ */
+static int
+reshape_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ int width;
+ int height;
+ float aspect;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ width = Togl_Width(togl);
+ height = Togl_Height(togl);
+ aspect = (float) width / (float) height;
+ glViewport(0, 0, width, height);
+
+ /* Set up projection transform */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-aspect, aspect, -1, 1, -1, 1);
+
+ /* Change back to model view transform for rendering */
+ glMatrixMode(GL_MODELVIEW);
+
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget display callback. This is called by Tcl/Tk when the widget's
+ * contents have to be redrawn. Typically, we clear the color and depth
+ * buffers, render our objects, then swap the front/back color buffers.
+ */
+static int
+display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ glClearIndex((float) black);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glPushMatrix();
+ glTranslatef(0.3f, -0.3f, 0);
+ glRotatef(Angle, 0, 0, 1);
+ glIndexi(red);
+ glBegin(GL_TRIANGLES);
+ glVertex2f(-0.5f, -0.3f);
+ glVertex2f(0.5f, -0.3f);
+ glVertex2f(0, 0.6f);
+ glEnd();
+ glPopMatrix();
+
+ glPushMatrix();
+ glRotatef(Angle, 0, 0, 1);
+ glIndexi(green);
+ glBegin(GL_TRIANGLES);
+ glVertex2f(-0.5f, -0.3f);
+ glVertex2f(0.5f, -0.3f);
+ glVertex2f(0, 0.6f);
+ glEnd();
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-0.3f, 0.3f, 0);
+ glRotatef(Angle, 0, 0, 1);
+ glIndexi(blue);
+ glBegin(GL_TRIANGLES);
+ glVertex2f(-0.5f, -0.3f);
+ glVertex2f(0.5f, -0.3f);
+ glVertex2f(0, 0.6f);
+ glEnd();
+ glPopMatrix();
+
+ glFlush();
+ Togl_SwapBuffers(togl);
+
+ return TCL_OK;
+}
+
+
+static int
+timer_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Angle += 5.0;
+ Togl_PostRedisplay(togl);
+
+ return TCL_OK;
+}
+
+
+EXTERN int
+Index_Init(Tcl_Interp *interp)
+{
+ /*
+ * Initialize Tcl and the Togl widget module.
+ */
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL
+ || Togl_InitStubs(interp, "2.0", 0) == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Specify the C callback functions for widget creation, display,
+ * and reshape.
+ */
+ Tcl_CreateObjCommand(interp, "::index::create_cb", create_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "::index::display_cb", display_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "::index::reshape_cb", reshape_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "::index::timer_cb", timer_cb, NULL, NULL);
+
+ /*
+ * Make a new Togl widget command so the Tcl code can set a C variable.
+ */
+ /* NONE */
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+ return TCL_OK;
+}
diff --git a/ng/Togl2.1/index.tcl b/ng/Togl2.1/index.tcl
new file mode 100644
index 00000000..ab2d49a8
--- /dev/null
+++ b/ng/Togl2.1/index.tcl
@@ -0,0 +1,50 @@
+#!/bin/sh
+# the next line restarts using tclsh \
+exec tclsh "$0" "$@"
+
+# $Id: index.tcl,v 1.8 2007/08/03 16:48:50 gregcouch Exp $
+
+# Togl - a Tk OpenGL widget
+# Copyright (C) 1996 Brian Paul and Ben Bederson
+# Copyright (C) 2006-2007 Greg Couch
+# See the LICENSE file for copyright details.
+
+
+# A Tk/OpenGL widget demo using color-index mode.
+
+package provide index 1.0
+
+# add parent directory to path to find Togl's pkgIndex in current directory
+if { [file exists pkgIndex.tcl] } {
+ set auto_path [linsert $auto_path 0 ..]
+}
+# following load also loads Tk and Togl packages
+load [file dirname [info script]]/index[info sharedlibextension]
+
+# create ::index namespace
+namespace eval ::index {
+}
+
+proc ::index::setup {} {
+ wm title . "Color index demo"
+
+ togl .win -width 200 -height 200 -rgba false -double true -privatecmap false -time 10 -timer ::index::timer_cb -create ::index::create_cb -reshape ::index::reshape_cb -display ::index::display_cb
+ button .photo -text "Take Photo" -command ::index::take_photo
+ button .btn -text Quit -command exit
+
+ pack .win -expand true -fill both
+ pack .photo -expand true -fill both
+ pack .btn -expand true -fill both
+}
+
+proc ::index::take_photo {} {
+ image create photo img
+ .win takephoto img
+ img write image.ppm -format ppm
+}
+
+
+# Execution starts here!
+if { [info script] == $argv0 } {
+ ::index::setup
+}
diff --git a/ng/Togl2.1/multisample.tcl b/ng/Togl2.1/multisample.tcl
new file mode 100644
index 00000000..bdbcd100
--- /dev/null
+++ b/ng/Togl2.1/multisample.tcl
@@ -0,0 +1,96 @@
+#!/bin/sh
+# the next line restarts using tclsh \
+exec tclsh "$0" "$@"
+
+# $Id: multisample.tcl,v 1.3 2009/03/12 23:59:35 gregcouch Exp $
+
+# Togl - a Tk OpenGL widget
+# Copyright (C) 1996 Brian Paul and Ben Bederson
+# Copyright (C) 2006-2007 Greg Couch
+# See the LICENSE file for copyright details.
+
+
+# An Tk/OpenGL widget demo with two windows, one aliased and the
+# other multisampled. Reuse C code from double buffering demo.
+
+package provide multisample 1.0
+
+# add parent directory to path to find Togl's pkgIndex in current directory
+if { [file exists pkgIndex.tcl] } {
+ set auto_path [linsert $auto_path 0 ..]
+}
+# following load also loads Tk and Togl packages
+load [file dirname [info script]]/double[info sharedlibextension]
+
+# create ::multisample namespace
+namespace eval ::multisample {
+}
+
+proc multisample::setup {} {
+ wm title . "Multisample vs Aliased"
+
+ # create first Togl widget
+ togl .o1 -width 200 -height 200 -rgba true -double true -depth true -create double::create_cb -display double::display_cb -reshape double::reshape_cb -multisample false -ident Aliased
+
+ # create second Togl widget, share display lists with first widget
+ togl .o2 -width 200 -height 200 -rgba true -double true -depth true -create double::create_cb -display double::display_cb -reshape double::reshape_cb -multisample true -ident Multisampled -sharelist Aliased
+
+ scale .sx -label {X Axis} -from 0 -to 360 -command {::multisample::setAngle x} -orient horizontal
+ scale .sy -label {Y Axis} -from 0 -to 360 -command {::multisample::setAngle y} -orient horizontal
+ button .btn -text Quit -command exit
+
+ bind .o1 {
+ ::multisample::motion_event [lindex [%W config -width] 4] \
+ [lindex [%W config -height] 4] \
+ %x %y
+ }
+
+ bind .o2 {
+ ::multisample::motion_event [lindex [%W config -width] 4] \
+ [lindex [%W config -height] 4] \
+ %x %y
+ }
+
+ grid rowconfigure . 0 -weight 1
+ grid columnconfigure . 0 -weight 1 -uniform same
+ grid columnconfigure . 1 -weight 1 -uniform same
+ grid .o1 -row 0 -column 0 -sticky nesw -padx 3 -pady 3
+ grid .o2 -row 0 -column 1 -sticky nesw -padx 3 -pady 3
+ #grid .l1 -row 1 -column 0 -sticky ew -padx 3 -pady 3
+ #grid .l2 -row 1 -column 1 -sticky ew -padx 3 -pady 3
+ grid .sx -row 2 -column 0 -columnspan 2 -sticky ew
+ grid .sy -row 3 -column 0 -columnspan 2 -sticky ew
+ grid .btn -row 4 -column 0 -columnspan 2 -sticky ew
+}
+
+
+
+# This is called when mouse button 1 is pressed and moved in either of
+# the OpenGL windows.
+proc multisample::motion_event { width height x y } {
+ .sx set [double::setXrot [expr 360.0 * $y / $height]]
+ .sy set [double::setYrot [expr 360.0 * ($width - $x) / $width]]
+
+ .o1 postredisplay
+ .o2 postredisplay
+}
+
+# This is called when a slider is changed.
+proc multisample::setAngle {axis value} {
+ global xAngle yAngle zAngle
+
+ switch -exact $axis {
+ x {double::setXrot $value
+ double::setXrot $value}
+ y {double::setYrot $value
+ double::setYrot $value}
+ }
+
+ .o1 postredisplay
+ .o2 postredisplay
+}
+
+# Execution starts here!
+if { [info script] == $argv0 } {
+ ::multisample::setup
+}
diff --git a/ng/Togl2.1/overlay.c b/ng/Togl2.1/overlay.c
new file mode 100644
index 00000000..630179ca
--- /dev/null
+++ b/ng/Togl2.1/overlay.c
@@ -0,0 +1,214 @@
+/* $Id: overlay.c,v 1.10 2007/08/03 16:48:50 gregcouch Exp $ */
+
+/*
+ * Togl - a Tk OpenGL widget
+ * Copyright (C) 1996-1997 Brian Paul and Ben Bederson
+ * Copyright (C) 2006-2007 Greg Couch
+ * See the LICENSE file for copyright details.
+ */
+
+
+/*
+ * An example Togl program using an overlay.
+ */
+
+#define USE_TOGL_STUBS
+
+#include "togl.h"
+#include
+#include
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+
+
+/* Overlay color indexes: */
+static unsigned long Red, Green;
+
+
+/*
+ * Togl widget create callback. This is called by Tcl/Tk when the widget has
+ * been realized. Here's where one may do some one-time context setup or
+ * initializations.
+ */
+static int
+create_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* allocate overlay color indexes */
+ Red = Togl_AllocColorOverlay(togl, 1, 0, 0);
+ Green = Togl_AllocColorOverlay(togl, 0, 1, 0);
+
+ /* in this demo we always show the overlay */
+ if (Togl_ExistsOverlay(togl)) {
+ Togl_ShowOverlay(togl);
+ printf("Red and green lines are in the overlay\n");
+ } else {
+ printf("Sorry, this display doesn't support overlays\n");
+ }
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget reshape callback. This is called by Tcl/Tk when the widget
+ * has been resized. Typically, we call glViewport and perhaps setup the
+ * projection matrix.
+ */
+static int
+reshape_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ int width;
+ int height;
+ float aspect;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ width = Togl_Width(togl);
+ height = Togl_Height(togl);
+ aspect = (float) width / (float) height;
+
+ /* Set up viewing for normal plane's context */
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-aspect, aspect, -1, 1, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+
+ /* Set up viewing for overlay plane's context */
+ if (Togl_ExistsOverlay(togl)) {
+ Togl_UseLayer(togl, TOGL_OVERLAY);
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-1, 1, -1, 1, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ Togl_UseLayer(togl, TOGL_NORMAL);
+ }
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget overlay display callback. This is called by Tcl/Tk when the
+ * overlay has to be redrawn.
+ */
+static int
+overlay_display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glIndexi(Red);
+ glBegin(GL_LINES);
+ glVertex2f(-1, -1);
+ glVertex2f(1, 1);
+ glVertex2f(-1, 1);
+ glVertex2f(1, -1);
+ glEnd();
+
+ glIndexi(Green);
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(-0.5f, -0.5f);
+ glVertex2f(0.5f, -0.5f);
+ glVertex2f(0.5f, 0.5f);
+ glVertex2f(-0.5f, 0.5f);
+ glEnd();
+ glFlush();
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget display callback. This is called by Tcl/Tk when the widget's
+ * contents have to be redrawn. Typically, we clear the color and depth
+ * buffers, render our objects, then swap the front/back color buffers.
+ */
+static int
+display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glLoadIdentity();
+
+ glBegin(GL_TRIANGLES);
+
+ glColor3f(1, 0, 1);
+ glVertex2f(-0.5f, -0.3f);
+ glVertex2f(0.5f, -0.3f);
+ glVertex2f(0, 0.6f);
+
+ glColor3f(1, 1, 0);
+ glVertex2f(-0.5f + 0.2f, -0.3f - 0.2f);
+ glVertex2f(0.5f + 0.2f, -0.3f - 0.2f);
+ glVertex2f(0 + 0.2f, 0.6f - 0.2f);
+
+ glColor3f(0, 1, 1);
+ glVertex2f(-0.5f + 0.4f, -0.3f - 0.4f);
+ glVertex2f(0.5f + 0.4f, -0.3f - 0.4f);
+ glVertex2f(0 + 0.4f, 0.6f - 0.4f);
+
+ glEnd();
+
+ glFlush();
+ return TCL_OK;
+}
+
+
+/*
+ * Called by Tcl to let me initialize the modules (Togl) I will need.
+ */
+EXTERN int
+Overlay_Init(Tcl_Interp *interp)
+{
+ /*
+ * Initialize Tcl and the Togl widget module.
+ */
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL
+ || Togl_InitStubs(interp, "2.0", 0) == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Specify the C callback functions for widget creation, display,
+ * and reshape.
+ */
+ Tcl_CreateObjCommand(interp, "create_cb", create_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "display_cb", display_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "reshape_cb", reshape_cb, NULL, NULL);
+
+ Tcl_CreateObjCommand(interp, "overlay_display_cb", overlay_display_cb, NULL,
+ NULL);
+
+ /*
+ * Make a new Togl widget command so the Tcl code can set a C variable.
+ */
+ /* NONE */
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+ return TCL_OK;
+}
diff --git a/ng/Togl2.1/overlay.tcl b/ng/Togl2.1/overlay.tcl
new file mode 100644
index 00000000..9a1d83d6
--- /dev/null
+++ b/ng/Togl2.1/overlay.tcl
@@ -0,0 +1,37 @@
+#!/bin/sh
+# the next line restarts using tclsh \
+exec tclsh "$0" "$@"
+
+# $Id: overlay.tcl,v 1.7 2007/08/03 16:48:50 gregcouch Exp $
+
+# Togl - a Tk OpenGL widget
+# Copyright (C) 1996 Brian Paul and Ben Bederson
+# Copyright (C) 2006-2007 Greg Couch
+# See the LICENSE file for copyright details.
+
+
+# A Tk/OpenGL widget demo using an overlay.
+
+# add parent directory to path to find Togl's pkgIndex in current directory
+if { [file exists pkgIndex.tcl] } {
+ set auto_path [linsert $auto_path 0 ..]
+}
+# following load also loads Tk and Togl packages
+load [file dirname [info script]]/overlay[info sharedlibextension]
+
+proc setup {} {
+ wm title . "Overlay demo"
+
+ togl .win -width 200 -height 200 -rgba true -double false -overlay true -create create_cb -reshape reshape_cb -display display_cb -overlaydisplay overlay_display_cb
+ button .btn -text Quit -command exit
+
+ pack .win -expand true -fill both
+ pack .btn -expand true -fill both
+}
+
+
+# Execution starts here!
+# Execution starts here!
+if { [info script] == $argv0 } {
+ setup
+}
diff --git a/ng/Togl2.1/pbuffer.c b/ng/Togl2.1/pbuffer.c
new file mode 100644
index 00000000..a032d03c
--- /dev/null
+++ b/ng/Togl2.1/pbuffer.c
@@ -0,0 +1,489 @@
+/* $Id: pbuffer.c,v 1.2 2009/02/05 06:57:10 gregcouch Exp $ */
+
+/*
+ * Togl - a Tk OpenGL widget
+ * Copyright (C) 1996-1997 Brian Paul and Ben Bederson
+ * Copyright (C) 2006-2007 Greg Couch
+ * See the LICENSE file for copyright details.
+ */
+
+#undef PBUFFER_DEBUG
+
+#define USE_TOGL_STUBS
+
+#include "togl.h"
+#include
+#include
+#include
+#if defined(TOGL_AGL)
+# include
+# include
+#elif defined(TOGL_NSOPENGL)
+# include
+# include
+#else
+# include
+#endif
+#include /* OpenGL 1.4 GL_GENERATE_MIPMAP */
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+
+static double xAngle = 0, yAngle = 0, zAngle = 0;
+static GLdouble CornerX, CornerY, CornerZ; /* where to print strings */
+static GLuint texture;
+static Togl *output;
+
+/*
+ * Togl widget create callback. This is called by Tcl/Tk when the widget has
+ * been realized. Here's where one may do some one-time context setup or
+ * initializations.
+ */
+static int
+create_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+ double version;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ version = atof((const char *) glGetString(GL_VERSION));
+ if (version < 1.4) {
+ Tcl_SetResult(interp, "need OpenGL 1.4 or later", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget reshape callback. This is called by Tcl/Tk when the widget
+ * has been resized. Typically, we call glViewport and perhaps setup the
+ * projection matrix.
+ */
+static int
+reshape_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ int width;
+ int height;
+ double aspect;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ width = Togl_Width(togl);
+ height = Togl_Height(togl);
+ aspect = (double) width / (double) height;
+
+ glViewport(0, 0, width, height);
+
+ /* Set up projection transform */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-aspect, aspect, -1, 1, 1, 10);
+
+ CornerX = -aspect;
+ CornerY = -1;
+ CornerZ = -1.1;
+
+ /* Change back to model view transform for rendering */
+ glMatrixMode(GL_MODELVIEW);
+
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget reshape callback. This is called by Tcl/Tk when the widget
+ * has been resized. Typically, we call glViewport and perhaps setup the
+ * projection matrix.
+ */
+static int
+reshape2_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ int width;
+ int height;
+ double aspect;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ width = Togl_Width(togl);
+ height = Togl_Height(togl);
+ aspect = (double) width / (double) height;
+
+ glViewport(0, 0, width, height);
+
+ /* Set up projection transform */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-aspect, aspect, -1, 1, -1, 1);
+
+ /* Change back to model view transform for rendering */
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ return TCL_OK;
+}
+
+
+static void
+draw_object()
+{
+ static GLuint cubeList = 0;
+
+ glLoadIdentity(); /* Reset modelview matrix to the identity
+ * matrix */
+ glTranslatef(0, 0, -3); /* Move the camera back three units */
+ glRotated(xAngle, 1, 0, 0); /* Rotate by X, Y, and Z angles */
+ glRotated(yAngle, 0, 1, 0);
+ glRotated(zAngle, 0, 0, 1);
+
+ glEnable(GL_DEPTH_TEST);
+
+ if (!cubeList) {
+ cubeList = glGenLists(1);
+ glNewList(cubeList, GL_COMPILE);
+
+ /* Front face */
+ glBegin(GL_QUADS);
+ glColor3f(0, 0.7f, 0.1f); /* Green */
+ glVertex3f(-1, 1, 1);
+ glVertex3f(1, 1, 1);
+ glVertex3f(1, -1, 1);
+ glVertex3f(-1, -1, 1);
+ /* Back face */
+ glColor3f(0.9f, 1, 0); /* Yellow */
+ glVertex3f(-1, 1, -1);
+ glVertex3f(1, 1, -1);
+ glVertex3f(1, -1, -1);
+ glVertex3f(-1, -1, -1);
+ /* Top side face */
+ glColor3f(0.2f, 0.2f, 1); /* Blue */
+ glVertex3f(-1, 1, 1);
+ glVertex3f(1, 1, 1);
+ glVertex3f(1, 1, -1);
+ glVertex3f(-1, 1, -1);
+ /* Bottom side face */
+ glColor3f(0.7f, 0, 0.1f); /* Red */
+ glVertex3f(-1, -1, 1);
+ glVertex3f(1, -1, 1);
+ glVertex3f(1, -1, -1);
+ glVertex3f(-1, -1, -1);
+ glEnd();
+
+ glEndList();
+
+ }
+ glCallList(cubeList);
+}
+
+/*
+ * Togl widget display callback. This is called by Tcl/Tk when the widget's
+ * contents have to be redrawn. Typically, we clear the color and depth
+ * buffers, render our objects, then swap the front/back color buffers.
+ */
+static int
+display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK)
+ return TCL_ERROR;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ draw_object();
+
+#ifdef PBUFFER_DEBUG
+ {
+ Tk_PhotoHandle photo;
+
+ /* first tcl: image create photo test */
+ photo = Tk_FindPhoto(interp, "test2");
+ if (photo == NULL) {
+ fprintf(stderr, "missing tk photo object test2\n");
+ } else {
+ Togl_TakePhoto(togl, photo);
+ Tcl_Eval(interp, "test2 write test2.ppm -format ppm");
+ }
+ }
+#endif
+ Togl_SwapBuffers(togl);
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget display callback. This is called by Tcl/Tk when the widget's
+ * contents have to be redrawn. Typically, we clear the color and depth
+ * buffers, render our objects, then swap the front/back color buffers.
+ */
+static int
+display2_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK)
+ return TCL_ERROR;
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ if (texture) {
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glBegin(GL_QUADS);
+ glTexCoord2i(0, 0);
+ glVertex2i(-1, -1);
+ glTexCoord2i(1, 0);
+ glVertex2i(1, -1);
+ glTexCoord2i(1, 1);
+ glVertex2i(1, 1);
+ glTexCoord2i(0, 1);
+ glVertex2i(-1, 1);
+ glEnd();
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+
+ Togl_SwapBuffers(togl);
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget display callback. This is called by Tcl/Tk when the widget's
+ * contents have to be redrawn. Typically, we clear the color and depth
+ * buffers, render our objects, then swap the front/back color buffers.
+ */
+static int
+pbuffer_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+ int width;
+ int height;
+ GLenum error;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK)
+ return TCL_ERROR;
+
+ width = Togl_Width(togl);
+ height = Togl_Height(togl);
+
+ if (texture == 0) {
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+#if !defined(TOGL_AGL) && !defined(TOGL_NSOPENGL)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_LINEAR);
+#else
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+#endif
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
+ GL_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ error = glGetError();
+ if (error != GL_NO_ERROR) {
+ fprintf(stderr, "texture init: %s\n", gluErrorString(error));
+ }
+#if 0 && defined(TOGL_AGL)
+ AGLContext ctx = aglGetCurrentContext();
+ AGLPbuffer pbuf;
+ GLint face, level, screen;
+ GLenum err;
+
+ aglGetPBuffer(ctx, &pbuf, &face, &level, &screen);
+ err = aglGetError();
+ if (err != AGL_NO_ERROR)
+ fprintf(stderr, "getPBuffer: %s\n", aglErrorString(err));
+ aglTexImagePBuffer(ctx, pbuf, GL_FRONT);
+ err = aglGetError();
+ if (err != AGL_NO_ERROR)
+ fprintf(stderr, "teximagepbuffer: %s\n", aglErrorString(err));
+#endif
+ }
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ draw_object();
+
+#if 1 || !defined(TOGL_AGL)
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ error = glGetError();
+ if (error != GL_NO_ERROR) {
+ fprintf(stderr, "after tex copy: %s\n", gluErrorString(error));
+ }
+#endif
+#ifdef PBUFFER_DEBUG
+ {
+ Tk_PhotoHandle photo;
+
+ /* first tcl: image create photo test */
+ photo = Tk_FindPhoto(interp, "test");
+ Togl_TakePhoto(togl, photo);
+ Tcl_Eval(interp, "test write test.ppm -format ppm");
+ }
+#endif
+ Togl_SwapBuffers(togl);
+ if (output)
+ Togl_PostRedisplay(output);
+
+ return TCL_OK;
+}
+
+
+static int
+setXrot_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "angle");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[1], &xAngle) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* printf( "before %f ", xAngle ); */
+
+ xAngle = fmod(xAngle, 360.0);
+ if (xAngle < 0.0)
+ xAngle += 360.0;
+
+ /* printf( "after %f \n", xAngle ); */
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+}
+
+
+static int
+setYrot_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "angle");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[1], &yAngle) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ yAngle = fmod(yAngle, 360.0);
+ if (yAngle < 0.0)
+ yAngle += 360.0;
+
+ /* Let result equal value */
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+}
+
+static int
+setOutput_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &output) != TCL_OK)
+ return TCL_ERROR;
+
+ return TCL_OK;
+}
+
+/*
+ * Called by Tcl to let me initialize the modules (Togl) I will need.
+ */
+EXTERN int
+Pbuffer_Init(Tcl_Interp *interp)
+{
+ /*
+ * Initialize Tcl and the Togl widget module.
+ */
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL
+#ifdef PBUFFER_DEBUG
+ || Tk_InitStubs(interp, "8.1", 0) == NULL
+#endif
+ || Togl_InitStubs(interp, "2.0", 0) == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Specify the C callback functions for widget creation, display,
+ * and reshape.
+ */
+ Tcl_CreateObjCommand(interp, "create_cb", create_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "display_cb", display_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "display2_cb", display2_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "pbuffer_cb", pbuffer_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "reshape_cb", reshape_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "reshape2_cb", reshape2_cb, NULL, NULL);
+
+ /*
+ * Make a new Togl widget command so the Tcl code can set a C variable.
+ */
+
+ Tcl_CreateObjCommand(interp, "setXrot", setXrot_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "setYrot", setYrot_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "setOutput", setOutput_cb, NULL, NULL);
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+
+ return TCL_OK;
+}
diff --git a/ng/Togl2.1/pbuffer.tcl b/ng/Togl2.1/pbuffer.tcl
new file mode 100644
index 00000000..8ffbfa79
--- /dev/null
+++ b/ng/Togl2.1/pbuffer.tcl
@@ -0,0 +1,115 @@
+#!/bin/sh
+# the next line restarts using tclsh \
+exec tclsh "$0" "$@"
+
+# $Id: pbuffer.tcl,v 1.1 2009/01/29 22:45:46 gregcouch Exp $
+
+# Togl - a Tk OpenGL widget
+# Copyright (C) 1996 Brian Paul and Ben Bederson
+# Copyright (C) 2006-2007 Greg Couch
+# See the LICENSE file for copyright details.
+
+
+# An Tk/OpenGL widget demo with two double-buffered OpenGL windows.
+# The first shows the aliased object, the second show the results of
+# rendering the same object in a higher resolution Pbuffer and using
+# texture mapping to antialias it.
+
+package provide pbuffer 1.0
+
+# add parent directory to path to find Togl's pkgIndex in current directory
+if { [file exists pkgIndex.tcl] } {
+ set auto_path [linsert $auto_path 0 ..]
+}
+# following load also loads Tk and Togl packages
+load [file dirname [info script]]/pbuffer[info sharedlibextension]
+
+# create ::pbuffer namespace
+namespace eval ::pbuffer {
+}
+
+proc pbuffer::setup {} {
+ wm title . "Pbuffer test"
+
+#debug
+ image create photo test
+ image create photo test2
+#end debug
+
+ # create first Togl widget
+ togl .o1 -width 300 -height 300 -rgba true -double true -depth true -ident main -create create_cb -reshape reshape_cb -display display_cb
+ label .l1 -text "RGB, Z, double"
+
+ # create second Togl widget, share display lists with first widget, no depth
+ togl .o2 -width 300 -height 300 -rgba true -double true -sharelist main -reshape reshape2_cb -display display2_cb -ident second
+ setOutput .o2
+ label .l2 -text "RGB from pbuffer texture"
+
+ # create off-screen pbuffer, share display lists with other widgets
+ # must power of 2 squared in size
+ togl .pbuf -width 2048 -height 2048 -rgba true -depth true -sharelist main -pbuffer 1 -reshape reshape_cb -display pbuffer_cb -ident pbuffer
+
+ scale .sx -label {X Axis} -from 0 -to 360 -command {::pbuffer::setAngle x} -orient horizontal
+ scale .sy -label {Y Axis} -from 0 -to 360 -command {::pbuffer::setAngle y} -orient horizontal
+ button .btn -text Quit -command exit
+
+ bind .o1 {
+ ::pbuffer::motion_event [lindex [%W config -width] 4] \
+ [lindex [%W config -height] 4] \
+ %x %y
+ }
+
+ bind .o2 {
+ ::pbuffer::motion_event [lindex [%W config -width] 4] \
+ [lindex [%W config -height] 4] \
+ %x %y
+ }
+
+ grid rowconfigure . 0 -weight 1
+ grid columnconfigure . 0 -weight 1 -uniform same
+ grid columnconfigure . 1 -weight 1 -uniform same
+ grid .o1 -row 0 -column 0 -sticky nesw -padx 3 -pady 3
+ grid .o2 -row 0 -column 1 -sticky nesw -padx 3 -pady 3
+ grid .l1 -row 1 -column 0 -sticky ew -padx 3 -pady 3
+ grid .l2 -row 1 -column 1 -sticky ew -padx 3 -pady 3
+ grid .sx -row 2 -column 0 -columnspan 2 -sticky ew
+ grid .sy -row 3 -column 0 -columnspan 2 -sticky ew
+ grid .btn -row 4 -column 0 -columnspan 2 -sticky ew
+}
+
+
+proc pbuffer::display { } {
+ pbuffer_cb .pbuf
+ .o2 postredisplay
+}
+
+
+# This is called when mouse button 1 is pressed and moved in either of
+# the OpenGL windows.
+proc pbuffer::motion_event { width height x y } {
+ .sx set [setXrot [expr 360.0 * $y / $height]]
+ .sy set [setYrot [expr 360.0 * ($width - $x) / $width]]
+
+ .o1 postredisplay
+ .pbuf postredisplay
+}
+
+# This is called when a slider is changed.
+proc pbuffer::setAngle {axis value} {
+ global xAngle yAngle zAngle
+
+ switch -exact $axis {
+ x {setXrot $value
+ setXrot $value}
+ y {setYrot $value
+ setYrot $value}
+ }
+
+ .o1 postredisplay
+ .pbuf postredisplay
+}
+
+# Execution starts here!
+if { [info script] == $argv0 } {
+ ::pbuffer::setup
+}
diff --git a/ng/Togl2.1/pkgIndex.tcl.in b/ng/Togl2.1/pkgIndex.tcl.in
new file mode 100644
index 00000000..af071e36
--- /dev/null
+++ b/ng/Togl2.1/pkgIndex.tcl.in
@@ -0,0 +1,5 @@
+#
+# Tcl package index file
+#
+package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ \
+ [list load [file join $dir @PKG_LIB_FILE@]]
diff --git a/ng/Togl2.1/stereo.c b/ng/Togl2.1/stereo.c
new file mode 100644
index 00000000..99bd22f2
--- /dev/null
+++ b/ng/Togl2.1/stereo.c
@@ -0,0 +1,343 @@
+/* $Id: stereo.c,v 1.14 2009/02/07 07:04:50 gregcouch Exp $ */
+
+/*
+ * Togl - a Tk OpenGL widget
+ * Copyright (C) 1996-1997 Brian Paul and Ben Bederson
+ * Copyright (C) 2006-2009 Greg Couch
+ * See the LICENSE file for copyright details.
+ */
+
+#define USE_TOGL_STUBS
+
+#include "togl.h"
+#include
+#include
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+
+
+static Tcl_Obj *toglFont;
+static double xAngle = 0, yAngle = 0, zAngle = 0;
+static GLfloat CornerX, CornerY, CornerZ; /* where to print strings */
+static double coord_scale = 1;
+
+
+
+/*
+ * Togl widget create callback. This is called by Tcl/Tk when the widget has
+ * been realized. Here's where one may do some one-time context setup or
+ * initializations.
+ */
+static int
+create_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget reshape callback. This is called by Tcl/Tk when the widget
+ * has been resized. Typically, we call glViewport and perhaps setup the
+ * projection matrix.
+ */
+static int
+reshape_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ int width;
+ int height;
+ float aspect;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ width = Togl_Width(togl);
+ height = Togl_Height(togl);
+ aspect = (float) width / (float) height;
+
+ glViewport(0, 0, width, height);
+
+ /* Set up projection transform */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-aspect, aspect, -1, 1, 1, 10);
+
+ CornerX = -aspect;
+ CornerY = -1;
+ CornerZ = -1.1f;
+
+ /* Change back to model view transform for rendering */
+ glMatrixMode(GL_MODELVIEW);
+ return TCL_OK;
+}
+
+
+static void
+draw_eye(Togl *togl)
+{
+ static GLuint cubeList = 0;
+
+ Togl_Clear(togl, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ Togl_Frustum(togl, -1, 1, -1, 1, 1, 10);
+ glMatrixMode(GL_MODELVIEW);
+
+ if (!cubeList) {
+ cubeList = glGenLists(1);
+ glNewList(cubeList, GL_COMPILE);
+
+ /* Front face */
+ glBegin(GL_QUADS);
+ glColor3f(0.4f, 0.8f, 0.4f); /* Green-ish */
+ glVertex3f(-1, 1, 1);
+ glVertex3f(1, 1, 1);
+ glVertex3f(1, -1, 1);
+ glVertex3f(-1, -1, 1);
+ /* Back face */
+ glColor3f(0.8f, 0.8f, 0.4f); /* Yellow-ish */
+ glVertex3f(-1, 1, -1);
+ glVertex3f(1, 1, -1);
+ glVertex3f(1, -1, -1);
+ glVertex3f(-1, -1, -1);
+ /* Top side face */
+ glColor3f(0.4f, 0.4f, 0.8f); /* Blue-ish */
+ glVertex3f(-1, 1, 1);
+ glVertex3f(1, 1, 1);
+ glVertex3f(1, 1, -1);
+ glVertex3f(-1, 1, -1);
+ /* Bottom side face */
+ glColor3f(0.8f, 0.4f, 0.4f); /* Red-ish */
+ glVertex3f(-1, -1, 1);
+ glVertex3f(1, -1, 1);
+ glVertex3f(1, -1, -1);
+ glVertex3f(-1, -1, -1);
+ glEnd();
+
+ glEndList();
+ }
+ glCallList(cubeList);
+}
+
+/*
+ * Togl widget display callback. This is called by Tcl/Tk when the widget's
+ * contents have to be redrawn. Typically, we clear the color and depth
+ * buffers, render our objects, then swap the front/back color buffers.
+ */
+static int
+display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* setup modelview matrix */
+ glLoadIdentity(); /* Reset modelview matrix to the identity
+ * matrix */
+ glTranslatef(0, 0, -3.0); /* Move the camera back three units */
+ glScaled(coord_scale, coord_scale, coord_scale); /* Zoom in and out */
+ glRotated(xAngle, 1, 0, 0); /* Rotate by X, Y, and Z angles */
+ glRotated(yAngle, 0, 1, 0);
+ glRotated(zAngle, 0, 0, 1);
+
+ glEnable(GL_DEPTH_TEST);
+
+ if (Togl_NumEyes(togl) == 1) {
+ /* single eye */
+ Togl_DrawBuffer(togl, GL_BACK);
+ draw_eye(togl);
+ } else {
+ /* stereo left eye */
+ Togl_DrawBuffer(togl, GL_BACK_LEFT);
+ draw_eye(togl);
+
+ /* stereo right eye */
+ Togl_DrawBuffer(togl, GL_BACK_RIGHT);
+ draw_eye(togl);
+ }
+
+ glDisable(GL_DEPTH_TEST);
+ glLoadIdentity();
+ glColor3f(1, 1, 1);
+ glRasterPos3f(CornerX, CornerY, CornerZ);
+ Togl_SwapBuffers(togl);
+ return TCL_OK;
+}
+
+
+static int
+setXrot_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName angle");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &xAngle) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* printf( "before %f ", xAngle ); */
+
+ if (xAngle < 0) {
+ xAngle += 360;
+ } else if (xAngle > 360) {
+ xAngle -= 360;
+ }
+
+ /* printf( "after %f \n", xAngle ); */
+
+ Togl_PostRedisplay(togl);
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ return TCL_OK;
+}
+
+
+static int
+setYrot_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName angle");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &yAngle) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (yAngle < 0) {
+ yAngle += 360;
+ } else if (yAngle > 360) {
+ yAngle -= 360;
+ }
+
+ Togl_PostRedisplay(togl);
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ return TCL_OK;
+}
+
+
+int
+getXrot_cb(ClientData clientData, Tcl_Interp *interp,
+ int argc, CONST84 char *argv[])
+{
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(xAngle));
+ return TCL_OK;
+}
+
+
+int
+getYrot_cb(ClientData clientData, Tcl_Interp *interp,
+ int argc, CONST84 char *argv[])
+{
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(yAngle));
+ return TCL_OK;
+}
+
+
+static int
+coord_scale_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName value");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &coord_scale) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Togl_PostRedisplay(togl);
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ return TCL_OK;
+}
+
+
+EXTERN int
+Stereo_Init(Tcl_Interp *interp)
+{
+ /*
+ * Initialize Tcl and the Togl widget module.
+ */
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL
+ || Togl_InitStubs(interp, "2.0", 0) == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Specify the C callback functions for widget creation, display,
+ * and reshape.
+ */
+ Tcl_CreateObjCommand(interp, "create_cb", create_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "display_cb", display_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "reshape_cb", reshape_cb, NULL, NULL);
+
+ Tcl_CreateObjCommand(interp, "setXrot", setXrot_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "setYrot", setYrot_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "coord_scale", coord_scale_cb, NULL, NULL);
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+
+ Tcl_CreateCommand(interp, "getXrot", getXrot_cb, NULL, NULL);
+ Tcl_CreateCommand(interp, "getYrot", getYrot_cb, NULL, NULL);
+
+ return TCL_OK;
+}
diff --git a/ng/Togl2.1/stereo.tcl b/ng/Togl2.1/stereo.tcl
new file mode 100644
index 00000000..905df5a2
--- /dev/null
+++ b/ng/Togl2.1/stereo.tcl
@@ -0,0 +1,106 @@
+#!/bin/sh
+# the next line restarts using tclsh \
+exec tclsh "$0" "$@"
+
+# $Id: stereo.tcl,v 1.13 2009/03/31 23:21:13 gregcouch Exp $
+
+# Togl - a Tk OpenGL widget
+# Copyright (C) 1996 Brian Paul and Ben Bederson
+# Copyright (C) 2006-2009 Greg Couch
+# See the LICENSE file for copyright details.
+
+# add parent directory to path to find Togl's pkgIndex in current directory
+if { [file exists pkgIndex.tcl] } {
+ set auto_path [linsert $auto_path 0 ..]
+}
+# following load also loads Tk and Togl packages
+load [file dirname [info script]]/stereo[info sharedlibextension]
+
+# create ::stereo namespace
+namespace eval ::stereo {
+}
+
+variable stereo::mode none
+proc stereo::setup {} {
+ grid rowconfigure . 0 -weight 1 -minsize 200p
+ grid columnconfigure . 1 -weight 1 -minsize 200p
+ labelframe .c -text "Stereo mode:"
+ grid .c -padx 2 -pady 2 -ipadx 2 -ipady 1
+ foreach {b} {none native sgioldstyle anaglyph cross-eye wall-eye DTI "row interleaved" "left eye" "right eye" } {
+ set name [string map {- _ " " _} $b]
+ radiobutton .c.b$name -text "$b" -command "::stereo::makeGraphics {$b}" -variable stereo::mode -value "$b"
+ pack .c.b$name -padx 2 -pady 1 -anchor w
+ }
+ scale .sx -label {X Axis} -from 0 -to 360 -command {::stereo::setAngle x} -orient horizontal
+ grid .sx -columnspan 2 -sticky ew
+ scale .sy -label {Y Axis} -from 0 -to 360 -command {::stereo::setAngle y} -orient horizontal
+ grid .sy -columnspan 2 -sticky ew
+ if {[string first IRIX $::tcl_platform(os)] != -1} {
+ label .irix -justify left -wraplength 250p -text "Use /usr/gfx/setmon or /usr/bin/X11/xsetmon to change video mode for native stereo (eg., 1024x768_120s) or sgioldstyle stereo (eg., str_bot) and back."
+ grid .irix -sticky new -columnspan 2
+ }
+ button .quit -text Close -command exit
+ grid .quit -sticky se -columnspan 2 -padx 2 -pady 2
+ frame .f -relief groove -borderwidth 2 -bg black
+ grid .f -row 0 -column 1 -sticky news
+ bind . {exit}
+ label .f.error -wraplength 100p -bg black -fg white
+ ::stereo::makeGraphics $stereo::mode
+}
+
+set stereo::count 0
+set stereo::gwidget ""
+proc stereo::makeGraphics {mode} {
+ incr stereo::count
+ set name .f.gr$stereo::count
+ set width 200
+ set height 200
+ if { [catch { togl $name -width $width -height $height -rgba true -stereo "$mode" -double true -depth true -sharelist main -create create_cb -display display_cb -reshape reshape_cb -eyeseparation 0.05 -convergence 2.0 -stencil true } error] } {
+ pack forget $stereo::gwidget
+ .f.error configure -text "$error\n\nMake another choice from the stereo modes on the left."
+ pack .f.error -expand 1 -fill both
+ } else {
+ pack forget .f.error
+ $name configure -ident main
+ if { "$stereo::gwidget" != "" } {
+ destroy $stereo::gwidget
+ }
+ set stereo::gwidget $name
+ pack $name -expand 1 -fill both
+ bind $name {
+ ::stereo::motion_event %W \
+ [lindex [%W config -width] 4] \
+ [lindex [%W config -height] 4] %x %y
+ }
+ }
+}
+
+# This is called when mouse button 1 is pressed and moved
+proc stereo::motion_event { widget width height x y } {
+ setXrot $widget [expr 360.0 * $y / $height]
+ setYrot $widget [expr 360.0 * ($width - $x) / $width]
+
+# .sx set [expr 360.0 * $y / $height]
+# .sy set [expr 360.0 * ($width - $x) / $width]
+
+ .sx set [getXrot]
+ .sy set [getYrot]
+}
+
+# This is called when a slider is changed.
+proc stereo::setAngle {axis value} {
+ # catch because .f.gr might be a label instead of a Togl widget
+ catch {
+ switch -exact $axis {
+ x {setXrot $stereo::gwidget $value}
+ y {setYrot $stereo::gwidget $value}
+ }
+ }
+}
+
+if { [info script] == $argv0 } {
+ if { $argc == 1 } {
+ set stereo::mode [lindex $argv 0]
+ }
+ ::stereo::setup
+}
diff --git a/ng/Togl2.1/tclconfig/install-sh b/ng/Togl2.1/tclconfig/install-sh
new file mode 100755
index 00000000..0ff4b6a0
--- /dev/null
+++ b/ng/Togl2.1/tclconfig/install-sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+ echo "install: no destination specified"
+ exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+ dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
diff --git a/ng/Togl2.1/tclconfig/tcl.m4 b/ng/Togl2.1/tclconfig/tcl.m4
new file mode 100644
index 00000000..ab07457b
--- /dev/null
+++ b/ng/Togl2.1/tclconfig/tcl.m4
@@ -0,0 +1,4105 @@
+# tcl.m4 --
+#
+# This file provides a set of autoconf macros to help TEA-enable
+# a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: tcl.m4,v 1.12 2009/01/08 04:40:39 gregcouch Exp $
+
+AC_PREREQ(2.57)
+
+dnl TEA extensions pass us the version of TEA they think they
+dnl are compatible with (must be set in TEA_INIT below)
+dnl TEA_VERSION="3.7"
+
+# Possible values for key variables defined:
+#
+# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
+# TEA_PLATFORM - windows unix
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+# Locate the tclConfig.sh file and perform a sanity check on
+# the Tcl compile flags
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tcl=...
+#
+# Defines the following vars:
+# TCL_BIN_DIR Full path to the directory containing
+# the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+ #
+ # Ok, lets find the tcl configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tcl
+ #
+
+ if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tcl,
+ AC_HELP_STRING([--with-tcl],
+ [directory containing tcl configuration (tclConfig.sh)]),
+ with_tclconfig=${withval})
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tcl was specified.
+ if test x"${with_tclconfig}" != x ; then
+ case ${with_tclconfig} in
+ */tclConfig.sh )
+ if test -f ${with_tclconfig}; then
+ AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+ with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+ fi ;;
+ esac
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ ; do
+ if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCL_BIN_DIR="# no Tcl configs found"
+ AC_MSG_ERROR([Can't find Tcl configuration definitions])
+ else
+ no_tcl=
+ TCL_BIN_DIR=${ac_cv_c_tclconfig}
+ AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+# Locate the tkConfig.sh file
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tk=...
+#
+# Defines the following vars:
+# TK_BIN_DIR Full path to the directory containing
+# the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+ #
+ # Ok, lets find the tk configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tk
+ #
+
+ if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tk,
+ AC_HELP_STRING([--with-tk],
+ [directory containing tk configuration (tkConfig.sh)]),
+ with_tkconfig=${withval})
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ case ${with_tkconfig} in
+ */tkConfig.sh )
+ if test -f ${with_tkconfig}; then
+ AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+ with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'`
+ fi ;;
+ esac
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ ; do
+ if test -f "$i/Tk.framework/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TK_BIN_DIR="# no Tk configs found"
+ AC_MSG_ERROR([Can't find Tk configuration definitions])
+ else
+ no_tk=
+ TK_BIN_DIR=${ac_cv_c_tkconfig}
+ AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+# Load the tclConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TCL_BIN_DIR
+#
+# Results:
+#
+# Subst the following vars:
+# TCL_BIN_DIR
+# TCL_SRC_DIR
+# TCL_LIB_FILE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+ if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TCL_BIN_DIR}/tclConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+ eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+ # If the TCL_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TCL_LIB_SPEC will be set to the value
+ # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+ # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+ TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+ TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tcl.framework installed in an arbitary location.
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+ for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+ "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+ TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+ TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+ TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+ eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+ eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+ eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_BIN_DIR)
+ AC_SUBST(TCL_SRC_DIR)
+
+ AC_SUBST(TCL_LIB_FILE)
+ AC_SUBST(TCL_LIB_FLAG)
+ AC_SUBST(TCL_LIB_SPEC)
+
+ AC_SUBST(TCL_STUB_LIB_FILE)
+ AC_SUBST(TCL_STUB_LIB_FLAG)
+ AC_SUBST(TCL_STUB_LIB_SPEC)
+
+ # TEA specific:
+ AC_SUBST(TCL_LIBS)
+ AC_SUBST(TCL_DEFS)
+ AC_SUBST(TCL_EXTRA_CFLAGS)
+ AC_SUBST(TCL_LD_FLAGS)
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+# Load the tkConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TK_BIN_DIR
+#
+# Results:
+#
+# Sets the following vars that should be in tkConfig.sh:
+# TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+ if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TK_BIN_DIR}/tkConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+ eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+ # If the TK_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TK_LIB_SPEC will be set to the value
+ # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+ # instead of TK_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ TK_LIB_SPEC=${TK_BUILD_LIB_SPEC}
+ TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC}
+ TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH}
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tk.framework installed in an arbitary location.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+ for i in "`cd ${TK_BIN_DIR}; pwd`" \
+ "`cd ${TK_BIN_DIR}/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+ TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+ TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}"
+ TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+ eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+ eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+ eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+ # TEA specific: Ensure windowingsystem is defined
+ if test "${TEA_PLATFORM}" = "unix" ; then
+ case ${TK_DEFS} in
+ *MAC_OSX_TK*)
+ AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+ TEA_WINDOWINGSYSTEM="aqua"
+ ;;
+ *)
+ TEA_WINDOWINGSYSTEM="x11"
+ ;;
+ esac
+ elif test "${TEA_PLATFORM}" = "windows" ; then
+ TEA_WINDOWINGSYSTEM="win32"
+ fi
+
+ AC_SUBST(TK_VERSION)
+ AC_SUBST(TK_BIN_DIR)
+ AC_SUBST(TK_SRC_DIR)
+
+ 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)
+
+ # TEA specific:
+ AC_SUBST(TK_LIBS)
+ AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+# Determine the fully qualified path name of the tclsh executable
+# in the Tcl build directory or the tclsh installed in a bin
+# directory. This macro will correctly determine the name
+# of the tclsh executable even if tclsh has not yet been
+# built in the build directory. The tclsh found is always
+# associated with a tclConfig.sh file. This tclsh should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+# none
+#
+# Results
+# Subst's the following values:
+# TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+ AC_MSG_CHECKING([for tclsh])
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ # tclConfig.sh is in Tcl build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+ else
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+ fi
+ else
+ # tclConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+ else
+ TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+ fi
+ list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${TCLSH_PROG}" ; then
+ REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+ fi
+ AC_MSG_RESULT([${TCLSH_PROG}])
+ AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+# Determine the fully qualified path name of the wish executable
+# in the Tk build directory or the wish installed in a bin
+# directory. This macro will correctly determine the name
+# of the wish executable even if wish has not yet been
+# built in the build directory. The wish found is always
+# associated with a tkConfig.sh file. This wish should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+# none
+#
+# Results
+# Subst's the following values:
+# WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+ AC_MSG_CHECKING([for wish])
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ # tkConfig.sh is in Tk build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ else
+ WISH_PROG="${TK_BIN_DIR}/wish"
+ fi
+ else
+ # tkConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ else
+ WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+ fi
+ list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${WISH_PROG}" ; then
+ REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+ fi
+ AC_MSG_RESULT([${WISH_PROG}])
+ AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+# Allows the building of shared libraries
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-shared=yes|no
+#
+# Defines the following vars:
+# STATIC_BUILD Used for building import/export libraries
+# on Windows.
+#
+# Sets the following vars:
+# SHARED_BUILD Value of 1 or 0
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SHARED], [
+ AC_MSG_CHECKING([how to build libraries])
+ AC_ARG_ENABLE(shared,
+ AC_HELP_STRING([--enable-shared],
+ [build and link with shared libraries (default: on)]),
+ [tcl_ok=$enableval], [tcl_ok=yes])
+
+ if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ tcl_ok=$enableval
+ else
+ tcl_ok=yes
+ fi
+
+ if test "$tcl_ok" = "yes" ; then
+ AC_MSG_RESULT([shared])
+ SHARED_BUILD=1
+ else
+ AC_MSG_RESULT([static])
+ SHARED_BUILD=0
+ AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
+ fi
+ AC_SUBST(SHARED_BUILD)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+# Specify if thread support should be enabled. If "yes" is specified
+# as an arg (optional), threads are enabled by default, "no" means
+# threads are disabled. "yes" is the default.
+#
+# TCL_THREADS is checked so that if you are compiling an extension
+# against a threaded core, your extension must be compiled threaded
+# as well.
+#
+# Note that it is legal to have a thread enabled extension run in a
+# threaded or non-threaded Tcl core, but a non-threaded extension may
+# only run in a non-threaded Tcl core.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-threads
+#
+# Sets the following vars:
+# THREADS_LIBS Thread library(s)
+#
+# Defines the following vars:
+# TCL_THREADS
+# _REENTRANT
+# _THREAD_SAFE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+ AC_ARG_ENABLE(threads,
+ AC_HELP_STRING([--enable-threads],
+ [build with threads]),
+ [tcl_ok=$enableval], [tcl_ok=yes])
+
+ if test "${enable_threads+set}" = set; then
+ enableval="$enable_threads"
+ tcl_ok=$enableval
+ else
+ tcl_ok=yes
+ fi
+
+ if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+ TCL_THREADS=1
+
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ # We are always OK on Windows, so check what this platform wants:
+
+ # USE_THREAD_ALLOC tells us to try the special thread-based
+ # allocator that significantly reduces lock contention
+ AC_DEFINE(USE_THREAD_ALLOC, 1,
+ [Do we want to use the threaded memory allocator?])
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ if test "`uname -s`" = "SunOS" ; then
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+ fi
+ AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+ AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ # Check a little harder for __pthread_mutex_init in the same
+ # library, as some systems hide it there until pthread.h is
+ # defined. We could alternatively do an AC_TRY_COMPILE with
+ # pthread.h, but that will work with libpthread really doesn't
+ # exist, like AIX 4.2. [Bug: 4359]
+ AC_CHECK_LIB(pthread, __pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ fi
+
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthread"
+ else
+ AC_CHECK_LIB(pthreads, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthreads"
+ else
+ AC_CHECK_LIB(c, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ AC_CHECK_LIB(c_r, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -pthread"
+ else
+ TCL_THREADS=0
+ AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+ fi
+ fi
+ fi
+ fi
+ fi
+ else
+ TCL_THREADS=0
+ fi
+ # Do checking message here to not mess up interleaved configure output
+ AC_MSG_CHECKING([for building with threads])
+ if test "${TCL_THREADS}" = 1; then
+ AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+ AC_MSG_RESULT([yes (default)])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ # TCL_THREADS sanity checking. See if our request for building with
+ # threads is the same as the way Tcl was built. If not, warn the user.
+ case ${TCL_DEFS} in
+ *THREADS=1*)
+ if test "${TCL_THREADS}" = "0"; then
+ AC_MSG_WARN([
+ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+ that IS thread-enabled. It is recommended to use --enable-threads.])
+ fi
+ ;;
+ *)
+ if test "${TCL_THREADS}" = "1"; then
+ AC_MSG_WARN([
+ --enable-threads requested, but building against a Tcl that is NOT
+ thread-enabled. This is an OK configuration that will also run in
+ a thread-enabled core.])
+ fi
+ ;;
+ esac
+ AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+# Specify if debugging symbols should be used.
+# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+# none
+#
+# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+# Requires the following vars to be set in the Makefile:
+# CFLAGS_DEFAULT
+# LDFLAGS_DEFAULT
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-symbols
+#
+# Defines the following vars:
+# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
+# Sets to $(CFLAGS_OPTIMIZE) if false
+# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+# Sets to $(LDFLAGS_OPTIMIZE) if false
+# DBGX Formerly used as debug library extension;
+# always blank now.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_CONFIG_CFLAGS])
+ AC_MSG_CHECKING([for build with symbols])
+ AC_ARG_ENABLE(symbols,
+ AC_HELP_STRING([--enable-symbols],
+ [build with debugging symbols (default: off)]),
+ [tcl_ok=$enableval], [tcl_ok=no])
+ DBGX=""
+ if test "$tcl_ok" = "no"; then
+ CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+ LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+ AC_MSG_RESULT([no])
+ else
+ CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+ LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+ if test "$tcl_ok" = "yes"; then
+ AC_MSG_RESULT([yes (standard debugging)])
+ fi
+ fi
+ # TEA specific:
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ LDFLAGS_DEFAULT="${LDFLAGS}"
+ fi
+ AC_SUBST(CFLAGS_DEFAULT)
+ AC_SUBST(LDFLAGS_DEFAULT)
+ AC_SUBST(TCL_DBGX)
+
+ if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+ AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+ fi
+
+ if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+ if test "$tcl_ok" = "all"; then
+ AC_MSG_RESULT([enabled symbols mem debugging])
+ else
+ AC_MSG_RESULT([enabled $tcl_ok debugging])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+# Allows use of modern nl_langinfo check for better l10n.
+# This is only relevant for Unix.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-langinfo=yes|no (default is yes)
+#
+# Defines the following vars:
+# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+ AC_ARG_ENABLE(langinfo,
+ AC_HELP_STRING([--enable-langinfo],
+ [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+ [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+ HAVE_LANGINFO=0
+ if test "$langinfo_ok" = "yes"; then
+ AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+ fi
+ AC_MSG_CHECKING([whether to use nl_langinfo])
+ if test "$langinfo_ok" = "yes"; then
+ AC_CACHE_VAL(tcl_cv_langinfo_h, [
+ AC_TRY_COMPILE([#include ], [nl_langinfo(CODESET);],
+ [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+ AC_MSG_RESULT([$tcl_cv_langinfo_h])
+ if test $tcl_cv_langinfo_h = yes; then
+ AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+ fi
+ else
+ AC_MSG_RESULT([$langinfo_ok])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+# Determine what the system is (some things cannot be easily checked
+# on a feature-driven basis, alas). This can usually be done via the
+# "uname" command, but there are a few systems, like Next, where
+# this doesn't work.
+#
+# Arguments:
+# none
+#
+# Results:
+# Defines the following var:
+#
+# system - System/platform/version identification code.
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+ # TEA specific:
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ tcl_cv_sys_version=windows
+ elif test -f /usr/lib/NextStep/software_version; then
+ tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+ else
+ tcl_cv_sys_version=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ AC_MSG_WARN([can't find uname command])
+ tcl_cv_sys_version=unknown
+ else
+ # Special check for weird MP-RAS system (uname returns weird
+ # results, and the version is kept in special file).
+
+ if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+ tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
+ fi
+ if test "`uname -s`" = "AIX" ; then
+ tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+ fi
+ fi
+ fi
+ ])
+ system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+# Try to determine the proper flags to pass to the compiler
+# for building shared libraries and other such nonsense.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substitutes the following vars:
+#
+# DL_OBJS - Name of the object file that implements dynamic
+# loading for Tcl on this system.
+# DL_LIBS - Library file(s) to include in tclsh and other base
+# applications in order for the "load" command to work.
+# LDFLAGS - Flags to pass to the compiler when linking object
+# files into an executable application binary such
+# as tclsh.
+# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile. Could
+# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile.
+# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
+# of a shared library (may request position-independent
+# code, among other things).
+# SHLIB_LD - Base command to use for combining object files
+# into a shared library.
+# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+# creating shared libraries. This symbol typically
+# goes at the end of the "ld" commands that build
+# shared libraries. The value of the symbol is
+# "${LIBS}" if all of the dependent libraries should
+# be specified when creating a shared library. If
+# dependent libraries should not be specified (as on
+# SunOS 4.x, where they cause the link to fail, or in
+# general if Tcl and Tk aren't themselves shared
+# libraries), then this symbol has an empty string
+# as its value.
+# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
+# extensions. An empty string means we don't know how
+# to use shared libraries on this platform.
+# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
+# in a static or shared library name, using the $VERSION variable
+# to put the version in the right place. This is used
+# by platforms that need non-standard library names.
+# Examples: ${VERSION}.so.1.1 on NetBSD, since it needs
+# to have a version after the .so, and ${VERSION}.a
+# on AIX, since a shared library needs to have
+# a .a extension whereas shared objects for loadable
+# extensions have a .so extension. Defaults to
+# ${VERSION}${SHLIB_SUFFIX}.
+# TCL_NEEDS_EXP_FILE -
+# 1 means that an export file is needed to link to a
+# shared library.
+# TCL_EXP_FILE - The name of the installed export / import file which
+# should be used to link to the Tcl shared library.
+# Empty if Tcl is unshared.
+# TCL_BUILD_EXP_FILE -
+# The name of the built export / import file which
+# should be used to link to the Tcl shared library.
+# Empty if Tcl is unshared.
+# CFLAGS_DEBUG -
+# Flags used when running the compiler in debug mode
+# CFLAGS_OPTIMIZE -
+# Flags used when running the compiler in optimize mode
+# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+
+ # Step 0.a: Enable 64 bit support?
+
+ AC_MSG_CHECKING([if 64bit support is requested])
+ AC_ARG_ENABLE(64bit,
+ AC_HELP_STRING([--enable-64bit],
+ [enable 64bit support (default: off)]),
+ [do64bit=$enableval], [do64bit=no])
+ AC_MSG_RESULT([$do64bit])
+
+ # Step 0.b: Enable Solaris 64 bit VIS support?
+
+ AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+ AC_ARG_ENABLE(64bit-vis,
+ AC_HELP_STRING([--enable-64bit-vis],
+ [enable 64bit Sparc VIS support (default: off)]),
+ [do64bitVIS=$enableval], [do64bitVIS=no])
+ AC_MSG_RESULT([$do64bitVIS])
+ # Force 64bit on with VIS
+ AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
+
+ # Step 0.c: Check if visibility support is available. Do this here so
+ # that platform specific alternatives can be used below if this fails.
+
+ AC_CACHE_CHECK([if compiler supports visibility "hidden"],
+ tcl_cv_cc_visibility_hidden, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+ AC_TRY_LINK([
+ extern __attribute__((__visibility__("hidden"))) void f(void);
+ void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
+ tcl_cv_cc_visibility_hidden=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+ AC_DEFINE(MODULE_SCOPE,
+ [extern __attribute__((__visibility__("hidden")))],
+ [Compiler support for module scope symbols])
+ ])
+
+ # Step 0.d: Disable -rpath support?
+
+ AC_MSG_CHECKING([if rpath support is requested])
+ AC_ARG_ENABLE(rpath,
+ AC_HELP_STRING([--disable-rpath],
+ [disable rpath support (default: on)]),
+ [doRpath=$enableval], [doRpath=yes])
+ AC_MSG_RESULT([$doRpath])
+
+ # TEA specific: Cross-compiling options for Windows/CE builds?
+
+ AS_IF([test "${TEA_PLATFORM}" = windows], [
+ AC_MSG_CHECKING([if Windows/CE build is requested])
+ AC_ARG_ENABLE(wince,
+ AC_HELP_STRING([--enable-wince],
+ [enable Win/CE support (where applicable)]),
+ [doWince=$enableval], [doWince=no])
+ AC_MSG_RESULT([$doWince])
+ ])
+
+ # Step 1: set the variable "system" to hold the name and version number
+ # for the system.
+
+ TEA_CONFIG_SYSTEM
+
+ # Step 2: check for existence of -ldl library. This is needed because
+ # Linux can use either -ldl or -ldld for dynamic loading.
+
+ AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
+
+ # Require ranlib early so we can override it in special cases below.
+
+ AC_REQUIRE([AC_PROG_RANLIB])
+
+ # Step 3: set configuration options based on system name and version.
+ # This is similar to Tcl's unix/tcl.m4 except that we've added a
+ # "windows" case.
+
+ do64bit_ok=no
+ LDFLAGS_ORIG="$LDFLAGS"
+ # When ld needs options to work in 64-bit mode, put them in
+ # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+ # is disabled by the user. [Bug 1016796]
+ LDFLAGS_ARCH=""
+ TCL_EXPORT_FILE_SUFFIX=""
+ UNSHARED_LIB_SUFFIX=""
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+ ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+ TCL_LIB_VERSIONS_OK=ok
+ CFLAGS_DEBUG=-g
+ CFLAGS_OPTIMIZE=-O
+ AS_IF([test "$GCC" = yes], [
+ # TEA specific:
+ CFLAGS_OPTIMIZE=-O2
+ CFLAGS_WARNING="-Wall -Wno-implicit-int"
+ ], [CFLAGS_WARNING=""])
+ TCL_NEEDS_EXP_FILE=0
+ TCL_BUILD_EXP_FILE=""
+ TCL_EXP_FILE=""
+dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.
+dnl AC_CHECK_TOOL(AR, ar)
+ AC_CHECK_PROG(AR, ar, ar)
+ STLIB_LD='${AR} cr'
+ LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+ case $system in
+ # TEA specific:
+ windows)
+ # This is a 2-stage check to make sure we have the 64-bit SDK
+ # We have to know where the SDK is installed.
+ # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+ # MACHINE is IX86 for LINK, but this is used by the manifest,
+ # which requires x86|amd64|ia64.
+ MACHINE="X86"
+ if test "$do64bit" != "no" ; then
+ if test "x${MSSDK}x" = "xx" ; then
+ MSSDK="C:/Progra~1/Microsoft Platform SDK"
+ fi
+ MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'`
+ PATH64=""
+ case "$do64bit" in
+ amd64|x64|yes)
+ MACHINE="AMD64" ; # default to AMD64 64-bit build
+ PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+ ;;
+ ia64)
+ MACHINE="IA64"
+ PATH64="${MSSDK}/Bin/Win64"
+ ;;
+ esac
+ if test ! -d "${PATH64}" ; then
+ AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+ AC_MSG_WARN([Ensure latest Platform SDK is installed])
+ do64bit="no"
+ else
+ AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
+ do64bit_ok="yes"
+ fi
+ fi
+
+ if test "$doWince" != "no" ; then
+ if test "$do64bit" != "no" ; then
+ AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+ fi
+ if test "$GCC" = "yes" ; then
+ AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+ fi
+ TEA_PATH_CELIB
+ # Set defaults for common evc4/PPC2003 setup
+ # Currently Tcl requires 300+, possibly 420+ for sockets
+ CEVERSION=420; # could be 211 300 301 400 420 ...
+ TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
+ ARCH=ARM; # could be ARM MIPS X86EM ...
+ PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+ if test "$doWince" != "yes"; then
+ # If !yes then the user specified something
+ # Reset ARCH to allow user to skip specifying it
+ ARCH=
+ eval `echo $doWince | awk -F, '{ \
+ if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+ if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+ if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+ if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+ if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+ }'`
+ if test "x${ARCH}" = "x" ; then
+ ARCH=$TARGETCPU;
+ fi
+ fi
+ OSVERSION=WCE$CEVERSION;
+ if test "x${WCEROOT}" = "x" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+ if test ! -d "${WCEROOT}" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+ fi
+ fi
+ if test "x${SDKROOT}" = "x" ; then
+ SDKROOT="C:/Program Files/Windows CE Tools"
+ if test ! -d "${SDKROOT}" ; then
+ SDKROOT="C:/Windows CE Tools"
+ fi
+ fi
+ WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+ SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+ if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+ AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+ doWince="no"
+ else
+ # We could PATH_NOSPACE these, but that's not important,
+ # as long as we quote them when used.
+ CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+ if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+ CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+ fi
+ CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+ fi
+ fi
+
+ if test "$GCC" != "yes" ; then
+ if test "${SHARED_BUILD}" = "0" ; then
+ runtime=-MT
+ else
+ runtime=-MD
+ fi
+
+ if test "$do64bit" != "no" ; then
+ # All this magic is necessary for the Win64 SDK RC1 - hobbs
+ CC="\"${PATH64}/cl.exe\""
+ CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+ RC="\"${MSSDK}/bin/rc.exe\""
+ lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+ LINKBIN="\"${PATH64}/link.exe\""
+ CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+ CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+ # Avoid 'unresolved external symbol __security_cookie'
+ # errors, c.f. http://support.microsoft.com/?id=894573
+ TEA_ADD_LIBS([bufferoverflowU.lib])
+ elif test "$doWince" != "no" ; then
+ CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+ if test "${TARGETCPU}" = "X86"; then
+ CC="\"${CEBINROOT}/cl.exe\""
+ else
+ CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+ fi
+ CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+ RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+ arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+ defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+ if test "${SHARED_BUILD}" = "1" ; then
+ # Static CE builds require static celib as well
+ defs="${defs} _DLL"
+ fi
+ for i in $defs ; do
+ AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+ done
+ AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+ AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+ CFLAGS_DEBUG="-nologo -Zi -Od"
+ CFLAGS_OPTIMIZE="-nologo -Ox"
+ lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+ lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+ LINKBIN="\"${CEBINROOT}/link.exe\""
+ AC_SUBST(CELIB_DIR)
+ else
+ RC="rc"
+ lflags="-nologo"
+ LINKBIN="link"
+ CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+ CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+ fi
+ fi
+
+ if test "$GCC" = "yes"; then
+ # mingw gcc mode
+ RC="windres"
+ CFLAGS_DEBUG="-g"
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+ SHLIB_LD="$CC -shared"
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+ LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+ else
+ SHLIB_LD="${LINKBIN} -dll ${lflags}"
+ # link -lib only works when -lib is the first arg
+ STLIB_LD="${LINKBIN} -lib ${lflags}"
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+ PATHTYPE=-w
+ # For information on what debugtype is most useful, see:
+ # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+ # and also
+ # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
+ # This essentially turns it all on.
+ LDFLAGS_DEBUG="-debug -debugtype:cv"
+ LDFLAGS_OPTIMIZE="-release"
+ if test "$doWince" != "no" ; then
+ LDFLAGS_CONSOLE="-link ${lflags}"
+ LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+ else
+ LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+ LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+ fi
+ fi
+
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".dll"
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+ TCL_LIB_VERSIONS_OK=nodots
+ # Bogus to avoid getting this turned off
+ DL_OBJS="tclLoadNone.obj"
+ ;;
+ AIX-*)
+ AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
+ # AIX requires the _r compiler when gcc isn't being used
+ case "${CC}" in
+ *_r)
+ # ok ...
+ ;;
+ *)
+ CC=${CC}_r
+ ;;
+ esac
+ AC_MSG_RESULT([Using $CC for compiling with threads])
+ ])
+ LIBS="$LIBS -lc"
+ SHLIB_CFLAGS=""
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+
+ DL_OBJS="tclLoadDl.o"
+ LD_LIBRARY_PATH_VAR="LIBPATH"
+
+ # Check to enable 64-bit flags for compiler/linker on AIX 4+
+ AS_IF([test "$do64bit" = yes -a "`uname -v`" -gt 3], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -q64"
+ LDFLAGS_ARCH="-q64"
+ RANLIB="${RANLIB} -X64"
+ AR="${AR} -X64"
+ SHLIB_LD_FLAGS="-b64"
+ ])
+ ])
+
+ AS_IF([test "`uname -m`" = ia64], [
+ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ # AIX-5 has dl* in libc.so
+ DL_LIBS=""
+ AS_IF([test "$GCC" = yes], [
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ ], [
+ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+ ])
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ], [
+ AS_IF([test "$GCC" = yes], [SHLIB_LD='${CC} -shared'], [
+ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+ ])
+ SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+ DL_LIBS="-ldl"
+ CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ TCL_NEEDS_EXP_FILE=1
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+ ])
+
+ # AIX v<=4.1 has some different flags than 4.2+
+ AS_IF([test "$system" = "AIX-4.1" -o "`uname -v`" -lt 4], [
+ AC_LIBOBJ([tclLoadAix])
+ DL_LIBS="-lld"
+ ])
+
+ # On AIX <=v4 systems, libbsd.a has to be linked in to support
+ # non-blocking file IO. This library has to be linked in after
+ # the MATH_LIBS or it breaks the pow() function. The way to
+ # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+ # This library also supplies gettimeofday.
+ #
+ # AIX does not have a timezone field in struct tm. When the AIX
+ # bsd library is used, the timezone global and the gettimeofday
+ # methods are to be avoided for timezone deduction instead, we
+ # deduce the timezone by comparing the localtime result on a
+ # known GMT value.
+
+ AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no)
+ AS_IF([test $libbsd = yes], [
+ MATH_LIBS="$MATH_LIBS -lbsd"
+ AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?])
+ ])
+ ;;
+ BeOS*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD='${CC} -nostart'
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+
+ #-----------------------------------------------------------
+ # Check for inet_ntoa in -lbind, for BeOS (which also needs
+ # -lsocket, even if the network functions are in -lnet which
+ # is always linked to, for compatibility.
+ #-----------------------------------------------------------
+ AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+ ;;
+ BSD/OS-2.1*|BSD/OS-3*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="shlicc -r"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ BSD/OS-4.*)
+ SHLIB_CFLAGS="-export-dynamic -fPIC"
+ SHLIB_LD='${CC} -shared'
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ dgux*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ HP-UX-*.11.*)
+ # Use updated header definitions where possible
+ AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+ # TEA specific: Needed by Tcl, but not most extensions
+ #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+ #LIBS="$LIBS -lxnet" # Use the XOPEN network library
+
+ AS_IF([test "`uname -m`" = ia64], [
+ SHLIB_SUFFIX=".so"
+ # Use newer C++ library for C++ extensions
+ #if test "$GCC" != "yes" ; then
+ # CPPFLAGS="-AA"
+ #fi
+ ], [
+ SHLIB_SUFFIX=".sl"
+ ])
+ AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+ AS_IF([test "$tcl_ok" = yes], [
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+ SHLIB_LD_LIBS='${LIBS}'
+ DL_OBJS="tclLoadShl.o"
+ DL_LIBS="-ldld"
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+ LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+ ])
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ SHLIB_LD_LIBS='${LIBS}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+
+ # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+ #CFLAGS="$CFLAGS +DAportable"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = "yes"], [
+ AS_IF([test "$GCC" = yes], [
+ case `${CC} -dumpmachine` in
+ hppa64*)
+ # 64-bit gcc in use. Fix flags for GNU ld.
+ do64bit_ok=yes
+ SHLIB_LD='${CC} -shared'
+ SHLIB_LD_LIBS='${LIBS}'
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ;;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ;;
+ esac
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS +DD64"
+ LDFLAGS_ARCH="+DD64"
+ ])
+ ]) ;;
+ HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+ SHLIB_SUFFIX=".sl"
+ AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+ AS_IF([test "$tcl_ok" = yes], [
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+ SHLIB_LD_LIBS=""
+ DL_OBJS="tclLoadShl.o"
+ DL_LIBS="-ldld"
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+ LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+ ]) ;;
+ IRIX-5.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -shared -rdata_shared"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ ;;
+ IRIX-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS="$CFLAGS -mabi=n32"
+ LDFLAGS="$LDFLAGS -mabi=n32"
+ ], [
+ case $system in
+ IRIX-6.3)
+ # Use to build 6.2 compatible binaries on 6.3.
+ CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+ ;;
+ *)
+ CFLAGS="$CFLAGS -n32"
+ ;;
+ esac
+ LDFLAGS="$LDFLAGS -n32"
+ ])
+ ;;
+ IRIX64-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+
+ # Check to enable 64-bit flags for compiler/linker
+
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported by gcc])
+ ], [
+ do64bit_ok=yes
+ SHLIB_LD="ld -64 -shared -rdata_shared"
+ CFLAGS="$CFLAGS -64"
+ LDFLAGS_ARCH="-64"
+ ])
+ ])
+ ;;
+ Linux*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+
+ # TEA specific:
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+ # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
+ # when you inline the string and math operations. Turn this off to
+ # get rid of the warnings.
+ #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+ AS_IF([test $do64bit = yes], [
+ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -m64"
+ AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_m64 = yes], [
+ CFLAGS="$CFLAGS -m64"
+ do64bit_ok=yes
+ ])
+ ])
+
+ # The combo of gcc + glibc has a bug related to inlining of
+ # functions like strtod(). The -fno-builtin flag should address
+ # this problem but it does not work. The -fno-inline flag is kind
+ # of overkill but it works. Disable inlining only when one of the
+ # files in compat/*.c is being linked in.
+
+ AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
+
+ ;;
+ GNU*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+
+ SHLIB_LD='${CC} -shared'
+ DL_OBJS=""
+ DL_LIBS="-ldl"
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+ ;;
+ Lynx*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ CFLAGS_OPTIMIZE=-02
+ SHLIB_LD='${CC} -shared'
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-mshared -ldl"
+ LD_FLAGS="-Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ ;;
+ MP-RAS-02*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ MP-RAS-*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ NetBSD-1.*|FreeBSD-[[1-2]].*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+ AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+ yes
+#endif
+ ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+ AS_IF([test $tcl_cv_ld_elf = yes], [
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+ ], [
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+ ])
+
+ # Ancient FreeBSD doesn't handle version numbers with dots.
+
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ OpenBSD-*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+ AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+ AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+ yes
+#endif
+ ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+ AS_IF([test $tcl_cv_ld_elf = yes], [
+ LDFLAGS=-Wl,-export-dynamic
+ ], [LDFLAGS=""])
+
+ # OpenBSD doesn't do version numbers with dots.
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ NetBSD-*|FreeBSD-*)
+ # FreeBSD 3.* and greater have ELF.
+ # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the CFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ case $system in
+ FreeBSD-3.*)
+ # FreeBSD-3 doesn't handle version numbers with dots.
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ esac
+ ;;
+ Darwin-*)
+ CFLAGS_OPTIMIZE="-Os"
+ SHLIB_CFLAGS="-fno-common"
+ # To avoid discrepancies between what headers configure sees during
+ # preprocessing tests and compiling tests, move any -isysroot and
+ # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+ CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+ if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
+ CFLAGS="`echo " ${CFLAGS}" | \
+ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+ if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
+ AS_IF([test $do64bit = yes], [
+ case `arch` in
+ ppc)
+ AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+ tcl_cv_cc_arch_ppc64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+ tcl_cv_cc_arch_ppc64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ do64bit_ok=yes
+ ]);;
+ i386)
+ AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+ tcl_cv_cc_arch_x86_64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch x86_64"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+ tcl_cv_cc_arch_x86_64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
+ CFLAGS="$CFLAGS -arch x86_64"
+ do64bit_ok=yes
+ ]);;
+ *)
+ AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+ esac
+ ], [
+ # Check for combined 32-bit and 64-bit fat build
+ AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
+ fat_32_64=yes])
+ ])
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_single_module = yes], [
+ SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+ ])
+ # TEA specific: link shlib with current and compatiblity version flags
+ vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
+ SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".dylib"
+ DL_OBJS="tclLoadDyld.o"
+ DL_LIBS=""
+ # Don't use -prebind when building for Mac OS X 10.4 or later only:
+ AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
+ LDFLAGS="$LDFLAGS -prebind"])
+ LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+ AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
+ tcl_cv_ld_search_paths_first, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
+ tcl_cv_ld_search_paths_first=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ ])
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [__private_extern__],
+ [Compiler support for module scope symbols])
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+ # TEA specific: for combined 32 & 64 bit fat builds of Tk
+ # extensions, verify that 64-bit build is possible.
+ AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
+ 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 ], [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])
+ ])
+ # remove 64-bit arch flags from CFLAGS et al. if configuration
+ # does not support 64-bit.
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua -o "$tcl_cv_lib_x11_64" = no], [
+ 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])
+ ])
+ ;;
+ NEXTSTEP-*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD='${CC} -nostdlib -r'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadNext.o"
+ DL_LIBS=""
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ OS/390-*)
+ CFLAGS_OPTIMIZE="" # Optimizer is buggy
+ AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
+ [Should OS/390 do the right thing with sockets?])
+ ;;
+ OSF1-1.0|OSF1-1.1|OSF1-1.2)
+ # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+ SHLIB_CFLAGS=""
+ # Hack: make package name same as library name
+ SHLIB_LD='ld -R -export $@:'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadOSF.o"
+ DL_LIBS=""
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ OSF1-1.*)
+ # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+ SHLIB_CFLAGS="-fPIC"
+ AS_IF([test "$SHARED_BUILD" = 1], [SHLIB_LD="ld -shared"], [
+ SHLIB_LD="ld -non_shared"
+ ])
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ OSF1-V*)
+ # Digital OSF/1
+ SHLIB_CFLAGS=""
+ AS_IF([test "$SHARED_BUILD" = 1], [
+ SHLIB_LD='${CC} -shared'
+ ], [
+ SHLIB_LD='${CC} -non_shared'
+ ])
+ SHLIB_LD_LIBS="${LIBS}"
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
+ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
+ # see pthread_intro(3) for pthread support on osf1, k.furukawa
+ AS_IF([test "${TCL_THREADS}" = 1], [
+ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+ CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+ LIBS=`echo $LIBS | sed s/-lpthreads//`
+ AS_IF([test "$GCC" = yes], [
+ LIBS="$LIBS -lpthread -lmach -lexc"
+ ], [
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ])
+ ;;
+ QNX-6*)
+ # QNX RTP
+ # This may work for all QNX, but it was only reported for v6.
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ # dlopen is in -lc on QNX
+ DL_LIBS=""
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SCO_SV-3.2*)
+ # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+ # this test works, since "uname -s" was non-standard in 3.2.4 and
+ # below.
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_CFLAGS="-fPIC -melf"
+ LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+ ], [
+ SHLIB_CFLAGS="-Kpic -belf"
+ LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+ ])
+ SHLIB_LD="ld -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SINIX*5.4*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SunOS-4*)
+ SHLIB_CFLAGS="-PIC"
+ SHLIB_LD="ld"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+ # SunOS can't handle version numbers with dots in them in library
+ # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it
+ # requires an extra version number at the end of .so file names.
+ # So, the library has to have a name like libtcl75.so.1.0
+
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ SunOS-5.[[0-6]])
+ # Careful to not let 5.10+ fall into this case
+
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+
+ # Note: need the LIBS below, otherwise Tk won't find Tcl's
+ # symbols when dynamically loaded into tclsh.
+
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ SunOS-5*)
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ arch=`isainfo`
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ AS_IF([test "$GCC" = yes], [
+ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
+ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64 -mcpu=v9"
+ LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+ SHLIB_CFLAGS="-fPIC"
+ ])
+ ], [
+ do64bit_ok=yes
+ AS_IF([test "$do64bitVIS" = yes], [
+ CFLAGS="$CFLAGS -xarch=v9a"
+ LDFLAGS_ARCH="-xarch=v9a"
+ ], [
+ CFLAGS="$CFLAGS -xarch=v9"
+ LDFLAGS_ARCH="-xarch=v9"
+ ])
+ # Solaris 64 uses this as well
+ #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+ ])
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
+ esac
+ ], [
+ do64bit_ok=yes
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ CFLAGS="$CFLAGS -xarch=amd64"
+ LDFLAGS="$LDFLAGS -xarch=amd64";;
+ esac
+ ])
+ ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
+ ])
+
+ # Note: need the LIBS below, otherwise Tk won't find Tcl's
+ # symbols when dynamically loaded into tclsh.
+
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "$do64bit_ok" = yes], [
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ # We need to specify -static-libgcc or we need to
+ # add the path to the sparv9 libgcc.
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+ # for finding sparcv9 libgcc, get the regular libgcc
+ # path, remove so name and append 'sparcv9'
+ #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+ #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+ ])])
+ ])
+ ], [
+ case $system in
+ SunOS-5.[[1-9]][[0-9]]*)
+ SHLIB_LD='${CC} -G -z text ${LDFLAGS}';;
+ *)
+ SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+ esac
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ])
+ ;;
+ UNIX_SV* | UnixWare-5*)
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+ # that don't grok the -Bexport option. Test that it does.
+ AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_Bexport = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ esac
+
+ AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
+ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+ ])
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+ AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+ # Step 4: disable dynamic loading if requested via a command-line switch.
+
+ AC_ARG_ENABLE(load,
+ AC_HELP_STRING([--enable-load],
+ [allow dynamic loading and "load" command (default: on)]),
+ [tcl_ok=$enableval], [tcl_ok=yes])
+ AS_IF([test "$tcl_ok" = no], [DL_OBJS=""])
+
+ AS_IF([test "x$DL_OBJS" != x], [BUILD_DLTEST="\$(DLTEST_TARGETS)"], [
+ AC_MSG_WARN([Can't figure out how to do dynamic loading or shared libraries on this system.])
+ SHLIB_CFLAGS=""
+ SHLIB_LD=""
+ SHLIB_SUFFIX=""
+ DL_OBJS="tclLoadNone.o"
+ DL_LIBS=""
+ LDFLAGS="$LDFLAGS_ORIG"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ BUILD_DLTEST=""
+ ])
+ LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+ # If we're running gcc, then change the C flags for compiling shared
+ # libraries to the right flags for gcc, instead of those for the
+ # standard manufacturer compiler.
+
+ AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
+ case $system in
+ AIX-*) ;;
+ BSD/OS*) ;;
+ IRIX*) ;;
+ NetBSD-*|FreeBSD-*) ;;
+ Darwin-*) ;;
+ SCO_SV-3.2*) ;;
+ *) SHLIB_CFLAGS="-fPIC" ;;
+ esac])
+
+ AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
+ AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
+
+ AC_SUBST(DL_LIBS)
+
+ AC_SUBST(CFLAGS_DEBUG)
+ AC_SUBST(CFLAGS_OPTIMIZE)
+ AC_SUBST(CFLAGS_WARNING)
+
+ AC_SUBST(STLIB_LD)
+ AC_SUBST(SHLIB_LD)
+
+ AC_SUBST(SHLIB_LD_LIBS)
+ AC_SUBST(SHLIB_CFLAGS)
+
+ AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+ # These must be called after we do the basic CFLAGS checks and
+ # verify any possible 64-bit or similar switches are necessary
+ TEA_TCL_EARLY_FLAGS
+ TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+# Determine which interface to use to talk to the serial port.
+# Note that #include lines must begin in leftmost column for
+# some compilers to recognize them as preprocessor directives,
+# and some build environments have stdin not pointing at a
+# pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines only one of the following vars:
+# HAVE_SYS_MODEM_H
+# USE_TERMIOS
+# USE_TERMIO
+# USE_SGTTY
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+ AC_CHECK_HEADERS(sys/modem.h)
+ AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+ AC_TRY_RUN([
+#include
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include
+#include
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include
+#include
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+ }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include
+#include
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+ fi])
+ case $tcl_cv_api_serial in
+ termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+ termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+ sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_MISSING_POSIX_HEADERS
+#
+# Supply substitutes for missing POSIX header files. Special
+# notes:
+# - stdlib.h doesn't define strtol, strtoul, or
+# strtod insome versions of SunOS
+# - some versions of string.h don't declare procedures such
+# as strstr
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# NO_DIRENT_H
+# NO_ERRNO_H
+# NO_VALUES_H
+# HAVE_LIMITS_H or NO_LIMITS_H
+# NO_STDLIB_H
+# NO_STRING_H
+# NO_SYS_WAIT_H
+# NO_DLFCN_H
+# HAVE_SYS_PARAM_H
+#
+# HAVE_STRING_H ?
+#
+# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+# CHECK on limits.h
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
+ AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
+ AC_TRY_LINK([#include
+#include ], [
+#ifndef _POSIX_SOURCE
+# ifdef __Lynx__
+ /*
+ * Generate compilation error to make the test fail: Lynx headers
+ * are only valid if really in the POSIX environment.
+ */
+
+ missing_procedure();
+# endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
+
+ if test $tcl_cv_dirent_h = no; then
+ AC_DEFINE(NO_DIRENT_H, 1, [Do we have ?])
+ fi
+
+ # TEA specific:
+ AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have ?])])
+ AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have ?])])
+ AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have ?])])
+ AC_CHECK_HEADER(limits.h,
+ [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have ?])],
+ [AC_DEFINE(NO_LIMITS_H, 1, [Do we have ?])])
+ AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
+ AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
+ AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
+ AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
+ if test $tcl_ok = 0; then
+ AC_DEFINE(NO_STDLIB_H, 1, [Do we have ?])
+ fi
+ AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+ AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
+ AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
+
+ # See also memmove check below for a place where NO_STRING_H can be
+ # set and why.
+
+ if test $tcl_ok = 0; then
+ AC_DEFINE(NO_STRING_H, 1, [Do we have ?])
+ fi
+
+ AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have ?])])
+ AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have ?])])
+
+ # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+ AC_HAVE_HEADERS(sys/param.h)
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+# 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.
+#
+# This should be called after TEA_CONFIG_CFLAGS as setting the
+# LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets the following vars:
+# XINCLUDES
+# XLIBSW
+# PKG_LIBS (appends to)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+ TEA_PATH_UNIX_X
+ fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+ AC_PATH_X
+ not_really_there=""
+ if test "$no_x" = ""; then
+ if test "$x_includes" = ""; then
+ AC_TRY_CPP([#include ], , not_really_there="yes")
+ else
+ if test ! -r $x_includes/X11/Intrinsic.h; then
+ not_really_there="yes"
+ fi
+ fi
+ fi
+ if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+ AC_MSG_CHECKING([for X11 header files])
+ found_xincludes="no"
+ AC_TRY_CPP([#include ], found_xincludes="yes", found_xincludes="no")
+ if test "$found_xincludes" = "no"; then
+ dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+ for i in $dirs ; do
+ if test -r $i/X11/Intrinsic.h; then
+ AC_MSG_RESULT([$i])
+ XINCLUDES=" -I$i"
+ found_xincludes="yes"
+ break
+ fi
+ done
+ fi
+ else
+ if test "$x_includes" != ""; then
+ XINCLUDES="-I$x_includes"
+ found_xincludes="yes"
+ fi
+ fi
+ if test found_xincludes = "no"; then
+ AC_MSG_RESULT([couldn't find any!])
+ fi
+
+ if test "$no_x" = yes; then
+ AC_MSG_CHECKING([for X11 libraries])
+ XLIBSW=nope
+ dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+ for i in $dirs ; do
+ if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+ AC_MSG_RESULT([$i])
+ XLIBSW="-L$i -lX11"
+ x_libraries="$i"
+ break
+ fi
+ done
+ else
+ if test "$x_libraries" = ""; then
+ XLIBSW=-lX11
+ else
+ XLIBSW="-L$x_libraries -lX11"
+ fi
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_MSG_RESULT([could not find any! Using -lX11.])
+ XLIBSW=-lX11
+ fi
+ # TEA specific:
+ if test x"${XLIBSW}" != x ; then
+ PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+# The statements below check for systems where POSIX-style
+# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+# On these systems (mostly older ones), use the old BSD-style
+# FIONBIO approach instead.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# HAVE_SYS_IOCTL_H
+# HAVE_SYS_FILIO_H
+# USE_FIONBIO
+# O_NONBLOCK
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+ AC_CHECK_HEADERS(sys/ioctl.h)
+ AC_CHECK_HEADERS(sys/filio.h)
+ TEA_CONFIG_SYSTEM
+ AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+ case $system in
+ # There used to be code here to use FIONBIO under AIX. However, it
+ # was reported that FIONBIO doesn't work under AIX 3.2.5. Since
+ # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
+ # code (JO, 5/31/97).
+
+ OSF*)
+ AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+ AC_MSG_RESULT([FIONBIO])
+ ;;
+ SunOS-4*)
+ AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+ AC_MSG_RESULT([FIONBIO])
+ ;;
+ *)
+ AC_MSG_RESULT([O_NONBLOCK])
+ ;;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANLDER
+#
+# Checks how the system deals with time.h, what time structures
+# are used on the system, and what fields the structures have.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# USE_DELTA_FOR_TZ
+# HAVE_TM_GMTOFF
+# HAVE_TM_TZADJ
+# HAVE_TIMEZONE_VAR
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+ AC_CHECK_HEADERS(sys/time.h)
+ AC_HEADER_TIME
+ AC_STRUCT_TIMEZONE
+
+ AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+ AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+ AC_TRY_COMPILE([#include ], [struct tm tm; tm.tm_tzadj;],
+ tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+ if test $tcl_cv_member_tm_tzadj = yes ; then
+ AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+ fi
+
+ AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+ AC_TRY_COMPILE([#include ], [struct tm tm; tm.tm_gmtoff;],
+ tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+ if test $tcl_cv_member_tm_gmtoff = yes ; then
+ AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+ fi
+
+ #
+ # Its important to include time.h in this check, as some systems
+ # (like convex) have timezone functions, etc.
+ #
+ AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+ AC_TRY_COMPILE([#include ],
+ [extern long timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+ if test $tcl_cv_timezone_long = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ else
+ #
+ # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+ #
+ AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+ AC_TRY_COMPILE([#include ],
+ [extern time_t timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+ if test $tcl_cv_timezone_time = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+# 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.
+# Also, on Compaq's Tru64 Unix 5.0,
+# strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Might defines some of the following vars:
+# strtod (=fixstrtod)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+ if test "$tcl_strtod" = 1; then
+ AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+ AC_TRY_RUN([
+ extern double strtod();
+ int main() {
+ char *infString="Inf", *nanString="NaN", *spaceString=" ";
+ char *term;
+ double value;
+ value = strtod(infString, &term);
+ if ((term != infString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(nanString, &term);
+ if ((term != nanString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(spaceString, &term);
+ if (term == (spaceString+1)) {
+ exit(1);
+ }
+ exit(0);
+ }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+ tcl_cv_strtod_buggy=buggy)])
+ if test "$tcl_cv_strtod_buggy" = buggy; then
+ AC_LIBOBJ([fixstrtod])
+ USE_COMPAT=1
+ AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_LINK_LIBS
+#
+# Search for the libraries needed to link the Tcl shell.
+# Things like the math library (-lm) and socket stuff (-lsocket vs.
+# -lnsl) are dealt with here.
+#
+# Arguments:
+# Requires the following vars to be set in the Makefile:
+# DL_LIBS
+# LIBS
+# MATH_LIBS
+#
+# Results:
+#
+# Subst's the following var:
+# TCL_LIBS
+# MATH_LIBS
+#
+# Might append to the following vars:
+# LIBS
+#
+# Might define the following vars:
+# HAVE_NET_ERRNO_H
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_LINK_LIBS], [
+ #--------------------------------------------------------------------
+ # On a few very rare systems, all of the libm.a stuff is
+ # already in libc.a. Set compiler flags accordingly.
+ # Also, Linux requires the "ieee" library for math to work
+ # right (and it must appear before "-lm").
+ #--------------------------------------------------------------------
+
+ AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
+ AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
+
+ #--------------------------------------------------------------------
+ # Interactive UNIX requires -linet instead of -lsocket, plus it
+ # needs net/errno.h to define the socket-related error codes.
+ #--------------------------------------------------------------------
+
+ AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
+ AC_CHECK_HEADER(net/errno.h, [
+ AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have ?])])
+
+ #--------------------------------------------------------------------
+ # Check for the existence of the -lsocket and -lnsl libraries.
+ # The order here is important, so that they end up in the right
+ # order in the command line generated by make. Here are some
+ # special considerations:
+ # 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.
+ #--------------------------------------------------------------------
+
+ tcl_checkBoth=0
+ AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
+ if test "$tcl_checkSocket" = 1; then
+ AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
+ LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
+ fi
+ if test "$tcl_checkBoth" = 1; then
+ tk_oldLibs=$LIBS
+ LIBS="$LIBS -lsocket -lnsl"
+ AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
+ fi
+ AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
+ [LIBS="$LIBS -lnsl"])])
+
+ # TEA specific: Don't perform the eval of the libraries here because
+ # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
+
+ TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+ AC_SUBST(TCL_LIBS)
+ AC_SUBST(MATH_LIBS)
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+# Check for what flags are needed to be passed so the correct OS
+# features are available.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# _ISOC99_SOURCE
+# _LARGEFILE64_SOURCE
+# _LARGEFILE_SOURCE64
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+ AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+ AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+ if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+ AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+ tcl_flags="$tcl_flags $1"
+ fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+ AC_MSG_CHECKING([for required early compiler flags])
+ tcl_flags=""
+ TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include ],
+ [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include ],
+ [struct stat64 buf; int i = stat64("/", &buf);])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include ],
+ [char *p = (char *)open64;])
+ if test "x${tcl_flags}" = "x" ; then
+ AC_MSG_RESULT([none])
+ else
+ AC_MSG_RESULT([${tcl_flags}])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+# Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# TCL_WIDE_INT_IS_LONG
+# TCL_WIDE_INT_TYPE
+# HAVE_STRUCT_DIRENT64
+# HAVE_STRUCT_STAT64
+# HAVE_TYPE_OFF64_T
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+ AC_MSG_CHECKING([for 64-bit integer type])
+ AC_CACHE_VAL(tcl_cv_type_64bit,[
+ tcl_cv_type_64bit=none
+ # See if the compiler knows natively about __int64
+ AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+ tcl_type_64bit=__int64, tcl_type_64bit="long long")
+ # See if we should use long anyway Note that we substitute in the
+ # type that is our current guess for a 64-bit type inside this check
+ # program, so it should be modified only carefully...
+ AC_TRY_COMPILE(,[switch (0) {
+ case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
+ }],tcl_cv_type_64bit=${tcl_type_64bit})])
+ if test "${tcl_cv_type_64bit}" = none ; then
+ AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+ AC_MSG_RESULT([using long])
+ elif test "${tcl_cv_type_64bit}" = "__int64" \
+ -a "${TEA_PLATFORM}" = "windows" ; then
+ # TEA specific: We actually want to use the default tcl.h checks in
+ # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+ AC_MSG_RESULT([using Tcl header defaults])
+ else
+ AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+ [What type should be used to define wide integers?])
+ AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+ # Now check for auxiliary declarations
+ AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+ AC_TRY_COMPILE([#include
+#include ],[struct dirent64 p;],
+ tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+ if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in ?])
+ fi
+
+ AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+ AC_TRY_COMPILE([#include ],[struct stat64 p;
+],
+ tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+ if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in ?])
+ fi
+
+ AC_CHECK_FUNCS(open64 lseek64)
+ AC_MSG_CHECKING([for off64_t])
+ AC_CACHE_VAL(tcl_cv_type_off64_t,[
+ AC_TRY_COMPILE([#include ],[off64_t offset;
+],
+ tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+ dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+ dnl functions lseek64 and open64 are defined.
+ if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+ test "x${ac_cv_func_lseek64}" = "xyes" && \
+ test "x${ac_cv_func_open64}" = "xyes" ; then
+ AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in ?])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+# Init various Tcl Extension Architecture (TEA) variables.
+# This should be the first called TEA_* macro.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substs the following vars:
+# CYGPATH
+# EXEEXT
+# Defines only:
+# TEA_VERSION
+# TEA_INITED
+# TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+# Select the executable extension based on the host type. This
+# is a lightweight replacement for AC_EXEEXT that doesn't require
+# a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+ # TEA extensions pass this us the version of TEA they think they
+ # are compatible with.
+ TEA_VERSION="3.7"
+
+ AC_MSG_CHECKING([for correct TEA configuration])
+ if test x"${PACKAGE_NAME}" = x ; then
+ AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.in])
+ fi
+ if test x"$1" = x ; then
+ AC_MSG_ERROR([
+TEA version not specified.])
+ elif test "$1" != "${TEA_VERSION}" ; then
+ AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
+ else
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+ fi
+ case "`uname -s`" in
+ *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
+ EXEEXT=".exe"
+ TEA_PLATFORM="windows"
+ ;;
+ *)
+ CYGPATH=echo
+ EXEEXT=""
+ TEA_PLATFORM="unix"
+ ;;
+ esac
+
+ # Check if exec_prefix is set. If not use fall back to prefix.
+ # Note when adjusted, so that TEA_PREFIX can correct for this.
+ # This is needed for recursive configures, since autoconf propagates
+ # $prefix, but not $exec_prefix (doh!).
+ if test x$exec_prefix = xNONE ; then
+ exec_prefix_default=yes
+ exec_prefix=$prefix
+ fi
+
+ AC_SUBST(EXEEXT)
+ AC_SUBST(CYGPATH)
+
+ # This package name must be replaced statically for AC_SUBST to work
+ AC_SUBST(PKG_LIB_FILE)
+ # Substitute STUB_LIB_FILE in case package creates a stub library too.
+ AC_SUBST(PKG_STUB_LIB_FILE)
+
+ # We AC_SUBST these here to ensure they are subst'ed,
+ # in case the user doesn't call TEA_ADD_...
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+ AC_SUBST(PKG_TCL_SOURCES)
+ AC_SUBST(PKG_HEADERS)
+ AC_SUBST(PKG_INCLUDES)
+ AC_SUBST(PKG_LIBS)
+ AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_SOURCES
+# PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ case $i in
+ [\$]*)
+ # allow $-var names
+ PKG_SOURCES="$PKG_SOURCES $i"
+ PKG_OBJECTS="$PKG_OBJECTS $i"
+ ;;
+ *)
+ # check for existence - allows for generic/win/unix VPATH
+ # To add more dirs here (like 'src'), you have to update VPATH
+ # in Makefile.in as well
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ ; then
+ AC_MSG_ERROR([could not find source file '$i'])
+ fi
+ PKG_SOURCES="$PKG_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_OBJECTS="$PKG_OBJECTS $j"
+ ;;
+ esac
+ done
+ AC_SUBST(PKG_SOURCES)
+ AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_STUB_SOURCES
+# PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence - allows for generic/win/unix VPATH
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ ; then
+ AC_MSG_ERROR([could not find stub source file '$i'])
+ fi
+ PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+ done
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+# Specify one or more Tcl source files. These should be platform
+# independent runtime files.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+ fi
+ PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+ done
+ AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+# Specify one or more source headers. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+ fi
+ PKG_HEADERS="$PKG_HEADERS $i"
+ done
+ AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+# Specify one or more include dirs. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+ vars="$@"
+ for i in $vars; do
+ PKG_INCLUDES="$PKG_INCLUDES $i"
+ done
+ AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+# Specify one or more libraries. Users should check for
+# the right platform before adding to their list. For Windows,
+# libraries provided in "foo.lib" format will be converted to
+# "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+ vars="$@"
+ for i in $vars; do
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+ # Convert foo.lib to -lfoo for GCC. No-op if not *.lib
+ i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+ fi
+ PKG_LIBS="$PKG_LIBS $i"
+ done
+ AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+# Specify one or more CFLAGS. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+ PKG_CFLAGS="$PKG_CFLAGS $@"
+ AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+# Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# If --prefix or --exec-prefix was not specified, $prefix and
+# $exec_prefix will be set to the values given to Tcl when it was
+# configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+ if test "${prefix}" = "NONE"; then
+ prefix_default=yes
+ if test x"${TCL_PREFIX}" != x; then
+ AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+ prefix=${TCL_PREFIX}
+ else
+ AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+ prefix=/usr/local
+ fi
+ fi
+ if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+ -o x"${exec_prefix_default}" = x"yes" ; then
+ if test x"${TCL_EXEC_PREFIX}" != x; then
+ AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+ exec_prefix=${TCL_EXEC_PREFIX}
+ else
+ AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+ exec_prefix=$prefix
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+# Do compiler checks the way we want. This is just a replacement
+# for AC_PROG_CC in TEA configure.in files to make them cleaner.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+ # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+ # 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_PROG_CPP
+
+ AC_PROG_INSTALL
+
+ #--------------------------------------------------------------------
+ # Checks to see if the make program sets the $MAKE variable.
+ #--------------------------------------------------------------------
+
+ AC_PROG_MAKE_SET
+
+ #--------------------------------------------------------------------
+ # Find ranlib
+ #--------------------------------------------------------------------
+
+ AC_PROG_RANLIB
+
+ #--------------------------------------------------------------------
+ # Determines the correct binary file extension (.o, .obj, .exe etc.)
+ #--------------------------------------------------------------------
+
+ AC_OBJEXT
+ AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+# Do compiler checks that use the compiler. This must go after
+# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+ AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+ #------------------------------------------------------------------------
+ # 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" -a -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
+
+ #--------------------------------------------------------------------
+ # Common compiler flag setup
+ #--------------------------------------------------------------------
+
+ AC_C_BIGENDIAN
+ if test "${TEA_PLATFORM}" = "unix" ; then
+ TEA_TCL_LINK_LIBS
+ TEA_MISSING_POSIX_HEADERS
+ # Let the user call this, because if it triggers, they will
+ # need a compat/strtod.c that is correct. Users can also
+ # use Tcl_GetDouble(FromObj) instead.
+ #TEA_BUGGY_STRTOD
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+# Generate a line that can be used to build a shared/unshared library
+# in a platform independent manner.
+#
+# Arguments:
+# none
+#
+# Requires:
+#
+# Results:
+#
+# Defines the following vars:
+# CFLAGS - Done late here to note disturb other AC macros
+# MAKE_LIB - Command to execute to build the Tcl library;
+# differs depending on whether or not Tcl is being
+# compiled as a shared library.
+# MAKE_SHARED_LIB Makefile rule for building a shared library
+# MAKE_STATIC_LIB Makefile rule for building a static library
+# MAKE_STUB_LIB Makefile rule for building a stub library
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+ MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+ MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
+ else
+ MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+ MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
+ fi
+
+ if test "${SHARED_BUILD}" = "1" ; then
+ MAKE_LIB="${MAKE_SHARED_LIB} "
+ else
+ MAKE_LIB="${MAKE_STATIC_LIB} "
+ fi
+
+ #--------------------------------------------------------------------
+ # Shared libraries and static libraries have different names.
+ # Use the double eval to make sure any variables in the suffix is
+ # substituted. (@@@ Might not be necessary anymore)
+ #--------------------------------------------------------------------
+
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ if test "${SHARED_BUILD}" = "1" ; then
+ # We force the unresolved linking of symbols that are really in
+ # the private libraries of Tcl and Tk.
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+ if test x"${TK_BIN_DIR}" != x ; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+ fi
+ eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+ else
+ eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+ fi
+ # Some packages build their own stubs libraries
+ eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+ if test "$GCC" = "yes"; then
+ PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+ fi
+ # These aren't needed on Windows (either MSVC or gcc)
+ RANLIB=:
+ RANLIB_STUB=:
+ else
+ RANLIB_STUB="${RANLIB}"
+ if test "${SHARED_BUILD}" = "1" ; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+ if test x"${TK_BIN_DIR}" != x ; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+ fi
+ eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+ RANLIB=:
+ else
+ eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+ fi
+ # Some packages build their own stubs libraries
+ eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+ fi
+
+ # These are escaped so that only CFLAGS is picked up at configure time.
+ # The other values will be substituted at make time.
+ CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+ if test "${SHARED_BUILD}" = "1" ; then
+ CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+ fi
+
+ AC_SUBST(MAKE_LIB)
+ AC_SUBST(MAKE_SHARED_LIB)
+ AC_SUBST(MAKE_STATIC_LIB)
+ AC_SUBST(MAKE_STUB_LIB)
+ AC_SUBST(RANLIB_STUB)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+# Compute the name of an existing object library located in libdir
+# from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+# basename The base name of the library without version
+# numbers, extensions, or "lib" prefixes.
+# extra_dir Extra directory in which to search for the
+# library. This location is used first, then
+# $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+# TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+# Defines the following vars:
+# ${basename}_LIB_NAME The computed library name.
+# ${basename}_LIB_SPEC The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+ AC_MSG_CHECKING([for $1 library])
+
+ # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+ tea_lib_name_dir="${exec_prefix}/lib"
+
+ # Or in a user-specified location.
+
+ if test x"$2" != x ; then
+ tea_extra_lib_dir=$2
+ else
+ tea_extra_lib_dir=NONE
+ fi
+
+ for i in \
+ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+ if test -f "$i" ; then
+ tea_lib_name_dir=`dirname $i`
+ $1_LIB_NAME=`basename $i`
+ $1_LIB_PATH_NAME=$i
+ break
+ fi
+ done
+
+ if test "${TEA_PLATFORM}" = "windows"; then
+ $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+ else
+ # Strip off the leading "lib" and trailing ".a" or ".so"
+
+ tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+ $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+ fi
+
+ if test "x${$1_LIB_NAME}" = x ; then
+ AC_MSG_ERROR([not found])
+ else
+ AC_MSG_RESULT([${$1_LIB_SPEC}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+# Locate the private Tcl include files
+#
+# Arguments:
+#
+# Requires:
+# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substs the following vars:
+# TCL_TOP_DIR_NATIVE
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+ AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
+ AC_MSG_CHECKING([for Tcl private include files])
+
+ TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+ TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+ # Check to see if tclPort.h isn't already with the public headers
+ # Don't look for tclInt.h because that resides with tcl.h in the core
+ # sources, but the Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tclh}/tclWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+ else
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TCL_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -d "${TCL_BIN_DIR}/Headers" -a \
+ -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+ TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+ else
+ TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TCL_INCLUDES}"
+ else
+ if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+ fi
+ result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TCL_TOP_DIR_NATIVE)
+
+ AC_SUBST(TCL_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+# Locate the installed public Tcl header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tclinclude switch to configure.
+# Result is cached.
+#
+# Substs the following vars:
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+ AC_MSG_CHECKING([for Tcl public headers])
+
+ AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tclh, [
+ # Use the value from --with-tclinclude, if it was given
+
+ if test x"${with_tclinclude}" != x ; then
+ if test -f "${with_tclinclude}/tcl.h" ; then
+ ac_cv_c_tclh=${with_tclinclude}
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+ fi
+ else
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers directory
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tcl is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TCL_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tcl.h" ; then
+ ac_cv_c_tclh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tclh}" = x ; then
+ AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tclh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+ TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+# Locate the private Tk include files
+#
+# Arguments:
+#
+# Requires:
+# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substs the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+ AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
+ AC_MSG_CHECKING([for Tk private include files])
+
+ TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+ TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+ # Check to see if tkPort.h isn't already with the public headers
+ # Don't look for tkInt.h because that resides with tk.h in the core
+ # sources, but the Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tkh}/tkWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+ TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+ else
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TK_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+ # Detect and add ttk subdir
+ if test -d "${TK_SRC_DIR}/generic/ttk"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ TK_INCLUDES="${TK_INCLUDES} -I${TK_XLIB_DIR_NATIVE}"
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+ fi
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -d "${TK_BIN_DIR}/Headers" -a \
+ -d "${TK_BIN_DIR}/PrivateHeaders"; then
+ TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+ else
+ TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TK_INCLUDES}"
+ else
+ if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+ fi
+ result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TK_TOP_DIR_NATIVE)
+ AC_SUBST(TK_XLIB_DIR_NATIVE)
+
+ AC_SUBST(TK_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+# Locate the installed public Tk header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tkinclude switch to configure.
+# Result is cached.
+#
+# Substs the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+ AC_MSG_CHECKING([for Tk public headers])
+
+ AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tkh, [
+ # Use the value from --with-tkinclude, if it was given
+
+ if test x"${with_tkinclude}" != x ; then
+ if test -f "${with_tkinclude}/tk.h" ; then
+ ac_cv_c_tkh=${with_tkinclude}
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+ fi
+ else
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers directory.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tk is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tk's --prefix location,
+ # relative to directory of tkConfig.sh, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ fi
+ for i in $list ; do
+ if test -f "$i/tk.h" ; then
+ ac_cv_c_tkh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tkh}" = x ; then
+ AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tkh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+ TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TK_INCLUDES)
+
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ # On Windows and Aqua, we need the X compat headers
+ AC_MSG_CHECKING([for X11 header files])
+ if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+ INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+ TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+ AC_SUBST(TK_XINCLUDES)
+ fi
+ AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+# Locate the ${1}Config.sh file and perform a sanity check on
+# the ${1} compile flags. These are used by packages like
+# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-$1=...
+#
+# Defines the following vars:
+# $1_BIN_DIR Full path to the directory containing
+# the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+ #
+ # Ok, lets find the $1 configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-$1
+ #
+
+ if test x"${no_$1}" = x ; then
+ # we reset no_$1 in case something fails here
+ no_$1=true
+ AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+ AC_MSG_CHECKING([for $1 configuration])
+ AC_CACHE_VAL(ac_cv_c_$1config,[
+
+ # First check to see if --with-$1 was specified.
+ if test x"${with_$1config}" != x ; then
+ case ${with_$1config} in
+ */$1Config.sh )
+ if test -f ${with_$1config}; then
+ AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+ with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+ fi;;
+ esac
+ if test -f "${with_$1config}/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+ else
+ AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+ fi
+ fi
+
+ # then check for a private $1 installation
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in \
+ ../$1 \
+ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../$1 \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../../$1 \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../$1 \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ if test -f "$i/unix/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_$1config}" = x ; then
+ $1_BIN_DIR="# no $1 configs found"
+ AC_MSG_WARN([Cannot find $1 configuration definitions])
+ exit 0
+ else
+ no_$1=
+ $1_BIN_DIR=${ac_cv_c_$1config}
+ AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+# Load the $1Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1_BIN_DIR
+#
+# Results:
+#
+# Subst the following vars:
+# $1_SRC_DIR
+# $1_LIB_FILE
+# $1_LIB_SPEC
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+ if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${$1_BIN_DIR}/$1Config.sh"
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+
+ #
+ # If the $1_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable $1_LIB_SPEC will be set to the value
+ # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+ # instead of $1_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ #
+
+ if test -f "${$1_BIN_DIR}/Makefile" ; then
+ AC_MSG_WARN([Found Makefile - using build library specs for $1])
+ $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+ $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+ $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+ fi
+
+ AC_SUBST($1_VERSION)
+ AC_SUBST($1_BIN_DIR)
+ AC_SUBST($1_SRC_DIR)
+
+ AC_SUBST($1_LIB_FILE)
+ AC_SUBST($1_LIB_SPEC)
+
+ AC_SUBST($1_STUB_LIB_FILE)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_PATH)
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+# Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-celib=...
+#
+# Defines the following vars:
+# CELIB_DIR Full path to the directory containing
+# the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-celib
+
+ if test x"${no_celib}" = x ; then
+ # we reset no_celib in case something fails here
+ no_celib=true
+ AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
+ AC_MSG_CHECKING([for Windows/CE celib directory])
+ AC_CACHE_VAL(ac_cv_c_celibconfig,[
+ # First check to see if --with-celibconfig was specified.
+ if test x"${with_celibconfig}" != x ; then
+ if test -d "${with_celibconfig}/inc" ; then
+ ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+ fi
+ fi
+
+ # then check for a celib library
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ for i in \
+ ../celib-palm-3.0 \
+ ../celib \
+ ../../celib-palm-3.0 \
+ ../../celib \
+ `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../celib-palm-3.0 \
+ ${srcdir}/../celib \
+ `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -d "$i/inc" ; then
+ ac_cv_c_celibconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ AC_MSG_ERROR([Cannot find celib support library directory])
+ else
+ no_celib=
+ CELIB_DIR=${ac_cv_c_celibconfig}
+ CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+ AC_MSG_RESULT([found $CELIB_DIR])
+ fi
+ fi
+])
+
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/ng/Togl2.1/texture.c b/ng/Togl2.1/texture.c
new file mode 100644
index 00000000..295f3666
--- /dev/null
+++ b/ng/Togl2.1/texture.c
@@ -0,0 +1,663 @@
+/* $Id: texture.c,v 1.14 2007/08/03 16:48:50 gregcouch Exp $ */
+
+/*
+ * Togl - a Tk OpenGL widget
+ * Copyright (C) 1996-1997 Brian Paul and Ben Bederson
+ * Copyright (C) 2006-2007 Greg Couch
+ * See the LICENSE file for copyright details.
+ */
+
+
+/*
+ * An example Togl program demonstrating texture mapping
+ */
+
+#define USE_TOGL_STUBS
+
+#include "togl.h"
+#include
+#include
+#if defined(TOGL_AGL)
+# include
+#else
+# include
+#endif
+#include "image.h"
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+
+#define CHECKER 0
+#define FACE 1
+#define TREE 2
+
+
+static GLenum minfilter = GL_NEAREST_MIPMAP_LINEAR;
+static GLenum magfilter = GL_LINEAR;
+static GLenum swrap = GL_REPEAT;
+static GLenum twrap = GL_REPEAT;
+static GLenum envmode = GL_MODULATE;
+static GLubyte polycolor[4] = { 255, 255, 255, 255 };
+static int teximage = CHECKER;
+static double coord_scale = 1;
+static double xrot = 0;
+static double yrot = 0;
+static double texscale = 1;
+
+static GLint width, height;
+
+static GLboolean blend = GL_FALSE;
+
+
+/*
+ * Load a texture image. n is one of CHECKER, FACE or TREE.
+ */
+static void
+texture_image(int n)
+{
+ if (n == CHECKER) {
+#define WIDTH 64
+#define HEIGHT 64
+ GLubyte teximage[WIDTH * HEIGHT][4];
+ int i, j;
+
+ for (i = 0; i < HEIGHT; i++) {
+ for (j = 0; j < WIDTH; j++) {
+ GLubyte value;
+
+ value = ((i / 4 + j / 4) % 2) ? 0xff : 0x00;
+ teximage[i * WIDTH + j][0] = value;
+ teximage[i * WIDTH + j][1] = value;
+ teximage[i * WIDTH + j][2] = value;
+ teximage[i * WIDTH + j][3] = value;
+ }
+ }
+
+ glEnable(GL_TEXTURE_2D);
+ gluBuild2DMipmaps(GL_TEXTURE_2D, 4, WIDTH, HEIGHT,
+ GL_RGBA, GL_UNSIGNED_BYTE, teximage);
+ blend = GL_FALSE;
+
+#undef WIDTH
+#undef HEIGHT
+ } else if (n == FACE) {
+ TK_RGBImageRec *img = tkRGBImageLoad("ben.rgb");
+
+ if (img) {
+ glEnable(GL_TEXTURE_2D);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ gluBuild2DMipmaps(GL_TEXTURE_2D, img->sizeZ, img->sizeX, img->sizeY,
+ img->sizeZ == 3 ? GL_RGB : GL_RGBA,
+ GL_UNSIGNED_BYTE, img->data);
+
+ blend = GL_TRUE;
+ }
+ } else if (n == TREE) {
+ TK_RGBImageRec *img = tkRGBImageLoad("tree2.rgba");
+
+ if (img) {
+ glEnable(GL_TEXTURE_2D);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ gluBuild2DMipmaps(GL_TEXTURE_2D, img->sizeZ, img->sizeX, img->sizeY,
+ img->sizeZ == 3 ? GL_RGB : GL_RGBA,
+ GL_UNSIGNED_BYTE, img->data);
+
+ blend = GL_TRUE;
+ }
+ } else {
+ abort();
+ }
+}
+
+
+/*
+ * Togl widget create callback. This is called by Tcl/Tk when the widget has
+ * been realized. Here's where one may do some one-time context setup or
+ * initializations.
+ */
+static int
+create_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ glEnable(GL_DEPTH_TEST); /* Enable depth buffering */
+
+ texture_image(CHECKER);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
+
+ return TCL_OK;
+}
+
+
+/*
+ * Togl widget reshape callback. This is called by Tcl/Tk when the widget
+ * has been resized. Typically, we call glViewport and perhaps setup the
+ * projection matrix.
+ */
+static int
+reshape_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ width = Togl_Width(togl);
+ height = Togl_Height(togl);
+
+ glViewport(0, 0, width, height);
+
+ return TCL_OK;
+}
+
+
+static void
+check_error(char *where)
+{
+ GLenum error;
+
+ while (1) {
+ error = glGetError();
+ if (error == GL_NO_ERROR) {
+ break;
+ }
+ printf("OpenGL error near %s: %s\n", where, gluErrorString(error));
+ }
+}
+
+
+
+/*
+ * Togl widget display callback. This is called by Tcl/Tk when the widget's
+ * contents have to be redrawn. Typically, we clear the color and depth
+ * buffers, render our objects, then swap the front/back color buffers.
+ */
+static int
+display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ float aspect = (float) width / (float) height;
+ Togl *togl;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ check_error("begin display\n");
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ /* Draw background image */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_DEPTH_TEST);
+ glBegin(GL_POLYGON);
+ glColor3f(0, 0, 0.3f);
+ glVertex2f(-1, -1);
+ glColor3f(0, 0, 0.3f);
+ glVertex2f(1, -1);
+ glColor3f(0, 0, 0.9f);
+ glVertex2f(1, 1);
+ glColor3f(0, 0, 0.9f);
+ glVertex2f(-1, 1);
+ glEnd();
+
+ /* draw textured object */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-aspect, aspect, -1, 1, 2, 10);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -5);
+ glScaled(texscale, texscale, texscale);
+ glRotated(yrot, 0, 1, 0);
+ glRotated(xrot, 1, 0, 0);
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ glColor4ubv(polycolor);
+
+ if (blend) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ }
+
+ glBegin(GL_POLYGON);
+ glTexCoord2f(0, 0);
+ glVertex2f(-1, -1);
+ glTexCoord2d(coord_scale, 0);
+ glVertex2f(1, -1);
+ glTexCoord2d(coord_scale, coord_scale);
+ glVertex2f(1, 1);
+ glTexCoord2d(0, coord_scale);
+ glVertex2f(-1, 1);
+ glEnd();
+
+ glDisable(GL_BLEND);
+
+ Togl_SwapBuffers(togl);
+
+ return TCL_OK;
+}
+
+
+/*
+ * Called when a magnification filter radio button is pressed.
+ */
+static int
+magfilter_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ static const char *names[] = { "GL_NEAREST", "GL_LINEAR", NULL };
+ static const GLenum magfilters[] = { GL_NEAREST, GL_LINEAR };
+ int result, index;
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName magnification-filter-type");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ result = Tcl_GetIndexFromObj(interp, objv[2], names,
+ "magnification filter type", 0, &index);
+ if (result == TCL_OK) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ magfilters[index]);
+ Togl_PostRedisplay(togl);
+ }
+ return result;
+}
+
+
+/*
+ * Called when a minification filter radio button is pressed.
+ */
+static int
+minfilter_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ static const char *names[] = {
+ "GL_NEAREST", "GL_LINEAR",
+ "GL_NEAREST_MIPMAP_NEAREST", "GL_LINEAR_MIPMAP_NEAREST",
+ "GL_NEAREST_MIPMAP_LINEAR", "GL_LINEAR_MIPMAP_LINEAR", NULL
+ };
+ static const GLenum minfilters[] = {
+ GL_NEAREST, GL_LINEAR,
+ GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST,
+ GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR
+ };
+ int result, index;
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName minification-filter-type");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ result = Tcl_GetIndexFromObj(interp, objv[2], names,
+ "minification filter type", 0, &index);
+ if (result == TCL_OK) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ minfilters[index]);
+ Togl_PostRedisplay(togl);
+ }
+ return result;
+}
+
+
+static int
+xrot_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName angle");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &xrot) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Togl_PostRedisplay(togl);
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ return TCL_OK;
+}
+
+
+static int
+yrot_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName angle");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &yrot) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Togl_PostRedisplay(togl);
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ return TCL_OK;
+}
+
+
+static int
+texscale_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName value");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &texscale) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Togl_PostRedisplay(togl);
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ return TCL_OK;
+}
+
+
+/*
+ * Called when S texture coordinate wrapping is changed.
+ */
+static int
+swrap_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ static const char *names[] = { "GL_CLAMP", "GL_REPEAT", NULL };
+ static const GLenum swraps[] = { GL_CLAMP, GL_REPEAT };
+ int result, index;
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName wrap-mode");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ result = Tcl_GetIndexFromObj(interp, objv[2], names,
+ "wrap mode", 0, &index);
+ if (result == TCL_OK) {
+ swrap = swraps[index];
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, swrap);
+ Togl_PostRedisplay(togl);
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ }
+ return result;
+}
+
+
+/*
+ * Called when T texture coordinate wrapping is changed.
+ */
+static int
+twrap_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ static const char *names[] = { "GL_CLAMP", "GL_REPEAT", NULL };
+ static const GLenum twraps[] = { GL_CLAMP, GL_REPEAT };
+ int result, index;
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName wrap-mode");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ result = Tcl_GetIndexFromObj(interp, objv[2], names,
+ "wrap mode", 0, &index);
+ if (result == TCL_OK) {
+ twrap = twraps[index];
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, twrap);
+ Togl_PostRedisplay(togl);
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ }
+ return result;
+}
+
+
+/*
+ * Called when the texture environment mode is changed.
+ */
+static int
+envmode_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ static const char *names[] = {
+ "GL_MODULATE", "GL_DECAL", "GL_BLEND", NULL
+ };
+ static const GLenum envmodes[] = { GL_MODULATE, GL_DECAL, GL_BLEND };
+ int result, index;
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName texture-env-mode");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ result = Tcl_GetIndexFromObj(interp, objv[2], names,
+ "texture env mode", 0, &index);
+ if (result == TCL_OK) {
+ envmode = envmodes[index];
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, envmode);
+ Togl_PostRedisplay(togl);
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ }
+ return result;
+}
+
+
+/*
+ * Called when the polygon color is changed.
+ */
+static int
+polycolor_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl;
+ int r, g, b;
+
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName r g b");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetIntFromObj(interp, objv[2], &r) != TCL_OK
+ || Tcl_GetIntFromObj(interp, objv[3], &g) != TCL_OK
+ || Tcl_GetIntFromObj(interp, objv[4], &b) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ polycolor[0] = r;
+ polycolor[1] = g;
+ polycolor[2] = b;
+
+ Togl_PostRedisplay(togl);
+
+ return TCL_OK;
+}
+
+
+/*
+ * Called when the texture image is to be changed
+ */
+static int
+teximage_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ static const char *names[] = {
+ "CHECKER", "FACE", "TREE", NULL
+ };
+ static const GLenum teximages[] = {
+ CHECKER, FACE, TREE
+ };
+ int result, index;
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName texture-image-name");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ result = Tcl_GetIndexFromObj(interp, objv[2], names,
+ "texture image name", 0, &index);
+ if (result == TCL_OK) {
+ teximage = teximages[index];
+ texture_image(teximage);
+ Togl_PostRedisplay(togl);
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ }
+ return result;
+}
+
+
+/*
+ * Called when the texture coordinate scale is changed.
+ */
+static int
+coord_scale_cmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ double s;
+ Togl *togl;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName scale");
+ return TCL_ERROR;
+ }
+
+ if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &s) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (s > 0 && s < 10) {
+ coord_scale = s;
+ Togl_PostRedisplay(togl);
+ }
+
+ /* Let result string equal value */
+ Tcl_SetObjResult(interp, objv[2]);
+ return TCL_OK;
+}
+
+
+EXTERN int
+Texture_Init(Tcl_Interp *interp)
+{
+ /*
+ * Initialize Tcl and the Togl widget module.
+ */
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL
+ || Togl_InitStubs(interp, "2.0", 0) == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Specify the C callback functions for widget creation, display,
+ * and reshape.
+ */
+ Tcl_CreateObjCommand(interp, "create_cb", create_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "display_cb", display_cb, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "reshape_cb", reshape_cb, NULL, NULL);
+
+ /*
+ * Make a new Togl widget command so the Tcl code can set a C variable.
+ */
+ Tcl_CreateObjCommand(interp, "min_filter", minfilter_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "mag_filter", magfilter_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "xrot", xrot_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "yrot", yrot_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "texscale", texscale_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "swrap", swrap_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "twrap", twrap_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "envmode", envmode_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "polycolor", polycolor_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "teximage", teximage_cmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "coord_scale", coord_scale_cmd, NULL, NULL);
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+
+ return TCL_OK;
+}
diff --git a/ng/Togl2.1/texture.tcl b/ng/Togl2.1/texture.tcl
new file mode 100644
index 00000000..85067ff2
--- /dev/null
+++ b/ng/Togl2.1/texture.tcl
@@ -0,0 +1,278 @@
+#!/bin/sh
+# the next line restarts using tclsh \
+exec tclsh "$0" "$@"
+
+# $Id: texture.tcl,v 1.8 2007/08/03 16:48:50 gregcouch Exp $
+
+# Togl - a Tk OpenGL widget
+# Copyright (C) 1996 Brian Paul and Ben Bederson
+# Copyright (C) 2006-2007 Greg Couch
+# See the LICENSE file for copyright details.
+
+
+# Togl texture map demo
+
+package provide texture 1.0
+
+# add parent directory to path to find Togl's pkgIndex in current directory
+if { [file exists pkgIndex.tcl] } {
+ set auto_path [linsert $auto_path 0 ..]
+}
+# following load also loads Tk and Togl packages
+load [file dirname [info script]]/texture[info sharedlibextension]
+
+# create ::texture namespace
+namespace eval ::texture {
+}
+
+# Called magnification filter changes
+proc ::texture::new_magfilter {} {
+ global magfilter
+ mag_filter .f1.view $magfilter
+}
+
+
+# Called minification filter changes
+proc ::texture::new_minfilter {} {
+ global minfilter
+ min_filter .f1.view $minfilter
+}
+
+
+# Called when texture image radio button changes
+proc ::texture::new_image {} {
+ global image
+ teximage .f1.view $image
+}
+
+
+# Called when texture S wrap button changes
+proc ::texture::new_swrap {} {
+ global swrap
+ swrap .f1.view $swrap
+}
+
+
+# Called when texture T wrap button changes
+proc ::texture::new_twrap {} {
+ global twrap
+ twrap .f1.view $twrap
+}
+
+
+# Called when texture environment radio button selected
+proc ::texture::new_env {} {
+ global envmode
+ envmode .f1.view $envmode
+}
+
+
+# Called when polygon color sliders change
+proc ::texture::new_color { foo } {
+ global poly_red poly_green poly_blue
+ polycolor .f1.view $poly_red $poly_green $poly_blue
+}
+
+
+proc ::texture::new_coord_scale { name element op } {
+ global coord_scale
+ coord_scale .f1.view $coord_scale
+}
+
+proc ::texture::take_photo {} {
+ image create photo teximg
+ .f1.view takephoto teximg
+ teximg write image.ppm -format ppm
+}
+
+# Make the widgets
+proc ::texture::setup {} {
+ global magfilter
+ global minfilter
+ global image
+ global swrap
+ global twrap
+ global envmode
+ global poly_red
+ global poly_green
+ global poly_blue
+ global coord_scale
+ global startx starty # location of mouse when button pressed
+ global xangle yangle
+ global xangle0 yangle0
+ global texscale texscale0
+
+ wm title . "Texture Map Options"
+
+ ### Two frames: top half and bottom half
+ frame .f1
+ frame .f2
+
+ ### The OpenGL window
+ togl .f1.view -width 250 -height 250 -rgba true -double true -depth true -create create_cb -reshape reshape_cb -display display_cb
+
+
+ ### Filter radio buttons
+ frame .f1.filter -relief ridge -borderwidth 3
+
+ frame .f1.filter.mag -relief ridge -borderwidth 2
+
+ label .f1.filter.mag.label -text "Magnification Filter" -anchor w
+ radiobutton .f1.filter.mag.nearest -text GL_NEAREST -anchor w -variable magfilter -value GL_NEAREST -command ::texture::new_magfilter
+ radiobutton .f1.filter.mag.linear -text GL_LINEAR -anchor w -variable magfilter -value GL_LINEAR -command ::texture::new_magfilter
+
+ frame .f1.filter.min -relief ridge -borderwidth 2
+
+ label .f1.filter.min.label -text "Minification Filter" -anchor w
+ radiobutton .f1.filter.min.nearest -text GL_NEAREST -anchor w -variable minfilter -value GL_NEAREST -command ::texture::new_minfilter
+ radiobutton .f1.filter.min.linear -text GL_LINEAR -anchor w -variable minfilter -value GL_LINEAR -command ::texture::new_minfilter
+ radiobutton .f1.filter.min.nearest_mipmap_nearest -text GL_NEAREST_MIPMAP_NEAREST -anchor w -variable minfilter -value GL_NEAREST_MIPMAP_NEAREST -command ::texture::new_minfilter
+ radiobutton .f1.filter.min.linear_mipmap_nearest -text GL_LINEAR_MIPMAP_NEAREST -anchor w -variable minfilter -value GL_LINEAR_MIPMAP_NEAREST -command ::texture::new_minfilter
+ radiobutton .f1.filter.min.nearest_mipmap_linear -text GL_NEAREST_MIPMAP_LINEAR -anchor w -variable minfilter -value GL_NEAREST_MIPMAP_LINEAR -command ::texture::new_minfilter
+ radiobutton .f1.filter.min.linear_mipmap_linear -text GL_LINEAR_MIPMAP_LINEAR -anchor w -variable minfilter -value GL_LINEAR_MIPMAP_LINEAR -command ::texture::new_minfilter
+
+ pack .f1.filter.mag -fill x
+ pack .f1.filter.mag.label -fill x
+ pack .f1.filter.mag.nearest -side top -fill x
+ pack .f1.filter.mag.linear -side top -fill x
+
+ pack .f1.filter.min -fill both -expand true
+ pack .f1.filter.min.label -side top -fill x
+ pack .f1.filter.min.nearest -side top -fill x
+ pack .f1.filter.min.linear -side top -fill x
+ pack .f1.filter.min.nearest_mipmap_nearest -side top -fill x
+ pack .f1.filter.min.linear_mipmap_nearest -side top -fill x
+ pack .f1.filter.min.nearest_mipmap_linear -side top -fill x
+ pack .f1.filter.min.linear_mipmap_linear -side top -fill x
+
+
+ ### Texture coordinate scale and wrapping
+ frame .f2.coord -relief ridge -borderwidth 3
+ frame .f2.coord.scale -relief ridge -borderwidth 2
+ label .f2.coord.scale.label -text "Max Texture Coord" -anchor w
+ entry .f2.coord.scale.entry -textvariable coord_scale
+ trace variable coord_scale w ::texture::new_coord_scale
+
+ frame .f2.coord.s -relief ridge -borderwidth 2
+ label .f2.coord.s.label -text "GL_TEXTURE_WRAP_S" -anchor w
+ radiobutton .f2.coord.s.repeat -text "GL_REPEAT" -anchor w -variable swrap -value GL_REPEAT -command ::texture::new_swrap
+ radiobutton .f2.coord.s.clamp -text "GL_CLAMP" -anchor w -variable swrap -value GL_CLAMP -command ::texture::new_swrap
+
+ frame .f2.coord.t -relief ridge -borderwidth 2
+ label .f2.coord.t.label -text "GL_TEXTURE_WRAP_T" -anchor w
+ radiobutton .f2.coord.t.repeat -text "GL_REPEAT" -anchor w -variable twrap -value GL_REPEAT -command ::texture::new_twrap
+ radiobutton .f2.coord.t.clamp -text "GL_CLAMP" -anchor w -variable twrap -value GL_CLAMP -command ::texture::new_twrap
+
+ pack .f2.coord.scale -fill both -expand true
+ pack .f2.coord.scale.label -side top -fill x
+ pack .f2.coord.scale.entry -side top -fill x
+
+ pack .f2.coord.s -fill x
+ pack .f2.coord.s.label -side top -fill x
+ pack .f2.coord.s.repeat -side top -fill x
+ pack .f2.coord.s.clamp -side top -fill x
+
+ pack .f2.coord.t -fill x
+ pack .f2.coord.t.label -side top -fill x
+ pack .f2.coord.t.repeat -side top -fill x
+ pack .f2.coord.t.clamp -side top -fill x
+
+
+ ### Texture image radio buttons (just happens to fit into the coord frame)
+ frame .f2.env -relief ridge -borderwidth 3
+ frame .f2.env.image -relief ridge -borderwidth 2
+ label .f2.env.image.label -text "Texture Image" -anchor w
+ radiobutton .f2.env.image.checker -text "Checker" -anchor w -variable image -value CHECKER -command ::texture::new_image
+ radiobutton .f2.env.image.tree -text "Tree" -anchor w -variable image -value TREE -command ::texture::new_image
+ radiobutton .f2.env.image.face -text "Face" -anchor w -variable image -value FACE -command ::texture::new_image
+ pack .f2.env.image -fill x
+ pack .f2.env.image.label -side top -fill x
+ pack .f2.env.image.checker -side top -fill x
+ pack .f2.env.image.tree -side top -fill x
+ pack .f2.env.image.face -side top -fill x
+
+
+ ### Texture Environment
+ label .f2.env.label -text "GL_TEXTURE_ENV_MODE" -anchor w
+ radiobutton .f2.env.modulate -text "GL_MODULATE" -anchor w -variable envmode -value GL_MODULATE -command ::texture::new_env
+ radiobutton .f2.env.decal -text "GL_DECAL" -anchor w -variable envmode -value GL_DECAL -command ::texture::new_env
+ radiobutton .f2.env.blend -text "GL_BLEND" -anchor w -variable envmode -value GL_BLEND -command ::texture::new_env
+ pack .f2.env.label -fill x
+ pack .f2.env.modulate -side top -fill x
+ pack .f2.env.decal -side top -fill x
+ pack .f2.env.blend -side top -fill x
+
+ ### Polygon color
+ frame .f2.color -relief ridge -borderwidth 3
+ label .f2.color.label -text "Polygon color" -anchor w
+ scale .f2.color.red -label Red -from 0 -to 255 -orient horizontal -variable poly_red -command ::texture::new_color
+ scale .f2.color.green -label Green -from 0 -to 255 -orient horizontal -variable poly_green -command ::texture::new_color
+ scale .f2.color.blue -label Blue -from 0 -to 255 -orient horizontal -variable poly_blue -command ::texture::new_color
+ pack .f2.color.label -fill x
+ pack .f2.color.red -side top -fill x
+ pack .f2.color.green -side top -fill x
+ pack .f2.color.blue -side top -fill x
+
+
+ ### Main widgets
+ pack .f1.view -side left -fill both -expand true
+ pack .f1.filter -side left -fill y
+ pack .f1 -side top -fill both -expand true
+
+ pack .f2.coord .f2.env -side left -fill both
+ pack .f2.color -fill x
+ pack .f2 -side top -fill x
+
+ button .photo -text "Take Photo" -command ::texture::take_photo
+ pack .photo -expand true -fill both
+ button .quit -text Quit -command exit
+ pack .quit -expand true -fill both
+
+ bind .f1.view {
+ set startx %x
+ set starty %y
+ set xangle0 $xangle
+ set yangle0 $yangle
+ }
+
+ bind .f1.view {
+ set xangle [expr $xangle0 + (%x - $startx) / 3.0 ]
+ set yangle [expr $yangle0 + (%y - $starty) / 3.0 ]
+ yrot .f1.view $xangle
+ xrot .f1.view $yangle
+ }
+
+ bind .f1.view {
+ set startx %x
+ set starty %y
+ set texscale0 $texscale
+ }
+
+ bind .f1.view {
+ set q [ expr ($starty - %y) / 400.0 ]
+ set texscale [expr $texscale0 * exp($q)]
+ texscale .f1.view $texscale
+ }
+
+ # set default values:
+ set minfilter GL_NEAREST_MIPMAP_LINEAR
+ set magfilter GL_LINEAR
+ set swrap GL_REPEAT
+ set twrap GL_REPEAT
+ set envmode GL_MODULATE
+ set image CHECKER
+ set poly_red 255
+ set poly_green 255
+ set poly_blue 255
+ set coord_scale 1.0
+
+ set xangle 0.0
+ set yangle 0.0
+ set texscale 1.0
+}
+
+
+# Execution starts here!
+if { [info script] == $argv0 } {
+ ::texture::setup
+}
diff --git a/ng/Togl2.1/togl.c b/ng/Togl2.1/togl.c
new file mode 100644
index 00000000..d9fe9321
--- /dev/null
+++ b/ng/Togl2.1/togl.c
@@ -0,0 +1,5405 @@
+/* $Id: togl.c,v 1.142 2009/12/23 21:50:49 gregcouch Exp $ */
+
+/* vi:set sw=4 expandtab: */
+
+/*
+ * Togl - a Tk OpenGL widget
+ *
+ * Copyright (C) 1996-2002 Brian Paul and Ben Bederson
+ * Copyright (C) 2005-2009 Greg Couch
+ * See the LICENSE file for copyright details.
+ */
+
+/*
+ * Currently we support X11, Win32 and Mac OS X only
+ */
+
+#define USE_TOGL_STUB_PROCS
+#include "togl.h"
+#include
+#include
+#include
+
+#ifndef TOGL_USE_FONTS
+# define TOGL_USE_FONTS 1
+#endif
+#if (TK_MAJOR_VERSION > 8 || TK_MINOR_VERSION > 4) && !defined(TOGL_WGL)
+/* X11 and Aqua font technology changed in 8.5 */
+# undef TOGL_USE_FONTS
+#endif
+#ifndef TOGL_USE_OVERLAY
+# if defined(TOGL_X11) || defined(TOGL_WGL)
+# define TOGL_USE_OVERLAY 1
+# endif
+#endif
+
+/* Use TCL_STUPID to cast (const char *) to (char *) where the Tcl function
+ * prototype argument should really be const */
+#define TCL_STUPID (char *)
+
+/* Use WIDGREC to cast widgRec or recordPtr arguments */
+#define WIDGREC (char *)
+
+/*** Windows headers ***/
+#if defined(TOGL_WGL)
+# define WIN32_LEAN_AND_MEAN
+# include
+# undef WIN32_LEAN_AND_MEAN
+# include
+# ifndef PFD_SUPPORT_COMPOSITION
+// for Vista -- not strictly needed because we don't use PFD_SUPPORT_GDI/BITMAP
+# define PFD_SUPPORT_COMPOSITION 0x00008000
+# endif
+# include
+# include
+# ifdef _MSC_VER
+# include
+# else
+# ifdef UNICODE
+# define StringCchPrintf snwprintf
+# else
+# define StringCchPrintf snprintf
+# endif
+# endif
+
+/*** X Window System headers ***/
+#elif defined(TOGL_X11)
+# include
+# include
+# include /* for XA_RGB_DEFAULT_MAP atom */
+# if !defined(USE_SYSTEM_XMU)
+# include "Xmu/StdCmap.h"
+# else
+# if defined(__vms)
+# include /* for XmuLookupStandardColormap */
+# else
+# include /* for XmuLookupStandardColormap */
+# endif
+# endif
+# define GLX_GLXEXT_LEGACY /* include glxext.h separately */
+# include
+ /* we want the prototype typedefs from glxext.h */
+# undef GLX_VERSION_1_3
+# undef GLX_VERSION_1_4
+# ifdef UNDEF_GET_PROC_ADDRESS
+# undef GLX_ARB_get_proc_address
+# endif
+# include
+# ifdef __sgi
+# include
+# endif
+# ifdef HAVE_AUTOSTEREO
+# include
+# endif
+
+/*** Mac Carbon headers ***/
+#elif defined(TOGL_AGL)
+# define Cursor QDCursor
+# include
+# undef Cursor
+# include /* usa MacDrawable */
+# include
+# define Togl_MacOSXGetDrawablePort(togl) TkMacOSXGetDrawablePort((Drawable) ((TkWindow *) togl->TkWin)->privatePtr)
+
+/*** Mac Cocoa headers ***/
+#elif defined(TOGL_NSOPENGL)
+#undef panic
+# include
+# include /* Use NSOpenGLContext */
+# include /* Use NSView */
+# include /* Use NSWindow */
+# include /* Use NSView setWantsBestResolutionOpenGLSurface */
+# include /* Use NSEvent */
+# include /* Use NSTouch */
+# include /* Use NSRect */
+# include /* Use MacDrawable */
+# include
+# define Togl_MacOSXGetDrawablePort(togl) TkMacOSXGetDrawablePort((Drawable) ((TkWindow *) togl->TkWin)->privatePtr)
+
+# include
+# ifndef __MAC_10_7
+/* Define Mac retina display routines not available prior to Mac OS 10.7 */
+@interface NSView (NSOpenGLSurfaceResolution)
+- (BOOL)wantsBestResolutionOpenGLSurface;
+- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag;
+- (NSRect)convertRectToBacking:(NSRect)aRect;
+#define NSEventPhaseNone 0
+@end
+# endif
+
+#else /* make sure only one platform defined */
+# error Unsupported platform, or confused platform defines...
+#endif
+
+#define NC3D "NVidia Consumer 3D Stereo"
+
+#ifndef STEREO_BUFFER_NONE
+/* From , but we use this constants elsewhere */
+# define STEREO_BUFFER_NONE 0
+# define STEREO_BUFFER_LEFT 1
+# define STEREO_BUFFER_RIGHT 2
+#endif
+
+/*** Standard C headers ***/
+#include
+#include
+#include
+
+#ifdef TOGL_WGL
+# include
+#endif
+
+#if TK_MAJOR_VERSION < 8
+# error Sorry Togl requires Tcl/Tk ver 8.0 or higher.
+#endif
+
+#ifdef USE_TCL_STUBS
+# if TK_MAJOR_VERSION < 8 || (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 1)
+# error Sorry stub support requires Tcl/Tk ver 8.1 or higher.
+# endif
+#endif
+
+#if defined(TOGL_AGL)
+# if TK_MAJOR_VERSION < 8 || (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 4)
+# error Sorry Mac Aqua version requires Tcl/Tk ver 8.4.0 or higher.
+# endif
+#endif /* TOGL_AGL */
+
+#if defined(TOGL_NSOPENGL)
+# if TK_MAJOR_VERSION < 8 || (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 6)
+# error Sorry Mac Cocoa version requires Tcl/Tk ver 8.6.0 or higher.
+# endif
+#endif /* TOGL_NSOPENGL */
+
+#if defined(TOGL_WGL) && defined(_MSC_VER)
+# define snprintf _snprintf
+# pragma warning(disable:4995)
+#endif
+
+/* workaround for bug #123153 in tcl ver8.4a2 (tcl.h) */
+#if defined(Tcl_InitHashTable) && defined(USE_TCL_STUBS)
+# undef Tcl_InitHashTable
+# define Tcl_InitHashTable (tclStubsPtr->tcl_InitHashTable)
+#endif
+#if TK_MAJOR_VERSION > 8 || (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION >= 4)
+# define HAVE_TK_SETCLASSPROCS
+/* pointer to Tk_SetClassProcs function in the stub table */
+
+#if TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 6
+static void (*SetClassProcsPtr)
+ _ANSI_ARGS_((Tk_Window, Tk_ClassProcs *, ClientData));
+#else
+static void (*SetClassProcsPtr)
+ _ANSI_ARGS_((Tk_Window, const Tk_ClassProcs *, ClientData));
+#endif
+#endif
+
+/*
+ * Copy of TkClassProcs declarations from tkInt.h
+ * (this is needed for Tcl ver =< 8.4a3)
+ */
+
+typedef Window (TkClassCreateProc) _ANSI_ARGS_((Tk_Window tkwin,
+ Window parent, ClientData instanceData));
+typedef void (TkClassGeometryProc) _ANSI_ARGS_((ClientData instanceData));
+typedef void (TkClassModalProc) _ANSI_ARGS_((Tk_Window tkwin,
+ XEvent *eventPtr));
+typedef struct TkClassProcs
+{
+ TkClassCreateProc *createProc;
+ TkClassGeometryProc *geometryProc;
+ TkClassModalProc *modalProc;
+} TkClassProcs;
+
+
+/* Defaults */
+#define DEFAULT_WIDTH "400"
+#define DEFAULT_HEIGHT "400"
+#define DEFAULT_IDENT ""
+#define DEFAULT_FONTNAME "Courier"
+#define DEFAULT_TIME "1"
+
+
+#ifdef TOGL_WGL
+/* Maximum size of a logical palette corresponding to a colormap in color index
+ * mode. */
+# define MAX_CI_COLORMAP_SIZE 4096
+# define MAX_CI_COLORMAP_BITS 12
+
+# if TOGL_USE_FONTS != 1
+/*
+ * copy of TkWinColormap from tkWinInt.h
+ */
+
+typedef struct
+{
+ HPALETTE palette; /* Palette handle used when drawing. */
+ UINT size; /* Number of entries in the palette. */
+ int stale; /* 1 if palette needs to be realized, otherwise
+ * 0. If the palette is stale, then an idle
+ * handler is scheduled to realize the palette.
+ */
+ Tcl_HashTable refCounts; /* Hash table of palette entry reference counts
+ * indexed by pixel value. */
+} TkWinColormap;
+# else
+# include
+# endif
+
+static LRESULT(CALLBACK *tkWinChildProc) (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam) = NULL;
+
+# ifndef TK_WIN_CHILD_CLASS_NAME
+# define TK_WIN_CHILD_CLASS_NAME "TkChild"
+# endif
+
+#endif /* TOGL_WGL */
+
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+#define TCL_ERR(interp, string) \
+ do { \
+ Tcl_ResetResult(interp); \
+ Tcl_AppendResult(interp, string, NULL); \
+ return TCL_ERROR; \
+ } while (0)
+
+#define ALL_EVENTS_MASK \
+ (KeyPressMask \
+ |KeyReleaseMask \
+ |ButtonPressMask \
+ |ButtonReleaseMask \
+ |EnterWindowMask \
+ |LeaveWindowMask \
+ |PointerMotionMask \
+ |ExposureMask \
+ |VisibilityChangeMask \
+ |FocusChangeMask \
+ |PropertyChangeMask \
+ |ColormapChangeMask)
+
+/*
+ * The following structure contains pointers to functions used for
+ * processing the custom "-stereo" option. Copied from tkPanedWindow.c.
+ */
+static int SetStereo(ClientData clientData, Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj **value, char *recordPtr,
+ int internalOffset, char *oldInternalPtr, int flags);
+static Tcl_Obj *GetStereo(ClientData clientData, Tk_Window tkwin,
+ char *recordPtr, int internalOffset);
+static void RestoreStereo(ClientData clientData, Tk_Window tkwin,
+ char *internalPtr, char *oldInternalPtr);
+
+static Tk_ObjCustomOption stereoOption = {
+ "stereo", /* name */
+ SetStereo, /* setProc */
+ GetStereo, /* getProc */
+ RestoreStereo, /* restoreProc */
+ NULL, /* freeProc */
+ 0
+};
+
+/*
+ * The following structure contains pointers to functions used for
+ * processing the custom "-pixelformat" option. Copied from tkPanedWindow.c.
+ */
+static int SetWideInt(ClientData clientData, Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj **value, char *recordPtr,
+ int internalOffset, char *oldInternalPtr, int flags);
+static Tcl_Obj *GetWideInt(ClientData clientData, Tk_Window tkwin,
+ char *recordPtr, int internalOffset);
+static void RestoreWideInt(ClientData clientData, Tk_Window tkwin,
+ char *internalPtr, char *oldInternalPtr);
+
+static Tk_ObjCustomOption wideIntOption = {
+ "wide int", /* name */
+ SetWideInt, /* setProc */
+ GetWideInt, /* getProc */
+ RestoreWideInt, /* restoreProc */
+ NULL, /* freeProc */
+ 0
+};
+
+/*
+ * Stuff we initialize on a per package (Togl_Init) basis.
+ * Since Tcl uses one interpreter per thread, any per-thread
+ * data goes here.
+ */
+struct Togl_PackageGlobals
+{
+ Tk_OptionTable optionTable; /* Used to parse options */
+ Togl *toglHead; /* Head of linked list of all Togl widgets */
+ int nextContextTag; /* Used to assign similar context tags */
+};
+typedef struct Togl_PackageGlobals Togl_PackageGlobals;
+
+extern ToglStubs toglStubs; /* should be only non-const global */
+
+#if defined(TOGL_NSOPENGL)
+
+/* Handle window drags between retina and non-retina displays. */
+@interface ToglNSView : NSView {
+ struct Togl *togl;
+}
+- (void) setTogl: (struct Togl*)t;
+- (void) viewDidChangeBackingProperties;
+- (void) magnifyWithEvent: (NSEvent *)event;
+- (void) rotateWithEvent: (NSEvent *)event;
+- (void) scrollWheel: (NSEvent *)event;
+- (void)touchesBeganWithEvent:(NSEvent *)event;
+- (void)touchesMovedWithEvent:(NSEvent *)event;
+- (void)touchesEndedWithEvent:(NSEvent *)event;
+- (void)touchesCancelledWithEvent:(NSEvent *)event;
+- (void)reportEventTouches:(NSEvent *)event;
+
+@end
+
+#endif
+
+struct Togl
+{
+ Togl *Next; /* next in linked list */
+
+#if defined(TOGL_WGL)
+ HGLRC Ctx; /* OpenGL rendering context to be made current */
+ HDC tglGLHdc; /* Device context of device that OpenGL calls
+ * will be drawn on */
+ int CiColormapSize; /* (Maximum) size of colormap in color index
+ * mode */
+#elif defined(TOGL_X11)
+ GLXContext Ctx; /* Normal planes GLX context */
+#elif defined(TOGL_AGL)
+ AGLContext Ctx;
+#elif defined(TOGL_NSOPENGL)
+ NSOpenGLContext *Ctx;
+ ToglNSView *nsview;
+#endif
+ int contextTag; /* all contexts with same tag share display
+ * lists */
+
+ XVisualInfo *VisInfo; /* Visual info of the current */
+
+ Display *display; /* X's token for the window's display. */
+ Tk_Window TkWin; /* Tk window structure */
+ Tcl_Interp *Interp; /* Tcl interpreter */
+ Tcl_Command widgetCmd; /* Token for togl's widget command */
+ Togl_PackageGlobals *tpg; /* Used to access globals */
+#ifndef NO_TK_CURSOR
+ Tk_Cursor Cursor; /* The widget's cursor */
+#endif
+ int Width, Height; /* Dimensions of window */
+ int PixelScale; /* Graphics pixels per Tk pixel. */
+ /* 1 for normal display. */
+ /* 2 for Mac retina display. */
+ int SetGrid; /* positive is grid size for window manager */
+ int TimerInterval; /* Time interval for timer in milliseconds */
+ Tcl_TimerToken timerHandler; /* Token for togl's timer handler */
+ Bool RgbaFlag; /* configuration flags (ala GLX parameters) */
+ int RgbaRed;
+ int RgbaGreen;
+ int RgbaBlue;
+ Bool DoubleFlag;
+ Bool DepthFlag;
+ int DepthSize;
+ Bool AccumFlag;
+ int AccumRed;
+ int AccumGreen;
+ int AccumBlue;
+ int AccumAlpha;
+ Bool AlphaFlag;
+ int AlphaSize;
+ Bool StencilFlag;
+ int StencilSize;
+ Bool PrivateCmapFlag;
+ Bool OverlayFlag;
+ int Stereo;
+ double EyeSeparation;
+ double Convergence;
+ GLuint riStencilBit; /* row interleaved stencil bit */
+ int AuxNumber;
+ Bool Indirect;
+#if defined(TOGL_NSOPENGL)
+ NSOpenGLPixelFormat *PixelFormat;
+#else
+ Tcl_WideInt PixelFormat;
+#endif
+ int SwapInterval;
+ Bool MultisampleFlag;
+ Bool FullscreenFlag;
+ Bool PbufferFlag;
+ Bool LargestPbufferFlag;
+#if defined(TOGL_X11)
+ GLXFBConfig fbcfg; /* cache FBConfig for pbuffer creation */
+ GLXPbuffer pbuf;
+#elif defined(TOGL_WGL)
+ HPBUFFERARB pbuf;
+ int pbufferLost;
+#elif defined(TOGL_AGL)
+ AGLPbuffer pbuf;
+#elif defined(TOGL_NSOPENGL)
+ NSOpenGLPixelBuffer *pbuf;
+#endif
+ const char *ShareList; /* name (ident) of Togl to share dlists with */
+ const char *ShareContext; /* name (ident) to share OpenGL context with */
+
+ const char *Ident; /* User's identification string */
+ ClientData Client_Data; /* Pointer to user data */
+
+ Bool UpdatePending; /* Should normal planes be redrawn? */
+
+ Tcl_Obj *CreateProc; /* Callback when widget is realized */
+ Tcl_Obj *DisplayProc; /* Callback when widget is redrawn */
+ Tcl_Obj *ReshapeProc; /* Callback when window size changes */
+ Tcl_Obj *DestroyProc; /* Callback when widget is destroyed */
+ Tcl_Obj *TimerProc; /* Callback when widget is idle */
+ Tcl_Obj *MagnifyProc; /* Callback for track pad pinch gesture */
+ Tcl_Obj *RotateProc; /* Callback for track pad rotate gesture */
+ Tcl_Obj *ScrollProc; /* Callback for track pad scroll gesture */
+ Tcl_Obj *ScrollWheelProc; /* Callback for mouse scroll wheel, not trackpad */
+ Tcl_Obj *TouchesProc; /* Callback for track pad touches */
+
+ /* Overlay stuff */
+#if defined(TOGL_X11)
+ GLXContext OverlayCtx; /* Overlay planes OpenGL context */
+#elif defined(TOGL_WGL)
+ HGLRC tglGLOverlayHglrc;
+#endif
+
+ Window OverlayWindow; /* The overlay window, or 0 */
+ Tcl_Obj *OverlayDisplayProc; /* Overlay redraw proc */
+ Bool OverlayUpdatePending; /* Should overlay be redrawn? */
+ Colormap OverlayCmap; /* colormap for overlay is created */
+ int OverlayTransparentPixel; /* transparent pixel */
+ Bool OverlayIsMapped;
+
+ GLfloat *RedMap; /* Index2RGB Maps for Color index modes */
+ GLfloat *GreenMap;
+ GLfloat *BlueMap;
+ GLint MapSize; /* = Number of indices in our Togl */
+ int currentStereoBuffer;
+#ifdef HAVE_AUTOSTEREO
+ int as_initialized; /* for autostereo package */
+ ASHandle ash; /* for autostereo package */
+#endif
+ int badWindow; /* true when Togl_MakeWindow fails or should
+ * create a dummy window */
+};
+
+int Togl_CallCallback(Togl *togl, Tcl_Obj *cmd);
+static int Togl_CallCallback_P(Togl *togl, Tcl_Obj *cmd, double *params, int nparams);
+
+#if defined(TOGL_NSOPENGL)
+
+static int viewPixelScale(NSView *nsview);
+@implementation ToglNSView
+
+- (void) setTogl: (struct Togl*)t
+{
+ togl = t;
+}
+
+- (void) viewDidChangeBackingProperties
+{
+ [super viewDidChangeBackingProperties];
+ if (togl && togl->ReshapeProc) {
+ int pscale = viewPixelScale(self);
+ if (pscale != togl->PixelScale) {
+ togl->PixelScale = pscale;
+ if (togl->ReshapeProc)
+ (void) Togl_CallCallback(togl, togl->ReshapeProc);
+ Togl_PostRedisplay(togl);
+ }
+ }
+}
+
+- (void) magnifyWithEvent: (NSEvent *)event
+{
+ if (togl && togl->MagnifyProc) {
+ double mag = [event magnification] + 1.0;
+ (void) Togl_CallCallback_P(togl, togl->MagnifyProc, &mag, 1);
+ }
+}
+
+- (void) rotateWithEvent: (NSEvent *)event
+{
+ if (togl && togl->RotateProc) {
+ double deg = [event rotation];
+ (void) Togl_CallCallback_P(togl, togl->RotateProc, °, 1);
+ }
+}
+
+- (void) scrollWheel: (NSEvent *)event
+{
+ if (togl && (togl->ScrollProc || togl->ScrollWheelProc)) {
+ float dx = [event deltaX], dy = [event deltaY];
+ if (dx != 0 || dy != 0) {
+ // float track_pad = ((([event phase] == NSEventPhaseNone) &&
+ // ([event momentumPhase] == NSEventPhaseNone)) ? 0 : 1);
+ float track_pad = ([event subtype] == NSMouseEventSubtype ? 0 : 1);
+ double args[3] = {dx, dy, track_pad};
+ if (togl->ScrollProc)
+ (void) Togl_CallCallback_P(togl, togl->ScrollProc, args, 3);
+ if (togl->ScrollWheelProc && !track_pad)
+ (void) Togl_CallCallback_P(togl, togl->ScrollWheelProc, args+1, 1);
+ }
+ }
+}
+
+- (void)touchesBeganWithEvent:(NSEvent *)event
+{ NSWindow *win = [self window];
+ [win makeKeyWindow];
+ [win makeMainWindow];
+ [self reportEventTouches:event];
+ }
+- (void)touchesMovedWithEvent:(NSEvent *)event
+{ [self reportEventTouches:event]; }
+- (void)touchesEndedWithEvent:(NSEvent *)event
+{ [self reportEventTouches:event]; }
+- (void)touchesCancelledWithEvent:(NSEvent *)event;
+{ [self reportEventTouches:event]; }
+- (void)reportEventTouches: (NSEvent *)event
+{
+ if (togl && togl->TouchesProc) {
+ NSSet *touches = [event touchesMatchingPhase:NSTouchPhaseTouching inView:self];
+ int n = touches.count, i;
+ double *id_xy = NULL;
+ if (n >= 0) {
+ id_xy = (double *)malloc(3*n*sizeof(double));
+ NSArray *array = [touches allObjects];
+ for (i = 0 ; i < n ; ++i) {
+ NSTouch *t = [array objectAtIndex:i];
+ id_xy[3*i] = (long)t.identity;
+ id_xy[3*i+1] = t.normalizedPosition.x * t.deviceSize.width;
+ id_xy[3*i+2] = t.normalizedPosition.y * t.deviceSize.height;
+ }
+ (void) Togl_CallCallback_P(togl, togl->TouchesProc, id_xy, 3*n);
+ if (id_xy)
+ free(id_xy);
+ }
+ }
+}
+
+@end
+
+#endif
+
+/*
+ * Prototypes for functions local to this file
+ */
+static int Togl_ObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const *objv);
+static void Togl_ObjCmdDelete(ClientData clientData);
+static void Togl_EventProc(ClientData clientData, XEvent *eventPtr);
+static void Togl_RedisplayProc(ClientData clientData, XEvent *eventPtr);
+static Window Togl_MakeWindow(Tk_Window, Window, ClientData);
+static void Togl_WorldChanged(ClientData);
+static void Togl_SetViewPort(const struct Togl *);
+
+#ifdef MESA_COLOR_HACK
+static int get_free_color_cells(Display *display, int screen,
+ Colormap colormap);
+static void free_default_color_cells(Display *display, Colormap colormap);
+#endif
+static void ToglCmdDeletedProc(ClientData);
+
+#if defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+static void SetMacBufRect(Togl *togl);
+#endif
+
+#if defined(TOGL_WGL)
+# include "toglWGL.c"
+#elif defined(TOGL_AGL)
+# include "toglAGL.c"
+#elif defined(TOGL_NSOPENGL)
+# include "toglNSOpenGL.c"
+#elif defined(TOGL_X11)
+# include "toglGLX.c"
+#endif
+
+
+/*
+ * Setup Togl widget configuration options:
+ */
+
+#define GEOMETRY_MASK 0x1 /* widget geometry */
+#define FORMAT_MASK 0x2 /* pixel format */
+#define CURSOR_MASK 0x4
+#define TIMER_MASK 0x8
+#define OVERLAY_MASK 0x10
+#define SWAP_MASK 0x20
+#define STEREO_MASK 0x40
+#define STEREO_FORMAT_MASK 0x80
+
+static Tk_OptionSpec optionSpecs[] = {
+ {TK_OPTION_PIXELS, TCL_STUPID "-height", "height", "Height",
+ DEFAULT_HEIGHT, -1, Tk_Offset(Togl, Height), 0, NULL,
+ GEOMETRY_MASK},
+ {TK_OPTION_PIXELS, TCL_STUPID "-width", "width", "Width",
+ DEFAULT_WIDTH, -1, Tk_Offset(Togl, Width), 0, NULL,
+ GEOMETRY_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-pixelscale", "pixelscale", "PixelScale",
+ "1", -1, Tk_Offset(Togl, PixelScale), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-rgba", "rgba", "Rgba",
+ "true", -1, Tk_Offset(Togl, RgbaFlag), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-redsize", "redsize", "RedSize",
+ "1", -1, Tk_Offset(Togl, RgbaRed), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-greensize", "greensize", "GreenSize",
+ "1", -1, Tk_Offset(Togl, RgbaGreen), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-bluesize", "bluesize", "BlueSize",
+ "1", -1, Tk_Offset(Togl, RgbaBlue), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-double", "double", "Double",
+ "false", -1, Tk_Offset(Togl, DoubleFlag), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-depth", "depth", "Depth",
+ "false", -1, Tk_Offset(Togl, DepthFlag), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-depthsize", "depthsize", "DepthSize",
+ "1", -1, Tk_Offset(Togl, DepthSize), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-accum", "accum", "Accum",
+ "false", -1, Tk_Offset(Togl, AccumFlag), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-accumredsize", "accumredsize", "AccumRedSize",
+ "1", -1, Tk_Offset(Togl, AccumRed), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-accumgreensize", "accumgreensize",
+ "AccumGreenSize",
+ "1", -1, Tk_Offset(Togl, AccumGreen), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-accumbluesize", "accumbluesize",
+ "AccumBlueSize",
+ "1", -1, Tk_Offset(Togl, AccumBlue), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-accumalphasize", "accumalphasize",
+ "AccumAlphaSize",
+ "1", -1, Tk_Offset(Togl, AccumAlpha), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-alpha", "alpha", "Alpha",
+ "false", -1, Tk_Offset(Togl, AlphaFlag), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-alphasize", "alphasize", "AlphaSize",
+ "1", -1, Tk_Offset(Togl, AlphaSize), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-stencil", "stencil", "Stencil",
+ "false", -1, Tk_Offset(Togl, StencilFlag), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-stencilsize", "stencilsize", "StencilSize",
+ "1", -1, Tk_Offset(Togl, StencilSize), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-auxbuffers", "auxbuffers", "AuxBuffers",
+ "0", -1, Tk_Offset(Togl, AuxNumber), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-privatecmap", "privateCmap", "PrivateCmap",
+ "false", -1, Tk_Offset(Togl, PrivateCmapFlag), 0, NULL,
+ FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-overlay", "overlay", "Overlay",
+ "false", -1, Tk_Offset(Togl, OverlayFlag), 0, NULL, OVERLAY_MASK},
+ {TK_OPTION_CUSTOM, TCL_STUPID "-stereo", "stereo", "Stereo",
+ "", -1, Tk_Offset(Togl, Stereo), 0,
+ (ClientData) &stereoOption, STEREO_FORMAT_MASK},
+ {TK_OPTION_DOUBLE, TCL_STUPID "-eyeseparation", "eyeseparation",
+ "EyeSeparation",
+ "2.0", -1, Tk_Offset(Togl, EyeSeparation), 0, NULL, STEREO_MASK},
+ {TK_OPTION_DOUBLE, TCL_STUPID "-convergence", "convergence", "Convergence",
+ "35.0", -1, Tk_Offset(Togl, Convergence), 0, NULL, STEREO_MASK},
+#ifndef NO_TK_CURSOR
+ {TK_OPTION_CURSOR, TCL_STUPID "-cursor", "cursor", "Cursor",
+ "", -1, Tk_Offset(Togl, Cursor), TK_OPTION_NULL_OK, NULL,
+ CURSOR_MASK},
+#endif
+ {TK_OPTION_INT, TCL_STUPID "-setgrid", "setGrid", "SetGrid",
+ "0", -1, Tk_Offset(Togl, SetGrid), 0, NULL, GEOMETRY_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-time", "time", "Time",
+ DEFAULT_TIME, -1, Tk_Offset(Togl, TimerInterval), 0, NULL,
+ TIMER_MASK},
+ {TK_OPTION_STRING, TCL_STUPID "-sharelist", "sharelist", "ShareList",
+ NULL, -1, Tk_Offset(Togl, ShareList), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_STRING, TCL_STUPID "-sharecontext", "sharecontext",
+ "ShareContext", NULL,
+ -1, Tk_Offset(Togl, ShareContext), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_STRING, TCL_STUPID "-ident", "ident", "Ident",
+ DEFAULT_IDENT, -1, Tk_Offset(Togl, Ident), 0, NULL, 0},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-indirect", "indirect", "Indirect",
+ "false", -1, Tk_Offset(Togl, Indirect), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_CUSTOM, TCL_STUPID "-pixelformat", "pixelFormat", "PixelFormat",
+ "0", -1, Tk_Offset(Togl, PixelFormat), 0,
+ (ClientData) &wideIntOption, FORMAT_MASK},
+ {TK_OPTION_INT, TCL_STUPID "-swapinterval", "swapInterval", "SwapInterval",
+ "1", -1, Tk_Offset(Togl, SwapInterval), 0, NULL, SWAP_MASK},
+#if 0
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-fullscreen", "fullscreen", "Fullscreen",
+ "false", -1, Tk_Offset(Togl, FullscreenFlag), 0, NULL,
+ GEOMETRY_MASK|FORMAT_MASK},
+#endif
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-multisample", "multisample", "Multisample",
+ "false", -1, Tk_Offset(Togl, MultisampleFlag), 0, NULL,
+ FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-pbuffer", "pbuffer", "Pbuffer",
+ "false", -1, Tk_Offset(Togl, PbufferFlag), 0, NULL, FORMAT_MASK},
+ {TK_OPTION_BOOLEAN, TCL_STUPID "-largestpbuffer", "largestpbuffer",
+ "LargestPbuffer",
+ "false", -1, Tk_Offset(Togl, LargestPbufferFlag), 0, NULL, 0},
+ {TK_OPTION_STRING, TCL_STUPID "-createcommand", "createCommand",
+ "CallbackCommand", NULL,
+ Tk_Offset(Togl, CreateProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, TCL_STUPID "-create", NULL, NULL,
+ NULL, -1, -1, 0, (ClientData) "-createcommand", 0},
+ {TK_OPTION_STRING, TCL_STUPID "-displaycommand", "displayCommand",
+ "CallbackCommand", NULL,
+ Tk_Offset(Togl, DisplayProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, TCL_STUPID "-display", NULL, NULL,
+ NULL, -1, -1, 0, (ClientData) "-displaycommand", 0},
+ {TK_OPTION_STRING, TCL_STUPID "-reshapecommand", "reshapeCommand",
+ "CallbackCommand", NULL,
+ Tk_Offset(Togl, ReshapeProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, TCL_STUPID "-reshape", NULL, NULL,
+ NULL, -1, -1, 0, (ClientData) "-reshapecommand", 0},
+ {TK_OPTION_STRING, TCL_STUPID "-destroycommand", "destroyCommand",
+ "CallbackCommand", NULL,
+ Tk_Offset(Togl, DestroyProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, TCL_STUPID "-destroy", NULL, NULL,
+ NULL, -1, -1, 0, (ClientData) "-destroycommand", 0},
+ {TK_OPTION_STRING, TCL_STUPID "-timercommand", "timerCommand",
+ "CallabckCommand", NULL,
+ Tk_Offset(Togl, TimerProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, TCL_STUPID "-timer", NULL, NULL,
+ NULL, -1, -1, 0, (ClientData) "-timercommand", 0},
+ {TK_OPTION_STRING, TCL_STUPID "-overlaydisplaycommand",
+ "overlaydisplayCommand", "CallbackCommand", NULL,
+ Tk_Offset(Togl, OverlayDisplayProc), -1,
+ TK_OPTION_NULL_OK, NULL, OVERLAY_MASK},
+ {TK_OPTION_SYNONYM, TCL_STUPID "-overlaydisplay", NULL, NULL,
+ NULL, -1, -1, 0, (ClientData) "-overlaydisplaycommand", 0},
+ {TK_OPTION_STRING, TCL_STUPID "-magnifycommand", "magnifyCommand",
+ "CallbackCommand", NULL,
+ Tk_Offset(Togl, MagnifyProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_STRING, TCL_STUPID "-rotatecommand", "rotateCommand",
+ "CallbackCommand", NULL,
+ Tk_Offset(Togl, RotateProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_STRING, TCL_STUPID "-scrollcommand", "scrollCommand",
+ "CallbackCommand", NULL,
+ Tk_Offset(Togl, ScrollProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_STRING, TCL_STUPID "-scrollwheelcommand", "scrollWheelCommand",
+ "CallbackCommand", NULL,
+ Tk_Offset(Togl, ScrollWheelProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_STRING, TCL_STUPID "-touchescommand", "touchesCommand",
+ "CallbackCommand", NULL,
+ Tk_Offset(Togl, TouchesProc), -1, TK_OPTION_NULL_OK, NULL, 0},
+
+ /* Tcl3D backwards compatibility */
+ {TK_OPTION_SYNONYM, TCL_STUPID "-createproc", NULL, NULL,
+ NULL, -1, -1, 0, (ClientData) "-createcommand", 0},
+ {TK_OPTION_SYNONYM, TCL_STUPID "-displayproc", NULL, NULL,
+ NULL, -1, -1, 0, (ClientData) "-displaycommand", 0},
+ {TK_OPTION_SYNONYM, TCL_STUPID "-reshapeproc", NULL, NULL,
+ NULL, -1, -1, 0, (ClientData) "-reshapecommand", 0},
+ /* end Tcl3D compatibility */
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, -1, 0, NULL, 0}
+};
+
+/*
+ * Add given togl widget to linked list.
+ */
+static void
+AddToList(Togl *t)
+{
+ t->Next = t->tpg->toglHead;
+ t->tpg->toglHead = t;
+}
+
+/*
+ * Remove given togl widget from linked list.
+ */
+static void
+RemoveFromList(Togl *t)
+{
+ Togl *prev;
+ Togl *cur;
+
+ for (cur = t->tpg->toglHead, prev = NULL; cur; prev = cur, cur = cur->Next) {
+ if (t != cur)
+ continue;
+ if (prev) {
+ prev->Next = cur->Next;
+ } else {
+ t->tpg->toglHead = cur->Next;
+ }
+ break;
+ }
+ if (cur)
+ cur->Next = NULL;
+}
+
+/*
+ * Return pointer to togl widget given a user identifier string.
+ */
+static Togl *
+FindTogl(Togl *togl, const char *ident)
+{
+ Togl *t;
+
+ if (ident[0] != '.') {
+ for (t = togl->tpg->toglHead; t; t = t->Next) {
+ if (strcmp(t->Ident, ident) == 0)
+ break;
+ }
+ } else {
+ for (t = togl->tpg->toglHead; t; t = t->Next) {
+ const char *pathname = Tk_PathName(t->TkWin);
+
+ if (strcmp(pathname, ident) == 0)
+ break;
+ }
+ }
+ return t;
+}
+
+
+/*
+ * Return pointer to another togl widget with same OpenGL context.
+ */
+static Togl *
+FindToglWithSameContext(const Togl *togl)
+{
+ Togl *t;
+
+ for (t = togl->tpg->toglHead; t != NULL; t = t->Next) {
+ if (t == togl)
+ continue;
+ if (t->Ctx == togl->Ctx) {
+ return t;
+ }
+ }
+ return NULL;
+}
+
+#if TOGL_USE_OVERLAY
+/*
+ * Return pointer to another togl widget with same OpenGL overlay context.
+ */
+static Togl *
+FindToglWithSameOverlayContext(const Togl *togl)
+{
+ Togl *t;
+
+ for (t = togl->tpg->toglHead; t != NULL; t = t->Next) {
+ if (t == togl)
+ continue;
+# if defined(TOGL_X11)
+ if (t->OverlayCtx == togl->OverlayCtx)
+# elif defined(TOGL_WGL)
+ if (t->tglGLOverlayHglrc == togl->tglGLOverlayHglrc)
+# endif
+ {
+ return t;
+ }
+ }
+ return NULL;
+}
+#endif
+
+#if defined(TOGL_X11)
+/*
+ * Return an X colormap to use for OpenGL RGB-mode rendering.
+ * Input: dpy - the X display
+ * scrnum - the X screen number
+ * visinfo - the XVisualInfo as returned by glXChooseVisual()
+ * Return: an X Colormap or 0 if there's a _serious_ error.
+ */
+static Colormap
+get_rgb_colormap(Display *dpy,
+ int scrnum, const XVisualInfo *visinfo, Tk_Window tkwin)
+{
+ Atom hp_cr_maps;
+ Status status;
+ int numCmaps;
+ int i;
+ XStandardColormap *standardCmaps;
+ Window root = XRootWindow(dpy, scrnum);
+ Bool using_mesa;
+
+ /*
+ * First check if visinfo's visual matches the default/root visual.
+ */
+ if (visinfo->visual == Tk_Visual(tkwin)) {
+ /* use the default/root colormap */
+ Colormap cmap;
+
+ cmap = Tk_Colormap(tkwin);
+# ifdef MESA_COLOR_HACK
+ (void) get_free_color_cells(dpy, scrnum, cmap);
+# endif
+ return cmap;
+ }
+
+ /*
+ * Check if we're using Mesa.
+ */
+ if (strstr(glXQueryServerString(dpy, scrnum, GLX_VERSION), "Mesa")) {
+ using_mesa = True;
+ } else {
+ using_mesa = False;
+ }
+
+ /*
+ * Next, if we're using Mesa and displaying on an HP with the "Color
+ * Recovery" feature and the visual is 8-bit TrueColor, search for a
+ * special colormap initialized for dithering. Mesa will know how to
+ * dither using this colormap.
+ */
+ if (using_mesa) {
+ hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
+ if (hp_cr_maps
+# ifdef __cplusplus
+ && visinfo->visual->c_class == TrueColor
+# else
+ && visinfo->visual->class == TrueColor
+# endif
+ && visinfo->depth == 8) {
+ status = XGetRGBColormaps(dpy, root, &standardCmaps,
+ &numCmaps, hp_cr_maps);
+ if (status) {
+ for (i = 0; i < numCmaps; i++) {
+ if (standardCmaps[i].visualid == visinfo->visual->visualid) {
+ Colormap cmap = standardCmaps[i].colormap;
+
+ (void) XFree(standardCmaps);
+ return cmap;
+ }
+ }
+ (void) XFree(standardCmaps);
+ }
+ }
+ }
+
+ /*
+ * Next, try to find a standard X colormap.
+ */
+# if !HP && !SUN
+# ifndef SOLARIS_BUG
+ status = XmuLookupStandardColormap(dpy, visinfo->screen,
+ visinfo->visualid, visinfo->depth, XA_RGB_DEFAULT_MAP,
+ /* replace */ False, /* retain */ True);
+ if (status == 1) {
+ status = XGetRGBColormaps(dpy, root, &standardCmaps,
+ &numCmaps, XA_RGB_DEFAULT_MAP);
+ if (status == 1) {
+ for (i = 0; i < numCmaps; i++) {
+ if (standardCmaps[i].visualid == visinfo->visualid) {
+ Colormap cmap = standardCmaps[i].colormap;
+
+ (void) XFree(standardCmaps);
+ return cmap;
+ }
+ }
+ (void) XFree(standardCmaps);
+ }
+ }
+# endif
+# endif
+
+ /*
+ * If we get here, give up and just allocate a new colormap.
+ */
+ return XCreateColormap(dpy, root, visinfo->visual, AllocNone);
+}
+#elif defined(TOGL_WGL)
+
+/* Code to create RGB palette is taken from the GENGL sample program of Win32
+ * SDK */
+
+static const unsigned char threeto8[8] = {
+ 0, 0111 >> 1, 0222 >> 1, 0333 >> 1, 0444 >> 1, 0555 >> 1, 0666 >> 1, 0377
+};
+
+static const unsigned char twoto8[4] = {
+ 0, 0x55, 0xaa, 0xff
+};
+
+static const unsigned char oneto8[2] = {
+ 0, 255
+};
+
+static const int defaultOverride[13] = {
+ 0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
+};
+
+static const PALETTEENTRY defaultPalEntry[20] = {
+ {0, 0, 0, 0},
+ {0x80, 0, 0, 0},
+ {0, 0x80, 0, 0},
+ {0x80, 0x80, 0, 0},
+ {0, 0, 0x80, 0},
+ {0x80, 0, 0x80, 0},
+ {0, 0x80, 0x80, 0},
+ {0xC0, 0xC0, 0xC0, 0},
+
+ {192, 220, 192, 0},
+ {166, 202, 240, 0},
+ {255, 251, 240, 0},
+ {160, 160, 164, 0},
+
+ {0x80, 0x80, 0x80, 0},
+ {0xFF, 0, 0, 0},
+ {0, 0xFF, 0, 0},
+ {0xFF, 0xFF, 0, 0},
+ {0, 0, 0xFF, 0},
+ {0xFF, 0, 0xFF, 0},
+ {0, 0xFF, 0xFF, 0},
+ {0xFF, 0xFF, 0xFF, 0}
+};
+
+static unsigned char
+ComponentFromIndex(int i, UINT nbits, UINT shift)
+{
+ unsigned char val;
+
+ val = (unsigned char) (i >> shift);
+ switch (nbits) {
+
+ case 1:
+ val &= 0x1;
+ return oneto8[val];
+
+ case 2:
+ val &= 0x3;
+ return twoto8[val];
+
+ case 3:
+ val &= 0x7;
+ return threeto8[val];
+
+ default:
+ return 0;
+ }
+}
+
+static Colormap
+Win32CreateRgbColormap(PIXELFORMATDESCRIPTOR pfd)
+{
+ TkWinColormap *cmap = (TkWinColormap *) ckalloc(sizeof (TkWinColormap));
+ LOGPALETTE *pPal;
+ int n, i;
+
+ n = 1 << pfd.cColorBits;
+ pPal = (PLOGPALETTE) LocalAlloc(LMEM_FIXED, sizeof (LOGPALETTE)
+ + n * sizeof (PALETTEENTRY));
+ pPal->palVersion = 0x300;
+ pPal->palNumEntries = n;
+ for (i = 0; i < n; i++) {
+ pPal->palPalEntry[i].peRed =
+ ComponentFromIndex(i, pfd.cRedBits, pfd.cRedShift);
+ pPal->palPalEntry[i].peGreen =
+ ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenShift);
+ pPal->palPalEntry[i].peBlue =
+ ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShift);
+ pPal->palPalEntry[i].peFlags = 0;
+ }
+
+ /* fix up the palette to include the default GDI palette */
+ if ((pfd.cColorBits == 8)
+ && (pfd.cRedBits == 3) && (pfd.cRedShift == 0)
+ && (pfd.cGreenBits == 3) && (pfd.cGreenShift == 3)
+ && (pfd.cBlueBits == 2) && (pfd.cBlueShift == 6)) {
+ for (i = 1; i <= 12; i++)
+ pPal->palPalEntry[defaultOverride[i]] = defaultPalEntry[i];
+ }
+
+ cmap->palette = CreatePalette(pPal);
+ LocalFree(pPal);
+ cmap->size = n;
+ cmap->stale = 0;
+
+ /* Since this is a private colormap of a fix size, we do not need a valid
+ * hash table, but a dummy one */
+
+ Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS);
+ return (Colormap) cmap;
+}
+
+static Colormap
+Win32CreateCiColormap(Togl *togl)
+{
+ /* Create a colormap with size of togl->CiColormapSize and set all entries
+ * to black */
+
+ LOGPALETTE logPalette;
+ TkWinColormap *cmap = (TkWinColormap *) ckalloc(sizeof (TkWinColormap));
+
+ logPalette.palVersion = 0x300;
+ logPalette.palNumEntries = 1;
+ logPalette.palPalEntry[0].peRed = 0;
+ logPalette.palPalEntry[0].peGreen = 0;
+ logPalette.palPalEntry[0].peBlue = 0;
+ logPalette.palPalEntry[0].peFlags = 0;
+
+ cmap->palette = CreatePalette(&logPalette);
+ cmap->size = togl->CiColormapSize;
+ ResizePalette(cmap->palette, cmap->size); /* sets new entries to black */
+ cmap->stale = 0;
+
+ /* Since this is a private colormap of a fix size, we do not need a valid
+ * hash table, but a dummy one */
+
+ Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS);
+ return (Colormap) cmap;
+}
+
+/* ErrorExit is from */
+static void
+ErrorExit(LPTSTR lpszFunction)
+{
+ /* Retrieve the system error message for the last-error code */
+ LPTSTR lpMsgBuf;
+ LPTSTR lpDisplayBuf;
+ DWORD err = GetLastError();
+
+ if (err == 0) {
+ /* The function said it failed, but GetLastError says it didn't, so
+ * pretend it didn't. */
+ return;
+ }
+
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf, 0, NULL);
+
+ /* Display the error message and exit the process */
+
+ lpDisplayBuf = (LPTSTR) LocalAlloc(LMEM_ZEROINIT,
+ (lstrlen(lpMsgBuf) + lstrlen(lpszFunction) + 40) * sizeof (TCHAR));
+ StringCchPrintf(lpDisplayBuf, LocalSize(lpDisplayBuf),
+ TEXT("%s failed with error %ld: %s"), lpszFunction, err, lpMsgBuf);
+ MessageBox(NULL, lpDisplayBuf, TEXT("Error"), MB_OK);
+
+ LocalFree(lpMsgBuf);
+ LocalFree(lpDisplayBuf);
+ ExitProcess(err);
+}
+#endif
+
+/*
+ * Togl_Init
+ *
+ * Called upon system startup to create togl command.
+ */
+int
+Togl_Init(Tcl_Interp *interp)
+{
+ int major, minor, patchLevel, releaseType;
+
+#ifdef USE_TCL_STUBS
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
+ return TCL_ERROR;
+ }
+#endif
+#ifdef USE_TK_STUBS
+ if (Tk_InitStubs(interp, TCL_STUPID "8.1", 0) == NULL) {
+ return TCL_ERROR;
+ }
+#endif
+
+ Tcl_GetVersion(&major, &minor, &patchLevel, &releaseType);
+#ifdef HAVE_TK_SETCLASSPROCS
+ if (major > 8
+ || (major == 8
+ && (minor > 4
+ || (minor == 4 && (releaseType > 0
+ || patchLevel >= 2))))) {
+# ifdef USE_TK_STUBS
+ SetClassProcsPtr = tkStubsPtr->tk_SetClassProcs;
+# else
+ SetClassProcsPtr = Tk_SetClassProcs;
+# endif
+ } else {
+ SetClassProcsPtr = NULL;
+ }
+#else
+ if (major > 8
+ || (major == 8
+ && (minor > 4
+ || (minor == 4 && (releaseType > 0
+ || patchLevel >= 2))))) {
+ TCL_ERR(interp,
+ "Sorry, this instance of Togl was not compiled to work with Tcl/Tk 8.4a2 or higher.");
+ }
+#endif
+
+ if (Tcl_CreateObjCommand(interp, "togl", Togl_ObjCmd, NULL,
+ Togl_ObjCmdDelete) == NULL) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_PkgProvideEx(interp, "Togl", TOGL_VERSION, &toglStubs) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ return TCL_OK;
+}
+
+
+/*
+ * Togl_CallCallback
+ *
+ * Call command with togl widget as only argument
+ */
+
+int
+Togl_CallCallback(Togl *togl, Tcl_Obj *cmd)
+{
+ int result;
+ Tcl_Obj *objv[3];
+
+ if (cmd == NULL || togl->widgetCmd == NULL)
+ return TCL_OK;
+
+ objv[0] = cmd;
+ Tcl_IncrRefCount(objv[0]);
+ objv[1] =
+ Tcl_NewStringObj(Tcl_GetCommandName(togl->Interp, togl->widgetCmd),
+ -1);
+ Tcl_IncrRefCount(objv[1]);
+ objv[2] = NULL;
+ result = Tcl_EvalObjv(togl->Interp, 2, objv, TCL_EVAL_GLOBAL);
+ Tcl_DecrRefCount(objv[1]);
+ Tcl_DecrRefCount(objv[0]);
+ if (result != TCL_OK)
+ Tcl_BackgroundError(togl->Interp);
+ return result;
+}
+
+static int
+Togl_CallCallback_P(Togl *togl, Tcl_Obj *cmd, double *params, int nparams)
+{
+ int result, i;
+ Tcl_Obj **objv = (Tcl_Obj **)malloc((3+nparams)*sizeof(Tcl_Obj *));
+
+ if (cmd == NULL || togl->widgetCmd == NULL)
+ return TCL_OK;
+
+ objv[0] = cmd;
+ Tcl_IncrRefCount(objv[0]);
+ objv[1] = Tcl_NewStringObj(Tcl_GetCommandName(togl->Interp, togl->widgetCmd), -1);
+ Tcl_IncrRefCount(objv[1]);
+ for (i = 0 ; i < nparams ; ++i) {
+ objv[2+i] = Tcl_NewDoubleObj(params[i]);
+ Tcl_IncrRefCount(objv[2+i]);
+ }
+ objv[2+nparams] = NULL;
+ result = Tcl_EvalObjv(togl->Interp, 2+nparams, objv, TCL_EVAL_GLOBAL);
+ for (i = 1+nparams ; i >= 0 ; --i)
+ Tcl_DecrRefCount(objv[i]);
+ free(objv);
+ if (result != TCL_OK)
+ Tcl_BackgroundError(togl->Interp);
+ return result;
+}
+
+
+/*
+ * Togl_Timer
+ *
+ * Gets called from Tk_CreateTimerHandler.
+ */
+static void
+Togl_Timer(ClientData clientData)
+{
+ Togl *togl = (Togl *) clientData;
+
+ if (togl->TimerProc) {
+ if (Togl_CallCallback(togl, togl->TimerProc) != TCL_OK) {
+ togl->timerHandler = NULL;
+ return;
+ }
+ /*
+ * Re-register this callback since Tcl/Tk timers are "one-shot".
+ * That is, after the timer callback is called it not normally
+ * called again. That's not the behavior we want for Togl.
+ */
+ togl->timerHandler =
+ Tcl_CreateTimerHandler(togl->TimerInterval, Togl_Timer,
+ (ClientData) togl);
+ }
+}
+
+
+/*
+ * Togl_MakeCurrent
+ *
+ * Bind the OpenGL rendering context to the specified
+ * Togl widget. If given a NULL argument, then the
+ * OpenGL context is released without assigning a new one.
+ */
+void
+Togl_MakeCurrent(const Togl *togl)
+{
+#if defined(TOGL_WGL)
+ int res = TRUE;
+
+ if (togl == NULL) {
+ HDC hdc = wglGetCurrentDC();
+
+ if (hdc != NULL)
+ res = wglMakeCurrent(hdc, NULL);
+ } else {
+ if (togl->pbufferLost) {
+ Bool keepContext = FindToglWithSameContext(togl) != NULL;
+ Togl *t = (Togl *) togl; /* conceptually const */
+
+ if (!keepContext) {
+ wglDeleteContext(t->Ctx);
+ }
+ togl_destroyPbuffer(t);
+ t->pbuf = togl_createPbuffer(t);
+ if (!keepContext) {
+ t->Ctx = wglCreateContext(t->tglGLHdc);
+ }
+ }
+ res = wglMakeCurrent(togl->tglGLHdc, togl->Ctx);
+ }
+ if (!res) {
+ ErrorExit(TEXT("wglMakeCurrent"));
+ }
+#elif defined(TOGL_X11)
+ Display *display = togl ? togl->display : glXGetCurrentDisplay();
+
+ if (display) {
+ GLXDrawable drawable;
+
+ if (!togl)
+ drawable = None;
+ else if (togl->PbufferFlag)
+ drawable = togl->pbuf;
+ else if (togl->TkWin)
+ drawable = Tk_WindowId(togl->TkWin);
+ else
+ drawable = None;
+ (void) glXMakeCurrent(display, drawable, drawable ? togl->Ctx : NULL);
+ }
+#elif defined(TOGL_AGL)
+ if (togl == NULL || togl->Ctx == NULL) {
+ (void) aglSetCurrentContext(NULL);
+ } else {
+ (void) aglSetCurrentContext(togl->Ctx);
+ if (FindToglWithSameContext(togl) != NULL) {
+ if (!togl->PbufferFlag) {
+ AGLDrawable d = Togl_MacOSXGetDrawablePort(togl);
+
+ aglSetDrawable(togl->Ctx, d);
+ } else {
+ GLint virtualScreen = aglGetVirtualScreen(togl->Ctx);
+
+ aglSetPBuffer(togl->Ctx, togl->pbuf, 0, 0, virtualScreen);
+ }
+ }
+ }
+#elif defined(TOGL_NSOPENGL)
+ if (togl != NULL && togl->Ctx != NULL) {
+ [togl->Ctx makeCurrentContext];
+ if (FindToglWithSameContext(togl) != NULL) {
+ if (!togl->PbufferFlag) {
+ [togl->Ctx setView:togl->nsview];
+ } else {
+ GLint virtualScreen = [togl->Ctx currentVirtualScreen];
+ [togl->Ctx setPixelBuffer:togl->pbuf cubeMapFace:0
+ mipMapLevel:0 currentVirtualScreen:virtualScreen];
+ }
+ }
+ }
+#endif
+}
+
+/*
+ * Togl_TakePhoto
+ *
+ * Take a photo image of the current OpenGL window. May have problems
+ * if window is partially obscured, either by other windows or by the
+ * edges of the display.
+ */
+int
+Togl_TakePhoto(Togl *togl, Tk_PhotoHandle photo)
+{
+ GLubyte *buffer;
+ Tk_PhotoImageBlock photoBlock;
+ int y, midy;
+ unsigned char *cp;
+ int width = togl->Width, height = togl->Height;
+
+ /*
+ * TIP #116 altered Tk_PhotoPutBlock API to add interp arg that 8.4
+ * doesn't have.
+ * We need to remove that for compiling with 8.4.
+ */
+#if (TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION < 5)
+# define TK_PHOTOPUTBLOCK(interp, hdl, blk, x, y, w, h, cr) \
+ Tk_PhotoPutBlock(hdl, blk, x, y, w, h, cr)
+#else
+# define TK_PHOTOPUTBLOCK Tk_PhotoPutBlock
+#endif
+ buffer = (GLubyte *) ckalloc(width * height * 4);
+ photoBlock.pixelPtr = buffer;
+ photoBlock.width = width;
+ photoBlock.height = height;
+ photoBlock.pitch = width * 4;
+ photoBlock.pixelSize = 4;
+ photoBlock.offset[0] = 0;
+ photoBlock.offset[1] = 1;
+ photoBlock.offset[2] = 2;
+ photoBlock.offset[3] = 3;
+
+ if (!togl->RgbaFlag) {
+#if defined(TOGL_WGL)
+ /* Due to the lack of a unique inverse mapping from the frame buffer to
+ * the logical palette we need a translation map from the complete
+ * logical palette. */
+ int n, i;
+ TkWinColormap *cmap = (TkWinColormap *) Tk_Colormap(togl->TkWin);
+ LPPALETTEENTRY entry = (LPPALETTEENTRY) malloc(togl->MapSize *
+ sizeof (PALETTEENTRY));
+
+ n = GetPaletteEntries(cmap->palette, 0, togl->MapSize, entry);
+ for (i = 0; i < n; i++) {
+ togl->RedMap[i] = (GLfloat) (entry[i].peRed / 255.0);
+ togl->GreenMap[i] = (GLfloat) (entry[i].peGreen / 255.0);
+ togl->BlueMap[i] = (GLfloat) (entry[i].peBlue / 255.0);
+ }
+ free(entry);
+#endif /* TOGL_WGL */
+
+ glPixelMapfv(GL_PIXEL_MAP_I_TO_R, togl->MapSize, togl->RedMap);
+ glPixelMapfv(GL_PIXEL_MAP_I_TO_G, togl->MapSize, togl->GreenMap);
+ glPixelMapfv(GL_PIXEL_MAP_I_TO_B, togl->MapSize, togl->BlueMap);
+ }
+
+ glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4); /* guarantee performance */
+ glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+
+#if 1
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+ glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ /* Some OpenGL drivers are buggy and return zero for Alpha instead of one
+ * for RGB pixel formats. If that is happening to you, upgrade your
+ * graphics driver. */
+
+ /* OpenGL's origin is bottom-left, Tk Photo image's is top-left, so mirror
+ * the rows around the middle row. */
+ midy = height / 2;
+ cp = buffer;
+ for (y = 0; y < midy; ++y) {
+ int m_y = height - 1 - y; /* mirror y */
+ unsigned char *m_cp = buffer + m_y * photoBlock.pitch;
+ int x;
+
+ for (x = 0; x < photoBlock.pitch; ++x) {
+ unsigned char c = *cp;
+
+ *cp++ = *m_cp;
+ *m_cp++ = c;
+ }
+ }
+#else
+ /* OpenGL's origin is bottom-left, Tk Photo image's is top-left, so save
+ * rows in reverse order. */
+ glPixelStorei(GL_PACK_ROW_LENGTH, width);
+ glPixelStorei(GL_PACK_SKIP_ROWS, -1);
+ glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
+ buffer + width * (height - 1) * 4);
+#endif
+
+ TK_PHOTOPUTBLOCK(togl->Interp, photo, &photoBlock, 0, 0, width, height,
+ TK_PHOTO_COMPOSITE_SET);
+
+ glPopClientAttrib(); /* restore PACK_ALIGNMENT */
+ ckfree((char *) buffer);
+ return TCL_OK;
+}
+
+Bool
+Togl_SwapInterval(const Togl *togl, int interval)
+{
+#ifdef TOGL_AGL
+ GLint swapInterval = interval;
+
+ return aglSetInteger(togl->Ctx, AGL_SWAP_INTERVAL, &swapInterval);
+#endif
+#ifdef TOGL_NSOPENGL
+ GLint swapInterval = interval;
+ [togl->Ctx setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
+ return True;
+#endif
+#ifdef TOGL_WGL
+ typedef BOOL (WINAPI *BOOLFuncInt) (int);
+ typedef const char *(WINAPI *StrFuncHDC) (HDC);
+ static BOOLFuncInt swapInterval = NULL;
+ static BOOL initialized = False;
+
+ if (!initialized) {
+ const char *extensions;
+ StrFuncHDC getExtensionsString;
+
+ getExtensionsString = (StrFuncHDC)
+ wglGetProcAddress("wglGetExtensionsStringARB");
+ if (getExtensionsString == NULL)
+ getExtensionsString = (StrFuncHDC)
+ wglGetProcAddress("wglGetExtensionsStringEXT");
+ if (getExtensionsString) {
+ extensions = getExtensionsString(togl->tglGLHdc);
+ if (strstr(extensions, "WGL_EXT_swap_control") != NULL) {
+ swapInterval =
+ (BOOLFuncInt) wglGetProcAddress("wglSwapIntervalEXT");
+ }
+ }
+ initialized = True;
+ }
+ if (swapInterval)
+ return swapInterval(interval);
+ return False;
+#endif
+#ifdef TOGL_X11
+ typedef int (*IntFuncInt) (int);
+ static IntFuncInt swapInterval = NULL;
+ static int initialized = False;
+
+ if (!initialized) {
+ const char *extensions = glXQueryExtensionsString(togl->display,
+ Tk_ScreenNumber(togl->TkWin));
+
+ if (strstr(extensions, "GLX_SGI_swap_control") != NULL) {
+ swapInterval = (IntFuncInt) Togl_GetProcAddr("glXSwapIntervalSGI");
+ } else if (strstr(extensions, "GLX_MESA_swap_control") != NULL) {
+ swapInterval = (IntFuncInt) Togl_GetProcAddr("glXSwapIntervalMESA");
+ }
+ initialized = True;
+ }
+ if (swapInterval)
+ return swapInterval(interval) == 0;
+ return False;
+#endif
+}
+
+#if defined(TOGL_AGL)
+/* tell OpenGL which part of the Mac window to render to */
+static void
+SetMacBufRect(Togl *togl)
+{
+ GLint wrect[4];
+ Rect r;
+ MacDrawable *d = ((TkWindow *) togl->TkWin)->privatePtr;
+
+ /* set wrect[0,1] to lower left corner of widget */
+ wrect[2] = Tk_Width(togl->TkWin);
+ wrect[3] = Tk_Height(togl->TkWin);
+ wrect[0] = d->xOff;
+
+ GetPortBounds(Togl_MacOSXGetDrawablePort(togl), &r);
+
+ wrect[1] = r.bottom - wrect[3] - d->yOff;
+
+ if (togl->FullscreenFlag) {
+ aglEnable(togl->Ctx, AGL_FS_CAPTURE_SINGLE);
+ aglSetFullScreen(togl->Ctx, 0, 0, 0, 0);
+ } else {
+ aglUpdateContext(togl->Ctx);
+ }
+ aglSetInteger(togl->Ctx, AGL_BUFFER_RECT, wrect);
+ aglEnable(togl->Ctx, AGL_BUFFER_RECT);
+}
+
+static void
+ReconfigureCB(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags,
+ void *closure)
+{
+ /* Display reconfiguration callback. Documented as needed by Apple QA1209.
+ * Updated for 10.3 (and later) to use
+ * CGDisplayRegisterReconfigurationCallback. */
+ Togl *togl = (Togl *) closure;
+
+ if (0 != (flags & kCGDisplayBeginConfigurationFlag))
+ return; /* wait until display is reconfigured */
+
+ SetMacBufRect(togl);
+ Togl_MakeCurrent(togl);
+ if (togl->Ctx) {
+ if (togl->ReshapeProc) {
+ Togl_CallCallback(togl, togl->ReshapeProc);
+ } else {
+ Togl_SetViewPort(togl);
+ }
+ }
+}
+#endif
+
+#if defined(TOGL_NSOPENGL)
+/*
+TODO: It appears that Tk only makes an NSView for toplevel windows.
+Also it looks like NSOpenGL does not have the equivalent of AGL_BUFFER_RECT
+that allows opengl drawing to just part of an NSView. So we might need to
+create our own NSView for controlling the opengl bounds.
+Look at TkMacOSXMakeRealWindowExist() in tkMacOSXWm.c.
+*/
+
+/* tell OpenGL which part of the Mac window to render to */
+static void
+SetMacBufRect(Togl *togl)
+{
+ Rect r, rt;
+ NSRect rect;
+ TkWindow *w = (TkWindow *) togl->TkWin;
+ TkWindow *t = w->privatePtr->toplevel->winPtr;
+
+ TkMacOSXWinBounds(w, &r);
+ TkMacOSXWinBounds(t, &rt);
+
+ rect.origin.x = r.left - rt.left;
+ rect.origin.y = rt.bottom - r.bottom;
+ rect.size.width = r.right - r.left;
+ rect.size.height = r.bottom - r.top;
+
+ [togl->nsview setFrame:rect];
+ [togl->Ctx update];
+
+ /* TODO: Support full screen. */
+}
+
+static void
+ReconfigureCB(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags,
+ void *closure)
+{
+ /* Display reconfiguration callback. Documented as needed by Apple QA1209.
+ * Updated for 10.3 (and later) to use
+ * CGDisplayRegisterReconfigurationCallback. */
+ Togl *togl = (Togl *) closure;
+
+ if (0 != (flags & kCGDisplayBeginConfigurationFlag))
+ return; /* wait until display is reconfigured */
+
+ SetMacBufRect(togl);
+ Togl_MakeCurrent(togl);
+ if (togl->Ctx) {
+ if (togl->ReshapeProc) {
+ Togl_CallCallback(togl, togl->ReshapeProc);
+ } else {
+ Togl_SetViewPort(togl);
+ }
+ }
+}
+#endif
+
+/*
+ * Called when the widget's contents must be redrawn. Basically, we
+ * just call the user's render callback function.
+ *
+ * Note that the parameter type is ClientData so this function can be
+ * passed to Tk_DoWhenIdle().
+ */
+static void
+Togl_Render(ClientData clientData)
+{
+ Togl *togl = (Togl *) clientData;
+
+ if (togl->DisplayProc) {
+ Togl_MakeCurrent(togl);
+ Togl_CallCallback(togl, togl->DisplayProc);
+ }
+ togl->UpdatePending = False;
+}
+
+
+static void
+Togl_RenderOverlay(ClientData clientData)
+{
+ Togl *togl = (Togl *) clientData;
+
+ if (togl->OverlayFlag && togl->OverlayDisplayProc) {
+#if defined(TOGL_WGL)
+ int res = wglMakeCurrent(togl->tglGLHdc, togl->tglGLOverlayHglrc);
+
+ if (!res) {
+ ErrorExit(TEXT("wglMakeCurrent overlay"));
+ }
+#elif defined(TOGL_X11)
+ (void) glXMakeCurrent(Tk_Display(togl->TkWin),
+ togl->OverlayWindow, togl->OverlayCtx);
+#endif /* TOGL_WGL */
+
+ Togl_CallCallback(togl, togl->OverlayDisplayProc);
+ }
+ togl->OverlayUpdatePending = False;
+}
+
+
+static int
+Togl_EnterStereo(Togl *togl)
+{
+ if (togl->Stereo == TOGL_STEREO_ROW_INTERLEAVED) {
+ GLint stencil_bits;
+ Tk_Window top;
+
+ Togl_MakeCurrent(togl);
+ glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
+ if (stencil_bits == 0) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "need stencil buffer for row interleaved stereo",
+ TCL_STATIC);
+ return False;
+ }
+ togl->riStencilBit = 1u << (stencil_bits - 1);
+ glEnable(GL_STENCIL_TEST);
+
+ /* Need to redraw window when moved between odd and even scanlines, so
+ * bind to top level window so we're notified when that happens. */
+ top = togl->TkWin;
+ while (!Tk_IsTopLevel(top)) {
+ top = Tk_Parent(top);
+ if (top == NULL)
+ break;
+ }
+ if (top) {
+ Tk_CreateEventHandler(top, StructureNotifyMask, Togl_RedisplayProc,
+ (ClientData) togl);
+ }
+ }
+ return True;
+}
+
+
+static void
+Togl_LeaveStereo(Togl *togl, int oldStereo)
+{
+ switch (oldStereo) {
+ default:
+ break;
+#ifdef HAVE_AUTOSTEREO
+ case TOGL_STEREO_NATIVE:
+ if (togl->ash != -1) {
+ ASClosedStereoWindow(togl->ash);
+ togl->ash = -1;
+ }
+ break;
+#endif
+#ifdef __sgi
+ case TOGL_STEREO_SGIOLDSTYLE:
+ togl->currentStereoBuffer = STEREO_BUFFER_NONE;
+ glXWaitGL(); /* sync with GL command stream before calling X
+ */
+ XSGISetStereoBuffer(togl->display, Tk_WindowId(togl->TkWin),
+ togl->currentStereoBuffer);
+ glXWaitX(); /* sync with X command stream before calling GL
+ */
+ break;
+#endif
+ case TOGL_STEREO_ROW_INTERLEAVED:
+ if (togl->riStencilBit) {
+ Tk_Window top;
+
+ glDisable(GL_STENCIL_TEST);
+
+ /* need to remove previously added top level event handler */
+ top = togl->TkWin;
+ while (!Tk_IsTopLevel(top)) {
+ top = Tk_Parent(top);
+ if (top == NULL)
+ break;
+ }
+ if (top) {
+ Tk_DeleteEventHandler(top, StructureNotifyMask,
+ Togl_RedisplayProc, (ClientData) togl);
+ }
+ }
+ break;
+ }
+}
+
+
+/*
+ * See domentation about what can't be changed
+ */
+static int
+Togl_ObjConfigure(Tcl_Interp *interp, Togl *togl,
+ int objc, Tcl_Obj *const *objv)
+{
+ Tk_SavedOptions savedOptions;
+ int error, mask;
+ int undoMask = 0;
+ Tcl_Obj *errorResult = NULL;
+ int oldStereo = togl->Stereo;
+ int oldWidth = togl->Width;
+ int oldHeight = togl->Height;
+
+ for (error = 0; error <= 1; ++error, mask = undoMask) {
+ if (error == 0) {
+ /*
+ * Tk_SetOptions parses the command arguments
+ * and looks for defaults in the resource database.
+ */
+ if (Tk_SetOptions(interp, WIDGREC togl, togl->tpg->optionTable,
+ objc, objv, togl->TkWin, &savedOptions, &mask)
+ != TCL_OK) {
+ /* previous values are restored, so nothing to do */
+ return TCL_ERROR;
+ }
+ } else {
+ /*
+ * Restore options from saved values
+ */
+ errorResult = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(errorResult);
+ Tk_RestoreSavedOptions(&savedOptions);
+ }
+
+ if (togl->Ident && togl->Ident[0] == '.') {
+ Tcl_AppendResult(interp, "Can not set ident to a window path name",
+ NULL);
+ continue;
+ }
+
+ if (togl->FullscreenFlag) {
+ /* override width and height */
+ togl->Width = WidthOfScreen(Tk_Screen(togl->TkWin));
+ togl->Height = HeightOfScreen(Tk_Screen(togl->TkWin));
+ undoMask |= GEOMETRY_MASK;
+ }
+
+ if (mask & GEOMETRY_MASK) {
+ if (!togl->PbufferFlag) {
+ Togl_WorldChanged((ClientData) togl);
+ /* Reset width and height so ConfigureNotify
+ * event will call reshape callback */
+ togl->Width = oldWidth;
+ togl->Height = oldHeight;
+ undoMask |= GEOMETRY_MASK;
+ }
+ }
+
+ if (mask & OVERLAY_MASK) {
+#if !TOGL_USE_OVERLAY
+ if (togl->OverlayFlag) {
+ Tcl_AppendResult(interp, "Sorry, overlay was disabled", NULL);
+ continue;
+ }
+#else
+# if defined(TOGL_X11)
+ if (togl->OverlayCtx)
+# elif defined(TOGL_WGL)
+ if (togl->tglGLOverlayHglrc)
+# endif
+ {
+ /*
+ * Trying to change existing pixel format/graphics context
+ */
+ Tcl_AppendResult(interp,
+ "Unable to change overlay pixel format", NULL);
+ continue;
+ }
+#endif
+ }
+
+ if (mask & SWAP_MASK) {
+ if (togl->Ctx) {
+ /*
+ * Change existing swap interval
+ */
+ Togl_MakeCurrent(togl); /* TODO: needed? */
+ Togl_SwapInterval(togl, togl->SwapInterval);
+ undoMask |= SWAP_MASK;
+ }
+ }
+
+ if (error == 0 && (mask & STEREO_FORMAT_MASK) != 0) {
+ if (oldStereo == TOGL_STEREO_NATIVE
+ || togl->Stereo == TOGL_STEREO_NATIVE) {
+ /* only native stereo affects the visual format */
+ mask |= FORMAT_MASK;
+ }
+ if (togl->Stereo == TOGL_STEREO_SGIOLDSTYLE) {
+#ifndef __sgi
+ Tcl_AppendResult(interp,
+ "sgioldstyle: only available on SGI computers", NULL);
+ continue;
+#else
+ int event, error;
+
+ /* Make sure Display supports SGIStereo */
+ if (XSGIStereoQueryExtension(Tk_Display(togl->TkWin), &event,
+ &error) == False) {
+ Tcl_AppendResult(interp,
+ "sgioldstyle: SGIStereo X extension is missing",
+ NULL);
+ continue;
+ }
+ /* Make sure Window (Screen) supports SGIStereo */
+ if (XSGIQueryStereoMode(Tk_Display(togl->TkWin),
+ Tk_WindowId(Tk_Parent(togl->TkWin))) ==
+ X_STEREO_UNSUPPORTED) {
+ Tcl_AppendResult(interp,
+ "sgioldstyle: unsupported by screen", NULL);
+ continue;
+ }
+#endif
+ }
+ }
+
+ if (mask & FORMAT_MASK) {
+ if (togl->Ctx) {
+ /*
+ * Trying to change existing pixel format/graphics context
+ * TODO: (re)create graphics context
+ *
+ * save old graphics context
+ * try to create new one and share display lists
+ * if failure, then restore old one
+ */
+ Tcl_AppendResult(interp, "Unable to change pixel format", NULL);
+ continue;
+ }
+ if (togl->ShareContext && togl->ShareList) {
+ Tcl_AppendResult(interp,
+ "only one of -sharelist and -sharecontext allowed",
+ NULL);
+ continue;
+ }
+ if (togl->PbufferFlag && togl->Stereo) {
+ Tcl_AppendResult(interp, "pbuffer not supported with stereo",
+ NULL);
+ continue;
+ }
+ if (togl->PbufferFlag && togl->OverlayFlag) {
+ Tcl_AppendResult(interp, "pbuffer not supported with overlay",
+ NULL);
+ continue;
+ }
+ if (togl->FullscreenFlag) {
+#if defined(TOGL_NSOPENGL)
+ Tcl_AppendResult(interp,
+ "Fullscreen not supported with Cocoa Tk", NULL);
+ continue;
+#endif
+#ifndef TOGL_AGL
+# if TK_MAJOR_VERSION < 8 || (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 5)
+ Tcl_AppendResult(interp,
+ "Need Tk 8.5 or later for fullscreen support", NULL);
+ continue;
+# endif
+#endif
+ }
+ /* Whether or not the format is okay is figured out when togl tries
+ * to create the window. */
+#ifdef MESA_COLOR_HACK
+ free_default_color_cells(Tk_Display(togl->TkWin),
+ Tk_Colormap(togl->TkWin));
+#endif
+ undoMask |= FORMAT_MASK;
+ }
+
+ if (togl->Ctx) {
+ if (oldStereo != togl->Stereo) {
+ /* leaving stereo */
+ Togl_LeaveStereo(togl, oldStereo);
+ if (togl->Stereo && !Togl_EnterStereo(togl))
+ continue;
+ }
+ }
+
+ if (mask & TIMER_MASK) {
+ if (togl->timerHandler != NULL) {
+ Tcl_DeleteTimerHandler(togl->timerHandler);
+ }
+ if (togl->TimerProc) {
+ togl->timerHandler =
+ Tcl_CreateTimerHandler(togl->TimerInterval, Togl_Timer,
+ (ClientData) togl);
+ }
+ undoMask |= TIMER_MASK;
+ }
+ break;
+ }
+
+ if (error == 0) {
+ Tk_FreeSavedOptions(&savedOptions);
+ return TCL_OK;
+ } else {
+ Tcl_SetObjResult(interp, errorResult);
+ Tcl_DecrRefCount(errorResult);
+ return TCL_ERROR;
+ }
+}
+
+
+static int
+Togl_ObjWidget(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl *togl = (Togl *) clientData;
+ const char *commands[] = {
+ "cget", "configure", "extensions",
+ "postredisplay", "render",
+ "swapbuffers", "makecurrent", "takephoto",
+ "loadbitmapfont", "unloadbitmapfont", "write",
+ "uselayer", "showoverlay", "hideoverlay",
+ "postredisplayoverlay", "renderoverlay",
+ "existsoverlay", "ismappedoverlay",
+ "getoverlaytransparentvalue",
+ "drawbuffer", "clear", "frustum", "ortho",
+ "numeyes", "contexttag", "copycontextto", "maketopfortrackpadevents",
+ NULL
+ };
+ enum command
+ {
+ TOGL_CGET, TOGL_CONFIGURE, TOGL_EXTENSIONS,
+ TOGL_POSTREDISPLAY, TOGL_RENDER,
+ TOGL_SWAPBUFFERS, TOGL_MAKECURRENT, TOGL_TAKEPHOTO,
+ TOGL_LOADBITMAPFONT, TOGL_UNLOADBITMAPFONT, TOGL_WRITE,
+ TOGL_USELAYER, TOGL_SHOWOVERLAY, TOGL_HIDEOVERLAY,
+ TOGL_POSTREDISPLAYOVERLAY, TOGL_RENDEROVERLAY,
+ TOGL_EXISTSOVERLAY, TOGL_ISMAPPEDOVERLAY,
+ TOGL_GETOVERLAYTRANSPARENTVALUE,
+ TOGL_DRAWBUFFER, TOGL_CLEAR, TOGL_FRUSTUM, TOGL_ORTHO,
+ TOGL_NUMEYES, TOGL_CONTEXTTAG, TOGL_COPYCONTEXTTO, TOGL_MAKETOPFORTRACKPADEVENTS
+ };
+ int result = TCL_OK;
+ Tcl_Obj *objPtr;
+ int index;
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "command ?arg arg ...?");
+ return TCL_ERROR;
+ }
+
+ Tk_Preserve((ClientData) togl);
+
+ result = Tcl_GetIndexFromObj(interp, objv[1], commands, "option", 0,
+ &index);
+
+ switch (index) {
+ case TOGL_CGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option");
+ result = TCL_ERROR;
+ break;
+ }
+ objPtr = Tk_GetOptionValue(interp, WIDGREC togl,
+ togl->tpg->optionTable, (objc == 3) ? objv[2] : NULL,
+ togl->TkWin);
+ if (objPtr == NULL) {
+ result = TCL_ERROR;
+ break;
+ }
+ Tcl_SetObjResult(interp, objPtr);
+ break;
+
+ case TOGL_CONFIGURE:
+ if (objc <= 3) {
+ /*
+ * Return one item if the option is given,
+ * or return all configuration information
+ */
+ objPtr = Tk_GetOptionInfo(interp, WIDGREC togl,
+ togl->tpg->optionTable, (objc == 3) ? objv[2] : NULL,
+ togl->TkWin);
+ if (objPtr == NULL) {
+ result = TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ }
+ } else {
+ /* Execute a configuration change */
+ result = Togl_ObjConfigure(interp, togl, objc - 2, objv + 2);
+ }
+ break;
+
+ case TOGL_EXTENSIONS:
+ /* Return a list of OpenGL extensions available */
+ /* TODO: -glu for glu extensions, -platform for glx/wgl extensions */
+ if (objc == 2) {
+ const char *extensions;
+ Tcl_Obj *objPtr;
+ int length = -1;
+
+ extensions = (const char *) glGetString(GL_EXTENSIONS);
+ objPtr = Tcl_NewStringObj(extensions, -1);
+ /* convert to list by asking for its length */
+ (void) Tcl_ListObjLength(interp, objPtr, &length);
+ Tcl_SetObjResult(interp, objPtr);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_POSTREDISPLAY:
+ /* schedule the widget to be redrawn */
+ if (objc == 2) {
+ Togl_PostRedisplay(togl);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_RENDER:
+ /* force the widget to be redrawn */
+ if (objc == 2) {
+ Togl_Render((ClientData) togl);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_SWAPBUFFERS:
+ /* force the widget to be redrawn */
+ if (objc == 2) {
+ Togl_SwapBuffers(togl);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_MAKECURRENT:
+ /* force the widget to be redrawn */
+ if (objc == 2) {
+ Togl_MakeCurrent(togl);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_TAKEPHOTO:
+ {
+ /* force the widget to be redrawn */
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name");
+ result = TCL_ERROR;
+ } else {
+ const char *name;
+ Tk_PhotoHandle photo;
+
+ name = Tcl_GetStringFromObj(objv[2], NULL);
+ photo = Tk_FindPhoto(interp, name);
+ if (photo == NULL) {
+ Tcl_AppendResult(interp, "image \"", name,
+ "\" doesn't exist or is not a photo image", NULL);
+ result = TCL_ERROR;
+ break;
+ }
+ glPushAttrib(GL_PIXEL_MODE_BIT);
+ if (togl->DoubleFlag) {
+ glReadBuffer(GL_FRONT);
+ }
+ Togl_TakePhoto(togl, photo);
+ glPopAttrib(); /* restore glReadBuffer */
+ }
+ break;
+ }
+
+ case TOGL_LOADBITMAPFONT:
+#if TOGL_USE_FONTS != 1
+ Tcl_AppendResult(interp, "unsupported", NULL);
+ result = TCL_ERROR;
+#else
+ if (objc >= 3) {
+ Tcl_Obj *font, *list;
+
+ list = Tcl_NewListObj(objc - 2, objv + 2);
+ Tcl_IncrRefCount(list);
+ font = Togl_LoadBitmapFont(togl, Tcl_GetString(list));
+ Tcl_DecrRefCount(list);
+ if (font) {
+ Tcl_SetObjResult(interp, font);
+ result = TCL_OK;
+ } else {
+ Tcl_AppendResult(interp, "Could not allocate font", NULL);
+ result = TCL_ERROR;
+ }
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "fontname");
+ result = TCL_ERROR;
+ }
+#endif
+ break;
+
+ case TOGL_UNLOADBITMAPFONT:
+#if TOGL_USE_FONTS != 1
+ Tcl_AppendResult(interp, "unsupported", NULL);
+ result = TCL_ERROR;
+#else
+ if (objc == 3) {
+ result = Togl_UnloadBitmapFont(togl, objv[2]);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "toglfont");
+ result = TCL_ERROR;
+ }
+#endif
+ break;
+
+ case TOGL_WRITE:{
+#if TOGL_USE_FONTS != 1
+ Tcl_AppendResult(interp, "unsupported", NULL);
+ result = TCL_ERROR;
+#else
+ /* Tcl_Obj *toglfont = objv[2]; */
+ int wobjc = objc - 3;
+ Tcl_Obj *const *wobjv = objv + 3;
+
+ while (wobjc > 1) {
+ const char *name = Tcl_GetStringFromObj(wobjv[0], NULL);
+ int oc, i;
+ Tcl_Obj **ov;
+ double args[4];
+
+ if (Tcl_ListObjGetElements(NULL, wobjv[1], &oc, &ov) != TCL_OK) {
+ oc = 0;
+ } else if (oc <= 4) {
+ for (i = 0; i < oc; ++i) {
+ if (Tcl_GetDoubleFromObj(NULL, ov[i], &args[i]) != TCL_OK) {
+ }
+ }
+ }
+ if (strcmp(name, "-color") == 0) {
+ if (oc == 4)
+ glColor4d(args[0], args[1], args[2], args[3]);
+ else if (oc == 3)
+ glColor3d(args[0], args[1], args[2]);
+ else
+ goto write_usage;
+ } else if (strcmp(name, "-pos") == 0) {
+ if (oc == 4)
+ glRasterPos4d(args[0], args[1], args[2], args[3]);
+ else if (oc == 3)
+ glRasterPos3d(args[0], args[1], args[2]);
+ else if (oc == 2)
+ glRasterPos2d(args[0], args[1]);
+ else
+ goto write_usage;
+ } else
+ goto write_usage;
+ wobjc -= 2;
+ wobjv += 2;
+ }
+ if (wobjc != 1)
+ goto write_usage;
+ result = Togl_WriteObj(togl, objv[2], wobjv[0]);
+ if (result != -1)
+ result = TCL_OK;
+ else {
+ Tcl_AppendResult(interp, "togl write failed", NULL);
+ result = TCL_ERROR;
+ }
+ break;
+ write_usage:
+ Tcl_WrongNumArgs(interp, 2, objv, "[-pos {x y [z [w]]}]"
+ " [-color {r g b [a]}" " string");
+ result = TCL_ERROR;
+#endif
+ break;
+ }
+
+ case TOGL_USELAYER:
+ if (objc == 3) {
+ int layer;
+
+ result = Tcl_GetIntFromObj(interp, objv[2], &layer);
+ if (result == TCL_OK) {
+ Togl_UseLayer(togl, layer);
+ }
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "layer");
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_SHOWOVERLAY:
+ if (objc == 2) {
+ Togl_ShowOverlay(togl);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_HIDEOVERLAY:
+ if (objc == 2) {
+ Togl_HideOverlay(togl);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_POSTREDISPLAYOVERLAY:
+ if (objc == 2) {
+ Togl_PostOverlayRedisplay(togl);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_RENDEROVERLAY:
+ /* force the overlay to be redrawn */
+ if (objc == 2) {
+ Togl_RenderOverlay((ClientData) togl);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_EXISTSOVERLAY:
+ if (objc == 2) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(Togl_ExistsOverlay(togl)));
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_ISMAPPEDOVERLAY:
+ if (objc == 2) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj(Togl_IsMappedOverlay(togl)));
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_GETOVERLAYTRANSPARENTVALUE:
+ if (objc == 2) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj(Togl_GetOverlayTransparentValue(togl)));
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_DRAWBUFFER:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "mode");
+ result = TCL_ERROR;
+ } else {
+ int mask;
+
+ result = Tcl_GetIntFromObj(interp, objv[2], &mask);
+ if (result == TCL_ERROR)
+ break;
+ Togl_DrawBuffer(togl, (GLenum) mask);
+ }
+ break;
+
+ case TOGL_CLEAR:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "mask");
+ result = TCL_ERROR;
+ } else {
+ int mask;
+
+ result = Tcl_GetIntFromObj(interp, objv[2], &mask);
+ if (result == TCL_ERROR)
+ break;
+ Togl_Clear(togl, (GLbitfield) mask);
+ }
+ break;
+
+ case TOGL_FRUSTUM:
+ if (objc != 8) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "left right bottom top near far");
+ result = TCL_ERROR;
+ } else {
+ double left, right, bottom, top, zNear, zFar;
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &left) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[3],
+ &right) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[4],
+ &bottom) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[5],
+ &top) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[6],
+ &zNear) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[7],
+ &zFar) == TCL_ERROR) {
+ result = TCL_ERROR;
+ break;
+ }
+ Togl_Frustum(togl, left, right, bottom, top, zNear, zFar);
+ }
+ break;
+
+ case TOGL_ORTHO:
+ if (objc != 8) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "left right bottom top near far");
+ result = TCL_ERROR;
+ } else {
+ double left, right, bottom, top, zNear, zFar;
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &left) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[3],
+ &right) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[4],
+ &bottom) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[5],
+ &top) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[6],
+ &zNear) == TCL_ERROR
+ || Tcl_GetDoubleFromObj(interp, objv[7],
+ &zFar) == TCL_ERROR) {
+ result = TCL_ERROR;
+ break;
+ }
+ Togl_Ortho(togl, left, right, bottom, top, zNear, zFar);
+ }
+ break;
+
+ case TOGL_NUMEYES:
+ if (objc == 2) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(Togl_NumEyes(togl)));
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_CONTEXTTAG:
+ if (objc == 2) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(Togl_ContextTag(togl)));
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+
+ case TOGL_COPYCONTEXTTO:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ } else {
+ Togl *to;
+ unsigned int mask;
+
+ if (Togl_GetToglFromObj(togl->Interp, objv[2], &to) == TCL_ERROR
+ || Tcl_GetIntFromObj(togl->Interp, objv[3],
+ (int *) &mask) == TCL_ERROR) {
+ result = TCL_ERROR;
+ break;
+ }
+ result = Togl_CopyContext(togl, to, mask);
+ }
+#ifdef TOGL_NSOPENGL
+ case TOGL_MAKETOPFORTRACKPADEVENTS:
+ if (objc == 2) {
+ // This hack places the Togl NSView at the top of sibling views so that it receives
+ // trackpad events. The hierarchy is not used for drawing, nor for mouse event dispatching.
+ [togl->nsview retain];
+ [togl->nsview removeFromSuperview];
+ MacDrawable *d = ((TkWindow *) togl->TkWin)->privatePtr;
+ NSView *topview = d->toplevel->view;
+ [topview addSubview:togl->nsview];
+ [togl->nsview release];
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ }
+ break;
+#endif
+ }
+
+ Tk_Release((ClientData) togl);
+ return result;
+}
+
+/*
+ * Togl_ObjCmdDelete
+ *
+ * Called when togl command is removed from interpreter.
+ */
+
+static void
+Togl_ObjCmdDelete(ClientData clientData)
+{
+ if (clientData != NULL) {
+ Togl_PackageGlobals *tpg = (Togl_PackageGlobals *) clientData;
+
+ Tk_DeleteOptionTable(tpg->optionTable);
+ ckfree((char *) clientData);
+ }
+}
+
+
+/*
+ * Togl_ObjCmd
+ *
+ * Called when Togl is executed - creation of a Togl widget.
+ * * Creates a new window
+ * * Creates an 'Togl' data structure
+ * * Creates an event handler for this window
+ * * Creates a command that handles this object
+ * * Configures this Togl for the given arguments
+ */
+int
+Togl_ObjCmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const *objv)
+{
+ Togl_PackageGlobals *tpg;
+ Togl *togl;
+ Tk_Window tkwin;
+ Tcl_SavedResult saveError;
+
+ if (objc <= 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
+ return TCL_ERROR;
+ }
+ tpg = (Togl_PackageGlobals *) clientData;
+ if (tpg == NULL) {
+ Tcl_CmdInfo info;
+ const char *name;
+
+ /*
+ * Initialize the Togl_PackageGlobals for this widget the
+ * first time a Togl widget is created. The globals are
+ * saved as our client data.
+ */
+
+ tpg = (Togl_PackageGlobals *) ckalloc(sizeof (Togl_PackageGlobals));
+ if (tpg == NULL) {
+ return TCL_ERROR;
+ }
+ tpg->nextContextTag = 0;
+ tpg->optionTable = Tk_CreateOptionTable(interp, optionSpecs);
+ tpg->toglHead = NULL;
+
+ name = Tcl_GetString(objv[0]);
+ Tcl_GetCommandInfo(interp, name, &info);
+ info.objClientData = (ClientData) tpg;
+ Tcl_SetCommandInfo(interp, name, &info);
+ }
+
+ /* Create the window. */
+ tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
+ Tcl_GetString(objv[1]), NULL);
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+
+ Tk_SetClass(tkwin, "Togl");
+
+ /* Create Togl data structure */
+ togl = (Togl *) ckalloc(sizeof (Togl));
+ if (togl == NULL) {
+ return TCL_ERROR;
+ }
+
+ /* initialize Togl data structures values */
+ togl->Next = NULL;
+ togl->Ctx = NULL;
+#if defined(TOGL_WGL)
+ togl->tglGLHdc = NULL;
+ togl->tglGLOverlayHglrc = NULL;
+#elif defined(TOGL_X11)
+ togl->OverlayCtx = NULL;
+#endif
+ togl->contextTag = 0;
+ togl->display = Tk_Display(tkwin);
+ togl->TkWin = tkwin;
+ togl->Interp = interp;
+ togl->VisInfo = NULL;
+ togl->OverlayWindow = None;
+ togl->OverlayCmap = None;
+ togl->OverlayTransparentPixel = 0;
+ togl->OverlayIsMapped = False;
+
+ togl->UpdatePending = False;
+ togl->OverlayUpdatePending = False;
+ togl->tpg = tpg;
+ togl->Client_Data = NULL;
+
+ /* for color index mode photos */
+ togl->RedMap = togl->GreenMap = togl->BlueMap = NULL;
+ togl->MapSize = 0;
+
+#ifndef NO_TK_CURSOR
+ togl->Cursor = None;
+#endif
+ togl->Width = 0;
+ togl->Height = 0;
+ togl->PixelScale = 1;
+ togl->SetGrid = 0;
+ togl->TimerInterval = 0;
+ togl->RgbaFlag = True;
+ togl->RgbaRed = 1;
+ togl->RgbaGreen = 1;
+ togl->RgbaBlue = 1;
+ togl->DoubleFlag = False;
+ togl->DepthFlag = False;
+ togl->DepthSize = 1;
+ togl->AccumFlag = False;
+ togl->AccumRed = 1;
+ togl->AccumGreen = 1;
+ togl->AccumBlue = 1;
+ togl->AccumAlpha = 1;
+ togl->AlphaFlag = False;
+ togl->AlphaSize = 1;
+ togl->StencilFlag = False;
+ togl->StencilSize = 1;
+ togl->OverlayFlag = False;
+ togl->Stereo = TOGL_STEREO_NONE;
+ togl->EyeSeparation = 0;
+ togl->Convergence = 0;
+ togl->riStencilBit = 0;
+ togl->AuxNumber = 0;
+ togl->Indirect = False;
+ togl->PixelFormat = 0;
+ togl->SwapInterval = 1;
+ togl->MultisampleFlag = False;
+ togl->FullscreenFlag = False;
+ togl->PbufferFlag = False;
+ togl->LargestPbufferFlag = False;
+#if defined(TOGL_X11)
+ togl->fbcfg = None;
+ togl->pbuf = None;
+#elif defined(TOGL_WGL)
+ togl->pbuf = None;
+ togl->pbufferLost = 0;
+#elif defined(TOGL_AGL)
+ togl->pbuf = NULL;
+#elif defined(TOGL_NSOPENGL)
+ togl->pbuf = NULL;
+#endif
+
+ togl->CreateProc = NULL;
+ togl->DisplayProc = NULL;
+ togl->ReshapeProc = NULL;
+ togl->DestroyProc = NULL;
+ togl->TimerProc = NULL;
+ togl->timerHandler = NULL;
+ togl->OverlayDisplayProc = NULL;
+ togl->MagnifyProc = NULL;
+ togl->RotateProc = NULL;
+ togl->ScrollProc = NULL;
+ togl->ScrollWheelProc = NULL;
+ togl->TouchesProc = NULL;
+ togl->ShareList = NULL;
+ togl->ShareContext = NULL;
+ togl->Ident = NULL;
+ togl->PrivateCmapFlag = False;
+ togl->currentStereoBuffer = STEREO_BUFFER_NONE;
+#ifdef HAVE_AUTOSTEREO
+ togl->as_initialized = False;
+ togl->ash = -1;
+#endif
+ togl->badWindow = False;
+
+ /* Create command event handler */
+ togl->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin),
+ Togl_ObjWidget, (ClientData) togl, ToglCmdDeletedProc);
+
+ /*
+ * Setup the Tk_ClassProcs callbacks to point at our own window creation
+ * function
+ *
+ * We need to check at runtime if we should use the new Tk_SetClassProcs()
+ * API or if we need to modify the window structure directly
+ */
+#ifdef HAVE_TK_SETCLASSPROCS
+
+ if (SetClassProcsPtr != NULL) { /* use public API (Tk 8.4+) */
+ Tk_ClassProcs *procsPtr;
+
+ procsPtr = (Tk_ClassProcs *) ckalloc(sizeof (Tk_ClassProcs));
+ procsPtr->size = sizeof (Tk_ClassProcs);
+ procsPtr->createProc = Togl_MakeWindow;
+ procsPtr->worldChangedProc = Togl_WorldChanged;
+ procsPtr->modalProc = NULL;
+ /* Tk_SetClassProcs(togl->TkWin, procsPtr, (ClientData) togl); */
+ (SetClassProcsPtr) (togl->TkWin, procsPtr, (ClientData) togl);
+ } else
+#endif
+ { /* use private API */
+ /*
+ * We need to set these fields in the Tk_FakeWin structure: dummy17 =
+ * classProcsPtr dummy18 = instanceData */
+ TkClassProcs *procsPtr;
+ Tk_FakeWin *winPtr = (Tk_FakeWin *) (togl->TkWin);
+
+ procsPtr = (TkClassProcs *) ckalloc(sizeof (TkClassProcs));
+ procsPtr->createProc = Togl_MakeWindow;
+ procsPtr->geometryProc = Togl_WorldChanged;
+ procsPtr->modalProc = NULL;
+ winPtr->dummy17 = (char *) procsPtr;
+ winPtr->dummy18 = (ClientData) togl;
+ }
+
+ Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask,
+ Togl_EventProc, (ClientData) togl);
+
+ /* Configure Togl widget */
+ if (Tk_InitOptions(interp, WIDGREC togl, tpg->optionTable, tkwin) != TCL_OK
+ || Togl_ObjConfigure(interp, togl, objc - 2, objv + 2) != TCL_OK) {
+ goto error;
+ }
+
+ /*
+ * If OpenGL window wasn't already created by Togl_ObjConfigure() we
+ * create it now. We can tell by checking if the OpenGL context has
+ * been initialized.
+ */
+ if (!togl->Ctx) {
+ Tk_MakeWindowExist(togl->TkWin);
+ if (togl->badWindow) {
+ goto error;
+ }
+ }
+ Togl_MakeCurrent(togl);
+ if (togl->contextTag == 0)
+ togl->contextTag = ++tpg->nextContextTag;
+
+ (void) Togl_SwapInterval(togl, togl->SwapInterval);
+
+ /* If defined, call create callback */
+ if (togl->CreateProc) {
+ if (Togl_CallCallback(togl, togl->CreateProc) != TCL_OK) {
+ goto error;
+ }
+ }
+#if defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ if (!togl->PbufferFlag)
+ SetMacBufRect(togl);
+#endif
+ /* If defined, call reshape proc */
+ if (togl->ReshapeProc) {
+ if (Togl_CallCallback(togl, togl->ReshapeProc) != TCL_OK) {
+ goto error;
+ }
+ } else {
+ Togl_SetViewPort(togl);
+#if defined(TOGL_X11)
+ if (togl->OverlayFlag) {
+ Togl_UseLayer(togl, TOGL_OVERLAY);
+ Togl_SetViewPort(togl);
+ Togl_UseLayer(togl, TOGL_NORMAL);
+ }
+#endif
+ }
+
+ if (togl->Stereo && !Togl_EnterStereo(togl))
+ goto error;
+
+ Tcl_AppendResult(interp, Tk_PathName(tkwin), NULL);
+
+ /* Add to linked list */
+ AddToList(togl);
+
+ return TCL_OK;
+
+ error:
+ Tcl_SaveResult(interp, &saveError);
+ togl->badWindow = True;
+ (void) Tcl_DeleteCommandFromToken(interp, togl->widgetCmd);
+ Tcl_RestoreResult(interp, &saveError);
+ Tcl_AppendResult(interp, "\nCouldn't configure togl widget", NULL);
+ return TCL_ERROR;
+}
+
+
+#if TOGL_USE_OVERLAY
+
+/*
+ * Do all the setup for overlay planes
+ * Return: TCL_OK or TCL_ERROR
+ */
+static int
+SetupOverlay(Togl *togl)
+{
+# if defined(TOGL_X11)
+
+# ifdef GLX_TRANSPARENT_TYPE_EXT
+ static int ovAttributeList[] = {
+ GLX_BUFFER_SIZE, 2,
+ GLX_LEVEL, 1,
+ GLX_TRANSPARENT_TYPE_EXT, GLX_TRANSPARENT_INDEX_EXT,
+ None
+ };
+# else
+ static int ovAttributeList[] = {
+ GLX_BUFFER_SIZE, 2,
+ GLX_LEVEL, 1,
+ None
+ };
+# endif
+
+ XVisualInfo *visinfo;
+ TkWindow *winPtr = (TkWindow *) togl->TkWin;
+
+ XSetWindowAttributes swa;
+ Tcl_HashEntry *hPtr;
+ int new_flag;
+
+ visinfo =
+ glXChooseVisual(togl->display, Tk_ScreenNumber(winPtr),
+ ovAttributeList);
+ if (!visinfo) {
+ Tcl_AppendResult(togl->Interp, Tk_PathName(winPtr),
+ ": No suitable overlay index visual available", NULL);
+ togl->OverlayCtx = NULL;
+ togl->OverlayWindow = 0;
+ togl->OverlayCmap = 0;
+ return TCL_ERROR;
+ }
+# ifdef GLX_TRANSPARENT_INDEX_EXT
+ {
+ int fail = glXGetConfig(togl->display, visinfo,
+ GLX_TRANSPARENT_INDEX_VALUE_EXT,
+ &togl->OverlayTransparentPixel);
+
+ if (fail)
+ togl->OverlayTransparentPixel = 0; /* maybe, maybe ... */
+ }
+# else
+ togl->OverlayTransparentPixel = 0; /* maybe, maybe ... */
+# endif
+
+ /* share display lists with normal layer context */
+ togl->OverlayCtx = glXCreateContext(togl->display, visinfo, togl->Ctx,
+ !togl->Indirect);
+
+ swa.colormap = XCreateColormap(togl->display,
+ XRootWindow(togl->display, visinfo->screen),
+ visinfo->visual, AllocNone);
+ togl->OverlayCmap = swa.colormap;
+
+ swa.border_pixel = 0;
+ swa.event_mask = ALL_EVENTS_MASK;
+ togl->OverlayWindow = XCreateWindow(togl->display,
+ Tk_WindowId(togl->TkWin), 0, 0,
+ togl->Width, togl->Height, 0,
+ visinfo->depth, InputOutput,
+ visinfo->visual, CWBorderPixel | CWColormap | CWEventMask, &swa);
+
+ hPtr = Tcl_CreateHashEntry(&winPtr->dispPtr->winTable,
+ (const char *) togl->OverlayWindow, &new_flag);
+ Tcl_SetHashValue(hPtr, winPtr);
+
+ /* XMapWindow(togl->display, togl->OverlayWindow); */
+ togl->OverlayIsMapped = False;
+
+ /* Make sure window manager installs our colormap */
+ XSetWMColormapWindows(togl->display, togl->OverlayWindow,
+ &togl->OverlayWindow, 1);
+
+ return TCL_OK;
+
+# elif defined(TOGL_WGL) || defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ /* not yet implemented on these */
+ return TCL_ERROR;
+# endif
+}
+
+#endif /* TOGL_USE_OVERLAY */
+
+
+
+#ifdef TOGL_WGL
+# define TOGL_CLASS_NAME "Togl Class"
+static Bool ToglClassInitialized = False;
+
+static LRESULT CALLBACK
+Win32WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LONG result;
+ Togl *togl = (Togl *) GetWindowLongPtr(hwnd, 0);
+ WNDCLASS childClass;
+
+ switch (message) {
+
+ case WM_WINDOWPOSCHANGED:
+ /* Should be processed by DefWindowProc, otherwise a double buffered
+ * context is not properly resized when the corresponding window is
+ * resized. */
+ break;
+
+ case WM_DESTROY:
+ if (togl && togl->TkWin != NULL) {
+ if (togl->SetGrid > 0) {
+ Tk_UnsetGrid(togl->TkWin);
+ }
+ (void) Tcl_DeleteCommandFromToken(togl->Interp, togl->widgetCmd);
+ }
+ break;
+
+ case WM_ERASEBKGND:
+ /* We clear our own window */
+ return 1;
+
+ case WM_DISPLAYCHANGE:
+ if (togl->PbufferFlag && hasARBPbuffer && !togl->pbufferLost) {
+ queryPbuffer(togl->pbuf, WGL_PBUFFER_LOST_ARB,
+ &togl->pbufferLost);
+ }
+ /* FALLTHROUGH */
+
+ default:
+# if USE_STATIC_LIB
+ return TkWinChildProc(hwnd, message, wParam, lParam);
+# else
+ /*
+ * OK, since TkWinChildProc is not explicitly exported in the
+ * dynamic libraries, we have to retrieve it from the class info
+ * registered with windows.
+ *
+ */
+ if (tkWinChildProc == NULL) {
+ GetClassInfo(Tk_GetHINSTANCE(), TK_WIN_CHILD_CLASS_NAME,
+ &childClass);
+ tkWinChildProc = childClass.lpfnWndProc;
+ }
+ return tkWinChildProc(hwnd, message, wParam, lParam);
+# endif
+ }
+ result = DefWindowProc(hwnd, message, wParam, lParam);
+ Tcl_ServiceAll();
+ return result;
+}
+#endif /* TOGL_WGL */
+
+
+/*
+ * Togl_MakeWindow
+ *
+ * Window creation function, invoked as a callback from Tk_MakeWindowExist.
+ * This is called instead of TkpMakeWindow and must always succeed.
+ */
+static Window
+Togl_MakeWindow(Tk_Window tkwin, Window parent, ClientData instanceData)
+{
+ Togl *togl = (Togl *) instanceData;
+ Display *dpy;
+ Colormap cmap;
+ int scrnum;
+ Window window = None;
+
+#if defined(TOGL_X11)
+ Bool directCtx = True;
+ XSetWindowAttributes swa;
+ int width, height;
+#elif defined(TOGL_WGL)
+ HWND hwnd, parentWin;
+ DWORD style;
+ HINSTANCE hInstance;
+ PIXELFORMATDESCRIPTOR pfd;
+ int width, height;
+ Bool createdPbufferDC = False;
+#elif defined(TOGL_AGL)
+#endif
+
+ if (togl->badWindow) {
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
+ return TkpMakeWindow(winPtr, parent);
+ }
+
+ /* for color index mode photos */
+ if (togl->RedMap)
+ free(togl->RedMap);
+ if (togl->GreenMap)
+ free(togl->GreenMap);
+ if (togl->BlueMap)
+ free(togl->BlueMap);
+ togl->RedMap = togl->GreenMap = togl->BlueMap = NULL;
+ togl->MapSize = 0;
+
+ dpy = Tk_Display(tkwin);
+ scrnum = Tk_ScreenNumber(tkwin);
+
+ /*
+ * Windows and Mac OS X need the window created before OpenGL context
+ * is created. So do that now and set the window variable.
+ */
+#if defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ {
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
+ window = TkpMakeWindow(winPtr, parent);
+ if (!togl->PbufferFlag)
+ (void) XMapWindow(dpy, window);
+ }
+#elif defined(TOGL_WGL)
+ hInstance = Tk_GetHINSTANCE();
+ if (!ToglClassInitialized) {
+ WNDCLASS ToglClass;
+
+ ToglClassInitialized = True;
+ ToglClass.style = CS_HREDRAW | CS_VREDRAW;
+ ToglClass.cbClsExtra = 0;
+ ToglClass.cbWndExtra = sizeof (LONG_PTR); /* to save Togl* */
+ ToglClass.hInstance = hInstance;
+ ToglClass.hbrBackground = NULL;
+ ToglClass.lpszMenuName = NULL;
+ ToglClass.lpszClassName = TOGL_CLASS_NAME;
+ ToglClass.lpfnWndProc = Win32WinProc;
+ ToglClass.hIcon = NULL;
+ ToglClass.hCursor = NULL;
+ if (!RegisterClass(&ToglClass)) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "unable register Togl window class", TCL_STATIC);
+ goto error;
+ }
+ }
+
+ /* duplicate tkpMakeWindow logic from tk8.[45]/win/tkWinWindow.c */
+ if (parent != None) {
+ parentWin = Tk_GetHWND(parent);
+ style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+ } else {
+ parentWin = NULL;
+ style = WS_POPUP | WS_CLIPCHILDREN;
+ }
+ if (togl->PbufferFlag) {
+ width = height = 1; /* TODO: demo code mishaves when set to 1000 */
+ } else {
+ width = togl->Width;
+ height = togl->Height;
+ }
+ hwnd = CreateWindowEx(WS_EX_NOPARENTNOTIFY, TOGL_CLASS_NAME, NULL, style,
+ 0, 0, width, height, parentWin, NULL, hInstance, NULL);
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+ window = Tk_AttachHWND(tkwin, hwnd);
+ SetWindowLongPtr(hwnd, 0, (LONG_PTR) togl);
+ if (togl->PbufferFlag) {
+ ShowWindow(hwnd, SW_HIDE); /* make sure it's hidden */
+ }
+#endif
+
+ /*
+ * Figure out which OpenGL context to use
+ */
+
+#ifdef TOGL_WGL
+ togl->tglGLHdc = GetDC(hwnd);
+#endif
+ if (togl->PixelFormat) {
+#if defined(TOGL_X11)
+ XVisualInfo template;
+ int count = 0;
+
+ template.visualid = togl->PixelFormat;
+ togl->VisInfo = XGetVisualInfo(dpy, VisualIDMask, &template, &count);
+ if (togl->VisInfo == NULL) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "missing visual information", TCL_STATIC);
+ goto error;
+ }
+#endif
+ if (!togl_describePixelFormat(togl)) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "couldn't choose pixel format", TCL_STATIC);
+ goto error;
+ }
+ } else {
+#if defined(TOGL_X11)
+ togl->VisInfo = togl_pixelFormat(togl, scrnum);
+ if (togl->VisInfo == NULL)
+#elif defined(TOGL_WGL) || defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+# ifdef TOGL_WGL
+ togl->PixelFormat = togl_pixelFormat(togl, hwnd);
+# elif defined(TOGL_NSOPENGL)
+ togl->PixelFormat = (void *)togl_pixelFormat(togl);
+# else
+ togl->PixelFormat = (Tcl_WideInt)togl_pixelFormat(togl);
+# endif
+ if (togl->PixelFormat == 0)
+#endif
+ {
+ goto error;
+ }
+ }
+#ifdef TOGL_WGL
+ if (togl->PbufferFlag) {
+ togl->pbuf = togl_createPbuffer(togl);
+ if (togl->pbuf == NULL) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "couldn't create pbuffer", TCL_STATIC);
+ goto error;
+ }
+ ReleaseDC(hwnd, togl->tglGLHdc);
+ togl->tglGLHdc = getPbufferDC(togl->pbuf);
+ createdPbufferDC = True;
+ } else if (SetPixelFormat(togl->tglGLHdc, (int) togl->PixelFormat,
+ NULL) == FALSE) {
+ Tcl_SetResult(togl->Interp, TCL_STUPID "couldn't set pixel format",
+ TCL_STATIC);
+ goto error;
+ }
+#endif
+#if defined(TOGL_WGL) || defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ if (togl->VisInfo == NULL) {
+ /*
+ * Create a new OpenGL rendering context. And check to share lists.
+ */
+ Visual *visual;
+
+ /* Just for portability, define the simplest visinfo */
+ visual = DefaultVisual(dpy, scrnum);
+ togl->VisInfo = (XVisualInfo *) calloc(1, sizeof (XVisualInfo));
+ togl->VisInfo->screen = scrnum;
+ togl->VisInfo->visual = visual;
+ togl->VisInfo->visualid = visual->visualid;
+# if defined(__cplusplus) || defined(c_plusplus)
+ togl->VisInfo->c_class = visual->c_class;
+# else
+ togl->VisInfo->class = visual->class;
+# endif
+ togl->VisInfo->depth = visual->bits_per_rgb;
+ }
+#endif
+
+#if defined(TOGL_X11)
+ if (togl->Indirect) {
+ directCtx = False;
+ }
+#endif
+
+ /*
+ * Create a new OpenGL rendering context.
+ */
+#if defined(TOGL_X11)
+ if (togl->ShareList) {
+ /* share display lists with existing togl widget */
+ Togl *shareWith = FindTogl(togl, togl->ShareList);
+ GLXContext shareCtx;
+ int error_code;
+
+ if (shareWith) {
+ shareCtx = shareWith->Ctx;
+ togl->contextTag = shareWith->contextTag;
+ } else {
+ shareCtx = None;
+ }
+ if (shareCtx) {
+ togl_SetupXErrorHandler();
+ }
+ togl->Ctx = glXCreateContext(dpy, togl->VisInfo, shareCtx, directCtx);
+ if (shareCtx && (error_code = togl_CheckForXError(togl))) {
+ char buf[256];
+
+ togl->Ctx = NULL;
+ XGetErrorText(dpy, error_code, buf, sizeof buf);
+ Tcl_AppendResult(togl->Interp,
+ "unable to share display lists: ", buf, NULL);
+ goto error;
+ }
+ } else {
+ if (togl->ShareContext && FindTogl(togl, togl->ShareContext)) {
+ /* share OpenGL context with existing Togl widget */
+ Togl *shareWith = FindTogl(togl, togl->ShareContext);
+
+ if (togl->VisInfo->visualid != shareWith->VisInfo->visualid) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "unable to share OpenGL context",
+ TCL_STATIC);
+ goto error;
+ }
+ togl->Ctx = shareWith->Ctx;
+ } else {
+ /* don't share display lists */
+ togl->ShareContext = False;
+ togl->Ctx = glXCreateContext(dpy, togl->VisInfo, None, directCtx);
+ }
+ }
+#elif defined(TOGL_WGL)
+ if (togl->ShareContext && FindTogl(togl, togl->ShareContext)) {
+ /* share OpenGL context with existing Togl widget */
+ Togl *shareWith = FindTogl(togl, togl->ShareContext);
+
+ if (togl->PixelFormat != shareWith->PixelFormat) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "unable to share OpenGL context", TCL_STATIC);
+ goto error;
+ }
+ togl->Ctx = shareWith->Ctx;
+ } else {
+ togl->Ctx = wglCreateContext(togl->tglGLHdc);
+ }
+
+ if (togl->ShareList) {
+ /* share display lists with existing togl widget */
+ Togl *shareWith = FindTogl(togl, togl->ShareList);
+
+ if (shareWith) {
+ if (!wglShareLists(shareWith->Ctx, togl->Ctx)) {
+# if 0
+ LPVOID lpMsgBuf;
+ DWORD err = GetLastError();
+
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf, 0, NULL);
+ fprintf(stderr, "unable to share display lists: %d: %s\n",
+ err, lpMsgBuf);
+ LocalFree(lpMsgBuf);
+# endif
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "unable to share display lists", TCL_STATIC);
+ goto error;
+ }
+ togl->contextTag = shareWith->contextTag;
+ }
+ }
+#elif defined(TOGL_AGL)
+ AGLContext shareCtx = NULL;
+
+ if (togl->ShareList) {
+ /* share display lists with existing togl widget */
+ Togl *shareWith = FindTogl(togl, togl->ShareList);
+
+ if (shareWith) {
+ shareCtx = shareWith->Ctx;
+ togl->contextTag = shareWith->contextTag;
+ }
+ }
+ if (togl->ShareContext && FindTogl(togl, togl->ShareContext)) {
+ /* share OpenGL context with existing Togl widget */
+ Togl *shareWith = FindTogl(togl, togl->ShareContext);
+
+ if (togl->PixelFormat != shareWith->PixelFormat) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "unable to share OpenGL context", TCL_STATIC);
+ goto error;
+ }
+ togl->Ctx = shareWith->Ctx;
+ } else if ((togl->Ctx = aglCreateContext((AGLPixelFormat) togl->PixelFormat,
+ shareCtx)) == NULL) {
+ GLenum err = aglGetError();
+
+ aglDestroyPixelFormat((AGLPixelFormat) togl->PixelFormat);
+ togl->PixelFormat = 0;
+ if (err == AGL_BAD_MATCH)
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "unable to share display lists"
+ ": shared context doesn't match", TCL_STATIC);
+ else if (err == AGL_BAD_CONTEXT)
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "unable to share display lists"
+ ": bad shared context", TCL_STATIC);
+ else if (err == AGL_BAD_PIXELFMT)
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "could not create rendering context"
+ ": bad pixel format", TCL_STATIC);
+ else
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "could not create rendering context"
+ ": unknown reason", TCL_STATIC);
+ goto error;
+ }
+
+ if (!togl->PbufferFlag
+ && !aglSetDrawable(togl->Ctx, Togl_MacOSXGetDrawablePort(togl))) {
+ /* aglSetDrawable is deprecated in OS X 10.5 */
+ aglDestroyContext(togl->Ctx);
+ togl->Ctx = NULL;
+ aglDestroyPixelFormat((AGLPixelFormat) togl->PixelFormat);
+ togl->PixelFormat = 0;
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "couldn't set drawable", TCL_STATIC);
+ goto error;
+ }
+#elif defined(TOGL_NSOPENGL)
+ NSOpenGLContext *shareCtx = NULL;
+ if (togl->ShareList) {
+ /* share display lists with existing togl widget */
+ Togl *shareWith = FindTogl(togl, togl->ShareList);
+
+ if (shareWith) {
+ shareCtx = shareWith->Ctx;
+ togl->contextTag = shareWith->contextTag;
+ }
+ }
+ if (togl->ShareContext && FindTogl(togl, togl->ShareContext)) {
+ /* share OpenGL context with existing Togl widget */
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "unable to share NSOpenGL context", TCL_STATIC);
+ goto error;
+ /*
+ Togl *shareWith = FindTogl(togl, togl->ShareContext);
+
+ if (togl->PixelFormat != shareWith->PixelFormat) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "unable to share OpenGL context", TCL_STATIC);
+ goto error;
+ }
+ togl->Ctx = [[NSOpenGLContext alloc] initWithCGLContextObj:shareWith->Ctx];
+ */
+ /* initWithCGLContextObj requires Mac OS 10.6 */
+ } else {
+ togl->Ctx = [NSOpenGLContext alloc];
+ if ([togl->Ctx initWithFormat:togl->PixelFormat shareContext:shareCtx]
+ == nil)
+ {
+ [togl->PixelFormat release];
+ togl->PixelFormat = 0;
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "Could not obtain OpenGL context",
+ TCL_STATIC);
+ goto error;
+ }
+ }
+
+ if (!togl->PbufferFlag) {
+ togl->nsview = [[ToglNSView alloc] initWithFrame:NSZeroRect];
+ [togl->nsview setTogl:togl];
+ if ([togl->nsview respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
+ [togl->nsview setWantsBestResolutionOpenGLSurface:YES];
+ }
+ [togl->nsview setAcceptsTouchEvents:YES];
+ MacDrawable *d = ((TkWindow *) togl->TkWin)->privatePtr;
+ NSView *topview = d->toplevel->view;
+ [topview addSubview:togl->nsview];
+ /* TODO: Appears setView has to be deferred until window mapped.
+ * or it gives "invalid drawable" error. But MapNotify doesn't happen.
+ * I think toplevel is already mapped. Iconifying and uniconifying
+ * main window makes the graphics work.
+ */
+ /* [togl->Ctx setView:togl->nsview];*/
+ }
+#endif
+
+ if (togl->Ctx == NULL) {
+ Tcl_SetResult(togl->Interp,
+ TCL_STUPID "could not create rendering context", TCL_STATIC);
+ goto error;
+ }
+#if defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ CGDisplayRegisterReconfigurationCallback(ReconfigureCB, togl);
+#endif
+
+ if (togl->PbufferFlag) {
+ /* Don't need a colormap, nor overlay, nor be displayed */
+#if defined(TOGL_X11) || defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ togl->pbuf = togl_createPbuffer(togl);
+ if (!togl->pbuf) {
+ /* tcl result set in togl_createPbuffer */
+# ifdef TOGL_AGL
+ if (!togl->ShareContext) {
+ aglDestroyContext(togl->Ctx);
+ aglDestroyPixelFormat((AGLPixelFormat) togl->PixelFormat);
+ }
+ togl->Ctx = NULL;
+ togl->PixelFormat = 0;
+# endif
+# ifdef TOGL_NSOPENGL
+ if (!togl->ShareContext) {
+ [togl->Ctx release];
+ [togl->PixelFormat release];
+ }
+ togl->Ctx = NULL;
+ togl->PixelFormat = 0;
+# endif
+ goto error;
+ }
+# ifdef TOGL_X11
+ window = TkpMakeWindow((TkWindow *) tkwin, parent);
+# endif
+#endif
+ return window;
+ }
+#ifdef TOGL_WGL
+ DescribePixelFormat(togl->tglGLHdc, (int) togl->PixelFormat, sizeof (pfd),
+ &pfd);
+#endif
+
+ /*
+ * find a colormap
+ */
+ if (togl->RgbaFlag) {
+ /* Colormap for RGB mode */
+#if defined(TOGL_X11)
+ cmap = get_rgb_colormap(dpy, scrnum, togl->VisInfo, tkwin);
+#elif defined(TOGL_WGL)
+ if (pfd.dwFlags & PFD_NEED_PALETTE) {
+ cmap = Win32CreateRgbColormap(pfd);
+ } else {
+ cmap = DefaultColormap(dpy, scrnum);
+ }
+#elif defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ cmap = DefaultColormap(dpy, scrnum);
+#endif
+ } else {
+ /* Colormap for CI mode */
+#ifdef TOGL_WGL
+ /* this logic is to overcome a combination driver/compiler bug: (1)
+ * cColorBits may be unusally large (e.g., 32 instead of 8 or 12) and
+ * (2) 1 << 32 might be 1 instead of zero (gcc for ia32) */
+ if (pfd.cColorBits >= MAX_CI_COLORMAP_BITS) {
+ togl->CiColormapSize = MAX_CI_COLORMAP_SIZE;
+ } else {
+ togl->CiColormapSize = 1 << pfd.cColorBits;
+ if (togl->CiColormapSize >= MAX_CI_COLORMAP_SIZE)
+ togl->CiColormapSize = MAX_CI_COLORMAP_SIZE;
+ }
+
+#endif
+ if (togl->PrivateCmapFlag) {
+ /* need read/write colormap so user can store own color entries */
+#if defined(TOGL_X11)
+ cmap = XCreateColormap(dpy, XRootWindow(dpy, togl->VisInfo->screen),
+ togl->VisInfo->visual, AllocAll);
+#elif defined(TOGL_WGL)
+ cmap = Win32CreateCiColormap(togl);
+#elif defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ /* need to figure out how to do this correctly on Mac... */
+ cmap = DefaultColormap(dpy, scrnum);
+#endif
+ } else {
+ if (togl->VisInfo->visual == DefaultVisual(dpy, scrnum)) {
+ /* share default/root colormap */
+ cmap = Tk_Colormap(tkwin);
+ } else {
+ /* make a new read-only colormap */
+ cmap = XCreateColormap(dpy,
+ XRootWindow(dpy, togl->VisInfo->screen),
+ togl->VisInfo->visual, AllocNone);
+ }
+ }
+ }
+
+ /* Make sure Tk knows to switch to the new colormap when the cursor is over
+ * this window when running in color index mode. */
+ (void) Tk_SetWindowVisual(tkwin, togl->VisInfo->visual,
+ togl->VisInfo->depth, cmap);
+
+#ifdef TOGL_WGL
+ /* Install the colormap */
+ SelectPalette(togl->tglGLHdc, ((TkWinColormap *) cmap)->palette, TRUE);
+ RealizePalette(togl->tglGLHdc);
+#endif
+
+#if defined(TOGL_X11)
+ swa.background_pixmap = None;
+ swa.border_pixel = 0;
+ swa.colormap = cmap;
+ swa.event_mask = ALL_EVENTS_MASK;
+ if (togl->PbufferFlag) {
+ width = height = 1;
+ } else {
+ width = togl->Width;
+ height = togl->Height;
+ }
+ window = XCreateWindow(dpy, parent,
+ 0, 0, width, height,
+ 0, togl->VisInfo->depth, InputOutput, togl->VisInfo->visual,
+ CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask, &swa);
+ /* Make sure window manager installs our colormap */
+ (void) XSetWMColormapWindows(dpy, window, &window, 1);
+
+ if (!togl->DoubleFlag) {
+ int dbl_flag;
+
+ /* See if we requested single buffering but had to accept a double
+ * buffered visual. If so, set the GL draw buffer to be the front
+ * buffer to simulate single buffering. */
+ if (glXGetConfig(dpy, togl->VisInfo, GLX_DOUBLEBUFFER, &dbl_flag)) {
+ if (dbl_flag) {
+ glXMakeCurrent(dpy, window, togl->Ctx);
+ glDrawBuffer(GL_FRONT);
+ glReadBuffer(GL_FRONT);
+ }
+ }
+ }
+#elif defined(TOGL_WGL)
+ if (!togl->DoubleFlag) {
+ /* See if we requested single buffering but had to accept a double
+ * buffered visual. If so, set the GL draw buffer to be the front
+ * buffer to simulate single buffering. */
+ if (getPixelFormatAttribiv == NULL) {
+ /* pfd is already set */
+ if ((pfd.dwFlags & PFD_DOUBLEBUFFER) != 0) {
+ wglMakeCurrent(togl->tglGLHdc, togl->Ctx);
+ glDrawBuffer(GL_FRONT);
+ glReadBuffer(GL_FRONT);
+ }
+ } else {
+ static int attribs[] = {
+ WGL_DOUBLE_BUFFER_ARB,
+ };
+# define NUM_ATTRIBS (sizeof attribs / sizeof attribs[0])
+ int info[NUM_ATTRIBS];
+
+ getPixelFormatAttribiv(togl->tglGLHdc, (int) togl->PixelFormat, 0,
+ NUM_ATTRIBS, attribs, info);
+# undef NUM_ATTRIBS
+ if (info[0]) {
+ wglMakeCurrent(togl->tglGLHdc, togl->Ctx);
+ glDrawBuffer(GL_FRONT);
+ glReadBuffer(GL_FRONT);
+ }
+ }
+ }
+#endif
+
+#if TOGL_USE_OVERLAY
+ if (togl->OverlayFlag) {
+ if (SetupOverlay(togl) == TCL_ERROR) {
+ fprintf(stderr, "Warning: couldn't setup overlay.\n");
+ togl->OverlayFlag = False;
+ }
+ }
+#endif
+
+#if !defined(TOGL_AGL)
+ /* Request the X window to be displayed */
+ (void) XMapWindow(dpy, window);
+#endif
+
+ if (!togl->RgbaFlag) {
+ int index_size;
+
+#if defined(TOGL_X11) || defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ GLint index_bits;
+
+ glGetIntegerv(GL_INDEX_BITS, &index_bits);
+ index_size = 1 << index_bits;
+#elif defined(TOGL_WGL)
+ index_size = togl->CiColormapSize;
+#endif
+ if (togl->MapSize != index_size) {
+ if (togl->RedMap)
+ free(togl->RedMap);
+ if (togl->GreenMap)
+ free(togl->GreenMap);
+ if (togl->BlueMap)
+ free(togl->BlueMap);
+ togl->MapSize = index_size;
+ togl->RedMap = (GLfloat *) calloc(index_size, sizeof (GLfloat));
+ togl->GreenMap = (GLfloat *) calloc(index_size, sizeof (GLfloat));
+ togl->BlueMap = (GLfloat *) calloc(index_size, sizeof (GLfloat));
+ }
+ }
+#ifdef HAVE_AUTOSTEREO
+ if (togl->Stereo == TOGL_STEREO_NATIVE) {
+ if (!togl->as_initialized) {
+ const char *autostereod;
+
+ togl->as_initialized = True;
+ if ((autostereod = getenv("AUTOSTEREOD")) == NULL)
+ autostereod = AUTOSTEREOD;
+ if (autostereod && *autostereod) {
+ if (ASInitialize(togl->display, autostereod) == Success) {
+ togl->ash = ASCreatedStereoWindow(dpy);
+ }
+ }
+ } else {
+ togl->ash = ASCreatedStereoWindow(dpy);
+ }
+ }
+#endif
+
+ return window;
+
+ error:
+
+ togl->badWindow = True;
+
+#if defined(TOGL_X11)
+ if (window == None) {
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
+ window = TkpMakeWindow(winPtr, parent);
+ }
+#elif defined(TOGL_WGL)
+ if (togl->tglGLHdc) {
+ if (createdPbufferDC)
+ releasePbufferDC(togl->pbuf, togl->tglGLHdc);
+ else
+ ReleaseDC(hwnd, togl->tglGLHdc);
+ togl->tglGLHdc = NULL;
+ }
+#endif
+ return window;
+}
+
+/*
+ * Togl_WorldChanged
+ *
+ * Add support for setgrid option.
+ */
+static void
+Togl_WorldChanged(ClientData instanceData)
+{
+ Togl *togl = (Togl *) instanceData;
+ int width;
+ int height;
+
+ if (togl->PbufferFlag)
+ width = height = 1;
+ else {
+ width = togl->Width;
+ height = togl->Height;
+ }
+ Tk_GeometryRequest(togl->TkWin, width, height);
+ Tk_SetInternalBorder(togl->TkWin, 0);
+ if (togl->SetGrid > 0) {
+ Tk_SetGrid(togl->TkWin, width / togl->SetGrid,
+ height / togl->SetGrid, togl->SetGrid, togl->SetGrid);
+ } else {
+ Tk_UnsetGrid(togl->TkWin);
+ }
+}
+
+static void
+Togl_SetViewPort(const struct Togl *togl)
+{
+ glViewport(0, 0, togl->Width*togl->PixelScale, togl->Height*togl->PixelScale);
+}
+
+/*
+ * ToglFree
+ *
+ * Wrap the ckfree macro.
+ */
+static void
+ToglFree(char *clientData)
+{
+ ckfree(clientData);
+}
+
+/*
+ * ToglCmdDeletedProc
+ *
+ * This procedure is invoked when a widget command is deleted. If
+ * the widget isn't already in the process of being destroyed,
+ * this command destroys it.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The widget is destroyed.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+ToglCmdDeletedProc(ClientData clientData)
+{
+ Togl *togl = (Togl *) clientData;
+ Tk_Window tkwin = togl->TkWin;
+
+ /*
+ * This procedure could be invoked either because the window was
+ * destroyed and the command was then deleted (in which case tkwin
+ * is NULL) or because the command was deleted, and then this procedure
+ * destroys the widget.
+ */
+
+ if (tkwin) {
+ Tk_DeleteEventHandler(tkwin, ExposureMask | StructureNotifyMask,
+ Togl_EventProc, (ClientData) togl);
+ }
+
+ Tk_Preserve((ClientData) togl);
+ Tcl_EventuallyFree((ClientData) togl, ToglFree);
+
+ Togl_LeaveStereo(togl, togl->Stereo);
+
+ if (togl->DestroyProc) {
+ /* call user's cleanup code */
+ Togl_CallCallback(togl, togl->DestroyProc);
+ }
+
+ if (togl->TimerProc != NULL) {
+ Tcl_DeleteTimerHandler(togl->timerHandler);
+ togl->timerHandler = NULL;
+ }
+ if (togl->UpdatePending) {
+ Tcl_CancelIdleCall(Togl_Render, (ClientData) togl);
+ togl->UpdatePending = False;
+ }
+#ifndef NO_TK_CURSOR
+ if (togl->Cursor != None) {
+ Tk_FreeCursor(togl->display, togl->Cursor);
+ togl->Cursor = None;
+ }
+#endif
+
+ /* remove from linked list */
+ RemoveFromList(togl);
+
+ togl->TkWin = NULL;
+ if (tkwin != NULL) {
+
+ if (togl->Ctx) {
+ if (FindToglWithSameContext(togl) == NULL) {
+#if defined(TOGL_X11)
+ glXDestroyContext(togl->display, togl->Ctx);
+#elif defined(TOGL_WGL)
+ wglDeleteContext(togl->Ctx);
+#elif defined(TOGL_AGL)
+ aglDestroyContext(togl->Ctx);
+ CGDisplayRemoveReconfigurationCallback(ReconfigureCB, togl);
+#elif defined(TOGL_NSOPENGL)
+ [togl->Ctx release];
+ togl->Ctx = nil;
+ [togl->nsview setTogl:nil];
+ [togl->nsview release];
+ togl->nsview = nil;
+ CGDisplayRemoveReconfigurationCallback(ReconfigureCB, togl);
+#endif
+#if defined(TOGL_X11)
+ XFree(togl->VisInfo);
+#else
+ free(togl->VisInfo);
+#endif
+ }
+#if defined(TOGL_WGL)
+ if (togl->tglGLHdc) {
+ if (togl->PbufferFlag) {
+ releasePbufferDC(togl->pbuf, togl->tglGLHdc);
+ } else {
+ HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));
+
+ ReleaseDC(hwnd, togl->tglGLHdc);
+ }
+ togl->tglGLHdc = NULL;
+ }
+#endif
+ if (togl->PbufferFlag && togl->pbuf) {
+ togl_destroyPbuffer(togl);
+ togl->pbuf = 0;
+ }
+ togl->Ctx = NULL;
+ togl->VisInfo = NULL;
+ }
+#if defined(TOGL_X11)
+# if TOGL_USE_OVERLAY
+ if (togl->OverlayCtx) {
+ Tcl_HashEntry *entryPtr;
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
+ if (winPtr) {
+ entryPtr = Tcl_FindHashEntry(&winPtr->dispPtr->winTable,
+ (const char *) togl->OverlayWindow);
+ Tcl_DeleteHashEntry(entryPtr);
+ }
+ if (FindToglWithSameOverlayContext(togl) == NULL)
+ glXDestroyContext(togl->display, togl->OverlayCtx);
+ togl->OverlayCtx = NULL;
+ }
+# endif /* TOGL_USE_OVERLAY */
+#endif
+
+ if (togl->SetGrid > 0) {
+ Tk_UnsetGrid(tkwin);
+ }
+ Tk_DestroyWindow(tkwin);
+ }
+
+ Tk_Release((ClientData) togl);
+}
+
+
+/*
+ * This gets called to track top level position changes for
+ * row interleaved stereo.
+ */
+static void
+Togl_RedisplayProc(ClientData clientData, XEvent *eventPtr)
+{
+ Togl *togl = (Togl *) clientData;
+
+ switch (eventPtr->type) {
+ case ConfigureNotify:
+ Togl_PostRedisplay(togl);
+ break;
+ }
+}
+
+#if defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+static int
+viewPixelScale(NSView *nsview)
+{
+ int pixelScale = 1;
+ if ([nsview respondsToSelector:@selector(convertRectToBacking:)])
+ {
+ NSRect wbounds = [nsview bounds];
+ NSRect gbounds = [nsview convertRectToBacking:wbounds];
+ pixelScale = (wbounds.size.width > 0 ?
+ gbounds.size.width / wbounds.size.width : 1);
+ }
+ return pixelScale;
+}
+#endif
+
+/*
+ * This gets called to handle Togl window configuration events
+ */
+static void
+Togl_EventProc(ClientData clientData, XEvent *eventPtr)
+{
+ Togl *togl = (Togl *) clientData;
+
+ switch (eventPtr->type) {
+ case Expose:
+#if defined(TOGL_NSOPENGL)
+ if (!Tk_IsMapped(togl->TkWin))
+ /* Tk Cocoa generates expose events for unmapped windows! */
+ break;
+#endif
+ if (eventPtr->xexpose.count == 0) {
+ if (!togl->UpdatePending
+ && eventPtr->xexpose.window == Tk_WindowId(togl->TkWin)) {
+ Togl_PostRedisplay(togl);
+ }
+#if defined(TOGL_X11)
+ if (!togl->OverlayUpdatePending && togl->OverlayFlag
+ && togl->OverlayIsMapped
+ && eventPtr->xexpose.window == togl->OverlayWindow) {
+ Togl_PostOverlayRedisplay(togl);
+ }
+#endif
+#if defined(TOGL_NSOPENGL)
+ [togl->Ctx setView:togl->nsview];
+ SetMacBufRect(togl);
+#endif
+ }
+ break;
+ case ConfigureNotify:
+ if (togl->PbufferFlag)
+ break;
+#if defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ int pixelScale = viewPixelScale(togl->nsview);
+ if (togl->Width == Tk_Width(togl->TkWin)
+ && togl->Height == Tk_Height(togl->TkWin)
+ && togl->PixelScale == pixelScale) {
+
+ // Even though the size hasn't changed,
+ // it's position on the screen may have.
+ if (Tk_IsMapped(togl->TkWin))
+ SetMacBufRect(togl);
+ break;
+ }
+#endif
+ togl->Width = Tk_Width(togl->TkWin);
+ togl->Height = Tk_Height(togl->TkWin);
+#if defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ togl->PixelScale = pixelScale;
+#endif
+ (void) XResizeWindow(Tk_Display(togl->TkWin),
+ Tk_WindowId(togl->TkWin), togl->Width, togl->Height);
+#if defined(TOGL_X11)
+ if (togl->OverlayFlag) {
+ (void) XResizeWindow(Tk_Display(togl->TkWin),
+ togl->OverlayWindow, togl->Width, togl->Height);
+ (void) XRaiseWindow(Tk_Display(togl->TkWin), togl->OverlayWindow);
+ }
+#endif
+
+#if defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ SetMacBufRect(togl);
+#endif
+
+ Togl_MakeCurrent(togl);
+ if (togl->ReshapeProc) {
+ Togl_SetViewPort(togl);
+ (void) Togl_CallCallback(togl, togl->ReshapeProc);
+ } else {
+ Togl_SetViewPort(togl);
+#if defined(TOGL_X11)
+ if (togl->OverlayFlag) {
+ Togl_UseLayer(togl, TOGL_OVERLAY);
+ Togl_SetViewPort(togl);
+ Togl_UseLayer(togl, TOGL_NORMAL);
+ }
+#endif
+ }
+ break;
+ case MapNotify:
+#if defined(TOGL_AGL)
+ if (!togl->PbufferFlag) {
+ /*
+ * See comment for the UnmapNotify case below.
+ */
+ AGLDrawable d = Togl_MacOSXGetDrawablePort(togl);
+
+ /* aglSetDrawable is deprecated in OS X 10.5 */
+ aglSetDrawable(togl->Ctx, d);
+ SetMacBufRect(togl);
+ }
+#endif
+#if defined(TOGL_NSOPENGL)
+ if (!togl->PbufferFlag) {
+ /*
+ * See comment for the UnmapNotify case below.
+ */
+ [togl->Ctx setView:togl->nsview];
+ SetMacBufRect(togl);
+ }
+#endif
+ break;
+ case UnmapNotify:
+#if defined(TOGL_AGL)
+ if (!togl->PbufferFlag) {
+ /*
+ * For Mac OS X Aqua, Tk subwindows are not implemented as
+ * separate Aqua windows. They are just different regions of
+ * a single Aqua window. To unmap them they are just not drawn.
+ * Have to disconnect the AGL context otherwise they will continue
+ * to be displayed directly by Aqua.
+ */
+ /* aglSetDrawable is deprecated in OS X 10.5 */
+ aglSetDrawable(togl->Ctx, NULL);
+ }
+#endif
+#if defined(TOGL_NSOPENGL)
+ if (!togl->PbufferFlag) {
+ /*
+ * For Mac OS X Aqua, Tk subwindows are not implemented as
+ * separate Aqua windows. They are just different regions of
+ * a single Aqua window. To unmap them they are just not drawn.
+ * Have to disconnect the NSView otherwise they will continue
+ * to be displayed directly by Aqua.
+ */
+ [togl->Ctx clearDrawable];
+ }
+#endif
+ break;
+ case DestroyNotify:
+ if (togl->TkWin != NULL) {
+#ifdef TOGL_WGL
+ HWND hwnd = Tk_GetHWND(Tk_WindowId(togl->TkWin));
+
+ /* Prevent Win32WinProc from calling Tcl_DeleteCommandFromToken
+ * a second time */
+ SetWindowLongPtr(hwnd, 0, (LONG_PTR) 0);
+#endif
+ if (togl->SetGrid > 0) {
+ Tk_UnsetGrid(togl->TkWin);
+ }
+ (void) Tcl_DeleteCommandFromToken(togl->Interp, togl->widgetCmd);
+ }
+ break;
+ default:
+ /* nothing */
+ ;
+ }
+}
+
+
+void
+Togl_PostRedisplay(Togl *togl)
+{
+ if (!togl->UpdatePending) {
+ togl->UpdatePending = True;
+ Tk_DoWhenIdle(Togl_Render, (ClientData) togl);
+ }
+}
+
+
+Bool
+Togl_UpdatePending(const Togl *togl)
+{
+ return togl->UpdatePending;
+}
+
+
+void
+Togl_SwapBuffers(const Togl *togl)
+{
+ if (togl->DoubleFlag) {
+#if defined(TOGL_WGL)
+ int res = SwapBuffers(togl->tglGLHdc);
+
+ if (!res) {
+ ErrorExit(TEXT("SwapBuffers"));
+ }
+#elif defined(TOGL_X11)
+ glXSwapBuffers(Tk_Display(togl->TkWin), Tk_WindowId(togl->TkWin));
+#elif defined(TOGL_AGL)
+ aglSwapBuffers(togl->Ctx);
+#elif defined(TOGL_NSOPENGL)
+ [togl->Ctx flushBuffer];
+#endif
+ } else {
+ glFlush();
+ }
+}
+
+
+
+const char *
+Togl_Ident(const Togl *togl)
+{
+ return togl->Ident;
+}
+
+
+int
+Togl_Width(const Togl *togl)
+{
+ return togl->Width;
+}
+
+
+int
+Togl_Height(const Togl *togl)
+{
+ return togl->Height;
+}
+
+int
+Togl_PixelScale(const Togl *togl)
+{
+ return togl->PixelScale;
+}
+
+
+Tcl_Interp *
+Togl_Interp(const Togl *togl)
+{
+ return togl->Interp;
+}
+
+
+Tk_Window
+Togl_TkWin(const Togl *togl)
+{
+ return togl->TkWin;
+}
+
+
+const char *
+Togl_CommandName(const Togl *togl)
+{
+ return Tcl_GetCommandName(togl->Interp, togl->widgetCmd);
+}
+
+int
+Togl_ContextTag(const Togl *togl)
+{
+ return togl->contextTag;
+}
+
+Bool
+Togl_HasRGBA(const Togl *togl)
+{
+ return togl->RgbaFlag;
+}
+
+Bool
+Togl_IsDoubleBuffered(const Togl *togl)
+{
+ return togl->DoubleFlag;
+}
+
+Bool
+Togl_HasDepthBuffer(const Togl *togl)
+{
+ return togl->DepthFlag;
+}
+
+Bool
+Togl_HasAccumulationBuffer(const Togl *togl)
+{
+ return togl->AccumFlag;
+}
+
+Bool
+Togl_HasDestinationAlpha(const Togl *togl)
+{
+ return togl->AlphaFlag;
+}
+
+Bool
+Togl_HasStencilBuffer(const Togl *togl)
+{
+ return togl->StencilFlag;
+}
+
+int
+Togl_StereoMode(const Togl *togl)
+{
+ return togl->Stereo;
+}
+
+Bool
+Togl_HasMultisample(const Togl *togl)
+{
+ return togl->MultisampleFlag;
+}
+
+
+#if defined(TOGL_X11)
+/*
+ * A replacement for XAllocColor. This function should never
+ * fail to allocate a color. When XAllocColor fails, we return
+ * the nearest matching color. If we have to allocate many colors
+ * this function isn't too efficient; the XQueryColors() could be
+ * done just once.
+ * Written by Michael Pichler, Brian Paul, Mark Kilgard
+ * Input: dpy - X display
+ * cmap - X colormap
+ * cmapSize - size of colormap
+ * In/Out: color - the XColor struct
+ * Output: exact - 1=exact color match, 0=closest match
+ */
+static void
+noFaultXAllocColor(Display *dpy, Colormap cmap, int cmapSize,
+ XColor *color, int *exact)
+{
+ XColor *ctable, subColor;
+ int i, bestmatch;
+ double mindist; /* 3*2^16^2 exceeds long int precision. */
+
+ /* First try just using XAllocColor. */
+ if (XAllocColor(dpy, cmap, color)) {
+ *exact = 1;
+ return;
+ }
+
+ /* Retrieve color table entries. */
+ /* XXX alloca candidate. */
+ ctable = (XColor *) ckalloc(cmapSize * sizeof (XColor));
+ for (i = 0; i < cmapSize; i++) {
+ ctable[i].pixel = i;
+ }
+ (void) XQueryColors(dpy, cmap, ctable, cmapSize);
+
+ /* Find best match. */
+ bestmatch = -1;
+ mindist = 0;
+ for (i = 0; i < cmapSize; i++) {
+ double dr = (double) color->red - (double) ctable[i].red;
+ double dg = (double) color->green - (double) ctable[i].green;
+ double db = (double) color->blue - (double) ctable[i].blue;
+ double dist = dr * dr + dg * dg + db * db;
+
+ if (bestmatch < 0 || dist < mindist) {
+ bestmatch = i;
+ mindist = dist;
+ }
+ }
+
+ /* Return result. */
+ subColor.red = ctable[bestmatch].red;
+ subColor.green = ctable[bestmatch].green;
+ subColor.blue = ctable[bestmatch].blue;
+ ckfree((char *) ctable);
+ /* Try to allocate the closest match color. This should only fail if the
+ * cell is read/write. Otherwise, we're incrementing the cell's reference
+ * count. */
+ if (!XAllocColor(dpy, cmap, &subColor)) {
+ /* do this to work around a problem reported by Frank Ortega */
+ subColor.pixel = (unsigned long) bestmatch;
+ subColor.red = ctable[bestmatch].red;
+ subColor.green = ctable[bestmatch].green;
+ subColor.blue = ctable[bestmatch].blue;
+ subColor.flags = DoRed | DoGreen | DoBlue;
+ }
+ *color = subColor;
+}
+
+#elif defined(TOGL_WGL)
+
+static UINT
+Win32AllocColor(const Togl *togl, float red, float green, float blue)
+{
+ /* Modified version of XAllocColor emulation of Tk. - returns index,
+ * instead of color itself - allocates logical palette entry even for
+ * non-palette devices */
+
+ TkWinColormap *cmap = (TkWinColormap *) Tk_Colormap(togl->TkWin);
+ UINT index;
+ COLORREF newColor, closeColor;
+ PALETTEENTRY entry, closeEntry;
+ int isNew, refCount;
+ Tcl_HashEntry *entryPtr;
+
+ entry.peRed = (unsigned char) (red * 255 + .5);
+ entry.peGreen = (unsigned char) (green * 255 + .5);
+ entry.peBlue = (unsigned char) (blue * 255 + .5);
+ entry.peFlags = 0;
+
+ /*
+ * Find the nearest existing palette entry.
+ */
+
+ newColor = RGB(entry.peRed, entry.peGreen, entry.peBlue);
+ index = GetNearestPaletteIndex(cmap->palette, newColor);
+ GetPaletteEntries(cmap->palette, index, 1, &closeEntry);
+ closeColor = RGB(closeEntry.peRed, closeEntry.peGreen, closeEntry.peBlue);
+
+ /*
+ * If this is not a duplicate and colormap is not full, allocate a new entry.
+ */
+
+ if (newColor != closeColor) {
+ if (cmap->size == (unsigned int) togl->CiColormapSize) {
+ entry = closeEntry;
+ } else {
+ cmap->size++;
+ ResizePalette(cmap->palette, cmap->size);
+ index = cmap->size - 1;
+ SetPaletteEntries(cmap->palette, index, 1, &entry);
+ SelectPalette(togl->tglGLHdc, cmap->palette, TRUE);
+ RealizePalette(togl->tglGLHdc);
+ }
+ }
+ newColor = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue);
+ entryPtr = Tcl_CreateHashEntry(&cmap->refCounts,
+ (CONST char *) newColor, &isNew);
+ if (isNew) {
+ refCount = 1;
+ } else {
+ refCount = ((int) Tcl_GetHashValue(entryPtr)) + 1;
+ }
+ Tcl_SetHashValue(entryPtr, (ClientData) refCount);
+
+ /* for color index mode photos */
+ togl->RedMap[index] = (GLfloat) (entry.peRed / 255.0);
+ togl->GreenMap[index] = (GLfloat) (entry.peGreen / 255.0);
+ togl->BlueMap[index] = (GLfloat) (entry.peBlue / 255.0);
+ return index;
+}
+
+static void
+Win32FreeColor(const Togl *togl, unsigned long index)
+{
+ TkWinColormap *cmap = (TkWinColormap *) Tk_Colormap(togl->TkWin);
+ COLORREF cref;
+ UINT count, refCount;
+ PALETTEENTRY entry, *entries;
+ Tcl_HashEntry *entryPtr;
+
+ if (index >= cmap->size) {
+ panic("Tried to free a color that isn't allocated.");
+ }
+ GetPaletteEntries(cmap->palette, index, 1, &entry);
+
+ cref = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue);
+ entryPtr = Tcl_FindHashEntry(&cmap->refCounts, (CONST char *) cref);
+ if (!entryPtr) {
+ panic("Tried to free a color that isn't allocated.");
+ }
+ refCount = (int) Tcl_GetHashValue(entryPtr) - 1;
+ if (refCount == 0) {
+ count = cmap->size - index;
+ entries = (PALETTEENTRY *) ckalloc(sizeof (PALETTEENTRY) * count);
+ GetPaletteEntries(cmap->palette, index + 1, count, entries);
+ SetPaletteEntries(cmap->palette, index, count, entries);
+ SelectPalette(togl->tglGLHdc, cmap->palette, TRUE);
+ RealizePalette(togl->tglGLHdc);
+ ckfree((char *) entries);
+ cmap->size--;
+ Tcl_DeleteHashEntry(entryPtr);
+ } else {
+ Tcl_SetHashValue(entryPtr, (ClientData) refCount);
+ }
+}
+
+static void
+Win32SetColor(const Togl *togl,
+ unsigned long index, float red, float green, float blue)
+{
+ TkWinColormap *cmap = (TkWinColormap *) Tk_Colormap(togl->TkWin);
+ PALETTEENTRY entry;
+
+ entry.peRed = (unsigned char) (red * 255 + .5);
+ entry.peGreen = (unsigned char) (green * 255 + .5);
+ entry.peBlue = (unsigned char) (blue * 255 + .5);
+ entry.peFlags = 0;
+ SetPaletteEntries(cmap->palette, index, 1, &entry);
+ SelectPalette(togl->tglGLHdc, cmap->palette, TRUE);
+ RealizePalette(togl->tglGLHdc);
+
+ /* for color index mode photos */
+ togl->RedMap[index] = (GLfloat) (entry.peRed / 255.0);
+ togl->GreenMap[index] = (GLfloat) (entry.peGreen / 255.0);
+ togl->BlueMap[index] = (GLfloat) (entry.peBlue / 255.0);
+}
+#endif /* TOGL_X11 */
+
+
+unsigned long
+Togl_AllocColor(const Togl *togl, float red, float green, float blue)
+{
+ if (togl->RgbaFlag) {
+ (void) fprintf(stderr,
+ "Error: Togl_AllocColor illegal in RGBA mode.\n");
+ return 0;
+ }
+ /* TODO: maybe not... */
+ if (togl->PrivateCmapFlag) {
+ (void) fprintf(stderr,
+ "Error: Togl_AllocColor illegal with private colormap\n");
+ return 0;
+ }
+#if defined(TOGL_X11)
+ {
+ XColor xcol;
+ int exact;
+
+ xcol.red = (short) (red * 65535.0);
+ xcol.green = (short) (green * 65535.0);
+ xcol.blue = (short) (blue * 65535.0);
+
+ noFaultXAllocColor(Tk_Display(togl->TkWin), Tk_Colormap(togl->TkWin),
+ Tk_Visual(togl->TkWin)->map_entries, &xcol, &exact);
+ /* for color index mode photos */
+ togl->RedMap[xcol.pixel] = (float) xcol.red / 65535.0;
+ togl->GreenMap[xcol.pixel] = (float) xcol.green / 65535.0;
+ togl->BlueMap[xcol.pixel] = (float) xcol.blue / 65535.0;
+
+ return xcol.pixel;
+ }
+
+#elif defined(TOGL_WGL)
+ return Win32AllocColor(togl, red, green, blue);
+
+#elif defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+ /* still need to implement this on Mac... */
+ return 0;
+
+#endif
+}
+
+
+
+void
+Togl_FreeColor(const Togl *togl, unsigned long pixel)
+{
+ if (togl->RgbaFlag) {
+ (void) fprintf(stderr, "Error: Togl_FreeColor illegal in RGBA mode.\n");
+ return;
+ }
+ /* TODO: maybe not... */
+ if (togl->PrivateCmapFlag) {
+ (void) fprintf(stderr,
+ "Error: Togl_FreeColor illegal with private colormap\n");
+ return;
+ }
+#if defined(TOGL_X11)
+ (void) XFreeColors(Tk_Display(togl->TkWin), Tk_Colormap(togl->TkWin),
+ &pixel, 1, 0);
+#elif defined(TOGL_WGL)
+ Win32FreeColor(togl, pixel);
+#endif
+}
+
+
+
+void
+Togl_SetColor(const Togl *togl,
+ unsigned long index, float red, float green, float blue)
+{
+
+ if (togl->RgbaFlag) {
+ (void) fprintf(stderr, "Error: Togl_SetColor illegal in RGBA mode.\n");
+ return;
+ }
+ if (!togl->PrivateCmapFlag) {
+ (void) fprintf(stderr,
+ "Error: Togl_SetColor requires a private colormap\n");
+ return;
+ }
+#if defined(TOGL_X11)
+ {
+ XColor xcol;
+
+ xcol.pixel = index;
+ xcol.red = (short) (red * 65535.0);
+ xcol.green = (short) (green * 65535.0);
+ xcol.blue = (short) (blue * 65535.0);
+ xcol.flags = DoRed | DoGreen | DoBlue;
+
+ (void) XStoreColor(Tk_Display(togl->TkWin), Tk_Colormap(togl->TkWin),
+ &xcol);
+
+ /* for color index mode photos */
+ togl->RedMap[xcol.pixel] = (float) xcol.red / 65535.0;
+ togl->GreenMap[xcol.pixel] = (float) xcol.green / 65535.0;
+ togl->BlueMap[xcol.pixel] = (float) xcol.blue / 65535.0;
+ }
+#elif defined(TOGL_WGL)
+ Win32SetColor(togl, index, red, green, blue);
+#endif
+}
+
+
+#if TOGL_USE_FONTS == 1
+# include "toglFont.c"
+#else
+
+Tcl_Obj *
+Togl_LoadBitmapFont(const Togl *togl, const char *fontname)
+{
+ return NULL;
+}
+
+int
+Togl_UnloadBitmapFont(const Togl *togl, Tcl_Obj *bitmapfont)
+{
+ return TCL_OK;
+}
+
+int
+Togl_WriteObj(const Togl *togl, const Tcl_Obj *toglfont, Tcl_Obj *obj)
+{
+ return -1;
+}
+
+int
+Togl_WriteChars(const Togl *togl, const Tcl_Obj *toglfont, const char *str,
+ int len)
+{
+ return -1;
+}
+#endif /* TOGL_USE_FONTS */
+
+
+
+/*
+ * Overlay functions
+ */
+
+
+void
+Togl_UseLayer(Togl *togl, int layer)
+{
+ if (layer == TOGL_NORMAL) {
+#if defined(TOGL_WGL)
+ int res = wglMakeCurrent(togl->tglGLHdc, togl->Ctx);
+
+ if (!res) {
+ ErrorExit(TEXT("wglMakeCurrent"));
+ }
+#elif defined(TOGL_X11)
+ (void) glXMakeCurrent(Tk_Display(togl->TkWin),
+ Tk_WindowId(togl->TkWin), togl->Ctx);
+#elif defined(TOGL_AGL)
+ (void) aglSetCurrentContext(togl->Ctx);
+#elif defined(TOGL_NSOPENGL)
+ [togl->Ctx makeCurrentContext];
+#endif
+ } else if (layer == TOGL_OVERLAY && togl->OverlayWindow) {
+#if defined(TOGL_WGL)
+ int res = wglMakeCurrent(togl->tglGLHdc, togl->tglGLOverlayHglrc);
+
+ if (!res) {
+ ErrorExit(TEXT("wglMakeCurrent overlay"));
+ }
+#elif defined(TOGL_X11)
+ (void) glXMakeCurrent(Tk_Display(togl->TkWin),
+ togl->OverlayWindow, togl->OverlayCtx);
+#elif defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+#endif
+ } else {
+ /* error */
+ }
+}
+
+
+void
+Togl_ShowOverlay(Togl *togl)
+{
+#if defined(TOGL_X11) /* not yet implemented on Windows */
+ if (togl->OverlayWindow) {
+ (void) XMapWindow(Tk_Display(togl->TkWin), togl->OverlayWindow);
+ (void) XInstallColormap(Tk_Display(togl->TkWin), togl->OverlayCmap);
+ togl->OverlayIsMapped = True;
+ }
+#endif
+}
+
+
+void
+Togl_HideOverlay(Togl *togl)
+{
+ if (togl->OverlayWindow && togl->OverlayIsMapped) {
+ (void) XUnmapWindow(Tk_Display(togl->TkWin), togl->OverlayWindow);
+ togl->OverlayIsMapped = False;
+ }
+}
+
+
+void
+Togl_PostOverlayRedisplay(Togl *togl)
+{
+ if (!togl->OverlayUpdatePending
+ && togl->OverlayWindow && togl->OverlayDisplayProc) {
+ Tk_DoWhenIdle(Togl_RenderOverlay, (ClientData) togl);
+ togl->OverlayUpdatePending = True;
+ }
+}
+
+
+int
+Togl_ExistsOverlay(const Togl *togl)
+{
+ return togl->OverlayFlag;
+}
+
+
+int
+Togl_GetOverlayTransparentValue(const Togl *togl)
+{
+ return togl->OverlayTransparentPixel;
+}
+
+
+int
+Togl_IsMappedOverlay(const Togl *togl)
+{
+ return togl->OverlayFlag && togl->OverlayIsMapped;
+}
+
+
+unsigned long
+Togl_AllocColorOverlay(const Togl *togl, float red, float green, float blue)
+{
+#if defined(TOGL_X11) /* not yet implemented on Windows */
+ if (togl->OverlayFlag && togl->OverlayCmap) {
+ XColor xcol;
+
+ xcol.red = (short) (red * 65535.0);
+ xcol.green = (short) (green * 65535.0);
+ xcol.blue = (short) (blue * 65535.0);
+ if (!XAllocColor(Tk_Display(togl->TkWin), togl->OverlayCmap, &xcol))
+ return (unsigned long) -1;
+ return xcol.pixel;
+ }
+#endif /* TOGL_X11 */
+ return (unsigned long) -1;
+}
+
+
+void
+Togl_FreeColorOverlay(const Togl *togl, unsigned long pixel)
+{
+#if defined(TOGL_X11) /* not yet implemented on Windows */
+ if (togl->OverlayFlag && togl->OverlayCmap) {
+ (void) XFreeColors(Tk_Display(togl->TkWin), togl->OverlayCmap, &pixel,
+ 1, 0);
+ }
+#endif /* TOGL_X11 */
+}
+
+
+/*
+ * User client data
+ */
+
+ClientData
+Togl_GetClientData(const Togl *togl)
+{
+ return togl->Client_Data;
+}
+
+
+void
+Togl_SetClientData(Togl *togl, ClientData clientData)
+{
+ togl->Client_Data = clientData;
+}
+
+int
+Togl_CopyContext(const Togl *from, const Togl *to, unsigned mask)
+{
+#ifdef TOGL_X11
+ int error_code;
+ int same = (glXGetCurrentContext() == to->Ctx);
+
+ if (same)
+ (void) glXMakeCurrent(to->display, None, NULL);
+ togl_SetupXErrorHandler();
+ glXCopyContext(from->display, from->Ctx, to->Ctx, mask);
+ if (error_code = togl_CheckForXError(from)) {
+ char buf[256];
+
+ XGetErrorText(from->display, error_code, buf, sizeof buf);
+ Tcl_AppendResult(from->Interp, "unable to copy context: ", buf, NULL);
+ return TCL_ERROR;
+ }
+#elif defined(TOGL_WGL)
+ int same = (wglGetCurrentContext() == to->Ctx);
+
+ if (same)
+ (void) wglMakeCurrent(to->tglGLHdc, NULL);
+ if (!wglCopyContext(from->Ctx, to->Ctx, mask)) {
+ char buf[256];
+
+ snprintf(buf, sizeof buf, "unable to copy context: %d", GetLastError());
+ Tcl_AppendElement(from->Interp, buf);
+ return TCL_ERROR;
+ }
+#elif defined(TOGL_AGL)
+ int same = (aglGetCurrentContext() == to->Ctx);
+
+ if (same)
+ (void) aglSetCurrentContext(NULL);
+ if (!aglCopyContext(from->Ctx, to->Ctx, mask)) {
+ Tcl_AppendResult(from->Interp, "unable to copy context: ",
+ aglErrorString(aglGetError()), NULL);
+ return TCL_ERROR;
+ }
+#elif defined(TOGL_NSOPENGL)
+ int same = (from->Ctx == to->Ctx);
+
+ if (same) {
+ [NSOpenGLContext clearCurrentContext];
+ }
+ [to->Ctx copyAttributesFromContext:from->Ctx withMask:mask];
+#endif
+ if (same)
+ Togl_MakeCurrent(to);
+ return TCL_OK;
+}
+
+
+#ifdef MESA_COLOR_HACK
+/*
+ * Let's know how many free colors do we have
+ */
+# define RLEVELS 5
+# define GLEVELS 9
+# define BLEVELS 5
+
+/* to free dithered_rgb_colormap pixels allocated by Mesa */
+static unsigned long *ToglMesaUsedPixelCells = NULL;
+static int ToglMesaUsedFreeCells = 0;
+
+static int
+get_free_color_cells(Display *display, int screen, Colormap colormap)
+{
+ if (!ToglMesaUsedPixelCells) {
+ XColor xcol;
+ int i;
+ int colorsfailed, ncolors = XDisplayCells(display, screen);
+
+ long r, g, b;
+
+ ToglMesaUsedPixelCells =
+ (unsigned long *) ckalloc(ncolors * sizeof (unsigned long));
+
+ /* Allocate X colors and initialize color_table[], red_table[], etc */
+ /* de Mesa 2.1: xmesa1.c setup_dithered_(...) */
+ i = colorsfailed = 0;
+ for (r = 0; r < RLEVELS; r++)
+ for (g = 0; g < GLEVELS; g++)
+ for (b = 0; b < BLEVELS; b++) {
+ int exact;
+
+ xcol.red = (r * 65535) / (RLEVELS - 1);
+ xcol.green = (g * 65535) / (GLEVELS - 1);
+ xcol.blue = (b * 65535) / (BLEVELS - 1);
+ noFaultXAllocColor(display, colormap, ncolors,
+ &xcol, &exact);
+ ToglMesaUsedPixelCells[i++] = xcol.pixel;
+ if (!exact) {
+ colorsfailed++;
+ }
+ }
+ ToglMesaUsedFreeCells = i;
+
+ XFreeColors(display, colormap, ToglMesaUsedPixelCells,
+ ToglMesaUsedFreeCells, 0x00000000);
+ }
+ return ToglMesaUsedFreeCells;
+}
+
+
+static void
+free_default_color_cells(Display *display, Colormap colormap)
+{
+ if (ToglMesaUsedPixelCells) {
+ XFreeColors(display, colormap, ToglMesaUsedPixelCells,
+ ToglMesaUsedFreeCells, 0x00000000);
+ ckfree((char *) ToglMesaUsedPixelCells);
+ ToglMesaUsedPixelCells = NULL;
+ ToglMesaUsedFreeCells = 0;
+ }
+}
+#endif
+
+/*
+ * Original stereo code contributed by Ben Evans (Ben.Evans@anusf.anu.edu.au)
+ * and was based on SGI's /usr/share/src/OpenGL/teach/stereo/glwstereo.c,
+ * which is identical to the 1997/12/1 glwstereo.c code in the CrystalEyes
+ * Software Development Kit.
+ */
+
+int
+Togl_NumEyes(const Togl *togl)
+{
+ if (togl->Stereo > TOGL_STEREO_ONE_EYE_MAX)
+ return 2;
+ return 1;
+}
+
+/* call instead of glDrawBuffer */
+void
+Togl_DrawBuffer(Togl *togl, GLenum mode)
+{
+ if (togl->Stereo <= TOGL_STEREO_ONE_EYE_MAX) {
+ /* Only drawing a single eye */
+ if (togl->currentStereoBuffer != STEREO_BUFFER_NONE) {
+ Togl_SetViewPort(togl);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ togl->currentStereoBuffer = STEREO_BUFFER_NONE;
+ }
+ switch (mode) {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
+ case GL_LEFT:
+ case GL_FRONT_LEFT:
+ case GL_RIGHT:
+ case GL_FRONT_RIGHT:
+ mode = GL_FRONT;
+ break;
+ case GL_BACK_LEFT:
+ case GL_BACK_RIGHT:
+ mode = GL_BACK;
+ break;
+ default:
+ break;
+ }
+ glDrawBuffer(mode);
+ return;
+ }
+ /* called once for each eye */
+ switch (mode) {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ /*
+ ** Simultaneous drawing to both left and right buffers isn't
+ ** really possible if we don't have a stereo capable visual.
+ ** For now just fall through and use the left buffer.
+ */
+ case GL_LEFT:
+ case GL_FRONT_LEFT:
+ case GL_BACK_LEFT:
+ togl->currentStereoBuffer = STEREO_BUFFER_LEFT;
+ break;
+ case GL_RIGHT:
+ case GL_FRONT_RIGHT:
+ case GL_BACK_RIGHT:
+ togl->currentStereoBuffer = STEREO_BUFFER_RIGHT;
+ break;
+ default:
+ break;
+ }
+ if (togl->Stereo != TOGL_STEREO_NATIVE) {
+ switch (mode) {
+ default:
+ mode = GL_FRONT;
+ break;
+ case GL_BACK:
+ case GL_BACK_LEFT:
+ case GL_BACK_RIGHT:
+ mode = GL_BACK;
+ break;
+ }
+ }
+ int w = togl->Width*togl->PixelScale, h = togl->Height*togl->PixelScale;
+ switch (togl->Stereo) {
+ default:
+ break;
+#ifdef __sgi
+ case TOGL_STEREO_SGIOLDSTYLE:
+ glXWaitGL(); /* sync with GL command stream before calling X
+ */
+ XSGISetStereoBuffer(togl->display, Tk_WindowId(togl->TkWin),
+ togl->currentStereoBuffer);
+ glXWaitX(); /* sync with X command stream before calling GL
+ */
+ break;
+#endif
+ case TOGL_STEREO_ANAGLYPH:
+ if (togl->currentStereoBuffer == STEREO_BUFFER_LEFT)
+ glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
+ else
+ glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glViewport(0, 0, w, h);
+ break;
+ case TOGL_STEREO_CROSS_EYE:
+ if (togl->currentStereoBuffer == STEREO_BUFFER_LEFT)
+ glViewport(w / 2 + 1, 0, w / 2, h);
+ else
+ glViewport(0, 0, w / 2, h);
+ break;
+ case TOGL_STEREO_WALL_EYE:
+ if (togl->currentStereoBuffer == STEREO_BUFFER_LEFT)
+ glViewport(0, 0, w / 2, h);
+ else
+ glViewport(w / 2 + 1, 0, w / 2, h);
+ break;
+ case TOGL_STEREO_DTI:
+ if (togl->currentStereoBuffer == STEREO_BUFFER_LEFT)
+ glViewport(0, 0, w / 2, h);
+ else
+ glViewport(w / 2 + 1, 0, w / 2, h);
+ break;
+ case TOGL_STEREO_ROW_INTERLEAVED:
+ glViewport(0, 0, w, h);
+ break;
+ }
+ glDrawBuffer(mode);
+}
+
+/* call instead of glClear */
+void
+Togl_Clear(const Togl *togl, GLbitfield mask)
+{
+ GLint stencil_write_mask = 0;
+ GLint stencil_clear_value = 0;
+
+ switch (togl->Stereo) {
+ default:
+ break;
+ case TOGL_STEREO_CROSS_EYE:
+ case TOGL_STEREO_WALL_EYE:
+ case TOGL_STEREO_DTI:
+ if (togl->currentStereoBuffer != STEREO_BUFFER_LEFT) {
+ /* Since glViewport does not affect what is cleared (unlike
+ * glScissor), only clear in left eye */
+ return;
+ }
+ break;
+ case TOGL_STEREO_ROW_INTERLEAVED:
+ if (togl->currentStereoBuffer == STEREO_BUFFER_LEFT) {
+ if ((mask & GL_STENCIL_BUFFER_BIT) == 0) {
+ mask |= GL_STENCIL_BUFFER_BIT;
+ glStencilMask(~0u);
+ glClearStencil(0);
+ } else {
+ glGetIntegerv(GL_STENCIL_WRITEMASK, &stencil_write_mask);
+ glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &stencil_clear_value);
+ glStencilMask(stencil_write_mask | togl->riStencilBit);
+ glClearStencil(stencil_clear_value & ~togl->riStencilBit);
+ }
+ } else {
+ mask &= ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ break;
+ }
+#if 0
+ /* only needed if we wish to support multi-eye clears */
+ if (togl->Stereo > TOGL_STEREO_ONE_EYE_MAX) {
+ GLenum drawBuffer = togl->currentDrawBuffer;
+
+ switch (drawBuffer) {
+ case GL_FRONT:
+ Togl_DrawBuffer(togl, GL_FRONT_RIGHT);
+ glClear(mask);
+ Togl_DrawBuffer(togl, drawBuffer);
+ break;
+ case GL_BACK:
+ Togl_DrawBuffer(togl, GL_BACK_RIGHT);
+ glClear(mask);
+ Togl_DrawBuffer(togl, drawBuffer);
+ break;
+ case GL_FRONT_AND_BACK:
+ Togl_DrawBuffer(togl, GL_RIGHT);
+ glClear(mask);
+ Togl_DrawBuffer(togl, drawBuffer);
+ break;
+ case GL_LEFT:
+ case GL_FRONT_LEFT:
+ case GL_BACK_LEFT:
+ case GL_RIGHT:
+ case GL_FRONT_RIGHT:
+ case GL_BACK_RIGHT:
+ default:
+ break;
+ }
+ }
+#endif
+ if (mask != 0)
+ glClear(mask);
+ if (togl->Stereo == TOGL_STEREO_ROW_INTERLEAVED) {
+ int x, y;
+
+ if (togl->currentStereoBuffer == STEREO_BUFFER_LEFT) {
+ int i;
+
+ /* initialize stencil buffer mask */
+ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT
+ | GL_LINE_BIT | GL_VIEWPORT_BIT);
+ // 2d projection
+ Togl_SetViewPort(togl);
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0, togl->Width, 0, togl->Height, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glTranslatef(0.375f, 0.375f, 0);
+ glDisable(GL_ALPHA_TEST);
+ glDisable(GL_COLOR_LOGIC_OP);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_DITHER);
+ glDisable(GL_INDEX_LOGIC_OP);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_MULTISAMPLE);
+ glLineWidth(1);
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ glStencilFunc(GL_ALWAYS, togl->riStencilBit, togl->riStencilBit);
+ glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ glBegin(GL_LINES);
+ for (i = 0; i < togl->Height; i += 2) {
+ glVertex2i(0, i);
+ glVertex2i(togl->Width, i);
+ }
+ glEnd();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glPopAttrib();
+
+ if (stencil_write_mask) {
+ glStencilMask(stencil_write_mask & ~togl->riStencilBit);
+ } else {
+ glStencilMask(~togl->riStencilBit);
+ }
+
+ Tk_GetRootCoords(togl->TkWin, &x, &y);
+ if ((y + togl->Height) % 2) {
+ glStencilFunc(GL_NOTEQUAL, togl->riStencilBit,
+ togl->riStencilBit);
+ } else {
+ glStencilFunc(GL_EQUAL, togl->riStencilBit, togl->riStencilBit);
+ }
+ } else {
+ Tk_GetRootCoords(togl->TkWin, &x, &y);
+ if ((y + togl->Height) % 2) {
+ glStencilFunc(GL_EQUAL, togl->riStencilBit, togl->riStencilBit);
+ } else {
+ glStencilFunc(GL_NOTEQUAL, togl->riStencilBit,
+ togl->riStencilBit);
+ }
+ }
+ }
+}
+
+/*
+ * Togl_Frustum and Togl_Ortho:
+ *
+ * eyeOffset is the distance from the center line
+ * and is negative for the left eye and positive for right eye.
+ * eyeDist and eyeOffset need to be in the same units as your model space.
+ * In physical space, eyeDist might be 30 inches from the screen
+ * and eyeDist would be +/- 1.25 inch (for a total interocular distance
+ * of 2.5 inches).
+ */
+
+void
+Togl_Frustum(const Togl *togl, GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+ GLdouble eyeOffset = 0, eyeShift = 0;
+
+ if (togl->Stereo == TOGL_STEREO_LEFT_EYE
+ || togl->currentStereoBuffer == STEREO_BUFFER_LEFT)
+ eyeOffset = -togl->EyeSeparation / 2; /* for left eye */
+ else if (togl->Stereo == TOGL_STEREO_RIGHT_EYE
+ || togl->currentStereoBuffer == STEREO_BUFFER_RIGHT)
+ eyeOffset = togl->EyeSeparation / 2; /* for right eye */
+ eyeShift = (togl->Convergence - zNear) * (eyeOffset / togl->Convergence);
+
+ /* compenstate for altered viewports */
+ switch (togl->Stereo) {
+ default:
+ break;
+ case TOGL_STEREO_SGIOLDSTYLE:
+ case TOGL_STEREO_DTI:
+ /* squished image is expanded, nothing needed */
+ break;
+ case TOGL_STEREO_CROSS_EYE:
+ case TOGL_STEREO_WALL_EYE:{
+ GLdouble delta = (top - bottom) / 2;
+
+ top += delta;
+ bottom -= delta;
+ break;
+ }
+ }
+
+ glFrustum(left + eyeShift, right + eyeShift, bottom, top, zNear, zFar);
+ glTranslated(-eyeShift, 0, 0);
+}
+
+void
+Togl_Ortho(const Togl *togl, GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+ /* TODO: debug this */
+ GLdouble eyeOffset = 0, eyeShift = 0;
+
+ if (togl->currentStereoBuffer == STEREO_BUFFER_LEFT)
+ eyeOffset = -togl->EyeSeparation / 2; /* for left eye */
+ else if (togl->currentStereoBuffer == STEREO_BUFFER_RIGHT)
+ eyeOffset = togl->EyeSeparation / 2; /* for right eye */
+ eyeShift = (togl->Convergence - zNear) * (eyeOffset / togl->Convergence);
+
+ /* compenstate for altered viewports */
+ switch (togl->Stereo) {
+ default:
+ break;
+ case TOGL_STEREO_SGIOLDSTYLE:
+ case TOGL_STEREO_DTI:
+ /* squished image is expanded, nothing needed */
+ break;
+ case TOGL_STEREO_CROSS_EYE:
+ case TOGL_STEREO_WALL_EYE:{
+ GLdouble delta = (top - bottom) / 2;
+
+ top += delta;
+ bottom -= delta;
+ break;
+ }
+ }
+
+ glOrtho(left + eyeShift, right + eyeShift, bottom, top, zNear, zFar);
+ glTranslated(-eyeShift, 0, 0);
+}
+
+int
+Togl_GetToglFromObj(Tcl_Interp *interp, Tcl_Obj *obj, Togl **toglPtr)
+{
+ Tcl_Command toglCmd;
+ Tcl_CmdInfo info;
+
+ toglCmd = Tcl_GetCommandFromObj(interp, obj);
+ if (Tcl_GetCommandInfoFromToken(toglCmd, &info) == 0
+ || info.objProc != Togl_ObjWidget) {
+ Tcl_AppendResult(interp, "expected togl command argument", NULL);
+ return TCL_ERROR;
+ }
+ *toglPtr = (Togl *) info.objClientData;
+ return TCL_OK;
+}
+
+int
+Togl_GetToglFromName(Tcl_Interp *interp, const char *cmdName, Togl **toglPtr)
+{
+ Tcl_CmdInfo info;
+
+ if (Tcl_GetCommandInfo(interp, cmdName, &info) == 0
+ || info.objProc != Togl_ObjWidget) {
+ Tcl_AppendResult(interp, "expected togl command argument", NULL);
+ return TCL_ERROR;
+ }
+ *toglPtr = (Togl *) info.objClientData;
+ return TCL_OK;
+}
+
+static int ObjectIsEmpty(Tcl_Obj *objPtr);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetStereo -
+ *
+ * Converts an internal int into a a Tcl string obj.
+ *
+ * Results:
+ * Tcl_Obj containing the string representation of the stereo value.
+ *
+ * Side effects:
+ * Creates a new Tcl_Obj.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+GetStereo(ClientData clientData, Tk_Window tkwin, char *recordPtr,
+ int internalOffset)
+ /* recordPtr is a pointer to widget record. */
+ /* internalOffset is the offset within *recordPtr containing the stereo
+ * value. */
+{
+ int stereo = *(int *) (recordPtr + internalOffset);
+ const char *name = "unknown";
+
+ switch (stereo) {
+ case TOGL_STEREO_NONE:
+ name = "";
+ break;
+ case TOGL_STEREO_LEFT_EYE:
+ name = "left eye";
+ break;
+ case TOGL_STEREO_RIGHT_EYE:
+ name = "right eye";
+ break;
+ case TOGL_STEREO_NATIVE:
+ name = "native";
+ break;
+ case TOGL_STEREO_SGIOLDSTYLE:
+ name = "sgioldstyle";
+ break;
+ case TOGL_STEREO_ANAGLYPH:
+ name = "anaglyph";
+ break;
+ case TOGL_STEREO_CROSS_EYE:
+ name = "cross-eye";
+ break;
+ case TOGL_STEREO_WALL_EYE:
+ name = "wall-eye";
+ break;
+ case TOGL_STEREO_DTI:
+ name = "dti";
+ break;
+ case TOGL_STEREO_ROW_INTERLEAVED:
+ name = "row interleaved";
+ break;
+ }
+ return Tcl_NewStringObj(name, -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetStereo --
+ *
+ * Converts a Tcl_Obj representing a widgets stereo into an
+ * integer value.
+ *
+ * Results:
+ * Standard Tcl result.
+ *
+ * Side effects:
+ * May store the integer value into the internal representation
+ * pointer. May change the pointer to the Tcl_Obj to NULL to indicate
+ * that the specified string was empty and that is acceptable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetStereo(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin,
+ Tcl_Obj **value, char *recordPtr, int internalOffset,
+ char *oldInternalPtr, int flags)
+ /* interp is the current interp; may be used for errors. */
+ /* tkwin is the Window for which option is being set. */
+ /* value is a pointer to the pointer to the value object. We use a pointer
+ * to the pointer because we may need to return a value (NULL). */
+ /* recordPtr is a pointer to storage for the widget record. */
+ /* internalOffset is the offset within *recordPtr at which the internal
+ * value is to be stored. */
+ /* oldInternalPtr is a pointer to storage for the old value. */
+ /* flags are the flags for the option, set Tk_SetOptions. */
+{
+ int stereo = 0;
+ char *string, *internalPtr;
+
+ internalPtr = (internalOffset > 0) ? recordPtr + internalOffset : NULL;
+
+ if ((flags & TK_OPTION_NULL_OK) && ObjectIsEmpty(*value)) {
+ *value = NULL;
+ } else {
+ /*
+ * Convert the stereo specifier into an integer value.
+ */
+
+ if (Tcl_GetBooleanFromObj(NULL, *value, &stereo) == TCL_OK) {
+ stereo = stereo ? TOGL_STEREO_NATIVE : TOGL_STEREO_NONE;
+ } else {
+ string = Tcl_GetString(*value);
+
+ if (strcmp(string, "") == 0 || strcasecmp(string, "none") == 0) {
+ stereo = TOGL_STEREO_NONE;
+ } else if (strcasecmp(string, "native") == 0) {
+ stereo = TOGL_STEREO_NATIVE;
+ /* check if available when creating visual */
+ } else if (strcasecmp(string, "left eye") == 0) {
+ stereo = TOGL_STEREO_LEFT_EYE;
+ } else if (strcasecmp(string, "right eye") == 0) {
+ stereo = TOGL_STEREO_RIGHT_EYE;
+ } else if (strcasecmp(string, "sgioldstyle") == 0) {
+ stereo = TOGL_STEREO_SGIOLDSTYLE;
+ } else if (strcasecmp(string, "anaglyph") == 0) {
+ stereo = TOGL_STEREO_ANAGLYPH;
+ } else if (strcasecmp(string, "cross-eye") == 0) {
+ stereo = TOGL_STEREO_CROSS_EYE;
+ } else if (strcasecmp(string, "wall-eye") == 0) {
+ stereo = TOGL_STEREO_WALL_EYE;
+ } else if (strcasecmp(string, "dti") == 0) {
+ stereo = TOGL_STEREO_DTI;
+ } else if (strcasecmp(string, "row interleaved") == 0) {
+ stereo = TOGL_STEREO_ROW_INTERLEAVED;
+ } else {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad stereo value \"",
+ Tcl_GetString(*value), "\"", NULL);
+ return TCL_ERROR;
+ }
+ }
+ }
+
+ if (internalPtr != NULL) {
+ *((int *) oldInternalPtr) = *((int *) internalPtr);
+ *((int *) internalPtr) = stereo;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ * RestoreStereo --
+ *
+ * Restore a stereo option value from a saved value.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Restores the old value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RestoreStereo(ClientData clientData, Tk_Window tkwin, char *internalPtr,
+ char *oldInternalPtr)
+{
+ *(int *) internalPtr = *(int *) oldInternalPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetWideInt -
+ *
+ * Converts an internal wide integer into a a Tcl WideInt obj.
+ *
+ * Results:
+ * Tcl_Obj containing the wide int value.
+ *
+ * Side effects:
+ * Creates a new Tcl_Obj.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+GetWideInt(ClientData clientData, Tk_Window tkwin, char *recordPtr,
+ int internalOffset)
+ /* recordPtr is a pointer to widget record. */
+ /* internalOffset is the offset within *recordPtr containing the wide int
+ * value. */
+{
+ Tcl_WideInt wi = *(Tcl_WideInt *) (recordPtr + internalOffset);
+
+ return Tcl_NewWideIntObj(wi);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetWideInt --
+ *
+ * Converts a Tcl_Obj representing a Tcl_WideInt.
+ *
+ * Results:
+ * Standard Tcl result.
+ *
+ * Side effects:
+ * May store the wide int value into the internal representation
+ * pointer. May change the pointer to the Tcl_Obj to NULL to indicate
+ * that the specified string was empty and that is acceptable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetWideInt(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin,
+ Tcl_Obj **value, char *recordPtr, int internalOffset,
+ char *oldInternalPtr, int flags)
+ /* interp is the current interp; may be used for errors. */
+ /* tkwin is the Window for which option is being set. */
+ /* value is a pointer to the pointer to the value object. We use a pointer
+ * to the pointer because we may need to return a value (NULL). */
+ /* recordPtr is a pointer to storage for the widget record. */
+ /* internalOffset is the offset within *recordPtr at which the internal
+ * value is to be stored. */
+ /* oldInternalPtr is a pointer to storage for the old value. */
+ /* flags are the flags for the option, set Tk_SetOptions. */
+{
+ char *internalPtr;
+ Tcl_WideInt w;
+
+ internalPtr = (internalOffset > 0) ? recordPtr + internalOffset : NULL;
+
+ if ((flags & TK_OPTION_NULL_OK) && ObjectIsEmpty(*value)) {
+ *value = NULL;
+ w = 0;
+ } else {
+ if (Tcl_GetWideIntFromObj(interp, *value, &w) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
+
+ if (internalPtr != NULL) {
+ *((Tcl_WideInt *) oldInternalPtr) = *((Tcl_WideInt *) internalPtr);
+ *((Tcl_WideInt *) internalPtr) = w;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ * RestoreWideInt --
+ *
+ * Restore a wide int option value from a saved value.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Restores the old value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RestoreWideInt(ClientData clientData, Tk_Window tkwin, char *internalPtr,
+ char *oldInternalPtr)
+{
+ *(Tcl_WideInt *) internalPtr = *(Tcl_WideInt *) oldInternalPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ObjectIsEmpty --
+ *
+ * This procedure tests whether the string value of an object is
+ * empty.
+ *
+ * Results:
+ * The return value is 1 if the string value of objPtr has length
+ * zero, and 0 otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ObjectIsEmpty(Tcl_Obj *objPtr)
+/* objPtr = Object to test. May be NULL. */
+{
+ int length;
+
+ if (objPtr == NULL) {
+ return 1;
+ }
+ if (objPtr->bytes != NULL) {
+ return (objPtr->length == 0);
+ }
+ Tcl_GetStringFromObj(objPtr, &length);
+ return (length == 0);
+}
diff --git a/ng/Togl2.1/togl.decls b/ng/Togl2.1/togl.decls
new file mode 100644
index 00000000..54d10797
--- /dev/null
+++ b/ng/Togl2.1/togl.decls
@@ -0,0 +1,195 @@
+library togl
+interface togl
+
+# Declare each of the functions in the public Togl interface. Note that
+# the an index should never be reused for a different function in order
+# to preserve backwards compatibility.
+
+# package initialization
+declare 0 generic {
+ int Togl_Init(Tcl_Interp *interp)
+}
+
+# Miscellaneous
+declare 1 generic {
+ void Togl_MakeCurrent(const Togl *togl)
+}
+declare 2 generic {
+ void Togl_PostRedisplay(Togl *togl)
+}
+declare 3 generic {
+ void Togl_SwapBuffers(const Togl *togl)
+}
+declare 33 generic {
+ Bool Togl_SwapInterval(const Togl *togl, int interval)
+}
+declare 48 generic {
+ int Togl_CopyContext(const Togl *from, const Togl *to, unsigned int mask)
+}
+
+# Query functions
+declare 4 generic {
+ const char *Togl_Ident(const Togl *togl)
+}
+declare 5 generic {
+ int Togl_Width(const Togl *togl)
+}
+declare 6 generic {
+ int Togl_Height(const Togl *togl)
+}
+declare 7 generic {
+ Tcl_Interp *Togl_Interp(const Togl *togl)
+}
+declare 8 generic {
+ Tk_Window Togl_TkWin(const Togl *togl)
+}
+declare 9 generic {
+ const char *Togl_CommandName(const Togl *togl)
+}
+declare 36 generic {
+ int Togl_ContextTag(const Togl *togl)
+}
+declare 37 generic {
+ Bool Togl_UpdatePending(const Togl *togl)
+}
+
+declare 40 generic {
+ Bool Togl_HasRGBA(const Togl *togl)
+}
+
+declare 41 generic {
+ Bool Togl_IsDoubleBuffered(const Togl *togl)
+}
+
+declare 42 generic {
+ Bool Togl_HasDepthBuffer(const Togl *togl)
+}
+
+declare 43 generic {
+ Bool Togl_HasAccumulationBuffer(const Togl *togl)
+}
+
+declare 44 generic {
+ Bool Togl_HasDestinationAlpha(const Togl *togl)
+}
+
+declare 45 generic {
+ Bool Togl_HasStencilBuffer(const Togl *togl)
+}
+
+declare 46 generic {
+ int Togl_StereoMode(const Togl *togl)
+}
+
+declare 47 generic {
+ Bool Togl_HasMultisample(const Togl *togl)
+}
+
+declare 49 generic {
+ int Togl_PixelScale(const Togl *togl)
+}
+
+
+# Color Index mode
+declare 10 generic {
+ unsigned long Togl_AllocColor(const Togl *togl, float red,
+ float green, float blue)
+}
+declare 11 generic {
+ void Togl_FreeColor(const Togl *togl, unsigned long index)
+}
+declare 12 generic {
+ void Togl_SetColor(const Togl *togl, unsigned long index,
+ float red, float green, float blue)
+}
+
+# Bitmap fonts
+declare 13 generic {
+ Tcl_Obj *Togl_LoadBitmapFont(const Togl *togl, const char *fontname)
+}
+declare 14 generic {
+ int Togl_UnloadBitmapFont(const Togl *togl, Tcl_Obj *toglfont)
+}
+
+declare 38 generic {
+ int Togl_WriteObj(const Togl *togl, const Tcl_Obj *toglfont, Tcl_Obj *obj)
+}
+
+declare 39 generic {
+ int Togl_WriteChars(const Togl *togl, const Tcl_Obj *toglfont, const char *str, int len)
+}
+
+# Overlay functions
+declare 15 generic {
+ void Togl_UseLayer(Togl *togl, int layer)
+}
+declare 16 generic {
+ void Togl_ShowOverlay(Togl *togl)
+}
+declare 17 generic {
+ void Togl_HideOverlay(Togl *togl)
+}
+declare 18 generic {
+ void Togl_PostOverlayRedisplay(Togl *togl)
+}
+declare 19 generic {
+ int Togl_ExistsOverlay(const Togl *togl)
+}
+declare 20 generic {
+ int Togl_GetOverlayTransparentValue(const Togl *togl)
+}
+declare 21 generic {
+ int Togl_IsMappedOverlay(const Togl *togl)
+}
+declare 22 generic {
+ unsigned long Togl_AllocColorOverlay(const Togl *togl,
+ float red, float green, float blue)
+}
+declare 23 generic {
+ void Togl_FreeColorOverlay(const Togl *togl, unsigned long index)
+}
+
+# User client data
+declare 24 generic {
+ ClientData Togl_GetClientData(const Togl *togl)
+}
+declare 25 generic {
+ void Togl_SetClientData(Togl *togl, ClientData clientData)
+}
+
+# Stereo support
+declare 26 generic {
+ void Togl_DrawBuffer(Togl *togl, GLenum mode)
+}
+declare 27 generic {
+ void Togl_Clear(const Togl *togl, GLbitfield mask)
+}
+declare 28 generic {
+ void Togl_Frustum(const Togl *togl, GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
+}
+declare 34 generic {
+ void Togl_Ortho(const Togl *togl, GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
+}
+declare 35 generic {
+ int Togl_NumEyes(const Togl *togl)
+}
+
+# save current contents of OpenGL window into photo image
+declare 30 generic {
+ int Togl_TakePhoto(Togl *togl, Tk_PhotoHandle photo)
+}
+
+# platform-independent lookup of OpenGL functions
+declare 31 generic {
+ Togl_FuncPtr Togl_GetProcAddr(const char *funcname)
+}
+
+# Return the Togl data associated with pathName
+declare 29 generic {
+ int Togl_GetToglFromObj(Tcl_Interp *interp, Tcl_Obj *obj, Togl **toglPtr)
+}
+declare 32 generic {
+ int Togl_GetToglFromName(Tcl_Interp *interp, const char *cmdName, Togl **toglPtr)
+}
diff --git a/ng/Togl2.1/togl.h b/ng/Togl2.1/togl.h
new file mode 100644
index 00000000..ba71cb35
--- /dev/null
+++ b/ng/Togl2.1/togl.h
@@ -0,0 +1,145 @@
+/* $Id: togl.h,v 1.39 2009/03/31 23:21:13 gregcouch Exp $ */
+
+/* vi:set sw=4: */
+
+/*
+ * Togl - a Tk OpenGL widget
+ *
+ * Copyright (C) 1996-2002 Brian Paul and Ben Bederson
+ * Copyright (C) 2005-2009 Greg Couch
+ * See the LICENSE file for copyright details.
+ */
+
+
+#ifndef TOGL_H
+# define TOGL_H
+
+//# include "togl_ws.h"
+
+# ifdef TOGL_WGL
+# define WIN32_LEAN_AND_MEAN
+# include
+# undef WIN32_LEAN_AND_MEAN
+# if defined(_MSC_VER)
+# define DllEntryPoint DllMain
+# endif
+# endif
+
+# if defined(TOGL_AGL) || defined(TOGL_NSOPENGL)
+# ifndef MAC_OSX_TCL
+# define MAC_OSX_TCL 1
+# endif
+# ifndef MAC_OSX_TK
+# define MAC_OSX_TK 1
+# endif
+# endif
+
+# ifdef USE_TOGL_STUBS
+# ifndef USE_TCL_STUBS
+# define USE_TCL_STUBS
+# endif
+# ifndef USE_TK_STUBS
+# define USE_TK_STUBS
+# endif
+# endif
+
+# include
+# include
+# if defined(TOGL_AGL)
+# include
+# elif defined(TOGL_NSOPENGL)
+# include
+# include